Cleaned up duplicate dynamic type functions (#5338)

* Cleaned up duplicated dynamic type functions

* Small cleanup

* Oops, last cleanup broke stuff

* Alignment

Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>

---------

Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
Eduardo Quezada 2024-09-08 14:14:05 -03:00 committed by GitHub
parent 8c3531ffc7
commit 6d020eb366
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 202 additions and 282 deletions

View file

@ -80,6 +80,7 @@ s32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);
void RunBattleScriptCommands_PopCallbacksStack(void); void RunBattleScriptCommands_PopCallbacksStack(void);
void RunBattleScriptCommands(void); void RunBattleScriptCommands(void);
void SpecialStatusesClear(void); void SpecialStatusesClear(void);
u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost);
void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk); void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk);
bool32 IsWildMonSmart(void); bool32 IsWildMonSmart(void);
u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags); u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags);

View file

@ -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_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_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_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 // 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. #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.

View file

@ -1720,7 +1720,6 @@ static void MoveSelectionDisplayMoveType(u32 battler)
{ {
if (IsGimmickSelected(battler, GIMMICK_TERA) || GetActiveGimmick(battler) == GIMMICK_TERA) if (IsGimmickSelected(battler, GIMMICK_TERA) || GetActiveGimmick(battler) == GIMMICK_TERA)
type = GetBattlerTeraType(battler); type = GetBattlerTeraType(battler);
end = StringCopy(txtPtr, gTypesInfo[type].name);
} }
else if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_IVY_CUDGEL) 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_HEARTHFLAME_MASK || speciesId == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA
|| speciesId == SPECIES_OGERPON_CORNERSTONE_MASK || speciesId == SPECIES_OGERPON_CORNERSTONE_MASK_TERA) || speciesId == SPECIES_OGERPON_CORNERSTONE_MASK || speciesId == SPECIES_OGERPON_CORNERSTONE_MASK_TERA)
type = gBattleMons[battler].types[1]; 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 else if (gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].category == DAMAGE_CATEGORY_STATUS
&& (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX))) && (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX)))
{ {
type = TYPE_NORMAL; type = TYPE_NORMAL; // Max Guard is always a Normal-type move
end = StringCopy(txtPtr, gTypesInfo[type].name);
} }
else if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_TERA_STARSTORM) else if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_TERA_STARSTORM)
{ {
if (gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR if (gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR
|| (IsGimmickSelected(battler, GIMMICK_TERA) && gBattleMons[battler].species == SPECIES_TERAPAGOS_TERASTAL)) || (IsGimmickSelected(battler, GIMMICK_TERA) && gBattleMons[battler].species == SPECIES_TERAPAGOS_TERASTAL))
type = TYPE_STELLAR; 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]]; struct Pokemon *mon = &gPlayerParty[gBattlerPartyIndexes[battler]];
type = CheckDynamicMoveType(mon, moveInfo->moves[gMoveSelectionCursor[battler]], 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); PrependFontIdToFit(txtPtr, end, FONT_NORMAL, WindowWidthPx(B_WIN_MOVE_TYPE) - 25);
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_TYPE); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_TYPE);

View file

@ -23,6 +23,7 @@
#include "dma3.h" #include "dma3.h"
#include "event_data.h" #include "event_data.h"
#include "evolution_scene.h" #include "evolution_scene.h"
#include "field_weather.h"
#include "graphics.h" #include "graphics.h"
#include "gpu_regs.h" #include "gpu_regs.h"
#include "international_string_util.h" #include "international_string_util.h"
@ -67,6 +68,7 @@
#include "constants/rgb.h" #include "constants/rgb.h"
#include "constants/songs.h" #include "constants/songs.h"
#include "constants/trainers.h" #include "constants/trainers.h"
#include "constants/weather.h"
#include "cable_club.h" #include "cable_club.h"
extern const struct BgTemplate gBattleBgTemplates[]; extern const struct BgTemplate gBattleBgTemplates[];
@ -5774,151 +5776,246 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility)
return FALSE; 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; u32 moveType = gMovesInfo[move].type;
u16 holdEffect = GetBattlerHoldEffect(battlerAtk, TRUE); u32 moveEffect = gMovesInfo[move].effect;
u32 species, heldItem, holdEffect, ability, type1, type2, type3;
if (move == MOVE_STRUGGLE) if (move == MOVE_STRUGGLE)
return; return TYPE_NORMAL;
gBattleStruct->dynamicMoveType = 0; if (gMain.inBattle)
gBattleStruct->ateBoost[battlerAtk] = 0;
gSpecialStatuses[battlerAtk].gemBoost = FALSE;
if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL)
{ {
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) 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) 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) else if (gBattleWeather & B_WEATHER_SUN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA)
gBattleStruct->dynamicMoveType = TYPE_FIRE | F_DYNAMIC_TYPE_SET; return TYPE_FIRE;
else if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) else if (gBattleWeather & (B_WEATHER_SNOW | B_WEATHER_HAIL))
gBattleStruct->dynamicMoveType = TYPE_ICE | F_DYNAMIC_TYPE_SET; return TYPE_ICE;
else 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) u8 typeBits;
| ((gBattleMons[battlerAtk].attackIV & 1) << 1) if (gMain.inBattle)
| ((gBattleMons[battlerAtk].defenseIV & 1) << 2) {
| ((gBattleMons[battlerAtk].speedIV & 1) << 3) typeBits = ((gBattleMons[battler].hpIV & 1) << 0)
| ((gBattleMons[battlerAtk].spAttackIV & 1) << 4) | ((gBattleMons[battler].attackIV & 1) << 1)
| ((gBattleMons[battlerAtk].spDefenseIV & 1) << 5); | ((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) // 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. // The final + 2 skips past TYPE_NONE and Normal.
gBattleStruct->dynamicMoveType = ((NUMBER_OF_MON_TYPES - 6) * typeBits) / 63 + 2; moveType = ((NUMBER_OF_MON_TYPES - 6) * typeBits) / 63 + 2;
if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY) if (moveType >= TYPE_MYSTERY)
gBattleStruct->dynamicMoveType++; moveType++;
gBattleStruct->dynamicMoveType |= F_DYNAMIC_TYPE_IGNORE_PHYSICALITY | F_DYNAMIC_TYPE_SET; 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) u8 teraType;
gBattleStruct->dynamicMoveType = GetBattlerTeraType(battlerAtk); if (GetActiveGimmick(battler) == GIMMICK_TERA && ((teraType = GetMonData(mon, MON_DATA_TERA_TYPE)) != TYPE_STELLAR))
else if (gBattleMons[battlerAtk].types[0] != TYPE_MYSTERY && !(gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST && gBattleMons[battlerAtk].types[0] == TYPE_FLYING)) return teraType;
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[0] | F_DYNAMIC_TYPE_SET; else if (type1 != TYPE_MYSTERY && !(gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST && type1 == TYPE_FLYING))
else if (gBattleMons[battlerAtk].types[1] != TYPE_MYSTERY && !(gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST && gBattleMons[battlerAtk].types[1] == TYPE_FLYING)) return type1;
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[1] | F_DYNAMIC_TYPE_SET; else if (type2 != TYPE_MYSTERY && !(gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST && type2 == TYPE_FLYING))
else if (gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST) return type2;
gBattleStruct->dynamicMoveType = (B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY) | F_DYNAMIC_TYPE_SET; else if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST)
else if (gBattleMons[battlerAtk].types[2] != TYPE_MYSTERY) return (B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY);
gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[2] | F_DYNAMIC_TYPE_SET; else if (type3 != TYPE_MYSTERY)
return type3;
else else
gBattleStruct->dynamicMoveType = TYPE_MYSTERY | F_DYNAMIC_TYPE_SET; return TYPE_MYSTERY;
} }
else if (gMovesInfo[move].effect == EFFECT_RAGING_BULL else if (moveEffect == EFFECT_RAGING_BULL
&& (gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED && (species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED
|| gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED || species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED
|| gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_AQUA_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 else if (moveEffect == EFFECT_IVY_CUDGEL
&& (gBattleMons[battlerAtk].species == SPECIES_OGERPON_WELLSPRING_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_WELLSPRING_MASK_TERA && (species == SPECIES_OGERPON_WELLSPRING_MASK || species == SPECIES_OGERPON_WELLSPRING_MASK_TERA
|| gBattleMons[battlerAtk].species == SPECIES_OGERPON_HEARTHFLAME_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA || species == SPECIES_OGERPON_HEARTHFLAME_MASK || species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA
|| gBattleMons[battlerAtk].species == SPECIES_OGERPON_CORNERSTONE_MASK || gBattleMons[battlerAtk].species == SPECIES_OGERPON_CORNERSTONE_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) if (ItemId_GetPocket(heldItem) == POCKET_BERRIES)
gBattleStruct->dynamicMoveType = gNaturalGiftTable[ITEM_TO_BERRY(gBattleMons[battlerAtk].item)].type; 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) if (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY))
gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | F_DYNAMIC_TYPE_SET; {
else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
gBattleStruct->dynamicMoveType = TYPE_GRASS | F_DYNAMIC_TYPE_SET; return TYPE_ELECTRIC;
else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN)
gBattleStruct->dynamicMoveType = TYPE_FAIRY | F_DYNAMIC_TYPE_SET; return TYPE_GRASS;
else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)
gBattleStruct->dynamicMoveType = TYPE_PSYCHIC | F_DYNAMIC_TYPE_SET; return TYPE_FAIRY;
else //failsafe else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN)
gBattleStruct->dynamicMoveType = TYPE_NORMAL | F_DYNAMIC_TYPE_SET; 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 (moveType == TYPE_NORMAL
if (gMovesInfo[move].type == TYPE_NORMAL && ((!gMain.inBattle || TrySetAteType(move, battler, ability))
&& TrySetAteType(move, battlerAtk, attackerAbility) && GetActiveGimmick(battler) != GIMMICK_DYNAMAX))
&& GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX)
{ {
gBattleStruct->ateBoost[battlerAtk] = 1; if (gMain.inBattle && ateBoost != NULL)
*ateBoost = TRUE;
} }
else if (gMovesInfo[move].type != TYPE_NORMAL else if (moveType != TYPE_NORMAL
&& gMovesInfo[move].effect != EFFECT_HIDDEN_POWER && moveEffect != EFFECT_HIDDEN_POWER
&& gMovesInfo[move].effect != EFFECT_WEATHER_BALL && moveEffect != EFFECT_WEATHER_BALL
&& attackerAbility == ABILITY_NORMALIZE && ability == ABILITY_NORMALIZE
&& GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE) && GetActiveGimmick(battler) != GIMMICK_Z_MOVE)
{ {
gBattleStruct->dynamicMoveType = TYPE_NORMAL | F_DYNAMIC_TYPE_SET; if (gMain.inBattle && ateBoost != NULL && GetActiveGimmick(battler) != GIMMICK_DYNAMAX)
if (GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX) *ateBoost = TRUE;
gBattleStruct->ateBoost[battlerAtk] = 1; 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); moveType = GetMoveType(move);
if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL) 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; gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | F_DYNAMIC_TYPE_SET;
// Check if a gem should activate. // Check if a gem should activate.
moveType = GetMoveType(move); moveType = GetMoveType(move);
if (holdEffect == HOLD_EFFECT_GEMS if (holdEffect == HOLD_EFFECT_GEMS
&& moveType == ItemId_GetSecondaryId(gBattleMons[battlerAtk].item)) && moveType == ItemId_GetSecondaryId(heldItem))
{ {
gSpecialStatuses[battlerAtk].gemParam = GetBattlerHoldEffectParam(battlerAtk); gSpecialStatuses[battler].gemParam = GetBattlerHoldEffectParam(battler);
gSpecialStatuses[battlerAtk].gemBoost = TRUE; gSpecialStatuses[battler].gemBoost = TRUE;
} }
} }

View file

@ -6410,7 +6410,7 @@ static void Cmd_moveend(void)
gBattleStruct->targetsDone[gBattlerAttacker] = 0; gBattleStruct->targetsDone[gBattlerAttacker] = 0;
gProtectStructs[gBattlerAttacker].targetAffected = FALSE; gProtectStructs[gBattlerAttacker].targetAffected = FALSE;
gProtectStructs[gBattlerAttacker].shellTrap = FALSE; gProtectStructs[gBattlerAttacker].shellTrap = FALSE;
gBattleStruct->ateBoost[gBattlerAttacker] = 0; gBattleStruct->ateBoost[gBattlerAttacker] = FALSE;
gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST; gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST;
gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE; gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE;
gSpecialStatuses[gBattlerAttacker].damagedMons = 0; gSpecialStatuses[gBattlerAttacker].damagedMons = 0;

View file

@ -6963,172 +6963,8 @@ static inline u32 CalculateHiddenPowerType(struct Pokemon *mon)
u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
{ {
u32 type = gMovesInfo[move].type; u32 moveType = GetDynamicMoveType(mon, move, battler, NULL);
u32 species = GetMonData(mon, MON_DATA_SPECIES); if (moveType != TYPE_NONE)
u32 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); return moveType;
u32 heldItemEffect = ItemId_GetHoldEffect(heldItem); return gMovesInfo[move].type;
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;
} }

View file

@ -3956,28 +3956,23 @@ static void SetMonTypeIcons(void)
static void SetMoveTypeIcons(void) static void SetMoveTypeIcons(void)
{ {
u32 i; u32 i;
u32 type;
struct PokeSummary *summary = &sMonSummaryScreen->summary; struct PokeSummary *summary = &sMonSummaryScreen->summary;
struct Pokemon *mon = &sMonSummaryScreen->currentMon; struct Pokemon *mon = &sMonSummaryScreen->currentMon;
u32 type;
for (i = 0; i < MAX_MON_MOVES; i++) for (i = 0; i < MAX_MON_MOVES; i++)
{ {
if (summary->moves[i] != MOVE_NONE) if (summary->moves[i] != MOVE_NONE)
{ {
type = gMovesInfo[summary->moves[i]].type;
if (P_SHOW_DYNAMIC_TYPES) if (P_SHOW_DYNAMIC_TYPES)
{
type = CheckDynamicMoveType(mon, summary->moves[i], 0); type = CheckDynamicMoveType(mon, summary->moves[i], 0);
SetTypeSpritePosAndPal(type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE); 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);
}
} }
else else
{ {
SetSpriteInvisibility(i + SPRITE_ARR_ID_TYPE, TRUE); SetSpriteInvisibility(i + SPRITE_ARR_ID_TYPE, TRUE);
} }
} }
} }