From 378045dded5577bb56844db5dffe4bb1295bccd8 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Fri, 10 Oct 2025 15:20:04 +0100 Subject: [PATCH] Add Notes Minigame enhancements: Integrate new notepad assets and styles, update minigame logic for improved navigation and observation editing. Introduce responsive design elements and ensure inventory integration for the notepad. Refactor existing code for better maintainability and user experience. --- assets/mini-games/backpack.png | Bin 0 -> 453 bytes assets/objects/chair-white-1.aseprite | Bin 0 -> 5057 bytes assets/objects/notes5.png | Bin 0 -> 603 bytes css/minigames-framework.css | 12 +- css/notes.css | 319 ++++++++++++ index_new.html | 1 + js/minigames/framework/base-minigame.js | 47 +- js/minigames/framework/minigame-manager.js | 13 + js/minigames/notes/notes-minigame.js | 562 ++++++++------------- js/systems/interactions.js | 19 + js/systems/inventory.js | 54 +- 11 files changed, 663 insertions(+), 364 deletions(-) create mode 100644 assets/mini-games/backpack.png create mode 100644 assets/objects/chair-white-1.aseprite create mode 100644 assets/objects/notes5.png create mode 100644 css/notes.css diff --git a/assets/mini-games/backpack.png b/assets/mini-games/backpack.png new file mode 100644 index 0000000000000000000000000000000000000000..2d704fb4deeeb1425095d93777bda6f5999c1d3c GIT binary patch literal 453 zcmV;$0XqJPP)Px$e@R3^R5*>5R6$AuF%*3x-3;V26NrU@&cezlNGTpcs2A`&UG@UKi5Kt$E<{Ul zVQF1Vp->7lG6UU+absfACe!w9LVo^#c`rXn01sluWv89uYrD1L`DzyUYP^UUmuZqo zGnOWqj2V}{n!R1_`UCm8cxl{-NH`U?%*p-LrThlaX{U{3f}P`YR?n za-E~B3(e7LPKVWiC=45O&rDUWgz;#I@o4B&wF@mVO)^PA5hy>Ck!*nr0nq(jn7~BrDA|l~FGX)}n z$M;X9NoLuK!Vpmy;(7k&wCyBQveg)cA$r}ucinUr#EeTKp%<0(L)T!r&Y|9JRc%n# zMX-0z4w3i}GcNaRo(ij*ro~f0B(PlP`dEm>e*;u-_y2Oim(y~oI)-o;`Dzxlj92gd v^n57mLX83b-lmKhM_Cs^(=XaUsOx?KgY}^LoMQBh00000NkvXXu0mjfQwPa; literal 0 HcmV?d00001 diff --git a/assets/objects/chair-white-1.aseprite b/assets/objects/chair-white-1.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..0a09d532378892604c54317305feeda19bb2bfc8 GIT binary patch literal 5057 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 + diff --git a/js/minigames/framework/base-minigame.js b/js/minigames/framework/base-minigame.js index 5a3db03..315a7b9 100644 --- a/js/minigames/framework/base-minigame.js +++ b/js/minigames/framework/base-minigame.js @@ -13,6 +13,9 @@ export class MinigameScene { } init() { + // Check if cancel button should be shown (default: true) + const showCancel = this.params.showCancel !== false; + this.container.innerHTML = `
@@ -20,9 +23,7 @@ export class MinigameScene {
-
- -
+ ${showCancel ? `
` : ''} `; this.headerElement = this.container.querySelector('.minigame-header'); @@ -32,26 +33,50 @@ export class MinigameScene { // Set up close button const closeBtn = document.getElementById('minigame-close'); - this.addEventListener(closeBtn, 'click', () => { + this.addEventListener(closeBtn, 'click', (e) => { + e.preventDefault(); + e.stopPropagation(); + console.log('Close button clicked'); this.complete(false); }); - // Set up cancel button + // Set up cancel button only if it exists const cancelBtn = document.getElementById('minigame-cancel'); - this.addEventListener(cancelBtn, 'click', () => { - this.complete(false); - }); + if (cancelBtn) { + console.log('Cancel button found, setting up event listener'); + this.addEventListener(cancelBtn, 'click', (e) => { + e.preventDefault(); + e.stopPropagation(); + console.log('Cancel button clicked'); + this.complete(false); + }); + } else { + console.log('Cancel button not found'); + } } start() { this.gameState.isActive = true; console.log("Minigame started"); + + // Add a fallback mechanism to ensure minigame can be closed + // This helps if there are issues with button event listeners + this._fallbackCloseHandler = (e) => { + if (e.key === 'Escape') { + console.log('Escape key pressed, closing minigame'); + this.complete(false); + } + }; + document.addEventListener('keydown', this._fallbackCloseHandler); } complete(success) { + console.log('Minigame complete called with success:', success); this.gameState.isActive = false; if (window.MinigameFramework) { window.MinigameFramework.endMinigame(success, this.gameResult); + } else { + console.error('MinigameFramework not available'); } } @@ -101,5 +126,11 @@ export class MinigameScene { element.removeEventListener(eventType, handler); }); this._eventListeners = []; + + // Clean up fallback close handler + if (this._fallbackCloseHandler) { + document.removeEventListener('keydown', this._fallbackCloseHandler); + this._fallbackCloseHandler = null; + } } } \ No newline at end of file diff --git a/js/minigames/framework/minigame-manager.js b/js/minigames/framework/minigame-manager.js index 18b355e..645a277 100644 --- a/js/minigames/framework/minigame-manager.js +++ b/js/minigames/framework/minigame-manager.js @@ -18,6 +18,12 @@ export const MinigameFramework = { return null; } + // If there's already a minigame running, end it first + if (this.currentMinigame) { + console.log('Ending current minigame before starting new one'); + this.endMinigame(false, null); + } + // Disable main game input if we have a main game scene if (this.mainGameScene && this.mainGameScene.input) { this.mainGameScene.input.mouse.enabled = false; @@ -42,12 +48,15 @@ export const MinigameFramework = { }, endMinigame(success, result) { + console.log('endMinigame called with success:', success, 'result:', result); if (this.currentMinigame) { + console.log('Cleaning up current minigame'); this.currentMinigame.cleanup(); // Remove minigame container only if it was auto-created const container = document.querySelector('.minigame-container'); if (container && !container.hasAttribute('data-external')) { + console.log('Removing minigame container'); container.remove(); } @@ -55,15 +64,19 @@ export const MinigameFramework = { if (this.mainGameScene && this.mainGameScene.input) { this.mainGameScene.input.mouse.enabled = true; this.mainGameScene.input.keyboard.enabled = true; + console.log('Re-enabled main game input'); } // Call completion callback if (this.currentMinigame.params && this.currentMinigame.params.onComplete) { + console.log('Calling onComplete callback'); this.currentMinigame.params.onComplete(success, result); } this.currentMinigame = null; console.log(`Ended minigame with success: ${success}`); + } else { + console.log('No current minigame to end'); } }, diff --git a/js/minigames/notes/notes-minigame.js b/js/minigames/notes/notes-minigame.js index 37f52be..21c1979 100644 --- a/js/minigames/notes/notes-minigame.js +++ b/js/minigames/notes/notes-minigame.js @@ -1,11 +1,18 @@ import { MinigameScene } from '../framework/base-minigame.js'; -// Load handwritten font -const fontLink = document.createElement('link'); -fontLink.href = 'https://fonts.googleapis.com/css2?family=Kalam:wght@300;400;700&display=swap'; -fontLink.rel = 'stylesheet'; -if (!document.querySelector('link[href*="Kalam"]')) { - document.head.appendChild(fontLink); +// Load fonts +const fontLink1 = document.createElement('link'); +fontLink1.href = 'https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400;500;600;700&display=swap'; +fontLink1.rel = 'stylesheet'; +if (!document.querySelector('link[href*="Pixelify+Sans"]')) { + document.head.appendChild(fontLink1); +} + +const fontLink2 = document.createElement('link'); +fontLink2.href = 'https://fonts.googleapis.com/css2?family=VT323&display=swap'; +fontLink2.rel = 'stylesheet'; +if (!document.querySelector('link[href*="VT323"]')) { + document.head.appendChild(fontLink2); } // Notes Minigame Scene implementation @@ -19,6 +26,10 @@ export class NotesMinigame extends MinigameScene { params.title = 'Reading Notes'; } + // Enable cancel button for notes minigame with custom text + params.showCancel = true; + params.cancelText = 'Continue'; + super(container, params); this.item = params.item; @@ -37,133 +48,47 @@ export class NotesMinigame extends MinigameScene { console.log("Notes minigame initializing"); - // Set container dimensions to take up most of the screen - this.container.style.width = '90%'; - this.container.style.height = '85%'; - this.container.style.padding = '20px'; + // Refresh collected notes to ensure we have the latest data + this.collectedNotes = this.getCollectedNotes(); + console.log("Collected notes:", this.collectedNotes); - // Set up header content - this.headerElement.innerHTML = ` -

Reading Notes

-

Note automatically added to your collection

- `; + // Set container dimensions to take up most of the screen + this.container.className += ' notes-minigame-container'; + + // Clear header content + this.headerElement.innerHTML = ''; // Configure game container with notepad background - scaled to fill most of the screen - this.gameContainer.style.cssText = ` - width: 100%; - min-height: 100%; - max-width: 800px; - max-height: none; - background-image: url('assets/mini-games/notepad.png'); - background-size: contain; - background-repeat: no-repeat; - background-position: center; - position: relative; - margin: 20px auto; - padding: 10px 140px 50px 150px; - box-sizing: border-box; - image-rendering: -moz-crisp-edges; - image-rendering: -webkit-crisp-edges; - image-rendering: pixelated; - image-rendering: crisp-edges; - `; + this.gameContainer.className += ' notes-minigame-game-container'; // Create content area const contentArea = document.createElement('div'); - contentArea.style.cssText = ` - width: 100%; - min-height: 100%; - font-family: 'Courier New', monospace; - font-size: 18px; - line-height: 1.5; - color: #333; - background: transparent; - padding: 0; - margin: 0; - `; + contentArea.className = 'notes-minigame-content-area'; // Create text box container to look like it's stuck in a binder const textBox = document.createElement('div'); - textBox.style.cssText = ` - margin: 20px 50px 60px 80px; - padding: 40px; - background: #fefefe; - border: 2px solid #ddd; - border-radius: 3px; - box-shadow: - 0 2px 4px rgba(0,0,0,0.1), - inset 0 1px 0 rgba(255,255,255,0.8); - position: relative; - min-height: fit-content; - `; + textBox.className = 'notes-minigame-text-box'; // Add celotape effect const celotape = document.createElement('div'); celotape.className = 'notes-minigame-celotape'; - celotape.style.cssText = ` - position: absolute; - top: -8px; - left: 80px; - right: 80px; - height: 16px; - background: linear-gradient(90deg, - rgba(255,255,255,0.9) 0%, - rgba(255,255,255,0.7) 20%, - rgba(255,255,255,0.9) 40%, - rgba(255,255,255,0.7) 60%, - rgba(255,255,255,0.9) 80%, - rgba(255,255,255,0.7) 100%); - border: 1px solid rgba(200,200,200,0.8); - border-radius: 2px; - box-shadow: - 0 1px 2px rgba(0,0,0,0.1), - inset 0 1px 0 rgba(255,255,255,0.9); - z-index: 1; - `; textBox.appendChild(celotape); // Add binder holes effect const binderHoles = document.createElement('div'); - binderHoles.style.cssText = ` - position: absolute; - left: 12px; - top: 50%; - transform: translateY(-50%); - width: 8px; - height: 80px; - display: flex; - flex-direction: column; - justify-content: space-between; - `; + binderHoles.className = 'notes-minigame-binder-holes'; // Add note title/name above the text box const noteTitle = document.createElement('div'); noteTitle.className = 'notes-minigame-title'; - noteTitle.style.cssText = ` - margin: 0 50px 20px 80px; - font-family: 'Kalam', 'Comic Sans MS', cursive; - font-size: 20px; - font-weight: bold; - color: #2c3e50; - text-decoration: underline; - text-decoration-color: #3498db; - text-underline-offset: 3px; - text-align: center; - `; noteTitle.textContent = this.item?.scenarioData?.name || 'Note'; contentArea.appendChild(noteTitle); // Add note content const noteText = document.createElement('div'); noteText.className = 'notes-minigame-text'; - noteText.style.cssText = ` - margin-left: 30px; - white-space: pre-wrap; - word-wrap: break-word; - color: #333; - `; noteText.textContent = this.noteContent; textBox.appendChild(noteText); @@ -173,49 +98,17 @@ export class NotesMinigame extends MinigameScene { if (this.observationText) { const observationContainer = document.createElement('div'); observationContainer.className = 'notes-minigame-observation-container'; - observationContainer.style.cssText = ` - margin: 20px 50px 60px 80px; - position: relative; - `; const observationDiv = document.createElement('div'); observationDiv.className = 'notes-minigame-observation'; - observationDiv.style.cssText = ` - font-family: 'Kalam', 'Comic Sans MS', cursive; - font-style: italic; - color: #666; - font-size: 18px; - line-height: 1.4; - text-align: left; - min-height: 30px; - padding: 10px; - border: 1px dashed #ccc; - border-radius: 3px; - background: rgba(255, 255, 255, 0.3); - `; observationDiv.innerHTML = this.observationText; + observationDiv.style.cursor = 'pointer'; // Make it clear it's clickable + observationDiv.title = 'Click to edit observations'; + observationDiv.addEventListener('click', () => this.editObservations(observationDiv)); // Add edit button const editBtn = document.createElement('button'); editBtn.className = 'notes-minigame-edit-btn'; - editBtn.style.cssText = ` - position: absolute; - top: -8px; - right: -8px; - background: #3498db; - color: white; - border: none; - border-radius: 50%; - width: 24px; - height: 24px; - cursor: pointer; - font-size: 12px; - display: flex; - align-items: center; - justify-content: center; - box-shadow: 0 2px 4px rgba(0,0,0,0.3); - transition: background-color 0.3s ease; - `; editBtn.innerHTML = '✏️'; editBtn.title = 'Edit observations'; editBtn.addEventListener('click', () => this.editObservations(observationDiv)); @@ -227,49 +120,17 @@ export class NotesMinigame extends MinigameScene { // Add empty observation area with edit button const observationContainer = document.createElement('div'); observationContainer.className = 'notes-minigame-observation-container'; - observationContainer.style.cssText = ` - margin: 20px 50px 60px 80px; - position: relative; - `; const observationDiv = document.createElement('div'); - observationDiv.className = 'notes-minigame-observation'; - observationDiv.style.cssText = ` - font-family: 'Kalam', 'Comic Sans MS', cursive; - font-style: italic; - color: #999; - font-size: 18px; - line-height: 1.4; - text-align: left; - min-height: 30px; - padding: 10px; - border: 1px dashed #ccc; - border-radius: 3px; - background: rgba(255, 255, 255, 0.3); - `; + observationDiv.className = 'notes-minigame-observation empty'; observationDiv.innerHTML = 'Click edit to add your observations...'; + observationDiv.style.cursor = 'pointer'; // Make it clear it's clickable + observationDiv.title = 'Click to add observations'; + observationDiv.addEventListener('click', () => this.editObservations(observationDiv)); // Add edit button const editBtn = document.createElement('button'); editBtn.className = 'notes-minigame-edit-btn'; - editBtn.style.cssText = ` - position: absolute; - top: -8px; - right: -8px; - background: #3498db; - color: white; - border: none; - border-radius: 50%; - width: 24px; - height: 24px; - cursor: pointer; - font-size: 12px; - display: flex; - align-items: center; - justify-content: center; - box-shadow: 0 2px 4px rgba(0,0,0,0.3); - transition: background-color 0.3s ease; - `; editBtn.innerHTML = '✏️'; editBtn.title = 'Add observations'; editBtn.addEventListener('click', () => this.editObservations(observationDiv)); @@ -279,134 +140,52 @@ export class NotesMinigame extends MinigameScene { contentArea.appendChild(observationContainer); } - this.gameContainer.appendChild(contentArea); + // Create notepad container + const notepadContainer = document.createElement('div'); + notepadContainer.className = 'notes-minigame-notepad'; - // Create navigation buttons container - const navContainer = document.createElement('div'); - navContainer.style.cssText = ` - position: absolute; - bottom: 80px; - left: 50%; - transform: translateX(-50%); - display: flex; - gap: 15px; - z-index: 10; - `; + // Add content area to notepad container + notepadContainer.appendChild(contentArea); - // Add search input if there are multiple notes - if (this.collectedNotes.length > 1) { - const searchInput = document.createElement('input'); - searchInput.type = 'text'; - searchInput.placeholder = 'Search notes...'; - searchInput.className = 'notes-minigame-search'; - searchInput.style.cssText = ` - padding: 8px 12px; - border: 1px solid #555; - border-radius: 5px; - background: rgba(0,0,0,0.7); - color: white; - font-size: 14px; - width: 200px; - margin-right: 10px; - `; - searchInput.addEventListener('input', (e) => this.searchNotes(e.target.value)); - navContainer.appendChild(searchInput); + // Add notepad container to game container + this.gameContainer.appendChild(notepadContainer); + + // Create navigation buttons container (only if navigation is not hidden) + if (!this.params.hideNavigation) { + const navContainer = document.createElement('div'); + navContainer.className = 'notes-minigame-nav-container'; - const prevBtn = document.createElement('button'); - prevBtn.className = 'minigame-button notes-nav-button'; - prevBtn.style.cssText = ` - background: #95a5a6; - color: white; - border: none; - padding: 8px 15px; - border-radius: 5px; - cursor: pointer; - font-size: 14px; - font-weight: bold; - transition: background-color 0.3s ease; - `; - prevBtn.textContent = '← Previous'; - prevBtn.addEventListener('click', () => this.navigateToNote(-1)); - navContainer.appendChild(prevBtn); - - const nextBtn = document.createElement('button'); - nextBtn.className = 'minigame-button notes-nav-button'; - nextBtn.style.cssText = ` - background: #95a5a6; - color: white; - border: none; - padding: 8px 15px; - border-radius: 5px; - cursor: pointer; - font-size: 14px; - font-weight: bold; - transition: background-color 0.3s ease; - `; - nextBtn.textContent = 'Next →'; - nextBtn.addEventListener('click', () => this.navigateToNote(1)); - navContainer.appendChild(nextBtn); - - // Add note counter - const noteCounter = document.createElement('div'); - noteCounter.className = 'notes-minigame-counter'; - noteCounter.style.cssText = ` - color: white; - font-size: 14px; - display: flex; - align-items: center; - padding: 8px 15px; - background: rgba(0,0,0,0.5); - border-radius: 5px; - `; - noteCounter.textContent = `${this.currentNoteIndex + 1} / ${this.collectedNotes.length}`; - navContainer.appendChild(noteCounter); - - this.container.appendChild(navContainer); + // Add search input if there are multiple notes + if (this.collectedNotes.length > 1) { + const searchInput = document.createElement('input'); + searchInput.type = 'text'; + searchInput.placeholder = 'Search notes...'; + searchInput.className = 'notes-minigame-search'; + searchInput.addEventListener('input', (e) => this.searchNotes(e.target.value)); + navContainer.appendChild(searchInput); + + const prevBtn = document.createElement('button'); + prevBtn.className = 'minigame-button notes-minigame-nav-button'; + prevBtn.textContent = '← Previous'; + prevBtn.addEventListener('click', () => this.navigateToNote(-1)); + navContainer.appendChild(prevBtn); + + const nextBtn = document.createElement('button'); + nextBtn.className = 'minigame-button notes-minigame-nav-button'; + nextBtn.textContent = 'Next →'; + nextBtn.addEventListener('click', () => this.navigateToNote(1)); + navContainer.appendChild(nextBtn); + + // Add note counter + const noteCounter = document.createElement('div'); + noteCounter.className = 'notes-minigame-counter'; + noteCounter.textContent = `${this.currentNoteIndex + 1} / ${this.collectedNotes.length}`; + navContainer.appendChild(noteCounter); + + this.container.appendChild(navContainer); + } } - // Create action buttons container - const buttonsContainer = document.createElement('div'); - buttonsContainer.style.cssText = ` - position: absolute; - bottom: 20px; - left: 50%; - transform: translateX(-50%); - display: flex; - gap: 15px; - z-index: 10; - `; - - - // Close button - const closeBtn = document.createElement('button'); - closeBtn.className = 'minigame-button notes-close-button'; - closeBtn.style.cssText = ` - background: #95a5a6; - color: white; - border: none; - padding: 10px 20px; - border-radius: 5px; - cursor: pointer; - font-size: 14px; - font-weight: bold; - transition: background-color 0.3s ease; - `; - closeBtn.textContent = 'Close'; - - closeBtn.addEventListener('mouseenter', () => { - closeBtn.style.backgroundColor = '#7f8c8d'; - }); - closeBtn.addEventListener('mouseleave', () => { - closeBtn.style.backgroundColor = '#95a5a6'; - }); - - closeBtn.addEventListener('click', () => { - this.complete(false); - }); - - buttonsContainer.appendChild(closeBtn); - - this.container.appendChild(buttonsContainer); } @@ -451,19 +230,13 @@ export class NotesMinigame extends MinigameScene { } getCollectedNotes() { - // Get all notes from the notes system that are marked as important or have been collected + // Get all notes from the notes system if (!window.gameState || !window.gameState.notes) { return []; } - // Filter for important notes or notes that look like they were collected from objects - return window.gameState.notes.filter(note => - note.important || - note.title.includes('Log') || - note.title.includes('Note') || - note.title.includes('Security') || - note.title.includes('Report') - ); + // Return all notes - no filtering needed since we want to show all collected notes + return window.gameState.notes.slice(); // Return a copy to avoid modifying the original array } navigateToNote(direction) { @@ -519,12 +292,22 @@ export class NotesMinigame extends MinigameScene { if (this.observationText) { observationDiv.innerHTML = this.observationText; observationDiv.style.color = '#666'; + observationDiv.style.cursor = 'pointer'; + observationDiv.title = 'Click to edit observations'; editBtn.title = 'Edit observations'; } else { observationDiv.innerHTML = 'Click edit to add your observations...'; observationDiv.style.color = '#999'; + observationDiv.style.cursor = 'pointer'; + observationDiv.title = 'Click to add observations'; editBtn.title = 'Add observations'; } + + // Re-attach click event listener for the observation text + // Clone the element to remove all event listeners + const newObservationDiv = observationDiv.cloneNode(true); + newObservationDiv.addEventListener('click', () => this.editObservations(newObservationDiv)); + observationDiv.parentNode.replaceChild(newObservationDiv, observationDiv); } } @@ -574,6 +357,70 @@ export class NotesMinigame extends MinigameScene { } } + updateNavigation() { + // Check if navigation container exists + let navContainer = this.container.querySelector('.notes-minigame-nav-container'); + + // If navigation is hidden, remove any existing navigation + if (this.params.hideNavigation) { + if (navContainer) { + navContainer.remove(); + console.log('Navigation hidden as requested'); + } + return; + } + + // If we have multiple notes and no navigation, create it + if (this.collectedNotes.length > 1 && !navContainer) { + navContainer = document.createElement('div'); + navContainer.className = 'notes-minigame-nav-container'; + + const searchInput = document.createElement('input'); + searchInput.type = 'text'; + searchInput.placeholder = 'Search notes...'; + searchInput.className = 'notes-minigame-search'; + searchInput.addEventListener('input', (e) => this.searchNotes(e.target.value)); + navContainer.appendChild(searchInput); + + const prevBtn = document.createElement('button'); + prevBtn.className = 'minigame-button notes-minigame-nav-button'; + prevBtn.textContent = '← Previous'; + prevBtn.addEventListener('click', () => this.navigateToNote(-1)); + navContainer.appendChild(prevBtn); + + const nextBtn = document.createElement('button'); + nextBtn.className = 'minigame-button notes-minigame-nav-button'; + nextBtn.textContent = 'Next →'; + nextBtn.addEventListener('click', () => this.navigateToNote(1)); + navContainer.appendChild(nextBtn); + + const noteCounter = document.createElement('div'); + noteCounter.className = 'notes-minigame-counter'; + noteCounter.textContent = `${this.currentNoteIndex + 1} / ${this.collectedNotes.length}`; + navContainer.appendChild(noteCounter); + + this.container.appendChild(navContainer); + } + + // Update counter if navigation exists + if (navContainer) { + const noteCounter = navContainer.querySelector('.notes-minigame-counter'); + if (noteCounter) { + noteCounter.textContent = `${this.currentNoteIndex + 1} / ${this.collectedNotes.length}`; + } + } + } + + // Method to navigate to a specific note index + navigateToNoteIndex(index) { + if (index >= 0 && index < this.collectedNotes.length) { + this.currentNoteIndex = index; + this.updateDisplayedNote(); + this.updateCounter(); + console.log('Navigated to note at index:', index); + } + } + editObservations(observationDiv) { const currentText = observationDiv.textContent.trim(); const isPlaceholder = currentText === 'Click edit to add your observations...'; @@ -582,44 +429,22 @@ export class NotesMinigame extends MinigameScene { // Create textarea for editing const textarea = document.createElement('textarea'); textarea.value = originalText; - textarea.style.cssText = ` - width: 100%; - min-height: 60px; - font-family: 'Kalam', 'Comic Sans MS', cursive; - font-size: 18px; - line-height: 1.4; - color: #666; - border: 2px solid #3498db; - border-radius: 3px; - padding: 10px; - background: rgba(255, 255, 255, 0.9); - resize: vertical; - outline: none; - `; + textarea.className = 'notes-minigame-edit-textarea'; textarea.placeholder = 'Add your observations here...'; // Create button container const buttonContainer = document.createElement('div'); - buttonContainer.style.cssText = ` - margin-top: 10px; - display: flex; - gap: 10px; - justify-content: flex-end; - `; + buttonContainer.className = 'notes-minigame-edit-buttons'; // Save button const saveBtn = document.createElement('button'); saveBtn.textContent = 'Save'; - saveBtn.style.cssText = ` - background: #2ecc71; - color: white; - border: none; - padding: 8px 16px; - border-radius: 3px; - cursor: pointer; - font-size: 14px; - `; - saveBtn.addEventListener('click', () => { + saveBtn.className = 'notes-minigame-save-btn'; + saveBtn.addEventListener('click', (e) => { + e.preventDefault(); + e.stopPropagation(); + console.log('Save button clicked'); + const newText = textarea.value.trim(); observationDiv.innerHTML = newText || 'Click edit to add your observations...'; observationDiv.style.color = newText ? '#666' : '#999'; @@ -633,21 +458,22 @@ export class NotesMinigame extends MinigameScene { // Remove editing elements textarea.remove(); buttonContainer.remove(); + + // Re-attach click event listener for the observation text + const newObservationDiv = observationDiv.cloneNode(true); + newObservationDiv.addEventListener('click', () => this.editObservations(newObservationDiv)); + observationDiv.parentNode.replaceChild(newObservationDiv, observationDiv); }); // Cancel button const cancelBtn = document.createElement('button'); cancelBtn.textContent = 'Cancel'; - cancelBtn.style.cssText = ` - background: #95a5a6; - color: white; - border: none; - padding: 8px 16px; - border-radius: 3px; - cursor: pointer; - font-size: 14px; - `; - cancelBtn.addEventListener('click', () => { + cancelBtn.className = 'notes-minigame-cancel-btn'; + cancelBtn.addEventListener('click', (e) => { + e.preventDefault(); + e.stopPropagation(); + console.log('Cancel button clicked'); + // Restore original text if (originalText) { observationDiv.innerHTML = originalText; @@ -660,6 +486,11 @@ export class NotesMinigame extends MinigameScene { // Remove editing elements textarea.remove(); buttonContainer.remove(); + + // Re-attach click event listener for the observation text + const newObservationDiv = observationDiv.cloneNode(true); + newObservationDiv.addEventListener('click', () => this.editObservations(newObservationDiv)); + observationDiv.parentNode.replaceChild(newObservationDiv, observationDiv); }); buttonContainer.appendChild(saveBtn); @@ -712,6 +543,16 @@ export class NotesMinigame extends MinigameScene { super.start(); console.log("Notes minigame started"); + // Always refresh collected notes to ensure we have the latest data + this.collectedNotes = this.getCollectedNotes(); + console.log("Refreshed collected notes on start:", this.collectedNotes); + + // Navigate to specific note if requested + if (this.params.navigateToNote !== null && this.params.navigateToNote !== undefined) { + this.currentNoteIndex = this.params.navigateToNote; + console.log('Navigated to requested note at index:', this.currentNoteIndex); + } + // Automatically add current note to notes system when starting if (this.autoAddToNotes && window.addNote) { const noteTitle = this.item?.scenarioData?.name || 'Note'; @@ -723,6 +564,24 @@ export class NotesMinigame extends MinigameScene { console.log('Note automatically added to notes system on start:', addedNote); // Refresh collected notes this.collectedNotes = this.getCollectedNotes(); + console.log('Refreshed collected notes after adding new note:', this.collectedNotes); + + // Find the index of the newly added note and navigate to it + const newNoteIndex = this.collectedNotes.findIndex(note => + note.title === noteTitle && note.text === noteText + ); + if (newNoteIndex !== -1) { + // Only navigate to the new note if we're not already navigating to a specific note + if (this.params.navigateToNote === null || this.params.navigateToNote === undefined) { + this.currentNoteIndex = newNoteIndex; + console.log('Navigated to newly added note at index:', newNoteIndex); + } + } + + // Update the UI to show all collected notes + this.updateDisplayedNote(); + this.updateCounter(); + this.updateNavigation(); // Automatically remove the note from the scene this.removeNoteFromScene(); @@ -760,12 +619,12 @@ export function showMissionBrief() { } }; - startNotesMinigame(missionBriefItem, window.gameScenario.scenario_brief, ''); + startNotesMinigame(missionBriefItem, window.gameScenario.scenario_brief, '', null, true); } // Function to start the notes minigame -export function startNotesMinigame(item, noteContent, observationText) { - console.log('Starting notes minigame with:', { item, noteContent, observationText }); +export function startNotesMinigame(item, noteContent, observationText, navigateToNote = null, hideNavigation = false) { + console.log('Starting notes minigame with:', { item, noteContent, observationText, navigateToNote, hideNavigation }); // Make sure the minigame is registered if (window.MinigameFramework && !window.MinigameFramework.registeredScenes['notes']) { @@ -784,6 +643,9 @@ export function startNotesMinigame(item, noteContent, observationText) { item: item, noteContent: noteContent, observationText: observationText, + autoAddToNotes: true, // Automatically add notes to the notes system + navigateToNote: navigateToNote, // Which note to navigate to + hideNavigation: hideNavigation, // Whether to hide navigation buttons onComplete: (success, result) => { if (success && result && result.addedToInventory) { console.log('NOTES SUCCESS - Added to inventory', result); diff --git a/js/systems/interactions.js b/js/systems/interactions.js index 95f9e4e..c997bb5 100644 --- a/js/systems/interactions.js +++ b/js/systems/interactions.js @@ -168,6 +168,25 @@ export function handleObjectInteraction(sprite) { return; } + // Handle the Notepad - open notes minigame + if (sprite.scenarioData.type === "notepad") { + if (window.startNotesMinigame) { + // Check if notes minigame is already running + if (window.MinigameFramework && window.MinigameFramework.currentMinigame) { + console.log('Notes minigame already running, navigating to notepad note instead'); + // If notes minigame is already running, just navigate to the notepad note + if (window.MinigameFramework.currentMinigame.navigateToNoteIndex) { + window.MinigameFramework.currentMinigame.navigateToNoteIndex(0); + } + return; + } + + // Navigate to the notepad note (index 0) when clicking the notepad + window.startNotesMinigame(sprite, sprite.scenarioData.text, sprite.scenarioData.observations, 0); + return; + } + } + // Handle biometric scanner interaction if (sprite.scenarioData.biometricType === 'fingerprint') { handleBiometricScan(sprite); diff --git a/js/systems/inventory.js b/js/systems/inventory.js index 618b263..b707022 100644 --- a/js/systems/inventory.js +++ b/js/systems/inventory.js @@ -30,6 +30,9 @@ export function initializeInventory() { // Store reference to container window.inventory.container = inventoryContainer; + // Add notepad to inventory + addNotepadToInventory(); + console.log('INVENTORY INITIALIZED', window.inventory); } @@ -191,7 +194,56 @@ function addToInventory(sprite) { } } +// Add notepad to inventory +function addNotepadToInventory() { + // Check if notepad is already in inventory + const notepadExists = window.inventory.items.some(item => + item && item.scenarioData && item.scenarioData.type === 'notepad' + ); + + if (notepadExists) { + console.log('Notepad already in inventory'); + return; + } + + // Create notepad item data + const notepadData = { + type: 'notepad', + name: 'Notepad', + takeable: true, + readable: true, + text: 'Use this notepad to review your collected notes and observations.', + observations: 'A handy notepad for keeping track of important information.' + }; + + // Create a mock sprite object for the notepad + const notepadSprite = { + name: 'notes5', + objectId: 'notepad_inventory', + scenarioData: notepadData + }; + + // Add to inventory + addToInventory(notepadSprite); + + // Also add the notepad as a note at the beginning of the notes collection + if (window.addNote) { + const notepadNote = window.addNote('Notepad', 'Use this notepad to review your collected notes and observations.', false); + if (notepadNote) { + // Move the notepad note to the beginning of the notes array + const notes = window.gameState.notes; + const notepadIndex = notes.findIndex(note => note.id === notepadNote.id); + if (notepadIndex !== -1) { + const notepadNoteItem = notes.splice(notepadIndex, 1)[0]; + notes.unshift(notepadNoteItem); // Add to beginning + console.log('Notepad note added to beginning of notes collection'); + } + } + } +} + // Export for global access window.initializeInventory = initializeInventory; window.processInitialInventoryItems = processInitialInventoryItems; -window.addToInventory = addToInventory; \ No newline at end of file +window.addToInventory = addToInventory; +window.addNotepadToInventory = addNotepadToInventory; \ No newline at end of file