Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Neon Protocol - Hacking Simulator</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap'); | |
| :root { | |
| --neon-green: #39ff14; | |
| --dark-bg: #0a0a0a; | |
| --terminal-bg: rgba(10, 10, 10, 0.9); | |
| } | |
| body { | |
| font-family: 'Share Tech Mono', monospace; | |
| background-color: var(--dark-bg); | |
| color: var(--neon-green); | |
| overflow-x: hidden; | |
| } | |
| .terminal { | |
| background-color: var(--terminal-bg); | |
| border: 1px solid var(--neon-green); | |
| box-shadow: 0 0 10px var(--neon-green); | |
| } | |
| .cursor { | |
| animation: blink 1s infinite; | |
| } | |
| @keyframes blink { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0; } | |
| } | |
| .hack-button { | |
| transition: all 0.3s; | |
| box-shadow: 0 0 5px var(--neon-green); | |
| } | |
| .hack-button:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 0 15px var(--neon-green); | |
| } | |
| .progress-bar { | |
| height: 5px; | |
| background-color: var(--neon-green); | |
| transition: width 0.1s linear; | |
| } | |
| .mission-complete { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background-color: black; | |
| z-index: 1000; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| flex-direction: column; | |
| animation: explode 2s forwards; | |
| } | |
| @keyframes explode { | |
| 0% { | |
| opacity: 0; | |
| transform: scale(1); | |
| } | |
| 10% { | |
| opacity: 1; | |
| transform: scale(1); | |
| } | |
| 100% { | |
| opacity: 0; | |
| transform: scale(10); | |
| } | |
| } | |
| .binary-particle { | |
| position: absolute; | |
| color: var(--neon-green); | |
| font-size: 1rem; | |
| animation: float 3s linear forwards; | |
| } | |
| @keyframes float { | |
| to { | |
| transform: translate(var(--tx), var(--ty)); | |
| opacity: 0; | |
| } | |
| } | |
| .location-button { | |
| transition: all 0.3s; | |
| } | |
| .location-button:hover { | |
| transform: scale(1.05); | |
| box-shadow: 0 0 10px var(--neon-green); | |
| } | |
| .enemy-attack { | |
| animation: shake 0.5s linear infinite; | |
| } | |
| @keyframes shake { | |
| 0%, 100% { transform: translateX(0); } | |
| 25% { transform: translateX(-5px); } | |
| 75% { transform: translateX(5px); } | |
| } | |
| @media (max-width: 768px) { | |
| .terminal-input { | |
| width: 80%; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen flex flex-col"> | |
| <!-- Mission Complete Animation (hidden by default) --> | |
| <div id="missionComplete" class="mission-complete hidden"> | |
| <h1 class="text-4xl mb-4">MISSION COMPLETE</h1> | |
| <p class="text-xl">Access Granted</p> | |
| </div> | |
| <!-- Main Game Container --> | |
| <div class="container mx-auto px-4 py-6 flex-grow flex flex-col"> | |
| <!-- Header --> | |
| <header class="flex justify-between items-center mb-6 border-b border-neon-green pb-4"> | |
| <div> | |
| <h1 class="text-3xl font-bold text-neon-green">NEON PROTOCOL</h1> | |
| <p class="text-sm">White Hat Hacking Simulator</p> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div id="playerStats" class="text-right"> | |
| <p>Reputation: <span id="reputation">0</span></p> | |
| <p>Credits: $<span id="credits">1000</span></p> | |
| <p>Firewall: <span id="firewall">50</span>%</p> | |
| </div> | |
| <button id="saveGame" class="bg-black text-neon-green border border-neon-green px-3 py-1 rounded hover:bg-neon-green hover:text-black"> | |
| <i class="fas fa-save"></i> Save | |
| </button> | |
| <button id="loadGame" class="bg-black text-neon-green border border-neon-green px-3 py-1 rounded hover:bg-neon-green hover:text-black"> | |
| <i class="fas fa-folder-open"></i> Load | |
| </button> | |
| </div> | |
| </header> | |
| <!-- Game Content --> | |
| <div class="flex flex-col md:flex-row flex-grow gap-6"> | |
| <!-- Left Panel - Game Info --> | |
| <div class="w-full md:w-1/4 flex flex-col gap-4"> | |
| <!-- Player Info --> | |
| <div class="terminal p-4"> | |
| <h2 class="text-xl mb-2 border-b border-neon-green pb-2">Player: <span id="playerName">Neo_Byte</span></h2> | |
| <p class="mb-1">Level: <span id="playerLevel">1</span></p> | |
| <p class="mb-1">Skills:</p> | |
| <div class="mb-2"> | |
| <p class="text-sm">Brute Force: <span id="skillBrute">1</span>/10</p> | |
| <p class="text-sm">Cryptography: <span id="skillCrypto">1</span>/10</p> | |
| <p class="text-sm">Stealth: <span id="skillStealth">1</span>/10</p> | |
| </div> | |
| <p class="mb-1">Current Location: <span id="currentLocation">Home Base</span></p> | |
| </div> | |
| <!-- Locations --> | |
| <div class="terminal p-4"> | |
| <h2 class="text-xl mb-2 border-b border-neon-green pb-2">Locations</h2> | |
| <div class="grid grid-cols-2 gap-2"> | |
| <button class="location-button bg-black text-neon-green border border-neon-green p-2 rounded" data-location="home"> | |
| Home Base | |
| </button> | |
| <button class="location-button bg-black text-neon-green border border-neon-green p-2 rounded" data-location="darkweb"> | |
| Dark Web | |
| </button> | |
| <button class="location-button bg-black text-neon-green border border-neon-green p-2 rounded" data-location="bank"> | |
| City Bank | |
| </button> | |
| <button class="location-button bg-black text-neon-green border border-neon-green p-2 rounded" data-location="corp"> | |
| MegaCorp | |
| </button> | |
| <button class="location-button bg-black text-neon-green border border-neon-green p-2 rounded" data-location="police"> | |
| Police DB | |
| </button> | |
| <button class="location-button bg-black text-neon-green border border-neon-green p-2 rounded" data-location="shadow"> | |
| Shadow Net | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Quick Actions --> | |
| <div class="terminal p-4"> | |
| <h2 class="text-xl mb-2 border-b border-neon-green pb-2">Quick Actions</h2> | |
| <div class="grid grid-cols-2 gap-2"> | |
| <button class="hack-button bg-black text-neon-green border border-neon-green p-2 rounded" data-command="scan"> | |
| <i class="fas fa-search"></i> Scan | |
| </button> | |
| <button class="hack-button bg-black text-neon-green border border-neon-green p-2 rounded" data-command="firewall"> | |
| <i class="fas fa-shield-alt"></i> Firewall | |
| </button> | |
| <button class="hack-button bg-black text-neon-green border border-neon-green p-2 rounded" data-command="upgrade"> | |
| <i class="fas fa-level-up-alt"></i> Upgrade | |
| </button> | |
| <button class="hack-button bg-black text-neon-green border border-neon-green p-2 rounded" data-command="help"> | |
| <i class="fas fa-question"></i> Help | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Panel - Terminal --> | |
| <div class="w-full md:w-2/4 flex flex-col"> | |
| <div class="terminal p-4 flex-grow flex flex-col"> | |
| <h2 class="text-xl mb-2 border-b border-neon-green pb-2">Terminal</h2> | |
| <div id="terminalOutput" class="flex-grow overflow-y-auto mb-4 h-64"> | |
| <p>> Welcome to Neon Protocol, Neo_Byte.</p> | |
| <p>> Fresh out of high school, you're ready to make your mark in the hacking world.</p> | |
| <p>> Your goal: Use your skills to take down criminal organizations while avoiding detection.</p> | |
| <p>> Type 'help' for available commands.</p> | |
| <p>> </p> | |
| </div> | |
| <div class="flex items-center"> | |
| <span class="mr-2">></span> | |
| <input id="terminalInput" type="text" class="terminal-input bg-transparent border-b border-neon-green outline-none flex-grow text-neon-green" autofocus> | |
| </div> | |
| </div> | |
| <!-- Active Mission --> | |
| <div id="activeMission" class="terminal p-4 mt-4 hidden"> | |
| <h2 class="text-xl mb-2 border-b border-neon-green pb-2">Active Mission</h2> | |
| <p id="missionTitle" class="font-bold"></p> | |
| <p id="missionDesc" class="mb-2"></p> | |
| <div class="progress-bar-container bg-gray-800 w-full h-1 mb-2"> | |
| <div id="missionProgress" class="progress-bar" style="width: 0%"></div> | |
| </div> | |
| <p id="missionTimer" class="text-right"></p> | |
| <div class="flex justify-between mt-2"> | |
| <button id="abortMission" class="hack-button bg-black text-red-500 border border-red-500 px-3 py-1 rounded"> | |
| Abort | |
| </button> | |
| <button id="completeMission" class="hack-button bg-black text-neon-green border border-neon-green px-3 py-1 rounded hidden"> | |
| Complete | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Panel - Missions & Alerts --> | |
| <div class="w-full md:w-1/4 flex flex-col gap-4"> | |
| <!-- Available Missions --> | |
| <div class="terminal p-4"> | |
| <h2 class="text-xl mb-2 border-b border-neon-green pb-2">Available Missions</h2> | |
| <div id="missionsList" class="space-y-2"> | |
| <div class="mission-item border border-neon-green p-2 rounded"> | |
| <h3 class="font-bold">Tutorial: First Hack</h3> | |
| <p class="text-sm mb-2">Learn basic commands by hacking a test server.</p> | |
| <button class="hack-button bg-black text-neon-green border border-neon-green w-full py-1 rounded" data-mission="tutorial"> | |
| Accept | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Alerts --> | |
| <div id="alerts" class="terminal p-4"> | |
| <h2 class="text-xl mb-2 border-b border-neon-green pb-2">Alerts</h2> | |
| <div id="alertsList"> | |
| <p class="text-sm">No active alerts</p> | |
| </div> | |
| </div> | |
| <!-- Enemy Attacks --> | |
| <div id="enemyAttack" class="terminal p-4 hidden enemy-attack border border-red-500"> | |
| <h2 class="text-xl mb-2 border-b border-red-500 pb-2 text-red-500">INTRUSION DETECTED!</h2> | |
| <p class="text-red-500 mb-2">You're under attack by <span id="attackerName">Shadow Syndicate</span>!</p> | |
| <div class="flex justify-between"> | |
| <button id="defendAttack" class="hack-button bg-black text-red-500 border border-red-500 px-3 py-1 rounded"> | |
| Defend | |
| </button> | |
| <button id="escapeAttack" class="hack-button bg-black text-neon-green border border-neon-green px-3 py-1 rounded"> | |
| Escape | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Game State | |
| const gameState = { | |
| player: { | |
| name: "Neo_Byte", | |
| level: 1, | |
| reputation: 0, | |
| credits: 1000, | |
| firewall: 50, | |
| skills: { | |
| brute: 1, | |
| crypto: 1, | |
| stealth: 1 | |
| }, | |
| location: "home", | |
| missionsCompleted: 0 | |
| }, | |
| missions: { | |
| tutorial: { | |
| title: "Tutorial: First Hack", | |
| description: "Learn basic commands by hacking a test server. Use 'scan' to find vulnerabilities, then 'exploit' to break in.", | |
| difficulty: 1, | |
| reward: 500, | |
| repReward: 10, | |
| timeLimit: 300, // 5 minutes | |
| progress: 0, | |
| active: false | |
| }, | |
| bankJob: { | |
| title: "Bank Heist: Stop the Robbers", | |
| description: "A criminal group is planning to hack City Bank. Infiltrate their systems and stop the transfer.", | |
| difficulty: 3, | |
| reward: 2000, | |
| repReward: 30, | |
| timeLimit: 600, // 10 minutes | |
| progress: 0, | |
| active: false, | |
| requiredLevel: 2 | |
| }, | |
| corpEspionage: { | |
| title: "Corporate Espionage", | |
| description: "MegaCorp is stealing data from small businesses. Find evidence and expose them.", | |
| difficulty: 4, | |
| reward: 3500, | |
| repReward: 50, | |
| timeLimit: 900, // 15 minutes | |
| progress: 0, | |
| active: false, | |
| requiredLevel: 3 | |
| }, | |
| shadowSyndicate: { | |
| title: "Shadow Syndicate Takedown", | |
| description: "The notorious hacking group is planning a major attack. Take down their servers.", | |
| difficulty: 5, | |
| reward: 5000, | |
| repReward: 100, | |
| timeLimit: 1200, // 20 minutes | |
| progress: 0, | |
| active: false, | |
| requiredLevel: 5 | |
| } | |
| }, | |
| availableMissions: ["tutorial"], | |
| currentMission: null, | |
| enemyAttack: null, | |
| enemies: [ | |
| { name: "Script Kiddies", strength: 1, reward: 200 }, | |
| { name: "Dark Web Thugs", strength: 2, reward: 500 }, | |
| { name: "Cyber Mafia", strength: 3, reward: 1000 }, | |
| { name: "Shadow Syndicate", strength: 4, reward: 2000 } | |
| ], | |
| locations: { | |
| home: "Home Base", | |
| darkweb: "Dark Web", | |
| bank: "City Bank", | |
| corp: "MegaCorp", | |
| police: "Police DB", | |
| shadow: "Shadow Net" | |
| } | |
| }; | |
| // DOM Elements | |
| const terminalInput = document.getElementById('terminalInput'); | |
| const terminalOutput = document.getElementById('terminalOutput'); | |
| const playerName = document.getElementById('playerName'); | |
| const playerLevel = document.getElementById('playerLevel'); | |
| const reputation = document.getElementById('reputation'); | |
| const credits = document.getElementById('credits'); | |
| const firewall = document.getElementById('firewall'); | |
| const skillBrute = document.getElementById('skillBrute'); | |
| const skillCrypto = document.getElementById('skillCrypto'); | |
| const skillStealth = document.getElementById('skillStealth'); | |
| const currentLocation = document.getElementById('currentLocation'); | |
| const missionsList = document.getElementById('missionsList'); | |
| const activeMission = document.getElementById('activeMission'); | |
| const missionTitle = document.getElementById('missionTitle'); | |
| const missionDesc = document.getElementById('missionDesc'); | |
| const missionProgress = document.getElementById('missionProgress'); | |
| const missionTimer = document.getElementById('missionTimer'); | |
| const completeMission = document.getElementById('completeMission'); | |
| const abortMission = document.getElementById('abortMission'); | |
| const alertsList = document.getElementById('alertsList'); | |
| const enemyAttack = document.getElementById('enemyAttack'); | |
| const defendAttack = document.getElementById('defendAttack'); | |
| const escapeAttack = document.getElementById('escapeAttack'); | |
| const missionComplete = document.getElementById('missionComplete'); | |
| const saveGame = document.getElementById('saveGame'); | |
| const loadGame = document.getElementById('loadGame'); | |
| // Game Variables | |
| let missionInterval; | |
| let attackInterval; | |
| let missionTimeLeft; | |
| let enemyAttackTime = 30; | |
| // Initialize Game | |
| function initGame() { | |
| updatePlayerStats(); | |
| renderMissions(); | |
| setupEventListeners(); | |
| // Random enemy attacks | |
| setInterval(() => { | |
| if (!gameState.currentMission && Math.random() > 0.7) { | |
| startEnemyAttack(); | |
| } | |
| }, 300000); // Every 5 minutes | |
| // Check for new missions | |
| setInterval(checkForNewMissions, 60000); // Every minute | |
| } | |
| // Update player stats display | |
| function updatePlayerStats() { | |
| playerName.textContent = gameState.player.name; | |
| playerLevel.textContent = gameState.player.level; | |
| reputation.textContent = gameState.player.reputation; | |
| credits.textContent = gameState.player.credits; | |
| firewall.textContent = gameState.player.firewall; | |
| skillBrute.textContent = gameState.player.skills.brute; | |
| skillCrypto.textContent = gameState.player.skills.crypto; | |
| skillStealth.textContent = gameState.player.skills.stealth; | |
| currentLocation.textContent = gameState.locations[gameState.player.location]; | |
| } | |
| // Render available missions | |
| function renderMissions() { | |
| missionsList.innerHTML = ''; | |
| gameState.availableMissions.forEach(missionId => { | |
| const mission = gameState.missions[missionId]; | |
| const missionElement = document.createElement('div'); | |
| missionElement.className = 'mission-item border border-neon-green p-2 rounded'; | |
| missionElement.innerHTML = ` | |
| <h3 class="font-bold">${mission.title}</h3> | |
| <p class="text-sm mb-2">${mission.description}</p> | |
| <button class="hack-button bg-black text-neon-green border border-neon-green w-full py-1 rounded" data-mission="${missionId}"> | |
| Accept | |
| </button> | |
| `; | |
| missionsList.appendChild(missionElement); | |
| }); | |
| // Add event listeners to mission buttons | |
| document.querySelectorAll('[data-mission]').forEach(button => { | |
| button.addEventListener('click', function() { | |
| startMission(this.dataset.mission); | |
| }); | |
| }); | |
| } | |
| // Check for new missions based on player level | |
| function checkForNewMissions() { | |
| if (!gameState.availableMissions.includes('bankJob') && gameState.player.level >= 2) { | |
| gameState.availableMissions.push('bankJob'); | |
| addToTerminal("> New mission available: Bank Heist - Stop the Robbers"); | |
| renderMissions(); | |
| } | |
| if (!gameState.availableMissions.includes('corpEspionage') && gameState.player.level >= 3) { | |
| gameState.availableMissions.push('corpEspionage'); | |
| addToTerminal("> New mission available: Corporate Espionage"); | |
| renderMissions(); | |
| } | |
| if (!gameState.availableMissions.includes('shadowSyndicate') && gameState.player.level >= 5) { | |
| gameState.availableMissions.push('shadowSyndicate'); | |
| addToTerminal("> New mission available: Shadow Syndicate Takedown"); | |
| renderMissions(); | |
| } | |
| } | |
| // Start a mission | |
| function startMission(missionId) { | |
| if (gameState.currentMission) { | |
| addToTerminal("> You're already on a mission. Finish or abort it first."); | |
| return; | |
| } | |
| const mission = gameState.missions[missionId]; | |
| gameState.currentMission = missionId; | |
| mission.active = true; | |
| mission.progress = 0; | |
| missionTimeLeft = mission.timeLimit; | |
| // Update UI | |
| activeMission.classList.remove('hidden'); | |
| missionTitle.textContent = mission.title; | |
| missionDesc.textContent = mission.description; | |
| missionProgress.style.width = '0%'; | |
| updateMissionTimer(); | |
| completeMission.classList.add('hidden'); | |
| // Remove mission from available | |
| gameState.availableMissions = gameState.availableMissions.filter(m => m !== missionId); | |
| renderMissions(); | |
| // Start mission timer | |
| missionInterval = setInterval(() => { | |
| missionTimeLeft--; | |
| updateMissionTimer(); | |
| if (missionTimeLeft <= 0) { | |
| failMission(); | |
| } | |
| }, 1000); | |
| addToTerminal(`> Mission started: ${mission.title}`); | |
| addToTerminal(`> Time limit: ${Math.floor(mission.timeLimit / 60)} minutes`); | |
| } | |
| // Update mission timer display | |
| function updateMissionTimer() { | |
| const minutes = Math.floor(missionTimeLeft / 60); | |
| const seconds = missionTimeLeft % 60; | |
| missionTimer.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`; | |
| } | |
| // Update mission progress | |
| function updateMissionProgress(increment) { | |
| const mission = gameState.missions[gameState.currentMission]; | |
| mission.progress += increment; | |
| if (mission.progress >= 100) { | |
| mission.progress = 100; | |
| missionProgress.style.width = '100%'; | |
| completeMission.classList.remove('hidden'); | |
| addToTerminal("> Mission objective complete! Click 'Complete' to finish."); | |
| } else { | |
| missionProgress.style.width = `${mission.progress}%`; | |
| } | |
| } | |
| // Complete current mission | |
| function completeCurrentMission() { | |
| const mission = gameState.missions[gameState.currentMission]; | |
| // Calculate rewards | |
| const timeBonus = Math.floor((missionTimeLeft / mission.timeLimit) * 0.5 * mission.reward); | |
| const totalReward = mission.reward + timeBonus; | |
| // Update player stats | |
| gameState.player.credits += totalReward; | |
| gameState.player.reputation += mission.repReward; | |
| gameState.player.missionsCompleted++; | |
| // Check for level up | |
| if (gameState.player.missionsCompleted >= gameState.player.level * 2) { | |
| gameState.player.level++; | |
| gameState.player.skills.brute = Math.min(10, gameState.player.skills.brute + 1); | |
| gameState.player.skills.crypto = Math.min(10, gameState.player.skills.crypto + 1); | |
| gameState.player.skills.stealth = Math.min(10, gameState.player.skills.stealth + 1); | |
| addToTerminal(`> Level up! You're now level ${gameState.player.level}`); | |
| } | |
| updatePlayerStats(); | |
| addToTerminal(`> Mission complete! Reward: $${totalReward} ($${mission.reward} + $${timeBonus} time bonus)`); | |
| addToTerminal(`> Reputation increased by ${mission.repReward}`); | |
| // Show mission complete animation | |
| showMissionComplete(); | |
| // Clean up | |
| clearInterval(missionInterval); | |
| gameState.currentMission = null; | |
| activeMission.classList.add('hidden'); | |
| // Check for new missions | |
| checkForNewMissions(); | |
| } | |
| // Fail current mission | |
| function failMission() { | |
| const mission = gameState.missions[gameState.currentMission]; | |
| addToTerminal("> Mission failed! Time's up."); | |
| // Penalty | |
| gameState.player.reputation = Math.max(0, gameState.player.reputation - Math.floor(mission.repReward / 2)); | |
| updatePlayerStats(); | |
| // Clean up | |
| clearInterval(missionInterval); | |
| gameState.currentMission = null; | |
| activeMission.classList.add('hidden'); | |
| // Add mission back to available | |
| if (!gameState.availableMissions.includes(mission)) { | |
| gameState.availableMissions.push(mission); | |
| renderMissions(); | |
| } | |
| } | |
| // Abort current mission | |
| function abortCurrentMission() { | |
| const missionId = gameState.currentMission; | |
| addToTerminal("> Mission aborted."); | |
| // Clean up | |
| clearInterval(missionInterval); | |
| gameState.currentMission = null; | |
| activeMission.classList.add('hidden'); | |
| // Add mission back to available | |
| if (!gameState.availableMissions.includes(missionId)) { | |
| gameState.availableMissions.push(missionId); | |
| renderMissions(); | |
| } | |
| } | |
| // Show mission complete animation | |
| function showMissionComplete() { | |
| missionComplete.classList.remove('hidden'); | |
| // Create binary explosion effect | |
| for (let i = 0; i < 100; i++) { | |
| const binary = document.createElement('div'); | |
| binary.className = 'binary-particle'; | |
| binary.textContent = Math.random() > 0.5 ? '1' : '0'; | |
| binary.style.left = `${50 + (Math.random() - 0.5) * 20}%`; | |
| binary.style.top = `${50 + (Math.random() - 0.5) * 20}%`; | |
| binary.style.setProperty('--tx', `${(Math.random() - 0.5) * 500}px`); | |
| binary.style.setProperty('--ty', `${(Math.random() - 0.5) * 500}px`); | |
| missionComplete.appendChild(binary); | |
| } | |
| setTimeout(() => { | |
| missionComplete.classList.add('hidden'); | |
| missionComplete.innerHTML = ` | |
| <h1 class="text-4xl mb-4">MISSION COMPLETE</h1> | |
| <p class="text-xl">Access Granted</p> | |
| `; | |
| }, 2000); | |
| } | |
| // Start enemy attack | |
| function startEnemyAttack() { | |
| if (gameState.enemyAttack) return; | |
| const enemy = gameState.enemies[Math.min(gameState.player.level - 1, gameState.enemies.length - 1)]; | |
| gameState.enemyAttack = { | |
| enemy: enemy, | |
| timeLeft: enemyAttackTime | |
| }; | |
| // Update UI | |
| enemyAttack.classList.remove('hidden'); | |
| document.getElementById('attackerName').textContent = enemy.name; | |
| alertsList.innerHTML = `<p class="text-red-500">Under attack by ${enemy.name}!</p>`; | |
| // Start attack timer | |
| attackInterval = setInterval(() => { | |
| gameState.enemyAttack.timeLeft--; | |
| if (gameState.enemyAttack.timeLeft <= 0) { | |
| enemyAttackSuccess(); | |
| } | |
| }, 1000); | |
| addToTerminal(`> WARNING: Under attack by ${enemy.name}!`); | |
| } | |
| // Defend against enemy attack | |
| function defendAgainstAttack() { | |
| const attack = gameState.enemyAttack; | |
| const defenseChance = gameState.player.firewall / 100; | |
| if (Math.random() < defenseChance) { | |
| // Successful defense | |
| addToTerminal(`> Successfully defended against ${attack.enemy.name}!`); | |
| gameState.player.credits += attack.enemy.reward; | |
| updatePlayerStats(); | |
| } else { | |
| // Failed defense | |
| const damage = Math.floor(Math.random() * 20) + 10; | |
| gameState.player.firewall = Math.max(0, gameState.player.firewall - damage); | |
| addToTerminal(`> Defense failed! Firewall damaged: -${damage}%`); | |
| updatePlayerStats(); | |
| } | |
| endEnemyAttack(); | |
| } | |
| // Escape from enemy attack | |
| function escapeFromAttack() { | |
| const attack = gameState.enemyAttack; | |
| const escapeChance = gameState.player.skills.stealth / 10; | |
| if (Math.random() < escapeChance) { | |
| // Successful escape | |
| addToTerminal(`> Successfully escaped from ${attack.enemy.name}!`); | |
| } else { | |
| // Failed escape | |
| const damage = Math.floor(Math.random() * 30) + 20; | |
| gameState.player.firewall = Math.max(0, gameState.player.firewall - damage); | |
| addToTerminal(`> Escape failed! Firewall damaged: -${damage}%`); | |
| updatePlayerStats(); | |
| } | |
| endEnemyAttack(); | |
| } | |
| // Enemy attack succeeds | |
| function enemyAttackSuccess() { | |
| const attack = gameState.enemyAttack; | |
| const damage = Math.floor(Math.random() * 40) + 30; | |
| gameState.player.firewall = Math.max(0, gameState.player.firewall - damage); | |
| addToTerminal(`> ${attack.enemy.name} breached your firewall! Damage: -${damage}%`); | |
| updatePlayerStats(); | |
| endEnemyAttack(); | |
| } | |
| // End enemy attack | |
| function endEnemyAttack() { | |
| clearInterval(attackInterval); | |
| gameState.enemyAttack = null; | |
| enemyAttack.classList.add('hidden'); | |
| alertsList.innerHTML = `<p class="text-sm">No active alerts</p>`; | |
| } | |
| // Add text to terminal | |
| function addToTerminal(text) { | |
| const line = document.createElement('p'); | |
| line.textContent = text; | |
| terminalOutput.appendChild(line); | |
| terminalOutput.scrollTop = terminalOutput.scrollHeight; | |
| } | |
| // Process terminal command | |
| function processCommand(command) { | |
| command = command.toLowerCase().trim(); | |
| if (!command) return; | |
| addToTerminal(`> ${command}`); | |
| if (gameState.currentMission) { | |
| handleMissionCommand(command); | |
| return; | |
| } | |
| switch (command) { | |
| case 'help': | |
| showHelp(); | |
| break; | |
| case 'scan': | |
| scanNetwork(); | |
| break; | |
| case 'firewall': | |
| checkFirewall(); | |
| break; | |
| case 'upgrade': | |
| showUpgradeOptions(); | |
| break; | |
| case 'clear': | |
| terminalOutput.innerHTML = ''; | |
| break; | |
| case 'status': | |
| showStatus(); | |
| break; | |
| case 'exploit': | |
| addToTerminal("> No target specified. Use 'scan' first."); | |
| break; | |
| default: | |
| addToTerminal("> Command not recognized. Type 'help' for available commands."); | |
| } | |
| } | |
| // Handle commands during a mission | |
| function handleMissionCommand(command) { | |
| const mission = gameState.missions[gameState.currentMission]; | |
| switch (command) { | |
| case 'scan': | |
| if (mission.progress < 30) { | |
| updateMissionProgress(10); | |
| addToTerminal("> Scanning for vulnerabilities... Found weak encryption."); | |
| } else { | |
| addToTerminal("> No new vulnerabilities found."); | |
| } | |
| break; | |
| case 'exploit': | |
| if (mission.progress >= 20 && mission.progress < 70) { | |
| updateMissionProgress(15); | |
| addToTerminal("> Exploiting vulnerability... Gained partial access."); | |
| } else if (mission.progress >= 70) { | |
| updateMissionProgress(25); | |
| addToTerminal("> Exploiting main system... Root access achieved!"); | |
| } else { | |
| addToTerminal("> Not enough information. Use 'scan' first."); | |
| } | |
| break; | |
| case 'decrypt': | |
| if (mission.progress >= 40 && mission.progress < 80) { | |
| updateMissionProgress(20); | |
| addToTerminal("> Decrypting data... Retrieved sensitive information."); | |
| } else { | |
| addToTerminal("> No encrypted data found or insufficient access."); | |
| } | |
| break; | |
| case 'help': | |
| showMissionHelp(); | |
| break; | |
| default: | |
| addToTerminal("> Command not recognized. Type 'help' for mission commands."); | |
| } | |
| } | |
| // Show help | |
| function showHelp() { | |
| addToTerminal("> Available commands:"); | |
| addToTerminal("> help - Show this help message"); | |
| addToTerminal("> scan - Scan the network for vulnerabilities"); | |
| addToTerminal("> firewall - Check firewall status"); | |
| addToTerminal("> upgrade - Show upgrade options"); | |
| addToTerminal("> status - Show player status"); | |
| addToTerminal("> clear - Clear terminal"); | |
| addToTerminal("> Missions:"); | |
| addToTerminal("> Accept missions from the right panel"); | |
| } | |
| // Show mission help | |
| function showMissionHelp() { | |
| addToTerminal("> Mission commands:"); | |
| addToTerminal("> scan - Find vulnerabilities in target system"); | |
| addToTerminal("> exploit - Attempt to exploit found vulnerabilities"); | |
| addToTerminal("> decrypt - Decrypt encrypted data (requires crypto skill)"); | |
| } | |
| // Scan network | |
| function scanNetwork() { | |
| addToTerminal("> Scanning network..."); | |
| setTimeout(() => { | |
| const locations = Object.keys(gameState.locations).filter(l => l !== gameState.player.location); | |
| const randomLoc = locations[Math.floor(Math.random() * locations.length)]; | |
| addToTerminal(`> Found ${gameState.locations[randomLoc]} network`); | |
| addToTerminal(`> Use 'travel ${randomLoc}' to connect`); | |
| }, 2000); | |
| } | |
| // Check firewall | |
| function checkFirewall() { | |
| addToTerminal(`> Firewall integrity: ${gameState.player.firewall}%`); | |
| addToTerminal(`> Upgrade cost: $${Math.floor(500 * (1 + gameState.player.firewall / 100))}`); | |
| addToTerminal("> Use 'upgrade firewall' to strengthen"); | |
| } | |
| // Show upgrade options | |
| function showUpgradeOptions() { | |
| addToTerminal("> Upgrade options:"); | |
| addToTerminal(`> firewall - Strengthen firewall (current: ${gameState.player.firewall}%) - $${Math.floor(500 * (1 + gameState.player.firewall / 100))}`); | |
| addToTerminal(`> brute - Improve brute force skill (current: ${gameState.player.skills.brute}/10) - $${1000 * gameState.player.skills.brute}`); | |
| addToTerminal(`> crypto - Improve cryptography skill (current: ${gameState.player.skills.crypto}/10) - $${1000 * gameState.player.skills.crypto}`); | |
| addToTerminal(`> stealth - Improve stealth skill (current: ${gameState.player.skills.stealth}/10) - $${1000 * gameState.player.skills. | |
| </html> |