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.

This commit is contained in:
Z. Cliffe Schreuders
2025-10-10 15:20:04 +01:00
parent 039a76d5cc
commit 378045dded
11 changed files with 663 additions and 364 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

BIN
assets/objects/notes5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

View File

@@ -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;

319
css/notes.css Normal file
View File

@@ -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;
}

View File

@@ -32,6 +32,7 @@
<link rel="stylesheet" href="css/inventory.css">
<link rel="stylesheet" href="css/minigames-framework.css">
<link rel="stylesheet" href="css/modals.css">
<link rel="stylesheet" href="css/notes.css">
<!-- External JavaScript libraries -->
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.min.js"></script>

View File

@@ -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 = `
<button class="minigame-close-button" id="minigame-close">&times;</button>
<div class="minigame-header">
@@ -20,9 +23,7 @@ export class MinigameScene {
</div>
<div class="minigame-game-container"></div>
<div class="minigame-message-container"></div>
<div class="minigame-controls">
<button class="minigame-button" id="minigame-cancel">Cancel</button>
</div>
${showCancel ? `<div class="minigame-controls"><button class="minigame-button" id="minigame-cancel">${this.params.cancelText || 'Cancel'}</button></div>` : ''}
`;
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;
}
}
}

View File

@@ -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');
}
},

View File

@@ -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 = `
<h3>Reading Notes</h3>
<p>Note automatically added to your collection</p>
`;
// 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 = '<em>Click edit to add your observations...</em>';
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 = '<em>Click edit to add your observations...</em>';
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 || '<em>Click edit to add your observations...</em>';
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);

View File

@@ -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);

View File

@@ -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;
window.addToInventory = addToInventory;
window.addNotepadToInventory = addNotepadToInventory;