From 1228bc15fe1b97d4b80156d4d399f4dd477703dd Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Tue, 28 Oct 2025 13:31:20 +0000 Subject: [PATCH] feat: Normalize keyPins from 0-100 scale to 25-65 scale across scenarios and rooms --- js/core/game.js | 50 ++++++++++++++++++++++++++++++++++++++++ js/core/rooms.js | 11 +++++++++ scenarios/ceo_exfil.json | 16 ++++++------- 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/js/core/game.js b/js/core/game.js index d26ac12..352efff 100644 --- a/js/core/game.js +++ b/js/core/game.js @@ -418,6 +418,9 @@ export function create() { } gameScenario = window.gameScenario; + // Normalize keyPins in all rooms and objects from 0-100 scale to 25-65 scale + normalizeScenarioKeyPins(gameScenario); + // Debug: log what we loaded console.log('🎮 Loaded gameScenario with rooms:', Object.keys(gameScenario?.rooms || {})); if (gameScenario?.rooms?.office1) { @@ -669,6 +672,53 @@ function findObjectsAtPosition(worldX, worldY) { return objectsAtPosition; } +// Normalize keyPins from 0-100 scale to 25-65 scale in entire scenario +function normalizeScenarioKeyPins(scenario) { + if (!scenario || !scenario.rooms) { + return; + } + + // Helper function to convert a single keyPins value + function convertKeyPin(value) { + // Convert from 0-100 scale to 25-65 scale + // Formula: 25 + (value / 100) * 40 + return Math.round(25 + (value / 100) * 40); + } + + // Iterate through all rooms + Object.entries(scenario.rooms).forEach(([roomId, roomData]) => { + if (!roomData) return; + + // Convert room-level keyPins (for door locks) + if (roomData.keyPins && Array.isArray(roomData.keyPins)) { + roomData.keyPins = roomData.keyPins.map(convertKeyPin); + console.log(`🔄 Normalized room keyPins for ${roomId}:`, roomData.keyPins); + } + + // Convert keyPins for all objects in the room + if (roomData.objects && Array.isArray(roomData.objects)) { + roomData.objects.forEach((obj, index) => { + if (obj.keyPins && Array.isArray(obj.keyPins)) { + obj.keyPins = obj.keyPins.map(convertKeyPin); + console.log(`🔄 Normalized object keyPins for ${roomId}[${index}] (${obj.type}):`, obj.keyPins); + } + + // Also check contents of objects (for keys in briefcases, etc.) + if (obj.contents && Array.isArray(obj.contents)) { + obj.contents.forEach((content, contentIndex) => { + if (content.keyPins && Array.isArray(content.keyPins)) { + content.keyPins = content.keyPins.map(convertKeyPin); + console.log(`🔄 Normalized content keyPins for ${roomId}[${index}].contents[${contentIndex}] (${content.type}):`, content.keyPins); + } + }); + } + }); + } + }); + + console.log('✓ All keyPins normalized to 25-65 range'); +} + // Hide a room function hideRoom(roomId) { if (window.rooms[roomId]) { diff --git a/js/core/rooms.js b/js/core/rooms.js index 9a31006..2668877 100644 --- a/js/core/rooms.js +++ b/js/core/rooms.js @@ -301,6 +301,17 @@ function applyTiledProperties(sprite, tiledItem) { * Stores scenario data and makes sprite interactive */ function applyScenarioProperties(sprite, scenarioObj, roomId, index) { + // Convert keyPins from 0-100 scale to 25-65 scale if needed + if (scenarioObj.keyPins && Array.isArray(scenarioObj.keyPins)) { + scenarioObj.keyPins = scenarioObj.keyPins.map(value => { + // Convert from 0-100 scale to 25-65 scale + // Formula: 25 + (value / 100) * 40 + const converted = 25 + (value / 100) * 40; + return Math.round(converted); + }); + console.log(`🔄 Converted keyPins to valid range (25-65):`, scenarioObj.keyPins); + } + sprite.scenarioData = scenarioObj; sprite.interactable = true; // Mark scenario items as interactable sprite.name = scenarioObj.name; diff --git a/scenarios/ceo_exfil.json b/scenarios/ceo_exfil.json index 969ebfe..150ba66 100644 --- a/scenarios/ceo_exfil.json +++ b/scenarios/ceo_exfil.json @@ -86,7 +86,7 @@ "name": "Office Key", "takeable": true, "key_id": "office1_key", - "keyPins": [65.5, 25.5, 65.5, 25.5], + "keyPins": [100, 0, 100, 0], "observations": "A key to access the office areas" }, { @@ -102,7 +102,7 @@ "locked": true, "lockType": "key", "requires": "office1_key", - "keyPins": [65.5, 25.5, 65.5, 25.5], + "keyPins": [100, 0, 100, 0], "difficulty": "easy", "door_sign": "4A Hot Desks", @@ -170,7 +170,7 @@ "name": "CEO Office Key", "takeable": true, "key_id": "ceo_office_key", - "keyPins": [10, 20, 30, 40], + "keyPins": [0, 50, 100, 150], "observations": "A spare key to the CEO's office, carelessly left behind" } ] @@ -210,7 +210,7 @@ "locked": true, "lockType": "key", "requires": "ceo_office_key", - "keyPins": [10, 20, 30, 40], + "keyPins": [0, 50, 100, 150], "difficulty": "easy", "objects": [ { @@ -233,7 +233,7 @@ "locked": true, "lockType": "key", "requires": "briefcase_key", - "keyPins": [45, 35, 25, 15], + "keyPins": [50, 25, 0, 75], "difficulty": "medium", "observations": "An expensive leather briefcase with a sturdy lock", "contents": [ @@ -250,7 +250,7 @@ "name": "Safe Key", "takeable": true, "key_id": "safe_key", - "keyPins": [52, 29, 44, 37], + "keyPins": [68, 10, 48, 30], "observations": "A heavy-duty safe key hidden behind server equipment" } ] @@ -283,7 +283,7 @@ "locked": true, "lockType": "key", "requires": "safe_key", - "keyPins": [52, 29, 44, 37], + "keyPins": [68, 10, 48, 30], "difficulty": "hard", "observations": "A well-hidden wall safe behind a painting", "contents": [ @@ -319,7 +319,7 @@ "name": "Briefcase Key", "takeable": true, "key_id": "briefcase_key", - "keyPins": [45, 35, 25, 15], + "keyPins": [50, 25, 0, 75], "observations": "A small key labeled 'Personal - Do Not Copy'" } ]