No equipment configured.
";
}
uegConfig.equipment.forEach((eq) => {
const level = uegState.equipmentLevels[eq.id] || 1;
const cost = calculateUpgradeCost(eq);
const item = document.createElement("div");
item.className = "ueg-equipment-item";
item.innerHTML = `
${eq.name}
LVL ${level}
Upgrade: ${formatCurrency(
cost
)}
`;
equipmentBay.appendChild(item);
});
}
/**
* Renders the dive log.
*/
function renderDiveLog() {
if (!diveLog) return;
diveLog.innerHTML = "";
if (uegState.diveLog.length === 0) {
logDive("Welcome, Captain! Ready for your first dive.", "info");
return;
}
uegState.diveLog.forEach((entry) => {
const item = document.createElement("div");
item.className = `ueg-log-entry ueg-log-${entry.type}`;
item.textContent = entry.message;
diveLog.appendChild(item);
});
}
/**
* Renders the configuration lists.
*/
function renderConfigLists() {
if (!configEquipmentList || !configZoneList) return;
// 1. Render Equipment List
configEquipmentList.innerHTML = "";
if (uegConfig.equipment.length === 0) {
configEquipmentList.innerHTML = "
No equipment defined.
";
}
uegConfig.equipment.forEach((eq) => {
const item = document.createElement("div");
item.className = "ueg-list-item";
item.innerHTML = `
${eq.name}
Base Cost: ${formatCurrency(
eq.baseCost
)}
Bonus: ${formatCurrency(
eq.rewardBonus
)}
`;
configEquipmentList.appendChild(item);
});
// 2. Render Zone List
configZoneList.innerHTML = "";
if (uegConfig.zones.length === 0) {
configZoneList.innerHTML = "
No dive zones defined.
";
}
uegConfig.zones.forEach((zone) => {
const item = document.createElement("div");
item.className = "ueg-list-item";
item.innerHTML = `
${zone.name}
Fuel: ${zone.fuelCost}
Reward: ${formatCurrency(
zone.minReward
)} - ${formatCurrency(zone.maxReward)}
`;
configZoneList.appendChild(item);
});
}
/**
* Update navigation button states.
*/
function updateNavButtons() {
if (!nextBtn || !prevBtn) return;
if (currentTabId === "ueg-tab-dashboard") {
prevBtn.disabled = true;
nextBtn.disabled = false;
} else if (currentTabId === "ueg-tab-config") {
prevBtn.disabled = false;
nextBtn.disabled = true;
}
}
/**
* Re-renders all UI components.
*/
function fullRefreshUI() {
renderDashboard();
renderConfigLists();
renderDiveLog();
updateNavButtons();
}
// === EVENT HANDLERS (Must be global for onclick) ===
window.uegShowTab = (tabId, element) => {
// Hide all content
container
.querySelectorAll(".ueg-tab-content")
.forEach((tab) => (tab.style.display = "none"));
// Deactivate all links
container
.querySelectorAll(".ueg-tab-link")
.forEach((link) => link.classList.remove("ueg-active"));
// Show selected content
const tabToShow = container.querySelector("#" + tabId);
if (tabToShow) {
tabToShow.style.display = "block";
}
// Activate selected link
if (element) {
element.classList.add("ueg-active");
}
currentTabId = tabId;
updateNavButtons();
};
window.uegNavigateTabs = (isNext) => {
const tabs = Array.from(
container.querySelectorAll(".ueg-tab-link")
);
const currentIdx = tabs.findIndex((tab) =>
tab.classList.contains("ueg-active")
);
let newIdx = isNext ? currentIdx + 1 : currentIdx - 1;
if (newIdx >= 0 && newIdx < tabs.length) {
tabs[newIdx].click();
}
};
// --- Config Tab Handlers ---
window.uegAddEquipment = () => {
if (
!newEqName ||
!newEqCost ||
!newEqMulti ||
!newEqBonus
)
return;
const name = newEqName.value.trim();
const baseCost = parseFloat(newEqCost.value);
const costMultiplier = parseFloat(newEqMulti.value);
const rewardBonus = parseFloat(newEqBonus.value);
if (
!name ||
isNaN(baseCost) ||
isNaN(costMultiplier) ||
isNaN(rewardBonus)
) {
alert("Please fill in all equipment fields with valid numbers.");
return;
}
const newId = "e" + Date.now();
uegConfig.equipment.push({
id: newId,
name,
baseCost,
costMultiplier,
rewardBonus,
});
uegState.equipmentLevels[newId] = 1; // Initialize level
newEqName.value = "";
newEqCost.value = "";
newEqMulti.value = "";
newEqBonus.value = "";
renderConfigLists();
renderDashboard(); // Update equipment bay
};
window.uegRemoveEquipment = (id) => {
if (
!confirm("Are you sure you want to remove this equipment?")
) {
return;
}
uegConfig.equipment = uegConfig.equipment.filter(
(eq) => eq.id !== id
);
delete uegState.equipmentLevels[id];
renderConfigLists();
renderDashboard(); // Update equipment bay
};
window.uegAddZone = () => {
if (
!newZoneName ||
!newZoneFuel ||
!newZoneMin ||
!newZoneMax
)
return;
const name = newZoneName.value.trim();
const fuelCost = parseFloat(newZoneFuel.value);
const minReward = parseFloat(newZoneMin.value);
const maxReward = parseFloat(newZoneMax.value);
if (
!name ||
isNaN(fuelCost) ||
isNaN(minReward) ||
isNaN(maxReward)
) {
alert("Please fill in all zone fields with valid numbers.");
return;
}
if (minReward > maxReward) {
alert("Min Reward cannot be greater than Max Reward.");
return;
}
uegConfig.zones.push({
id: "z" + Date.now(),
name,
fuelCost,
minReward,
maxReward,
});
newZoneName.value = "";
newZoneFuel.value = "";
newZoneMin.value = "";
newZoneMax.value = "";
renderConfigLists();
renderDashboard(); // Update zone dropdown
};
window.uegRemoveZone = (id) => {
if (
!confirm("Are you sure you want to remove this dive zone?")
) {
return;
}
uegConfig.zones = uegConfig.zones.filter(
(z) => z.id !== id
);
renderConfigLists();
renderDashboard(); // Update zone dropdown
};
// --- Dashboard Tab Handlers ---
window.uegDoDive = () => {
if (!zoneSelect) return;
const zoneId = zoneSelect.value;
if (!zoneId) {
logDive("No dive zone selected!", "fail");
return;
}
const zone = uegConfig.zones.find(
(z) => z.id === zoneId
);
if (!zone) {
logDive("Error: Selected zone not found.", "fail");
return;
}
// 1. Check fuel
if (uegState.resources.fuel < zone.fuelCost) {
logDive(
`Dive failed: Not enough fuel for ${zone.name}. (Required: ${zone.fuelCost})`,
"fail"
);
renderDashboard();
return;
}
// 2. Pay cost
uegState.resources.fuel -= zone.fuelCost;
uegState.totalDives++;
// 3. Calculate reward
const baseReward =
Math.floor(
Math.random() * (zone.maxReward - zone.minReward + 1)
) + zone.minReward;
const bonusReward = calculateTotalBonus();
const totalReward = baseReward + bonusReward;
// 4. Get reward
uegState.resources.money += totalReward;
logDive(
`Dive to ${
zone.name
} successful! Found treasure worth ${formatCurrency(
baseReward
)} + ${formatCurrency(
bonusReward
)} (Bonus). Total: ${formatCurrency(
totalReward
)}.`,
"success"
);
renderDashboard();
};
window.uegUpgradeEquipment = (id) => {
const eq = uegConfig.equipment.find((e) => e.id === id);
if (!eq) {
logDive("Error: Equipment not found.", "fail");
return;
}
const cost = calculateUpgradeCost(eq);
// 1. Check money
if (uegState.resources.money < cost) {
logDive(
`Upgrade failed: Not enough money for ${
eq.name
}. (Required: ${formatCurrency(cost)})`,
"fail"
);
renderDashboard();
return;
}
// 2. Pay cost
uegState.resources.money -= cost;
// 3. Increment level
uegState.equipmentLevels[id]++;
logDive(
`Upgraded ${eq.name} to LVL ${uegState.equipmentLevels[id]}!`,
"upgrade"
);
renderDashboard();
};
// --- PDF Download ---
window.uegDownloadPDF = () => {
if (!jsPDF) {
alert("PDF library is not loaded. Please try again.");
return;
}
try {
const doc = new jsPDF();
const pageMargin = 15;
const pageWidth = doc.internal.pageSize.getWidth();
const contentWidth = pageWidth - pageMargin * 2;
let y = 20;
// 1. Title
doc.setFontSize(20);
doc.text(
"Captain's Status Report",
pageWidth / 2,
y, {
align: "center"
}
);
y += 20;
// 2. Current Status
doc.setFontSize(16);
doc.text("Current Resources", pageMargin, y);
y += 8;
doc.setFontSize(12);
doc.text(
`Money: ${formatCurrency(uegState.resources.money)}`,
pageMargin,
y
);
y += 7;
doc.text(
`Fuel: ${formatNumber(uegState.resources.fuel)}`,
pageMargin,
y
);
y += 7;
doc.text(
`Total Dives: ${formatNumber(uegState.totalDives)}`,
pageMargin,
y
);
y += 15;
// 3. Equipment Status
doc.setFontSize(16);
doc.text("Equipment Status", pageMargin, y);
y += 8;
doc.setFontSize(12);
uegConfig.equipment.forEach((eq) => {
doc.text(
`${eq.name}: LVL ${
uegState.equipmentLevels[eq.id] || 1
}`,
pageMargin,
y
);
y += 7;
if (y > 270) {
doc.addPage();
y = pageMargin;
}
});
y += 8;
// 4. Dive Log
doc.setFontSize(16);
doc.text("Recent Log", pageMargin, y);
y += 8;
doc.setFontSize(10);
const logEntries = uegState.diveLog.slice(0, 20); // Get last 20
logEntries.forEach((entry) => {
if (y > 270) {
doc.addPage();
y = pageMargin;
}
const splitText = doc.splitTextToSize(
entry.message,
contentWidth
);
doc.text(splitText, pageMargin, y);
y += splitText.length * 4 + 4;
});
doc.save("Underwater_Exploration_Report.pdf");
} catch (e) {
console.error("Error generating PDF:", e);
alert(
"An error occurred while generating the PDF."
);
}
};
// === INITIALIZATION ===
fullRefreshUI();
});