Skip to content

Commit

Permalink
Confusion, cursed body and poison touch trigger chance fixes and tests (
Browse files Browse the repository at this point in the history
#4831)

* accurate confusion chance and a test

* Accurate Poison Touch chance and tests

* Accurate cursed body chance

* Create cursed_body.c
  • Loading branch information
Sneed69 authored Jun 18, 2024
1 parent 7581f20 commit b6d3bdf
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ enum RandomTag
RNG_ACCURACY,
RNG_CONFUSION,
RNG_CRITICAL_HIT,
RNG_CURSED_BODY,
RNG_CUTE_CHARM,
RNG_DAMAGE_MODIFIER,
RNG_DIRE_CLAW,
Expand All @@ -175,6 +176,7 @@ enum RandomTag
RNG_METRONOME,
RNG_PARALYSIS,
RNG_POISON_POINT,
RNG_POISON_TOUCH,
RNG_RAMPAGE_TURNS,
RNG_SECONDARY_EFFECT,
RNG_SECONDARY_EFFECT_2,
Expand Down
6 changes: 3 additions & 3 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -3371,7 +3371,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
{
// confusion dmg
if (RandomWeighted(RNG_CONFUSION, (B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 2 : 1), 1))
if (RandomPercentage(RNG_CONFUSION, (B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50)))
{
gBattleCommunication[MULTISTRING_CHOOSER] = TRUE;
gBattlerTarget = gBattlerAttacker;
Expand Down Expand Up @@ -5295,7 +5295,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
&& gBattleMons[gBattlerAttacker].pp[gChosenMovePos] != 0
&& !IsDynamaxed(gBattlerAttacker) // TODO: Max Moves don't make contact, useless?
&& (Random() % 3) == 0)
&& RandomPercentage(RNG_CURSED_BODY, 30))
{
gDisableStructs[gBattlerAttacker].disabledMove = gChosenMove;
gDisableStructs[gBattlerAttacker].disableTimer = 4;
Expand Down Expand Up @@ -5749,7 +5749,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker)
&& TARGET_TURN_DAMAGED // Need to actually hit the target
&& (Random() % 3) == 0)
&& RandomPercentage(RNG_POISON_TOUCH, 30))
{
gBattleScripting.moveEffect = MOVE_EFFECT_POISON;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
Expand Down
17 changes: 17 additions & 0 deletions test/battle/ability/cursed_body.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "global.h"
#include "test/battle.h"

SINGLE_BATTLE_TEST("Cursed Body triggers 30% of the time")
{
PASSES_RANDOMLY(3, 10, RNG_CURSED_BODY);
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_FRILLISH) { Ability(ABILITY_CURSED_BODY); }
} WHEN {
TURN { MOVE(player, MOVE_AQUA_JET); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_AQUA_JET, player);
ABILITY_POPUP(opponent, ABILITY_CURSED_BODY);
MESSAGE("Wobbuffet's Aqua Jet was disabled by Foe Frillish's Cursed Body!");
}
}
77 changes: 77 additions & 0 deletions test/battle/ability/poison_touch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "global.h"
#include "test/battle.h"

SINGLE_BATTLE_TEST("Poison Touch has a 30% chance to poison when attacking with contact moves")
{
PASSES_RANDOMLY(3, 10, RNG_POISON_TOUCH);
GIVEN {
ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("Foe Wobbuffet was poisoned by Grimer's Poison Touch!");
STATUS_ICON(opponent, poison: TRUE);
}
}

SINGLE_BATTLE_TEST("Poison Touch only applies when using contact moves")
{
u32 move;

PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, player);
if (gMovesInfo[move].makesContact) {
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("Foe Wobbuffet was poisoned by Grimer's Poison Touch!");
STATUS_ICON(opponent, poison: TRUE);
} else {
NONE_OF {
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("Foe Wobbuffet was poisoned by Grimer's Poison Touch!");
STATUS_ICON(opponent, poison: TRUE);
}
}
}
}

SINGLE_BATTLE_TEST("Poison Touch applies between multi-hit move hits")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_ARM_THRUST].effect == EFFECT_MULTI_HIT);
ASSUME(gMovesInfo[MOVE_ARM_THRUST].makesContact);
ASSUME(gItemsInfo[ITEM_PECHA_BERRY].holdEffect == HOLD_EFFECT_CURE_PSN);
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_PECHA_BERRY); };
} WHEN {
TURN { MOVE(player, MOVE_ARM_THRUST); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ARM_THRUST, player);
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("Foe Wobbuffet was poisoned by Grimer's Poison Touch!");
STATUS_ICON(opponent, poison: TRUE);
MESSAGE("Foe Wobbuffet's Pecha Berry cured poison!");
STATUS_ICON(opponent, poison: FALSE);
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("Foe Wobbuffet was poisoned by Grimer's Poison Touch!");
STATUS_ICON(opponent, poison: TRUE);
}
}
28 changes: 28 additions & 0 deletions test/battle/status2/confusion.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "global.h"
#include "test/battle.h"

SINGLE_BATTLE_TEST("Confusion adds a 50/33% chance to hit self with 40 power")
{
s16 damage[2];

ASSUME(gMovesInfo[MOVE_TACKLE].power == 40);

PASSES_RANDOMLY(B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50, 100, RNG_CONFUSION);
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(1); };
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); };
} WHEN {
TURN { MOVE(opponent, MOVE_TACKLE, WITH_RNG(RNG_DAMAGE_MODIFIER, 0)); MOVE(player, MOVE_CONFUSE_RAY); }
TURN;
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
HP_BAR(player, captureDamage: &damage[0]);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFUSE_RAY, player);
MESSAGE("Foe Wobbuffet became confused!");
MESSAGE("Foe Wobbuffet is confused!");
MESSAGE("It hurt itself in its confusion!");
HP_BAR(opponent, captureDamage: &damage[1]);
} THEN {
EXPECT_EQ(damage[0], damage[1]);
}
}

0 comments on commit b6d3bdf

Please sign in to comment.