Merge pull request #29 from cliffe/19-copy-paste-from-notes----load-notes-etc-onto-the-page-rather-than-using-js-alert-pop-ups

19 copy paste from notes    load notes etc onto the page rather than using js alert pop ups
This commit is contained in:
Damian Idzinski
2025-03-08 04:25:15 +00:00
committed by GitHub

View File

@@ -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 @@
<!-- Notes Panel -->
<div id="notes-panel">
<div id="notes-header">
<div id="notes-title">Notes</div>
<div id="notes-title">Notes & Information</div>
<div id="notes-close">×</div>
</div>
<div id="notes-search-container">
<input type="text" id="notes-search" placeholder="Search notes...">
</div>
<div id="notes-categories">
<div class="notes-category active" data-category="all">All</div>
<div class="notes-category" data-category="important">Important</div>
<div class="notes-category" data-category="unread">Unread</div>
</div>
<div id="notes-content"></div>
</div>
<div id="notes-toggle">
@@ -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 = '<div class="note-item">No notes yet.</div>';
if (filteredNotes.length === 0) {
if (searchTerm) {
notesContent.innerHTML = '<div class="note-item">No notes match your search.</div>';
} else if (activeCategory !== 'all') {
notesContent.innerHTML = `<div class="note-item">No ${activeCategory} notes found.</div>`;
} else {
notesContent.innerHTML = '<div class="note-item">No notes yet.</div>';
}
} else {
sortedNotes.forEach(note => {
filteredNotes.forEach(note => {
const noteElement = document.createElement('div');
noteElement.className = 'note-item';
noteElement.dataset.id = note.id;
let noteContent = `<div class="note-title">`;
// 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 = `<div class="note-title">
<span>${note.title}</span>
<div class="note-icons">`;
if (note.important) {
noteContent += ``;
noteContent += `<span class="note-icon">⭐</span>`;
}
if (!note.read) {
noteContent += `📌 `;
noteContent += `<span class="note-icon">📌</span>`;
}
noteContent += `${note.title}</div>`;
noteContent += `</div></div>`;
noteContent += `<div class="note-text">${note.text}</div>`;
noteContent += `<div class="note-timestamp">${formattedDate} ${formattedTime}</div>`;
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;
});
}
</script>
</body>
</html>