Skip to content

Commit

Permalink
Merge pull request alex4200#4 from alex4200/update_1.19
Browse files Browse the repository at this point in the history
froglight blocks added
  • Loading branch information
alex4200 authored and EriseZero committed Mar 12, 2023
2 parents 9ad5999 + b18c8f1 commit a3a61d5
Show file tree
Hide file tree
Showing 6 changed files with 3 additions and 1,082 deletions.
1 change: 0 additions & 1 deletion pyblock/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from .block import Block
from .section import Section
from .editor import Editor
from .maze import Maze
from .region import Region
#from .mapper import PyMap
from .errors import OutOfBoundsCoordinates
3 changes: 3 additions & 0 deletions pyblock/block_items.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ minecraft:netherrack
minecraft:oak_log
minecraft:oak_planks
minecraft:oak_wood
minecraft:ochre_froglight
minecraft:obsidian
minecraft:orange_concrete
minecraft:orange_concrete_powder
Expand All @@ -143,6 +144,7 @@ minecraft:orange_terracotta
minecraft:orange_wool
minecraft:packed_ice
minecraft:packed_mud
minecraft:pearlescent_froglight
minecraft:pink_concrete
minecraft:pink_concrete_powder
minecraft:pink_glazed_terracotta
Expand Down Expand Up @@ -206,6 +208,7 @@ minecraft:stripped_warped_stem
minecraft:terracotta
minecraft:tnt
minecraft:tube_coral_block
minecraft:verdant_froglight
minecraft:white_concrete
minecraft:white_concrete_powder
minecraft:white_glazed_terracotta
Expand Down
329 changes: 0 additions & 329 deletions pyblock/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,95 +142,6 @@ def get_section(self, section_id) -> pyblock.Section:
# Return the section
return chunk.get_section(ylevel)

def place_piece(
self,
x1: int,
y1: int,
z1: int,
block_floor: pyblock.Block,
block_fill: pyblock.Block,
block_ceil: pyblock.Block,
height: int = 4,
mag: int = 1,
):
"""Places an element of the maze.
Args:
x1: x coordinate
y1: y coordinate
z1: z coordinate
block_floor: minecraft block for the floor
block_fill: minecraft block to fill
block_ceil: minecraft block for the ceiling
height: The height of the walls
mag: Magnifier of the maze. 1 means 1:1 size, 2 means all walls, ways
are double size etc.
"""
for dx in range(mag):
for dz in range(mag):
x = x1 + dx
z = z1 + dz
self.set_block(block_floor, x, y1, z)
for y in range(y1, y1 + height):
self.set_block(block_fill, x, y + 1, z)
self.set_block(block_ceil, x, y1 + height + 1, z)

def create_maze(
self, maze: list, coord: list, blocks: list, height: int = 4, mag: int = 1
):
"""Creates and places a maze with given width and height.
start_coord is the starting coorinates (x,y,z) and
blocks is a list of the three blocks for the floow, the wall and the ceiling.
Args:
size (int, int): Size of the maze in x/z direction
coord (int, int, int): Start coordinates of the maze
blocks (string, string, string): Names for the blocks for floor, wall and ceiling
height (int): Height of the inside of the maze (default: 4)
mag (int): Magnifier number of the maze (thickness of path/walls)
"""
# Get the maze as a simple 0/1 matrix
matrix = maze.get_matrix()

# Define the blocks
block_floor = pyblock.Block(blocks[0])
block_wall = pyblock.Block(blocks[1])
block_ceil = pyblock.Block(blocks[2])
block_air = pyblock.Block("air")

# Get the start coordinates
x0 = coord[0]
y0 = coord[1]
z0 = coord[2]

# Place the walls, floor and ceiling
for row, lines in enumerate(matrix):
for col, block in enumerate(lines):
x = x0 + mag * row
z = z0 + mag * col

if block:
self.place_piece(
x,
y0,
z,
block_floor,
block_wall,
block_ceil,
height=height,
mag=mag,
)
else:
self.place_piece(
x,
y0,
z,
block_floor,
block_air,
block_ceil,
height=height,
mag=mag,
)

def copy_blocks(
self,
Expand Down Expand Up @@ -357,246 +268,6 @@ def copy_blocks(
# Save entity
self.entities[key].append(entity)

def analyze_chest(self, regions: dict):
"""Analyzes all chests found in the areas."""

# Loop over all regions and chunks to analyze
for region_coords, chunk_list in regions.items():

# Read the region
region = pyblock.Region(self.path, region_coords)
L.debug(
f"Analyzing region {region_coords[0]}/{region_coords[1]} "
f"with {len(chunk_list)} chunks"
)

# region.analyze_chest(chunk_list)
for chunk_coord in chunk_list:

# Read the chunk
chunk = region.read_chunk(chunk_coord)

base_x = 512 * region.x + 16 * chunk_coord[0]
base_z = 512 * region.z + 16 * chunk_coord[1]
L.debug(f"Analyzing {base_x}/{base_z} to {base_x+15}/{base_z+15}")

if "block_entities" not in chunk.nbt_data:
continue

for entity in chunk.nbt_data["block_entities"]:
eid = entity["id"].value

# Check if we have a chest
if eid == "minecraft:chest":
x = entity["x"].value
y = entity["y"].value
z = entity["z"].value

# Print the coordinates and the content
print(f"Chest at {x=} {y=} {z=} contains:")
try:
for item in entity["Items"]:
iid = item["id"].value
n = item["Count"].value
print(f" {n} {iid}")
except KeyError:
print("Unknown content")

def list_blocks(self, start: list, end: int) -> dict:
"""List all blocks in the given region of radius around coordinates
Args:
start: x,y,z start coordinates
end: x,y,z end coordinates
"""
blocks = {}
for x in range(start[0], end[0]):
for z in range(start[2], end[2]):
for y in range(start[1], end[1]):
block = self.get_block(x, y, z)

if block.id in blocks:
blocks[block.id] += 1
else:
blocks[block.id] = 1

# Create final sorted output for console
sorted_tuples = sorted(blocks.items(), key=operator.itemgetter(1))
sorted_dict = OrderedDict()
for k, v in sorted_tuples[::-1]:
sorted_dict[k] = v

return sorted_dict

def find_blocks(
self, start: list, end: int, block: pyblock.Block, exact: bool = False
) -> dict:
"""List all blocks in the given region of radius around coordinates
Args:
start: x,y,z start coordinates
end: x,y,z end coordinates
block: Block to search for
exact: True, if an exakt match is required including the properties
"""

def comp_exact(block, myblock):
return block == myblock

def comp_name(block, myblock):
return block.id == myblock.id

if exact:
fun_compare = comp_exact
else:
fun_compare = comp_name

locations = []
for x in range(start[0], end[0]):
for z in range(start[2], end[2]):
for y in range(start[1], end[1]):
#print(f"{x=} {y=} {z=} {self.get_block(x,y,z)}")
if fun_compare(block, self.get_block(x, y, z)):
locations.append((x, y, z))

return locations

def wayfinder(self, position: list, start: list, end: int, block: pyblock.Block):
"""Prints the next location of the given block in that area."""
def dist(a, b):
"""Returns the taxicab distance between two points"""
dx = abs(a[0] - b[0])
dy = abs(a[1] - b[1])
dz = abs(a[2] - b[2])
return dx + dy + dz

locations = self.find_blocks(start, end, block)
print(locations)

while True:

# calculate distances
distances = [dist(position, location) for location in locations]
index = distances.index(min(distances))

next_coord = locations[index]
next_dist = distances[index]
dx = next_coord[0] - position[0]
dy = next_coord[1] - position[1]
dz = next_coord[2] - position[2]

print(
f"Go dx: {dx} dz: {dz} dy: {dy} "
f"for next location at {next_coord} with distance {next_dist}. "
)

key = input("Enter key: ")
if key == "q":
sys.exit(0)

# remove the coordinate
locations.remove(next_coord)
position = next_coord

@staticmethod
def search_closest_color(colormap: dict, color: list) -> str:
"""Searches the item from the colormap with the color closest to 'color'.
Args:
colormap: dict with item as key and color as value
color: the RGB tuple defining a color
"""
mindist = 10000
minitem = None
for item, col in colormap.items():
dr = col[0] - color[0]
dg = col[1] - color[1]
db = col[2] - color[2]
dist = np.sqrt(dr * dr + dg * dg + db * db)
if dist < mindist:
mindist = dist
minitem = item
return minitem

def surface(
self, imagefile: str, scale: float, start_x: int, start_y: int, start_z: int
):
"""Create a 2-dimensional surface based on a real image.
Args:
imagefile: Name of the file for the image
scale: scaling factor, meters per pixel.
start_x, start_y, start_z: Start coordinates to place the surface
"""
# Read image and get image size
img = Image.open(imagefile)
width, height = img.size

# Get the size of the minecraft area in meters (or blocks)
width_meter = int(width * scale)
height_meter = int(height * scale)

L.info(
f"Image of size {width}x{height} will create a minecraft surface of "
f"{width_meter}x{height_meter} blocks"
)

# Load default color map
path = os.path.dirname(os.path.realpath(__file__))
with open(path + "/color_map.json", encoding="UTF-8") as json_file:
all_colors = json.load(json_file)

# Read the list of blocks to use and create the colormap from these blocks only
with open(path + "/block_items.txt") as filein:
blocks_to_use = [word.split(":")[1] for word in filein.read().splitlines()]
colormap = {
item: color for item, color in all_colors.items() if item in blocks_to_use
}

# Define a reverse map (to retrieve a block for a known color; performance increase)
reversemap = {}

# define stone block (on which the surface will be created) and air block
# to remove all above the surface
air = pyblock.Block("air")
stone = pyblock.Block("stone")

# Loop over the minecraft surface
for index_x in range(width_meter):
for index_z in range(height_meter):

# Get the corresponding location of the pixel on the original image
# No interpolation will be done!
pixel_x = int(index_x / scale)
pixel_y = int(index_z / scale)
color = img.getpixel((pixel_x, pixel_y))

# Check if the color is in the reverse map
if color in reversemap:
block = reversemap[color]
else:
# Otherwise find the item with the closest color and get the block
item = self.search_closest_color(colormap, color)
block = pyblock.Block(item)
reversemap[color] = block

# Get the plot coordinates
plot_x = start_x + index_x
plot_y = start_y
plot_z = start_z + index_z

L.debug(
f"index: {index_x}/{index_z} pixel: {pixel_x}/{pixel_y} "
f"plot: {plot_x}/{plot_z} {color=} {item=}"
)
# Set the block at this position above a stone block, and remove all above it
self.set_block(stone, plot_x, plot_y - 1, plot_z)
self.set_block(block, plot_x, plot_y, plot_z)
for y in range(plot_y + 1, 320):
self.set_block(air, plot_x, y, plot_z)

# write the blocks
self.done()

def done(self):
"""
Expand Down
Loading

0 comments on commit a3a61d5

Please sign in to comment.