From f449efa72b27be1cf6ab9ade95325baf94b98b9c Mon Sep 17 00:00:00 2001 From: bibulle Date: Thu, 4 May 2017 16:39:18 +0200 Subject: [PATCH 1/3] Add beam to activated beacons Beams are not real blocks so, we decide to add some "fake" blocks on chunck loading. Those blocks are "beacon blocks" with data (=1) Then, we create the corresponding texture --- overviewer_core/textures.py | 93 ++++++++++++++++++++++++++++++------- overviewer_core/world.py | 38 ++++++++++++++- 2 files changed, 111 insertions(+), 20 deletions(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index c9085b6c6..94ec37d09 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -4041,26 +4041,83 @@ def command_block(self, blockid, data): # beacon block # at the moment of writing this, it seems the beacon block doens't use -# the data values -@material(blockid=138, transparent=True, nodata = True) +# the data values (we create a "fake" data to add a beam block) +@material(blockid=138, transparent=True, data=range(2)) def beacon(self, blockid, data): - # generate the three pieces of the block - t = self.load_image_texture("assets/minecraft/textures/blocks/glass.png") - glass = self.build_block(t,t) - t = self.load_image_texture("assets/minecraft/textures/blocks/obsidian.png") - obsidian = self.build_full_block((t,12),None, None, t, t) - obsidian = obsidian.resize((20,20), Image.ANTIALIAS) - t = self.load_image_texture("assets/minecraft/textures/blocks/beacon.png") - crystal = self.build_block(t,t) - crystal = crystal.resize((16,16),Image.ANTIALIAS) - - # compose the block - img = Image.new("RGBA", (24,24), self.bgcolor) - alpha_over(img, obsidian, (2, 4), obsidian) - alpha_over(img, crystal, (4,3), crystal) - alpha_over(img, glass, (0,0), glass) + + # First create the normal (real) block + if (data == 0): + # generate the three pieces of the block + t = self.load_image_texture("assets/minecraft/textures/blocks/glass.png") + glass = self.build_block(t,t) + t = self.load_image_texture("assets/minecraft/textures/blocks/obsidian.png") + obsidian = self.build_full_block((t,12),None, None, t, t) + obsidian = obsidian.resize((20,20), Image.ANTIALIAS) + t = self.load_image_texture("assets/minecraft/textures/blocks/beacon.png") + crystal = self.build_block(t,t) + crystal = crystal.resize((16,16),Image.ANTIALIAS) + + # compose the block + img = Image.new("RGBA", (24,24), self.bgcolor) + alpha_over(img, obsidian, (2, 4), obsidian) + alpha_over(img, crystal, (4,3), crystal) + alpha_over(img, glass, (0,0), glass) - return img + return img + + # This is a "fake" block to display the beam + else: + + # first, the beam itself + beacon_beam_top = self.load_image_texture("assets/minecraft/textures/entity/beacon_beam.png") + beacon_beam_top = beacon_beam_top.resize((8,8), Image.ANTIALIAS); + + beam_top = Image.new("RGBA", (24,24), self.bgcolor) + alpha_over(beam_top, beacon_beam_top, (8, 8), beacon_beam_top) + beam_top = self.transform_image_top(beam_top) + + + beacon_beam = self.load_image_texture("assets/minecraft/textures/entity/beacon_beam.png").copy() + beacon_beam = beacon_beam.resize((8,24),Image.ANTIALIAS) + + beam_side = Image.new("RGBA", (24,24), self.bgcolor) + alpha_over(beam_side, beacon_beam, (8, 0), beacon_beam) + beam_side = self.transform_image_side(beam_side) + beam_other_side = beam_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 = beam_side.split()[3] + beam_side = ImageEnhance.Brightness(beam_side).enhance(0.9) + beam_side.putalpha(sidealpha) + othersidealpha = beam_other_side.split()[3] + beam_other_side = ImageEnhance.Brightness(beam_other_side).enhance(0.8) + beam_other_side.putalpha(othersidealpha) + + # then, the halo around the beam + halo_top = Image.new("RGBA", (24,24), self.bgcolor) + halo_side = self.load_image_texture("assets/minecraft/textures/entity/beacon_beam.png").copy() + halo_block = self.build_block(halo_top,halo_side) + halo_block_copy = halo_block.copy() + halo_block_copy = ImageEnhance.Brightness(halo_block_copy).enhance(0.2) + halo_block.putalpha(halo_block_copy.split()[3]) + #halo_block = ImageEnhance.Brightness(halo_block).enhance(0.4) + + ## create the block + beam_block = Image.new("RGBA", (24,24), self.bgcolor) + alpha_over(beam_block, beam_top, (0,0), beam_top) + alpha_over(beam_block,beam_side, (4,4),beam_side) + alpha_over(beam_block,beam_other_side, (8,4),beam_other_side) + alpha_over(beam_block,halo_block, (0,0),halo_block) + + + #beam2 = self.build_block(t,t) + #beam2 = beam1.resize((16,24),Image.ANTIALIAS) + + + return beam_block + # cobblestone and mossy cobblestone walls, chorus plants # one additional bit of data value added for mossy and cobblestone diff --git a/overviewer_core/world.py b/overviewer_core/world.py index 49ac9769f..d3d05710b 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -394,6 +394,14 @@ def get_chunk(self, x, z): biomes = numpy.zeros((16, 16), dtype=numpy.uint8) chunk_data['Biomes'] = biomes + + # Looking for activated beacons + beacons = []; + for entity in chunk_data['TileEntities']: + if (entity['id'] == "minecraft:beacon") and (entity['Levels'] > 0): + beacons.append({'x': entity['x'], 'y': entity['y'], 'z':entity['z']}) + + sectionCount = 0 for section in chunk_data['Sections']: # Turn the Blocks array into a 16x16x16 numpy matrix of shorts, @@ -452,8 +460,34 @@ def get_chunk(self, x, z): logging.debug("Full traceback:", exc_info=1) raise nbt.CorruptChunkError() - - return chunk_data + + + # Add beacon beam to the current section (if needed) + for beacon in beacons: + if (beacon['y'] / 16 <= sectionCount): + yMin=max(0, beacon['y'] - sectionCount * 16) + for y in range(yMin, 16): + if (section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] == 0): + section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] = 138 + section['Data'][y][beacon['z'] % 16][beacon['x'] % 16] = 1 + + sectionCount +=1 + + # Add section if beacon beams are needed (to reach the sky !!) + if beacons: + while sectionCount < 256/16: + section1 = {'Blocks': numpy.zeros((16,16,16), dtype=numpy.uint16), + 'Data': numpy.zeros((16,16,16), dtype=numpy.uint8), + 'SkyLight': numpy.zeros((16,16,16), dtype=numpy.uint8), + 'BlockLight': numpy.zeros((16,16,16), dtype=numpy.uint8)} + for beacon in beacons: + for y in range(0, 16): + if (section1['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] == 0): + section1['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] = 138 + section1['Data'][y][beacon['z'] % 16][beacon['x'] % 16] = 1 + chunk_data['Sections'].append(section1) + sectionCount+=1; + return chunk_data def iterate_chunks(self): From a650efc62a505a291f09ec48382e39ba0b803381 Mon Sep 17 00:00:00 2001 From: bibulle Date: Tue, 9 May 2017 13:10:51 +0200 Subject: [PATCH 2/3] Add chunk sections do get beam going to the sky --- overviewer_core/world.py | 59 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/overviewer_core/world.py b/overviewer_core/world.py index d3d05710b..896e13ea1 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -402,6 +402,7 @@ def get_chunk(self, x, z): beacons.append({'x': entity['x'], 'y': entity['y'], 'z':entity['z']}) sectionCount = 0 + newSections = []; for section in chunk_data['Sections']: # Turn the Blocks array into a 16x16x16 numpy matrix of shorts, @@ -461,34 +462,50 @@ def get_chunk(self, x, z): logging.debug("Full traceback:", exc_info=1) raise nbt.CorruptChunkError() + # if we got beacons and missing regions, add one + while beacons and section['Y'] > sectionCount: + section1 = {'Y': sectionCount, + 'Blocks': numpy.zeros((16, 16, 16), dtype=numpy.uint16), + 'Data': numpy.zeros((16, 16, 16), dtype=numpy.uint8), + 'SkyLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8), + 'BlockLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8)} + self.add_beams_to_section(beacons, section1) + newSections.append(section1) + sectionCount += 1 + # Add beacon beam to the current section (if needed) - for beacon in beacons: - if (beacon['y'] / 16 <= sectionCount): - yMin=max(0, beacon['y'] - sectionCount * 16) - for y in range(yMin, 16): - if (section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] == 0): - section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] = 138 - section['Data'][y][beacon['z'] % 16][beacon['x'] % 16] = 1 + self.add_beams_to_section(beacons, section) + newSections.append(section) sectionCount +=1 # Add section if beacon beams are needed (to reach the sky !!) - if beacons: - while sectionCount < 256/16: - section1 = {'Blocks': numpy.zeros((16,16,16), dtype=numpy.uint16), - 'Data': numpy.zeros((16,16,16), dtype=numpy.uint8), - 'SkyLight': numpy.zeros((16,16,16), dtype=numpy.uint8), - 'BlockLight': numpy.zeros((16,16,16), dtype=numpy.uint8)} - for beacon in beacons: - for y in range(0, 16): - if (section1['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] == 0): - section1['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] = 138 - section1['Data'][y][beacon['z'] % 16][beacon['x'] % 16] = 1 - chunk_data['Sections'].append(section1) - sectionCount+=1; + while beacons and sectionCount < 16: + section1 = {'Y': sectionCount, + 'Blocks': numpy.zeros((16, 16, 16), dtype=numpy.uint16), + 'Data': numpy.zeros((16, 16, 16), dtype=numpy.uint8), + 'SkyLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8), + 'BlockLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8)} + self.add_beams_to_section(beacons, section1) + newSections.append(section1) + sectionCount += 1 + + chunk_data['Sections'] = newSections + + return chunk_data - + + def add_beams_to_section(self, beacons, section): + for beacon in beacons: + if (beacon['y'] / 16 <= section['Y']): + yMin=max(0, beacon['y'] - section['Y'] * 16) + for y in range(yMin, 16): + if (section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] == 0): + section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] = 138 + section['Data'][y][beacon['z'] % 16][beacon['x'] % 16] = 1 + section['BlockLight'][y][beacon['z'] % 16][beacon['x'] % 16] = 15 + section['SkyLight'][y][beacon['z'] % 16][beacon['x'] % 16] = 15 def iterate_chunks(self): """Returns an iterator over all chunk metadata in this world. Iterates From 5e567ed0d5edff30a26f3ecb08141679d8a55d69 Mon Sep 17 00:00:00 2001 From: bibulle Date: Tue, 9 May 2017 13:15:36 +0200 Subject: [PATCH 3/3] Change some formatting stuff --- overviewer_core/world.py | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/overviewer_core/world.py b/overviewer_core/world.py index 896e13ea1..801f7156d 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -394,15 +394,14 @@ def get_chunk(self, x, z): biomes = numpy.zeros((16, 16), dtype=numpy.uint8) chunk_data['Biomes'] = biomes - # Looking for activated beacons - beacons = []; - for entity in chunk_data['TileEntities']: + beacons = [] + for entity in chunk_data['TileEntities']: if (entity['id'] == "minecraft:beacon") and (entity['Levels'] > 0): - beacons.append({'x': entity['x'], 'y': entity['y'], 'z':entity['z']}) + beacons.append({'x': entity['x'], 'y': entity['y'], 'z': entity['z']}) - sectionCount = 0 - newSections = []; + section_count = 0 + new_sections = [] for section in chunk_data['Sections']: # Turn the Blocks array into a 16x16x16 numpy matrix of shorts, @@ -463,44 +462,42 @@ def get_chunk(self, x, z): raise nbt.CorruptChunkError() # if we got beacons and missing regions, add one - while beacons and section['Y'] > sectionCount: - section1 = {'Y': sectionCount, + while beacons and section['Y'] > section_count: + section1 = {'Y': section_count, 'Blocks': numpy.zeros((16, 16, 16), dtype=numpy.uint16), 'Data': numpy.zeros((16, 16, 16), dtype=numpy.uint8), 'SkyLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8), 'BlockLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8)} self.add_beams_to_section(beacons, section1) - newSections.append(section1) - sectionCount += 1 - + new_sections.append(section1) + section_count += 1 # Add beacon beam to the current section (if needed) self.add_beams_to_section(beacons, section) - newSections.append(section) + new_sections.append(section) - sectionCount +=1 + section_count += 1 # Add section if beacon beams are needed (to reach the sky !!) - while beacons and sectionCount < 16: - section1 = {'Y': sectionCount, + while beacons and section_count < 16: + section1 = {'Y': section_count, 'Blocks': numpy.zeros((16, 16, 16), dtype=numpy.uint16), 'Data': numpy.zeros((16, 16, 16), dtype=numpy.uint8), 'SkyLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8), 'BlockLight': numpy.zeros((16, 16, 16), dtype=numpy.uint8)} self.add_beams_to_section(beacons, section1) - newSections.append(section1) - sectionCount += 1 - - chunk_data['Sections'] = newSections + new_sections.append(section1) + section_count += 1 + chunk_data['Sections'] = new_sections return chunk_data def add_beams_to_section(self, beacons, section): for beacon in beacons: if (beacon['y'] / 16 <= section['Y']): - yMin=max(0, beacon['y'] - section['Y'] * 16) - for y in range(yMin, 16): + y_min=max(0, beacon['y'] - section['Y'] * 16) + for y in range(y_min, 16): if (section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] == 0): section['Blocks'][y][beacon['z'] % 16][beacon['x'] % 16] = 138 section['Data'][y][beacon['z'] % 16][beacon['x'] % 16] = 1