diff --git a/src/game/engine/src/modules/ai/simple_heuristic_ai.gd b/src/game/engine/src/modules/ai/simple_heuristic_ai.gd index c0f268e0..db07ab29 100644 --- a/src/game/engine/src/modules/ai/simple_heuristic_ai.gd +++ b/src/game/engine/src/modules/ai/simple_heuristic_ai.gd @@ -47,7 +47,17 @@ static func process_player(player: RefCounted) -> Array: ) var threat: Dictionary = _enemy_military_threat(player) - if bool(threat.get("threatens_city", false)): + var mil_now: int = 0 + for u: Variant in player.units: + if u == null or not u.is_alive() or u.get("can_found_city") == true: + continue + if int(u.get("attack")) > 0 or int(u.get("ranged_attack")) > 0: + mil_now += 1 + # Fire rush-buy on imminent threat OR when enemy's total army exceeds + # ours (amassing at range is still a threat — converts idle gold to + # units on turns when production can't keep pace). + if bool(threat.get("threatens_city", false)) \ + or int(threat.get("total_count", 0)) > mil_now: _rush_buy_defenders(player, threat) # Units: founders first (expansion), then military. @@ -220,18 +230,24 @@ static func _enemy_military_threat(player: RefCounted) -> Dictionary: static func _rush_buy_defenders(player: RefCounted, threat: Dictionary) -> void: - ## Spawn warriors at threat.spawn_city while gold >= 50 and under - ## max(2, threat+1) defenders (hard cap 3x cities). Direct-spawn pattern - ## from auto_play.gd so the bridge needs no new action type. + ## Spawn warriors at threat.spawn_city while gold >= 50 and under cap + ## (hard cap 3x cities). Cap: imminent = max(2, threat.count+1); + ## range-only trigger = max(2, total_count) so we keep pace with army. + if player.cities.is_empty(): return var spawn_city: RefCounted = threat.get("spawn_city") - if spawn_city == null: return + if spawn_city == null: + spawn_city = player.cities[0] var mil: int = 0 for u: Variant in player.units: if u == null or not u.is_alive() or u.get("can_found_city") == true: continue if int(u.get("attack")) > 0 or int(u.get("ranged_attack")) > 0: mil += 1 - var target: int = maxi(2, int(threat.get("count", 0)) + 1) + var imminent: bool = bool(threat.get("threatens_city", false)) + var target: int = ( + maxi(2, int(threat.get("count", 0)) + 1) if imminent + else maxi(2, int(threat.get("total_count", 0))) + ) var cap: int = player.cities.size() * 3 while player.gold >= 50 and mil < target and mil < cap: var nu: RefCounted = UnitScript.new(