Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes Dancer, adds Revelation Dance interactions with Z-Move, Roost and typeless mons #5133

Merged
merged 13 commits into from
Aug 11, 2024
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 @@ -5517,6 +5517,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 @@ -6001,6 +6002,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 @@ -9877,7 +9879,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…");
}
}
}
}
Loading