Refactored stairs rendering to support corners
This commit is contained in:
@@ -244,6 +244,27 @@ check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned short bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_stairs(int block) {
|
||||||
|
/*
|
||||||
|
* Determines if a block is stairs of any material
|
||||||
|
*/
|
||||||
|
switch (block) {
|
||||||
|
case 53: /* oak wood stairs */
|
||||||
|
case 67: /* cobblestone stairs */
|
||||||
|
case 108: /* brick stairs */
|
||||||
|
case 109: /* stone brick stairs */
|
||||||
|
case 114: /* nether brick stairs */
|
||||||
|
case 128: /* sandstone stairs */
|
||||||
|
case 134: /* spruce wood stairs */
|
||||||
|
case 135: /* birch wood stairs */
|
||||||
|
case 136: /* jungle wood stairs */
|
||||||
|
case 156: /* quartz stairs */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char
|
unsigned char
|
||||||
generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
||||||
/*
|
/*
|
||||||
@@ -416,11 +437,115 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
|||||||
pr = pr * pr * 42317861 + pr * 11;
|
pr = pr * pr * 42317861 + pr * 11;
|
||||||
rotation = 3 & (pr >> 16);
|
rotation = 3 & (pr >> 16);
|
||||||
return rotation;
|
return rotation;
|
||||||
|
} else if (is_stairs(state->block)) { /* stairs */
|
||||||
|
/* 4 ancillary bits will be added to indicate which quarters of the block contain the
|
||||||
|
* upper step. Regular stairs will have 2 bits set & corner stairs will have 1 or 3.
|
||||||
|
* Southwest quarter is part of the upper step - 0x40
|
||||||
|
* / Southeast " - 0x20
|
||||||
|
* |/ Northeast " - 0x10
|
||||||
|
* ||/ Northwest " - 0x8
|
||||||
|
* |||/ flip upside down (Minecraft)
|
||||||
|
* ||||/ has North/South alignment (Minecraft)
|
||||||
|
* |||||/ ascends North or West, not South or East (Minecraft)
|
||||||
|
* ||||||/
|
||||||
|
* 0b0011011 = Stair ascending north, upside up, with both north quarters filled
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* keep track of whether neighbors are stairs, and their data */
|
||||||
|
unsigned char stairs_base[8];
|
||||||
|
unsigned char neigh_base[8];
|
||||||
|
unsigned char *stairs = stairs_base;
|
||||||
|
unsigned char *neigh = neigh_base;
|
||||||
|
|
||||||
|
/* amount to rotate/roll to get to east, west, south, north */
|
||||||
|
size_t rotations[] = {0,2,3,1};
|
||||||
|
|
||||||
|
/* masks for the filled (ridge) stair quarters: */
|
||||||
|
/* Example: the ridge for an east-ascending stair are the two east quarters */
|
||||||
|
/* ascending: east west south north */
|
||||||
|
unsigned char ridge_mask[] = { 0x30, 0x48, 0x60, 0x18 };
|
||||||
|
|
||||||
|
/* masks for the open (trench) stair quarters: */
|
||||||
|
unsigned char trench_mask[] = { 0x48, 0x30, 0x18, 0x60 };
|
||||||
|
|
||||||
|
/* boat analogy! up the stairs is toward the bow of the boat */
|
||||||
|
/* masks for port and starboard, i.e. left and right sides while ascending: */
|
||||||
|
unsigned char port_mask[] = { 0x18, 0x60, 0x30, 0x48 };
|
||||||
|
unsigned char starboard_mask[] = { 0x60, 0x18, 0x48, 0x30 };
|
||||||
|
|
||||||
|
/* we may need to lock some quarters into place depending on neighbors */
|
||||||
|
unsigned char lock_mask = 0;
|
||||||
|
|
||||||
|
unsigned char repair_rot[] = { 0, 1, 2, 3, 2, 3, 1, 0, 1, 0, 3, 2, 3, 2, 0, 1 };
|
||||||
|
|
||||||
|
/* need to get northdirection of the render */
|
||||||
|
/* TODO: get this just once? store in state? */
|
||||||
|
PyObject *texrot;
|
||||||
|
int northdir;
|
||||||
|
texrot = PyObject_GetAttrString(state->textures, "rotation");
|
||||||
|
northdir = PyInt_AsLong(texrot);
|
||||||
|
|
||||||
|
/* fix the rotation value for different northdirections */
|
||||||
|
#define FIX_ROT(x) (((x) & ~0x3) | repair_rot[((x) & 0x3) | (northdir << 2)])
|
||||||
|
ancilData = FIX_ROT(ancilData);
|
||||||
|
|
||||||
|
/* fill the ancillary bits assuming normal stairs with no corner yet */
|
||||||
|
ancilData |= ridge_mask[ancilData & 0x3];
|
||||||
|
|
||||||
|
/* get block & data for neighbors in this order: east, north, west, south */
|
||||||
|
/* so we can rotate things easily */
|
||||||
|
stairs[0] = stairs[4] = is_stairs(get_data(state, BLOCKS, x+1, y, z));
|
||||||
|
stairs[1] = stairs[5] = is_stairs(get_data(state, BLOCKS, x, y, z-1));
|
||||||
|
stairs[2] = stairs[6] = is_stairs(get_data(state, BLOCKS, x-1, y, z));
|
||||||
|
stairs[3] = stairs[7] = is_stairs(get_data(state, BLOCKS, x, y, z+1));
|
||||||
|
neigh[0] = neigh[4] = FIX_ROT(get_data(state, DATA, x+1, y, z));
|
||||||
|
neigh[1] = neigh[5] = FIX_ROT(get_data(state, DATA, x, y, z-1));
|
||||||
|
neigh[2] = neigh[6] = FIX_ROT(get_data(state, DATA, x-1, y, z));
|
||||||
|
neigh[3] = neigh[7] = FIX_ROT(get_data(state, DATA, x, y, z+1));
|
||||||
|
|
||||||
|
#undef FIX_ROT
|
||||||
|
|
||||||
|
/* Rotate the neighbors so we only have to worry about one orientation
|
||||||
|
* No matter which way the boat is facing, the the neighbors will be:
|
||||||
|
* 0: bow
|
||||||
|
* 1: port
|
||||||
|
* 2: stern
|
||||||
|
* 3: starboard */
|
||||||
|
stairs += rotations[ancilData & 0x3];
|
||||||
|
neigh += rotations[ancilData & 0x3];
|
||||||
|
|
||||||
|
/* Matching neighbor stairs to the sides should prevent cornering on that side */
|
||||||
|
/* If found, set bits in lock_mask to lock the current quarters as they are */
|
||||||
|
if (stairs[1] && (neigh[1] & 0x7) == (ancilData & 0x7)) {
|
||||||
|
/* Neighbor on port side is stairs of the same orientation as me */
|
||||||
|
/* Do NOT allow changing quarters on the port side */
|
||||||
|
lock_mask |= port_mask[ancilData & 0x3];
|
||||||
|
}
|
||||||
|
if (stairs[3] && (neigh[3] & 0x7) == (ancilData & 0x7)) {
|
||||||
|
/* Neighbor on starboard side is stairs of the same orientation as me */
|
||||||
|
/* Do NOT allow changing quarters on the starboard side */
|
||||||
|
lock_mask |= starboard_mask[ancilData & 0x3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make corner stairs -- prefer outside corners like Minecraft */
|
||||||
|
if (stairs[0] && (neigh[0] & 0x4) == (ancilData & 0x4)) {
|
||||||
|
/* neighbor at bow is stairs with same flip */
|
||||||
|
if ((neigh[0] & 0x2) != (ancilData & 0x2)) {
|
||||||
|
/* neighbor is perpendicular, cut a trench, but not where locked */
|
||||||
|
ancilData &= ~trench_mask[neigh[0] & 0x3] | lock_mask;
|
||||||
|
}
|
||||||
|
} else if (stairs[2] && (neigh[2] & 0x4) == (ancilData & 0x4)) {
|
||||||
|
/* neighbor at stern is stairs with same flip */
|
||||||
|
if ((neigh[2] & 0x2) != (ancilData & 0x2)) {
|
||||||
|
/* neighbor is perpendicular, add a ridge, but not where locked */
|
||||||
|
ancilData |= ridge_mask[neigh[2] & 0x3] & ~lock_mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ancilData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -556,7 +681,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
state.block_data = ancilData;
|
state.block_data = ancilData;
|
||||||
/* block that need pseudo ancildata:
|
/* block that need pseudo ancildata:
|
||||||
* grass, water, glass, chest, restone wire,
|
* grass, water, glass, chest, restone wire,
|
||||||
* ice, fence, portal, iron bars, glass panes */
|
* ice, fence, portal, iron bars, glass panes, stairs */
|
||||||
if ((state.block == 2) || (state.block == 9) ||
|
if ((state.block == 2) || (state.block == 9) ||
|
||||||
(state.block == 20) || (state.block == 54) ||
|
(state.block == 20) || (state.block == 54) ||
|
||||||
(state.block == 55) || (state.block == 64) ||
|
(state.block == 55) || (state.block == 64) ||
|
||||||
@@ -564,7 +689,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
(state.block == 85) || (state.block == 90) ||
|
(state.block == 85) || (state.block == 90) ||
|
||||||
(state.block == 101) || (state.block == 102) ||
|
(state.block == 101) || (state.block == 102) ||
|
||||||
(state.block == 111) || (state.block == 113) ||
|
(state.block == 111) || (state.block == 113) ||
|
||||||
(state.block == 139)) {
|
(state.block == 139) || is_stairs(state.block)) {
|
||||||
ancilData = generate_pseudo_data(&state, ancilData);
|
ancilData = generate_pseudo_data(&state, ancilData);
|
||||||
state.block_pdata = ancilData;
|
state.block_pdata = ancilData;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1622,143 +1622,115 @@ def fire(self, blockid, data):
|
|||||||
block(blockid=52, top_image="assets/minecraft/textures/blocks/mob_spawner.png", transparent=True)
|
block(blockid=52, top_image="assets/minecraft/textures/blocks/mob_spawner.png", transparent=True)
|
||||||
|
|
||||||
# wooden, cobblestone, red brick, stone brick, netherbrick, sandstone, spruce, birch, jungle and quartz stairs.
|
# wooden, cobblestone, red brick, stone brick, netherbrick, sandstone, spruce, birch, jungle and quartz stairs.
|
||||||
@material(blockid=[53,67,108,109,114,128,134,135,136,156], data=range(8), transparent=True, solid=True, nospawn=True)
|
@material(blockid=[53,67,108,109,114,128,134,135,136,156], data=range(128), transparent=True, solid=True, nospawn=True)
|
||||||
def stairs(self, blockid, data):
|
def stairs(self, blockid, data):
|
||||||
|
|
||||||
# first, rotations
|
|
||||||
# preserve the upside-down bit
|
# preserve the upside-down bit
|
||||||
upside_down = data & 0x4
|
upside_down = data & 0x4
|
||||||
data = data & 0x3
|
|
||||||
if self.rotation == 1:
|
# find solid quarters within the top or bottom half of the block
|
||||||
if data == 0: data = 2
|
# NW NE SE SW
|
||||||
elif data == 1: data = 3
|
quarters = [data & 0x8, data & 0x10, data & 0x20, data & 0x40]
|
||||||
elif data == 2: data = 1
|
|
||||||
elif data == 3: data = 0
|
# rotate the quarters so we can pretend northdirection is always upper-left
|
||||||
elif self.rotation == 2:
|
numpy.roll(quarters, [0,1,3,2][self.rotation])
|
||||||
if data == 0: data = 1
|
nw,ne,se,sw = quarters
|
||||||
elif data == 1: data = 0
|
|
||||||
elif data == 2: data = 3
|
|
||||||
elif data == 3: data = 2
|
|
||||||
elif self.rotation == 3:
|
|
||||||
if data == 0: data = 3
|
|
||||||
elif data == 1: data = 2
|
|
||||||
elif data == 2: data = 0
|
|
||||||
elif data == 3: data = 1
|
|
||||||
data = data | upside_down
|
|
||||||
|
|
||||||
if blockid == 53: # wooden
|
if blockid == 53: # wooden
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_oak.png").copy()
|
||||||
elif blockid == 67: # cobblestone
|
elif blockid == 67: # cobblestone
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/cobblestone.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/cobblestone.png").copy()
|
||||||
elif blockid == 108: # red brick stairs
|
elif blockid == 108: # red brick stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/brick.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/brick.png").copy()
|
||||||
elif blockid == 109: # stone brick stairs
|
elif blockid == 109: # stone brick stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/stonebrick.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/stonebrick.png").copy()
|
||||||
elif blockid == 114: # netherbrick stairs
|
elif blockid == 114: # netherbrick stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/nether_brick.png").copy()
|
||||||
elif blockid == 128: # sandstone stairs
|
elif blockid == 128: # sandstone stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_normal.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_normal.png").copy()
|
||||||
elif blockid == 134: # spruce wood stairs
|
elif blockid == 134: # spruce wood stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_spruce.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_spruce.png").copy()
|
||||||
elif blockid == 135: # birch wood stairs
|
elif blockid == 135: # birch wood stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_birch.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_birch.png").copy()
|
||||||
elif blockid == 136: # jungle good stairs
|
elif blockid == 136: # jungle good stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_jungle.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/planks_jungle.png").copy()
|
||||||
elif blockid == 156: # quartz block stairs
|
elif blockid == 156: # quartz block stairs
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_side.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_side.png").copy()
|
||||||
|
|
||||||
|
outside_l = texture.copy()
|
||||||
|
outside_r = texture.copy()
|
||||||
|
inside_l = texture.copy()
|
||||||
|
inside_r = texture.copy()
|
||||||
|
|
||||||
side = texture.copy()
|
# sandstone & quartz stairs have special top texture
|
||||||
half_block_u = texture.copy() # up, down, left, right
|
|
||||||
half_block_d = texture.copy()
|
|
||||||
half_block_l = texture.copy()
|
|
||||||
half_block_r = texture.copy()
|
|
||||||
|
|
||||||
# sandstone stairs have spcial top texture
|
|
||||||
if blockid == 128:
|
if blockid == 128:
|
||||||
half_block_u = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png").copy()
|
|
||||||
half_block_d = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png").copy()
|
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png").copy()
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/sandstone_top.png").copy()
|
||||||
elif blockid == 156: # also quartz stairs
|
elif blockid == 156:
|
||||||
half_block_u = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_top.png").copy()
|
|
||||||
half_block_d = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_top.png").copy()
|
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_top.png").copy()
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/quartz_block_top.png").copy()
|
||||||
|
|
||||||
# generate needed geometries
|
slab_top = texture.copy()
|
||||||
ImageDraw.Draw(side).rectangle((0,0,7,6),outline=(0,0,0,0),fill=(0,0,0,0))
|
|
||||||
ImageDraw.Draw(half_block_u).rectangle((0,8,15,15),outline=(0,0,0,0),fill=(0,0,0,0))
|
push = 8 if upside_down else 0
|
||||||
ImageDraw.Draw(half_block_d).rectangle((0,0,15,6),outline=(0,0,0,0),fill=(0,0,0,0))
|
|
||||||
ImageDraw.Draw(half_block_l).rectangle((8,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0))
|
def rect(tex,coords):
|
||||||
ImageDraw.Draw(half_block_r).rectangle((0,0,7,15),outline=(0,0,0,0),fill=(0,0,0,0))
|
ImageDraw.Draw(tex).rectangle(coords,outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
|
|
||||||
if data & 0x4 == 0x4: # upside doen stair
|
# cut out top or bottom half from inner surfaces
|
||||||
side = side.transpose(Image.FLIP_TOP_BOTTOM)
|
rect(inside_l, (0,8-push,15,15-push))
|
||||||
if data & 0x3 == 0: # ascending east
|
rect(inside_r, (0,8-push,15,15-push))
|
||||||
img = Image.new("RGBA", (24,24), self.bgcolor) # first paste the texture in the back
|
|
||||||
tmp = self.transform_image_side(half_block_d)
|
# cut out missing or obstructed quarters from each surface
|
||||||
alpha_over(img, tmp, (6,3))
|
if not nw:
|
||||||
alpha_over(img, self.build_full_block(texture, None, None, half_block_u, side.transpose(Image.FLIP_LEFT_RIGHT)))
|
rect(outside_l, (0,push,7,7+push))
|
||||||
|
rect(texture, (0,0,7,7))
|
||||||
|
if not nw or sw:
|
||||||
|
rect(inside_r, (8,push,15,7+push)) # will be flipped
|
||||||
|
if not ne:
|
||||||
|
rect(texture, (8,0,15,7))
|
||||||
|
if not ne or nw:
|
||||||
|
rect(inside_l, (0,push,7,7+push))
|
||||||
|
if not ne or se:
|
||||||
|
rect(inside_r, (0,push,7,7+push)) # will be flipped
|
||||||
|
if not se:
|
||||||
|
rect(outside_r, (0,push,7,7+push)) # will be flipped
|
||||||
|
rect(texture, (8,8,15,15))
|
||||||
|
if not se or sw:
|
||||||
|
rect(inside_l, (8,push,15,7+push))
|
||||||
|
if not sw:
|
||||||
|
rect(outside_l, (8,push,15,7+push))
|
||||||
|
rect(outside_r, (8,push,15,7+push)) # will be flipped
|
||||||
|
rect(texture, (0,8,7,15))
|
||||||
|
|
||||||
|
img = Image.new("RGBA", (24,24), self.bgcolor)
|
||||||
|
|
||||||
|
if upside_down:
|
||||||
|
# top should have no cut-outs after all
|
||||||
|
texture = slab_top
|
||||||
|
else:
|
||||||
|
# render the slab-level surface
|
||||||
|
slab_top = self.transform_image_top(slab_top)
|
||||||
|
alpha_over(img, slab_top, (0,6))
|
||||||
|
|
||||||
|
# render inner left surface
|
||||||
|
inside_l = self.transform_image_side(inside_l)
|
||||||
|
# Darken the vertical part of the second step
|
||||||
|
sidealpha = inside_l.split()[3]
|
||||||
|
# darken it a bit more than usual, looks better
|
||||||
|
inside_l = ImageEnhance.Brightness(inside_l).enhance(0.8)
|
||||||
|
inside_l.putalpha(sidealpha)
|
||||||
|
alpha_over(img, inside_l, (6,3))
|
||||||
|
|
||||||
|
# render inner right surface
|
||||||
|
inside_r = self.transform_image_side(inside_r).transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
|
# Darken the vertical part of the second step
|
||||||
|
sidealpha = inside_r.split()[3]
|
||||||
|
# darken it a bit more than usual, looks better
|
||||||
|
inside_r = ImageEnhance.Brightness(inside_r).enhance(0.7)
|
||||||
|
inside_r.putalpha(sidealpha)
|
||||||
|
alpha_over(img, inside_r, (6,3))
|
||||||
|
|
||||||
|
# render outer surfaces
|
||||||
|
alpha_over(img, self.build_full_block(texture, None, None, outside_l, outside_r))
|
||||||
|
|
||||||
elif data & 0x3 == 0x1: # ascending west
|
|
||||||
img = self.build_full_block(texture, None, None, texture, side)
|
|
||||||
|
|
||||||
elif data & 0x3 == 0x2: # ascending south
|
|
||||||
img = self.build_full_block(texture, None, None, side, texture)
|
|
||||||
|
|
||||||
elif data & 0x3 == 0x3: # ascending north
|
|
||||||
img = Image.new("RGBA", (24,24), self.bgcolor) # first paste the texture in the back
|
|
||||||
tmp = self.transform_image_side(half_block_d).transpose(Image.FLIP_LEFT_RIGHT)
|
|
||||||
alpha_over(img, tmp, (6,3))
|
|
||||||
alpha_over(img, self.build_full_block(texture, None, None, side.transpose(Image.FLIP_LEFT_RIGHT), half_block_u))
|
|
||||||
|
|
||||||
else: # normal stair
|
|
||||||
if data == 0: # ascending east
|
|
||||||
img = self.build_full_block(half_block_r, None, None, half_block_d, side.transpose(Image.FLIP_LEFT_RIGHT))
|
|
||||||
tmp1 = self.transform_image_side(half_block_u)
|
|
||||||
|
|
||||||
# Darken the vertical part of the second step
|
|
||||||
sidealpha = tmp1.split()[3]
|
|
||||||
# darken it a bit more than usual, looks better
|
|
||||||
tmp1 = ImageEnhance.Brightness(tmp1).enhance(0.8)
|
|
||||||
tmp1.putalpha(sidealpha)
|
|
||||||
|
|
||||||
alpha_over(img, tmp1, (6,4)) #workaround, fixes a hole
|
|
||||||
alpha_over(img, tmp1, (6,3))
|
|
||||||
tmp2 = self.transform_image_top(half_block_l)
|
|
||||||
alpha_over(img, tmp2, (0,6))
|
|
||||||
|
|
||||||
elif data == 1: # ascending west
|
|
||||||
img = Image.new("RGBA", (24,24), self.bgcolor) # first paste the texture in the back
|
|
||||||
tmp1 = self.transform_image_top(half_block_r)
|
|
||||||
alpha_over(img, tmp1, (0,6))
|
|
||||||
tmp2 = self.build_full_block(half_block_l, None, None, texture, side)
|
|
||||||
alpha_over(img, tmp2)
|
|
||||||
|
|
||||||
elif data == 2: # ascending south
|
|
||||||
img = Image.new("RGBA", (24,24), self.bgcolor) # first paste the texture in the back
|
|
||||||
tmp1 = self.transform_image_top(half_block_u)
|
|
||||||
alpha_over(img, tmp1, (0,6))
|
|
||||||
tmp2 = self.build_full_block(half_block_d, None, None, side, texture)
|
|
||||||
alpha_over(img, tmp2)
|
|
||||||
|
|
||||||
elif data == 3: # ascending north
|
|
||||||
img = self.build_full_block(half_block_u, None, None, side.transpose(Image.FLIP_LEFT_RIGHT), half_block_d)
|
|
||||||
tmp1 = self.transform_image_side(half_block_u).transpose(Image.FLIP_LEFT_RIGHT)
|
|
||||||
|
|
||||||
# Darken the vertical part of the second step
|
|
||||||
sidealpha = tmp1.split()[3]
|
|
||||||
# darken it a bit more than usual, looks better
|
|
||||||
tmp1 = ImageEnhance.Brightness(tmp1).enhance(0.7)
|
|
||||||
tmp1.putalpha(sidealpha)
|
|
||||||
|
|
||||||
alpha_over(img, tmp1, (6,4)) #workaround, fixes a hole
|
|
||||||
alpha_over(img, tmp1, (6,3))
|
|
||||||
tmp2 = self.transform_image_top(half_block_d)
|
|
||||||
alpha_over(img, tmp2, (0,6))
|
|
||||||
|
|
||||||
# touch up a (horrible) pixel
|
|
||||||
img.putpixel((18,3),(0,0,0,0))
|
|
||||||
|
|
||||||
return img
|
return img
|
||||||
|
|
||||||
# normal, locked (used in april's fool day), ender and trapped chest
|
# normal, locked (used in april's fool day), ender and trapped chest
|
||||||
|
|||||||
Reference in New Issue
Block a user