class_name TowerManager extends Node const TOWER_PLACEMENT_PARTICLES_SCENE := preload("res://Towers/PlacementParticles.tscn") @export var stage: Stage @export var towers_container: Node2D @export var money_manager: MoneyManager @export var path_manager: PathManager @export var notification_manager: NotificationManager func place_tower(tower: Tower): if not can_place_tower(): return var network_id = multiplayer.get_unique_id() tower.owner_id = network_id tower.name = "Tower@" + str(network_id) + "@" + str(Time.get_ticks_usec()) place_tower_in_stage.rpc(inst_to_dict(tower.to_network_data())) @rpc("any_peer", "call_local") func place_tower_in_stage(remote_data: Dictionary): var data: Tower.NetworkData = dict_to_inst(remote_data) var tower = Tower.from_network_data(data) var player = Network.get_player(tower.owner_id) player.towers[tower.global_position] = tower player.money -= money_manager.get_tower_price() Network.players_changed.emit() tower.get_node("AnimatedSprite2D").modulate = player.get_color() tower.get_node("%ComponentsAnchor").modulate = player.get_color() path_manager.fill_tower_region(tower, true) towers_container.add_child(tower, true) var particles := TOWER_PLACEMENT_PARTICLES_SCENE.instantiate() particles.global_position = tower.ground_anchor.global_position particles.play_sound = multiplayer.get_unique_id() == tower.owner_id particles.scale = tower.scale towers_container.add_child(particles) Client.placed_tower.emit(tower) func can_place_tower(): if Client.player.money < money_manager.get_tower_price(): notification_manager.add_status_message("Not enough money to build tower") return false return true