diff --git a/index.html b/index.html
index b93bfe2..8465522 100644
--- a/index.html
+++ b/index.html
@@ -1731,6 +1731,7 @@ document.getElementById('dev-win-slider')?.addEventListener('input', function()
}
Gamestate.updateButtonText = function() {
+ let end = document.getElementById('end');
if (!end) return;
if (this.stage === "Fortify") {
end.textContent = "Deploy Troops"; end.style.opacity = "0.5"; end.style.pointerEvents = "none";
@@ -1738,14 +1739,12 @@ Gamestate.updateButtonText = function() {
else if (this.stage === "Battle") {
end.textContent = "End Attack Phase"; end.style.opacity = "1"; end.style.pointerEvents = "auto";
}
-else if (this.stage === "Maneuver") {
- if(this.commandersEnabled && this.player.alive && this.player.commander) {
- end.textContent = this.hasManeuvered ? "End Moves" : "Skip Move";
- } else {
- end.textContent = "End Turn";
- }
+ else if (this.stage === "Maneuver") {
+ // If Commanders are on, it says Next Phase. Otherwise, End Turn.
+ let nextStr = (this.commandersEnabled && this.player.alive && this.player.commander) ? "Next Phase" : "End Turn";
+ end.textContent = this.hasManeuvered ? nextStr : "Skip Move";
end.style.opacity = "1"; end.style.pointerEvents = "auto";
- }
+ }
else if (this.stage === "Commander Phase") {
end.textContent = "End Turn"; end.style.opacity = "1"; end.style.pointerEvents = "auto";
}
@@ -2269,32 +2268,57 @@ Gamestate.updateInfo = function(){
if (this.player.areas.length <= 5) { hpFill.style.background = "#ff0000"; hpFill.style.boxShadow = "0 0 10px rgba(255, 0, 0, 0.8)"; }
else { hpFill.style.background = "var(--pip-color)"; hpFill.style.boxShadow = "var(--pip-glow)"; }
- let apPercentage = 0;
+let apPercentage = 0;
+ let shouldAutoSkip = false; // The Turbo Sensor
+
if (this.stage === "Fortify") {
- let maxReserve = Math.max(this.player.reserve + this.playerTroopsPlaced, 1); apPercentage = (this.player.reserve / maxReserve) * 100;
+ let maxReserve = Math.max(this.player.reserve + this.playerTroopsPlaced, 1);
+ apPercentage = (this.player.reserve / maxReserve) * 100;
} else if (this.stage === "Battle") {
- let currentStrikeForce = 0; let validAttacks = 0; let ownedTerritories = this.countries.filter(c => c.owner === this.player.name);
+ let currentStrikeForce = 0;
+ let validAttacks = 0; let ownedTerritories = this.countries.filter(c => c.owner === this.player.name);
ownedTerritories.forEach(t => {
if (t.army > 1) {
let hasEnemyNeighbor = t.neighbours.some(n => { let nc = this.countries.find(x => x.name === n); return nc && nc.owner !== this.player.name && !nc.isCrater; });
if (hasEnemyNeighbor) { currentStrikeForce += (t.army - 1); validAttacks++; }
}
});
- if (validAttacks === 0) apPercentage = 0;
+ if (validAttacks === 0) {
+ apPercentage = 0;
+ shouldAutoSkip = true; // No valid attacks left!
+ }
else {
if (this.lastStage !== "Battle") this.initialStrikeForce = currentStrikeForce;
if (currentStrikeForce > (this.initialStrikeForce || 1)) this.initialStrikeForce = currentStrikeForce;
apPercentage = Math.min(100, (currentStrikeForce / Math.max(this.initialStrikeForce, 1)) * 100);
}
} else if (this.stage === "Maneuver") {
- let canManeuver = false; let ownedTerritories = this.countries.filter(c => c.owner === this.player.name);
+ let canManeuver = false;
+ let ownedTerritories = this.countries.filter(c => c.owner === this.player.name);
for (let t of ownedTerritories) { if (t.army > 1 && t.neighbours.some(n => { let nc = this.countries.find(x => x.name === n); return nc && nc.owner === this.player.name; })) { canManeuver = true; break; } }
apPercentage = canManeuver ? (this.maneuverSource ? 0 : 100) : 0;
} else if (this.stage === "Commander Phase" && this.commandersEnabled && this.player.commander) {
apPercentage = (this.player.commander.ap / 2) * 100;
+ if (this.player.commander.ap <= 0) shouldAutoSkip = true; // Out of AP!
} else apPercentage = 0;
apFill.style.width = apPercentage + "%";
+
+ // --- TURBO MODE AUTO-SKIP ENGINE ---
+ let turbo = document.getElementById('turbo-toggle') && document.getElementById('turbo-toggle').checked;
+ if (turbo && shouldAutoSkip && !this.aiTurn) {
+ if (!this.autoSkipTimer) {
+ this.autoSkipTimer = setTimeout(() => {
+ this.autoSkipTimer = null;
+ if (!this.aiTurn && (this.stage === "Battle" || this.stage === "Commander Phase")) {
+ if (Gamestate.logAction) Gamestate.logAction("[ TURBO ] AP Depleted. Auto-advancing phase...", true);
+ this.handleEndTurn();
+ }
+ }, 1200); // 1.2 second delay so you can read the final combat logs
+ }
+ } else {
+ if (this.autoSkipTimer) { clearTimeout(this.autoSkipTimer); this.autoSkipTimer = null; }
+ }
if (apPercentage <= 0) { apFill.style.opacity = "0"; apFill.style.visibility = "hidden"; } else { apFill.style.opacity = "1"; apFill.style.visibility = "visible"; }
if (hpPercentage <= 0) { hpFill.style.opacity = "0"; hpFill.style.visibility = "hidden"; } else { hpFill.style.opacity = "1"; hpFill.style.visibility = "visible"; }
} else if (!this.player.alive && hpFill && apFill) {
@@ -2863,13 +2887,15 @@ country.army += moveAmount;
let sourceMap = document.getElementById(`${this.prevCountry.name}`); let destMap = document.getElementById(`${country.name}`);
if (sourceMap && sourceMap.nextElementSibling) sourceMap.nextElementSibling.textContent = this.prevCountry.army;
- if (destMap && destMap.nextElementSibling) destMap.nextElementSibling.textContent = country.army;
+if (destMap && destMap.nextElementSibling) destMap.nextElementSibling.textContent = country.army;
if(this.commandersEnabled && this.player.commander && this.player.commander.loc === this.prevCountry.name && e.shiftKey) {
this.player.commander.loc = country.name;
- this.player.commander.siegeTurns = 0; // Reset subversion timer
- this.logAction(`Commander escorted to ${formatTerritoryName(country.name)}.`);
+ if (Gamestate.logAction) this.logAction(`Commander escorted to ${formatTerritoryName(country.name)}.`);
}
+
+ this.hasManeuvered = true;
+ this.updateButtonText(); // <--- This forces the button to change!
this.updateInfo();
}
}
@@ -3255,11 +3281,13 @@ if (infoName[i-1]) infoName[i-1].parentElement.classList.remove('highlight');
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); }
+ 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!
+ // FIX: Refill the AI Commander's Action Points & Combat Fatigue every turn!
this.players[i].commander.ap = 2;
- this.players[i].commander.hasBeenAmbushed = false; // Reset attack limit
+ this.players[i].commander.hasBeenAmbushed = false;
+ this.players[i].commander.hasFought = false; // Wakes the AI up!
}
this.updateInfo();
@@ -3337,22 +3365,32 @@ Gamestate.aiManeuver = function(i){
});
enemyCmdrs.sort((a,b) => a.commander.hp - b.commander.hp);
- // PRIORITY 4: RETREAT (HP < 35%)
- if (player.commander.hp < 35 && friendlyNeighbors.length > 0) {
- let safeSpots = friendlyNeighbors.filter(c => !c.neighbours.some(n => {
- let nc = this.countries.find(x=>x.name===n); return nc && nc.owner !== player.name;
- }));
- if (safeSpots.length === 0) safeSpots = friendlyNeighbors;
- let silo = safeSpots.find(c => this.nukesEnabled && c.isSilo);
- safeSpots.sort((a,b) => b.army - a.army);
- let retreatTarget = silo ? silo : safeSpots[0];
-
- if (retreatTarget.name !== cmdrLoc.name && (retreatTarget.army > cmdrLoc.army || silo)) {
- player.commander.loc = retreatTarget.name;
+// PRIORITY 4: RETREAT (HP < 35%)
+ if (player.commander.hp < 35) {
+ if (friendlyNeighbors.length > 0) {
+ let safeSpots = friendlyNeighbors.filter(c => !c.neighbours.some(n => {
+ let nc = this.countries.find(x=>x.name===n); return nc && nc.owner !== player.name;
+ }));
+ if (safeSpots.length === 0) safeSpots = friendlyNeighbors;
+ let silo = safeSpots.find(c => this.nukesEnabled && c.isSilo);
+ safeSpots.sort((a,b) => b.army - a.army);
+ let retreatTarget = silo ? silo : safeSpots[0];
+
+ if (retreatTarget.name !== cmdrLoc.name && (retreatTarget.army > cmdrLoc.army || silo)) {
+ player.commander.loc = retreatTarget.name;
+ player.commander.ap -= 1; movedOrAction = true;
+ player.commander.siegeTurns = 0;
+ if (Gamestate.logAction) Gamestate.logAction(`VIP MOVEMENT: ${player.name}'s Commander retreats to ${formatTerritoryName(retreatTarget.name)}.`);
+ continue;
+ }
+ } else if (neighbors.length > 0) {
+ // DESPERATE ESCAPE: Completely surrounded! Run anywhere to survive!
+ let escapeRoute = neighbors[Math.floor(Math.random() * neighbors.length)];
+ player.commander.loc = escapeRoute.name;
player.commander.ap -= 1; movedOrAction = true;
player.commander.siegeTurns = 0;
- if (Gamestate.logAction) Gamestate.logAction(`VIP MOVEMENT: ${player.name}'s Commander retreats to ${formatTerritoryName(retreatTarget.name)}.`);
- continue;
+ if (Gamestate.logAction) Gamestate.logAction(`VIP MOVEMENT: ${player.name}'s stranded Commander desperately flees to ${formatTerritoryName(escapeRoute.name)}!`);
+ continue;
}
}