This commit is contained in:
cay 2026-04-14 10:32:01 +01:00
parent a17a6c1414
commit 61043ebdd4
3 changed files with 32 additions and 19 deletions

View File

@ -872,24 +872,25 @@ socket.on('hp_init', data => {
/* Avatar getroffen */ /* Avatar getroffen */
socket.on('avatar_damaged', data => { socket.on('avatar_damaged', data => {
const { slot, damage, remainingHp, maxHp } = data; const { slot, damage, remainingHp, maxHp, row } = data;
updateHpDisplay(slot, remainingHp, maxHp); updateHpDisplay(slot, remainingHp, maxHp);
console.log(`[HP] ${slot} -${damage}${remainingHp}/${maxHp}`); console.log(`[HP] ${slot} (${row}) -${damage}${remainingHp}/${maxHp}`);
/* Schadens-Zahl einblenden */ /* Schadens-Zahl einblenden Reihe 1 oben, Reihe 2 etwas tiefer */
const isLeft = slot === (window._leftSlot || 'player1'); const isLeft = slot === (window._leftSlot || 'player1');
const avEl = document.getElementById(isLeft ? 'avLeft' : 'avRight'); const avEl = document.getElementById(isLeft ? 'avLeft' : 'avRight');
const topPct = row === 'row2' ? '38%' : '14%';
if (avEl) { if (avEl) {
const dmg = document.createElement('div'); const dmg = document.createElement('div');
dmg.textContent = `-${damage}`; dmg.textContent = `-${damage}`;
dmg.style.cssText = ` dmg.style.cssText = `
position:absolute;top:15%;left:50%;transform:translateX(-50%); position:absolute;top:${topPct};left:50%;transform:translateX(-50%);
font-family:'Cinzel',serif;font-size:calc(var(--s)*24);font-weight:700; font-family:'Cinzel',serif;font-size:calc(var(--s)*24);font-weight:700;
color:#e74c3c;text-shadow:0 2px 10px rgba(0,0,0,0.95); color:#e74c3c;text-shadow:0 2px 10px rgba(0,0,0,0.95);
pointer-events:none;z-index:30; pointer-events:none;z-index:30;
animation:dmg-float 1s ease forwards;`; animation:dmg-float 2.5s ease forwards;`;
avEl.appendChild(dmg); avEl.appendChild(dmg);
setTimeout(() => dmg.remove(), 1000); setTimeout(() => dmg.remove(), 2500);
} }
}); });
@ -946,8 +947,11 @@ socket.on('ht_ai_setup', data => {
*/ */
function closeToArena() { function closeToArena() {
if (window.parent && window.parent !== window) { if (window.parent && window.parent !== window) {
window.parent.document.getElementById('arena-backdrop')?.remove(); const pd = window.parent.document;
window.parent.document.getElementById('arena-popup')?.remove(); /* Alle möglichen Popup-Varianten entfernen */
['arena-backdrop', 'arena-popup',
'ht-daily-backdrop', 'ht-daily-popup',
'ht-backdrop', 'ht-popup'].forEach(id => pd.getElementById(id)?.remove());
} else { } else {
window.location.href = '/launcher'; window.location.href = '/launcher';
} }
@ -1066,8 +1070,17 @@ function updateResultWithPoints(data) {
} }
}).catch(() => {}); }).catch(() => {});
/* Nach 3 Sekunden zur Arena weiterleiten */ /* Nach 5 Sekunden: Overlay ausblenden und zur Arena weiterleiten */
setTimeout(() => closeToArena(), 3000); setTimeout(() => {
const el = document.getElementById('match-end-overlay');
if (el) {
el.style.transition = 'opacity 0.6s ease';
el.style.opacity = '0';
setTimeout(() => { el.remove(); closeToArena(); }, 650);
} else {
closeToArena();
}
}, 5000);
} }
function closePopup() { closeToArena(); } function closePopup() { closeToArena(); }

View File

@ -543,29 +543,30 @@ async function processAvatarAttacks(io, matchId, room, events) {
const avatarEvents = events.filter(e => e.type === 'avatar_attack'); const avatarEvents = events.filter(e => e.type === 'avatar_attack');
if (avatarEvents.length === 0) return false; if (avatarEvents.length === 0) return false;
for (const ev of avatarEvents) { for (let i = 0; i < avatarEvents.length; i++) {
const target = ev.target; // 'player1' | 'player2' // Mehrere Avatar-Treffer im gleichen Zug: 500ms Abstand
if (i > 0) await new Promise(r => setTimeout(r, 500));
const ev = avatarEvents[i];
const target = ev.target;
// Sicherheits-Fallback: HP noch nicht initialisiert
if (room.hp[target] == null) { if (room.hp[target] == null) {
console.warn(`[HP] room.hp[${target}] nicht gesetzt überspringe`); console.warn(`[HP] room.hp[${target}] nicht gesetzt überspringe`);
continue; continue;
} }
// Schaden abziehen (niemals unter 0)
room.hp[target] = Math.max(0, room.hp[target] - (ev.damage ?? 0)); room.hp[target] = Math.max(0, room.hp[target] - (ev.damage ?? 0));
// Treffer an beide Clients melden
emitToMatch(io, matchId, 'avatar_damaged', { emitToMatch(io, matchId, 'avatar_damaged', {
slot : target, slot : target,
damage : ev.damage, damage : ev.damage,
remainingHp: room.hp[target], remainingHp: room.hp[target],
maxHp : room.maxHp[target] ?? 20, maxHp : room.maxHp[target] ?? 20,
row : ev.from?.split('-slot-')[0] ?? 'row1', // Reihe für Versatz
}); });
console.log(`[HP] ${target} -${ev.damage}${room.hp[target]}/${room.maxHp[target]}`); console.log(`[HP] ${target} (${ev.from}) -${ev.damage}${room.hp[target]}/${room.maxHp[target]}`);
// Match-Ende wenn HP auf 0
if (room.hp[target] <= 0) { if (room.hp[target] <= 0) {
await handleMatchEnd(io, matchId, room, target); await handleMatchEnd(io, matchId, room, target);
return true; return true;

View File

@ -56,7 +56,7 @@ function runCombatPhase(boardState, leftSlot, activeSlot) {
for (let r = 1; r <= range; r++) { for (let r = 1; r <= range; r++) {
const targetPos = currentPos + dir * r; const targetPos = currentPos + dir * r;
/* Avatar-Angriff: Range geht über das Spielfeld hinaus */ /* Avatar-Angriff: Range geht über das Spielfeld */
if (targetPos < 1 || targetPos > 11) { if (targetPos < 1 || targetPos > 11) {
events.push({ type: 'avatar_attack', from: currentSlotId, target: opponentSlot, damage: atk }); events.push({ type: 'avatar_attack', from: currentSlotId, target: opponentSlot, damage: atk });
break; break;
@ -70,7 +70,6 @@ function runCombatPhase(boardState, leftSlot, activeSlot) {
target.card = { ...target.card, defends: (target.card.defends ?? 0) - atk }; target.card = { ...target.card, defends: (target.card.defends ?? 0) - atk };
events.push({ type: 'attack', from: currentSlotId, to: targetSlotId, damage: atk, remainingDef: target.card.defends }); events.push({ type: 'attack', from: currentSlotId, to: targetSlotId, damage: atk, remainingDef: target.card.defends });
if (target.card.defends <= 0) { if (target.card.defends <= 0) {
delete boardState[targetSlotId]; delete boardState[targetSlotId];
events.push({ type: 'die', slotId: targetSlotId }); events.push({ type: 'die', slotId: targetSlotId });