änderungen hud 7

This commit is contained in:
Cay 2026-03-16 15:03:24 +00:00
parent 8e71687799
commit 8211e56cb4
5 changed files with 177 additions and 75 deletions

4
app.js
View File

@ -165,7 +165,7 @@ app.get("/api/hud", requireLogin, async (req, res) => {
[userId],
);
const [[currency]] = await db.query(
"SELECT silver, gold, gems FROM account_currency WHERE account_id = ?",
"SELECT silver, gold, gems, wood, stone FROM account_currency WHERE account_id = ?",
[userId],
);
res.json({
@ -173,6 +173,8 @@ app.get("/api/hud", requireLogin, async (req, res) => {
silver: currency?.silver || 0,
gold: currency?.gold || 0,
gems: currency?.gems || 0,
wood: currency?.wood || 0,
stone: currency?.stone || 0,
});
} catch (err) {
console.error(err);

View File

@ -170,8 +170,8 @@
#hud-currency {
display: flex;
align-items: center;
gap: 8px;
flex-direction: column;
gap: 4px;
background: linear-gradient(
135deg,
@ -191,6 +191,12 @@
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.7);
}
.hud-res-row {
display: flex;
align-items: center;
gap: 8px;
}
/* Einzelne Währung */
.hud-res {

View File

@ -1,4 +1,5 @@
import { showNotification } from "../notification.js";
import { refreshHud } from "../hud.js";
export async function loadMine(buildingId) {
const actionsTab = document.getElementById("tab-actions");
@ -10,7 +11,7 @@ export async function loadMine(buildingId) {
async function renderMineStatus(buildingId) {
const actionsTab = document.getElementById("tab-actions");
try {
const res = await fetch("/api/mine/" + buildingId + "/status");
const res = await fetch("/api/mine/" + buildingId + "/status");
if (!res.ok) throw new Error("API Fehler");
const data = await res.json();
@ -22,49 +23,75 @@ async function renderMineStatus(buildingId) {
const minutesLeft = Math.floor(data.next_cycle_in_seconds / 60);
const secondsLeft = data.next_cycle_in_seconds % 60;
const resourceRows = data.available.map((r) => {
const icon = resourceIcon(r.resource);
const label = resourceLabel(r.resource);
return (
"<div class='mine-resource-row " + (data.ready ? "mine-resource-ready" : "") + "'>" +
"<span class='mine-resource-icon'>" + icon + "</span>" +
"<span class='mine-resource-label'>" + label + "</span>" +
"<span class='mine-resource-amount'>" + r.amount + "</span>" +
"</div>"
);
}).join("");
const resourceRows = data.available
.map((r) => {
const icon = resourceIcon(r.resource);
const label = resourceLabel(r.resource);
return (
"<div class='mine-resource-row " +
(data.ready ? "mine-resource-ready" : "") +
"'>" +
"<span class='mine-resource-icon'>" +
icon +
"</span>" +
"<span class='mine-resource-label'>" +
label +
"</span>" +
"<span class='mine-resource-amount'>" +
r.amount +
"</span>" +
"</div>"
);
})
.join("");
actionsTab.innerHTML =
"<div class='mine-panel'>" +
"<div class='mine-header-row'>" +
"<span class='mine-level-badge'>Level " + data.level + "</span>" +
"<span class='mine-cycles'>" + (data.cycles > 0 ? data.cycles + "x Zyklus abgeschlossen" : "Laeuft...") + "</span>" +
"</div>" +
"<div class='mine-divider'></div>" +
"<p class='mine-section-title'>Abgebaut</p>" +
"<div class='mine-resources'>" + resourceRows + "</div>" +
"<div class='mine-divider'></div>" +
"<div class='mine-timer-row'>" +
"<span class='mine-timer-label'>Naechster Zyklus in</span>" +
"<span class='mine-timer' id='mine-countdown' data-seconds='" + data.next_cycle_in_seconds + "'>" +
minutesLeft + "m " + secondsLeft + "s" +
"</span>" +
"</div>" +
"<div class='mine-actions'>" +
"<button class='mine-btn-collect " + (data.ready ? "" : "mine-btn-disabled") + "'" +
" id='mine-collect-btn'" +
" data-building='" + buildingId + "'" +
(data.ready ? "" : " disabled") + ">" +
(data.ready ? "Abholen" : "Noch nicht bereit") +
"</button>" +
"</div>" +
"<div class='mine-header-row'>" +
"<span class='mine-level-badge'>Level " +
data.level +
"</span>" +
"<span class='mine-cycles'>" +
(data.cycles > 0 ? data.cycles + "x Zyklus abgeschlossen" : "Laeuft...") +
"</span>" +
"</div>" +
"<div class='mine-divider'></div>" +
"<p class='mine-section-title'>Abgebaut</p>" +
"<div class='mine-resources'>" +
resourceRows +
"</div>" +
"<div class='mine-divider'></div>" +
"<div class='mine-timer-row'>" +
"<span class='mine-timer-label'>Naechster Zyklus in</span>" +
"<span class='mine-timer' id='mine-countdown' data-seconds='" +
data.next_cycle_in_seconds +
"'>" +
minutesLeft +
"m " +
secondsLeft +
"s" +
"</span>" +
"</div>" +
"<div class='mine-actions'>" +
"<button class='mine-btn-collect " +
(data.ready ? "" : "mine-btn-disabled") +
"'" +
" id='mine-collect-btn'" +
" data-building='" +
buildingId +
"'" +
(data.ready ? "" : " disabled") +
">" +
(data.ready ? "Abholen" : "Noch nicht bereit") +
"</button>" +
"</div>" +
"</div>";
startCountdown(buildingId);
} catch (err) {
console.error("Mine Fehler:", err);
actionsTab.innerHTML = "<p class='mine-error'>Fehler beim Laden der Mineninfo.</p>";
actionsTab.innerHTML =
"<p class='mine-error'>Fehler beim Laden der Mineninfo.</p>";
}
}
@ -73,36 +100,50 @@ document.addEventListener("click", async (e) => {
if (!btn || btn.disabled) return;
const buildingId = btn.dataset.building;
btn.disabled = true;
btn.disabled = true;
btn.textContent = "Wird abgeholt...";
try {
const res = await fetch("/api/mine/" + buildingId + "/collect", { method: "POST" });
const res = await fetch("/api/mine/" + buildingId + "/collect", {
method: "POST",
});
if (!res.ok) throw new Error("API Fehler");
const data = await res.json();
if (data.error) {
showNotification(
data.ready_in_display
? "Die Mine ist noch nicht bereit.\nBereit in: " + data.ready_in_display
? "Die Mine ist noch nicht bereit.\nBereit in: " +
data.ready_in_display
: data.error,
"Mine",
"⛏️"
"⛏️",
);
await renderMineStatus(buildingId);
return;
}
const lines = data.collected
.map((c) => resourceIcon(c.resource) + " " + resourceLabel(c.resource) + ": +" + c.amount)
.map(
(c) =>
resourceIcon(c.resource) +
" " +
resourceLabel(c.resource) +
": +" +
c.amount,
)
.join("\n");
showNotification("Erfolgreich abgeholt!\n\n" + lines, "Mine", "⛏️");
await renderMineStatus(buildingId);
await refreshHud();
} catch (err) {
console.error("Abholen Fehler:", err);
showNotification("Fehler beim Abholen. Bitte erneut versuchen.", "Fehler", "⚠️");
showNotification(
"Fehler beim Abholen. Bitte erneut versuchen.",
"Fehler",
"⚠️",
);
await renderMineStatus(buildingId);
}
});
@ -114,7 +155,10 @@ function startCountdown(buildingId) {
countdownInterval = setInterval(() => {
const el = document.getElementById("mine-countdown");
if (!el) { clearInterval(countdownInterval); return; }
if (!el) {
clearInterval(countdownInterval);
return;
}
let secs = parseInt(el.dataset.seconds, 10) - 1;
if (secs < 0) secs = 0;
@ -129,11 +173,25 @@ function startCountdown(buildingId) {
}
function resourceIcon(resource) {
const map = { gold: "🪙", copper: "🟤", silver: "⚪", iron: "⚙️", stone: "🪨", wood: "🪵" };
const map = {
gold: "🪙",
copper: "🟤",
silver: "⚪",
iron: "⚙️",
stone: "🪨",
wood: "🪵",
};
return map[resource] || "📦";
}
function resourceLabel(resource) {
const map = { gold: "Gold", copper: "Kupfer", silver: "Silber", iron: "Eisen", stone: "Stein", wood: "Holz" };
const map = {
gold: "Gold",
copper: "Kupfer",
silver: "Silber",
iron: "Eisen",
stone: "Stein",
wood: "Holz",
};
return map[resource] || resource;
}
}

View File

@ -2,25 +2,47 @@
HUD Charakter & Währungsanzeige
================================ */
async function fetchHud() {
const res = await fetch("/api/hud");
if (!res.ok) throw new Error("HUD API Fehler");
return await res.json();
}
function applyHudData(data) {
const set = (id, val) => {
const el = document.getElementById(id);
if (el) el.textContent = formatNumber(val);
};
const nameEl = document.getElementById("hud-name");
if (nameEl) nameEl.textContent = data.name;
set("hud-silver", data.silver);
set("hud-gold", data.gold);
set("hud-gems", data.gems);
set("hud-wood", data.wood);
set("hud-stone", data.stone);
}
export async function loadHud() {
try {
const res = await fetch("/api/hud");
if (!res.ok) throw new Error("HUD API Fehler");
const data = await res.json();
// Name
document.getElementById("hud-name").textContent = data.name;
// Währungen
document.getElementById("hud-silver").textContent = formatNumber(data.silver);
document.getElementById("hud-gold").textContent = formatNumber(data.gold);
document.getElementById("hud-gems").textContent = formatNumber(data.gems);
const data = await fetchHud();
applyHudData(data);
} catch (err) {
console.error("HUD Fehler:", err);
}
}
// Wird von mine.js nach dem Abholen aufgerufen
export async function refreshHud() {
try {
const data = await fetchHud();
applyHudData(data);
} catch (err) {
console.error("HUD Refresh Fehler:", err);
}
}
function formatNumber(n) {
if (n === undefined || n === null) return "0";
return Number(n).toLocaleString("de-DE");

View File

@ -287,21 +287,35 @@
<!-- Währungs Panel -->
<div id="hud-currency">
<div class="hud-res">
<span class="hud-res-icon">⚪</span>
<span class="hud-res-value" id="hud-silver">0</span>
<div class="hud-res-row">
<div class="hud-res">
<span class="hud-res-icon">⚪</span>
<span class="hud-res-value" id="hud-silver">0</span>
</div>
<div class="hud-sep"></div>
<div class="hud-res">
<span class="hud-res-icon">💠</span>
<span class="hud-res-value" id="hud-gems">0</span>
</div>
<div class="hud-sep"></div>
<div class="hud-res">
<span class="hud-res-icon">🪙</span>
<span class="hud-res-value" id="hud-gold">0</span>
</div>
<button id="hud-gold-btn">Gold</button>
</div>
<div class="hud-sep"></div>
<div class="hud-res">
<span class="hud-res-icon">💠</span>
<span class="hud-res-value" id="hud-gems">0</span>
<div class="hud-res-row">
<div class="hud-res">
<span class="hud-res-icon">🪵</span>
<span class="hud-res-value" id="hud-wood">0</span>
</div>
<div class="hud-sep"></div>
<div class="hud-res">
<span class="hud-res-icon">🪨</span>
<span class="hud-res-value" id="hud-stone">0</span>
</div>
</div>
<div class="hud-sep"></div>
<div class="hud-res">
<span class="hud-res-icon">🪙</span>
<span class="hud-res-value" id="hud-gold">0</span>
</div>
<button id="hud-gold-btn">Gold</button>
</div>
</div>