mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-08 07:20:41 +00:00
Block captured trade routes from port destination selection for 100 ticks
This commit is contained in:
@@ -104,4 +104,79 @@ describe("PortExecution", () => {
|
||||
|
||||
expect(ports.length).toBe(1);
|
||||
});
|
||||
|
||||
test("Blocked trade route is omitted from trading ports", () => {
|
||||
game.config().proximityBonusPortsNb = () => 0;
|
||||
game.config().tradeShipShortRangeDebuff = () => 0;
|
||||
|
||||
player.conquer(game.ref(7, 10));
|
||||
const spawn = player.canBuild(UnitType.Port, game.ref(7, 10));
|
||||
if (spawn === false) {
|
||||
throw new Error("Unable to build port for test");
|
||||
}
|
||||
const port = player.buildUnit(UnitType.Port, spawn, {});
|
||||
const execution = new PortExecution(port);
|
||||
execution.init(game, 0);
|
||||
|
||||
other.conquer(game.ref(0, 0));
|
||||
const blockedPort = other.buildUnit(UnitType.Port, game.ref(0, 0), {});
|
||||
other.conquer(game.ref(0, 1));
|
||||
const openPort = other.buildUnit(UnitType.Port, game.ref(0, 1), {});
|
||||
|
||||
game.blockTradeRouteUntil(port.id(), blockedPort.id(), game.ticks() + 100);
|
||||
|
||||
const ports = execution.tradingPorts();
|
||||
|
||||
expect(ports).toContain(openPort);
|
||||
expect(ports).not.toContain(blockedPort);
|
||||
});
|
||||
|
||||
test("Blocked trade route becomes eligible again after expiry", () => {
|
||||
game.config().proximityBonusPortsNb = () => 0;
|
||||
game.config().tradeShipShortRangeDebuff = () => 0;
|
||||
|
||||
player.conquer(game.ref(7, 10));
|
||||
const spawn = player.canBuild(UnitType.Port, game.ref(7, 10));
|
||||
if (spawn === false) {
|
||||
throw new Error("Unable to build port for test");
|
||||
}
|
||||
const port = player.buildUnit(UnitType.Port, spawn, {});
|
||||
const execution = new PortExecution(port);
|
||||
execution.init(game, 0);
|
||||
|
||||
other.conquer(game.ref(0, 0));
|
||||
const blockedPort = other.buildUnit(UnitType.Port, game.ref(0, 0), {});
|
||||
|
||||
game.blockTradeRouteUntil(port.id(), blockedPort.id(), game.ticks() + 1);
|
||||
|
||||
expect(execution.tradingPorts()).not.toContain(blockedPort);
|
||||
expect(
|
||||
game.isTradeRouteBlocked(port.id(), blockedPort.id(), game.ticks()),
|
||||
).toBe(true);
|
||||
expect(
|
||||
game.isTradeRouteBlocked(port.id(), blockedPort.id(), game.ticks() + 1),
|
||||
).toBe(false);
|
||||
expect(execution.tradingPorts()).toContain(blockedPort);
|
||||
});
|
||||
|
||||
test("Trade route blacklist affects hash and expires cleanly", () => {
|
||||
player.conquer(game.ref(7, 10));
|
||||
const spawn = player.canBuild(UnitType.Port, game.ref(7, 10));
|
||||
if (spawn === false) {
|
||||
throw new Error("Unable to build port for test");
|
||||
}
|
||||
const port = player.buildUnit(UnitType.Port, spawn, {});
|
||||
|
||||
other.conquer(game.ref(0, 0));
|
||||
const otherPort = other.buildUnit(UnitType.Port, game.ref(0, 0), {});
|
||||
|
||||
const baseHash = (game as any).hash();
|
||||
game.blockTradeRouteUntil(port.id(), otherPort.id(), game.ticks() + 100);
|
||||
const blockedHash = (game as any).hash();
|
||||
(game as any)._ticks += 100;
|
||||
const expiredHash = (game as any).hash();
|
||||
|
||||
expect(blockedHash).not.toBe(baseHash);
|
||||
expect(expiredHash).toBe(baseHash);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -55,6 +55,7 @@ describe("TradeShipExecution", () => {
|
||||
} as any;
|
||||
|
||||
piratePort = {
|
||||
id: vi.fn(() => 201),
|
||||
tile: vi.fn(() => 56),
|
||||
owner: vi.fn(() => pirate),
|
||||
isActive: vi.fn(() => true),
|
||||
@@ -63,6 +64,7 @@ describe("TradeShipExecution", () => {
|
||||
} as any;
|
||||
|
||||
piratePort2 = {
|
||||
id: vi.fn(() => 202),
|
||||
tile: vi.fn(() => 75),
|
||||
owner: vi.fn(() => pirate),
|
||||
isActive: vi.fn(() => true),
|
||||
@@ -71,6 +73,7 @@ describe("TradeShipExecution", () => {
|
||||
} as any;
|
||||
|
||||
srcPort = {
|
||||
id: vi.fn(() => 101),
|
||||
tile: vi.fn(() => 10),
|
||||
owner: vi.fn(() => origOwner),
|
||||
isActive: vi.fn(() => true),
|
||||
@@ -79,6 +82,7 @@ describe("TradeShipExecution", () => {
|
||||
} as any;
|
||||
|
||||
dstPort = {
|
||||
id: vi.fn(() => 102),
|
||||
tile: vi.fn(() => 100),
|
||||
owner: vi.fn(() => dstOwner),
|
||||
isActive: vi.fn(() => true),
|
||||
@@ -131,6 +135,43 @@ describe("TradeShipExecution", () => {
|
||||
expect(tradeShip.setTargetUnit).toHaveBeenCalledWith(piratePort);
|
||||
});
|
||||
|
||||
it("blacklists the original route immediately on first capture", () => {
|
||||
tradeShip.owner = vi.fn(() => pirate);
|
||||
|
||||
tradeShipExecution.tick(1);
|
||||
|
||||
expect(
|
||||
game.isTradeRouteBlocked(srcPort.id(), dstPort.id(), game.ticks()),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps the blacklist on the original route after retargeting", () => {
|
||||
tradeShip.owner = vi.fn(() => pirate);
|
||||
|
||||
tradeShipExecution.tick(1);
|
||||
|
||||
expect(
|
||||
game.isTradeRouteBlocked(srcPort.id(), dstPort.id(), game.ticks()),
|
||||
).toBe(true);
|
||||
expect(
|
||||
game.isTradeRouteBlocked(srcPort.id(), piratePort.id(), game.ticks()),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("does not add a second blacklist event when the ship is recaptured", () => {
|
||||
const routeKey = `${srcPort.id()}:${dstPort.id()}`;
|
||||
tradeShip.owner = vi.fn(() => pirate);
|
||||
tradeShipExecution.tick(1);
|
||||
const blockedUntil = (game as any).tradeRouteBlockedUntil.get(routeKey);
|
||||
|
||||
tradeShip.owner = vi.fn(() => origOwner);
|
||||
tradeShipExecution.tick(2);
|
||||
|
||||
expect((game as any).tradeRouteBlockedUntil.get(routeKey)).toBe(
|
||||
blockedUntil,
|
||||
);
|
||||
});
|
||||
|
||||
it("should complete trade and award gold", () => {
|
||||
tradeShipExecution["pathFinder"] = {
|
||||
next: vi.fn(() => ({ status: PathStatus.COMPLETE, node: 32 })),
|
||||
@@ -141,4 +182,27 @@ describe("TradeShipExecution", () => {
|
||||
expect(tradeShipExecution.isActive()).toBe(false);
|
||||
expect(game.displayMessage).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not blacklist on NOT_FOUND", () => {
|
||||
tradeShipExecution["pathFinder"] = {
|
||||
next: vi.fn(() => ({ status: PathStatus.NOT_FOUND, node: 32 })),
|
||||
findPath: vi.fn((from: number) => [from]),
|
||||
} as any;
|
||||
|
||||
tradeShipExecution.tick(1);
|
||||
|
||||
expect(
|
||||
game.isTradeRouteBlocked(srcPort.id(), dstPort.id(), game.ticks()),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("does not blacklist when destination becomes invalid", () => {
|
||||
dstPort.isActive = vi.fn(() => false);
|
||||
|
||||
tradeShipExecution.tick(1);
|
||||
|
||||
expect(
|
||||
game.isTradeRouteBlocked(srcPort.id(), dstPort.id(), game.ticks()),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user