even more reordering

This commit is contained in:
cawtds 2024-06-17 23:24:23 +02:00
parent c179516bb7
commit bfb697c8f1

View File

@ -1238,6 +1238,24 @@ u8 GetImprisonedMovesCount(u8 battlerId, u16 move)
return imprisonedMoves;
}
u32 GetBattlerAffectionHearts(u32 battler)
{
u8 side = GetBattlerSide(battler);
struct Pokemon *party = GetSideParty(side);
u16 species = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
if (side != B_SIDE_PLAYER)
return AFFECTION_NO_HEARTS;
else if (gSpeciesInfo[species].isMegaEvolution
|| (gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_BATTLE_TOWER
| BATTLE_TYPE_RECORDED_LINK
| BATTLE_TYPE_LINK)))
return AFFECTION_NO_HEARTS;
return GetMonAffectionHearts(&party[gBattlerPartyIndexes[battler]]);
}
static void TryToRevertMimicryAndFlags(void)
{
u32 i;
@ -3385,6 +3403,62 @@ bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2
}
}
static const u16 sWeatherFlagsInfo[][3] =
{
[ENUM_WEATHER_RAIN] = {B_WEATHER_RAIN_TEMPORARY, B_WEATHER_RAIN_PERMANENT, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_RAIN_PRIMAL] = {B_WEATHER_RAIN_PRIMAL, B_WEATHER_RAIN_PRIMAL, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_SUN] = {B_WEATHER_SUN_TEMPORARY, B_WEATHER_SUN_PERMANENT, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SUN_PRIMAL] = {B_WEATHER_SUN_PRIMAL, B_WEATHER_SUN_PRIMAL, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SANDSTORM] = {B_WEATHER_SANDSTORM_TEMPORARY, B_WEATHER_SANDSTORM_PERMANENT, HOLD_EFFECT_SMOOTH_ROCK},
[ENUM_WEATHER_HAIL] = {B_WEATHER_HAIL_TEMPORARY, B_WEATHER_HAIL_PERMANENT, HOLD_EFFECT_ICY_ROCK},
[ENUM_WEATHER_STRONG_WINDS] = {B_WEATHER_STRONG_WINDS, B_WEATHER_STRONG_WINDS, HOLD_EFFECT_NONE},
[ENUM_WEATHER_SNOW] = {B_WEATHER_SNOW_TEMPORARY, B_WEATHER_SNOW_PERMANENT, HOLD_EFFECT_ICY_ROCK},
};
static void ShouldChangeFormInWeather(u32 battler)
{
int i;
int side = GetBattlerSide(battler);
struct Pokemon *party = GetSideParty(side);
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_EISCUE_NOICE_FACE)
gBattleStruct->allowedToChangeFormInWeather[i][side] = TRUE;
else
gBattleStruct->allowedToChangeFormInWeather[i][side] = FALSE;
}
}
bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility)
{
u16 battlerAbility = GetBattlerAbility(battler);
if (gBattleWeather & B_WEATHER_PRIMAL_ANY
&& battlerAbility != ABILITY_DESOLATE_LAND
&& battlerAbility != ABILITY_PRIMORDIAL_SEA
&& battlerAbility != ABILITY_DELTA_STREAM)
{
return FALSE;
}
else if (B_ABILITY_WEATHER < GEN_6 && viaAbility && !(gBattleWeather & sWeatherFlagsInfo[weatherEnumId][1]))
{
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]);
ShouldChangeFormInWeather(battler);
return TRUE;
}
else if (!(gBattleWeather & (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1])))
{
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0]);
if (GetBattlerHoldEffect(battler, TRUE) == sWeatherFlagsInfo[weatherEnumId][2])
gWishFutureKnock.weatherDuration = 8;
else
gWishFutureKnock.weatherDuration = 5;
ShouldChangeFormInWeather(battler);
return TRUE;
}
return FALSE;
}
static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer)
{
if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle)))
@ -6059,6 +6133,30 @@ static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
return 0;
}
u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute)
{
if (gFieldStatuses & terrainFlag && CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
{
BufferStatChange(battler, statId, STRINGID_STATROSE);
gLastUsedItem = itemId; // For surge abilities
gEffectBattler = gBattleScripting.battler = battler;
SET_STATCHANGER(statId, 1, FALSE);
gBattleScripting.animArg1 = 14 + statId;
gBattleScripting.animArg2 = 0;
if (execute)
{
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryStatRaiseRet;
}
return ITEM_STATS_CHANGE;
}
return 0;
}
static u32 ItemRestorePp(u32 battler, u32 itemId, bool32 execute)
{
struct Pokemon *party = GetBattlerParty(battler);
@ -7615,6 +7713,123 @@ static bool32 IsBattlerModernFatefulEncounter(u8 battlerId)
return GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_MODERN_FATEFUL_ENCOUNTER, NULL);
}
u8 IsMonDisobedient(void)
{
s32 rnd;
s32 calc;
u8 obedienceLevel = 0;
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
return 0;
if (BattlerHasAi(gBattlerAttacker))
return 0;
if ((gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_POKEDUDE)))
return 0;
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT)
return 0; // TODO: might not be reached? remove?
if (IsBattlerModernFatefulEncounter(gBattlerAttacker)) // only false if illegal Mew or Deoxys
{
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
return 0;
if (!IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
return 0;
if (FlagGet(FLAG_BADGE08_GET))
return 0;
obedienceLevel = 10;
if (FlagGet(FLAG_BADGE02_GET))
obedienceLevel = 30;
if (FlagGet(FLAG_BADGE04_GET))
obedienceLevel = 50;
if (FlagGet(FLAG_BADGE06_GET))
obedienceLevel = 70;
}
if (gBattleMons[gBattlerAttacker].level <= obedienceLevel)
return 0;
rnd = (Random() & 255);
calc = (gBattleMons[gBattlerAttacker].level + obedienceLevel) * rnd >> 8;
if (calc < obedienceLevel)
return 0;
// is not obedient
if (gCurrentMove == MOVE_RAGE)
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE;
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK))
{
gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep;
return 1;
}
rnd = (Random() & 255);
calc = (gBattleMons[gBattlerAttacker].level + obedienceLevel) * rnd >> 8;
if (calc < obedienceLevel && gCurrentMove != MOVE_FOCUS_PUNCH) // Additional check for focus punch in FR
{
calc = CheckMoveLimitations(gBattlerAttacker, gBitTable[gCurrMovePos], MOVE_LIMITATIONS_ALL);
if (calc == 0xF) // all moves cannot be used
{
// Randomly select, then print a disobedient string
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
gBattleCommunication[MULTISTRING_CHOOSER] = Random() & (NUM_LOAF_STRINGS - 1);
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAroundMsg;
return 1;
}
else // use a random move
{
do
{
gCurrMovePos = gChosenMovePos = Random() & (MAX_MON_MOVES - 1);
} while (gBitTable[gCurrMovePos] & calc);
gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
return 2;
}
}
else
{
obedienceLevel = gBattleMons[gBattlerAttacker].level - obedienceLevel;
calc = (Random() & 255);
if (calc < obedienceLevel && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) && gBattleMons[gBattlerAttacker].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gBattlerAttacker].ability != ABILITY_INSOMNIA)
{
// try putting asleep
int i;
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].status2 & STATUS2_UPROAR)
break;
}
if (i == gBattlersCount)
{
gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep;
return 1;
}
}
calc -= obedienceLevel;
if (calc < obedienceLevel)
{
gBattleMoveDamage = CalculateMoveDamage(MOVE_NONE, gBattlerAttacker, gBattlerAttacker, TYPE_MYSTERY, 40, FALSE, FALSE, TRUE);
gBattlerTarget = gBattlerAttacker;
gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
return 2;
}
else
{
// Randomly select, then print a disobedient string
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
gBattleCommunication[MULTISTRING_CHOOSER] = Random() & (NUM_LOAF_STRINGS - 1);
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAroundMsg;
return 1;
}
}
}
bool32 TryPrimalReversion(u32 battler)
{
if (GetBattlerHoldEffect(battler, FALSE) == HOLD_EFFECT_PRIMAL_ORB
@ -7874,6 +8089,22 @@ bool32 CanBattlerEscape(u32 battler) // no ability check
return TRUE;
}
static u32 GetBattlerItemHoldEffectParam(u32 battler, u32 item)
{
if (item == ITEM_ENIGMA_BERRY_E_READER)
return gEnigmaBerries[battler].holdEffectParam;
else
return ItemId_GetHoldEffectParam(item);
}
u32 GetBattlerHoldEffectParam(u32 battler)
{
if (gBattleMons[battler].item == ITEM_ENIGMA_BERRY_E_READER)
return gEnigmaBerries[battler].holdEffectParam;
else
return ItemId_GetHoldEffectParam(gBattleMons[battler].item);
}
bool32 IsMoveMakingContact(u32 move, u32 battlerAtk)
{
u32 atkHoldEffect = GetBattlerHoldEffect(battlerAtk, TRUE);
@ -10019,236 +10250,6 @@ bool32 CanUltraBurst(u32 battler)
return FALSE;
}
u32 GetBattlerHoldEffectParam(u32 battler)
{
if (gBattleMons[battler].item == ITEM_ENIGMA_BERRY_E_READER)
return gEnigmaBerries[battler].holdEffectParam;
else
return ItemId_GetHoldEffectParam(gBattleMons[battler].item);
}
u8 IsMonDisobedient(void)
{
s32 rnd;
s32 calc;
u8 obedienceLevel = 0;
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
return 0;
if (BattlerHasAi(gBattlerAttacker))
return 0;
if ((gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_POKEDUDE)))
return 0;
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT)
return 0; // TODO: might not be reached? remove?
if (IsBattlerModernFatefulEncounter(gBattlerAttacker)) // only false if illegal Mew or Deoxys
{
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
return 0;
if (!IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
return 0;
if (FlagGet(FLAG_BADGE08_GET))
return 0;
obedienceLevel = 10;
if (FlagGet(FLAG_BADGE02_GET))
obedienceLevel = 30;
if (FlagGet(FLAG_BADGE04_GET))
obedienceLevel = 50;
if (FlagGet(FLAG_BADGE06_GET))
obedienceLevel = 70;
}
if (gBattleMons[gBattlerAttacker].level <= obedienceLevel)
return 0;
rnd = (Random() & 255);
calc = (gBattleMons[gBattlerAttacker].level + obedienceLevel) * rnd >> 8;
if (calc < obedienceLevel)
return 0;
// is not obedient
if (gCurrentMove == MOVE_RAGE)
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE;
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK))
{
gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep;
return 1;
}
rnd = (Random() & 255);
calc = (gBattleMons[gBattlerAttacker].level + obedienceLevel) * rnd >> 8;
if (calc < obedienceLevel && gCurrentMove != MOVE_FOCUS_PUNCH) // Additional check for focus punch in FR
{
calc = CheckMoveLimitations(gBattlerAttacker, gBitTable[gCurrMovePos], MOVE_LIMITATIONS_ALL);
if (calc == 0xF) // all moves cannot be used
{
// Randomly select, then print a disobedient string
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
gBattleCommunication[MULTISTRING_CHOOSER] = Random() & (NUM_LOAF_STRINGS - 1);
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAroundMsg;
return 1;
}
else // use a random move
{
do
{
gCurrMovePos = gChosenMovePos = Random() & (MAX_MON_MOVES - 1);
} while (gBitTable[gCurrMovePos] & calc);
gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
return 2;
}
}
else
{
obedienceLevel = gBattleMons[gBattlerAttacker].level - obedienceLevel;
calc = (Random() & 255);
if (calc < obedienceLevel && !(gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY) && gBattleMons[gBattlerAttacker].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gBattlerAttacker].ability != ABILITY_INSOMNIA)
{
// try putting asleep
int i;
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].status2 & STATUS2_UPROAR)
break;
}
if (i == gBattlersCount)
{
gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep;
return 1;
}
}
calc -= obedienceLevel;
if (calc < obedienceLevel)
{
gBattleMoveDamage = CalculateMoveDamage(MOVE_NONE, gBattlerAttacker, gBattlerAttacker, TYPE_MYSTERY, 40, FALSE, FALSE, TRUE);
gBattlerTarget = gBattlerAttacker;
gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
return 2;
}
else
{
// Randomly select, then print a disobedient string
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
gBattleCommunication[MULTISTRING_CHOOSER] = Random() & (NUM_LOAF_STRINGS - 1);
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAroundMsg;
return 1;
}
}
}
u32 GetBattlerAffectionHearts(u32 battler)
{
u8 side = GetBattlerSide(battler);
struct Pokemon *party = GetSideParty(side);
u16 species = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
if (side != B_SIDE_PLAYER)
return AFFECTION_NO_HEARTS;
else if (gSpeciesInfo[species].isMegaEvolution
|| (gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_BATTLE_TOWER
| BATTLE_TYPE_RECORDED_LINK
| BATTLE_TYPE_LINK)))
return AFFECTION_NO_HEARTS;
return GetMonAffectionHearts(&party[gBattlerPartyIndexes[battler]]);
}
static const u16 sWeatherFlagsInfo[][3] =
{
[ENUM_WEATHER_RAIN] = {B_WEATHER_RAIN_TEMPORARY, B_WEATHER_RAIN_PERMANENT, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_RAIN_PRIMAL] = {B_WEATHER_RAIN_PRIMAL, B_WEATHER_RAIN_PRIMAL, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_SUN] = {B_WEATHER_SUN_TEMPORARY, B_WEATHER_SUN_PERMANENT, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SUN_PRIMAL] = {B_WEATHER_SUN_PRIMAL, B_WEATHER_SUN_PRIMAL, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SANDSTORM] = {B_WEATHER_SANDSTORM_TEMPORARY, B_WEATHER_SANDSTORM_PERMANENT, HOLD_EFFECT_SMOOTH_ROCK},
[ENUM_WEATHER_HAIL] = {B_WEATHER_HAIL_TEMPORARY, B_WEATHER_HAIL_PERMANENT, HOLD_EFFECT_ICY_ROCK},
[ENUM_WEATHER_STRONG_WINDS] = {B_WEATHER_STRONG_WINDS, B_WEATHER_STRONG_WINDS, HOLD_EFFECT_NONE},
[ENUM_WEATHER_SNOW] = {B_WEATHER_SNOW_TEMPORARY, B_WEATHER_SNOW_PERMANENT, HOLD_EFFECT_ICY_ROCK},
};
static void ShouldChangeFormInWeather(u32 battler)
{
int i;
int side = GetBattlerSide(battler);
struct Pokemon *party = GetSideParty(side);
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_EISCUE_NOICE_FACE)
gBattleStruct->allowedToChangeFormInWeather[i][side] = TRUE;
else
gBattleStruct->allowedToChangeFormInWeather[i][side] = FALSE;
}
}
bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility)
{
u16 battlerAbility = GetBattlerAbility(battler);
if (gBattleWeather & B_WEATHER_PRIMAL_ANY
&& battlerAbility != ABILITY_DESOLATE_LAND
&& battlerAbility != ABILITY_PRIMORDIAL_SEA
&& battlerAbility != ABILITY_DELTA_STREAM)
{
return FALSE;
}
else if (B_ABILITY_WEATHER < GEN_6 && viaAbility && !(gBattleWeather & sWeatherFlagsInfo[weatherEnumId][1]))
{
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]);
ShouldChangeFormInWeather(battler);
return TRUE;
}
else if (!(gBattleWeather & (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1])))
{
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0]);
if (GetBattlerHoldEffect(battler, TRUE) == sWeatherFlagsInfo[weatherEnumId][2])
gWishFutureKnock.weatherDuration = 8;
else
gWishFutureKnock.weatherDuration = 5;
ShouldChangeFormInWeather(battler);
return TRUE;
}
return FALSE;
}
u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute)
{
if (gFieldStatuses & terrainFlag && CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
{
BufferStatChange(battler, statId, STRINGID_STATROSE);
gLastUsedItem = itemId; // For surge abilities
gEffectBattler = gBattleScripting.battler = battler;
SET_STATCHANGER(statId, 1, FALSE);
gBattleScripting.animArg1 = 14 + statId;
gBattleScripting.animArg2 = 0;
if (execute)
{
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryStatRaiseRet;
}
return ITEM_STATS_CHANGE;
}
return 0;
}
static u32 GetBattlerItemHoldEffectParam(u32 battler, u32 item)
{
if (item == ITEM_ENIGMA_BERRY_E_READER)
return gEnigmaBerries[battler].holdEffectParam;
else
return ItemId_GetHoldEffectParam(item);
}
bool32 IsBattlerMegaEvolved(u32 battler)
{
// While Transform does copy stats and visuals, it shouldn't be counted as true Mega Evolution.