0

Merge branch 'fences' of https://github.com/Fenixin/Minecraft-Overviewer into Fenixin-fences

This commit is contained in:
Andrew Chin
2010-12-18 18:27:06 -05:00
2 changed files with 372 additions and 3 deletions

179
chunk.py
View File

@@ -284,6 +284,180 @@ class ChunkRenderer(object):
return self._right_blocklight return self._right_blocklight
right_blocklight = property(_load_right_blocklight) right_blocklight = property(_load_right_blocklight)
def _load_up_right(self):
"""Loads and sets data from upper-right chunk"""
chunk_path = self.world.get_chunk_path(self.coords[0] + 1, self.coords[1])
try:
chunk_data = get_lvldata(chunk_path)
self._up_right_skylight = get_skylight_array(chunk_data)
self._up_right_blocklight = get_blocklight_array(chunk_data)
self._up_right_blocks = get_blockarray(chunk_data)
except IOError:
self._up_right_skylight = None
self._up_right_blocklight = None
self._up_right_blocks = None
def _load_up_right_blocks(self):
"""Loads and returns upper-right block array"""
if not hasattr(self, "_up_right_blocks"):
self._load_up_right()
return self._up_right_blocks
up_right_blocks = property(_load_up_right_blocks)
def _load_up_left(self):
"""Loads and sets data from upper-left chunk"""
chunk_path = self.world.get_chunk_path(self.coords[0], self.coords[1] - 1)
try:
chunk_data = get_lvldata(chunk_path)
self._up_left_skylight = get_skylight_array(chunk_data)
self._up_left_blocklight = get_blocklight_array(chunk_data)
self._up_left_blocks = get_blockarray(chunk_data)
except IOError:
self._up_left_skylight = None
self._up_left_blocklight = None
self._up_left_blocks = None
def _load_up_left_blocks(self):
"""Loads and returns lower-left block array"""
if not hasattr(self, "_up_left_blocks"):
self._load_up_left()
return self._up_left_blocks
up_left_blocks = property(_load_up_left_blocks)
def generate_pseudo_ancildata(self,x,y,z,blockid):
""" Generates a pseudo ancillary data for blocks that depend of
what are surrounded and don't have ancillary data"""
blocks = self.blocks
up_left_blocks = self.up_left_blocks
up_right_blocks = self.up_right_blocks
left_blocks = self.left_blocks
right_blocks = self.right_blocks
if ( # The block is surrounded by 0 blocks with same blockid
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 1
# Now 3 in line, they should be more common:
elif ( # The block is surrounded by 2 blocks with same blockid, along x axis
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 2
elif ( # The block is surrounded by 2 blocks with same blockid, along y axis
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 3
# Now 3 in corner:
elif ( # The block is surrounded by 2 blocks with same blockid, in a -y to x corner
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 4
elif ( # The block is surrounded by 2 blocks with same blockid, in a -y to -x corner
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 5
elif ( # The block is surrounded by 2 blocks with same blockid, in a y to -x corner
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 6
elif ( # The block is surrounded by 2 blocks with same blockid, in a y to x corner
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 7
# Now 1 in dead end:
elif ( # The block is surrounded by 1 blocks with same blockid, in +x
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 8
elif ( # The block is surrounded by 1 blocks with same blockid, in -y
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 9
elif ( # The block is surrounded by 1 blocks with same blockid, in -x
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 10
elif ( # The block is surrounded by 1 blocks with same blockid, in +y
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 11
# Now surrounded by 3 identical blocks:
elif ( # The block is surrounded by 3 blocks with same blockid, in postiions -x, -y, +x
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] != blockid if y == 15 else blocks[x,y + 1,z] != blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 12
elif ( # The block is surrounded by 3 blocks with same blockid, in postiions +y, -y, -x
(up_right_blocks[0,y,z] != blockid if x == 15 else blocks[x+1,y,z] != blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 13
elif ( # The block is surrounded by 3 blocks with same blockid, in postiions -x, +y, +x
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] != blockid if y == 0 else blocks[x,y - 1,z] != blockid)
): return 14
elif ( # The block is surrounded by 3 blocks with same blockid, in postiions +y, -y, +x
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] != blockid if x == 0 else blocks[x - 1,y,z] != blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 15
# Block completely sourrounded by 4 blocks:
elif ( # The block is surrounded completely
(up_right_blocks[0,y,z] == blockid if x == 15 else blocks[x+1,y,z] == blockid) and
(left_blocks[15,y,z] == blockid if x == 0 else blocks[x - 1,y,z] == blockid) and
(right_blocks[x,0,z] == blockid if y == 15 else blocks[x,y + 1,z] == blockid) and
(up_left_blocks[x,15,z] == blockid if y == 0 else blocks[x,y - 1,z] == blockid)
): return 16
else: return None
def _hash_blockarray(self): def _hash_blockarray(self):
"""Finds a hash of the block array""" """Finds a hash of the block array"""
if hasattr(self, "_digest"): if hasattr(self, "_digest"):
@@ -482,6 +656,7 @@ class ChunkRenderer(object):
rendered, and blocks are drawn with a color tint depending on their rendered, and blocks are drawn with a color tint depending on their
depth.""" depth."""
blocks = self.blocks blocks = self.blocks
pseudo_ancildata_blocks = set([85])
left_blocks = self.left_blocks left_blocks = self.left_blocks
right_blocks = self.right_blocks right_blocks = self.right_blocks
@@ -535,6 +710,10 @@ class ChunkRenderer(object):
# also handle furnaces here, since one side has a different texture than the other # also handle furnaces here, since one side has a different texture than the other
ancilData = blockData_expanded[x,y,z] ancilData = blockData_expanded[x,y,z]
try: try:
if blockid in pseudo_ancildata_blocks:
pseudo_ancilData = self.generate_pseudo_ancildata(x,y,z,blockid)
ancilData = pseudo_ancilData
t = textures.specialblockmap[(blockid, ancilData)] t = textures.specialblockmap[(blockid, ancilData)]
except KeyError: except KeyError:
t = None t = None

View File

@@ -21,7 +21,7 @@ from cStringIO import StringIO
import math import math
import numpy import numpy
from PIL import Image, ImageEnhance, ImageOps from PIL import Image, ImageEnhance, ImageOps, ImageDraw
import util import util
import composite import composite
@@ -522,6 +522,195 @@ def generate_special_texture(blockID, data):
composite.alpha_over(img, top, (0,0), top) composite.alpha_over(img, top, (0,0), top)
return (img.convert("RGB"), img.split()[3]) return (img.convert("RGB"), img.split()[3])
if blockID == 85: # fences
# create needed images for Big stick fence
raw_texture = terrain_images[4]
raw_fence_top = Image.new("RGBA", (16,16), (38,92,255,0))
raw_fence_side = Image.new("RGBA", (16,16), (38,92,255,0))
fence_top_mask = Image.new("RGBA", (16,16), (38,92,255,0))
fence_side_mask = Image.new("RGBA", (16,16), (38,92,255,0))
# generate the masks images for textures of the fence
ImageDraw.Draw(fence_top_mask).rectangle((6,6,9,9),outline=(0,0,0),fill=(0,0,0))
ImageDraw.Draw(fence_side_mask).rectangle((6,1,9,15),outline=(0,0,0),fill=(0,0,0))
# create textures top and side for fence big stick
composite.alpha_over(raw_fence_top,raw_texture,(0,0),fence_top_mask)
composite.alpha_over(raw_fence_side,raw_texture,(0,0),fence_side_mask)
# Create the sides and the top of the big stick
fence_side = transform_image_side(raw_fence_side,85)
fence_other_side = fence_side.transpose(Image.FLIP_LEFT_RIGHT)
fence_top = transform_image(raw_fence_top,85)
# Darken the sides slightly. These methods also affect the alpha layer,
# so save them first (we don't want to "darken" the alpha layer making
# the block transparent)
sidealpha = fence_side.split()[3]
fence_side = ImageEnhance.Brightness(fence_side).enhance(0.9)
fence_side.putalpha(sidealpha)
othersidealpha = fence_other_side.split()[3]
fence_other_side = ImageEnhance.Brightness(fence_other_side).enhance(0.8)
fence_other_side.putalpha(othersidealpha)
# Compose the fence big stick
fence_big = Image.new("RGBA", (24,24), (38,92,255,0))
composite.alpha_over(fence_big,fence_side, (4,4),fence_side)
composite.alpha_over(fence_big,fence_other_side, (8,4),fence_other_side)
composite.alpha_over(fence_big,fence_top, (-1,1),fence_top)
# Now render the small sticks.
# Create needed images
raw_fence_small_side = Image.new("RGBA", (16,16), (38,92,255,0))
fence_small_side_mask = Image.new("RGBA", (16,16), (38,92,255,0))
# Generate mask
ImageDraw.Draw(fence_small_side_mask).rectangle((10,1,15,3),outline=(0,0,0),fill=(0,0,0))
ImageDraw.Draw(fence_small_side_mask).rectangle((10,7,15,9),outline=(0,0,0),fill=(0,0,0))
# create the texture for the side of small sticks fence
composite.alpha_over(raw_fence_small_side,raw_texture,(0,0),fence_small_side_mask)
# Create the sides and the top of the small sticks
fence_small_side = transform_image_side(raw_fence_small_side,85)
fence_small_other_side = fence_small_side.transpose(Image.FLIP_LEFT_RIGHT)
# Darken the sides slightly. These methods also affect the alpha layer,
# so save them first (we don't want to "darken" the alpha layer making
# the block transparent)
sidealpha = fence_small_other_side.split()[3]
fence_small_other_side = ImageEnhance.Brightness(fence_small_other_side).enhance(0.9)
fence_small_other_side.putalpha(sidealpha)
sidealpha = fence_small_side.split()[3]
fence_small_side = ImageEnhance.Brightness(fence_small_side).enhance(0.9)
fence_small_side.putalpha(sidealpha)
# Create img to compose the fence
img = Image.new("RGBA", (24,24), (38,92,255,0))
# Position of fence small sticks in img.
# These postitions are strange because the small sticks of the
# fence are at the very left and at the very right of the 16x16 images
pos_top_left = (-2,0)
pos_top_right = (14,0)
pos_bottom_right = (6,4)
pos_bottom_left = (6,4)
# +x axis points top right direction
# +y axis points bottom right direction
# First compose small sticks in the back of the image,
# then big stick and thecn small sticks in the front.
if data == 1:
img = fence_big
return (img.convert("RGB"),img.split()[3])
elif data == 2: #fence in line with x axis
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
return (img.convert("RGB"),img.split()[3])
elif data == 3: #fence in line with y axis
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
return (img.convert("RGB"),img.split()[3])
elif data == 4: #fence corner +x, -y
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_big,(0,0),fence_big)
return (img.convert("RGB"),img.split()[3])
elif data == 5: #fence corner -x, -y
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
return (img.convert("RGB"),img.split()[3])
elif data == 6: #fence corner -x, +y
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
return (img.convert("RGB"),img.split()[3])
elif data == 7: #fence corner +x, +y
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
return (img.convert("RGB"),img.split()[3])
elif data == 8: #fence dead end +x
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_big,(0,0),fence_big)
return (img.convert("RGB"),img.split()[3])
elif data == 9: #fence dead end -y
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_big,(0,0),fence_big)
return (img.convert("RGB"),img.split()[3])
elif data == 10: #fence dead end -x
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
return (img.convert("RGB"),img.split()[3])
elif data == 11: #fence dead end +y
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
return (img.convert("RGB"),img.split()[3])
elif data == 12: #fence cross with +y missing
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
return (img.convert("RGB"),img.split()[3])
elif data == 13: #fence cross with +x missing
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
return (img.convert("RGB"),img.split()[3])
elif data == 14: #fence cross with -y missing
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
return (img.convert("RGB"),img.split()[3])
elif data == 15: #fence cross with -x missing
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
return (img.convert("RGB"),img.split()[3])
elif data == 16: #fence cross
composite.alpha_over(img,fence_small_side, pos_top_left,fence_small_side) # top left
composite.alpha_over(img,fence_small_other_side, pos_top_right,fence_small_other_side) # top right
composite.alpha_over(img,fence_big,(0,0),fence_big)
composite.alpha_over(img,fence_small_other_side, pos_bottom_left,fence_small_other_side) # bottom left
composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right
return (img.convert("RGB"),img.split()[3])
elif data == None: # This can happend if a fence is in the border
# of a chunk and the chunk is in the border of the map.
composite.alpha_over(img,fence_big,(0,0),)
return (img.convert("RGB"), img.split()[3])
else: # just in case
composite.alpha_over(img,fence_big,(0,0),)
return (img.convert("RGB"), img.split()[3])
return None return None
@@ -608,7 +797,7 @@ def getBiomeData(worlddir, chunkX, chunkY):
# This set holds block ids that require special pre-computing. These are typically # This set holds block ids that require special pre-computing. These are typically
# things that require ancillary data to render properly (i.e. ladder plus orientation) # things that require ancillary data to render properly (i.e. ladder plus orientation)
special_blocks = set([66,59,61,62, 65,64,71,91,86,2,18]) special_blocks = set([66,59,61,62, 65,64,71,91,86,2,18,85])
# this is a map of special blockIDs to a list of all # this is a map of special blockIDs to a list of all
# possible values for ancillary data that it might have. # possible values for ancillary data that it might have.
@@ -622,6 +811,7 @@ special_map[64] = range(16) # wooden door
special_map[71] = range(16) # iron door special_map[71] = range(16) # iron door
special_map[91] = range(5) # jack-o-lantern special_map[91] = range(5) # jack-o-lantern
special_map[86] = range(5) # pumpkin special_map[86] = range(5) # pumpkin
special_map[85] = range(17) # fences
# apparently pumpkins and jack-o-lanterns have ancillary data, but it's unknown # apparently pumpkins and jack-o-lanterns have ancillary data, but it's unknown
# what that data represents. For now, assume that the range for data is 0 to 5 # what that data represents. For now, assume that the range for data is 0 to 5
# like torches # like torches