class_name Matter static var REGISTRY := Registry.new() static var NONE := Matter.new("none") static var PLASTIC := Matter.new("plastic") static var DEFAULT := NONE var id : int var name : String func _init(name: String) -> void: REGISTRY.add(name, self) class Layer extends MeshInstance2D: var data: PackedByteArray var chunk: Chunk: get: return get_parent() func _init() -> void: data.resize(Chunk.SIZE * Chunk.SIZE) texture = preload("res://world/blocks/plastic.png") static func load(buffer: StreamBuffer) -> Layer: var result := Layer.new() buffer.read_raw_buffer_into(result.data) return result func save(buffer: StreamBuffer) -> void: buffer.write_raw_buffer(data) func get_at(pos: Vector2i) -> Matter: var index := Chunk.array_index(pos) var id := data[index] return Matter.REGISTRY.lookup_by_id(id) func set_at(pos: Vector2i, value: Matter) -> void: set_id_at(pos, value.id) @rpc("reliable") func set_id_at(pos: Vector2i, id: int) -> void: var index := Chunk.array_index(pos) if data[index] == id: return # TODO: Keep track of how many non-air blocks are present, to allow for cleaning empty chunks. data[index] = id chunk.dirty = true if multiplayer.is_server(): # Send change to every player tracking this chunk. for player in chunk.get_players_tracking(): if player.network.is_local: continue # skip server player set_id_at.rpc_id(player.network.peer_id, pos, id) func _ready() -> void: chunk.clean.connect(_update_mesh) _update_mesh() func _update_mesh() -> void: const CHUNK_HALF_SIZE := (Vector2.ONE * Chunk.SIZE * Block.SIZE) / 2 var any_blocks := false var m := ImmediateMesh.new() m.surface_begin(Mesh.PRIMITIVE_TRIANGLES) var shapes: Shape.Layer = chunk.get_layer_or_null(Shape) if shapes: # Should exist, but let's sanity check. for pos in BlockRegion.LOCAL_CHUNK: var offset := (Vector2.ONE / 2) + Vector2(pos) # TODO: Support different matter. # var matter := get_at(pos) var shape := shapes.get_at(pos) if shape.points.is_empty(): continue any_blocks = true for i in range(2, shape.points.size()): var uv0 := shape.uvs[0 ] var uv1 := shape.uvs[i-1] var uv2 := shape.uvs[i ] var p0 := (offset + shape.points[0 ]) * Block.SIZE - CHUNK_HALF_SIZE var p1 := (offset + shape.points[i-1]) * Block.SIZE - CHUNK_HALF_SIZE var p2 := (offset + shape.points[i ]) * Block.SIZE - CHUNK_HALF_SIZE m.surface_set_uv(uv0); m.surface_add_vertex_2d(p0) m.surface_set_uv(uv1); m.surface_add_vertex_2d(p1) m.surface_set_uv(uv2); m.surface_add_vertex_2d(p2) if any_blocks: m.surface_end() mesh = m else: mesh = null