Update index20.html

This commit is contained in:
threememories 2026-04-16 14:02:00 +00:00
parent 0e005c9c5e
commit 983fbaffdc
1 changed files with 137 additions and 160 deletions

View File

@ -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(){ Gamestate.init = function(){
if (winModal) winModal.style.display = "none"; if (winModal) winModal.style.display = "none";
if (!map) return; if (!map) return;
@ -1967,8 +2080,9 @@ document.getElementById('secret-dev-key')?.addEventListener('click', (e) => {
this.showToast("Dev: +100 Troops (Deploy Phase Active)"); 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-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', () => { document.getElementById('dev-perk')?.addEventListener('click', () => {
if (!Gamestate.bobbleheads) return; if (!Gamestate.bobbleheads) return;
let unfoundItems = Gamestate.bobbleheads.filter(item => !item.found); 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() { 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); let val = parseInt(this.value);
if (val === -1) { if (val === -1) {
document.getElementById('dev-win-val').textContent = "NORMAL"; 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 (Gamestate.showToast) Gamestate.showToast("Dev Override: UI forced to " + theme.toUpperCase());
}); });
if (this.setupInventory) this.setupInventory();
} }
Gamestate.updateButtonText = function() { Gamestate.updateButtonText = function() {
if (!end) return; if (!end) return;
if (this.stage === "Fortify") { if (this.stage === "Fortify") {
@ -3148,123 +3264,11 @@ Gamestate.maneuver = async function(e){
this.prevCountry = country; 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() { Gamestate.useStimpak = async function() {
if(this.stage !== "Commander Phase" || !this.commandersEnabled || !this.player.commander) return; 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; 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); 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); await this.logAction("[ MEDICAL ] Commander injected a Stimpak. Recovered 20 HP.", true); this.updateInfo();
if (this.renderInventory) this.renderInventory();
this.updateInfo();
} }
Gamestate.initiateNukeSequence = function() { Gamestate.initiateNukeSequence = function() {
@ -3492,13 +3496,6 @@ for(let i = 1; i <= this.players.length; i++){
this.aiTurn = false; this.aiTurn = false;
await this.logAction(`--- DAY ${this.turn} BEGINS ---`, true); 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) { if(this.diplomacy.spiteTurns > 0) {
this.diplomacy.spiteTurns--; this.diplomacy.spiteTurns--;
if(this.diplomacy.spiteTurns <= 0) { if(this.diplomacy.spiteTurns <= 0) {
@ -3636,41 +3633,21 @@ if (infoName[i-1]) infoName[i-1].parentElement.classList.remove('highlight');
this.aiManeuver(i); this.aiManeuver(i);
if (this.player.conqueredThisTurn) { if (this.players[i].conqueredThisTurn) {
let newCap = deck.length > 0 ? deck.pop() : { country: "Wasteland Salvage", type: "Wild" }; let newCap = deck.length > 0 ? deck.pop() : { country: "Wasteland Salvage", type: "Wild" };
this.player.cards.push(newCap); 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++; }
}
let luckItem = this.bobbleheads && this.bobbleheads.find(i => i.key === 'l' && i.cooldown > 0); if(this.commandersEnabled && this.players[i].commander) {
const luckModifier = luckItem ? (luckItem.bonus / 10) : 0; // 30% if luck active, else 0% 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); }
if (this.bobbleheads && Math.random() < (0.05 + luckModifier)) { // 5% base chance // FIX: Refill the AI Commander's Action Points every turn!
let unfoundItems = this.bobbleheads.filter(item => !item.found); this.players[i].commander.ap = 2;
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.");
}
}
} 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(); this.updateInfo();
} }
} }