Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/core/execution/alliance/AllianceExtensionExecution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ export class AllianceExtensionExecution implements Execution {
) {}

init(mg: Game, ticks: number): void {
// Block alliance renewals after 40 minutes of game time
// 40 minutes = 2400 seconds = 24,000 ticks (10 ticks per second)
const ALLIANCE_BLOCK_TICKS = 40 * 60 * 10; // 24,000 ticks
if (mg.ticks() >= ALLIANCE_BLOCK_TICKS) {
return;
}

if (!mg.hasPlayer(this.toID)) {
console.warn(
`[AllianceExtensionExecution] Player ${this.toID} not found`,
Expand Down
7 changes: 7 additions & 0 deletions src/core/game/PlayerImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,13 @@ export class PlayerImpl implements Player {
}

canSendAllianceRequest(other: Player): boolean {
// Block alliance requests/renewals after 40 minutes of game time
// 40 minutes = 2400 seconds = 24,000 ticks (10 ticks per second)
const ALLIANCE_BLOCK_TICKS = 40 * 60 * 10; // 24,000 ticks
if (this.mg.ticks() >= ALLIANCE_BLOCK_TICKS) {
return false;
}

if (other === this) {
return false;
}
Expand Down
44 changes: 44 additions & 0 deletions tests/AllianceExtensionExecution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,48 @@ describe("AllianceExtensionExecution", () => {

displayMessageSpy.mockRestore();
});

test("Blocks alliance renewal messages after 40 minutes", () => {
jest.spyOn(player1, "canSendAllianceRequest").mockReturnValue(true);
jest.spyOn(player2, "isAlive").mockReturnValue(true);
jest.spyOn(player1, "isAlive").mockReturnValue(true);

// Create alliance between player1 and player2
game.addExecution(new AllianceRequestExecution(player1, player2.id()));
game.executeNextTick();
game.executeNextTick();

game.addExecution(
new AllianceRequestReplyExecution(player1.id(), player2, true),
);
game.executeNextTick();
game.executeNextTick();

expect(player1.allianceWith(player2)).toBeTruthy();
expect(player2.allianceWith(player1)).toBeTruthy();

// Advance game to 40 minutes (24,000 ticks)
// 40 minutes = 2400 seconds = 24,000 ticks (10 ticks per second)
const ALLIANCE_BLOCK_TICKS = 40 * 60 * 10;
const currentTicks = game.ticks();
const ticksToAdvance = ALLIANCE_BLOCK_TICKS - currentTicks;

for (let i = 0; i < ticksToAdvance; i++) {
game.executeNextTick();
}

expect(game.ticks()).toBeGreaterThanOrEqual(ALLIANCE_BLOCK_TICKS);

// Spy on displayMessage to verify it's NOT called
const displayMessageSpy = jest.spyOn(game, "displayMessage");

// Player1 tries to request renewal after 40 minutes
game.addExecution(new AllianceExtensionExecution(player1, player2.id()));
game.executeNextTick();

// Verify no renewal message was sent
expect(displayMessageSpy).not.toHaveBeenCalled();

displayMessageSpy.mockRestore();
});
});
25 changes: 25 additions & 0 deletions tests/AllianceRequestExecution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,29 @@ describe("AllianceRequestExecution", () => {
expect(player1.isAlliedWith(player2)).toBeFalsy();
expect(player2.isAlliedWith(player1)).toBeFalsy();
});

test("Blocks new alliance requests after 40 minutes", () => {
// Advance game to 40 minutes (24,000 ticks)
// 40 minutes = 2400 seconds = 24,000 ticks (10 ticks per second)
const ALLIANCE_BLOCK_TICKS = 40 * 60 * 10;
const currentTicks = game.ticks();
const ticksToAdvance = ALLIANCE_BLOCK_TICKS - currentTicks;

for (let i = 0; i < ticksToAdvance; i++) {
game.executeNextTick();
}

expect(game.ticks()).toBeGreaterThanOrEqual(ALLIANCE_BLOCK_TICKS);

// Try to send alliance request after 40 minutes
game.addExecution(new AllianceRequestExecution(player1, player2.id()));
game.executeNextTick();
game.executeNextTick();

// Verify no alliance request was created
expect(player1.outgoingAllianceRequests().length).toBe(0);
expect(player2.incomingAllianceRequests().length).toBe(0);
expect(player1.isAlliedWith(player2)).toBeFalsy();
expect(player2.isAlliedWith(player1)).toBeFalsy();
});
});
26 changes: 26 additions & 0 deletions tests/PlayerImpl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,30 @@ describe("PlayerImpl", () => {
}
expect(other.canSendAllianceRequest(player)).toBe(false);
});

test("Can't send alliance requests after 40 minutes", () => {
// Get initial state (might be true or false depending on game state)
const initialCanSend = player.canSendAllianceRequest(other);

// Advance game to 40 minutes (24,000 ticks)
// 40 minutes = 2400 seconds = 24,000 ticks (10 ticks per second)
const ALLIANCE_BLOCK_TICKS = 40 * 60 * 10;
const currentTicks = game.ticks();
const ticksToAdvance = ALLIANCE_BLOCK_TICKS - currentTicks;

for (let i = 0; i < ticksToAdvance; i++) {
game.executeNextTick();
}

expect(game.ticks()).toBeGreaterThanOrEqual(ALLIANCE_BLOCK_TICKS);

// Verify alliance requests are blocked after 40 minutes
// (regardless of whether they were allowed before)
expect(player.canSendAllianceRequest(other)).toBe(false);

// If it was true before, verify it changed
if (initialCanSend) {
expect(player.canSendAllianceRequest(other)).not.toBe(initialCanSend);
}
});
});
Loading