User prompt
Add the Airport Comissary button (Buy boosts and cosmetic items with varying Point levels.) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now, lore button! ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a tutorial button which introduces new players and tells them how to play. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Drakens keep firing after duration
User prompt
Add a menu when pressing the ally button to select the ally ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add different types of allies you can summon (2x Draken, Bandkanon, Strv 103 and Naval Barrage) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a ally button where you can summon Swedish forces for a monent to fight for you ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
No, I meant as guns, cannons and missiles fir the Viggen.
User prompt
Add an armament button
User prompt
Add optimization
User prompt
Fix it. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make it harder to unlock (so only me and the coworkers can access)
User prompt
Add a Dev Mode where you can spawn infinite points and every unit ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Remix started
Copy Viggen Strike: Soviet Skies
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Drone = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('drone', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.5; self.direction = 1; self.fireTimer = 0; self.fireRate = 45; self.update = function () { var speedMultiplier = currentSSR ? currentSSR.enemySpeedMultiplier : 1.0; self.x += self.speed * self.direction * speedMultiplier; self.y += self.speed * 0.5 * speedMultiplier; if (self.x <= 50 || self.x >= 1998) { self.direction *= -1; } self.fireTimer++; if (self.fireTimer >= self.fireRate) { self.fireTimer = 0; var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y; bullet.targetX = viggen.x; bullet.targetY = viggen.y; bullet.age = 0; game.addChild(bullet); enemyBullets.push(bullet); } graphics.rotation += 0.05; }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.targetX = 0; self.targetY = 0; self.update = function () { self.age = (self.age || 0) + 1; var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { var speedMultiplier = currentSSR ? currentSSR.enemySpeedMultiplier : 1.0; self.x += dx / distance * self.speed * speedMultiplier; self.y += dy / distance * self.speed * speedMultiplier; } }; return self; }); var MiG23 = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('mig23', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.fireTimer = 0; self.fireRate = 60; self.interceptorType = 'mig23'; self.scoreValue = 100; self.update = function () { var speedMultiplier = currentSSR ? currentSSR.enemySpeedMultiplier : 1.0; self.y += self.speed * speedMultiplier; self.fireTimer++; if (self.fireTimer >= self.fireRate) { self.fireTimer = 0; var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y; bullet.targetX = viggen.x; bullet.targetY = viggen.y; bullet.age = 0; game.addChild(bullet); enemyBullets.push(bullet); } }; return self; }); var Powerup = Container.expand(function () { var self = Container.call(this); self.powerupType = 'speed'; // 'speed', 'shield', 'rapidfire' self.speed = 2; self.bobOffset = 0; self.bobSpeed = 0.1; self.setPowerupType = function (type) { self.powerupType = type; if (self.graphics) { self.removeChild(self.graphics); } var assetName = 'powerupSpeed'; if (type === 'shield') { assetName = 'powerupShield'; } else if (type === 'rapidfire') { assetName = 'powerupRapidFire'; } self.graphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); }; self.update = function () { self.y += self.speed; self.bobOffset += self.bobSpeed; self.graphics.y = Math.sin(self.bobOffset) * 10; self.graphics.rotation += 0.05; }; return self; }); var SAMMissile = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('samMissile', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.targetX = 0; self.targetY = 0; self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } graphics.rotation += 0.1; }; return self; }); var SAMSite = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('sam', { anchorX: 0.5, anchorY: 0.5 }); self.fireTimer = 0; self.fireRate = 90; self.update = function () { self.fireTimer++; if (self.fireTimer >= self.fireRate) { self.fireTimer = 0; var missile = new SAMMissile(); missile.x = self.x; missile.y = self.y; missile.targetX = viggen.x; missile.targetY = viggen.y; game.addChild(missile); samMissiles.push(missile); LK.getSound('missile').play(); } }; return self; }); var SSR = Container.expand(function () { var self = Container.call(this); self.name = ''; self.difficultyMultiplier = 1.0; self.enemySpeedMultiplier = 1.0; self.spawnRateMultiplier = 1.0; self.scoreMultiplier = 1.0; self.backgroundColor = 0x1a1a2e; self.description = ''; self.setSSRData = function (data) { self.name = data.name; self.difficultyMultiplier = data.difficultyMultiplier; self.enemySpeedMultiplier = data.enemySpeedMultiplier; self.spawnRateMultiplier = data.spawnRateMultiplier; self.scoreMultiplier = data.scoreMultiplier; self.backgroundColor = data.backgroundColor; self.description = data.description; if (self.graphics) { self.removeChild(self.graphics); } self.graphics = self.attachAsset(data.assetName, { anchorX: 0.5, anchorY: 0.5 }); }; return self; }); var Shilka = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('shilka', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.2; self.direction = 1; self.fireTimer = 0; self.fireRate = 120; // Time between bursts self.burstStage = 0; // 0 = waiting, 1-5 = firing burst self.burstTimer = 0; self.burstDelay = 8; // Ticks between shots in burst self.rollRotation = 0; self.update = function () { var speedMultiplier = currentSSR ? currentSSR.enemySpeedMultiplier : 1.0; // Vertical rolling movement like drone self.x += self.speed * self.direction * speedMultiplier; self.y += self.speed * 0.4 * speedMultiplier; if (self.x <= 50 || self.x >= 1998) { self.direction *= -1; } // Vertical rolling animation self.rollRotation += 0.08; graphics.rotation = Math.sin(self.rollRotation) * 0.3; // Burst firing logic self.fireTimer++; if (self.burstStage === 0) { // Waiting for next burst if (self.fireTimer >= self.fireRate) { self.fireTimer = 0; self.burstStage = 1; self.burstTimer = 0; } } else if (self.burstStage <= 5) { // Firing burst (5 groups of 3 bullets) self.burstTimer++; if (self.burstTimer >= self.burstDelay) { self.burstTimer = 0; // Fire 3 bullets in current group for (var i = 0; i < 3; i++) { var bullet = new EnemyBullet(); bullet.x = self.x + (i - 1) * 15; // Spread bullets slightly bullet.y = self.y; bullet.targetX = viggen.x + (i - 1) * 20; // Slight target spread bullet.targetY = viggen.y; bullet.age = 0; game.addChild(bullet); enemyBullets.push(bullet); } self.burstStage++; if (self.burstStage > 5) { self.burstStage = 0; // Reset to waiting state } } } }; return self; }); var Su15 = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('su15', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2.5; self.fireTimer = 0; self.fireRate = 45; self.interceptorType = 'su15'; self.scoreValue = 150; self.update = function () { var speedMultiplier = currentSSR ? currentSSR.enemySpeedMultiplier : 1.0; self.y += self.speed * speedMultiplier; self.fireTimer++; if (self.fireTimer >= self.fireRate) { self.fireTimer = 0; // Su-15 fires two bullets for (var i = 0; i < 2; i++) { var bullet = new EnemyBullet(); bullet.x = self.x + (i === 0 ? -10 : 10); bullet.y = self.y; bullet.targetX = viggen.x; bullet.targetY = viggen.y; bullet.age = 0; game.addChild(bullet); enemyBullets.push(bullet); } } }; return self; }); var Viggen = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('viggen', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var ViggenBullet = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('viggenBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8 + (upgrades.bulletSpeed - 1) * 2; self.damage = upgrades.bulletDamage; self.update = function () { self.y -= self.speed; }; return self; }); var Yak38 = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('yak38', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.5; self.fireTimer = 0; self.fireRate = 90; self.interceptorType = 'yak38'; self.scoreValue = 80; self.sideMovement = 0; self.update = function () { var speedMultiplier = currentSSR ? currentSSR.enemySpeedMultiplier : 1.0; self.y += self.speed * speedMultiplier; // Yak-38 has slight side-to-side movement self.sideMovement += 0.05; self.x += Math.sin(self.sideMovement) * 0.8; self.fireTimer++; if (self.fireTimer >= self.fireRate) { self.fireTimer = 0; var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y; bullet.targetX = viggen.x; bullet.targetY = viggen.y; bullet.age = 0; game.addChild(bullet); enemyBullets.push(bullet); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ var viggen = game.addChild(new Viggen()); viggen.x = 1024; viggen.y = 2400; var shieldEffect = null; // Upgrade system variables var upgradeMenuOpen = false; var upgradeButton = null; var upgradeMenu = null; var upgrades = { fireRate: storage.fireRateLevel || 1, bulletSpeed: storage.bulletSpeedLevel || 1, bulletDamage: storage.bulletDamageLevel || 1, shieldDuration: storage.shieldDurationLevel || 1 }; var upgradeCosts = { fireRate: [100, 250, 500, 1000, 2000], bulletSpeed: [150, 300, 600, 1200, 2400], bulletDamage: [200, 400, 800, 1600, 3200], shieldDuration: [300, 600, 1200, 2400, 4800] }; var upgradeTexts = []; // SSR Travel System var currentSSR = null; var ssrMenuOpen = false; var ssrButton = null; var ssrMenu = null; var ssrUnlocked = { ukraine: true, russia: storage.russiaUnlocked || false, kazakh: storage.kazakhUnlocked || false, belarus: storage.belarusUnlocked || false }; // Enemy Codex System var codexMenuOpen = false; var codexMenu = null; // Guide System var guideMenuOpen = false; var guideMenu = null; var currentGuideSection = 'enemies'; // 'enemies', 'travel', 'upgrades', 'maneuvers' // Dev Mode System var devModeOpen = false; var devMenu = null; var devModeEnabled = storage.devModeEnabled || false; var enemiesEncountered = { mig23: storage.mig23Encountered || false, su15: storage.su15Encountered || false, yak38: storage.yak38Encountered || false, drone: storage.droneEncountered || false, samSite: storage.samSiteEncountered || false, shilka: storage.shilkaEncountered || false }; var enemyCodexData = { mig23: { name: 'MiG-23 Flogger', description: 'Standard Soviet interceptor. Fast attack aircraft with guided missiles. Flies straight down and fires single tracking bullets.', threat: 'Medium', speed: 'Fast', fireRate: 'Medium', health: '1 Hit', tips: 'Predictable flight path makes them easy targets', assetName: 'mig23' }, su15: { name: 'Su-15 Flagon', description: 'Heavy interceptor with twin cannons. Faster than MiG-23 and fires dual tracking bullets simultaneously.', threat: 'High', speed: 'Very Fast', fireRate: 'Fast', health: '1 Hit', tips: 'Dual fire pattern - dodge sideways to avoid both bullets', assetName: 'su15' }, yak38: { name: 'Yak-38 Forger', description: 'VTOL light interceptor with erratic movement. Slower but unpredictable side-to-side flight pattern.', threat: 'Medium-Low', speed: 'Slow', fireRate: 'Slow', health: '1 Hit', tips: 'Unpredictable movement but slower fire rate. Lead your shots.', assetName: 'yak38' }, drone: { name: 'Reconnaissance Drone', description: 'Agile unmanned aircraft with side-to-side movement. Fires tracking bullets while weaving.', threat: 'High', speed: 'Medium', fireRate: 'Fast', health: '1 Hit', tips: 'Unpredictable movement pattern. Lead your shots.', assetName: 'drone' }, samSite: { name: 'SA-6 SAM Site', description: 'Surface-to-Air Missile launcher. Fires homing missiles that track your position.', threat: 'Very High', speed: 'Stationary', fireRate: 'Slow', health: '1 Hit', tips: 'Priority target. Missiles are fast and accurate.', assetName: 'sam' }, shilka: { name: 'ZSU-23-4 Shilka', description: 'Anti-aircraft gun with quad cannons. Fires in devastating bursts of 5x 3-bullet groups while rolling vertically.', threat: 'Very High', speed: 'Medium', fireRate: 'Burst', health: '1 Hit', tips: 'Take cover during bursts - 15 bullets come fast!', assetName: 'shilka' } }; var ssrData = { ukraine: { name: 'Ukrainian SSR', assetName: 'ssrUkraine', difficultyMultiplier: 1.0, enemySpeedMultiplier: 1.0, spawnRateMultiplier: 1.0, scoreMultiplier: 1.0, backgroundColor: 0x1a1a2e, description: 'Starting region with standard difficulty', unlockScore: 0 }, russia: { name: 'Russian SFSR', assetName: 'ssrRussia', difficultyMultiplier: 1.3, enemySpeedMultiplier: 1.2, spawnRateMultiplier: 1.1, scoreMultiplier: 1.5, backgroundColor: 0x2e1a1a, description: 'Harsh winter conditions, faster enemies', unlockScore: 2000 }, kazakh: { name: 'Kazakh SSR', assetName: 'ssrKazakh', difficultyMultiplier: 1.5, enemySpeedMultiplier: 1.1, spawnRateMultiplier: 1.3, scoreMultiplier: 2.0, backgroundColor: 0x2e2e1a, description: 'Desert warfare, more frequent spawns', unlockScore: 5000 }, belarus: { name: 'Byelorussian SSR', assetName: 'ssrBelarus', difficultyMultiplier: 1.8, enemySpeedMultiplier: 1.4, spawnRateMultiplier: 1.2, scoreMultiplier: 2.5, backgroundColor: 0x1a2e1a, description: 'Forest combat, elite enemy units', unlockScore: 10000 } }; var interceptors = []; var mig23s = []; var su15s = []; var yak38s = []; var shilkas = []; var samSites = []; var drones = []; var enemyBullets = []; var samMissiles = []; var viggenBullets = []; var powerups = []; var spawnTimer = 0; var powerupSpawnTimer = 0; var fireTimer = 0; var difficultyTimer = 0; var survivalTime = 0; var baseSpawnRate = 180; var currentSpawnRate = baseSpawnRate; var dragNode = null; var lastIntersecting = false; var speedBoostActive = false; var speedBoostTimer = 0; var shieldActive = false; var shieldTimer = 0; var rapidFireActive = false; var rapidFireTimer = 0; var normalFireRate = 15; var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var timeTxt = new Text2('Time: 0s', { size: 50, fill: 0xFFFFFF }); timeTxt.anchor.set(1, 0); timeTxt.x = -20; timeTxt.y = 20; LK.gui.topRight.addChild(timeTxt); upgradeButton = new Text2('UPGRADES', { size: 40, fill: 0x00ff00 }); upgradeButton.anchor.set(0.5, 0); upgradeButton.x = 0; upgradeButton.y = 100; upgradeButton.interactive = true; LK.gui.top.addChild(upgradeButton); ssrButton = new Text2('TRAVEL', { size: 40, fill: 0x0088ff }); ssrButton.anchor.set(0.5, 0); ssrButton.x = 0; ssrButton.y = 160; ssrButton.interactive = true; LK.gui.top.addChild(ssrButton); var codexButton = new Text2('CODEX', { size: 40, fill: 0xff8800 }); codexButton.anchor.set(0.5, 0); codexButton.x = 0; codexButton.y = 220; codexButton.interactive = true; LK.gui.top.addChild(codexButton); var guideButton = new Text2('GUIDE', { size: 40, fill: 0xffff00 }); guideButton.anchor.set(0.5, 0); guideButton.x = 0; guideButton.y = 280; guideButton.interactive = true; LK.gui.top.addChild(guideButton); var devButton = new Text2('DEV', { size: 40, fill: 0xff00ff }); devButton.anchor.set(0.5, 0); devButton.x = 0; devButton.y = 340; devButton.interactive = true; LK.gui.top.addChild(devButton); // Initialize with Ukrainian SSR currentSSR = new SSR(); currentSSR.setSSRData(ssrData.ukraine); game.setBackgroundColor(currentSSR.backgroundColor); function handleMove(x, y, obj) { if (dragNode) { var moveSpeed = speedBoostActive ? 1.5 : 1.0; var targetX = x; var targetY = y; if (speedBoostActive) { // Smoother movement with speed boost var dx = targetX - dragNode.x; var dy = targetY - dragNode.y; dragNode.x = Math.max(40, Math.min(2008, dragNode.x + dx * moveSpeed)); dragNode.y = Math.max(60, Math.min(2672, dragNode.y + dy * moveSpeed)); } else { dragNode.x = Math.max(40, Math.min(2008, targetX)); dragNode.y = Math.max(60, Math.min(2672, targetY)); } } // Check viggen bullets vs enemies for (var i = viggenBullets.length - 1; i >= 0; i--) { var bullet = viggenBullets[i]; var hit = false; // Check vs interceptors for (var j = interceptors.length - 1; j >= 0; j--) { if (bullet.intersects(interceptors[j])) { LK.effects.flashObject(interceptors[j], 0xff0000, 200); var scoreValue = interceptors[j].scoreValue || 100; var interceptorType = interceptors[j].interceptorType; // Remove from specific type array if (interceptorType === 'mig23') { for (var k = mig23s.length - 1; k >= 0; k--) { if (mig23s[k] === interceptors[j]) { mig23s.splice(k, 1); break; } } } else if (interceptorType === 'su15') { for (var k = su15s.length - 1; k >= 0; k--) { if (su15s[k] === interceptors[j]) { su15s.splice(k, 1); break; } } } else if (interceptorType === 'yak38') { for (var k = yak38s.length - 1; k >= 0; k--) { if (yak38s[k] === interceptors[j]) { yak38s.splice(k, 1); break; } } } interceptors[j].destroy(); interceptors.splice(j, 1); bullet.destroy(); viggenBullets.splice(i, 1); var baseScore = scoreValue * bullet.damage; var ssrMultiplier = currentSSR ? currentSSR.scoreMultiplier : 1.0; LK.setScore(LK.getScore() + Math.floor(baseScore * ssrMultiplier)); hit = true; break; } } if (hit) continue; // Check vs drones for (var j = drones.length - 1; j >= 0; j--) { if (bullet.intersects(drones[j])) { LK.effects.flashObject(drones[j], 0xff0000, 200); drones[j].destroy(); drones.splice(j, 1); bullet.destroy(); viggenBullets.splice(i, 1); var baseScore = 150 * bullet.damage; var ssrMultiplier = currentSSR ? currentSSR.scoreMultiplier : 1.0; LK.setScore(LK.getScore() + Math.floor(baseScore * ssrMultiplier)); hit = true; break; } } if (hit) continue; // Check vs SAM sites for (var j = samSites.length - 1; j >= 0; j--) { if (bullet.intersects(samSites[j])) { LK.effects.flashObject(samSites[j], 0xff0000, 200); samSites[j].destroy(); samSites.splice(j, 1); bullet.destroy(); viggenBullets.splice(i, 1); var baseScore = 200 * bullet.damage; var ssrMultiplier = currentSSR ? currentSSR.scoreMultiplier : 1.0; LK.setScore(LK.getScore() + Math.floor(baseScore * ssrMultiplier)); hit = true; break; } } if (hit) continue; // Check vs Shilkas for (var j = shilkas.length - 1; j >= 0; j--) { if (bullet.intersects(shilkas[j])) { LK.effects.flashObject(shilkas[j], 0xff0000, 200); shilkas[j].destroy(); shilkas.splice(j, 1); bullet.destroy(); viggenBullets.splice(i, 1); var baseScore = 250 * bullet.damage; var ssrMultiplier = currentSSR ? currentSSR.scoreMultiplier : 1.0; LK.setScore(LK.getScore() + Math.floor(baseScore * ssrMultiplier)); hit = true; break; } } } // Check viggen vs powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; if (viggen.intersects(powerup)) { // Apply powerup effect if (powerup.powerupType === 'speed') { speedBoostActive = true; speedBoostTimer = 300; // 5 seconds at 60fps LK.effects.flashObject(viggen, 0x00ff00, 300); } else if (powerup.powerupType === 'shield') { shieldActive = true; shieldTimer = 600 + (upgrades.shieldDuration - 1) * 180; // Base 10s + upgrades if (!shieldEffect) { shieldEffect = LK.getAsset('powerupShield', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); shieldEffect.alpha = 0.3; viggen.addChild(shieldEffect); } } else if (powerup.powerupType === 'rapidfire') { rapidFireActive = true; rapidFireTimer = 450; // 7.5 seconds at 60fps LK.effects.flashObject(viggen, 0xff8800, 300); } LK.getSound('powerup').play(); LK.setScore(LK.getScore() + 50); powerup.destroy(); powerups.splice(i, 1); } } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = viggen; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; upgradeButton.down = function (x, y, obj) { if (!upgradeMenuOpen) { openUpgradeMenu(); } else { closeUpgradeMenu(); } }; ssrButton.down = function (x, y, obj) { // Check if we're in code input mode (dev mode not yet unlocked) if (!devModeEnabled && !ssrMenuOpen) { // Add current SSR to code input sequence currentCodeInput.push(currentSSR.name.toLowerCase().replace(' ssr', '').replace('ian', '').replace('russian sfsr', 'russia').replace('kazakh', 'kazakh').replace('byelorussian', 'belarus')); codeInputTimer = 0; // Reset timer // Check if sequence matches var isCorrect = true; if (currentCodeInput.length <= secretCode.length) { for (var i = 0; i < currentCodeInput.length; i++) { if (currentCodeInput[i] !== secretCode[i]) { isCorrect = false; break; } } } else { isCorrect = false; } // If sequence is complete and correct if (currentCodeInput.length === secretCode.length && isCorrect) { devModeEnabled = true; storage.devModeEnabled = true; currentCodeInput = []; LK.effects.flashScreen(0x00FF00, 1000); var unlockText = new Text2('DEV MODE UNLOCKED!', { size: 60, fill: 0x00FF00 }); unlockText.anchor.set(0.5, 0.5); unlockText.x = 1024; unlockText.y = 1366; game.addChild(unlockText); LK.setTimeout(function () { if (unlockText.parent) { game.removeChild(unlockText); } }, 3000); return; // Don't open SSR menu } // If sequence is wrong, reset if (!isCorrect || currentCodeInput.length > secretCode.length) { currentCodeInput = []; LK.effects.flashScreen(0xFF0000, 200); } // Show progress hint var progressText = new Text2('Code: ' + currentCodeInput.length + '/' + secretCode.length, { size: 30, fill: 0xFFFF00 }); progressText.anchor.set(0.5, 0.5); progressText.x = 1024; progressText.y = 100; game.addChild(progressText); LK.setTimeout(function () { if (progressText.parent) { game.removeChild(progressText); } }, 1500); } // Normal SSR menu functionality if (!ssrMenuOpen) { openSSRMenu(); } else { closeSSRMenu(); } }; codexButton.down = function (x, y, obj) { if (!codexMenuOpen) { openCodexMenu(); } else { closeCodexMenu(); } }; guideButton.down = function (x, y, obj) { if (!guideMenuOpen) { openGuideMenu(); } else { closeGuideMenu(); } }; // Secret code system for dev mode access var secretCode = ['ukraine', 'russia', 'kazakh', 'belarus', 'ukraine']; // SSR sequence var currentCodeInput = []; var codeInputTimer = 0; var maxCodeInputTime = 300; // 5 seconds at 60fps to complete sequence devButton.down = function (x, y, obj) { if (!devModeEnabled) { // Show hint that dev mode requires unlock var hintText = new Text2('DEV MODE LOCKED\nRequires secret sequence...', { size: 25, fill: 0xFF6666 }); hintText.anchor.set(0.5, 0.5); hintText.x = 1024; hintText.y = 1366; game.addChild(hintText); // Remove hint after 2 seconds LK.setTimeout(function () { if (hintText.parent) { game.removeChild(hintText); } }, 2000); } else if (!devModeOpen) { openDevMenu(); } else { closeDevMenu(); } }; function spawnInterceptor() { var interceptorType = Math.random(); var interceptor; if (interceptorType < 0.5) { interceptor = new MiG23(); mig23s.push(interceptor); markEnemyEncountered('mig23'); } else if (interceptorType < 0.8) { interceptor = new Su15(); su15s.push(interceptor); markEnemyEncountered('su15'); } else { interceptor = new Yak38(); yak38s.push(interceptor); markEnemyEncountered('yak38'); } interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } function spawnSAMSite() { var sam = new SAMSite(); sam.x = Math.random() * 1848 + 100; sam.y = Math.random() * 400 + 100; game.addChild(sam); samSites.push(sam); markEnemyEncountered('samSite'); } function spawnDrone() { var drone = new Drone(); drone.x = Math.random() * 1848 + 100; drone.y = -50; game.addChild(drone); drones.push(drone); markEnemyEncountered('drone'); } function spawnShilka() { var shilka = new Shilka(); shilka.x = Math.random() * 1848 + 100; shilka.y = -50; game.addChild(shilka); shilkas.push(shilka); markEnemyEncountered('shilka'); } function spawnPowerup() { var powerup = new Powerup(); powerup.x = Math.random() * 1600 + 224; powerup.y = -50; var powerupTypes = ['speed', 'shield', 'rapidfire']; var randomType = powerupTypes[Math.floor(Math.random() * powerupTypes.length)]; powerup.setPowerupType(randomType); game.addChild(powerup); powerups.push(powerup); } function openUpgradeMenu() { upgradeMenuOpen = true; upgradeButton.setText('CLOSE'); upgradeMenu = new Container(); upgradeMenu.x = 0; upgradeMenu.y = 0; game.addChild(upgradeMenu); var menuBg = LK.getAsset('sam', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 20 }); menuBg.x = 1024; menuBg.y = 1366; menuBg.alpha = 0.9; menuBg.tint = 0x000066; upgradeMenu.addChild(menuBg); var titleText = new Text2('UPGRADES', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1000; upgradeMenu.addChild(titleText); var currentScore = LK.getScore(); var scoreText = new Text2('Score: ' + currentScore, { size: 50, fill: 0xFFFF00 }); scoreText.anchor.set(0.5, 0.5); scoreText.x = 1024; scoreText.y = 1100; upgradeMenu.addChild(scoreText); createUpgradeOption('Fire Rate', 'fireRate', 1200); createUpgradeOption('Bullet Speed', 'bulletSpeed', 1300); createUpgradeOption('Bullet Damage', 'bulletDamage', 1400); createUpgradeOption('Shield Duration', 'shieldDuration', 1500); } function createUpgradeOption(name, upgradeType, yPos) { var level = upgrades[upgradeType]; var maxLevel = upgradeCosts[upgradeType].length; var cost = level < maxLevel ? upgradeCosts[upgradeType][level - 1] : 'MAX'; var upgradeText = new Text2(name + ' Lv.' + level + ' - Cost: ' + cost, { size: 40, fill: level < maxLevel && LK.getScore() >= cost ? 0x00ff00 : 0xff6666 }); upgradeText.anchor.set(0.5, 0.5); upgradeText.x = 1024; upgradeText.y = yPos; upgradeText.interactive = true; upgradeMenu.addChild(upgradeText); upgradeTexts.push({ text: upgradeText, type: upgradeType }); if (level < maxLevel && LK.getScore() >= cost) { upgradeText.down = function () { buyUpgrade(upgradeType); }; } } function buyUpgrade(upgradeType) { var level = upgrades[upgradeType]; var maxLevel = upgradeCosts[upgradeType].length; var cost = upgradeCosts[upgradeType][level - 1]; if (level < maxLevel && LK.getScore() >= cost) { LK.setScore(LK.getScore() - cost); upgrades[upgradeType]++; // Save to storage if (upgradeType === 'fireRate') storage.fireRateLevel = upgrades[upgradeType];else if (upgradeType === 'bulletSpeed') storage.bulletSpeedLevel = upgrades[upgradeType];else if (upgradeType === 'bulletDamage') storage.bulletDamageLevel = upgrades[upgradeType];else if (upgradeType === 'shieldDuration') storage.shieldDurationLevel = upgrades[upgradeType]; scoreTxt.setText('Score: ' + LK.getScore()); LK.getSound('powerup').play(); closeUpgradeMenu(); } } function closeUpgradeMenu() { upgradeMenuOpen = false; upgradeButton.setText('UPGRADES'); if (upgradeMenu) { game.removeChild(upgradeMenu); upgradeMenu = null; upgradeTexts = []; } } function openSSRMenu() { ssrMenuOpen = true; ssrButton.setText('CLOSE'); ssrMenu = new Container(); ssrMenu.x = 0; ssrMenu.y = 0; game.addChild(ssrMenu); var menuBg = LK.getAsset('sam', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 20 }); menuBg.x = 1024; menuBg.y = 1366; menuBg.alpha = 0.9; menuBg.tint = 0x006666; ssrMenu.addChild(menuBg); var titleText = new Text2('SOVIET SOCIALIST REPUBLICS', { size: 60, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 900; ssrMenu.addChild(titleText); var currentText = new Text2('Current: ' + currentSSR.name, { size: 40, fill: 0xFFFF00 }); currentText.anchor.set(0.5, 0.5); currentText.x = 1024; currentText.y = 980; ssrMenu.addChild(currentText); var yPos = 1100; for (var ssrKey in ssrData) { createSSROption(ssrKey, ssrData[ssrKey], yPos); yPos += 100; } // Check for unlocks checkSSRUnlocks(); } function createSSROption(ssrKey, data, yPos) { var isUnlocked = ssrUnlocked[ssrKey]; var isCurrent = currentSSR.name === data.name; var statusText = isCurrent ? ' (CURRENT)' : isUnlocked ? ' - AVAILABLE' : ' - LOCKED (Score: ' + data.unlockScore + ')'; var optionText = new Text2(data.name + statusText, { size: 35, fill: isCurrent ? 0xFFFF00 : isUnlocked ? 0x00ff00 : 0xff6666 }); optionText.anchor.set(0.5, 0.5); optionText.x = 1024; optionText.y = yPos; optionText.interactive = true; ssrMenu.addChild(optionText); var descText = new Text2(data.description, { size: 25, fill: 0xCCCCCC }); descText.anchor.set(0.5, 0.5); descText.x = 1024; descText.y = yPos + 30; ssrMenu.addChild(descText); if (isUnlocked && !isCurrent) { optionText.down = function () { travelToSSR(ssrKey); }; } } function travelToSSR(ssrKey) { var data = ssrData[ssrKey]; currentSSR.setSSRData(data); game.setBackgroundColor(currentSSR.backgroundColor); LK.getSound('travel').play(); LK.effects.flashScreen(0x00ffff, 500); // Reset some game state for new region spawnTimer = 0; currentSpawnRate = Math.floor(baseSpawnRate / currentSSR.spawnRateMultiplier); closeSSRMenu(); } function closeSSRMenu() { ssrMenuOpen = false; ssrButton.setText('TRAVEL'); if (ssrMenu) { game.removeChild(ssrMenu); ssrMenu = null; } } function checkSSRUnlocks() { var currentScore = LK.getScore(); for (var ssrKey in ssrData) { if (!ssrUnlocked[ssrKey] && currentScore >= ssrData[ssrKey].unlockScore) { ssrUnlocked[ssrKey] = true; // Save unlock status if (ssrKey === 'russia') storage.russiaUnlocked = true;else if (ssrKey === 'kazakh') storage.kazakhUnlocked = true;else if (ssrKey === 'belarus') storage.belarusUnlocked = true; LK.effects.flashScreen(0x00ff00, 300); } } } function openCodexMenu() { codexMenuOpen = true; codexButton.setText('CLOSE'); codexMenu = new Container(); codexMenu.x = 0; codexMenu.y = 0; game.addChild(codexMenu); var menuBg = LK.getAsset('sam', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 20 }); menuBg.x = 1024; menuBg.y = 1366; menuBg.alpha = 0.9; menuBg.tint = 0x660066; codexMenu.addChild(menuBg); var titleText = new Text2('ENEMY CODEX', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 900; codexMenu.addChild(titleText); var instructionText = new Text2('Encounter enemies to unlock their data', { size: 35, fill: 0xCCCCCC }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 980; codexMenu.addChild(instructionText); var yPos = 1100; for (var enemyKey in enemyCodexData) { createCodexEntry(enemyKey, enemyCodexData[enemyKey], yPos); yPos += 200; } } function createCodexEntry(enemyKey, data, yPos) { var isEncountered = enemiesEncountered[enemyKey]; var nameText = new Text2(isEncountered ? data.name : '??? CLASSIFIED ???', { size: 45, fill: isEncountered ? 0x00ff00 : 0x666666 }); nameText.anchor.set(0.5, 0.5); nameText.x = 1024; nameText.y = yPos; codexMenu.addChild(nameText); if (isEncountered) { var descText = new Text2(data.description, { size: 30, fill: 0xFFFFFF }); descText.anchor.set(0.5, 0.5); descText.x = 1024; descText.y = yPos + 40; codexMenu.addChild(descText); var statsText = new Text2('Threat: ' + data.threat + ' | Speed: ' + data.speed + ' | Fire Rate: ' + data.fireRate, { size: 25, fill: 0xFFFF88 }); statsText.anchor.set(0.5, 0.5); statsText.x = 1024; statsText.y = yPos + 75; codexMenu.addChild(statsText); var tipsText = new Text2('Tips: ' + data.tips, { size: 25, fill: 0x88FF88 }); tipsText.anchor.set(0.5, 0.5); tipsText.x = 1024; tipsText.y = yPos + 105; codexMenu.addChild(tipsText); } else { var lockedText = new Text2('Encounter this enemy type to unlock data', { size: 25, fill: 0x666666 }); lockedText.anchor.set(0.5, 0.5); lockedText.x = 1024; lockedText.y = yPos + 40; codexMenu.addChild(lockedText); } } function closeCodexMenu() { codexMenuOpen = false; codexButton.setText('CODEX'); if (codexMenu) { game.removeChild(codexMenu); codexMenu = null; } } function markEnemyEncountered(enemyType) { if (!enemiesEncountered[enemyType]) { enemiesEncountered[enemyType] = true; // Save to storage if (enemyType === 'mig23') storage.mig23Encountered = true;else if (enemyType === 'su15') storage.su15Encountered = true;else if (enemyType === 'yak38') storage.yak38Encountered = true;else if (enemyType === 'drone') storage.droneEncountered = true;else if (enemyType === 'samSite') storage.samSiteEncountered = true;else if (enemyType === 'shilka') storage.shilkaEncountered = true; // Flash effect for discovery LK.effects.flashScreen(0x00ffff, 200); } } function openGuideMenu() { guideMenuOpen = true; guideButton.setText('CLOSE'); guideMenu = new Container(); guideMenu.x = 0; guideMenu.y = 0; game.addChild(guideMenu); var menuBg = LK.getAsset('sam', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 20 }); menuBg.x = 1024; menuBg.y = 1366; menuBg.alpha = 0.95; menuBg.tint = 0x003366; guideMenu.addChild(menuBg); var titleText = new Text2('GAME GUIDE', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 700; guideMenu.addChild(titleText); // Section buttons var enemiesBtn = new Text2('[ENEMIES]', { size: 35, fill: currentGuideSection === 'enemies' ? 0xFFFF00 : 0x88CCFF }); enemiesBtn.anchor.set(0.5, 0.5); enemiesBtn.x = 700; enemiesBtn.y = 800; enemiesBtn.interactive = true; guideMenu.addChild(enemiesBtn); var travelBtn = new Text2('[TRAVEL]', { size: 35, fill: currentGuideSection === 'travel' ? 0xFFFF00 : 0x88CCFF }); travelBtn.anchor.set(0.5, 0.5); travelBtn.x = 900; travelBtn.y = 800; travelBtn.interactive = true; guideMenu.addChild(travelBtn); var upgradesBtn = new Text2('[UPGRADES]', { size: 35, fill: currentGuideSection === 'upgrades' ? 0xFFFF00 : 0x88CCFF }); upgradesBtn.anchor.set(0.5, 0.5); upgradesBtn.x = 1100; upgradesBtn.y = 800; upgradesBtn.interactive = true; guideMenu.addChild(upgradesBtn); var maneuversBtn = new Text2('[MANEUVERS]', { size: 35, fill: currentGuideSection === 'maneuvers' ? 0xFFFF00 : 0x88CCFF }); maneuversBtn.anchor.set(0.5, 0.5); maneuversBtn.x = 1350; maneuversBtn.y = 800; maneuversBtn.interactive = true; guideMenu.addChild(maneuversBtn); // Event handlers for section buttons enemiesBtn.down = function () { currentGuideSection = 'enemies'; closeGuideMenu(); openGuideMenu(); }; travelBtn.down = function () { currentGuideSection = 'travel'; closeGuideMenu(); openGuideMenu(); }; upgradesBtn.down = function () { currentGuideSection = 'upgrades'; closeGuideMenu(); openGuideMenu(); }; maneuversBtn.down = function () { currentGuideSection = 'maneuvers'; closeGuideMenu(); openGuideMenu(); }; // Display content based on current section if (currentGuideSection === 'enemies') { displayEnemyTips(); } else if (currentGuideSection === 'travel') { displayTravelGuide(); } else if (currentGuideSection === 'upgrades') { displayUpgradeGuide(); } else if (currentGuideSection === 'maneuvers') { displayManeuverGuide(); } } function displayEnemyTips() { var enemyTips = { mig23: { name: 'MiG-23 Flogger', tip1: '• Keep moving - they fire straight at your position', tip2: '• Destroy quickly before they crowd the screen' }, su15: { name: 'Su-15 Flagon', tip1: '• Watch for dual bullets - dodge sideways not just up/down', tip2: '• Priority target due to high fire rate and speed' }, yak38: { name: 'Yak-38 Forger', tip1: '• Slow but erratic - lead your shots ahead', tip2: '• Use their slow fire rate to get close safely' }, drone: { name: 'Reconnaissance Drone', tip1: '• Never stay still - they track while weaving', tip2: '• Focus fire when they reverse direction at edges' }, samSite: { name: 'SAM Site', tip1: '• Destroy immediately - missiles are hard to dodge', tip2: '• Move in circles to confuse missile tracking' }, shilka: { name: 'Shilka SPAA', tip1: '• Take cover during burst phases - 15 bullets incoming!', tip2: '• Attack between bursts when it\'s reloading' } }; var yPos = 900; for (var key in enemyTips) { var enemy = enemyTips[key]; var nameText = new Text2(enemy.name, { size: 35, fill: 0xFFFF00 }); nameText.anchor.set(0.5, 0.5); nameText.x = 1024; nameText.y = yPos; guideMenu.addChild(nameText); var tip1Text = new Text2(enemy.tip1, { size: 25, fill: 0xFFFFFF }); tip1Text.anchor.set(0.5, 0.5); tip1Text.x = 1024; tip1Text.y = yPos + 30; guideMenu.addChild(tip1Text); var tip2Text = new Text2(enemy.tip2, { size: 25, fill: 0xFFFFFF }); tip2Text.anchor.set(0.5, 0.5); tip2Text.x = 1024; tip2Text.y = yPos + 55; guideMenu.addChild(tip2Text); yPos += 100; } } function displayTravelGuide() { var travelGuideText = ['TRAVEL SYSTEM GUIDE', '', '• Unlock new SSRs by reaching score thresholds', '• Each SSR has unique difficulty modifiers:', ' - Enemy speed multiplier', ' - Spawn rate multiplier', ' - Score multiplier (risk vs reward!)', '', 'SSR ENEMY PATTERNS:', '• Ukraine: MiG-23s, Yak-38s, Drones', '• Russia: MiG-23s, Su-15s, SAM Sites', '• Kazakhstan: Yak-38 swarms, Drones, Shilkas', '• Belarus: SAMs, Su-15s, Shilkas, MiG-23s', '', 'STRATEGY TIPS:', '• Farm easy points in Ukraine first', '• Move to Russia (2000 pts) for 1.5x score', '• Kazakhstan (5000 pts) has more enemies', '• Belarus (10000 pts) is ultimate challenge', '', '• Higher difficulty = Higher score multiplier', '• Return to easier SSRs if struggling', '• Upgrades carry between all SSRs']; var yPos = 900; for (var i = 0; i < travelGuideText.length; i++) { var text = new Text2(travelGuideText[i], { size: i === 0 ? 40 : 28, fill: i === 0 ? 0xFFFF00 : travelGuideText[i].includes('SSR ENEMY PATTERNS:') || travelGuideText[i].includes('STRATEGY TIPS:') ? 0x88FF88 : 0xFFFFFF }); text.anchor.set(0.5, 0.5); text.x = 1024; text.y = yPos; guideMenu.addChild(text); yPos += i === 0 ? 50 : 35; } } function displayUpgradeGuide() { var upgradeGuideText = ['UPGRADE SYSTEM GUIDE', '', 'FIRE RATE (100-2000 pts):', '• Essential first upgrade', '• Reduces time between shots', '', 'BULLET SPEED (150-2400 pts):', '• Helps hit fast-moving enemies', '• Great for interceptors', '', 'BULLET DAMAGE (200-3200 pts):', '• Multiplies score per kill', '• Best long-term investment', '', 'SHIELD DURATION (300-4800 pts):', '• Extends power-up shield time', '• Crucial for high difficulty SSRs', '', 'TIP: Balance upgrades for best results!']; var yPos = 900; for (var i = 0; i < upgradeGuideText.length; i++) { var text = new Text2(upgradeGuideText[i], { size: i === 0 ? 40 : upgradeGuideText[i].includes(':') ? 30 : 25, fill: i === 0 ? 0xFFFF00 : upgradeGuideText[i].includes(':') ? 0x88FF88 : 0xFFFFFF }); text.anchor.set(0.5, 0.5); text.x = 1024; text.y = yPos; guideMenu.addChild(text); yPos += i === 0 ? 50 : 35; } } function displayManeuverGuide() { var maneuverGuideText = ['BASIC MANEUVERS', '', 'DEFENSIVE MOVES:', '• Circle Strafe - Move in circles vs SAMs', '• Edge Hugging - Use screen edges safely', '• Weaving - Small zigzags vs tracking', '', 'OFFENSIVE TACTICS:', '• Lead Shots - Aim ahead of moving targets', '• Focus Fire - One enemy at a time', '• Priority Targeting - SAMs > Su-15 > Rest', '', 'POWER-UP USAGE:', '• Speed (Green) - For dodging clusters', '• Shield (Blue) - Save for emergencies', '• Rapid Fire (Orange) - Clear screens fast', '', 'SURVIVAL TIP: Keep moving, never stop!']; var yPos = 900; for (var i = 0; i < maneuverGuideText.length; i++) { var text = new Text2(maneuverGuideText[i], { size: i === 0 ? 40 : maneuverGuideText[i].includes(':') ? 30 : 25, fill: i === 0 ? 0xFFFF00 : maneuverGuideText[i].includes(':') ? 0x88CCFF : 0xFFFFFF }); text.anchor.set(0.5, 0.5); text.x = 1024; text.y = yPos; guideMenu.addChild(text); yPos += i === 0 ? 50 : 32; } } function closeGuideMenu() { guideMenuOpen = false; guideButton.setText('GUIDE'); if (guideMenu) { game.removeChild(guideMenu); guideMenu = null; } } function openDevMenu() { devModeOpen = true; devButton.setText('CLOSE'); devMenu = new Container(); devMenu.x = 0; devMenu.y = 0; game.addChild(devMenu); var menuBg = LK.getAsset('sam', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 20 }); menuBg.x = 1024; menuBg.y = 1366; menuBg.alpha = 0.95; menuBg.tint = 0x660000; devMenu.addChild(menuBg); var titleText = new Text2('DEV MODE', { size: 80, fill: 0xFF0000 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 700; devMenu.addChild(titleText); var statusText = new Text2('Status: ' + (devModeEnabled ? 'ENABLED' : 'DISABLED'), { size: 40, fill: devModeEnabled ? 0x00FF00 : 0xFF6666 }); statusText.anchor.set(0.5, 0.5); statusText.x = 1024; statusText.y = 800; devMenu.addChild(statusText); // Toggle dev mode button var toggleBtn = new Text2(devModeEnabled ? 'DISABLE DEV MODE' : 'ENABLE DEV MODE', { size: 35, fill: 0xFFFF00 }); toggleBtn.anchor.set(0.5, 0.5); toggleBtn.x = 1024; toggleBtn.y = 900; toggleBtn.interactive = true; devMenu.addChild(toggleBtn); toggleBtn.down = function () { devModeEnabled = !devModeEnabled; storage.devModeEnabled = devModeEnabled; closeDevMenu(); openDevMenu(); }; if (devModeEnabled) { // Add 10000 points button var pointsBtn = new Text2('ADD 10000 POINTS', { size: 35, fill: 0x00FF00 }); pointsBtn.anchor.set(0.5, 0.5); pointsBtn.x = 1024; pointsBtn.y = 1000; pointsBtn.interactive = true; devMenu.addChild(pointsBtn); pointsBtn.down = function () { LK.setScore(LK.getScore() + 10000); scoreTxt.setText('Score: ' + LK.getScore()); LK.effects.flashScreen(0x00FF00, 300); }; // Spawn enemy buttons var spawnMig23Btn = new Text2('SPAWN MIG-23', { size: 30, fill: 0xFFAAAA }); spawnMig23Btn.anchor.set(0.5, 0.5); spawnMig23Btn.x = 700; spawnMig23Btn.y = 1100; spawnMig23Btn.interactive = true; devMenu.addChild(spawnMig23Btn); spawnMig23Btn.down = function () { var interceptor = new MiG23(); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); mig23s.push(interceptor); interceptors.push(interceptor); markEnemyEncountered('mig23'); }; var spawnSu15Btn = new Text2('SPAWN SU-15', { size: 30, fill: 0xAAAAFF }); spawnSu15Btn.anchor.set(0.5, 0.5); spawnSu15Btn.x = 1024; spawnSu15Btn.y = 1100; spawnSu15Btn.interactive = true; devMenu.addChild(spawnSu15Btn); spawnSu15Btn.down = function () { var interceptor = new Su15(); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); su15s.push(interceptor); interceptors.push(interceptor); markEnemyEncountered('su15'); }; var spawnYak38Btn = new Text2('SPAWN YAK-38', { size: 30, fill: 0xFFFFAA }); spawnYak38Btn.anchor.set(0.5, 0.5); spawnYak38Btn.x = 1348; spawnYak38Btn.y = 1100; spawnYak38Btn.interactive = true; devMenu.addChild(spawnYak38Btn); spawnYak38Btn.down = function () { var interceptor = new Yak38(); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); yak38s.push(interceptor); interceptors.push(interceptor); markEnemyEncountered('yak38'); }; var spawnDroneBtn = new Text2('SPAWN DRONE', { size: 30, fill: 0xAAFFAA }); spawnDroneBtn.anchor.set(0.5, 0.5); spawnDroneBtn.x = 700; spawnDroneBtn.y = 1200; spawnDroneBtn.interactive = true; devMenu.addChild(spawnDroneBtn); spawnDroneBtn.down = function () { spawnDrone(); }; var spawnSAMBtn = new Text2('SPAWN SAM', { size: 30, fill: 0xFFAAFF }); spawnSAMBtn.anchor.set(0.5, 0.5); spawnSAMBtn.x = 1024; spawnSAMBtn.y = 1200; spawnSAMBtn.interactive = true; devMenu.addChild(spawnSAMBtn); spawnSAMBtn.down = function () { spawnSAMSite(); }; var spawnShilkaBtn = new Text2('SPAWN SHILKA', { size: 30, fill: 0xAAAA00 }); spawnShilkaBtn.anchor.set(0.5, 0.5); spawnShilkaBtn.x = 1348; spawnShilkaBtn.y = 1200; spawnShilkaBtn.interactive = true; devMenu.addChild(spawnShilkaBtn); spawnShilkaBtn.down = function () { spawnShilka(); }; // Powerup spawn buttons var spawnSpeedBtn = new Text2('SPAWN SPEED', { size: 30, fill: 0x00FF00 }); spawnSpeedBtn.anchor.set(0.5, 0.5); spawnSpeedBtn.x = 700; spawnSpeedBtn.y = 1300; spawnSpeedBtn.interactive = true; devMenu.addChild(spawnSpeedBtn); spawnSpeedBtn.down = function () { var powerup = new Powerup(); powerup.x = viggen.x; powerup.y = viggen.y - 100; powerup.setPowerupType('speed'); game.addChild(powerup); powerups.push(powerup); }; var spawnShieldBtn = new Text2('SPAWN SHIELD', { size: 30, fill: 0x0000FF }); spawnShieldBtn.anchor.set(0.5, 0.5); spawnShieldBtn.x = 1024; spawnShieldBtn.y = 1300; spawnShieldBtn.interactive = true; devMenu.addChild(spawnShieldBtn); spawnShieldBtn.down = function () { var powerup = new Powerup(); powerup.x = viggen.x; powerup.y = viggen.y - 100; powerup.setPowerupType('shield'); game.addChild(powerup); powerups.push(powerup); }; var spawnRapidBtn = new Text2('SPAWN RAPID', { size: 30, fill: 0xFF8800 }); spawnRapidBtn.anchor.set(0.5, 0.5); spawnRapidBtn.x = 1348; spawnRapidBtn.y = 1300; spawnRapidBtn.interactive = true; devMenu.addChild(spawnRapidBtn); spawnRapidBtn.down = function () { var powerup = new Powerup(); powerup.x = viggen.x; powerup.y = viggen.y - 100; powerup.setPowerupType('rapidfire'); game.addChild(powerup); powerups.push(powerup); }; // Clear all enemies button var clearBtn = new Text2('CLEAR ALL ENEMIES', { size: 30, fill: 0xFF0000 }); clearBtn.anchor.set(0.5, 0.5); clearBtn.x = 1024; clearBtn.y = 1400; clearBtn.interactive = true; devMenu.addChild(clearBtn); clearBtn.down = function () { // Clear all enemy arrays and destroy objects for (var i = interceptors.length - 1; i >= 0; i--) { interceptors[i].destroy(); } interceptors = []; mig23s = []; su15s = []; yak38s = []; for (var i = drones.length - 1; i >= 0; i--) { drones[i].destroy(); } drones = []; for (var i = shilkas.length - 1; i >= 0; i--) { shilkas[i].destroy(); } shilkas = []; for (var i = samSites.length - 1; i >= 0; i--) { samSites[i].destroy(); } samSites = []; for (var i = enemyBullets.length - 1; i >= 0; i--) { enemyBullets[i].destroy(); } enemyBullets = []; for (var i = samMissiles.length - 1; i >= 0; i--) { samMissiles[i].destroy(); } samMissiles = []; LK.effects.flashScreen(0xFF0000, 500); }; } } function closeDevMenu() { devModeOpen = false; devButton.setText('DEV'); if (devMenu) { game.removeChild(devMenu); devMenu = null; } } function checkCollisions() { if (shieldActive) { // Shield protects from all damage return; } for (var i = 0; i < enemyBullets.length; i++) { if (viggen.intersects(enemyBullets[i])) { LK.effects.flashScreen(0xff0000, 1000); LK.getSound('explosion').play(); LK.showGameOver(); return; } } for (var i = 0; i < samMissiles.length; i++) { if (viggen.intersects(samMissiles[i])) { LK.effects.flashScreen(0xff0000, 1000); LK.getSound('explosion').play(); LK.showGameOver(); return; } } for (var i = 0; i < interceptors.length; i++) { if (viggen.intersects(interceptors[i])) { LK.effects.flashScreen(0xff0000, 1000); LK.getSound('explosion').play(); LK.showGameOver(); return; } } for (var i = 0; i < drones.length; i++) { if (viggen.intersects(drones[i])) { LK.effects.flashScreen(0xff0000, 1000); LK.getSound('explosion').play(); LK.showGameOver(); return; } } for (var i = 0; i < shilkas.length; i++) { if (viggen.intersects(shilkas[i])) { LK.effects.flashScreen(0xff0000, 1000); LK.getSound('explosion').play(); LK.showGameOver(); return; } } } function cleanupOffscreenEntities() { for (var i = interceptors.length - 1; i >= 0; i--) { if (interceptors[i].y > 2800) { var interceptorType = interceptors[i].interceptorType; // Remove from specific type array if (interceptorType === 'mig23') { for (var k = mig23s.length - 1; k >= 0; k--) { if (mig23s[k] === interceptors[i]) { mig23s.splice(k, 1); break; } } } else if (interceptorType === 'su15') { for (var k = su15s.length - 1; k >= 0; k--) { if (su15s[k] === interceptors[i]) { su15s.splice(k, 1); break; } } } else if (interceptorType === 'yak38') { for (var k = yak38s.length - 1; k >= 0; k--) { if (yak38s[k] === interceptors[i]) { yak38s.splice(k, 1); break; } } } interceptors[i].destroy(); interceptors.splice(i, 1); } } for (var i = drones.length - 1; i >= 0; i--) { if (drones[i].y > 2800) { drones[i].destroy(); drones.splice(i, 1); } } for (var i = shilkas.length - 1; i >= 0; i--) { if (shilkas[i].y > 2800) { shilkas[i].destroy(); shilkas.splice(i, 1); } } for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; if (bullet.x < -20 || bullet.x > 2068 || bullet.y < -20 || bullet.y > 2752 || bullet.age && bullet.age > 300) { bullet.destroy(); enemyBullets.splice(i, 1); } } for (var i = samMissiles.length - 1; i >= 0; i--) { var missile = samMissiles[i]; if (missile.x < -50 || missile.x > 2098 || missile.y < -50 || missile.y > 2782) { missile.destroy(); samMissiles.splice(i, 1); } } for (var i = samSites.length - 1; i >= 0; i--) { if (samSites[i].y > 2800 || samSites[i].x < -100 || samSites[i].x > 2148) { samSites[i].destroy(); samSites.splice(i, 1); } } // Clean up viggen bullets for (var i = viggenBullets.length - 1; i >= 0; i--) { if (viggenBullets[i].y < -50) { viggenBullets[i].destroy(); viggenBullets.splice(i, 1); } } // Clean up powerups for (var i = powerups.length - 1; i >= 0; i--) { if (powerups[i].y > 2800) { powerups[i].destroy(); powerups.splice(i, 1); } } } game.update = function () { survivalTime++; difficultyTimer++; spawnTimer++; if (LK.ticks % 60 === 0) { var timeInSeconds = Math.floor(survivalTime / 60); timeTxt.setText('Time: ' + timeInSeconds + 's'); var score = timeInSeconds * 10 + Math.floor(survivalTime / 6); LK.setScore(score); scoreTxt.setText('Score: ' + score); } if (difficultyTimer >= 300) { difficultyTimer = 0; currentSpawnRate = Math.max(60, currentSpawnRate - 10); } // Apply SSR spawn rate multiplier var ssrSpawnRate = currentSSR ? Math.floor(currentSpawnRate / currentSSR.spawnRateMultiplier) : currentSpawnRate; if (spawnTimer >= ssrSpawnRate) { spawnTimer = 0; var spawnType = Math.random(); // SSR-specific enemy spawning patterns if (currentSSR && currentSSR.name === 'Ukrainian SSR') { // Ukraine: MiG-23, Yak-38 and Drones if (spawnType < 0.4) { // Spawn MiG-23 specifically var interceptor = new MiG23(); mig23s.push(interceptor); markEnemyEncountered('mig23'); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } else if (spawnType < 0.7) { // Spawn Yak-38 specifically var interceptor = new Yak38(); yak38s.push(interceptor); markEnemyEncountered('yak38'); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } else { spawnDrone(); } } else if (currentSSR && currentSSR.name === 'Russian SFSR') { // Russia: MiG-23, Su-15, SAMs if (spawnType < 0.4) { // Spawn MiG-23 specifically var interceptor = new MiG23(); mig23s.push(interceptor); markEnemyEncountered('mig23'); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } else if (spawnType < 0.7) { // Spawn Su-15 specifically var interceptor = new Su15(); su15s.push(interceptor); markEnemyEncountered('su15'); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } else { spawnSAMSite(); } } else if (currentSSR && currentSSR.name === 'Kazakh SSR') { // Kazakhstan: Yak-38 (swarms), drones and Shilkas if (spawnType < 0.5) { // Spawn Yak-38 specifically (swarms) var interceptor = new Yak38(); yak38s.push(interceptor); markEnemyEncountered('yak38'); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } else if (spawnType < 0.75) { spawnDrone(); } else { spawnShilka(); } } else if (currentSSR && currentSSR.name === 'Byelorussian SSR') { // Belarus: SAMs, Su-15s, Shilkas and MiG-23s if (spawnType < 0.3) { spawnSAMSite(); } else if (spawnType < 0.55) { // Spawn Su-15 specifically var interceptor = new Su15(); su15s.push(interceptor); markEnemyEncountered('su15'); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } else if (spawnType < 0.8) { spawnShilka(); } else { // Spawn MiG-23 specifically var interceptor = new MiG23(); mig23s.push(interceptor); markEnemyEncountered('mig23'); interceptor.x = Math.random() * 1848 + 100; interceptor.y = -100; game.addChild(interceptor); interceptors.push(interceptor); } } else { // Default spawning (fallback) if (spawnType < 0.35) { spawnInterceptor(); } else if (spawnType < 0.7) { spawnDrone(); } else if (spawnType < 0.9) { spawnSAMSite(); } else { spawnShilka(); } } } // Check for SSR unlocks checkSSRUnlocks(); // Spawn powerups occasionally powerupSpawnTimer++; if (powerupSpawnTimer >= 900) { // Every 15 seconds powerupSpawnTimer = 0; spawnPowerup(); } // Update powerup effects if (speedBoostTimer > 0) { speedBoostTimer--; if (speedBoostTimer === 0) { speedBoostActive = false; } } if (shieldTimer > 0) { shieldTimer--; if (shieldTimer === 0) { shieldActive = false; if (shieldEffect) { viggen.removeChild(shieldEffect); shieldEffect = null; } } } if (rapidFireTimer > 0) { rapidFireTimer--; if (rapidFireTimer === 0) { rapidFireActive = false; } } // Fire viggen bullets fireTimer++; var upgradeFireRate = Math.max(5, normalFireRate - (upgrades.fireRate - 1) * 2); var currentFireRate = rapidFireActive ? Math.floor(upgradeFireRate / 3) : upgradeFireRate; if (fireTimer >= currentFireRate) { fireTimer = 0; var bullet = new ViggenBullet(); bullet.x = viggen.x; bullet.y = viggen.y - 60; game.addChild(bullet); viggenBullets.push(bullet); LK.getSound('shoot').play(); } checkCollisions(); cleanupOffscreenEntities(); if (enemyBullets.length > 200) { for (var i = 0; i < 50; i++) { if (enemyBullets[i]) { enemyBullets[i].destroy(); enemyBullets.splice(i, 1); } } } if (samMissiles.length > 100) { for (var i = 0; i < 25; i++) { if (samMissiles[i]) { samMissiles[i].destroy(); samMissiles.splice(i, 1); } } } // Handle secret code input timeout if (!devModeEnabled && currentCodeInput.length > 0) { codeInputTimer++; if (codeInputTimer >= maxCodeInputTime) { currentCodeInput = []; // Reset if too much time passes codeInputTimer = 0; } } }; LK.playMusic('combat');
===================================================================
--- original.js
+++ change.js
@@ -756,8 +756,67 @@
closeUpgradeMenu();
}
};
ssrButton.down = function (x, y, obj) {
+ // Check if we're in code input mode (dev mode not yet unlocked)
+ if (!devModeEnabled && !ssrMenuOpen) {
+ // Add current SSR to code input sequence
+ currentCodeInput.push(currentSSR.name.toLowerCase().replace(' ssr', '').replace('ian', '').replace('russian sfsr', 'russia').replace('kazakh', 'kazakh').replace('byelorussian', 'belarus'));
+ codeInputTimer = 0; // Reset timer
+ // Check if sequence matches
+ var isCorrect = true;
+ if (currentCodeInput.length <= secretCode.length) {
+ for (var i = 0; i < currentCodeInput.length; i++) {
+ if (currentCodeInput[i] !== secretCode[i]) {
+ isCorrect = false;
+ break;
+ }
+ }
+ } else {
+ isCorrect = false;
+ }
+ // If sequence is complete and correct
+ if (currentCodeInput.length === secretCode.length && isCorrect) {
+ devModeEnabled = true;
+ storage.devModeEnabled = true;
+ currentCodeInput = [];
+ LK.effects.flashScreen(0x00FF00, 1000);
+ var unlockText = new Text2('DEV MODE UNLOCKED!', {
+ size: 60,
+ fill: 0x00FF00
+ });
+ unlockText.anchor.set(0.5, 0.5);
+ unlockText.x = 1024;
+ unlockText.y = 1366;
+ game.addChild(unlockText);
+ LK.setTimeout(function () {
+ if (unlockText.parent) {
+ game.removeChild(unlockText);
+ }
+ }, 3000);
+ return; // Don't open SSR menu
+ }
+ // If sequence is wrong, reset
+ if (!isCorrect || currentCodeInput.length > secretCode.length) {
+ currentCodeInput = [];
+ LK.effects.flashScreen(0xFF0000, 200);
+ }
+ // Show progress hint
+ var progressText = new Text2('Code: ' + currentCodeInput.length + '/' + secretCode.length, {
+ size: 30,
+ fill: 0xFFFF00
+ });
+ progressText.anchor.set(0.5, 0.5);
+ progressText.x = 1024;
+ progressText.y = 100;
+ game.addChild(progressText);
+ LK.setTimeout(function () {
+ if (progressText.parent) {
+ game.removeChild(progressText);
+ }
+ }, 1500);
+ }
+ // Normal SSR menu functionality
if (!ssrMenuOpen) {
openSSRMenu();
} else {
closeSSRMenu();
@@ -776,10 +835,31 @@
} else {
closeGuideMenu();
}
};
+// Secret code system for dev mode access
+var secretCode = ['ukraine', 'russia', 'kazakh', 'belarus', 'ukraine']; // SSR sequence
+var currentCodeInput = [];
+var codeInputTimer = 0;
+var maxCodeInputTime = 300; // 5 seconds at 60fps to complete sequence
devButton.down = function (x, y, obj) {
- if (!devModeOpen) {
+ if (!devModeEnabled) {
+ // Show hint that dev mode requires unlock
+ var hintText = new Text2('DEV MODE LOCKED\nRequires secret sequence...', {
+ size: 25,
+ fill: 0xFF6666
+ });
+ hintText.anchor.set(0.5, 0.5);
+ hintText.x = 1024;
+ hintText.y = 1366;
+ game.addChild(hintText);
+ // Remove hint after 2 seconds
+ LK.setTimeout(function () {
+ if (hintText.parent) {
+ game.removeChild(hintText);
+ }
+ }, 2000);
+ } else if (!devModeOpen) {
openDevMenu();
} else {
closeDevMenu();
}
@@ -1905,6 +1985,14 @@
samMissiles.splice(i, 1);
}
}
}
+ // Handle secret code input timeout
+ if (!devModeEnabled && currentCodeInput.length > 0) {
+ codeInputTimer++;
+ if (codeInputTimer >= maxCodeInputTime) {
+ currentCodeInput = []; // Reset if too much time passes
+ codeInputTimer = 0;
+ }
+ }
};
LK.playMusic('combat');
\ No newline at end of file
Modern App Store icon, high definition, square with rounded corners, for a game titled "Viggen Strike: Soviet Skies" and with the description "Pilot a Saab 37 Viggen through Soviet airspace in this intense bullet hell game, dodging interceptors, SAMs, and drones in a test of aerial survival.". No text on icon!
A Saab 37 Viggen fighter jet.. In-Game asset. 2d. High contrast. No shadows. Top down view
A surface-to-air (SAM) missile.. In-Game asset. 2d. High contrast. No shadows
A surface-to-air (SAM) missile launcher.. In-Game asset. 2d. High contrast. No shadows. Top down view
A Orion fighter UAV.. In-Game asset. 2d. High contrast. No shadows. Top down view
A Su-15 Flagon heavy Interceptor aircraft.. In-Game asset. 2d. High contrast. No shadows. Top down view
Saab 35 Dakem fighter.. In-Game asset. 2d. High contrast. No shadows. Top down view