diff --git a/src/game/engine/src/autoloads/game_state_serialization_helpers.gd b/src/game/engine/src/autoloads/game_state_serialization_helpers.gd deleted file mode 100644 index 2c1b82e2..00000000 --- a/src/game/engine/src/autoloads/game_state_serialization_helpers.gd +++ /dev/null @@ -1,26 +0,0 @@ -extends RefCounted -## Stateless serialization helpers for GameState. -## Called by game_state.gd; not instanced — all methods are static. - -const GameMapScript: GDScript = preload("res://engine/src/map/game_map.gd") - - -static func serialize_layer(layer: Dictionary) -> Dictionary: - var serialized: Dictionary = {"id": layer.get("id", "")} - var map_ref: RefCounted = layer.get("map") - if map_ref is GameMapScript: - serialized["map"] = map_ref.to_dict() - return serialized - - -static func deserialize_layer(layer_data: Dictionary) -> Dictionary: - var layer: Dictionary = { - "id": layer_data.get("id", ""), - "map": null, - "fog": null, - "units": [], - "settlements": [], - } - if layer_data.has("map") and layer_data["map"] is Dictionary: - layer["map"] = GameMapScript.from_dict(layer_data["map"]) - return layer diff --git a/src/game/engine/src/modules/management/achievement_tracker.gd b/src/game/engine/src/modules/management/achievement_tracker.gd deleted file mode 100644 index feb35309..00000000 --- a/src/game/engine/src/modules/management/achievement_tracker.gd +++ /dev/null @@ -1,97 +0,0 @@ -class_name AchievementTracker -extends RefCounted - -signal achievement_unlocked(achievement_id: String, data: Dictionary) - -const DATA_PATH: String = "res://public/games/age-of-dwarves/data/achievements.json" - -var _achievements: Array[Dictionary] = [] -var _unlocked: Dictionary = {} -var _counts: Dictionary = {} - - -func load_data() -> void: - if not FileAccess.file_exists(DATA_PATH): - push_warning("AchievementTracker: missing %s" % DATA_PATH) - return - var file: FileAccess = FileAccess.open(DATA_PATH, FileAccess.READ) - if file == null: - return - var text: String = file.get_as_text() - file.close() - var json: JSON = JSON.new() - if json.parse(text) != OK or not (json.data is Dictionary): - return - var root: Dictionary = json.data as Dictionary - var entries: Array = root.get("achievements", []) as Array - for entry: Dictionary in entries: - _achievements.append(entry) - - -func connect_bus(bus: Node) -> void: - if bus == null: - return - bus.connect("combat_resolved", _on_combat_resolved) - bus.connect("city_founded", _on_city_founded) - bus.connect("city_captured", _on_city_captured) - bus.connect("tech_researched", _on_tech_researched) - bus.connect("wonder_built", _on_wonder_built) - bus.connect("victory_achieved", _on_victory) - - -func is_unlocked(id: String) -> bool: - return _unlocked.has(id) - - -func unlocked_ids() -> Array: - return _unlocked.keys() - - -func _increment(signal_name: String, match_fn: Callable = Callable()) -> void: - for entry: Dictionary in _achievements: - var trigger: Dictionary = entry.get("trigger", {}) as Dictionary - if String(trigger.get("signal", "")) != signal_name: - continue - if match_fn.is_valid() and not bool(match_fn.call(trigger)): - continue - var id: String = String(entry.get("id", "")) - if _unlocked.has(id): - continue - var new_count: int = int(_counts.get(id, 0)) + 1 - _counts[id] = new_count - if new_count >= int(trigger.get("count", 1)): - _unlock(entry) - - -func _unlock(entry: Dictionary) -> void: - var id: String = String(entry.get("id", "")) - _unlocked[id] = true - achievement_unlocked.emit(id, entry) - - -func _on_combat_resolved(_attacker: Variant, _defender: Variant, result: Dictionary) -> void: - var winner: String = String(result.get("winner", "")) - _increment("combat_resolved", func(t: Dictionary) -> bool: - var cond: String = String(t.get("condition", "")) - return cond == "" or (cond == "attacker_wins" and winner == "attacker") - ) - - -func _on_city_founded(_city: Variant, _player_index: int) -> void: - _increment("city_founded") - - -func _on_city_captured(_city: Variant, _old_owner: int, _new_owner: int) -> void: - _increment("city_captured") - - -func _on_tech_researched(_tech_id: String, _player_index: int) -> void: - _increment("tech_researched") - - -func _on_wonder_built(_wonder_id: String, _player_index: int) -> void: - _increment("wonder_built") - - -func _on_victory(_player_index: int, _victory_type: String) -> void: - _increment("victory_achieved") diff --git a/src/game/engine/src/modules/management/turn_processor_signals.gd b/src/game/engine/src/modules/management/turn_processor_signals.gd deleted file mode 100644 index c86fbd82..00000000 --- a/src/game/engine/src/modules/management/turn_processor_signals.gd +++ /dev/null @@ -1,143 +0,0 @@ -extends RefCounted -## Signal replay helpers for TurnProcessor. Parses the event arrays returned -## by GdTurnProcessor.advance_turn() and emits the corresponding EventBus -## signals so the UI stays in sync with Rust state mutations. - -const PlayerScript: GDScript = preload("res://engine/src/entities/player.gd") -const CityScript: GDScript = preload("res://engine/src/entities/city.gd") -const UnitScript: GDScript = preload("res://engine/src/entities/unit.gd") -const UnitManagerScript: GDScript = preload( - "res://engine/src/modules/management/unit_manager.gd" -) - -## Assigned by TurnProcessor after construction -var unit_manager: RefCounted # UnitManager - - -func replay_growth_events(player: PlayerScript, result: Dictionary) -> void: - var growth_events: Array = result.get("growth_events", []) as Array - for ev: Dictionary in growth_events: - var city_id: String = ev.get("city_id", "") as String - var event_type: String = ev.get("type", "") as String - var new_pop: int = int(ev.get("population", 0)) - for city_raw: RefCounted in player.cities: - var city: CityScript = city_raw as CityScript - if city == null or city.id != city_id: - continue - if event_type == "grew": - EventBus.city_grew.emit(city, new_pop) - elif event_type == "starved": - EventBus.city_starved.emit(city, new_pop) - break - - -func replay_production_events(player: PlayerScript, result: Dictionary) -> void: - var prod_events: Array = result.get("production_events", []) as Array - for ev: Dictionary in prod_events: - var city_id: String = ev.get("city_id", "") as String - var item_type: String = ev.get("item_type", "") as String - var item_id: String = ev.get("item_id", "") as String - var city_ref: CityScript = null - for city_raw: RefCounted in player.cities: - var city: CityScript = city_raw as CityScript - if city != null and city.id == city_id: - city_ref = city - break - if city_ref == null: - continue - if item_type == "unit": - var unit: RefCounted = (unit_manager as UnitManagerScript).create_unit( - item_id, player.index, city_ref.position, player - ) - if unit != null: - EventBus.city_unit_completed.emit(city_ref, unit) - elif item_type == "building": - EventBus.city_building_completed.emit(city_ref, item_id) - if DataLoader.get_building(item_id).get("is_wonder", false): - EventBus.wonder_built.emit(item_id, player.index) - - -func replay_research_events(player: PlayerScript, result: Dictionary) -> void: - var research_events: Array = result.get("research_events", []) as Array - for ev: Dictionary in research_events: - var event_type: String = ev.get("type", "") as String - var completed_id: String = ev.get("id", "") as String - if completed_id.is_empty(): - continue - if event_type == "tech": - EventBus.tech_researched.emit(completed_id, player.index) - - -func replay_improvement_events(player: PlayerScript, result: Dictionary) -> void: - var imp_events: Array = result.get("improvement_events", []) as Array - for ev: Dictionary in imp_events: - if ev.get("type", "") != "completed": - continue - var tile_x: int = int(ev.get("x", 0)) - var tile_y: int = int(ev.get("y", 0)) - var imp_type: String = ev.get("improvement_type", "") as String - EventBus.improvement_completed.emit(Vector2i(tile_x, tile_y), imp_type) - for i: int in range(player.pending_improvements.size() - 1, -1, -1): - var imp: Dictionary = player.pending_improvements[i] as Dictionary - if imp != null \ - and imp.get("x", -9999) == tile_x \ - and imp.get("y", -9999) == tile_y: - player.pending_improvements.remove_at(i) - break - - -func replay_fauna_events(result: Dictionary) -> void: - ## Emit EventBus signals for wild creature activity from the turn result. - var units_lost: Array = result.get("units_lost_to_fauna", []) as Array - for entry: Dictionary in units_lost: - var unit_id: String = entry.get("unit_id", "") as String - if unit_id.is_empty(): - continue - var primary: Dictionary = GameState.get_primary_layer() - for u: RefCounted in primary.get("units", []) as Array: - var unit: UnitScript = u as UnitScript - if unit != null and unit.id == unit_id: - EventBus.unit_destroyed.emit(unit, null) - break - - var fauna_events: Array = result.get("fauna_events", []) as Array - for ev: Dictionary in fauna_events: - if ev.get("type", "") == "spawned": - var lair_x: int = int(ev.get("lair_x", 0)) - var lair_y: int = int(ev.get("lair_y", 0)) - EventBus.wild_creature_spawned.emit(null, Vector2i(lair_x, lair_y)) - - -func replay_climate_events(result: Dictionary) -> void: - var climate_events: Array = result.get("climate_events", []) as Array - for ev: Dictionary in climate_events: - var event_type: String = ev.get("type", "") as String - match event_type: - "terrain_transformed": - var pos: Vector2i = Vector2i(int(ev.get("x", 0)), int(ev.get("y", 0))) - var gmap: RefCounted = GameState.get_game_map() - var tile: RefCounted = gmap.get_tile(pos) if gmap != null else null - EventBus.terrain_transformed.emit( - tile, - ev.get("old_type", "") as String, - ev.get("new_type", "") as String, - ) - "quality_changed": - var pos: Vector2i = Vector2i(int(ev.get("x", 0)), int(ev.get("y", 0))) - var gmap: RefCounted = GameState.get_game_map() - var tile: RefCounted = gmap.get_tile(pos) if gmap != null else null - EventBus.quality_changed.emit( - tile, - int(ev.get("old_quality", 0)), - int(ev.get("new_quality", 0)), - ) - "flood": - var pos: Vector2i = Vector2i(int(ev.get("x", 0)), int(ev.get("y", 0))) - EventBus.tile_flooded.emit(pos, ev.get("old_terrain", "") as String) - "biome_changed": - var pos: Vector2i = Vector2i(int(ev.get("x", 0)), int(ev.get("y", 0))) - EventBus.biome_changed.emit( - pos, - ev.get("old_biome", "") as String, - ev.get("new_biome", "") as String, - )