class_name Block extends RefCounted const SIZE := 16 # pixels var world : World var pos : Vector2i ## The chunk-local block position for this block. var local_pos: Vector2i func _init(world: World, pos: Vector2i) -> void: self.world = world self.pos = pos self.local_pos = Vector2i(posmod(pos.x, Chunk.SIZE), posmod(pos.y, Chunk.SIZE)) func _get_property_list() -> Array[Dictionary]: var result: Array[Dictionary] for layer_name in Layers.LOOKUP: result.append({ "name" = layer_name, "type" = TYPE_OBJECT }) return result func _get(property: StringName) -> Variant: var definition := Layers.lookup(property) if not definition: return null var layer := _get_chunk_layer(definition.value, false) if layer: return layer.get_at(local_pos) else: return definition.default func _set(property: StringName, value: Variant) -> bool: var definition := Layers.lookup(property) if not definition: return false # If value is default and layer is missing, we can skip creating it. var create := (value != definition.default) as bool # GDScript being weird? var layer := _get_chunk_layer(definition.value, create) if layer: layer.set_at(local_pos, value) return true func _get_chunk_layer(script: GDScript, create: bool) -> Node: var chunk_pos := pos_to_chunk(pos) var chunk := world.get_or_create_chunk(chunk_pos) if create else world.get_chunk_or_null(chunk_pos) if not chunk: return null return chunk.get_or_create_layer(script) if create else chunk.get_layer_or_null(script) ## Returns the block position as a `Vector2i` from the given global position. static func pos_from_vec(pos: Vector2) -> Vector2i: return Vector2i((pos / SIZE).floor()) ## Returns the global position at the center of the block with the given position. static func pos_to_center(block_pos: Vector2i) -> Vector2: return (Vector2(block_pos) + Vector2.ONE / 2) * SIZE ## Returns the chunk position that this block position resides in. static func pos_to_chunk(block_pos: Vector2i) -> Vector2i: return Vector2i((Vector2(block_pos) / Chunk.SIZE).floor())