1469 lines
62 KiB
Go
1469 lines
62 KiB
Go
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) from the game's
|
||
// selected packs. Combining packs is the rulebook's answer to seating more
|
||
// than two players: every pack's tier 1 cards shuffle together into one tier 1
|
||
// deck, its tier 2 cards into one tier 2 deck, and so on. A game on a single
|
||
// pack is just the one-element case.
|
||
func (g *Game) buildShopDecks() {
|
||
g.ShopDecks = make([][]Card, MaxRounds)
|
||
for _, pack := range g.packList() {
|
||
pets, foods := packTiers(pack)
|
||
for tierIdx := range pets {
|
||
deck := g.ShopDecks[tierIdx]
|
||
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
|
||
}
|
||
}
|
||
}
|
||
|
||
// packList is the game's pack selection, defaulting to the base pack so a
|
||
// zero-value Game (scratch simulations, tests) still builds real decks.
|
||
func (g *Game) packList() []string {
|
||
if len(g.Packs) == 0 {
|
||
return []string{DefaultPack}
|
||
}
|
||
return g.Packs
|
||
}
|
||
|
||
// Catalog returns the default pack's representative cards.
|
||
func Catalog() []Card { return CatalogForPacks([]string{DefaultPack}) }
|
||
|
||
// CatalogForPacks returns one representative card for every pet and food in
|
||
// the given packs, tier by tier, for the debug "buy any card" panel. IDs are
|
||
// name-based placeholders (not real instances); pets use their first printed
|
||
// suit. Cards are grouped by tier across all packs, matching how the shop
|
||
// decks combine.
|
||
func CatalogForPacks(packs []string) []Card {
|
||
var cards []Card
|
||
for tierIdx := range MaxRounds {
|
||
for _, pack := range packs {
|
||
pets, foods := packTiers(pack)
|
||
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
|
||
// templates of any pack in play (pets take their first printed suit). Returns
|
||
// false if unknown.
|
||
func (g *Game) cardByName(name string) (Card, bool) {
|
||
for _, pack := range g.packList() {
|
||
pets, foods := packTiers(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.",
|
||
}
|
||
}
|