Fix nurse shark and remove mid-battle choice.
This commit is contained in:
+12
-40
@@ -287,27 +287,18 @@ func effectCount(e Effect, s *battleSide, u *BattleUnit, enemy *battleSide) int
|
||||
// attack manages to hurt. A clash that changes nothing ends the battle as a
|
||||
// stalemate.
|
||||
//
|
||||
// resolveBattle is the orchestrator: it re-runs the (deterministic) simulation
|
||||
// from the recorded dice/decision tapes, publishing either a completed result
|
||||
// or a suspended one awaiting a mid-battle decision (Golden pack: Nurse Shark).
|
||||
// resolveBattle is the orchestrator: it runs the (deterministic) simulation and
|
||||
// publishes the completed result.
|
||||
func (g *Game) resolveBattle() {
|
||||
g.NextCardID = g.BattleCardBase
|
||||
g.battleRollCursor = 0
|
||||
g.battleDecisionCursor = 0
|
||||
res, pending := g.runBattle()
|
||||
res := g.runBattle()
|
||||
g.Battle = res
|
||||
if pending != nil {
|
||||
g.PendingBattle = pending
|
||||
return
|
||||
}
|
||||
g.PendingBattle = nil
|
||||
g.finalizeBattle(res)
|
||||
}
|
||||
|
||||
// finalizeBattle applies the persistent effects of a completed battle: trophies,
|
||||
// the priority token hand-off, the result log line, and clearing the per-round
|
||||
// apples-in-play bank. Deferred here (not inside runBattle) because runBattle
|
||||
// may re-run several times before the battle actually completes.
|
||||
// apples-in-play bank. Kept separate from runBattle, which mutates no persistent
|
||||
// player state.
|
||||
func (g *Game) finalizeBattle(res *BattleResult) {
|
||||
n := len(g.Players)
|
||||
winner := res.WinnerSeat
|
||||
@@ -332,13 +323,11 @@ func (g *Game) finalizeBattle(res *BattleResult) {
|
||||
}
|
||||
}
|
||||
|
||||
// runBattle plays the simulation to completion or until it needs a mid-battle
|
||||
// decision, returning the (partial) result and a non-nil pending in the latter
|
||||
// case. It mutates no persistent player state — that is finalizeBattle's job.
|
||||
func (g *Game) runBattle() (*BattleResult, *PendingBattleDecision) {
|
||||
// runBattle plays the simulation to completion, returning the result. It
|
||||
// mutates no persistent player state — that is finalizeBattle's job.
|
||||
func (g *Game) runBattle() *BattleResult {
|
||||
n := len(g.Players)
|
||||
res := &BattleResult{Round: g.Round, WinnerSeat: -1, StackSizes: make([]int, n), Lineups: make([][]Card, n)}
|
||||
var suspended *PendingBattleDecision
|
||||
sides := make([]*battleSide, n)
|
||||
emit := func(ev BattleEvent) { res.Events = append(res.Events, ev) }
|
||||
// pname is the owning player's display name for a seat, for log text.
|
||||
@@ -1190,19 +1179,10 @@ func (g *Game) runBattle() (*BattleResult, *PendingBattleDecision) {
|
||||
Text: fmt.Sprintf("%s shuffles an apple into %s's deck.", q.unit.Card.Name, pname(q.seat))})
|
||||
}
|
||||
case ActionSpendRocks:
|
||||
// Nurse Shark: the owner chooses how many Trumpets (0..available,
|
||||
// capped at Count) to spend; each throws two rocks. This is the one
|
||||
// mid-battle decision — it may suspend the whole simulation.
|
||||
// Nurse Shark: spend as many Trumpets as available (up to Count) to
|
||||
// throw two rocks each.
|
||||
s := sides[q.seat]
|
||||
maxSpend := min(q.effect.count(), s.trumpets)
|
||||
choice, pending := g.decideBattle(PendingBattleDecision{
|
||||
Seat: q.seat, Kind: "nurseShark", PetName: q.unit.Card.Name,
|
||||
Min: 0, Max: maxSpend, Trumpets: s.trumpets,
|
||||
})
|
||||
if pending != nil {
|
||||
suspended = pending
|
||||
break
|
||||
}
|
||||
choice := min(q.effect.count(), s.trumpets)
|
||||
if choice > 0 {
|
||||
s.trumpets -= choice
|
||||
emit(BattleEvent{Type: "trumpet", Seat: q.seat, Count: -choice,
|
||||
@@ -1214,14 +1194,6 @@ func (g *Game) runBattle() (*BattleResult, *PendingBattleDecision) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if suspended != nil {
|
||||
break // stop mid-plays; the battle re-runs once the choice is in
|
||||
}
|
||||
}
|
||||
// A pending decision unwinds the whole simulation; the events emitted so
|
||||
// far are a valid prefix the re-run reproduces exactly.
|
||||
if suspended != nil {
|
||||
return res, suspended
|
||||
}
|
||||
// Battle over? A side that can no longer field a pet is out (checked
|
||||
// after play effects so parting shots land, using canField so a pet that
|
||||
@@ -1337,5 +1309,5 @@ func (g *Game) runBattle() (*BattleResult, *PendingBattleDecision) {
|
||||
res.Trophies = 2
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
return res
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user