From 983fbaffdc730eddf40cd997fc8e4d8d4fd47ffa Mon Sep 17 00:00:00 2001 From: threememories Date: Thu, 16 Apr 2026 14:02:00 +0000 Subject: [PATCH] Update index20.html --- index20.html | 297 ++++++++++++++++++++++++--------------------------- 1 file changed, 137 insertions(+), 160 deletions(-) diff --git a/index20.html b/index20.html index d274602..a073895 100644 --- a/index20.html +++ b/index20.html @@ -1883,6 +1883,119 @@ Gamestate.showCodePopup = function() { } } +// --- INVENTORY & BOBBLEHEAD SYSTEM --- +Gamestate.bobbleheads = [ + { key: 's', name: 'STRENGTH BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 5, bonus: 0.10, desc: 'Grants +10% attack odds for 1 turn.' }, + { key: 'p', name: 'PERCEPTION BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 8, desc: 'Reveals all enemy territories for 1 turn.' }, + { key: 'e', name: 'ENDURANCE BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 5, bonus: 0.10, desc: 'Reduces defender losses by 10% for 1 turn.' }, + { key: 'c', name: 'CHARISMA BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 10, desc: 'Your next Bottle Cap trade-in yields maximum troops.' }, + { key: 'i', name: 'INTELLIGENCE BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 8, desc: 'Reveals all rival leaderboard data for 1 turn.' }, + { key: 'a', name: 'AGILITY BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 6, bonus: 1, desc: 'Grants one extra army maneuver this turn.' }, + { key: 'l', name: 'LUCK BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 7, bonus: 3, desc: 'Triples the chance to find loot for 1 turn.' } +]; + +Gamestate.setupInventory = function() { + const invModal = document.getElementById('inventory-modal'); + const navInv = document.getElementById('nav-inv'); + const navMap = document.getElementById('nav-map'); + const closeInvBtn = document.getElementById('close-inv-btn'); + + if (!invModal || !navInv) return; + + navInv.addEventListener('click', () => { + invModal.style.display = 'flex'; + navInv.classList.remove('inv-pulse'); + navInv.classList.add('map-active'); + if (navMap) navMap.classList.remove('map-active'); + if (this.renderInventory) this.renderInventory(); + }); + + if (closeInvBtn) { + closeInvBtn.addEventListener('click', () => { + invModal.style.display = 'none'; + navInv.classList.remove('map-active'); + if (navMap) navMap.classList.add('map-active'); + }); + } + + this.bobbleheads.forEach(item => { + const btn = document.querySelector(`#bobblehead-${item.key} .bobble-activate-btn`); + if (btn) { + btn.addEventListener('click', () => { + if(this.activateBobblehead) this.activateBobblehead(item.key); + }); + } + }); +}; + +Gamestate.renderInventory = function() { + const stimpakCountEl = document.getElementById('inv-stimpak-count'); + if (stimpakCountEl && this.player && this.player.commander) { + stimpakCountEl.textContent = this.player.commander.stimpaks; + } + + let foundCount = 0; + this.bobbleheads.forEach(item => { + const itemDiv = document.getElementById(`bobblehead-${item.key}`); + if (!itemDiv) return; + const btn = itemDiv.querySelector('.bobble-activate-btn'); + const cooldownEl = itemDiv.querySelector('.cooldown-timer'); + + if (item.found) { + itemDiv.classList.add('found'); + foundCount++; + if (item.cooldown > 0) { + if (btn) btn.style.display = 'none'; + if (cooldownEl) { + cooldownEl.style.display = 'block'; + cooldownEl.textContent = `ON COOLDOWN: ${item.cooldown} TURNS`; + } + } else { + if (btn) { + btn.disabled = false; + btn.style.display = 'block'; + btn.textContent = '[ ACTIVATE ]'; + } + if (cooldownEl) cooldownEl.style.display = 'none'; + } + } else { + itemDiv.classList.remove('found'); + if (btn) { + btn.disabled = true; + btn.style.display = 'block'; + btn.textContent = '[ NOT FOUND ]'; + } + if (cooldownEl) cooldownEl.style.display = 'none'; + } + }); + + const bonusDiv = document.getElementById('special-set-bonus'); + if (bonusDiv) { + bonusDiv.textContent = `FULL SET BONUS [ ${foundCount} / 7 ]`; + bonusDiv.style.opacity = (foundCount === 7) ? '1' : '0.5'; + } + + const activateBonusBtn = document.getElementById('special-set-activate'); + if (activateBonusBtn) activateBonusBtn.disabled = (foundCount !== 7); +}; + +Gamestate.activateBobblehead = async function(itemKey) { + const item = this.bobbleheads.find(i => i.key === itemKey); + if (!item || !item.found || item.cooldown > 0) return; + + item.cooldown = item.totalCooldown; + let logMessage = `[ BOBBLEHEAD ] ${item.name} activated! ${item.desc}`; + + if (item.key === 'a') { + this.hasManeuvered = false; // Grant an extra maneuver + } + + await this.logAction(logMessage, true); + if (this.renderInventory) this.renderInventory(); + this.updateInfo(); +}; + + Gamestate.init = function(){ if (winModal) winModal.style.display = "none"; if (!map) return; @@ -1967,8 +2080,9 @@ document.getElementById('secret-dev-key')?.addEventListener('click', (e) => { this.showToast("Dev: +100 Troops (Deploy Phase Active)"); }); document.getElementById('dev-heal')?.addEventListener('click', () => { if(this.player.commander) this.player.commander.hp = 100; this.updateInfo(); this.showToast("Dev: Commander Healed"); }); - document.getElementById('dev-storm')?.addEventListener('click', () => { this.radstorm.cooldown = 1; this.processRadstorm(); document.getElementById('dev-modal').style.display = 'none'; }); + document.getElementById('dev-storm')?.addEventListener('click', () => { this.radstorm.cooldown = 1; this.processRadstorm(); + // --- NEW DEV PERK BUTTON --- document.getElementById('dev-perk')?.addEventListener('click', () => { if (!Gamestate.bobbleheads) return; let unfoundItems = Gamestate.bobbleheads.filter(item => !item.found); @@ -1988,7 +2102,11 @@ document.getElementById('secret-dev-key')?.addEventListener('click', (e) => { }); document.getElementById('dev-win-slider')?.addEventListener('input', function() { + let val = parseInt(this.value); + if (val === -1) { + document.getElementById('dev-modal').style.display = 'none'; }); + document.getElementById('dev-win-slider')?.addEventListener('input', function() { let val = parseInt(this.value); if (val === -1) { document.getElementById('dev-win-val').textContent = "NORMAL"; @@ -2014,10 +2132,8 @@ document.getElementById('secret-dev-key')?.addEventListener('click', (e) => { if (Gamestate.showToast) Gamestate.showToast("Dev Override: UI forced to " + theme.toUpperCase()); }); - if (this.setupInventory) this.setupInventory(); } - Gamestate.updateButtonText = function() { if (!end) return; if (this.stage === "Fortify") { @@ -3148,123 +3264,11 @@ Gamestate.maneuver = async function(e){ this.prevCountry = country; } -// --- INVENTORY & BOBBLEHEAD SYSTEM --- -Gamestate.bobbleheads = [ - { key: 's', name: 'STRENGTH BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 5, bonus: 0.10, desc: 'Grants +10% attack odds for 1 turn.' }, - { key: 'p', name: 'PERCEPTION BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 8, desc: 'Reveals all enemy territories for 1 turn.' }, - { key: 'e', name: 'ENDURANCE BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 5, bonus: 0.10, desc: 'Reduces defender losses by 10% for 1 turn.' }, - { key: 'c', name: 'CHARISMA BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 10, desc: 'Your next Bottle Cap trade-in yields maximum troops.' }, - { key: 'i', name: 'INTELLIGENCE BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 8, desc: 'Reveals all rival leaderboard data for 1 turn.' }, - { key: 'a', name: 'AGILITY BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 6, bonus: 1, desc: 'Grants one extra army maneuver this turn.' }, - { key: 'l', name: 'LUCK BOBBLEHEAD', found: false, cooldown: 0, totalCooldown: 7, bonus: 3, desc: 'Triples the chance to find loot for 1 turn.' } -]; - -Gamestate.setupInventory = function() { - const invModal = document.getElementById('inventory-modal'); - const navInv = document.getElementById('nav-inv'); - const navMap = document.getElementById('nav-map'); - const closeInvBtn = document.getElementById('close-inv-btn'); - - if (!invModal || !navInv) return; - - navInv.addEventListener('click', () => { - invModal.style.display = 'flex'; - navInv.classList.remove('inv-pulse'); - navInv.classList.add('map-active'); - if (navMap) navMap.classList.remove('map-active'); - this.renderInventory(); - }); - - if (closeInvBtn) { - closeInvBtn.addEventListener('click', () => { - invModal.style.display = 'none'; - navInv.classList.remove('map-active'); - if (navMap) navMap.classList.add('map-active'); - }); - } - - this.bobbleheads.forEach(item => { - const btn = document.querySelector(`#bobblehead-${item.key} .bobble-activate-btn`); - if (btn) { - btn.addEventListener('click', () => this.activateBobblehead(item.key)); - } - }); -}; - -Gamestate.renderInventory = function() { - const stimpakCountEl = document.getElementById('inv-stimpak-count'); - if (stimpakCountEl && this.player && this.player.commander) { - stimpakCountEl.textContent = this.player.commander.stimpaks; - } - - let foundCount = 0; - this.bobbleheads.forEach(item => { - const itemDiv = document.getElementById(`bobblehead-${item.key}`); - if (!itemDiv) return; - const btn = itemDiv.querySelector('.bobble-activate-btn'); - const cooldownEl = itemDiv.querySelector('.cooldown-timer'); - - if (item.found) { - itemDiv.classList.add('found'); - foundCount++; - if (item.cooldown > 0) { - if (btn) btn.style.display = 'none'; - if (cooldownEl) { - cooldownEl.style.display = 'block'; - cooldownEl.textContent = `ON COOLDOWN: ${item.cooldown} TURNS`; - } - } else { - if (btn) { - btn.disabled = false; - btn.style.display = 'block'; - btn.textContent = '[ ACTIVATE ]'; - } - if (cooldownEl) cooldownEl.style.display = 'none'; - } - } else { - itemDiv.classList.remove('found'); - if (btn) { - btn.disabled = true; - btn.style.display = 'block'; - btn.textContent = '[ NOT FOUND ]'; - } - if (cooldownEl) cooldownEl.style.display = 'none'; - } - }); - - const bonusDiv = document.getElementById('special-set-bonus'); - if (bonusDiv) { - bonusDiv.textContent = `FULL SET BONUS [ ${foundCount} / 7 ]`; - bonusDiv.style.opacity = (foundCount === 7) ? '1' : '0.5'; - } - - const activateBonusBtn = document.getElementById('special-set-activate'); - if (activateBonusBtn) activateBonusBtn.disabled = (foundCount !== 7); -}; - -Gamestate.activateBobblehead = async function(itemKey) { - const item = this.bobbleheads.find(i => i.key === itemKey); - if (!item || !item.found || item.cooldown > 0) return; - - item.cooldown = item.totalCooldown; - let logMessage = `[ BOBBLEHEAD ] ${item.name} activated! ${item.desc}`; - - if (item.key === 'a') { - this.hasManeuvered = false; // Grant an extra maneuver - } - - await this.logAction(logMessage, true); - this.renderInventory(); - this.updateInfo(); -}; - Gamestate.useStimpak = async function() { if(this.stage !== "Commander Phase" || !this.commandersEnabled || !this.player.commander) return; if(this.player.commander.ap <= 0 || this.player.commander.stimpaks <= 0 || this.player.commander.hp >= 100) return; this.player.commander.stimpaks -= 1; this.player.commander.ap -= 1; this.player.commander.hp = Math.min(100, this.player.commander.hp + 20); - await this.logAction("[ MEDICAL ] Commander injected a Stimpak. Recovered 20 HP.", true); - if (this.renderInventory) this.renderInventory(); - this.updateInfo(); + await this.logAction("[ MEDICAL ] Commander injected a Stimpak. Recovered 20 HP.", true); this.updateInfo(); } Gamestate.initiateNukeSequence = function() { @@ -3488,17 +3492,10 @@ for(let i = 1; i <= this.players.length; i++){ } } - this.turn += 1; +this.turn += 1; this.aiTurn = false; await this.logAction(`--- DAY ${this.turn} BEGINS ---`, true); - // BOBBLEHEAD COOLDOWNS - if (this.bobbleheads) { - this.bobbleheads.forEach(item => { - if (item.cooldown > 0) item.cooldown--; - }); - } - if(this.diplomacy.spiteTurns > 0) { this.diplomacy.spiteTurns--; if(this.diplomacy.spiteTurns <= 0) { @@ -3636,43 +3633,23 @@ if (infoName[i-1]) infoName[i-1].parentElement.classList.remove('highlight'); this.aiManeuver(i); - if (this.player.conqueredThisTurn) { - let newCap = deck.length > 0 ? deck.pop() : { country: "Wasteland Salvage", type: "Wild" }; - this.player.cards.push(newCap); - - let luckItem = this.bobbleheads && this.bobbleheads.find(i => i.key === 'l' && i.cooldown > 0); - const luckModifier = luckItem ? (luckItem.bonus / 10) : 0; // 30% if luck active, else 0% - - if (this.bobbleheads && Math.random() < (0.05 + luckModifier)) { // 5% base chance - let unfoundItems = this.bobbleheads.filter(item => !item.found); - if (unfoundItems.length > 0) { - let foundItem = unfoundItems[Math.floor(Math.random() * unfoundItems.length)]; - foundItem.found = true; - let navInv = document.getElementById('nav-inv'); - if (navInv) navInv.classList.add('inv-pulse'); - await this.logAction(`[ LOOT FOUND! ] You discovered a '${foundItem.name}'!`, true); - } else { - // If all found, fallback to Stimpaks/Codes - if(this.commandersEnabled && this.player.commander && this.player.commander.stimpaks < 3 && Math.random() < 0.15) { - this.player.commander.stimpaks++; await this.logAction("SCAVENGED: Found a rare Stimpak in the ruins!"); - } else if (this.nukesEnabled && this.player.codes < 4 && this.globalCodes > 0 && Math.random() < 0.15) { - this.player.codes++; this.globalCodes--; this.showCodePopup(); await this.logAction("SCAVENGED: Recovered a heavily encrypted Launch Code Fragment!", true); - } else { - if (this.getBestTrade(this.player.cards)) await this.logAction("STASH FULL: Enough Caps collected to hire more troops."); - else await this.logAction("SCAVENGED: Found a Bottle Cap after securing enemy territory."); - } + if (this.players[i].conqueredThisTurn) { + let newCap = deck.length > 0 ? deck.pop() : { country: "Wasteland Salvage", type: "Wild" }; + this.players[i].cards.push(newCap); this.players[i].conqueredThisTurn = false; + if (this.nukesEnabled && this.players[i].codes < 4 && this.globalCodes > 0 && Math.random() < 0.15) { this.players[i].codes++; this.globalCodes--; } + if (this.commandersEnabled && this.players[i].commander && this.players[i].commander.stimpaks < 1 && Math.random() < 0.15) { this.players[i].commander.stimpaks++; } } - } else if (this.commandersEnabled && this.player.commander && this.player.commander.stimpaks < 3 && Math.random() < 0.15) { // Stimpak limit increased to 3 - this.player.commander.stimpaks++; - await this.logAction("SCAVENGED: Found a rare Stimpak in the ruins!"); - } else if (this.nukesEnabled && this.player.codes < 4 && this.globalCodes > 0 && Math.random() < 0.15) { - this.player.codes++; this.globalCodes--; this.showCodePopup(); await this.logAction("SCAVENGED: Recovered a heavily encrypted Launch Code Fragment!", true); - } else { - if (this.getBestTrade(this.player.cards)) await this.logAction("STASH FULL: Enough Caps collected to hire more troops."); - else await this.logAction("SCAVENGED: Found a Bottle Cap after securing enemy territory."); - } - this.updateInfo(); - } + +if(this.commandersEnabled && this.players[i].commander) { + let loc = this.countries.find(c => c.name === this.players[i].commander.loc); + if(loc && loc.owner === this.players[i].name) { let regen = loc.isSilo ? 4 : 2; this.players[i].commander.hp = Math.min(100, this.players[i].commander.hp + regen); } + + // FIX: Refill the AI Commander's Action Points every turn! + this.players[i].commander.ap = 2; + } + + this.updateInfo(); + } } }