remove played card
This commit is contained in:
parent
32bbf5b0d0
commit
4b3e1ed5c0
2 changed files with 57 additions and 24 deletions
|
|
@ -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');
|
||||
|
|
|
|||
37
server.js
37
server.js
|
|
@ -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 });
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue