From 48b1ad3bbfc24ab6385aff4f09b04eb8b5cac636 Mon Sep 17 00:00:00 2001 From: "Z. Cliffe Schreuders" Date: Wed, 22 Oct 2025 00:10:26 +0100 Subject: [PATCH] Refactor Lockpicking Minigame: Update button functionality for mode switching between key and lockpicking modes. Introduce new icons for keyway, password, and pin in the inventory. Enhance interaction logic for locked objects and doors, including visual indicators. Clean up CSS styles for improved layout and user experience. Remove unused assets and streamline code for better performance. --- assets/icons/keyway.png | Bin 0 -> 418 bytes assets/icons/password.png | Bin 0 -> 116 bytes assets/icons/pin.png | Bin 0 -> 607 bytes assets/objects/pc.png | Bin 0 -> 830 bytes assets/objects/pc13.png | Bin 856 -> 0 bytes css/container-minigame.css | 4 +- css/main.css | 85 +------- index.html | 2 +- js/core/game.js | 3 + .../lockpicking/lockpicking-game-phaser.js | 188 +++++++++++++++++- js/systems/interactions.js | 162 +++++++++++++++ js/systems/minigame-starters.js | 44 ++++ js/systems/unlock-system.js | 54 +++-- 13 files changed, 427 insertions(+), 115 deletions(-) create mode 100644 assets/icons/keyway.png create mode 100644 assets/icons/password.png create mode 100644 assets/icons/pin.png create mode 100644 assets/objects/pc.png delete mode 100644 assets/objects/pc13.png diff --git a/assets/icons/keyway.png b/assets/icons/keyway.png new file mode 100644 index 0000000000000000000000000000000000000000..e84da801c83bdf58c2a0c413b2500aa039f83486 GIT binary patch literal 418 zcmV;T0bTxyP)Px$TuDShR5*>5Q_W7oKoFi?P~rg&DkKFeg(^SsLX(mnfHcHNqVW;D^wNjwr7z(N zG|}k6XaWg=$YPUiB>Dt`l6rA#)vm?4?d!RD~lb!8?_-&DxNM0!It7?z%y6Cj~ zZaSTl!>f$LVAIf1E?bZ_?f9}Cev;j&;BD2VZS|Fu(6gZ~y=R M07*qoM6N<$g0o+|4FCWD literal 0 HcmV?d00001 diff --git a/assets/icons/password.png b/assets/icons/password.png new file mode 100644 index 0000000000000000000000000000000000000000..19668b5491d7c8313d9c5f67093dc427bdaae21d GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|^gLZ0Lo9le z6C_xhIapej{^RHH{@dT*%WH7)^27*6WzDXMdp9Ls&6)J2k12|Y!PHs6;rQdFUw}Fp NJYD@<);T3K0RW9Px%8A(JzR5*>LlRs!vQ5431=e(Quk~Y!eS$1~ zLkES5*ujDwyS85FWR2;M}3WA~`rpasb-gQX&(ue5c-OhLK{W#z6+$*;q zJhA-8GL;|SdAs=zL;yh@hk?E`td_PA5u~l38|b63wh`64l@y~_`cbR}5l#=^J#qm= zgqh)9mKUD4%>faXXRk$P01SYr@?q%_qKb%es7)+=h8NcnZEK=jx-lQs0CF??(E5!= zELSp>qEWBMv{Y9&^}SkDCtMFNnZ$%)NU^llYEuN&zcVP7xBq0&sPBOYxy3nVhI)Yx zgWTdAPltLBC31^%t^F7SYf;BAI5GwZjxmVP(L`{Z1OS60W2i9*9RnGixNlw0i{*9Q zB>VeuE}oad_d8sSaY?u?+MPbe%K9cN>swsNe4|+2p}tq6u(rumcAQ^d-m_ZT#`o(? zWyhJyjuwy7 z2>C)eG6TrJDM!=lFt~NkcBM11ypAyh&1Ot9#?U;XspH@{29r77!=2&+fwhD-#BT=7 z3|ytKR*Ghh2%D`Z3kYPihAT1Yt;MEq)LX20@F3XuDe>v=;FU tqJp#yq6nFu6R~zx1PfUE@1L%!{06Srz_35ns<{9F002ovPDHLkV1hn07VZE5 literal 0 HcmV?d00001 diff --git a/assets/objects/pc.png b/assets/objects/pc.png new file mode 100644 index 0000000000000000000000000000000000000000..e583626cab3faf1543a63557bcbcee96af8818c9 GIT binary patch literal 830 zcmV-E1Ht@>P)Px%_(?=TR7i={m)lDeQ5?s=vp3V#&C4=7V=813B4KSs4{1SR)b2(ysq_#8(Z5j8 zLk~U$Jx0_%NYq23kRU}VLR3@`7*Px2hGj~y?!|R4>W;d%>0x)y&N$mP|*40C?x zoc+ybe&_t={FXvqHr6FTql|`fq|&Q08-T1&RM7v5QsdJgHM}=D=uA2Q0M9u{|L)<} zFg4Lg_qX51=sL?11KVWkq03{a~FW<7o~#!Ws}^@0kZwac!elj1#{`Bob$M#caD z`_6@7%ovfT8#Q)1lnJqM zRnVDqWDBU3B0?h6)N@Oruj@0KOL?gREM-{)zg5C^m?uyGkcn*(NK|Xrk|swwla9bh z6=6!giqem!*?EaerABp2(>o6&N)6PO_t3x8+aJU;6te5mJrAC~yQRoD0LUh@nt^1q zXU46H51uHe+XtuHheSG!i6ILnhAiMY2Ud+{bf3Kso^#;J;DQY1`&hLsIWz;UuO-pa z8CN)QJp3uM`=Va-MZGW$41%I^$AxKN5Ov92=GmPsa~`+nK4^jg0CK+ASeGzz z@S0-6jd^cL2QRO)xbVnN+5m_R04LM6c(OFQxwA|Qh$!j9rEO8~^*%+PY9K9#;7(~v zX}=RvwXRZatee#C4Ym4zBh=8?BNVFyMQvB4WNB|Ya}mimFVIGJU?sJTaA+E<<%N>8 zx#kdlMLpzRSHWVDFJzXPVvrDWHBlSgfjQq7{0I+g0;N!7Ur1|ZGsPgOj~A_zOQ~b8 z6W-ugEb@L?^lYq4FdE8XZ)`_6wt!DlcVxiSW{P_?5F7shh)@mtuL`NeqU?84;BDR1 zA7@9&68-}|egFUf literal 0 HcmV?d00001 diff --git a/assets/objects/pc13.png b/assets/objects/pc13.png deleted file mode 100644 index 8a3cd8061910ed33dc108730dde445bb5aa42f9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 856 zcmV-e1E>6nP)Px&5=lfsR7i={mdk4sQ51*2Nt)D}TJ3{rQrm)6L`14laiMjgR5WR^L@O=?QFQB0 z!G#O|1Vyw96`KVPAOT3HC;r zcpxBbUmn(I0?F%2DH$&(l7T8K4DjOh3XB?34VUnF$c(LIq~9sV9gRc$h%CTj zw}>NPRJt8fpg!KNDA+n)(^M?V0;nj>5_(@w?V5yu0?3Ta5=ha?j!{#AEOv{4Q7hss zx)gmJQ{K~3K9vzwkM_?!kRl^cvpz$A(w_4nu2aaaU8noF^8C0i;{dYBtZ5*P_m_t? zx<5Qc-mU=Nt^o0Lnpf8;VOVoahlNHp4(>F2T9dtkQli zWazu9^?Ti9^lTW_|GPu=4V}4}DnUj6YNs@5Z{NC;#fLS&Qv;j6T#M=Dz
Crypto Workstation - +
diff --git a/js/core/game.js b/js/core/game.js index f2f6936..3635623 100644 --- a/js/core/game.js +++ b/js/core/game.js @@ -63,6 +63,9 @@ export function preload() { this.load.image('fingerprint', 'assets/objects/fingerprint_small.png'); this.load.image('lockpick', 'assets/objects/lockpick.png'); this.load.image('spoofing_kit', 'assets/objects/office-misc-headphones.png'); + this.load.image('keyway', 'assets/icons/keyway.png'); + this.load.image('password', 'assets/icons/password.png'); + this.load.image('pin', 'assets/icons/pin.png'); // Load new object sprites from Tiled map tileset // These are the key objects that appear in the new room_reception2.json diff --git a/js/minigames/lockpicking/lockpicking-game-phaser.js b/js/minigames/lockpicking/lockpicking-game-phaser.js index 8c5cd3c..5615609 100644 --- a/js/minigames/lockpicking/lockpicking-game-phaser.js +++ b/js/minigames/lockpicking/lockpicking-game-phaser.js @@ -59,6 +59,13 @@ export class LockpickingMinigamePhaser extends MinigameScene { this.skipStartingKey = params.skipStartingKey || false; // Skip creating initial key if true this.keySelectionMode = false; // Track if we're in key selection mode + // Mode switching settings + this.canSwitchToPickMode = params.canSwitchToPickMode || false; // Allow switching from key to pick mode + this.inventoryKeys = params.inventoryKeys || null; // Stored for mode switching + this.requirefKeyId = params.requiredKeyId || null; // Track required key ID + this.canSwitchToKeyMode = params.canSwitchToKeyMode || false; // Allow switching from lockpick to key mode + this.availableKeys = params.availableKeys || null; // Keys available for mode switching + // Sound effects this.sounds = {}; @@ -74,7 +81,9 @@ export class LockpickingMinigamePhaser extends MinigameScene { thresholdSensitivity: this.thresholdSensitivity, highlightBindingOrder: this.highlightBindingOrder, highlightPinAlignment: this.highlightPinAlignment, - liftSpeed: this.liftSpeed + liftSpeed: this.liftSpeed, + canSwitchToPickMode: this.canSwitchToPickMode, + canSwitchToKeyMode: this.canSwitchToKeyMode }); this.pins = []; @@ -278,6 +287,44 @@ export class LockpickingMinigamePhaser extends MinigameScene {
`; + // Add mode switch button if applicable + if (this.canSwitchToPickMode && this.keyMode) { + const buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = ` + display: flex; + gap: 10px; + margin-top: 10px; + justify-content: center; + `; + + const switchModeBtn = document.createElement('button'); + switchModeBtn.className = 'minigame-button'; + switchModeBtn.id = 'lockpicking-switch-mode-btn'; + switchModeBtn.innerHTML = 'Lockpick Switch to Lockpicking'; + switchModeBtn.onclick = () => this.switchToPickMode(); + + buttonContainer.appendChild(switchModeBtn); + itemDisplayDiv.appendChild(buttonContainer); + } else if (this.canSwitchToKeyMode && !this.keyMode) { + // Show switch to key mode button when in lockpicking mode + const buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = ` + display: flex; + gap: 10px; + margin-top: 10px; + justify-content: center; + `; + + const switchModeBtn = document.createElement('button'); + switchModeBtn.className = 'minigame-button'; + switchModeBtn.id = 'lockpicking-switch-to-keys-btn'; + switchModeBtn.innerHTML = 'Key Switch to Key Mode'; + switchModeBtn.onclick = () => this.switchToKeyMode(); + + buttonContainer.appendChild(switchModeBtn); + itemDisplayDiv.appendChild(buttonContainer); + } + // Insert before the game container this.gameContainer.parentElement.insertBefore(itemDisplayDiv, this.gameContainer); } @@ -4481,4 +4528,143 @@ export class LockpickingMinigamePhaser extends MinigameScene { }); } } + + switchToPickMode() { + // Switch from key selection mode to lockpicking mode + console.log('Switching from key mode to lockpicking mode'); + + // Hide the mode switch button + const switchBtn = document.getElementById('lockpicking-switch-mode-btn'); + if (switchBtn) { + switchBtn.style.display = 'none'; + } + + // Exit key mode + this.keyMode = false; + this.keySelectionMode = false; + + // Clean up key selection UI if visible + if (this.keySelectionContainer) { + this.keySelectionContainer.destroy(); + this.keySelectionContainer = null; + } + + // Clean up any key visuals + if (this.keyGroup) { + this.keyGroup.destroy(); + this.keyGroup = null; + } + if (this.keyClickZone) { + this.keyClickZone.destroy(); + this.keyClickZone = null; + } + + // Show lockpicking tools + if (this.tensionWrench) { + this.tensionWrench.setVisible(true); + } + if (this.hookGroup) { + this.hookGroup.setVisible(true); + } + if (this.wrenchText) { + this.wrenchText.setVisible(true); + } + if (this.hookPickLabel) { + this.hookPickLabel.setVisible(true); + } + + // Reset pins to original positions + this.resetPinsToOriginalPositions(); + + // Update feedback + this.updateFeedback("Lockpicking mode - Apply tension first, then lift pins in binding order"); + } + + showLockpickingTools() { + // Show tension wrench and hook pick in lockpicking mode + if (this.tensionWrench) { + this.tensionWrench.setVisible(true); + } + if (this.hookGroup) { + this.hookGroup.setVisible(true); + } + + // Show labels + if (this.wrenchText) { + this.wrenchText.setVisible(true); + } + if (this.hookPickLabel) { + this.hookPickLabel.setVisible(true); + } + } + + switchToKeyMode() { + // Switch from lockpicking mode to key selection mode + console.log('Switching from lockpicking mode to key mode'); + + // Hide the mode switch button + const switchBtn = document.getElementById('lockpicking-switch-to-keys-btn'); + if (switchBtn) { + switchBtn.style.display = 'none'; + } + + // Enter key mode + this.keyMode = true; + this.keySelectionMode = true; + + // Hide lockpicking tools + if (this.tensionWrench) { + this.tensionWrench.setVisible(false); + } + if (this.hookGroup) { + this.hookGroup.setVisible(false); + } + if (this.wrenchText) { + this.wrenchText.setVisible(false); + } + if (this.hookPickLabel) { + this.hookPickLabel.setVisible(false); + } + + // Reset pins to original positions + this.resetPinsToOriginalPositions(); + + // Add mode switch back button (can switch back to lockpicking if available) + if (this.canSwitchToPickMode) { + const itemDisplayDiv = document.querySelector('.lockpicking-item-section'); + if (itemDisplayDiv) { + // Remove any existing button container + const existingButtonContainer = itemDisplayDiv.querySelector('div[style*="margin-top"]'); + if (existingButtonContainer) { + existingButtonContainer.remove(); + } + + // Add new button container + const buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = ` + display: flex; + gap: 10px; + margin-top: 10px; + justify-content: center; + `; + + const switchModeBtn = document.createElement('button'); + switchModeBtn.className = 'minigame-button'; + switchModeBtn.id = 'lockpicking-switch-mode-btn'; + switchModeBtn.innerHTML = 'Lockpick Switch to Lockpicking'; + switchModeBtn.onclick = () => this.switchToPickMode(); + + buttonContainer.appendChild(switchModeBtn); + itemDisplayDiv.appendChild(buttonContainer); + } + } + + // Show key selection UI with available keys + if (this.availableKeys && this.availableKeys.length > 0) { + this.createKeySelectionUI(this.availableKeys, this.requiredKeyId); + this.updateFeedback("Select a key to use"); + } else { + this.updateFeedback("No keys available"); + } + } } \ No newline at end of file diff --git a/js/systems/interactions.js b/js/systems/interactions.js index a1479dc..8c589fc 100644 --- a/js/systems/interactions.js +++ b/js/systems/interactions.js @@ -55,6 +55,11 @@ export function checkObjectInteractions() { if (obj.isHighlighted) { obj.isHighlighted = false; obj.clearTint(); + // Clean up interaction sprite if exists + if (obj.interactionIndicator) { + obj.interactionIndicator.destroy(); + delete obj.interactionIndicator; + } } return; } @@ -69,6 +74,11 @@ export function checkObjectInteractions() { if (obj.isHighlighted) { obj.isHighlighted = false; obj.clearTint(); + // Clean up interaction sprite if exists + if (obj.interactionIndicator) { + obj.interactionIndicator.destroy(); + delete obj.interactionIndicator; + } } return; } @@ -82,15 +92,167 @@ export function checkObjectInteractions() { if (!obj.isHighlighted) { obj.isHighlighted = true; obj.setTint(0x4da6ff); // Blue tint for interactable objects + // Add interaction indicator sprite + addInteractionIndicator(obj); } } else if (obj.isHighlighted) { obj.isHighlighted = false; obj.clearTint(); + // Clean up interaction sprite if exists + if (obj.interactionIndicator) { + obj.interactionIndicator.destroy(); + delete obj.interactionIndicator; + } } }); + + // Also check door sprites + if (room.doorSprites) { + Object.values(room.doorSprites).forEach(door => { + // Skip inactive or non-locked doors + if (!door.active || !door.doorProperties || !door.doorProperties.locked) { + // Clear highlight if door was previously highlighted + if (door.isHighlighted) { + door.isHighlighted = false; + door.clearTint(); + // Clean up interaction sprite if exists + if (door.interactionIndicator) { + door.interactionIndicator.destroy(); + delete door.interactionIndicator; + } + } + return; + } + + // Skip doors outside viewport for performance (if viewport bounds available) + if (viewBounds && ( + door.x < viewBounds.left || + door.x > viewBounds.right || + door.y < viewBounds.top || + door.y > viewBounds.bottom)) { + // Clear highlight if door is outside viewport + if (door.isHighlighted) { + door.isHighlighted = false; + door.clearTint(); + // Clean up interaction sprite if exists + if (door.interactionIndicator) { + door.interactionIndicator.destroy(); + delete door.interactionIndicator; + } + } + return; + } + + // Use squared distance for performance + const dx = px - door.x; + const dy = py - door.y; + const distanceSq = dx * dx + dy * dy; + + if (distanceSq <= INTERACTION_RANGE_SQ) { + if (!door.isHighlighted) { + door.isHighlighted = true; + door.setTint(0x4da6ff); // Blue tint for locked doors + // Add interaction indicator sprite for doors + addInteractionIndicator(door); + } + } else if (door.isHighlighted) { + door.isHighlighted = false; + door.clearTint(); + // Clean up interaction sprite if exists + if (door.interactionIndicator) { + door.interactionIndicator.destroy(); + delete door.interactionIndicator; + } + } + }); + } }); } +function getInteractionSpriteKey(obj) { + // Determine which sprite to show based on the object's interaction type + + // Check for doors first (they may not have scenarioData) + if (obj.doorProperties) { + if (obj.doorProperties.locked) { + // Check door lock type + const lockType = obj.doorProperties.lockType; + if (lockType === 'password') return 'password'; + if (lockType === 'pin') return 'pin'; + return 'keyway'; // Default to keyway for key locks or unknown types + } + return null; // Unlocked doors don't need overlay + } + + if (!obj || !obj.scenarioData) { + return null; + } + + const data = obj.scenarioData; + + // Check for locked containers and items + if (data.locked === true) { + // Check specific lock type + const lockType = data.lockType; + if (lockType === 'password') return 'password'; + if (lockType === 'pin') return 'pin'; + if (lockType === 'biometric') return 'fingerprint'; + // Default to keyway for key locks or unknown types + return 'keyway'; + } + + // Check for containers with contents (even if not locked yet) + if (data.contents) { + return 'keyway'; + } + + // Check for fingerprint collection + if (data.hasFingerprint === true) { + return 'fingerprint'; + } + + return null; +} + +function addInteractionIndicator(obj) { + // Only add indicator if we have a game instance and the object has a scene + if (!gameRef || !obj.scene || !obj.scene.add) { + return; + } + + const spriteKey = getInteractionSpriteKey(obj); + if (!spriteKey) return; + + // Create indicator sprite centered over the object + try { + // Get the center of the parent sprite, accounting for its origin + const center = obj.getCenter(); + + // Position indicator above the object (accounting for parent's display height) + const indicatorX = center.x; + const indicatorY = center.y; // Position above with 10px offset + + const indicator = obj.scene.add.image(indicatorX, indicatorY, spriteKey); + indicator.setDepth(999); // High depth to appear on top + indicator.setOrigin(0.5, 0.5); // Center the sprite + // indicator.setScale(0.5); // Scale down to be less intrusive + + // Add pulsing animation + obj.scene.tweens.add({ + targets: indicator, + alpha: { from: 1, to: 0.5 }, + duration: 800, + yoyo: true, + repeat: -1 + }); + + // Store reference for cleanup + obj.interactionIndicator = indicator; + } catch (error) { + console.warn('Failed to add interaction indicator:', error); + } +} + export function handleObjectInteraction(sprite) { console.log('OBJECT INTERACTION', { name: sprite.name, diff --git a/js/systems/minigame-starters.js b/js/systems/minigame-starters.js index 1bec994..27a6a9e 100644 --- a/js/systems/minigame-starters.js +++ b/js/systems/minigame-starters.js @@ -79,6 +79,44 @@ export function startLockpickingMinigame(lockable, scene, difficulty = 'medium', itemImage: itemImage, itemObservations: itemObservations, cancelText: 'Close', + canSwitchToKeyMode: window.inventory.items.some(item => + item && item.scenarioData && + item.scenarioData.type === 'key' + ), + availableKeys: (() => { + // Collect all available keys for mode switching + const keys = []; + + // Individual keys + const individualKeys = window.inventory.items.filter(item => + item && item.scenarioData && + item.scenarioData.type === 'key' + ); + individualKeys.forEach(key => { + keys.push({ + id: key.scenarioData.key_id, + name: key.scenarioData.name, + cuts: key.scenarioData.cuts || [] + }); + }); + + // Keys from key ring + const keyRingItem = window.inventory.items.find(item => + item && item.scenarioData && + item.scenarioData.type === 'key_ring' + ); + if (keyRingItem && keyRingItem.scenarioData.allKeys) { + keyRingItem.scenarioData.allKeys.forEach(keyData => { + keys.push({ + id: keyData.key_id, + name: keyData.name, + cuts: keyData.cuts || [] + }); + }); + } + + return keys.length > 0 ? keys : null; + })(), onComplete: (success, result) => { if (success) { console.log('LOCKPICK SUCCESS'); @@ -246,6 +284,12 @@ export function startKeySelectionMinigame(lockable, type, playerKeys, requiredKe itemImage: itemImage, itemObservations: itemObservations, cancelText: 'Close', + canSwitchToPickMode: window.inventory.items.some(item => + item && item.scenarioData && + item.scenarioData.type === 'lockpick' + ), + inventoryKeys: keysToShow, + requiredKeyId: requiredKeyId, onComplete: (success, result) => { if (success) { console.log('KEY SELECTION SUCCESS'); diff --git a/js/systems/unlock-system.js b/js/systems/unlock-system.js index 45fb293..4f104be 100644 --- a/js/systems/unlock-system.js +++ b/js/systems/unlock-system.js @@ -82,39 +82,35 @@ export function handleUnlock(lockable, type) { playerKeys = playerKeys.concat(keyRingKeys); } + // Check for lockpick kit + const hasLockpick = window.inventory.items.some(item => + item && item.scenarioData && + item.scenarioData.type === 'lockpick' + ); + if (playerKeys.length > 0) { - // Show key selection interface + // Keys take priority - go straight to key selection + console.log('KEYS AVAILABLE - STARTING KEY SELECTION'); startKeySelectionMinigame(lockable, type, playerKeys, requiredKey, unlockTarget); - } else { - // Check for lockpick kit - const hasLockpick = window.inventory.items.some(item => - item && item.scenarioData && - item.scenarioData.type === 'lockpick' - ); + } else if (hasLockpick) { + // Only lockpick available - launch lockpicking minigame directly + console.log('LOCKPICK AVAILABLE - STARTING LOCKPICKING MINIGAME'); + let difficulty = lockable.scenarioData?.difficulty || lockable.properties?.difficulty || 'medium'; - if (hasLockpick) { - console.log('LOCKPICK AVAILABLE'); - if (confirm("Would you like to attempt picking this lock?")) { - let difficulty = lockable.scenarioData?.difficulty || lockable.properties?.difficulty || 'medium'; - - console.log('STARTING LOCKPICK MINIGAME', { difficulty }); - startLockpickingMinigame(lockable, window.game, difficulty, (success) => { - if (success) { - // Small delay to ensure minigame cleanup completes - setTimeout(() => { - unlockTarget(lockable, type, lockable.layer); - window.gameAlert(`Successfully picked the lock!`, 'success', 'Lock Picked', 4000); - }, 100); - } else { - console.log('LOCKPICK FAILED'); - window.gameAlert('Failed to pick the lock. Try again.', 'error', 'Pick Failed', 3000); - } - }); + startLockpickingMinigame(lockable, window.game, difficulty, (success) => { + if (success) { + setTimeout(() => { + unlockTarget(lockable, type, lockable.layer); + window.gameAlert(`Successfully picked the lock!`, 'success', 'Lock Picked', 4000); + }, 100); + } else { + console.log('LOCKPICK FAILED'); + window.gameAlert('Failed to pick the lock. Try again.', 'error', 'Pick Failed', 3000); } - } else { - console.log('NO KEYS OR LOCKPICK AVAILABLE'); - window.gameAlert(`Requires key: ${requiredKey}`, 'error', 'Locked', 4000); - } + }); + } else { + console.log('NO KEYS OR LOCKPICK AVAILABLE'); + window.gameAlert(`Requires key: ${requiredKey}`, 'error', 'Locked', 4000); } break;