From 29eff95f8b6bc797baf8c18e83483eb2ba1b0bb1 Mon Sep 17 00:00:00 2001 From: Joseph Camp Date: Thu, 13 Feb 2020 17:15:10 +0000 Subject: [PATCH] Amend (blast) furnace & smoker rendering - Use 'lit' property to determine when block is on or off - Account for facing when generating textures - Clean up smoker/furnace/dispenser/dropper texture generation code --- overviewer_core/textures.py | 119 ++++++++++++++++++------------------ overviewer_core/world.py | 6 +- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 3ac5dbc..80b7fc7 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -1214,53 +1214,68 @@ block(blockid=21, top_image="assets/minecraft/textures/block/lapis_ore.png") # lapis lazuli block block(blockid=22, top_image="assets/minecraft/textures/block/lapis_block.png") -# dispensers, dropper, furnaces, and burning furnaces -@material(blockid=[23, 61, 62, 158], data=list(range(6)), solid=True) + +# dispenser, dropper, furnace, blast furnace, and smoker +@material(blockid=[23, 61, 158, 11362, 11364], data=list(range(14)), solid=True) def furnaces(self, blockid, data): # first, do the rotation if needed - if self.rotation == 1: - if data == 2: data = 5 - elif data == 3: data = 4 - elif data == 4: data = 2 - elif data == 5: data = 3 - elif self.rotation == 2: - if data == 2: data = 3 - elif data == 3: data = 2 - elif data == 4: data = 5 - elif data == 5: data = 4 - elif self.rotation == 3: - if data == 2: data = 4 - elif data == 3: data = 5 - elif data == 4: data = 3 - elif data == 5: data = 2 - - top = self.load_image_texture("assets/minecraft/textures/block/furnace_top.png") - side = self.load_image_texture("assets/minecraft/textures/block/furnace_side.png") - - if blockid == 61: - front = self.load_image_texture("assets/minecraft/textures/block/furnace_front.png") - elif blockid == 62: - front = self.load_image_texture("assets/minecraft/textures/block/furnace_front_on.png") - elif blockid == 23: - front = self.load_image_texture("assets/minecraft/textures/block/dispenser_front.png") - if data == 0: # dispenser pointing down - return self.build_block(top, top) - elif data == 1: # dispenser pointing up - dispenser_top = self.load_image_texture("assets/minecraft/textures/block/dispenser_front_vertical.png") - return self.build_block(dispenser_top, top) - elif blockid == 158: - front = self.load_image_texture("assets/minecraft/textures/block/dropper_front.png") - if data == 0: # dropper pointing down - return self.build_block(top, top) - elif data == 1: # dispenser pointing up - dropper_top = self.load_image_texture("assets/minecraft/textures/block/dropper_front_vertical.png") - return self.build_block(dropper_top, top) - - if data == 3: # pointing west + # Masked as bit 4 indicates whether the block is lit/triggered or not + if self.rotation in [1, 2, 3] and data & 0b111 in [2, 3, 4, 5]: + rotation_map = {1: {2: 5, 3: 4, 4: 2, 5: 3}, + 2: {2: 3, 3: 2, 4: 5, 5: 4}, + 3: {2: 4, 3: 5, 4: 3, 5: 2}} + data = data & 0b1000 | rotation_map[self.rotation][data & 0b111] + + # Rotation angles for top texture using data & 0b111 as an index + top_rotation_map = [0, 0, 180, 0, 270, 90, 0, 0] + + # Dispenser + texture_map = {23: {'top': 'furnace_top', 'side': 'furnace_side', + 'front': 'dispenser_front', 'top_vert': 'dispenser_front_vertical'}, + # Furnace + 61: {'top': 'furnace_top', 'side': 'furnace_side', + 'front': 'furnace_front', 'front_on': 'furnace_front_on'}, + # Dropper + 158: {'top': 'furnace_top', 'side': 'furnace_side', + 'front': 'dropper_front', 'top_vert': 'dropper_front_vertical'}, + # Blast furance + 11362: {'top': 'blast_furnace_top', 'side': 'blast_furnace_side', + 'front': 'blast_furnace_front', 'front_on': 'blast_furnace_front_on'}, + # Smoker + 11364: {'top': 'smoker_top', 'side': 'smoker_side', + 'front': 'smoker_front', 'front_on': 'smoker_front_on'}} + + if data & 0b111 in [0, 1] and 'top_vert' in texture_map[blockid]: + # Block has a special top texture when it faces up/down + # This also affects which texture is used for the sides/front + top_name = 'top_vert' if data & 0b111 == 1 else 'top' + side_name = 'top' + front_name = 'top' + else: + top_name = 'top' + side_name = 'side' + # Use block's lit/on front texture if it is defined & bit 4 is set + # Note: Some front_on texture images have multiple frames, + # but load_image_texture() crops this appropriately + # as long as the image width is 16px + if data & 0b1000 == 8 and 'front_on' in texture_map[blockid]: + front_name = 'front_on' + else: + front_name = 'front' + + top = self.load_image_texture("assets/minecraft/textures/block/%s.png" % + texture_map[blockid][top_name]).copy() + top = top.rotate(top_rotation_map[data & 0b111]) + side = self.load_image_texture("assets/minecraft/textures/block/%s.png" % + texture_map[blockid][side_name]) + front = self.load_image_texture("assets/minecraft/textures/block/%s.png" % + texture_map[blockid][front_name]) + + if data & 0b111 == 3: # pointing west return self.build_full_block(top, None, None, side, front) - elif data == 4: # pointing north + elif data & 0b111 == 4: # pointing north return self.build_full_block(top, None, None, front, side) - else: # in any other direction the front can't be seen + else: # in any other direction the front can't be seen return self.build_full_block(top, None, None, side, side) # sandstone @@ -2508,24 +2523,6 @@ def smithing_table(self, blockid, data): img = self.build_full_block(top, None, None, side3, side4, None) return img -@material(blockid=11362, solid=True, nodata=True) -def blast_furnace(self, blockid, data): - top = self.load_image_texture("assets/minecraft/textures/block/blast_furnace_top.png") - side3 = self.load_image_texture("assets/minecraft/textures/block/blast_furnace_side.png") - side4 = self.load_image_texture("assets/minecraft/textures/block/blast_furnace_front.png") - - img = self.build_full_block(top, None, None, side3, side4, None) - return img - -@material(blockid=11364, solid=True, nodata=True) -def smoker(self, blockid, data): - top = self.load_image_texture("assets/minecraft/textures/block/smoker_top.png") - side3 = self.load_image_texture("assets/minecraft/textures/block/smoker_side.png") - side4 = self.load_image_texture("assets/minecraft/textures/block/smoker_front.png") - - img = self.build_full_block(top, None, None, side3, side4, None) - return img - @material(blockid=11366, solid=True, nodata=True) def lectern(self, blockid, data): top = self.load_image_texture("assets/minecraft/textures/block/lectern_top.png") diff --git a/overviewer_core/world.py b/overviewer_core/world.py index a008688..19ceb97 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -1007,13 +1007,17 @@ class RegionSet(object): elif key == 'minecraft:dark_prismarine_slab': data = 2 - elif key in ['minecraft:ladder', 'minecraft:chest', 'minecraft:ender_chest', 'minecraft:trapped_chest', 'minecraft:furnace']: + elif key in ['minecraft:ladder', 'minecraft:chest', 'minecraft:ender_chest', + 'minecraft:trapped_chest', 'minecraft:furnace', + 'minecraft:blast_furnace', 'minecraft:smoker']: facing = palette_entry['Properties']['facing'] data = {'north': 2, 'south': 3, 'west': 4, 'east': 5}[facing] if key in ['minecraft:chest', 'minecraft:trapped_chest']: # type property should exist, but default to 'single' just in case chest_type = palette_entry['Properties'].get('type', 'single') data |= {'left': 0x8, 'right': 0x10, 'single': 0x0}[chest_type] + elif key in ['minecraft:furnace', 'minecraft:blast_furnace', 'minecraft:smoker']: + data |= 8 if palette_entry['Properties'].get('lit', 'false') == 'true' else 0 elif key in ['minecraft:beehive', 'minecraft:bee_nest']: facing = palette_entry['Properties']['facing'] honey_level = int(palette_entry['Properties']['honey_level'])