// ═══ defs.js ═══ // ============================================================ // DEFINITIONS — elements, enemies, weapons, upgrades // ============================================================ // ── ELEMENTS ───────────────────────────────────────────────── const ELEMENTS = { fire: { name: 'Fire', color: '#ff6b35', glow: '#ff3300', icon: '🔥' }, ice: { name: 'Ice', color: '#7ecfff', glow: '#00cfff', icon: '❄️' }, lightning: { name: 'Lightning', color: '#ffe033', glow: '#ffcc00', icon: '⚡' }, poison: { name: 'Poison', color: '#7fff4f', glow: '#44ff00', icon: '☠️' }, void: { name: 'Void', color: '#c77dff', glow: '#9900ff', icon: '🌀' }, arcane: { name: 'Arcane', color: '#ff77e9', glow: '#ff00cc', icon: '✨' }, physical: { name: 'Physical', color: '#c8c8c8', glow: '#ffffff', icon: '💢' }, }; // ── ENEMY TYPES ─────────────────────────────────────────────── const ENEMY_DEFS = [ { id: 'grunt', name: 'GRUNT', desc: 'Basic foot soldier. No special traits.', hp: 8, speed: 0.9, radius: 7, armor: 0, color: '#aaaaaa', glowColor: '#ffffff', cost: 20, reward: 30, resistances: {}, weaknesses: { poison: 1.3 }, element: null, count: 1, }, { id: 'runner', name: 'RUNNER', desc: 'Very fast, low HP. Hard to track.', hp: 5, speed: 2.35, radius: 5, armor: 0, color: '#00ff88', glowColor: '#00ff88', cost: 30, reward: 44, resistances: {}, weaknesses: { lightning: 1.5, poison: 1.3 }, element: null, count: 1, }, { id: 'brute', name: 'BRUTE', desc: 'High HP and armor. Slow mover.', hp: 35, speed: 0.52, radius: 13, armor: 3, color: '#ff7043', glowColor: '#ff3300', cost: 80, reward: 112, resistances: { physical: 0.5 }, weaknesses: { void: 1.8, fire: 1.4, poison: 1.3 }, element: null, count: 1, }, { id: 'swarm', name: 'SWARM', desc: 'Spawns 6 tiny units at once.', hp: 3, speed: 1.85, radius: 4, armor: 0, color: '#ce93d8', glowColor: '#cc00ff', cost: 60, reward: 84, resistances: {}, weaknesses: { fire: 1.4, lightning: 1.4 }, element: null, count: 6, }, { id: 'phantom', name: 'PHANTOM', desc: '40% dodge. Void-touched.', hp: 6, speed: 1.7, radius: 7, armor: 0, color: '#c77dff', glowColor: '#9900ff', cost: 100, reward: 138, evasion: 0.3, resistances: { void: 0.3, arcane: 0.5 }, weaknesses: { fire: 1.5 }, element: 'void', count: 1, }, { id: 'iceling', name: 'ICELING', desc: 'Ice elemental. Slows bullets on contact.', hp: 12, speed: 0.88, radius: 9, armor: 1, color: '#7ecfff', glowColor: '#00cfff', cost: 90, reward: 125, resistances: { ice: 0.0 }, weaknesses: { fire: 1.6, lightning: 1.3 }, element: 'ice', count: 1, }, { id: 'sparkling', name: 'SPARKLING', desc: 'Lightning elemental. Fast and electric.', hp: 7, speed: 2.1, radius: 6, armor: 0, color: '#ffe033', glowColor: '#ffcc00', cost: 110, reward: 148, resistances: { lightning: 0.0 }, weaknesses: { ice: 1.5, void: 1.3 }, element: 'lightning', count: 1, }, { id: 'venom', name: 'VENOM', desc: 'Poison elemental. Immune to DoT.', hp: 14, speed: 0.96, radius: 10, armor: 0, color: '#7fff4f', glowColor: '#44ff00', cost: 120, reward: 160, resistances: { poison: 0.0, fire: 0.6 }, weaknesses: { ice: 1.4, arcane: 1.6 }, element: 'poison', count: 1, }, { id: 'titan', name: 'TITAN', desc: 'Massive HP, heavy armor, very slow.', hp: 120, speed: 0.31, radius: 20, armor: 8, color: '#ff1744', glowColor: '#ff0000', cost: 350, reward: 465, resistances: { physical: 0.4, fire: 0.7 }, weaknesses: { void: 2.0, arcane: 1.5 }, element: null, count: 1, }, { id: 'wraith', name: 'WRAITH', desc: 'Void entity. Ignores 80% of armor.', hp: 18, speed: 1.38, radius: 9, armor: 0, color: '#9900ff', glowColor: '#6600cc', cost: 200, reward: 265, armorPen: 0.8, resistances: { void: 0.2, poison: 0.5 }, weaknesses: { arcane: 2.0 }, element: 'void', count: 1, }, ]; // ── WEAPON DEFINITIONS ──────────────────────────────────────── const WEAPON_DEFS = [ { id: 'cannon', name: 'CANNON', desc: 'Standard projectile. Reliable, upgradeable.', icon: '💣', cost: 0, // starting weapon defaultElement: 'physical', targeting: 'nearest', fireRate: 72, // frames between shots damage: 4, projectileSpeed: 4.2, projectileRadius: 4, range: 9999, color: '#c8c8c8', type: 'projectile', }, { id: 'flamethrower', name: 'FLAMETHROWER', desc: 'Continuous cone of fire. Medium range, applies burn.', icon: '🔥', cost: 800, defaultElement: 'fire', targeting: 'nearest', fireRate: 8, damage: 1, range: 230, coneAngle: 0.35, color: '#ff6b35', type: 'cone', }, { id: 'chainlightning', name: 'CHAIN LIGHTNING', desc: 'Arcs between up to 3 enemies.', icon: '⚡', cost: 1200, defaultElement: 'lightning', targeting: 'nearest', fireRate: 70, damage: 4, chains: 3, chainRange: 120, color: '#ffe033', type: 'chain', }, { id: 'mortar', name: 'MORTAR', desc: 'Lobbed shell with AoE explosion. Slow reload.', icon: '💥', cost: 1500, defaultElement: 'physical', targeting: 'group', fireRate: 180, damage: 12, aoeRadius: 60, projectileSpeed: 2.8, color: '#ff7043', type: 'mortar', }, { id: 'laser', name: 'LASER', desc: 'Continuous beam piercing all enemies in a line.', icon: '🔴', cost: 2000, defaultElement: 'arcane', targeting: 'furthest', fireRate: 10, damage: 1, range: 9999, color: '#ff77e9', type: 'beam', }, { id: 'freezebomb', name: 'FREEZE BOMB', desc: 'AoE ice explosion. Freezes enemies solid briefly.', icon: '❄️', cost: 1800, defaultElement: 'ice', targeting: 'group', fireRate: 150, damage: 5, aoeRadius: 75, freezeDuration: 180, projectileSpeed: 2.4, color: '#7ecfff', type: 'mortar', }, { id: 'voidcannon', name: 'VOID CANNON', desc: 'Massive slow projectile. Strips armor, bypasses resistance.', icon: '🌀', cost: 2000, defaultElement: 'void', targeting: 'strongest', fireRate: 240, damage: 20, armorShred: 5, projectileSpeed: 1.8, projectileRadius: 12, color: '#c77dff', type: 'projectile', }, { id: 'missilepod', name: 'MISSILE POD', desc: 'Fires homing AoE missiles at 3 targets simultaneously.', icon: '🚀', cost: 2400, defaultElement: 'fire', targeting: 'group', fireRate: 120, damage: 8, targets: 3, aoeRadius: 36, projectileSpeed: 3.6, color: '#ff4500', type: 'multi', }, { id: 'arcaneturret', name: 'ARCANE TURRET', desc: 'Rapid magic bolts. Applies Amplify debuff (+25% dmg taken).', icon: '✨', cost: 2200, defaultElement: 'arcane', targeting: 'nearest', fireRate: 20, damage: 2, amplify: 0.25, projectileSpeed: 5.8, color: '#ff77e9', type: 'projectile', }, { id: 'poisoncloud', name: 'POISON CLOUD', desc: 'Launches a lingering poison gas cloud.', icon: '☠️', cost: 1600, defaultElement: 'poison', targeting: 'group', fireRate: 130, damage: 2, dotDamage: 1, dotInterval: 30, dotDuration: 180, aoeRadius: 55, projectileSpeed: 2.2, color: '#7fff4f', type: 'mortar', }, ]; const MAX_WEAPONS_PER_TYPE = 8; // ── UPGRADE TREES ───────────────────────────────────────────── // Tower general upgrades const TOWER_UPGRADE_TREE = [ { id: 'hp1', label: 'Reinforced Hull I', desc: '+5 Max HP', cost: 100, requires: [], effect: { maxHp: 5 }, }, { id: 'hp2', label: 'Reinforced Hull II', desc: '+10 Max HP', cost: 250, requires: ['hp1'], effect: { maxHp: 10 }, }, { id: 'hp3', label: 'Reinforced Hull III', desc: '+20 Max HP', cost: 600, requires: ['hp2'], effect: { maxHp: 20 }, }, { id: 'hp4', label: 'Reinforced Hull IV', desc: '+35 Max HP', cost: 1400, requires: ['hp3'], effect: { maxHp: 35 }, }, { id: 'hp5', label: 'Reinforced Hull V', desc: '+60 Max HP', cost: 3000, requires: ['hp4'], effect: { maxHp: 60 }, }, { id: 'armor1', label: 'Plating I', desc: '+1 Armor', cost: 150, requires: [], effect: { armor: 1 }, }, { id: 'armor2', label: 'Plating II', desc: '+2 Armor', cost: 400, requires: ['armor1'], effect: { armor: 2 }, }, { id: 'armor3', label: 'Plating III', desc: '+3 Armor', cost: 900, requires: ['armor2'], effect: { armor: 3 }, }, { id: 'armor4', label: 'Plating IV', desc: '+4 Armor', cost: 2000, requires: ['armor3'], effect: { armor: 4 }, }, { id: 'armor5', label: 'Plating V', desc: '+6 Armor', cost: 4500, requires: ['armor4'], effect: { armor: 6 }, }, { id: 'aim1', label: 'Servo Motors I', desc: '+0.015 Aim Speed', cost: 100, requires: [], effect: { aimSpeed: 0.015 }, }, { id: 'aim2', label: 'Servo Motors II', desc: '+0.02 Aim Speed', cost: 200, requires: ['aim1'], effect: { aimSpeed: 0.02 }, }, { id: 'aim3', label: 'Servo Motors III', desc: '+0.025 Aim Speed', cost: 350, requires: ['aim2'], effect: { aimSpeed: 0.025 }, }, { id: 'aim4', label: 'Servo Motors IV', desc: '+0.035 Aim Speed', cost: 600, requires: ['aim3'], effect: { aimSpeed: 0.035 }, }, { id: 'aim5', label: 'Servo Motors V', desc: '+0.05 Aim Speed', cost: 1200, requires: ['aim4'], effect: { aimSpeed: 0.05 }, }, { id: 'aim6', label: 'Servo Motors VI', desc: '+0.07 Aim Speed — Near instant', cost: 2500, requires: ['aim5'], effect: { aimSpeed: 0.07 }, }, { id: 'repair1', label: 'Field Repair', desc: 'Restore 5 HP', cost: 80, requires: [], effect: { repair: 5 }, repeatable: true, }, { id: 'slot2', label: 'Weapon Slot II', desc: 'Unlock 2nd weapon slot', cost: 500, requires: [], effect: { weaponSlot: 2 }, }, { id: 'slot3', label: 'Weapon Slot III', desc: 'Unlock 3rd weapon slot', cost: 1500, requires: ['slot2'], effect: { weaponSlot: 3 }, }, { id: 'slot4', label: 'Weapon Slot IV', desc: 'Unlock 4th weapon slot', cost: 3500, requires: ['slot3'], effect: { weaponSlot: 4 }, }, { id: 'slot5', label: 'Weapon Slot V', desc: 'Unlock 5th weapon slot', cost: 7000, requires: ['slot4'], effect: { weaponSlot: 5 }, }, { id: 'slot6', label: 'Weapon Slot VI', desc: 'Unlock 6th weapon slot', cost: 12000, requires: ['slot5'], effect: { weaponSlot: 6 }, }, { id: 'slot7', label: 'Weapon Slot VII', desc: 'Unlock 7th weapon slot', cost: 20000, requires: ['slot6'], effect: { weaponSlot: 7 }, }, { id: 'slot8', label: 'Weapon Slot VIII', desc: 'Unlock 8th weapon slot', cost: 30000, requires: ['slot7'], effect: { weaponSlot: 8 }, }, { id: 'range1', label: 'Scanner I', desc: '+40 range', cost: 180, requires: [], effect: { range: 40 }, }, { id: 'range2', label: 'Scanner II', desc: '+60 range', cost: 450, requires: ['range1'], effect: { range: 60 }, }, { id: 'range3', label: 'Scanner III', desc: '+80 range', cost: 1000, requires: ['range2'], effect: { range: 80 }, }, { id: 'range4', label: 'Scanner IV', desc: '+100 range — max coverage', cost: 2400, requires: ['range3'], effect: { range: 100 }, }, { id: 'shield_dome', label: 'Dome Shield', desc: 'Buy dome shield system', cost: 800, requires: [], effect: { shield: 'dome' }, }, { id: 'shield_dir', label: 'Directional Shield', desc: 'Buy directional shield', cost: 600, requires: [], effect: { shield: 'directional' }, }, ]; // Per-weapon upgrade trees — each node has a `category` for grouped display const WEAPON_UPGRADE_TREES = { cannon: [ // Damage { id: 'dmg1', label: 'Damage I', desc: '+2 damage', cost: 80, requires: [], effect: { damage: 2 }, category: 'Damage' }, { id: 'dmg2', label: 'Damage II', desc: '+3 damage', cost: 200, requires: ['dmg1'], effect: { damage: 3 }, category: 'Damage' }, { id: 'dmg3', label: 'Damage III', desc: '+5 damage', cost: 450, requires: ['dmg2'], effect: { damage: 5 }, category: 'Damage' }, { id: 'dmg4', label: 'Damage IV', desc: '+8 damage', cost: 900, requires: ['dmg3'], effect: { damage: 8 }, category: 'Damage' }, // Fire Rate { id: 'rate1', label: 'Fire Rate I', desc: '-15 frames', cost: 100, requires: [], effect: { fireRate: -15 }, category: 'Fire Rate' }, { id: 'rate2', label: 'Fire Rate II', desc: '-20 frames', cost: 250, requires: ['rate1'], effect: { fireRate: -20 }, category: 'Fire Rate' }, { id: 'rate3', label: 'Fire Rate III',desc: '-25 frames', cost: 550, requires: ['rate2'], effect: { fireRate: -25 }, category: 'Fire Rate' }, // Velocity { id: 'speed1', label: 'Velocity I', desc: '+3 proj speed', cost: 90, requires: [], effect: { projectileSpeed: 3 }, category: 'Velocity' }, { id: 'speed2', label: 'Velocity II', desc: '+4 proj speed', cost: 220, requires: ['speed1'], effect: { projectileSpeed: 4 }, category: 'Velocity' }, { id: 'speed3', label: 'Velocity III',desc: '+5 proj speed', cost: 500, requires: ['speed2'], effect: { projectileSpeed: 5 }, category: 'Velocity' }, // Special { id: 'pierce1', label: 'Piercing I', desc: 'Pierce 1 extra', cost: 200, requires: ['dmg1'], effect: { pierce: 1 }, category: 'Special' }, { id: 'pierce2', label: 'Piercing II', desc: 'Pierce 2 extra', cost: 500, requires: ['pierce1'], effect: { pierce: 1 }, category: 'Special' }, { id: 'pierce3', label: 'Piercing III', desc: 'Pierce 3 extra', cost: 1100, requires: ['pierce2'], effect: { pierce: 1 }, category: 'Special' }, { id: 'pierce4', label: 'Piercing IV', desc: 'Pierce 4 extra', cost: 2400, requires: ['pierce3'], effect: { pierce: 1 }, category: 'Special' }, { id: 'pierce5', label: 'Piercing V', desc: 'Pierce 5 extra', cost: 5000, requires: ['pierce4'], effect: { pierce: 1 }, category: 'Special' }, { id: 'crit1', label: 'Crit I', desc: '+10% crit', cost: 180, requires: ['dmg1'], effect: { critChance: 0.10 }, category: 'Special' }, { id: 'crit2', label: 'Crit II', desc: '+15% crit', cost: 400, requires: ['crit1'], effect: { critChance: 0.15 }, category: 'Special' }, { id: 'crit3', label: 'Crit III', desc: '+20% crit', cost: 900, requires: ['crit2'], effect: { critChance: 0.20 }, category: 'Special' }, // Elements { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, { id: 'el3', label: 'Infuse: Slot 3', desc: 'Unlock 3rd element slot', cost: 2000, requires: ['el2'], effect: { canInfuse3: true }, category: 'Elements' }, ], flamethrower: [ { id: 'dmg1', label: 'Heat I', desc: '+1 dmg/tick', cost: 120, requires: [], effect: { damage: 1 }, category: 'Damage' }, { id: 'dmg2', label: 'Heat II', desc: '+2 dmg/tick', cost: 300, requires: ['dmg1'], effect: { damage: 2 }, category: 'Damage' }, { id: 'dmg3', label: 'Heat III', desc: '+3 dmg/tick', cost: 700, requires: ['dmg2'], effect: { damage: 3 }, category: 'Damage' }, { id: 'range1', label: 'Range I', desc: '+40 range', cost: 150, requires: [], effect: { range: 40 }, category: 'Range' }, { id: 'range2', label: 'Range II', desc: '+60 range', cost: 350, requires: ['range1'], effect: { range: 60 }, category: 'Range' }, { id: 'range3', label: 'Range III',desc: '+80 range', cost: 800, requires: ['range2'], effect: { range: 80 }, category: 'Range' }, { id: 'cone1', label: 'Wide Cone I', desc: '+15° angle', cost: 200, requires: [], effect: { coneAngle: 0.07 }, category: 'Cone' }, { id: 'cone2', label: 'Wide Cone II', desc: '+20° angle', cost: 500, requires: ['cone1'], effect: { coneAngle: 0.10 }, category: 'Cone' }, { id: 'burn1', label: 'Burn I', desc: '+60 burn frames', cost: 180, requires: ['dmg1'], effect: { dotDuration: 60 }, category: 'Special' }, { id: 'burn2', label: 'Burn II', desc: '+90 burn frames', cost: 400, requires: ['burn1'], effect: { dotDuration: 90 }, category: 'Special' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, ], chainlightning: [ { id: 'dmg1', label: 'Voltage I', desc: '+2 damage', cost: 150, requires: [], effect: { damage: 2 }, category: 'Damage' }, { id: 'dmg2', label: 'Voltage II', desc: '+4 damage', cost: 380, requires: ['dmg1'], effect: { damage: 4 }, category: 'Damage' }, { id: 'dmg3', label: 'Voltage III',desc: '+6 damage', cost: 900, requires: ['dmg2'], effect: { damage: 6 }, category: 'Damage' }, { id: 'chains1', label: 'Chain +1', desc: '+1 arc target', cost: 300, requires: [], effect: { chains: 1 }, category: 'Chains' }, { id: 'chains2', label: 'Chain +2', desc: '+2 arc targets', cost: 700, requires: ['chains1'], effect: { chains: 2 }, category: 'Chains' }, { id: 'chains3', label: 'Chain +3', desc: '+3 arc targets', cost: 1600, requires: ['chains2'],effect: { chains: 3 }, category: 'Chains' }, { id: 'range1', label: 'Arc Range I', desc: '+50 chain range', cost: 200, requires: [], effect: { chainRange: 50 }, category: 'Range' }, { id: 'range2', label: 'Arc Range II', desc: '+80 chain range', cost: 500, requires: ['range1'], effect: { chainRange: 80 }, category: 'Range' }, { id: 'rate1', label: 'Frequency I', desc: '-15 frames', cost: 150, requires: [], effect: { fireRate: -15 }, category: 'Fire Rate' }, { id: 'rate2', label: 'Frequency II', desc: '-20 frames', cost: 400, requires: ['rate1'], effect: { fireRate: -20 }, category: 'Fire Rate' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, ], mortar: [ { id: 'dmg1', label: 'Payload I', desc: '+5 damage', cost: 200, requires: [], effect: { damage: 5 }, category: 'Damage' }, { id: 'dmg2', label: 'Payload II', desc: '+8 damage', cost: 500, requires: ['dmg1'], effect: { damage: 8 }, category: 'Damage' }, { id: 'dmg3', label: 'Payload III',desc: '+12 damage',cost: 1100, requires: ['dmg2'],effect: { damage: 12}, category: 'Damage' }, { id: 'aoe1', label: 'Blast Radius I', desc: '+20 AoE', cost: 180, requires: [], effect: { aoeRadius: 20 }, category: 'Blast' }, { id: 'aoe2', label: 'Blast Radius II', desc: '+30 AoE', cost: 450, requires: ['aoe1'], effect: { aoeRadius: 30 }, category: 'Blast' }, { id: 'aoe3', label: 'Blast Radius III',desc: '+40 AoE', cost: 950, requires: ['aoe2'], effect: { aoeRadius: 40 }, category: 'Blast' }, { id: 'rate1', label: 'Reload I', desc: '-40 frames', cost: 250, requires: [], effect: { fireRate: -40 }, category: 'Fire Rate' }, { id: 'rate2', label: 'Reload II', desc: '-50 frames', cost: 600, requires: ['rate1'], effect: { fireRate: -50 }, category: 'Fire Rate' }, { id: 'speed1', label: 'Velocity I', desc: '+1.5 proj spd', cost: 200, requires: [], effect: { projectileSpeed: 1.5 }, category: 'Velocity' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, { id: 'el3', label: 'Infuse: Slot 3', desc: 'Unlock 3rd element slot', cost: 2000, requires: ['el2'], effect: { canInfuse3: true }, category: 'Elements' }, ], laser: [ { id: 'dmg1', label: 'Focus I', desc: '+1 dmg/tick', cost: 180, requires: [], effect: { damage: 1 }, category: 'Damage' }, { id: 'dmg2', label: 'Focus II', desc: '+2 dmg/tick', cost: 450, requires: ['dmg1'], effect: { damage: 2 }, category: 'Damage' }, { id: 'dmg3', label: 'Focus III',desc: '+3 dmg/tick', cost: 1000, requires: ['dmg2'],effect: { damage: 3 }, category: 'Damage' }, { id: 'rate1', label: 'Frequency I', desc: '-2 tick frames', cost: 200, requires: [], effect: { fireRate: -2 }, category: 'Fire Rate' }, { id: 'rate2', label: 'Frequency II', desc: '-2 tick frames', cost: 500, requires: ['rate1'], effect: { fireRate: -2 }, category: 'Fire Rate' }, { id: 'rate3', label: 'Frequency III',desc: '-2 tick frames', cost: 1200, requires: ['rate2'],effect: { fireRate: -2 }, category: 'Fire Rate' }, { id: 'width1', label: 'Wide Beam I', desc: '+6 hit radius', cost: 300, requires: [], effect: { projectileRadius: 6 }, category: 'Width' }, { id: 'width2', label: 'Wide Beam II', desc: '+8 hit radius', cost: 700, requires: ['width1'], effect: { projectileRadius: 8 }, category: 'Width' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, ], freezebomb: [ { id: 'dmg1', label: 'Cold I', desc: '+3 damage', cost: 200, requires: [], effect: { damage: 3 }, category: 'Damage' }, { id: 'dmg2', label: 'Cold II', desc: '+5 damage', cost: 500, requires: ['dmg1'], effect: { damage: 5 }, category: 'Damage' }, { id: 'aoe1', label: 'Blast I', desc: '+25 AoE', cost: 220, requires: [], effect: { aoeRadius: 25 }, category: 'Blast' }, { id: 'aoe2', label: 'Blast II', desc: '+35 AoE', cost: 550, requires: ['aoe1'], effect: { aoeRadius: 35 }, category: 'Blast' }, { id: 'freeze1', label: 'Deep Freeze I', desc: '+60 freeze frames', cost: 280, requires: [], effect: { freezeDuration: 60 }, category: 'Freeze' }, { id: 'freeze2', label: 'Deep Freeze II', desc: '+90 freeze frames', cost: 600, requires: ['freeze1'], effect: { freezeDuration: 90 }, category: 'Freeze' }, { id: 'freeze3', label: 'Deep Freeze III',desc: '+120 freeze frames', cost: 1300, requires: ['freeze2'], effect: { freezeDuration: 120}, category: 'Freeze' }, { id: 'rate1', label: 'Reload I', desc: '-40 frames', cost: 300, requires: [], effect: { fireRate: -40 }, category: 'Fire Rate' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, ], voidcannon: [ { id: 'dmg1', label: 'Singularity I', desc: '+8 damage', cost: 300, requires: [], effect: { damage: 8 }, category: 'Damage' }, { id: 'dmg2', label: 'Singularity II', desc: '+15 damage', cost: 750, requires: ['dmg1'], effect: { damage: 15 }, category: 'Damage' }, { id: 'dmg3', label: 'Singularity III',desc: '+25 damage', cost: 1600, requires: ['dmg2'],effect: { damage: 25 }, category: 'Damage' }, { id: 'shred1', label: 'Armor Shred I', desc: '+3 armor shred', cost: 400, requires: [], effect: { armorShred: 3 }, category: 'Special' }, { id: 'shred2', label: 'Armor Shred II', desc: '+5 armor shred', cost: 900, requires: ['shred1'], effect: { armorShred: 5 }, category: 'Special' }, { id: 'speed1', label: 'Velocity I', desc: '+1.5 proj spd', cost: 350, requires: [], effect: { projectileSpeed: 1.5 }, category: 'Velocity' }, { id: 'speed2', label: 'Velocity II', desc: '+2 proj spd', cost: 800, requires: ['speed1'], effect: { projectileSpeed: 2 }, category: 'Velocity' }, { id: 'size1', label: 'Projectile Size I', desc: '+4 proj radius', cost: 400, requires: [], effect: { projectileRadius: 4 }, category: 'Size' }, { id: 'rate1', label: 'Reload I', desc: '-50 frames', cost: 500, requires: [], effect: { fireRate: -50 }, category: 'Fire Rate' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, { id: 'el3', label: 'Infuse: Slot 3', desc: 'Unlock 3rd element slot', cost: 2000, requires: ['el2'], effect: { canInfuse3: true }, category: 'Elements' }, ], missilepod: [ { id: 'dmg1', label: 'Warhead I', desc: '+4 damage', cost: 250, requires: [], effect: { damage: 4 }, category: 'Damage' }, { id: 'dmg2', label: 'Warhead II', desc: '+6 damage', cost: 600, requires: ['dmg1'], effect: { damage: 6 }, category: 'Damage' }, { id: 'dmg3', label: 'Warhead III',desc: '+10 damage',cost: 1400, requires: ['dmg2'],effect: { damage: 10}, category: 'Damage' }, { id: 'targets1', label: '+1 Target', desc: 'Fire at 1 more', cost: 500, requires: [], effect: { targets: 1 }, category: 'Targets' }, { id: 'targets2', label: '+2 Targets',desc: 'Fire at 2 more', cost: 1200, requires: ['targets1'], effect: { targets: 2 }, category: 'Targets' }, { id: 'targets3', label: '+3 Targets',desc: 'Fire at 3 more', cost: 2800, requires: ['targets2'], effect: { targets: 3 }, category: 'Targets' }, { id: 'rate1', label: 'Reload I', desc: '-30 frames', cost: 300, requires: [], effect: { fireRate: -30 }, category: 'Fire Rate' }, { id: 'rate2', label: 'Reload II', desc: '-40 frames', cost: 700, requires: ['rate1'], effect: { fireRate: -40 }, category: 'Fire Rate' }, { id: 'speed1', label: 'Velocity I', desc: '+2 proj spd', cost: 300, requires: [], effect: { projectileSpeed: 2 }, category: 'Velocity' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, ], arcaneturret: [ { id: 'dmg1', label: 'Potency I', desc: '+1 damage', cost: 120, requires: [], effect: { damage: 1 }, category: 'Damage' }, { id: 'dmg2', label: 'Potency II', desc: '+2 damage', cost: 300, requires: ['dmg1'], effect: { damage: 2 }, category: 'Damage' }, { id: 'dmg3', label: 'Potency III',desc: '+3 damage', cost: 700, requires: ['dmg2'], effect: { damage: 3 }, category: 'Damage' }, { id: 'rate1', label: 'Frequency I', desc: '-5 frames', cost: 150, requires: [], effect: { fireRate: -5 }, category: 'Fire Rate' }, { id: 'rate2', label: 'Frequency II', desc: '-5 frames', cost: 380, requires: ['rate1'], effect: { fireRate: -5 }, category: 'Fire Rate' }, { id: 'rate3', label: 'Frequency III',desc: '-4 frames', cost: 850, requires: ['rate2'], effect: { fireRate: -4 }, category: 'Fire Rate' }, { id: 'amp1', label: 'Amplify I', desc: '+10% amp', cost: 300, requires: ['dmg1'], effect: { amplify: 0.10 }, category: 'Special' }, { id: 'amp2', label: 'Amplify II', desc: '+15% amp', cost: 700, requires: ['amp1'], effect: { amplify: 0.15 }, category: 'Special' }, { id: 'speed1',label: 'Velocity I', desc: '+3 proj spd',cost: 200, requires: [], effect: { projectileSpeed: 3 }, category: 'Velocity' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, ], poisoncloud: [ { id: 'dmg1', label: 'Toxin I', desc: '+1 dot dmg', cost: 150, requires: [], effect: { dotDamage: 1 }, category: 'Damage' }, { id: 'dmg2', label: 'Toxin II', desc: '+2 dot dmg', cost: 380, requires: ['dmg1'], effect: { dotDamage: 2 }, category: 'Damage' }, { id: 'dmg3', label: 'Toxin III',desc: '+3 dot dmg', cost: 850, requires: ['dmg2'], effect: { dotDamage: 3 }, category: 'Damage' }, { id: 'dur1', label: 'Duration I', desc: '+60 cloud frames', cost: 180, requires: [], effect: { dotDuration: 60 }, category: 'Duration' }, { id: 'dur2', label: 'Duration II', desc: '+90 cloud frames', cost: 450, requires: ['dur1'], effect: { dotDuration: 90 }, category: 'Duration' }, { id: 'dur3', label: 'Duration III',desc: '+120 cloud frames', cost: 1000, requires: ['dur2'], effect: { dotDuration: 120}, category: 'Duration' }, { id: 'aoe1', label: 'Cloud I', desc: '+20 AoE', cost: 200, requires: [], effect: { aoeRadius: 20 }, category: 'Blast' }, { id: 'aoe2', label: 'Cloud II', desc: '+30 AoE', cost: 500, requires: ['aoe1'], effect: { aoeRadius: 30 }, category: 'Blast' }, { id: 'rate1', label: 'Reload I', desc: '-30 frames', cost: 250, requires: [], effect: { fireRate: -30 }, category: 'Fire Rate' }, { id: 'el1', label: 'Infuse: Slot 1', desc: 'Unlock 1st element slot', cost: 300, requires: [], effect: { canInfuse: true }, category: 'Elements' }, { id: 'el2', label: 'Infuse: Slot 2', desc: 'Unlock 2nd element slot', cost: 800, requires: ['el1'], effect: { canInfuse2: true }, category: 'Elements' }, ], }; // Shield upgrade trees const SHIELD_UPGRADE_TREES = { dome: [ { id: 'cap1', label: 'Capacity I', desc: '+5 shield HP', cost: 200, requires: [], effect: { capacity: 5 } }, { id: 'cap2', label: 'Capacity II', desc: '+10 shield HP', cost: 500, requires: ['cap1'], effect: { capacity: 10 } }, { id: 'cap3', label: 'Capacity III', desc: '+20 shield HP', cost: 1100, requires: ['cap2'], effect: { capacity: 20 } }, { id: 'regen1', label: 'Recharge I', desc: '-30 frames recharge', cost: 300, requires: [], effect: { rechargeDelay: -30 } }, { id: 'regen2', label: 'Recharge II', desc: '-60 frames recharge', cost: 700, requires: ['regen1'], effect: { rechargeDelay: -60 } }, { id: 'reflect1', label: 'Reflect', desc: 'Reflect 20% dmg back', cost: 1500, requires: ['cap2'], effect: { reflect: 0.2 } }, ], directional: [ { id: 'arc1', label: 'Wide Arc I', desc: '+20° arc width', cost: 200, requires: [], effect: { arcWidth: 0.35 } }, { id: 'arc2', label: 'Wide Arc II', desc: '+30° arc width', cost: 500, requires: ['arc1'], effect: { arcWidth: 0.52 } }, { id: 'cap1', label: 'Capacity I', desc: '+8 shield HP', cost: 250, requires: [], effect: { capacity: 8 } }, { id: 'cap2', label: 'Capacity II', desc: '+15 shield HP', cost: 600, requires: ['cap1'], effect: { capacity: 15 } }, { id: 'speed1', label: 'Track Speed I', desc: '+50% shield rotation', cost: 300, requires: [], effect: { trackSpeed: 0.03 } }, { id: 'speed2', label: 'Track Speed II', desc: '+100% shield rotation', cost: 700, requires: ['speed1'], effect: { trackSpeed: 0.06 } }, { id: 'absorb1', label: 'Absorption I', desc: 'Block 25% more damage', cost: 400, requires: ['cap1'], effect: { absorption: 0.25 } }, ], };