173 lines
3.9 KiB
TypeScript
173 lines
3.9 KiB
TypeScript
// Mirrors of the Go view types (internal/game/view.go).
|
|
|
|
export type Suit = 'red' | 'blue' | 'yellow'
|
|
export type CardKind = 'pet' | 'food'
|
|
export type Phase = 'lobby' | 'shop' | 'arrange' | 'battle' | 'gameover'
|
|
|
|
export interface Card {
|
|
id: string
|
|
kind: CardKind
|
|
name: string
|
|
tier?: number
|
|
power?: number
|
|
suit?: Suit
|
|
effects?: unknown[]
|
|
effectText?: string
|
|
food?: string
|
|
perk?: boolean
|
|
temporary?: boolean
|
|
}
|
|
|
|
export interface PlayerView {
|
|
id: string
|
|
name: string
|
|
seat: number
|
|
coins: number
|
|
trophies: number
|
|
ready: boolean
|
|
connected: boolean
|
|
isBot?: boolean
|
|
deckSize: number
|
|
petCount: number
|
|
avocados?: number // set-aside Avocado tokens (Golden pack)
|
|
firstBuyFree?: boolean // Manta Ray: next buy is free (self only)
|
|
buysThisRound?: number // Blue-Ringed Octopus counter (self only)
|
|
deck?: Card[]
|
|
}
|
|
|
|
export interface PendingTrade {
|
|
playerId: string
|
|
tier: number
|
|
options: [Card, Card]
|
|
}
|
|
|
|
// Cockatoo (Golden pack): the buyer must reveal one of their pets.
|
|
export interface PendingReveal {
|
|
playerId: string
|
|
source: string
|
|
options?: string[] // eligible pet card ids (buyer only)
|
|
}
|
|
|
|
// Nurse Shark (Golden pack): a mid-battle Trumpet-spend choice.
|
|
export interface PendingBattleDecision {
|
|
seat: number
|
|
kind: string
|
|
petName: string
|
|
min: number
|
|
max: number
|
|
trumpets: number
|
|
}
|
|
|
|
export interface BattleEvent {
|
|
type:
|
|
| 'prep'
|
|
| 'reveal'
|
|
| 'summon'
|
|
| 'mill'
|
|
| 'rock'
|
|
| 'clash'
|
|
| 'shield'
|
|
| 'strip'
|
|
| 'steal'
|
|
| 'eat'
|
|
| 'heal'
|
|
| 'setaside'
|
|
| 'release'
|
|
| 'trumpet' // a side gains (+) or spends/loses (-) Trumpets (Golden pack)
|
|
| 'prevent' // a Cone Snail shaves damage off a hit (Golden pack)
|
|
seat?: number
|
|
target?: number
|
|
card?: Card
|
|
count?: number
|
|
// clash
|
|
damage?: number[]
|
|
died?: boolean[]
|
|
// rock / strip / steal
|
|
roll?: number
|
|
dice?: number[] // rock: individual die faces (each 0, 1, or 2)
|
|
damageAfter?: number
|
|
targetDied?: boolean
|
|
// eat (new bonus total) / reveal (starting bonus)
|
|
bonus?: number
|
|
// human-readable description of this step for the event log
|
|
text?: string
|
|
}
|
|
|
|
export interface BattleResult {
|
|
round: number
|
|
stackSizes: number[]
|
|
lineups?: Card[][] // each seat's arranged deck (top first); public for peeking
|
|
events: BattleEvent[] | null
|
|
winnerSeat: number
|
|
trophies: number
|
|
}
|
|
|
|
export interface LogEntry {
|
|
seq: number
|
|
round: number
|
|
phase: Phase
|
|
seat: number // acting seat, or -1
|
|
icon?: string
|
|
kind?: string // e.g. 'result' (battle outcome)
|
|
text: string
|
|
source?: string // card id that caused a spawn
|
|
spawn?: string // 'apple' | 'bee'
|
|
}
|
|
|
|
export interface PackInfo {
|
|
id: string
|
|
name: string
|
|
emoji: string
|
|
playable: boolean
|
|
}
|
|
|
|
export interface GameView {
|
|
gameId: string
|
|
code: string
|
|
phase: Phase
|
|
round: number
|
|
maxRounds: number
|
|
maxPets: number
|
|
pack: string
|
|
packs: PackInfo[]
|
|
hostSeat: number
|
|
minPlayers: number
|
|
maxPlayers: number
|
|
youSeat: number
|
|
turn: number
|
|
shopRow: Card[]
|
|
deckCounts: number[]
|
|
players: PlayerView[]
|
|
pending?: PendingTrade
|
|
pendingReveal?: PendingReveal
|
|
pendingBattle?: PendingBattleDecision
|
|
battle?: BattleResult
|
|
winnerSeat: number
|
|
log?: LogEntry[]
|
|
debug?: boolean // server DEBUG mode: unlocks the buy-any-card panel
|
|
}
|
|
|
|
export type ClientMessage =
|
|
| { type: 'setPack'; pack: string }
|
|
| { type: 'addBot'; difficulty: string }
|
|
| { type: 'removePlayer'; target: string }
|
|
| { type: 'start' }
|
|
| { type: 'buy'; row: number }
|
|
| { type: 'buyAvocado'; row: number }
|
|
| { type: 'sell'; cards: string[] }
|
|
| { type: 'trade'; cards: string[] }
|
|
| { type: 'tradeChoose'; pick: number }
|
|
| { type: 'revealChoose'; card: string }
|
|
| { type: 'battleChoose'; value: number }
|
|
| { type: 'pass' }
|
|
| { type: 'arrange'; order: string[] }
|
|
| { type: 'ready' }
|
|
| { type: 'debugAdd'; name: string }
|
|
|
|
export interface Session {
|
|
gameId: string
|
|
code: string
|
|
playerId: string
|
|
token: string
|
|
}
|