carte travesti
This commit is contained in:
parent
9b5ce433e0
commit
3b5f37403c
5 changed files with 212 additions and 2 deletions
BIN
assets/img/cards/travesti.png
Normal file
BIN
assets/img/cards/travesti.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 245 KiB |
|
|
@ -386,6 +386,7 @@ logs...</pre
|
||||||
if (id.indexOf("medusa") !== -1) return "enemy";
|
if (id.indexOf("medusa") !== -1) return "enemy";
|
||||||
if (id.indexOf("parrure") !== -1) return "enemy_queen";
|
if (id.indexOf("parrure") !== -1) return "enemy_queen";
|
||||||
if (id.indexOf("tout") !== -1) return "piece";
|
if (id.indexOf("tout") !== -1) return "piece";
|
||||||
|
if (id.indexOf("travesti") !== -1) return "piece";
|
||||||
if (id.indexOf("kamikaz") !== -1) return "owned";
|
if (id.indexOf("kamikaz") !== -1) return "owned";
|
||||||
if (id.indexOf("invisible") !== -1) return "owned";
|
if (id.indexOf("invisible") !== -1) return "owned";
|
||||||
if (id.indexOf("rebond") !== -1) return "owned";
|
if (id.indexOf("rebond") !== -1) return "owned";
|
||||||
|
|
@ -2437,6 +2438,8 @@ logs...</pre
|
||||||
imgSrc = "/assets/img/cards/medusa.png";
|
imgSrc = "/assets/img/cards/medusa.png";
|
||||||
if (cid === "cachotier")
|
if (cid === "cachotier")
|
||||||
imgSrc = "/assets/img/cards/cachotier.png";
|
imgSrc = "/assets/img/cards/cachotier.png";
|
||||||
|
if (cid === "travesti")
|
||||||
|
imgSrc = "/assets/img/cards/travesti.png";
|
||||||
|
|
||||||
if (imgSrc) {
|
if (imgSrc) {
|
||||||
const img = document.createElement("img");
|
const img = document.createElement("img");
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,8 @@
|
||||||
imgSrc = "/assets/img/cards/medusa.png";
|
imgSrc = "/assets/img/cards/medusa.png";
|
||||||
if (cid === "cachotier")
|
if (cid === "cachotier")
|
||||||
imgSrc = "/assets/img/cards/cachotier.png";
|
imgSrc = "/assets/img/cards/cachotier.png";
|
||||||
|
if (cid === "travesti")
|
||||||
|
imgSrc = "/assets/img/cards/travesti.png";
|
||||||
|
|
||||||
if (imgSrc) {
|
if (imgSrc) {
|
||||||
const img = document.createElement("img");
|
const img = document.createElement("img");
|
||||||
|
|
|
||||||
|
|
@ -651,6 +651,8 @@
|
||||||
imgSrc = "/assets/img/cards/medusa.png";
|
imgSrc = "/assets/img/cards/medusa.png";
|
||||||
if (cid === "cachotier")
|
if (cid === "cachotier")
|
||||||
imgSrc = "/assets/img/cards/cachotier.png";
|
imgSrc = "/assets/img/cards/cachotier.png";
|
||||||
|
if (cid === "travesti")
|
||||||
|
imgSrc = "/assets/img/cards/travesti.png";
|
||||||
|
|
||||||
if (imgSrc) {
|
if (imgSrc) {
|
||||||
const img = document.createElement("img");
|
const img = document.createElement("img");
|
||||||
|
|
|
||||||
207
server.js
207
server.js
|
|
@ -253,6 +253,61 @@ function recordPlayerDrewPrev(room, playerId) {
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper: apply travesti effect at the start of each turn
|
||||||
|
// Changes the type of affected pieces randomly to P, N, B, R, or Q
|
||||||
|
function applyTraverstiEffects(room) {
|
||||||
|
try {
|
||||||
|
if (!room || !room.boardState) return;
|
||||||
|
const board = room.boardState;
|
||||||
|
const pieces = board.pieces || [];
|
||||||
|
const effects = room.activeCardEffects || [];
|
||||||
|
const travestiEffects = effects.filter((e) => e && e.type === "travesti");
|
||||||
|
if (!travestiEffects.length) return;
|
||||||
|
|
||||||
|
const possibleTypes = ["P", "N", "B", "R", "Q"];
|
||||||
|
|
||||||
|
travestiEffects.forEach((eff) => {
|
||||||
|
const piece = pieces.find((p) => p.id === eff.pieceId);
|
||||||
|
if (!piece) {
|
||||||
|
// Piece was captured, remove the effect
|
||||||
|
try {
|
||||||
|
room.activeCardEffects = effects.filter((e) => e !== eff);
|
||||||
|
io.to(room.id).emit("card:effect:removed", {
|
||||||
|
roomId: room.id,
|
||||||
|
effectId: eff.id,
|
||||||
|
type: "travesti",
|
||||||
|
playerId: eff.playerId,
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Choose a random type different from current (if possible)
|
||||||
|
const currentType = piece.type;
|
||||||
|
const availableTypes = possibleTypes.filter((t) => t !== currentType);
|
||||||
|
const newType = availableTypes[Math.floor(Math.random() * availableTypes.length)];
|
||||||
|
piece.type = newType;
|
||||||
|
|
||||||
|
// Update the effect to track the current type
|
||||||
|
eff.currentType = newType;
|
||||||
|
|
||||||
|
try {
|
||||||
|
io.to(room.id).emit("card:effect:updated", {
|
||||||
|
roomId: room.id,
|
||||||
|
effect: eff,
|
||||||
|
pieceChanged: { pieceId: piece.id, newType, square: piece.square },
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bump version so clients pick up the change
|
||||||
|
try {
|
||||||
|
board.version = (board.version || 0) + 1;
|
||||||
|
} catch (_) {}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("applyTraverstiEffects error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper: at the start of a player's turn, either perform an automatic draw
|
// Helper: at the start of a player's turn, either perform an automatic draw
|
||||||
// if room.autoDraw is enabled, or simply broadcast the room state so clients
|
// if room.autoDraw is enabled, or simply broadcast the room state so clients
|
||||||
// can update UI. This centralizes the auto-draw toggle behavior.
|
// can update UI. This centralizes the auto-draw toggle behavior.
|
||||||
|
|
@ -409,6 +464,10 @@ function endTurnAfterCard(room, senderId) {
|
||||||
(p) => (p.color && p.color[0]) === nextColor,
|
(p) => (p.color && p.color[0]) === nextColor,
|
||||||
);
|
);
|
||||||
if (nextPlayer) {
|
if (nextPlayer) {
|
||||||
|
// Apply travesti effect at the start of the new turn
|
||||||
|
try {
|
||||||
|
applyTraverstiEffects(room);
|
||||||
|
} catch (_) {}
|
||||||
maybeDrawAtTurnStart(room, nextPlayer.id);
|
maybeDrawAtTurnStart(room, nextPlayer.id);
|
||||||
} else {
|
} else {
|
||||||
sendRoomUpdate(room);
|
sendRoomUpdate(room);
|
||||||
|
|
@ -659,17 +718,21 @@ function buildDefaultDeck() {
|
||||||
"cachotier"
|
"cachotier"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
[
|
||||||
|
"Travesti",
|
||||||
|
"La pièce désignée change aléatoirement de type à chaque tour.",
|
||||||
|
"travesti"
|
||||||
|
]
|
||||||
|
|
||||||
// facile et intéresssant
|
// facile et intéresssant
|
||||||
// ["intrication quantique","Deux pièces sont intriquées. Quand l'une bouge, l'autre bouge de la même manière."],
|
// ["intrication quantique","Deux pièces sont intriquées. Quand l'une bouge, l'autre bouge de la même manière."],
|
||||||
// ['kurby','Choisis une pièce. À sa prochaine capture, récupère tous les mouvements de la pièce capturée.'],
|
// ['kurby','Choisis une pièce. À sa prochaine capture, récupère tous les mouvements de la pièce capturée.'],
|
||||||
|
|
||||||
// ['défausse','Le joueur adverse défausse une carte de son choix'],
|
// ['défausse','Le joueur adverse défausse une carte de son choix'],
|
||||||
// ['glue','Toutes les pièces autour de la pièce désignée ne peuvent pas bouger tant que cette dernière ne bouge pas'],
|
// ['glue','Toutes les pièces autour de la pièce désignée ne peuvent pas bouger tant que cette dernière ne bouge pas'],
|
||||||
// ['immunité à la capture','Désigne une pièce qui ne pourra pas être capturée au prochain tour'],
|
// ['immunité à la capture','Désigne une pièce qui ne pourra pas être capturée au prochain tour'],
|
||||||
// ['marécage','Pendant X tours, toutes les pièces ne peuvent se déplacer que comme un roi'],
|
// ['marécage','Pendant X tours, toutes les pièces ne peuvent se déplacer que comme un roi'],
|
||||||
// ['tricherie','Choisis une carte de la pioche parmis trois'],
|
// ['tricherie','Choisis une carte de la pioche parmis trois'],
|
||||||
// ['trêve','Aucun capture ne peut avoir lieu pendant 4 tours'],
|
// ['trêve','Aucun capture ne peut avoir lieu pendant 4 tours'],
|
||||||
// ['traversti','La pièce désignée change aléatoirement de type à chaque tour']
|
|
||||||
// ['pièce berserk','Une pièce choisie doit capturer dans les trois prochains tours, sinon elle est capturée'],
|
// ['pièce berserk','Une pièce choisie doit capturer dans les trois prochains tours, sinon elle est capturée'],
|
||||||
|
|
||||||
// moyen facile mais intéressant
|
// moyen facile mais intéressant
|
||||||
|
|
@ -2095,6 +2158,10 @@ io.on("connection", (socket) => {
|
||||||
(p) => (p.color && p.color[0]) === nextColor,
|
(p) => (p.color && p.color[0]) === nextColor,
|
||||||
);
|
);
|
||||||
if (nextPlayer) {
|
if (nextPlayer) {
|
||||||
|
// Apply travesti effect at the start of the new turn
|
||||||
|
try {
|
||||||
|
applyTraverstiEffects(room);
|
||||||
|
} catch (_) {}
|
||||||
maybeDrawAtTurnStart(room, nextPlayer.id);
|
maybeDrawAtTurnStart(room, nextPlayer.id);
|
||||||
} else {
|
} else {
|
||||||
sendRoomUpdate(room);
|
sendRoomUpdate(room);
|
||||||
|
|
@ -2552,6 +2619,10 @@ io.on("connection", (socket) => {
|
||||||
);
|
);
|
||||||
if (nextPlayer) {
|
if (nextPlayer) {
|
||||||
try {
|
try {
|
||||||
|
// Apply travesti effect at the start of the new turn
|
||||||
|
try {
|
||||||
|
applyTraverstiEffects(room);
|
||||||
|
} catch (_) {}
|
||||||
maybeDrawAtTurnStart(room, nextPlayer.id);
|
maybeDrawAtTurnStart(room, nextPlayer.id);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
sendRoomUpdate(room);
|
sendRoomUpdate(room);
|
||||||
|
|
@ -2667,6 +2738,8 @@ io.on("connection", (socket) => {
|
||||||
typeof cardId === "string" && cardId.indexOf("folie") !== -1;
|
typeof cardId === "string" && cardId.indexOf("folie") !== -1;
|
||||||
const isFort =
|
const isFort =
|
||||||
typeof cardId === "string" && cardId.indexOf("fortification") !== -1;
|
typeof cardId === "string" && cardId.indexOf("fortification") !== -1;
|
||||||
|
const isTraversti =
|
||||||
|
typeof cardId === "string" && cardId.indexOf("travesti") !== -1;
|
||||||
const isTargetCard = isRebond || isAdoub || isFolie || isFort;
|
const isTargetCard = isRebond || isAdoub || isFolie || isFort;
|
||||||
if (isTargetCard) {
|
if (isTargetCard) {
|
||||||
const board = room.boardState;
|
const board = room.boardState;
|
||||||
|
|
@ -2702,6 +2775,40 @@ io.on("connection", (socket) => {
|
||||||
payload.targetSquare = targetCandidate;
|
payload.targetSquare = targetCandidate;
|
||||||
played.payload = Object.assign({}, payload);
|
played.payload = Object.assign({}, payload);
|
||||||
}
|
}
|
||||||
|
// travesti: any piece except king
|
||||||
|
if (isTraversti) {
|
||||||
|
const board = room.boardState;
|
||||||
|
let targetCandidate = payload && payload.targetSquare;
|
||||||
|
if (!targetCandidate) {
|
||||||
|
try {
|
||||||
|
targetCandidate = socket.data && socket.data.lastSelectedSquare;
|
||||||
|
} catch (e) {
|
||||||
|
targetCandidate = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const targetPiece = ((board && board.pieces) || []).find(
|
||||||
|
(p) => p.square === targetCandidate,
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
!board ||
|
||||||
|
!targetCandidate ||
|
||||||
|
!targetPiece ||
|
||||||
|
targetPiece.type === "K"
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
cb &&
|
||||||
|
cb({
|
||||||
|
error: "no valid target",
|
||||||
|
message: targetPiece && targetPiece.type === "K"
|
||||||
|
? "Vous ne pouvez pas cibler un roi."
|
||||||
|
: "Sélectionnez une pièce à affecter.",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
payload = payload || {};
|
||||||
|
payload.targetSquare = targetCandidate;
|
||||||
|
played.payload = Object.assign({}, payload);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("target card pre-check error", e);
|
console.error("target card pre-check error", e);
|
||||||
}
|
}
|
||||||
|
|
@ -3816,6 +3923,10 @@ io.on("connection", (socket) => {
|
||||||
);
|
);
|
||||||
if (nextPlayer) {
|
if (nextPlayer) {
|
||||||
try {
|
try {
|
||||||
|
// Apply travesti effect at the start of the new turn
|
||||||
|
try {
|
||||||
|
applyTraverstiEffects(room);
|
||||||
|
} catch (_) {}
|
||||||
maybeDrawAtTurnStart(room, nextPlayer.id);
|
maybeDrawAtTurnStart(room, nextPlayer.id);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
@ -3995,6 +4106,10 @@ io.on("connection", (socket) => {
|
||||||
);
|
);
|
||||||
if (nextPlayer) {
|
if (nextPlayer) {
|
||||||
try {
|
try {
|
||||||
|
// Apply travesti effect at the start of the new turn
|
||||||
|
try {
|
||||||
|
applyTraverstiEffects(room);
|
||||||
|
} catch (_) {}
|
||||||
maybeDrawAtTurnStart(room, nextPlayer.id);
|
maybeDrawAtTurnStart(room, nextPlayer.id);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
@ -4739,6 +4854,10 @@ io.on("connection", (socket) => {
|
||||||
);
|
);
|
||||||
if (nextPlayer) {
|
if (nextPlayer) {
|
||||||
try {
|
try {
|
||||||
|
// Apply travesti effect at the start of the new turn
|
||||||
|
try {
|
||||||
|
applyTraverstiEffects(room);
|
||||||
|
} catch (_) {}
|
||||||
maybeDrawAtTurnStart(room, nextPlayer.id);
|
maybeDrawAtTurnStart(room, nextPlayer.id);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
@ -5113,6 +5232,86 @@ io.on("connection", (socket) => {
|
||||||
console.error("cachotier effect error", e);
|
console.error("cachotier effect error", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// travesti
|
||||||
|
else if (cardId === "travesti") {
|
||||||
|
try {
|
||||||
|
const board = room.boardState;
|
||||||
|
let target = payload && payload.targetSquare;
|
||||||
|
if (!target) {
|
||||||
|
try {
|
||||||
|
target = socket.data && socket.data.lastSelectedSquare;
|
||||||
|
} catch (e) {
|
||||||
|
target = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const targetPiece = ((board && board.pieces) || []).find(
|
||||||
|
(p) => p.square === target,
|
||||||
|
);
|
||||||
|
// Must select a piece that is not a king
|
||||||
|
if (
|
||||||
|
!board ||
|
||||||
|
!target ||
|
||||||
|
!targetPiece ||
|
||||||
|
targetPiece.type === "K"
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
room.hands = room.hands || {};
|
||||||
|
room.hands[senderId] = room.hands[senderId] || [];
|
||||||
|
if (removed) room.hands[senderId].push(removed);
|
||||||
|
room.discard = room.discard || [];
|
||||||
|
for (let i = room.discard.length - 1; i >= 0; i--) {
|
||||||
|
if (
|
||||||
|
room.discard[i] &&
|
||||||
|
room.discard[i].id === (removed && removed.id)
|
||||||
|
) {
|
||||||
|
room.discard.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("restore removed card error", e);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
cb &&
|
||||||
|
cb({
|
||||||
|
error: "no valid target",
|
||||||
|
message:
|
||||||
|
targetPiece && targetPiece.type === "K"
|
||||||
|
? "Vous ne pouvez pas cibler un roi."
|
||||||
|
: "Aucune cible valide n'a été sélectionnée.",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
room.activeCardEffects = room.activeCardEffects || [];
|
||||||
|
const effect = {
|
||||||
|
id: played.id,
|
||||||
|
type: "travesti",
|
||||||
|
pieceId: targetPiece.id,
|
||||||
|
pieceSquare: target,
|
||||||
|
originalType: targetPiece.type,
|
||||||
|
currentType: targetPiece.type,
|
||||||
|
playerId: senderId,
|
||||||
|
targetColor: targetPiece.color,
|
||||||
|
ts: Date.now(),
|
||||||
|
};
|
||||||
|
room.activeCardEffects.push(effect);
|
||||||
|
try {
|
||||||
|
io.to(room.id).emit("card:effect:applied", {
|
||||||
|
roomId: room.id,
|
||||||
|
effect,
|
||||||
|
});
|
||||||
|
} catch (_) {}
|
||||||
|
played.payload = Object.assign({}, payload, {
|
||||||
|
applied: "travesti",
|
||||||
|
appliedTo: target,
|
||||||
|
pieceId: targetPiece.id,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error("travesti effect error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("card:play effect error", e);
|
console.error("card:play effect error", e);
|
||||||
}
|
}
|
||||||
|
|
@ -5269,6 +5468,10 @@ io.on("connection", (socket) => {
|
||||||
(p) => (p.color && p.color[0]) === nextColor,
|
(p) => (p.color && p.color[0]) === nextColor,
|
||||||
);
|
);
|
||||||
if (nextPlayer) {
|
if (nextPlayer) {
|
||||||
|
// Apply travesti effect at the start of the new turn
|
||||||
|
try {
|
||||||
|
applyTraverstiEffects(room);
|
||||||
|
} catch (_) {}
|
||||||
maybeDrawAtTurnStart(room, nextPlayer.id);
|
maybeDrawAtTurnStart(room, nextPlayer.id);
|
||||||
} else {
|
} else {
|
||||||
sendRoomUpdate(room);
|
sendRoomUpdate(room);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue