Update test2

This commit is contained in:
threememories 2026-04-21 18:26:03 +00:00
parent 8caa1d8047
commit 29dd88f3a7
1 changed files with 356 additions and 222 deletions

578
test2
View File

@ -848,16 +848,18 @@ button:active {
</div> </div>
<div class="form-group" style="display: flex; gap: 10px;"> <div class="form-group" style="display: flex; gap: 10px;">
<div style="flex: 2;"> <div style="flex: 2; position: relative;"> <!-- Added position: relative -->
<label for="chosen-country">Primary Faction</label> <label for="chosen-country-input">Primary Faction</label>
<!-- This input is now linked to the datalist below --> <!-- This is our new, fake dropdown input -->
<input type="text" id="chosen-country" list="faction-list" value="New California Republic" 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%;"> <input type="text" id="chosen-country-input" value="New California Republic" autocomplete="off" style="height: 38px; ...">
<!-- This is the hidden list of selectable faction options -->
<datalist id="faction-list"> <!-- This container will hold our custom dropdown options -->
<!-- This will be populated by JavaScript --> <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;">
</datalist> <!-- Options will be generated by JavaScript here -->
</div>
</div> </div>
<div style="flex: 1;"> <div style="flex: 1;">
<label for="chosen-color">Color</label> <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;"> <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;">
@ -1834,190 +1836,6 @@ button:active {
return true; // Prevents the browser's default error handling return true; // Prevents the browser's default error handling
}; };
// --- DYNAMIC CURSOR FUNCTION ---
function updateDynamicCursor(hexColor) {
const encodedColor = hexColor.replace('#', '%23');
const cursorStyle = `
svg path, svg .area {
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><text x="0" y="24" font-size="32" fill="${encodedColor}" stroke="black" stroke-width="1.5" paint-order="stroke fill">⯐</text></svg>') 16 16, auto !important;
}
`;
let styleEl = document.getElementById('dynamic-cursor-style');
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.id = 'dynamic-cursor-style';
document.head.appendChild(styleEl);
}
styleEl.innerHTML = cursorStyle;
}
/*===============================
ROBCO RISK
===============================*/
if (!document.getElementById('radstorm-styles')) {
let style = document.createElement('style');
style.id = 'radstorm-styles';
style.innerHTML = `
@keyframes radstormWarn { 0% { fill: #ffcc00; filter: drop-shadow(0 0 5px #ffcc00); } 100% { fill: #ff8800; filter: drop-shadow(0 0 15px #ff8800); } }
@keyframes radstormAct { 0% { fill: #39ff14; filter: drop-shadow(0 0 10px #39ff14); } 100% { fill: #00ff00; filter: drop-shadow(0 0 25px #00ff00); } }
.radstorm-warning { animation: radstormWarn 1s infinite alternate !important; opacity: 0.85; }
.radstorm-active { animation: radstormAct 0.4s infinite alternate !important; opacity: 0.95; }
`;
document.head.appendChild(style);
}
function sanitizeInput(str) {
let temp = document.createElement('div');
temp.textContent = str;
return temp.innerHTML;
}
const continents = [
{ areas: ["indonesia", "new_guinea", "eastern_australia", "western_australia"], name: "The Southern Wastes", bonus: 2 },
{ areas: ["brazil", "peru", "venezuela", "argentina"], name: "Amazonian Wastes", bonus: 2 },
{ areas: ["egypt", "north_africa", "east_africa", "congo", "south_africa", "madagascar"], name: "Saharan Wastes", bonus: 3 },
{ areas: ["iceland", "uk", "scandinavia", "northern_europe", "western_europe", "ukraine", "southern_europe"], name: "European Commonwealth", bonus: 5 },
{ areas: ["central_america", "eastern_us", "western_us", "quebec", "ontario", "alberta", "northwest_territory", "alaska", "greenland"], name: "Capital Wasteland", bonus: 5 },
{ areas: ["middle_east", "afghanistan", "ural", "siberia", "irkutsk", "yakutsk", "kamchatka", "mongolia", "japan", "china", "siam", "india"], name: "The Great Wastes", bonus: 7 }
];
const countries = [
{name: "indonesia", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["siam", "western_australia", "new_guinea"]},
{name: "new_guinea", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["indonesia", "eastern_australia", "western_australia"]},
{name: "eastern_australia", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["western_australia", "new_guinea"]},
{name: "western_australia", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["eastern_australia", "new_guinea", "indonesia"]},
{name: "ural", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "siberia", "afghanistan", "china"]},
{name: "siberia", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ural", "mongolia", "yakutsk", "irkutsk", "china"]},
{name: "afghanistan", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "ural", "middle_east", "china", "india"]},
{name: "irkutsk", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["yakutsk", "siberia", "kamchatka", "mongolia"]},
{name: "yakutsk", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["irkutsk", "siberia", "kamchatka"]},
{name: "kamchatka", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["alaska", "yakutsk", "japan", "irkutsk", "mongolia"]},
{name: "middle_east", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "afghanistan", "india", "egypt", "east_africa", "southern_europe"]},
{name: "india", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["middle_east", "siam", "afghanistan", "china"]},
{name: "siam", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["indonesia", "india", "china"]},
{name: "china", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ural", "siberia", "afghanistan", "mongolia", "siam", "india"]},
{name: "mongolia", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["irkutsk", "siberia", "kamchatka", "china", "japan"]},
{name: "japan", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["kamchatka", "mongolia"]},
{name: "egypt", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["middle_east", "southern_europe", "north_africa", "east_africa"]},
{name: "north_africa", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["egypt", "southern_europe", "western_europe", "east_africa", "congo", "brazil"]},
{name: "east_africa", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["middle_east", "egypt", "north_africa", "congo", "madagascar", "south_africa"]},
{name: "congo", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["south_africa", "north_africa", "east_africa"]},
{name: "south_africa", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["congo", "madagascar", "east_africa"]},
{name: "madagascar", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["south_africa", "east_africa"]},
{name: "brazil", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["peru", "argentina", "north_africa", "venezuela"]},
{name: "peru", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["brazil", "argentina", "venezuela"]},
{name: "argentina", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["brazil", "peru"]},
{name: "venezuela", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["brazil", "peru", "central_america"]},
{name: "iceland", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["greenland", "uk", "scandinavia"]},
{name: "scandinavia", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["iceland", "uk", "ukraine", "northern_europe"]},
{name: "northern_europe", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "uk", "scandinavia", "southern_europe", "western_europe"]},
{name: "western_europe", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["north_africa", "uk", "northern_europe", "southern_europe"]},
{name: "southern_europe", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["north_africa", "egypt", "northern_europe", "western_europe", "middle_east", "ukraine"]},
{name: "uk", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["western_europe", "iceland", "northern_europe", "scandinavia"]},
{name: "ukraine", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["scandinavia", "ural", "northern_europe", "southern_europe", "afghanistan", "middle_east"]},
{name: "greenland", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["iceland", "quebec", "ontario", "northwest_territory"]},
{name: "central_america", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["venezuela", "eastern_us", "western_us"]},
{name: "eastern_us", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["central_america", "western_us", "ontario", "quebec"]},
{name: "western_us", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["central_america", "eastern_us", "ontario", "alberta"]},
{name: "quebec", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["eastern_us", "ontario", "greenland"]},
{name: "ontario", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["eastern_us", "western_us", "quebec", "alberta", "northwest_territory", "greenland"]},
{name: "alberta", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["western_us", "ontario", "northwest_territory", "alaska"]},
{name: "northwest_territory", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["alberta", "ontario", "greenland", "alaska"]},
{name: "alaska", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["alberta", "northwest_territory", "kamchatka"]}
];
function formatTerritoryName(str) {
return str.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
}
const wastelandEncounters = [
"Spotted a Vertibird flying low over the wastes.",
"Radio picked up a strange distress signal. Probably a raider trap.",
"Caravan guards chased off a pack of wild Mongrels.",
"Another settlement needs our help. Marking it on the global map.",
"Traded a handful of mutfruit for some polished 5.56 rounds.",
"Super Mutants spotted dragging captives into a metro tunnel.",
"Avoided a Radscorpion nest near the old irradiated crater.",
"Brahmin stampede delayed supply lines by three hours.",
"A wandering Eyebot is blasting patriotic music nearby.",
"Dust storm rolling in. Visibility dropping to near zero.",
"Picked up a HAM radio broadcast from KQ4JZM... Static approaching.",
"Scavenged an abandoned pickup truck. The tonneau cover was surprisingly intact.",
"Found an old pre-war safe containing detailed, multi-tiered bug-out lists.",
"Spotted survivors establishing a security perimeter around a ruined church.",
"A traveling merchant caravan was spotted on the horizon.",
"Distant gunfire echoes across the irradiated valleys.",
"A malfunctioning Eyebot floats by, blaring corrupted propaganda.",
"Scavengers report an abandoned Vault entrance was discovered nearby.",
"A pack of vicious mutated hounds was seen migrating east.",
"Vertibirds were heard passing high up through the cloud cover.",
"A local HAM radio operator picked up a strange numbers station broadcast.",
"Reports of a Super Mutant behemoth roaming the southern borders.",
"Wasteland weather spotters warn of a glowing green cloud bank moving in.",
"A group of heavily armed mercs passed through, looking for bounties.",
"Someone triggered a frag mine out in the ruins. The crows are scattering.",
"A mysterious stranger was seen watching the battle from a distance.",
"Hacked a terminal and found a manuscript for 'SurvivalSOS Fundamentals of Survival' by Joseph Howard.",
"A Brotherhood of Steel patrol was seen securing a pre-war tech cache.",
"Traders whisper about a synth replacing a local settlement leader.",
"A rogue Protectron is wandering the wastes demanding subway tokens.",
"Someone set off an ancient car alarm in the ruins, drawing a feral horde.",
"A crashed alien ship was reportedly sighted in the northern mountains.",
"A wandering scavenger is trying to sell fake 'charge cards' to the locals.",
"The regional water purifier is acting up; emergency rationing is in effect.",
"A caravan guard swears they saw the Mothman out in the dead woods.",
"A raider gang strung up fresh warning signs around the highway overpass.",
"A faint, looping distress signal just appeared on the emergency radio frequency.",
"Scouts report a massive dust storm kicking up out in the glowing sea.",
"A lone wanderer in a blue jumpsuit was seen walking quietly down the highway.",
"Wastelanders are trading rumors about a vault dweller desperately searching for a water chip.",
"A caravan from the Hub just passed through, complaining about relentless Khan raids.",
"An ancient, restored Highwayman car was heard roaring down the cracked interstate.",
"Scavengers claim they saw heavy power armor troops with an 'E' insignia stepping out of a Vertibird.",
"Talon Company mercenaries are sweeping the local ruins for a high-value bounty target.",
"A lone DJ's voice cuts through the static, reminding everyone to fight the good fight.",
"A squad of elite NCR Rangers was seen setting up a forward observation post on the ridge.",
"A heavily armed Securitron rolled past, displaying a grinning cowboy face on its monitor.",
"A blue artillery flare lit up the night sky, signaling a local Minutemen distress call.",
"Paranoia is spreading through a nearby settlement that the local bartender is an Institute synth.",
"A massive, irradiated bat-like Scorchbeast was spotted screeching over the treeline.",
"A traveling Responder is attempting to hand out boiled water and disease cures to the locals.",
"Radio picked up a faint transmission: 'Almost heaven, West Virginia. Blue Ridge Mountains, Shenandoah River. Life is old there...' before fading to static.",
"Met a caravan guard who used to be a wasteland adventurer like you, until he took a bullet to the knee.",
"You ran into a hyper guy with a purple gun and an Australian accent talking about 'horde bases'. Whatever that is...",
"A passing caravan handed me a sealed holotape. The label reads: 'To the sandbox. Keep your head down and come home soon. We're praying for you.'"
];
const combatFlavors = [
"while they were complaining about the radioactive heat.",
"after distracting their guards with a loaded Brahmin.",
"by unleashing a swarm of Cazadores on their flank.",
"while they were trying to hack a Novice terminal.",
"after hitting them with a Fat Man. Overkill, but effective.",
"catching them mid-game of Caravan and flipping the table.",
"storming the base while the commander was literally in the shower.",
"distracting the guards with a holotape of 'Butcher Pete'.",
"finding the leader trying to repair a toaster and hitting them with it.",
"by slipping a live frag grenade into their mess hall.",
"after hacking their turrets to fire on their own troops.",
"while their commander was distracted by a busted radio.",
"by charging through the ruins with rusted machetes.",
"after bribing their sentries with a few bottles of purified water.",
"while a stray Deathclaw softened up their frontline defenses.",
"by sneaking through the irradiated subway tunnels beneath them.",
"after spiking their water supply with glowing mushrooms.",
"by waiting patiently for their laser rifles to overheat.",
"while they were busy fending off a pack of rabid mole rats.",
"after a well-placed mini-nuke completely cleared the perimeter.",
"by dressing up as traveling merchants to bypass the main gate.",
"walking in the front door because the guards were asleep on Mentats."
];
// This new constant replaces both basePlayers and themeFactions.
// It contains all faction data, including perks and affinities, in one place.
const FACTIONS = { const FACTIONS = {
// --- Fallout 3 Factions --- // --- Fallout 3 Factions ---
"Brotherhood of Steel": { "Brotherhood of Steel": {
@ -2212,6 +2030,244 @@ const CUSTOM_FACTION = {
}; };
// --- DYNAMIC CURSOR FUNCTION ---
function updateDynamicCursor(hexColor) {
const encodedColor = hexColor.replace('#', '%23');
const cursorStyle = `
svg path, svg .area {
cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><text x="0" y="24" font-size="32" fill="${encodedColor}" stroke="black" stroke-width="1.5" paint-order="stroke fill">⯐</text></svg>') 16 16, auto !important;
}
`;
let styleEl = document.getElementById('dynamic-cursor-style');
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.id = 'dynamic-cursor-style';
document.head.appendChild(styleEl);
}
styleEl.innerHTML = cursorStyle;
}
document.addEventListener('DOMContentLoaded', () => {
const factionInput = document.getElementById('chosen-country');
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;
}
// This function will show and position the tooltip
const showPerkTooltip = (e) => {
const factionName = factionInput.value;
let factionData;
// Determine which faction data to show (canon or custom)
if (FACTIONS && FACTIONS[factionName]) {
factionData = FACTIONS[factionName];
} else if (CUSTOM_FACTION) {
factionData = CUSTOM_FACTION;
}
// If we have valid data, build and show the tooltip
if (factionData && factionData.perk) {
tooltip.innerHTML = `<strong style="color: #ffb84d;">${factionData.perk.name}:</strong> ${factionData.perk.description}`;
tooltip.style.display = 'block';
tooltip.style.left = (e.pageX + 15) + 'px';
tooltip.style.top = (e.pageY + 15) + 'px';
}
};
// This function will hide the tooltip
const hidePerkTooltip = () => {
tooltip.style.display = 'none';
};
// This function will move the tooltip with the mouse
const movePerkTooltip = (e) => {
if (tooltip.style.display === 'block') {
tooltip.style.left = (e.pageX + 15) + 'px';
tooltip.style.top = (e.pageY + 15) + 'px';
}
};
// --- Assign events to the faction input box ---
// When the mouse enters the input box...
factionInput.addEventListener('mouseenter', showPerkTooltip);
// When the mouse leaves the input box...
factionInput.addEventListener('mouseleave', hidePerkTooltip);
// As the mouse moves over the input box...
factionInput.addEventListener('mousemove', movePerkTooltip);
// When the text inside changes (e.g. user types or selects from dropdown)...
factionInput.addEventListener('input', showPerkTooltip);
});
if (!document.getElementById('radstorm-styles')) {
let style = document.createElement('style');
style.id = 'radstorm-styles';
style.innerHTML = `
@keyframes radstormWarn { 0% { fill: #ffcc00; filter: drop-shadow(0 0 5px #ffcc00); } 100% { fill: #ff8800; filter: drop-shadow(0 0 15px #ff8800); } }
@keyframes radstormAct { 0% { fill: #39ff14; filter: drop-shadow(0 0 10px #39ff14); } 100% { fill: #00ff00; filter: drop-shadow(0 0 25px #00ff00); } }
.radstorm-warning { animation: radstormWarn 1s infinite alternate !important; opacity: 0.85; }
.radstorm-active { animation: radstormAct 0.4s infinite alternate !important; opacity: 0.95; }
`;
document.head.appendChild(style);
}
function sanitizeInput(str) {
let temp = document.createElement('div');
temp.textContent = str;
return temp.innerHTML;
}
const continents = [
{ areas: ["indonesia", "new_guinea", "eastern_australia", "western_australia"], name: "The Southern Wastes", bonus: 2 },
{ areas: ["brazil", "peru", "venezuela", "argentina"], name: "Amazonian Wastes", bonus: 2 },
{ areas: ["egypt", "north_africa", "east_africa", "congo", "south_africa", "madagascar"], name: "Saharan Wastes", bonus: 3 },
{ areas: ["iceland", "uk", "scandinavia", "northern_europe", "western_europe", "ukraine", "southern_europe"], name: "European Commonwealth", bonus: 5 },
{ areas: ["central_america", "eastern_us", "western_us", "quebec", "ontario", "alberta", "northwest_territory", "alaska", "greenland"], name: "Capital Wasteland", bonus: 5 },
{ areas: ["middle_east", "afghanistan", "ural", "siberia", "irkutsk", "yakutsk", "kamchatka", "mongolia", "japan", "china", "siam", "india"], name: "The Great Wastes", bonus: 7 }
];
const countries = [
{name: "indonesia", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["siam", "western_australia", "new_guinea"]},
{name: "new_guinea", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["indonesia", "eastern_australia", "western_australia"]},
{name: "eastern_australia", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["western_australia", "new_guinea"]},
{name: "western_australia", continent: "The Southern Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["eastern_australia", "new_guinea", "indonesia"]},
{name: "ural", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "siberia", "afghanistan", "china"]},
{name: "siberia", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ural", "mongolia", "yakutsk", "irkutsk", "china"]},
{name: "afghanistan", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "ural", "middle_east", "china", "india"]},
{name: "irkutsk", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["yakutsk", "siberia", "kamchatka", "mongolia"]},
{name: "yakutsk", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["irkutsk", "siberia", "kamchatka"]},
{name: "kamchatka", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["alaska", "yakutsk", "japan", "irkutsk", "mongolia"]},
{name: "middle_east", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "afghanistan", "india", "egypt", "east_africa", "southern_europe"]},
{name: "india", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["middle_east", "siam", "afghanistan", "china"]},
{name: "siam", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["indonesia", "india", "china"]},
{name: "china", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ural", "siberia", "afghanistan", "mongolia", "siam", "india"]},
{name: "mongolia", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["irkutsk", "siberia", "kamchatka", "china", "japan"]},
{name: "japan", continent: "The Great Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["kamchatka", "mongolia"]},
{name: "egypt", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["middle_east", "southern_europe", "north_africa", "east_africa"]},
{name: "north_africa", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["egypt", "southern_europe", "western_europe", "east_africa", "congo", "brazil"]},
{name: "east_africa", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["middle_east", "egypt", "north_africa", "congo", "madagascar", "south_africa"]},
{name: "congo", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["south_africa", "north_africa", "east_africa"]},
{name: "south_africa", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["congo", "madagascar", "east_africa"]},
{name: "madagascar", continent: "Saharan Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["south_africa", "east_africa"]},
{name: "brazil", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["peru", "argentina", "north_africa", "venezuela"]},
{name: "peru", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["brazil", "argentina", "venezuela"]},
{name: "argentina", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["brazil", "peru"]},
{name: "venezuela", continent: "Amazonian Wastes", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["brazil", "peru", "central_america"]},
{name: "iceland", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["greenland", "uk", "scandinavia"]},
{name: "scandinavia", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["iceland", "uk", "ukraine", "northern_europe"]},
{name: "northern_europe", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["ukraine", "uk", "scandinavia", "southern_europe", "western_europe"]},
{name: "western_europe", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["north_africa", "uk", "northern_europe", "southern_europe"]},
{name: "southern_europe", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["north_africa", "egypt", "northern_europe", "western_europe", "middle_east", "ukraine"]},
{name: "uk", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["western_europe", "iceland", "northern_europe", "scandinavia"]},
{name: "ukraine", continent: "European Commonwealth", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["scandinavia", "ural", "northern_europe", "southern_europe", "afghanistan", "middle_east"]},
{name: "greenland", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["iceland", "quebec", "ontario", "northwest_territory"]},
{name: "central_america", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["venezuela", "eastern_us", "western_us"]},
{name: "eastern_us", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["central_america", "western_us", "ontario", "quebec"]},
{name: "western_us", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["central_america", "eastern_us", "ontario", "alberta"]},
{name: "quebec", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["eastern_us", "ontario", "greenland"]},
{name: "ontario", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["eastern_us", "western_us", "quebec", "alberta", "northwest_territory", "greenland"]},
{name: "alberta", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["western_us", "ontario", "northwest_territory", "alaska"]},
{name: "northwest_territory", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["alberta", "ontario", "greenland", "alaska"]},
{name: "alaska", continent: "Capital Wasteland", owner: "none", color:"#1a1a1a", army: 0, neighbours: ["alberta", "northwest_territory", "kamchatka"]}
];
function formatTerritoryName(str) {
return str.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
}
const wastelandEncounters = [
"Spotted a Vertibird flying low over the wastes.",
"Radio picked up a strange distress signal. Probably a raider trap.",
"Caravan guards chased off a pack of wild Mongrels.",
"Another settlement needs our help. Marking it on the global map.",
"Traded a handful of mutfruit for some polished 5.56 rounds.",
"Super Mutants spotted dragging captives into a metro tunnel.",
"Avoided a Radscorpion nest near the old irradiated crater.",
"Brahmin stampede delayed supply lines by three hours.",
"A wandering Eyebot is blasting patriotic music nearby.",
"Dust storm rolling in. Visibility dropping to near zero.",
"Picked up a HAM radio broadcast from KQ4JZM... Static approaching.",
"Scavenged an abandoned pickup truck. The tonneau cover was surprisingly intact.",
"Found an old pre-war safe containing detailed, multi-tiered bug-out lists.",
"Spotted survivors establishing a security perimeter around a ruined church.",
"A traveling merchant caravan was spotted on the horizon.",
"Distant gunfire echoes across the irradiated valleys.",
"A malfunctioning Eyebot floats by, blaring corrupted propaganda.",
"Scavengers report an abandoned Vault entrance was discovered nearby.",
"A pack of vicious mutated hounds was seen migrating east.",
"Vertibirds were heard passing high up through the cloud cover.",
"A local HAM radio operator picked up a strange numbers station broadcast.",
"Reports of a Super Mutant behemoth roaming the southern borders.",
"Wasteland weather spotters warn of a glowing green cloud bank moving in.",
"A group of heavily armed mercs passed through, looking for bounties.",
"Someone triggered a frag mine out in the ruins. The crows are scattering.",
"A mysterious stranger was seen watching the battle from a distance.",
"Hacked a terminal and found a manuscript for 'SurvivalSOS Fundamentals of Survival' by Joseph Howard.",
"A Brotherhood of Steel patrol was seen securing a pre-war tech cache.",
"Traders whisper about a synth replacing a local settlement leader.",
"A rogue Protectron is wandering the wastes demanding subway tokens.",
"Someone set off an ancient car alarm in the ruins, drawing a feral horde.",
"A crashed alien ship was reportedly sighted in the northern mountains.",
"A wandering scavenger is trying to sell fake 'charge cards' to the locals.",
"The regional water purifier is acting up; emergency rationing is in effect.",
"A caravan guard swears they saw the Mothman out in the dead woods.",
"A raider gang strung up fresh warning signs around the highway overpass.",
"A faint, looping distress signal just appeared on the emergency radio frequency.",
"Scouts report a massive dust storm kicking up out in the glowing sea.",
"A lone wanderer in a blue jumpsuit was seen walking quietly down the highway.",
"Wastelanders are trading rumors about a vault dweller desperately searching for a water chip.",
"A caravan from the Hub just passed through, complaining about relentless Khan raids.",
"An ancient, restored Highwayman car was heard roaring down the cracked interstate.",
"Scavengers claim they saw heavy power armor troops with an 'E' insignia stepping out of a Vertibird.",
"Talon Company mercenaries are sweeping the local ruins for a high-value bounty target.",
"A lone DJ's voice cuts through the static, reminding everyone to fight the good fight.",
"A squad of elite NCR Rangers was seen setting up a forward observation post on the ridge.",
"A heavily armed Securitron rolled past, displaying a grinning cowboy face on its monitor.",
"A blue artillery flare lit up the night sky, signaling a local Minutemen distress call.",
"Paranoia is spreading through a nearby settlement that the local bartender is an Institute synth.",
"A massive, irradiated bat-like Scorchbeast was spotted screeching over the treeline.",
"A traveling Responder is attempting to hand out boiled water and disease cures to the locals.",
"Radio picked up a faint transmission: 'Almost heaven, West Virginia. Blue Ridge Mountains, Shenandoah River. Life is old there...' before fading to static.",
"Met a caravan guard who used to be a wasteland adventurer like you, until he took a bullet to the knee.",
"You ran into a hyper guy with a purple gun and an Australian accent talking about 'horde bases'. Whatever that is...",
"A passing caravan handed me a sealed holotape. The label reads: 'To the sandbox. Keep your head down and come home soon. We're praying for you.'"
];
const combatFlavors = [
"while they were complaining about the radioactive heat.",
"after distracting their guards with a loaded Brahmin.",
"by unleashing a swarm of Cazadores on their flank.",
"while they were trying to hack a Novice terminal.",
"after hitting them with a Fat Man. Overkill, but effective.",
"catching them mid-game of Caravan and flipping the table.",
"storming the base while the commander was literally in the shower.",
"distracting the guards with a holotape of 'Butcher Pete'.",
"finding the leader trying to repair a toaster and hitting them with it.",
"by slipping a live frag grenade into their mess hall.",
"after hacking their turrets to fire on their own troops.",
"while their commander was distracted by a busted radio.",
"by charging through the ruins with rusted machetes.",
"after bribing their sentries with a few bottles of purified water.",
"while a stray Deathclaw softened up their frontline defenses.",
"by sneaking through the irradiated subway tunnels beneath them.",
"after spiking their water supply with glowing mushrooms.",
"by waiting patiently for their laser rifles to overheat.",
"while they were busy fending off a pack of rabid mole rats.",
"after a well-placed mini-nuke completely cleared the perimeter.",
"by dressing up as traveling merchants to bypass the main gate.",
"walking in the front door because the guards were asleep on Mentats."
];
// This new constant replaces both basePlayers and themeFactions.
// It contains all faction data, including perks and affinities, in one place.
const cardTypes = ["Nuka-Cola Cap", "Sunset Sarsaparilla Cap", "Quantum Cap"]; const cardTypes = ["Nuka-Cola Cap", "Sunset Sarsaparilla Cap", "Quantum Cap"];
let deck = []; let deck = [];
let tradeCount = 0; let tradeCount = 0;
@ -2400,40 +2456,86 @@ const themeSelector = document.getElementById('chosen-theme');
const leaderInput = document.getElementById('chosen-leader'); const leaderInput = document.getElementById('chosen-leader');
const factionInput = document.getElementById('chosen-country'); const factionInput = document.getElementById('chosen-country');
if (themeSelector) { // =================================================================
themeSelector.addEventListener('change', function(e) { // NEW CUSTOM DROPDOWN & TOOLTIP LOGIC
let theme = e.target.value; // =================================================================
document.addEventListener('DOMContentLoaded', () => {
// --- ADD THIS BLOCK to update the cursor color --- const factionInput = document.getElementById('chosen-country-input');
if (theme === 'fnv') { const optionsContainer = document.getElementById('custom-faction-options');
updateDynamicCursor('#ffb642'); // Amber const tooltip = document.getElementById('vats-tooltip');
} else if (theme === 'fo4') {
updateDynamicCursor('#22ccff'); // Blue
} else {
updateDynamicCursor('#18ff62'); // Default Green
}
// --- END OF ADDED BLOCK ---
// 1. Swap CSS if (!factionInput || !optionsContainer || !tooltip) return;
document.body.classList.remove('theme-fo3', 'theme-fnv', 'theme-fo4');
if (theme !== 'fo3') document.body.classList.add('theme-' + theme); // --- Function to populate the options ---
const populateCustomDropdown = () => {
// 2. Auto-fill names and adjust input width const themeDropdown = document.getElementById('chosen-theme');
if (theme === 'fo3') { const selectedTheme = themeDropdown ? themeDropdown.value : "fo3";
if(leaderInput) { leaderInput.value = "Lone Wanderer"; } optionsContainer.innerHTML = ''; // Clear old options
if(factionInput) { factionInput.value = "Brotherhood of Steel"; }
} else if (theme === 'fnv') { const factionThemes = {
if(leaderInput) { leaderInput.value = "Courier Six"; } "fo3": ["Brotherhood of Steel", "The Enclave", "Vault 87 Mutants", "Wasteland Raiders", "BOS Outcasts", "Reilly's Rangers"],
if(factionInput) { factionInput.value = "New California Republic"; } "fnv": ["New California Republic", "Caesar's Legion", "New Vegas Securitrons", "Mojave Brotherhood", "Great Khans", "The Fiends"],
} else if (theme === 'fo4') { "fo4": ["The Minutemen", "The Institute", "The Railroad", "The Gunners", "Nuka-World Raiders", "Brotherhood of Steel"]
if(leaderInput) { leaderInput.value = "Sole Survivor"; } };
if(factionInput) { factionInput.value = "The Minutemen"; } const factions = factionThemes[selectedTheme] || [];
factions.forEach(factionName => {
const optionDiv = document.createElement('div');
optionDiv.textContent = factionName;
optionDiv.style.padding = '8px 12px';
optionDiv.style.cursor = 'pointer';
// THIS IS THE KEY: We attach mouse events to each custom option DIV
optionDiv.addEventListener('mouseenter', (e) => {
optionDiv.style.background = 'var(--pip-color)';
optionDiv.style.color = 'var(--pip-dark)';
const factionData = FACTIONS[factionName];
if (factionData && factionData.perk) {
tooltip.innerHTML = `<strong>${factionData.perk.name}:</strong> ${factionData.perk.description}`;
tooltip.style.display = 'block';
}
});
optionDiv.addEventListener('mouseleave', () => {
optionDiv.style.background = '';
optionDiv.style.color = '';
tooltip.style.display = 'none';
});
optionDiv.addEventListener('mousemove', (e) => {
tooltip.style.left = (e.pageX + 15) + 'px';
tooltip.style.top = (e.pageY + 15) + 'px';
});
optionDiv.addEventListener('mousedown', () => {
factionInput.value = factionName;
optionsContainer.style.display = 'none';
});
optionsContainer.appendChild(optionDiv);
});
};
// --- Event Listeners to control the dropdown ---
factionInput.addEventListener('focus', () => {
populateCustomDropdown();
optionsContainer.style.display = 'block';
});
// Hide dropdown if you click anywhere else
document.addEventListener('click', (e) => {
if (!factionInput.contains(e.target) && !optionsContainer.contains(e.target)) {
optionsContainer.style.display = 'none';
} }
}); });
// Trigger on boot to apply the default theme immediately // Also attach populate logic to theme selector
themeSelector.dispatchEvent(new Event('change')); const themeSelector = document.getElementById('chosen-theme');
} if (themeSelector) {
themeSelector.addEventListener('change', populateCustomDropdown);
}
// Initial population
populateCustomDropdown();
});
Gamestate.logQueue = []; Gamestate.logQueue = [];
Gamestate.isLogging = false; Gamestate.isLogging = false;
@ -2703,7 +2805,34 @@ Gamestate.renderInventory = function() {
} }
}; };
Gamestate.populateFactionDropdown = function() {
const themeDropdown = document.getElementById('chosen-theme');
const selectedTheme = themeDropdown ? themeDropdown.value : "fo3";
const dataList = document.getElementById('faction-list');
if (!dataList) return; // Exit if the element doesn't exist
// Clear any old options from a previous selection
dataList.innerHTML = "";
// This object defines which factions belong to which theme
const factionThemes = {
"fo3": ["Brotherhood of Steel", "The Enclave", "Vault 87 Mutants", "Wasteland Raiders", "BOS Outcasts", "Reilly's Rangers"],
"fnv": ["New California Republic", "Caesar's Legion", "New Vegas Securitrons", "Mojave Brotherhood", "Great Khans", "The Fiends"],
"fo4": ["The Minutemen", "The Institute", "The Railroad", "The Gunners", "Nuka-World Raiders", "Brotherhood of Steel"]
};
const factionsForTheme = factionThemes[selectedTheme];
// Create a new <option> element for each faction and add it to the datalist
if (factionsForTheme) {
factionsForTheme.forEach(factionName => {
const option = document.createElement('option');
option.value = factionName;
dataList.appendChild(option);
});
}
};
Gamestate.init = function(){ Gamestate.init = function(){
@ -2758,6 +2887,7 @@ document.getElementById('secret-dev-key')?.addEventListener('click', (e) => {
if (helpModal) helpModal.style.display = 'block'; if (helpModal) helpModal.style.display = 'block';
}); });
// --- FIX: RESTORES THE PATCH NOTES BUTTONS --- // --- FIX: RESTORES THE PATCH NOTES BUTTONS ---
document.getElementById('open-updates-btn')?.addEventListener('click', (e) => { e.preventDefault(); document.getElementById('updates-modal').style.display = 'block'; }); document.getElementById('open-updates-btn')?.addEventListener('click', (e) => { e.preventDefault(); document.getElementById('updates-modal').style.display = 'block'; });
document.getElementById('close-updates-btn')?.addEventListener('click', () => { document.getElementById('updates-modal').style.display = 'none'; }); document.getElementById('close-updates-btn')?.addEventListener('click', () => { document.getElementById('updates-modal').style.display = 'none'; });
@ -2861,6 +2991,9 @@ document.getElementById('secret-dev-key')?.addEventListener('click', (e) => {
} }
// Paste this entire new function into your JavaScript file.
// A good spot is right after your Gamestate.init function.
Gamestate.updateButtonText = function() { Gamestate.updateButtonText = function() {
if (!end) return; if (!end) return;
if (this.stage === "Fortify") { if (this.stage === "Fortify") {
@ -2885,6 +3018,7 @@ Gamestate.updateButtonText = function() {
} }
} }
Gamestate.start = async function(){ Gamestate.start = async function(){
if(combatLog) combatLog.innerHTML = ""; if(combatLog) combatLog.innerHTML = "";