fix(victory): 🐛 Fix domination victory checks by restoring original capital owner tracking
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
89011e8dd3
commit
593f2d508f
1 changed files with 42 additions and 5 deletions
|
|
@ -11,6 +11,7 @@ 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")
|
||||
|
||||
## Minimum turn before any victory check fires. Without this, the very first
|
||||
## skirmish on turn 1 or 2 — when one side founds before the other or one
|
||||
|
|
@ -37,13 +38,49 @@ func check_all(_game_map: RefCounted) -> void:
|
|||
return
|
||||
|
||||
|
||||
## Domination: the last player with at least one city wins.
|
||||
## Domination: a player owns every opponent's original capital, OR is the
|
||||
## last player with at least one city (elimination fallback).
|
||||
##
|
||||
## A player without cities is still considered alive while they hold any
|
||||
## founder unit, since they can still settle. This prevents the check from
|
||||
## firing on the very first turn that one side founds before the other has
|
||||
## had a chance — a "haven't finished setting up" state, not a real victory.
|
||||
## The capital-based rule is classic Civ5 domination: founding-owners lose
|
||||
## the game-ending stake the moment their starting city is conquered, even
|
||||
## if they scramble to settle replacement cities elsewhere. Without this,
|
||||
## a defender who loses their capital can re-found forever and no domination
|
||||
## victory can ever fire within realistic turn limits.
|
||||
##
|
||||
## Fallback to elimination (last-player-with-cities) covers edge cases like
|
||||
## a 1v1 where neither side ever flipped a capital but one side was wiped.
|
||||
## The grace-period founder check still applies to the elimination rung.
|
||||
func _check_domination() -> int:
|
||||
# Gather every original-capital location and the index of the player
|
||||
# that originally founded it. Populated from live cities on the map —
|
||||
# if a founder was razed along with their capital (no city at the old
|
||||
# position), that player's capital requirement collapses automatically.
|
||||
var capital_owner_by_player: Dictionary = {} # player_index → current city.owner
|
||||
for player: Variant in GameState.players:
|
||||
if not player is PlayerScript:
|
||||
continue
|
||||
for city: Variant in player.cities:
|
||||
if city is CityScript and (city as CityScript).original_capital_owner >= 0:
|
||||
var orig: int = (city as CityScript).original_capital_owner
|
||||
capital_owner_by_player[orig] = (city as CityScript).owner
|
||||
|
||||
if capital_owner_by_player.size() >= 2:
|
||||
# Evaluate each candidate: do they own every other tracked capital?
|
||||
for candidate: Variant in GameState.players:
|
||||
if not candidate is PlayerScript:
|
||||
continue
|
||||
var idx: int = candidate.index
|
||||
var owns_all_other_capitals: bool = true
|
||||
for orig_player: Variant in capital_owner_by_player.keys():
|
||||
if int(orig_player) == idx:
|
||||
continue
|
||||
if int(capital_owner_by_player[orig_player]) != idx:
|
||||
owns_all_other_capitals = false
|
||||
break
|
||||
if owns_all_other_capitals and candidate.cities.size() > 0:
|
||||
return idx
|
||||
|
||||
# Elimination fallback — the original rule.
|
||||
var alive_players: Array[int] = []
|
||||
for player: Variant in GameState.players:
|
||||
if not player is PlayerScript:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue