mirror of
https://github.com/pret/pokeemerald.git
synced 2026-04-26 01:19:29 -05:00
Add RandomChance macro and ability trigger chance config (#4829)
* RandomChance macro, contact ability chance config * Unify config, add shed skin
This commit is contained in:
parent
f106b21344
commit
609754f0f6
|
|
@ -147,6 +147,9 @@
|
|||
#define B_INTREPID_SWORD GEN_LATEST // In Gen9+, Intrepid Sword raises Attack by one stage only once per Battle.
|
||||
#define B_DAUNTLESS_SHIELD GEN_LATEST // In Gen9+, Dauntless Shield raises Defense by one stage only once per Battle.
|
||||
#define B_DISGUISE_HP_LOSS GEN_LATEST // In Gen8+, when a Disguised Mimikyu's Disguise is busted, upon changing to its Busted Form it loses HP equal to 1/8 of its maximum HP.
|
||||
#define B_ABILITY_TRIGGER_CHANCE GEN_LATEST // In Gen3, Shed Skin, Cute Charm, Flame Body, Static and Poison Point have a 1/3 chance to trigger. In Gen 4+ it's 30%.
|
||||
// In Gen3, Effect Spore has a 10% chance to sleep, poison or paralyze, with an equal chance.
|
||||
// In Gen4, it's 30%. In Gen5+ it has 11% to sleep, 9% chance to poison and 10% chance to paralyze.
|
||||
|
||||
// Item settings
|
||||
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore HP activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.
|
||||
|
|
|
|||
|
|
@ -144,13 +144,16 @@ static inline void Shuffle(void *data, size_t n, size_t size)
|
|||
* probability. The array must be known at compile-time (e.g. a global
|
||||
* const array).
|
||||
*
|
||||
* RandomPercentage(tag, t) returns FALSE with probability (1-t)/100,
|
||||
* RandomPercentage(tag, t) returns FALSE with probability 1-t/100,
|
||||
* and TRUE with probability t/100.
|
||||
*
|
||||
* RandomWeighted(tag, w0, w1, ... wN) returns a number from 0 to N
|
||||
* inclusive. The return value is proportional to the weights, e.g.
|
||||
* RandomWeighted(..., 1, 1) returns 50% 0s and 50% 1s.
|
||||
* RandomWeighted(..., 2, 1) returns 2/3 0s and 1/3 1s. */
|
||||
* RandomWeighted(..., 2, 1) returns 2/3 0s and 1/3 1s.
|
||||
*
|
||||
* RandomChance(tag, successes, total) returns FALSE with probability
|
||||
* 1-successes/total, and TRUE with probability successes/total. */
|
||||
|
||||
enum RandomTag
|
||||
{
|
||||
|
|
@ -161,6 +164,7 @@ enum RandomTag
|
|||
RNG_CUTE_CHARM,
|
||||
RNG_DAMAGE_MODIFIER,
|
||||
RNG_DIRE_CLAW,
|
||||
RNG_EFFECT_SPORE,
|
||||
RNG_FLAME_BODY,
|
||||
RNG_FORCE_RANDOM_SWITCH,
|
||||
RNG_FROZEN,
|
||||
|
|
@ -179,6 +183,7 @@ enum RandomTag
|
|||
RNG_SECONDARY_EFFECT,
|
||||
RNG_SECONDARY_EFFECT_2,
|
||||
RNG_SECONDARY_EFFECT_3,
|
||||
RNG_SHED_SKIN,
|
||||
RNG_SLEEP_TURNS,
|
||||
RNG_SPEED_TIE,
|
||||
RNG_STATIC,
|
||||
|
|
@ -202,6 +207,8 @@ enum RandomTag
|
|||
RandomWeightedArray(tag, sum, ARRAY_COUNT(weights), weights); \
|
||||
})
|
||||
|
||||
#define RandomChance(tag, successes, total) (RandomWeighted(tag, total - successes, successes))
|
||||
|
||||
#define RandomPercentage(tag, t) \
|
||||
({ \
|
||||
u32 r; \
|
||||
|
|
|
|||
|
|
@ -1943,7 +1943,7 @@ static void Cmd_critcalc(void)
|
|||
else if (critChance == -2)
|
||||
gIsCriticalHit = TRUE;
|
||||
else
|
||||
gIsCriticalHit = RandomWeighted(RNG_CRITICAL_HIT, sCriticalHitOdds[critChance] - 1, 1);
|
||||
gIsCriticalHit = RandomChance(RNG_CRITICAL_HIT, 1, sCriticalHitOdds[critChance]);
|
||||
|
||||
// Counter for EVO_CRITICAL_HITS.
|
||||
partySlot = gBattlerPartyIndexes[gBattlerAttacker];
|
||||
|
|
|
|||
|
|
@ -4861,7 +4861,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
break;
|
||||
case ABILITY_SHED_SKIN:
|
||||
if ((gBattleMons[battler].status1 & STATUS1_ANY) && (Random() % 3) == 0)
|
||||
if ((gBattleMons[battler].status1 & STATUS1_ANY)
|
||||
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_SHED_SKIN, 30) : RandomChance(RNG_SHED_SKIN, 1, 3)))
|
||||
{
|
||||
ABILITY_HEAL_MON_STATUS:
|
||||
if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON))
|
||||
|
|
@ -5502,24 +5503,38 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
break;
|
||||
case ABILITY_EFFECT_SPORE:
|
||||
if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GRASS)
|
||||
if ((!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GRASS) || B_POWDER_GRASS < GEN_6)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_OVERCOAT
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES)
|
||||
{
|
||||
i = Random() % 3;
|
||||
if (i == 0)
|
||||
u32 poison, paralysis, sleep;
|
||||
|
||||
if (B_ABILITY_TRIGGER_CHANCE >= GEN_5)
|
||||
{
|
||||
poison = 9;
|
||||
paralysis = 19;
|
||||
}
|
||||
else
|
||||
{
|
||||
poison = 10;
|
||||
paralysis = 20;
|
||||
}
|
||||
sleep = 30;
|
||||
|
||||
i = RandomUniform(RNG_EFFECT_SPORE, 0, B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? 99 : 299);
|
||||
if (i < poison)
|
||||
goto POISON_POINT;
|
||||
if (i == 1)
|
||||
if (i < paralysis)
|
||||
goto STATIC;
|
||||
// Sleep
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
if (i < sleep
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& CanSleep(gBattlerAttacker)
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker)
|
||||
&& (Random() % 3) == 0)
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_SLEEP;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||
|
|
@ -5530,42 +5545,46 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
}
|
||||
}
|
||||
break;
|
||||
POISON_POINT:
|
||||
case ABILITY_POISON_POINT:
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& CanBePoisoned(gBattlerTarget, gBattlerAttacker)
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker)
|
||||
&& RandomWeighted(RNG_POISON_POINT, 2, 1))
|
||||
if (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_POISON_POINT, 30) : RandomChance(RNG_POISON_POINT, 1, 3))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_POISON;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_AbilityStatusEffect;
|
||||
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
effect++;
|
||||
POISON_POINT:
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& CanBePoisoned(gBattlerTarget, gBattlerAttacker)
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_POISON;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_AbilityStatusEffect;
|
||||
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
STATIC:
|
||||
case ABILITY_STATIC:
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& CanBeParalyzed(gBattlerAttacker)
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker)
|
||||
&& RandomWeighted(RNG_STATIC, 2, 1))
|
||||
if (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_STATIC, 30) : RandomChance(RNG_STATIC, 1, 3))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_PARALYSIS;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_AbilityStatusEffect;
|
||||
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
effect++;
|
||||
STATIC:
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& CanBeParalyzed(gBattlerAttacker)
|
||||
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
|
||||
&& IsMoveMakingContact(move, gBattlerAttacker))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_PARALYSIS;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_AbilityStatusEffect;
|
||||
gHitMarker |= HITMARKER_STATUS_ABILITY_EFFECT;
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABILITY_FLAME_BODY:
|
||||
|
|
@ -5576,7 +5595,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
&& (IsMoveMakingContact(move, gBattlerAttacker))
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& CanBeBurned(gBattlerAttacker)
|
||||
&& RandomWeighted(RNG_FLAME_BODY, 2, 1))
|
||||
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_FLAME_BODY, 30) : RandomChance(RNG_FLAME_BODY, 1, 3)))
|
||||
{
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN;
|
||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||
|
|
@ -5592,7 +5611,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& RandomWeighted(RNG_CUTE_CHARM, 2, 1)
|
||||
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_CUTE_CHARM, 30) : RandomChance(RNG_CUTE_CHARM, 1, 3))
|
||||
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
|
||||
&& AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_OBLIVIOUS
|
||||
|
|
@ -5826,7 +5845,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerTarget)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& RandomWeighted(RNG_STENCH, 9, 1)
|
||||
&& RandomChance(RNG_STENCH, 1, 10)
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& !MoveHasAdditionalEffect(gCurrentMove, MOVE_EFFECT_FLINCH))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,3 +45,22 @@ SINGLE_BATTLE_TEST("Cute Charm cannot infatuate same gender")
|
|||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Cute Charm triggers 30% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(3, 10, RNG_CUTE_CHARM);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); }
|
||||
OPPONENT(SPECIES_CLEFAIRY) { Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_CUTE_CHARM);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_INFATUATION, player);
|
||||
MESSAGE("Foe Clefairy's Cute Charm infatuated Wobbuffet!");
|
||||
MESSAGE("Wobbuffet is in love with Foe Clefairy!");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
90
test/battle/ability/effect_spore.c
Normal file
90
test/battle/ability/effect_spore.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Effect Spore only inflicts status on contact")
|
||||
{
|
||||
u32 move;
|
||||
|
||||
PARAMETRIZE { move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { move = MOVE_SWIFT; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move, WITH_RNG(RNG_EFFECT_SPORE, 1)); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
if (gMovesInfo[move].makesContact) {
|
||||
ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
|
||||
MESSAGE("Wobbuffet was poisoned by Foe Breloom's Effect Spore!");
|
||||
STATUS_ICON(player, poison: TRUE);
|
||||
} else {
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
|
||||
MESSAGE("Wobbuffet was poisoned by Foe Breloom's Effect Spore!");
|
||||
STATUS_ICON(player, poison: TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Effect Spore causes poison 9% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(9, 100, RNG_EFFECT_SPORE);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
|
||||
MESSAGE("Wobbuffet was poisoned by Foe Breloom's Effect Spore!");
|
||||
STATUS_ICON(player, poison: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Effect Spore causes paralysis 10% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(10, 100, RNG_EFFECT_SPORE);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player);
|
||||
MESSAGE("Foe Breloom's Effect Spore paralyzed Wobbuffet! It may be unable to move!");
|
||||
STATUS_ICON(player, paralysis: TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Effect Spore causes sleep 11% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
|
||||
MESSAGE("Foe Breloom's Effect Spore made Wobbuffet sleep!");
|
||||
STATUS_ICON(player, sleep: TRUE);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,3 +29,21 @@ SINGLE_BATTLE_TEST("Flame Body inflicts burn on contact")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Flame Body triggers 30% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(3, 10, RNG_FLAME_BODY);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_MAGMAR) { Ability(ABILITY_FLAME_BODY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_FLAME_BODY);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, player);
|
||||
MESSAGE("Foe Magmar's Flame Body burned Wobbuffet!");
|
||||
STATUS_ICON(player, burn: TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,3 +30,22 @@ SINGLE_BATTLE_TEST("Poison Point inflicts poison on contact")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Poison Point triggers 30% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(3, 10, RNG_POISON_POINT);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_NIDORAN_M) { Ability(ABILITY_POISON_POINT); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_POISON_POINT);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
|
||||
MESSAGE("Wobbuffet was poisoned by Foe Nidoran♂'s Poison Point!");
|
||||
STATUS_ICON(player, poison: TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
19
test/battle/ability/shed_skin.c
Normal file
19
test/battle/ability/shed_skin.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Shed Skin triggers 30% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(3, 10, RNG_SHED_SKIN);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ARBOK) { Status1(STATUS1_POISON); Ability(ABILITY_SHED_SKIN); }
|
||||
} WHEN {
|
||||
TURN;
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_SHED_SKIN);
|
||||
MESSAGE("Foe Arbok's Shed Skin cured its poison problem!");
|
||||
STATUS_ICON(opponent, poison: FALSE);
|
||||
}
|
||||
}
|
||||
|
|
@ -29,3 +29,21 @@ SINGLE_BATTLE_TEST("Static inflicts paralysis on contact")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Static triggers 30% of the time")
|
||||
{
|
||||
PASSES_RANDOMLY(3, 10, RNG_STATIC);
|
||||
GIVEN {
|
||||
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_STATIC);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player);
|
||||
MESSAGE("Foe Pikachu's Static paralyzed Wobbuffet! It may be unable to move!");
|
||||
STATUS_ICON(player, paralysis: TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ ASSUMPTIONS
|
|||
ASSUME(B_CRIT_CHANCE >= GEN_7);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Side effected by Lucky Chant blocks critical hits")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Side effected by Lucky Chant blocks critical hits")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_LUCKY_CHANT].effect == EFFECT_LUCKY_CHANT);
|
||||
|
|
@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Side effected by Lucky Chant blocks critical hits")
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Battle Armor and Shell Armor block critical hits")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Battle Armor and Shell Armor block critical hits")
|
||||
{
|
||||
u32 species;
|
||||
u32 ability;
|
||||
|
|
@ -39,7 +39,7 @@ SINGLE_BATTLE_TEST("Battle Armor and Shell Armor block critical hits")
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Flag ignoresTargetAbility ignores Battle Armor and Shell Armor")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Flag ignoresTargetAbility ignores Battle Armor and Shell Armor")
|
||||
{
|
||||
u32 species;
|
||||
u32 ability;
|
||||
|
|
@ -59,7 +59,7 @@ SINGLE_BATTLE_TEST("Flag ignoresTargetAbility ignores Battle Armor and Shell Arm
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mold Breaker, Teravolt and Turboblaze ignore Battle Armor and Shell Armor")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Mold Breaker, Teravolt and Turboblaze ignore Battle Armor and Shell Armor")
|
||||
{
|
||||
u32 j;
|
||||
static const u32 pokemonPlayer[][2] =
|
||||
|
|
@ -102,7 +102,7 @@ SINGLE_BATTLE_TEST("Mold Breaker, Teravolt and Turboblaze ignore Battle Armor an
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("User effected by Laser Focus causes moves to result in a critical hit")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: User effected by Laser Focus causes moves to result in a critical hit")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_LASER_FOCUS].effect == EFFECT_LASER_FOCUS);
|
||||
|
|
@ -118,7 +118,7 @@ SINGLE_BATTLE_TEST("User effected by Laser Focus causes moves to result in a cri
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("If the target is poisoned the ability Merciless causes a move to result in a critical hit")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: If the target is poisoned the ability Merciless causes a move to result in a critical hit")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_MAREANIE) { Ability(ABILITY_MERCILESS); }
|
||||
|
|
@ -131,7 +131,7 @@ SINGLE_BATTLE_TEST("If the target is poisoned the ability Merciless causes a mov
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Focus Energy increases the user's critical hit ratio by two stage")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases the user's critical hit ratio by two stage")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -148,7 +148,7 @@ SINGLE_BATTLE_TEST("Focus Energy increases the user's critical hit ratio by two
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("High crit rate increases the critical hit ratio by one stage")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: High crit rate increases the critical hit ratio by one stage")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -163,7 +163,7 @@ SINGLE_BATTLE_TEST("High crit rate increases the critical hit ratio by one stage
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Super Luck increases the critical hit ratio by one stage")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Super Luck increases the critical hit ratio by one stage")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -177,7 +177,7 @@ SINGLE_BATTLE_TEST("Super Luck increases the critical hit ratio by one stage")
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Scope Lens increases the critical hit ratio by one stage")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Scope Lens increases the critical hit ratio by one stage")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -192,7 +192,7 @@ SINGLE_BATTLE_TEST("Scope Lens increases the critical hit ratio by one stage")
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("High crit rate, Super Luck and Scope Lens cause the move to result in a critical hit")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: High crit rate, Super Luck and Scope Lens cause the move to result in a critical hit")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
|
||||
|
|
@ -207,7 +207,7 @@ SINGLE_BATTLE_TEST("High crit rate, Super Luck and Scope Lens cause the move to
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Signature items Leek and Lucky Punch increase the critical hit ratio by 2 stages")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Signature items Leek and Lucky Punch increase the critical hit ratio by 2 stages")
|
||||
{
|
||||
u32 species;
|
||||
u32 item;
|
||||
|
|
@ -232,7 +232,7 @@ SINGLE_BATTLE_TEST("Signature items Leek and Lucky Punch increase the critical h
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dire Hit increases a battler's critical hit chance by 2 stages")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Dire Hit increases a battler's critical hit chance by 2 stages")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -250,7 +250,7 @@ SINGLE_BATTLE_TEST("Dire Hit increases a battler's critical hit chance by 2 stag
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Focus Energy increases critical hit ratio by two")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases critical hit ratio by two")
|
||||
{
|
||||
PASSES_RANDOMLY(8, 8, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -269,7 +269,7 @@ SINGLE_BATTLE_TEST("Focus Energy increases critical hit ratio by two")
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dragon Cheer fails in a single battle")
|
||||
SINGLE_BATTLE_TEST("Crit Chance: Dragon Cheer fails in a single battle")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER);
|
||||
|
|
@ -282,7 +282,7 @@ SINGLE_BATTLE_TEST("Dragon Cheer fails in a single battle")
|
|||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by one on non Dragon types")
|
||||
DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by one on non Dragon types")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -302,7 +302,7 @@ DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by one on non Drag
|
|||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by two on Dragon types")
|
||||
DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by two on Dragon types")
|
||||
{
|
||||
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
|
||||
GIVEN {
|
||||
|
|
@ -322,7 +322,7 @@ DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by two on Dragon t
|
|||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Dragon Cheer fails if critical hit stage was already increased by Focus Energy")
|
||||
DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer fails if critical hit stage was already increased by Focus Energy")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user