allow alliance extension Fixes #491 (#1314)

## Description:

About 30s before an alliance is about to expire, both players receive a
prompt to extend the alliance. If both players agree the alliance is
extended.

## 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 understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

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

evan
This commit is contained in:
evanpelle
2025-07-02 15:25:20 -07:00
committed by GitHub
parent cfabdfebc7
commit 5b5ac7bfca
19 changed files with 358 additions and 19 deletions
+5
View File
@@ -2,6 +2,7 @@ import { Execution, Game } from "../game/Game";
import { PseudoRandom } from "../PseudoRandom";
import { ClientID, GameID, Intent, Turn } from "../Schemas";
import { simpleHash } from "../Util";
import { AllianceExtensionExecution } from "./alliance/AllianceExtensionExecution";
import { AllianceRequestExecution } from "./alliance/AllianceRequestExecution";
import { AllianceRequestReplyExecution } from "./alliance/AllianceRequestReplyExecution";
import { BreakAllianceExecution } from "./alliance/BreakAllianceExecution";
@@ -111,6 +112,10 @@ export class Executor {
this.mg.ref(intent.x, intent.y),
intent.unit,
);
case "allianceExtension": {
return new AllianceExtensionExecution(player, intent.recipient);
}
case "upgrade_structure":
return new UpgradeStructureExecution(player, intent.unitId);
case "create_station":
+1 -4
View File
@@ -72,10 +72,7 @@ export class PlayerExecution implements Execution {
const alliances = Array.from(this.player.alliances());
for (const alliance of alliances) {
if (
this.mg.ticks() - alliance.createdAt() >
this.mg.config().allianceDuration()
) {
if (alliance.expiresAt() <= this.mg.ticks()) {
alliance.expire();
}
}
@@ -0,0 +1,61 @@
import {
Execution,
Game,
MessageType,
Player,
PlayerID,
} from "../../game/Game";
export class AllianceExtensionExecution implements Execution {
constructor(
private readonly from: Player,
private readonly toID: PlayerID,
) {}
init(mg: Game, ticks: number): void {
if (!mg.hasPlayer(this.toID)) {
console.warn(
`[AllianceExtensionExecution] Player ${this.toID} not found`,
);
return;
}
const to = mg.player(this.toID);
const alliance = this.from.allianceWith(to);
if (!alliance) {
console.warn(
`[AllianceExtensionExecution] No alliance to extend between ${this.from.id()} and ${this.toID}`,
);
return;
}
// Mark this player's intent to extend
alliance.addExtensionRequest(this.from);
if (alliance.canExtend()) {
alliance.extend();
mg.displayMessage(
"alliance.renewed",
MessageType.ALLIANCE_ACCEPTED,
this.from.id(),
);
mg.displayMessage(
"alliance.renewed",
MessageType.ALLIANCE_ACCEPTED,
this.toID,
);
}
}
tick(ticks: number): void {
// No-op
}
isActive(): boolean {
return false;
}
activeDuringSpawnPhase(): boolean {
return false;
}
}