From 0a957b346a7dacb7eacdb91a834879f7450b83ad Mon Sep 17 00:00:00 2001 From: Didictateur Date: Sat, 22 Nov 2025 18:18:43 +0100 Subject: [PATCH] fortification --- server.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/server.js b/server.js index b247d5d..f8e5b52 100644 --- a/server.js +++ b/server.js @@ -52,9 +52,10 @@ function buildDefaultDeck(){ // ['tronquer le plateau','Tronque au maximum le plateau sans supprimer de pièce'], ['rebondir sur les bords','Les déplacements en diagonales de la pièce sélectionnée peuvent rebondir une fois sur les bords'], ['agrandir le plateau','Rajoute une rangée dans toutes les directions'], - ['adoubement','La pièce sélectionnée peut maintenant faire les déplacements du cavalier en plus'], - ['folie','La pièce sélectionnée peut maintenant faire les déplacements du fou en plus'], - // ['fortification','La pièce sélectionnée peut maintenant faire les déplacements de la tour en plus'], + ['adoubement','La pièce sélectionnée peut maintenant faire les déplacements du cavalier en plus'], + ['folie','La pièce sélectionnée peut maintenant faire les déplacements du fou en plus'], + ['fortification','La pièce sélectionnée peut maintenant faire les déplacements de la tour en plus'], + ['fortification','La pièce sélectionnée peut maintenant faire les déplacements de la tour en plus'], // ["l'anneau","Le plateau devient un anneau pendant un tour"], // ['brouillard de guerre','Les joueur ne peuvent voir que au alentour de leurs pièces pendant X tours'], // ['changer la pièce à capturer','Le joueur choisie la nouvelle pièce jouant le rôle de roi sans la révéler'], @@ -238,6 +239,9 @@ function computeLegalMoves(room, square){ // detect if this specific piece has a permanent folie effect (grants bishop moves) const hasFolie = (room.activeCardEffects || []).some(e => e.type === 'folie' && ((e.pieceId && e.pieceId === piece.id) || e.pieceSquare === square)); + // detect if this specific piece has a permanent fortification effect (grants rook moves) + const hasFortification = (room.activeCardEffects || []).some(e => e.type === 'fortification' && ((e.pieceId && e.pieceId === piece.id) || e.pieceSquare === square)); + // helper to add diagonal sliding moves when a piece has been "folié" function addFolieMoves(){ if(!hasFolie) return; @@ -260,6 +264,26 @@ function computeLegalMoves(room, square){ } }); } + // helper to add orthogonal sliding moves when a piece has been 'fortifié' + function addFortificationMoves(){ + if(!hasFortification) return; + const dirs = [[1,0],[-1,0],[0,1],[0,-1]]; + dirs.forEach(([dx,dy])=>{ + let tx = x + dx, ty = y + dy; + while(isInside(tx,ty)){ + const tsq = coordToSquare(tx,ty); + if(!moves.some(m => m.to === tsq)){ + const occ = getPieceAt(tsq); + if(!occ){ moves.push({ from: square, to: tsq }); } + else { if(occ.color !== color) moves.push({ from: square, to: tsq }); break; } + } else { + const occ = getPieceAt(tsq); + if(occ) break; + } + tx += dx; ty += dy; + } + }); + } if(type === 'P'){ // pawn const forward = (color === 'w') ? 1 : -1; @@ -282,7 +306,7 @@ function computeLegalMoves(room, square){ const occ = getPieceAt(tsq); if(occ && occ.color !== color) moves.push({ from: square, to: tsq }); }); - addAdoubementMoves(); addFolieMoves(); + addAdoubementMoves(); addFolieMoves(); addFortificationMoves(); return moves; } @@ -295,7 +319,7 @@ function computeLegalMoves(room, square){ const occ = getPieceAt(tsq); if(!occ || occ.color !== color) moves.push({ from: square, to: tsq }); }); - addAdoubementMoves(); addFolieMoves(); + addAdoubementMoves(); addFolieMoves(); addFortificationMoves(); return moves; } @@ -347,7 +371,7 @@ function computeLegalMoves(room, square){ } } }); - addAdoubementMoves(); addFolieMoves(); + addAdoubementMoves(); addFolieMoves(); addFortificationMoves(); return moves; } @@ -364,7 +388,7 @@ function computeLegalMoves(room, square){ return moves; } - addAdoubementMoves(); addFolieMoves(); + addAdoubementMoves(); addFolieMoves(); addFortificationMoves(); return moves; } @@ -850,6 +874,33 @@ io.on('connection', (socket) => { played.payload = Object.assign({}, payload, { applied: 'folie', appliedTo: target }); }catch(e){ console.error('folie effect error', e); } } + // fortification: grant permanent rook-move ability to the targeted piece + else if(cardId === 'fortification' || (typeof cardId === 'string' && cardId.indexOf('fortification') !== -1)){ + 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 permanent fortification effect (bind to piece id so it persists when the piece moves) + room.activeCardEffects = room.activeCardEffects || []; + 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); } + } // rebondir: grant a one-time bounce ability to a specific piece (targetSquare required in payload) else if(cardId === 'rebondir_sur_les_bords' || cardId === 'rebondir' || (typeof cardId === 'string' && cardId.indexOf('rebondir') !== -1)){ try{