From 85b620cfcd1f88464f195e9aaf0c5b7334188b56 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Wed, 19 Nov 2025 13:44:30 +0000 Subject: [PATCH] feat: Add automatic conversation closing for graceful #end_conversation tag Implemented proper handling for the #end_conversation tag to automatically close the conversation UI without requiring manual ESC key press. Changes: 1. Added event listener for 'npc-conversation-ended' event in setupEventListeners() - Saves NPC state when event is received - Automatically ends minigame and returns to game - Verifies event is for current NPC 2. Updated showCurrentDialogue() to detect graceful conversation endings - Checks for #end_conversation tag when story reaches hasEnded - If tag present, waits for event handler instead of showing manual exit message - Preserves manual exit message for unexpected/error END states Flow: - Ink script: #end_conversation -> DONE - PhoneChatConversation processes tag and dispatches npc-conversation-ended event - PersonChatMinigame receives event and automatically closes - Player sees smooth transition back to game This eliminates the "(End of conversation - press ESC to exit)" message for normal conversation endings while preserving it as a safety fallback. --- .../person-chat/person-chat-minigame.js | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/js/minigames/person-chat/person-chat-minigame.js b/js/minigames/person-chat/person-chat-minigame.js index 40082ee..b778fc9 100644 --- a/js/minigames/person-chat/person-chat-minigame.js +++ b/js/minigames/person-chat/person-chat-minigame.js @@ -192,7 +192,7 @@ export class PersonChatMinigame extends MinigameScene { this.handleChoice(choiceIndex); } }); - + // Continue button click handler if (this.ui.elements.continueButton) { this.addEventListener(this.ui.elements.continueButton, 'click', (e) => { @@ -201,6 +201,26 @@ export class PersonChatMinigame extends MinigameScene { this.handleContinueButtonClick(); }); } + + // Listen for conversation end event from the conversation handler + this.addEventListener(window, 'npc-conversation-ended', (e) => { + console.log(`👋 Received npc-conversation-ended event for ${e.detail.npcId}`); + + // Verify this event is for our current conversation + if (e.detail.npcId === this.npcId) { + console.log(`✅ Ending minigame - conversation state preserved at mission_hub`); + + // Save state before exiting + if (this.inkEngine && this.inkEngine.story) { + npcConversationStateManager.saveNPCState(this.npcId, this.inkEngine.story); + } + + // End the minigame and return to game + if (window.MinigameFramework) { + window.MinigameFramework.endMinigame(true, { conversationEnded: true }); + } + } + }); } /** @@ -368,17 +388,28 @@ export class PersonChatMinigame extends MinigameScene { */ showCurrentDialogue() { if (!this.conversation) return; - + try { // Get current content without advancing const result = this.conversation.continue(); - + // Store result for later use this.lastResult = result; - + // Check if story has ended if (result.hasEnded) { - // Story reached an END - save state and show message + // Check if this is a graceful conversation end (with #end_conversation tag) + const hasEndConversationTag = result.tags?.some(tag => + tag.trim().toLowerCase() === 'end_conversation' + ); + + if (hasEndConversationTag) { + // Graceful end - the npc-conversation-ended event will handle closing + console.log('👋 Graceful conversation end detected - waiting for event handler'); + return; + } + + // Otherwise, it's an unexpected END - save state and show manual exit message // Player should press ESC to exit and return to hub if (this.inkEngine && this.inkEngine.story) { npcConversationStateManager.saveNPCState(this.npcId, this.inkEngine.story);