diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 156db2d6af..5da278110f 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -353,6 +353,7 @@ enum { EFFECT_TERA_STARSTORM, EFFECT_DRAGON_DARTS, EFFECT_GUARDIAN_OF_ALOLA, + EFFECT_SHELL_SIDE_ARM, NUM_BATTLE_MOVE_EFFECTS, }; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 6fb3a83506..54172f9193 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -541,9 +541,9 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u } if (gMovesInfo[move].effect == EFFECT_PHOTON_GEYSER) - gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) == DAMAGE_CATEGORY_PHYSICAL); - else if (move == MOVE_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_PHYSICAL) - gBattleStruct->swapDamageCategory = TRUE; + gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != gMovesInfo[gCurrentMove].category); + else if (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM) + gBattleStruct->swapDamageCategory = (gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] != gMovesInfo[gCurrentMove].category); else if (gMovesInfo[move].effect == EFFECT_NATURE_POWER) move = GetNaturePowerMove(battlerAtk); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 9907edbe86..d77e42d368 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1962,8 +1962,8 @@ static void Cmd_damagecalc(void) u8 moveType; GET_MOVE_TYPE(gCurrentMove, moveType); - if (gBattleStruct->shellSideArmCategory[gBattlerAttacker][gBattlerTarget] == DAMAGE_CATEGORY_PHYSICAL && gCurrentMove == MOVE_SHELL_SIDE_ARM) - gBattleStruct->swapDamageCategory = TRUE; + if (gMovesInfo[gCurrentMove].effect == EFFECT_SHELL_SIDE_ARM) + gBattleStruct->swapDamageCategory = (gBattleStruct->shellSideArmCategory[gBattlerAttacker][gBattlerTarget] != gMovesInfo[gCurrentMove].category); gBattleMoveDamage = CalculateMoveDamage(gCurrentMove, gBattlerAttacker, gBattlerTarget, moveType, 0, gIsCriticalHit, TRUE, TRUE); gBattlescriptCurrInstr = cmd->nextInstr; } @@ -16865,7 +16865,7 @@ void BS_SetPhotonGeyserCategory(void) NATIVE_ARGS(); if (!((gMovesInfo[gCurrentMove].effect == EFFECT_TERA_BLAST && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA) || (gMovesInfo[gCurrentMove].effect == EFFECT_TERA_STARSTORM && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA && gBattleMons[gBattlerAttacker].species == SPECIES_TERAPAGOS_STELLAR))) - gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) == DAMAGE_CATEGORY_PHYSICAL); + gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != gMovesInfo[gCurrentMove].category); gBattlescriptCurrInstr = cmd->nextInstr; } diff --git a/src/battle_util.c b/src/battle_util.c index cba5c49711..01e4c9e559 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8456,7 +8456,7 @@ bool32 IsMoveMakingContact(u32 move, u32 battlerAtk) if (!gMovesInfo[move].makesContact) { - if (move == MOVE_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][gBattlerTarget] == DAMAGE_CATEGORY_PHYSICAL) + if (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][gBattlerTarget] == DAMAGE_CATEGORY_PHYSICAL) return TRUE; else return FALSE; @@ -8496,7 +8496,8 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) // Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here. // This means extra logic is needed to handle Shell Side Arm. if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST - && (gMovesInfo[move].makesContact || (move == MOVE_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_PHYSICAL)) + && (gMovesInfo[move].makesContact + || (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_PHYSICAL)) && !gProtectStructs[battlerDef].maxGuarded) // Max Guard cannot be bypassed by Unseen Fist return FALSE; else if (gMovesInfo[move].ignoresProtect) @@ -10990,10 +10991,17 @@ bool32 ShouldGetStatBadgeBoost(u16 badgeFlag, u32 battler) return FALSE; } +static u32 SwapMoveDamageCategory(u32 move) +{ + if (gMovesInfo[move].category == DAMAGE_CATEGORY_PHYSICAL) + return DAMAGE_CATEGORY_SPECIAL; + return DAMAGE_CATEGORY_PHYSICAL; +} + u8 GetBattleMoveCategory(u32 moveId) { if (gBattleStruct != NULL && gBattleStruct->swapDamageCategory) // Photon Geyser, Shell Side Arm, Light That Burns the Sky, Tera Blast - return DAMAGE_CATEGORY_PHYSICAL; + return SwapMoveDamageCategory(moveId); if (gBattleStruct != NULL && (IsZMove(moveId) || IsMaxMove(moveId))) // TODO: Might be buggy depending on when this is called. return gBattleStruct->categoryOverride; if (B_PHYSICAL_SPECIAL_SPLIT >= GEN_4) diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index 01f717b47e..f970f0e9f7 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -2250,4 +2250,9 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleTvScore = 0, // TODO: Assign points }, + [EFFECT_SHELL_SIDE_ARM] = + { + .battleScript = BattleScript_EffectHit, + .battleTvScore = 0, // TODO: Assign points + }, }; diff --git a/src/data/moves_info.h b/src/data/moves_info.h index 78dd0f118c..280a04cd4d 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -18079,7 +18079,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Deals better of physical and\n" "special damage. May poison."), - .effect = EFFECT_HIT, // The effect is hardcoded to the move since SetShellSideArmCategory() can't be used with anything but Shell Side Arm because of the BP requirement + .effect = EFFECT_SHELL_SIDE_ARM, .power = 90, .type = TYPE_POISON, .accuracy = 100, diff --git a/test/battle/move_effect/photon_geyser.c b/test/battle/move_effect/photon_geyser.c index 3f46547ee1..986d3865aa 100644 --- a/test/battle/move_effect/photon_geyser.c +++ b/test/battle/move_effect/photon_geyser.c @@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Photon Geyser can be mirror coated if it is a special move") } } -SINGLE_BATTLE_TEST("Photon Geyser can be countered if it is a physcal move") +SINGLE_BATTLE_TEST("Photon Geyser can be countered if it is a physical move") { GIVEN { PLAYER(SPECIES_WOBBUFFET) { Attack(110); SpAttack(100); } diff --git a/test/battle/move_effect/shell_side_arm.c b/test/battle/move_effect/shell_side_arm.c index f0b3dd74dc..13458e39ae 100644 --- a/test/battle/move_effect/shell_side_arm.c +++ b/test/battle/move_effect/shell_side_arm.c @@ -31,7 +31,7 @@ SINGLE_BATTLE_TEST("Shell Side Arm can be mirror coated if it is special") } } -SINGLE_BATTLE_TEST("Shell Side Arm does not change catogory mid-turn") +SINGLE_BATTLE_TEST("Shell Side Arm does not change category mid-turn") { s16 damage[3]; @@ -56,7 +56,7 @@ SINGLE_BATTLE_TEST("Shell Side Arm does not change catogory mid-turn") } } -DOUBLE_BATTLE_TEST("Shell Side Arm is choosing it's type for each battler on the field") +DOUBLE_BATTLE_TEST("Shell Side Arm chooses its category for each battler on the field") { GIVEN { PLAYER(SPECIES_WOBBUFFET) { Speed(10); Moves(MOVE_SHELL_SIDE_ARM); }