diff --git a/src/game/engine/src/modules/empire/happiness.gd b/src/game/engine/src/modules/empire/happiness.gd index 542852e0..5ab2e806 100644 --- a/src/game/engine/src/modules/empire/happiness.gd +++ b/src/game/engine/src/modules/empire/happiness.gd @@ -60,7 +60,12 @@ static func process_turn(player: RefCounted, _game_map: RefCounted) -> void: var ascension_active: bool = bool(player.ascension_active) var growth_tier: String = player.growth_tier if player.growth_tier != "" else "balanced" - var unique_luxuries: int = _count_unique_luxuries(player, _game_map) + # Collect the set of distinct luxury resource IDs accessible to this + # player. The Rust side expects `owned_luxuries: BTreeSet` and + # sums per-resource happiness_per_unique_copy values. Previously this + # was `unique_luxury_count: i32` — rename and payload shape both changed + # when luxury happiness moved from a flat count to a per-resource lookup. + var owned_luxuries: Array[String] = _collect_unique_luxury_ids(player, _game_map) var input_dict: Dictionary = { "city_count": player.cities.size(), @@ -68,7 +73,7 @@ static func process_turn(player: RefCounted, _game_map: RefCounted) -> void: "units_in_enemy_territory": units_in_enemy_territory, "ascension_active": ascension_active, "building_happiness": building_happiness, - "unique_luxury_count": unique_luxuries, + "owned_luxuries": owned_luxuries, "growth_tier": growth_tier, } @@ -127,11 +132,15 @@ const LUXURY_DEPOSITS: Array[String] = [ ] -static func _count_unique_luxuries(player: RefCounted, game_map: RefCounted) -> int: - ## Count unique luxury resources on tiles owned by the player's cities. +static func _collect_unique_luxury_ids(player: RefCounted, game_map: RefCounted) -> Array[String]: + ## Collect the set of distinct luxury resource IDs accessible to the + ## player via owned tiles. Returns a sorted Array[String] suitable for + ## JSON-serialising to Rust's `BTreeSet` (sorted order preserves + ## determinism across runs). + var result: Array[String] = [] if game_map == null: - return 0 - var found: Dictionary = {} # resource_id → true + return result + var found: Dictionary = {} # resource_id → true (dedupe) for city: Variant in player.cities: for tile_pos: Vector2i in city.owned_tiles: var tile: Resource = game_map.get_tile(tile_pos) @@ -139,7 +148,11 @@ static func _count_unique_luxuries(player: RefCounted, game_map: RefCounted) -> continue if tile.resource_id in LUXURY_DEPOSITS and tile.resource_id not in found: found[tile.resource_id] = true - return found.size() + var ids: Array = found.keys() + ids.sort() + for id_: Variant in ids: + result.append(String(id_)) + return result static func _count_units_in_enemy_territory(player: RefCounted) -> int: