dok/public/js/buildings/wohnhaus.js
2026-03-14 13:33:36 +00:00

359 lines
7.7 KiB
JavaScript

let inventoryPage = 0;
const slotsPerPage = 32;
let inventoryItems = [];
export async function loadWohnhaus() {
const ui = document.querySelector(".building-ui");
ui.innerHTML = `
<div id="character-ui">
<div class="slot helmet" data-slot="helmet">
<div class="slot-label">Helm</div>
</div>
<div class="slot shoulder" data-slot="shoulder">
<div class="slot-label">Schulter</div>
</div>
<div class="slot amulet" data-slot="amulet">
<div class="slot-label">Amulett</div>
</div>
<div class="slot gloves" data-slot="gloves">
<div class="slot-label">Handschuhe</div>
</div>
<div class="slot weapon" data-slot="weapon">
<div class="slot-label">Waffe</div>
</div>
<div class="character">
<img src="/images/avatar.png">
</div>
<div class="slot belt" data-slot="belt">
<div class="slot-label">Gürtel</div>
</div>
<div class="slot shield" data-slot="shield">
<div class="slot-label">Schild</div>
</div>
<div class="slot ring1" data-slot="ring">
<div class="slot-label">Ring</div>
</div>
<div class="slot ring2" data-slot="ring">
<div class="slot-label">Ring</div>
</div>
<div class="slot boots" data-slot="boots">
<div class="slot-label">Stiefel</div>
</div>
</div>
<h3>Inventar</h3>
<div id="inventory-wrapper">
<div id="inventory-grid"></div>
</div>
<div id="inventory-nav">
<button id="inv-left">◀</button>
<div id="inventory-page"></div>
<button id="inv-right">▶</button>
</div>
`;
await loadInventory();
await loadEquipment();
initInventoryButtons();
initDrag();
initSlotDrag();
initDrop();
initInventoryDrop();
}
/* ================================
INVENTAR LADEN
================================ */
async function loadInventory() {
const res = await fetch("/api/inventory");
inventoryItems = await res.json();
renderInventory();
}
/* ================================
INVENTAR RENDERN
================================ */
function renderInventory() {
const grid = document.getElementById("inventory-grid");
let html = "";
const start = inventoryPage * slotsPerPage;
const end = start + slotsPerPage;
for (let i = start; i < end; i++) {
const item = inventoryItems[i];
if (item) {
const icon = item.icon || "/images/items/default.png";
html += `
<div class="inventory-slot"
data-slot="${item.equip_slot || ""}"
data-id="${item.id}"
data-level="${item.level}"
draggable="true">
<img src="${icon}">
</div>
`;
} else {
html += `
<div class="inventory-slot empty"></div>
`;
}
}
grid.innerHTML = html;
const totalPages = Math.max(
1,
Math.ceil(inventoryItems.length / slotsPerPage),
);
document.getElementById("inventory-page").innerText =
"Seite " + (inventoryPage + 1) + " / " + totalPages;
initDrag();
}
/* ================================
INVENTAR BUTTONS
================================ */
function initInventoryButtons() {
document.getElementById("inv-left").onclick = () => {
if (inventoryPage > 0) {
inventoryPage--;
renderInventory();
}
};
document.getElementById("inv-right").onclick = () => {
inventoryPage++;
renderInventory();
};
}
/* ================================
EQUIPMENT LADEN
================================ */
async function loadEquipment() {
const res = await fetch("/api/equipment");
const equipment = await res.json();
equipment.forEach((item) => {
if (!item.item_id) return;
const slot = document.querySelector('.slot[data-slot="' + item.slot + '"]');
if (!slot) return;
const label = slot.querySelector(".slot-label");
slot.innerHTML = `
<img src="${item.icon}"
draggable="true"
data-id="${item.item_id}"
data-level="${item.item_level_id}">
`;
if (label) slot.appendChild(label);
slot.classList.add("has-item");
});
}
/* ================================
DRAG INVENTAR
================================ */
function initDrag() {
document.querySelectorAll(".inventory-slot:not(.empty)").forEach((item) => {
item.addEventListener("dragstart", (e) => {
e.dataTransfer.setData("itemId", item.dataset.id);
e.dataTransfer.setData("itemLevel", item.dataset.level);
e.dataTransfer.setData("slot", item.dataset.slot);
e.dataTransfer.setData("source", "inventory");
});
});
}
/* ================================
SLOT DRAG
================================ */
function initSlotDrag() {
document.querySelectorAll(".slot img").forEach((img) => {
img.setAttribute("draggable", "true");
img.addEventListener("dragstart", (e) => {
const slot = img.closest(".slot");
e.dataTransfer.setData("itemId", img.dataset.id);
e.dataTransfer.setData("itemLevel", img.dataset.level);
e.dataTransfer.setData("slot", slot.dataset.slot);
e.dataTransfer.setData("source", "slot");
});
});
}
/* ================================
SLOT DROP
================================ */
function initDrop() {
document.querySelectorAll(".slot").forEach((slot) => {
slot.addEventListener("dragover", (e) => e.preventDefault());
slot.addEventListener("drop", (e) => {
e.preventDefault();
const itemId = e.dataTransfer.getData("itemId");
const itemLevel = e.dataTransfer.getData("itemLevel");
const itemSlot = e.dataTransfer.getData("slot");
const source = e.dataTransfer.getData("source");
const targetSlot = slot.dataset.slot;
if (!itemSlot || itemSlot !== targetSlot) return;
let icon;
if (source === "inventory") {
const inventoryItem = document.querySelector(
'.inventory-slot[data-id="' + itemId + '"]',
);
if (!inventoryItem) return;
icon = inventoryItem.querySelector("img").src;
inventoryItem.classList.add("empty");
inventoryItem.innerHTML = "";
} else {
const slotItem = document.querySelector(
'.slot[data-slot="' + itemSlot + '"] img',
);
if (!slotItem) return;
icon = slotItem.src;
}
const label = slot.querySelector(".slot-label");
slot.innerHTML = `
<img src="${icon}"
draggable="true"
data-id="${itemId}"
data-level="${itemLevel}">
`;
if (label) slot.appendChild(label);
slot.classList.add("has-item");
initDrag();
initSlotDrag();
saveEquipment(targetSlot, itemId, itemLevel);
});
});
}
/* ================================
INVENTAR DROP
================================ */
function initInventoryDrop() {
const grid = document.getElementById("inventory-grid");
grid.addEventListener("dragover", (e) => e.preventDefault());
grid.addEventListener("drop", (e) => {
e.preventDefault();
const source = e.dataTransfer.getData("source");
if (source !== "slot") return;
const itemId = e.dataTransfer.getData("itemId");
const itemLevel = e.dataTransfer.getData("itemLevel");
const slotName = e.dataTransfer.getData("slot");
const slot = document.querySelector('.slot[data-slot="' + slotName + '"]');
if (!slot) return;
const img = slot.querySelector("img");
if (!img) return;
inventoryItems.push({
id: itemId,
level: itemLevel,
equip_slot: slotName,
icon: img.src,
});
renderInventory();
const label = slot.querySelector(".slot-label");
slot.innerHTML = "";
if (label) slot.appendChild(label);
slot.classList.remove("has-item");
saveEquipment(slotName, null, null);
initDrag();
initSlotDrag();
});
}
/* ================================
DB SPEICHERN
================================ */
async function saveEquipment(slot, itemId, itemLevelId) {
await fetch("/api/equip", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
slot: slot,
itemId: itemId,
itemLevelId: itemLevelId,
}),
});
}