Enhance GameLoop and GameStateManager for improved mission handling and health management
- Integrate narrative management into the GameLoop to handle mission completion and transitions, ensuring a smooth player experience. - Implement health restoration logic for units based on roster data, preserving health values across missions. - Update GameStateManager to clear active run data upon mission completion or failure, enhancing state management. - Enhance Persistence layer with detailed logging for campaign data loading and saving, improving debugging and data integrity. - Add event listeners in UI components to refresh mission data upon campaign changes, ensuring real-time updates for players.
This commit is contained in:
parent
45276d1bd4
commit
8d2baacd5f
9 changed files with 243 additions and 30 deletions
|
|
@ -25,6 +25,7 @@ import { skillRegistry } from "../managers/SkillRegistry.js";
|
||||||
import { InventoryManager } from "../managers/InventoryManager.js";
|
import { InventoryManager } from "../managers/InventoryManager.js";
|
||||||
import { InventoryContainer } from "../models/InventoryContainer.js";
|
import { InventoryContainer } from "../models/InventoryContainer.js";
|
||||||
import { itemRegistry } from "../managers/ItemRegistry.js";
|
import { itemRegistry } from "../managers/ItemRegistry.js";
|
||||||
|
import { narrativeManager } from "../managers/NarrativeManager.js";
|
||||||
|
|
||||||
// Import class definitions
|
// Import class definitions
|
||||||
import vanguardDef from "../assets/data/classes/vanguard.json" with { type: "json" };
|
import vanguardDef from "../assets/data/classes/vanguard.json" with { type: "json" };
|
||||||
|
|
@ -1223,6 +1224,13 @@ export class GameLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore currentHealth from roster (preserve HP that was paid for)
|
||||||
|
if (rosterUnit.currentHealth !== undefined && rosterUnit.currentHealth !== null) {
|
||||||
|
// Ensure currentHealth doesn't exceed maxHealth (in case maxHealth increased)
|
||||||
|
unit.currentHealth = Math.min(rosterUnit.currentHealth, unit.maxHealth || 100);
|
||||||
|
console.log(`Restored HP for ${unit.name}: ${unit.currentHealth}/${unit.maxHealth} (from roster)`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1256,11 +1264,16 @@ export class GameLoop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure unit starts with full health
|
// Ensure unit has valid health values
|
||||||
// Explorer constructor might set health to 0 if classDef is missing base_stats
|
// Only set to full health if currentHealth is invalid (0 or negative) and wasn't restored from roster
|
||||||
if (unit.currentHealth <= 0) {
|
// This preserves HP that was paid for in the barracks
|
||||||
|
if (unit.currentHealth <= 0 && (!unit.rosterId || !this.gameStateManager?.rosterManager?.roster.find(r => r.id === unit.rosterId)?.currentHealth)) {
|
||||||
|
// Only set to full if we didn't restore from roster (new unit or roster had no saved HP)
|
||||||
unit.currentHealth = unit.maxHealth || unit.baseStats?.health || 100;
|
unit.currentHealth = unit.maxHealth || unit.baseStats?.health || 100;
|
||||||
unit.maxHealth = unit.maxHealth || unit.baseStats?.health || 100;
|
}
|
||||||
|
// Ensure maxHealth is set
|
||||||
|
if (!unit.maxHealth) {
|
||||||
|
unit.maxHealth = unit.baseStats?.health || 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.grid.placeUnit(unit, targetTile);
|
this.grid.placeUnit(unit, targetTile);
|
||||||
|
|
@ -2588,13 +2601,49 @@ export class GameLoop {
|
||||||
// Stop the game loop
|
// Stop the game loop
|
||||||
this.stop();
|
this.stop();
|
||||||
|
|
||||||
// TODO: Show victory screen UI
|
// Clear the active run from persistence since mission is complete
|
||||||
// For now, just log and transition back to main menu after a delay
|
if (this.gameStateManager) {
|
||||||
setTimeout(() => {
|
this.gameStateManager.clearActiveRun();
|
||||||
if (this.gameStateManager) {
|
}
|
||||||
this.gameStateManager.transitionTo('STATE_MAIN_MENU');
|
|
||||||
}
|
// Wait for the outro narrative to complete before transitioning
|
||||||
}, 3000);
|
// The outro is played in MissionManager.completeActiveMission()
|
||||||
|
// We'll listen for the narrative-end event to know when it's done
|
||||||
|
const hasOutro = this.gameStateManager?.missionManager?.currentMissionDef?.narrative?.outro_success;
|
||||||
|
|
||||||
|
if (hasOutro) {
|
||||||
|
console.log('GameLoop: Waiting for outro narrative to complete...');
|
||||||
|
const handleNarrativeEnd = () => {
|
||||||
|
console.log('GameLoop: Narrative end event received, transitioning to hub');
|
||||||
|
narrativeManager.removeEventListener('narrative-end', handleNarrativeEnd);
|
||||||
|
|
||||||
|
// Small delay after narrative ends to let user see the final message
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.gameStateManager) {
|
||||||
|
this.gameStateManager.transitionTo('STATE_MAIN_MENU');
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
narrativeManager.addEventListener('narrative-end', handleNarrativeEnd);
|
||||||
|
|
||||||
|
// Fallback timeout: if narrative doesn't end within 30 seconds, transition anyway
|
||||||
|
setTimeout(() => {
|
||||||
|
console.warn('GameLoop: Narrative end timeout - transitioning to hub anyway');
|
||||||
|
narrativeManager.removeEventListener('narrative-end', handleNarrativeEnd);
|
||||||
|
if (this.gameStateManager) {
|
||||||
|
this.gameStateManager.transitionTo('STATE_MAIN_MENU');
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
} else {
|
||||||
|
// No outro, transition immediately after a short delay
|
||||||
|
console.log('GameLoop: No outro narrative, transitioning to hub');
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.gameStateManager) {
|
||||||
|
this.gameStateManager.transitionTo('STATE_MAIN_MENU');
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2663,6 +2712,11 @@ export class GameLoop {
|
||||||
// Stop the game loop
|
// Stop the game loop
|
||||||
this.stop();
|
this.stop();
|
||||||
|
|
||||||
|
// Clear the active run from persistence since mission is failed
|
||||||
|
if (this.gameStateManager) {
|
||||||
|
this.gameStateManager.clearActiveRun();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Show failure screen UI
|
// TODO: Show failure screen UI
|
||||||
// For now, just log and transition back to main menu after a delay
|
// For now, just log and transition back to main menu after a delay
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
||||||
|
|
@ -159,8 +159,15 @@ class GameStateManagerClass {
|
||||||
|
|
||||||
// 4. Load Campaign Progress
|
// 4. Load Campaign Progress
|
||||||
const savedCampaignData = await this.persistence.loadCampaign();
|
const savedCampaignData = await this.persistence.loadCampaign();
|
||||||
|
console.log("Loaded campaign data:", savedCampaignData);
|
||||||
if (savedCampaignData) {
|
if (savedCampaignData) {
|
||||||
this.missionManager.load(savedCampaignData);
|
this.missionManager.load(savedCampaignData);
|
||||||
|
console.log(
|
||||||
|
"Campaign data loaded. Completed missions:",
|
||||||
|
Array.from(this.missionManager.completedMissions)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log("No saved campaign data found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Set up mission rewards listener
|
// 5. Set up mission rewards listener
|
||||||
|
|
@ -426,8 +433,42 @@ class GameStateManagerClass {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _saveCampaign() {
|
async _saveCampaign() {
|
||||||
const data = this.missionManager.save();
|
try {
|
||||||
await this.persistence.saveCampaign(data);
|
const data = this.missionManager.save();
|
||||||
|
console.log("GameStateManager: Saving campaign data:", data);
|
||||||
|
console.log(
|
||||||
|
"GameStateManager: Completed missions count:",
|
||||||
|
this.missionManager.completedMissions.size
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"GameStateManager: Completed missions array:",
|
||||||
|
Array.from(this.missionManager.completedMissions)
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
!data ||
|
||||||
|
!data.completedMissions ||
|
||||||
|
data.completedMissions.length === 0
|
||||||
|
) {
|
||||||
|
console.warn(
|
||||||
|
"GameStateManager: Warning - no completed missions to save!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await this.persistence.saveCampaign(data);
|
||||||
|
console.log("GameStateManager: Campaign data saved successfully");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("GameStateManager: Error saving campaign data:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the active run from memory and persistence.
|
||||||
|
* Called when a mission is completed or failed.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async clearActiveRun() {
|
||||||
|
this.activeRunData = null;
|
||||||
|
await this.persistence.clearRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -468,8 +509,12 @@ class GameStateManagerClass {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_setupCampaignDataListener() {
|
_setupCampaignDataListener() {
|
||||||
window.addEventListener("campaign-data-changed", () => {
|
window.addEventListener("campaign-data-changed", async (event) => {
|
||||||
this._saveCampaign();
|
console.log(
|
||||||
|
"GameStateManager: Received campaign-data-changed event:",
|
||||||
|
event.detail
|
||||||
|
);
|
||||||
|
await this._saveCampaign();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const MARKET_STORE = "Market";
|
||||||
const CAMPAIGN_STORE = "Campaign";
|
const CAMPAIGN_STORE = "Campaign";
|
||||||
const HUB_STASH_STORE = "HubStash";
|
const HUB_STASH_STORE = "HubStash";
|
||||||
const UNLOCKS_STORE = "Unlocks";
|
const UNLOCKS_STORE = "Unlocks";
|
||||||
const VERSION = 5; // Bumped version to add HubStash and Unlocks stores
|
const VERSION = 6; // Bumped version to add Campaign store
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles game data persistence using IndexedDB.
|
* Handles game data persistence using IndexedDB.
|
||||||
|
|
@ -162,7 +162,14 @@ export class Persistence {
|
||||||
*/
|
*/
|
||||||
async saveCampaign(campaignData) {
|
async saveCampaign(campaignData) {
|
||||||
if (!this.db) await this.init();
|
if (!this.db) await this.init();
|
||||||
return this._put(CAMPAIGN_STORE, { id: "campaign_data", data: campaignData });
|
console.log("Persistence: Saving campaign data to Campaign store:", campaignData);
|
||||||
|
try {
|
||||||
|
await this._put(CAMPAIGN_STORE, { id: "campaign_data", data: campaignData });
|
||||||
|
console.log("Persistence: Campaign data saved successfully");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Persistence: Error saving campaign data:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -171,8 +178,15 @@ export class Persistence {
|
||||||
*/
|
*/
|
||||||
async loadCampaign() {
|
async loadCampaign() {
|
||||||
if (!this.db) await this.init();
|
if (!this.db) await this.init();
|
||||||
const result = await this._get(CAMPAIGN_STORE, "campaign_data");
|
console.log("Persistence: Loading campaign data from Campaign store");
|
||||||
return result ? result.data : null;
|
try {
|
||||||
|
const result = await this._get(CAMPAIGN_STORE, "campaign_data");
|
||||||
|
console.log("Persistence: Loaded campaign data result:", result);
|
||||||
|
return result ? result.data : null;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Persistence: Error loading campaign data:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- HUB STASH DATA ---
|
// --- HUB STASH DATA ---
|
||||||
|
|
|
||||||
|
|
@ -419,19 +419,24 @@ export class MissionManager {
|
||||||
|
|
||||||
// Mark mission as completed
|
// Mark mission as completed
|
||||||
this.completedMissions.add(this.activeMissionId);
|
this.completedMissions.add(this.activeMissionId);
|
||||||
|
console.log("MissionManager: Mission completed. Active mission ID:", this.activeMissionId);
|
||||||
|
console.log("MissionManager: Completed missions now:", Array.from(this.completedMissions));
|
||||||
|
|
||||||
|
// Dispatch event to save campaign data IMMEDIATELY (before outro)
|
||||||
|
// This ensures the save happens even if the outro doesn't complete
|
||||||
|
console.log("MissionManager: Dispatching campaign-data-changed event");
|
||||||
|
window.dispatchEvent(new CustomEvent('campaign-data-changed', {
|
||||||
|
detail: { missionCompleted: this.activeMissionId }
|
||||||
|
}));
|
||||||
|
console.log("MissionManager: campaign-data-changed event dispatched");
|
||||||
|
|
||||||
// Distribute rewards
|
// Distribute rewards
|
||||||
this.distributeRewards();
|
this.distributeRewards();
|
||||||
|
|
||||||
// Play outro narrative if available
|
// Play outro narrative if available (after saving)
|
||||||
if (this.currentMissionDef.narrative?.outro_success) {
|
if (this.currentMissionDef.narrative?.outro_success) {
|
||||||
await this.playOutro(this.currentMissionDef.narrative.outro_success);
|
await this.playOutro(this.currentMissionDef.narrative.outro_success);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch event to save campaign data
|
|
||||||
window.dispatchEvent(new CustomEvent('campaign-data-changed', {
|
|
||||||
detail: { missionCompleted: this.activeMissionId }
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,15 @@ export class NarrativeManager extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextId = this.currentNode.next;
|
const nextId = this.currentNode.next;
|
||||||
|
|
||||||
|
// If the next node is "END", we still need to wait for user to click again
|
||||||
|
// to actually close the dialogue. This gives them time to read the last message.
|
||||||
|
if (!nextId || nextId === "END") {
|
||||||
|
// User clicked on the last message - now close it
|
||||||
|
this.endSequence();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this._advanceToNode(nextId);
|
this._advanceToNode(nextId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,6 +137,11 @@ export class NarrativeManager extends EventTarget {
|
||||||
|
|
||||||
endSequence() {
|
endSequence() {
|
||||||
console.log("NarrativeManager: Sequence Ended");
|
console.log("NarrativeManager: Sequence Ended");
|
||||||
|
// Only end if we actually have a sequence active
|
||||||
|
if (!this.currentSequence) {
|
||||||
|
console.warn("NarrativeManager: endSequence called but no active sequence");
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.currentSequence = null;
|
this.currentSequence = null;
|
||||||
this.currentNode = null;
|
this.currentNode = null;
|
||||||
this.dispatchEvent(new CustomEvent("narrative-end"));
|
this.dispatchEvent(new CustomEvent("narrative-end"));
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,24 @@ export class MissionBoard extends LitElement {
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this._loadMissions();
|
this._loadMissions();
|
||||||
|
|
||||||
|
// Listen for campaign data changes to refresh completed missions
|
||||||
|
this._boundHandleCampaignChange = this._handleCampaignChange.bind(this);
|
||||||
|
window.addEventListener('campaign-data-changed', this._boundHandleCampaignChange);
|
||||||
|
window.addEventListener('gamestate-changed', this._boundHandleCampaignChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
if (this._boundHandleCampaignChange) {
|
||||||
|
window.removeEventListener('campaign-data-changed', this._boundHandleCampaignChange);
|
||||||
|
window.removeEventListener('gamestate-changed', this._boundHandleCampaignChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleCampaignChange() {
|
||||||
|
// Reload missions when campaign data changes (mission completed)
|
||||||
|
this._loadMissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadMissions() {
|
_loadMissions() {
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ export class DialogueOverlay extends LitElement {
|
||||||
super();
|
super();
|
||||||
this.activeNode = null;
|
this.activeNode = null;
|
||||||
this.isVisible = false;
|
this.isVisible = false;
|
||||||
|
this._isProcessingClick = false; // Prevent rapid clicks
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
|
|
@ -150,6 +151,9 @@ export class DialogueOverlay extends LitElement {
|
||||||
_onUpdate(e) {
|
_onUpdate(e) {
|
||||||
this.activeNode = e.detail.node;
|
this.activeNode = e.detail.node;
|
||||||
this.isVisible = e.detail.active;
|
this.isVisible = e.detail.active;
|
||||||
|
// Reset processing flag when a new node is shown
|
||||||
|
// This ensures each message can be clicked independently
|
||||||
|
this._isProcessingClick = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onEnd() {
|
_onEnd() {
|
||||||
|
|
@ -160,9 +164,28 @@ export class DialogueOverlay extends LitElement {
|
||||||
_handleInput(e) {
|
_handleInput(e) {
|
||||||
if (!this.isVisible) return;
|
if (!this.isVisible) return;
|
||||||
if (e.code === "Space" || e.code === "Enter") {
|
if (e.code === "Space" || e.code === "Enter") {
|
||||||
|
// Prevent rapid key presses
|
||||||
|
if (this._isProcessingClick) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Only advance if no choices
|
// Only advance if no choices
|
||||||
if (!this.activeNode.choices) {
|
if (!this.activeNode.choices) {
|
||||||
narrativeManager.next();
|
this._isProcessingClick = true;
|
||||||
|
|
||||||
|
// Check if this is the last message
|
||||||
|
const isLastMessage = !this.activeNode.next || this.activeNode.next === "END";
|
||||||
|
|
||||||
|
if (isLastMessage) {
|
||||||
|
narrativeManager.endSequence();
|
||||||
|
} else {
|
||||||
|
narrativeManager.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset flag after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
this._isProcessingClick = false;
|
||||||
|
}, 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +198,40 @@ export class DialogueOverlay extends LitElement {
|
||||||
class="dialogue-box ${this.activeNode.type === "TUTORIAL"
|
class="dialogue-box ${this.activeNode.type === "TUTORIAL"
|
||||||
? "type-tutorial"
|
? "type-tutorial"
|
||||||
: ""}"
|
: ""}"
|
||||||
@click="${() => !this.activeNode.choices && narrativeManager.next()}"
|
@click="${(e) => {
|
||||||
|
// Prevent event bubbling and default behavior
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Prevent rapid clicks
|
||||||
|
if (this._isProcessingClick) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only advance on click if there are no choices
|
||||||
|
// Check if we're clicking on the content area (not buttons or other interactive elements)
|
||||||
|
const isContentClick = e.target.closest('.content') && !e.target.closest('button');
|
||||||
|
|
||||||
|
if (!this.activeNode.choices && isContentClick) {
|
||||||
|
this._isProcessingClick = true;
|
||||||
|
|
||||||
|
// Check if this is the last message (next === "END")
|
||||||
|
const isLastMessage = !this.activeNode.next || this.activeNode.next === "END";
|
||||||
|
|
||||||
|
if (isLastMessage) {
|
||||||
|
// For the last message, close the dialogue
|
||||||
|
narrativeManager.endSequence();
|
||||||
|
} else {
|
||||||
|
// For other messages, advance normally
|
||||||
|
narrativeManager.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset flag after a short delay to prevent double-clicks
|
||||||
|
setTimeout(() => {
|
||||||
|
this._isProcessingClick = false;
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}}"
|
||||||
>
|
>
|
||||||
${this.activeNode.portrait
|
${this.activeNode.portrait
|
||||||
? html`
|
? html`
|
||||||
|
|
@ -210,7 +266,9 @@ export class DialogueOverlay extends LitElement {
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: html`<div class="next-indicator">
|
: html`<div class="next-indicator">
|
||||||
Press SPACE to continue...
|
${!this.activeNode.next || this.activeNode.next === "END"
|
||||||
|
? "Press SPACE or click to close"
|
||||||
|
: "Press SPACE to continue..."}
|
||||||
</div>`}
|
</div>`}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -335,7 +335,12 @@ export class TeamBuilder extends LitElement {
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>${item.name}</strong><br>
|
<strong>${item.name}</strong><br>
|
||||||
<small>${this.mode === 'ROSTER' ? `Lvl ${item.level || 1} ${item.classId.replace('CLASS_', '')}` : item.role}</small>
|
<small>${this.mode === 'ROSTER' ? (() => {
|
||||||
|
// Calculate level from classMastery
|
||||||
|
const activeClassId = item.activeClassId || item.classId;
|
||||||
|
const level = item.classMastery?.[activeClassId]?.level || 1;
|
||||||
|
return `Lvl ${level} ${item.classId.replace('CLASS_', '')}`;
|
||||||
|
})() : item.role}</small>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ describe("Core: Persistence", () => {
|
||||||
|
|
||||||
await initPromise;
|
await initPromise;
|
||||||
|
|
||||||
expect(globalObj.indexedDB.open.calledWith("AetherShardsDB", 4)).to.be.true;
|
expect(globalObj.indexedDB.open.calledWith("AetherShardsDB", 6)).to.be.true;
|
||||||
expect(mockDB.createObjectStore.calledWith("Runs", { keyPath: "id" })).to.be
|
expect(mockDB.createObjectStore.calledWith("Runs", { keyPath: "id" })).to.be
|
||||||
.true;
|
.true;
|
||||||
expect(mockDB.createObjectStore.calledWith("Roster", { keyPath: "id" })).to
|
expect(mockDB.createObjectStore.calledWith("Roster", { keyPath: "id" })).to
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue