From e8d151f950935fa48e47f5e66a30c23c72735aa7 Mon Sep 17 00:00:00 2001 From: autocommit Date: Sun, 7 Jun 2026 00:12:46 -0700 Subject: [PATCH] =?UTF-8?q?refactor(management):=20=E2=99=BB=EF=B8=8F=20Re?= =?UTF-8?q?place=20city=20garrison=20healing=20calculation=20with=20intern?= =?UTF-8?q?al=20helper=20to=20decouple=20from=20BuildingScript=20dependenc?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .../management/turn_processor_helpers.gd | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/game/engine/src/modules/management/turn_processor_helpers.gd b/src/game/engine/src/modules/management/turn_processor_helpers.gd index d0b47cab..3326cbbb 100644 --- a/src/game/engine/src/modules/management/turn_processor_helpers.gd +++ b/src/game/engine/src/modules/management/turn_processor_helpers.gd @@ -5,7 +5,6 @@ extends RefCounted const PlayerScript: GDScript = preload("res://engine/src/entities/player.gd") const UnitScript: GDScript = preload("res://engine/src/entities/unit.gd") const CityScript: GDScript = preload("res://engine/src/entities/city.gd") -const BuildingScript: GDScript = preload("res://engine/src/entities/building.gd") const TerrainAffinityScript: GDScript = preload("res://engine/src/core/terrain_affinity.gd") const HappinessScript: GDScript = preload("res://engine/src/modules/empire/happiness.gd") const TechWebScript: GDScript = preload("res://engine/src/modules/tech/tech_web.gd") @@ -258,7 +257,7 @@ static func _get_healing_rate( for city_ref: RefCounted in player.cities: if city_ref is CityScript and (city_ref as CityScript).position == unit.position: var base_heal: int = 20 - var building_heal: int = BuildingScript.get_healing_per_turn(city_ref) + var building_heal: int = _city_garrison_healing(city_ref as CityScript) if building_heal >= 999: return unit.max_hp return base_heal + building_heal @@ -269,6 +268,32 @@ static func _get_healing_rate( return 5 +## Sum a city's in-garrison healing bonus from its buildings' JSON `effects`. +## Replaces the former `BuildingScript.get_healing_per_turn(city)` static helper, +## dropped when `BuildingScript` collapsed to a thin view (p2-72a Stage 2) without +## its caller being updated — which raised "Nonexistent function +## 'get_healing_per_turn'" every turn a unit garrisoned a city. +## In-city effect types (Rail-2, data-driven): `heal_per_turn` (scope +## `garrisoned`/unset) and `unit_heal_in_city`. Field/global heal types +## (`unit_heal_in_field`, `global_unit_heal_bonus`) apply outside a garrison and +## are summed elsewhere. A `value >= 999` is the full-heal sentinel. +static func _city_garrison_healing(city: CityScript) -> int: + var total: int = 0 + for building_id: String in city.buildings: + var def: Dictionary = DataLoader.get_building(building_id) + if def.is_empty(): + continue + for effect: Dictionary in def.get("effects", []) as Array: + var effect_type: String = str(effect.get("type", "")) + if effect_type == "unit_heal_in_city": + total += int(effect.get("value", 0)) + elif effect_type == "heal_per_turn": + var scope: String = str(effect.get("scope", "garrisoned")) + if scope == "garrisoned": + total += int(effect.get("value", 0)) + return total + + # ── Research selection (Rail-1: scored in mc-ai, dispatched via GdAiController) ──