feat: système d'objets achetables (boutique + effets permanents) et refonte visuelle
- Nouveaux personnages illustrés (12 PNG remplacés dans client/public/cards) - 4 objets achetables (Trébuchet, Charrue, Trousse du Médecin, Sceau Royal) avec effets permanents (double_gain, guaranteed_gain, copy_best_in_game), stock unique par partie, priorité d'achat tournante entre joueurs - Boutique en colonne à gauche du plateau : icônes compactes, carte détaillée agrandie au survol (taille découplée du displayScale du jeton), bouton ACHETER actif/grisé selon la jauge du joueur, retrait immédiat de la colonne une fois l'objet acheté (les autres remontent pour combler) - Objets achetés affichés "posés sur la table" : à côté de la main pour soi, sous le slot de jeu pour les adversaires - Icône du premier joueur (priorité d'achat) dans le HUD Vue - Refonte des cartes personnage (CardObject) : portrait plein cadre épuré, valeurs d'attribut discrètes aux 4 coins - Fix removePlayer : nettoyage de pendingBuys/pendingPlays et recalage de firstPlayerIndex à la déconnexion d'un joueur - 77 tests unitaires serveur (node:test) : cards, items, Room, RoomManager - README mis à jour avec les règles complètes du jeu - .gitignore : exclusion de .idea/ et .serena/ (artefacts d'outils locaux)
This commit is contained in:
1 parent
da06ecaf2d
commit
6a1c800253
37 files changed
+3558
-188
No files matched your search
+24
-7
@@ -58,6 +58,24 @@ io.on('connection', (socket) => {
|
||||
socket.emit('game-state', room.getStateFor(socket.id))
|
||||
})
|
||||
|
||||
// ─── Acheter un objet ────────────────────────────────────────────────────────
|
||||
socket.on('buy-item', ({ roomId, itemId }) => {
|
||||
const room = rooms.get(roomId)
|
||||
if (!room) return
|
||||
|
||||
const result = room.buyItem(socket.id, itemId)
|
||||
if (!result.ok) {
|
||||
socket.emit('error', { message: result.error })
|
||||
return
|
||||
}
|
||||
|
||||
// L'achat est différé (résolu avec le tour) : on renvoie juste l'état à
|
||||
// jour à chaque joueur pour refléter la tentative en attente.
|
||||
room.players.forEach(player => {
|
||||
io.to(player.socketId).emit('game-state', room.getStateFor(player.socketId))
|
||||
})
|
||||
})
|
||||
|
||||
// ─── Jouer une carte ─────────────────────────────────────────────────────────
|
||||
socket.on('play-card', ({ roomId, cardId }) => {
|
||||
const room = rooms.get(roomId)
|
||||
@@ -87,19 +105,18 @@ io.on('connection', (socket) => {
|
||||
const roundResult = room.resolveRound()
|
||||
console.log(`[${roomId}] Tour ${room.currentTurn} résolu`)
|
||||
|
||||
// Révéler les cartes jouées et les gains par attribut
|
||||
// Révéler les cartes jouées, les gains par attribut, et les objets achetés
|
||||
io.to(roomId).emit('round-result', {
|
||||
playedCards: roundResult.playedCards,
|
||||
gains: roundResult.gains,
|
||||
boughtItems: roundResult.boughtItems,
|
||||
message: roundResult.message
|
||||
})
|
||||
|
||||
// Mise à jour scores
|
||||
io.to(roomId).emit('game-state', {
|
||||
players: room.getPlayersInfo(),
|
||||
currentTurn: room.currentTurn,
|
||||
maxTurns: room.maxTurns,
|
||||
phase: 'resolve'
|
||||
// Mise à jour scores (état personnalisé par joueur : items, achat en
|
||||
// attente, objets encore disponibles, etc.)
|
||||
room.players.forEach(player => {
|
||||
io.to(player.socketId).emit('game-state', room.getStateFor(player.socketId))
|
||||
})
|
||||
|
||||
// 3 secondes d'affichage puis tour suivant / fin
|
||||
|
||||
Reference in new issue
Block a user