File size: 4,788 Bytes
f92c150 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
import math
import random
import save
import chunk
import block_type
import texture_manager
# import custom block models
import models
class World:
def __init__(self):
self.texture_manager = texture_manager.Texture_manager(16, 16, 256)
self.block_types = [None]
# parse block type data file
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', '#']: # skip if empty line or comment
continue
number, props = block.split(':', 1)
number = int(number)
# default block
name = "Unknown"
model = models.cube
texture = {"all": "unknown"}
# read properties
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])
# add block type
_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()
# load the world
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):
# get block type and check if it's opaque or not
# air counts as a transparent block, so test for that too
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): # set number to 0 (air) to remove block
x, y, z = position
chunk_position = self.get_chunk_position(position)
if not chunk_position in self.chunks: # if no chunks exist at this position, create a new one
if number == 0:
return # no point in creating a whole new chunk if we're not gonna be adding anything
self.chunks[chunk_position] = chunk.Chunk(self, chunk_position)
if self.get_block_number(position) == number: # no point updating mesh if the block is the same
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 we're trying to remove a block, whatever let it go through
if not num:
return self.set_block(pos, 0)
# make sure the block doesn't intersect with the passed collider
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() |