Fixing game movement.

The git gods appear to have swallowed the code I previously wrote for
loadNextGame. Here is a fix for that. The games load in order, from 0 =>
infinity (more likely max of int).
This commit is contained in:
Tyler Marques 2025-06-04 09:35:37 -07:00
parent adccd41d89
commit ac8c511334
No known key found for this signature in database
GPG key ID: CB99EDCF41D3016F
3 changed files with 74 additions and 64 deletions

View file

@ -7,10 +7,10 @@ import { prevBtn, nextBtn, playBtn, speedSelector, mapView, updateGameIdDisplay
import { createChatWindows } from "./domElements/chatWindows";
import { logger } from "./logger";
import { OrbitControls } from "three/examples/jsm/Addons.js";
import { displayInitialPhase } from "./phase";
import { displayInitialPhase, togglePlayback } from "./phase";
import { Tween, Group as TweenGroup } from "@tweenjs/tween.js";
import { hideStandingsBoard, } from "./domElements/standingsBoard";
import { MomentsDataSchema, MomentsDataSchemaType, Moment, NormalizedMomentsData } from "./types/moments";
import { MomentsDataSchema, Moment, NormalizedMomentsData } from "./types/moments";
//FIXME: This whole file is a mess. Need to organize and format
@ -273,18 +273,27 @@ class GameState {
* Loads the next game in the order, reseting the board and gameState
*/
loadNextGame = () => {
//
let gameId = this.gameId + 1
let contPlaying = false
if (this.isPlaying) {
contPlaying = true
}
this.loadGameFile(gameId).then(() => {
this.gameId += 1
if (contPlaying) {
togglePlayback(true)
}
}
)
// Try to load the next game, if it fails, show end screen forever
}
/*
* Given a gameId, load that game's state into the GameState Object
*/
loadGameFile = (gameId: number) => {
loadGameFile = (gameId: number): Promise<void> => {
if (gameId === null || gameId < 0) {
throw Error(`Attempted to load game with invalid ID ${gameId}`)
@ -292,18 +301,18 @@ class GameState {
// Path to the default game file
const gameFilePath = `./games/${gameId}/game.json`;
loadFileFromServer(gameFilePath).then((data) => {
this.gameId = gameId
return loadFileFromServer(gameFilePath).then((data) => {
return this.loadGameData(data);
})
.then(() => {
console.log("Default game file loaded and parsed successfully");
console.log(`Game file with id ${gameId} loaded and parsed successfully`);
// Explicitly hide standings board after loading game
hideStandingsBoard();
// Update rotating display and relationship popup with game data
if (this.gameData) {
updateRotatingDisplay(this.gameData, this.phaseIndex, this.currentPower);
this.gameId = gameId
updateGameIdDisplay();
}
})

View file

@ -6,7 +6,7 @@ import { logger } from "./logger";
import { loadBtn, prevBtn, nextBtn, speedSelector, fileInput, playBtn, mapView, loadGameBtnFunction } from "./domElements";
import { updateChatWindows } from "./domElements/chatWindows";
import { initStandingsBoard, hideStandingsBoard, showStandingsBoard } from "./domElements/standingsBoard";
import { displayPhaseWithAnimation, advanceToNextPhase, resetToPhase, nextPhase, previousPhase } from "./phase";
import { displayPhaseWithAnimation, advanceToNextPhase, resetToPhase, nextPhase, previousPhase, togglePlayback } from "./phase";
import { config } from "./config";
import { Tween, Group, Easing } from "@tweenjs/tween.js";
import { initRotatingDisplay, updateRotatingDisplay } from "./components/rotatingDisplay";
@ -186,58 +186,6 @@ function onWindowResize() {
// --- PLAYBACK CONTROLS ---
function togglePlayback() {
// If the game doesn't have any data, or there are no phases, return;
if (!gameState.gameData || gameState.gameData.phases.length <= 0) {
alert("This game file appears to be broken. Please reload the page and load a different game.")
throw Error("Bad gameState, exiting.")
};
// TODO: Likely not how we want to handle the speaking section of this.
// Should be able to pause the other elements while we're speaking
if (gameState.isSpeaking) return;
gameState.isPlaying = !gameState.isPlaying;
if (gameState.isPlaying) {
playBtn.textContent = "⏸ Pause";
prevBtn.disabled = true;
nextBtn.disabled = true;
logger.log("Starting playback...");
if (gameState.cameraPanAnim) gameState.cameraPanAnim.getAll()[1].start()
// Hide standings board when playback starts
hideStandingsBoard();
// Update rotating display
if (gameState.gameData) {
updateRotatingDisplay(gameState.gameData, gameState.phaseIndex, gameState.currentPower);
}
// First, show the messages of the current phase if it's the initial playback
const phase = gameState.gameData.phases[gameState.phaseIndex];
if (phase.messages && phase.messages.length) {
// Show messages with stepwise animation
logger.log(`Playing ${phase.messages.length} messages from phase ${gameState.phaseIndex + 1}/${gameState.gameData.phases.length}`);
updateChatWindows(phase, true);
} else {
// No messages, go straight to unit animations
logger.log("No messages for this phase, proceeding to animations");
displayPhaseWithAnimation();
}
} else {
if (gameState.cameraPanAnim) gameState.cameraPanAnim.getAll()[0].pause();
playBtn.textContent = "▶ Play";
if (gameState.playbackTimer) {
clearTimeout(gameState.playbackTimer);
gameState.playbackTimer = null;
}
gameState.messagesPlaying = false;
prevBtn.disabled = false;
nextBtn.disabled = false;
}
}
@ -252,7 +200,6 @@ fileInput.addEventListener('change', e => {
// Update rotating display and relationship popup with game data
if (gameState.gameData) {
updateRotatingDisplay(gameState.gameData, gameState.phaseIndex, gameState.currentPower);
updateRelationshipPopup();
}
}
});

View file

@ -1,6 +1,6 @@
import { gameState } from "./gameState";
import { logger } from "./logger";
import { updatePhaseDisplay } from "./domElements";
import { updatePhaseDisplay, playBtn, prevBtn, nextBtn } from "./domElements";
import { initUnits } from "./units/create";
import { updateSupplyCenterOwnership, updateLeaderboard, updateMapOwnership as _updateMapOwnership, updateMapOwnership } from "./map/state";
import { updateChatWindows, addToNewsBanner } from "./domElements/chatWindows";
@ -11,6 +11,7 @@ import { debugMenuInstance } from "./debug/debugMenu";
import { showTwoPowerConversation, closeTwoPowerConversation } from "./components/twoPowerConversation";
import { closeVictoryModal, showVictoryModal } from "./components/victoryModal";
import { notifyPhaseChange } from "./webhooks/phaseNotifier";
import { updateRotatingDisplay } from "./components/rotatingDisplay";
const MOMENT_THRESHOLD = 8.0
// If we're in debug mode or instant mode, show it quick, otherwise show it for 30 seconds
@ -69,6 +70,59 @@ export function _setPhase(phaseIndex: number) {
notifyPhaseChange(oldPhaseIndex, phaseIndex);
}
// --- PLAYBACK CONTROLS ---
export function togglePlayback(explicitSet: boolean) {
// If the game doesn't have any data, or there are no phases, return;
if (!gameState.gameData || gameState.gameData.phases.length <= 0) {
alert("This game file appears to be broken. Please reload the page and load a different game.")
throw Error("Bad gameState, exiting.")
};
// TODO: Likely not how we want to handle the speaking section of this.
// Should be able to pause the other elements while we're speaking
if (gameState.isSpeaking) return;
gameState.isPlaying = !gameState.isPlaying;
if (explicitSet !== undefined) {
gameState.isPlaying = explicitSet
}
if (gameState.isPlaying) {
playBtn.textContent = "⏸ Pause";
prevBtn.disabled = true;
nextBtn.disabled = true;
logger.log("Starting playback...");
if (gameState.cameraPanAnim) gameState.cameraPanAnim.getAll()[1].start()
// Update rotating display
if (gameState.gameData) {
updateRotatingDisplay(gameState.gameData, gameState.phaseIndex, gameState.currentPower);
}
// First, show the messages of the current phase if it's the initial playback
const phase = gameState.gameData.phases[gameState.phaseIndex];
if (phase.messages && phase.messages.length) {
// Show messages with stepwise animation
logger.log(`Playing ${phase.messages.length} messages from phase ${gameState.phaseIndex + 1}/${gameState.gameData.phases.length}`);
updateChatWindows(phase, true);
} else {
// No messages, go straight to unit animations
logger.log("No messages for this phase, proceeding to animations");
displayPhaseWithAnimation();
}
} else {
if (gameState.cameraPanAnim) gameState.cameraPanAnim.getAll()[0].pause();
playBtn.textContent = "▶ Play";
if (gameState.playbackTimer) {
clearTimeout(gameState.playbackTimer);
gameState.playbackTimer = null;
}
gameState.messagesPlaying = false;
prevBtn.disabled = false;
nextBtn.disabled = false;
}
}
export function nextPhase() {