mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 11:18:08 +00:00
feat: Improve NPC dialogue and objectives handling with global variable synchronization and task unlocking
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
/* Raised so minigames appear above other UI (inventory, NPC barks, HUD, etc.) */
|
||||
z-index: 11000;
|
||||
z-index: 1500;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
@@ -382,6 +382,20 @@ export class PersonChatMinigame extends MinigameScene {
|
||||
npcConversationStateManager.syncGlobalVariablesToStory(this.inkEngine.story);
|
||||
// Also sync inventory-based variables on initial load
|
||||
npcConversationStateManager.syncInventoryVariablesToStory(this.inkEngine.story, this.npc);
|
||||
|
||||
// CRITICAL: If we're at a choice point after restoring state, the choices were
|
||||
// evaluated with OLD global variable values. We need to re-navigate to the
|
||||
// current position to force Ink to re-evaluate choices with updated globals.
|
||||
// The hub pattern means choices depend on global state (e.g., alice_talked).
|
||||
const story = this.inkEngine.story;
|
||||
if (story.currentChoices && story.currentChoices.length > 0) {
|
||||
// Get current path and re-navigate to it
|
||||
const currentPath = story.state.currentPathString;
|
||||
if (currentPath) {
|
||||
console.log(`🔄 Re-navigating to ${currentPath} to re-evaluate choices with updated globals`);
|
||||
story.ChoosePathString(currentPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -479,19 +493,10 @@ export class PersonChatMinigame extends MinigameScene {
|
||||
console.log(`📋 No text, just showing choices`);
|
||||
}
|
||||
} else if (result.text && result.text.trim()) {
|
||||
// Have text but no choices - display and continue
|
||||
console.log(`🗣️ Calling showDialogue with speaker: ${speaker}`);
|
||||
this.ui.showDialogue(result.text, speaker);
|
||||
|
||||
if (result.canContinue) {
|
||||
// Can continue - schedule next advance
|
||||
console.log(`📋 Setting pendingContinueCallback - canContinue: true, no choices`);
|
||||
this.scheduleDialogueAdvance(() => this.showCurrentDialogue(), DIALOGUE_AUTO_ADVANCE_DELAY);
|
||||
} else {
|
||||
// Can't continue but have text - story will end
|
||||
console.log('✓ Waiting for story to end...');
|
||||
this.scheduleDialogueAdvance(() => this.endConversation(), DIALOGUE_END_DELAY);
|
||||
}
|
||||
// Have text but no choices - use displayAccumulatedDialogue for proper speaker parsing
|
||||
// This ensures line prefix format (Speaker: text) is handled correctly
|
||||
console.log(`🗣️ Single line dialogue without choices - using block display for speaker parsing`);
|
||||
this.displayAccumulatedDialogue(result);
|
||||
} else {
|
||||
// No text and no choices - story has ended
|
||||
console.log('🏁 No text and no choices - story ended');
|
||||
@@ -826,8 +831,29 @@ export class PersonChatMinigame extends MinigameScene {
|
||||
this.isProcessingDialogue = true;
|
||||
|
||||
try {
|
||||
if (!result.text || !result.tags) {
|
||||
// No content to display
|
||||
// Process any game action tags (give_item, unlock_door, exit_conversation, etc.) FIRST
|
||||
// This ensures tags are processed even if there's no visible text
|
||||
if (result.tags && result.tags.length > 0) {
|
||||
console.log('🏷️ Processing action tags from accumulated dialogue:', result.tags);
|
||||
processGameActionTags(result.tags, this.ui);
|
||||
|
||||
// Check for exit_conversation tag - close the minigame
|
||||
const shouldExit = result.tags.some(tag => tag.includes('exit_conversation'));
|
||||
if (shouldExit) {
|
||||
console.log('🚪 Exit conversation tag detected in displayAccumulatedDialogue - closing minigame');
|
||||
// Final state save before closing
|
||||
if (this.inkEngine && this.inkEngine.story) {
|
||||
npcConversationStateManager.saveNPCState(this.npcId, this.inkEngine.story);
|
||||
}
|
||||
this.scheduleDialogueAdvance(() => {
|
||||
this.complete(true);
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.text) {
|
||||
// No text content to display
|
||||
if (result.hasEnded) {
|
||||
// Story ended - save state and show message
|
||||
if (this.inkEngine && this.inkEngine.story) {
|
||||
@@ -835,22 +861,23 @@ export class PersonChatMinigame extends MinigameScene {
|
||||
}
|
||||
this.ui.showDialogue('(Conversation ended - press ESC to close)', 'system');
|
||||
console.log('🏁 Story has reached an end point');
|
||||
} else if (result.canContinue) {
|
||||
// No text but more content available - get next line
|
||||
console.log('📖 No text in result, getting next line...');
|
||||
const nextLine = this.conversation.continue();
|
||||
this.lastResult = nextLine;
|
||||
this.displayAccumulatedDialogue(nextLine);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Process any game action tags (give_item, unlock_door, etc.) BEFORE displaying dialogue
|
||||
if (result.tags && result.tags.length > 0) {
|
||||
console.log('🏷️ Processing action tags from accumulated dialogue:', result.tags);
|
||||
processGameActionTags(result.tags, this.ui);
|
||||
}
|
||||
|
||||
// Split text into lines
|
||||
const lines = result.text.split('\n').filter(line => line.trim());
|
||||
|
||||
// We have lines and tags - pair them up
|
||||
// Each tag corresponds to a line (or group of lines before the next tag)
|
||||
if (lines.length === 0) {
|
||||
// Text was only whitespace - tags already processed above
|
||||
if (result.hasEnded) {
|
||||
// Story ended - save state and show message
|
||||
if (this.inkEngine && this.inkEngine.story) {
|
||||
@@ -858,6 +885,16 @@ export class PersonChatMinigame extends MinigameScene {
|
||||
}
|
||||
this.ui.showDialogue('(Conversation ended - press ESC to close)', 'system');
|
||||
console.log('🏁 Story has reached an end point');
|
||||
} else if (result.canContinue) {
|
||||
// No visible text but more content available - get next line
|
||||
console.log('📖 No visible lines, getting next line...');
|
||||
const nextLine = this.conversation.continue();
|
||||
this.lastResult = nextLine;
|
||||
this.displayAccumulatedDialogue(nextLine);
|
||||
} else if (result.choices && result.choices.length > 0) {
|
||||
// Choices available
|
||||
console.log(`📋 No visible lines, showing ${result.choices.length} choices`);
|
||||
this.ui.showChoices(result.choices);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -935,6 +972,7 @@ export class PersonChatMinigame extends MinigameScene {
|
||||
|
||||
// Try to parse line prefix format
|
||||
const parsed = this.parseDialogueLine(line);
|
||||
console.log(`🔍 parseDialogueLine("${line.substring(0, 50)}...") =>`, parsed);
|
||||
|
||||
if (parsed) {
|
||||
// This line has a prefix - speaker changed!
|
||||
@@ -1012,29 +1050,37 @@ export class PersonChatMinigame extends MinigameScene {
|
||||
this.lastResult = originalResult;
|
||||
this.ui.showChoices(originalResult.choices);
|
||||
} else {
|
||||
// Try to continue for more dialogue
|
||||
console.log('⏸️ Blocks finished, checking for more dialogue...');
|
||||
this.scheduleDialogueAdvance(() => {
|
||||
const nextLine = this.conversation.continue();
|
||||
|
||||
// Store for choice handling
|
||||
this.lastResult = nextLine;
|
||||
|
||||
if (nextLine.text && nextLine.text.trim()) {
|
||||
this.displayAccumulatedDialogue(nextLine);
|
||||
} else if (nextLine.choices && nextLine.choices.length > 0) {
|
||||
// Back to choices - display them
|
||||
console.log(`📋 Back to choices: ${nextLine.choices.length} options available`);
|
||||
this.ui.showChoices(nextLine.choices);
|
||||
} else if (nextLine.hasEnded) {
|
||||
// Story ended - save state and show message
|
||||
if (this.inkEngine && this.inkEngine.story) {
|
||||
npcConversationStateManager.saveNPCState(this.npcId, this.inkEngine.story);
|
||||
}
|
||||
this.ui.showDialogue('(Conversation ended - press ESC to close)', 'system');
|
||||
console.log('🏁 Story has reached an end point');
|
||||
// More dialogue available - get next line immediately (no extra click needed)
|
||||
// The user already clicked to see the last line of current block
|
||||
console.log('⏸️ Blocks finished, getting next line immediately...');
|
||||
const nextLine = this.conversation.continue();
|
||||
|
||||
// Store for choice handling
|
||||
this.lastResult = nextLine;
|
||||
|
||||
// Check for exit_conversation tag FIRST (may come with empty text)
|
||||
if (nextLine.tags && nextLine.tags.some(tag => tag.includes('exit_conversation'))) {
|
||||
console.log('🚪 Exit conversation tag detected after blocks - closing minigame');
|
||||
if (this.inkEngine && this.inkEngine.story) {
|
||||
npcConversationStateManager.saveNPCState(this.npcId, this.inkEngine.story);
|
||||
}
|
||||
}, DIALOGUE_AUTO_ADVANCE_DELAY);
|
||||
this.scheduleDialogueAdvance(() => {
|
||||
this.complete(true);
|
||||
}, 1000);
|
||||
} else if (nextLine.text && nextLine.text.trim()) {
|
||||
this.displayAccumulatedDialogue(nextLine);
|
||||
} else if (nextLine.choices && nextLine.choices.length > 0) {
|
||||
// Back to choices - display them
|
||||
console.log(`📋 Back to choices: ${nextLine.choices.length} options available`);
|
||||
this.ui.showChoices(nextLine.choices);
|
||||
} else if (nextLine.hasEnded) {
|
||||
// Story ended - save state and show message
|
||||
if (this.inkEngine && this.inkEngine.story) {
|
||||
npcConversationStateManager.saveNPCState(this.npcId, this.inkEngine.story);
|
||||
}
|
||||
this.ui.showDialogue('(Conversation ended - press ESC to close)', 'system');
|
||||
console.log('🏁 Story has reached an end point');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,15 @@ export default class PhoneChatConversation {
|
||||
window.eventDispatcher.on('npc_items_changed', this._itemsChangedListener);
|
||||
}
|
||||
|
||||
// Set up global variable observer to sync changes back to window.gameState
|
||||
// This is critical for cross-NPC variable sharing
|
||||
if (window.npcConversationStateManager && this.engine.story) {
|
||||
window.npcConversationStateManager.discoverGlobalVariables(this.engine.story);
|
||||
window.npcConversationStateManager.syncGlobalVariablesToStory(this.engine.story);
|
||||
window.npcConversationStateManager.observeGlobalVariableChanges(this.engine.story, this.npcId);
|
||||
console.log(`🌐 Global variable observer set up for ${this.npcId}`);
|
||||
}
|
||||
|
||||
console.log(`✅ Story loaded successfully for ${this.npcId}`);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -24,7 +24,10 @@ export default class InkEngine {
|
||||
return this.story;
|
||||
}
|
||||
|
||||
// Continue the story and return the current text plus state
|
||||
// Continue the story and return ONE line of visible text plus state
|
||||
// BEHAVIOR: Skips empty/whitespace lines, accumulates their tags, returns first line with content.
|
||||
// This ensures tags are processed with their specific line of dialogue.
|
||||
// The caller will see canContinue=true and call continue() again for more.
|
||||
continue() {
|
||||
if (!this.story) throw new Error('Story not loaded');
|
||||
|
||||
@@ -35,22 +38,27 @@ export default class InkEngine {
|
||||
console.log('🔍 InkEngine.continue() - canContinue:', this.story.canContinue);
|
||||
console.log('🔍 InkEngine.continue() - currentChoices before:', this.story.currentChoices?.length);
|
||||
|
||||
// Continue until we hit choices or end
|
||||
// Note: We gather all text until the next choice point or end
|
||||
// Get lines until we have visible text (or hit choices/end)
|
||||
while (this.story.canContinue) {
|
||||
const newText = this.story.Continue();
|
||||
console.log('🔍 InkEngine.continue() - got text:', newText);
|
||||
text += newText;
|
||||
const lineText = this.story.Continue();
|
||||
const lineTags = this.story.currentTags || [];
|
||||
|
||||
// Collect tags from this passage
|
||||
if (this.story.currentTags && this.story.currentTags.length > 0) {
|
||||
console.log('🏷️ InkEngine.continue() - found tags:', this.story.currentTags);
|
||||
tags = tags.concat(this.story.currentTags);
|
||||
// Always accumulate tags
|
||||
if (lineTags.length > 0) {
|
||||
console.log('🏷️ InkEngine.continue() - found tags:', lineTags);
|
||||
tags = tags.concat(lineTags);
|
||||
}
|
||||
|
||||
// Check if this line has visible content
|
||||
if (lineText.trim()) {
|
||||
text = lineText;
|
||||
console.log('🔍 InkEngine.continue() - got text:', text);
|
||||
break; // Stop - we have a line to show
|
||||
} else {
|
||||
console.log('🔍 InkEngine.continue() - skipping empty line, continuing...');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🔍 InkEngine.continue() - accumulated text:', text);
|
||||
console.log('🏷️ InkEngine.continue() - accumulated tags:', tags);
|
||||
console.log('🔍 InkEngine.continue() - canContinue after:', this.story.canContinue);
|
||||
console.log('🔍 InkEngine.continue() - currentChoices after:', this.story.currentChoices?.length);
|
||||
console.log('🔍 InkEngine.continue() - hasEnded:', this.story.hasEnded);
|
||||
|
||||
@@ -42,6 +42,7 @@ Great to meet you too! This task is now complete.
|
||||
#complete_task:talk_to_alice
|
||||
~ alice_talked = true
|
||||
You should go talk to Bob next - I just unlocked that task for you.
|
||||
#exit_conversation
|
||||
-> hub
|
||||
|
||||
=== explain_objectives ===
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"inkVersion":21,"root":[[["done",{"#n":"g-0"}],null],"done",{"start":["^Hey there! I'm Alice. Welcome to the objectives system test.","\n","^Player: Hi there!","\n",{"->":"hub"},null],"hub":[["ev","str","^Nice to meet you, Alice","/str",{"VAR?":"alice_talked"},"!","/ev",{"*":".^.c-0","flg":5},"ev","str","^Tell me about the secret mission","/str",{"VAR?":"alice_talked"},{"VAR?":"secret_revealed"},"!","&&","/ev",{"*":".^.c-1","flg":5},"ev","str","^I'm ready for the secret task","/str",{"VAR?":"secret_revealed"},{"VAR?":"secret_task_done"},"!","&&","/ev",{"*":".^.c-2","flg":5},"ev","str","^Any final words?","/str",{"VAR?":"secret_task_done"},"/ev",{"*":".^.c-3","flg":5},"ev","str","^What can you tell me about objectives?","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^I need to go","/str","/ev",{"*":".^.c-5","flg":4},{"c-0":["\n",{"->":"first_meeting"},null],"c-1":["\n",{"->":"reveal_secret"},null],"c-2":["\n",{"->":"complete_secret_task"},null],"c-3":["\n",{"->":"final_words"},null],"c-4":["\n",{"->":"explain_objectives"},null],"c-5":["^ ","\n","^See you around!","\n","#","^exit_conversation","/#",{"->":"hub"},null]}],null],"first_meeting":["^Great to meet you too! This task is now complete.","\n","#","^complete_task:talk_to_alice","/#","ev",true,"/ev",{"VAR=":"alice_talked","re":true},"^You should go talk to Bob next - I just unlocked that task for you.","\n",{"->":"hub"},null],"explain_objectives":["^The objectives system uses three Ink tags:","\n",{"->":"explain_objectives_detail"},null],"explain_objectives_detail":[["ev","str","^Tell me about complete_task","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Tell me about unlock_task","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Tell me about unlock_aim","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^That's enough info, thanks","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","^NPC: **complete_task:task_id** marks a task as completed. The ObjectivesManager will update the UI and sync with the server.","\n",{"->":".^.^.^"},null],"c-1":["\n","^NPC: **unlock_task:task_id** unlocks a locked task so it becomes active and visible.","\n",{"->":".^.^.^"},null],"c-2":["\n","^NPC: **unlock_aim:aim_id** unlocks an entire aim (objective group) that was previously locked.","\n",{"->":".^.^.^"},null],"c-3":["\n","^NPC: These tags let NPCs control the player's objectives through dialogue!","\n",{"->":"hub"},null]}],null],"reveal_secret":["^Alright, I'll let you in on a secret...","\n","^There's a hidden mission that only unlocks through dialogue!","\n","#","^unlock_aim:secret_mission","/#","ev",true,"/ev",{"VAR=":"secret_revealed","re":true},"^I've just unlocked the \"Secret Mission\" aim for you. Check your objectives!","\n","^But the tasks inside are still locked. Let me unlock the first one...","\n","#","^unlock_task:secret_task_1","/#","^There! Now you can complete the first secret task.","\n",{"->":"hub"},null],"complete_secret_task":["^Excellent! You're doing great with the secret mission.","\n","#","^complete_task:secret_task_1","/#","ev",true,"/ev",{"VAR=":"secret_task_done","re":true},"^That's one secret task down! Bob can help you with the second one.","\n",{"->":"hub"},null],"final_words":["^You've done great! Once Bob helps you finish, come back for the final debrief.","\n",{"->":"hub"},null],"final_debrief":[["^NPC: *Alice looks up as you approach*","\n","^Narrator: Alice gives you a knowing smile.","\n","^Bob: You did it! The secret mission is complete.","\n","^NPC: I just received confirmation from headquarters.","\n","#","^complete_task:final_debrief","/#","^NPC: Mission accomplished, agent. You've proven yourself.","\n","^NPC: The objectives system test is now complete. Well done!","\n","ev","str","^Thank you, Alice","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^What's next?","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n","^NPC: Anytime. See you on the next mission.","\n","#","^exit_conversation","/#",{"->":"hub"},null],"c-1":["\n","^NPC: Take a break. You've earned it.","\n","^NPC: When you're ready, there will be more missions waiting.","\n","#","^exit_conversation","/#",{"->":"hub"},null]}],null],"global decl":["ev",false,{"VAR=":"alice_talked"},false,{"VAR=":"secret_revealed"},false,{"VAR=":"secret_task_done"},"/ev","end",null]}],"listDefs":{}}
|
||||
{"inkVersion":21,"root":[[["done",{"#n":"g-0"}],null],"done",{"start":["^Hey there! I'm Alice. Welcome to the objectives system test.","\n","^Player: Hi there!","\n",{"->":"hub"},null],"hub":[["ev","str","^Nice to meet you, Alice","/str",{"VAR?":"alice_talked"},"!","/ev",{"*":".^.c-0","flg":5},"ev","str","^Tell me about the secret mission","/str",{"VAR?":"alice_talked"},{"VAR?":"secret_revealed"},"!","&&","/ev",{"*":".^.c-1","flg":5},"ev","str","^I'm ready for the secret task","/str",{"VAR?":"secret_revealed"},{"VAR?":"secret_task_done"},"!","&&","/ev",{"*":".^.c-2","flg":5},"ev","str","^Any final words?","/str",{"VAR?":"secret_task_done"},"/ev",{"*":".^.c-3","flg":5},"ev","str","^What can you tell me about objectives?","/str","/ev",{"*":".^.c-4","flg":4},"ev","str","^I need to go","/str","/ev",{"*":".^.c-5","flg":4},{"c-0":["\n",{"->":"first_meeting"},null],"c-1":["\n",{"->":"reveal_secret"},null],"c-2":["\n",{"->":"complete_secret_task"},null],"c-3":["\n",{"->":"final_words"},null],"c-4":["\n",{"->":"explain_objectives"},null],"c-5":["^ ","\n","^See you around!","\n","#","^exit_conversation","/#",{"->":"hub"},null]}],null],"first_meeting":["^Great to meet you too! This task is now complete.","\n","#","^complete_task:talk_to_alice","/#","ev",true,"/ev",{"VAR=":"alice_talked","re":true},"^You should go talk to Bob next - I just unlocked that task for you.","\n","#","^exit_conversation","/#",{"->":"hub"},null],"explain_objectives":["^The objectives system uses three Ink tags:","\n",{"->":"explain_objectives_detail"},null],"explain_objectives_detail":[["ev","str","^Tell me about complete_task","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^Tell me about unlock_task","/str","/ev",{"*":".^.c-1","flg":4},"ev","str","^Tell me about unlock_aim","/str","/ev",{"*":".^.c-2","flg":4},"ev","str","^That's enough info, thanks","/str","/ev",{"*":".^.c-3","flg":4},{"c-0":["\n","^NPC: **complete_task:task_id** marks a task as completed. The ObjectivesManager will update the UI and sync with the server.","\n",{"->":".^.^.^"},null],"c-1":["\n","^NPC: **unlock_task:task_id** unlocks a locked task so it becomes active and visible.","\n",{"->":".^.^.^"},null],"c-2":["\n","^NPC: **unlock_aim:aim_id** unlocks an entire aim (objective group) that was previously locked.","\n",{"->":".^.^.^"},null],"c-3":["\n","^NPC: These tags let NPCs control the player's objectives through dialogue!","\n",{"->":"hub"},null]}],null],"reveal_secret":["^Alright, I'll let you in on a secret...","\n","^There's a hidden mission that only unlocks through dialogue!","\n","#","^unlock_aim:secret_mission","/#","ev",true,"/ev",{"VAR=":"secret_revealed","re":true},"^I've just unlocked the \"Secret Mission\" aim for you. Check your objectives!","\n","^But the tasks inside are still locked. Let me unlock the first one...","\n","#","^unlock_task:secret_task_1","/#","^There! Now you can complete the first secret task.","\n",{"->":"hub"},null],"complete_secret_task":["^Excellent! You're doing great with the secret mission.","\n","#","^complete_task:secret_task_1","/#","ev",true,"/ev",{"VAR=":"secret_task_done","re":true},"^That's one secret task down! Bob can help you with the second one.","\n",{"->":"hub"},null],"final_words":["^You've done great! Once Bob helps you finish, come back for the final debrief.","\n",{"->":"hub"},null],"final_debrief":[["^NPC: *Alice looks up as you approach*","\n","^Narrator: Alice gives you a knowing smile.","\n","^Bob: You did it! The secret mission is complete.","\n","^NPC: I just received confirmation from headquarters.","\n","#","^complete_task:final_debrief","/#","^NPC: Mission accomplished, agent. You've proven yourself.","\n","^NPC: The objectives system test is now complete. Well done!","\n","ev","str","^Thank you, Alice","/str","/ev",{"*":".^.c-0","flg":4},"ev","str","^What's next?","/str","/ev",{"*":".^.c-1","flg":4},{"c-0":["\n","^NPC: Anytime. See you on the next mission.","\n","#","^exit_conversation","/#",{"->":"hub"},null],"c-1":["\n","^NPC: Take a break. You've earned it.","\n","^NPC: When you're ready, there will be more missions waiting.","\n","#","^exit_conversation","/#",{"->":"hub"},null]}],null],"global decl":["ev",false,{"VAR=":"alice_talked"},false,{"VAR=":"secret_revealed"},false,{"VAR=":"secret_task_done"},"/ev","end",null]}],"listDefs":{}}
|
||||
@@ -51,11 +51,11 @@ Speaking of which... if there are any locked tasks you need help with, just ask.
|
||||
=== secret_task_help ===
|
||||
The secret task, eh? Let me help you with that.
|
||||
#unlock_task:secret_task_2
|
||||
#unlock_aim:finale
|
||||
#complete_task:secret_task_2
|
||||
~ helped_with_secret = true
|
||||
Done! Both secret tasks are now complete.
|
||||
That means the secret aim should be finished too.
|
||||
#unlock_aim:finale
|
||||
#unlock_task:final_debrief
|
||||
I've also unlocked the finale for you. Go talk to Alice for the final debrief!
|
||||
-> hub
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"inkVersion":21,"root":[[["done",{"#n":"g-0"}],null],"done",{"start":["^Narrator: You see a hooded figure waiting for you.","\n","^NPC: Oh, hey. I'm Bob.","\n",{"->":"hub"},null],"hub":[["ev","str","^Alice sent me to talk to you","/str",{"VAR?":"alice_talked"},{"VAR?":"bob_talked"},"!","&&","/ev",{"*":".^.c-0","flg":5},"ev","str","^Can you help with the secret task?","/str",{"VAR?":"bob_talked"},{"VAR?":"secret_revealed"},"&&",{"VAR?":"helped_with_secret"},"!","&&","/ev",{"*":".^.c-1","flg":5},"ev","str","^Thanks for the help!","/str",{"VAR?":"helped_with_secret"},"/ev",{"*":".^.c-2","flg":5},"ev","str","^What do you do here?","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Goodbye","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["\n",{"->":"first_meeting"},null],"c-1":["\n",{"->":"secret_task_help"},null],"c-2":["\n",{"->":"thanks_response"},null],"c-3":["\n",{"->":"about_bob"},null],"c-4":["\n","^Later.","\n","#","^exit_conversation","/#",{"->":"hub"},null]}],null],"first_meeting":["^Ah, Alice sent you? Good, good.","\n","#","^complete_task:talk_to_bob","/#","ev",true,"/ev",{"VAR=":"bob_talked","re":true},"^I've just marked that task complete.","\n","^If Alice told you about anything... special... come back and ask me.","\n",{"->":"hub"},null],"about_bob":["^I handle the technical side of things.","\n","^Mostly just unlocking things that need to be unlocked.","\n","^Speaking of which... if there are any locked tasks you need help with, just ask.","\n",{"->":"hub"},null],"secret_task_help":["^The secret task, eh? Let me help you with that.","\n","#","^unlock_task:secret_task_2","/#","#","^complete_task:secret_task_2","/#","ev",true,"/ev",{"VAR=":"helped_with_secret","re":true},"^Done! Both secret tasks are now complete.","\n","^That means the secret aim should be finished too.","\n","#","^unlock_aim:finale","/#","#","^unlock_task:final_debrief","/#","^I've also unlocked the finale for you. Go talk to Alice for the final debrief!","\n",{"->":"hub"},null],"thanks_response":["^No problem! Go see Alice for the final debrief. She's waiting for you.","\n",{"->":"hub"},null],"global decl":["ev",false,{"VAR=":"alice_talked"},false,{"VAR=":"bob_talked"},false,{"VAR=":"helped_with_secret"},false,{"VAR=":"secret_revealed"},"/ev","end",null]}],"listDefs":{}}
|
||||
{"inkVersion":21,"root":[[["done",{"#n":"g-0"}],null],"done",{"start":["^Narrator: You see a hooded figure waiting for you.","\n","^NPC: Oh, hey. I'm Bob.","\n",{"->":"hub"},null],"hub":[["ev","str","^Alice sent me to talk to you","/str",{"VAR?":"alice_talked"},{"VAR?":"bob_talked"},"!","&&","/ev",{"*":".^.c-0","flg":5},"ev","str","^Can you help with the secret task?","/str",{"VAR?":"bob_talked"},{"VAR?":"secret_revealed"},"&&",{"VAR?":"helped_with_secret"},"!","&&","/ev",{"*":".^.c-1","flg":5},"ev","str","^Thanks for the help!","/str",{"VAR?":"helped_with_secret"},"/ev",{"*":".^.c-2","flg":5},"ev","str","^What do you do here?","/str","/ev",{"*":".^.c-3","flg":4},"ev","str","^Goodbye","/str","/ev",{"*":".^.c-4","flg":4},{"c-0":["\n",{"->":"first_meeting"},null],"c-1":["\n",{"->":"secret_task_help"},null],"c-2":["\n",{"->":"thanks_response"},null],"c-3":["\n",{"->":"about_bob"},null],"c-4":["\n","^Later.","\n","#","^exit_conversation","/#",{"->":"hub"},null]}],null],"first_meeting":["^Ah, Alice sent you? Good, good.","\n","#","^complete_task:talk_to_bob","/#","ev",true,"/ev",{"VAR=":"bob_talked","re":true},"^I've just marked that task complete.","\n","^If Alice told you about anything... special... come back and ask me.","\n",{"->":"hub"},null],"about_bob":["^I handle the technical side of things.","\n","^Mostly just unlocking things that need to be unlocked.","\n","^Speaking of which... if there are any locked tasks you need help with, just ask.","\n",{"->":"hub"},null],"secret_task_help":["^The secret task, eh? Let me help you with that.","\n","#","^unlock_task:secret_task_2","/#","#","^unlock_aim:finale","/#","#","^complete_task:secret_task_2","/#","ev",true,"/ev",{"VAR=":"helped_with_secret","re":true},"^Done! Both secret tasks are now complete.","\n","^That means the secret aim should be finished too.","\n","#","^unlock_task:final_debrief","/#","^I've also unlocked the finale for you. Go talk to Alice for the final debrief!","\n",{"->":"hub"},null],"thanks_response":["^No problem! Go see Alice for the final debrief. She's waiting for you.","\n",{"->":"hub"},null],"global decl":["ev",false,{"VAR=":"alice_talked"},false,{"VAR=":"bob_talked"},false,{"VAR=":"helped_with_secret"},false,{"VAR=":"secret_revealed"},"/ev","end",null]}],"listDefs":{}}
|
||||
Reference in New Issue
Block a user