toucher c'est jouer
This commit is contained in:
parent
18403495eb
commit
95bef7ea51
2 changed files with 57 additions and 1 deletions
|
|
@ -94,6 +94,8 @@
|
||||||
id = id.replace(/[^\x00-\x7F]/g, '');
|
id = id.replace(/[^\x00-\x7F]/g, '');
|
||||||
}
|
}
|
||||||
if(id.indexOf('mine') !== -1) return 'empty';
|
if(id.indexOf('mine') !== -1) return 'empty';
|
||||||
|
// 'toucher c'est jouer' : require selecting an enemy piece as the card target
|
||||||
|
if(id.indexOf('toucher') !== -1) return 'enemy';
|
||||||
// kamikaz targets one of your pieces (play card, then choose a piece)
|
// kamikaz targets one of your pieces (play card, then choose a piece)
|
||||||
if(id.indexOf('kamikaz') !== -1) return 'owned';
|
if(id.indexOf('kamikaz') !== -1) return 'owned';
|
||||||
if(id.indexOf('invis') !== -1 || id.indexOf('invisible') !== -1) return 'owned';
|
if(id.indexOf('invis') !== -1 || id.indexOf('invisible') !== -1) return 'owned';
|
||||||
|
|
|
||||||
56
server.js
56
server.js
|
|
@ -171,7 +171,7 @@ function buildDefaultDeck(){
|
||||||
['changement de camp','On retourne le plateau'],
|
['changement de camp','On retourne le plateau'],
|
||||||
// ['ça tangue','Toutes les pièces se décale du même côté'],
|
// ['ça tangue','Toutes les pièces se décale du même côté'],
|
||||||
// ['réinitialisation','Toutes les pièces reviennent à leur position initiale. S il y a des pièces supplémenaires, se rangent devant les pions'],
|
// ['réinitialisation','Toutes les pièces reviennent à leur position initiale. S il y a des pièces supplémenaires, se rangent devant les pions'],
|
||||||
// ['toucher c est jouer','Toucher une pièce adverse qu il sera obligé de jouer'],
|
["toucher c'est jouer","Toucher une pièce adverse qu'il sera obligé de jouer"],
|
||||||
// ['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'],
|
||||||
// ['sniper','Capturer une pièce sans avoir à bouger la pièce capturante'],
|
// ['sniper','Capturer une pièce sans avoir à bouger la pièce capturante'],
|
||||||
// ['inversion','Échange la position d une pièce avec une pièce adverse'],
|
// ['inversion','Échange la position d une pièce avec une pièce adverse'],
|
||||||
|
|
@ -748,6 +748,16 @@ io.on('connection', (socket) => {
|
||||||
if(!moving) return cb && cb({ error: 'no piece at source' });
|
if(!moving) return cb && cb({ error: 'no piece at source' });
|
||||||
if(moving.color !== playerColorShort) return cb && cb({ error: 'not your piece' });
|
if(moving.color !== playerColorShort) return cb && cb({ error: 'not your piece' });
|
||||||
|
|
||||||
|
// Enforce 'toucher' restriction: if there is an active 'toucher' effect targeting this player,
|
||||||
|
// they may ONLY move the specified piece(s).
|
||||||
|
try{
|
||||||
|
const effects = room.activeCardEffects || [];
|
||||||
|
const toucher = effects.find(e => e && e.type === 'toucher' && e.playerId === senderId);
|
||||||
|
if(toucher && toucher.pieceId && moving.id !== toucher.pieceId){
|
||||||
|
return cb && cb({ error: 'must_move_restricted_piece' });
|
||||||
|
}
|
||||||
|
}catch(_){ }
|
||||||
|
|
||||||
// validate that 'to' is among legal moves
|
// validate that 'to' is among legal moves
|
||||||
const legal = computeLegalMoves(room, from) || [];
|
const legal = computeLegalMoves(room, from) || [];
|
||||||
const ok = legal.some(m => m.to === to);
|
const ok = legal.some(m => m.to === to);
|
||||||
|
|
@ -1040,6 +1050,19 @@ io.on('connection', (socket) => {
|
||||||
console.error('computeLegalMoves error', e);
|
console.error('computeLegalMoves error', e);
|
||||||
moves = [];
|
moves = [];
|
||||||
}
|
}
|
||||||
|
// Enforce 'toucher' restriction: if the selecting player is affected by a 'toucher' effect,
|
||||||
|
// they may only move the targeted piece. If they select another piece, show no moves.
|
||||||
|
try{
|
||||||
|
const effects = room.activeCardEffects || [];
|
||||||
|
const toucherEffects = effects.filter(e => e && e.type === 'toucher' && e.playerId === playerId);
|
||||||
|
if(toucherEffects && toucherEffects.length > 0){
|
||||||
|
const selectedPiece = (room.boardState && room.boardState.pieces || []).find(p => p.square === square);
|
||||||
|
const allowedPieceIds = toucherEffects.map(e => e.pieceId).filter(Boolean);
|
||||||
|
if(!selectedPiece || allowedPieceIds.indexOf(selectedPiece.id) === -1){
|
||||||
|
moves = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(_){ /* ignore enforcement errors */ }
|
||||||
// send selection to the selecting client WITH moves, but broadcast selection WITHOUT moves to other clients
|
// send selection to the selecting client WITH moves, but broadcast selection WITHOUT moves to other clients
|
||||||
try{
|
try{
|
||||||
// send to selecting socket (include moves)
|
// send to selecting socket (include moves)
|
||||||
|
|
@ -1334,6 +1357,37 @@ io.on('connection', (socket) => {
|
||||||
played.payload = Object.assign({}, payload, { applied: 'fortification', appliedTo: target });
|
played.payload = Object.assign({}, payload, { applied: 'fortification', appliedTo: target });
|
||||||
}catch(e){ console.error('fortification effect error', e); }
|
}catch(e){ console.error('fortification effect error', e); }
|
||||||
}
|
}
|
||||||
|
// toucher c'est jouer: force the targeted player to move only the chosen piece on their next turn
|
||||||
|
else if((typeof cardId === 'string' && cardId.indexOf('toucher') !== -1) || cardId === 'toucher_cest_jouer'){
|
||||||
|
try{
|
||||||
|
const board = room.boardState;
|
||||||
|
let target = payload && payload.targetSquare;
|
||||||
|
if(!target){ try{ target = socket.data && socket.data.lastSelectedSquare; }catch(e){ target = null; } }
|
||||||
|
const roomPlayer = room.players.find(p => p.id === senderId);
|
||||||
|
const playerColorShort = (roomPlayer && roomPlayer.color && roomPlayer.color[0]) || null;
|
||||||
|
const targetPiece = (board && board.pieces || []).find(p => p.square === target);
|
||||||
|
// validate target exists and belongs to the opponent
|
||||||
|
if(!board || !target || !targetPiece || targetPiece.color === playerColorShort){
|
||||||
|
// invalid target: restore removed card to hand and abort
|
||||||
|
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' });
|
||||||
|
}
|
||||||
|
// find the owner (player) of the targeted piece
|
||||||
|
const targetOwner = (room.players || []).find(p => (p.color && p.color[0]) === targetPiece.color) || null;
|
||||||
|
// create a one-turn effect that forces the targetOwner to move only this piece on their next turn
|
||||||
|
room.activeCardEffects = room.activeCardEffects || [];
|
||||||
|
const effect = { id: played.id, type: 'toucher', playerId: (targetOwner && targetOwner.id) || null, pieceId: targetPiece.id, pieceSquare: targetPiece.square, remainingTurns: 1, decrementOn: 'owner', imposedBy: senderId, ts: Date.now() };
|
||||||
|
room.activeCardEffects.push(effect);
|
||||||
|
played.payload = Object.assign({}, payload, { applied: 'toucher', appliedTo: target });
|
||||||
|
try{ io.to(room.id).emit('card:effect:applied', { roomId: room.id, effect }); }catch(_){ }
|
||||||
|
}catch(e){ console.error('toucher effect error', e); }
|
||||||
|
}
|
||||||
// teleportation: allow the selected piece to move to any empty square for one turn
|
// teleportation: allow the selected piece to move to any empty square for one turn
|
||||||
else if((typeof cardId === 'string' && (cardId.indexOf('teleport') !== -1 || cardId.indexOf('t_l_portation') !== -1 || cardId.indexOf('t_lportation') !== -1)) || cardId === 'teleport'){
|
else if((typeof cardId === 'string' && (cardId.indexOf('teleport') !== -1 || cardId.indexOf('t_l_portation') !== -1 || cardId.indexOf('t_lportation') !== -1)) || cardId === 'teleport'){
|
||||||
try{
|
try{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue