let inventoryPage = 0; const slotsPerPage = 32; let inventoryItems = []; let totalInventoryPages = 1; export async function loadCharacterHouse() { const ui = document.querySelector(".building-ui"); ui.innerHTML = `
Schulter
Handschuhe
Ring 1
Helm
Amulett
Avatar
Guertel
Stiefel
Waffe
Schild
Ring 2
Inventar
`; // Variablen zurücksetzen beim Öffnen inventoryPage = 0; totalInventoryPages = 1; inventoryItems = []; // Buttons zuerst initialisieren initInventoryButtons(); await loadInventory(); await loadEquipment(); initDrag(); initSlotDrag(); initDrop(); initInventoryDrop(); } /* ================================ AVATAR OVERLAY AKTUALISIEREN ================================ */ function updateAvatarOverlay(slotName, iconSrc) { const overlay = document.querySelector( `.avatar-overlay[data-slot="${slotName}"]`, ); if (!overlay) return; const img = overlay.querySelector("img"); if (iconSrc) { img.src = iconSrc; overlay.classList.add("visible"); } else { overlay.classList.remove("visible"); setTimeout(() => { img.src = ""; }, 250); } } /* ================================ INVENTAR LADEN ================================ */ async function loadInventory() { const res = await fetch("/api/inventory"); const data = await res.json(); inventoryItems = data.items; totalInventoryPages = data.totalPages; 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 += `
`; } else { html += `
`; } } grid.innerHTML = html; document.getElementById("inventory-page").innerText = "Seite " + (inventoryPage + 1) + " / " + totalInventoryPages; // Buttons aktivieren/deaktivieren const btnLeft = document.getElementById("inv-left"); const btnRight = document.getElementById("inv-right"); if (btnLeft) btnLeft.disabled = inventoryPage === 0; if (btnRight) btnRight.disabled = inventoryPage >= totalInventoryPages - 1; initDrag(); } /* ================================ INVENTAR BUTTONS ================================ */ function initInventoryButtons() { document.getElementById("inv-left").onclick = () => { if (inventoryPage > 0) { inventoryPage--; renderInventory(); } }; document.getElementById("inv-right").onclick = () => { if (inventoryPage < totalInventoryPages - 1) { 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 = ``; if (label) slot.appendChild(label); slot.classList.add("has-item"); // Avatar Overlay aktualisieren updateAvatarOverlay(item.slot, item.icon); }); } /* ================================ 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 KOMPATIBILITÄT PRÜFEN Ring-Items (equip_slot="ring") passen in ring1 und ring2 ================================ */ function isSlotCompatible(itemSlot, targetSlot) { if (itemSlot === targetSlot) return true; if (itemSlot === "ring" && (targetSlot === "ring1" || targetSlot === "ring2")) return true; return false; } /* ================================ 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 || !isSlotCompatible(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; // Item aus dem Array entfernen damit es sich nicht verdoppelt inventoryItems = inventoryItems.filter( (item) => String(item.id) !== String(itemId), ); 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 = ``; if (label) slot.appendChild(label); slot.classList.add("has-item"); // Avatar Overlay anzeigen updateAvatarOverlay(targetSlot, icon); 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; // Ring-Slots normalisiert als "ring" im Inventar speichern const normalizedSlot = slotName === "ring1" || slotName === "ring2" ? "ring" : slotName; inventoryItems.push({ id: itemId, level: itemLevel, equip_slot: normalizedSlot, icon: img.src, }); renderInventory(); const label = slot.querySelector(".slot-label"); slot.innerHTML = ""; if (label) slot.appendChild(label); slot.classList.remove("has-item"); // Avatar Overlay entfernen updateAvatarOverlay(slotName, null); 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, itemId, itemLevelId }), }); }