Files
VariableVince 9c24d29824 AFK team mate v2: better ship handling + tests + bugfix (#2396)
## Description:

See PR https://github.com/openfrontio/OpenFrontIO/pull/2203

It was reverted. This unreverts it, with an added fix for boat troops
not getting returned to owner. And small comment updates. And a const
for boatOwner to re-use.

The added bugfix is check for this.sourceTile === null in the retreat()
function in AttackExecution. A boat attack always sets removeTroops to
false because the troops were already removed from owner troops when the
boat departed. They don't have to be removed again in AttackExecution
init, when the boat lands and the attack starts. But at the end of the
attack, in retreat() in AttackExecution, the starting/boat troops still
need to be returned to the owner. That's why even if removeTroops is
false, when sourceTile is not null (only when it's a boat attack) we add
back the troops to the owner.

## 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:

tryout33

---------

Co-authored-by: Fx Morin <28154542+FxMorin@users.noreply.github.com>
Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
2025-11-18 14:57:33 -08:00

87 lines
2.3 KiB
TypeScript

import fs from "fs";
import path from "path";
import {
Difficulty,
Game,
GameMapSize,
GameMapType,
GameMode,
GameType,
PlayerInfo,
PlayerType,
} from "../../src/core/game/Game";
import { createGame } from "../../src/core/game/GameImpl";
import {
genTerrainFromBin,
MapManifest,
} from "../../src/core/game/TerrainMapLoader";
import { UserSettings } from "../../src/core/game/UserSettings";
import { GameConfig } from "../../src/core/Schemas";
import { TestConfig } from "./TestConfig";
import { TestServerConfig } from "./TestServerConfig";
export async function setup(
mapName: string,
_gameConfig: Partial<GameConfig> = {},
humans: PlayerInfo[] = [],
currentDir: string = __dirname,
ConfigClass: typeof TestConfig = TestConfig,
): Promise<Game> {
// Suppress console.debug for tests.
console.debug = () => {};
// Simple binary file loading using fs.readFileSync()
const mapBinPath = path.join(
currentDir,
`../testdata/maps/${mapName}/map.bin`,
);
const miniMapBinPath = path.join(
currentDir,
`../testdata/maps/${mapName}/map4x.bin`,
);
const manifestPath = path.join(
currentDir,
`../testdata/maps/${mapName}/manifest.json`,
);
const mapBinBuffer = fs.readFileSync(mapBinPath);
const miniMapBinBuffer = fs.readFileSync(miniMapBinPath);
const manifest = JSON.parse(
fs.readFileSync(manifestPath, "utf8"),
) satisfies MapManifest;
const gameMap = await genTerrainFromBin(manifest.map, mapBinBuffer);
const miniGameMap = await genTerrainFromBin(manifest.map4x, miniMapBinBuffer);
// Configure the game
const serverConfig = new TestServerConfig();
const gameConfig: GameConfig = {
gameMap: GameMapType.Asia,
gameMapSize: GameMapSize.Normal,
gameMode: GameMode.FFA,
gameType: GameType.Singleplayer,
difficulty: Difficulty.Medium,
disableNPCs: false,
donateGold: false,
donateTroops: false,
bots: 0,
infiniteGold: false,
infiniteTroops: false,
instantBuild: false,
randomSpawn: false,
..._gameConfig,
};
const config = new ConfigClass(
serverConfig,
gameConfig,
new UserSettings(),
false,
);
return createGame(humans, [], gameMap, miniGameMap, config);
}
export function playerInfo(name: string, type: PlayerType): PlayerInfo {
return new PlayerInfo(name, type, null, name);
}