Enhance phone chat functionality by adding NPC filtering; update related systems to support allowed NPCs in conversations and inventory management

This commit is contained in:
Z. Cliffe Schreuders
2025-11-08 22:35:31 +00:00
parent f83b2a7388
commit 9229df8bc8
6 changed files with 64 additions and 17 deletions

View File

@@ -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');

View File

@@ -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<string>} 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 = `
<div class="no-contacts">

View File

@@ -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;

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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",