diff --git a/public/css/building.css b/public/css/building.css
index 0ad1ba3..30725db 100644
--- a/public/css/building.css
+++ b/public/css/building.css
@@ -238,17 +238,122 @@ body {
position: relative;
}
-.character-center img {
+/* ========================
+ Avatar Wrapper
+======================== */
+
+.avatar-wrapper {
+ position: relative;
width: 180px;
height: 320px;
- object-fit: cover;
- object-position: top;
border-radius: 8px;
border: 2px solid #8b6a3c;
+ background: radial-gradient(ellipse at center, #2a1f14 0%, #0d0a07 100%);
box-shadow:
- 0 0 20px rgba(0, 0, 0, 0.7),
- inset 0 0 10px rgba(0, 0, 0, 0.3);
- filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.8));
+ 0 0 20px rgba(0, 0, 0, 0.8),
+ inset 0 0 30px rgba(0, 0, 0, 0.5);
+ overflow: hidden;
+}
+
+.avatar-base {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ display: block;
+ opacity: 0.9;
+}
+
+/* Item Overlays */
+
+.avatar-overlay {
+ position: absolute;
+ pointer-events: none;
+ display: none;
+ z-index: 2;
+}
+
+.avatar-overlay.visible {
+ display: block;
+ animation: overlayFadeIn 0.25s ease;
+}
+
+.avatar-overlay img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ filter: drop-shadow(0 0 4px rgba(255, 200, 80, 0.5))
+ drop-shadow(0 2px 6px rgba(0, 0, 0, 0.9));
+}
+
+@keyframes overlayFadeIn {
+ from {
+ opacity: 0;
+ transform: scale(1.15);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+/* Positionen der Item-Overlays (180x320px) */
+
+.avatar-overlay[data-slot="helmet"] {
+ top: 1%;
+ left: 22%;
+ width: 56%;
+ height: 20%;
+}
+.avatar-overlay[data-slot="amulet"] {
+ top: 21%;
+ left: 58%;
+ width: 30%;
+ height: 11%;
+}
+.avatar-overlay[data-slot="shoulder"] {
+ top: 19%;
+ left: 3%;
+ width: 30%;
+ height: 13%;
+}
+.avatar-overlay[data-slot="weapon"] {
+ top: 38%;
+ left: 56%;
+ width: 40%;
+ height: 32%;
+}
+.avatar-overlay[data-slot="gloves"] {
+ top: 54%;
+ left: 2%;
+ width: 30%;
+ height: 13%;
+}
+.avatar-overlay[data-slot="shield"] {
+ top: 36%;
+ left: 4%;
+ width: 36%;
+ height: 30%;
+}
+.avatar-overlay[data-slot="belt"] {
+ top: 51%;
+ left: 18%;
+ width: 64%;
+ height: 11%;
+}
+.avatar-overlay[data-slot="ring"] {
+ top: 67%;
+ left: 3%;
+ width: 24%;
+ height: 9%;
+}
+.avatar-overlay[data-slot="boots"] {
+ top: 80%;
+ left: 12%;
+ width: 76%;
+ height: 18%;
}
/* Top-Slots (Helm + Amulett) über dem Avatar */
diff --git a/public/images/avatar_silhouette.svg b/public/images/avatar_silhouette.svg
new file mode 100644
index 0000000..156ebf0
--- /dev/null
+++ b/public/images/avatar_silhouette.svg
@@ -0,0 +1,24 @@
+
diff --git a/public/js/buildings/wohnhaus.js b/public/js/buildings/wohnhaus.js
index e38c61d..37a5af1 100644
--- a/public/js/buildings/wohnhaus.js
+++ b/public/js/buildings/wohnhaus.js
@@ -6,7 +6,6 @@ export async function loadWohnhaus() {
const ui = document.querySelector(".building-ui");
ui.innerHTML = `
-
@@ -22,7 +21,20 @@ export async function loadWohnhaus() {
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+
@@ -38,7 +50,6 @@ export async function loadWohnhaus() {
-
Inventar
@@ -46,22 +57,39 @@ export async function loadWohnhaus() {
`;
await loadInventory();
await loadEquipment();
-
initInventoryButtons();
-
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
================================ */
@@ -69,7 +97,6 @@ export async function loadWohnhaus() {
async function loadInventory() {
const res = await fetch("/api/inventory");
inventoryItems = await res.json();
-
renderInventory();
}
@@ -79,7 +106,6 @@ async function loadInventory() {
function renderInventory() {
const grid = document.getElementById("inventory-grid");
-
let html = "";
const start = inventoryPage * slotsPerPage;
@@ -90,32 +116,22 @@ function renderInventory() {
if (item) {
const icon = item.icon || "/images/items/default.png";
-
html += `
-
-

-
-
-`;
+ data-slot="${item.equip_slot || ""}"
+ data-id="${item.id}"
+ data-level="${item.level}"
+ draggable="true">
+
+`;
} else {
- html += `
-
-`;
+ html += ``;
}
}
grid.innerHTML = html;
- const totalPages = Math.max(
- 1,
- Math.ceil(inventoryItems.length / slotsPerPage),
- );
-
+ const totalPages = Math.max(1, Math.ceil(inventoryItems.length / slotsPerPage));
document.getElementById("inventory-page").innerText =
"Seite " + (inventoryPage + 1) + " / " + totalPages;
@@ -135,11 +151,7 @@ function initInventoryButtons() {
};
document.getElementById("inv-right").onclick = () => {
- const totalPages = Math.max(
- 1,
- Math.ceil(inventoryItems.length / slotsPerPage),
- );
-
+ const totalPages = Math.max(1, Math.ceil(inventoryItems.length / slotsPerPage));
if (inventoryPage < totalPages - 1) {
inventoryPage++;
renderInventory();
@@ -163,16 +175,12 @@ async function loadEquipment() {
const label = slot.querySelector(".slot-label");
- slot.innerHTML = `
-
-`;
-
+ slot.innerHTML = `
`;
if (label) slot.appendChild(label);
-
slot.classList.add("has-item");
+
+ // Avatar Overlay aktualisieren
+ updateAvatarOverlay(item.slot, item.icon);
});
}
@@ -201,7 +209,6 @@ function initSlotDrag() {
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);
@@ -221,11 +228,10 @@ function initDrop() {
slot.addEventListener("drop", (e) => {
e.preventDefault();
- const itemId = e.dataTransfer.getData("itemId");
+ 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 itemSlot = e.dataTransfer.getData("slot");
+ const source = e.dataTransfer.getData("source");
const targetSlot = slot.dataset.slot;
if (!itemSlot || itemSlot !== targetSlot) return;
@@ -233,41 +239,27 @@ function initDrop() {
let icon;
if (source === "inventory") {
- const inventoryItem = document.querySelector(
- '.inventory-slot[data-id="' + itemId + '"]',
- );
-
+ 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',
- );
+ const slotItem = document.querySelector('.slot[data-slot="' + itemSlot + '"] img');
if (!slotItem) return;
-
icon = slotItem.src;
}
const label = slot.querySelector(".slot-label");
-
- slot.innerHTML = `
-
-`;
-
+ slot.innerHTML = `
`;
if (label) slot.appendChild(label);
-
slot.classList.add("has-item");
+ // Avatar Overlay anzeigen
+ updateAvatarOverlay(targetSlot, icon);
+
initDrag();
initSlotDrag();
-
saveEquipment(targetSlot, itemId, itemLevel);
});
});
@@ -285,20 +277,17 @@ function initInventoryDrop() {
grid.addEventListener("drop", (e) => {
e.preventDefault();
- const source = e.dataTransfer.getData("source");
-
+ const source = e.dataTransfer.getData("source");
if (source !== "slot") return;
- const itemId = e.dataTransfer.getData("itemId");
+ const itemId = e.dataTransfer.getData("itemId");
const itemLevel = e.dataTransfer.getData("itemLevel");
- const slotName = e.dataTransfer.getData("slot");
+ 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({
@@ -311,14 +300,14 @@ function initInventoryDrop() {
renderInventory();
const label = slot.querySelector(".slot-label");
-
slot.innerHTML = "";
if (label) slot.appendChild(label);
-
slot.classList.remove("has-item");
- saveEquipment(slotName, null, null);
+ // Avatar Overlay entfernen
+ updateAvatarOverlay(slotName, null);
+ saveEquipment(slotName, null, null);
initDrag();
initSlotDrag();
});
@@ -332,10 +321,6 @@ 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,
- }),
+ body: JSON.stringify({ slot, itemId, itemLevelId }),
});
-}
+}
\ No newline at end of file