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)