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 */
socket.on('avatar_damaged', data => {
const { slot, damage, remainingHp, maxHp } = data;
const { slot, damage, remainingHp, maxHp, row } = data;
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 avEl = document.getElementById(isLeft ? 'avLeft' : 'avRight');
const topPct = row === 'row2' ? '38%' : '14%';
if (avEl) {
const dmg = document.createElement('div');
dmg.textContent = `-${damage}`;
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;
color:#e74c3c;text-shadow:0 2px 10px rgba(0,0,0,0.95);
pointer-events:none;z-index:30;
animation:dmg-float 1s ease forwards;`;
animation:dmg-float 2.5s ease forwards;`;
avEl.appendChild(dmg);
setTimeout(() => dmg.remove(), 1000);
setTimeout(() => dmg.remove(), 2500);
}
});
@ -946,8 +947,11 @@ socket.on('ht_ai_setup', data => {
*/
function closeToArena() {
if (window.parent && window.parent !== window) {
window.parent.document.getElementById('arena-backdrop')?.remove();
window.parent.document.getElementById('arena-popup')?.remove();
const pd = window.parent.document;
/* 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 {
window.location.href = '/launcher';
}
@ -1066,8 +1070,17 @@ function updateResultWithPoints(data) {
}
}).catch(() => {});
/* Nach 3 Sekunden zur Arena weiterleiten */
setTimeout(() => closeToArena(), 3000);
/* Nach 5 Sekunden: Overlay ausblenden und zur Arena weiterleiten */
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(); }

View File

@ -543,29 +543,30 @@ 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'
for (let i = 0; i < avatarEvents.length; i++) {
// 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) {
console.warn(`[HP] room.hp[${target}] nicht gesetzt überspringe`);
continue;
}
// 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,
remainingHp: room.hp[target],
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) {
await handleMatchEnd(io, matchId, room, target);
return true;

View File

@ -56,7 +56,7 @@ function runCombatPhase(boardState, leftSlot, activeSlot) {
for (let r = 1; r <= range; 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) {
events.push({ type: 'avatar_attack', from: currentSlotId, target: opponentSlot, damage: atk });
break;
@ -70,7 +70,6 @@ function runCombatPhase(boardState, leftSlot, activeSlot) {
target.card = { ...target.card, defends: (target.card.defends ?? 0) - atk };
events.push({ type: 'attack', from: currentSlotId, to: targetSlotId, damage: atk, remainingDef: target.card.defends });
if (target.card.defends <= 0) {
delete boardState[targetSlotId];
events.push({ type: 'die', slotId: targetSlotId });