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
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):
"""Finds a hash of the block array"""
if hasattr(self, "_digest"):
@@ -482,6 +656,7 @@ class ChunkRenderer(object):
rendered, and blocks are drawn with a color tint depending on their
depth."""
blocks = self.blocks
pseudo_ancildata_blocks = set([85])
left_blocks = self.left_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
ancilData = blockData_expanded[x,y,z]
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)]
except KeyError:
t = None

View File

@@ -21,7 +21,7 @@ from cStringIO import StringIO
import math
import numpy
from PIL import Image, ImageEnhance, ImageOps
from PIL import Image, ImageEnhance, ImageOps, ImageDraw
import util
import composite
@@ -521,7 +521,196 @@ def generate_special_texture(blockID, data):
composite.alpha_over(img, side2, (12,6), side2)
composite.alpha_over(img, top, (0,0), top)
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
@@ -608,7 +797,7 @@ def getBiomeData(worlddir, chunkX, chunkY):
# 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)
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
# 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[91] = range(5) # jack-o-lantern
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
# what that data represents. For now, assume that the range for data is 0 to 5
# like torches