diff --git a/assets/objects/bluetooth_scanner.png b/assets/objects/bluetooth_scanner.png new file mode 100644 index 0000000..cd0be1a Binary files /dev/null and b/assets/objects/bluetooth_scanner.png differ diff --git a/assets/objects/tablet.png b/assets/objects/tablet.png new file mode 100644 index 0000000..2af66bc Binary files /dev/null and b/assets/objects/tablet.png differ diff --git a/assets/objects/workstation.png b/assets/objects/workstation.png new file mode 100644 index 0000000..00ab468 Binary files /dev/null and b/assets/objects/workstation.png differ diff --git a/assets/rooms/room_reception.json b/assets/rooms/room_reception.json index 38d006c..eb88f44 100644 --- a/assets/rooms/room_reception.json +++ b/assets/rooms/room_reception.json @@ -222,7 +222,30 @@ "width":48, "x":236.666666666667, "y":168.666666666667 - }], + }, + { + "height":48, + "id":11, + "name":"tablet", + "rotation":0, + "type":"", + "visible":true, + "width":48, + "x":430, + "y":380 + }, + { + "height":48, + "id":12, + "name":"bluetooth_scanner", + "rotation":0, + "type":"", + "visible":true, + "width":48, + "x":380, + "y":166 + } + ], "opacity":1, "type":"objectgroup", "visible":true, diff --git a/assets/scenarios/ceo_exfil.json b/assets/scenarios/ceo_exfil.json index ead7d23..701d051 100644 --- a/assets/scenarios/ceo_exfil.json +++ b/assets/scenarios/ceo_exfil.json @@ -30,6 +30,23 @@ "takeable": false, "requires": "password", "observations": "The reception's computer, currently locked" + }, + { + "type": "tablet", + "name": "Tablet Device", + "takeable": true, + "locked": true, + "lockType": "bluetooth", + "mac": "00:11:22:33:44:55", + "observations": "A locked tablet device that requires Bluetooth pairing" + }, + { + "type": "bluetooth_scanner", + "name": "Bluetooth Scanner", + "takeable": true, + "observations": "A device for detecting nearby Bluetooth signals", + "canScanBluetooth": true, + "mac": "00:11:22:33:44:55" } ] }, diff --git a/index.html b/index.html index f793cca..290608d 100644 --- a/index.html +++ b/index.html @@ -190,6 +190,10 @@ const INTERACTION_RANGE = 2 * TILE_SIZE; const INTERACTION_RANGE_SQ = INTERACTION_RANGE * INTERACTION_RANGE; + // Bluetooth constants + const BLUETOOTH_SCAN_RANGE = TILE_SIZE * 2; // 2 tiles range for Bluetooth scanning + let lastBluetoothScan = 0; // Track last scan time + const BLUETOOTH_SCAN_INTERVAL = 500; // Scan every 500ms // preloads the assets function preload() { @@ -222,6 +226,9 @@ this.load.image('safe', 'assets/objects/safe.png'); this.load.image('book', 'assets/objects/book.png'); this.load.image('workstation', 'assets/objects/workstation.png'); + this.load.image('bluetooth_scanner', 'assets/objects/bluetooth_scanner.png'); + this.load.image('tablet', 'assets/objects/tablet.png'); + this.load.json('gameScenarioJSON', 'assets/scenarios/ceo_exfil.json'); gameScenario = this.cache.json.get('gameScenarioJSON'); @@ -458,6 +465,13 @@ // checks for room transitions checkRoomTransitions.call(this); + // Check for Bluetooth devices + const currentTime = this.time.now; + if (currentTime - lastBluetoothScan >= BLUETOOTH_SCAN_INTERVAL) { + checkBluetoothDevices.call(this); + lastBluetoothScan = currentTime; + } + // adds a circle to the start of the path if (currentPath && currentPath.length > 0 && isMoving) { this.add.circle(currentPath[0].x, currentPath[0].y, 5, 0xff0000).setDepth(1000); @@ -1834,6 +1848,43 @@ } break; + case 'bluetooth': + if (lockable.scenarioData?.locked) { + alert("You need a Bluetooth scanner to unlock this device."); + // Don't return here - allow the item to be picked up even without scanner + if (type === 'item' && lockable.scenarioData?.takeable) { + addToInventory(lockable); + // Remove from room objects if it exists there + if (currentRoom && rooms[currentRoom].objects) { + delete rooms[currentRoom].objects[lockable.name]; + } + } + return; + } + + // Calculate distance between player and tablet + const distance = Phaser.Math.Distance.Between( + player.x, player.y, + lockable.x, lockable.y + ); + + console.log('Distance to tablet:', distance); + + // Check if player is within range (using BLUETOOTH_SCAN_RANGE) + if (distance <= BLUETOOTH_SCAN_RANGE) { + console.log('Bluetooth unlock success: Player in range', { + itemName: lockable.scenarioData?.name, + itemMac: lockable.scenarioData?.mac, + distance: distance + }); + unlockTarget(lockable, type, lockable.layer); + alert(`Bluetooth connection established. Device unlocked.`); + return; + } + + alert("Too far from device to establish Bluetooth connection."); + break; + default: alert(`Requires: ${lockRequirements.requires}`); } @@ -2059,6 +2110,39 @@ alert('You collected the items from the container.'); } + function checkBluetoothDevices() { + // Find scanner in inventory + const scanner = inventory.items.find(item => + item.scenarioData?.type === "bluetooth_scanner" + ); + + if (!scanner) return; + + // Find all tablets in the current room + if (!currentRoom || !rooms[currentRoom] || !rooms[currentRoom].objects) return; + + Object.values(rooms[currentRoom].objects).forEach(obj => { + if (obj.scenarioData?.type === "tablet" && obj.scenarioData?.locked) { + const distance = Phaser.Math.Distance.Between( + player.x, player.y, + obj.x, obj.y + ); + + if (distance <= BLUETOOTH_SCAN_RANGE) { + console.log('🔍 TABLET IN RANGE:', { + distance: Math.round(distance), + range: BLUETOOTH_SCAN_RANGE + }); + + // Unlock the tablet + obj.scenarioData.locked = false; + console.log('🔓 TABLET UNLOCKED!'); + alert('Bluetooth connection established. Device unlocked.'); + } + } + }); + } + \ No newline at end of file