diff --git a/app.js b/app.js index 04b7e31..8df9010 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,4 @@ -require("dotenv").config(); +require("dotenv").config(); const express = require("express"); const path = require("path"); @@ -21,8 +21,8 @@ const avatar = require("./routes/avatar"); const equip = require("./routes/equip"); const equipment = require("./routes/equipment"); const blackmarket = require("./routes/blackmarket"); -const mineRoute = require("./routes/mine_route"); -const arenaRoutes = require("./routes/routes_arena"); +const mineRoute = require("./routes/mine"); +const arenaRoutes = require("./routes/arena"); const { registerArenaHandlers } = require("./sockets/arena"); const { registerChatHandlers } = require("./sockets/chat"); diff --git a/public/css/building.css b/public/css/building.css index 75d3978..faad0d6 100644 --- a/public/css/building.css +++ b/public/css/building.css @@ -1,3 +1,9 @@ +/* ================================================ + building.css – Charakter, Equipment, Inventar + Dynasty of Knights + Popup/Tooltip/Notification → popup.css +================================================ */ + /* ========================= Base ========================= */ @@ -27,195 +33,6 @@ body { box-shadow: 0 0 6px #3cff3c; } -/* ========================= - Popup Fenster -========================= */ - -.building-popup { - position: fixed; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - - width: 900px; - max-width: 90vw; - max-height: 1000px; - - background: url("/images/parchment.png") center / cover no-repeat; - - border: 4px solid #6b4b2a; - border-radius: 10px; - - box-shadow: - 0 0 40px rgba(0, 0, 0, 0.9), - inset 0 0 25px rgba(0, 0, 0, 0.5); - - display: none; - flex-direction: column; - z-index: 1000; - - animation: popupFade 0.25s ease; -} - -.building-popup.active { - display: flex; -} - -/* ========================= - Popup Header -========================= */ - -.popup-header { - padding: 14px; - font-family: "Tangerine", serif; - font-size: 36px; - - background: linear-gradient(#6b4b2a, #3c2414); - - border-bottom: 2px solid #8b6a3c; - - display: flex; - justify-content: space-between; - - color: #f0d9a6; - text-shadow: 0 2px 4px black; -} - -.popup-header span { - cursor: pointer; -} - -/* ========================= - Tabs -========================= */ - -.popup-tabs { - display: flex; - border-bottom: 2px solid #8b6a3c; -} - -.popup-tabs button { - flex: 1; - padding: 10px; - - font-family: "Cinzel", serif; - font-weight: bold; - - background: linear-gradient(#5c3b20, #3a2513); - - border: 1px solid #8b6a3c; - color: #e7d9b4; - - cursor: pointer; - transition: 0.2s; -} - -.popup-tabs button:hover { - background: linear-gradient(#8b6a3c, #5c3b20); -} - -.popup-tabs button.active { - background: linear-gradient(#d4b97a, #9c7a3a); - color: #2b1b0f; -} - -/* ========================= - Popup Inhalt -========================= */ - -.popup-content { - padding: 16px 60px 16px 60px; - - font-size: 15px; - line-height: 1.6; - letter-spacing: 0.5px; - - background: rgba(255, 255, 255, 0.08); - border-radius: 6px; - - color: #2b1b0f; - - overflow-y: auto; - flex: 1; -} - -.popup-content h3 { - font-family: "Tangerine", serif; - font-size: 32px; - color: #3b2412; - margin-top: 0; -} - -.popup-content p { - color: #3a2413; -} - -/* ========================= - Tab Inhalte -========================= */ - -.tab-content { - display: none; -} - -.tab-content.active { - display: block; -} - -/* ========================= - Buttons -========================= */ - -.popup-content button { - margin-top: 10px; - - background: linear-gradient(#7a5a2a, #caa24b); - - border: 1px solid #e0c67b; - padding: 10px 18px; - - color: #1a1206; - font-weight: bold; - - cursor: pointer; - transition: 0.2s; -} - -.popup-content button:hover { - transform: scale(1.05); - box-shadow: - 0 0 10px #ffd66b, - 0 0 25px #caa24b; -} - -/* ========================= - Tooltip -========================= */ - -#map-tooltip { - position: fixed; - pointer-events: none; - - background: rgba(0, 0, 0, 0.85); - color: #fff; - - padding: 8px 12px; - border-radius: 6px; - - font-size: 14px; - - display: none; - z-index: 9999; - - max-width: 200px; - - box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); -} - -#map-tooltip strong { - color: #ffd700; -} - /* ========================= Character Window ========================= */ @@ -601,127 +418,6 @@ body { box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); } -/* ========================= - Game Notification -========================= */ - -#game-notification { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%) scale(0.85); - - z-index: 9999; - - width: 360px; - max-width: 90vw; - - background: url("/images/parchment.png") center / cover no-repeat; - - border: 3px solid #6b4b2a; - border-radius: 10px; - - box-shadow: - 0 0 40px rgba(0, 0, 0, 0.9), - inset 0 0 20px rgba(0, 0, 0, 0.4); - - display: none; - opacity: 0; - - transition: - opacity 0.2s ease, - transform 0.2s ease; -} - -#game-notification.show { - display: block; - opacity: 1; - transform: translate(-50%, -50%) scale(1); -} - -.notification-header { - padding: 12px 16px; - - background: linear-gradient(#6b4b2a, #3c2414); - border-bottom: 2px solid #8b6a3c; - border-radius: 7px 7px 0 0; - - font-family: "Tangerine", serif; - font-size: 28px; - color: #f0d9a6; - text-shadow: 0 2px 4px black; - - display: flex; - align-items: center; - gap: 8px; -} - -.notification-body { - padding: 20px 20px 10px 20px; - - font-family: "Cinzel", serif; - font-size: 15px; - color: #2b1b0f; - line-height: 1.8; - text-align: center; - white-space: pre-line; -} - -.notification-footer { - padding: 10px 20px 16px 20px; - display: flex; - justify-content: center; -} - -.notification-btn { - padding: 8px 28px !important; - font-size: 14px !important; - font-family: "Cinzel", serif !important; - font-weight: bold !important; - background: linear-gradient(#7a5a2a, #caa24b) !important; - border: 1px solid #e0c67b !important; - border-radius: 4px; - color: #1a1206 !important; - cursor: pointer; - transition: 0.2s; - margin-top: 0 !important; -} - -.notification-btn:hover { - transform: scale(1.05); - box-shadow: - 0 0 10px #ffd66b, - 0 0 20px #caa24b; -} - -#game-notification-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 9998; - display: none; -} - -#game-notification-overlay.show { - display: block; -} - -/* ========================= - Animation -========================= */ - -@keyframes popupFade { - from { - opacity: 0; - transform: translate(-50%, -40%); - } - - to { - opacity: 1; - transform: translate(-50%, -50%); - } -} - /* ========================= Schwarzmarkt Tabs ========================= */ diff --git a/public/css/hud.css b/public/css/hud.css index 2ca23dd..ce37e12 100644 --- a/public/css/hud.css +++ b/public/css/hud.css @@ -206,108 +206,24 @@ } .hud-res-icon { - font-size: 0; /* Emoji unsichtbar */ + font-size: 0; /* Emoji unsichtbar */ color: transparent; display: inline-block; width: 20px; height: 20px; flex-shrink: 0; - background: url("/images/items/blauer%20cristal.png") center / contain no-repeat; + background: url("/images/items/blauer%20cristal.png") center / contain + no-repeat; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); vertical-align: middle; } -/* Blauer Kristall / Gems – Bild aus der Datenbank */ -.hud-res-icon-gem { - width: 28px; - height: 28px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.hud-res-icon-gem img { - width: 28px; - height: 28px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Silbermünze – Bild aus der Datenbank */ -.hud-res-icon-silver { - width: 28px; - height: 28px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.hud-res-icon-silver img { - width: 28px; - height: 28px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Holz – Bild aus der Datenbank */ -.hud-res-icon-wood { - width: 28px; - height: 28px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.hud-res-icon-wood img { - width: 28px; - height: 28px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Stein – Bild aus der Datenbank */ -.hud-res-icon-stone { - width: 28px; - height: 28px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.hud-res-icon-stone img { - width: 28px; - height: 28px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Goldmünze – Bild aus der Datenbank */ -.hud-res-icon-gold { - width: 28px; - height: 28px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.hud-res-icon-gold img { - width: 28px; - height: 28px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Eisen – Bild aus der Datenbank */ +/* Ressource Icons (gem, silver, wood, stone, gold, iron) – einheitliche Größe */ +.hud-res-icon-gem, +.hud-res-icon-silver, +.hud-res-icon-wood, +.hud-res-icon-stone, +.hud-res-icon-gold, .hud-res-icon-iron { width: 28px; height: 28px; @@ -317,6 +233,11 @@ justify-content: center; } +.hud-res-icon-gem img, +.hud-res-icon-silver img, +.hud-res-icon-wood img, +.hud-res-icon-stone img, +.hud-res-icon-gold img, .hud-res-icon-iron img { width: 28px; height: 28px; @@ -376,6 +297,6 @@ height: 18px; object-fit: contain; vertical-align: middle; - filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6)); + filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6)); display: inline-block; } diff --git a/public/css/launcher-dev.css b/public/css/launcher-dev.css new file mode 100644 index 0000000..c806312 --- /dev/null +++ b/public/css/launcher-dev.css @@ -0,0 +1,31 @@ +/* ================================================ + launcher-dev.css – Map Developer Tool + Dynasty of Knights +================================================ */ + +body { + margin: 0; + background: #000; + display: flex; + justify-content: center; +} + +.wrapper { + position: relative; +} + +img { + display: block; +} + +svg { + position: absolute; + top: 0; + left: 0; +} + +polygon { + fill: rgba(255, 0, 0, 0.35); + stroke: red; + stroke-width: 2; +} diff --git a/public/css/launcher.css b/public/css/launcher.css index bc0379c..deb5405 100644 --- a/public/css/launcher.css +++ b/public/css/launcher.css @@ -171,3 +171,54 @@ margin-right: 6px; box-shadow: 0 0 6px #3cff3c; } + +/* ── Music Control ─────────────────────────────── */ +#music-control { + position: fixed; + bottom: 16px; + right: 16px; + z-index: 9999; + display: flex; + align-items: center; + gap: 8px; + background: rgba(10, 5, 0, 0.85); + border: 1px solid #c8960c; + border-radius: 8px; + padding: 6px 10px; + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.6); +} + +#music-mute-btn { + background: none; + border: none; + cursor: pointer; + font-size: 20px; + line-height: 1; + padding: 0; + color: #f0d080; + transition: transform 0.15s; +} + +#music-mute-btn:hover { + transform: scale(1.2); +} + +#music-volume { + -webkit-appearance: none; + appearance: none; + width: 80px; + height: 4px; + background: #3a2000; + border-radius: 2px; + outline: none; + cursor: pointer; +} + +#music-volume::-webkit-slider-thumb { + -webkit-appearance: none; + width: 12px; + height: 12px; + border-radius: 50%; + background: #c8960c; + cursor: pointer; +} diff --git a/public/css/login.css b/public/css/login.css new file mode 100644 index 0000000..16a68ad --- /dev/null +++ b/public/css/login.css @@ -0,0 +1,165 @@ +/* ================================================ + login.css – Login-Seite & Register-Seite + Dynasty of Knights +================================================ */ + +/* ── Base ──────────────────────────────────────── */ +* { + box-sizing: border-box; + font-family: "Tangerine", serif; +} + +body { + margin: 0; + min-height: 100vh; + background: url("/images/background_login.png") center / cover no-repeat fixed; + display: flex; + justify-content: center; + align-items: center; +} + +/* ── Nebel ─────────────────────────────────────── */ +.fog { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 40%; + z-index: 0; + pointer-events: none; +} + +@keyframes fogmove { + 0% { transform: translateX(0); } + 100% { transform: translateX(-50%); } +} + +/* ── Login Panel ───────────────────────────────── */ +.launcher { + width: 380px; + padding: 30px; + position: relative; + z-index: 2; + font-family: "Tangerine", serif; + font-size: 16px; + background: rgba(10, 15, 20, 0.75); + backdrop-filter: blur(10px); + border-radius: 10px; + border: 1px solid rgba(100, 170, 255, 0.4); + box-shadow: + 0 0 40px rgba(0, 0, 0, 0.8), + 0 0 20px rgba(70, 120, 255, 0.5); +} + +/* ── Register Box ──────────────────────────────── */ +.register-box { + width: 380px; + padding: 30px; + background: rgba(10, 15, 20, 0.8); + border-radius: 10px; + border: 1px solid rgba(100, 170, 255, 0.4); + box-shadow: + 0 0 40px rgba(0, 0, 0, 0.8), + 0 0 20px rgba(70, 120, 255, 0.5); +} + +/* ── Charakter Box ─────────────────────────────── */ +.box { + background: rgba(0, 0, 0, 0.7); + padding: 40px; + border-radius: 10px; + text-align: center; + width: 400px; +} + +/* ── Inputs / Selects / Buttons ────────────────── */ +input, +select, +button, +.register, +.server-status { + width: 100%; + padding: 13px; + font-size: 24px; + margin-bottom: 15px; + font-family: "Tangerine", serif; + background: rgba(255, 255, 255, 0.08); + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 6px; + color: white; +} + +/* ── Login Button ──────────────────────────────── */ +.login { + width: 100%; + padding: 14px; + font-size: 32px; + background: linear-gradient(45deg, #3da2ff, #7dd3ff); + border: none; + border-radius: 6px; + font-weight: bold; + cursor: pointer; + transition: 0.25s; +} + +.login:hover { + transform: scale(1.05); + box-shadow: + 0 0 20px #4aa3ff, + 0 0 40px #4aa3ff; +} + +/* ── Register Link ─────────────────────────────── */ +.register { + display: block; + text-align: center; + margin-top: 10px; + color: #ccc; + text-decoration: none; +} + +.register:hover { + color: white; +} + +/* ── Zurück Link ───────────────────────────────── */ +.back { + display: block; + text-align: center; + color: #ccc; + margin-top: 10px; + text-decoration: none; +} + +.back:hover { + color: white; +} + +/* ── Server Status Box ─────────────────────────── */ +.server-status { + margin-top: 18px; + font-size: 24px; + padding: 10px; + background: rgba(0, 0, 0, 0.45); + border-radius: 6px; +} + +.online { color: #3cff5a; } +.offline { color: #ff4b4b; } + +/* ── Fehler-Meldung ────────────────────────────── */ +.error { + color: red; + margin-bottom: 15px; +} + +/* ── Charakter-Seite: Input/Button ─────────────── */ +.box input, +.box button { + width: 100%; + padding: 14px; + margin-top: 10px; + border-radius: 6px; + border: none; + box-sizing: border-box; +} diff --git a/public/css/mine.css b/public/css/mine.css index b8ab3b8..785314d 100644 --- a/public/css/mine.css +++ b/public/css/mine.css @@ -68,7 +68,9 @@ border: 1px solid rgba(122, 90, 26, 0.3); border-radius: 6px; padding: 7px 12px; - transition: border-color 0.2s, background 0.2s; + transition: + border-color 0.2s, + background 0.2s; } .mine-resource-row.mine-resource-ready { @@ -85,97 +87,12 @@ justify-content: center; } -/* Blauer Kristall / Gems – Bild aus der Datenbank */ -.mine-resource-icon-gem { - width: 100px; - height: 100px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.mine-resource-icon-gem img { - width: 100px; - height: 100px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Silbermünze – Bild aus der Datenbank */ -.mine-resource-icon-silver { - width: 100px; - height: 100px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.mine-resource-icon-silver img { - width: 100px; - height: 100px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Holz – Bild aus der Datenbank */ -.mine-resource-icon-wood { - width: 100px; - height: 100px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.mine-resource-icon-wood img { - width: 100px; - height: 100px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Stein – Bild aus der Datenbank */ -.mine-resource-icon-stone { - width: 100px; - height: 100px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.mine-resource-icon-stone img { - width: 100px; - height: 100px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Goldmünze – Bild aus der Datenbank */ -.mine-resource-icon-gold { - width: 100px; - height: 100px; - flex-shrink: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.mine-resource-icon-gold img { - width: 100px; - height: 100px; - object-fit: contain; - filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7)); - display: block; -} - -/* Eisen – Bild aus der Datenbank */ +/* Ressource Icons (gem, silver, wood, stone, gold, iron) – einheitliche Größe */ +.mine-resource-icon-gem, +.mine-resource-icon-silver, +.mine-resource-icon-wood, +.mine-resource-icon-stone, +.mine-resource-icon-gold, .mine-resource-icon-iron { width: 100px; height: 100px; @@ -185,6 +102,11 @@ justify-content: center; } +.mine-resource-icon-gem img, +.mine-resource-icon-silver img, +.mine-resource-icon-wood img, +.mine-resource-icon-stone img, +.mine-resource-icon-gold img, .mine-resource-icon-iron img { width: 100px; height: 100px; @@ -253,7 +175,9 @@ font-weight: bold; cursor: pointer; letter-spacing: 0.04em; - transition: filter 0.15s, transform 0.1s; + transition: + filter 0.15s, + transform 0.1s; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); width: 100%; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5); @@ -291,8 +215,13 @@ } @keyframes minePulse { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.45; } + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.45; + } } .mine-error { diff --git a/public/js/buildings/schwarzmarkt.js b/public/js/buildings/blackmarket.js similarity index 97% rename from public/js/buildings/schwarzmarkt.js rename to public/js/buildings/blackmarket.js index b846a48..e628a51 100644 --- a/public/js/buildings/schwarzmarkt.js +++ b/public/js/buildings/blackmarket.js @@ -1,6 +1,6 @@ -import { showNotification } from "../notification.js"; +import { showNotification } from "../notification.js"; -export async function loadSchwarzmarkt() { +export async function loadBlackmarket() { const ui = document.querySelector(".building-ui"); ui.innerHTML = ` diff --git a/public/js/buildings/wohnhaus.js b/public/js/buildings/character-house.js similarity index 99% rename from public/js/buildings/wohnhaus.js rename to public/js/buildings/character-house.js index f99d9d6..52ca111 100644 --- a/public/js/buildings/wohnhaus.js +++ b/public/js/buildings/character-house.js @@ -3,7 +3,7 @@ const slotsPerPage = 32; let inventoryItems = []; let totalInventoryPages = 1; -export async function loadWohnhaus() { +export async function loadCharacterHouse() { const ui = document.querySelector(".building-ui"); ui.innerHTML = ` diff --git a/public/js/map-ui.js b/public/js/map-ui.js index c2a9502..16cc4ce 100644 --- a/public/js/map-ui.js +++ b/public/js/map-ui.js @@ -1,5 +1,5 @@ -import { loadWohnhaus } from "./buildings/wohnhaus.js"; -import { loadSchwarzmarkt } from "./buildings/schwarzmarkt.js"; +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"); @@ -8,8 +8,8 @@ const tooltip = document.getElementById("map-tooltip"); const tooltipCache = {}; const buildingModules = { - 11: loadWohnhaus, // Tabs ausblenden, eigenes UI - 12: loadSchwarzmarkt, // Tabs ausblenden, eigenes UI + 11: loadCharacterHouse, // Tabs ausblenden, eigenes UI + 12: loadBlackmarket, // Tabs ausblenden, eigenes UI 10: loadMine, // Tabs bleiben sichtbar, nur Aktionen-Tab befüllen }; @@ -70,7 +70,7 @@ document.querySelectorAll(".building").forEach((building) => {
${data.description}
+${data.description}