Cancel alliance requests if the recipient attacks (#1733)

Problem: attacking a player right before accepting an alliance request
is very effective since the requester can't fight back or reclaim his
territory without canceling the alliance and being penalized with the
traitor debuff.

Change:
- Attacking a player after he requested an alliance automatically
rejects the request
- No changes to existing attacks in both directions, only new attacks
affect the request

- [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).

regression is found:

IngloriousTom
This commit is contained in:
DevelopingTom
2025-08-08 02:10:39 +02:00
committed by evanpelle
parent 14b188c66d
commit e027983f41
3 changed files with 117 additions and 62 deletions
+18 -1
View File
@@ -470,7 +470,24 @@ export class EventsDisplay extends LitElement implements Layer {
onAllianceRequestReplyEvent(update: AllianceRequestReplyUpdate) {
const myPlayer = this.game.myPlayer();
if (!myPlayer || update.request.requestorID !== myPlayer.smallID()) {
if (!myPlayer) {
return;
}
// myPlayer can deny alliances without clicking on the button
if (update.request.recipientID === myPlayer.smallID()) {
// Remove alliance requests whose requestors are the same as the reply's requestor
// Noop unless the request was denied through other means (e.g attacking the requestor)
this.events = this.events.filter(
(event) =>
!(
event.type === MessageType.ALLIANCE_REQUEST &&
event.focusID === update.request.requestorID
),
);
this.requestUpdate();
return;
}
if (update.request.requestorID !== myPlayer.smallID()) {
return;
}
+16 -6
View File
@@ -62,6 +62,12 @@ export class AttackExecution implements Execution {
? mg.terraNullius()
: mg.player(this._targetID);
if (this._owner === this.target) {
console.error(`Player ${this._owner} cannot attack itself`);
this.active = false;
return;
}
if (this.target && this.target.isPlayer()) {
const targetPlayer = this.target as Player;
if (
@@ -70,15 +76,10 @@ export class AttackExecution implements Execution {
) {
// Don't let bots embargo since they can't trade anyway.
targetPlayer.addEmbargo(this._owner, true);
this.rejectIncomingAllianceRequests(targetPlayer);
}
}
if (this._owner === this.target) {
console.error(`Player ${this._owner} cannot attack itself`);
this.active = false;
return;
}
if (this.target.isPlayer()) {
if (
this.mg.config().numSpawnPhaseTurns() +
@@ -295,6 +296,15 @@ export class AttackExecution implements Execution {
}
}
private rejectIncomingAllianceRequests(target: Player) {
const request = this._owner
.incomingAllianceRequests()
.find((ar) => ar.requestor() === target);
if (request !== undefined) {
request.reject();
}
}
private addNeighbors(tile: TileRef) {
if (this.attack === null) {
throw new Error("Attack not initialized");