affichage des mouvements
This commit is contained in:
parent
d02f83fb8e
commit
fad93ae70b
3 changed files with 108 additions and 6 deletions
|
|
@ -371,6 +371,29 @@ logs...</pre
|
||||||
if (data.boardState) {
|
if (data.boardState) {
|
||||||
renderBoardFromState(data.boardState);
|
renderBoardFromState(data.boardState);
|
||||||
updateTurnBanner(data.boardState);
|
updateTurnBanner(data.boardState);
|
||||||
|
// re-apply any active 'toucher' effects sent by the server (useful after refresh/reconnect)
|
||||||
|
try {
|
||||||
|
if (Array.isArray(data.activeCardEffects) && data.activeCardEffects.length) {
|
||||||
|
data.activeCardEffects.forEach((eff) => {
|
||||||
|
try {
|
||||||
|
if (eff && eff.type === 'toucher') {
|
||||||
|
let targetSquare = eff.pieceSquare || null;
|
||||||
|
if (!targetSquare && eff.pieceId && data.boardState && Array.isArray(data.boardState.pieces)) {
|
||||||
|
const p = data.boardState.pieces.find((x) => x.id === eff.pieceId);
|
||||||
|
if (p && p.square) targetSquare = p.square;
|
||||||
|
}
|
||||||
|
if (targetSquare && boardEl) {
|
||||||
|
const el = boardEl.querySelector(`.square[data-square="${targetSquare}"]`);
|
||||||
|
if (el) {
|
||||||
|
el.classList.add('targeted');
|
||||||
|
try { el.dataset.toucherEffectId = eff.id || ''; } catch(_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(_) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch(_) {}
|
||||||
// restore last-move highlight from localStorage (persist across refresh)
|
// restore last-move highlight from localStorage (persist across refresh)
|
||||||
try {
|
try {
|
||||||
if (roomId) {
|
if (roomId) {
|
||||||
|
|
@ -554,10 +577,62 @@ logs...</pre
|
||||||
// public notable effects
|
// public notable effects
|
||||||
showEffectNotification(effect);
|
showEffectNotification(effect);
|
||||||
}
|
}
|
||||||
|
// toucher
|
||||||
|
try {
|
||||||
|
if (effect.type === "toucher") {
|
||||||
|
const sq = effect.pieceSquare || null;
|
||||||
|
let targetSquare = sq;
|
||||||
|
if (!targetSquare && effect.pieceId && currentBoardState && Array.isArray(currentBoardState.pieces)) {
|
||||||
|
const p = currentBoardState.pieces.find((x) => x.id === effect.pieceId);
|
||||||
|
if (p && p.square) targetSquare = p.square;
|
||||||
|
}
|
||||||
|
if (targetSquare && boardEl) {
|
||||||
|
const el = boardEl.querySelector(`.square[data-square="${targetSquare}"]`);
|
||||||
|
if (el) {
|
||||||
|
el.classList.add("targeted");
|
||||||
|
try { el.dataset.toucherEffectId = effect.id || ""; } catch(_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("card:effect:applied handler error", e);
|
console.warn("card:effect:applied handler error", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// toucher
|
||||||
|
socket.on("card:effect:removed", (data) => {
|
||||||
|
try {
|
||||||
|
const effId = data && (data.effectId || data.id);
|
||||||
|
const type = data && data.type;
|
||||||
|
if (!effId) return;
|
||||||
|
if (type === "toucher") {
|
||||||
|
// find any square with matching dataset.toucherEffectId and remove the visual
|
||||||
|
try {
|
||||||
|
const sq = boardEl && boardEl.querySelector && boardEl.querySelector(`.square[data-toucher-effect-id][data-toucher-effect-id="${effId}"]`);
|
||||||
|
if (sq) {
|
||||||
|
sq.classList.remove("last-move-source");
|
||||||
|
sq.classList.remove("targeted");
|
||||||
|
try { delete sq.dataset.toucherEffectId; } catch(_) {}
|
||||||
|
} else {
|
||||||
|
// fallback: remove any .last-move-source or .targeted if its dataset matches
|
||||||
|
const all = boardEl.querySelectorAll('.square.last-move-source, .square.targeted');
|
||||||
|
all.forEach((s) => {
|
||||||
|
try {
|
||||||
|
if (s.dataset && s.dataset.toucherEffectId === String(effId)) {
|
||||||
|
s.classList.remove('last-move-source');
|
||||||
|
s.classList.remove('targeted');
|
||||||
|
delete s.dataset.toucherEffectId;
|
||||||
|
}
|
||||||
|
} catch(_) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('card:effect:removed handler error', e);
|
||||||
|
}
|
||||||
|
});
|
||||||
// when the server sends the stolen card to the stealer (private)
|
// when the server sends the stolen card to the stealer (private)
|
||||||
socket.on("card:stolen", (data) => {
|
socket.on("card:stolen", (data) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -245,23 +245,29 @@ button:hover{transform:translateY(-3px);transition:all 180ms ease}
|
||||||
}
|
}
|
||||||
#board.shuffle-play .square img{ transition: transform 700ms cubic-bezier(.2,.9,.2,1); transform: rotate(2deg) scale(0.995); filter: drop-shadow(0 6px 18px rgba(0,0,0,0.06)); }
|
#board.shuffle-play .square img{ transition: transform 700ms cubic-bezier(.2,.9,.2,1); transform: rotate(2deg) scale(0.995); filter: drop-shadow(0 6px 18px rgba(0,0,0,0.06)); }
|
||||||
|
|
||||||
/* overlay that fills the whole square (subtle green) so the entire cell is highlighted */
|
.square.targeted::after{
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0; top: 0; right: 0; bottom: 0;
|
||||||
|
background: rgb(255, 201, 201);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
.square.last-move-dest::after{
|
.square.last-move-dest::after{
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0; top: 0; right: 0; bottom: 0;
|
left: 0; top: 0; right: 0; bottom: 0;
|
||||||
background: rgb(164, 229, 208);
|
background: rgb(212, 255, 241);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subtle highlight for the source square of the last move (less prominent) */
|
|
||||||
.square.last-move-source::after{
|
.square.last-move-source::after{
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0; top: 0; right: 0; bottom: 0;
|
left: 0; top: 0; right: 0; bottom: 0;
|
||||||
background: rgb(164, 229, 208);
|
background: rgb(212, 255, 241);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
21
server.js
21
server.js
|
|
@ -2538,6 +2538,27 @@ io.on("connection", (socket) => {
|
||||||
const removed = hand.splice(idx, 1)[0];
|
const removed = hand.splice(idx, 1)[0];
|
||||||
room.hands[senderId] = hand;
|
room.hands[senderId] = hand;
|
||||||
room.discard = room.discard || [];
|
room.discard = room.discard || [];
|
||||||
|
// touhcer
|
||||||
|
try {
|
||||||
|
room.activeCardEffects = room.activeCardEffects || [];
|
||||||
|
for (let ei = room.activeCardEffects.length - 1; ei >= 0; ei--) {
|
||||||
|
const ev = room.activeCardEffects[ei];
|
||||||
|
if (!ev) continue;
|
||||||
|
if (ev.type === "toucher" && ev.playerId === senderId) {
|
||||||
|
try {
|
||||||
|
room.activeCardEffects.splice(ei, 1);
|
||||||
|
} catch (_) {}
|
||||||
|
try {
|
||||||
|
io.to(room.id).emit("card:effect:removed", {
|
||||||
|
roomId: room.id,
|
||||||
|
effectId: ev.id,
|
||||||
|
type: ev.type,
|
||||||
|
playerId: ev.playerId,
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
if (!room.noRemise) {
|
if (!room.noRemise) {
|
||||||
room.discard.push(removed);
|
room.discard.push(removed);
|
||||||
played.card = removed;
|
played.card = removed;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue