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(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);

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_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.

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}
}
}
}