| | import math |
| | import random |
| |
|
| | import save |
| | import chunk |
| |
|
| | import block_type |
| | import texture_manager |
| |
|
| | |
| |
|
| | import models |
| |
|
| | class World: |
| | def __init__(self): |
| | self.texture_manager = texture_manager.Texture_manager(16, 16, 256) |
| | self.block_types = [None] |
| |
|
| | |
| |
|
| | blocks_data_file = open("data/blocks.mcpy") |
| | blocks_data = blocks_data_file.readlines() |
| | blocks_data_file.close() |
| |
|
| | for block in blocks_data: |
| | if block[0] in ['\n', '#']: |
| | continue |
| | |
| | number, props = block.split(':', 1) |
| | number = int(number) |
| |
|
| | |
| |
|
| | name = "Unknown" |
| | model = models.cube |
| | texture = {"all": "unknown"} |
| |
|
| | |
| |
|
| | for prop in props.split(','): |
| | prop = prop.strip() |
| | prop = list(filter(None, prop.split(' ', 1))) |
| |
|
| | if prop[0] == "sameas": |
| | sameas_number = int(prop[1]) |
| |
|
| | name = self.block_types[sameas_number].name |
| | texture = self.block_types[sameas_number].block_face_textures |
| | model = self.block_types[sameas_number].model |
| | |
| | elif prop[0] == "name": |
| | name = eval(prop[1]) |
| | |
| | elif prop[0][:7] == "texture": |
| | _, side = prop[0].split('.') |
| | texture[side] = prop[1].strip() |
| |
|
| | elif prop[0] == "model": |
| | model = eval(prop[1]) |
| | |
| | |
| |
|
| | _block_type = block_type.Block_type(self.texture_manager, name, texture, model) |
| |
|
| | if number < len(self.block_types): |
| | self.block_types[number] = _block_type |
| | |
| | else: |
| | self.block_types.append(_block_type) |
| |
|
| | self.texture_manager.generate_mipmaps() |
| |
|
| | |
| |
|
| | self.save = save.Save(self) |
| |
|
| | self.chunks = {} |
| | self.save.load() |
| | |
| | for chunk_position in self.chunks: |
| | self.chunks[chunk_position].update_subchunk_meshes() |
| | self.chunks[chunk_position].update_mesh() |
| | |
| | def get_chunk_position(self, position): |
| | x, y, z = position |
| |
|
| | return ( |
| | math.floor(x / chunk.CHUNK_WIDTH), |
| | math.floor(y / chunk.CHUNK_HEIGHT), |
| | math.floor(z / chunk.CHUNK_LENGTH)) |
| |
|
| | def get_local_position(self, position): |
| | x, y, z = position |
| | |
| | return ( |
| | int(x % chunk.CHUNK_WIDTH), |
| | int(y % chunk.CHUNK_HEIGHT), |
| | int(z % chunk.CHUNK_LENGTH)) |
| |
|
| | def get_block_number(self, position): |
| | x, y, z = position |
| | chunk_position = self.get_chunk_position(position) |
| |
|
| | if not chunk_position in self.chunks: |
| | return 0 |
| | |
| | lx, ly, lz = self.get_local_position(position) |
| |
|
| | block_number = self.chunks[chunk_position].blocks[lx][ly][lz] |
| | return block_number |
| |
|
| | def is_opaque_block(self, position): |
| | |
| | |
| | |
| | block_type = self.block_types[self.get_block_number(position)] |
| |
|
| | if not block_type: |
| | return False |
| | |
| | return not block_type.transparent |
| |
|
| | def set_block(self, position, number): |
| | x, y, z = position |
| | chunk_position = self.get_chunk_position(position) |
| |
|
| | if not chunk_position in self.chunks: |
| | if number == 0: |
| | return |
| |
|
| | self.chunks[chunk_position] = chunk.Chunk(self, chunk_position) |
| | |
| | if self.get_block_number(position) == number: |
| | return |
| | |
| | lx, ly, lz = self.get_local_position(position) |
| |
|
| | self.chunks[chunk_position].blocks[lx][ly][lz] = number |
| | self.chunks[chunk_position].modified = True |
| |
|
| | self.chunks[chunk_position].update_at_position((x, y, z)) |
| | self.chunks[chunk_position].update_mesh() |
| |
|
| | cx, cy, cz = chunk_position |
| |
|
| | def try_update_chunk_at_position(chunk_position, position): |
| | if chunk_position in self.chunks: |
| | self.chunks[chunk_position].update_at_position(position) |
| | self.chunks[chunk_position].update_mesh() |
| | |
| | if lx == chunk.CHUNK_WIDTH - 1: try_update_chunk_at_position((cx + 1, cy, cz), (x + 1, y, z)) |
| | if lx == 0: try_update_chunk_at_position((cx - 1, cy, cz), (x - 1, y, z)) |
| |
|
| | if ly == chunk.CHUNK_HEIGHT - 1: try_update_chunk_at_position((cx, cy + 1, cz), (x, y + 1, z)) |
| | if ly == 0: try_update_chunk_at_position((cx, cy - 1, cz), (x, y - 1, z)) |
| |
|
| | if lz == chunk.CHUNK_LENGTH - 1: try_update_chunk_at_position((cx, cy, cz + 1), (x, y, z + 1)) |
| | if lz == 0: try_update_chunk_at_position((cx, cy, cz - 1), (x, y, z - 1)) |
| |
|
| | def try_set_block(self, pos, num, collider): |
| | |
| |
|
| | if not num: |
| | return self.set_block(pos, 0) |
| | |
| | |
| |
|
| | for block_collider in self.block_types[num].colliders: |
| | if collider & (block_collider + pos): |
| | return |
| | |
| | self.set_block(pos, num) |
| |
|
| | def draw(self): |
| | for chunk_position in self.chunks: |
| | self.chunks[chunk_position].draw() |