This commit is contained in:
Marek Le
2026-05-09 23:37:26 +02:00
parent 6d28b04c12
commit 2d4002bd3f
263 changed files with 5250 additions and 4597 deletions

View File

@@ -0,0 +1,92 @@
extends Node
const BUILDING_SCENE: PackedScene = preload("res://scenes/entities/building/building.tscn")
const GRID_SIZE: float = 1.0
@onready var inventory_system: Node = get_node("../InventorySystem")
var blueprints: Array = []
func _ready() -> void:
blueprints = [
{"id": &"floor", "name": "Floor", "size": Vector3(1, 0.2, 1), "color": Color(0.55, 0.4, 0.25), "material": &"wood", "cost": 1},
{"id": &"wall", "name": "Wall", "size": Vector3(1, 2, 0.2), "color": Color(0.7, 0.6, 0.45), "material": &"wood", "cost": 1},
{"id": &"door", "name": "Door", "size": Vector3(1, 2, 0.15), "color": Color(0.4, 0.25, 0.15), "material": &"wood", "cost": 2},
{"id": &"roof", "name": "Roof", "size": Vector3(1, 0.2, 1), "color": Color(0.5, 0.3, 0.2), "material": &"wood", "cost": 1}
]
func _building_root() -> Node3D:
var n: Node = get_node_or_null("/root/World/EntityRoot/Buildings")
if n == null:
n = get_node_or_null("/root/Dungeon/EntityRoot/Buildings")
return n
func get_blueprints() -> Array:
return blueprints
func find_blueprint(id: StringName) -> Dictionary:
for b in blueprints:
if b.id == id:
return b
return {}
func snap_position(pos: Vector3) -> Vector3:
return Vector3(round(pos.x / GRID_SIZE) * GRID_SIZE, max(0.0, pos.y), round(pos.z / GRID_SIZE) * GRID_SIZE)
func place(player: Node, id: StringName, pos: Vector3, rot: float) -> bool:
if not (multiplayer.is_server() or multiplayer.multiplayer_peer == null):
request_place.rpc_id(1, player.get_path(), id, pos, rot)
return false
var bp: Dictionary = find_blueprint(id)
if bp.is_empty():
return false
var mat: StringName = bp.material
var cost: int = bp.cost
if inventory_system.get_amount(player, mat) < cost:
return false
inventory_system.remove_item(player, mat, cost)
var root := _building_root()
if root == null:
return false
var b: StaticBody3D = BUILDING_SCENE.instantiate()
b.building_id = id
b.name = "B_%s_%d" % [str(id), Time.get_ticks_msec() + randi() % 1000]
root.add_child(b, true)
b.global_position = snap_position(pos)
b.rotation.y = rot
b.apply_building(id)
_apply_building_visual.rpc(b.get_path(), id)
EventBus.building_placed.emit(b)
return true
func remove(player: Node, b_path: NodePath) -> bool:
if not (multiplayer.is_server() or multiplayer.multiplayer_peer == null):
request_remove.rpc_id(1, player.get_path(), b_path)
return false
var node: Node = get_node_or_null(b_path)
if node == null:
return false
var bp: Dictionary = find_blueprint(node.building_id)
if not bp.is_empty():
inventory_system.add_item(player, bp.material, max(1, int(float(bp.cost) * 0.5)))
EventBus.building_removed.emit(node)
node.queue_free()
return true
@rpc("any_peer", "reliable")
func request_place(player_path: NodePath, id: StringName, pos: Vector3, rot: float) -> void:
var p: Node = get_node_or_null(player_path)
if p:
place(p, id, pos, rot)
@rpc("any_peer", "reliable")
func request_remove(player_path: NodePath, b_path: NodePath) -> void:
var p: Node = get_node_or_null(player_path)
if p:
remove(p, b_path)
@rpc("authority", "reliable", "call_local")
func _apply_building_visual(b_path: NodePath, id: StringName) -> void:
var node: Node = get_node_or_null(b_path)
if node and node.has_method("apply_building"):
node.apply_building(id)