mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
feat: Normalize keyPins in starting inventory and generate cuts from lock configuration in minigames
This commit is contained in:
@@ -682,6 +682,16 @@ function normalizeScenarioKeyPins(scenario) {
|
||||
return Math.round(25 + (value / 100) * 40);
|
||||
}
|
||||
|
||||
// Normalize keyPins in startItemsInInventory (for starting keys)
|
||||
if (scenario.startItemsInInventory && Array.isArray(scenario.startItemsInInventory)) {
|
||||
scenario.startItemsInInventory.forEach((item, index) => {
|
||||
if (item.keyPins && Array.isArray(item.keyPins)) {
|
||||
item.keyPins = item.keyPins.map(convertKeyPin);
|
||||
console.log(`🔄 Normalized startItem keyPins [${index}] (${item.type} "${item.name}"):`, item.keyPins);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Iterate through all rooms
|
||||
Object.entries(scenario.rooms).forEach(([roomId, roomData]) => {
|
||||
if (!roomData) return;
|
||||
|
||||
@@ -301,16 +301,8 @@ 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);
|
||||
}
|
||||
// NOTE: keyPins are already normalized by normalizeScenarioKeyPins() in game.js
|
||||
// Do NOT normalize here again to avoid double normalization
|
||||
|
||||
sprite.scenarioData = scenarioObj;
|
||||
sprite.interactable = true; // Mark scenario items as interactable
|
||||
|
||||
@@ -121,10 +121,32 @@ export function startLockpickingMinigame(lockable, scene, difficulty = 'medium',
|
||||
item.scenarioData.type === 'key'
|
||||
);
|
||||
individualKeys.forEach(key => {
|
||||
let cuts = key.scenarioData.cuts;
|
||||
|
||||
// If no cuts but keyPins exists, keyPins represents the LOCK configuration this key matches
|
||||
// Generate the cuts that would work with that lock configuration
|
||||
if (!cuts && (key.scenarioData.keyPins || key.keyPins)) {
|
||||
const lockKeyPins = key.scenarioData.keyPins || key.keyPins;
|
||||
console.log(`Generating cuts from lock keyPins for key "${key.scenarioData.name}":`, lockKeyPins);
|
||||
|
||||
// Generate cuts that match this lock configuration
|
||||
// Use the generateKeyCutsForLock function with the key's keyPins as the lock config
|
||||
cuts = lockKeyPins.map(keyPinLength => {
|
||||
const keyBladeTop_world = 175;
|
||||
const shearLine_world = 155;
|
||||
const gapFromKeyBladeTopToShearLine = keyBladeTop_world - shearLine_world;
|
||||
const cutDepth_needed = keyPinLength - gapFromKeyBladeTopToShearLine;
|
||||
const clampedCutDepth = Math.max(0, Math.min(110, cutDepth_needed));
|
||||
return Math.round(clampedCutDepth);
|
||||
});
|
||||
|
||||
console.log(`Generated cuts for key "${key.scenarioData.name}":`, cuts);
|
||||
}
|
||||
|
||||
keys.push({
|
||||
id: key.scenarioData.key_id,
|
||||
name: key.scenarioData.name,
|
||||
cuts: key.scenarioData.cuts || []
|
||||
cuts: cuts || []
|
||||
});
|
||||
});
|
||||
|
||||
@@ -135,10 +157,29 @@ export function startLockpickingMinigame(lockable, scene, difficulty = 'medium',
|
||||
);
|
||||
if (keyRingItem && keyRingItem.scenarioData.allKeys) {
|
||||
keyRingItem.scenarioData.allKeys.forEach(keyData => {
|
||||
let cuts = keyData.cuts;
|
||||
|
||||
// If no cuts but keyPins exists, generate cuts from lock configuration
|
||||
if (!cuts && keyData.keyPins) {
|
||||
const lockKeyPins = keyData.keyPins;
|
||||
console.log(`Generating cuts from lock keyPins for key ring key "${keyData.name}":`, lockKeyPins);
|
||||
|
||||
cuts = lockKeyPins.map(keyPinLength => {
|
||||
const keyBladeTop_world = 175;
|
||||
const shearLine_world = 155;
|
||||
const gapFromKeyBladeTopToShearLine = keyBladeTop_world - shearLine_world;
|
||||
const cutDepth_needed = keyPinLength - gapFromKeyBladeTopToShearLine;
|
||||
const clampedCutDepth = Math.max(0, Math.min(110, cutDepth_needed));
|
||||
return Math.round(clampedCutDepth);
|
||||
});
|
||||
|
||||
console.log(`Generated cuts for key ring key "${keyData.name}":`, cuts);
|
||||
}
|
||||
|
||||
keys.push({
|
||||
id: keyData.key_id,
|
||||
name: keyData.name,
|
||||
cuts: keyData.cuts || []
|
||||
cuts: cuts || []
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -220,6 +261,32 @@ export function startKeySelectionMinigame(lockable, type, playerKeys, requiredKe
|
||||
const inventoryKeys = keysToShow.map(key => {
|
||||
// Generate cuts data if not present
|
||||
let cuts = key.scenarioData.cuts;
|
||||
|
||||
// If no cuts but keyPins exists, keyPins represents the LOCK configuration this key matches
|
||||
// Generate the cuts that would work with that lock configuration
|
||||
if (!cuts && (key.scenarioData.keyPins || key.keyPins)) {
|
||||
const lockKeyPins = key.scenarioData.keyPins || key.keyPins;
|
||||
console.log(`Generating cuts from lock keyPins for key "${key.scenarioData.name}":`, lockKeyPins);
|
||||
|
||||
// Generate cuts that match this lock configuration
|
||||
// keyPins on a key represent the lock's pin configuration, not the key's own properties
|
||||
cuts = lockKeyPins.map(keyPinLength => {
|
||||
const keyBladeTop_world = 175; // Key blade top position
|
||||
const shearLine_world = 155; // Shear line position
|
||||
const gapFromKeyBladeTopToShearLine = keyBladeTop_world - shearLine_world; // 20
|
||||
|
||||
// Calculate the required cut depth
|
||||
const cutDepth_needed = keyPinLength - gapFromKeyBladeTopToShearLine;
|
||||
|
||||
// Clamp to valid range (0 to 110, which is key blade height)
|
||||
const clampedCutDepth = Math.max(0, Math.min(110, cutDepth_needed));
|
||||
return Math.round(clampedCutDepth);
|
||||
});
|
||||
|
||||
console.log(`Generated cuts for key "${key.scenarioData.name}":`, cuts);
|
||||
}
|
||||
|
||||
// If still no cuts, generate from lock configuration
|
||||
if (!cuts) {
|
||||
// Generate cuts that match the lock's pin configuration
|
||||
cuts = generateKeyCutsForLock(key, lockable);
|
||||
@@ -229,7 +296,7 @@ export function startKeySelectionMinigame(lockable, type, playerKeys, requiredKe
|
||||
id: key.scenarioData.key_id,
|
||||
name: key.scenarioData.name,
|
||||
cuts: cuts,
|
||||
pinCount: key.scenarioData.pinCount || 4, // Default to 4 pins to match most locks
|
||||
pinCount: cuts.length || key.scenarioData.pinCount || 4, // Use cuts length or default to 4 pins
|
||||
matchesLock: doesKeyMatchLock(key.scenarioData.key_id, lockId) // Add flag for matching
|
||||
};
|
||||
});
|
||||
@@ -363,6 +430,32 @@ export function startKeySelectionMinigame(lockable, type, playerKeys, requiredKe
|
||||
// Regenerate keys with the actual lock configuration now that it's been created
|
||||
const updatedInventoryKeys = playerKeys.map(key => {
|
||||
let cuts = key.scenarioData.cuts;
|
||||
|
||||
// If no cuts but keyPins exists, keyPins represents the LOCK configuration this key matches
|
||||
// Generate the cuts that would work with that lock configuration
|
||||
if (!cuts && (key.scenarioData.keyPins || key.keyPins)) {
|
||||
const lockKeyPins = key.scenarioData.keyPins || key.keyPins;
|
||||
console.log(`Generating cuts from lock keyPins for key "${key.scenarioData.name}":`, lockKeyPins);
|
||||
|
||||
// Generate cuts that match this lock configuration
|
||||
// keyPins on a key represent the lock's pin configuration, not the key's own properties
|
||||
cuts = lockKeyPins.map(keyPinLength => {
|
||||
const keyBladeTop_world = 175; // Key blade top position
|
||||
const shearLine_world = 155; // Shear line position
|
||||
const gapFromKeyBladeTopToShearLine = keyBladeTop_world - shearLine_world; // 20
|
||||
|
||||
// Calculate the required cut depth
|
||||
const cutDepth_needed = keyPinLength - gapFromKeyBladeTopToShearLine;
|
||||
|
||||
// Clamp to valid range (0 to 110, which is key blade height)
|
||||
const clampedCutDepth = Math.max(0, Math.min(110, cutDepth_needed));
|
||||
return Math.round(clampedCutDepth);
|
||||
});
|
||||
|
||||
console.log(`Generated cuts for key "${key.scenarioData.name}":`, cuts);
|
||||
}
|
||||
|
||||
// If still no cuts, generate from lock configuration
|
||||
if (!cuts) {
|
||||
cuts = generateKeyCutsForLock(key, lockable);
|
||||
}
|
||||
@@ -371,7 +464,7 @@ export function startKeySelectionMinigame(lockable, type, playerKeys, requiredKe
|
||||
id: key.scenarioData.key_id,
|
||||
name: key.scenarioData.name,
|
||||
cuts: cuts,
|
||||
pinCount: key.scenarioData.pinCount || 4
|
||||
pinCount: cuts.length || key.scenarioData.pinCount || 4
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user