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>
This commit is contained in:
Aotumuri
2025-05-08 09:00:25 -07:00
committed by GitHub
parent 5de469e312
commit 5ddc25897f
16 changed files with 1014 additions and 0 deletions
+8
View File
@@ -15,6 +15,7 @@ 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";
@@ -108,6 +109,13 @@ export class Executor {
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`);
}
+98
View File
@@ -0,0 +1,98 @@
import quickChatData from "../../../resources/QuickChat.json";
import { consolex } from "../Consolex";
import { Execution, Game, MessageType, Player, PlayerID } from "../game/Game";
export class QuickChatExecution implements Execution {
private sender: Player;
private recipient: Player;
private mg: Game;
private active = true;
constructor(
private senderID: PlayerID,
private recipientID: PlayerID,
private quickChatKey: string,
private variables: Record<string, string>,
) {}
init(mg: Game, ticks: number): void {
this.mg = mg;
if (!mg.hasPlayer(this.senderID)) {
consolex.warn(`QuickChatExecution: sender ${this.senderID} not found`);
this.active = false;
return;
}
if (!mg.hasPlayer(this.recipientID)) {
consolex.warn(
`QuickChatExecution: recipient ${this.recipientID} not found`,
);
this.active = false;
return;
}
this.sender = mg.player(this.senderID);
this.recipient = mg.player(this.recipientID);
}
tick(ticks: number): void {
const message = this.getMessageFromKey(this.quickChatKey, this.variables);
this.mg.displayMessage(
`${this.sender.name()}: ${message}`,
MessageType.CHAT,
this.recipient.id(),
);
this.mg.displayMessage(
`You sent to ${this.recipient.name()}: ${message}`,
MessageType.CHAT,
this.sender.id(),
);
consolex.log(
`[QuickChat] ${this.sender.name}${this.recipient.name}: ${message}`,
);
this.active = false;
}
owner(): Player {
return this.sender;
}
isActive(): boolean {
return this.active;
}
activeDuringSpawnPhase(): boolean {
return false;
}
private getMessageFromKey(
fullKey: string,
vars: Record<string, string>,
): string {
// Key for translation
const [category, key] = fullKey.split(".");
const phrases = quickChatData[category];
if (!phrases) {
consolex.warn(`QuickChat: Unknown category '${category}'`);
return `[${fullKey}]`;
}
const phraseObj = phrases.find((p) => p.key === key);
if (!phraseObj) {
consolex.warn(
`QuickChat: Key '${key}' not found in category '${category}'`,
);
return `[${fullKey}]`;
}
return phraseObj.text.replace(
/\[(\w+)\]/g,
(_, p1) => vars[p1] || `[${p1}]`,
);
}
}