From 8ec998abff1ed517592a656de1209b15c1a188cd Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Thu, 22 May 2025 14:07:36 +0200 Subject: [PATCH] Fixes ate type being ignored after checking summary screen (#6888) --- include/battle_main.h | 2 +- include/constants/battle.h | 6 ++++ include/pokemon.h | 3 +- src/battle_controller_player.c | 3 +- src/battle_main.c | 58 ++++++++++++++++------------------ src/pokemon.c | 6 ++-- src/pokemon_summary_screen.c | 33 +++++++++++-------- 7 files changed, 60 insertions(+), 51 deletions(-) diff --git a/include/battle_main.h b/include/battle_main.h index f78d2f78c3..544d4ea134 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -80,7 +80,7 @@ s32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves); void RunBattleScriptCommands_PopCallbacksStack(void); void RunBattleScriptCommands(void); void SpecialStatusesClear(void); -u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost); +u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, enum MonState monInBattle); void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk); bool32 IsWildMonSmart(void); u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags); diff --git a/include/constants/battle.h b/include/constants/battle.h index d7f055a81b..cfb5d05e7e 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -622,4 +622,10 @@ enum SlideMsgStates RESTORE_BATTLER_SLIDE_CONTROL, }; +enum MonState +{ + MON_IN_BATTLE, + MON_OUTSIDE_BATTLE, +}; + #endif // GUARD_CONSTANTS_BATTLE_H diff --git a/include/pokemon.h b/include/pokemon.h index c562e3af74..994197c44a 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -6,6 +6,7 @@ #include "constants/regions.h" #include "constants/region_map_sections.h" #include "constants/map_groups.h" +#include "constants/battle.h" #include "contest_effect.h" #define GET_BASE_SPECIES_ID(speciesId) (GetFormSpeciesId(speciesId, 0)) @@ -805,7 +806,7 @@ void HealPokemon(struct Pokemon *mon); void HealBoxPokemon(struct BoxPokemon *boxMon); void UpdateDaysPassedSinceFormChange(u16 days); void TrySetDayLimitToFormChange(struct Pokemon *mon); -u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler); +u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, enum MonState state); uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier); u32 GetRegionalFormByRegion(u32 species, u32 region); bool32 IsSpeciesForeignRegionalForm(u32 species, u32 currentRegion); diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index e9cdab0f32..8eac6cb304 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1714,7 +1714,6 @@ static void MoveSelectionDisplayMoveType(u32 battler) } else if (effect == EFFECT_IVY_CUDGEL) { - if (speciesId == SPECIES_OGERPON_WELLSPRING || speciesId == SPECIES_OGERPON_WELLSPRING_TERA || speciesId == SPECIES_OGERPON_HEARTHFLAME || speciesId == SPECIES_OGERPON_HEARTHFLAME_TERA || speciesId == SPECIES_OGERPON_CORNERSTONE || speciesId == SPECIES_OGERPON_CORNERSTONE_TERA) @@ -1734,7 +1733,7 @@ static void MoveSelectionDisplayMoveType(u32 battler) else if (P_SHOW_DYNAMIC_TYPES) // Non-vanilla changes to battle UI showing dynamic types { struct Pokemon *mon = &gPlayerParty[gBattlerPartyIndexes[battler]]; - type = CheckDynamicMoveType(mon, move, battler); + type = CheckDynamicMoveType(mon, move, battler, MON_IN_BATTLE); } end = StringCopy(txtPtr, gTypesInfo[type].name); diff --git a/src/battle_main.c b/src/battle_main.c index 15c30ba013..728022237a 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5771,19 +5771,19 @@ void RunBattleScriptCommands(void) gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); } -bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) +u32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) { - u32 ateType; + u32 ateType = TYPE_NONE; switch (GetMoveEffect(move)) { case EFFECT_TERA_BLAST: if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA) - return FALSE; + return ateType; break; case EFFECT_TERA_STARSTORM: if (gBattleMons[battlerAtk].species == SPECIES_TERAPAGOS_STELLAR) - return FALSE; + return ateType; break; case EFFECT_HIDDEN_POWER: case EFFECT_WEATHER_BALL: @@ -5791,10 +5791,9 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) case EFFECT_CHANGE_TYPE_ON_ITEM: case EFFECT_REVELATION_DANCE: case EFFECT_TERRAIN_PULSE: - return FALSE; + return ateType; } - ateType = TYPE_NONE; switch (attackerAbility) { case ABILITY_PIXILATE: @@ -5814,28 +5813,21 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) break; } - if (ateType != TYPE_NONE && GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE) - { - gBattleStruct->dynamicMoveType = ateType | F_DYNAMIC_TYPE_SET; - return TRUE; - } - - return FALSE; + return ateType; } // Returns TYPE_NONE if type doesn't change. -// NULL can be passed to ateBoost to avoid applying ate-ability boosts when opening the summary screen in-battle. -u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) +u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, enum MonState state) { u32 moveType = GetMoveType(move); u32 moveEffect = GetMoveEffect(move); u32 species, heldItem, holdEffect, ability, type1, type2, type3; - bool32 monInBattle = gMain.inBattle && gPartyMenu.menuType != PARTY_MENU_TYPE_IN_BATTLE; + enum Gimmick gimmick = GetActiveGimmick(battler); if (move == MOVE_STRUGGLE) return TYPE_NORMAL; - if (monInBattle) + if (state == MON_IN_BATTLE) { species = gBattleMons[battler].species; heldItem = gBattleMons[battler].item; @@ -5859,7 +5851,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) switch (moveEffect) { case EFFECT_WEATHER_BALL: - if (monInBattle) + if (state == MON_IN_BATTLE) { if (HasWeatherEffect()) { @@ -5900,7 +5892,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) case EFFECT_HIDDEN_POWER: { u32 typeBits = 0; - if (monInBattle) + if (state == MON_IN_BATTLE) { typeBits = ((gBattleMons[battler].hpIV & 1) << 0) | ((gBattleMons[battler].attackIV & 1) << 1) @@ -5935,10 +5927,10 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) return ItemId_GetSecondaryId(heldItem); break; case EFFECT_REVELATION_DANCE: - if (GetActiveGimmick(battler) != GIMMICK_Z_MOVE) + if (gimmick != GIMMICK_Z_MOVE) { u32 teraType; - if (GetActiveGimmick(battler) == GIMMICK_TERA && ((teraType = GetMonData(mon, MON_DATA_TERA_TYPE)) != TYPE_STELLAR)) + if (gimmick == GIMMICK_TERA && ((teraType = GetMonData(mon, MON_DATA_TERA_TYPE)) != TYPE_STELLAR)) return teraType; else if (type1 != TYPE_MYSTERY && !(gDisableStructs[battler].roostActive && type1 == TYPE_FLYING)) return type1; @@ -5979,7 +5971,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) else return moveType; case EFFECT_TERRAIN_PULSE: - if (monInBattle) + if (state == MON_IN_BATTLE) { if (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY)) { @@ -6013,7 +6005,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) } break; case EFFECT_TERA_BLAST: - if (GetActiveGimmick(battler) == GIMMICK_TERA) + if (gimmick == GIMMICK_TERA) return GetMonData(mon, MON_DATA_TERA_TYPE); break; case EFFECT_TERA_STARSTORM: @@ -6031,20 +6023,23 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost) return TYPE_DARK; } else if (moveType == TYPE_NORMAL - && ((!gMain.inBattle || TrySetAteType(move, battler, ability)) - && GetActiveGimmick(battler) != GIMMICK_DYNAMAX)) + && ability != ABILITY_NORMALIZE + && gimmick != GIMMICK_DYNAMAX + && gimmick != GIMMICK_Z_MOVE) { - if (gMain.inBattle && ateBoost != NULL) - *ateBoost = TRUE; + u32 ateType = TrySetAteType(move, battler, ability); + if (ateType != TYPE_NONE && state == MON_IN_BATTLE) + gBattleStruct->ateBoost[battler] = TRUE; + return ateType; } else if (moveType != TYPE_NORMAL && moveEffect != EFFECT_HIDDEN_POWER && moveEffect != EFFECT_WEATHER_BALL && ability == ABILITY_NORMALIZE - && GetActiveGimmick(battler) != GIMMICK_Z_MOVE) + && gimmick != GIMMICK_Z_MOVE) { - if (gMain.inBattle && ateBoost != NULL && GetActiveGimmick(battler) != GIMMICK_DYNAMAX) - *ateBoost = TRUE; + if (state == MON_IN_BATTLE && gimmick != GIMMICK_DYNAMAX) + gBattleStruct->ateBoost[battler] = TRUE; return TYPE_NORMAL; } @@ -6064,7 +6059,8 @@ void SetTypeBeforeUsingMove(u32 move, u32 battler) moveType = GetDynamicMoveType(&GetBattlerParty(battler)[gBattlerPartyIndexes[battler]], move, battler, - &gBattleStruct->ateBoost[battler]); + MON_IN_BATTLE); + if (moveType != TYPE_NONE) gBattleStruct->dynamicMoveType = moveType | F_DYNAMIC_TYPE_SET; diff --git a/src/pokemon.c b/src/pokemon.c index 3bd0e4dd5d..a24d08ece2 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -1170,7 +1170,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, isShiny = GET_SHINY_VALUE(value, personality) < SHINY_ODDS; } } - + if (hasFixedPersonality) personality = fixedPersonality; @@ -7005,9 +7005,9 @@ void UpdateDaysPassedSinceFormChange(u16 days) } } -u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) +u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, enum MonState state) { - u32 moveType = GetDynamicMoveType(mon, move, battler, NULL); + u32 moveType = GetDynamicMoveType(mon, move, battler, state); if (moveType != TYPE_NONE) return moveType; return GetMoveType(move); diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 3636d2f0ae..d34b0dd40d 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -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 @@ -4306,7 +4306,11 @@ static void SetMoveTypeIcons(void) { type = GetMoveType(summary->moves[i]); if (P_SHOW_DYNAMIC_TYPES) - type = CheckDynamicMoveType(mon, summary->moves[i], 0); + { + enum MonState state = gMain.inBattle ? MON_IN_BATTLE : MON_OUTSIDE_BATTLE; + type = CheckDynamicMoveType(mon, sMonSummaryScreen->newMove, 0, state); // Bug: in battle, this only shows the dynamic type of battler in position 0 + } + SetTypeSpritePosAndPal(type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); } else @@ -4335,7 +4339,10 @@ static void SetNewMoveTypeIcon(void) struct Pokemon *mon = &sMonSummaryScreen->currentMon; if (P_SHOW_DYNAMIC_TYPES) - type = CheckDynamicMoveType(mon, sMonSummaryScreen->newMove, 0); + { + enum MonState state = gMain.inBattle ? MON_IN_BATTLE : MON_OUTSIDE_BATTLE; + type = CheckDynamicMoveType(mon, sMonSummaryScreen->newMove, 0, state); // Bug: in battle, this only shows the dynamic type of battler in position 0 + } if (sMonSummaryScreen->newMove == MOVE_NONE) {