diff --git a/include/battle_main.h b/include/battle_main.h index eb0af5aa77..7e3206c554 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -80,6 +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); 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/config/pokemon.h b/include/config/pokemon.h index 89e72cec17..15db4881b5 100644 --- a/include/config/pokemon.h +++ b/include/config/pokemon.h @@ -51,7 +51,7 @@ #define P_TWO_FRAME_FRONT_SPRITES TRUE // In Pokémon Emerald, Pokémon front sprites always consist of two frames. This config can revert it to only use the first frame, as is the case in the other Gen 3 games. #define P_ONLY_OBTAINABLE_SHINIES FALSE // If TRUE, Pokémon encountered in the Battle Pyramid won't be shiny. #define P_NO_SHINIES_WITHOUT_POKEBALLS FALSE // If TRUE, Pokémon encountered when the player is out of Poké Balls won't be shiny -#define P_SHOW_DYNAMIC_TYPES FALSE // If TRUE, moves with dynamic type changes will be reflected as their current type in battle/summary screens. +#define P_SHOW_DYNAMIC_TYPES FALSE // If TRUE, all moves with dynamic type changes will be reflected as their current type in battle/summary screens instead of just select ones like in vanilla. // Learnset helper toggles #define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/teachable.py using the included JSON files based on available TMs and tutors. diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 209a40e751..afff143266 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1720,7 +1720,6 @@ static void MoveSelectionDisplayMoveType(u32 battler) { if (IsGimmickSelected(battler, GIMMICK_TERA) || GetActiveGimmick(battler) == GIMMICK_TERA) type = GetBattlerTeraType(battler); - end = StringCopy(txtPtr, gTypesInfo[type].name); } else if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_IVY_CUDGEL) { @@ -1730,32 +1729,24 @@ static void MoveSelectionDisplayMoveType(u32 battler) || speciesId == SPECIES_OGERPON_HEARTHFLAME_MASK || speciesId == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA || speciesId == SPECIES_OGERPON_CORNERSTONE_MASK || speciesId == SPECIES_OGERPON_CORNERSTONE_MASK_TERA) type = gBattleMons[battler].types[1]; - end = StringCopy(txtPtr, gTypesInfo[type].name); } - // Max Guard is a Normal-type move else if (gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].category == DAMAGE_CATEGORY_STATUS && (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX))) { - type = TYPE_NORMAL; - end = StringCopy(txtPtr, gTypesInfo[type].name); + type = TYPE_NORMAL; // Max Guard is always a Normal-type move } else if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_TERA_STARSTORM) { if (gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR || (IsGimmickSelected(battler, GIMMICK_TERA) && gBattleMons[battler].species == SPECIES_TERAPAGOS_TERASTAL)) type = TYPE_STELLAR; - end = StringCopy(txtPtr, gTypesInfo[type].name); } - else if (P_SHOW_DYNAMIC_TYPES) + else if (P_SHOW_DYNAMIC_TYPES) // Non-vanilla changes to battle UI showing dynamic types { struct Pokemon *mon = &gPlayerParty[gBattlerPartyIndexes[battler]]; type = CheckDynamicMoveType(mon, moveInfo->moves[gMoveSelectionCursor[battler]], battler); - end = StringCopy(txtPtr, gTypesInfo[type].name); - } - else - { - end = StringCopy(txtPtr, gTypesInfo[type].name); } + end = StringCopy(txtPtr, gTypesInfo[type].name); PrependFontIdToFit(txtPtr, end, FONT_NORMAL, WindowWidthPx(B_WIN_MOVE_TYPE) - 25); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_TYPE); diff --git a/src/battle_main.c b/src/battle_main.c index c77c325db2..a4c55ce9b5 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -23,6 +23,7 @@ #include "dma3.h" #include "event_data.h" #include "evolution_scene.h" +#include "field_weather.h" #include "graphics.h" #include "gpu_regs.h" #include "international_string_util.h" @@ -67,6 +68,7 @@ #include "constants/rgb.h" #include "constants/songs.h" #include "constants/trainers.h" +#include "constants/weather.h" #include "cable_club.h" extern const struct BgTemplate gBattleBgTemplates[]; @@ -5774,151 +5776,246 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) return FALSE; } -void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk) +// 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 moveType, attackerAbility; - u16 holdEffect = GetBattlerHoldEffect(battlerAtk, TRUE); + u32 moveType = gMovesInfo[move].type; + u32 moveEffect = gMovesInfo[move].effect; + u32 species, heldItem, holdEffect, ability, type1, type2, type3; if (move == MOVE_STRUGGLE) - return; + return TYPE_NORMAL; - gBattleStruct->dynamicMoveType = 0; - gBattleStruct->ateBoost[battlerAtk] = 0; - gSpecialStatuses[battlerAtk].gemBoost = FALSE; - - if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL) + if (gMain.inBattle) { - if (WEATHER_HAS_EFFECT) + species = gBattleMons[battler].species; + heldItem = gBattleMons[battler].item; + holdEffect = GetBattlerHoldEffect(battler, TRUE); + ability = GetBattlerAbility(battler); + type1 = gBattleMons[battler].types[0]; + type2 = gBattleMons[battler].types[1]; + type3 = gBattleMons[battler].types[2]; + } + else + { + species = GetMonData(mon, MON_DATA_SPECIES); + heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); + holdEffect = ItemId_GetHoldEffect(heldItem); + ability = GetMonAbility(mon); + type1 = gSpeciesInfo[species].types[0]; + type2 = gSpeciesInfo[species].types[1]; + type3 = TYPE_MYSTERY; + } + + if (moveEffect == EFFECT_WEATHER_BALL) + { + if (gMain.inBattle && WEATHER_HAS_EFFECT) { if (gBattleWeather & B_WEATHER_RAIN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA) - gBattleStruct->dynamicMoveType = TYPE_WATER | F_DYNAMIC_TYPE_SET; + return TYPE_WATER; else if (gBattleWeather & B_WEATHER_SANDSTORM) - gBattleStruct->dynamicMoveType = TYPE_ROCK | F_DYNAMIC_TYPE_SET; + return TYPE_ROCK; else if (gBattleWeather & B_WEATHER_SUN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA) - gBattleStruct->dynamicMoveType = TYPE_FIRE | F_DYNAMIC_TYPE_SET; - else if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) - gBattleStruct->dynamicMoveType = TYPE_ICE | F_DYNAMIC_TYPE_SET; + return TYPE_FIRE; + else if (gBattleWeather & (B_WEATHER_SNOW | B_WEATHER_HAIL)) + return TYPE_ICE; else - gBattleStruct->dynamicMoveType = TYPE_NORMAL | F_DYNAMIC_TYPE_SET; + return moveType; + } + else + { + switch (gWeatherPtr->currWeather) + { + case WEATHER_DROUGHT: + if (holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA) + return TYPE_FIRE; + break; + case WEATHER_RAIN: + case WEATHER_RAIN_THUNDERSTORM: + if (holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA) + return TYPE_WATER; + break; + case WEATHER_SNOW: + return TYPE_ICE; + case WEATHER_SANDSTORM: + return TYPE_ROCK; + } + return moveType; } } - else if (gMovesInfo[move].effect == EFFECT_HIDDEN_POWER) + else if (moveEffect == EFFECT_HIDDEN_POWER) { - u8 typeBits = ((gBattleMons[battlerAtk].hpIV & 1) << 0) - | ((gBattleMons[battlerAtk].attackIV & 1) << 1) - | ((gBattleMons[battlerAtk].defenseIV & 1) << 2) - | ((gBattleMons[battlerAtk].speedIV & 1) << 3) - | ((gBattleMons[battlerAtk].spAttackIV & 1) << 4) - | ((gBattleMons[battlerAtk].spDefenseIV & 1) << 5); + u8 typeBits; + if (gMain.inBattle) + { + typeBits = ((gBattleMons[battler].hpIV & 1) << 0) + | ((gBattleMons[battler].attackIV & 1) << 1) + | ((gBattleMons[battler].defenseIV & 1) << 2) + | ((gBattleMons[battler].speedIV & 1) << 3) + | ((gBattleMons[battler].spAttackIV & 1) << 4) + | ((gBattleMons[battler].spDefenseIV & 1) << 5); + } + else + { + typeBits = ((GetMonData(mon, MON_DATA_HP_IV) & 1) << 0) + | ((GetMonData(mon, MON_DATA_ATK_IV) & 1) << 1) + | ((GetMonData(mon, MON_DATA_DEF_IV) & 1) << 2) + | ((GetMonData(mon, MON_DATA_SPEED_IV) & 1) << 3) + | ((GetMonData(mon, MON_DATA_SPATK_IV) & 1) << 4) + | ((GetMonData(mon, MON_DATA_SPDEF_IV) & 1) << 5); + } // Subtract 6 instead of 1 below because 5 types are excluded (TYPE_NONE, TYPE_NORMAL, TYPE_MYSTERY, TYPE_FAIRY and TYPE_STELLAR) // The final + 2 skips past TYPE_NONE and Normal. - gBattleStruct->dynamicMoveType = ((NUMBER_OF_MON_TYPES - 6) * typeBits) / 63 + 2; - if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY) - gBattleStruct->dynamicMoveType++; - gBattleStruct->dynamicMoveType |= F_DYNAMIC_TYPE_IGNORE_PHYSICALITY | F_DYNAMIC_TYPE_SET; + moveType = ((NUMBER_OF_MON_TYPES - 6) * typeBits) / 63 + 2; + if (moveType >= TYPE_MYSTERY) + moveType++; + return (moveType | F_DYNAMIC_TYPE_IGNORE_PHYSICALITY); } - else if (gMovesInfo[move].effect == EFFECT_CHANGE_TYPE_ON_ITEM && holdEffect == gMovesInfo[move].argument) + else if (moveEffect == EFFECT_CHANGE_TYPE_ON_ITEM && holdEffect == gMovesInfo[move].argument) { - gBattleStruct->dynamicMoveType = ItemId_GetSecondaryId(gBattleMons[battlerAtk].item) | F_DYNAMIC_TYPE_SET; + return ItemId_GetSecondaryId(heldItem); } - else if (gMovesInfo[move].effect == EFFECT_REVELATION_DANCE && GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE) + else if (moveEffect == EFFECT_REVELATION_DANCE && GetActiveGimmick(battler) != GIMMICK_Z_MOVE) { - if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA && GetBattlerTeraType(battlerAtk) != TYPE_STELLAR) - gBattleStruct->dynamicMoveType = GetBattlerTeraType(battlerAtk); - 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 && !(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; + u8 teraType; + if (GetActiveGimmick(battler) == GIMMICK_TERA && ((teraType = GetMonData(mon, MON_DATA_TERA_TYPE)) != TYPE_STELLAR)) + return teraType; + else if (type1 != TYPE_MYSTERY && !(gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST && type1 == TYPE_FLYING)) + return type1; + else if (type2 != TYPE_MYSTERY && !(gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST && type2 == TYPE_FLYING)) + return type2; + else if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST) + return (B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY); + else if (type3 != TYPE_MYSTERY) + return type3; else - gBattleStruct->dynamicMoveType = TYPE_MYSTERY | F_DYNAMIC_TYPE_SET; + return TYPE_MYSTERY; } - else if (gMovesInfo[move].effect == EFFECT_RAGING_BULL - && (gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED - || gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED - || gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_AQUA_BREED)) + else if (moveEffect == EFFECT_RAGING_BULL + && (species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED + || species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED + || species == SPECIES_TAUROS_PALDEAN_AQUA_BREED)) { - gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[1] | F_DYNAMIC_TYPE_SET; + return type2; } - else if (gMovesInfo[move].effect == EFFECT_IVY_CUDGEL - && (gBattleMons[battlerAtk].species == SPECIES_OGERPON_WELLSPRING_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_WELLSPRING_MASK_TERA - || gBattleMons[battlerAtk].species == SPECIES_OGERPON_HEARTHFLAME_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA - || gBattleMons[battlerAtk].species == SPECIES_OGERPON_CORNERSTONE_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA )) + else if (moveEffect == EFFECT_IVY_CUDGEL + && (species == SPECIES_OGERPON_WELLSPRING_MASK || species == SPECIES_OGERPON_WELLSPRING_MASK_TERA + || species == SPECIES_OGERPON_HEARTHFLAME_MASK || species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA + || species == SPECIES_OGERPON_CORNERSTONE_MASK || species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA)) { - gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[1] | F_DYNAMIC_TYPE_SET; + return type2; } - else if (gMovesInfo[move].effect == EFFECT_NATURAL_GIFT) + else if (moveEffect == EFFECT_NATURAL_GIFT) { - if (ItemId_GetPocket(gBattleMons[battlerAtk].item) == POCKET_BERRIES) - gBattleStruct->dynamicMoveType = gNaturalGiftTable[ITEM_TO_BERRY(gBattleMons[battlerAtk].item)].type; + if (ItemId_GetPocket(heldItem) == POCKET_BERRIES) + return gNaturalGiftTable[ITEM_TO_BERRY(heldItem)].type; + else + return moveType; } - else if (gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE) + else if (moveEffect == EFFECT_TERRAIN_PULSE) { - if (IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_TERRAIN_ANY)) + if (gMain.inBattle) { - if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) - gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | F_DYNAMIC_TYPE_SET; - else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) - gBattleStruct->dynamicMoveType = TYPE_GRASS | F_DYNAMIC_TYPE_SET; - else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) - gBattleStruct->dynamicMoveType = TYPE_FAIRY | F_DYNAMIC_TYPE_SET; - else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) - gBattleStruct->dynamicMoveType = TYPE_PSYCHIC | F_DYNAMIC_TYPE_SET; - else //failsafe - gBattleStruct->dynamicMoveType = TYPE_NORMAL | F_DYNAMIC_TYPE_SET; + if (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY)) + { + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + return TYPE_ELECTRIC; + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + return TYPE_GRASS; + else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + return TYPE_FAIRY; + else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + return TYPE_PSYCHIC; + else //failsafe + return moveType; + } + } + else + { + switch (gWeatherPtr->currWeather) + { + case WEATHER_RAIN_THUNDERSTORM: + if (B_THUNDERSTORM_TERRAIN) + return TYPE_ELECTRIC; + break; + case WEATHER_FOG_HORIZONTAL: + case WEATHER_FOG_DIAGONAL: + if (B_OVERWORLD_FOG >= GEN_8) + return TYPE_FAIRY; + break; + } + return moveType; } } - else if (gMovesInfo[move].effect == EFFECT_TERA_BLAST && GetActiveGimmick(battlerAtk) == GIMMICK_TERA) + else if (moveEffect == EFFECT_TERA_BLAST && GetActiveGimmick(battler) == GIMMICK_TERA) { - gBattleStruct->dynamicMoveType = GetBattlerTeraType(battlerAtk) | F_DYNAMIC_TYPE_SET; + return GetMonData(mon, MON_DATA_TERA_TYPE); } - else if (gMovesInfo[move].effect == EFFECT_TERA_STARSTORM && gBattleMons[battlerAtk].species == SPECIES_TERAPAGOS_STELLAR) + else if (moveEffect == EFFECT_TERA_STARSTORM && species == SPECIES_TERAPAGOS_STELLAR) { - gBattleStruct->dynamicMoveType = TYPE_STELLAR | F_DYNAMIC_TYPE_SET; + return TYPE_STELLAR; } - attackerAbility = GetBattlerAbility(battlerAtk); - if (gMovesInfo[move].type == TYPE_NORMAL - && TrySetAteType(move, battlerAtk, attackerAbility) - && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX) + if (moveType == TYPE_NORMAL + && ((!gMain.inBattle || TrySetAteType(move, battler, ability)) + && GetActiveGimmick(battler) != GIMMICK_DYNAMAX)) { - gBattleStruct->ateBoost[battlerAtk] = 1; + if (gMain.inBattle && ateBoost != NULL) + *ateBoost = TRUE; } - else if (gMovesInfo[move].type != TYPE_NORMAL - && gMovesInfo[move].effect != EFFECT_HIDDEN_POWER - && gMovesInfo[move].effect != EFFECT_WEATHER_BALL - && attackerAbility == ABILITY_NORMALIZE - && GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE) + else if (moveType != TYPE_NORMAL + && moveEffect != EFFECT_HIDDEN_POWER + && moveEffect != EFFECT_WEATHER_BALL + && ability == ABILITY_NORMALIZE + && GetActiveGimmick(battler) != GIMMICK_Z_MOVE) { - gBattleStruct->dynamicMoveType = TYPE_NORMAL | F_DYNAMIC_TYPE_SET; - if (GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX) - gBattleStruct->ateBoost[battlerAtk] = 1; + if (gMain.inBattle && ateBoost != NULL && GetActiveGimmick(battler) != GIMMICK_DYNAMAX) + *ateBoost = TRUE; + return TYPE_NORMAL; } - else if (gMovesInfo[move].soundMove && attackerAbility == ABILITY_LIQUID_VOICE) + else if (gMovesInfo[move].soundMove && ability == ABILITY_LIQUID_VOICE) { - gBattleStruct->dynamicMoveType = TYPE_WATER | F_DYNAMIC_TYPE_SET; + return TYPE_WATER; } - else if (gMovesInfo[move].effect == EFFECT_AURA_WHEEL && gBattleMons[battlerAtk].species == SPECIES_MORPEKO_HANGRY) + else if (moveEffect == EFFECT_AURA_WHEEL && species == SPECIES_MORPEKO_HANGRY) { - gBattleStruct->dynamicMoveType = TYPE_DARK | F_DYNAMIC_TYPE_SET; + return TYPE_DARK; } + return TYPE_NONE; +} + +void SetTypeBeforeUsingMove(u32 move, u32 battler) +{ + u32 moveType; + u32 heldItem = gBattleMons[battler].item; + u32 holdEffect = GetBattlerHoldEffect(battler, TRUE); + + gBattleStruct->dynamicMoveType = 0; + gBattleStruct->ateBoost[battler] = FALSE; + gSpecialStatuses[battler].gemBoost = FALSE; + + moveType = GetDynamicMoveType(&GetBattlerParty(battler)[gBattlerPartyIndexes[battler]], + move, + battler, + &gBattleStruct->ateBoost[battler]); + if (moveType != TYPE_NONE) + gBattleStruct->dynamicMoveType = moveType | F_DYNAMIC_TYPE_SET; + moveType = GetMoveType(move); if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL) - || gStatuses4[battlerAtk] & STATUS4_ELECTRIFIED) + || gStatuses4[battler] & STATUS4_ELECTRIFIED) gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | F_DYNAMIC_TYPE_SET; // Check if a gem should activate. moveType = GetMoveType(move); if (holdEffect == HOLD_EFFECT_GEMS - && moveType == ItemId_GetSecondaryId(gBattleMons[battlerAtk].item)) + && moveType == ItemId_GetSecondaryId(heldItem)) { - gSpecialStatuses[battlerAtk].gemParam = GetBattlerHoldEffectParam(battlerAtk); - gSpecialStatuses[battlerAtk].gemBoost = TRUE; + gSpecialStatuses[battler].gemParam = GetBattlerHoldEffectParam(battler); + gSpecialStatuses[battler].gemBoost = TRUE; } } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 231afefc1f..9f649252fd 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6410,7 +6410,7 @@ static void Cmd_moveend(void) gBattleStruct->targetsDone[gBattlerAttacker] = 0; gProtectStructs[gBattlerAttacker].targetAffected = FALSE; gProtectStructs[gBattlerAttacker].shellTrap = FALSE; - gBattleStruct->ateBoost[gBattlerAttacker] = 0; + gBattleStruct->ateBoost[gBattlerAttacker] = FALSE; gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST; gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE; gSpecialStatuses[gBattlerAttacker].damagedMons = 0; diff --git a/src/pokemon.c b/src/pokemon.c index 92a50ed1aa..d76d1df58c 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -6963,172 +6963,8 @@ static inline u32 CalculateHiddenPowerType(struct Pokemon *mon) u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) { - u32 type = gMovesInfo[move].type; - u32 species = GetMonData(mon, MON_DATA_SPECIES); - u32 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); - u32 heldItemEffect = ItemId_GetHoldEffect(heldItem); - u32 ability = GetMonAbility(mon); - u32 type1 = gSpeciesInfo[species].types[0]; - u32 type2 = gSpeciesInfo[species].types[1]; - u32 effect = gMovesInfo[move].effect; - - if (effect == EFFECT_IVY_CUDGEL - && (species == SPECIES_OGERPON_WELLSPRING_MASK || species == SPECIES_OGERPON_WELLSPRING_MASK_TERA - || species == SPECIES_OGERPON_HEARTHFLAME_MASK || species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA - || species == SPECIES_OGERPON_CORNERSTONE_MASK || species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA)) - { - type = type2; - } - else if (move == MOVE_STRUGGLE) - { - return TYPE_NORMAL; - } - else if (effect == EFFECT_TERA_BLAST && GetActiveGimmick(battler) == GIMMICK_TERA && gBattleMons[battler].species == species) - { - return GetMonData(mon, MON_DATA_TERA_TYPE); - } - else if (effect == EFFECT_TERA_STARSTORM && species == SPECIES_TERAPAGOS_STELLAR) - { - return TYPE_STELLAR; - } - else if (move == MOVE_HIDDEN_POWER) - { - return CalculateHiddenPowerType(mon); - } - else if (effect == EFFECT_AURA_WHEEL && species == SPECIES_MORPEKO_HANGRY) - { - type = TYPE_DARK; - } - else if (effect == EFFECT_CHANGE_TYPE_ON_ITEM) - { - if (heldItemEffect == gMovesInfo[move].argument) - return ItemId_GetSecondaryId(heldItem); - else - return TYPE_NORMAL; - } - else if (effect == EFFECT_NATURAL_GIFT) - { - if (ItemId_GetPocket(heldItem) == POCKET_BERRIES) - return gNaturalGiftTable[ITEM_TO_BERRY(heldItem)].type; - else - return TYPE_NORMAL; - } - else if (effect == EFFECT_RAGING_BULL - && (species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED - || species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED - || species == SPECIES_TAUROS_PALDEAN_AQUA_BREED)) - { - return type2; - } - else if (effect == EFFECT_REVELATION_DANCE) - { - if (gBattleMons[battler].species != species && type1 != TYPE_MYSTERY) - type = type1; - else if (gBattleMons[battler].species != species && type2 != TYPE_MYSTERY) - type = type2; - else if (GetBattlerTeraType(battler) != TYPE_STELLAR && (GetActiveGimmick(battler) == GIMMICK_TERA || IsGimmickSelected(battler, GIMMICK_TERA))) - type = GetMonData(mon, MON_DATA_TERA_TYPE); - else if (gBattleMons[battler].types[0] != TYPE_MYSTERY) - type = gBattleMons[battler].types[0]; - else if (gBattleMons[battler].types[1] != TYPE_MYSTERY) - type = gBattleMons[battler].types[1]; - else if (gBattleMons[battler].types[2] != TYPE_MYSTERY) - type = gBattleMons[battler].types[2]; - } - else if (effect == EFFECT_TERRAIN_PULSE - && ((IsMonGrounded(heldItemEffect, ability, type1, type2) && gBattleMons[battler].species != species) - || (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY) && gBattleMons[battler].species == species))) - { - if (gMain.inBattle) - { - if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) - return TYPE_ELECTRIC; - else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) - return TYPE_GRASS; - else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) - return TYPE_FAIRY; - else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) - return TYPE_PSYCHIC; - else //failsafe - type = TYPE_NORMAL; - } - else - { - switch (gWeatherPtr->currWeather) - { - case WEATHER_RAIN_THUNDERSTORM: - if (B_THUNDERSTORM_TERRAIN) - return TYPE_ELECTRIC; - break; - case WEATHER_FOG_HORIZONTAL: - case WEATHER_FOG_DIAGONAL: - if (B_OVERWORLD_FOG >= GEN_8) - return TYPE_FAIRY; - break; - } - return TYPE_NORMAL; - } - } - - if (effect == EFFECT_WEATHER_BALL) - { - if (gMain.inBattle && WEATHER_HAS_EFFECT) - { - if (gBattleWeather & B_WEATHER_RAIN && heldItemEffect != HOLD_EFFECT_UTILITY_UMBRELLA) - return TYPE_WATER; - else if (gBattleWeather & B_WEATHER_SANDSTORM) - return TYPE_ROCK; - else if (gBattleWeather & B_WEATHER_SUN && heldItemEffect != HOLD_EFFECT_UTILITY_UMBRELLA) - return TYPE_FIRE; - else if (gBattleWeather & (B_WEATHER_SNOW | B_WEATHER_HAIL)) - return TYPE_ICE; - else - return TYPE_NORMAL; - } - else - { - switch (gWeatherPtr->currWeather) - { - case WEATHER_DROUGHT: - if (heldItem != ITEM_UTILITY_UMBRELLA) - return TYPE_FIRE; - break; - case WEATHER_RAIN: - case WEATHER_RAIN_THUNDERSTORM: - if (heldItem != ITEM_UTILITY_UMBRELLA) - return TYPE_WATER; - break; - case WEATHER_SNOW: - return TYPE_ICE; - break; - case WEATHER_SANDSTORM: - return TYPE_ROCK; - break; - } - return TYPE_NORMAL; - } - } - - if (ability == ABILITY_NORMALIZE && gMovesInfo[move].type != TYPE_NORMAL && GetActiveGimmick(battler) != GIMMICK_Z_MOVE) - type = TYPE_NORMAL; - - if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && type == TYPE_NORMAL) || gStatuses4[battler] & STATUS4_ELECTRIFIED) - type = TYPE_ELECTRIC; - - if (gMovesInfo[move].type == TYPE_NORMAL && gMovesInfo[move].category != DAMAGE_CATEGORY_STATUS) - { - switch (ability) - { - case ABILITY_PIXILATE: return TYPE_FAIRY; - case ABILITY_REFRIGERATE: return TYPE_ICE; - case ABILITY_AERILATE: return TYPE_FLYING; - case ABILITY_GALVANIZE: return TYPE_ELECTRIC; - default: break; - } - } - - if (ability == ABILITY_LIQUID_VOICE && gMovesInfo[move].soundMove == TRUE) - return TYPE_WATER; - - return type; + u32 moveType = GetDynamicMoveType(mon, move, battler, NULL); + if (moveType != TYPE_NONE) + return moveType; + return gMovesInfo[move].type; } diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index bf6ab45a2a..de0b54800b 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -3956,28 +3956,23 @@ static void SetMonTypeIcons(void) static void SetMoveTypeIcons(void) { u32 i; - u32 type; struct PokeSummary *summary = &sMonSummaryScreen->summary; struct Pokemon *mon = &sMonSummaryScreen->currentMon; + u32 type; for (i = 0; i < MAX_MON_MOVES; i++) { if (summary->moves[i] != MOVE_NONE) { + type = gMovesInfo[summary->moves[i]].type; if (P_SHOW_DYNAMIC_TYPES) - { type = CheckDynamicMoveType(mon, summary->moves[i], 0); - SetTypeSpritePosAndPal(type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); - } - else - { - SetTypeSpritePosAndPal(gMovesInfo[summary->moves[i]].type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); - } + SetTypeSpritePosAndPal(type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); } else { SetSpriteInvisibility(i + SPRITE_ARR_ID_TYPE, TRUE); - } + } } }