dok/public/js/map-ui.js
2026-03-29 13:22:35 +01:00

261 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { loadCharacterHouse } from "./buildings/character-house.js";
import { loadBlackmarket } from "./buildings/blackmarket.js";
import { loadMine } from "./buildings/mine.js";
const popup = document.getElementById("building-popup");
const title = document.getElementById("popup-title");
const tooltip = document.getElementById("map-tooltip");
const tooltipCache = {};
const buildingModules = {
11: loadCharacterHouse, // Tabs ausblenden, eigenes UI
12: loadBlackmarket, // Tabs ausblenden, eigenes UI
10: loadMine, // Tabs bleiben sichtbar, nur Aktionen-Tab befüllen
};
// Gebäude die ihre eigenen Tabs behalten sollen
const keepTabsVisible = new Set([10]);
/* ================================
Tabs zurücksetzen
================================ */
function resetTabs() {
document
.querySelectorAll(".tab")
.forEach((t) => t.classList.remove("active"));
document
.querySelectorAll(".tab-content")
.forEach((c) => c.classList.remove("active"));
const firstTab = document.querySelector(".tab");
const firstContent = document.querySelector(".tab-content");
if (firstTab) firstTab.classList.add("active");
if (firstContent) firstContent.classList.add("active");
}
/* ================================
Gebäude Popup öffnen
================================ */
document.querySelectorAll(".building").forEach((building) => {
building.addEventListener("click", async (e) => {
e.preventDefault();
try {
const url = building.getAttribute("href");
title.innerText = "Lädt...";
popup.style.left = "50%";
popup.style.top = "50%";
popup.classList.add("active");
resetTabs();
const res = await fetch("/api" + url);
if (!res.ok) throw new Error("API Fehler");
const data = await res.json();
title.innerText = data.name;
const infoTab = document.getElementById("tab-info");
const tabs = document.querySelector(".popup-tabs");
// Standard: Info anzeigen
infoTab.innerHTML = `
<div class="popup-info-title">${data.name}</div>
<div class="popup-stat-row"><span class="popup-stat-key">Level</span><span class="popup-stat-val">${data.level}</span></div>
<div class="popup-stat-row"><span class="popup-stat-key">Punkte</span><span class="popup-stat-val">${data.points} / ${data.nextLevelPoints}</span></div>
<p class="popup-desc" style="color:#cccccc !important;font-size:13px;line-height:1.8;">${data.description}</p>
<div class="popup-xp-wrap">
<div class="popup-xp-label">Fortschritt zum nächsten Level</div>
<div class="popup-xp-track">
<div class="popup-xp-fill" style="width:${Math.min((data.points / data.nextLevelPoints) * 100, 100)}%">
<div class="popup-xp-shimmer"></div>
</div>
</div>
</div>
<div class="popup-divider">✦ · ✦ · ✦</div>
`;
// Standard Tabs anzeigen
tabs.style.display = "flex";
// Prüfen ob Gebäude eigenes UI hat
const buildingType = Number(data.type);
if (buildingModules[buildingType]) {
if (keepTabsVisible.has(buildingType)) {
// Tabs sichtbar lassen (z.B. Mine)
tabs.style.display = "flex";
// Aktionen-Tab aktivieren
document
.querySelectorAll(".tab")
.forEach((t) => t.classList.remove("active"));
document
.querySelectorAll(".tab-content")
.forEach((c) => c.classList.remove("active"));
document
.querySelector(".tab[data-tab='actions']")
.classList.add("active");
document.getElementById("tab-actions").classList.add("active");
} else {
// Tabs ausblenden, eigenes Voll-UI (Wohnhaus, Schwarzmarkt)
tabs.style.display = "none";
infoTab.innerHTML = `<div class="building-ui"></div>`;
}
buildingModules[buildingType](buildingType);
}
document.getElementById("tab-upgrade").innerHTML = `
<div class="popup-info-title">Upgrade</div>
<div class="popup-stat-row"><span class="popup-stat-key">Holz</span><span class="popup-stat-val">${data.upgradeWood ?? ""}</span></div>
<div class="popup-stat-row"><span class="popup-stat-key">Stein</span><span class="popup-stat-val">${data.upgradeStone ?? ""}</span></div>
<div class="popup-stat-row"><span class="popup-stat-key">Gold</span><span class="popup-stat-val">${data.upgradeGold ?? ""}</span></div>
<button class="popup-upgrade-btn" id="upgrade-btn" data-building="${url.split('/').pop()}"
${data.upgradeWood === null ? 'disabled style="opacity:0.4;cursor:not-allowed;"' : ''}>
⚒ UPGRADE STARTEN ⚒
</button>
`;
} catch (error) {
console.error("Gebäude konnte nicht geladen werden:", error);
}
});
});
/* ================================
Tabs wechseln
================================ */
document.querySelectorAll(".tab").forEach((tab) => {
tab.addEventListener("click", () => {
document
.querySelectorAll(".tab")
.forEach((t) => t.classList.remove("active"));
tab.classList.add("active");
document
.querySelectorAll(".tab-content")
.forEach((c) => c.classList.remove("active"));
document.getElementById("tab-" + tab.dataset.tab).classList.add("active");
});
});
/* ================================
Popup schließen
================================ */
document.querySelector(".popup-close").onclick = () => {
popup.classList.remove("active");
};
/* ================================
Upgrade Button
================================ */
document.addEventListener("click", async (e) => {
const btn = e.target.closest("#upgrade-btn");
if (!btn || btn.disabled) return;
const buildingId = btn.dataset.building;
btn.disabled = true;
btn.textContent = "Wird durchgeführt...";
try {
const res = await fetch("/api/building/" + buildingId + "/upgrade", {
method: "POST",
});
const data = await res.json();
if (!res.ok || data.error) {
window.showNotification(data.error || "Upgrade fehlgeschlagen.", "Upgrade", "⚒️");
btn.disabled = false;
btn.textContent = "⚒ UPGRADE STARTEN ⚒";
return;
}
window.showNotification(
`Upgrade erfolgreich!\nNeues Level: ${data.newLevel}\n\nKosten: ${data.cost.wood} Holz, ${data.cost.stone} Stein, ${data.cost.gold} Gold`,
"Upgrade",
"⚒️"
);
// Popup neu laden mit aktualisierten Daten
const building = document.querySelector(`.building[href="/building/${buildingId}"]`);
if (building) building.dispatchEvent(new MouseEvent("click", { bubbles: true }));
// HUD aktualisieren
import("/js/hud.js").then(({ loadHud }) => loadHud());
} catch (err) {
console.error("Upgrade Fehler:", err);
window.showNotification("Fehler beim Upgrade. Bitte erneut versuchen.", "Fehler", "⚠️");
btn.disabled = false;
btn.textContent = "⚒ UPGRADE STARTEN ⚒";
}
});
/* ================================
Tooltip
================================ */
document.querySelectorAll(".building").forEach((building) => {
building.addEventListener("mouseenter", async (e) => {
try {
const id = building.dataset.id;
if (!tooltipCache[id]) {
const res = await fetch("/api/building/" + id);
if (!res.ok) throw new Error("API Fehler");
tooltipCache[id] = await res.json();
}
const data = tooltipCache[id];
tooltip.innerHTML = `
<strong>${data.name}</strong><br>
Level ${data.level}<br>
Punkte ${data.points}/${data.nextLevelPoints}<br>
<hr>
Upgrade Kosten:<br>
${data.upgradeCost}
`;
tooltip.style.display = "block";
} catch (err) {
console.error("Tooltip Fehler:", err);
}
});
building.addEventListener("mousemove", (e) => {
// Tooltip erst rendern lassen damit offsetWidth korrekt ist
const tw = tooltip.offsetWidth;
const th = tooltip.offsetHeight;
let x = e.clientX + 15;
let y = e.clientY + 15;
// Rechter Rand Tooltip links vom Cursor anzeigen
if (x + tw > window.innerWidth - 10) x = e.clientX - tw - 10;
// Unterer Rand Tooltip über dem Cursor anzeigen
if (y + th > window.innerHeight - 10) y = e.clientY - th - 10;
tooltip.style.left = x + "px";
tooltip.style.top = y + "px";
});
building.addEventListener("mouseleave", () => {
tooltip.style.display = "none";
});
});