Upload files to "/"
This commit is contained in:
parent
a4125271ca
commit
7329d1a1cc
557
index.html
557
index.html
|
|
@ -80,12 +80,13 @@ body {
|
|||
|
||||
/* --- Modals --- */
|
||||
.overlay { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.85); z-index: 9000; }
|
||||
.start-modal, .cards-modal, .win-content, #confirm-restart-modal .content {
|
||||
position: absolute !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important;
|
||||
background: var(--pip-panel-solid) !important; color: var(--pip-color) !important;
|
||||
padding: 25px 35px !important; border-radius: 4px !important; box-shadow: var(--pip-glow) !important;
|
||||
text-align: center; border: 2px solid var(--pip-color) !important; width: 320px; max-width: 90vw;
|
||||
}
|
||||
.start-modal, .cards-modal, .win-content, #confirm-restart-modal .content {
|
||||
position: absolute !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important;
|
||||
background: var(--pip-panel-solid) !important; color: var(--pip-color) !important;
|
||||
padding: 25px 35px !important; border-radius: 4px !important; box-shadow: var(--pip-glow) !important;
|
||||
text-align: center; border: 2px solid var(--pip-color) !important; width: 650px; max-width: 90vw;
|
||||
}
|
||||
|
||||
.help-modal-content { width: 850px !important; max-width: 95vw !important; text-align: left !important; }
|
||||
.manual-footer { font-size: 14px; margin-top: 30px; opacity: 0.7; font-family: 'VT323', monospace; text-transform: uppercase; text-align: center; line-height: 1.2; }
|
||||
.form-group { margin-bottom: 15px; text-align: left; }
|
||||
|
|
@ -830,117 +831,111 @@ button:active {
|
|||
</div>
|
||||
<div class="container">
|
||||
|
||||
<div id="start-modal" class="overlay">
|
||||
<div class="start-modal">
|
||||
<h1 class="title">ROBCO OS v2.0</h1>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="chosen-theme">Loaded Holotape (Theme)</label>
|
||||
<select id="chosen-theme">
|
||||
<option value="fo3" selected>Fallout 3 (Capital Wasteland)</option>
|
||||
<option value="fnv">Fallout: New Vegas (Mojave)</option>
|
||||
<option value="fo4">Fallout 4 (The Commonwealth)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="start-modal" class="overlay">
|
||||
<div class="start-modal">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="chosen-leader">Commander Name</label>
|
||||
<input type="text" id="chosen-leader" value="Courier Six">
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: flex; gap: 10px;">
|
||||
<div style="flex: 2; position: relative;"> <!-- Added position: relative -->
|
||||
<label for="chosen-country-input">Primary Faction</label>
|
||||
<!-- This is our new, fake dropdown input -->
|
||||
<input type="text" id="chosen-country-input" value="New California Republic" autocomplete="off" style="height: 38px; ...">
|
||||
|
||||
<!-- This container will hold our custom dropdown options -->
|
||||
<div id="custom-faction-options" style="display: none; position: absolute; top: 100%; left: 0; right: 0; background: var(--pip-panel-solid); border: 1px solid var(--pip-color); z-index: 1001; max-height: 180px; overflow-y: auto;">
|
||||
<!-- Options will be generated by JavaScript here -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- UPDATED: Title and Subtitle -->
|
||||
<h1 class="title" style="margin-bottom: 0;">Wasteland Conquest</h1>
|
||||
<p style="margin-top: 0; margin-bottom: 20px; font-size: 14px; opacity: 0.7;">A RobCo Industries Strategic Simulation</p>
|
||||
|
||||
|
||||
<div style="flex: 1;">
|
||||
<label for="chosen-color">Color</label>
|
||||
<select id="chosen-color" style="height: 38px; box-sizing: border-box; padding: 4px 8px; font-size: 18px; font-family: inherit; background: rgba(0,0,0,0.8); color: var(--pip-color); border: 1px solid var(--pip-color); width: 100%; cursor: pointer;">
|
||||
<option value="#3a8dcb" style="color: #3a8dcb;">BLUE</option>
|
||||
<option value="#b74545" style="color: #b74545;">RED</option>
|
||||
<option value="#d19a4f" style="color: #d19a4f;">ORANGE</option>
|
||||
<option value="#8e6aa5" style="color: #8e6aa5;">PURPLE</option>
|
||||
<option value="#5a8b5c" style="color: #5a8b5c;">GREEN</option>
|
||||
<option value="#bdb862" style="color: #bdb862;">YELLOW</option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="chosen-difficulty">Simulation Difficulty</label>
|
||||
<select id="chosen-difficulty">
|
||||
<option value="Easy">Easy (Favorable Combat Odds)</option>
|
||||
<option value="Normal" selected>Normal (Standard 50/50)</option>
|
||||
<option value="Hard">Hard (Odds Stacked Against You)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 15px 10px; margin-top: 20px; margin-bottom: 25px; text-align: left;">
|
||||
|
||||
<!-- ROW 1 -->
|
||||
<label title="Watch the skies! Random radioactive storms wipe out 10-25% of troops caught in the blast zone." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-radstorms" style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px;">RADSTORMS</span>
|
||||
</label>
|
||||
|
||||
<label title="Unclaimed territories are filled with Feral Ghouls that slowly multiply depending on your difficulty setting." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-horrors" style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px;">WILD GHOULS</span>
|
||||
</label>
|
||||
|
||||
<label title="Secure Launch Codes and hold Command Silos (☢) to unleash permanent radiation." style="cursor: help; display: flex; align-items: center; color: #ff3333;">
|
||||
<input type="checkbox" id="opt-nukes" style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px;">SCORCHED EARTH</span>
|
||||
</label>
|
||||
|
||||
<!-- ROW 2 -->
|
||||
<label title="Each faction is led by a Commander (★). If they die, you lose instantly. Manage AP and Stimpaks to survive." style="cursor: help; display: flex; align-items: center; color: var(--vip-color);">
|
||||
<input type="checkbox" id="opt-commander" style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px;">COMMANDER PROTOCOL</span>
|
||||
</label>
|
||||
|
||||
<label title="Trading in Bottle Caps will ALWAYS give exactly 3 troops instead of increasing as the game goes on." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-flat-trade" style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px;">FIXED REINFORCEMENTS</span>
|
||||
</label>
|
||||
|
||||
<label title="Hides enemy territory ownership, troop counts, and leaderboard data for any faction you are not adjacent to." style="cursor: help; display: flex; align-items: center; color: #00ff00;">
|
||||
<input type="checkbox" id="opt-fog-of-war" checked style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px; text-shadow: 0 0 5px #00ff00;">FOG OF WAR</span>
|
||||
</label>
|
||||
|
||||
<!-- ROW 3 (NEW) -->
|
||||
<label title="Enables unique abilities and starting relationships for each faction. Uncheck for a classic, symmetrical game." style="cursor: help; display: flex; align-items: center; color: #ffb84d;">
|
||||
<input type="checkbox" id="opt-perks" checked style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px; text-shadow: 0 0 5px #ffb84d;">FACTION PERKS</span>
|
||||
</label>
|
||||
|
||||
<label title="Enables random story events and creature attacks that can occur during gameplay." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-encounters" checked style="width: auto; cursor: pointer; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px;">DYNAMIC ENCOUNTERS</span>
|
||||
</label>
|
||||
|
||||
|
||||
<label style="opacity: 0.2; display: flex; align-items: center;">
|
||||
<input type="checkbox" disabled style="width: auto; cursor: not-allowed; margin-right: 8px; margin-bottom: 0;">
|
||||
<span style="font-size: 14px;">[REDACTED]</span>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<button id="submit-name">BOOT SEQUENCE...</button>
|
||||
<div class="form-group">
|
||||
<label for="chosen-theme">Loaded Holotape (Theme)</label>
|
||||
<select id="chosen-theme">
|
||||
<option value="fo3" selected>Fallout 3 (Capital Wasteland)</option>
|
||||
<option value="fnv">Fallout: New Vegas (Mojave)</option>
|
||||
<option value="fo4">Fallout 4 (The Commonwealth)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="chosen-leader">Commander Name</label>
|
||||
<input type="text" id="chosen-leader" value="Courier Six">
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: flex; gap: 10px;">
|
||||
<div style="flex: 2; position: relative;">
|
||||
<label for="chosen-country-input">Primary Faction</label>
|
||||
<input type="text" id="chosen-country-input" value="New California Republic" autocomplete="off" style="height: 38px;">
|
||||
<div id="custom-faction-options" style="display: none; position: absolute; top: 100%; left: 0; right: 0; background: var(--pip-panel-solid); border: 1px solid var(--pip-color); z-index: 1001; max-height: 180px; overflow-y: auto;">
|
||||
<!-- Options will be generated by JavaScript here -->
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex: 1;">
|
||||
<label for="chosen-color">Color</label>
|
||||
<select id="chosen-color" style="height: 38px; box-sizing: border-box; padding: 4px 8px; font-size: 18px; font-family: inherit; background: rgba(0,0,0,0.8); color: var(--pip-color); border: 1px solid var(--pip-color); width: 100%; cursor: pointer;">
|
||||
<option value="#3a8dcb" style="color: #3a8dcb;">BLUE</option>
|
||||
<option value="#b74545" style="color: #b74545;">RED</option>
|
||||
<option value="#d19a4f" style="color: #d19a4f;">ORANGE</option>
|
||||
<option value="#8e6aa5" style="color: #8e6aa5;">PURPLE</option>
|
||||
<option value="#5a8b5c" style="color: #5a8b5c;">GREEN</option>
|
||||
<option value="#bdb862" style="color: #bdb862;">YELLOW</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="chosen-difficulty">Simulation Difficulty</label>
|
||||
<select id="chosen-difficulty">
|
||||
<option value="Easy">Easy (Favorable Combat Odds)</option>
|
||||
<option value="Normal" selected>Normal (Standard 50/50)</option>
|
||||
<option value="Hard">Hard (Odds Stacked Against You)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- NEW: Game Mode Preset System -->
|
||||
<div class="form-group" style="margin-top: 20px;">
|
||||
<label for="game-mode-preset">Game Mode</label>
|
||||
<select id="game-mode-preset">
|
||||
<option value="classic">Classic Conquest</option>
|
||||
<option value="survival">Wasteland Survival</option>
|
||||
<option value="heroes">Heroes of the Wasteland</option>
|
||||
<option value="apocalypse">Apocalypse Now</option>
|
||||
<option value="alliance">Alliance Warfare</option>
|
||||
<option value="covert">Covert Warfare</option>
|
||||
<option value="nuclear">Nuclear Option</option>
|
||||
<option value="custom">Custom Ruleset</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- NEW: Preset Description Box -->
|
||||
<div id="preset-description" style="background: rgba(0,0,0,0.4); border: 1px inset var(--pip-color); padding: 10px; margin-top: 10px; min-height: 120px; text-align: left; font-size: 18px; line-height: 1.4; white-space: normal;">
|
||||
<!-- Description will be injected here by JavaScript -->
|
||||
</div>
|
||||
|
||||
<!-- NEW: Container for Custom Checkboxes (hidden by default) -->
|
||||
<div id="custom-rules-container" style="display: none;">
|
||||
<div class="form-group" style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px 10px; margin-top: 20px; text-align: left;">
|
||||
<label title="Enables unique abilities and starting relationships for each faction." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-perks" class="custom-opt" checked> <span style="margin-left: 8px;">Faction Perks</span>
|
||||
</label>
|
||||
<label title="Each faction is led by a killable VIP." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-commander" class="custom-opt"> <span style="margin-left: 8px;">Commanders</span>
|
||||
</label>
|
||||
<label title="Hides territories not adjacent to your own." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-fog-of-war" class="custom-opt" checked> <span style="margin-left: 8px;">Fog of War</span>
|
||||
</label>
|
||||
<label title="Watch the skies! Random radioactive storms." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-radstorms" class="custom-opt"> <span style="margin-left: 8px;">Radstorms</span>
|
||||
</label>
|
||||
<label title="Unclaimed territories are filled with Feral Ghouls." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-horrors" class="custom-opt"> <span style="margin-left: 8px;">Wild Ghouls</span>
|
||||
</label>
|
||||
<label title="Enables random story events and creature attacks." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-encounters" class="custom-opt" checked> <span style="margin-left: 8px;">Dynamic Encounters</span>
|
||||
</label>
|
||||
<label title="Unleash permanent radiation with nuclear weapons." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-nukes" class="custom-opt"> <span style="margin-left: 8px;">Scorched Earth</span>
|
||||
</label>
|
||||
<label title="Card trade-ins always give a flat 3 troops." style="cursor: help; display: flex; align-items: center;">
|
||||
<input type="checkbox" id="opt-flat-trade" class="custom-opt"> <span style="margin-left: 8px;">Fixed Reinforcements</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="submit-name">Initiate Simulation</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="central-toast-popup" class="toast">
|
||||
<!-- Content will be injected by JavaScript -->
|
||||
|
|
@ -1048,7 +1043,11 @@ button:active {
|
|||
<input type="range" id="recruitment-slider" min="0" max="0" value="0" style="width: 100%;">
|
||||
</div>
|
||||
<p>Total Cost: <span id="recruitment-cost" style="color: var(--pip-color); font-weight: bold;">0</span> Caps</p>
|
||||
<button id="recruitment-confirm">Confirm Recruitment</button>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
|
||||
<button id="recruitment-skip">Cancel</button>
|
||||
<button id="recruitment-confirm">Recruit Units</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -2096,9 +2095,10 @@ function updateDynamicCursor(hexColor) {
|
|||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const factionInput = document.getElementById('chosen-country');
|
||||
const factionInput = document.getElementById('chosen-country-input');
|
||||
const tooltip = document.getElementById('vats-tooltip'); // WE ARE USING YOUR EXISTING TOOLTIP ELEMENT
|
||||
|
||||
|
||||
if (!factionInput || !tooltip) {
|
||||
console.error("Tooltip or Faction Input not found!");
|
||||
return;
|
||||
|
|
@ -2538,11 +2538,148 @@ const helpBtn = document.querySelector('#help-btn');
|
|||
const helpModal = document.querySelector('#help-modal');
|
||||
const closeHelpBtn = document.querySelector('#close-help-btn');
|
||||
|
||||
// --- NEW: GAME MODE PRESET LOGIC (FINAL FORMATTING) ---
|
||||
const presetSelector = document.getElementById('game-mode-preset');
|
||||
const descriptionBox = document.getElementById('preset-description');
|
||||
const customRulesBox = document.getElementById('custom-rules-container');
|
||||
const checkboxes = {
|
||||
perks: document.getElementById('opt-perks'),
|
||||
commander: document.getElementById('opt-commander'),
|
||||
fog: document.getElementById('opt-fog-of-war'),
|
||||
radstorms: document.getElementById('opt-radstorms'),
|
||||
horrors: document.getElementById('opt-horrors'),
|
||||
encounters: document.getElementById('opt-encounters'),
|
||||
nukes: document.getElementById('opt-nukes'),
|
||||
flatTrade: document.getElementById('opt-flat-trade')
|
||||
};
|
||||
|
||||
const presetData = {
|
||||
'classic': {
|
||||
narrative: `"The old world is dead. The new world is a battleground. This is a pure contest of strategy and will. Amass your forces, conquer the continents, and eliminate all rivals. In this simulation, only tactical superiority matters. No heroes, no cataclysms—just war. War never changes."`,
|
||||
mechanics: { economy: false, perks: false, commander: false, fog: false, radstorms: false, horrors: false, encounters: false, nukes: false }
|
||||
},
|
||||
'survival': {
|
||||
narrative: `"Forget conquering the world; your only goal is to survive it. The air itself is poison, radioactive storms blot out the sun, and packs of ghouls infest the ruins. The map is a dark, unknown space. Every cap counts. Every step could be your last. Welcome to the real wasteland."`,
|
||||
mechanics: { economy: true, perks: false, commander: false, fog: true, radstorms: true, horrors: true, encounters: true, nukes: false }
|
||||
},
|
||||
'heroes': {
|
||||
narrative: `"History is not made by armies, but by individuals. In this simulation, the fate of the wasteland rests on the shoulders of its Commanders. Leverage your faction's unique doctrines and your leader's abilities to outmaneuver your foes. This is a war of personalities, where a single heroic action can turn the tide."`,
|
||||
mechanics: { economy: true, perks: true, commander: true, fog: false, radstorms: false, horrors: false, encounters: true, nukes: false }
|
||||
},
|
||||
'apocalypse': {
|
||||
narrative: `"The end of the world wasn't the end. The real apocalypse is now. The sky rains radiation, the dead walk the earth, and the forgotten keys to nuclear fire are back in play. There are no safe havens. There is no hope. There is only the roar of the storm, the shriek of the ghouls, and the terrifying whistle of the falling bomb."`,
|
||||
mechanics: { economy: true, perks: false, commander: false, fog: false, radstorms: true, horrors: true, encounters: true, nukes: true }
|
||||
},
|
||||
'alliance': {
|
||||
narrative: `"No faction can stand alone against the darkness. In this scenario, you are bound by oath to a brother-in-arms. You will be automatically allied with a lore-friendly faction, and you will share their fate. If they fall, you fall. Coordinate your attacks, defend your ally's borders, and crush the other coalitions to achieve a shared victory."`,
|
||||
mechanics: { economy: true, perks: true, commander: true, fog: true, radstorms: false, horrors: false, encounters: false, nukes: false }
|
||||
},
|
||||
'covert': {
|
||||
narrative: `"The deadliest weapon is the one your enemy never sees coming. This is a war fought in the shadows. Use your Commander to infiltrate enemy lines, leverage your faction's perks for an asymmetric advantage, and navigate the fog of war to set the perfect trap. Information is your ammunition. Secrecy is your armor."`,
|
||||
mechanics: { economy: true, perks: true, commander: true, fog: true, radstorms: false, horrors: false, encounters: true, nukes: false }
|
||||
},
|
||||
'nuclear': {
|
||||
narrative: `"The ghosts of the Great War have returned. This simulation is a tense cold war, a frantic arms race to secure the world's remaining nuclear arsenal. Protect your Commander, hunt for launch codes, and make the impossible choice. Will you be the savior of the wasteland, or will you become its destroyer?"`,
|
||||
mechanics: { economy: true, perks: false, commander: true, fog: true, radstorms: false, horrors: false, encounters: false, nukes: true }
|
||||
}
|
||||
};
|
||||
|
||||
function updatePresetView() {
|
||||
const selectedMode = presetSelector.value;
|
||||
if (themeSelector) { themeSelector.dispatchEvent(new Event('change')); }
|
||||
|
||||
if (selectedMode === 'custom') {
|
||||
descriptionBox.style.display = 'none';
|
||||
customRulesBox.style.display = 'block';
|
||||
} else {
|
||||
descriptionBox.style.display = 'block';
|
||||
customRulesBox.style.display = 'none';
|
||||
|
||||
const data = presetData[selectedMode];
|
||||
if (!data) return;
|
||||
|
||||
// Update checkboxes behind the scenes
|
||||
checkboxes.perks.checked = data.mechanics.perks;
|
||||
checkboxes.commander.checked = data.mechanics.commander;
|
||||
checkboxes.fog.checked = data.mechanics.fog;
|
||||
checkboxes.radstorms.checked = data.mechanics.radstorms;
|
||||
checkboxes.horrors.checked = data.mechanics.horrors;
|
||||
checkboxes.encounters.checked = data.mechanics.encounters;
|
||||
checkboxes.nukes.checked = data.mechanics.nukes;
|
||||
|
||||
const economyEnabled = data.mechanics.economy;
|
||||
|
||||
// Build the comma-separated mechanics string
|
||||
let enabledMechanics = [];
|
||||
if (economyEnabled) enabledMechanics.push("Wasteland Economy");
|
||||
if (data.mechanics.perks) enabledMechanics.push("Faction Perks");
|
||||
if (data.mechanics.commander) enabledMechanics.push("Commanders");
|
||||
if (data.mechanics.fog) enabledMechanics.push("Fog of War");
|
||||
if (data.mechanics.radstorms) enabledMechanics.push("Radstorms");
|
||||
if (data.mechanics.horrors) enabledMechanics.push("Wild Ghouls");
|
||||
if (data.mechanics.encounters) enabledMechanics.push("Dynamic Encounters");
|
||||
if (data.mechanics.nukes) enabledMechanics.push("Scorched Earth");
|
||||
|
||||
let mechanicsString;
|
||||
if (enabledMechanics.length > 0) {
|
||||
mechanicsString = enabledMechanics.join(', ');
|
||||
} else {
|
||||
mechanicsString = "None (Card trade-in reinforcements only)";
|
||||
}
|
||||
|
||||
// Build the final description HTML
|
||||
descriptionBox.innerHTML = `<p style="margin-top: 0; margin-bottom: 10px;">${data.narrative}</p><strong>MECHANICS ENABLED:</strong><br>${mechanicsString}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add event listener and run once on load
|
||||
presetSelector.addEventListener('change', updatePresetView);
|
||||
document.addEventListener('DOMContentLoaded', updatePresetView);
|
||||
|
||||
|
||||
let Gamestate = {};
|
||||
|
||||
// --- STANDALONE VISUAL THEME CONTROLLER ---
|
||||
function applyTheme() {
|
||||
const themeDropdown = document.getElementById('chosen-theme');
|
||||
if (!themeDropdown) return;
|
||||
|
||||
const theme = themeDropdown.value;
|
||||
const leaderInput = document.getElementById('chosen-leader');
|
||||
const factionInput = document.getElementById('chosen-country-input');
|
||||
|
||||
// 1. Apply Theme: Update cursor color
|
||||
if (typeof updateDynamicCursor === 'function') {
|
||||
if (theme === 'fnv') { updateDynamicCursor('#ffb642'); }
|
||||
else if (theme === 'fo4') { updateDynamicCursor('#22ccff'); }
|
||||
else { updateDynamicCursor('#18ff62'); }
|
||||
}
|
||||
// 2. Apply Theme: Swap CSS body class
|
||||
document.body.classList.remove('theme-fo3', 'theme-fnv', 'theme-fo4');
|
||||
if (theme !== 'fo3') { document.body.classList.add('theme-' + theme); }
|
||||
|
||||
// 3. Apply Theme: Auto-fill default names
|
||||
if (theme === 'fo3') {
|
||||
if (leaderInput) { leaderInput.value = "Lone Wanderer"; }
|
||||
if (factionInput) { factionInput.value = "Brotherhood of Steel"; }
|
||||
} else if (theme === 'fnv') {
|
||||
if (leaderInput) { leaderInput.value = "Courier Six"; }
|
||||
if (factionInput) { factionInput.value = "New California Republic"; }
|
||||
} else if (theme === 'fo4') {
|
||||
if (leaderInput) { leaderInput.value = "Sole Survivor"; }
|
||||
if (factionInput) { factionInput.value = "The Minutemen"; }
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the theme is applied on page load and when the theme dropdown is changed.
|
||||
document.addEventListener('DOMContentLoaded', applyTheme);
|
||||
document.getElementById('chosen-theme')?.addEventListener('change', applyTheme);
|
||||
|
||||
|
||||
// --- ERA-SPECIFIC DYNAMIC THEME LOADER ---
|
||||
const themeSelector = document.getElementById('chosen-theme');
|
||||
const leaderInput = document.getElementById('chosen-leader');
|
||||
const factionInput = document.getElementById('chosen-country');
|
||||
|
||||
|
||||
// =================================================================
|
||||
// NEW CUSTOM DROPDOWN & TOOLTIP LOGIC
|
||||
|
|
@ -2554,27 +2691,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
|
||||
const perksEnabledCheckbox = document.getElementById('opt-perks');
|
||||
|
||||
// Function to enable or disable the custom dropdown based on the checkbox
|
||||
const toggleFactionInput = () => {
|
||||
const perksAreOn = perksEnabledCheckbox.checked;
|
||||
if (perksAreOn) {
|
||||
factionInput.disabled = false;
|
||||
factionInput.style.pointerEvents = 'auto';
|
||||
factionInput.style.opacity = '1';
|
||||
} else {
|
||||
factionInput.disabled = true;
|
||||
factionInput.style.pointerEvents = 'none';
|
||||
factionInput.style.opacity = '0.5';
|
||||
tooltip.style.display = 'none'; // Also hide the tooltip
|
||||
}
|
||||
};
|
||||
|
||||
// Add an event listener to the checkbox itself
|
||||
perksEnabledCheckbox.addEventListener('change', toggleFactionInput);
|
||||
|
||||
// Call it once on load to set the initial state
|
||||
toggleFactionInput();
|
||||
|
||||
if (!factionInput || !optionsContainer || !tooltip) return;
|
||||
|
||||
// --- Function to populate the options ---
|
||||
|
|
@ -2626,10 +2742,35 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
|
||||
// --- Event Listeners to control the dropdown ---
|
||||
factionInput.addEventListener('focus', () => {
|
||||
populateCustomDropdown();
|
||||
optionsContainer.style.display = 'block';
|
||||
const selectedMode = presetSelector.value;
|
||||
|
||||
// For Alliance Warfare, force the dropdown open and make the input read-only.
|
||||
if (selectedMode === 'alliance') {
|
||||
factionInput.readOnly = true;
|
||||
populateCustomDropdown();
|
||||
optionsContainer.style.display = 'block';
|
||||
}
|
||||
// For other modes with perks, allow the dropdown but also allow typing.
|
||||
else if (checkboxes.perks.checked) {
|
||||
factionInput.readOnly = false;
|
||||
populateCustomDropdown();
|
||||
optionsContainer.style.display = 'block';
|
||||
}
|
||||
// For modes without perks, do nothing, leaving it as a simple textbox.
|
||||
else {
|
||||
factionInput.readOnly = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Add a listener to remove the read-only state if the user switches away from Alliance mode.
|
||||
presetSelector.addEventListener('change', () => {
|
||||
if (presetSelector.value !== 'alliance') {
|
||||
factionInput.readOnly = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Hide dropdown if you click anywhere else
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!factionInput.contains(e.target) && !optionsContainer.contains(e.target)) {
|
||||
|
|
@ -2641,46 +2782,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
const themeSelector = document.getElementById('chosen-theme');
|
||||
if (themeSelector) {
|
||||
themeSelector.addEventListener('change', (e) => {
|
||||
// First, populate the faction list for the new theme
|
||||
populateCustomDropdown();
|
||||
|
||||
// Now, perform all the theme-switching actions
|
||||
const theme = e.target.value;
|
||||
const leaderInput = document.getElementById('chosen-leader');
|
||||
const factionInput = document.getElementById('chosen-country-input');
|
||||
|
||||
// 1. Update cursor color
|
||||
if (typeof updateDynamicCursor === 'function') {
|
||||
if (theme === 'fnv') {
|
||||
updateDynamicCursor('#ffb642');
|
||||
} else if (theme === 'fo4') {
|
||||
updateDynamicCursor('#22ccff');
|
||||
} else {
|
||||
updateDynamicCursor('#18ff62');
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Swap CSS body class
|
||||
document.body.classList.remove('theme-fo3', 'theme-fnv', 'theme-fo4');
|
||||
if (theme !== 'fo3') {
|
||||
document.body.classList.add('theme-' + theme);
|
||||
}
|
||||
|
||||
// 3. Auto-fill default names
|
||||
if (theme === 'fo3') {
|
||||
if (leaderInput) { leaderInput.value = "Lone Wanderer"; }
|
||||
if (factionInput) { factionInput.value = "Brotherhood of Steel"; }
|
||||
} else if (theme === 'fnv') {
|
||||
if (leaderInput) { leaderInput.value = "Courier Six"; }
|
||||
if (factionInput) { factionInput.value = "New California Republic"; }
|
||||
} else if (theme === 'fo4') {
|
||||
if (leaderInput) { leaderInput.value = "Sole Survivor"; }
|
||||
if (factionInput) { factionInput.value = "The Minutemen"; }
|
||||
}
|
||||
// The populateCustomDropdown function is now called by the faction input's 'focus' event.
|
||||
});
|
||||
|
||||
// Trigger on boot to apply the default theme immediately
|
||||
themeSelector.dispatchEvent(new Event('change'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3188,6 +3294,20 @@ Gamestate.updateButtonText = function() {
|
|||
|
||||
|
||||
Gamestate.start = async function() {
|
||||
|
||||
// --- APPLY VISUAL THEME AT GAME START ---
|
||||
const themeDropdown = document.getElementById('chosen-theme');
|
||||
if (themeDropdown) {
|
||||
const theme = themeDropdown.value;
|
||||
document.body.classList.remove('theme-fo3', 'theme-fnv', 'theme-fo4');
|
||||
if (theme !== 'fo3') {
|
||||
document.body.classList.add('theme-' + theme);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --- Read Game Options from UI First ---
|
||||
this.perksEnabled = document.getElementById('opt-perks')?.checked;
|
||||
this.nukesEnabled = document.getElementById('opt-nukes')?.checked;
|
||||
|
|
@ -3312,6 +3432,8 @@ this.wastelandEconomyActive = this.perksEnabled || this.nukesEnabled || this.com
|
|||
});
|
||||
} else {
|
||||
// --- CLASSIC SETUP: Faction Perks Disabled (Corrected) ---
|
||||
const themeDropdown = document.getElementById('chosen-theme');
|
||||
const selectedTheme = themeDropdown ? themeDropdown.value : "fo3";
|
||||
const playerLeaderInput = document.getElementById('chosen-leader');
|
||||
const playerCountryInput = document.getElementById('chosen-country-input');
|
||||
const playerColorInput = document.getElementById('chosen-color');
|
||||
|
|
@ -4375,7 +4497,8 @@ if (cardCount) {
|
|||
let viewCardsBtn = document.getElementById('view-cards-btn');
|
||||
if (viewCardsBtn) {
|
||||
if (this.wastelandEconomyActive) {
|
||||
viewCardsBtn.textContent = "VIEW STASH";
|
||||
viewCardsBtn.textContent = "RECRUITMENT";
|
||||
viewCardsBtn.onclick = () => this.showRecruitmentModal();
|
||||
viewCardsBtn.style.opacity = "1";
|
||||
viewCardsBtn.style.pointerEvents = "auto";
|
||||
viewCardsBtn.classList.remove('ready-to-trade');
|
||||
|
|
@ -5744,7 +5867,7 @@ Gamestate.aiMove = async function() {
|
|||
if (this.wastelandEconomyActive) {
|
||||
this.stage = "Income";
|
||||
this.updateButtonText();
|
||||
if (turnInfoMessage) turnInfoMessage.textContent = "Collect your taxes from the wasteland.";
|
||||
if (turnInfoMessage) turnInfoMessage.textContent = "Collect taxes and recruit new troops.";
|
||||
|
||||
let income = this.player.areas.length * 2;
|
||||
let continentIncome = 0;
|
||||
|
|
@ -5762,7 +5885,6 @@ if (this.wastelandEconomyActive) {
|
|||
this.stage = "Fortify";
|
||||
let bonus = this.unitBonus(this.player, 0);
|
||||
this.player.reserve += bonus;
|
||||
this.player.army += bonus;
|
||||
}
|
||||
|
||||
this.updateButtonText();
|
||||
|
|
@ -5892,20 +6014,38 @@ if (this.wastelandEconomyActive) {
|
|||
if (!turbo) await this.logAction(`${this.players[i].name} recruited ${troopsToBuy} new troops.`);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Original AI card trade-in and reinforcement logic
|
||||
if (this.wastelandEconomyActive) {
|
||||
// New AI Economy Logic
|
||||
let income = this.players[i].areas.length * 2;
|
||||
let continentIncome = 0;
|
||||
continents.forEach(continent => {
|
||||
let ownsContinent = continent.areas.every(area => this.players[i].areas.includes(area) && !this.countries.find(c => c.name === area).isCrater);
|
||||
if (ownsContinent) { continentIncome += 5; }
|
||||
});
|
||||
income += continentIncome;
|
||||
this.players[i].caps += income;
|
||||
if (!turbo) await this.logAction(`${this.players[i].name} collected ${income} Caps in taxes.`);
|
||||
|
||||
const troopCost = 5;
|
||||
const spendingPercentage = (Math.random() * 0.5) + 0.5; // AI will spend 50-100% of their caps
|
||||
const affordableTroops = Math.floor(this.players[i].caps / troopCost);
|
||||
const troopsToBuy = Math.floor(affordableTroops * spendingPercentage);
|
||||
const totalCost = troopsToBuy * troopCost;
|
||||
|
||||
if (troopsToBuy > 0) {
|
||||
this.players[i].caps -= totalCost;
|
||||
this.players[i].reserve += troopsToBuy;
|
||||
this.players[i].army += troopsToBuy;
|
||||
if (!turbo) await this.logAction(`${this.players[i].name} recruited ${troopsToBuy} new troops.`);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Original AI card trade-in and reinforcement logic
|
||||
this.players[i].reserve = this.unitBonus(this.players[i], i);
|
||||
let troopsToPlace = this.players[i].reserve;
|
||||
let tradeIndices = this.getBestTrade(this.players[i].cards);
|
||||
const mrHousePlayer = this.players.find(p => this.perksEnabled && p.perk && p.perk.id === 'the_house_always_wins');
|
||||
if (mrHousePlayer && tradeIndices) {
|
||||
const cardsTraded = 3;
|
||||
const houseBonus = Math.floor(cardsTraded / 3);
|
||||
if (houseBonus > 0) {
|
||||
mrHousePlayer.cards.push({ country: "House Always Wins", type: "Wild" });
|
||||
if (!turbo) await this.logAction(`"The House Always Wins..." Mr. House takes a cut of the trade.`);
|
||||
}
|
||||
}
|
||||
if (tradeIndices) {
|
||||
let bonus = getTradeBonus();
|
||||
tradeIndices.sort((a, b) => b - a).forEach(index => {
|
||||
|
|
@ -5917,6 +6057,8 @@ if (this.wastelandEconomyActive) {
|
|||
}
|
||||
this.players[i].army += this.players[i].reserve;
|
||||
if (troopsToPlace > 0 && !turbo) await this.logAction(`${this.players[i].name} deployed ${troopsToPlace} troops to their sectors.`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let areaToFortify = ["", 0];
|
||||
|
|
@ -6712,22 +6854,31 @@ Gamestate.showRecruitmentModal = function() {
|
|||
costDisplay.textContent = this.value * troopCost;
|
||||
};
|
||||
|
||||
const newConfirmBtn = confirmBtn.cloneNode(true);
|
||||
confirmBtn.parentNode.replaceChild(newConfirmBtn, confirmBtn);
|
||||
const newConfirmBtn = confirmBtn.cloneNode(true);
|
||||
const cancelBtn = document.getElementById('recruitment-skip'); // Or 'recruitment-cancel' if you renamed it
|
||||
const newCancelBtn = cancelBtn.cloneNode(true);
|
||||
|
||||
newConfirmBtn.onclick = () => {
|
||||
const troopsToBuy = parseInt(slider.value);
|
||||
const totalCost = troopsToBuy * troopCost;
|
||||
confirmBtn.parentNode.replaceChild(newConfirmBtn, confirmBtn);
|
||||
cancelBtn.parentNode.replaceChild(newCancelBtn, cancelBtn);
|
||||
|
||||
if (this.player.caps >= totalCost) {
|
||||
this.player.caps -= totalCost;
|
||||
this.player.reserve += troopsToBuy;
|
||||
this.player.army += troopsToBuy;
|
||||
this.logAction(`RECRUITMENT: Purchased +${troopsToBuy} troops for ${totalCost} Caps.`, true);
|
||||
}
|
||||
modal.style.display = 'none';
|
||||
resolve();
|
||||
};
|
||||
newConfirmBtn.onclick = () => {
|
||||
const troopsToBuy = parseInt(slider.value);
|
||||
const totalCost = troopsToBuy * troopCost;
|
||||
|
||||
if (this.player.caps >= totalCost) {
|
||||
this.player.caps -= totalCost;
|
||||
this.player.reserve += troopsToBuy;
|
||||
this.player.army += troopsToBuy;
|
||||
this.logAction(`RECRUITMENT: Purchased +${troopsToBuy} troops for ${totalCost} Caps.`, true);
|
||||
}
|
||||
modal.style.display = 'none';
|
||||
resolve();
|
||||
};
|
||||
|
||||
newCancelBtn.onclick = () => {
|
||||
modal.style.display = 'none';
|
||||
resolve();
|
||||
};
|
||||
|
||||
modal.style.display = 'flex';
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue