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 Shell Side Arm #4753

Merged
merged 7 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions asm/macros/battle_script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1637,11 +1637,11 @@
.macro trygulpmissile
callnative BS_TryGulpMissile
.endm

.macro tryactivategulpmissile
callnative BS_TryActivateGulpMissile
.endm

.macro tryquash failInstr:req
callnative BS_TryQuash
.4byte \failInstr
Expand Down Expand Up @@ -2211,10 +2211,6 @@
.4byte \failInstr
.endm

.macro shellsidearmcheck
various BS_ATTACKER, VARIOUS_SHELL_SIDE_ARM_CHECK
.endm

.macro jumpifteanoberry jumpInstr:req
various BS_ATTACKER, VARIOUS_TEATIME_TARGETS
.4byte \jumpInstr
Expand Down
4 changes: 0 additions & 4 deletions data/battle_scripts_1.s
Original file line number Diff line number Diff line change
Expand Up @@ -719,10 +719,6 @@ BattleScript_FlingMissed:
ppreduce
goto BattleScript_MoveMissedPause

BattleScript_EffectShellSideArm::
shellsidearmcheck
goto BattleScript_EffectHit

BattleScript_EffectPhotonGeyser::
setphotongeysercategory
goto BattleScript_EffectHit
Expand Down
1 change: 1 addition & 0 deletions include/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ struct BattleStruct
u8 supremeOverlordCounter[MAX_BATTLERS_COUNT];
u8 quickClawRandom[MAX_BATTLERS_COUNT];
u8 quickDrawRandom[MAX_BATTLERS_COUNT];
u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT];
};

// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
Expand Down
1 change: 0 additions & 1 deletion include/battle_scripts.h
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,6 @@ extern const u8 BattleScript_EffectPlasmaFists[];
extern const u8 BattleScript_EffectHyperspaceFury[];
extern const u8 BattleScript_EffectAuraWheel[];
extern const u8 BattleScript_EffectPhotonGeyser[];
extern const u8 BattleScript_EffectShellSideArm[];
extern const u8 BattleScript_EffectNoRetreat[];
extern const u8 BattleScript_EffectTarShot[];
extern const u8 BattleScript_EffectPoltergeist[];
Expand Down
3 changes: 2 additions & 1 deletion include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ u32 IsAbilityOnOpposingSide(u32 battler, u32 ability);
u32 IsAbilityOnField(u32 ability);
u32 IsAbilityOnFieldExcept(u32 battler, u32 ability);
u32 IsAbilityPreventingEscape(u32 battler);
bool32 IsBattlerProtected(u32 battler, u32 move);
bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 CanBattlerEscape(u32 battler); // no ability check
void BattleScriptExecute(const u8 *BS_ptr);
void BattleScriptPushCursorAndCallback(const u8 *BS_ptr);
Expand Down Expand Up @@ -206,6 +206,7 @@ bool32 IsBelchPreventingMove(u32 battler, u32 move);
bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId);
bool32 IsPartnerMonFromSameTrainer(u32 battler);
u8 GetCategoryBasedOnStats(u32 battler);
void SetShellSideArmCategory(void);
bool32 MoveIsAffectedBySheerForce(u32 move);
bool32 TestIfSheerForceAffected(u32 battler, u16 move);
void TryRestoreHeldItems(void);
Expand Down
1 change: 0 additions & 1 deletion include/constants/battle_move_effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,6 @@ enum {
EFFECT_HYPERSPACE_FURY,
EFFECT_AURA_WHEEL,
EFFECT_PHOTON_GEYSER,
EFFECT_SHELL_SIDE_ARM,
EFFECT_TERRAIN_PULSE,
EFFECT_NO_RETREAT,
EFFECT_TAR_SHOT,
Expand Down
57 changes: 28 additions & 29 deletions include/constants/battle_script_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,35 +208,34 @@
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 116
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 117
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 118
#define VARIOUS_SHELL_SIDE_ARM_CHECK 119
#define VARIOUS_TRY_NO_RETREAT 120
#define VARIOUS_TRY_TAR_SHOT 121
#define VARIOUS_CAN_TAR_SHOT_WORK 122
#define VARIOUS_CHECK_POLTERGEIST 123
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 124
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 125
#define VARIOUS_JUMP_IF_UNDER_200 126
#define VARIOUS_SET_SKY_DROP 127
#define VARIOUS_CLEAR_SKY_DROP 128
#define VARIOUS_SKY_DROP_YAWN 129
#define VARIOUS_CURE_CERTAIN_STATUSES 130
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 131
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 132
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 133
#define VARIOUS_SAVE_BATTLER_ITEM 134
#define VARIOUS_RESTORE_BATTLER_ITEM 135
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 136
#define VARIOUS_SET_BEAK_BLAST 137
#define VARIOUS_SWAP_SIDE_STATUSES 138
#define VARIOUS_SWAP_STATS 139
#define VARIOUS_TEATIME_INVUL 140
#define VARIOUS_TEATIME_TARGETS 141
#define VARIOUS_TRY_WIND_RIDER_POWER 142
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 143
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 144
#define VARIOUS_STORE_HEALING_WISH 145
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 146
#define VARIOUS_TRY_REVIVAL_BLESSING 147
#define VARIOUS_TRY_NO_RETREAT 119
#define VARIOUS_TRY_TAR_SHOT 120
#define VARIOUS_CAN_TAR_SHOT_WORK 121
#define VARIOUS_CHECK_POLTERGEIST 122
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 123
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 124
#define VARIOUS_JUMP_IF_UNDER_200 125
#define VARIOUS_SET_SKY_DROP 126
#define VARIOUS_CLEAR_SKY_DROP 127
#define VARIOUS_SKY_DROP_YAWN 128
#define VARIOUS_CURE_CERTAIN_STATUSES 129
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 130
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 131
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 132
#define VARIOUS_SAVE_BATTLER_ITEM 133
#define VARIOUS_RESTORE_BATTLER_ITEM 134
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 135
#define VARIOUS_SET_BEAK_BLAST 136
#define VARIOUS_SWAP_SIDE_STATUSES 137
#define VARIOUS_SWAP_STATS 138
#define VARIOUS_TEATIME_INVUL 139
#define VARIOUS_TEATIME_TARGETS 140
#define VARIOUS_TRY_WIND_RIDER_POWER 141
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 142
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 143
#define VARIOUS_STORE_HEALING_WISH 144
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 145
#define VARIOUS_TRY_REVIVAL_BLESSING 146

// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0
Expand Down
1 change: 1 addition & 0 deletions include/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ enum RandomTag
RNG_TRACE,
RNG_FICKLE_BEAM,
RNG_AI_ABILITY,
RNG_SHELL_SIDE_ARM,
};

#define RandomWeighted(tag, ...) \
Expand Down
5 changes: 3 additions & 2 deletions src/battle_ai_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,9 @@ s32 AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u8 *typeEffectivenes
}
else if (gMovesInfo[move].effect == EFFECT_PHOTON_GEYSER)
gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) == DAMAGE_CATEGORY_PHYSICAL);

if (gMovesInfo[move].effect == EFFECT_NATURE_POWER)
else if (move == MOVE_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_SPECIAL)
gBattleStruct->swapDamageCategory = TRUE;
else if (gMovesInfo[move].effect == EFFECT_NATURE_POWER)
move = GetNaturePowerMove();

gBattleStruct->dynamicMoveType = 0;
Expand Down
8 changes: 5 additions & 3 deletions src/battle_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3677,8 +3677,8 @@ const u8* FaintClearSetData(u32 battler)
gBattleStruct->zmove.toBeUsed[battler] = MOVE_NONE;
gBattleStruct->zmove.effect = EFFECT_HIT;
// Clear Dynamax data
UndoDynamax(battler);
UndoDynamax(battler);

return result;
}

Expand Down Expand Up @@ -4162,6 +4162,7 @@ static void TryDoEventsBeforeFirstTurn(void)

memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts)); // erase all totem boosts just to be safe

SetShellSideArmCategory();
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers

if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
Expand Down Expand Up @@ -4254,6 +4255,7 @@ void BattleTurnPassed(void)

*(&gBattleStruct->absentBattlerFlags) = gAbsentBattlerFlags;
BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG);
SetShellSideArmCategory();
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
gBattleMainFunc = HandleTurnActionSelectionState;

Expand Down Expand Up @@ -5835,7 +5837,7 @@ static void TryEvolvePokemon(void)
sTriedEvolving |= gBitTable[i];

if (species == SPECIES_NONE && (gLeveledUpInBattle & gBitTable[i]))
{
{
gLeveledUpInBattle &= ~(gBitTable[i]);
species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_ONLY, gLeveledUpInBattle, NULL);
}
Expand Down
56 changes: 10 additions & 46 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ static void Cmd_attackcanceler(void)
gBattlescriptCurrInstr = BattleScript_TookAttack;
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
}
else if (IsBattlerProtected(gBattlerTarget, gCurrentMove)
else if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove)
&& (gCurrentMove != MOVE_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
&& (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
&& gMovesInfo[gCurrentMove].effect != EFFECT_SUCKER_PUNCH
Expand Down Expand Up @@ -1535,7 +1535,7 @@ static void Cmd_unused5(void)
{
CMD_ARGS(const u8 *failInstr);

if (IsBattlerProtected(gBattlerTarget, gCurrentMove))
if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove))
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
JumpIfMoveFailed(sizeof(*cmd), MOVE_NONE);
Expand All @@ -1550,7 +1550,7 @@ static void Cmd_unused5(void)
static bool8 JumpIfMoveAffectedByProtect(u16 move)
{
bool8 affected = FALSE;
if (IsBattlerProtected(gBattlerTarget, move))
if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, move))
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
JumpIfMoveFailed(7, move);
Expand Down Expand Up @@ -2009,6 +2009,8 @@ static void Cmd_damagecalc(void)
u8 moveType;

GET_MOVE_TYPE(gCurrentMove, moveType);
if (gBattleStruct->shellSideArmCategory[gBattlerAttacker][gBattlerTarget] == DAMAGE_CATEGORY_SPECIAL && gCurrentMove == MOVE_SHELL_SIDE_ARM)
gBattleStruct->swapDamageCategory = TRUE;
gBattleMoveDamage = CalculateMoveDamage(gCurrentMove, gBattlerAttacker, gBattlerTarget, moveType, 0, gIsCriticalHit, TRUE, TRUE);
gBattlescriptCurrInstr = cmd->nextInstr;
}
Expand Down Expand Up @@ -2106,7 +2108,7 @@ static void Cmd_adjustdamage(void)
gLastUsedItem = gBattleMons[gBattlerTarget].item;
gSpecialStatuses[gBattlerTarget].focusBanded = FALSE;
gSpecialStatuses[gBattlerTarget].focusSashed = FALSE;

}
AlexOn1ine marked this conversation as resolved.
Show resolved Hide resolved
else if (gSpecialStatuses[gBattlerTarget].sturdied)
{
Expand Down Expand Up @@ -3225,8 +3227,8 @@ void SetMoveEffect(bool32 primary, bool32 certain)
{
gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[gBattleScripting.moveEffect];
gBattlescriptCurrInstr++;
}
else
}
else
{
gBattlescriptCurrInstr++;
}
Expand Down Expand Up @@ -6285,7 +6287,7 @@ static void Cmd_moveend(void)
break;
}
}

if (!(gBattleStruct->lastMoveFailed & gBitTable[gBattlerAttacker]
|| (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove
&& gBattleStruct->bouncedMoveIsUsed)))
Expand Down Expand Up @@ -10487,44 +10489,6 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_SHELL_SIDE_ARM_CHECK: // 0% chance GameFreak actually checks this way according to DaWobblefet, but this is the only functional explanation at the moment
{
VARIOUS_ARGS();

u32 attackerAtkStat = gBattleMons[gBattlerAttacker].attack;
u32 targetDefStat = gBattleMons[gBattlerTarget].defense;
u32 attackerSpAtkStat = gBattleMons[gBattlerAttacker].spAttack;
u32 targetSpDefStat = gBattleMons[gBattlerTarget].spDefense;
u8 statStage;
u32 physical;
u32 special;

gBattleStruct->swapDamageCategory = FALSE;

statStage = gBattleMons[gBattlerAttacker].statStages[STAT_ATK];
attackerAtkStat *= gStatStageRatios[statStage][0];
attackerAtkStat /= gStatStageRatios[statStage][1];

statStage = gBattleMons[gBattlerTarget].statStages[STAT_DEF];
targetDefStat *= gStatStageRatios[statStage][0];
targetDefStat /= gStatStageRatios[statStage][1];

physical = ((((2 * gBattleMons[gBattlerAttacker].level / 5 + 2) * gMovesInfo[gCurrentMove].power * attackerAtkStat) / targetDefStat) / 50);

statStage = gBattleMons[gBattlerAttacker].statStages[STAT_SPATK];
attackerSpAtkStat *= gStatStageRatios[statStage][0];
attackerSpAtkStat /= gStatStageRatios[statStage][1];

statStage = gBattleMons[gBattlerTarget].statStages[STAT_SPDEF];
targetSpDefStat *= gStatStageRatios[statStage][0];
targetSpDefStat /= gStatStageRatios[statStage][1];

special = ((((2 * gBattleMons[gBattlerAttacker].level / 5 + 2) * gMovesInfo[gCurrentMove].power * attackerSpAtkStat) / targetSpDefStat) / 50);

if (((physical > special) || (physical == special && (Random() % 2) == 0)))
gBattleStruct->swapDamageCategory = TRUE;
break;
}
case VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED:
{
VARIOUS_ARGS(const u8 *jumpInstr);
Expand Down Expand Up @@ -13903,7 +13867,7 @@ static void Cmd_trymemento(void)
if (B_MEMENTO_FAIL >= GEN_4
&& (gBattleCommunication[MISS_TYPE] == B_MSG_PROTECTED
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE
|| IsBattlerProtected(gBattlerTarget, gCurrentMove)
|| IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove)
|| DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)))
{
// Failed, target was protected.
Expand Down
Loading
Loading