diff --git a/index.html b/index.html
index acc1117..93820bb 100644
--- a/index.html
+++ b/index.html
@@ -31,10 +31,9 @@
#notification-container {
position: fixed;
top: 20px;
- left: 50%;
- transform: translateX(-50%);
- width: 80%;
- max-width: 600px;
+ right: 20px;
+ width: 300px;
+ max-width: 80%;
z-index: 2000;
font-family: Arial, sans-serif;
pointer-events: none;
@@ -114,22 +113,23 @@
position: fixed;
bottom: 80px;
right: 20px;
- width: 300px;
- max-height: 400px;
- background-color: rgba(0, 0, 0, 0.8);
+ width: 350px;
+ max-height: 500px;
+ background-color: rgba(0, 0, 0, 0.9);
color: white;
border-radius: 5px;
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+ box-shadow: 0 2px 15px rgba(0, 0, 0, 0.5);
z-index: 1999;
font-family: Arial, sans-serif;
display: none;
overflow: hidden;
transition: all 0.3s ease;
+ border: 1px solid #444;
}
#notes-header {
background-color: #222;
- padding: 10px 15px;
+ padding: 12px 15px;
display: flex;
justify-content: space-between;
align-items: center;
@@ -138,18 +138,66 @@
#notes-title {
font-weight: bold;
- font-size: 16px;
+ font-size: 18px;
+ color: #3498db;
}
#notes-close {
cursor: pointer;
- font-size: 16px;
+ font-size: 18px;
color: #aaa;
+ transition: color 0.2s;
}
#notes-close:hover {
color: white;
}
+
+ #notes-search-container {
+ padding: 10px 15px;
+ background-color: #333;
+ border-bottom: 1px solid #444;
+ }
+
+ #notes-search {
+ width: 100%;
+ padding: 8px 10px;
+ border: none;
+ border-radius: 3px;
+ background-color: #222;
+ color: white;
+ font-size: 14px;
+ }
+
+ #notes-search:focus {
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.5);
+ }
+
+ #notes-categories {
+ display: flex;
+ padding: 5px 15px;
+ background-color: #2c2c2c;
+ border-bottom: 1px solid #444;
+ }
+
+ .notes-category {
+ padding: 5px 10px;
+ margin-right: 5px;
+ cursor: pointer;
+ border-radius: 3px;
+ font-size: 12px;
+ transition: all 0.2s;
+ }
+
+ .notes-category.active {
+ background-color: #3498db;
+ color: white;
+ }
+
+ .notes-category:hover:not(.active) {
+ background-color: #444;
+ }
#notes-content {
padding: 15px;
@@ -161,6 +209,14 @@
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #444;
+ cursor: pointer;
+ transition: background-color 0.2s;
+ padding: 10px;
+ border-radius: 3px;
+ }
+
+ .note-item:hover {
+ background-color: #333;
}
.note-item:last-child {
@@ -174,20 +230,47 @@
margin-bottom: 5px;
font-size: 14px;
color: #3498db;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .note-icons {
+ display: flex;
+ gap: 5px;
+ }
+
+ .note-icon {
+ font-size: 12px;
+ color: #aaa;
}
.note-text {
font-size: 13px;
line-height: 1.4;
white-space: pre-wrap;
+ max-height: 80px;
+ overflow: hidden;
+ transition: max-height 0.3s;
+ }
+
+ .note-item.expanded .note-text {
+ max-height: 1000px;
+ }
+
+ .note-timestamp {
+ font-size: 11px;
+ color: #888;
+ margin-top: 5px;
+ text-align: right;
}
#notes-toggle {
position: fixed;
bottom: 20px;
right: 20px;
- width: 50px;
- height: 50px;
+ width: 60px;
+ height: 60px;
background-color: #3498db;
color: white;
border-radius: 50%;
@@ -197,7 +280,7 @@
cursor: pointer;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
z-index: 1998;
- font-size: 24px;
+ font-size: 28px;
transition: all 0.3s ease;
}
@@ -213,9 +296,9 @@
background-color: #e74c3c;
color: white;
border-radius: 50%;
- width: 20px;
- height: 20px;
- font-size: 12px;
+ width: 24px;
+ height: 24px;
+ font-size: 14px;
display: flex;
justify-content: center;
align-items: center;
@@ -322,9 +405,17 @@
@@ -371,6 +462,7 @@
// Debug system variables - moved to the top
let debugMode = false;
+ let debugLevel = 1; // 1 = basic, 2 = detailed, 3 = verbose
let visualDebugMode = false;
let fpsCounter = null;
@@ -447,6 +539,15 @@
// Add a note to the notes panel
function addNote(title, text, important = false) {
+ // Check if a note with the same title and text already exists
+ const noteExists = gameNotes.some(note => note.title === title && note.text === text);
+
+ // If the note already exists, don't add it again
+ if (noteExists) {
+ debugLog(`Note "${title}" already exists, not adding duplicate`, 2);
+ return null;
+ }
+
const note = {
id: Date.now(),
title: title,
@@ -469,9 +570,31 @@
// Update the notes panel with current notes
function updateNotesPanel() {
const notesContent = document.getElementById('notes-content');
+ const searchTerm = document.getElementById('notes-search')?.value?.toLowerCase() || '';
+
+ // Get active category
+ const activeCategory = document.querySelector('.notes-category.active')?.dataset.category || 'all';
+
+ // Filter notes based on search and category
+ let filteredNotes = [...gameNotes];
+
+ // Apply category filter
+ if (activeCategory === 'important') {
+ filteredNotes = filteredNotes.filter(note => note.important);
+ } else if (activeCategory === 'unread') {
+ filteredNotes = filteredNotes.filter(note => !note.read);
+ }
+
+ // Apply search filter
+ if (searchTerm) {
+ filteredNotes = filteredNotes.filter(note =>
+ note.title.toLowerCase().includes(searchTerm) ||
+ note.text.toLowerCase().includes(searchTerm)
+ );
+ }
// Sort notes with important ones first, then by timestamp (newest first)
- const sortedNotes = [...gameNotes].sort((a, b) => {
+ filteredNotes.sort((a, b) => {
if (a.important !== b.important) {
return a.important ? -1 : 1;
}
@@ -482,29 +605,48 @@
notesContent.innerHTML = '';
// Add notes
- if (sortedNotes.length === 0) {
- notesContent.innerHTML = '
No notes yet.
';
+ if (filteredNotes.length === 0) {
+ if (searchTerm) {
+ notesContent.innerHTML = '
No notes match your search.
';
+ } else if (activeCategory !== 'all') {
+ notesContent.innerHTML = `
No ${activeCategory} notes found.
`;
+ } else {
+ notesContent.innerHTML = '
No notes yet.
';
+ }
} else {
- sortedNotes.forEach(note => {
+ filteredNotes.forEach(note => {
const noteElement = document.createElement('div');
noteElement.className = 'note-item';
noteElement.dataset.id = note.id;
- let noteContent = `
`;
+ // Format the timestamp
+ const timestamp = new Date(note.timestamp);
+ const formattedDate = timestamp.toLocaleDateString();
+ const formattedTime = timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
+
+ let noteContent = `
+
${note.title}
+
`;
+
if (note.important) {
- noteContent += `⭐ `;
+ noteContent += `⭐`;
}
if (!note.read) {
- noteContent += `📌 `;
+ noteContent += `📌`;
}
- noteContent += `${note.title}
`;
+
+ noteContent += `
`;
noteContent += `
${note.text}
`;
+ noteContent += `
${formattedDate} ${formattedTime}
`;
noteElement.innerHTML = noteContent;
- // Mark as read when clicked
+ // Toggle expanded state when clicked
noteElement.addEventListener('click', () => {
- if (!note.read) {
+ noteElement.classList.toggle('expanded');
+
+ // Mark as read when expanded
+ if (!note.read && noteElement.classList.contains('expanded')) {
note.read = true;
updateNotesCount();
updateNotesPanel();
@@ -531,15 +673,6 @@
const isVisible = notesPanel.style.display === 'block';
notesPanel.style.display = isVisible ? 'none' : 'block';
-
- // Mark all as read when panel is opened
- if (!isVisible) {
- gameNotes.forEach(note => {
- note.read = true;
- });
- updateNotesCount();
- updateNotesPanel();
- }
}
// Replace alert with our custom notification system
@@ -548,42 +681,51 @@
}
// Debug logging function that only logs when debug mode is active
- function debugLog(...args) {
- if (debugMode) {
- // Check if the first argument is a string
- if (typeof args[0] === 'string') {
- // Create the formatted debug message
- const message = args[0];
- const formattedMessage = `[DEBUG] === ${message} ===`;
-
- // Determine color based on message content
- let color = '#0077FF'; // Default blue for general info
- let fontWeight = 'bold';
-
- // Success messages - green
- if (message.includes('SUCCESS') ||
- message.includes('UNLOCKED') ||
- message.includes('NOT LOCKED')) {
- color = '#00AA00'; // Green
- }
- // Error/failure messages - red
- else if (message.includes('FAIL') ||
- message.includes('ERROR') ||
- message.includes('NO LOCK REQUIREMENTS FOUND')) {
- color = '#DD0000'; // Red
- }
- // Sensitive information - purple
- else if (message.includes('PIN') ||
- message.includes('PASSWORD') ||
- message.includes('KEY') ||
- message.includes('LOCK REQUIREMENTS')) {
- color = '#AA00AA'; // Purple
- }
-
- // Replace the first argument with the formatted message and add CSS styling
- args.splice(0, 1, '%c' + formattedMessage, `color: ${color}; font-weight: ${fontWeight};`);
+ function debugLog(message, data = null, level = 1) {
+ if (!debugMode || debugLevel < level) return;
+
+ // Check if the first argument is a string
+ if (typeof message === 'string') {
+ // Create the formatted debug message
+ const formattedMessage = `[DEBUG] === ${message} ===`;
+
+ // Determine color based on message content
+ let color = '#0077FF'; // Default blue for general info
+ let fontWeight = 'bold';
+
+ // Success messages - green
+ if (message.includes('SUCCESS') ||
+ message.includes('UNLOCKED') ||
+ message.includes('NOT LOCKED')) {
+ color = '#00AA00'; // Green
}
- console.log(...args);
+ // Error/failure messages - red
+ else if (message.includes('FAIL') ||
+ message.includes('ERROR') ||
+ message.includes('NO LOCK REQUIREMENTS FOUND')) {
+ color = '#DD0000'; // Red
+ }
+ // Sensitive information - purple
+ else if (message.includes('PIN') ||
+ message.includes('PASSWORD') ||
+ message.includes('KEY') ||
+ message.includes('LOCK REQUIREMENTS')) {
+ color = '#AA00AA'; // Purple
+ }
+
+ // Add level indicator to the message
+ const levelIndicator = level > 1 ? ` [L${level}]` : '';
+ const finalMessage = formattedMessage + levelIndicator;
+
+ // Log with formatting
+ if (data) {
+ console.log(`%c${finalMessage}`, `color: ${color}; font-weight: ${fontWeight};`, data);
+ } else {
+ console.log(`%c${finalMessage}`, `color: ${color}; font-weight: ${fontWeight};`);
+ }
+ } else {
+ // If not a string, just log as is
+ console.log(message, data);
}
}
@@ -592,7 +734,7 @@
if (!debugMode) return; // Skip all calculations if debug mode is off
// Your existing debug code here
- debugLog("Tension debug information:");
+ debugLog("Tension debug information:", null, 2);
// Add other debug information as needed
}
@@ -613,6 +755,13 @@
scene.physics.world.drawDebug = debugMode && visualDebugMode;
}
}
+ } else if (event.ctrlKey) {
+ // Cycle through debug levels with Ctrl+backtick
+ if (debugMode) {
+ debugLevel = (debugLevel % 3) + 1; // Cycle through 1, 2, 3
+ console.log(`%c[DEBUG] === DEBUG LEVEL ${debugLevel} ===`,
+ `color: #0077FF; font-weight: bold;`);
+ }
} else {
// Regular debug mode toggle
debugMode = !debugMode;
@@ -640,6 +789,23 @@
const notesClose = document.getElementById('notes-close');
notesClose.addEventListener('click', toggleNotesPanel);
+ // Set up search functionality
+ const notesSearch = document.getElementById('notes-search');
+ notesSearch.addEventListener('input', updateNotesPanel);
+
+ // Set up category filters
+ const categories = document.querySelectorAll('.notes-category');
+ categories.forEach(category => {
+ category.addEventListener('click', () => {
+ // Remove active class from all categories
+ categories.forEach(c => c.classList.remove('active'));
+ // Add active class to clicked category
+ category.classList.add('active');
+ // Update notes panel
+ updateNotesPanel();
+ });
+ });
+
// Initialize notes count
updateNotesCount();
});
@@ -969,14 +1135,14 @@
});
if (clickedItem) {
- console.log('Inventory item clicked:', clickedItem.name);
+ debugLog('INVENTORY ITEM CLICKED', { name: clickedItem.name }, 2);
handleObjectInteraction(clickedItem);
return;
}
}
// if not clicking inventory, handle as movement
- console.log('Click detected at:', pointer.worldX, pointer.worldY);
+ debugLog('CLICK DETECTED', { x: pointer.worldX, y: pointer.worldY }, 3);
movePlayerToPoint.call(this, pointer.worldX, pointer.worldY);
});
@@ -1022,7 +1188,7 @@
initializeSamplesUI();
// Log initial debug status
- console.log("%cPress ` (backtick) to toggle debug mode", "color: #888; font-style: italic;");
+ console.log("%cPress ` (backtick) to toggle debug mode, Ctrl+` to cycle debug levels (1-3), Shift+` for visual debug", "color: #888; font-style: italic;");
}
function update() {
@@ -1109,7 +1275,7 @@
width: width * 48, // tile width is 48
height: height * 48 // tile height is 48
};
- console.log(`Room ${roomId} dimensions:`, roomDimensions[roomId]);
+ debugLog('ROOM DIMENSIONS', { roomId, dimensions: roomDimensions[roomId] }, 3);
} else {
console.error(`Could not find tilemap data for room ${roomId}`);
// Fallback to default dimensions if needed
@@ -1189,7 +1355,7 @@
}
} else {
if (processed.has(connected)) {
- console.log(`Room ${connected} already processed, skipping`);
+ debugLog('ROOM ALREADY PROCESSED', { roomId: connected }, 3);
return;
}
@@ -1385,10 +1551,10 @@
// Add click handler for all objects
sprite.on('pointerdown', () => {
if (isActiveObject) {
- console.log(`Clicked active object ${obj.name}`);
+ debugLog('OBJECT CLICKED', { name: obj.name }, 2);
handleObjectInteraction(sprite);
} else {
- alert("Nothing of note here");
+ gameAlert("Nothing of note here", 'info', '', 2000);
}
});
});
@@ -1554,7 +1720,7 @@
}
// Otherwise, handle as movement click
- console.log('Click detected at:', worldPoint.x, worldPoint.y);
+ debugLog('CLICK DETECTED', { x: worldPoint.x, y: worldPoint.y }, 3);
movePlayerToPoint.call(this, worldPoint.x, worldPoint.y);
});
}
@@ -1965,10 +2131,14 @@
// handles interactions with objects
// displays the object's data in an alert
function handleObjectInteraction(sprite) {
- console.log('CyberChef: handleObjectInteraction called for:', sprite.name, 'Has open workstation:', !!sprite.openCryptoWorkstation);
+ // Only log detailed object interactions at debug level 2+
+ debugLog('OBJECT INTERACTION', {
+ name: sprite.name,
+ hasWorkstation: !!sprite.openCryptoWorkstation
+ }, 2);
if (sprite.openCryptoWorkstation && sprite.openCryptoWorkstation()) {
- console.log('CyberChef: Crypto workstation opened');
+ debugLog('WORKSTATION OPENED', null, 1);
return;
}
@@ -1987,7 +2157,7 @@
if (distanceSq > INTERACTION_RANGE_SQ) {
// Show notification instead of alert
- gameAlert("Too far away to interact with this object.", 'warning', '', 2000);
+ //gameAlert("Too far away to interact with this object.", 'warning', '', 2000);
return;
}
}
@@ -2045,7 +2215,7 @@
// Check if item is locked
if (data.locked === true) {
- console.log('Item is locked:', data);
+ debugLog('ITEM LOCKED', data, 2);
handleUnlock(sprite, 'item');
return;
}
@@ -2058,32 +2228,71 @@
// Add readable text as a note
if (data.text.trim().length > 0) {
- addNote(data.name, data.text);
+ const addedNote = addNote(data.name, data.text, data.important || false);
+
+ // Only show notification if a new note was actually added (not a duplicate)
+ if (addedNote) {
+ gameAlert(`Added "${data.name}" to your notes.`, 'info', 'Note Added', 3000);
+
+ // If this is a note in the inventory, remove it after adding to notes list
+ if (isInventoryItem && data.type === 'notes') {
+ // Remove from inventory after a short delay to allow the player to see the message
+ setTimeout(() => {
+ if (removeFromInventory(sprite)) {
+ gameAlert(`Removed "${data.name}" from inventory after recording in notes.`, 'success', 'Inventory Updated', 3000);
+ }
+ }, 1000);
+ }
+ }
}
}
if (data.takeable) {
- message += `This item can be taken\n\n`;
+ // If it's a note type item that's already been read and added to notes,
+ // don't add it to inventory unless it has a special purpose
+ const isJustInformationalNote =
+ data.type === 'notes' &&
+ data.readable &&
+ data.text &&
+ !data.hasSpecialPurpose; // Add this flag to notes that need to be in inventory
- if (!inventory || !Array.isArray(inventory.items)) {
- console.error('Inventory not properly initialized');
- return;
- }
-
- const isInRoom = currentRoom &&
- rooms[currentRoom] &&
- rooms[currentRoom].objects &&
- rooms[currentRoom].objects[sprite.name];
+ if (!isJustInformationalNote) {
+ message += `This item can be taken\n\n`;
+
+ if (!inventory || !Array.isArray(inventory.items)) {
+ console.error('Inventory not properly initialized');
+ return;
+ }
+
+ const isInRoom = currentRoom &&
+ rooms[currentRoom] &&
+ rooms[currentRoom].objects &&
+ rooms[currentRoom].objects[sprite.name];
+
+ const itemIdentifier = createItemIdentifier(sprite.scenarioData);
+
+ const isInInventory = inventory.items.some(item =>
+ item && createItemIdentifier(item.scenarioData) === itemIdentifier
+ );
+
+ if (isInRoom && !isInInventory) {
+ debugLog('INVENTORY ITEM ADDED', { item: itemIdentifier }, 2);
+ addToInventory(sprite);
+ }
+ } else {
+ // For informational notes, just remove them from the room after reading
+ if (currentRoom &&
+ rooms[currentRoom] &&
+ rooms[currentRoom].objects &&
+ rooms[currentRoom].objects[sprite.name]) {
- const itemIdentifier = createItemIdentifier(sprite.scenarioData);
+ const roomObj = rooms[currentRoom].objects[sprite.name];
+ roomObj.setVisible(false);
+ roomObj.active = false;
- const isInInventory = inventory.items.some(item =>
- item && createItemIdentifier(item.scenarioData) === itemIdentifier
- );
-
- if (isInRoom && !isInInventory) {
- console.log('Adding item to inventory:', itemIdentifier);
- addToInventory(sprite);
+ // Show notification about adding to notes instead of inventory
+ gameAlert(`Information recorded in your notes.`, 'success', 'Note Recorded', 3000);
+ }
}
}
@@ -2154,10 +2363,11 @@
inventory.container.add(inventorySprite);
inventory.items.push(inventorySprite);
- console.log('Item added to inventory:', {
+ // Use debugLog with level 3 (verbose) for detailed inventory tracking
+ debugLog('INVENTORY ITEM DETAILS', {
name: sprite.name,
totalItems: inventory.items.length
- });
+ }, 3);
} catch (error) {
console.error('Error adding item to inventory:', error);
}
@@ -2193,7 +2403,7 @@
.setScrollFactor(0)
.setDepth(2001);
- console.log('Inventory initialized:', inventory); // Debug log
+ debugLog('INVENTORY INITIALIZED', inventory, 2); // Debug log at level 2
}
// runs after rooms are fully set up
@@ -2341,14 +2551,14 @@
if (distance <= DOOR_INTERACTION_RANGE) {
if (doorTile.properties?.locked) {
- console.log('Door is locked, attempting unlock');
+ debugLog('DOOR LOCKED - ATTEMPTING UNLOCK', null, 2);
colorDoorTiles(doorTile, room);
handleDoorUnlock(doorTile, room);
} else {
- console.log('Door is not locked');
+ debugLog('DOOR NOT LOCKED', null, 2);
}
} else {
- console.log("Too far from door to interact");
+ debugLog('DOOR TOO FAR TO INTERACT', null, 2);
}
});
@@ -2378,13 +2588,13 @@
}
function handleDoorUnlock(doorTile, room) {
- debugLog('DOOR UNLOCK ATTEMPT');
+ // No need to log here since handleUnlock will log 'UNLOCK ATTEMPT'
doorTile.layer = room.doorsLayer; // Ensure layer reference is set
handleUnlock(doorTile, 'door');
}
function handleUnlock(lockable, type) {
- debugLog('UNLOCK ATTEMPT');
+ debugLog('UNLOCK ATTEMPT', null, 2);
// Check locked state in scenarioData for items
const isLocked = type === 'door' ?
@@ -2392,7 +2602,7 @@
lockable.scenarioData?.locked;
if (!isLocked) {
- debugLog('OBJECT NOT LOCKED');
+ debugLog('OBJECT NOT LOCKED', null, 2);
return;
}
@@ -2401,17 +2611,17 @@
? getLockRequirementsForDoor(lockable)
: getLockRequirementsForItem(lockable);
- debugLog('LOCK REQUIREMENTS', lockRequirements);
+ // Don't log lock requirements here since it's already logged in the getter functions
if (!lockRequirements) {
- debugLog('NO LOCK REQUIREMENTS FOUND');
+ // Don't log here since it's already logged in the getter functions if applicable
return;
}
switch(lockRequirements.lockType) {
case 'key':
const requiredKey = lockRequirements.requires;
- debugLog('KEY REQUIRED', requiredKey);
+ debugLog('KEY REQUIRED', requiredKey, 2);
const hasKey = inventory.items.some(item =>
item && item.scenarioData &&
item.scenarioData.key_id === requiredKey
@@ -2425,7 +2635,7 @@
const keyName = keyItem?.scenarioData?.name || 'key';
const keyLocation = keyItem?.scenarioData?.foundIn || 'your inventory';
- debugLog('KEY UNLOCK SUCCESS');
+ debugLog('KEY UNLOCK SUCCESS', null, 1);
unlockTarget(lockable, type, lockable.layer);
gameAlert(`You used the ${keyName} that you found in ${keyLocation} to unlock the ${type}.`, 'success', 'Unlock Successful', 5000);
} else {
@@ -2436,7 +2646,7 @@
);
if (hasLockpick) {
- debugLog('LOCKPICK AVAILABLE');
+ debugLog('LOCKPICK AVAILABLE', null, 2);
if (confirm("Would you like to attempt picking this lock?")) {
let difficulty;
@@ -2452,38 +2662,38 @@
// If not found, try object-level difficulty
difficulty = difficulty || lockable.scenarioData?.difficulty || lockable.properties?.difficulty;
- debugLog('STARTING LOCKPICK MINIGAME', { difficulty });
+ debugLog('STARTING LOCKPICK MINIGAME', { difficulty }, 2);
startLockpickingMinigame(lockable, game.scene.scenes[0], difficulty);
}
} else {
- debugLog('KEY NOT FOUND - FAIL');
+ debugLog('KEY NOT FOUND - FAIL', null, 2);
gameAlert(`Requires key: ${requiredKey}`, 'error', 'Locked', 4000);
}
}
break;
case 'pin':
- debugLog('PIN CODE REQUESTED');
+ debugLog('PIN CODE REQUESTED', null, 2);
const pinInput = prompt(`Enter PIN code:`);
if (pinInput === lockRequirements.requires) {
unlockTarget(lockable, type, lockable.layer); // Pass the layer here
- debugLog('PIN CODE SUCCESS');
+ debugLog('PIN CODE SUCCESS', null, 1);
gameAlert(`Correct PIN! The ${type} is now unlocked.`, 'success', 'PIN Accepted', 4000);
} else if (pinInput !== null) {
- debugLog('PIN CODE FAIL');
+ debugLog('PIN CODE FAIL', null, 2);
gameAlert("Incorrect PIN code.", 'error', 'PIN Rejected', 3000);
}
break;
case 'password':
- debugLog('PASSWORD REQUESTED');
+ debugLog('PASSWORD REQUESTED', null, 2);
const passwordInput = prompt(`Enter password:`);
if (passwordInput === lockRequirements.requires) {
unlockTarget(lockable, type, lockable.layer); // Pass the layer here
- debugLog('PASSWORD SUCCESS');
+ debugLog('PASSWORD SUCCESS', null, 1);
gameAlert(`Correct password! The ${type} is now unlocked.`, 'success', 'Password Accepted', 4000);
} else if (passwordInput !== null) {
- debugLog('PASSWORD FAIL');
+ debugLog('PASSWORD FAIL', null, 2);
gameAlert("Incorrect password.", 'error', 'Password Rejected', 3000);
}
break;
@@ -2508,7 +2718,7 @@
lockable.x, lockable.y
);
- debugLog('BLUETOOTH DISTANCE', distance);
+ debugLog('BLUETOOTH DISTANCE', distance, 3);
// Check if player is within range (using BLUETOOTH_SCAN_RANGE)
if (distance <= BLUETOOTH_SCAN_RANGE) {
@@ -2517,7 +2727,7 @@
itemMac: lockable.scenarioData?.mac,
distance: Math.round(distance),
range: BLUETOOTH_SCAN_RANGE
- });
+ }, 1);
unlockTarget(lockable, type, lockable.layer);
gameAlert("Bluetooth connection established. Device unlocked.", 'success', 'Connection Successful', 4000);
return;
@@ -2656,7 +2866,7 @@
}
function getLockRequirementsForDoor(doorTile) {
- debugLog('CHECKING DOOR REQUIREMENTS');
+ debugLog('CHECKING DOOR REQUIREMENTS', null, 3);
if (!doorTile.layer) {
console.error('Door tile missing layer reference');
@@ -2666,7 +2876,7 @@
const doorWorldX = doorTile.layer.x + (doorTile.x * TILE_SIZE);
const doorWorldY = doorTile.layer.y + (doorTile.y * TILE_SIZE);
- debugLog('DOOR COORDINATES', { doorWorldX, doorWorldY });
+ debugLog('DOOR COORDINATES', { doorWorldX, doorWorldY }, 3);
const overlappingRooms = [];
Object.entries(rooms).forEach(([roomId, otherRoom]) => {
@@ -2685,7 +2895,7 @@
};
if (boundsOverlap(doorCheckArea, roomBounds)) {
- debugLog(`ROOM ${roomId} OVERLAPS WITH DOOR`);
+ debugLog(`ROOM ${roomId} OVERLAPS WITH DOOR`, null, 3);
const roomCenterX = roomBounds.x + (roomBounds.width / 2);
const roomCenterY = roomBounds.y + (roomBounds.height / 2);
const distanceToPlayer = Phaser.Math.Distance.Between(
@@ -2704,13 +2914,13 @@
}
});
- debugLog('OVERLAPPING ROOMS', overlappingRooms);
+ debugLog('OVERLAPPING ROOMS', overlappingRooms, 3);
const lockedRooms = overlappingRooms
.filter(r => r.locked)
.sort((a, b) => b.distance - a.distance);
- debugLog('LOCKED ROOMS', lockedRooms);
+ debugLog('LOCKED ROOMS', lockedRooms, 3);
if (lockedRooms.length > 0) {
const targetRoom = lockedRooms[0];
@@ -2718,11 +2928,11 @@
lockType: targetRoom.lockType,
requires: targetRoom.requires
};
- debugLog('LOCK REQUIREMENTS', requirements);
+ debugLog('LOCK REQUIREMENTS', requirements, 2);
return requirements;
}
- debugLog('NO LOCK REQUIREMENTS FOUND');
+ debugLog('NO LOCK REQUIREMENTS FOUND', null, 2);
return null;
}
@@ -2773,11 +2983,11 @@
debugLog('BLUETOOTH DEVICE DETECTED', {
distance: Math.round(distance),
range: BLUETOOTH_SCAN_RANGE
- });
+ }, 2);
// Unlock the tablet
obj.scenarioData.locked = false;
- debugLog('BLUETOOTH UNLOCK SUCCESS');
+ debugLog('BLUETOOTH UNLOCK SUCCESS', null, 1);
}
}
});
@@ -2811,7 +3021,7 @@
}
if (!scanner.scenarioData?.biometricType === 'fingerprint') {
- debugLog('SCANNER TYPE ERROR - FAIL', scanner.scenarioData);
+ debugLog('SCANNER TYPE ERROR - FAIL', scanner.scenarioData, 2);
gameAlert('Invalid scanner type', 'error', 'Scanner Error', 3000);
return false;
}
@@ -4278,6 +4488,12 @@
else if (lockable && lockable.scenarioData) {
console.log('Unlocking container:', lockable.scenarioData);
lockable.scenarioData.locked = false;
+
+ // Set the flag to indicate the container is unlocked but contents not collected
+ if (lockable.scenarioData.contents && lockable.scenarioData.contents.length > 0) {
+ lockable.scenarioData.isUnlockedButNotCollected = true;
+ debugLog('Container unlocked and ready for collection', lockable.scenarioData, 1);
+ }
}
// Remove the minigame
@@ -4355,6 +4571,52 @@
}
}
+ // removes an item from the inventory
+ function removeFromInventory(sprite) {
+ if (!sprite || !inventory.items) {
+ return false;
+ }
+
+ try {
+ // Find the index of the sprite in the inventory
+ const index = inventory.items.indexOf(sprite);
+
+ if (index === -1) {
+ return false; // Item not found in inventory
+ }
+
+ // Remove from container
+ inventory.container.remove(sprite);
+
+ // Remove from items array
+ inventory.items.splice(index, 1);
+
+ // Destroy the sprite
+ sprite.destroy();
+
+ // Rearrange remaining items
+ rearrangeInventoryItems();
+
+ // Log the removal
+ debugLog('INVENTORY ITEM REMOVED', {
+ name: sprite.name,
+ totalItems: inventory.items.length
+ }, 2);
+
+ return true;
+ } catch (error) {
+ console.error('Error removing item from inventory:', error);
+ return false;
+ }
+ }
+
+ // Rearrange inventory items after removal
+ function rearrangeInventoryItems() {
+ inventory.items.forEach((item, index) => {
+ item.x = index * 60 + 100;
+ });
+ }
+