Improve rock attribution.

This commit is contained in:
Greyson Parrelli
2026-07-23 11:17:56 -04:00
parent 235b1d9cc8
commit 816ad13f7e
2 changed files with 43 additions and 20 deletions
+37 -20
View File
@@ -172,7 +172,7 @@ type battleSide struct {
petBonus int // Mammoth aura: +power for later friendly pets
oneShotRocks []setAsideRocks // Badger/Blowfish: on next own pet play
recurringRocks []int // Snake: on every own pet play
recurringRocks []setAsideRocks // Snake: on every own pet play
lastPetRocks []lastPetVolley // Crocodile: when the enemy plays their last pet
shieldCards []Card // Turtle set-aside cards, parallel to shields
}
@@ -194,6 +194,7 @@ type queuedPlay struct {
effect Effect
everyone bool // rock volley hits every active pet (Badger)
release *Card // set-aside card to release once this play resolves (Blowfish/Badger/Croc)
source *Card // set-aside pet credited as the effect's source (Blowfish/Badger/Croc/Snake)
}
// effectCount resolves an effect's final count: base × Per statistic,
@@ -389,7 +390,8 @@ func (g *Game) resolveBattle() {
setAsideRocks{dice: e.count(), everyone: e.Target == "all", src: u.Card})
setAside()
case ActionRecurringRocks:
s.recurringRocks = append(s.recurringRocks, e.count())
s.recurringRocks = append(s.recurringRocks,
setAsideRocks{dice: e.count(), src: u.Card})
setAside()
case ActionEnemyLastPetRocks:
s.lastPetRocks = append(s.lastPetRocks, lastPetVolley{dice: e.count(), src: u.Card})
@@ -457,7 +459,7 @@ func (g *Game) resolveBattle() {
// throwRocks rolls `dice` rock dice against one seat's pet. Rocks are
// not "attacks with" the pet, so no knockout applies. Reports a kill.
throwRocks := func(from, target, dice int) (killed bool) {
throwRocks := func(from, target, dice int, source *Card) (killed bool) {
tu := sides[target].unit
if tu == nil {
return false
@@ -470,18 +472,32 @@ func (g *Game) resolveBattle() {
}
dealt, block := hitUnit(target, roll)
died := !tu.Alive()
thrower := pname(from)
if su := sides[from].unit; su != nil {
thrower = su.Card.Name
}
// A set-aside pet (Snake/Blowfish/Badger/Croc) throws its rocks after a
// different pet has been played, so credit `source` explicitly; only
// fall back to the pet in play for direct throwers (Hedgehog/Rhino).
var rockTxt string
switch {
case roll == 0:
rockTxt = fmt.Sprintf("%s's rocks miss %s.", thrower, tu.Card.Name)
case died:
rockTxt = fmt.Sprintf("%s pelts %s for %d — it faints.", thrower, tu.Card.Name, roll)
default:
rockTxt = fmt.Sprintf("%s pelts %s for %d.", thrower, tu.Card.Name, roll)
if source != nil {
switch {
case roll == 0:
rockTxt = fmt.Sprintf("%s's set-aside rocks miss %s.", source.Name, tu.Card.Name)
case died:
rockTxt = fmt.Sprintf("%s's set-aside rocks pelt %s for %d — it faints.", source.Name, tu.Card.Name, roll)
default:
rockTxt = fmt.Sprintf("%s's set-aside rocks pelt %s for %d.", source.Name, tu.Card.Name, roll)
}
} else {
thrower := pname(from)
if su := sides[from].unit; su != nil {
thrower = su.Card.Name
}
switch {
case roll == 0:
rockTxt = fmt.Sprintf("%s's rocks miss %s.", thrower, tu.Card.Name)
case died:
rockTxt = fmt.Sprintf("%s pelts %s for %d — it faints.", thrower, tu.Card.Name, roll)
default:
rockTxt = fmt.Sprintf("%s pelts %s for %d.", thrower, tu.Card.Name, roll)
}
}
emit(BattleEvent{
Type: "rock", Seat: from, Target: target, Roll: roll, Dice: faces,
@@ -561,12 +577,13 @@ func (g *Game) resolveBattle() {
for _, r := range s.oneShotRocks {
src := r.src
plays = append(plays, queuedPlay{seat: seat, everyone: r.everyone,
effect: Effect{Action: ActionThrowRock, Count: r.dice}, release: &src})
effect: Effect{Action: ActionThrowRock, Count: r.dice}, release: &src, source: &src})
}
s.oneShotRocks = nil
for _, dice := range s.recurringRocks {
for _, r := range s.recurringRocks {
src := r.src
plays = append(plays, queuedPlay{seat: seat,
effect: Effect{Action: ActionThrowRock, Count: dice}})
effect: Effect{Action: ActionThrowRock, Count: r.dice}, source: &src})
}
// Walk the pet's own play effects, then its active perk's, so a
// play-time shield knows its source (an innate pet block vs a
@@ -622,7 +639,7 @@ func (g *Game) resolveBattle() {
for _, v := range os.lastPetRocks {
src := v.src
plays = append(plays, queuedPlay{seat: other,
effect: Effect{Action: ActionThrowRock, Count: v.dice}, release: &src})
effect: Effect{Action: ActionThrowRock, Count: v.dice}, release: &src, source: &src})
}
os.lastPetRocks = nil
}
@@ -669,12 +686,12 @@ func (g *Game) resolveBattle() {
}
if q.everyone {
for seat := range sides {
if throwRocks(q.seat, seat, dice) {
if throwRocks(q.seat, seat, dice, q.source) {
anyDeath = true
}
}
} else if t := nextTarget(q.seat); t >= 0 {
if throwRocks(q.seat, t, dice) {
if throwRocks(q.seat, t, dice, q.source) {
anyDeath = true
}
}