mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 10:21:27 +00:00
Improve "Better troop management for nations 🤖" (#4278)
## Description: **Allow Hard/Impossible nations to retaliate and expand freely** Previously, nations on Hard/Impossible difficulty could be stuck unable to fight back if their `troopSendCap` or `isAttackTooWeak` checks blocked them from sending enough troops. **@legan320** on the main discord noticed it. Now: - `troopSendCap` raises the cap to at least the total incoming attack troops, so nations can match the force being used against them - `isAttackTooWeak` bypasses the 20% minimum check entirely when under attack - `troopSendCap` no longer applies when attacking Terra Nullius, so nations can always expand into unowned land with full troops All checks still apply normally for unprovoked attacks against other players. ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: FloPinguin
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { AttackExecution } from "../src/core/execution/AttackExecution";
|
||||
import { NationEmojiBehavior } from "../src/core/execution/nation/NationEmojiBehavior";
|
||||
import { AiAttackBehavior } from "../src/core/execution/utils/AiAttackBehavior";
|
||||
import {
|
||||
@@ -567,4 +568,37 @@ describe("Hard/Impossible troop floor", () => {
|
||||
expect(exec).toBeDefined();
|
||||
expect(exec.startTroops).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("Hard: nation under attack bypasses troopSendCap and isAttackTooWeak", async () => {
|
||||
const { testGame, attacker, neighbor, behavior } =
|
||||
await setupTroopFloorTest(Difficulty.Hard);
|
||||
|
||||
// Neighbor has far more troops, so the normal cap would be 0
|
||||
attacker.addTroops(100_000);
|
||||
neighbor.addTroops(200_000);
|
||||
// Normal cap = max(0, 100k - ceil(200k * 0.75)) = max(0, 100k - 150k) = 0
|
||||
// Without the bypass, the nation couldn't attack at all.
|
||||
const normalCap = Math.max(
|
||||
0,
|
||||
attacker.troops() - Math.ceil(neighbor.troops() * 0.75),
|
||||
);
|
||||
expect(normalCap).toBe(0);
|
||||
|
||||
// Simulate the neighbor attacking with 50k troops
|
||||
testGame.addExecution(new AttackExecution(50_000, neighbor, attacker.id()));
|
||||
testGame.executeNextTick();
|
||||
expect(attacker.incomingAttacks().length).toBeGreaterThan(0);
|
||||
|
||||
// With incoming attacks, troopSendCap raises to at least totalIncoming
|
||||
const addExecSpy = vi.spyOn(testGame, "addExecution");
|
||||
const result = behavior.sendAttack(neighbor);
|
||||
|
||||
expect(result).toBe(true);
|
||||
const exec = addExecSpy.mock.calls.find(
|
||||
(c) => c[0].constructor.name === "AttackExecution",
|
||||
)?.[0] as any;
|
||||
expect(exec).toBeDefined();
|
||||
// The bypass allows retaliation with at least the incoming 50k
|
||||
expect(exec.startTroops).toBeGreaterThanOrEqual(50_000);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user