Files
super-auto-pets-board-game/internal/game/cards.go
T

1448 lines
61 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package game
import "fmt"
// Suit is the colored trade-in symbol printed on pet cards. Three pets of
// the same suit can be traded (the "Triple" action) for a pick from the next
// tier's deck.
type Suit string
const (
SuitRed Suit = "red"
SuitBlue Suit = "blue"
SuitYellow Suit = "yellow"
)
// CardKind distinguishes pets from foods.
type CardKind string
const (
KindPet CardKind = "pet"
KindFood CardKind = "food"
// KindAilment (Unicorn pack) is a temporary debuff card (Spooked, Exposed)
// attached to a pet during battle. It is neither a pet nor a food.
KindAilment CardKind = "ailment"
)
// Food identifiers.
const (
FoodApple = "apple"
FoodHoney = "honey"
FoodGarlic = "garlic"
FoodPineapple = "pineapple"
FoodChili = "chili"
FoodMelon = "melon"
// FoodAvocado (Golden pack) is a persistent set-aside token: buying it puts
// it aside rather than in the deck, and it can later be discarded in place
// of spending a coin on a buy. It is neither a perk nor a battle food.
FoodAvocado = "avocado"
// FoodPotato / FoodDurian / FoodTomato (Golden pack) are perk foods.
FoodPotato = "potato"
FoodDurian = "durian"
FoodTomato = "tomato"
// FoodFairyDust (Unicorn pack) is a perk food: the pet it's on gains 1 Mana
// when played. FoodWaterOfYouth is a one-shot shop food (not a perk) that
// upgrades a pet into a next-tier card.
FoodFairyDust = "fairyDust"
FoodWaterOfYouth = "waterOfYouth"
// Unicorn pack perk foods, tiers 4-6.
FoodHealthPotion = "healthPotion" // Hurt: heal 3 damage
FoodBigManaPotion = "bigManaPotion" // Play: gain 3 Mana
FoodCornucopia = "cornucopia" // Play: eat 2 Apples, add 2 on deck
)
// EffectTrigger is when an effect fires.
type EffectTrigger string
const (
TriggerFaint EffectTrigger = "faint" // defeated in battle
TriggerSell EffectTrigger = "sell" // sold in the shop (the discard→apple action)
TriggerBuy EffectTrigger = "buy" // purchased (also fires on pets gained via Triple)
TriggerPlay EffectTrigger = "play" // revealed on the stack during battle
TriggerTriple EffectTrigger = "triple" // used as one of the three traded-in cards
TriggerHurt EffectTrigger = "hurt" // attacked and received damage
// TriggerBattlePrep fires right after the shop phase ends, as players
// begin ordering their decks.
TriggerBattlePrep EffectTrigger = "battlePrep"
// TriggerEnemyFaint fires on a pet in play whenever an enemy pet faints.
TriggerEnemyFaint EffectTrigger = "enemyFaint"
// TriggerEnemyPlay fires on a pet in play whenever the enemy plays a pet.
TriggerEnemyPlay EffectTrigger = "enemyPlay"
// TriggerPassive marks always-on effects (e.g. Garlic's damage
// prevention); they're consulted contextually rather than fired.
TriggerPassive EffectTrigger = "passive"
// TriggerAfterAttack fires on a pet right after it survives a clash it
// took part in (Golden pack: Bulldog). Effects here may be marked once
// per battle via the unit's after-attack flag.
TriggerAfterAttack EffectTrigger = "afterAttack"
// TriggerShopStart fires on a pet in the deck at the moment a shop round
// opens (Golden pack: Manta Ray).
TriggerShopStart EffectTrigger = "shopStart"
)
// EffectAction is what the effect does.
type EffectAction string
const (
// ActionSummonTop puts Count cards (Effect.Card: "apple" or "bee") on
// top of a deck/stack — the owner's, or the enemy's when Target is
// "enemy". Battle-time.
ActionSummonTop EffectAction = "summonTop"
// ActionGainApple adds Count apples to the player's hand. Shop-time.
ActionGainApple EffectAction = "gainApple"
// ActionThrowRock rolls Count rock dice (faces: 0,0,1,1,2,2) and deals
// the total to the opposing pet in play. Battle-time.
ActionThrowRock EffectAction = "throwRock"
// ActionEatApple gives the pet itself +Count power (as if it ate
// apples), if it hasn't fainted. Battle-time. With Per set, Count is
// multiplied by a battle statistic (see Effect.Per).
ActionEatApple EffectAction = "eatApple"
// ActionRefreshGold returns Count spent coins to the player (never
// above the round's allowance). Shop-time.
ActionRefreshGold EffectAction = "refreshGold"
// ActionPreventDamage (passive) reduces every attack that hits this pet
// by Count damage.
ActionPreventDamage EffectAction = "preventDamage"
// ActionRecycleApples (faint) puts up to Count of this pet's attached
// apples back on top of its owner's deck.
ActionRecycleApples EffectAction = "recycleApples"
// ActionDelayedRocks (faint) sets the pet aside: when its owner plays
// their next pet, it throws Count rocks. With Target "all" (Badger)
// the volley hits EACH active pet — the owner's own included;
// otherwise it targets the enemy pet as usual (Blowfish).
ActionDelayedRocks EffectAction = "delayedRocks"
// ActionRecurringRocks (faint) sets the pet aside: EVERY time its owner
// plays a pet, it throws Count rocks at the enemy pet (Snake).
ActionRecurringRocks EffectAction = "recurringRocks"
// ActionEnemyLastPetRocks (faint) sets the pet aside: when the enemy
// plays the last pet in their deck, it throws Count rocks (Crocodile).
ActionEnemyLastPetRocks EffectAction = "enemyLastPetRocks"
// ActionShieldNext (faint) sets the pet aside: the next Count times a
// friendly pet is hit, ALL damage from that hit is prevented (Turtle).
ActionShieldNext EffectAction = "shieldNext"
// ActionShieldSelf gives the pet itself Count charges that each prevent
// all damage from one hit (Gorilla on hurt, Melon on play).
ActionShieldSelf EffectAction = "shieldSelf"
// ActionStripFoods (play) discards every food attached to the enemy
// pet in play (losing their buffs and perks, which can faint it).
ActionStripFoods EffectAction = "stripFoods"
// ActionStealApples (play) moves up to Count apples from the enemy pet
// to this pet (Wolverine). Losing apples can faint the victim.
ActionStealApples EffectAction = "stealApples"
// ActionMillEnemy (play) discards cards off the top of the enemy deck
// until a non-Bee pet is showing (Chili).
ActionMillEnemy EffectAction = "millEnemy"
// ActionHeal removes Count damage markers from the pet, if it hasn't
// fainted.
ActionHeal EffectAction = "heal"
// ActionKnockout (passive) makes any pet this pet hurts with its clash
// attack faint outright (Scorpion). Rocks don't count, and a fully
// prevented attack KOs nothing.
ActionKnockout EffectAction = "knockout"
// ActionApplesInPlay (battle prep) starts the battle with Count apples
// already in play, attached to the owner's first pet (Monkey).
ActionApplesInPlay EffectAction = "applesInPlay"
// ActionDoubleApples doubles the apples in the player's hand (Cat).
// Shop-time.
ActionDoubleApples EffectAction = "doubleApples"
// ActionBeeAura (faint) sets the pet aside: the owner's Bees have
// +Count power for the rest of the battle (Turkey).
ActionBeeAura EffectAction = "beeAura"
// ActionPetAura (faint) sets the pet aside: the owner's pets have
// +Count power for the rest of the battle (Mammoth).
ActionPetAura EffectAction = "petAura"
// --- Golden pack ---
// ActionGainTrumpet adds Count Trumpets to the acting side's battle pool
// (Groundhog, Black-Necked Stilt, Guinea Fowl, Osprey, Honduran White
// Bat). With Per set, Count is multiplied by a battle statistic.
ActionGainTrumpet EffectAction = "gainTrumpet"
// ActionDrainTrumpet removes up to Count Trumpets from the enemy side's
// pool (Flea).
ActionDrainTrumpet EffectAction = "drainTrumpet"
// ActionPreventNextHit (faint) sets the pet aside: the next time a friendly
// pet is hit, prevent Count damage from that hit (Cone Snail). Unlike
// ActionShieldNext (Turtle), it reduces rather than fully blocks.
ActionPreventNextHit EffectAction = "preventNextHit"
// ActionSummonBottom puts Count cards (Effect.Card) on the BOTTOM of a
// deck. With Target "all" it hits every player's deck (Bear).
ActionSummonBottom EffectAction = "summonBottom"
// ActionBuyTopFree (sell) takes the top card of the current tier's shop
// deck into the player's deck for free, firing its Buy effect (Stoat).
ActionBuyTopFree EffectAction = "buyTopFree"
// ActionSetAside (buy) diverts the just-bought card out of the deck into a
// persistent set-aside zone (Avocado). Shop-time.
ActionSetAside EffectAction = "setAside"
// --- Golden pack, tiers 4-5 ---
// ActionDoubleTrumpets (play) grants the side extra Trumpets equal to what
// it holds, up to Cap (Vaquita).
ActionDoubleTrumpets EffectAction = "doubleTrumpets"
// ActionBeeRocks (faint) sets the pet aside: each time its owner plays a
// Bee, throw Count rocks at the enemy (Poison Dart Frog).
ActionBeeRocks EffectAction = "beeRocks"
// ActionFeedOnPlay (faint) sets the pet aside: each time its owner plays a
// pet, spend 1 Trumpet to feed that pet Count apples — mandatory when
// affordable (Giant Isopod).
ActionFeedOnPlay EffectAction = "feedOnPlay"
// ActionStealPerk (play) takes the enemy pet's active perk and puts it on
// top of this pet's owner's deck (Raccoon).
ActionStealPerk EffectAction = "stealPerk"
// ActionRecyclePerkApples (faint) puts this pet's active perk and up to
// Count of its apples on top of the owner's deck (Macaque).
ActionRecyclePerkApples EffectAction = "recyclePerkApples"
// ActionPreventSelf (play) gives the pet Cap one-shot charges that each
// prevent Count damage from a hit (Potato perk).
ActionPreventSelf EffectAction = "preventSelf"
// ActionStripApples (play) discards every apple attached to the enemy pet
// in play (Durian perk) — like ActionStripFoods but apples only.
ActionStripApples EffectAction = "stripApples"
// ActionSpendRocks (play) spends as many Trumpets as available (up to Count)
// and throws twice that many rocks at the enemy (Nurse Shark).
ActionSpendRocks EffectAction = "spendRocks"
// ActionFirstBuyFree (shop start) makes the player's first Buy this round
// cost no gold, if they hold Count or fewer pets (Manta Ray).
ActionFirstBuyFree EffectAction = "firstBuyFree"
// ActionRevealForApples (buy) asks the player to reveal another pet in hand;
// they gain apples equal to its power (Cockatoo). Shop-time decision.
ActionRevealForApples EffectAction = "revealForApples"
// --- Golden pack, tier 6 ---
// ActionShuffleApples (play) adds Count apples to the owner's remaining
// deck and shuffles the whole deck (Komodo). Gated by ConditionFirstPet.
ActionShuffleApples EffectAction = "shuffleApples"
// ActionReactivateBuys (battle prep) re-fires the Buy ability of every pet
// in the owner's hand (Catfish).
ActionReactivateBuys EffectAction = "reactivateBuys"
// ActionStartTrumpets (buy) banks Count Trumpets to start the next battle
// with (Bird of Paradise).
ActionStartTrumpets EffectAction = "startTrumpets"
// ActionGuardRetriever (faint) sets the pet aside: the owner's Golden
// Retriever, when summoned, prevents Count damage on its first hit (German
// Shepherd).
ActionGuardRetriever EffectAction = "guardRetriever"
// --- Unicorn pack ---
// ActionGainMana adds Count Mana to the acting side. Mana is a persistent
// resource (unlike Trumpets): it is gained shop-time (Buy: Cuddle Toad,
// Thunderbird) or battle-time (Play/Faint: Alchemedes, Fur-Bearing Trout),
// kept between rounds, and spent via CostMana (see Effect.CostMana).
ActionGainMana EffectAction = "gainMana"
// ActionAddAilment attaches Count Ailment cards (Effect.Ailment: "spooked" |
// "exposed") to the enemy. Target "" hits the enemy pet in play; Target
// "enemyDeck" puts them on top of the enemy deck to snare the next pet. When
// Eat > 0 (Calygreyhound) the pet also eats that many apples. Battle-time.
ActionAddAilment EffectAction = "addAilment"
// ActionAilmentImmune (passive) makes the pet discard the first Ailment it
// would receive (or one it enters play with) — Baku.
ActionAilmentImmune EffectAction = "ailmentImmune"
// ActionThrowRockGainMana (play) throws Count rocks at the enemy pet, then
// gains 1 Mana for each rock that rolled a blank (a 0) — Tatzelwurm.
ActionThrowRockGainMana EffectAction = "throwRockGainMana"
// ActionReviveSelf (faint) puts a plain copy of this pet back on top of its
// owner's deck once per battle (the copy carries no faint ability, so it
// can't loop) — Slime.
ActionReviveSelf EffectAction = "reviveSelf"
// ActionNegateEnemyFaint (faint) sets the pet aside: the next enemy pet to
// faint has its Faint ability do nothing — Mandrake.
ActionNegateEnemyFaint EffectAction = "negateEnemyFaint"
// ActionNextRoundApple (faint) banks Count apples that land in the owner's
// hand at the start of the next round — Skeleton Dog.
ActionNextRoundApple EffectAction = "nextRoundApple"
// ActionPeekShop (passive) marks a pet whose owner may reveal it from hand to
// look at the top of the current shop deck, once per round — Bigfoot. It is
// an optional shop action (see Game.PeekShopDeck), never auto-fired.
ActionPeekShop EffectAction = "peekShop"
// ActionUpgradeNextTier (buy) discards this food and a pet from the player's
// hand to take the top card of the next tier's deck for free — Water of
// Youth. Shop-time; opens a PendingSacrifice choice.
ActionUpgradeNextTier EffectAction = "upgradeNextTier"
// --- Unicorn pack, tiers 4-6 ---
// ActionAilmentToApples (faint) sets the pet aside and arms a side guard: the
// next Ailment that would land on a friendly pet or friendly deck is replaced
// by 2 Apples on top of the owner's deck — Unicorn.
ActionAilmentToApples EffectAction = "ailmentToApples"
// ActionSmallPetAura (faint) sets the pet aside: friendly pets with base
// Power <= 2 get +Count Power for the rest of the battle — Rootlin.
ActionSmallPetAura EffectAction = "smallPetAura"
// ActionReviveNextFaint (faint) sets the pet aside (paying CostMana): the next
// time a friendly pet faints, a copy goes on the bottom of the owner's deck —
// Fairy.
ActionReviveNextFaint EffectAction = "reviveNextFaint"
// ActionGainAbility (play) reveals a random pet from the highest tier with
// discards and copies its effects onto this pet — Abomination.
ActionGainAbility EffectAction = "gainAbility"
// ActionSummonFromDiscard (faint, paying CostMana) adds Count random cards
// from the FromTier discard pile as temporary copies on top of the deck —
// Chimera.
ActionSummonFromDiscard EffectAction = "summonFromDiscard"
// ActionSummonFromTierDeck (faint, paying CostMana) adds a temporary copy of
// the top of the FromTier shop deck on top of the owner's deck — Pixiu.
ActionSummonFromTierDeck EffectAction = "summonFromTierDeck"
// ActionRockThenEat (play) throws Count rocks at the enemy pet, then feeds
// this pet Apples equal to the damage those rocks actually dealt (Exposed
// counts) — Vampire Bat. Usually gated on ConditionEnemyAilment.
ActionRockThenEat EffectAction = "rockThenEat"
// ActionBounceEnemy (play) sends the enemy pet to the bottom of the enemy
// deck as a fresh body (its Play ability stripped so it can't re-loop) —
// Loveland Frogman.
ActionBounceEnemy EffectAction = "bounceEnemy"
// ActionManaPower (passive) sets the pet's base Power to the owner's Mana at
// play time, capped at Cap — Sleipnir.
ActionManaPower EffectAction = "manaPower"
// ActionSpendManaRocks (play) spends all the owner's Mana to throw that many
// rocks at the enemy pet — Sea Serpent.
ActionSpendManaRocks EffectAction = "spendManaRocks"
// ActionSpendManaSpook (play) spends all the owner's Mana to add that many
// Spooked to the enemy pet — Bakunawa.
ActionSpendManaSpook EffectAction = "spendManaSpook"
// ActionAilmentBoost (faint) sets the pet aside: Ailments on enemy pets count
// for Count more — Manticore.
ActionAilmentBoost EffectAction = "ailmentBoost"
// ActionManaFeedOnPlay (faint) sets the pet aside: each time the owner plays a
// pet, spend 1 Mana to feed it Count Apples — Team Spirit.
ActionManaFeedOnPlay EffectAction = "manaFeedOnPlay"
// ActionRevealTierForApples (buy) opens a reveal of a hand pet at tier <= Cap
// for Count Apples — Quetzalcoatl. Shop-time.
ActionRevealTierForApples EffectAction = "revealTierForApples"
)
// Per multipliers for dynamic effect counts.
const (
PerFaintedBees = "faintedBees" // × friendly bees fainted this battle
PerFaintedPets = "faintedPets" // × friendly pets fainted this battle
PerEatenApples = "eatenApples" // × apples this pet ate (its attached apples)
PerPower = "power" // × this pet's current power
// PerUniqueFaintedHats × distinct suits ("hats") among friendly fainted
// pets this battle (Honduran White Bat). Battle-time.
PerUniqueFaintedHats = "uniqueFaintedHats"
// PerEnemyFaintedPets × pets the ENEMY side has fainted this battle (Royal
// Flycatcher). Battle-time.
PerEnemyFaintedPets = "enemyFaintedPets"
// PerShopFaintPets × pets currently in the shop row with a Faint effect
// (Opossum). Shop-time.
PerShopFaintPets = "shopFaintPets"
// PerBuysThisRound × Buy actions the player has taken this round, including
// the current one (Blue-Ringed Octopus). Shop-time.
PerBuysThisRound = "buysThisRound"
)
// Effect conditions.
const (
ConditionTripled = "tripledThisRound" // player Tripled during this round's shop
ConditionHasPerk = "hasPerk" // this pet has a perk attached
ConditionFirstPet = "firstPet" // this is the first pet the side has played (Komodo)
// ConditionEnemyAilment gates a battle effect on the enemy pet in play
// carrying at least one Ailment (Unicorn pack: Mothman).
ConditionEnemyAilment = "enemyAilment"
// ConditionEvenRound gates a battle effect to even-numbered rounds (Unicorn
// pack: Werewolf).
ConditionEvenRound = "evenRound"
)
// Ailment kinds (Unicorn pack). Ailments are temporary debuff cards attached to
// a pet during battle; they stack and are removed at the end of the round.
const (
AilmentSpooked = "spooked" // the pet deals N less damage in a clash (min 0)
AilmentExposed = "exposed" // the pet takes N extra damage each time it is hit
)
// Effect is one trigger→action pair printed on a card.
type Effect struct {
Trigger EffectTrigger `json:"trigger"`
Action EffectAction `json:"action"`
Card string `json:"card,omitempty"` // summonTop: "apple" | "bee"
Count int `json:"count,omitempty"` // 0 means 1
Target string `json:"target,omitempty"` // summonTop: "" (self) | "enemy"
// Per multiplies Count by a battle statistic (e.g. PerFaintedBees).
Per string `json:"per,omitempty"`
// Cap limits the final count when > 0 ("up to N").
Cap int `json:"cap,omitempty"`
// Condition gates the effect (e.g. ConditionTripled).
Condition string `json:"condition,omitempty"`
// MinRound gates the effect to round >= MinRound (0 = always).
MinRound int `json:"minRound,omitempty"`
// CostTrumpet, when > 0, is a Trumpet cost the acting side must pay for the
// effect to fire (Golden pack). It's auto-paid when affordable and the
// effect is skipped otherwise — battles take no player input.
CostTrumpet int `json:"costTrumpet,omitempty"`
// CostMana, when > 0, is a Mana cost paid the same way as CostTrumpet
// (Unicorn pack). Unlike Trumpets, Mana persists across rounds.
CostMana int `json:"costMana,omitempty"`
// Ailment names the debuff an ActionAddAilment applies ("spooked" |
// "exposed"); Count is how many (Unicorn pack).
Ailment string `json:"ailment,omitempty"`
// Eat, on an ActionAddAilment, also feeds the pet that many apples
// (Calygreyhound spends 1 Mana to eat and spook in one ability).
Eat int `json:"eat,omitempty"`
// FromTier names a tier a battle effect pulls from — a discard pile (Chimera)
// or a shop deck (Pixiu) — 1-based (Unicorn pack).
FromTier int `json:"fromTier,omitempty"`
// Once marks an After-Attack effect that fires at most once per battle
// (Bulldog); without it the effect fires after every clash survived
// (Behemoth).
Once bool `json:"once,omitempty"`
// SurviveOnly marks a Hurt effect that fires only when the pet lives through
// the hit. By default a Hurt effect still fires on a fatal hit (the Lizard
// drops its Bee even when killed); self-buffs that are pointless once the
// pet is gone (Peacock's apple, Gorilla's shield) opt out with this.
SurviveOnly bool `json:"surviveOnly,omitempty"`
// Posthumous marks a Play effect that still resolves even after its own pet
// has left play — so the Manatee still adds its Apples after rocking itself
// to death.
Posthumous bool `json:"posthumous,omitempty"`
}
// count normalizes the zero value to 1.
func (e Effect) count() int {
if e.Count <= 0 {
return 1
}
return e.Count
}
// Card is a single physical card instance. IDs are unique per game.
type Card struct {
ID string `json:"id"`
Kind CardKind `json:"kind"`
Name string `json:"name"`
Tier int `json:"tier,omitempty"`
Power int `json:"power,omitempty"`
Suit Suit `json:"suit,omitempty"`
// Effects drive the engine; EffectText is the human-readable rule shown
// on the card face.
Effects []Effect `json:"effects,omitempty"`
EffectText string `json:"effectText,omitempty"`
Food string `json:"food,omitempty"`
// Perk foods (e.g. Honey) attach like any food, but a pet only benefits
// from the last-applied perk.
Perk bool `json:"perk,omitempty"`
// Temporary cards (apples, bees) are removed from the deck after the
// next battle.
Temporary bool `json:"temporary,omitempty"`
// Ailment marks a debuff card (Unicorn pack): "spooked" | "exposed". Set
// together with Kind == KindAilment.
Ailment string `json:"ailment,omitempty"`
}
func (c Card) IsPet() bool { return c.Kind == KindPet }
func (c Card) IsFood() bool { return c.Kind == KindFood }
func (c Card) IsAilment() bool { return c.Kind == KindAilment }
// petTemplate is the printed definition of a pet. Suits lists the suit of
// each physical copy in the tier deck (one card per entry).
type petTemplate struct {
Name string
Power int
Suits []Suit
Effects []Effect
EffectText string
}
// foodTemplate is the printed definition of a food card that lives in a
// shop deck (e.g. Honey).
type foodTemplate struct {
Name string
Food string
Copies int
Perk bool
Effects []Effect
EffectText string
}
// petTiers defines the shop decks' pets. Index 0 is tier 1 (round 1)
// through index 5 for tier 6 (round 6). All six tiers are real card data.
var petTiers = [MaxRounds][]petTemplate{
{ // Tier 1
{
Name: "Ant", Power: 1, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple"}},
EffectText: "Faint: add an Apple on top of your deck",
},
{
Name: "Cricket", Power: 1, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee"}},
EffectText: "Faint: add a Bee on top of your deck",
},
{
Name: "Duck", Power: 2, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{{Trigger: TriggerSell, Action: ActionGainApple}},
EffectText: "Sell: add 1 extra Apple to your hand",
},
{
Name: "Otter", Power: 1, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionGainApple}},
EffectText: "Buy: add an Apple to your hand",
},
{
Name: "Mosquito", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock}},
EffectText: "Play: throw 1 Rock",
},
{
Name: "Fish", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerTriple, Action: ActionGainApple}},
EffectText: "Triple: add an Apple to your hand",
},
},
{ // Tier 2
{
Name: "Worm", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionGainApple, Count: 2}},
EffectText: "Buy: add 2 Apples to your hand",
},
{
Name: "Flamingo", Power: 1, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple", Count: 2}},
EffectText: "Faint: add 2 Apples on top of your deck",
},
{
Name: "Peacock", Power: 2, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerHurt, Action: ActionEatApple, SurviveOnly: true}},
EffectText: "Hurt: if this pet hasn't fainted, it eats 1 Apple",
},
{
Name: "Swan", Power: 1, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerTriple, Action: ActionRefreshGold, MinRound: 3}},
EffectText: "Triple: if it is round 3 or later, refresh a spent Gold",
},
{
Name: "Rat", Power: 4, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee", Target: "enemy"}},
EffectText: "Faint: add a Bee on top of the enemy deck",
},
{
Name: "Spider", Power: 2, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee"},
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple"},
},
EffectText: "Faint: add a Bee, then an Apple, on top of your deck",
},
},
{ // Tier 3
{
Name: "Dog", Power: 2, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionEatApple, Per: PerFaintedBees}},
EffectText: "Play: eats 1 Apple for each friendly fainted Bee",
},
{
Name: "Dolphin", Power: 2, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Count: 3}},
EffectText: "Play: throw 3 Rocks",
},
{
Name: "Giraffe", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerBattlePrep, Action: ActionGainApple, Count: 2}},
EffectText: "Battle Prep: add 2 Apples to your hand",
},
{
Name: "Camel", Power: 3, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{{Trigger: TriggerHurt, Action: ActionSummonTop, Card: "apple"}},
EffectText: "Hurt: add an Apple on top of your deck",
},
{
Name: "Sheep", Power: 3, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee", Count: 2}},
EffectText: "Faint: add 2 Bees on top of your deck",
},
{
Name: "Dodo", Power: 3, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionRecycleApples, Count: 3}},
EffectText: "Faint: put up to 3 of this pet's Apples on top of your deck",
},
{
Name: "Badger", Power: 3, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionDelayedRocks, Count: 2, Target: "all"}},
EffectText: "Faint: set aside — when you play your next pet, throw 2 Rocks at each active pet",
},
},
{ // Tier 4
{
Name: "Squirrel", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{
{Trigger: TriggerBuy, Action: ActionGainApple, Count: 2},
{Trigger: TriggerSell, Action: ActionGainApple, Count: 2},
},
EffectText: "Buy: add 2 Apples to your hand · Sell: add 2 extra Apples to your hand",
},
{
Name: "Turtle", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionShieldNext}},
EffectText: "Faint: set aside — the next time a friendly pet is hit, prevent all damage",
},
{
Name: "Rooster", Power: 4, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee", Per: PerEatenApples, Cap: 3}},
EffectText: "Faint: add a Bee on top of your deck for each Apple this pet ate, up to 3",
},
{
Name: "Bison", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerBattlePrep, Action: ActionGainApple, Count: 3, Condition: ConditionTripled}},
EffectText: "Battle Prep: if you Tripled during this round's shop, add 3 Apples to your hand",
},
{
Name: "Blowfish", Power: 3, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionDelayedRocks, Count: 3}},
EffectText: "Faint: set aside — when you play your next pet, throw 3 Rocks",
},
{
Name: "Skunk", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionStripFoods}},
EffectText: "Play: discard all Food from the enemy pet",
},
{
Name: "Hippo", Power: 4, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerEnemyFaint, Action: ActionHeal}},
EffectText: "Enemy Faints: if this pet hasn't fainted, heal 1 damage",
},
},
{ // Tier 5
{
Name: "Monkey", Power: 3, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerBattlePrep, Action: ActionApplesInPlay, Count: 3}},
EffectText: "Battle Prep: start with 3 Apples in play, attached to your first pet",
},
{
Name: "Rhino", Power: 5, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerEnemyPlay, Action: ActionThrowRock}},
EffectText: "Enemy Played: throw 1 Rock",
},
{
Name: "Crocodile", Power: 4, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionEnemyLastPetRocks, Count: 3}},
EffectText: "Faint: set aside — when the last pet in the enemy deck is played, throw 3 Rocks",
},
{
Name: "Scorpion", Power: 1, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPassive, Action: ActionKnockout}},
EffectText: "This pet KOs any pet it hurts with an attack",
},
{
Name: "Seal", Power: 3, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionSummonTop, Card: "apple", Count: 3, Condition: ConditionHasPerk}},
EffectText: "Play: if this pet has a Perk, add 3 Apples on top of your deck",
},
{
Name: "Shark", Power: 1, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionEatApple, Per: PerFaintedPets}},
EffectText: "Play: eats 1 Apple for each friendly fainted pet",
},
{
Name: "Turkey", Power: 4, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionBeeAura}},
EffectText: "Faint: set aside — your Bees have +1 power",
},
},
{ // Tier 6
{
Name: "Gorilla", Power: 6, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerHurt, Action: ActionShieldSelf, SurviveOnly: true}},
EffectText: "Hurt: the next time this pet is hit, prevent all damage",
},
{
Name: "Fly", Power: 4, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee", Count: 3}},
EffectText: "Faint: add 3 Bees on top of your deck",
},
{
Name: "Leopard", Power: 4, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Per: PerPower}},
EffectText: "Play: throw Rocks equal to this pet's power",
},
{
Name: "Mammoth", Power: 4, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionPetAura}},
EffectText: "Faint: set aside — your pets have +1 power",
},
{
Name: "Cat", Power: 2, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{
{Trigger: TriggerBuy, Action: ActionGainApple, Count: 2},
{Trigger: TriggerBuy, Action: ActionDoubleApples},
},
EffectText: "Buy: add 2 Apples to your hand, then double your Apples in hand",
},
{
Name: "Snake", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionRecurringRocks, Count: 2}},
EffectText: "Faint: set aside — each time you play a pet, throw 2 Rocks",
},
{
Name: "Wolverine", Power: 5, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionStealApples, Count: 3}},
EffectText: "Play: steal up to 3 Apples from the enemy pet",
},
},
}
// foodTiers defines the food cards mixed into each tier's shop deck.
var foodTiers = [MaxRounds][]foodTemplate{
{}, // Tier 1
{ // Tier 2
{
Name: "Honey", Food: FoodHoney, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee"}},
EffectText: "Faint: add a Bee on top of your deck",
},
},
{ // Tier 3
{
Name: "Garlic", Food: FoodGarlic, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPassive, Action: ActionPreventDamage}},
EffectText: "Every attack that hits this pet deals 1 less damage",
},
},
{ // Tier 4
{
Name: "Pineapple", Food: FoodPineapple, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Count: 3}},
EffectText: "Play: throw 3 Rocks",
},
},
{ // Tier 5
{
Name: "Chili", Food: FoodChili, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionMillEnemy}},
EffectText: "Play: discard cards from the top of the enemy deck until a non-Bee pet is showing",
},
},
{ // Tier 6
{
Name: "Melon", Food: FoodMelon, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionShieldSelf}},
EffectText: "The first time this pet is hit, prevent all damage",
},
},
}
// goldenPetTiers defines the Golden pack's pets — all six tiers. Each pet ships
// as two copies (one per listed suit).
var goldenPetTiers = [MaxRounds][]petTemplate{
{ // Tier 1
{
Name: "Groundhog", Power: 1, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionGainTrumpet}},
EffectText: "Faint: gain 1 Trumpet",
},
{
Name: "Pied Tamarin", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Count: 2, CostTrumpet: 1}},
EffectText: "Play: spend 1 Trumpet to throw 2 Rocks",
},
{
Name: "Chipmunk", Power: 1, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerSell, Action: ActionGainApple, Count: 2}},
EffectText: "Sell: add 2 extra Apples to your hand",
},
{
Name: "Cone Snail", Power: 1, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionPreventNextHit, Count: 2}},
EffectText: "Faint: set aside — the next time a friendly pet is hit, prevent 2 damage",
},
{
Name: "Bulldog", Power: 2, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerAfterAttack, Action: ActionEatApple, Once: true}},
EffectText: "After Attacking: if it hasn't fainted, eat 1 Apple (once per round)",
},
{
Name: "Opossum", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerSell, Action: ActionGainApple, Per: PerShopFaintPets}},
EffectText: "Sell: add 1 extra Apple to your hand for each Faint pet in the shop",
},
},
{ // Tier 2
{
Name: "Black-Necked Stilt", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionGainTrumpet}},
EffectText: "Faint: gain 1 Trumpet",
},
{
Name: "Lizard", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerHurt, Action: ActionSummonTop, Card: "bee"}},
EffectText: "Hurt: add a Bee on top of your deck",
},
{
Name: "Hercules Beetle", Power: 1, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerSell, Action: ActionApplesInPlay, Count: 3, MinRound: 3}},
EffectText: "Sell: if it is round 3 or later, start the battle with 3 Apples in play",
},
{
Name: "Stoat", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerSell, Action: ActionBuyTopFree}},
EffectText: "Sell: buy the top card of the shop deck for free",
},
{
Name: "Desert Rain Frog", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee", Count: 2, CostTrumpet: 1}},
EffectText: "Faint: spend 1 Trumpet to add 2 Bees on top of your deck",
},
{
Name: "Honduran White Bat", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainTrumpet, Per: PerUniqueFaintedHats}},
EffectText: "Play: gain 1 Trumpet for each unique suit among friendly fainted pets",
},
},
{ // Tier 3
{
Name: "Guinea Fowl", Power: 3, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerHurt, Action: ActionGainTrumpet}},
EffectText: "Hurt: gain 1 Trumpet",
},
{
Name: "Surgeon Fish", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionSummonTop, Card: "apple", Count: 3, CostTrumpet: 1}},
EffectText: "Play: spend 1 Trumpet to add 3 Apples on top of your deck",
},
{
Name: "Osprey", Power: 3, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionGainTrumpet},
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee"},
},
EffectText: "Faint: gain 1 Trumpet and add a Bee on top of your deck",
},
{
Name: "Anteater", Power: 3, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple"},
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee"},
},
EffectText: "Faint: add an Apple, then a Bee, on top of your deck",
},
{
Name: "Bear", Power: 4, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonBottom, Card: "bee", Target: "all"}},
EffectText: "Faint: add a Bee to the bottom of every player's deck",
},
{
Name: "Royal Flycatcher", Power: 1, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Per: PerEnemyFaintedPets}},
EffectText: "Play: throw a Rock for each enemy fainted pet",
},
{
Name: "Flea", Power: 2, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionDrainTrumpet, Count: 3}},
EffectText: "Faint: your opponent loses 3 Trumpets",
},
},
{ // Tier 4
{
Name: "Saiga Antelope", Power: 1, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainTrumpet, Per: PerFaintedPets}},
EffectText: "Play: gain 1 Trumpet for each friendly fainted pet",
},
{
Name: "Vaquita", Power: 2, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionDoubleTrumpets, Cap: 4}},
EffectText: "Play: double your Trumpets (up to 4 gained)",
},
{
Name: "Poison Dart Frog", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionBeeRocks, Count: 2}},
EffectText: "Faint: set aside — each time you play a Bee, throw 2 Rocks",
},
{
Name: "Manta Ray", Power: 4, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerShopStart, Action: ActionFirstBuyFree, Count: 4}},
EffectText: "Shop start: if you have 4 or fewer pets, your first Buy is free",
},
{
Name: "Slug", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "bee", Count: 2},
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple"},
},
EffectText: "Faint: add 2 Bees, then an Apple, on top of your deck",
},
{
Name: "Cockatoo", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionRevealForApples}},
EffectText: "Buy: reveal another pet in your hand — gain Apples equal to its Power",
},
{
Name: "Manatee", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{
{Trigger: TriggerPlay, Action: ActionThrowRock, Count: 2, Target: "self"},
{Trigger: TriggerPlay, Action: ActionSummonTop, Card: "apple", Count: 4, Posthumous: true},
},
EffectText: "Play: throw 2 Rocks at itself, then add 4 Apples on top of your deck",
},
},
{ // Tier 5
{
Name: "Nyala", Power: 4, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionGainTrumpet, Count: 2}},
EffectText: "Faint: gain 2 Trumpets",
},
{
Name: "Nurse Shark", Power: 3, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionSpendRocks, Count: 3}},
EffectText: "Play: spend up to 3 Trumpets to throw twice as many Rocks",
},
{
Name: "Giant Isopod", Power: 4, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionFeedOnPlay, Count: 2}},
EffectText: "Faint: set aside — each time you play a pet, spend 1 Trumpet to feed it 2 Apples",
},
{
Name: "Blue-Ringed Octopus", Power: 4, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionGainApple, Per: PerBuysThisRound}},
EffectText: "Buy: add an Apple to your hand for each Buy you've made this round",
},
{
Name: "Raccoon", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionStealPerk}},
EffectText: "Play: steal the enemy pet's Perk onto the top of your deck",
},
{
Name: "Fire Ant", Power: 2, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple", Count: 4}},
EffectText: "Faint: add 4 Apples on top of your deck",
},
{
Name: "Macaque", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionRecyclePerkApples, Count: 4}},
EffectText: "Faint: put this pet's Perk and up to 4 of its Apples on top of your deck",
},
},
{ // Tier 6
{
Name: "Highland Cow", Power: 3, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainTrumpet, Per: PerPower}},
EffectText: "Play: gain Trumpets equal to this pet's Power",
},
{
Name: "Wildebeest", Power: 6, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionShieldSelf, CostTrumpet: 3}},
EffectText: "Play: spend 3 Trumpets to prevent all damage the first time it is hit",
},
{
Name: "Grizzly Bear", Power: 5, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Per: PerFaintedPets}},
EffectText: "Play: throw a Rock for each friendly fainted pet",
},
{
Name: "Catfish", Power: 5, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{{Trigger: TriggerBattlePrep, Action: ActionReactivateBuys}},
EffectText: "Battle Prep: reactivate every Buy ability on the pets in your hand",
},
{
Name: "Komodo", Power: 6, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionShuffleApples, Count: 6, Condition: ConditionFirstPet}},
EffectText: "Play: if this is your first pet, shuffle 6 Apples into your deck",
},
{
Name: "Bird of Paradise", Power: 4, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{
{Trigger: TriggerBuy, Action: ActionApplesInPlay, Count: 2},
{Trigger: TriggerBuy, Action: ActionStartTrumpets, Count: 2},
},
EffectText: "Buy: start the next battle with 2 Apples and 2 Trumpets in play",
},
{
Name: "German Shepherd", Power: 5, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionGuardRetriever, Count: 5}},
EffectText: "Faint: set aside — your Golden Retriever prevents 5 damage the first time it is hit",
},
},
}
// goldenFoodTiers defines the Golden pack's food cards. Only Avocado (tier 3)
// exists so far.
var goldenFoodTiers = [MaxRounds][]foodTemplate{
{}, {}, // Tiers 1-2
{ // Tier 3
{
Name: "Avocado", Food: FoodAvocado, Copies: 2,
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionSetAside}},
EffectText: "Buy: set aside — later discard it instead of a coin to buy a card",
},
},
{ // Tier 4
{
Name: "Potato", Food: FoodPotato, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionPreventSelf, Count: 2, Cap: 2}},
EffectText: "The first two times this pet is hit, prevent 2 damage",
},
},
{ // Tier 5
{
Name: "Durian", Food: FoodDurian, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionStripApples}},
EffectText: "Play: discard all enemy Apples in play",
},
},
{ // Tier 6
{
Name: "Tomato", Food: FoodTomato, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Count: 4}},
EffectText: "Play: throw 4 Rocks",
},
},
}
// unicornPetTiers defines the Unicorn pack's pets. Tiers 1-3 are printed;
// tiers 4-6 are still being authored. Each pet ships as two copies (one per
// listed suit). The pack adds two mechanics the others don't have: Mana (a
// persistent resource spent to power abilities) and Ailments (Spooked/Exposed
// debuffs attached to enemy pets during battle).
var unicornPetTiers = [MaxRounds][]petTemplate{
{ // Tier 1
{
Name: "Alchemedes", Power: 1, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainMana}},
EffectText: "Play: gain 1 Mana",
},
{
Name: "Cuddle Toad", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionGainMana}},
EffectText: "Buy: gain 1 Mana",
},
{
Name: "Pengobble", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRock, Count: 2, CostMana: 1}},
EffectText: "Play: spend 1 Mana to throw 2 Rocks",
},
{
Name: "Barghest", Power: 1, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentSpooked}},
EffectText: "Play: add 1 Spooked to the enemy pet",
},
{
Name: "Basilisk", Power: 1, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentExposed}},
EffectText: "Play: add 1 Exposed to the enemy pet",
},
{
Name: "Baku", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPassive, Action: ActionAilmentImmune}},
EffectText: "Discard the first Ailment added to this pet",
},
},
{ // Tier 2
{
Name: "Thunderbird", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionGainMana, Count: 2}},
EffectText: "Buy: gain 2 Mana",
},
{
Name: "Gargoyle", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple", Count: 2, CostMana: 1}},
EffectText: "Faint: spend 1 Mana to add 2 Apples on top of your deck",
},
{
Name: "Frost Wolf", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionAddAilment, Ailment: AilmentExposed},
{Trigger: TriggerFaint, Action: ActionAddAilment, Ailment: AilmentExposed, Target: "enemyDeck"},
},
EffectText: "Faint: add 1 Exposed to the enemy pet and 1 on top of the enemy deck",
},
{
Name: "Mothman", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionEatApple, Count: 2, Condition: ConditionEnemyAilment}},
EffectText: "Play: if the enemy pet has an Ailment, eat 2 Apples",
},
{
Name: "Nightcrawler", Power: 1, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentSpooked, Count: 2}},
EffectText: "Play: add 2 Spooked to the enemy pet",
},
{
Name: "Bigfoot", Power: 3, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPassive, Action: ActionPeekShop}},
EffectText: "Reveal from your hand to look at the top of the shop deck (once per round)",
},
},
{ // Tier 3
{
Name: "Fur-Bearing Trout", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionGainMana},
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple", Count: 2},
},
EffectText: "Faint: gain 1 Mana and add 2 Apples on top of your deck",
},
{
Name: "Calygreyhound", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentSpooked, Eat: 1, CostMana: 1}},
EffectText: "Play: spend 1 Mana to eat 1 Apple and add 1 Spooked to the enemy pet",
},
{
Name: "Tatzelwurm", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionThrowRockGainMana, Count: 2}},
EffectText: "Play: throw 2 Rocks, then gain 1 Mana for each blank rolled",
},
{
Name: "Skeleton Dog", Power: 3, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionSummonTop, Card: "apple"},
{Trigger: TriggerFaint, Action: ActionNextRoundApple},
},
EffectText: "Faint: add 1 Apple on top of your deck and 1 to your hand next round",
},
{
Name: "Mandrake", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionNegateEnemyFaint}},
EffectText: "Faint: set aside — the next enemy Faint ability does nothing",
},
{
Name: "Lucky Cat", Power: 3, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerTriple, Action: ActionGainApple, Count: 3}},
EffectText: "Triple: add 3 Apples to your hand",
},
{
Name: "Slime", Power: 2, Suits: []Suit{SuitBlue, SuitRed},
Effects: []Effect{
{Trigger: TriggerFaint, Action: ActionReviveSelf},
{Trigger: TriggerFaint, Action: ActionAddAilment, Ailment: AilmentExposed, Target: "enemyDeck"},
},
EffectText: "Faint: put this pet on top of your deck and 1 Exposed on the enemy deck (once per round)",
},
},
{ // Tier 4
{
Name: "Roc", Power: 4, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{
{Trigger: TriggerPlay, Action: ActionGainMana},
{Trigger: TriggerSell, Action: ActionGainMana},
},
EffectText: "Play: gain 1 Mana · Sell: gain 1 Mana",
},
{
Name: "Chimera", Power: 1, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonFromDiscard, Count: 2, FromTier: 1, CostMana: 4}},
EffectText: "Faint: spend 4 Mana to add 2 random cards from the tier 1 discard pile on top of your deck",
},
{
Name: "Kraken", Power: 4, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{
{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentSpooked},
{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentSpooked, Target: "enemyDeck"},
},
EffectText: "Play: add 1 Spooked to the enemy pet and 1 on top of the enemy deck",
},
{
Name: "Unicorn", Power: 4, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionAilmentToApples}},
EffectText: "Faint: set aside — replace the next friendly Ailment with 2 Apples on your deck",
},
{
Name: "Abomination", Power: 4, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainAbility}},
EffectText: "Play: reveal a random pet from the highest tier discard pile and gain its ability",
},
{
Name: "Rootlin", Power: 4, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSmallPetAura, Count: 1}},
EffectText: "Faint: set aside — your pets with base Power 2 or less have +1 Power",
},
{
Name: "Fairy", Power: 1, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionReviveNextFaint, CostMana: 3}},
EffectText: "Faint: spend 3 Mana to set aside — the next friendly faint returns to the bottom of your deck",
},
},
{ // Tier 5
{
Name: "Kitsune", Power: 2, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainMana, Per: PerFaintedPets}},
EffectText: "Play: gain 1 Mana for each friendly fainted pet",
},
{
Name: "Pixiu", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionSummonFromTierDeck, FromTier: 6, CostMana: 4}},
EffectText: "Faint: spend 4 Mana to add the top card of the tier 6 deck on top of your deck",
},
{
Name: "Red Dragon", Power: 2, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{
{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentExposed, Count: 2},
{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentExposed, Count: 2, Target: "enemyDeck"},
{Trigger: TriggerPlay, Action: ActionThrowRock, Count: 2},
},
EffectText: "Play: add 2 Exposed to the enemy pet and 2 on the enemy deck, then throw 2 Rocks",
},
{
Name: "Amalgamation", Power: 1, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{
{Trigger: TriggerPlay, Action: ActionEatApple, Per: PerFaintedPets},
{Trigger: TriggerPlay, Action: ActionAddAilment, Ailment: AilmentSpooked, Count: 2},
},
EffectText: "Play: eat 1 Apple per friendly fainted pet, then add 2 Spooked to the enemy pet",
},
{
Name: "Vampire Bat", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionRockThenEat, Count: 2, Condition: ConditionEnemyAilment}},
EffectText: "Play: if the enemy pet has an Ailment, throw 2 Rocks, then eat Apples equal to the damage dealt",
},
{
Name: "Werewolf", Power: 2, Suits: []Suit{SuitRed, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionEatApple, Count: 6, Condition: ConditionEvenRound}},
EffectText: "Play: on an even-numbered round, eat 6 Apples",
},
{
Name: "Loveland Frogman", Power: 2, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionBounceEnemy}},
EffectText: "Play: put the enemy pet on the bottom of the enemy deck",
},
},
{ // Tier 6
{
Name: "Sleipnir", Power: 0, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerPassive, Action: ActionManaPower, Cap: 9}},
EffectText: "This pet's base Power equals your Mana (max 9)",
},
{
Name: "Sea Serpent", Power: 4, Suits: []Suit{SuitYellow, SuitRed},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionSpendManaRocks}},
EffectText: "Play: spend any number of Mana to throw that many Rocks",
},
{
Name: "Bakunawa", Power: 3, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionSpendManaSpook}},
EffectText: "Play: spend any number of Mana to add that many Spooked to the enemy pet",
},
{
Name: "Manticore", Power: 6, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionAilmentBoost, Count: 1}},
EffectText: "Faint: set aside — Ailments on enemy pets count for 1 more",
},
{
Name: "Team Spirit", Power: 4, Suits: []Suit{SuitYellow, SuitBlue},
Effects: []Effect{{Trigger: TriggerFaint, Action: ActionManaFeedOnPlay, Count: 2}},
EffectText: "Faint: set aside — each pet you play, spend 1 Mana to feed it 2 Apples",
},
{
Name: "Behemoth", Power: 6, Suits: []Suit{SuitBlue, SuitYellow},
Effects: []Effect{{Trigger: TriggerAfterAttack, Action: ActionEatApple, Count: 2}},
EffectText: "After Attacking: if it hasn't fainted, eat 2 Apples",
},
{
Name: "Quetzalcoatl", Power: 6, Suits: []Suit{SuitRed, SuitBlue},
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionRevealTierForApples, Count: 3, Cap: 3}},
EffectText: "Buy: reveal a tier 3 or lower pet from your hand to gain 3 Apples",
},
},
}
// unicornFoodTiers defines the Unicorn pack's food cards (tiers 1-3 printed).
var unicornFoodTiers = [MaxRounds][]foodTemplate{
{}, // Tier 1
{ // Tier 2
{
Name: "Fairy Dust", Food: FoodFairyDust, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainMana}},
EffectText: "Play: gain 1 Mana",
},
},
{ // Tier 3
{
Name: "Water of Youth", Food: FoodWaterOfYouth, Copies: 2,
Effects: []Effect{{Trigger: TriggerBuy, Action: ActionUpgradeNextTier}},
EffectText: "Buy: discard this and a pet to buy the top of the next tier for free",
},
},
{ // Tier 4
{
Name: "Health Potion", Food: FoodHealthPotion, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerHurt, Action: ActionHeal, Count: 3, SurviveOnly: true}},
EffectText: "Hurt: if this pet hasn't fainted, heal 3 damage",
},
},
{ // Tier 5
{
Name: "Big Mana Potion", Food: FoodBigManaPotion, Copies: 2, Perk: true,
Effects: []Effect{{Trigger: TriggerPlay, Action: ActionGainMana, Count: 3}},
EffectText: "Play: gain 3 Mana",
},
},
{ // Tier 6
{
Name: "Cornucopia", Food: FoodCornucopia, Copies: 2, Perk: true,
Effects: []Effect{
{Trigger: TriggerPlay, Action: ActionEatApple, Count: 2},
{Trigger: TriggerPlay, Action: ActionSummonTop, Card: "apple", Count: 2},
},
EffectText: "Play: eat 2 Apples and add 2 Apples on top of your deck",
},
},
}
// newCardID mints a unique card ID within the game.
func (g *Game) newCardID() string {
g.NextCardID++
return fmt.Sprintf("c%d", g.NextCardID)
}
// packTiers returns the pet and food templates for a pack, tier by tier. Only
// the Turtle pack has real data today; the other (not-yet-playable) packs fall
// back to it so this is the single seam future packs plug their cards into.
func packTiers(pack string) (*[MaxRounds][]petTemplate, *[MaxRounds][]foodTemplate) {
switch pack {
case "golden":
return &goldenPetTiers, &goldenFoodTiers
case "unicorn":
return &unicornPetTiers, &unicornFoodTiers
default: // turtle (and the placeholder packs, until they ship)
return &petTiers, &foodTiers
}
}
// buildShopDecks creates all six tier decks (unshuffled) for the game's pack.
func (g *Game) buildShopDecks() {
pets, foods := packTiers(g.Pack)
g.ShopDecks = make([][]Card, MaxRounds)
for tierIdx := range pets {
var deck []Card
for _, t := range pets[tierIdx] {
for _, suit := range t.Suits {
deck = append(deck, Card{
ID: g.newCardID(),
Kind: KindPet,
Name: t.Name,
Tier: tierIdx + 1,
Power: t.Power,
Suit: suit,
Effects: t.Effects,
EffectText: t.EffectText,
})
}
}
for _, f := range foods[tierIdx] {
for range f.Copies {
deck = append(deck, Card{
ID: g.newCardID(),
Kind: KindFood,
Name: f.Name,
Tier: tierIdx + 1,
Food: f.Food,
Perk: f.Perk,
Effects: f.Effects,
EffectText: f.EffectText,
})
}
}
g.ShopDecks[tierIdx] = deck
}
}
// Catalog returns the default pack's representative cards.
func Catalog() []Card { return CatalogForPack(DefaultPack) }
// CatalogForPack returns one representative card for every pet and food in a
// pack, tier by tier, for the debug "buy any card" panel. IDs are name-based
// placeholders (not real instances); pets use their first printed suit.
func CatalogForPack(pack string) []Card {
pets, foods := packTiers(pack)
var cards []Card
for tierIdx := range pets {
for _, t := range pets[tierIdx] {
suit := SuitRed
if len(t.Suits) > 0 {
suit = t.Suits[0]
}
cards = append(cards, Card{
ID: "pet-" + t.Name, Kind: KindPet, Name: t.Name, Tier: tierIdx + 1,
Power: t.Power, Suit: suit, Effects: t.Effects, EffectText: t.EffectText,
})
}
for _, f := range foods[tierIdx] {
cards = append(cards, Card{
ID: "food-" + f.Name, Kind: KindFood, Name: f.Name, Tier: tierIdx + 1,
Food: f.Food, Perk: f.Perk, Effects: f.Effects, EffectText: f.EffectText,
})
}
}
return cards
}
// cardByName mints a fresh instance of the named pet or food from the current
// pack's templates (pets take their first printed suit). Returns false if
// unknown.
func (g *Game) cardByName(name string) (Card, bool) {
pets, foods := packTiers(g.Pack)
for tierIdx := range pets {
for _, t := range pets[tierIdx] {
if t.Name == name {
suit := SuitRed
if len(t.Suits) > 0 {
suit = t.Suits[0]
}
return Card{
ID: g.newCardID(), Kind: KindPet, Name: t.Name, Tier: tierIdx + 1,
Power: t.Power, Suit: suit, Effects: t.Effects, EffectText: t.EffectText,
}, true
}
}
for _, f := range foods[tierIdx] {
if f.Name == name {
return Card{
ID: g.newCardID(), Kind: KindFood, Name: f.Name, Tier: tierIdx + 1,
Food: f.Food, Perk: f.Perk, Effects: f.Effects, EffectText: f.EffectText,
}, true
}
}
}
return Card{}, false
}
// newApple mints an apple food card. Apples are temporary: they vanish from
// the deck after the next battle.
func (g *Game) newApple() Card {
return Card{
ID: g.newCardID(),
Kind: KindFood,
Name: "Apple",
Food: FoodApple,
Temporary: true,
}
}
// newAilment mints an ailment debuff card (Unicorn pack). It is temporary — it
// leaves play at the end of the round, like an apple — and belongs to no deck
// until an effect attaches it to a pet or drops it on a deck.
func (g *Game) newAilment(kind string) Card {
name := "Spooked"
if kind == AilmentExposed {
name = "Exposed"
}
return Card{
ID: g.newCardID(),
Kind: KindAilment,
Name: name,
Ailment: kind,
Temporary: true,
}
}
// newBee mints a bee: a temporary 1-power pet with no effect, summoned by
// other pets' effects. It counts as a pet while it exists (foods can attach
// to it in battle).
func (g *Game) newBee() Card {
return Card{
ID: g.newCardID(),
Kind: KindPet,
Name: "Bee",
Power: 1,
Temporary: true,
}
}
// newGoldenRetriever mints the Golden pack's supply pet: a temporary,
// unbuyable pet whose base Power equals the Trumpets that summoned it. Those
// Trumpets can't be added to or removed, so it takes no auras and eats no
// apples (documented no-op today: tiers 1-3 have no auras).
func (g *Game) newGoldenRetriever(power int) Card {
return Card{
ID: g.newCardID(),
Kind: KindPet,
Name: "Golden Retriever",
Power: power,
Temporary: true,
EffectText: "Its Power equals its Trumpets, which can't be changed.",
}
}