mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 16:50:15 +00:00
fa7b7fceb3
## Description: ### ✅ Summary of Changes This PR enables the ESLint rule **`@typescript-eslint/no-unused-vars`** as requested in the issue and applies the necessary code adjustments across the project. #### 🔧 What was done: - Activated the rule `@typescript-eslint/no-unused-vars` in the ESLint config. - Updated ~70 files to comply with the rule: - Replaced unused variables with a `_` prefix where appropriate. - Added inline ESLint disable comments (`eslint-disable-next-line`) for specific cases where the variable or code block seemed important for context, readability, or future use. - Ensured no linting errors remain related to this rule. --- ### ❓ Clarification Some cases were handled with inline disable comments instead of removing the variable entirely, to avoid accidental breaking changes or loss of intent. If a different approach is preferred (e.g., stricter removal or alternative handling), I’m happy to adjust the implementation accordingly — just let me know! --- ### 🙌 Next Steps Please review and let me know if: - Any file should be handled differently. - You prefer removal instead of disabling in certain areas. - Additional rules should be enforced or reverted. I’m available to make any follow-up improvements needed. --- ### 🎃 Hacktoberfest Note I'm participating in **Hacktoberfest**, so if this PR is accepted, please add the label: `hacktoberfest-accepted` Thank you! #1784 ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: DISCORD_USERNAME
294 lines
8.1 KiB
TypeScript
294 lines
8.1 KiB
TypeScript
import { DefensePostExecution } from "../src/core/execution/DefensePostExecution";
|
|
import { ShellExecution } from "../src/core/execution/ShellExecution";
|
|
import { WarshipExecution } from "../src/core/execution/WarshipExecution";
|
|
import {
|
|
Game,
|
|
Player,
|
|
PlayerInfo,
|
|
PlayerType,
|
|
UnitType,
|
|
} from "../src/core/game/Game";
|
|
import { setup } from "./util/Setup";
|
|
|
|
const coastX = 7;
|
|
let game: Game;
|
|
let player1: Player;
|
|
let player2: Player;
|
|
|
|
describe("Shell Random Damage", () => {
|
|
beforeEach(async () => {
|
|
game = await setup(
|
|
"half_land_half_ocean",
|
|
{
|
|
infiniteGold: true,
|
|
instantBuild: true,
|
|
},
|
|
[
|
|
new PlayerInfo("attacker", PlayerType.Human, null, "player_1_id"),
|
|
new PlayerInfo("defender", PlayerType.Human, null, "player_2_id"),
|
|
],
|
|
);
|
|
|
|
while (game.inSpawnPhase()) {
|
|
game.executeNextTick();
|
|
}
|
|
|
|
player1 = game.player("player_1_id");
|
|
player2 = game.player("player_2_id");
|
|
});
|
|
|
|
test("Shell damage varies randomly between 200-300 base damage", () => {
|
|
const target = player2.buildUnit(
|
|
UnitType.Warship,
|
|
game.ref(coastX + 5, 10),
|
|
{
|
|
patrolTile: game.ref(coastX + 5, 10),
|
|
},
|
|
);
|
|
const initialHealth = target.health();
|
|
|
|
const damages: number[] = [];
|
|
const numShells = 50;
|
|
|
|
for (let i = 0; i < numShells; i++) {
|
|
const shell = new ShellExecution(
|
|
game.ref(coastX, 10),
|
|
player1,
|
|
player1.buildUnit(UnitType.Warship, game.ref(coastX, 10), {
|
|
patrolTile: game.ref(coastX, 10),
|
|
}),
|
|
target,
|
|
);
|
|
|
|
shell.init(game, game.ticks() + i);
|
|
|
|
const healthBefore = target.health();
|
|
target.modifyHealth(-shell.getEffectOnTargetForTesting(), player1);
|
|
const healthAfter = target.health();
|
|
|
|
const damage = healthBefore - healthAfter;
|
|
if (damage > 0) {
|
|
damages.push(damage);
|
|
}
|
|
|
|
target.modifyHealth(-(healthBefore - initialHealth));
|
|
}
|
|
|
|
expect(damages.length).toBeGreaterThan(0);
|
|
|
|
const baseDamage = game.config().unitInfo(UnitType.Shell).damage ?? 250;
|
|
const minExpectedDamage = Math.round((baseDamage / 250) * 200);
|
|
const maxExpectedDamage = Math.round((baseDamage / 250) * 300);
|
|
|
|
damages.forEach((damage) => {
|
|
expect(damage).toBeGreaterThanOrEqual(minExpectedDamage);
|
|
expect(damage).toBeLessThanOrEqual(maxExpectedDamage);
|
|
});
|
|
|
|
expect(damages.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
test("Warship shell attacks have random damage", () => {
|
|
player1.buildUnit(UnitType.Port, game.ref(coastX, 10), {});
|
|
|
|
const warship = player1.buildUnit(
|
|
UnitType.Warship,
|
|
game.ref(coastX + 1, 10),
|
|
{
|
|
patrolTile: game.ref(coastX + 1, 10),
|
|
},
|
|
);
|
|
|
|
const target = player2.buildUnit(
|
|
UnitType.Warship,
|
|
game.ref(coastX + 2, 10),
|
|
{
|
|
patrolTile: game.ref(coastX + 2, 10),
|
|
},
|
|
);
|
|
const initialHealth = target.health();
|
|
|
|
warship.setTargetUnit(target);
|
|
|
|
game.addExecution(new WarshipExecution(warship));
|
|
|
|
const damages: number[] = [];
|
|
const maxAttempts = 100;
|
|
let attempts = 0;
|
|
|
|
while (damages.length < 10 && attempts < maxAttempts) {
|
|
const healthBefore = target.health();
|
|
game.executeNextTick();
|
|
const healthAfter = target.health();
|
|
|
|
if (healthAfter < healthBefore) {
|
|
damages.push(healthBefore - healthAfter);
|
|
target.modifyHealth(-(healthBefore - initialHealth));
|
|
}
|
|
|
|
attempts++;
|
|
}
|
|
|
|
expect(damages.length).toBeGreaterThan(0);
|
|
|
|
const uniqueDamages = new Set(damages);
|
|
expect(uniqueDamages.size).toBeGreaterThan(1);
|
|
|
|
const baseDamage = game.config().unitInfo(UnitType.Shell).damage ?? 250;
|
|
const minExpectedDamage = Math.round((baseDamage / 250) * 200);
|
|
const maxExpectedDamage = Math.round((baseDamage / 250) * 300);
|
|
|
|
damages.forEach((damage) => {
|
|
expect(damage).toBeGreaterThanOrEqual(minExpectedDamage);
|
|
expect(damage).toBeLessThanOrEqual(maxExpectedDamage);
|
|
});
|
|
});
|
|
|
|
test("Defense post shell attacks have random damage", () => {
|
|
const defensePost = new DefensePostExecution(player1, game.ref(coastX, 5));
|
|
|
|
const target = player2.buildUnit(
|
|
UnitType.Warship,
|
|
game.ref(coastX + 1, 10),
|
|
{
|
|
patrolTile: game.ref(coastX + 1, 10),
|
|
},
|
|
);
|
|
const initialHealth = target.health();
|
|
|
|
defensePost.init(game, game.ticks());
|
|
|
|
const damages: number[] = [];
|
|
const maxAttempts = 100;
|
|
let attempts = 0;
|
|
|
|
while (damages.length < 5 && attempts < maxAttempts) {
|
|
const healthBefore = target.health();
|
|
defensePost.tick(game.ticks());
|
|
game.executeNextTick();
|
|
const healthAfter = target.health();
|
|
|
|
if (healthAfter < healthBefore) {
|
|
damages.push(healthBefore - healthAfter);
|
|
target.modifyHealth(-(healthBefore - initialHealth));
|
|
}
|
|
|
|
attempts++;
|
|
}
|
|
|
|
if (damages.length > 0) {
|
|
const uniqueDamages = new Set(damages);
|
|
expect(uniqueDamages.size).toBeGreaterThan(1);
|
|
|
|
const baseDamage = game.config().unitInfo(UnitType.Shell).damage ?? 250;
|
|
const minExpectedDamage = Math.round((baseDamage / 250) * 200);
|
|
const maxExpectedDamage = Math.round((baseDamage / 250) * 300);
|
|
|
|
damages.forEach((damage) => {
|
|
expect(damage).toBeGreaterThanOrEqual(minExpectedDamage);
|
|
expect(damage).toBeLessThanOrEqual(maxExpectedDamage);
|
|
});
|
|
}
|
|
});
|
|
|
|
test("Shell damage distribution follows expected pattern", () => {
|
|
const target = player2.buildUnit(
|
|
UnitType.Warship,
|
|
game.ref(coastX + 5, 10),
|
|
{
|
|
patrolTile: game.ref(coastX + 5, 10),
|
|
},
|
|
);
|
|
const initialHealth = target.health();
|
|
|
|
const damages: number[] = [];
|
|
const numShells = 1000;
|
|
|
|
for (let i = 0; i < numShells; i++) {
|
|
const shell = new ShellExecution(
|
|
game.ref(coastX, 10),
|
|
player1,
|
|
player1.buildUnit(UnitType.Warship, game.ref(coastX, 10), {
|
|
patrolTile: game.ref(coastX, 10),
|
|
}),
|
|
target,
|
|
);
|
|
|
|
shell.init(game, game.ticks() + i);
|
|
|
|
const healthBefore = target.health();
|
|
target.modifyHealth(-shell.getEffectOnTargetForTesting(), player1);
|
|
const healthAfter = target.health();
|
|
|
|
const damage = healthBefore - healthAfter;
|
|
if (damage > 0) {
|
|
damages.push(damage);
|
|
}
|
|
|
|
target.modifyHealth(-(healthBefore - initialHealth));
|
|
}
|
|
|
|
expect(damages.length).toBeGreaterThan(0);
|
|
|
|
const uniqueDamages = new Set(damages);
|
|
expect(uniqueDamages.size).toBeGreaterThan(0);
|
|
|
|
const damageCounts = new Map<number, number>();
|
|
damages.forEach((damage) => {
|
|
damageCounts.set(damage, (damageCounts.get(damage) ?? 0) + 1);
|
|
});
|
|
|
|
const maxCount = Math.max(...damageCounts.values());
|
|
const minCount = Math.min(...damageCounts.values());
|
|
|
|
expect(maxCount - minCount).toBeLessThan(damages.length * 0.8);
|
|
});
|
|
|
|
test("Shell damage is consistent with same random seed", () => {
|
|
const target = player2.buildUnit(
|
|
UnitType.Warship,
|
|
game.ref(coastX + 5, 10),
|
|
{
|
|
patrolTile: game.ref(coastX + 5, 10),
|
|
},
|
|
);
|
|
const initialHealth = target.health();
|
|
|
|
const shell1 = new ShellExecution(
|
|
game.ref(coastX, 10),
|
|
player1,
|
|
player1.buildUnit(UnitType.Warship, game.ref(coastX, 10), {
|
|
patrolTile: game.ref(coastX, 10),
|
|
}),
|
|
target,
|
|
);
|
|
|
|
const shell2 = new ShellExecution(
|
|
game.ref(coastX, 10),
|
|
player1,
|
|
player1.buildUnit(UnitType.Warship, game.ref(coastX, 10), {
|
|
patrolTile: game.ref(coastX, 10),
|
|
}),
|
|
target,
|
|
);
|
|
|
|
game.executeNextTick();
|
|
const currentTicks = game.ticks();
|
|
|
|
shell1.init(game, currentTicks);
|
|
shell2.init(game, currentTicks);
|
|
|
|
const healthBefore1 = target.health();
|
|
target.modifyHealth(-shell1.getEffectOnTargetForTesting(), player1);
|
|
const damage1 = healthBefore1 - target.health();
|
|
|
|
target.modifyHealth(-(healthBefore1 - initialHealth));
|
|
|
|
const healthBefore2 = target.health();
|
|
target.modifyHealth(-shell2.getEffectOnTargetForTesting(), player1);
|
|
const damage2 = healthBefore2 - target.health();
|
|
|
|
expect(damage1).toBe(damage2);
|
|
});
|
|
});
|