mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
122 lines
3.8 KiB
JavaScript
122 lines
3.8 KiB
JavaScript
|
|
/**
|
|||
|
|
* NPC Conversation State Manager
|
|||
|
|
*
|
|||
|
|
* Persists NPC conversation state (Ink variables, choices, progress) across multiple conversations.
|
|||
|
|
* Stores serialized story state so NPCs remember their relationships and story progression.
|
|||
|
|
*
|
|||
|
|
* @module npc-conversation-state
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
class NPCConversationStateManager {
|
|||
|
|
constructor() {
|
|||
|
|
this.conversationStates = new Map(); // { npcId: { storyState, variables, ... } }
|
|||
|
|
console.log('🗂️ NPC Conversation State Manager initialized');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Save the current state of an NPC's conversation
|
|||
|
|
* @param {string} npcId - NPC identifier
|
|||
|
|
* @param {Object} story - The Ink story object
|
|||
|
|
*/
|
|||
|
|
saveNPCState(npcId, story) {
|
|||
|
|
if (!npcId || !story) return;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// Serialize the story state (includes all variables and progress)
|
|||
|
|
// Use uppercase ToJson as per inkjs API
|
|||
|
|
const storyState = story.state.ToJson();
|
|||
|
|
|
|||
|
|
const state = {
|
|||
|
|
storyState: storyState,
|
|||
|
|
timestamp: Date.now()
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.conversationStates.set(npcId, state);
|
|||
|
|
console.log(`💾 Saved conversation state for NPC: ${npcId}`, {
|
|||
|
|
timestamp: new Date(state.timestamp).toLocaleTimeString()
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(`❌ Error saving NPC state for ${npcId}:`, error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Restore the state of an NPC's conversation
|
|||
|
|
* @param {string} npcId - NPC identifier
|
|||
|
|
* @param {Object} story - The Ink story object to restore into
|
|||
|
|
* @returns {boolean} True if state was restored
|
|||
|
|
*/
|
|||
|
|
restoreNPCState(npcId, story) {
|
|||
|
|
if (!npcId || !story) return false;
|
|||
|
|
|
|||
|
|
const state = this.conversationStates.get(npcId);
|
|||
|
|
if (!state) {
|
|||
|
|
console.log(`ℹ️ No saved state for NPC: ${npcId} (first conversation)`);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// Restore the serialized story state
|
|||
|
|
// Use uppercase LoadJson as per inkjs API
|
|||
|
|
story.state.LoadJson(state.storyState);
|
|||
|
|
|
|||
|
|
console.log(`✅ Restored conversation state for NPC: ${npcId}`, {
|
|||
|
|
savedAt: new Date(state.timestamp).toLocaleTimeString()
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(`❌ Error restoring NPC state for ${npcId}:`, error);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get the current state for an NPC (for debugging)
|
|||
|
|
* @param {string} npcId - NPC identifier
|
|||
|
|
* @returns {Object|null} Conversation state or null if not found
|
|||
|
|
*/
|
|||
|
|
getNPCState(npcId) {
|
|||
|
|
return this.conversationStates.get(npcId) || null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Clear the state for an NPC (useful for resetting conversations)
|
|||
|
|
* @param {string} npcId - NPC identifier
|
|||
|
|
*/
|
|||
|
|
clearNPCState(npcId) {
|
|||
|
|
if (this.conversationStates.has(npcId)) {
|
|||
|
|
this.conversationStates.delete(npcId);
|
|||
|
|
console.log(`🗑️ Cleared conversation state for NPC: ${npcId}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Clear all NPC states (useful for scenario reset)
|
|||
|
|
*/
|
|||
|
|
clearAllStates() {
|
|||
|
|
const count = this.conversationStates.size;
|
|||
|
|
this.conversationStates.clear();
|
|||
|
|
console.log(`🗑️ Cleared all NPC conversation states (${count} NPCs)`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Get list of NPCs with saved state
|
|||
|
|
* @returns {Array<string>} Array of NPC IDs with persistent state
|
|||
|
|
*/
|
|||
|
|
getSavedNPCs() {
|
|||
|
|
return Array.from(this.conversationStates.keys());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Create global instance
|
|||
|
|
const npcConversationStateManager = new NPCConversationStateManager();
|
|||
|
|
|
|||
|
|
// Export for use in modules
|
|||
|
|
export default npcConversationStateManager;
|
|||
|
|
|
|||
|
|
// Also attach to window for global access
|
|||
|
|
if (typeof window !== 'undefined') {
|
|||
|
|
window.npcConversationStateManager = npcConversationStateManager;
|
|||
|
|
}
|