Fix Race conditions on alliances (#1605)

## Description:

Players received "traitor" debuff when alliances were formed after
attacks started, creating an unfair race condition.

the problem was mentioned here
https://discord.com/channels/1284581928254701718/1399115120486912100

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I have read and accepted the CLA agreement (only required once).

## Please put your Discord username so you can be contacted if a bug or
regression is found:

Kipstzz

---------

Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
This commit is contained in:
Kipstz Avenger
2025-08-02 22:12:23 +00:00
committed by GitHub
co-authored by Scott Anderson
parent 86a329f7cb
commit 0943b1544c
2 changed files with 154 additions and 3 deletions
+10 -3
View File
@@ -17,6 +17,7 @@ import { FlatBinaryHeap } from "./utils/FlatBinaryHeap"; // adjust path if neede
const malusForRetreat = 25;
export class AttackExecution implements Execution {
private breakAlliance = false;
private wasAlliedAtInit = false; // Store alliance state at initialization
private active: boolean = true;
private toConquer = new FlatBinaryHeap();
@@ -147,8 +148,9 @@ export class AttackExecution implements Execution {
}
if (this.target.isPlayer()) {
if (this._owner.isAlliedWith(this.target)) {
// No updates should happen in init.
// Store the alliance state at initialization time to prevent race conditions
this.wasAlliedAtInit = this._owner.isAlliedWith(this.target);
if (this.wasAlliedAtInit) {
this.breakAlliance = true;
}
this.target.updateRelation(this._owner, -80);
@@ -226,8 +228,13 @@ export class AttackExecution implements Execution {
this.breakAlliance = false;
this._owner.breakAlliance(alliance);
}
if (targetPlayer && this._owner.isAlliedWith(targetPlayer)) {
if (
targetPlayer &&
this._owner.isAlliedWith(targetPlayer) &&
!this.wasAlliedAtInit
) {
// In this case a new alliance was created AFTER the attack started.
// We should retreat to avoid the attacker becoming a traitor.
this.retreat();
return;
}