diff --git a/sockets/arena.socket.js b/sockets/arena.socket.js index f7750c9..a09fdc0 100644 --- a/sockets/arena.socket.js +++ b/sockets/arena.socket.js @@ -430,62 +430,60 @@ function emitToOpponent(io, matchId, senderSlot, event, data) { AVATAR-HP HELPERS ═══════════════════════════════════════════════════════════ */ -/** HP für beide Spieler beim Spielstart initialisieren */ +/** HP für beide Spieler beim Spielstart initialisieren. + * Lookup aus arena_avatar_levels, Fallback auf Formel. + * HP-Tracking läuft rein im Speicher (room.hp / room.maxHp). */ async function initMatchHP(io, matchId, room) { - try { - for (const slot of ['player1', 'player2']) { - const accountId = room.accountIds[slot]; - if (!accountId) continue; + for (const slot of ['player1', 'player2']) { + const accountId = room.accountIds[slot]; + let maxHp = 20; // Fallback + try { const [[acc]] = await db.query( "SELECT level FROM accounts WHERE id = ?", - [accountId] + [accountId || 0] ); - const level = acc?.level ?? 1; - const maxHp = calcAvatarHp(level); + const level = acc?.level ?? 1; - room.hp[slot] = maxHp; - room.maxHp[slot] = maxHp; - - await db.query( - `INSERT INTO arena_match_hp (match_id, slot, account_id, current_hp, max_hp) - VALUES (?, ?, ?, ?, ?) - ON DUPLICATE KEY UPDATE current_hp = ?, max_hp = ?`, - [matchId, slot, accountId, maxHp, maxHp, maxHp, maxHp] + // Aus Lookup-Tabelle lesen, Formel als Fallback + const [[row]] = await db.query( + "SELECT max_hp FROM arena_avatar_levels WHERE level = ?", + [level] ); + maxHp = row?.max_hp ?? calcAvatarHp(level); + } catch (err) { + console.error(`[HP] Level-Lookup Fehler (${slot}):`, err); + // Formel-Fallback – Spiel läuft trotzdem weiter } - // Initiale HP an beide Clients senden - emitToMatch(io, matchId, 'hp_init', { hp: room.hp, maxHp: room.maxHp }); - console.log(`[HP] Init Match ${matchId}: P1=${room.hp.player1}/${room.maxHp.player1}, P2=${room.hp.player2}/${room.maxHp.player2}`); - } catch (err) { - console.error('[HP] initMatchHP Fehler:', err); + room.hp[slot] = maxHp; + room.maxHp[slot] = maxHp; } + + // Initiale HP an beide Clients senden + emitToMatch(io, matchId, 'hp_init', { hp: room.hp, maxHp: room.maxHp }); + console.log(`[HP] Init ${matchId}: P1=${room.hp.player1}/${room.maxHp.player1}, P2=${room.hp.player2}/${room.maxHp.player2}`); } -/** Avatar-Treffer aus Combat-Events verarbeiten, Match bei Tod beenden */ +/** Avatar-Treffer aus Combat-Events verarbeiten, Match bei Tod beenden. + * HP wird nur im Speicher (room.hp) verwaltet – kein DB-Schreiben. */ async function processAvatarAttacks(io, matchId, room, events) { const avatarEvents = events.filter(e => e.type === 'avatar_attack'); if (avatarEvents.length === 0) return false; for (const ev of avatarEvents) { const target = ev.target; // 'player1' | 'player2' - if (room.hp[target] == null) continue; - room.hp[target] = Math.max(0, (room.hp[target] ?? 0) - ev.damage); - - // In DB persistieren - try { - await db.query( - `UPDATE arena_match_hp SET current_hp = ? - WHERE match_id = ? AND slot = ?`, - [room.hp[target], matchId, target] - ); - } catch (err) { - console.error('[HP] DB Update Fehler:', err); + // Sicherheits-Fallback: HP noch nicht initialisiert + if (room.hp[target] == null) { + console.warn(`[HP] room.hp[${target}] nicht gesetzt – überspringe`); + continue; } - // Treffer an beide Clients senden + // Schaden abziehen (niemals unter 0) + room.hp[target] = Math.max(0, room.hp[target] - (ev.damage ?? 0)); + + // Treffer an beide Clients melden emitToMatch(io, matchId, 'avatar_damaged', { slot : target, damage : ev.damage, @@ -493,12 +491,12 @@ async function processAvatarAttacks(io, matchId, room, events) { maxHp : room.maxHp[target] ?? 20, }); - console.log(`[HP] ${target} trifft ${ev.damage} Schaden → verbleibend: ${room.hp[target]}`); + console.log(`[HP] ${target} -${ev.damage} → ${room.hp[target]}/${room.maxHp[target]}`); - // Match-Ende prüfen + // Match-Ende wenn HP auf 0 if (room.hp[target] <= 0) { await handleMatchEnd(io, matchId, room, target); - return true; // Match beendet + return true; } } return false; @@ -556,10 +554,7 @@ async function handleMatchEnd(io, matchId, room, loserSlot) { }); } - // HP-Eintrag bereinigen - try { - await db.query("DELETE FROM arena_match_hp WHERE match_id = ?", [matchId]); - } catch {} + // HP läuft nur im Speicher – kein DB-Cleanup nötig } /* ═══════════════════════════════════════════════════════════