diff --git a/assets/mini-games/backpack.png b/assets/mini-games/backpack.png new file mode 100644 index 0000000..2d704fb Binary files /dev/null and b/assets/mini-games/backpack.png differ diff --git a/assets/objects/chair-white-1.aseprite b/assets/objects/chair-white-1.aseprite new file mode 100644 index 0000000..0a09d53 Binary files /dev/null and b/assets/objects/chair-white-1.aseprite differ diff --git a/assets/objects/notes5.png b/assets/objects/notes5.png new file mode 100644 index 0000000..a0d51dc Binary files /dev/null and b/assets/objects/notes5.png differ diff --git a/css/minigames-framework.css b/css/minigames-framework.css index 400b7f1..8754aeb 100644 --- a/css/minigames-framework.css +++ b/css/minigames-framework.css @@ -97,15 +97,18 @@ display: flex; justify-content: center; gap: 10px; - margin-top: 20px; + margin-top: 10px; + position: absolute; + bottom: 20px; + left: 50%; + transform: translateX(-50%); } .minigame-button { background: #3498db; color: white; - border: none; + border: 4px solid #2980b9; padding: 10px 20px; - border-radius: 5px; cursor: pointer; font-family: 'VT323', monospace; font-size: 16px; @@ -155,8 +158,7 @@ height: 30px; background: #e74c3c; color: white; - border: none; - border-radius: 50%; + border: 4px solid #c0392b; cursor: pointer; font-family: 'VT323', monospace; font-size: 14px; diff --git a/css/notes.css b/css/notes.css new file mode 100644 index 0000000..bd7bb15 --- /dev/null +++ b/css/notes.css @@ -0,0 +1,319 @@ +/* Notes Minigame Styles */ + +/* Container styles */ +.notes-minigame-container { + width: 90%; + height: 85%; + padding: 20px; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .notes-minigame-container { + width: 95%; + height: 90%; + padding: 10px; + } + + .notes-minigame-game-container { + max-width: 100%; + padding: 1% 10% 6% 15%; /* Reduce padding on smaller screens */ + } + + .notes-minigame-text-box { + margin: 2% 4% 6% 8%; + padding: 30px; + } + + .notes-minigame-observation-container { + margin: 2% 4% 6% 8%; + } +} + +/* Game container */ +.notes-minigame-game-container { + width: 100%; + max-width: min(90vw, 90vh * (165/205)); /* Scale based on smaller dimension */ + position: relative; + margin: 0 auto; /* Centered with no top margin */ +} + +/* Notepad background container */ +.notes-minigame-notepad { + width: 100%; + aspect-ratio: 165 / 205; /* Match notepad image dimensions */ + background-image: url('../assets/mini-games/notepad.png'); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + position: relative; + image-rendering: -moz-crisp-edges; + image-rendering: -webkit-crisp-edges; + image-rendering: pixelated; + image-rendering: crisp-edges; +} + +/* Content area */ +.notes-minigame-content-area { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + padding: 2% 12% 8% 18%; + font-family: 'Courier New', monospace; + font-size: 18px; + line-height: 1.5; + color: #333; + background: transparent; + margin: 0; + overflow: auto; /* Allow scrolling if content is too long */ + box-sizing: border-box; +} + +/* Text box container */ +.notes-minigame-text-box { + margin: 3% 6% 8% 10%; + padding: 15px; + background: #fefefe; + border: 4px solid #ddd; + 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; +} + +/* Celotape effect */ +.notes-minigame-celotape { + position: absolute; + top: -14px; + left: 10%; + right: 10%; + 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: 4px solid rgba(200,200,200,0.8); + box-shadow: + 0 2px 4px rgba(0,0,0,0.1), + inset 0 2px 0 rgba(255,255,255,0.9); + z-index: 1; +} + +/* Binder holes effect */ +.notes-minigame-binder-holes { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + width: 8px; + height: 80px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.notes-minigame-binder-hole { + width: 8px; + height: 8px; + background: #666; + border: 2px solid #333; +} + +/* Note title */ +.notes-minigame-title { + margin: 0 6% 3% 10%; + font-family: 'Press Start 2P', monospace; + font-size: 20px; + font-weight: bold; + color: #2c3e50; + text-decoration: underline; + text-decoration-color: #3498db; + text-underline-offset: 3px; + text-align: center; +} + +/* Note text content */ +.notes-minigame-text { + margin-left: 30px; + white-space: pre-wrap; + word-wrap: break-word; + color: #333; + font-family: 'VT323', monospace; +} + +/* Observation container */ +.notes-minigame-observation-container { + margin: 3% 6% 8% 10%; + position: relative; +} + +/* Observation text */ +.notes-minigame-observation { + font-family: 'Pixelify Sans', '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: 4px dashed #ccc; + background: rgba(255, 255, 255, 0.3); + cursor: pointer; + transition: background-color 0.2s ease; +} + +.notes-minigame-observation:hover { + background: rgba(255, 255, 255, 0.5); + border-color: #999; +} + +.notes-minigame-observation.empty { + color: #999; +} + +/* Edit button */ +.notes-minigame-edit-btn { + position: absolute; + top: -8px; + right: -8px; + background: #3498db; + color: white; + border: 4px solid #2980b9; + 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; +} + +.notes-minigame-edit-btn:hover { + background: #2980b9; +} + +/* Navigation container */ +.notes-minigame-nav-container { + position: absolute; + bottom: 80px; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 15px; + z-index: 10; +} + +/* Search input */ +.notes-minigame-search { + padding: 8px 12px; + border: 4px solid #555; + background: rgba(0,0,0,0.7); + color: white; + font-size: 14px; + font-family: 'VT323', monospace; + width: 200px; + margin-right: 10px; +} + +/* Navigation buttons */ +.notes-minigame-nav-button { + background: #95a5a6; + color: white; + border: 4px solid #7f8c8d; + padding: 8px 15px; + cursor: pointer; + font-size: 14px; + font-weight: bold; + transition: background-color 0.3s ease; +} + +.notes-minigame-nav-button:hover { + background: #7f8c8d; +} + +/* Note counter */ +.notes-minigame-counter { + color: white; + font-size: 14px; + display: flex; + align-items: center; + padding: 8px 15px; + background: rgba(0,0,0,0.5); + border: 4px solid rgba(255,255,255,0.3); +} + +/* Action buttons container */ +.notes-minigame-buttons-container { + position: absolute; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 15px; + z-index: 10; +} + + +/* Edit interface styles */ +.notes-minigame-edit-textarea { + width: calc(100% - 20px); /* Account for padding */ + min-height: 60px; + font-family: 'Pixelify Sans', 'Comic Sans MS', cursive; + font-size: 18px; + line-height: 1.4; + color: #666; + border: 4px solid #3498db; + padding: 10px; + background: rgba(255, 255, 255, 0.9); + resize: vertical; + outline: none; + box-sizing: border-box; +} + +.notes-minigame-edit-buttons { + margin-top: 10px; + display: flex; + gap: 10px; + justify-content: flex-end; +} + +.notes-minigame-save-btn { + background: #2ecc71; + color: white; + border: 4px solid #27ae60; + padding: 8px 16px; + cursor: pointer; + font-size: 14px; + font-family: 'VT323', monospace; +} + +.notes-minigame-save-btn:hover { + background: #27ae60; +} + +.notes-minigame-cancel-btn { + background: #95a5a6; + color: white; + border: 4px solid #7f8c8d; + padding: 8px 16px; + cursor: pointer; + font-size: 14px; + font-family: 'VT323', monospace; +} + +.notes-minigame-cancel-btn:hover { + background: #7f8c8d; +} diff --git a/index_new.html b/index_new.html index 27cee60..9e4770b 100644 --- a/index_new.html +++ b/index_new.html @@ -32,6 +32,7 @@ + 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