mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-07 21:05:58 +00:00
aa4b490e68
## Summary The WebGL renderer was adapted from an external extension and carried a lot of machinery this integration never uses (replay playback, its own input/event system, a GL radial menu). This PR is two mechanical cleanup passes with **no behavior change**: delete the dead code, then untangle the `GameView` naming collision. **78 files, +142 / −2,197.** ### Pass 1 — remove dead extension baggage - **Replay/copy mode**: `FrameData.tileMode` was hard-coded `"live"`; the copy branches in `frame/Upload.ts`, `UploadOptions` (never passed), `applyFullFrame`/`applyFullTiles`/`applyDelta` on the facade and `GPURenderer`, `HeatManager.resetForSeek`, and the seek-upload methods on `TerritoryPass`/`TrailPass` were all unreachable. Also deletes `types/Replay.ts`, `types/FrameSource.ts`, `types/GameUpdates.ts`, `types/Game.ts` (imported only by the types barrel). - **FrameEvents**: trimmed from 14 fields to the 3 actually populated and read (`deadUnits`, `conquestEvents`, `bonusEvents`). The other 11 fed the extension's stats system and were never written or read here. - **GL radial menu**: `RadialMenuPass`, its 4 shaders, and ~10 API methods on facade + renderer had zero callers — the game uses the DOM/d3 radial menu in `hud/layers/RadialMenu.ts`. The pass was constructed and drawn every frame for nothing. - **Facade event system**: `GameViewEventMap` defined 10 event types (`click`, `hover`, `scroll`, …) but only `contextrestored` was ever emitted — input actually flows through `InputHandler` → EventBus → controllers. Replaced the listener map with a single `onContextRestored` callback and deleted `Events.ts`. Also fixed the stale header comment claiming the facade handles user interaction. - **Unused API surface**: removed ~20 facade/renderer methods with zero callers (camera passthroughs like `panTo`/`zoomTo`/`fitMap`/`screenToWorld`, hit-testing queries, SAM replay setters, `setSelectedUnit`, `clearFx`/`setFxTimeFn`, `onFrame`/`afterRender`/fps tracking). Deliberately left alone: `Camera`'s pan/zoom primitives (building blocks for a possible future camera unification) and the `timeFn` plumbing inside the FX passes (deeply embedded as defaults; only the dead renderer-level wrappers were removed). ### Pass 2 — untangle the three GameViews - `render/gl/GameView.ts` → **`MapRenderer.ts`** (class `MapRenderer`). Every importer was already aliasing it as `WebGLGameView` to dodge the collision with the simulation-mirror `GameView` in `client/view/`, so this removes aliasing rather than adding churn. `render/CLAUDE.md` updated. - Deleted the `src/core/game/GameView.ts` back-compat shim (its own TODO asked for this). All 51 importers now import from `src/client/view/` directly via a new 3-line barrel `view/index.ts`. ## Test plan - `tsc --noEmit` clean, `eslint` clean - Full test suite passes (1,385 + 65 server tests) - Manual verification via headless Chromium: started a singleplayer game and confirmed the renderer works end-to-end — terrain draws, spawn-phase overlay shows, territories fill with borders after spawning, player names/flags render, no renderer console errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
103 lines
3.1 KiB
TypeScript
103 lines
3.1 KiB
TypeScript
import { EventBus } from "../../../core/EventBus";
|
|
import { SendQuickChatEvent } from "../../Transport";
|
|
import { translateText } from "../../Utils";
|
|
import { GameView, PlayerView } from "../../view";
|
|
import { ChatModal, QuickChatPhrase, quickChatPhrases } from "./ChatModal";
|
|
import { COLORS, MenuElement, MenuElementParams } from "./RadialMenuElements";
|
|
|
|
export class ChatIntegration {
|
|
private ctModal: ChatModal;
|
|
|
|
constructor(
|
|
private game: GameView,
|
|
private eventBus: EventBus,
|
|
) {
|
|
this.ctModal = document.querySelector("chat-modal") as ChatModal;
|
|
|
|
if (!this.ctModal) {
|
|
throw new Error(
|
|
"Chat modal element not found. Ensure chat-modal element exists in DOM before initializing ChatIntegration",
|
|
);
|
|
}
|
|
}
|
|
|
|
setupChatModal(sender: PlayerView, recipient: PlayerView) {
|
|
this.ctModal.setSender(sender);
|
|
this.ctModal.setRecipient(recipient);
|
|
}
|
|
|
|
createQuickChatMenu(recipient: PlayerView): MenuElement[] {
|
|
if (!this.ctModal) {
|
|
throw new Error("Chat modal not set");
|
|
}
|
|
|
|
const myPlayer = this.game.myPlayer();
|
|
if (!myPlayer) {
|
|
throw new Error("Current player not found");
|
|
}
|
|
|
|
return this.ctModal.categories.map((category) => {
|
|
const categoryTranslation = translateText(`chat.cat.${category.id}`);
|
|
|
|
const categoryColor =
|
|
COLORS.chat[category.id as keyof typeof COLORS.chat] ||
|
|
COLORS.chat.default;
|
|
const phrases = quickChatPhrases[category.id] || [];
|
|
|
|
const phraseItems: MenuElement[] = phrases.map(
|
|
(phrase: QuickChatPhrase) => {
|
|
const phraseText = translateText(`chat.${category.id}.${phrase.key}`);
|
|
|
|
return {
|
|
id: `phrase-${category.id}-${phrase.key}`,
|
|
name: phraseText,
|
|
disabled: () => false,
|
|
text: this.shortenText(phraseText),
|
|
fontSize: "10px",
|
|
color: categoryColor,
|
|
tooltipItems: [
|
|
{
|
|
text: phraseText,
|
|
className: "description",
|
|
},
|
|
],
|
|
action: (params: MenuElementParams) => {
|
|
if (phrase.requiresPlayer) {
|
|
this.ctModal.openWithSelection(
|
|
category.id,
|
|
phrase.key,
|
|
myPlayer,
|
|
recipient,
|
|
);
|
|
} else {
|
|
this.eventBus.emit(
|
|
new SendQuickChatEvent(
|
|
recipient,
|
|
`${category.id}.${phrase.key}`,
|
|
undefined,
|
|
),
|
|
);
|
|
}
|
|
},
|
|
};
|
|
},
|
|
);
|
|
|
|
return {
|
|
id: `chat-category-${category.id}`,
|
|
name: categoryTranslation,
|
|
disabled: () => false,
|
|
text: categoryTranslation,
|
|
color: categoryColor,
|
|
_action: () => {}, // Empty action placeholder for RadialMenu
|
|
subMenu: () => phraseItems,
|
|
};
|
|
});
|
|
}
|
|
|
|
shortenText(text: string, maxLength = 15): string {
|
|
if (text.length <= maxLength) return text;
|
|
return text.substring(0, maxLength - 3) + "...";
|
|
}
|
|
}
|