Skip to content

Commit

Permalink
Fixes Dancer, adds Revelation Dance interactions with Z-Move, Roost a…
Browse files Browse the repository at this point in the history
…nd typeless mons (#5133)

* Add Revelation Dance interactions with typeless mons, Roost and Z-Move

* Fixes Dancer-called moves not updating their type

* Adds Revelation Dance tests

* Make sure target isn't immune in Dancer test

* Missing ... in message

* Missing Assume

* CI ends Dancer test too early?

* Z-Revelation Dance is Breakneck Blitz (Test)

* Fix test (Zoroark too strong?)

* Replace H!Zoroark

* Remove Ability specification

* Remove HP_Bars

* Fix Dancer checking for battlers that don't exist in single battles
  • Loading branch information
PhallenTree committed Aug 11, 2024
1 parent 137c15a commit 779cedd
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 7 deletions.
10 changes: 7 additions & 3 deletions src/battle_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5824,16 +5824,20 @@ void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk)
{
gBattleStruct->dynamicMoveType = ItemId_GetSecondaryId(gBattleMons[battlerAtk].item) | F_DYNAMIC_TYPE_SET;
}
else if (gMovesInfo[move].effect == EFFECT_REVELATION_DANCE)
else if (gMovesInfo[move].effect == EFFECT_REVELATION_DANCE && GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE)
{
if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA && GetBattlerTeraType(battlerAtk) != TYPE_STELLAR)
gBattleStruct->dynamicMoveType = GetBattlerTeraType(battlerAtk);
else if (gBattleMons[battlerAtk].types[0] != TYPE_MYSTERY)
else if (gBattleMons[battlerAtk].types[0] != TYPE_MYSTERY && !(gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST && gBattleMons[battlerAtk].types[0] == TYPE_FLYING))
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[0] | F_DYNAMIC_TYPE_SET;
else if (gBattleMons[battlerAtk].types[1] != TYPE_MYSTERY)
else if (gBattleMons[battlerAtk].types[1] != TYPE_MYSTERY && !(gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST && gBattleMons[battlerAtk].types[1] == TYPE_FLYING))
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[1] | F_DYNAMIC_TYPE_SET;
else if (gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST)
gBattleStruct->dynamicMoveType = (B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY) | F_DYNAMIC_TYPE_SET;
else if (gBattleMons[battlerAtk].types[2] != TYPE_MYSTERY)
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[2] | F_DYNAMIC_TYPE_SET;
else
gBattleStruct->dynamicMoveType = TYPE_MYSTERY | F_DYNAMIC_TYPE_SET;
}
else if (gMovesInfo[move].effect == EFFECT_RAGING_BULL
&& (gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED
Expand Down
6 changes: 3 additions & 3 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -6257,7 +6257,7 @@ static void Cmd_moveend(void)
u32 battler, nextDancer = 0;
bool32 turnOnHitmarker = FALSE;

for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++)
for (battler = 0; battler < gBattlersCount; battler++)
{
if (gSpecialStatuses[battler].dancerUsedMove)
{
Expand All @@ -6278,7 +6278,7 @@ static void Cmd_moveend(void)
gBattleScripting.savedBattler |= (gBattlerAttacker << 4);
gSpecialStatuses[gBattlerAttacker].dancerUsedMove = TRUE;
}
for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++)
for (battler = 0; battler < gBattlersCount; battler++)
{
if (GetBattlerAbility(battler) == ABILITY_DANCER && !gSpecialStatuses[battler].dancerUsedMove)
{
Expand Down Expand Up @@ -12898,7 +12898,7 @@ static void Cmd_settypetorandomresistance(void)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else if (gLastHitByType[gBattlerAttacker] == TYPE_STELLAR)
else if (gLastHitByType[gBattlerAttacker] == TYPE_STELLAR || gLastHitByType[gBattlerAttacker] == TYPE_MYSTERY)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
Expand Down
6 changes: 5 additions & 1 deletion src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -5565,6 +5565,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& TARGET_TURN_DAMAGED
&& !IS_BATTLER_OF_TYPE(battler, moveType)
&& moveType != TYPE_STELLAR
&& moveType != TYPE_MYSTERY
&& IsBattlerAlive(battler))
{
SET_BATTLER_TYPE(battler, moveType);
Expand Down Expand Up @@ -6049,6 +6050,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32

// Edge case for dance moves that hit multiply targets
gHitMarker &= ~HITMARKER_NO_ATTACKSTRING;
SetTypeBeforeUsingMove(gCalledMove, battler);

// Make sure that the target isn't an ally - if it is, target the original user
if (GetBattlerSide(gBattlerTarget) == GetBattlerSide(gBattlerAttacker))
Expand Down Expand Up @@ -9860,7 +9862,9 @@ static inline uq4_12_t GetParentalBondModifier(u32 battlerAtk)

static inline uq4_12_t GetSameTypeAttackBonusModifier(u32 battlerAtk, u32 moveType, u32 move, u32 abilityAtk)
{
if (gBattleStruct->pledgeMove && IS_BATTLER_OF_TYPE(BATTLE_PARTNER(battlerAtk), moveType))
if (moveType == TYPE_MYSTERY)
return UQ_4_12(1.0);
else if (gBattleStruct->pledgeMove && IS_BATTLER_OF_TYPE(BATTLE_PARTNER(battlerAtk), moveType))
return (abilityAtk == ABILITY_ADAPTABILITY) ? UQ_4_12(2.0) : UQ_4_12(1.5);
else if (!IS_BATTLER_OF_TYPE(battlerAtk, moveType) || move == MOVE_STRUGGLE || move == MOVE_NONE)
return UQ_4_12(1.0);
Expand Down
19 changes: 19 additions & 0 deletions test/battle/ability/dancer.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,22 @@ DOUBLE_BATTLE_TEST("Dancer still triggers if another dancer flinches")
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
}
}

SINGLE_BATTLE_TEST("Dancer-called attacks have their type updated")
{
GIVEN {
ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE);
ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE);
PLAYER(SPECIES_TANGROWTH);
OPPONENT(SPECIES_ORICORIO_BAILE);
} WHEN {
TURN { MOVE(player, MOVE_REVELATION_DANCE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
MESSAGE("It's not very effective…");
ABILITY_POPUP(opponent, ABILITY_DANCER);
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, opponent);
NOT MESSAGE("It's not very effective…");
MESSAGE("It's super effective!");
}
}
19 changes: 19 additions & 0 deletions test/battle/gimmick/zmove.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,3 +599,22 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Searing Sunraze Smash ignores the target's abilitie
MESSAGE("A critical hit!");
}
}

SINGLE_BATTLE_TEST("(Z-MOVE) Z-Revelation Dance always transforms into Breakneck Blitz")
{
u16 species;
PARAMETRIZE { species = SPECIES_ORICORIO_BAILE; }
PARAMETRIZE { species = SPECIES_ORICORIO_PAU; }
PARAMETRIZE { species = SPECIES_ORICORIO_POM_POM; }
PARAMETRIZE { species = SPECIES_ORICORIO_SENSU; }
GIVEN {
ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].type == TYPE_NORMAL);
PLAYER(species) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_REVELATION_DANCE, gimmick: GIMMICK_Z_MOVE); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ZMOVE_ACTIVATE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_BREAKNECK_BLITZ, player);
}
}
149 changes: 149 additions & 0 deletions test/battle/move_effect/revelation_dance.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#include "global.h"
#include "test/battle.h"

ASSUMPTIONS
{
ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE);
ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE);
ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE));
ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].effect == EFFECT_THIRD_TYPE);
ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].argument == TYPE_GRASS);
ASSUME(gMovesInfo[MOVE_ROOST].effect == EFFECT_ROOST);
}

SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 1st Type")
{
u16 speciesPlayer;
u16 speciesOpponent;

PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_POM_POM; speciesOpponent = SPECIES_DUGTRIO; }
PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_BAILE; speciesOpponent = SPECIES_BLASTOISE; }
PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_PAU; speciesOpponent = SPECIES_LIEPARD; }
PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_SENSU; speciesOpponent = SPECIES_PERSIAN; }

GIVEN {
PLAYER(speciesPlayer);
OPPONENT(speciesOpponent);
} WHEN {
TURN { MOVE(player, MOVE_REVELATION_DANCE); }
} SCENE {
if (speciesPlayer == SPECIES_ORICORIO_BAILE) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
HP_BAR(opponent);
MESSAGE("It's not very effective…");
}
else {
NONE_OF {
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
HP_BAR(opponent);
MESSAGE("It's not very effective…");
}
}
}
}

SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 2nd Type if it has no 1st type")
{
GIVEN {
PLAYER(SPECIES_ORICORIO_BAILE);
OPPONENT(SPECIES_EMPOLEON);
} WHEN {
TURN { MOVE(player, MOVE_BURN_UP); }
TURN { MOVE(player, MOVE_REVELATION_DANCE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player);
HP_BAR(opponent);
NONE_OF {
MESSAGE("It's not very effective…");
MESSAGE("It's super effective!");
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
HP_BAR(opponent);
MESSAGE("It's not very effective…");
}
}

SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 3rd Type if it has no 1st or 2nd type")
{
GIVEN {
PLAYER(SPECIES_GROWLITHE);
OPPONENT(SPECIES_TREVENANT);
} WHEN {
TURN { MOVE(player, MOVE_BURN_UP); MOVE(opponent, MOVE_FORESTS_CURSE); }
TURN { MOVE(player, MOVE_REVELATION_DANCE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player);
HP_BAR(opponent);
MESSAGE("It's super effective!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_FORESTS_CURSE, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
HP_BAR(opponent);
MESSAGE("It's not very effective…");
}
}

SINGLE_BATTLE_TEST("Revelation Dance becomes Typeless if its user is Typeless")
{
u16 speciesOpponent;

PARAMETRIZE { speciesOpponent = SPECIES_BLISSEY; }
PARAMETRIZE { speciesOpponent = SPECIES_BLASTOISE; }
PARAMETRIZE { speciesOpponent = SPECIES_CHARIZARD; }
PARAMETRIZE { speciesOpponent = SPECIES_VENUSAUR; }
PARAMETRIZE { speciesOpponent = SPECIES_GOLEM; }
PARAMETRIZE { speciesOpponent = SPECIES_AEGISLASH; }

GIVEN {
PLAYER(SPECIES_GROWLITHE);
OPPONENT(speciesOpponent);
} WHEN {
TURN { MOVE(player, MOVE_BURN_UP); }
TURN { MOVE(player, MOVE_REVELATION_DANCE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
HP_BAR(opponent);
NONE_OF {
MESSAGE("It's not very effective…");
MESSAGE("It's super effective!");
}
}
}

SINGLE_BATTLE_TEST("Revelation Dance becomes Normal type if used by a Typeless Pokemon due to Roost")
{
u16 speciesOpponent;

PARAMETRIZE { speciesOpponent = SPECIES_SABLEYE; }
PARAMETRIZE { speciesOpponent = SPECIES_AGGRON; }

ASSUME(B_ROOST_PURE_FLYING >= GEN_5);

GIVEN {
PLAYER(SPECIES_ORICORIO_BAILE) { Ability(ABILITY_DANCER); }
OPPONENT(speciesOpponent);
} WHEN {
TURN { MOVE(player, MOVE_BURN_UP); MOVE(opponent, MOVE_TACKLE); }
TURN { MOVE(player, MOVE_ROOST); MOVE(opponent, MOVE_REVELATION_DANCE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROOST, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, opponent);
HP_BAR(player);
ABILITY_POPUP(player, ABILITY_DANCER);
if (speciesOpponent == SPECIES_AGGRON) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
HP_BAR(opponent);
MESSAGE("It's not very effective…");
}
else {
NONE_OF {
ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player);
HP_BAR(opponent);
MESSAGE("It's not very effective…");
}
}
}
}

0 comments on commit 779cedd

Please sign in to comment.