diff --git a/public/game.html b/public/game.html index 17e36ae..9d5015d 100644 --- a/public/game.html +++ b/public/game.html @@ -210,7 +210,7 @@ logs... e && e.type === "brouillard", + (e) => e && (e.type === "brouillard" || e.type === "medusa" || e.type === "empathie"), ); if (!effects || !effects.length) { dest.textContent = "Aucun effet actif pour l'instant."; @@ -793,9 +793,13 @@ logs... { + try { + if (s.dataset && s.dataset.medusaEffectId === String(eff.id)) { + s.classList.remove("petrified"); + delete s.dataset.medusaEffectId; + } + } catch (_) {} + }); + } + } + } catch (_) {} + try { + refreshEffectsFeed(); + } catch (_) {} + } else { + activeEffects[eff.id] = eff; + try { + refreshEffectsFeed(); + } catch (_) {} + } } catch (_) {} } catch (e) { console.warn("card:effect:updated handler error", e); @@ -877,9 +918,13 @@ logs... { // room = { id, boardState: object|null, players: [{id, socketId, color}], status, size } const rooms = new Map(); +// Remove any active effects whose remainingTurns <= 0 and notify clients. +function purgeExpiredEffects(room) { + try { + if (!room || !Array.isArray(room.activeCardEffects)) return; + for (let i = room.activeCardEffects.length - 1; i >= 0; i--) { + const e = room.activeCardEffects[i]; + if (!e) continue; + if (typeof e.remainingTurns === "number" && e.remainingTurns <= 0) { + try { + // handle special expiry side-effects (empathie etc.) if needed + if (e && e.type === "empathie") { + try { + (room.players || []).forEach((pl) => { + if (!pl || !pl.color) return; + if (pl.color === "white") pl.color = "black"; + else if (pl.color === "black") pl.color = "white"; + }); + try { + if (room.boardState) + room.boardState.version = (room.boardState.version || 0) + 1; + } catch (_) {} + } catch (_) {} + } + } catch (_) {} + try { + room.activeCardEffects.splice(i, 1); + } catch (_) {} + try { + io.to(room.id).emit("card:effect:removed", { + roomId: room.id, + effectId: e.id, + type: e.type, + playerId: e.playerId, + }); + } catch (_) {} + } + } + } catch (err) { + console.error("purgeExpiredEffects error", err); + } +} + // Send a room:update payload to each player individually so hands remain private. function sendRoomUpdate(room) { if (!room) return; + try { + purgeExpiredEffects(room); + } catch (_) {} const base = { boardState: room.boardState || null, players: (room.players || []).map((p) => ({ id: p.id, color: p.color })), @@ -3193,12 +3239,13 @@ io.on("connection", (socket) => { room.activeCardEffects = room.activeCardEffects || []; const effect = { id: played.id, + title: "Médusa", type: "medusa", playerId: senderId, pieceId: targetPiece.id, pieceSquare: targetPiece.square, remainingTurns: 4, - decrementOn: "owner", + decrementOn: "both", imposedBy: senderId, ts: Date.now(), }; @@ -3212,7 +3259,8 @@ io.on("connection", (socket) => { pieceId: targetPiece.id, pieceSquare: targetPiece.square, remainingTurns: 1, - decrementOn: "owner", + // remove the visual marker after any player's action + decrementOn: "both", imposedBy: senderId, ts: Date.now(), }; @@ -3667,6 +3715,7 @@ io.on("connection", (socket) => { const effect = { id: played.id, + title: "Empathie", type: "empathie", playerId: senderId, // lasts 6 turns (decrement on every end-of-turn)