From 4d114385b3de423128d2b0b2ba8f9d90fdc88ba3 Mon Sep 17 00:00:00 2001 From: cay Date: Tue, 14 Apr 2026 10:46:01 +0100 Subject: [PATCH] xhfmjf --- public/css/daily.css | 16 +++++----- public/js/buildings/1v1.js | 23 +++++++------- public/js/buildings/daily.js | 48 +++++++++++++---------------- sockets/1vKI_daily.socket.js | 58 +++++++++++++++++++++++++++--------- 4 files changed, 83 insertions(+), 62 deletions(-) diff --git a/public/css/daily.css b/public/css/daily.css index 1d8440c..0a4043b 100644 --- a/public/css/daily.css +++ b/public/css/daily.css @@ -67,9 +67,8 @@ /* Locked: dunkle Abdunklung über dem Bildkreis */ .ds-locked .ds-overlay { - fill: rgba(0,0,5,.62); - stroke: rgba(50,60,100,.45); - stroke-width: .8; + fill: rgba(0,0,5,.35); + stroke: none; } .ds-locked .ds-num { fill: rgba(120,130,160,.38); @@ -79,9 +78,8 @@ /* Available: transparente Mitte, leuchtender Rand */ .ds-available .ds-overlay { - fill: rgba(40,100,255,.08); - stroke: rgba(100,200,255,.9); - stroke-width: 1.2; + fill: transparent; + stroke: none; } .ds-available .ds-num { fill: #fff; @@ -112,9 +110,9 @@ /* Done: grüne Einfärbung */ .ds-done .ds-overlay { - fill: rgba(30,160,70,.35); - stroke: rgba(80,220,110,.85); - stroke-width: 1.2; + fill: rgba(30,160,70,.55); + stroke: rgba(80,220,110,.7); + stroke-width: .8; } .ds-done .ds-check { fill: #fff; diff --git a/public/js/buildings/1v1.js b/public/js/buildings/1v1.js index 371d1f9..4355902 100644 --- a/public/js/buildings/1v1.js +++ b/public/js/buildings/1v1.js @@ -843,18 +843,6 @@ function updateHpDisplay(slot, currentHp, maxHp) { orbEl.style.boxShadow = `0 0 12px ${color}cc`; } - /* Avatar-Schüttelanimation + roter Flash */ - if (avEl) { - avEl.style.transition = 'transform 0.07s ease'; - avEl.style.transform = 'scale(1.07)'; - setTimeout(() => { avEl.style.transform = 'scale(0.96)'; }, 70); - setTimeout(() => { avEl.style.transform = ''; }, 150); - - const flash = document.createElement('div'); - flash.style.cssText = 'position:absolute;inset:0;border-radius:inherit;background:rgba(220,50,50,0.4);z-index:20;pointer-events:none;'; - avEl.appendChild(flash); - setTimeout(() => flash.remove(), 320); - } } function applyHpFromEvent(data) { @@ -891,6 +879,17 @@ socket.on('avatar_damaged', data => { animation:dmg-float 2.5s ease forwards;`; avEl.appendChild(dmg); setTimeout(() => dmg.remove(), 2500); + + /* Schüttelanimation + roter Flash NUR bei Treffer */ + avEl.style.transition = 'transform 0.07s ease'; + avEl.style.transform = 'scale(1.07)'; + setTimeout(() => { avEl.style.transform = 'scale(0.96)'; }, 70); + setTimeout(() => { avEl.style.transform = ''; }, 150); + + const flash = document.createElement('div'); + flash.style.cssText = 'position:absolute;inset:0;border-radius:inherit;background:rgba(220,50,50,0.4);z-index:20;pointer-events:none;'; + avEl.appendChild(flash); + setTimeout(() => flash.remove(), 320); } }); diff --git a/public/js/buildings/daily.js b/public/js/buildings/daily.js index d7d6006..f72c0bb 100644 --- a/public/js/buildings/daily.js +++ b/public/js/buildings/daily.js @@ -3,13 +3,13 @@ /* ── Positionen (% in viewBox 0 0 100 100) ───────────────── */ const STATIONS = [ - { id:1, cx:49.5, cy:86.5 }, - { id:2, cx:37.0, cy:73.0 }, - { id:3, cx:44.5, cy:62.0 }, - { id:4, cx:54.5, cy:53.5 }, - { id:5, cx:49.0, cy:46.0 }, - { id:6, cx:44.5, cy:37.5 }, - { id:7, cx:50.0, cy:22.0 }, + { id:1, cx:48.5, cy:87.0 }, + { id:2, cx:36.5, cy:73.5 }, + { id:3, cx:44.0, cy:63.0 }, + { id:4, cx:53.5, cy:54.5 }, + { id:5, cx:47.5, cy:46.5 }, + { id:6, cx:43.5, cy:38.5 }, + { id:7, cx:49.5, cy:23.0 }, ]; const R = 4.8; // Kreis-Radius in SVG-Einheiten @@ -90,40 +90,34 @@ function buildSvg(completed) { `); } else if (isAvail) { + // Available: nur pulsierende Ringe über dem Bild-Kreis, kein eigener Kreis parts.push(` - - + + values="${R+1.2};${R+2.8};${R+1.2}" dur="2s" repeatCount="indefinite"/> + values=".8;0;.8" dur="2s" repeatCount="indefinite"/> - - + + values="${R+2};${R+4};${R+2}" dur="2s" begin=".7s" repeatCount="indefinite"/> + values=".5;0;.5" dur="2s" begin=".7s" repeatCount="indefinite"/> - - - - ${s.id} - + + fill="transparent" stroke="none" data-station="${s.id}"/> `); } else { + // Locked: unsichtbare Hitfläche, kein eigener Kreis (Bild-Kreis bleibt sichtbar) parts.push(` - - ${s.id} + + `); } }); diff --git a/sockets/1vKI_daily.socket.js b/sockets/1vKI_daily.socket.js index 0d6ec6d..a1291ac 100644 --- a/sockets/1vKI_daily.socket.js +++ b/sockets/1vKI_daily.socket.js @@ -76,21 +76,41 @@ async function loadAiDeck(station, playerLevel) { [maxRarity, deckSize] ); - if (cards.length > 0) { - console.log(`[HT] KI-Deck Station ${station}: ${cards.length} Karten, max. Rarity ${maxRarity}`); - return cards.map(c => ({ ...c, currentCd: 0 })); + // Wenn nicht genug Karten → Rarity schrittweise erhöhen + let result = [...cards]; + + if (result.length < deckSize) { + for (let r = maxRarity + 1; r <= 6 && result.length < deckSize; r++) { + const [more] = await db.query( + `SELECT id, name, image, attack, defends, cooldown, \`range\`, \`race\`, rarity + FROM cards WHERE rarity = ? ORDER BY RAND() LIMIT ?`, + [r, deckSize - result.length] + ); + result = [...result, ...more]; + } } - // Fallback: beliebige Karten wenn keine mit passender Rarity gefunden - console.warn(`[HT] Keine Karten mit Rarity <= ${maxRarity} – Fallback auf alle Karten`); - const [all] = await db.query( - `SELECT id, name, image, attack, defends, cooldown, \`range\`, \`race\`, rarity - FROM cards - ORDER BY RAND() - LIMIT ?`, - [deckSize] - ); - return all.map(c => ({ ...c, currentCd: 0 })); + // Letzter Fallback: alle Karten ohne Rarity-Filter + if (result.length === 0) { + const [all] = await db.query( + `SELECT id, name, image, attack, defends, cooldown, \`range\`, \`race\`, rarity + FROM cards ORDER BY RAND() LIMIT ?`, + [deckSize] + ); + result = all; + } + + // Noch immer zu wenig? → vorhandene Karten so oft wiederholen bis deckSize erreicht + if (result.length > 0 && result.length < deckSize) { + const base = [...result]; + while (result.length < deckSize) { + result.push({ ...base[result.length % base.length] }); + } + console.log(`[HT] KI-Deck aufgefüllt durch Wiederholung: ${base.length} unique → ${result.length} Karten`); + } + + console.log(`[HT] KI-Deck Station ${station}: ${result.length} Karten, max. Rarity ${maxRarity}`); + return result.map(c => ({ ...c, currentCd: 0 })); } catch (err) { console.error('[HT] loadAiDeck Fehler:', err); @@ -437,8 +457,18 @@ function registerHimmelstorHandlers(io, socket) { const aiRoom = htAiRooms.get(matchId); if (!aiRoom) return; - // Socket + Namen aktualisieren + // Socket + Namen + AccountId aktualisieren aiRoom.playerSocketId = socket.id; + // accountId aus arena_join data setzen falls noch nicht gesetzt (Session-Fallback) + if (!aiRoom.playerAccountId && data.accountId) { + aiRoom.playerAccountId = data.accountId; + } + // Auch io._arenaRooms synchronisieren + const ioRoom2 = io._arenaRooms?.get(matchId); + if (ioRoom2 && !ioRoom2.accountIds?.player1 && data.accountId) { + if (!ioRoom2.accountIds) ioRoom2.accountIds = {}; + ioRoom2.accountIds.player1 = data.accountId; + } const myIngameName = data.playerName || 'Du'; const ioRoom = io._arenaRooms?.get(matchId); if (ioRoom) ioRoom.sockets.player1 = socket.id;