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.
82 lines
2.6 KiB
82 lines
2.6 KiB
class_name Chunk |
|
extends Node2D |
|
|
|
const SIZE := 32 # blocks |
|
|
|
## Emitted once after a chunk has been marked dirty. |
|
signal clean |
|
|
|
var chunk_pos: Vector2i |
|
var dirty := false |
|
|
|
var tracked_by: Dictionary[ChunkLoader, Variant] # value is unused |
|
func get_players_tracking() -> Array[Player]: |
|
var result: Array[Player] |
|
for chunk_loader in tracked_by: |
|
var player := chunk_loader.get_parent() as Player |
|
if player: result.append(player) |
|
return result |
|
|
|
func _init(chunk_pos: Vector2i) -> void: |
|
self.chunk_pos = chunk_pos |
|
name = "Chunk %s" % chunk_pos |
|
position = (Vector2(chunk_pos) + Vector2.ONE / 2) * (Block.SIZE * SIZE) |
|
|
|
func _process(delta: float) -> void: |
|
if not dirty: return |
|
clean.emit() |
|
dirty = false |
|
|
|
|
|
static func load(buffer: StreamBuffer) -> Chunk: |
|
var chunk_pos := buffer.read_vector2i_16() |
|
var chunk := Chunk.new(chunk_pos) |
|
|
|
var layer_count := buffer.read_int8() |
|
for i in layer_count: |
|
var layer_name := buffer.read_string() |
|
var layer := Layers.load(layer_name, buffer) |
|
chunk.add_child(layer) |
|
|
|
return chunk |
|
|
|
func save(buffer: StreamBuffer) -> void: |
|
buffer.write_vector2i_16(chunk_pos) |
|
buffer.write_int8(get_child_count()) |
|
for layer in get_children(): |
|
buffer.write_string(layer.name) |
|
layer.save(buffer) |
|
|
|
|
|
func get_layer_or_null(script: GDScript) -> Node: |
|
var layer_name := str(script.get_global_name()) |
|
var layer := get_node_or_null(layer_name) |
|
return layer |
|
|
|
func get_or_create_layer(script: GDScript) -> Node: |
|
var layer_name := str(script.get_global_name()) |
|
var layer := get_node_or_null(layer_name) |
|
if layer: return layer |
|
|
|
# We actually want to create is the inner "Layer" script. |
|
var layer_script: GDScript = script.get_script_constant_map().get("Layer") |
|
layer = layer_script.new() |
|
layer.name = layer_name |
|
add_child(layer) |
|
return layer |
|
|
|
|
|
## Returns the chunk position as a `Vector2i` from the given global position. |
|
static func pos_from_vec(pos: Vector2) -> Vector2i: |
|
return Vector2i((pos / (Block.SIZE * SIZE)).floor()) |
|
|
|
## Returns the global position at the center of the chunk with the given position. |
|
static func pos_to_center(chunk_pos: Vector2i) -> Vector2: |
|
return (Vector2(chunk_pos) + Vector2.ONE / 2) * (Block.SIZE * SIZE) |
|
|
|
## Creates an integer index from a chunk-local block position that can be used to index into an array. |
|
static func array_index(local_pos: Vector2i) -> int: |
|
assert((local_pos.x >= 0) and (local_pos.x < Chunk.SIZE)) |
|
assert((local_pos.y >= 0) and (local_pos.y < Chunk.SIZE)) |
|
# Using `posmod` ensures `local_pos` is valid, and this returns a valid index. |
|
return posmod(local_pos.x, Chunk.SIZE) + posmod(local_pos.y, Chunk.SIZE) * Chunk.SIZE
|
|
|