fix: update item ID handling and prevent local state overwrite in room sync

This commit is contained in:
Z. Cliffe Schreuders
2026-02-18 13:36:21 +00:00
parent 91d4670b2a
commit 11ac3ab5e4
3 changed files with 26 additions and 7 deletions

View File

@@ -342,11 +342,18 @@ function applyScenarioProperties(sprite, scenarioObj, roomId, index) {
sprite.scenarioData = scenarioObj;
sprite.interactable = true; // Mark scenario items as interactable
sprite.name = scenarioObj.name;
sprite.objectId = `${roomId}_${scenarioObj.type}_${index}`;
// Prefer the item's own id (set for server-synced dropped items) so that
// removeItemFromRoom sends the correct id when the player picks it up.
sprite.objectId = scenarioObj.id || `${roomId}_${scenarioObj.type}_${index}`;
sprite.setInteractive({ useHandCursor: true });
// Store all scenario properties for interaction system
// IMPORTANT: Skip 'texture' - it is a Phaser-internal property (TextureFrame object).
// Synced items from the server include texture as a plain string (e.g. 'id_badge').
// Overwriting sprite.texture with a string breaks sprite.texture.key, which the
// inventory system uses to build the icon image path.
Object.keys(scenarioObj).forEach(key => {
if (key === 'texture') return;
sprite[key] = scenarioObj[key];
});

View File

@@ -42,11 +42,23 @@ export async function addItemToRoom(roomId, item, options = {}) {
if (result.success) {
console.log(`✅ Synced item add to room ${roomId}:`, item.type);
// Update local room state if room is loaded
if (window.rooms && window.rooms[roomId]) {
window.rooms[roomId].objects = window.rooms[roomId].objects || {};
window.rooms[roomId].objects[item.id] = item;
}
// CRITICAL: DO NOT update local room state here!
//
// The calling code (e.g., npc-hostile.js dropNPCItems) has already:
// 1. Created a Phaser sprite for the item
// 2. Made it interactive (setInteractive, interactable=true, takeable=true)
// 3. Stored it in room.objects[item.id] = sprite
//
// If we overwrite room.objects[item.id] with a plain JS object here,
// the Phaser sprite reference is lost, and the interaction system
// can no longer detect/interact with the item!
//
// The local state is ALREADY correct - this sync is just persisting
// to the database for reload. When the page reloads, the server
// returns the item in roomData, and rooms.js creates a fresh sprite.
//
// Bug fixed: Items dropped by NPCs are now pickupable immediately,
// not just after refresh.
return true;
} else {

View File

@@ -285,7 +285,7 @@ password_hints = "Common passwords: Marketing123, Campaign2024, Viral_Dynamics_A
"displayName": "Sarah Martinez",
"npcType": "person",
"position": { "x": 4, "y": 1.5 },
"spriteSheet": "female_blowse",
"spriteSheet": "female_office_worker",
"spriteTalk": "assets/characters/hacker-red-talk.png",
"spriteConfig": {
"idleFrameRate": 2,