remove played card

This commit is contained in:
Didictateur 2025-11-22 16:39:09 +01:00
parent 32bbf5b0d0
commit 4b3e1ed5c0
2 changed files with 57 additions and 24 deletions

View file

@ -22,10 +22,7 @@
</div>
<pre id="log" style="margin-top:8px;height:160px;overflow:auto">logs...</pre>
</section>
<section class="card" id="handsSection" style="margin-top:12px">
<div><strong>Cartes du joueur</strong></div>
<div id="hands" style="margin-top:8px;display:flex;flex-direction:column;gap:8px"></div>
</section>
<div id="hands" style="margin-top:8px;display:flex;flex-direction:column;gap:8px"></div>
</aside>
</div>
@ -120,6 +117,31 @@
showCardDrawnNotification(data);
}catch(e){ console.warn('card:drawn handler error', e); }
});
// when a card is played by any player, ensure the UI removes it from the owner's hand
socket.on('card:played', (data) => {
try{
log('recv card:played', data);
// data.played or data depending on server shape
const played = data && data.played ? data.played : data;
const cardObj = played && (played.card || played.cardObj || null);
const owner = played && played.playerId;
// if we have the card object and it's our card, remove its DOM element
if(owner === myPlayerId){
// find the card element by uuid (data-card-uuid) or by cardId
const row = document.querySelector('.cards-row');
if(row){
const elems = Array.from(row.querySelectorAll('.pokemon-card'));
elems.forEach(el => {
const uuid = el.dataset.cardUuid || '';
const cid = el.dataset.cardId || '';
if((cardObj && cardObj.id && uuid && uuid === cardObj.id) || (cardObj && cardObj.cardId && cid && cid === cardObj.cardId)){
el.remove();
}
});
}
}
}catch(e){ console.warn('card:played handler error', e); }
});
// selection events (include moves) broadcasted by server
socket.on('game:select', (data) => {
try{
@ -445,21 +467,9 @@
const header = document.createElement('div');
header.className = 'pokemon-hand-header';
const title = document.createElement('div');
title.textContent = 'Votre main';
title.textContent = 'Vos cartes';
title.className = 'pokemon-hand-title';
header.appendChild(title);
// show public counts for other players (small badges)
const countsWrap = document.createElement('div');
countsWrap.className = 'pokemon-hand-counts';
Object.entries(handCounts||{}).forEach(([pid, cnt])=>{
if(pid === myPlayerId) return;
const b = document.createElement('div');
b.className = 'opponent-count';
b.textContent = `${pid}: ${cnt}`;
countsWrap.appendChild(b);
});
header.appendChild(countsWrap);
wrap.appendChild(header);
const row = document.createElement('div');

View file

@ -27,7 +27,8 @@ function sendRoomUpdate(room){
hostId: room.hostId,
size: (room.boardState && room.boardState.width) || room.size,
cards: Object.keys(room.cards || {}),
deckCount: (room.deck && room.deck.length) || 0
deckCount: (room.deck && room.deck.length) || 0,
discardCount: (room.discard && room.discard.length) || 0
};
const handCounts = {};
@ -571,10 +572,32 @@ io.on('connection', (socket) => {
socket.on('card:play', ({ roomId, playerId, cardId, payload }, cb) => {
const room = rooms.get(roomId);
if(!room) return cb && cb({ error: 'room not found' });
// enforce sender identity from socket (don't trust client-supplied playerId)
const senderId = socket.data.playerId;
if(!senderId) return cb && cb({ error: 'not joined' });
// store played card and apply card effects when applicable
const played = { id: uuidv4().slice(0,8), playerId, cardId, payload, ts: Date.now() };
const played = { id: uuidv4().slice(0,8), playerId: senderId, cardId, payload, ts: Date.now() };
room.playedCards = room.playedCards || [];
// remove the played card from the player's hand and move it to discard
try{
room.hands = room.hands || {};
const hand = room.hands[senderId] || [];
// find by unique id or by cardId (first match)
const idx = hand.findIndex(c => (c.id && c.id === (payload && payload.id)) || (c.cardId && c.cardId === cardId) || (c.id && c.id === cardId));
if(idx === -1){
return cb && cb({ error: 'you do not have that card' });
}
const removed = hand.splice(idx,1)[0];
room.hands[senderId] = hand;
room.discard = room.discard || [];
room.discard.push(removed);
// attach the removed card object to the played record for informational broadcast
played.card = removed;
}catch(e){
console.error('card removal error', e);
}
// Implement specific card effects here
try{
if(cardId === 'agrandir_plateau' || cardId === 'expand_board'){
@ -618,11 +641,11 @@ io.on('connection', (socket) => {
console.error('card:play effect error', e);
}
room.playedCards.push(played);
// emit card played to entire room (informational)
io.to(roomId).emit('card:played', played);
// send personalized room updates
sendRoomUpdate(room);
room.playedCards.push(played);
// emit card played to entire room (informational)
io.to(roomId).emit('card:played', played);
// send personalized room updates (will include updated hands and discardCount)
sendRoomUpdate(room);
cb && cb({ ok: true, played });
});