teleportation
This commit is contained in:
parent
3d2bb42aa6
commit
ad00592c33
2 changed files with 54 additions and 1 deletions
|
|
@ -485,8 +485,13 @@
|
|||
if(!occ || occ.color === myShort){ log('select an enemy piece'); return; }
|
||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.error); }
|
||||
else { log('card played with target', resp); }
|
||||
else { log('card played with target', resp);
|
||||
// after server applied the card effect, request legal moves for the selected piece so the client
|
||||
// will receive the updated legal moves (including teleport to empty squares)
|
||||
try{ setSelection(square); }catch(_){ }
|
||||
}
|
||||
});
|
||||
// keep pendingCard until server response processed (client will call setSelection on success)
|
||||
pendingCard = null; clearTargetHighlights(); return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
48
server.js
48
server.js
|
|
@ -312,6 +312,25 @@ function computeLegalMoves(room, square){
|
|||
});
|
||||
}
|
||||
}catch(_){ }
|
||||
// detect teleport effect: allow this piece to move to any empty square (one-turn temporary effect)
|
||||
try{
|
||||
const hasTeleport = (room.activeCardEffects || []).some(e => e && e.type === 'teleport' && ((e.pieceId && e.pieceId === piece.id) || e.pieceSquare === square));
|
||||
if(hasTeleport){
|
||||
// iterate all board squares and add empty ones as legal non-capturing moves
|
||||
for(let tx = 0; tx < width; tx++){
|
||||
for(let ty = 0; ty < height; ty++){
|
||||
const tsq = coordToSquare(tx, ty);
|
||||
if(!tsq) continue;
|
||||
// avoid adding the current square
|
||||
if(tsq === square) continue;
|
||||
const occ = getPieceAt(tsq);
|
||||
if(!occ && !moves.some(m => m.to === tsq)){
|
||||
moves.push({ from: square, to: tsq });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(_){ }
|
||||
// detect if this specific piece has a permanent adoubement effect (grants knight moves)
|
||||
// effects may be bound either to the piece's current square or to the piece id (preferred)
|
||||
const hasAdoubement = (room.activeCardEffects || []).some(e => e.type === 'adoubement' && ((e.pieceId && e.pieceId === piece.id) || e.pieceSquare === square));
|
||||
|
|
@ -1212,6 +1231,35 @@ io.on('connection', (socket) => {
|
|||
room.activeCardEffects.push({ id: played.id, type: 'fortification', pieceId: targetPiece.id, pieceSquare: target, playerId: senderId });
|
||||
played.payload = Object.assign({}, payload, { applied: 'fortification', appliedTo: target });
|
||||
}catch(e){ console.error('fortification effect error', e); }
|
||||
}
|
||||
// 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'){
|
||||
try{
|
||||
const board = room.boardState;
|
||||
let target = payload && payload.targetSquare;
|
||||
if(!target){ try{ target = socket.data && socket.data.lastSelectedSquare; }catch(e){ target = null; } }
|
||||
// validate target exists and belongs to the player
|
||||
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);
|
||||
if(!board || !target || !targetPiece || targetPiece.color !== playerColorShort){
|
||||
// restore removed card to hand and remove from discard if necessary
|
||||
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' });
|
||||
}
|
||||
// apply a temporary teleport effect bound to the piece id for one owner turn
|
||||
room.activeCardEffects = room.activeCardEffects || [];
|
||||
const effect = { id: played.id, type: 'teleport', pieceId: targetPiece.id, pieceSquare: target, playerId: senderId, remainingTurns: 1, decrementOn: 'owner' };
|
||||
room.activeCardEffects.push(effect);
|
||||
played.payload = Object.assign({}, payload, { applied: 'teleport', appliedTo: target });
|
||||
try{ io.to(room.id).emit('card:effect:applied', { roomId: room.id, effect }); }catch(_){ }
|
||||
}catch(e){ console.error('teleport effect error', e); }
|
||||
}
|
||||
// promotion: promote one of your pawns to a queen
|
||||
else if(cardId === 'promotion' || cardId === 'promote' || (typeof cardId === 'string' && (cardId.indexOf('promotion') !== -1 || cardId.indexOf('promot') !== -1 || cardId.indexOf('promouvoir') !== -1))){
|
||||
|
|
|
|||
Loading…
Reference in a new issue