You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
2.0 KiB
59 lines
2.0 KiB
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())
|
|
|