diff --git a/sapai/battle.py b/sapai/battle.py index bb750cf..c419ed4 100644 --- a/sapai/battle.py +++ b/sapai/battle.py @@ -241,7 +241,7 @@ def update_pet_priority(t0, t1): # idx = np.array([idx[x] for x in sort_idx]) sort_idx = np.arange(0, len(attack)) attack = np.array(attack) - health = np.array(attack) + health = np.array(health) teams = np.array(teams) idx = np.array(idx) @@ -289,7 +289,7 @@ def update_pet_priority(t0, t1): ### Dereference temp_sort_idx and store in sort_idx end_idx = start_idx + len(temp_idx) - sort_idx[start_idx:end_idx] = temp_idx + sort_idx[start_idx:end_idx] = temp_idx[temp_sort_idx] start_idx = end_idx ### Finish sorting by max attack @@ -511,7 +511,33 @@ def battle_phase_hurt_and_faint(battle_obj, phase, teams, pet_priority, phase_di pp = pet_priority status_list = [] while True: - ### Get a list of fainted pets + ### Hurt triggers resolve before fainted pets are removed + hurt_list = [] + for team_idx, pet_idx in pp: + fteam, oteam = get_teams([team_idx, pet_idx], teams) + p = fteam[pet_idx].pet + while p._hurt > 0: + hurt_list.append([team_idx, pet_idx]) + activated, targets, possible = p.hurt_trigger(oteam) + append_phase_list( + phase_list, p, team_idx, pet_idx, activated, targets, possible + ) + for te_team_idx, te_pet_idx in pp: + if te_team_idx != team_idx: + continue + other_pet = teams[te_team_idx][te_pet_idx].pet + tempa, tempt, tempp = other_pet.friend_hurt_trigger(p, oteam) + append_phase_list( + phase_list, + other_pet, + te_team_idx, + te_pet_idx, + tempa, + tempt, + tempp, + ) + + ### Get a list of fainted pets after all queued hurt events resolved fainted_list = [] for team_idx, pet_idx in pp: p = teams[team_idx][pet_idx].pet @@ -596,6 +622,20 @@ def battle_phase_hurt_and_faint(battle_obj, phase, teams, pet_priority, phase_di append_phase_list( phase_list, p, team_idx, pet_idx, activated, targets, possible ) + for te_team_idx, te_pet_idx in pp: + if te_team_idx != team_idx: + continue + other_pet = teams[te_team_idx][te_pet_idx].pet + tempa, tempt, tempp = other_pet.friend_hurt_trigger(p, oteam) + append_phase_list( + phase_list, + other_pet, + te_team_idx, + te_pet_idx, + tempa, + tempt, + tempp, + ) battle_obj.pet_priority = battle_obj.update_pet_priority( battle_obj.t0, battle_obj.t1 @@ -702,9 +742,9 @@ def battle_phase_attack_after(battle_obj, phase, teams, pet_priority, phase_dict t1_pidx = attack_history[0][1][1] for team_idx, pet_idx in pp: - ### Check if current pet is directly behind the pet that just attacked - test_idx = [t0_pidx, t1_pidx][team_idx] + 1 - if pet_idx != test_idx: + attacker_idx = [t0_pidx, t1_pidx][team_idx] + behind_idx = attacker_idx + 1 + if pet_idx not in [attacker_idx, behind_idx]: continue ### If it is, then the after_attack ability can be activated @@ -808,8 +848,9 @@ def battle_phase_attack(battle_obj, phase, teams, pet_priority, phase_dict): p0._until_end_of_battle_attack_buff = 0 if len(nidx[1]) != 0: pn1 = teams[1][nidx[1][1]].pet - p0a, p1a = get_attack(p0, pn1) - pn1.hurt(p0a) + # Splash is one-sided damage: defender does not attack back. + splash_damage = pn1.get_damage(p0.attack) + pn1.hurt(splash_damage) phase_list.append(["splash", (aidx[0]), (str(p0)), [str(pn1)]]) if pn1.health <= 0: @@ -827,8 +868,9 @@ def battle_phase_attack(battle_obj, phase, teams, pet_priority, phase_dict): p1._until_end_of_battle_attack_buff = 0 if len(nidx[0]) != 0: pn0 = teams[0][nidx[0][1]].pet - p0a, p1a = get_attack(pn0, p1) - pn0.hurt(p1a) + # Splash is one-sided damage: defender does not attack back. + splash_damage = pn0.get_damage(p1.attack) + pn0.hurt(splash_damage) phase_list.append(["splash", (aidx[1]), (str(p1)), [str(pn0)]]) if pn0.health <= 0: diff --git a/sapai/data.py b/sapai/data.py index efe3ca4..ed82c6d 100644 --- a/sapai/data.py +++ b/sapai/data.py @@ -64,178 +64,85 @@ }, "tier": 1, "baseAttack": 2, - "baseHealth": 1, + "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Give a random friend +2/+1", + "description": "Faint: Give one random friend +1 attack and +1 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "attackAmount": 2, + "attackAmount": 1, "healthAmount": 1, "target": {"kind": "RandomFriend", "n": 1}, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Faint: Give a random friend +4/+2", + "description": "Faint: Give one random friend +2 attack and +2 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "attackAmount": 4, + "attackAmount": 2, "healthAmount": 2, "target": {"kind": "RandomFriend", "n": 1}, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Faint: Give a random friend +6/+3", + "description": "Faint: Give one random friend +3 attack and +3 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "attackAmount": 6, + "attackAmount": 3, "healthAmount": 3, "target": {"kind": "RandomFriend", "n": 1}, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - ], + }, + "pet-armadillo": { + "name": "Armadillo", + "id": "pet-armadillo", + "tier": 5, + "baseAttack": 4, + "baseHealth": 8, + "packs": ["StandardPack"], + "level1Ability": { + "description": "Start of battle: Give ALL pets +8 health.", + "trigger": "StartOfBattle", + "triggeredBy": {"kind": "Player"}, + "effect": { + "kind": "ModifyStats", + "healthAmount": 8, + "target": {"kind": "All"}, + "untilEndOfBattle": False, + }, + }, + "level2Ability": { + "description": "Start of battle: Give ALL pets +16 health.", + "trigger": "StartOfBattle", + "triggeredBy": {"kind": "Player"}, + "effect": { + "kind": "ModifyStats", + "healthAmount": 16, + "target": {"kind": "All"}, + "untilEndOfBattle": False, + }, + }, + "level3Ability": { + "description": "Start of battle: Give ALL pets +24 health.", + "trigger": "StartOfBattle", + "triggeredBy": {"kind": "Player"}, + "effect": { + "kind": "ModifyStats", + "healthAmount": 24, + "target": {"kind": "All"}, + "untilEndOfBattle": False, + }, + }, }, "pet-beaver": { "name": "Beaver", @@ -250,172 +157,38 @@ "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Sell: Give two random friends +1 health", + "description": "Sell: Give two random friends +1 attack.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "healthAmount": 1, + "attackAmount": 1, "target": {"kind": "RandomFriend", "n": 2}, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Sell: Give two random friends +2 health", + "description": "Sell: Give two random friends +2 attack.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "healthAmount": 2, + "attackAmount": 2, "target": {"kind": "RandomFriend", "n": 2}, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Sell: Give two random friends +3 health", + "description": "Sell: Give two random friends +3 attack.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "healthAmount": 3, + "attackAmount": 3, "target": {"kind": "RandomFriend", "n": 2}, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - ], }, "pet-beetle": { "name": "Beetle", @@ -462,74 +235,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"ExpansionPack1": 0.2976680384087793}, - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"ExpansionPack1": 0.2976680384087793}, - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - ], }, "pet-bluebird": { "name": "Bluebird", @@ -576,74 +281,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"ExpansionPack1": 0.2976680384087793}, - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"ExpansionPack1": 0.2976680384087793}, - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - ], }, "pet-cricket": { "name": "Cricket", @@ -655,10 +292,10 @@ }, "tier": 1, "baseAttack": 1, - "baseHealth": 2, + "baseHealth": 3, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Summon a 1/1 Cricket", + "description": "Faint: Summon one 1/1 Cricket.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -670,7 +307,7 @@ }, }, "level2Ability": { - "description": "Faint: Summon a 2/2 Cricket", + "description": "Faint: Summon one 2/2 Cricket.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -682,7 +319,7 @@ }, }, "level3Ability": { - "description": "Faint: Summon a 3/3 Cricket", + "description": "Faint: Summon one 3/3 Cricket.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -693,140 +330,6 @@ "team": "Friendly", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - ], }, "pet-duck": { "name": "Duck", @@ -838,10 +341,10 @@ }, "tier": 1, "baseAttack": 2, - "baseHealth": 3, + "baseHealth": 2, "packs": ["StandardPack"], "level1Ability": { - "description": "Sell: Give shop animals +1 Health", + "description": "Sell: Give shop pets +1 health.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": { @@ -852,7 +355,7 @@ }, }, "level2Ability": { - "description": "Sell: Give shop animals +2 Health", + "description": "Sell: Give shop pets +2 health.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": { @@ -863,7 +366,7 @@ }, }, "level3Ability": { - "description": "Sell: Give shop animals +3 Health", + "description": "Sell: Give shop pets +3 health.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": { @@ -873,74 +376,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"StandardPack": 0.2976680384087793}, - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"StandardPack": 0.2976680384087793}, - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - ], }, "pet-fish": { "name": "Fish", @@ -953,166 +388,32 @@ }, "tier": 1, "baseAttack": 2, - "baseHealth": 2, + "baseHealth": 3, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Level-up: Give all friends +1/+1", + "description": "Level-up: Give two friends +1 attack and +1 health.", "trigger": "LevelUp", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "EachFriend"}, + "target": {"kind": "RandomFriend", "n": 2}, "attackAmount": 1, "healthAmount": 1, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Level-up: Give all friends +2/+2", + "description": "Level-up: Give two friends +2 attack and +2 health.", "trigger": "LevelUp", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "EachFriend"}, + "target": {"kind": "RandomFriend", "n": 2}, "attackAmount": 2, "healthAmount": 2, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - ], }, "pet-horse": { "name": "Horse", @@ -1127,7 +428,7 @@ "baseHealth": 1, "packs": ["StandardPack"], "level1Ability": { - "description": "Friend summoned: Give it +1 Attack until end of battle", + "description": "Friend summoned: Give it +1 attack until next turn.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -1138,7 +439,7 @@ }, }, "level2Ability": { - "description": "Friend summoned: Give it +2 Attack until end of battle", + "description": "Friend summoned: Give it +2 attack until next turn.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -1149,7 +450,7 @@ }, }, "level3Ability": { - "description": "Friend summoned: Give it +3 Attack until end of battle", + "description": "Friend summoned: Give it +3 attack until next turn.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -1159,74 +460,6 @@ "untilEndOfBattle": True, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"StandardPack": 0.2976680384087793}, - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"StandardPack": 0.2976680384087793}, - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - ], }, "pet-ladybug": { "name": "Ladybug", @@ -1276,74 +509,6 @@ "untilEndOfBattle": True, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"ExpansionPack1": 0.2976680384087793}, - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"ExpansionPack1": 0.2976680384087793}, - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - ], }, "pet-mosquito": { "name": "Mosquito", @@ -1358,7 +523,7 @@ "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Start of battle: Deal 1 damage to a random enemy", + "description": "Start of battle: Deal 1 damage to one random enemy.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -1368,7 +533,7 @@ }, }, "level2Ability": { - "description": "Start of battle: Deal 2 damage to a random enemy", + "description": "Start of battle: Deal 1 damage to two random enemies.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -1378,7 +543,7 @@ }, }, "level3Ability": { - "description": "Start of battle: Deal 3 damage to a random enemy", + "description": "Start of battle: Deal 1 damage to three random enemies.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -1387,140 +552,6 @@ "amount": 1, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - ], }, "pet-otter": { "name": "Otter", @@ -1532,112 +563,41 @@ }, "tier": 1, "baseAttack": 1, - "baseHealth": 2, + "baseHealth": 4, "packs": ["StandardPack"], "level1Ability": { - "description": "Buy: Give one random friend +1/+1", + "description": "Buy: Give one random friend +1 health.", "trigger": "Buy", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "RandomFriend", "n": 1}, - "attackAmount": 1, "healthAmount": 1, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Buy: Give two random friend +1/+1", + "description": "Buy: Give two random friends +1 health.", "trigger": "Buy", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "RandomFriend", "n": 2}, - "attackAmount": 1, "healthAmount": 1, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Buy: Give three random friend +1/+1", + "description": "Buy: Give three random friends +1 health.", "trigger": "Buy", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "RandomFriend", "n": 3}, - "attackAmount": 1, "healthAmount": 1, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"StandardPack": 0.2976680384087793}, - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"StandardPack": 0.2976680384087793}, - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - ], }, "pet-pig": { "name": "Pig", @@ -1652,157 +612,69 @@ "baseHealth": 1, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Sell: Gain an extra 1 gold", + "description": "Sell: Gain +1 gold.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": {"kind": "GainGold", "amount": 1}, }, "level2Ability": { - "description": "Sell: Gain an extra 2 gold", + "description": "Sell: Gain +2 gold.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": {"kind": "GainGold", "amount": 2}, }, "level3Ability": { - "description": "Sell: Gain an extra 3 gold", + "description": "Sell: Gain +3 gold.", "trigger": "Sell", "triggeredBy": {"kind": "Self"}, "effect": {"kind": "GainGold", "amount": 3}, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": { - "StandardPack": 0.2976680384087793, - "ExpansionPack1": 0.2976680384087793, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - ], + }, + "pet-pigeon": { + "name": "Pigeon", + "id": "pet-pigeon", + "image": { + "source": "noto-emoji", + "commit": "e022fd6573782431ac9a65b520376b57511c31cd", + "unicodeCodePoint": "🕊️", + }, + "tier": 1, + "baseAttack": 3, + "baseHealth": 1, + "packs": ["StandardPack"], + "level1Ability": { + "description": "Sell: Stock one free Bread Crumbs.", + "trigger": "Sell", + "triggeredBy": {"kind": "Self"}, + "effect": { + "kind": "StockShopFood", + "shop": "Food", + "food": "food-bread-crumbs", + "amount": 1, + }, + }, + "level2Ability": { + "description": "Sell: Stock two free Bread Crumbs.", + "trigger": "Sell", + "triggeredBy": {"kind": "Self"}, + "effect": { + "kind": "StockShopFood", + "shop": "Food", + "food": "food-bread-crumbs", + "amount": 2, + }, + }, + "level3Ability": { + "description": "Sell: Stock three free Bread Crumbs.", + "trigger": "Sell", + "triggeredBy": {"kind": "Self"}, + "effect": { + "kind": "StockShopFood", + "shop": "Food", + "food": "food-bread-crumbs", + "amount": 3, + }, + }, }, "pet-sloth": { "name": "Sloth", @@ -1860,72 +732,6 @@ "to": {"kind": "NonWeakEnemy", "n": 3}, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"ExpansionPack1": 0.1}, - }, - ], }, "pet-crab": { "name": "Crab", @@ -1936,11 +742,11 @@ "unicodeCodePoint": "🦀", }, "tier": 2, - "baseAttack": 3, + "baseAttack": 4, "baseHealth": 1, "packs": ["StandardPack"], "level1Ability": { - "description": "Start of battle: copy 50% of health from most healthy friend", + "description": "Start of battle: Gain health equal to 25% of the most healthy friend.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -1949,11 +755,11 @@ "copyHealth": True, "from": {"kind": "HighestHealthFriend"}, "to": {"kind": "Self"}, - "percentage": 50, + "percentage": 25, }, }, "level2Ability": { - "description": "Start of battle: copy 100% of health from most healthy friend", + "description": "Start of battle: Gain health equal to 50% of the most healthy friend.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -1962,11 +768,11 @@ "copyHealth": True, "from": {"kind": "HighestHealthFriend"}, "to": {"kind": "Self"}, - "percentage": 100, + "percentage": 50, }, }, "level3Ability": { - "description": "Start of battle: copy 150% of health from most healthy friend", + "description": "Start of battle: Gain health equal to 75% of the most healthy friend.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -1975,67 +781,9 @@ "copyHealth": True, "from": {"kind": "HighestHealthFriend"}, "to": {"kind": "Self"}, - "percentage": 150, + "percentage": 75, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - {"kind": "levelup", "turn": "turn-1", "perSlot": {"StandardPack": 0.1}}, - {"kind": "levelup", "turn": "turn-2", "perSlot": {"StandardPack": 0.1}}, - ], }, "pet-dodo": { "name": "Dodo", @@ -2045,12 +793,12 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🦤", }, - "tier": 2, - "baseAttack": 2, - "baseHealth": 3, + "tier": 3, + "baseAttack": 4, + "baseHealth": 2, "packs": ["StandardPack"], "level1Ability": { - "description": "Start of battle: Give 50% Attack to friend ahead.", + "description": "Start of battle: Give 50% of attack to the nearest friend ahead.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -2063,7 +811,7 @@ }, }, "level2Ability": { - "description": "Start of battle: Give 100% Attack to friend ahead.", + "description": "Start of battle: Give 100% of attack to the nearest friend ahead.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -2076,7 +824,7 @@ }, }, "level3Ability": { - "description": "Start of battle: Give 150% Attack to friend ahead.", + "description": "Start of battle: Give 150% of attack to the nearest friend ahead.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -2088,64 +836,6 @@ "percentage": 150, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - {"kind": "levelup", "turn": "turn-1", "perSlot": {"StandardPack": 0.1}}, - {"kind": "levelup", "turn": "turn-2", "perSlot": {"StandardPack": 0.1}}, - ], }, "pet-dog": { "name": "Dog", @@ -2157,10 +847,10 @@ }, "tier": 3, "baseAttack": 3, - "baseHealth": 3, + "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Friend summoned: Gain +1 Attack or +1 Health.", + "description": "Friend summoned: Gain +2 attack and +1 health until next turn.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -2170,7 +860,7 @@ "kind": "ModifyStats", "untilEndOfBattle": False, "target": {"kind": "Self"}, - "attackAmount": 1, + "attackAmount": 2, }, { "kind": "ModifyStats", @@ -2182,7 +872,7 @@ }, }, "level2Ability": { - "description": "Friend summoned: Gain +2 Attack or +2 Health.", + "description": "Friend summoned: Gain +4 attack and +2 health until next turn.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -2192,7 +882,7 @@ "kind": "ModifyStats", "untilEndOfBattle": False, "target": {"kind": "Self"}, - "attackAmount": 2, + "attackAmount": 4, }, { "kind": "ModifyStats", @@ -2204,7 +894,7 @@ }, }, "level3Ability": { - "description": "Friend summoned: Gain +3 Attack or +3 Health.", + "description": "Friend summoned: Gain +6 attack and +3 health until next turn.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -2214,7 +904,7 @@ "kind": "ModifyStats", "untilEndOfBattle": False, "target": {"kind": "Self"}, - "attackAmount": 3, + "attackAmount": 6, }, { "kind": "ModifyStats", @@ -2225,108 +915,6 @@ ], }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-dromedary": { "name": "Dromedary", @@ -2376,72 +964,6 @@ "healthAmount": 3, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"ExpansionPack1": 0.1}, - }, - ], }, "pet-elephant": { "name": "Elephant", @@ -2451,13 +973,13 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🐘", }, - "tier": 2, + "tier": 3, "baseAttack": 3, - "baseHealth": 5, + "baseHealth": 7, "packs": ["StandardPack"], "level1Ability": { - "description": "Before Attack: Deal 1 damage to 1 friends behind.", - "trigger": "BeforeAttack", + "description": "After attack: Deal 1 damage to the nearest friend behind.", + "trigger": "AfterAttack", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "DealDamage", @@ -2466,83 +988,50 @@ }, }, "level2Ability": { - "description": "Before Attack: Deal 1 damage to 2 friends behind.", - "trigger": "BeforeAttack", + "description": "After attack: Deal 1 damage to the nearest friend behind. Triggers 2 times.", + "trigger": "AfterAttack", "triggeredBy": {"kind": "Self"}, "effect": { - "kind": "DealDamage", - "target": {"kind": "FriendBehind", "n": 2}, - "amount": 1, + "kind": "AllOf", + "effects": [ + { + "kind": "DealDamage", + "target": {"kind": "FriendBehind", "n": 1}, + "amount": 1, + }, + { + "kind": "DealDamage", + "target": {"kind": "FriendBehind", "n": 1}, + "amount": 1, + }, + ], }, }, "level3Ability": { - "description": "Before Attack: Deal 1 damage to 3 friends behind.", - "trigger": "BeforeAttack", + "description": "After attack: Deal 1 damage to the nearest friend behind. Triggers 3 times.", + "trigger": "AfterAttack", "triggeredBy": {"kind": "Self"}, "effect": { - "kind": "DealDamage", - "target": {"kind": "FriendBehind", "n": 3}, - "amount": 1, + "kind": "AllOf", + "effects": [ + { + "kind": "DealDamage", + "target": {"kind": "FriendBehind", "n": 1}, + "amount": 1, + }, + { + "kind": "DealDamage", + "target": {"kind": "FriendBehind", "n": 1}, + "amount": 1, + }, + { + "kind": "DealDamage", + "target": {"kind": "FriendBehind", "n": 1}, + "amount": 1, + }, + ], }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"StandardPack": 0.14973028138212574}, - "perSlot": {"StandardPack": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - {"kind": "levelup", "turn": "turn-1", "perSlot": {"StandardPack": 0.1}}, - {"kind": "levelup", "turn": "turn-2", "perSlot": {"StandardPack": 0.1}}, - ], }, "pet-flamingo": { "name": "Flamingo", @@ -2553,11 +1042,11 @@ "unicodeCodePoint": "🦩", }, "tier": 2, - "baseAttack": 4, + "baseAttack": 3, "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Give the two friends behind +1/+1.", + "description": "Faint: Give the two nearest friends behind +1 attack and +1 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -2569,7 +1058,7 @@ }, }, "level2Ability": { - "description": "Faint: Give the two friends behind +2/+2.", + "description": "Faint: Give the two nearest friends behind +2 attack and +2 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -2581,7 +1070,7 @@ }, }, "level3Ability": { - "description": "Faint: Give the two friends behind +3/+3.", + "description": "Faint: Give the two nearest friends behind +3 attack and +3 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -2592,126 +1081,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - ], }, "pet-hedgehog": { "name": "Hedgehog", @@ -2722,11 +1091,11 @@ "unicodeCodePoint": "🦔", }, "tier": 2, - "baseAttack": 3, + "baseAttack": 4, "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Deal 2 damage to all.", + "description": "Faint: Deal 2 damage to ALL pets.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -2736,7 +1105,7 @@ }, }, "level2Ability": { - "description": "Faint: Deal 4 damage to all.", + "description": "Faint: Deal 4 damage to ALL pets.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -2746,7 +1115,7 @@ }, }, "level3Ability": { - "description": "Faint: Deal 6 damage to all.", + "description": "Faint: Deal 6 damage to ALL pets.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -2755,126 +1124,6 @@ "amount": 6, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - ], }, "pet-peacock": { "name": "Peacock", @@ -2889,158 +1138,38 @@ "baseHealth": 5, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Hurt: Gain 4 attack.", + "description": "Hurt: Gain +3 attack.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 4, + "attackAmount": 3, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Hurt: Gain 8 attack.", + "description": "Hurt: Gain +6 attack.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 8, + "attackAmount": 6, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Hurt: Gain 12 attack.", + "description": "Hurt: Gain +9 attack.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 12, + "attackAmount": 9, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - ], }, "pet-rat": { "name": "Rat", @@ -3051,159 +1180,42 @@ "unicodeCodePoint": "🐀", }, "tier": 2, - "baseAttack": 4, - "baseHealth": 5, + "baseAttack": 3, + "baseHealth": 6, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: summon one 1/1 Dirty Rat for the opponent that betrays him.", + "description": "Faint: Summon one 1/1 Dirty Rat up front for the opponent.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonPet", "pet": "pet-dirty-rat", "team": "Enemy", + "amount": 1, }, }, "level2Ability": { - "description": "Faint: summon one 1/1 Dirty Rat for the opponent that betrays him.", + "description": "Faint: Summon two 1/1 Dirty Rats up front for the opponent.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonPet", "pet": "pet-dirty-rat", "team": "Enemy", + "amount": 2, }, }, "level3Ability": { - "description": "Faint: summon one 1/1 Dirty Rat for the opponent that betrays him.", + "description": "Faint: Summon three 1/1 Dirty Rats up front for the opponent.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonPet", "pet": "pet-dirty-rat", "team": "Enemy", + "amount": 3, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - ], }, "pet-shrimp": { "name": "Shrimp", @@ -3216,7 +1228,7 @@ "tier": 2, "baseAttack": 2, "baseHealth": 3, - "packs": ["StandardPack", "ExpansionPack1"], + "packs": ["ExpansionPack1"], "level1Ability": { "description": "Friend sold: Give a random friend +1 Health.", "trigger": "Sell", @@ -3250,126 +1262,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - ], }, "pet-spider": { "name": "Spider", @@ -3384,7 +1276,7 @@ "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Summon a level 1 tier 3 animal as a 2/2", + "description": "Faint: Summon one tier 3 pet as a 2/2 level 1.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -3396,149 +1288,29 @@ }, }, "level2Ability": { - "description": "Faint: Summon a level 2 tier 3 animal as a 2/2", + "description": "Faint: Summon one tier 3 pet as a 4/4 level 2.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonRandomPet", "tier": 3, - "baseAttack": 2, - "baseHealth": 2, + "baseAttack": 4, + "baseHealth": 4, "level": 2, }, }, "level3Ability": { - "description": "Faint: Summon a level 3 tier 3 animal as a 2/2", + "description": "Faint: Summon one tier 3 pet as a 6/6 level 3.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonRandomPet", "tier": 3, - "baseAttack": 2, - "baseHealth": 2, + "baseAttack": 6, + "baseHealth": 6, "level": 3, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - ], }, "pet-swan": { "name": "Swan", @@ -3550,7 +1322,7 @@ }, "tier": 2, "baseAttack": 1, - "baseHealth": 3, + "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { "description": "Start of turn: Gain 1 gold.", @@ -3570,126 +1342,6 @@ "triggeredBy": {"kind": "Player"}, "effect": {"kind": "GainGold", "amount": 3}, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.14973028138212574, - "ExpansionPack1": 0.14973028138212574, - }, - "perSlot": { - "StandardPack": 0.05263157894736842, - "ExpansionPack1": 0.05263157894736842, - }, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"StandardPack": 0.1, "ExpansionPack1": 0.1}, - }, - ], }, "pet-tabby-cat": { "name": "Tabby Cat", @@ -3736,72 +1388,6 @@ "untilEndOfBattle": True, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": {"ExpansionPack1": 0.14973028138212574}, - "perSlot": {"ExpansionPack1": 0.05263157894736842}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-1", - "perSlot": {"ExpansionPack1": 0.1}, - }, - { - "kind": "levelup", - "turn": "turn-2", - "perSlot": {"ExpansionPack1": 0.1}, - }, - ], }, "pet-badger": { "name": "Badger", @@ -3812,11 +1398,11 @@ "unicodeCodePoint": "🦡", }, "tier": 3, - "baseAttack": 5, + "baseAttack": 6, "baseHealth": 3, "packs": ["StandardPack"], "level1Ability": { - "description": "Faint: Deal Attack damage to adjacent animals", + "description": "Faint: Deal 50% attack damage to adjacent pets.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -3826,7 +1412,7 @@ }, }, "level2Ability": { - "description": "Faint: Deal Attack damage to adjacent animals", + "description": "Faint: Deal 100% attack damage to adjacent pets.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -3836,7 +1422,7 @@ }, }, "level3Ability": { - "description": "Faint: Deal Attack damage to adjacent animals", + "description": "Faint: Deal 150% attack damage to adjacent pets.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -3845,60 +1431,6 @@ "amount": {"attackDamagePercent": 150}, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-blowfish": { "name": "Blowfish", @@ -3908,142 +1440,40 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🐡", }, - "tier": 3, + "tier": 4, "baseAttack": 3, - "baseHealth": 5, + "baseHealth": 6, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Hurt: Deal 2 damage to a random enemy.", + "description": "Hurt: Deal 3 damage to one random enemy.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "DealDamage", "target": {"kind": "RandomEnemy", "n": 1}, - "amount": 2, + "amount": 3, }, }, "level2Ability": { - "description": "Hurt: Deal 4 damage to a random enemy.", + "description": "Hurt: Deal 6 damage to one random enemy.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "DealDamage", "target": {"kind": "RandomEnemy", "n": 1}, - "amount": 4, + "amount": 6, }, }, "level3Ability": { - "description": "Hurt: Deal 6 damage to a random enemy.", + "description": "Hurt: Deal 9 damage to one random enemy.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "DealDamage", "target": {"kind": "RandomEnemy", "n": 1}, - "amount": 6, + "amount": 9, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-caterpillar": { "name": "Caterpillar", @@ -4087,60 +1517,6 @@ "target": {"kind": "Self"}, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-camel": { "name": "Camel", @@ -4151,99 +1527,45 @@ "unicodeCodePoint": "🐫", }, "tier": 3, - "baseAttack": 2, - "baseHealth": 6, + "baseAttack": 3, + "baseHealth": 3, "packs": ["StandardPack"], "level1Ability": { - "description": "Hurt: Give friend behind +2/+2", + "description": "Hurt: Give the nearest friend behind +1 attack and +2 health.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "FriendBehind", "n": 1}, - "attackAmount": 2, + "attackAmount": 1, "healthAmount": 2, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Hurt: Give friend behind +4/+4", + "description": "Hurt: Give the nearest friend behind +2 attack and +4 health.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "FriendBehind", "n": 1}, - "attackAmount": 4, + "attackAmount": 2, "healthAmount": 4, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Hurt: Give friend behind +6/+6", + "description": "Hurt: Give the nearest friend behind +3 attack and +6 health.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "FriendBehind", "n": 1}, - "attackAmount": 6, + "attackAmount": 3, "healthAmount": 6, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-hatching-chick": { "name": "Hatching Chick", @@ -4291,60 +1613,6 @@ "amount": 1, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-giraffe": { "name": "Giraffe", @@ -4355,12 +1623,12 @@ "unicodeCodePoint": "🦒", }, "tier": 3, - "baseAttack": 2, - "baseHealth": 4, + "baseAttack": 1, + "baseHealth": 2, "packs": ["StandardPack"], "level1Ability": { - "description": "End turn: Give friend ahead +1/+1", - "trigger": "EndOfTurn", + "description": "Start of turn: Give the nearest friend ahead +1 attack and +1 health.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", @@ -4371,8 +1639,8 @@ }, }, "level2Ability": { - "description": "End turn: Give 2 friends ahead +1/+1", - "trigger": "EndOfTurn", + "description": "Start of turn: Give the nearest two friends ahead +1 attack and +1 health.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", @@ -4383,8 +1651,8 @@ }, }, "level3Ability": { - "description": "End turn: Give 3 friends ahead +1/+1", - "trigger": "EndOfTurn", + "description": "Start of turn: Give the nearest three friends ahead +1 attack and +1 health.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", @@ -4394,60 +1662,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-kangaroo": { "name": "Kangaroo", @@ -4457,100 +1671,46 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🦘", }, - "tier": 3, - "baseAttack": 1, + "tier": 2, + "baseAttack": 2, "baseHealth": 2, "packs": ["StandardPack"], "level1Ability": { - "description": "Friend ahead attacks: Gain +2/+2", + "description": "Friend ahead attacks: Gain +1 attack and +1 health.", "trigger": "AfterAttack", "triggeredBy": {"kind": "FriendAhead", "n": 1}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 2, - "healthAmount": 2, + "attackAmount": 1, + "healthAmount": 1, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Friend ahead attacks: Gain +4/+4", + "description": "Friend ahead attacks: Gain +2 attack and +2 health.", "trigger": "AfterAttack", "triggeredBy": {"kind": "FriendAhead", "n": 1}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 4, - "healthAmount": 4, + "attackAmount": 2, + "healthAmount": 2, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Friend ahead attacks: Gain +6/+6", + "description": "Friend ahead attacks: Gain +3 attack and +3 health.", "trigger": "AfterAttack", "triggeredBy": {"kind": "FriendAhead", "n": 1}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 6, - "healthAmount": 6, + "attackAmount": 3, + "healthAmount": 3, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-owl": { "name": "Owl", @@ -4600,60 +1760,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-ox": { "name": "Ox", @@ -4668,9 +1774,10 @@ "baseHealth": 3, "packs": ["StandardPack"], "level1Ability": { - "description": "Friend ahead attacks: Gain Melon Armor and +1 attack", + "description": "Friend ahead faints: Gain Melon perk and +1 attack. Works 1 time per turn.", "trigger": "Faint", "triggeredBy": {"kind": "FriendAhead", "n": 1}, + "maxTriggers": 1, "effect": { "kind": "AllOf", "effects": [ @@ -4689,9 +1796,10 @@ }, }, "level2Ability": { - "description": "Friend ahead attacks: Gain Melon Armor and +2 attack", + "description": "Friend ahead faints: Gain Melon perk and +1 attack. Works 2 times per turn.", "trigger": "Faint", "triggeredBy": {"kind": "FriendAhead", "n": 1}, + "maxTriggers": 2, "effect": { "kind": "AllOf", "effects": [ @@ -4703,16 +1811,17 @@ { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 2, + "attackAmount": 1, "untilEndOfBattle": False, }, ], }, }, "level3Ability": { - "description": "Friend ahead attacks: Gain Melon Armor and +3 attack", + "description": "Friend ahead faints: Gain Melon perk and +1 attack. Works 3 times per turn.", "trigger": "Faint", "triggeredBy": {"kind": "FriendAhead", "n": 1}, + "maxTriggers": 3, "effect": { "kind": "AllOf", "effects": [ @@ -4724,66 +1833,12 @@ { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 3, + "attackAmount": 1, "untilEndOfBattle": False, }, ], }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"StandardPack": 0.12681358024691358}, - "perSlot": {"StandardPack": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-puppy": { "name": "Puppy", @@ -4833,60 +1888,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-rabbit": { "name": "Rabbit", @@ -4901,9 +1902,10 @@ "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Pet eats shop food: Give it +1 Health", + "description": "Friendly ate food: Give them +1 health. Works 3 times per turn.", "trigger": "EatsShopFood", "triggeredBy": {"kind": "EachFriend"}, + "maxTriggers": 3, "effect": { "kind": "ModifyStats", "target": {"kind": "TriggeringEntity"}, @@ -4912,9 +1914,10 @@ }, }, "level2Ability": { - "description": "Pet eats shop food: Give it +2 Health", + "description": "Friendly ate food: Give them +2 health. Works 3 times per turn.", "trigger": "EatsShopFood", "triggeredBy": {"kind": "EachFriend"}, + "maxTriggers": 3, "effect": { "kind": "ModifyStats", "target": {"kind": "TriggeringEntity"}, @@ -4923,9 +1926,10 @@ }, }, "level3Ability": { - "description": "Pet eats shop food: Give it +3 Health", + "description": "Friendly ate food: Give them +3 health. Works 3 times per turn.", "trigger": "EatsShopFood", "triggeredBy": {"kind": "EachFriend"}, + "maxTriggers": 3, "effect": { "kind": "ModifyStats", "target": {"kind": "TriggeringEntity"}, @@ -4933,108 +1937,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-sheep": { "name": "Sheep", @@ -5058,6 +1960,7 @@ "withAttack": 2, "withHealth": 2, "team": "Friendly", + "amount": 2, }, }, "level2Ability": { @@ -5070,6 +1973,7 @@ "withAttack": 4, "withHealth": 4, "team": "Friendly", + "amount": 2, }, }, "level3Ability": { @@ -5082,110 +1986,9 @@ "withAttack": 6, "withHealth": 6, "team": "Friendly", + "amount": 2, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-snail": { "name": "Snail", @@ -5195,148 +1998,43 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🐌", }, - "tier": 3, + "tier": 2, "baseAttack": 2, "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Buy: If you lost last battle, give all friends +2/+1", - "trigger": "BuyAfterLoss", + "description": "End Turn: If you lost last battle, give the three nearest friends ahead +1 attack.", + "trigger": "EndOfTurnAfterLoss", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "EachFriend"}, + "target": {"kind": "FriendAhead", "n": 3}, "attackAmount": 1, - "healthAmount": 1, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Buy: If you lost last battle, give all friends +4/+2", - "trigger": "BuyAfterLoss", + "description": "End Turn: If you lost last battle, give the three nearest friends ahead +1 attack.", + "trigger": "EndOfTurnAfterLoss", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "EachFriend"}, - "attackAmount": 2, - "healthAmount": 2, + "target": {"kind": "FriendAhead", "n": 3}, + "attackAmount": 1, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Buy: If you lost last battle, give all friends +6/+3", - "trigger": "BuyAfterLoss", + "description": "End Turn: If you lost last battle, give the three nearest friends ahead +1 attack.", + "trigger": "EndOfTurnAfterLoss", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "EachFriend"}, - "attackAmount": 3, - "healthAmount": 3, + "target": {"kind": "FriendAhead", "n": 3}, + "attackAmount": 1, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-tropical-fish": { "name": "Tropical Fish", @@ -5383,60 +2081,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": {"ExpansionPack1": 0.12681358024691358}, - "perSlot": {"ExpansionPack1": 0.03333333333333333}, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-turtle": { "name": "Turtle", @@ -5446,12 +2090,12 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🐢", }, - "tier": 3, - "baseAttack": 1, - "baseHealth": 2, + "tier": 4, + "baseAttack": 2, + "baseHealth": 5, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Give friend behind Melon Armor", + "description": "Faint: Give Melon perk to the nearest friend behind.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -5461,7 +2105,7 @@ }, }, "level2Ability": { - "description": "Faint: Give 2 friends behind Melon Armor", + "description": "Faint: Give Melon perk to the two nearest friends behind.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -5471,7 +2115,7 @@ }, }, "level3Ability": { - "description": "Faint: Give 3 friends behind Melon Armor", + "description": "Faint: Give Melon perk to the three nearest friends behind.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -5480,108 +2124,6 @@ "to": {"kind": "FriendBehind", "n": 3}, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.12681358024691358, - "ExpansionPack1": 0.12681358024691358, - }, - "perSlot": { - "StandardPack": 0.03333333333333333, - "ExpansionPack1": 0.03333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-3", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-4", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-whale": { "name": "Whale", @@ -5593,10 +2135,10 @@ }, "tier": 4, "baseAttack": 3, - "baseHealth": 8, + "baseHealth": 7, "packs": ["StandardPack"], "level1Ability": { - "description": "Start of battle: Swallow friend ahead and release it as a level 1 after fainting.", + "description": "Start of battle: Swallow the nearest friend ahead and release it at level 1 on faint.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -5605,7 +2147,7 @@ }, }, "level2Ability": { - "description": "Start of battle: Swallow friend ahead and release it as a level 2 after fainting.", + "description": "Start of battle: Swallow the nearest friend ahead and release it at level 2 on faint.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -5614,7 +2156,7 @@ }, }, "level3Ability": { - "description": "Start of battle: Swallow friend ahead and release it as a level 3 after fainting.", + "description": "Start of battle: Swallow the nearest friend ahead and release it at level 3 on faint.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -5622,48 +2164,6 @@ "target": {"kind": "FriendAhead", "n": 1}, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-bison": { "name": "Bison", @@ -5678,119 +2178,41 @@ "baseHealth": 4, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "End turn: Gain +2/+2 if there is at least one Lvl. 3 friend.", + "description": "End turn: If this has a level 3 friend, gain +1 attack and +2 health.", "trigger": "EndOfTurnWithLvl3Friend", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 2, + "attackAmount": 1, "healthAmount": 2, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "End turn: Gain +4/+4 if there is at least one Lvl. 3 friend.", + "description": "End turn: If this has a level 3 friend, gain +2 attack and +4 health.", "trigger": "EndOfTurnWithLvl3Friend", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 4, + "attackAmount": 2, "healthAmount": 4, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "End turn: Gain +6/+6 if there is at least one Lvl. 3 friend.", + "description": "End turn: If this has a level 3 friend, gain +3 attack and +6 health.", "trigger": "EndOfTurnWithLvl3Friend", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 6, + "attackAmount": 3, "healthAmount": 6, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-buffalo": { "name": "Buffalo", @@ -5840,48 +2262,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-deer": { "name": "Deer", @@ -5892,123 +2272,45 @@ "unicodeCodePoint": "🦌", }, "tier": 4, - "baseAttack": 1, - "baseHealth": 1, + "baseAttack": 2, + "baseHealth": 2, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Summon a 5/5 Bus with Splash Attack", + "description": "Faint: Summon one 5/3 Bus with Chili.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonPet", "pet": "pet-bus", "withAttack": 5, - "withHealth": 5, + "withHealth": 3, "team": "Friendly", }, }, "level2Ability": { - "description": "Faint: Summon a 10/10 Bus with Splash Attack", + "description": "Faint: Summon one 10/6 Bus with Chili.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonPet", "pet": "pet-bus", "withAttack": 10, - "withHealth": 10, + "withHealth": 6, "team": "Friendly", }, }, "level3Ability": { - "description": "Faint: Summon a 15/15 Bus with Splash Attack", + "description": "Faint: Summon one 15/9 Bus with Chili.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "SummonPet", "pet": "pet-bus", "withAttack": 15, - "withHealth": 15, + "withHealth": 9, "team": "Friendly", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-dolphin": { "name": "Dolphin", @@ -6018,118 +2320,65 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🐬", }, - "tier": 4, + "tier": 3, "baseAttack": 4, - "baseHealth": 6, + "baseHealth": 3, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Start of battle: Deal 5 damage to the lowest health enemy", + "description": "Start of battle: Deal 4 damage to the lowest health enemy.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "DealDamage", "target": {"kind": "LowestHealthEnemy"}, - "amount": 5, + "amount": 4, }, }, "level2Ability": { - "description": "Start of battle: Deal 10 damage to the lowest health enemy", + "description": "Start of battle: Deal 4 damage to the lowest health enemy. Triggers 2 times.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { - "kind": "DealDamage", - "target": {"kind": "LowestHealthEnemy"}, - "amount": 10, + "kind": "AllOf", + "effects": [ + { + "kind": "DealDamage", + "target": {"kind": "LowestHealthEnemy"}, + "amount": 4, + }, + { + "kind": "DealDamage", + "target": {"kind": "LowestHealthEnemy"}, + "amount": 4, + }, + ], }, }, "level3Ability": { - "description": "Start of battle: Deal 15 damage to the lowest health enemy", + "description": "Start of battle: Deal 4 damage to the lowest health enemy. Triggers 3 times.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { - "kind": "DealDamage", - "target": {"kind": "LowestHealthEnemy"}, - "amount": 15, + "kind": "AllOf", + "effects": [ + { + "kind": "DealDamage", + "target": {"kind": "LowestHealthEnemy"}, + "amount": 4, + }, + { + "kind": "DealDamage", + "target": {"kind": "LowestHealthEnemy"}, + "amount": 4, + }, + { + "kind": "DealDamage", + "target": {"kind": "LowestHealthEnemy"}, + "amount": 4, + }, + ], }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-hippo": { "name": "Hippo", @@ -6141,12 +2390,13 @@ }, "tier": 4, "baseAttack": 4, - "baseHealth": 7, + "baseHealth": 6, "packs": ["StandardPack"], "level1Ability": { - "description": "Knock out: Gain +3/+3.", + "description": "Knock out: Gain +3 attack and +3 health. Works 3 times per battle.", "trigger": "KnockOut", "triggeredBy": {"kind": "Self"}, + "maxTriggers": 3, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, @@ -6156,9 +2406,10 @@ }, }, "level2Ability": { - "description": "Knock out: Gain +6/+6.", + "description": "Knock out: Gain +6 attack and +6 health. Works 3 times per battle.", "trigger": "KnockOut", "triggeredBy": {"kind": "Self"}, + "maxTriggers": 3, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, @@ -6168,9 +2419,10 @@ }, }, "level3Ability": { - "description": "Knock out: Gain +9/+9.", + "description": "Knock out: Gain +9 attack and +9 health. Works 3 times per battle.", "trigger": "KnockOut", "triggeredBy": {"kind": "Self"}, + "maxTriggers": 3, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, @@ -6179,48 +2431,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-llama": { "name": "Llama", @@ -6270,48 +2480,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-lobster": { "name": "Lobster", @@ -6361,48 +2529,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-monkey": { "name": "Monkey", @@ -6417,71 +2543,41 @@ "baseHealth": 2, "packs": ["StandardPack"], "level1Ability": { - "description": "End turn: Give right-most friend +2/+3", + "description": "End turn: Give front-most friendly pet +2 attack and +2 health.", "trigger": "EndOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", "target": {"kind": "RightMostFriend"}, "attackAmount": 2, - "healthAmount": 3, + "healthAmount": 2, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "End turn: Give right-most friend +4/+6", + "description": "End turn: Give front-most friendly pet +4 attack and +4 health.", "trigger": "EndOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", "target": {"kind": "RightMostFriend"}, "attackAmount": 4, - "healthAmount": 6, + "healthAmount": 4, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "End turn: Give right-most friend +6/+9", + "description": "End turn: Give front-most friendly pet +6 attack and +6 health.", "trigger": "EndOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", "target": {"kind": "RightMostFriend"}, "attackAmount": 6, - "healthAmount": 9, + "healthAmount": 6, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125}, - }, - ], }, "pet-penguin": { "name": "Penguin", @@ -6492,87 +2588,45 @@ "unicodeCodePoint": "🐧", }, "tier": 4, - "baseAttack": 1, - "baseHealth": 2, + "baseAttack": 2, + "baseHealth": 3, "packs": ["StandardPack"], "level1Ability": { - "description": "End turn: Give other Lvl. 2 and 3 friends +1/+1", - "trigger": "EndOfTurn", + "description": "Start of turn: Give two level 2 or higher friends +1 attack and +1 health.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "Level2And3Friends"}, + "target": {"kind": "Level2And3Friends", "n": 2}, "attackAmount": 1, "healthAmount": 1, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "End turn: Give other Lvl. 2 and 3 friends +2/+2", - "trigger": "EndOfTurn", + "description": "Start of turn: Give two level 2 or higher friends +2 attack and +2 health.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "Level2And3Friends"}, + "target": {"kind": "Level2And3Friends", "n": 2}, "attackAmount": 2, "healthAmount": 2, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "End turn: Give other Lvl. 2 and 3 friends +3/+3", - "trigger": "EndOfTurn", + "description": "Start of turn: Give two level 2 or higher friends +3 attack and +3 health.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "Level2And3Friends"}, + "target": {"kind": "Level2And3Friends", "n": 2}, "attackAmount": 3, "healthAmount": 3, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-poodle": { "name": "Poodle", @@ -6622,36 +2676,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"ExpansionPack1": 0.125}, - }, - ], }, "pet-rooster": { "name": "Rooster", @@ -6661,106 +2685,43 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🐓", }, - "tier": 4, - "baseAttack": 5, - "baseHealth": 3, + "tier": 5, + "baseAttack": 6, + "baseHealth": 5, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Summon a Chick with 1 health and half the Attack of this.", + "description": "Faint: Summon one Chick with 1 health and 50% attack of this.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, - "effect": {"kind": "SummonPet", "pet": "pet-chick", "team": "Friendly"}, + "effect": { + "kind": "SummonPet", + "pet": "pet-chick", + "team": "Friendly", + "amount": 1, + }, }, "level2Ability": { - "description": "Faint: Summon 2 Chicks with 1 health and half the Attack of this.", + "description": "Faint: Summon two Chicks with 1 health and 50% attack of this.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, - "effect": {"kind": "SummonPet", "pet": "pet-chick", "team": "Friendly"}, + "effect": { + "kind": "SummonPet", + "pet": "pet-chick", + "team": "Friendly", + "amount": 2, + }, }, "level3Ability": { - "description": "Faint: Summon 3 Chicks with 1 health and half the Attack of this.", + "description": "Faint: Summon three Chicks with 1 health and 50% attack of this.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, - "effect": {"kind": "SummonPet", "pet": "pet-chick", "team": "Friendly"}, - }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], + "effect": { + "kind": "SummonPet", + "pet": "pet-chick", + "team": "Friendly", + "amount": 3, + }, + }, }, "pet-skunk": { "name": "Skunk", @@ -6775,7 +2736,7 @@ "baseHealth": 5, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Start of battle: Reduce the highest Health enemy by 33%.", + "description": "Start of battle: Remove 33% health from the highest health enemy.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -6785,7 +2746,7 @@ }, }, "level2Ability": { - "description": "Start of battle: Reduce the highest Health enemy by 66%.", + "description": "Start of battle: Remove 66% health from the highest health enemy.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -6795,93 +2756,15 @@ }, }, "level3Ability": { - "description": "Start of battle: Reduce the highest Health enemy by 100%.", + "description": "Start of battle: Remove 99% health from the highest health enemy.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { "kind": "ReduceHealth", "target": {"kind": "HighestHealthEnemy"}, - "percentage": 100, + "percentage": 99, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-squirrel": { "name": "Squirrel", @@ -6892,105 +2775,27 @@ "unicodeCodePoint": "🐿", }, "tier": 4, - "baseAttack": 2, + "baseAttack": 3, "baseHealth": 5, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Start of turn: Discount shop food by 1 gold", + "description": "Start of turn: Discount all shop food by 1 gold.", "trigger": "StartOfTurn", "triggeredBy": {"kind": "Self"}, "effect": {"kind": "DiscountFood", "amount": 1}, }, "level2Ability": { - "description": "Start of turn: Discount shop food by 2 gold", + "description": "Start of turn: Discount all shop food by 2 gold.", "trigger": "StartOfTurn", "triggeredBy": {"kind": "Self"}, "effect": {"kind": "DiscountFood", "amount": 2}, }, "level3Ability": { - "description": "Start of turn: Discount shop food by 3 gold", + "description": "Start of turn: Discount all shop food by 3 gold.", "trigger": "StartOfTurn", "triggeredBy": {"kind": "Self"}, "effect": {"kind": "DiscountFood", "amount": 3}, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-worm": { "name": "Worm", @@ -7000,124 +2805,52 @@ "commit": "e022fd6573782431ac9a65b520376b57511c31cd", "unicodeCodePoint": "🪱", }, - "tier": 4, - "baseAttack": 3, - "baseHealth": 3, + "tier": 2, + "baseAttack": 1, + "baseHealth": 4, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Eats shop food: Gain +1/+1", - "trigger": "EatsShopFood", + "description": "Start of turn: Stock one 2-gold Apple.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Self"}, "effect": { - "kind": "ModifyStats", - "attackAmount": 1, - "healthAmount": 1, - "target": {"kind": "Self"}, - "untilEndOfBattle": False, + "kind": "StockShopFood", + "shop": "Food", + "food": "food-apple", + "amount": 1, + "withAttack": 1, + "withHealth": 1, + "withCost": 2, }, }, "level2Ability": { - "description": "Eats shop food: Gain +2/+2", - "trigger": "EatsShopFood", + "description": "Start of turn: Stock one 2-gold Better Apple.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Self"}, "effect": { - "kind": "ModifyStats", - "attackAmount": 2, - "healthAmount": 2, - "target": {"kind": "Self"}, - "untilEndOfBattle": False, + "kind": "StockShopFood", + "shop": "Food", + "food": "food-apple", + "amount": 1, + "withAttack": 2, + "withHealth": 2, + "withCost": 2, }, }, "level3Ability": { - "description": "Eats shop food: Gain +3/+3", - "trigger": "EatsShopFood", + "description": "Start of turn: Stock one 2-gold Best Apple.", + "trigger": "StartOfTurn", "triggeredBy": {"kind": "Self"}, "effect": { - "kind": "ModifyStats", - "attackAmount": 3, - "healthAmount": 3, - "target": {"kind": "Self"}, - "untilEndOfBattle": False, + "kind": "StockShopFood", + "shop": "Food", + "food": "food-apple", + "amount": 1, + "withAttack": 3, + "withHealth": 3, + "withCost": 2, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.09404935520024527, - "ExpansionPack1": 0.09404935520024527, - }, - "perSlot": { - "StandardPack": 0.024390243902439025, - "ExpansionPack1": 0.024390243902439025, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": { - "StandardPack": 0.09090909090909091, - "ExpansionPack1": 0.09090909090909091, - }, - }, - ], }, "pet-chicken": { "name": "Chicken", @@ -7167,36 +2900,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"ExpansionPack1": 0.125}, - }, - ], }, "pet-cow": { "name": "Cow", @@ -7211,71 +2914,44 @@ "baseHealth": 6, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Buy: Replace food shop with 2 free milk that gives +1/+2.", + "description": "Buy: Replace shop food with two free Milk.", "trigger": "Buy", "triggeredBy": {"kind": "Self"}, - "effect": {"kind": "RefillShops", "shop": "Food", "food": "food-milk"}, + "effect": { + "kind": "StockShopFood", + "shop": "Food", + "food": "food-milk", + "amount": 2, + "withAttack": 1, + "withHealth": 2, + }, }, "level2Ability": { - "description": "Buy: Replace food shop with 2 free milk that gives +2/+4.", + "description": "Buy: Replace shop food with two free Better Milk.", "trigger": "Buy", "triggeredBy": {"kind": "Self"}, - "effect": {"kind": "RefillShops", "shop": "Food", "food": "food-milk"}, + "effect": { + "kind": "StockShopFood", + "shop": "Food", + "food": "food-milk", + "amount": 2, + "withAttack": 2, + "withHealth": 4, + }, }, "level3Ability": { - "description": "Buy: Replace food shop with 2 free milk that gives +3/+6.", + "description": "Buy: Replace shop food with two free Best Milk.", "trigger": "Buy", "triggeredBy": {"kind": "Self"}, - "effect": {"kind": "RefillShops", "shop": "Food", "food": "food-milk"}, - }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - ], + "effect": { + "kind": "StockShopFood", + "shop": "Food", + "food": "food-milk", + "amount": 2, + "withAttack": 3, + "withHealth": 6, + }, + }, }, "pet-crocodile": { "name": "Crocodile", @@ -7300,55 +2976,50 @@ }, }, "level2Ability": { - "description": "Start of battle: Deal 16 damage to the last enemy", + "description": "Start of battle: Deal 8 damage to the last enemy. Triggers 2 times.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { - "kind": "DealDamage", - "target": {"kind": "LastEnemy"}, - "amount": 16, + "kind": "AllOf", + "effects": [ + { + "kind": "DealDamage", + "target": {"kind": "LastEnemy"}, + "amount": 8, + }, + { + "kind": "DealDamage", + "target": {"kind": "LastEnemy"}, + "amount": 8, + }, + ], }, }, "level3Ability": { - "description": "Start of battle: Deal 24 damage to the last enemy", + "description": "Start of battle: Deal 8 damage to the last enemy. Triggers 3 times.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { - "kind": "DealDamage", - "target": {"kind": "LastEnemy"}, - "amount": 24, + "kind": "AllOf", + "effects": [ + { + "kind": "DealDamage", + "target": {"kind": "LastEnemy"}, + "amount": 8, + }, + { + "kind": "DealDamage", + "target": {"kind": "LastEnemy"}, + "amount": 8, + }, + { + "kind": "DealDamage", + "target": {"kind": "LastEnemy"}, + "amount": 8, + }, + ], }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125}, - }, - ], }, "pet-eagle": { "name": "Eagle", @@ -7395,36 +3066,6 @@ "statsModifier": 3, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"ExpansionPack1": 0.125}, - }, - ], }, "pet-goat": { "name": "Goat", @@ -7459,36 +3100,6 @@ "effect": {"kind": "GainGold", "amount": 3}, "maxTriggers": 2, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"ExpansionPack1": 0.125}, - }, - ], }, "pet-microbe": { "name": "Microbe", @@ -7532,48 +3143,6 @@ "to": {"kind": "All"}, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"ExpansionPack1": 0.09404935520024527}, - "perSlot": {"ExpansionPack1": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"ExpansionPack1": 0.09796001985292535}, - "perSlot": {"ExpansionPack1": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"ExpansionPack1": 0.09090909090909091}, - }, - ], }, "pet-parrot": { "name": "Parrot", @@ -7585,10 +3154,10 @@ }, "tier": 4, "baseAttack": 4, - "baseHealth": 3, + "baseHealth": 2, "packs": ["StandardPack"], "level1Ability": { - "description": "End Turn: Copy ability from pet ahead as lvl. 1 until end of battle.", + "description": "End turn: Copy ability from the nearest pet ahead as level 1 until next turn.", "trigger": "EndOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { @@ -7599,7 +3168,7 @@ }, }, "level2Ability": { - "description": "End Turn: Copy ability from pet ahead as lvl. 2 until end of battle.", + "description": "End turn: Copy ability from the nearest pet ahead as level 2 until next turn.", "trigger": "EndOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { @@ -7610,7 +3179,7 @@ }, }, "level3Ability": { - "description": "End Turn: Copy ability from pet ahead as lvl. 3 until end of battle.", + "description": "End turn: Copy ability from the nearest pet ahead as level 3 until next turn.", "trigger": "EndOfTurn", "triggeredBy": {"kind": "Player"}, "effect": { @@ -7620,48 +3189,6 @@ "level": 3, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": {"StandardPack": 0.09404935520024527}, - "perSlot": {"StandardPack": 0.024390243902439025}, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-5", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - { - "kind": "levelup", - "turn": "turn-6", - "perSlot": {"StandardPack": 0.09090909090909091}, - }, - ], }, "pet-rhino": { "name": "Rhino", @@ -7672,11 +3199,11 @@ "unicodeCodePoint": "🦏", }, "tier": 5, - "baseAttack": 5, - "baseHealth": 8, + "baseAttack": 6, + "baseHealth": 7, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Knock out: Deal 4 damage to the first enemy.", + "description": "Knock out: Deal 4 damage to the first enemy. Double against tier 1 pets.", "trigger": "KnockOut", "triggeredBy": {"kind": "Self"}, "effect": { @@ -7686,7 +3213,7 @@ }, }, "level2Ability": { - "description": "Knock out: Deal 8 damage to the first enemy.", + "description": "Knock out: Deal 8 damage to the first enemy. Double against tier 1 pets.", "trigger": "KnockOut", "triggeredBy": {"kind": "Self"}, "effect": { @@ -7696,7 +3223,7 @@ }, }, "level3Ability": { - "description": "Knock out: Deal 12 damage to the first enemy.", + "description": "Knock out: Deal 12 damage to the first enemy. Double against tier 1 pets.", "trigger": "KnockOut", "triggeredBy": {"kind": "Self"}, "effect": { @@ -7705,54 +3232,6 @@ "amount": 12, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - ], }, "pet-scorpion": { "name": "Scorpion", @@ -7767,54 +3246,6 @@ "baseHealth": 1, "packs": ["StandardPack", "ExpansionPack1"], "status": "status-poison-attack", - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - ], }, "pet-seal": { "name": "Seal", @@ -7829,89 +3260,38 @@ "baseHealth": 8, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Eats shop food: Give 2 random friends +1/+1.", + "description": "Eats food: Give three random friends +1 attack.", "trigger": "EatsShopFood", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "RandomFriend", "n": 2}, + "target": {"kind": "RandomFriend", "n": 3}, "attackAmount": 1, - "healthAmount": 1, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Eats shop food: Give 2 random friends +2/+2.", + "description": "Eats food: Give three random friends +2 attack.", "trigger": "EatsShopFood", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "RandomFriend", "n": 2}, + "target": {"kind": "RandomFriend", "n": 3}, "attackAmount": 2, - "healthAmount": 2, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Eats shop food: Give 2 random friends +3/+3.", + "description": "Eats food: Give three random friends +3 attack.", "trigger": "EatsShopFood", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", - "target": {"kind": "RandomFriend", "n": 2}, + "target": {"kind": "RandomFriend", "n": 3}, "attackAmount": 3, - "healthAmount": 3, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.09796001985292535, - "ExpansionPack1": 0.09796001985292535, - }, - "perSlot": { - "StandardPack": 0.02040816326530612, - "ExpansionPack1": 0.02040816326530612, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125, "ExpansionPack1": 0.125}, - }, - ], }, "pet-shark": { "name": "Shark", @@ -7922,11 +3302,11 @@ "unicodeCodePoint": "🦈", }, "tier": 5, - "baseAttack": 4, - "baseHealth": 4, + "baseAttack": 2, + "baseHealth": 2, "packs": ["StandardPack"], "level1Ability": { - "description": "Friend faints: Gain +2/+2.", + "description": "Friend faints: Gain +2 attack and +2 health.", "trigger": "Faint", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -7938,7 +3318,7 @@ }, }, "level2Ability": { - "description": "Friend faints: Gain +4/+4.", + "description": "Friend faints: Gain +4 attack and +4 health.", "trigger": "Faint", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -7950,7 +3330,7 @@ }, }, "level3Ability": { - "description": "Friend faints: Gain +6/+6.", + "description": "Friend faints: Gain +6 attack and +6 health.", "trigger": "Faint", "triggeredBy": {"kind": "EachFriend"}, "effect": { @@ -7961,36 +3341,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125}, - }, - ], }, "pet-turkey": { "name": "Turkey", @@ -8005,71 +3355,41 @@ "baseHealth": 4, "packs": ["StandardPack"], "level1Ability": { - "description": "Friend summoned: Give it +3/+3.", + "description": "Friend summoned: Give it +3 attack and +1 health.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { "kind": "ModifyStats", "target": {"kind": "TriggeringEntity"}, "attackAmount": 3, - "healthAmount": 3, + "healthAmount": 1, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Friend summoned: Give it +6/+6.", + "description": "Friend summoned: Give it +6 attack and +2 health.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { "kind": "ModifyStats", "target": {"kind": "TriggeringEntity"}, "attackAmount": 6, - "healthAmount": 6, + "healthAmount": 2, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Friend summoned: Give it +9/+9.", + "description": "Friend summoned: Give it +9 attack and +3 health.", "trigger": "Summoned", "triggeredBy": {"kind": "EachFriend"}, "effect": { "kind": "ModifyStats", "target": {"kind": "TriggeringEntity"}, "attackAmount": 9, - "healthAmount": 9, + "healthAmount": 3, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": {"StandardPack": 0.09796001985292535}, - "perSlot": {"StandardPack": 0.02040816326530612}, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-7", - "perSlot": {"StandardPack": 0.125}, - }, - { - "kind": "levelup", - "turn": "turn-8", - "perSlot": {"StandardPack": 0.125}, - }, - ], }, "pet-cat": { "name": "Cat", @@ -8084,46 +3404,26 @@ "baseHealth": 5, "packs": ["StandardPack"], "level1Ability": { - "description": "Food with Health and Attack effects are doubled.", + "description": "Shop food gives two times attack and health. Works 2 times per turn.", "trigger": "PurchaseFood", "triggeredBy": {"kind": "Self"}, + "maxTriggers": 2, "effect": {"kind": "FoodMultiplier", "amount": 2}, }, "level2Ability": { - "description": "Food with Health and Attack effects are tripled.", + "description": "Shop food gives three times attack and health. Works 2 times per turn.", "trigger": "PurchaseFood", "triggeredBy": {"kind": "Self"}, + "maxTriggers": 2, "effect": {"kind": "FoodMultiplier", "amount": 3}, }, "level3Ability": { - "description": "Food with Health and Attack effects are quadrupled.", + "description": "Shop food gives four times attack and health. Works 2 times per turn.", "trigger": "PurchaseFood", "triggeredBy": {"kind": "Self"}, + "maxTriggers": 2, "effect": {"kind": "FoodMultiplier", "amount": 4}, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - ], }, "pet-boar": { "name": "Boar", @@ -8138,79 +3438,41 @@ "baseHealth": 6, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Before attack: Gain +2/+2.", + "description": "Before attack: Gain +4 attack and +2 health.", "trigger": "BeforeAttack", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 2, + "attackAmount": 4, "healthAmount": 2, "untilEndOfBattle": False, }, }, "level2Ability": { - "description": "Before attack: Gain +4/+4.", + "description": "Before attack: Gain +8 attack and +4 health.", "trigger": "BeforeAttack", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 4, + "attackAmount": 8, "healthAmount": 4, "untilEndOfBattle": False, }, }, "level3Ability": { - "description": "Before attack: Gain +6/+6.", + "description": "Before attack: Gain +12 attack and +6 health.", "trigger": "BeforeAttack", "triggeredBy": {"kind": "Self"}, "effect": { "kind": "ModifyStats", "target": {"kind": "Self"}, - "attackAmount": 6, + "attackAmount": 12, "healthAmount": 6, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - ], }, "pet-dragon": { "name": "Dragon", @@ -8221,13 +3483,14 @@ "unicodeCodePoint": "🐉", }, "tier": 6, - "baseAttack": 6, + "baseAttack": 3, "baseHealth": 8, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Buy tier 1 animal: Give all friends +1/+1.", + "description": "Tier 1 friend bought: Give friends +1 attack and +1 health. Works 4 times per turn.", "trigger": "BuyTier1Animal", "triggeredBy": {"kind": "Player"}, + "maxTriggers": 4, "effect": { "kind": "ModifyStats", "target": {"kind": "EachFriend"}, @@ -8237,9 +3500,10 @@ }, }, "level2Ability": { - "description": "Buy tier 1 animal: Give all friends +2/+2.", + "description": "Tier 1 friend bought: Give friends +2 attack and +2 health. Works 4 times per turn.", "trigger": "BuyTier1Animal", "triggeredBy": {"kind": "Player"}, + "maxTriggers": 4, "effect": { "kind": "ModifyStats", "target": {"kind": "EachFriend"}, @@ -8249,9 +3513,10 @@ }, }, "level3Ability": { - "description": "Buy tier 1 animal: Give all friends +3/+3.", + "description": "Tier 1 friend bought: Give friends +3 attack and +3 health. Works 4 times per turn.", "trigger": "BuyTier1Animal", "triggeredBy": {"kind": "Player"}, + "maxTriggers": 4, "effect": { "kind": "ModifyStats", "target": {"kind": "EachFriend"}, @@ -8260,44 +3525,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - ], }, "pet-fly": { "name": "Fly", @@ -8308,71 +3535,48 @@ "unicodeCodePoint": "🪰", }, "tier": 6, - "baseAttack": 5, - "baseHealth": 5, + "baseAttack": 4, + "baseHealth": 4, "packs": ["StandardPack"], "level1Ability": { - "description": "Friend faints: Summon a 5/5 fly in its place (Max 3 times)", + "description": "Friend faints: Summon one 4/4 fly in its place. Works 3 times per turn.", "trigger": "Faint", "triggeredBy": {"kind": "EachFriend"}, "effect": { "kind": "SummonPet", "pet": "pet-zombie-fly", - "withAttack": 5, - "withHealth": 5, + "withAttack": 4, + "withHealth": 4, "team": "Friendly", }, "maxTriggers": 3, }, "level2Ability": { - "description": "Friend faints: Summon a 10/10 fly in its place (Max 3 times)", + "description": "Friend faints: Summon one 8/8 fly in its place. Works 3 times per turn.", "trigger": "Faint", "triggeredBy": {"kind": "EachFriend"}, "effect": { "kind": "SummonPet", "pet": "pet-zombie-fly", - "withAttack": 10, - "withHealth": 10, + "withAttack": 8, + "withHealth": 8, "team": "Friendly", }, "maxTriggers": 3, }, "level3Ability": { - "description": "Friend faints: Summon a 15/15 fly in its place (Max 3 times)", + "description": "Friend faints: Summon one 12/12 fly in its place. Works 3 times per turn.", "trigger": "Faint", "triggeredBy": {"kind": "EachFriend"}, "effect": { "kind": "SummonPet", "pet": "pet-zombie-fly", - "withAttack": 15, - "withHealth": 15, + "withAttack": 12, + "withHealth": 12, "team": "Friendly", }, "maxTriggers": 3, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - ], }, "pet-gorilla": { "name": "Gorilla", @@ -8383,11 +3587,11 @@ "unicodeCodePoint": "🦍", }, "tier": 6, - "baseAttack": 6, - "baseHealth": 9, + "baseAttack": 7, + "baseHealth": 10, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Hurt: Gain Coconut Shield. Works 1 time per turn.", + "description": "Hurt: Gain Coconut perk. Works 1 time per turn.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { @@ -8398,7 +3602,7 @@ "maxTriggers": 1, }, "level2Ability": { - "description": "Hurt: Gain Coconut Shield. Works 2 times per turn.", + "description": "Hurt: Gain Coconut perk. Works 2 times per turn.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { @@ -8409,7 +3613,7 @@ "maxTriggers": 2, }, "level3Ability": { - "description": "Hurt: Gain Coconut Shield. Works 3 times per turn.", + "description": "Hurt: Gain Coconut perk. Works 3 times per turn.", "trigger": "Hurt", "triggeredBy": {"kind": "Self"}, "effect": { @@ -8419,44 +3623,6 @@ }, "maxTriggers": 3, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - ], }, "pet-leopard": { "name": "Leopard", @@ -8472,7 +3638,7 @@ "baseHealth": 4, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Start of battle: Deal 50% Attack damage to a random enemy.", + "description": "Start of battle: Deal 50% attack damage to one random enemy.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -8482,7 +3648,7 @@ }, }, "level2Ability": { - "description": "Start of battle: Deal 50% Attack damage to 2 random enemies.", + "description": "Start of battle: Deal 50% attack damage to two random enemies.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -8492,7 +3658,7 @@ }, }, "level3Ability": { - "description": "Start of battle: Deal 50% Attack damage to 3 random enemies.", + "description": "Start of battle: Deal 50% attack damage to three random enemies.", "trigger": "StartOfBattle", "triggeredBy": {"kind": "Player"}, "effect": { @@ -8501,44 +3667,6 @@ "amount": {"attackDamagePercent": 50}, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - ], }, "pet-mammoth": { "name": "Mammoth", @@ -8549,11 +3677,11 @@ "unicodeCodePoint": "🦣", }, "tier": 6, - "baseAttack": 3, - "baseHealth": 10, + "baseAttack": 4, + "baseHealth": 12, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { - "description": "Faint: Give all friends +2/+2", + "description": "Faint: Give friends +2 attack and +2 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -8565,7 +3693,7 @@ }, }, "level2Ability": { - "description": "Faint: Give all friends +4/+4", + "description": "Faint: Give friends +4 attack and +4 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -8577,7 +3705,7 @@ }, }, "level3Ability": { - "description": "Faint: Give all friends +6/+6", + "description": "Faint: Give friends +6 attack and +6 health.", "trigger": "Faint", "triggeredBy": {"kind": "Self"}, "effect": { @@ -8588,44 +3716,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - ], }, "pet-octopus": { "name": "Octopus", @@ -8679,29 +3769,6 @@ "amount": 5, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - ], }, "pet-sauropod": { "name": "Sauropod", @@ -8736,29 +3803,6 @@ "effect": {"kind": "GainGold", "amount": 1}, "maxTriggers": 3, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, - }, - ], }, "pet-snake": { "name": "Snake", @@ -8769,13 +3813,14 @@ "unicodeCodePoint": "🐍", }, "tier": 6, - "baseAttack": 6, - "baseHealth": 6, + "baseAttack": 8, + "baseHealth": 3, "packs": ["StandardPack"], "level1Ability": { - "description": "Friend ahead attacks: Deal 5 damage to a random enemy.", + "description": "Friend ahead attacks: Deal 5 damage to one random enemy. Works 5 times per battle.", "trigger": "AfterAttack", "triggeredBy": {"kind": "FriendAhead", "n": 1}, + "maxTriggers": 5, "effect": { "kind": "DealDamage", "target": {"kind": "RandomEnemy", "n": 1}, @@ -8783,9 +3828,10 @@ }, }, "level2Ability": { - "description": "Friend ahead attacks: Deal 10 damage to a random enemy.", + "description": "Friend ahead attacks: Deal 10 damage to one random enemy. Works 5 times per battle.", "trigger": "AfterAttack", "triggeredBy": {"kind": "FriendAhead", "n": 1}, + "maxTriggers": 5, "effect": { "kind": "DealDamage", "target": {"kind": "RandomEnemy", "n": 1}, @@ -8793,38 +3839,16 @@ }, }, "level3Ability": { - "description": "Friend ahead attacks: Deal 15 damage to a random enemy.", + "description": "Friend ahead attacks: Deal 15 damage to one random enemy. Works 5 times per battle.", "trigger": "AfterAttack", "triggeredBy": {"kind": "FriendAhead", "n": 1}, + "maxTriggers": 5, "effect": { "kind": "DealDamage", "target": {"kind": "RandomEnemy", "n": 1}, "amount": 15, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"StandardPack": 0.08328505725105906}, - "perSlot": {"StandardPack": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": {"StandardPack": 0.1111111111111111}, - }, - ], }, "pet-tiger": { "name": "Tiger", @@ -8835,8 +3859,8 @@ "unicodeCodePoint": "🐅", }, "tier": 6, - "baseAttack": 4, - "baseHealth": 3, + "baseAttack": 6, + "baseHealth": 4, "packs": ["StandardPack", "ExpansionPack1"], "level1Ability": { "description": "The friend ahead repeats their ability in battle as if they were level 1.", @@ -8868,44 +3892,6 @@ "level": 3, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.08328505725105906, - "ExpansionPack1": 0.08328505725105906, - }, - "perSlot": { - "StandardPack": 0.017241379310344827, - "ExpansionPack1": 0.017241379310344827, - }, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - ], }, "pet-tyrannosaurus": { "name": "Tyrannosaurus", @@ -8955,29 +3941,49 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": {"ExpansionPack1": 0.08328505725105906}, - "perSlot": {"ExpansionPack1": 0.017241379310344827}, - }, - { - "kind": "levelup", - "turn": "turn-9", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, + }, + "pet-wolverine": { + "name": "Wolverine", + "id": "pet-wolverine", + "image": { + "source": "noto-emoji", + "commit": "e022fd6573782431ac9a65b520376b57511c31cd", + "unicodeCodePoint": "🐺", + }, + "tier": 6, + "baseAttack": 5, + "baseHealth": 7, + "packs": ["StandardPack"], + "level1Ability": { + "description": "Four friends hurt: Remove 3 health from all enemies.", + "trigger": "FriendHurt", + "triggeredBy": {"kind": "EachFriend", "n": 4, "excludeSelf": True}, + "effect": { + "kind": "ReduceHealth", + "target": {"kind": "EachEnemy"}, + "amount": 3, }, - { - "kind": "levelup", - "turn": "turn-10", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, + }, + "level2Ability": { + "description": "Four friends hurt: Remove 6 health from all enemies.", + "trigger": "FriendHurt", + "triggeredBy": {"kind": "EachFriend", "n": 4, "excludeSelf": True}, + "effect": { + "kind": "ReduceHealth", + "target": {"kind": "EachEnemy"}, + "amount": 6, }, - { - "kind": "levelup", - "turn": "turn-11", - "perSlot": {"ExpansionPack1": 0.1111111111111111}, + }, + "level3Ability": { + "description": "Four friends hurt: Remove 9 health from all enemies.", + "trigger": "FriendHurt", + "triggeredBy": {"kind": "EachFriend", "n": 4, "excludeSelf": True}, + "effect": { + "kind": "ReduceHealth", + "target": {"kind": "EachEnemy"}, + "amount": 9, }, - ], + }, }, "pet-zombie-cricket": { "name": "Zombie Cricket", @@ -9121,119 +4127,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - "perSlot": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - "perSlot": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-honey": { "name": "Honey", @@ -9255,119 +4148,6 @@ "status": "status-honey-bee", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-1", - "perShop": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - "perSlot": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - }, - { - "kind": "shop", - "turn": "turn-2", - "perShop": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - "perSlot": {"StandardPack": 0.5, "ExpansionPack1": 0.5}, - }, - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-cupcake": { "name": "Cupcake", @@ -9391,107 +4171,6 @@ "untilEndOfBattle": True, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-meat-bone": { "name": "Meat Bone", @@ -9513,107 +4192,6 @@ "status": "status-bone-attack", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-sleeping-pill": { "name": "Sleeping Pill", @@ -9634,107 +4212,6 @@ "trigger": "Buy", "effect": {"kind": "Faint", "target": {"kind": "PurchaseTarget"}}, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-3", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-4", - "perShop": { - "StandardPack": 0.3599999999999999, - "ExpansionPack1": 0.3599999999999999, - }, - "perSlot": {"StandardPack": 0.2, "ExpansionPack1": 0.2}, - }, - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-garlic": { "name": "Garlic", @@ -9756,89 +4233,6 @@ "status": "status-garlic-armor", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-salad-bowl": { "name": "Salad Bowl", @@ -9862,89 +4256,28 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-5", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-6", - "perShop": { - "StandardPack": 0.26530612244897966, - "ExpansionPack1": 0.26530612244897966, - }, - "perSlot": { - "StandardPack": 0.14285714285714285, - "ExpansionPack1": 0.14285714285714285, - }, - }, - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], + }, + "food-cake": { + "name": "Cake", + "id": "food-cake", + "image": { + "source": "twemoji", + "commit": "793a6a93f303c08877dd6eb589b2fabb3d1c45ee", + "unicodeCodePoint": "🎂", + }, + "tier": 3, + "packs": ["StandardPack"], + "cost": 3, + "ability": { + "description": "Give an animal Cake.", + "triggeredBy": {"kind": "Self"}, + "trigger": "Buy", + "effect": { + "kind": "ApplyStatus", + "to": {"kind": "PurchaseTarget"}, + "status": "status-cake", + }, + }, }, "food-canned-food": { "name": "Canned Food", @@ -9957,76 +4290,17 @@ "tier": 4, "packs": ["StandardPack", "ExpansionPack1"], "ability": { - "description": "Give all current and future shop animals +2/+1.", + "description": "Give all current and future shop pets +1/+1.", "triggeredBy": {"kind": "Self"}, "trigger": "Buy", "effect": { "kind": "ModifyStats", "target": {"kind": "EachShopAnimal", "includingFuture": True}, - "attackAmount": 2, + "attackAmount": 1, "healthAmount": 1, "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-pear": { "name": "Pear", @@ -10050,65 +4324,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-7", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-8", - "perShop": { - "StandardPack": 0.2098765432098766, - "ExpansionPack1": 0.2098765432098766, - }, - "perSlot": { - "StandardPack": 0.1111111111111111, - "ExpansionPack1": 0.1111111111111111, - }, - }, - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-chili": { "name": "Chili", @@ -10130,41 +4345,6 @@ "status": "status-splash-attack", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-chocolate": { "name": "Chocolate", @@ -10186,41 +4366,6 @@ "amount": 1, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-sushi": { "name": "Sushi", @@ -10244,41 +4389,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-9", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-10", - "perShop": { - "StandardPack": 0.15972222222222232, - "ExpansionPack1": 0.15972222222222232, - }, - "perSlot": { - "StandardPack": 0.08333333333333333, - "ExpansionPack1": 0.08333333333333333, - }, - }, - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - }, - ], }, "food-melon": { "name": "Melon", @@ -10300,17 +4410,6 @@ "status": "status-melon-armor", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - } - ], }, "food-mushroom": { "name": "Mushroom", @@ -10332,17 +4431,6 @@ "status": "status-extra-life", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - } - ], }, "food-pizza": { "name": "Pizza", @@ -10366,17 +4454,6 @@ "untilEndOfBattle": False, }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - } - ], }, "food-steak": { "name": "Steak", @@ -10398,17 +4475,6 @@ "status": "status-steak-attack", }, }, - "probabilities": [ - { - "kind": "shop", - "turn": "turn-11", - "perShop": { - "StandardPack": 0.12109375, - "ExpansionPack1": 0.12109375, - }, - "perSlot": {"StandardPack": 0.0625, "ExpansionPack1": 0.0625}, - } - ], }, "food-milk": { "name": "Milk", @@ -10435,6 +4501,31 @@ }, }, }, + "food-bread-crumbs": { + "name": "Bread Crumbs", + "id": "food-bread-crumbs", + "notes": "This is free!", + "image": { + "source": "twemoji", + "commit": "793a6a93f303c08877dd6eb589b2fabb3d1c45ee", + "unicodeCodePoint": "🍞", + }, + "tier": "Summoned", + "packs": ["StandardPack"], + "cost": 0, + "ability": { + "description": "Give an animal +1 attack.", + "triggeredBy": {"kind": "Self"}, + "trigger": "Buy", + "effect": { + "kind": "ModifyStats", + "target": {"kind": "PurchaseTarget"}, + "attackAmount": 1, + "healthAmount": 0, + "untilEndOfBattle": False, + }, + }, + }, }, "statuses": { "status-weak": { @@ -10499,16 +4590,31 @@ "unicodeCodePoint": "🍖", }, "ability": { - "description": "Attack for 5 more damage.", + "description": "Attack for 3 more damage.", "triggeredBy": {"kind": "Self"}, "trigger": "WhenAttacking", "effect": { "kind": "ModifyDamage", - "damageModifier": 5, + "damageModifier": 3, "appliesOnce": False, }, }, }, + "status-cake": { + "name": "Cake", + "id": "status-cake", + "image": { + "source": "twemoji", + "commit": "793a6a93f303c08877dd6eb589b2fabb3d1c45ee", + "unicodeCodePoint": "🎂", + }, + "ability": { + "description": "End turn: Increase sell value by 1 gold.", + "triggeredBy": {"kind": "Self"}, + "trigger": "EndOfTurn", + "effect": {"kind": "ModifySellValue", "target": {"kind": "Self"}, "amount": 1}, + }, + }, "status-garlic-armor": { "name": "Garlic Armor", "id": "status-garlic-armor", @@ -10641,7 +4747,7 @@ "name": "Turn 3", "id": "turn-3", "index": 3, - "foodShopSlots": 2, + "foodShopSlots": 1, "animalShopSlots": 3, "livesLost": 2, "tiersAvailable": 2, @@ -10651,7 +4757,7 @@ "name": "Turn 4", "id": "turn-4", "index": 4, - "foodShopSlots": 2, + "foodShopSlots": 1, "animalShopSlots": 3, "livesLost": 2, "tiersAvailable": 2, @@ -10788,4 +4894,9 @@ def add_dummy_fields(fields, d): add_dummy_fields(temp_all_fields, dummy_foods) data["foods"]["food-none"] = dummy_foods +### Generate probabilities at run time +from sapai.probabilities import generate_probabilities + +generate_probabilities(data) + # %% diff --git a/sapai/effects.py b/sapai/effects.py index 3972b70..9090df9 100644 --- a/sapai/effects.py +++ b/sapai/effects.py @@ -360,19 +360,27 @@ def get_target( return [fteam[max_idx].pet], [[fteam[max_idx].pet]] elif kind == "Level2And3Friends": - level_list = [] + keep_fidx = [] for temp_idx in fidx: - level_list.append(fteam[temp_idx].pet.level) - if len(level_list) > 0: - keep_idx = np.where(np.array(level_list) > 1)[0] - ret_pets = [] - for temp_idx in keep_idx: - ### Dereference idx - temp_idx = fidx[temp_idx] - ret_pets.append(fteam[temp_idx].pet) - return ret_pets, [ret_pets] - else: + if temp_idx == apet_idx[1]: + continue + if fteam[temp_idx].pet.level > 1: + keep_fidx.append(temp_idx) + if len(keep_fidx) == 0: return [], [] + if len(keep_fidx) < n: + n = len(keep_fidx) + all_idx = [x for x in itertools.combinations(keep_fidx, n)] + all_possible = [] + for temp_idx in all_idx: + temp_chosen = [fteam[x].pet for x in temp_idx] + all_possible.append(temp_chosen) + crange = np.arange(0, len(all_possible)) + cidx = apet.rs.choice(crange, (1,), replace=False)[0] + ### Update internal state of random generator + apet.seed_state = apet.rs.get_state() + ret_pets = all_possible[cidx] + return ret_pets, all_possible elif kind == "LowestHealthEnemy": health_list = [] @@ -414,15 +422,16 @@ def get_target( ret_pets = [] all_possible = [] if len(fidx) > 0: - if len(fidx) < n: - n = len(fidx) keep_fidx = [] for temp_entry in fidx: if temp_entry == apet_idx[1]: continue keep_fidx.append(temp_entry) - fidx = keep_fidx - all_idx = [x for x in itertools.combinations(fidx, n)] + if len(keep_fidx) == 0: + return [], [] + if len(keep_fidx) < n: + n = len(keep_fidx) + all_idx = [x for x in itertools.combinations(keep_fidx, n)] all_possible = [] for temp_idx in all_idx: temp_chosen = [fteam[x].pet for x in temp_idx] @@ -558,18 +567,25 @@ def DealDamage(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None): else: raise Exception() for target_pet in target: + temp_health_amount = health_amount + if ( + apet.name == "pet-rhino" + and apet.ability["trigger"] == "KnockOut" + and target_pet.tier == 1 + ): + temp_health_amount *= 2 if target_pet.status == "status-melon-armor": - health_amount = max(0, health_amount - 20) + temp_health_amount = max(0, temp_health_amount - 20) target_pet.status = "none" elif target_pet.status == "status-garlic-armor": - health_amount = max(1, health_amount - 2) + temp_health_amount = max(1, temp_health_amount - 2) elif target_pet.status == "status-coconut-shield": - health_amount = 0 + temp_health_amount = 0 target_pet.status = "none" elif target_pet.status == "status-weak": - health_amount += 3 + temp_health_amount += 3 - target_pet.hurt(health_amount) + target_pet.hurt(temp_health_amount) return target, possible @@ -692,6 +708,21 @@ def ModifyStats(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None) return target, possible +def ModifySellValue(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None): + fixed_targets = fixed_targets or [] + + if len(fixed_targets) == 0: + target, possible = get_target(apet, apet_idx, teams, te=te) + else: + target = fixed_targets + possible = [fixed_targets] + + amount = apet.ability["effect"]["amount"] + for target_pet in target: + target_pet.sell_value += amount + return target, possible + + def OneOf(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None): """ Dog is only one with OneOf anyways @@ -728,35 +759,72 @@ def ReduceHealth(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None else: target = fixed_targets possible = [fixed_targets] - per = apet.ability["effect"]["percentage"] * 0.01 - for temp_pet in target: - if temp_pet.health > 0: - temp_pet._health = temp_pet.health - int(np.round(temp_pet.health * per)) - if temp_pet._health == 0: - ### Floor health of 1 - temp_pet._health = 1 - return target, possible + effect = apet.ability["effect"] + if "percentage" in effect: + per = effect["percentage"] * 0.01 + for temp_pet in target: + if temp_pet.health > 0: + temp_pet._health = temp_pet.health - int(np.round(temp_pet.health * per)) + if temp_pet._health == 0: + ### Floor health of 1 + temp_pet._health = 1 + elif "amount" in effect: + amount = effect["amount"] + for temp_pet in target: + if temp_pet.health > 0: + temp_pet._health = temp_pet.health - amount + else: + raise Exception("ReduceHealth requires either percentage or amount") + return target, possible -def RefillShops(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None): - """ - Only Cow has refill shop in newest patch anyways... - """ +def StockShopFood(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None): fixed_targets = fixed_targets or [] - if apet.name != "pet-cow": - raise Exception("Only cow implemented for RefillShops") + effect = apet.ability["effect"] + shop_kind = effect["shop"] + if shop_kind != "Food": + raise Exception(f"Unsupported shop kind for StockShopFood: {shop_kind}") + shop = apet.shop - level = apet.level + if shop is None: + raise Exception("No shop found to stock food") + + if apet.name == "pet-cow": + ### Cow replaces all shop food + non_food_slots = [slot for slot in shop.slots if slot.slot_type != "food"] + shop.slots = non_food_slots + shop.nslots = len(non_food_slots) + + food_name = effect["food"] + amount = effect["amount"] + with_attack = effect.get("withAttack") + with_health = effect.get("withHealth") + with_cost = effect.get("withCost") + targets = [] - for slot in shop: - if slot.slot_type == "food": - temp_food = Food("milk") - temp_food.attack *= level - temp_food.health *= level - slot.item = temp_food - targets.append(slot) + max_food_slots = shop.max_food_slots + for _ in range(amount): + food_slot_count = sum(1 for slot in shop.slots if slot.slot_type == "food") + if food_slot_count >= max_food_slots: + break + temp_food = Food(food_name) + if with_attack is not None: + temp_food.attack = with_attack + if with_health is not None: + temp_food.health = with_health + if with_cost is not None: + temp_food.cost = with_cost + shop.append(temp_food) + added_slot = None + for slot in shop.slots: + if slot.obj is temp_food: + added_slot = slot + break + if added_slot is None: + break + targets.append(added_slot) return targets, [targets] @@ -884,11 +952,7 @@ def SummonPet(apet, apet_idx, teams, te=None, te_idx=None, fixed_targets=None): else: raise Exception(apet.ability["effect"]["team"]) - n = 1 - if apet.name == "pet-sheep": - n = 2 - elif apet.name == "pet-rooster": - n = apet.level + n = apet.ability["effect"].get("amount", 1) target = [] for _ in range(n): diff --git a/sapai/graph.py b/sapai/graph.py index 4118679..2df626a 100644 --- a/sapai/graph.py +++ b/sapai/graph.py @@ -20,7 +20,7 @@ def html_table( header_font_attr = header_font_attr or [("COLOR", "#000000")] cell_font_attr = cell_font_attr or [] column_align = column_align or ["RIGHT", "LEFT"] - cell_bg_colors = cell_bg_colors or [[]] + cell_bg_colors = [] if cell_bg_colors is None else cell_bg_colors table_attr_str = "" for attr, value in table_attr: @@ -166,7 +166,7 @@ def graph_battle(f, file_name="", verbose=False): "CENTER", "CENTER", ], - cell_bg_colors=[[]], + cell_bg_colors=[], ) g.node( str(node_idx), style="rounded,invisible", shape="box", label=temp_table @@ -283,7 +283,7 @@ def graph_battle(f, file_name="", verbose=False): cell_font_attr=[], cell_border=0, column_align=["CENTER", "CENTER", "CENTER", "CENTER", "CENTER"], - cell_bg_colors=[[]], + cell_bg_colors=[], ) g.node( str(node_idx), style="rounded,invisible", shape="box", label=temp_table diff --git a/sapai/pets.py b/sapai/pets.py index 34dacd2..1972099 100644 --- a/sapai/pets.py +++ b/sapai/pets.py @@ -54,12 +54,14 @@ def __init__( self._until_end_of_battle_attack_buff = 0 self._until_end_of_battle_health_buff = 0 self._hurt = 0 + self._friend_hurt_counter = 0 self.status = "none" if "status" in self.fd: self.status = self.fd["status"] self.level = 1 self.experience = 0 + self.sell_value = 1 #### Add pet to team if not already present if self.team is not None: @@ -132,9 +134,6 @@ def eat(self, food): return self.gain_experience() elif food.name == "food-sleeping-pill": self._health = -1000 - elif food.name == "food-canned-food": - food.shop.shop_attack += food.attack - food.shop.shop_health += food.health return False def init_battle(self): @@ -155,6 +154,7 @@ def gain_experience(self, amount=1): if self.level == 1: if self.experience >= 2: self.level += 1 + self.sell_value += 1 self.experience -= 2 ### Call recursive incase multiple level-ups occuring self.gain_experience(0) @@ -162,6 +162,7 @@ def gain_experience(self, amount=1): elif self.level == 2: if self.experience >= 3: self.level += 1 + self.sell_value += 1 self.experience -= 3 self.gain_experience(0) level_up = True @@ -185,11 +186,17 @@ def sot_trigger(self, trigger=None): ### Reset ability_counter for goat at sot_trigger self.ability_counter = 0 + ### Parrot copies an ability until the next turn; expire override after + ### this start-of-turn processing completes. + parrot_override = self.name == "pet-parrot" and self.override_ability activated = False targets = [] possible = [] if self.ability["trigger"] != "StartOfTurn": + if parrot_override: + self.override_ability = False + self.override_ability_dict = {} return activated, targets, possible func = get_effect_function(self) @@ -197,6 +204,9 @@ def sot_trigger(self, trigger=None): targets, possible = func(self, [0, pet_idx], [self.team], trigger) activated = True + if parrot_override: + self.override_ability = False + self.override_ability_dict = {} return activated, targets, possible def cat_trigger(self, trigger=None): @@ -448,47 +458,77 @@ def eot_trigger(self, trigger=None): activated = False targets = [] possible = [] - if not self.ability["trigger"].startswith("EndOfTurn"): + pet_has_eot = self.ability["trigger"].startswith("EndOfTurn") + status_ability = None + status_has_eot = False + if self.status in data["statuses"]: + status_ability = data["statuses"][self.status]["ability"] + status_has_eot = status_ability["trigger"].startswith("EndOfTurn") + if not pet_has_eot and not status_has_eot: return activated, targets, possible - ### Check gold for puppy and tyrannosaurus - if self.ability["trigger"] == "EndOfTurnWith3PlusGold": - if self.player is not None: - if self.player.gold >= 3: - pass + if status_has_eot: + previous_override = self.override_ability + previous_override_dict = self.override_ability_dict + self.set_ability(status_ability) + func = get_effect_function(self) + pet_idx = self.team.get_idx(self) + temp_targets, temp_possible = func(self, [0, pet_idx], [self.team], te=trigger) + targets += temp_targets + possible += temp_possible + self.override_ability = previous_override + self.override_ability_dict = previous_override_dict + activated = True + + if pet_has_eot: + ### Check gold for puppy and tyrannosaurus + if self.ability["trigger"] == "EndOfTurnWith3PlusGold": + if self.player is not None: + if self.player.gold >= 3: + pass + else: + return activated, targets, possible else: return activated, targets, possible - else: - return activated, targets, possible - ### Check for bison - elif self.ability["trigger"] == "EndOfTurnWithLvl3Friend": - if self.team is not None: - if not self.team.check_lvl3(): + ### Check for bison + elif self.ability["trigger"] == "EndOfTurnWithLvl3Friend": + if self.team is not None: + if not self.team.check_lvl3(): + return activated, targets, possible + else: return activated, targets, possible - else: - return activated, targets, possible - ### Check for llama - elif self.ability["trigger"] == "EndOfTurnWith4OrLessAnimals": - if self.team is not None: - if len(self.team) > 4: + ### Check for llama + elif self.ability["trigger"] == "EndOfTurnWith4OrLessAnimals": + if self.team is not None: + if len(self.team) > 4: + return activated, targets, possible + else: + return activated, targets, possible + ### Check for snail + elif self.ability["trigger"] == "EndOfTurnAfterLoss": + if self.player is not None: + if self.player.lf_winner == False: + pass + else: + return activated, targets, possible + else: return activated, targets, possible else: - return activated, targets, possible - else: - if self.ability["trigger"] != "EndOfTurn": - raise Exception(f"Unrecognized trigger {self.ability['trigger']}") + if self.ability["trigger"] != "EndOfTurn": + raise Exception(f"Unrecognized trigger {self.ability['trigger']}") - if "maxTriggers" in self.ability: - if self.ability_counter >= self.ability["maxTriggers"]: - return activated, targets, possible - else: - self.ability_counter += 1 + if "maxTriggers" in self.ability: + if self.ability_counter >= self.ability["maxTriggers"]: + return activated, targets, possible + else: + self.ability_counter += 1 - func = get_effect_function(self) - pet_idx = self.team.get_idx(self) - targets, possible = func(self, [0, pet_idx], [self.team], te=trigger) + func = get_effect_function(self) + pet_idx = self.team.get_idx(self) + targets, possible = func(self, [0, pet_idx], [self.team], te=trigger) + + activated = True - activated = True return activated, targets, possible def faint_trigger(self, trigger=None, te_idx=None, oteam=None): @@ -638,7 +678,7 @@ def after_attack_trigger(self, trigger): opponent's Team. Pets: - ["kangaroo","snake"] + ["elephant", "kangaroo", "snake"] """ activated = False @@ -650,19 +690,22 @@ def after_attack_trigger(self, trigger): if type(trigger).__name__ != "Team": raise Exception("Trigger must be a Team") - if self.ability["triggeredBy"]["kind"] != "FriendAhead": + if self.ability["triggeredBy"]["kind"] == "FriendAhead": + ### Check that self is behind the front friend which should have just + ### attacked + slot_ahead = self.team.get_ahead(self, n=1) + if len(slot_ahead) == 0: + return activated, targets, possible + if self.team.index(slot_ahead[0]) != 0: + return activated, targets, possible + elif self.ability["triggeredBy"]["kind"] == "Self": + if self.team.get_idx(self) != 0: + return activated, targets, possible + else: raise Exception( - "Only triggeredBy FriendAhead implemented for after_attack_trigger" + "Only triggeredBy FriendAhead and Self implemented for after_attack_trigger" ) - ### Check that self is behind the front friend which should have just - ### attacked - slot_ahead = self.team.get_ahead(self, n=1) - if len(slot_ahead) == 0: - return activated, targets, possible - if self.team.index(slot_ahead[0]) != 0: - return activated, targets, possible - if "maxTriggers" in self.ability: if self.ability_counter >= self.ability["maxTriggers"]: return activated, targets, possible @@ -683,8 +726,7 @@ def after_attack_trigger(self, trigger): def hurt_trigger(self, trigger): """ Apply pet's ability after being hurt attacking. Input trigger is the - opponent's Team. Only activate hurt trigger if the pet has health above - 0. + opponent's Team. There is no way to test if hurt_trigger should be activated within this function. Therefore, only call hurt trigger where appropriate during @@ -713,10 +755,6 @@ def hurt_trigger(self, trigger): else: raise Exception("Only Self trigger available for hurt_trigger") - ### Cannot call if health is less than zero because fainted - if self._health <= 0: - return activated, targets, possible - if "maxTriggers" in self.ability: if self.ability_counter >= self.ability["maxTriggers"]: return activated, targets, possible @@ -732,6 +770,59 @@ def hurt_trigger(self, trigger): activated = True return activated, targets, possible + def friend_hurt_trigger(self, trigger, oteam): + """ + Apply pet's ability after friendly hurt events. + + Pets: + ["wolverine"] + """ + activated = False + targets = [] + possible = [] + + if self.ability["trigger"] != "FriendHurt": + return activated, targets, possible + + if type(trigger).__name__ != "Pet": + raise Exception("Trigger must be a Pet") + + if type(oteam).__name__ != "Team": + raise Exception("Trigger must include opponent Team") + + if not self.team.check_friend(self): + return activated, targets, possible + + if self.ability["triggeredBy"]["kind"] != "EachFriend": + raise Exception("Only EachFriend trigger available for friend_hurt_trigger") + + if trigger == self: + return activated, targets, possible + + if not self.team.check_friend(trigger): + return activated, targets, possible + + n_hurt = self.ability["triggeredBy"].get("n", 1) + if n_hurt < 1: + raise Exception(f"Invalid friend hurt threshold: {n_hurt}") + + self._friend_hurt_counter += 1 + if self._friend_hurt_counter < n_hurt: + return activated, targets, possible + + func = get_effect_function(self) + pet_idx = self.team.get_idx(self) + while self._friend_hurt_counter >= n_hurt: + self._friend_hurt_counter -= n_hurt + temp_targets, temp_possible = tiger_func( + func, False, self, [0, pet_idx], [self.team, oteam], trigger + ) + targets += temp_targets + possible += temp_possible + activated = True + + return activated, targets, possible + def knockout_trigger(self, trigger): """ Apply pet's ability after knockout on opponent. Input trigger is the @@ -819,6 +910,7 @@ def state(self): "status": self.status, "level": self.level, "experience": self.experience, + "sell_value": self.sell_value, "seed_state": seed_state, } @@ -844,6 +936,10 @@ def from_state(cls, state): pet.status = state["status"] pet.level = state["level"] pet.experience = state["experience"] + if "sell_value" in state: + pet.sell_value = state["sell_value"] + else: + pet.sell_value = state["level"] ### Supply seed_state in state dict should be optional if "seed_state" in state: diff --git a/sapai/player.py b/sapai/player.py index 52e8810..4c5b8c0 100644 --- a/sapai/player.py +++ b/sapai/player.py @@ -217,6 +217,10 @@ def buy_food(self, food, team_pet=None): ### Make all updates self.gold -= cost self.shop.buy(food) + if food.name == "food-canned-food": + ### Canned food boosts future shop pets once per purchase + self.shop.shop_attack += food.attack + self.shop.shop_health += food.health for pet in targets: levelup = pet.eat(food) ### Check for levelup triggers if appropriate @@ -341,8 +345,8 @@ def sell(self, pet): if self.team.check_friend(pet): self.team.remove(pet) - ### Add default gold - self.gold += 1 + ### Add sell gold, including any sell value buffs. + self.gold += pet.sell_value return (pet,) @@ -406,12 +410,22 @@ def roll(self): @staticmethod def combine_pet_stats(pet_to_keep, pet_to_be_merged): """Pet 1 is the pet that is kept""" - c_attack = max(pet_to_keep._attack, pet_to_be_merged._attack) + 1 + if pet_to_keep.level == 3 or pet_to_be_merged.level == 3: + raise Exception("Attempted to combine with level 3 pet") + + exp_value_by_level = {1: 1, 2: 3} + keep_exp_value = exp_value_by_level[pet_to_keep.level] + pet_to_keep.experience + consumed_exp_value = exp_value_by_level[pet_to_be_merged.level] + pet_to_be_merged.experience + + ### Stat bonus uses the lower XP-value between keep/consumed pets. + stat_bonus = min(keep_exp_value, consumed_exp_value) + + c_attack = max(pet_to_keep._attack, pet_to_be_merged._attack) + stat_bonus c_until_end_of_battle_attack = max( pet_to_keep._until_end_of_battle_attack_buff, pet_to_be_merged._until_end_of_battle_attack_buff, ) - c_health = max(pet_to_keep._health, pet_to_be_merged._health) + 1 + c_health = max(pet_to_keep._health, pet_to_be_merged._health) + stat_bonus c_until_end_of_battle_health = max( pet_to_keep._until_end_of_battle_health_buff, pet_to_be_merged._until_end_of_battle_health_buff, @@ -423,7 +437,7 @@ def combine_pet_stats(pet_to_keep, pet_to_be_merged): pet_to_keep._until_end_of_battle_attack_buff = c_until_end_of_battle_attack pet_to_keep._until_end_of_battle_health_buff = c_until_end_of_battle_health pet_to_keep.status = cstatus - levelup = pet_to_keep.gain_experience() + levelup = pet_to_keep.gain_experience(amount=consumed_exp_value) # Check for levelup triggers if appropriate if levelup: @@ -455,6 +469,8 @@ def buy_combine(self, shop_pet, team_pet): raise Exception( f"Attempted combine for pets {team_pet.name} and {shop_pet.name}" ) + if team_pet.level == 3 or shop_pet.level == 3: + raise Exception("Attempted to combine with level 3 pet") shop_idx = self.shop.index(shop_pet) shop_slot = self.shop.slots[shop_idx] @@ -499,9 +515,12 @@ def combine(self, pet1, pet2): if pet1.name != pet2.name: raise Exception(f"Attempted combine for pets {pet1.name} and {pet2.name}") + if pet1.level == 3 or pet2.level == 3: + raise Exception("Attempted to combine with level 3 pet") + skip_levelup_reward = pet1.level == 2 and pet2.level == 2 levelup = Player.combine_pet_stats(pet1, pet2) - if levelup: + if levelup and not skip_levelup_reward: self.shop.levelup() ### Remove pet2 from team diff --git a/sapai/probabilities.py b/sapai/probabilities.py new file mode 100644 index 0000000..1936c22 --- /dev/null +++ b/sapai/probabilities.py @@ -0,0 +1,86 @@ +def get_pack_names(data): + packs = set() + for group in ("pets", "foods"): + for entry in data[group].values(): + for pack in entry.get("packs", []): + packs.add(pack) + return tuple(packs) + + +def _turn_numbers(data): + turns = [] + for key in data["turns"]: + if not key.startswith("turn-"): + raise ValueError(f"Invalid turns key '{key}'. Expected format 'turn-N'.") + turn_token = key.split("-")[-1] + if not turn_token.isdigit(): + raise ValueError(f"Invalid turn number in key '{key}'. Expected 'turn-N'.") + turns.append(int(turn_token)) + return sorted(turns) + + +def _count_shop_entries(data, group, pack, tier_limit): + count = 0 + for entry in data[group].values(): + if not isinstance(entry.get("tier"), int): + continue + if entry["tier"] > tier_limit: + continue + if pack not in entry.get("packs", []): + continue + count += 1 + return count + + +def generate_probabilities(data): + turns = _turn_numbers(data) + pack_names = get_pack_names(data) + group_configs = ( + ("pets", "animalShopSlots", "pet"), + ("foods", "foodShopSlots", "food"), + ) + + shop_counts = {group: {pack: {} for pack in pack_names} for group, _, _ in group_configs} + for turn in turns: + tiers_available = data["turns"][f"turn-{turn}"]["tiersAvailable"] + for group, _, _ in group_configs: + for pack in pack_names: + shop_counts[group][pack][turn] = _count_shop_entries( + data, group, pack, tiers_available + ) + + for group, slots_key, label in group_configs: + for entry in data[group].values(): + if not isinstance(entry.get("tier"), int): + entry["probabilities"] = "none" + continue + + probabilities = [] + for turn in turns: + turn_data = data["turns"][f"turn-{turn}"] + per_slot = {} + per_shop = {} + if entry["tier"] <= turn_data["tiersAvailable"]: + for pack in pack_names: + if pack not in entry.get("packs", []): + continue + count = shop_counts[group][pack][turn] + if count <= 0: + raise ValueError( + f"Invalid {label} shop count for pack={pack}, turn={turn}, " + f"entry={entry.get('id', '')}: {count}" + ) + slot_prob = 1 / count + per_slot[pack] = slot_prob + per_shop[pack] = 1 - (1 - slot_prob) ** turn_data[slots_key] + if per_slot: + probabilities.append( + { + "kind": "shop", + "turn": f"turn-{turn}", + "perShop": per_shop, + "perSlot": per_slot, + } + ) + + entry["probabilities"] = probabilities or "none" diff --git a/sapai/shop.py b/sapai/shop.py index b4bb3ce..24fe036 100644 --- a/sapai/shop.py +++ b/sapai/shop.py @@ -114,7 +114,9 @@ def __init__( else: self.rs = MockRandomState() - self.max_slots = 7 + self.max_pet_slots = 7 + self.max_food_slots = 5 + self.max_slots = self.max_pet_slots + self.max_food_slots self.turn = turn self.pack = pack self.shop_attack = shop_attack ### Keep track of can/chicken stats @@ -185,6 +187,7 @@ def buy(self, obj): raise Exception(f"Unrecognized Shop Object {obj}") del self.slots[idx] + self.nslots = len(self.slots) def index(self, obj): if isinstance(obj, ShopSlot): @@ -278,8 +281,19 @@ def levelup(self): with a new pet """ - new_slot = ShopSlot("levelup", pack=self.pack, turn=self.turn) - self.append(new_slot) + first_slot = ShopSlot("levelup", pack=self.pack, turn=self.turn, seed_state=self.seed_state) + self.append(first_slot) + self.seed_state = first_slot.seed_state + + second_slot = ShopSlot( + "levelup", + pack=self.pack, + turn=self.turn, + seed_state=self.seed_state, + not_allowed_pets={first_slot.obj.name}, + ) + self.append(second_slot) + self.seed_state = second_slot.seed_state def update_shop_rules(self, turn=-1, roll_only_empty=False): if turn < 0: @@ -436,21 +450,27 @@ def append(self, obj): """ Append should be used when adding an animal from a levelup """ - if len(self.slots) >= self.max_slots: - ### Max slots already reached so cannot be added - return - add_slot = ShopSlot( obj, pack=self.pack, turn=self.turn, seed_state=self.seed_state ) pslots = [] fslots = [] for iter_idx, slot in enumerate(self.slots): - if slot.slot_type == "pet": + if slot.slot_type == "pet" or slot.slot_type == "levelup": pslots.append(slot) if slot.slot_type == "food": fslots.append(slot) + if add_slot.slot_type == "food": + if len(fslots) >= self.max_food_slots: + return + else: + if len(pslots) >= self.max_pet_slots: + return + + if len(self.slots) >= self.max_slots: + return + new_slots = [] new_slots += [x for x in pslots] new_slots += [add_slot] @@ -747,6 +767,7 @@ def __init__( cost=3, pack="StandardPack", seed_state=None, + not_allowed_pets=None, ): self.seed_state = seed_state if self.seed_state is not None: @@ -759,6 +780,7 @@ def __init__( self.slot_type = slot_type self.turn = turn self.pack = pack + self.not_allowed_pets = set(not_allowed_pets or []) self.frozen = frozen self.cost = cost self.obj = ShopSlotNoneItem(seed_state=self.seed_state) @@ -778,6 +800,7 @@ def __init__( self.slot_type = obj.slot_type self.turn = obj.turn self.pack = obj.pack + self.not_allowed_pets = set(obj.not_allowed_pets) self.frozen = obj.frozen self.cost = obj.cost if self.slot_type == "food": @@ -903,6 +926,7 @@ def roll_levelup(self): avail_pets = pet_tier_lookup_std[levelup_tier] else: avail_pets = pet_tier_lookup[levelup_tier] + avail_pets = [pet for pet in avail_pets if pet not in self.not_allowed_pets] pet_choice = self.rs.choice(avail_pets, size=(1,), replace=True)[0] self.seed_state = self.rs.get_state() self.obj = Pet(pet_choice, seed_state=self.seed_state) diff --git a/sapai/status.py b/sapai/status.py index 818ff38..61f6f73 100644 --- a/sapai/status.py +++ b/sapai/status.py @@ -19,7 +19,7 @@ def apply_coconut_shield(value): def apply_bone_attack(value): if value > 0: - return value + 4 + return value + 3 else: return 0 @@ -60,6 +60,7 @@ def apply_extra_life(pet, team): apply_null_dict = { "none": apply_, "status-bone-attack": apply_, + "status-cake": apply_, "status-coconut-shield": apply_, "status-extra-life": apply_, "status-garlic-armor": apply_, @@ -74,6 +75,7 @@ def apply_extra_life(pet, team): apply_damage_dict = { "none": apply_, "status-bone-attack": apply_, + "status-cake": apply_, "status-coconut-shield": apply_coconut_shield, "status-extra-life": apply_, "status-garlic-armor": apply_garlic_armor, @@ -88,6 +90,7 @@ def apply_extra_life(pet, team): apply_attack_dict = { "none": apply_, "status-bone-attack": apply_bone_attack, + "status-cake": apply_, "status-coconut-shield": apply_, "status-extra-life": apply_, "status-garlic-armor": apply_, @@ -102,6 +105,7 @@ def apply_extra_life(pet, team): apply_faint_dict = { "none": apply_, "status-bone-attack": apply_, + "status-cake": apply_, "status-coconut-shield": apply_, "status-extra-life": apply_extra_life, "status-garlic-armor": apply_, diff --git a/tests/test_battles.py b/tests/test_battles.py index 41196ec..6c644f1 100644 --- a/tests/test_battles.py +++ b/tests/test_battles.py @@ -145,8 +145,8 @@ def test_horse_in_battle(self): test_battle = Battle(team1, team2) result = test_battle.battle() - self.assertEqual(test_battle.t0.empty, [0, 1, 2, 3, 4]) - self.assertEqual(test_battle.t1[0].health, 1) + self.assertEqual(test_battle.t0.empty, [1, 2, 3, 4]) + self.assertEqual(test_battle.t1.empty, [0, 1, 2, 3, 4]) def test_horse_with_bee_in_battle(self): cricket = Pet("cricket") @@ -185,17 +185,17 @@ def test_blowfish_pingpong(self): ) # they attack eachother, then keep using hurt_triggers until one of them dies, should never reach a 2nd attack phase def test_elephant_blowfish(self): - # blowfish snipes first fish in 'before-attack' phase of elephant, leaving elephant without a target to attack normally - # then snipes second fish in next turn's 'before attack' + # Blowfish triggers on both the splash hurt and the lethal elephant + # ability, so the second and third fish are sniped before both teams faint state = np.random.RandomState(seed=1).get_state() e1 = Pet("elephant") e1._attack = 1 - e1._health = 5 + e1._health = 6 b1 = Pet("blowfish", seed_state=state) b1._attack = 1 - b1._health = 5 + b1._health = 6 f1 = Pet("fish") f1._attack = 50 @@ -207,9 +207,194 @@ def test_elephant_blowfish(self): f2._health = 1 f2.status = "status-splash-attack" - b = Battle(Team([e1, b1]), Team([f1, f2])) + f3 = Pet("fish") + f3._attack = 50 + f3._health = 1 + f3.status = "status-splash-attack" + + b = Battle(Team([e1, b1]), Team([f1, f2, f3])) r = b.battle() - self.assertEqual(r, 0) + self.assertEqual(r, 2) + + def test_wolverine_triggers_once_at_four_friendly_hurts(self): + elephant = Pet("elephant") + elephant.level = 2 + elephant._attack = 50 + elephant._health = 50 + + hurt_friend_1 = Pet("fish") + hurt_friend_1._health = 20 + hurt_friend_2 = Pet("fish") + hurt_friend_2._health = 20 + wolverine = Pet("wolverine") + + enemy = Pet("pig") + enemy._attack = 1 + enemy._health = 1 + enemy.status = "status-splash-attack" + + battle = Battle( + Team([elephant, hurt_friend_1, hurt_friend_2, wolverine]), + Team([enemy]), + ) + battle.battle() + + reduce_health_events = 0 + for phase in battle.battle_history.values(): + if type(phase) != dict: + continue + for phase_entries in phase.values(): + for entry in phase_entries: + if type(entry) != tuple: + continue + if entry[0] != "ReduceHealth": + continue + if "pet-wolverine" in entry[2]: + reduce_health_events += 1 + + self.assertEqual(reduce_health_events, 1) + + def test_wolverine_triggers_twice_at_eight_friendly_hurts(self): + elephant = Pet("elephant") + elephant.level = 2 + elephant._attack = 1 + elephant._health = 20 + + hurt_friend_1 = Pet("fish") + hurt_friend_1._health = 20 + hurt_friend_2 = Pet("fish") + hurt_friend_2._health = 20 + wolverine = Pet("wolverine") + + enemy = Pet("pig") + enemy._attack = 1 + enemy._health = 5 + enemy.status = "status-splash-attack" + + battle = Battle( + Team([elephant, hurt_friend_1, hurt_friend_2, wolverine]), + Team([enemy]), + ) + battle.battle() + + reduce_health_events = 0 + for phase in battle.battle_history.values(): + if type(phase) != dict: + continue + for phase_entries in phase.values(): + for entry in phase_entries: + if type(entry) != tuple: + continue + if entry[0] != "ReduceHealth": + continue + if "pet-wolverine" in entry[2]: + reduce_health_events += 1 + + self.assertEqual(reduce_health_events, 2) + + def test_two_wolverines_on_team_both_trigger(self): + fish = Pet("fish") + fish._health = 1 + w1 = Pet("wolverine") + w2 = Pet("wolverine") + w1._friend_hurt_counter = 3 + w2._friend_hurt_counter = 3 + + enemy = Pet("pig") + enemy._attack = 1 + enemy._health = 1 + + b = Battle(Team([fish, w1, w2]), Team([enemy])) + b.battle() + + reduce_health_events = 0 + for phase in b.battle_history.values(): + if type(phase) != dict: + continue + for phase_entries in phase.values(): + for entry in phase_entries: + if type(entry) != tuple: + continue + if entry[0] != "ReduceHealth": + continue + if "pet-wolverine" in entry[2]: + reduce_health_events += 1 + + self.assertEqual(reduce_health_events, 2) + wolverines = [slot.pet for slot in b.t0 if slot.pet.name == "pet-wolverine"] + self.assertEqual(len(wolverines), 2) + self.assertEqual(wolverines[0]._friend_hurt_counter, 0) + self.assertEqual(wolverines[1]._friend_hurt_counter, 0) + + def test_tiger_behind_wolverine_repeats_reduce_health(self): + fish = Pet("fish") + fish._health = 50 + wolverine = Pet("wolverine") + wolverine._friend_hurt_counter = 3 + tiger = Pet("tiger") + + enemy = Pet("pig") + enemy._attack = 1 + enemy._health = 10 + + b = Battle(Team([fish, wolverine, tiger]), Team([enemy])) + b.battle() + + phase_entries = b.battle_history["attack 0"]["phase_hurt_and_faint_aa"] + reduce_entries = [ + entry + for entry in phase_entries + if isinstance(entry, tuple) + and entry[0] == "ReduceHealth" + and "pet-wolverine" in entry[2] + ] + + self.assertEqual(len(reduce_entries), 2) + + def test_wolverine_counts_lethal_hurt_with_competing_faint_chains(self): + t0 = Team([Pet("hedgehog"), Pet("wolverine"), Pet("fish"), Pet("fish")]) + t1 = Team([Pet("hedgehog"), Pet("cricket"), Pet("fish")]) + + ### Deterministic priority for simultaneous front-line faint events + t0[0].pet._attack = 5 + t1[0].pet._attack = 4 + + ### Set Wolverine at threshold edge so next friendly hurt should trigger + t0[1].pet._friend_hurt_counter = 3 + + b = Battle(t0, t1) + b.battle() + + phase_entries = b.battle_history["attack 0"]["phase_hurt_and_faint_aa"] + reduce_entries = [ + entry + for entry in phase_entries + if isinstance(entry, tuple) + and entry[0] == "ReduceHealth" + and "pet-wolverine" in entry[2] + ] + hedgehog_faint_entries = [ + entry + for entry in phase_entries + if isinstance(entry, tuple) + and entry[0] == "DealDamage" + and "pet-hedgehog" in entry[2] + ] + + ### Both teams' faint abilities should still execute in this chain + self.assertEqual(len(hedgehog_faint_entries), 2) + self.assertEqual(len(reduce_entries), 2) + + reduce_targets = reduce_entries[0][3] + self.assertTrue(any("pet-cricket" in target for target in reduce_targets)) + self.assertTrue(any("pet-fish" in target for target in reduce_targets)) + self.assertFalse(any("pet-zombie-cricket" in target for target in reduce_targets)) + self.assertFalse(any("pet-hedgehog" in target for target in reduce_targets)) + + self.assertEqual(b.t0[0].pet._friend_hurt_counter, 0) + + ### Lethal-hurt counting occurs before faint-ability chain resolution + self.assertLess(phase_entries.index(reduce_entries[0]), phase_entries.index(hedgehog_faint_entries[0])) def test_hedgehog_blowfish_camel_hurt_team(self): # standard hedgehog blowfish camel teams facing off against eachother @@ -248,8 +433,8 @@ def test_hedgehog_blowfish_camel_hurt_team(self): hh4 = Pet("hedgehog") b = Battle(Team([hh1, hh2, c1, bf1]), Team([hh3, hh4, c2, bf2])) - r = b.battle() - self.assertEqual(r, 2) + + self.assertEqual(b.battle(), 2) def test_hedgehog_vs_honey(self): hh1 = Pet("hedgehog") @@ -337,7 +522,7 @@ def test_badger_draws(self): # badger with less attack can kill zombie-cricket b1 = Pet("badger") c1 = Pet("cricket") - c1._attack = 6 + c1._attack = 7 b = Battle(Team([b1]), Team([c1])) r = b.battle() self.assertEqual(r, 2) @@ -372,7 +557,7 @@ def test_badger_wins(self): hb1 = Pet("badger") hb1.status = "status-honey-bee" c1 = Pet("cricket") - c1._attack = 6 + c1._attack = 7 b = Battle(Team([hb1]), Team([c1])) r = b.battle() self.assertEqual(r, 0) @@ -399,5 +584,27 @@ def test_peacock(self): ### Implement later with others pass + def test_steak_not_consumed_when_hit_by_splash(self): + splash_attacker = Pet("fish") + splash_attacker.status = "status-splash-attack" + splash_attacker._attack = 1 + splash_attacker._health = 1 + + front_enemy = Pet("ant") + front_enemy._attack = 50 + front_enemy._health = 50 + + back_enemy = Pet("pig") + back_enemy.status = "status-steak-attack" + back_enemy._health = 50 + + battle = Battle(Team([splash_attacker]), Team([front_enemy, back_enemy])) + battle.battle() + + # Back enemy was splashed but never attacked, so steak should remain. + self.assertEqual(battle.t1[1].pet.status, "status-steak-attack") + # Chili splash should deal exactly 5 damage to the second enemy. + self.assertEqual(battle.t1[1].pet.health, 45) + # %% diff --git a/tests/test_effects.py b/tests/test_effects.py index d44ceb1..8d2fb3b 100644 --- a/tests/test_effects.py +++ b/tests/test_effects.py @@ -74,6 +74,57 @@ def test_tiger_func(self): continue slot.pet.faint_trigger(slot.pet, [0, t.index(slot)]) + def test_rat_faint_summon_count_scales_with_level(self): + for level in [1, 2, 3]: + rat = Pet("rat") + rat.level = level + Team([rat], battle=True) + + front_fish = Pet("fish") + front_fish._attack = 7 + back_fish = Pet("fish") + back_fish._attack = 9 + enemy = Team([front_fish, back_fish], battle=True) + + rat.faint_trigger(rat, [0, 0], oteam=enemy) + + self.assertEqual( + [slot.pet.name if not slot.empty else "empty" for slot in enemy], + ["pet-dirty-rat"] * level + ["pet-fish", "pet-fish"] + ["empty"] * (3 - level), + ) + self.assertEqual(enemy[level].pet.name, "pet-fish") + self.assertEqual(enemy[level].pet.attack, 7) + self.assertEqual(enemy[level + 1].pet.name, "pet-fish") + self.assertEqual(enemy[level + 1].pet.attack, 9) + + def test_rat_faint_summon_respects_limited_board_space(self): + rat = Pet("rat") + rat.level = 3 + Team([rat], battle=True) + + enemy_with_one_slot = Team( + [Pet("fish"), Pet("pig"), Pet("ant"), Pet("beaver")], battle=True + ) + rat.faint_trigger(rat, [0, 0], oteam=enemy_with_one_slot) + self.assertEqual( + [slot.pet.name if not slot.empty else "empty" for slot in enemy_with_one_slot], + ["pet-dirty-rat", "pet-fish", "pet-pig", "pet-ant", "pet-beaver"], + ) + + rat_full = Pet("rat") + rat_full.level = 3 + Team([rat_full], battle=True) + + enemy_full = Team( + [Pet("fish"), Pet("pig"), Pet("ant"), Pet("beaver"), Pet("otter")], + battle=True, + ) + rat_full.faint_trigger(rat_full, [0, 0], oteam=enemy_full) + self.assertEqual( + [slot.pet.name if not slot.empty else "empty" for slot in enemy_full], + ["pet-fish", "pet-pig", "pet-ant", "pet-beaver", "pet-otter"], + ) + def test_eagle_stats(self): # seed for Snake 6/6 state = np.random.RandomState(seed=4).get_state() @@ -83,10 +134,11 @@ def test_eagle_stats(self): t = Team([pet], battle=True) t[0].pet.faint_trigger(t[0].pet, [0, t.index(t[0])]) - # should spawn Snake Lvl3 18/18 since Eagle was lvl 3 + # should spawn Snake Lvl3 with 3 times base stats + snake = Pet("snake") self.assertEqual(t[0].level, 3) - self.assertEqual(t[0].attack, 18) - self.assertEqual(t[0].health, 18) + self.assertEqual(t[0].attack, snake.fd["baseAttack"] * 3) + self.assertEqual(t[0].health, snake.fd["baseHealth"] * 3) def test_multiple_cats(self): player = Player(shop=Shop(["pear"]), team=Team([Pet("cat")])) @@ -142,10 +194,10 @@ def test_garlic(self): t = Team(["dolphin", "otter", "mosquito"], battle=True) t2 = Team([fish], battle=True) t[0].pet.sob_trigger(t2) - self.assertEqual(fish.health, 47) # 5 damage, -2 garlic + self.assertEqual(fish.health, 48) # 4 damage, -2 garlic t[2].pet.sob_trigger(t2) - self.assertEqual(fish.health, 46) # should still do 1 damage + self.assertEqual(fish.health, 47) # should still do 1 damage attack_phase = get_attack(t[0].pet, fish) self.assertEqual(attack_phase[0], 2) # dolphin 4/6 @@ -155,13 +207,14 @@ def test_garlic(self): def test_coconut(self): gorilla = Pet("gorilla") + base_health = gorilla.health gorilla.status = "status-coconut-shield" t = Team([gorilla], battle=True) t2 = Team(["crocodile"], battle=True) t3 = Team(["dragon"], battle=True) t2[0].pet.sob_trigger(t) - self.assertEqual(gorilla.health, 9) # unchanged + self.assertEqual(gorilla.health, base_health) # unchanged self.assertEqual(gorilla.status, "none") gorilla.status = "status-coconut-shield" @@ -179,10 +232,10 @@ def test_weak(self): t3 = Team(["dragon"], battle=True) t2[0].pet.sob_trigger(t) - self.assertEqual(fish.health, 42) # 5 + 3 + self.assertEqual(fish.health, 43) # 4 + 3 attack_phase = get_attack(fish, t3[0].pet) - self.assertEqual(attack_phase[1], 9) # 6/8 + 3 + self.assertEqual(attack_phase[1], t3[0].pet.attack + 3) def test_hatching_chick_level_3(self): hc = Pet("hatching-chick") @@ -190,3 +243,131 @@ def test_hatching_chick_level_3(self): t = Team(["dragon", hc]) hc.sot_trigger(t) self.assertEqual(t[0].pet.experience, 1) + + def test_armadillo_start_of_battle_targets_all(self): + friendly = Team([Pet("armadillo"), Pet("fish")], battle=True) + enemy = Team([Pet("pig"), Pet("ant")], battle=True) + + base_health = { + "armadillo": friendly[0].pet.health, + "fish": friendly[1].pet.health, + "pig": enemy[0].pet.health, + "ant": enemy[1].pet.health, + } + + activated, targets, _ = friendly[0].pet.sob_trigger(enemy) + self.assertTrue(activated) + self.assertEqual(len(targets), 4) + + self.assertEqual(friendly[0].pet.health, base_health["armadillo"] + 8) + self.assertEqual(friendly[1].pet.health, base_health["fish"] + 8) + self.assertEqual(enemy[0].pet.health, base_health["pig"] + 8) + self.assertEqual(enemy[1].pet.health, base_health["ant"] + 8) + + def test_armadillo_start_of_battle_level_scaling(self): + for level, bonus in [(1, 8), (2, 16), (3, 24)]: + friendly = Team([Pet("armadillo"), Pet("fish")], battle=True) + enemy = Team([Pet("pig"), Pet("ant")], battle=True) + friendly[0].pet.level = level + + base_health = [friendly[0].pet.health, friendly[1].pet.health] + base_enemy_health = [enemy[0].pet.health, enemy[1].pet.health] + + activated, _, _ = friendly[0].pet.sob_trigger(enemy) + self.assertTrue(activated) + + self.assertEqual(friendly[0].pet.health, base_health[0] + bonus) + self.assertEqual(friendly[1].pet.health, base_health[1] + bonus) + self.assertEqual(enemy[0].pet.health, base_enemy_health[0] + bonus) + self.assertEqual(enemy[1].pet.health, base_enemy_health[1] + bonus) + + def test_armadillo_start_of_battle_health_is_capped_at_50(self): + friendly = Team([Pet("armadillo"), Pet("fish")], battle=True) + enemy = Team([Pet("pig"), Pet("ant")], battle=True) + + friendly[0].pet._health = 49 + friendly[1].pet._health = 48 + enemy[0].pet._health = 50 + enemy[1].pet._health = 47 + + activated, _, _ = friendly[0].pet.sob_trigger(enemy) + self.assertTrue(activated) + + self.assertEqual(friendly[0].pet.health, 50) + self.assertEqual(friendly[1].pet.health, 50) + self.assertEqual(enemy[0].pet.health, 50) + self.assertEqual(enemy[1].pet.health, 50) + + def test_armadillo_happens_before_skunk_when_higher_attack(self): + t0 = Team([Pet("armadillo")], battle=True) + t1 = Team([Pet("skunk")], battle=True) + + battle = Battle(t0, t1) + battle.start() + + ### Armadillo (4 attack) acts before Skunk (3 attack): + ### Armadillo health goes 8 -> 16, then Skunk reduces by 33% to 11. + self.assertEqual(battle.t0[0].pet.health, 11) + self.assertEqual(battle.t1[0].pet.health, 13) + + def test_armadillo_battle_health_boost_does_not_persist_after_battle(self): + friendly = Team([Pet("armadillo"), Pet("fish")], battle=True) + enemy = Team([Pet("pig"), Pet("ant")], battle=True) + + base_friendly_health = [friendly[0].pet.health, friendly[1].pet.health] + base_enemy_health = [enemy[0].pet.health, enemy[1].pet.health] + + battle = Battle(friendly, enemy) + battle.start() + + ### Battle runs on cloned teams, so start-of-battle health changes should + ### not persist back to the original teams passed into Battle. + self.assertEqual(friendly[0].pet.health, base_friendly_health[0]) + self.assertEqual(friendly[1].pet.health, base_friendly_health[1]) + self.assertEqual(enemy[0].pet.health, base_enemy_health[0]) + self.assertEqual(enemy[1].pet.health, base_enemy_health[1]) + + def test_stock_shop_food_targets_new_slots_with_duplicate_foods(self): + player = Player(shop=Shop(["bread-crumbs", "bread-crumbs"]), team=Team([Pet("pigeon")])) + player.team[0].pet.level = 2 + + existing_slots = [slot for slot in player.shop.slots if slot.slot_type == "food"] + existing_slot_ids = {id(slot) for slot in existing_slots} + existing_obj_ids = {id(slot.obj) for slot in existing_slots} + + activated, targets, _ = player.team[0].pet.sell_trigger(player.team[0].pet) + self.assertTrue(activated) + self.assertEqual(len(targets), 2) + + for slot in targets: + self.assertEqual(slot.slot_type, "food") + self.assertEqual(slot.obj.name, "food-bread-crumbs") + self.assertNotIn(id(slot), existing_slot_ids) + self.assertNotIn(id(slot.obj), existing_obj_ids) + + def test_reduce_health_amount_reduces_each_enemy(self): + friendly = Team([Pet("wolverine")], battle=True) + enemy = Team([Pet("pig"), Pet("ant")], battle=True) + + enemy[0].pet._health = 9 + enemy[1].pet._health = 4 + + targets, _ = ReduceHealth(friendly[0].pet, [0, 0], [friendly, enemy]) + self.assertEqual(len(targets), 2) + self.assertEqual(enemy[0].pet.health, 6) + self.assertEqual(enemy[1].pet.health, 1) + + def test_rhino_knockout_damage_doubles_against_tier_1_only(self): + rhino = Pet("rhino") + friendly = Team([rhino], battle=True) + rhino.team = friendly + + tier_1_enemy = Team([Pet("pig")], battle=True) + base_tier_1_health = tier_1_enemy[0].pet.health + DealDamage(rhino, [0, 0], [friendly, tier_1_enemy]) + self.assertEqual(tier_1_enemy[0].pet.health, base_tier_1_health - 8) + + non_tier_1_enemy = Team([Pet("camel")], battle=True) + base_non_tier_1_health = non_tier_1_enemy[0].pet.health + DealDamage(rhino, [0, 0], [friendly, non_tier_1_enemy]) + self.assertEqual(non_tier_1_enemy[0].pet.health, base_non_tier_1_health - 4) diff --git a/tests/test_pet_triggers.py b/tests/test_pet_triggers.py index 5c39124..be70644 100644 --- a/tests/test_pet_triggers.py +++ b/tests/test_pet_triggers.py @@ -5,6 +5,7 @@ from sapai import * from sapai.compress import compress, decompress +from sapai.battle import Battle, battle_phase_hurt_and_faint class TestPetTriggers(unittest.TestCase): @@ -43,7 +44,7 @@ def print_pet_list(pet_list): print(print_str) def test_start_of_turn_triggers(self): - test_pet_names = ["dromedary", "swan", "caterpillar", "squirrel"] + test_pet_names = ["dromedary", "swan", "caterpillar", "squirrel", "giraffe", "worm"] test_pet_list = [ Pet(x, shop=Shop(), team=Team(), player=Player()) for x in test_pet_names ] @@ -59,7 +60,7 @@ def test_start_of_turn_triggers(self): def test_sell_triggers_self(self): test_team = Team([Pet("dragon"), Pet("cat"), Pet("horse")]) - test_pet_names = ["beaver", "duck", "pig", "shrimp", "owl"] + test_pet_names = ["beaver", "duck", "pig", "shrimp", "owl", "pigeon"] test_pet_list = [ Pet(x, shop=Shop(), team=test_team.copy(), player=Player()) for x in test_pet_names @@ -67,27 +68,27 @@ def test_sell_triggers_self(self): self.print_pet_list(test_pet_list) # Sell Self - test_bool_list = [True, True, True, False, True] + test_bool_list = [True, True, True, False, True, True] for iter_idx, pet in enumerate(test_pet_list): activated_bool, targets, possible = pet.sell_trigger(pet) self.assertEqual(activated_bool, test_bool_list[iter_idx]) def test_sell_triggers_other(self): test_team = Team([Pet("dragon"), Pet("cat"), Pet("horse")]) - test_pet_names = ["beaver", "duck", "pig", "shrimp", "owl"] + test_pet_names = ["beaver", "duck", "pig", "shrimp", "owl", "pigeon"] # Sell Other test_pet_list = [ Pet(x, shop=Shop(), team=test_team.copy()) for x in test_pet_names ] - test_bool_list = [False, False, False, True, False] + test_bool_list = [False, False, False, True, False, False] for iter_idx, pet in enumerate(test_pet_list): activated_bool, targets, possible = pet.sell_trigger(pet.team[0].pet) self.assertEqual(activated_bool, test_bool_list[iter_idx]) def test_eats_shop_food_triggers_self(self): test_team = Team([Pet("dragon"), Pet("cat")]) - test_pet_names = ["beetle", "tabby-cat", "rabbit", "worm", "seal"] + test_pet_names = ["beetle", "tabby-cat", "rabbit", "seal"] test_pet_list = [ Pet(x, shop=Shop(), team=test_team.copy(), player=Player()) @@ -165,11 +166,9 @@ def test_buy_friend_triggers_self(self): self.print_pet_list(test_pet_list) # Buy friend as self - test_bool_list = [True, False, True, False, False, True, False, False] + test_bool_list = [True, False, False, False, False, True, False, False] for iter_idx, pet in enumerate(test_pet_list): activated_bool, targets, possible = pet.buy_friend_trigger(pet) - if pet.name == "pet-snail": - continue self.assertEqual(activated_bool, test_bool_list[iter_idx]) def test_buy_friend_triggers_self_other_tier_1(self): @@ -260,12 +259,10 @@ def test_end_of_turn_triggers(self): test_pet_names = [ "bluebird", "hatching-chick", - "giraffe", "puppy", "tropical-fish", "bison", "llama", - "penguin", "parrot", "monkey", "poodle", @@ -282,6 +279,63 @@ def test_end_of_turn_triggers(self): activated_bool, targets, possible = pet.eot_trigger(pet.team[0].pet) self.assertTrue(activated_bool) + def test_penguin_start_of_turn_targets_two_level_2_or_higher_friends(self): + player = Player() + team = Team([Pet("penguin"), Pet("fish"), Pet("ant"), Pet("beaver"), Pet("pig")]) + for slot in team: + slot.pet.player = player + slot.pet.team = team + + team[1].pet.level = 2 + team[2].pet.level = 2 + team[3].pet.level = 3 + team[4].pet.level = 1 + + base_stats = { + idx: (team[idx].pet.attack, team[idx].pet.health) + for idx in [1, 2, 3, 4] + } + + penguin = team[0].pet + activated_bool, targets, _ = penguin.sot_trigger() + self.assertTrue(activated_bool) + self.assertEqual(len(targets), 2) + self.assertTrue(all(target.level > 1 for target in targets)) + self.assertTrue(all(target != penguin for target in targets)) + + buffed = 0 + for idx in [1, 2, 3, 4]: + attack_before, health_before = base_stats[idx] + attack_after = team[idx].pet.attack + health_after = team[idx].pet.health + if attack_after == attack_before + 1 and health_after == health_before + 1: + buffed += 1 + else: + self.assertEqual(attack_after, attack_before) + self.assertEqual(health_after, health_before) + self.assertEqual(buffed, 2) + + activated_bool, _, _ = penguin.eot_trigger() + self.assertFalse(activated_bool) + + def test_snail_end_of_turn_after_loss(self): + player = Player() + team = Team([Pet("fish"), Pet("ant"), Pet("snail")]) + for slot in team: + slot.pet.player = player + slot.pet.team = team + snail = team[2].pet + + player.lf_winner = True + activated_bool, _, _ = snail.eot_trigger() + self.assertFalse(activated_bool) + + player.lf_winner = False + activated_bool, targets, _ = snail.eot_trigger() + self.assertTrue(activated_bool) + self.assertEqual(len(targets), 2) + self.assertTrue(all(target.name in ["pet-fish", "pet-ant"] for target in targets)) + def test_faint_triggers_self(self): test_team = Team([Pet("fish")], battle=True) test_pet_names = [ @@ -396,6 +450,7 @@ def test_start_of_battle_triggers(self): test_pet_names = [ "mosquito", "bat", + "armadillo", "crab", "whale", "dolphin", @@ -425,7 +480,7 @@ def test_before_attack_triggers(self): test_team = Team([Pet("fish"), Pet("dragon"), Pet("cat")], battle=True) cteam = compress(test_team) - test_pet_names = ["elephant", "boar", "octopus"] + test_pet_names = ["boar", "octopus"] test_pet_list = [ Pet(x, shop=Shop(), team=test_team.copy(), player=Player()) @@ -458,6 +513,24 @@ def test_after_attack_triggers(self): activated_bool, targets, possible = pet.after_attack_trigger(trigger) self.assertTrue(activated_bool) + def test_elephant_after_attack_hurts_nearest_friend_behind(self): + team = Team([Pet("elephant"), Pet("fish"), Pet("fish")], battle=True) + enemy = Team([Pet("pig")], battle=True) + + elephant = team[0].pet + elephant.level = 2 + fish_1 = team[1].pet + fish_2 = team[2].pet + base_health_1 = fish_1.health + base_health_2 = fish_2.health + + activated_bool, targets, _ = elephant.after_attack_trigger(enemy) + + self.assertTrue(activated_bool) + self.assertEqual(targets, [[fish_1], [fish_1]]) + self.assertEqual(fish_1.health, base_health_1 - 2) + self.assertEqual(fish_2.health, base_health_2) + def test_hurt_triggers(self): test_team = Team([Pet("fish")], battle=True) cteam = compress(test_team) @@ -477,6 +550,84 @@ def test_hurt_triggers(self): activated_bool, targets, possible = pet.hurt_trigger(trigger) self.assertTrue(activated_bool) + def test_wolverine_friend_hurt_trigger_threshold(self): + friendly_team = Team( + [Pet("wolverine"), Pet("fish"), Pet("fish"), Pet("fish")], battle=True + ) + enemy_team = Team([Pet("pig"), Pet("ant")], battle=True) + wolverine = friendly_team[0].pet + + ### Self hurt should not count towards trigger threshold + activated_bool, targets, possible = wolverine.friend_hurt_trigger( + wolverine, enemy_team + ) + self.assertFalse(activated_bool) + self.assertEqual(wolverine._friend_hurt_counter, 0) + + for n in range(3): + activated_bool, targets, possible = wolverine.friend_hurt_trigger( + friendly_team[n + 1].pet, enemy_team + ) + self.assertFalse(activated_bool) + self.assertEqual(wolverine._friend_hurt_counter, n + 1) + + ### 4th non-self friend hurt should trigger ability once + start_enemy_health = [enemy_team[0].pet.health, enemy_team[1].pet.health] + activated_bool, targets, possible = wolverine.friend_hurt_trigger( + friendly_team[1].pet, enemy_team + ) + self.assertTrue(activated_bool) + self.assertEqual(wolverine._friend_hurt_counter, 0) + self.assertEqual(enemy_team[0].pet.health, start_enemy_health[0] - 3) + self.assertEqual(enemy_team[1].pet.health, start_enemy_health[1] - 3) + + def test_wolverine_friend_hurt_trigger_repeats_every_four(self): + friendly_team = Team([Pet("wolverine"), Pet("fish"), Pet("fish")], battle=True) + enemy_team = Team([Pet("pig"), Pet("ant")], battle=True) + enemy_team[0].pet._health = 20 + enemy_team[1].pet._health = 20 + wolverine = friendly_team[0].pet + start_enemy_health = [enemy_team[0].pet.health, enemy_team[1].pet.health] + + for _ in range(8): + wolverine.friend_hurt_trigger(friendly_team[1].pet, enemy_team) + + ### Two activations at level 1 should remove 6 health from each enemy + self.assertEqual(enemy_team[0].pet.health, start_enemy_health[0] - 6) + self.assertEqual(enemy_team[1].pet.health, start_enemy_health[1] - 6) + self.assertEqual(wolverine._friend_hurt_counter, 0) + + def test_wolverine_counts_lethal_hurt_in_battle_hurt_loop(self): + battle = Battle(Team([Pet("wolverine"), Pet("fish")]), Team([Pet("pig")])) + + wolverine = battle.t0[0].pet + hurt_friend = battle.t0[1].pet + enemy = battle.t1[0].pet + + hurt_friend._health = 4 + for _ in range(4): + hurt_friend.hurt(1) + + start_enemy_health = enemy.health + phase_dict = {"phase_hurt_and_faint": []} + battle_phase_hurt_and_faint( + battle, + "phase_hurt_and_faint", + [battle.t0, battle.t1], + battle.pet_priority, + phase_dict, + ) + + reduce_health_events = [ + entry + for entry in phase_dict["phase_hurt_and_faint"] + if type(entry) == tuple and entry[0] == "ReduceHealth" and "pet-wolverine" in entry[2] + ] + + self.assertEqual(len(reduce_health_events), 1) + self.assertEqual(wolverine._friend_hurt_counter, 0) + self.assertEqual(enemy.health, start_enemy_health - 3) + def test_knockout_triggers(self): test_team = Team([Pet("fish")], battle=True) cteam = compress(test_team) @@ -497,16 +648,19 @@ def test_knockout_triggers(self): def test_dragon_ability(self): player = Player(shop=Shop(["ant"]), team=Team([Pet("fish"), Pet("dragon")])) - self.assertEqual(player.team[0].attack, 2) - self.assertEqual(player.team[0].health, 2) - self.assertEqual(player.team[1].attack, 6) - self.assertEqual(player.team[1].health, 8) + fish_attack = player.team[0].attack + fish_health = player.team[0].health + dragon_attack = player.team[1].attack + dragon_health = player.team[1].health player.buy_pet(0) - self.assertEqual(player.team[0].attack, 3) - self.assertEqual(player.team[0].health, 3) - self.assertEqual(player.team[1].attack, 6) - self.assertEqual(player.team[1].health, 8) + self.assertEqual(player.team[0].attack, fish_attack + 1) + self.assertEqual(player.team[0].health, fish_health + 1) + self.assertEqual(player.team[1].attack, dragon_attack) + self.assertEqual(player.team[1].health, dragon_health) + self.assertEqual(player.team[2].pet.name, "pet-ant") + self.assertEqual(player.team[2].pet.health, Pet("ant").health + 1) + self.assertEqual(player.team[2].pet.attack, Pet("ant").attack + 1) def test_shop_hurt(self): player = Player( @@ -534,28 +688,73 @@ def test_dodo(self): def test_crab(self): t = Team(["crab", "dragon"]) activated_bool, targets, possible = t[0].obj.sob_trigger(t) - self.assertEqual(t[0].health, 4) + self.assertEqual(t[0].health, 2) t[0].obj.level = 2 activated_bool, targets, possible = t[0].obj.sob_trigger(t) - self.assertEqual(t[0].health, 8) + self.assertEqual(t[0].health, 4) t[0].obj.level = 3 activated_bool, targets, possible = t[0].obj.sob_trigger(t) - self.assertEqual(t[0].health, 12) + self.assertEqual(t[0].health, 6) def test_horse(self): player = Player(shop=Shop(["fish"]), team=Team([Pet("horse")])) + fish = Pet("fish") player.buy_pet(0) - self.assertEqual(player.team[1].attack, 3) - self.assertEqual(player.team[1].health, 2) + self.assertEqual(player.team[1].attack, fish.attack + 1) + self.assertEqual(player.team[1].health, fish.health) player.end_turn() player.start_turn() - self.assertEqual(player.team[1].attack, 2) - self.assertEqual(player.team[1].health, 2) + self.assertEqual(player.team[1].attack, fish.attack) + self.assertEqual(player.team[1].health, fish.health) + + def test_swan_parrot_gain_two_gold_after_loss(self): + player = Player(team=Team([Pet("swan"), Pet("parrot")]), shop=Shop(), gold=10, default_gold=10) + + player.end_turn() + player.start_turn(winner=False) + + self.assertEqual(player.gold, 12) + + def test_parrot_no_longer_gives_gold_when_fish_inserted_between_swan_and_parrot(self): + player = Player(team=Team([Pet("swan"), Pet("parrot")]), shop=Shop(), gold=10, default_gold=10) + + ### Cycle 1: parrot copies swan and both should grant +1 gold next start turn + player.end_turn() + player.start_turn(winner=False) + self.assertEqual(player.gold, 12) + + ### Buy fish, then place it between swan and parrot + player.shop = Shop(["fish"]) + player.buy_pet(0) + player.reorder([0, 2, 1]) + self.assertEqual([slot.pet.name for slot in player.team[:3]], ["pet-swan", "pet-fish", "pet-parrot"]) + + ### Cycle 2: only swan should grant +1 gold + player.end_turn() + player.start_turn(winner=False) + self.assertEqual(player.gold, 11) + + def test_parrot_no_longer_gives_gold_when_moved_in_front_of_swan(self): + player = Player(team=Team([Pet("swan"), Pet("parrot")]), shop=Shop(), gold=10, default_gold=10) + + ### Cycle 1: parrot copies swan and both should grant +1 gold next start turn + player.end_turn() + player.start_turn(winner=False) + self.assertEqual(player.gold, 12) + + ### Reorder to parrot in front of swan + player.reorder([1, 0]) + self.assertEqual([slot.pet.name for slot in player.team[:2]], ["pet-parrot", "pet-swan"]) + + ### Cycle 2: only swan should grant +1 gold + player.end_turn() + player.start_turn(winner=False) + self.assertEqual(player.gold, 11) def test_cupcake_cat(self): player = Player(shop=Shop(["cupcake"]), team=Team([Pet("cat")])) @@ -575,19 +774,19 @@ def test_ant_pill_in_shop(self): shop=Shop(["sleeping-pill"]), team=Team([Pet("ant"), Pet("beaver")]) ) player.buy_food(0, 0) - self.assertEqual(player.team[1].attack, 5) + self.assertEqual(player.team[1].attack, 4) self.assertEqual(player.team[1].health, 3) def test_beaver_sell(self): player = Player(team=Team([Pet("beaver"), Pet("fish"), Pet("fish")])) player.sell(0) - self.assertEqual(player.team[1].health, 3) - self.assertEqual(player.team[2].health, 3) + self.assertEqual(player.team[1].attack, Pet("fish").attack + 1) + self.assertEqual(player.team[2].attack, Pet("fish").attack + 1) def test_beaver_sell_only_one_other_pet_on_team(self): player = Player(team=Team([Pet("fish"), Pet("beaver")])) player.sell(1) - self.assertEqual(player.team[0].health, 3) + self.assertEqual(player.team[0].attack, Pet("fish").attack + 1) def test_cricket_pill_in_shop(self): player = Player(shop=Shop(["sleeping-pill"]), team=Team([Pet("cricket")])) @@ -618,22 +817,22 @@ def test_fish_combine(self): def test_otter(self): player = Player(shop=Shop(["otter"]), team=Team([Pet("beaver")])) player.buy_pet(0) - self.assertEqual(player.team[0].attack, 4) + self.assertEqual(player.team[0].attack, 3) self.assertEqual(player.team[0].health, 3) self.assertEqual(player.team[1].attack, 1) - self.assertEqual(player.team[1].health, 2) + self.assertEqual(player.team[1].health, 4) def test_buy_otter_on_empty_team(self): player = Player(shop=Shop(["otter"])) player.buy_pet(0) self.assertEqual(player.team[0].attack, 1) - self.assertEqual(player.team[0].health, 2) + self.assertEqual(player.team[0].health, 4) def test_buy_otter_on_level_up(self): otter = Pet("otter") player = Player(shop=Shop(["otter"]), team=Team([otter, Pet("beaver")])) player.buy_combine(0, 0) - self.assertEqual(player.team[1].attack, 4) + self.assertEqual(player.team[1].attack, 3) self.assertEqual(player.team[1].health, 3) otter = Pet("otter") @@ -642,10 +841,10 @@ def test_buy_otter_on_level_up(self): shop=Shop(["otter"]), team=Team([otter, Pet("beaver"), Pet("fish")]) ) player.buy_combine(0, 0) - self.assertEqual(player.team[1].attack, 4) + self.assertEqual(player.team[1].attack, 3) self.assertEqual(player.team[1].health, 3) - self.assertEqual(player.team[2].attack, 3) - self.assertEqual(player.team[2].health, 3) + self.assertEqual(player.team[2].attack, 2) + self.assertEqual(player.team[2].health, 4) otter = Pet("otter") otter.experience = 4 @@ -654,12 +853,12 @@ def test_buy_otter_on_level_up(self): team=Team([otter, Pet("beaver"), Pet("fish"), Pet("ant")]), ) player.buy_combine(0, 0) - self.assertEqual(player.team[1].attack, 4) + self.assertEqual(player.team[1].attack, 3) self.assertEqual(player.team[1].health, 3) - self.assertEqual(player.team[2].attack, 3) - self.assertEqual(player.team[2].health, 3) - self.assertEqual(player.team[3].attack, 3) - self.assertEqual(player.team[3].health, 2) + self.assertEqual(player.team[2].attack, 2) + self.assertEqual(player.team[2].health, 4) + self.assertEqual(player.team[3].attack, 2) + self.assertEqual(player.team[3].health, 3) def test_pig(self): player = Player(team=Team([Pet("pig")])) @@ -672,7 +871,7 @@ def test_cricket_pill_in_shop_with_turkey(self): ) player.buy_food(0, 0) self.assertEqual(player.team[0].attack, 4) - self.assertEqual(player.team[0].health, 4) + self.assertEqual(player.team[0].health, 2) def test_sheep_pill_in_shop_with_turkey(self): player = Player( @@ -681,9 +880,9 @@ def test_sheep_pill_in_shop_with_turkey(self): player.buy_food(0, 0) print(player.team) self.assertEqual(player.team[0].attack, 5) - self.assertEqual(player.team[0].health, 5) + self.assertEqual(player.team[0].health, 3) self.assertEqual(player.team[1].attack, 5) - self.assertEqual(player.team[1].health, 5) + self.assertEqual(player.team[1].health, 3) def test_cricket_pill_in_shop_with_horse(self): player = Player( @@ -708,7 +907,7 @@ def test_faint_hurt_summon_trigger_priority(self): team=Team(["peacock", ant, spider, "hedgehog", horse]), ) player.buy_food(0, 3) - self.assertEqual(player.team[2].attack, 5) # base 2 + horse + ant + self.assertEqual(player.team[2].attack, 4) # base 2 + horse + ant self.assertEqual(player.team[2].health, 3) # base 2 + ant def test_mushroom_scorpion_in_shop(self): @@ -746,40 +945,42 @@ def test_zombie_fly_location(self): def test_flamingo(self): t = Team(["flamingo", "dragon", "dragon", "dragon"]) + dragon_attack = t[1].attack + dragon_health = t[1].health t[0].obj.level = 1 pet = t[0].obj te_idx = [0, 0] t[0].obj.faint_trigger(pet, te_idx) - self.assertEqual(t[1].attack, 6 + 1) - self.assertEqual(t[1].health, 8 + 1) - self.assertEqual(t[2].attack, 6 + 1) - self.assertEqual(t[2].health, 8 + 1) - self.assertEqual(t[3].attack, 6) - self.assertEqual(t[3].health, 8) + self.assertEqual(t[1].attack, dragon_attack + 1) + self.assertEqual(t[1].health, dragon_health + 1) + self.assertEqual(t[2].attack, dragon_attack + 1) + self.assertEqual(t[2].health, dragon_health + 1) + self.assertEqual(t[3].attack, dragon_attack) + self.assertEqual(t[3].health, dragon_health) t = Team(["flamingo", "dragon", "dragon", "dragon"]) t[0].obj.level = 2 pet = t[0].obj te_idx = [0, 0] t[0].obj.faint_trigger(pet, te_idx) - self.assertEqual(t[1].attack, 6 + 2) - self.assertEqual(t[1].health, 8 + 2) - self.assertEqual(t[2].attack, 6 + 2) - self.assertEqual(t[2].health, 8 + 2) - self.assertEqual(t[3].attack, 6) - self.assertEqual(t[3].health, 8) + self.assertEqual(t[1].attack, dragon_attack + 2) + self.assertEqual(t[1].health, dragon_health + 2) + self.assertEqual(t[2].attack, dragon_attack + 2) + self.assertEqual(t[2].health, dragon_health + 2) + self.assertEqual(t[3].attack, dragon_attack) + self.assertEqual(t[3].health, dragon_health) t = Team(["flamingo", "dragon", "dragon", "dragon"]) t[0].obj.level = 3 pet = t[0].obj te_idx = [0, 0] t[0].obj.faint_trigger(pet, te_idx) - self.assertEqual(t[1].attack, 6 + 3) - self.assertEqual(t[1].health, 8 + 3) - self.assertEqual(t[2].attack, 6 + 3) - self.assertEqual(t[2].health, 8 + 3) - self.assertEqual(t[3].attack, 6) - self.assertEqual(t[3].health, 8) + self.assertEqual(t[1].attack, dragon_attack + 3) + self.assertEqual(t[1].health, dragon_health + 3) + self.assertEqual(t[2].attack, dragon_attack + 3) + self.assertEqual(t[2].health, dragon_health + 3) + self.assertEqual(t[3].attack, dragon_attack) + self.assertEqual(t[3].health, dragon_health) def test_peacock(self): t = Team(["peacock"]) @@ -787,21 +988,21 @@ def test_peacock(self): t[0].obj.level = 1 t[0].obj.hurt(1) t[0].obj.hurt_trigger(enemy) - self.assertEqual(t[0].attack, 6) + self.assertEqual(t[0].attack, 5) t = Team(["peacock"]) enemy = Team(["fish"]) t[0].obj.level = 2 t[0].obj.hurt(1) t[0].obj.hurt_trigger(enemy) - self.assertEqual(t[0].attack, 10) + self.assertEqual(t[0].attack, 8) t = Team(["peacock"]) enemy = Team(["fish"]) t[0].obj.level = 3 t[0].obj.hurt(1) t[0].obj.hurt_trigger(enemy) - self.assertEqual(t[0].attack, 14) + self.assertEqual(t[0].attack, 11) def test_badger(self): t = Team(["badger", "dragon"]) @@ -813,8 +1014,8 @@ def test_badger(self): t[0].obj.hurt(3) t[0].obj.faint_trigger(t[0].obj, [0, 0], other_team) self.assertEqual(pet.health, 0) - self.assertEqual(ally.health, 8 - 2) - self.assertEqual(enemy.health, 2 - 2) + self.assertEqual(ally.health, 8 - 3) + self.assertEqual(enemy.health, 3 - 3) t = Team(["badger", "dragon"]) pet = t[0].obj @@ -825,8 +1026,8 @@ def test_badger(self): t[0].obj.hurt(3) t[0].obj.faint_trigger(t[0].obj, [0, 0], other_team) self.assertEqual(pet.health, 0) - self.assertEqual(ally.health, 8 - 5) - self.assertEqual(enemy.health, 2 - 5) + self.assertEqual(ally.health, 8 - 6) + self.assertEqual(enemy.health, 3 - 6) t = Team(["badger", "dragon"]) pet = t[0].obj @@ -837,8 +1038,8 @@ def test_badger(self): t[0].obj.hurt(3) t[0].obj.faint_trigger(t[0].obj, [0, 0], other_team) self.assertEqual(pet.health, 0) - self.assertEqual(ally.health, 8 - 7) - self.assertEqual(enemy.health, 2 - 7) + self.assertEqual(ally.health, 8 - 9) + self.assertEqual(enemy.health, 3 - 9) # %% diff --git a/tests/test_probabilities_generation.py b/tests/test_probabilities_generation.py new file mode 100644 index 0000000..d53c24f --- /dev/null +++ b/tests/test_probabilities_generation.py @@ -0,0 +1,57 @@ +import unittest + +from sapai.data import data +from sapai.probabilities import get_pack_names + + +class TestProbabilitiesGeneration(unittest.TestCase): + packs = get_pack_names(data) + groups = (("pets", "animalShopSlots"), ("foods", "foodShopSlots")) + + def _count_shop(self, group, pack, turn): + tier_limit = data["turns"][f"turn-{turn}"]["tiersAvailable"] + count = 0 + for entry in data[group].values(): + if not isinstance(entry.get("tier"), int): + continue + if entry["tier"] > tier_limit: + continue + if pack not in entry.get("packs", []): + continue + count += 1 + return count + + def test_non_shop_entries_use_none_probabilities(self): + for group, _ in self.groups: + for entry in data[group].values(): + if isinstance(entry.get("tier"), int): + continue + self.assertEqual(entry.get("probabilities"), "none") + + def test_shop_probabilities_match_generated_counts(self): + for group, slots_key in self.groups: + for entry in data[group].values(): + probs = entry.get("probabilities") + if probs == "none": + continue + for prob in probs: + self.assertEqual(prob["kind"], "shop") + turn = int(prob["turn"].split("-")[-1]) + slots = data["turns"][f"turn-{turn}"][slots_key] + for pack, per_slot in prob["perSlot"].items(): + expected_slot = 1 / self._count_shop(group, pack, turn) + self.assertAlmostEqual(per_slot, expected_slot) + expected_shop = 1 - (1 - expected_slot) ** slots + self.assertAlmostEqual(prob["perShop"][pack], expected_shop) + + def test_probabilities_have_known_pack_keys(self): + for group, _ in self.groups: + for entry in data[group].values(): + probs = entry.get("probabilities") + if probs == "none": + continue + for prob in probs: + for pack in prob.get("perSlot", {}): + self.assertIn(pack, self.packs) + for pack in prob.get("perShop", {}): + self.assertIn(pack, self.packs) diff --git a/tests/test_shop.py b/tests/test_shop.py index 4e9e1fc..f055eee 100644 --- a/tests/test_shop.py +++ b/tests/test_shop.py @@ -79,16 +79,17 @@ def test_pill_1gold(self): def test_cupcake(self): player = Player(shop=Shop(["cupcake"]), team=Team([Pet("fish")])) + fish = Pet("fish") player.buy_food(0, 0) - self.assertEqual(player.team[0].attack, 5) # fish 2/2 - self.assertEqual(player.team[0].health, 5) + self.assertEqual(player.team[0].attack, fish.attack + 3) + self.assertEqual(player.team[0].health, fish.health + 3) player.end_turn() player.start_turn() - self.assertEqual(player.team[0].attack, 2) - self.assertEqual(player.team[0].health, 2) + self.assertEqual(player.team[0].attack, fish.attack) + self.assertEqual(player.team[0].health, fish.health) def test_apple(self): player = Player(shop=Shop(["apple"]), team=Team([Pet("beaver")])) @@ -97,11 +98,245 @@ def test_apple(self): self.assertEqual(player.team[0].attack, 4) self.assertEqual(player.team[0].health, 3) + def test_cake_in_food_data(self): + cake = Food("cake") + self.assertEqual(cake.name, "food-cake") + self.assertEqual(cake.cost, 3) + self.assertEqual(cake.fd["effect"]["status"], "status-cake") + + def test_cake_increases_sell_value_each_end_turn(self): + player = Player(shop=Shop(["cake"]), team=Team([Pet("fish")])) + + player.buy_food(0, 0) + self.assertEqual(player.gold, 7) + self.assertEqual(player.team[0].pet.sell_value, 1) + + player.end_turn() + self.assertEqual(player.team[0].pet.sell_value, 2) + + player.end_turn() + self.assertEqual(player.team[0].pet.sell_value, 3) + + player.start_turn() + player.sell(0) + self.assertEqual(player.gold, 13) + + def test_sell_value_increases_on_level_up(self): + player = Player(shop=Shop(["chocolate", "chocolate"]), team=Team([Pet("fish")])) + self.assertEqual(player.team[0].pet.level, 1) + self.assertEqual(player.team[0].pet.sell_value, 1) + + player.buy_food(0, 0) + player.buy_food(0, 0) + + self.assertEqual(player.team[0].pet.level, 2) + self.assertEqual(player.team[0].pet.sell_value, 2) + + def test_sell_value_level2_merge_to_level3(self): + fish1 = Pet("fish") + fish2 = Pet("fish") + fish1.level = 2 + fish1.sell_value = 2 + fish2.level = 2 + fish2.sell_value = 2 + player = Player(team=Team([fish1, fish2])) + + player.combine(0, 1) + self.assertEqual(player.team[0].pet.level, 3) + self.assertEqual(player.team[0].pet.sell_value, 3) + + def test_combine_two_level1_pets_with_one_exp_each_keeps_level2_progress(self): + fish1 = Pet("fish") + fish2 = Pet("fish") + fish1.experience = 1 + fish2.experience = 1 + player = Player(team=Team([fish1, fish2])) + + player.combine(0, 1) + self.assertEqual(player.team[0].pet.level, 2) + self.assertEqual(player.team[0].pet.experience, 1) + self.assertEqual(player.team[0].pet.sell_value, 2) + + def _assert_combine_stat_bonus(self, flip_order=False): + ant1 = Pet("ant") + ant1.level = 1 + ant1.experience = 1 + ant1._attack = 3 + ant1._health = 3 + ant2 = Pet("ant") + ant2.level = 2 + ant2.experience = 1 + ant2._attack = 5 + ant2._health = 5 + player = Player(team=Team([ant1, ant2])) + + if flip_order: + player.combine(1, 0) + combined = player.team[1].pet + else: + player.combine(0, 1) + combined = player.team[0].pet + + self.assertEqual(combined.level, 3) + self.assertEqual(combined.attack, 7) + self.assertEqual(combined.health, 7) + + def _assert_combine_stat_bonus_over_leveled(self, flip_order=False): + ant1 = Pet("ant") + ant1.level = 1 + ant1.experience = 1 + ant1._attack = 3 + ant1._health = 3 + ant2 = Pet("ant") + ant2.level = 2 + ant2.experience = 2 + ant2._attack = 6 + ant2._health = 6 + player = Player(team=Team([ant1, ant2])) + + if flip_order: + player.combine(1, 0) + combined = player.team[1].pet + else: + player.combine(0, 1) + combined = player.team[0].pet + + self.assertEqual(combined.level, 3) + self.assertEqual(combined.attack, 8) + self.assertEqual(combined.health, 8) + + def _assert_combine_stat_bonus_both_pets_level_2(self, flip_order=False): + ant1 = Pet("ant") + ant1.level = 2 + ant1._attack = 4 + ant1._health = 4 + ant2 = Pet("ant") + ant2.level = 2 + ant2._attack = 4 + ant2._health = 4 + player = Player(team=Team([ant1, ant2])) + + if flip_order: + player.combine(1, 0) + combined = player.team[1].pet + else: + player.combine(0, 1) + combined = player.team[0].pet + + self.assertEqual(combined.level, 3) + self.assertEqual(combined.attack, 7) + self.assertEqual(combined.health, 7) + + def test_combine_stat_bonus(self): + self._assert_combine_stat_bonus(flip_order=False) + + def test_combine_stat_bonus_flipped(self): + self._assert_combine_stat_bonus(flip_order=True) + + def test_combine_stat_bonus_over_leveled(self): + self._assert_combine_stat_bonus_over_leveled(flip_order=False) + + def test_combine_stat_bonus_over_leveled_flipped(self): + self._assert_combine_stat_bonus_over_leveled(flip_order=True) + + def test_combine_stat_bonus_both_pets_level_2(self): + self._assert_combine_stat_bonus_both_pets_level_2(flip_order=False) + + def test_combine_stat_bonus_both_pets_level_2_flipped(self): + self._assert_combine_stat_bonus_both_pets_level_2(flip_order=True) + + + def test_level3_combine_not_allowed(self): + fish1 = Pet("fish") + fish2 = Pet("fish") + fish1.level = 3 + player = Player(team=Team([fish1, fish2])) + + with self.assertRaises(Exception): + player.combine(0, 1) + + def test_level3_buy_combine_not_allowed(self): + fish1 = Pet("fish") + fish1.level = 3 + player = Player(shop=Shop(["fish"]), team=Team([fish1])) + + with self.assertRaises(Exception): + player.buy_combine(0, 0) + + def test_cake_sell_value_with_end_turn_and_levelup(self): + player = Player( + shop=Shop(["cake", "chocolate", "chocolate"]), + team=Team([Pet("fish")]), + ) + + player.buy_food(0, 0) + self.assertEqual(player.team[0].pet.sell_value, 1) + + player.end_turn() + self.assertEqual(player.team[0].pet.sell_value, 2) + + player.buy_food(0, 0) + self.assertEqual(player.team[0].pet.level, 1) + self.assertEqual(player.team[0].pet.sell_value, 2) + + player.buy_food(0, 0) + self.assertEqual(player.team[0].pet.level, 2) + self.assertEqual(player.team[0].pet.sell_value, 3) + + player.end_turn() + self.assertEqual(player.team[0].pet.sell_value, 4) + def test_shop_levelup_from_combine(self): player = Player(shop=Shop(["fish", "fish"]), team=Team([Pet("fish")])) player.buy_combine(1, 0) player.buy_combine(0, 0) - self.assertEqual(len(player.shop), 1) + self.assertEqual(len(player.shop), 2) + + def test_no_levelup_reward_from_level2_plus_level2_combine(self): + fish1 = Pet("fish") + fish2 = Pet("fish") + fish1.level = 2 + fish2.level = 2 + player = Player(shop=Shop([]), team=Team([fish1, fish2])) + + levelup_slots = [s for s in player.shop.slots if s.slot_type == "levelup"] + self.assertEqual(len(levelup_slots), 0) + + player.combine(0, 1) + + levelup_slots = [s for s in player.shop.slots if s.slot_type == "levelup"] + self.assertEqual(player.team[0].pet.level, 3) + self.assertEqual(len(levelup_slots), 0) + + def test_levelup_reward_choices_are_without_replacement(self): + for _ in range(1000): + shop = Shop([]) + shop.levelup() + choices = [s.obj.name for s in shop.slots if s.slot_type == "levelup"] + self.assertEqual(len(choices), 2) + self.assertEqual(len(set(choices)), 2) + + def test_levelup_rewards_are_independent_between_events(self): + found_overlap_between_reward_sets = False + max_attempts = 1000 + + for _ in range(max_attempts): + shop = Shop(slots=[], fixed_rules=True) + shop.levelup() + shop.levelup() + + reward_names = [s.obj.name for s in shop.slots if s.slot_type == "levelup"] + self.assertEqual(len(reward_names), 4) + self.assertNotEqual(reward_names[0], reward_names[1]) + self.assertNotEqual(reward_names[2], reward_names[3]) + + first_set = set(reward_names[:2]) + second_set = set(reward_names[2:]) + if len(first_set.intersection(second_set)) > 0: + found_overlap_between_reward_sets = True + break + + self.assertTrue(found_overlap_between_reward_sets) def test_shop_levelup_from_ability(self): pet = Pet("caterpillar") @@ -109,63 +344,182 @@ def test_shop_levelup_from_ability(self): pet.experience = 2 player = Player(shop=Shop([]), team=Team([pet])) pet.sot_trigger() - self.assertEqual(len(player.shop.filled), 5) + self.assertEqual(len(player.shop.filled), 6) def test_buy_multi_target_food(self): + base_seal = Pet("seal") + base_rabbit = Pet("rabbit") + base_ladybug = Pet("ladybug") + player = Player(shop=["sushi"], team=["seal", "rabbit", "ladybug"]) player.buy_food(0) - self.assertEqual(player.team[0].attack, 4) # 3 + sushi - self.assertEqual(player.team[0].health, 10) # 8 + sushi + rabbit - self.assertEqual(player.team[1].attack, 3) # 1 + sushi + seal - self.assertEqual(player.team[1].health, 5) # 2 + sushi + seal + rabbit - self.assertEqual(player.team[2].attack, 4) # 1 + sushi + seal + ladybug - self.assertEqual( - player.team[2].health, 7 - ) # 3 + sushi + seal + rabbit + ladybug + self.assertEqual(player.team[0].attack, base_seal.attack + 1) # sushi + self.assertEqual(player.team[0].health, base_seal.health + 1 + 1) # sushi + rabbit + self.assertEqual(player.team[1].attack, base_rabbit.attack + 1 + 1) # sushi + seal + self.assertEqual(player.team[1].health, base_rabbit.health + 1 + 1) # sushi + rabbit + self.assertEqual(player.team[2].attack, base_ladybug.attack + 1 + 1 + 1) # sushi + ladybug + seal + self.assertEqual(player.team[2].health, base_ladybug.health + 1 + 1 + 1) # sushi + rabbit + ladybug def test_buy_multi_target_food_empty_team(self): player = Player(shop=["sushi"], team=[]) player.buy_food(0) def test_buy_chocolate(self): + base_seal = Pet("seal") + base_rabbit = Pet("rabbit") + base_ladybug = Pet("ladybug") + player = Player(shop=["chocolate"], team=["seal", "rabbit", "ladybug"]) player.buy_food(0, 0) self.assertEqual(player.team[0].pet.experience, 1) - self.assertEqual(player.team[0].attack, 3) # 3 - self.assertEqual(player.team[0].health, 9) # 8 + rabbit - self.assertEqual(player.team[1].attack, 2) # 1 + seal - self.assertEqual(player.team[1].health, 3) # 2 + seal - self.assertEqual(player.team[2].attack, 3) # 1 + seal + ladybug - self.assertEqual(player.team[2].health, 5) # 3 + seal + ladybug + self.assertEqual(player.team[0].attack, base_seal.attack) + self.assertEqual(player.team[0].health, base_seal.health + 1) # rabbit + self.assertEqual(player.team[1].attack, base_rabbit.attack + 1) #seal + self.assertEqual(player.team[1].health, base_rabbit.health) + self.assertEqual(player.team[2].attack, base_ladybug.attack + 1 + 1) # ladybug + seal + self.assertEqual(player.team[2].health, base_ladybug.health + 1) # ladybug def test_buy_apple(self): + base_seal = Pet("seal") + base_rabbit = Pet("rabbit") + base_ladybug = Pet("ladybug") + player = Player(shop=["apple"], team=["seal", "rabbit", "ladybug"]) player.buy_food(0, 0) - self.assertEqual(player.team[0].attack, 4) # 3 + apple - self.assertEqual(player.team[0].health, 10) # 8 + apple + rabbit - self.assertEqual(player.team[1].attack, 2) # 1 + seal - self.assertEqual(player.team[1].health, 3) # 2 + seal - self.assertEqual(player.team[2].attack, 3) # 1 + seal + ladybug - self.assertEqual(player.team[2].health, 5) # 3 + seal + ladybug + self.assertEqual(player.team[0].attack, base_seal.attack + 1) # apple + self.assertEqual(player.team[0].health, base_seal.health + 1 + 1) # apple + rabbit + self.assertEqual(player.team[1].attack, base_rabbit.attack + 1) # seal + self.assertEqual(player.team[1].health, base_rabbit.health) + self.assertEqual(player.team[2].attack, base_ladybug.attack + 1 + 1) # ladybug + seal + self.assertEqual(player.team[2].health, base_ladybug.health + 1) # ladybug + + def test_cow_replaces_food_shop_then_stocks_two_milk(self): + player = Player(shop=Shop(["apple", "pear", "cow"]), team=Team()) + player.buy_pet(2) + + shop_food_names = [slot.obj.name for slot in player.shop.slots if slot.slot_type == "food"] + self.assertNotIn("food-apple", shop_food_names) + self.assertNotIn("food-pear", shop_food_names) + self.assertEqual(shop_food_names.count("food-milk"), 2) + + def test_cow_stocked_milk_after_buy_combine_levelup(self): + team_cow = Pet("cow") + team_cow.level = 2 + team_cow.experience = 2 + shop_cow = Pet("cow") + player = Player(shop=Shop([shop_cow]), team=Team([team_cow])) + + player.buy_combine(0, 0) + self.assertEqual(player.team[0].pet.level, 3) + + milk_slots = [slot for slot in player.shop.slots if slot.obj.name == "food-milk"] + self.assertEqual(len(milk_slots), 2) + for slot in milk_slots: + self.assertEqual(slot.cost, 0) + self.assertEqual(slot.obj.attack, 3) + self.assertEqual(slot.obj.health, 6) + + def test_pigeon_sell_stocks_bread_crumbs_by_level(self): + for level, expected in [(1, 1), (2, 2), (3, 3)]: + pigeon = Pet("pigeon") + pigeon.level = level + player = Player(shop=Shop(["apple"]), team=Team([pigeon])) + + player.sell(0) + crumb_slots = [ + slot for slot in player.shop.slots if slot.slot_type == "food" and slot.obj.name == "food-bread-crumbs" + ] + self.assertEqual(len(crumb_slots), expected) + for slot in crumb_slots: + self.assertEqual(slot.cost, 0) + + def test_worm_start_turn_stocks_two_gold_apple_by_level(self): + for level, expected in [(1, (1, 1)), (2, (2, 2)), (3, (3, 3))]: + worm = Pet("worm") + worm.level = level + player = Player(shop=Shop(["fish"]), team=Team([worm])) + + activated, targets, _ = player.team[0].pet.sot_trigger() + self.assertTrue(activated) + self.assertEqual(len(targets), 1) + + stocked_slot = targets[0] + self.assertEqual(stocked_slot.slot_type, "food") + self.assertEqual(stocked_slot.obj.name, "food-apple") + self.assertEqual(stocked_slot.cost, 2) + self.assertEqual(stocked_slot.obj.attack, expected[0]) + self.assertEqual(stocked_slot.obj.health, expected[1]) + + def test_bread_crumbs_buy_gives_plus_one_attack(self): + player = Player(shop=Shop(["bread-crumbs"]), team=Team([Pet("fish")])) + base_attack = player.team[0].pet.attack + base_health = player.team[0].pet.health + + player.buy_food(0, 0) + self.assertEqual(player.team[0].pet.attack, base_attack + 1) + self.assertEqual(player.team[0].pet.health, base_health) + + def test_stock_shop_food_respects_capacity(self): + player = Player( + shop=Shop( + [ + "apple", + "pear", + "honey", + "cupcake", + "salad-bowl", + ] + ), + team=Team([Pet("pigeon")]), + ) + + player.sell(0) + self.assertEqual(len(player.shop.slots), 5) + crumb_count = sum(1 for slot in player.shop.slots if slot.obj.name == "food-bread-crumbs") + self.assertEqual(crumb_count, 0) + + def test_stock_shop_food_partial_capacity(self): + pigeon = Pet("pigeon") + pigeon.level = 3 + player = Player( + shop=Shop(["apple", "pear", "honey", "cupcake"]), + team=Team([pigeon]), + ) + + player.sell(0) + food_count = sum(1 for slot in player.shop.slots if slot.slot_type == "food") + self.assertEqual(food_count, 5) + crumb_count = sum( + 1 for slot in player.shop.slots if slot.slot_type == "food" and slot.obj.name == "food-bread-crumbs" + ) + self.assertEqual(crumb_count, 1) + + def test_shop_pet_cap_prevents_eighth_pet_slot(self): + shop = Shop(["ant", "beaver", "cricket", "fish", "mosquito", "otter", "pig"]) + + shop.append(Pet("horse")) + + self.assertEqual(sum(1 for slot in shop.slots if slot.slot_type in ["pet", "levelup"]), 7) + self.assertNotIn("pet-horse", [slot.obj.name for slot in shop.slots if slot.slot_type == "pet"]) def test_chicken(self): state = np.random.RandomState(seed=1).get_state() player = Player(shop=Shop(["fish", "fish"], seed_state=state), team=["chicken"]) player.buy_pet(0) - self.assertEqual(player.shop[0].obj.attack, 3) # fish 2/2 - self.assertEqual(player.shop[0].obj.health, 3) + self.assertEqual(player.shop[0].obj.attack, player.shop[0].obj.fd["baseAttack"] + 1) + self.assertEqual(player.shop[0].obj.health, player.shop[0].obj.fd["baseHealth"] + 1) ### check result after 1 roll player.roll() - self.assertEqual(player.shop[0].obj.attack, 3) # duck 2/3 - self.assertEqual(player.shop[0].obj.health, 4) + self.assertEqual(player.shop[0].obj.attack, player.shop[0].obj.fd["baseAttack"] + 1) + self.assertEqual(player.shop[0].obj.health, player.shop[0].obj.fd["baseHealth"] + 1) ### check result in a new turn player.end_turn() player.start_turn() - self.assertEqual(player.shop[0].obj.attack, 3) # mosquito 2/2 - self.assertEqual(player.shop[0].obj.health, 3) + self.assertEqual(player.shop[0].obj.attack, player.shop[0].obj.fd["baseAttack"] + 1) + self.assertEqual(player.shop[0].obj.health, player.shop[0].obj.fd["baseHealth"] + 1) def test_canned_food(self): state = np.random.RandomState(seed=1).get_state() @@ -175,19 +529,47 @@ def test_canned_food(self): player.buy_food(1) ### check immediate result - self.assertEqual(player.shop[0].obj.attack, 4) # fish 2/2 - self.assertEqual(player.shop[0].obj.health, 3) + self.assertEqual(player.shop[0].obj.attack, player.shop[0].obj.fd["baseAttack"] + 1) + self.assertEqual(player.shop[0].obj.health, player.shop[0].obj.fd["baseHealth"] + 1) ### check result after 1 roll player.roll() - self.assertEqual(player.shop[0].obj.attack, 4) # duck 2/3 - self.assertEqual(player.shop[0].obj.health, 4) + self.assertEqual(player.shop[0].obj.attack, player.shop[0].obj.fd["baseAttack"] + 1) + self.assertEqual(player.shop[0].obj.health, player.shop[0].obj.fd["baseHealth"] + 1) ### check result in a new turn player.end_turn() player.start_turn() - self.assertEqual(player.shop[0].obj.attack, 4) # mosquito 2/2 - self.assertEqual(player.shop[0].obj.health, 3) + self.assertEqual(player.shop[0].obj.attack, player.shop[0].obj.fd["baseAttack"] + 1) + self.assertEqual(player.shop[0].obj.health, player.shop[0].obj.fd["baseHealth"] + 1) + + def test_canned_food_future_buff_applies_once_with_multiple_current_targets(self): + state = np.random.RandomState(seed=1).get_state() + player = Player(shop=Shop(["fish", "ant", "canned-food"], seed_state=state)) + + player.buy_food(2) + player.roll() + + for slot in player.shop.slots: + if slot.slot_type != "pet": + continue + self.assertEqual(slot.obj.attack, slot.obj.fd["baseAttack"] + 1) + self.assertEqual(slot.obj.health, slot.obj.fd["baseHealth"] + 1) + + def test_canned_food_future_buff_applies_when_no_current_shop_pets(self): + state = np.random.RandomState(seed=1).get_state() + player = Player(shop=Shop(["fish", "ant", "canned-food"], seed_state=state)) + + player.buy_pet(0) + player.buy_pet(0) + player.buy_food(0) + player.roll() + + for slot in player.shop.slots: + if slot.slot_type != "pet": + continue + self.assertEqual(slot.obj.attack, slot.obj.fd["baseAttack"] + 1) + self.assertEqual(slot.obj.health, slot.obj.fd["baseHealth"] + 1) # %% diff --git a/tests/test_status.py b/tests/test_status.py index 30ee29b..27bed54 100644 --- a/tests/test_status.py +++ b/tests/test_status.py @@ -52,5 +52,12 @@ def test_weak(self): for i in range(1, MAX): self.assertEqual(p.get_damage(i), i + 3) + def test_bone_attack_damage(self): + p = Pet("fish") + p.eat(Food("meat-bone")) + fish_base_attack = p.fd["baseAttack"] + bone_attack_bonus = data["statuses"]["status-bone-attack"]["ability"]["effect"]["damageModifier"] + self.assertEqual(p.attack, fish_base_attack + bone_attack_bonus) + # %%