Files
OpenFrontIO/src/core/execution/ExecutionManager.ts
T
Aotumuri 5ddc25897f Add quick chat (#412)
## Description:

Fixes #480 

## Please complete the following:

- [ ] I have added screenshots for all UI updates
- [ ] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [ ] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

<DISCORD USERNAME>
2025-05-08 09:00:25 -07:00

136 lines
4.6 KiB
TypeScript

import { Execution, Game } from "../game/Game";
import { PseudoRandom } from "../PseudoRandom";
import { ClientID, GameID, Intent, Turn } from "../Schemas";
import { simpleHash } from "../Util";
import { AllianceRequestExecution } from "./alliance/AllianceRequestExecution";
import { AllianceRequestReplyExecution } from "./alliance/AllianceRequestReplyExecution";
import { BreakAllianceExecution } from "./alliance/BreakAllianceExecution";
import { AttackExecution } from "./AttackExecution";
import { BotSpawner } from "./BotSpawner";
import { ConstructionExecution } from "./ConstructionExecution";
import { DonateGoldExecution } from "./DonateGoldExecution";
import { DonateTroopsExecution } from "./DonateTroopExecution";
import { EmbargoExecution } from "./EmbargoExecution";
import { EmojiExecution } from "./EmojiExecution";
import { FakeHumanExecution } from "./FakeHumanExecution";
import { MoveWarshipExecution } from "./MoveWarshipExecution";
import { NoOpExecution } from "./NoOpExecution";
import { QuickChatExecution } from "./QuickChatExecution";
import { RetreatExecution } from "./RetreatExecution";
import { SetTargetTroopRatioExecution } from "./SetTargetTroopRatioExecution";
import { SpawnExecution } from "./SpawnExecution";
import { TargetPlayerExecution } from "./TargetPlayerExecution";
import { TransportShipExecution } from "./TransportShipExecution";
export class Executor {
// private random = new PseudoRandom(999)
private random: PseudoRandom = null;
constructor(
private mg: Game,
private gameID: GameID,
private clientID: ClientID,
) {
// Add one to avoid id collisions with bots.
this.random = new PseudoRandom(simpleHash(gameID) + 1);
}
createExecs(turn: Turn): Execution[] {
return turn.intents.map((i) => this.createExec(i));
}
createExec(intent: Intent): Execution {
const player = this.mg.playerByClientID(intent.clientID);
if (!player) {
console.warn(`player with clientID ${intent.clientID} not found`);
return new NoOpExecution();
}
const playerID = player.id();
switch (intent.type) {
case "attack": {
return new AttackExecution(
intent.troops,
playerID,
intent.targetID,
null,
);
}
case "cancel_attack":
return new RetreatExecution(playerID, intent.attackID);
case "move_warship":
return new MoveWarshipExecution(intent.unitId, intent.tile);
case "spawn":
return new SpawnExecution(
player.info(),
this.mg.ref(intent.x, intent.y),
);
case "boat":
let src = null;
if (intent.srcX != null || intent.srcY != null) {
src = this.mg.ref(intent.srcX, intent.srcY);
}
return new TransportShipExecution(
playerID,
intent.targetID,
this.mg.ref(intent.dstX, intent.dstY),
intent.troops,
src,
);
case "allianceRequest":
return new AllianceRequestExecution(playerID, intent.recipient);
case "allianceRequestReply":
return new AllianceRequestReplyExecution(
intent.requestor,
playerID,
intent.accept,
);
case "breakAlliance":
return new BreakAllianceExecution(playerID, intent.recipient);
case "targetPlayer":
return new TargetPlayerExecution(playerID, intent.target);
case "emoji":
return new EmojiExecution(playerID, intent.recipient, intent.emoji);
case "donate_troops":
return new DonateTroopsExecution(
playerID,
intent.recipient,
intent.troops,
);
case "donate_gold":
return new DonateGoldExecution(playerID, intent.recipient, intent.gold);
case "troop_ratio":
return new SetTargetTroopRatioExecution(playerID, intent.ratio);
case "embargo":
return new EmbargoExecution(player, intent.targetID, intent.action);
case "build_unit":
return new ConstructionExecution(
playerID,
this.mg.ref(intent.x, intent.y),
intent.unit,
);
case "quick_chat":
return new QuickChatExecution(
playerID,
intent.recipient,
intent.quickChatKey,
intent.variables ?? {},
);
default:
throw new Error(`intent type ${intent} not found`);
}
}
spawnBots(numBots: number): Execution[] {
return new BotSpawner(this.mg, this.gameID).spawnBots(numBots);
}
fakeHumanExecutions(): Execution[] {
const execs = [];
for (const nation of this.mg.nations()) {
execs.push(new FakeHumanExecution(this.gameID, nation));
}
return execs;
}
}