From 9229df8bc833aa93ec6c34549aada5b17e43d487 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Sat, 8 Nov 2025 22:35:31 +0000 Subject: [PATCH] Enhance phone chat functionality by adding NPC filtering; update related systems to support allowed NPCs in conversations and inventory management --- .../phone-chat/phone-chat-minigame.js | 21 +++++++++++++---- js/minigames/phone-chat/phone-chat-ui.js | 13 +++++++++-- js/systems/interactions.js | 3 ++- js/systems/inventory.js | 23 +++++++++++++------ js/systems/npc-manager.js | 10 ++++++-- scenarios/npc-sprite-test2.json | 11 ++++++++- 6 files changed, 64 insertions(+), 17 deletions(-) diff --git a/js/minigames/phone-chat/phone-chat-minigame.js b/js/minigames/phone-chat/phone-chat-minigame.js index fb6f2b1..d60370a 100644 --- a/js/minigames/phone-chat/phone-chat-minigame.js +++ b/js/minigames/phone-chat/phone-chat-minigame.js @@ -53,11 +53,13 @@ export class PhoneChatMinigame extends MinigameScene { // State this.currentNPCId = safeParams.npcId || null; this.phoneId = safeParams.phoneId || 'player_phone'; + this.allowedNpcIds = safeParams.npcIds || null; // Filter contacts to only these NPCs if provided this.isConversationActive = false; console.log('📱 PhoneChatMinigame created', { npcId: this.currentNPCId, - phoneId: this.phoneId + phoneId: this.phoneId, + allowedNpcIds: this.allowedNpcIds }); } @@ -83,7 +85,7 @@ export class PhoneChatMinigame extends MinigameScene { `; // Initialize UI - this.ui = new PhoneChatUI(this.gameContainer, safeParams, this.npcManager); + this.ui = new PhoneChatUI(this.gameContainer, safeParams, this.npcManager, this.allowedNpcIds); this.ui.render(); // Add notebook button to minigame controls (before close button) @@ -226,10 +228,16 @@ export class PhoneChatMinigame extends MinigameScene { */ async preloadIntroMessages() { // Get all NPCs for this phone - const npcs = this.phoneId + let npcs = this.phoneId ? this.npcManager.getNPCsByPhone(this.phoneId) : Array.from(this.npcManager.npcs.values()); + // Filter to only allowed NPCs if npcIds was specified + if (this.allowedNpcIds && this.allowedNpcIds.length > 0) { + console.log(`🔍 Filtering NPCs for preload: allowed = ${this.allowedNpcIds.join(', ')}`); + npcs = npcs.filter(npc => this.allowedNpcIds.includes(npc.id)); + } + console.log('📱 Preloading intro messages for phone:', this.phoneId); console.log('📱 Found NPCs:', npcs.length, npcs.map(n => n.displayName)); console.log('📱 All registered NPCs:', Array.from(this.npcManager.npcs.values()).map(n => ({ id: n.id, phoneId: n.phoneId, displayName: n.displayName }))); @@ -580,7 +588,12 @@ export class PhoneChatMinigame extends MinigameScene { } // Get all NPCs for this phone - const npcs = this.npcManager.getNPCsByPhone(this.phoneId); + let npcs = this.npcManager.getNPCsByPhone(this.phoneId); + + // Filter to only allowed NPCs if specified + if (this.allowedNpcIds && this.allowedNpcIds.length > 0) { + npcs = npcs.filter(npc => this.allowedNpcIds.includes(npc.id)); + } if (!npcs || npcs.length === 0) { console.warn('No contacts to save'); diff --git a/js/minigames/phone-chat/phone-chat-ui.js b/js/minigames/phone-chat/phone-chat-ui.js index 2fc8eae..26a6d31 100644 --- a/js/minigames/phone-chat/phone-chat-ui.js +++ b/js/minigames/phone-chat/phone-chat-ui.js @@ -13,8 +13,9 @@ export default class PhoneChatUI { * @param {HTMLElement} container - Container element for the UI * @param {Object} params - Configuration parameters * @param {Object} npcManager - NPCManager instance + * @param {Array} allowedNpcIds - Optional array of NPC IDs to show (filters contact list) */ - constructor(container, params, npcManager) { + constructor(container, params, npcManager, allowedNpcIds = null) { if (!container) { throw new Error('PhoneChatUI requires a container element'); } @@ -22,6 +23,7 @@ export default class PhoneChatUI { this.container = container; this.params = params || {}; this.npcManager = npcManager; + this.allowedNpcIds = allowedNpcIds; // Filter contacts to only these NPCs if provided this.currentView = 'contact-list'; // 'contact-list' or 'conversation' this.currentNPCId = null; this.elements = {}; @@ -43,7 +45,7 @@ export default class PhoneChatUI { this.setupVoiceSelection(); } - console.log('📱 PhoneChatUI initialized'); + console.log('📱 PhoneChatUI initialized', { allowedNpcIds }); } /** @@ -310,6 +312,13 @@ export default class PhoneChatUI { npcs = Array.from(this.npcManager.npcs.values()); } + // Filter to only allowed NPCs if npcIds was specified + if (this.allowedNpcIds && this.allowedNpcIds.length > 0) { + console.log(`🔍 Filtering contacts: allowed NPCs = ${this.allowedNpcIds.join(', ')}`); + npcs = npcs.filter(npc => this.allowedNpcIds.includes(npc.id)); + console.log(`✅ Filtered to ${npcs.length} contacts`); + } + if (!npcs || npcs.length === 0) { contactList.innerHTML = `
diff --git a/js/systems/interactions.js b/js/systems/interactions.js index e92f4ca..72a1ee9 100644 --- a/js/systems/interactions.js +++ b/js/systems/interactions.js @@ -672,10 +672,11 @@ export function handleObjectInteraction(sprite) { // Check if phone has already been converted or has npcIds if (data.npcIds && data.npcIds.length > 0) { - console.log('Phone has npcIds, opening phone-chat directly'); + console.log('Phone has npcIds, opening phone-chat directly', { npcIds: data.npcIds }); // Phone already has NPCs, open directly window.MinigameFramework.startMinigame('phone-chat', null, { phoneId: phoneId, + npcIds: data.npcIds, title: data.name || 'Phone' }); return; diff --git a/js/systems/inventory.js b/js/systems/inventory.js index 84e2361..3585371 100644 --- a/js/systems/inventory.js +++ b/js/systems/inventory.js @@ -39,8 +39,8 @@ export function initializeInventory() { } // Helper function to preload intro messages for a phone -async function preloadPhoneIntroMessages(phoneId) { - console.log(`📱 preloadPhoneIntroMessages called for ${phoneId}`); +async function preloadPhoneIntroMessages(phoneId, allowedNpcIds = null) { + console.log(`📱 preloadPhoneIntroMessages called for ${phoneId}`, { allowedNpcIds }); if (!window.npcManager) { console.warn('❌ npcManager not available'); @@ -53,7 +53,14 @@ async function preloadPhoneIntroMessages(phoneId) { // Create a temporary ink engine for preloading const tempEngine = new InkEngine(); - const npcs = window.npcManager.getNPCsByPhone(phoneId); + let npcs = window.npcManager.getNPCsByPhone(phoneId); + + // Filter to only allowed NPCs if specified + if (allowedNpcIds && allowedNpcIds.length > 0) { + console.log(`🔍 Filtering NPCs: allowed = ${allowedNpcIds.join(', ')}`); + npcs = npcs.filter(npc => allowedNpcIds.includes(npc.id)); + } + console.log(`📱 Found ${npcs.length} NPCs on phone ${phoneId}:`, npcs.map(n => n.id)); for (const npc of npcs) { @@ -262,13 +269,14 @@ export function addToInventory(sprite) { // For phones, add unread message count and badge if (sprite.scenarioData?.type === 'phone' && sprite.scenarioData?.phoneId) { const phoneId = sprite.scenarioData.phoneId; + const npcIds = sprite.scenarioData.npcIds || null; // Get allowed NPCs for this phone itemImg.setAttribute('data-phone-id', phoneId); if (window.npcManager) { // Preload intro messages for all NPCs on this phone - preloadPhoneIntroMessages(phoneId).then(() => { - const unreadCount = window.npcManager.getTotalUnreadCount(phoneId); - console.log(`📱 Phone ${phoneId} added to inventory, unread count: ${unreadCount}`); + preloadPhoneIntroMessages(phoneId, npcIds).then(() => { + const unreadCount = window.npcManager.getTotalUnreadCount(phoneId, npcIds); + console.log(`📱 Phone ${phoneId} added to inventory, unread count: ${unreadCount}`, { npcIds }); itemImg.setAttribute('data-unread-count', unreadCount); // Create badge element if there are unread messages @@ -591,7 +599,8 @@ export function updatePhoneBadge(phoneId) { // Update badge for each phone with this ID phoneItems.forEach(phoneItem => { - const unreadCount = window.npcManager.getTotalUnreadCount(phoneId); + const npcIds = phoneItem.scenarioData?.npcIds || null; // Get allowed NPCs for this phone + const unreadCount = window.npcManager.getTotalUnreadCount(phoneId, npcIds); phoneItem.setAttribute('data-unread-count', unreadCount); // Get the inventory slot (parent element) diff --git a/js/systems/npc-manager.js b/js/systems/npc-manager.js index a28670a..b1ee3c4 100644 --- a/js/systems/npc-manager.js +++ b/js/systems/npc-manager.js @@ -162,8 +162,14 @@ export default class NPCManager { } // Get total unread message count for a phone - getTotalUnreadCount(phoneId) { - const npcs = this.getNPCsByPhone(phoneId); + getTotalUnreadCount(phoneId, allowedNpcIds = null) { + let npcs = this.getNPCsByPhone(phoneId); + + // Filter to only allowed NPCs if specified + if (allowedNpcIds && allowedNpcIds.length > 0) { + npcs = npcs.filter(npc => allowedNpcIds.includes(npc.id)); + } + let totalUnread = 0; for (const npc of npcs) { diff --git a/scenarios/npc-sprite-test2.json b/scenarios/npc-sprite-test2.json index f392711..6df2f87 100644 --- a/scenarios/npc-sprite-test2.json +++ b/scenarios/npc-sprite-test2.json @@ -5,7 +5,16 @@ }, "startRoom": "test_room", - "startItemsInInventory": [], + "startItemsInInventory": [ + { + "type": "phone", + "name": "Your Phone 0", + "takeable": true, + "phoneId": "player_phone", + "npcIds": ["gossip_girl"], + "observations": "Your personal phone with some interesting contacts" + } + ], "player": { "id": "player",