Unifies dynamic move category checks (#6443)

This commit is contained in:
Alex 2025-03-19 23:06:08 +01:00 committed by GitHub
parent 4c4d043c13
commit adc2c61fe8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 72 additions and 92 deletions

View File

@ -1641,10 +1641,6 @@
callnative BS_TryTriggerStatusForm
.endm
.macro setdynamicmovecategory
callnative BS_SetDynamicMoveCategory
.endm
.macro tryupperhand failInstr:req
callnative BS_TryUpperHand
.4byte \failInstr
@ -2382,7 +2378,7 @@
callnative BS_SwapStats
.byte \stat
.endm
.macro restoresavedmove
callnative BS_RestoreSavedMove
.endm

View File

@ -840,10 +840,6 @@ BattleScript_FlingMissed:
ppreduce
goto BattleScript_MoveMissedPause
BattleScript_EffectDynamicCategory::
setdynamicmovecategory
goto BattleScript_EffectHit
BattleScript_EffectAuraWheel:: @ Aura Wheel can only be used by Morpeko
jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_FULL_BELLY, BattleScript_EffectHit
jumpifspecies BS_ATTACKER, SPECIES_MORPEKO_HANGRY, BattleScript_EffectHit

View File

@ -825,7 +825,6 @@ extern const u8 BattleScript_MoveEffectHaze[];
extern const u8 BattleScript_MoveEffectIonDeluge[];
extern const u8 BattleScript_EffectHyperspaceFury[];
extern const u8 BattleScript_EffectAuraWheel[];
extern const u8 BattleScript_EffectDynamicCategory[];
extern const u8 BattleScript_EffectNoRetreat[];
extern const u8 BattleScript_EffectTarShot[];
extern const u8 BattleScript_EffectPoltergeist[];

View File

@ -277,7 +277,8 @@ struct Pokemon *GetIllusionMonPtr(u32 battler);
void ClearIllusionMon(u32 battler);
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
bool32 ShouldGetStatBadgeBoost(u16 flagId, u32 battler);
u8 GetBattleMoveCategory(u32 moveId);
u32 GetBattleMoveCategory(u32 move);
void SetDynamicMoveCategory(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 CanFling(u32 battler);
bool32 IsTelekinesisBannedSpecies(u16 species);
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);

View File

@ -40,8 +40,8 @@ static bool32 AI_IsDoubleSpreadMove(u32 battlerAtk, u32 move)
if (moveTargetType == MOVE_TARGET_BOTH && battlerAtk == BATTLE_PARTNER(battlerDef))
continue;
if (IsBattlerAlive(battlerDef) && !IsSemiInvulnerable(battlerDef, move))
numOfTargets++;
if (IsBattlerAlive(battlerDef) && !IsSemiInvulnerable(battlerDef, move))
numOfTargets++;
}
if (numOfTargets > 1)
@ -534,28 +534,6 @@ static inline s32 GetDamageByRollType(s32 dmg, enum DamageRollType rollType)
return DmgRoll(dmg);
}
static inline void SetMoveDamageCategory(u32 battlerAtk, u32 battlerDef, u32 move)
{
switch (GetMoveEffect(move))
{
case EFFECT_PHOTON_GEYSER:
gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL);
break;
case EFFECT_SHELL_SIDE_ARM:
if (gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_PHYSICAL)
gBattleStruct->swapDamageCategory = TRUE;
break;
case EFFECT_TERA_BLAST:
if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA)
gBattleStruct->swapDamageCategory = GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL;
break;
case EFFECT_TERA_STARSTORM:
if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA && GET_BASE_SPECIES_ID(GetMonData(GetPartyBattlerData(battlerAtk), MON_DATA_SPECIES)) == SPECIES_TERAPAGOS)
gBattleStruct->swapDamageCategory = GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL;
break;
}
}
static inline s32 SetFixedMoveBasePower(u32 battlerAtk, u32 move)
{
s32 fixedBasePower = 0, n = 0;
@ -669,17 +647,17 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal
minimum *= strikeCount;
maximum *= strikeCount;
}
if (abilityAtk == ABILITY_PARENTAL_BOND
if (abilityAtk == ABILITY_PARENTAL_BOND
&& !strikeCount
&& effect != EFFECT_TRIPLE_KICK
&& effect != EFFECT_TRIPLE_KICK
&& effect != EFFECT_MULTI_HIT
&& !AI_IsDoubleSpreadMove(damageCalcData->battlerAtk, move))
{
median += median / (B_PARENTAL_BOND_DMG >= GEN_7 ? 4 : 2);
minimum += minimum / (B_PARENTAL_BOND_DMG >= GEN_7 ? 4 : 2);
maximum += maximum / (B_PARENTAL_BOND_DMG >= GEN_7 ? 4 : 2);
}
}
if (median == 0)
median = 1;
@ -742,7 +720,7 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u
SetActiveGimmick(battlerAtk, gBattleStruct->gimmick.usableGimmick[battlerAtk]);
}
SetMoveDamageCategory(battlerAtk, battlerDef, move);
SetDynamicMoveCategory(battlerAtk, battlerDef, move);
SetTypeBeforeUsingMove(move, battlerAtk);
moveType = GetBattleMoveType(move);
effectivenessMultiplier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, aiData->abilities[battlerDef], FALSE);

View File

@ -1996,9 +1996,7 @@ static void Cmd_critcalc(void)
static inline void CalculateAndSetMoveDamage(struct DamageCalculationData *damageCalcData, u32 battlerDef)
{
if (GetMoveEffect(gCurrentMove) == EFFECT_SHELL_SIDE_ARM)
gBattleStruct->swapDamageCategory = (gBattleStruct->shellSideArmCategory[gBattlerAttacker][battlerDef] != GetMoveCategory(gCurrentMove));
SetDynamicMoveCategory(gBattlerAttacker, battlerDef, gCurrentMove);
damageCalcData->battlerDef = battlerDef;
damageCalcData->isCrit = gSpecialStatuses[battlerDef].criticalHit;
gBattleStruct->moveDamage[battlerDef] = CalculateMoveDamage(damageCalcData, 0);
@ -17712,28 +17710,6 @@ void BS_AllySwitchFailChance(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_SetDynamicMoveCategory(void)
{
NATIVE_ARGS();
switch (GetMoveEffect(gCurrentMove))
{
case EFFECT_TERA_BLAST:
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA)
gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != GetMoveCategory(gCurrentMove));
break;
case EFFECT_TERA_STARSTORM:
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA && gBattleMons[gBattlerAttacker].species == SPECIES_TERAPAGOS_STELLAR)
gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != GetMoveCategory(gCurrentMove));
break;
default:
gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != GetMoveCategory(gCurrentMove));
break;
}
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_RunStatChangeItems(void)
{
NATIVE_ARGS(u8 battler);

View File

@ -11390,18 +11390,52 @@ static u32 SwapMoveDamageCategory(u32 move)
return DAMAGE_CATEGORY_PHYSICAL;
}
u8 GetBattleMoveCategory(u32 moveId)
/*
The Global States gBattleStruct->categoryOverride and gBattleStruct->swapDamageCategory
can be removed but a lot of function arguments (battlerAtk and battlerDef) have to be added for this, about 50+.
This is potentially a good change because it is less likely to cause bugs in the future.
*/
u32 GetBattleMoveCategory(u32 move)
{
if (gBattleStruct != NULL && gBattleStruct->swapDamageCategory) // Photon Geyser, Shell Side Arm, Light That Burns the Sky, Tera Blast
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)
return GetMoveCategory(moveId);
if (gMain.inBattle)
{
if (gBattleStruct->swapDamageCategory) // Photon Geyser, Shell Side Arm, Light That Burns the Sky, Tera Blast
return SwapMoveDamageCategory(move);
if (IsZMove(move) || IsMaxMove(move)) // TODO: Might be buggy depending on when this is called.
return gBattleStruct->categoryOverride;
if (IsBattleMoveStatus(move))
return DAMAGE_CATEGORY_STATUS;
}
if (IsBattleMoveStatus(moveId))
return DAMAGE_CATEGORY_STATUS;
return gTypesInfo[GetBattleMoveType(moveId)].damageCategory;
if (B_PHYSICAL_SPECIAL_SPLIT <= GEN_4)
return gTypesInfo[GetBattleMoveType(move)].damageCategory;
return GetMoveCategory(move);
}
void SetDynamicMoveCategory(u32 battlerAtk, u32 battlerDef, u32 move)
{
switch (GetMoveEffect(move))
{
case EFFECT_PHOTON_GEYSER:
gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL);
break;
case EFFECT_SHELL_SIDE_ARM:
if (gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_PHYSICAL)
gBattleStruct->swapDamageCategory = TRUE;
break;
case EFFECT_TERA_BLAST:
if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA)
gBattleStruct->swapDamageCategory = GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL;
break;
case EFFECT_TERA_STARSTORM:
if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA && GET_BASE_SPECIES_ID(GetMonData(GetPartyBattlerData(battlerAtk), MON_DATA_SPECIES)) == SPECIES_TERAPAGOS)
gBattleStruct->swapDamageCategory = GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL;
break;
default:
gBattleStruct->swapDamageCategory = FALSE;
break;
}
}
static bool32 TryRemoveScreens(u32 battler)

View File

@ -1909,7 +1909,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_PHOTON_GEYSER] =
{
.battleScript = BattleScript_EffectDynamicCategory,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 0, // TODO: Assign points
},
@ -2201,13 +2201,13 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_TERA_BLAST] =
{
.battleScript = BattleScript_EffectDynamicCategory,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 0, // TODO: Assign points
},
[EFFECT_TERA_STARSTORM] =
{
.battleScript = BattleScript_EffectDynamicCategory,
.battleScript = BattleScript_EffectHit,
.battleTvScore = 0, // TODO: Assign points
},

View File

@ -735,7 +735,7 @@ static void DoMoveRelearnerMain(void)
{
u16 moveId = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_MOVE1 + sMoveRelearnerStruct->moveSlot);
u8 originalPP = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_PP1 + sMoveRelearnerStruct->moveSlot);
StringCopy(gStringVar3, GetMoveName(moveId));
RemoveMonPPBonus(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->moveSlot);
SetMonMoveSlot(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove(), sMoveRelearnerStruct->moveSlot);

View File

@ -5295,7 +5295,7 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId)
PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gStringVar1, moves_x + 45, moves_y);
//Physical/Special/Status Category
DestroyCategoryIcon();
ShowCategoryIcon(GetBattleMoveCategory(move));
ShowCategoryIcon(GetMoveCategory(move));
//Accuracy
u32 accuracy = GetMoveAccuracy(move);
if (accuracy == 0)
@ -6158,7 +6158,7 @@ static void Task_HandleEvolutionScreenInput(u8 taskId)
u16 dexNum = SpeciesToNationalPokedexNum(targetSpecies);
if (sPokedexView->isSearchResults && sPokedexView->originalSearchSelectionNum == 0)
sPokedexView->originalSearchSelectionNum = sPokedexListItem->dexNum;
sPokedexListItem->dexNum = dexNum;
sPokedexListItem->seen = GetSetPokedexFlag(dexNum, FLAG_GET_SEEN);
sPokedexListItem->owned = GetSetPokedexFlag(dexNum, FLAG_GET_CAUGHT);

View File

@ -1720,7 +1720,7 @@ static void Task_HandleInput(u8 taskId)
PlaySE(SE_SELECT);
BeginCloseSummaryScreen(taskId);
}
else if (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES
else if (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES
|| sMonSummaryScreen->currPageIndex == PSS_PAGE_CONTEST_MOVES)
{
PlaySE(SE_SELECT);
@ -1773,7 +1773,7 @@ static u8 IncrementSkillsStatsMode(u8 mode)
sMonSummaryScreen->skillsPageMode = SUMMARY_SKILLS_MODE_EVS;
return SUMMARY_SKILLS_MODE_EVS;
}
else
else
{
sMonSummaryScreen->skillsPageMode = SUMMARY_SKILLS_MODE_IVS;
return SUMMARY_SKILLS_MODE_IVS;
@ -1956,7 +1956,7 @@ static void Task_ChangeSummaryMon(u8 taskId)
if (P_SUMMARY_SCREEN_RENAME && sMonSummaryScreen->currPageIndex == PSS_PAGE_INFO)
ShowUtilityPrompt(SUMMARY_MODE_NORMAL);
if (ShouldShowIvEvPrompt() && sMonSummaryScreen->currPageIndex == PSS_PAGE_SKILLS)
{
{
sMonSummaryScreen->skillsPageMode = SUMMARY_SKILLS_MODE_STATS;
ChangeStatLabel(SUMMARY_SKILLS_MODE_STATS);
}
@ -2108,7 +2108,7 @@ static void ChangePage(u8 taskId, s8 delta)
CreateTextPrinterTask(sMonSummaryScreen->currPageIndex);
HidePageSpecificSprites();
if (sMonSummaryScreen->currPageIndex == PSS_PAGE_SKILLS
if (sMonSummaryScreen->currPageIndex == PSS_PAGE_SKILLS
|| (sMonSummaryScreen->currPageIndex + delta) == PSS_PAGE_SKILLS)
{
struct Pokemon *mon = &sMonSummaryScreen->currentMon;
@ -2244,7 +2244,7 @@ static void SwitchToMoveSelection(u8 taskId)
{
if (ShouldShowMoveRelearner())
ClearWindowTilemap(PSS_LABEL_WINDOW_PROMPT_RELEARN);
ShowUtilityPrompt(SUMMARY_MODE_SELECT_MOVE);
}
else
@ -3774,10 +3774,10 @@ static void BufferStat(u8 *dst, u8 statIndex, u32 stat, u32 strId, u32 n)
else
txtPtr = StringCopy(dst, sTextNatureNeutral);
if (!P_SUMMARY_SCREEN_IV_EV_VALUES
if (!P_SUMMARY_SCREEN_IV_EV_VALUES
&& sMonSummaryScreen->skillsPageMode == SUMMARY_SKILLS_MODE_IVS)
StringAppend(dst, GetLetterGrade(stat));
else
else
ConvertIntToDecimalStringN(txtPtr, stat, STR_CONV_MODE_RIGHT_ALIGN, n);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(strId, dst);
@ -3791,7 +3791,7 @@ static const u8 *GetLetterGrade(u32 stat)
static const u8 gText_GradeB[] = _("B");
static const u8 gText_GradeA[] = _("A");
static const u8 gText_GradeS[] = _("S");
if (stat > 0 && stat <= 15)
return gText_GradeD;
else if (stat > 15 && stat <= 25)
@ -3833,7 +3833,7 @@ static void BufferLeftColumnIvEvStats(void)
u8 *hpIvEvString = Alloc(20);
u8 *attackIvEvString = Alloc(20);
u8 *defenseIvEvString = Alloc(20);
DynamicPlaceholderTextUtil_Reset();
BufferStat(hpIvEvString, STAT_HP, sMonSummaryScreen->summary.currentHP, 0, 7);
@ -3850,7 +3850,7 @@ static void BufferLeftColumnIvEvStats(void)
static void PrintLeftColumnStats(void)
{
int x;
if (sMonSummaryScreen->skillsPageMode == SUMMARY_SKILLS_MODE_IVS && !P_SUMMARY_SCREEN_IV_EV_VALUES)
x = GetStringRightAlignXOffset(FONT_NORMAL, gStringVar4, 46);
else
@ -3873,7 +3873,7 @@ static void BufferRightColumnStats(void)
static void PrintRightColumnStats(void)
{
int x;
if (sMonSummaryScreen->skillsPageMode == SUMMARY_SKILLS_MODE_IVS && !P_SUMMARY_SCREEN_IV_EV_VALUES)
x = GetStringRightAlignXOffset(FONT_NORMAL, gStringVar4, 20);
else