From 12d2ef9c00a4a877d4cdc5573062b70bb04120b5 Mon Sep 17 00:00:00 2001 From: David Vierra Date: Mon, 16 Nov 2015 23:08:11 -1000 Subject: [PATCH] Revise method for finding places where mobs can spawn. --- .../rendering/chunkmeshes/mobspawns.py | 45 ++++++++++++++----- src/mceditlib/blocktypes/__init__.py | 13 +++++- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/mcedit2/rendering/chunkmeshes/mobspawns.py b/src/mcedit2/rendering/chunkmeshes/mobspawns.py index 3994aec..6750705 100644 --- a/src/mcedit2/rendering/chunkmeshes/mobspawns.py +++ b/src/mcedit2/rendering/chunkmeshes/mobspawns.py @@ -28,6 +28,7 @@ class MobSpawnsBlockMesh(ChunkMeshBase): """ vertexes = [] + blocktypes = chunk.blocktypes for cy in chunk.sectionPositions(): section = chunk.getSection(cy) @@ -37,29 +38,49 @@ class MobSpawnsBlockMesh(ChunkMeshBase): blockLight = section.BlockLight skyLight = section.SkyLight blocks = section.Blocks + normalCube = blocktypes.normalCube[blocks] + materialLiquid = blocktypes.materialLiquid[blocks] - # A block can spawn monsters if it is air, and the block above it is air, - # and the block below it is solid, and the light level is < 8. - # blocks with blockLight < 8 AND skyLight < 8 will always spawn monsters - # blocks with blockLight < 8 AND skyLight >= 8 will only spawn monsters at night + # A block can spawn monsters if: + # the block is not a normal cube + # the block is not a liquid + # the block above is not a normal cube + # the block below has a solid top surface + # the block below is not bedrock or barrier + # And the block's light level: + # blockLight < 8 AND skyLight < 8 will always spawn monsters + # blockLight < 8 AND skyLight >= 8 will only spawn monsters at night + + # A block "has a solid top surface" if: + # it is opaque and is a full cube OR + # it is a stairs of type "half=top" OR + # it is a slab of type "half=top" OR + # it is a hopper OR + # it is a snow layer of type "level==7" + + # fuck it + validBelowBlocks = normalCube & (blocks != blocktypes['minecraft:bedrock'].ID) + validBelowBlocks &= (blocks != blocktypes['minecraft:barrier'].ID) lowBlockLight = blockLight < 8 lowNightLight = lowBlockLight & (skyLight < 8) lowDayLight = lowBlockLight & (skyLight >= 8) - validBlocks = blocks == 0 # block is air - validBlocks[:-1] &= blocks[1:] == 0 # block above is air - validBlocks[1:] &= blocks[:-1] != 0 # block below is not air + validBlocks = normalCube == 0 # block is not normal + validBlocks &= materialLiquid == 0 # block is not liquid + validBlocks[:-1] &= normalCube[1:] == 0 # block above is not normal + validBlocks[1:] &= validBelowBlocks[:-1] # block below has solid top surface belowSection = chunk.getSection(cy-1) if belowSection: - validBlocks[:1] &= belowSection.Blocks[-1:] != 0 + belowSectionBlocks = belowSection.Blocks[-1:] + validBlocks[:1] &= blocktypes.normalCube[belowSectionBlocks] else: validBlocks[:1] = 0 - aboveSection = chunk.getSection(cy+1) + aboveSection = chunk.getSection(cy+1) if aboveSection: - validBlocks[-1:] &= aboveSection.Blocks[:1] == 0 + validBlocks[-1:] &= blocktypes.normalCube[aboveSection.Blocks[:1]] == 0 def getVertexes(mask, color): y, z, x = mask.nonzero() @@ -75,8 +96,8 @@ class MobSpawnsBlockMesh(ChunkMeshBase): vertexBuffer.rgba[:] = color return vertexBuffer - nightVertexes = getVertexes(lowNightLight & validBlocks, (0xff, 0x00, 0x00, 0x3f)) - dayVertexes = getVertexes(lowDayLight & validBlocks, (0xff, 0xFF, 0x00, 0x3f)) + nightVertexes = getVertexes(lowNightLight & validBlocks, (0xff, 0x00, 0x00, 0x6f)) + dayVertexes = getVertexes(lowDayLight & validBlocks, (0xff, 0xFF, 0x00, 0x6f)) vertexes.append(dayVertexes) vertexes.append(nightVertexes) diff --git a/src/mceditlib/blocktypes/__init__.py b/src/mceditlib/blocktypes/__init__.py index 43fd42c..bbc35ae 100644 --- a/src/mceditlib/blocktypes/__init__.py +++ b/src/mceditlib/blocktypes/__init__.py @@ -91,26 +91,35 @@ class BlockTypeSet(object): 'color': 0xffffff, 'biomeTintType': None, # "grass", "leaves", or None 'useNeighborBrightness': False, + 'normalCube': True, + 'materialLiquid': False, } self.aka = defaultdict(lambda: "") - self.useNeighborBrightness = numpy.zeros(id_limit, dtype='uint8') self.useNeighborBrightness[:] = self.defaults['useNeighborBrightness'] self.brightness = numpy.zeros(id_limit, dtype='uint8') self.brightness[:] = self.defaults['brightness'] + self.opacity = numpy.zeros(id_limit, dtype='uint8') self.opacity[:] = self.defaults['opacity'] + self.renderColor = numpy.zeros((id_limit, 16, 3), dtype='uint8') self.renderColor[:] = 0xFF + self.mapColor = numpy.zeros((id_limit, 16, 3), dtype='uint8') self.mapColor[:] = 0xFF self.opaqueCube = numpy.ones((id_limit, ), dtype='uint8') self.opaqueCube[0] = 0 + self.normalCube = numpy.ones((id_limit, ), dtype='uint8') + self.normalCube[0] = 0 + + self.materialLiquid = numpy.zeros((id_limit, ), dtype='uint8') + self.name = "Unnamed Set" self.namePrefix = "minecraft:" @@ -316,6 +325,8 @@ class BlockTypeSet(object): 'brightness', 'opacity', 'useNeighborBrightness', + 'normalCube', + 'materialLiquid', ]: # does not have data axis if key in blockJson: array = getattr(self, key)