Optimized battle gender checks (#3020)

* Optimized battle gender checks

* Apply suggestions from code review

Co-authored-by: AgustinGDLV <103095241+AgustinGDLV@users.noreply.github.com>

---------

Co-authored-by: AgustinGDLV <103095241+AgustinGDLV@users.noreply.github.com>
This commit is contained in:
Eduardo Quezada D'Ottone 2023-05-27 17:23:02 -04:00 committed by GitHub
parent 05895c5308
commit d0e6ea7612
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 62 deletions

View file

@ -143,7 +143,7 @@ bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtk
bool32 ShouldBurnSelf(u8 battler, u16 ability); bool32 ShouldBurnSelf(u8 battler, u16 ability);
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove); bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove); bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender); bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility);
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof); bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof);
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move); u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move); bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move);

View file

@ -234,5 +234,7 @@ u32 CountBattlerStatIncreases(u8 battlerId, bool32 countEvasionAcc);
bool32 IsMyceliumMightOnField(void); bool32 IsMyceliumMightOnField(void);
bool8 ChangeTypeBasedOnTerrain(u8 battlerId); bool8 ChangeTypeBasedOnTerrain(u8 battlerId);
void RemoveConfusionStatus(u8 battlerId); void RemoveConfusionStatus(u8 battlerId);
u8 GetBattlerGender(u8 battlerId);
bool8 AreBattlersOfOppositeGender(u8 battler1, u8 battler2);
#endif // GUARD_BATTLE_UTIL_H #endif // GUARD_BATTLE_UTIL_H

View file

@ -248,7 +248,7 @@ static void CopyBattlerDataToAIParty(u32 bPosition, u32 side)
aiMon->species = bMon->species; aiMon->species = bMon->species;
aiMon->level = bMon->level; aiMon->level = bMon->level;
aiMon->status = bMon->status1; aiMon->status = bMon->status1;
aiMon->gender = GetGenderFromSpeciesAndPersonality(bMon->species, bMon->personality); aiMon->gender = GetBattlerGender(battler);
aiMon->isFainted = FALSE; aiMon->isFainted = FALSE;
aiMon->wasSentInBattle = TRUE; aiMon->wasSentInBattle = TRUE;
aiMon->switchInCount++; aiMon->switchInCount++;
@ -1287,12 +1287,8 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 8; score -= 8;
break; break;
case EFFECT_CAPTIVATE: case EFFECT_CAPTIVATE:
{ if (!AreBattlersOfOppositeGender(battlerAtk, battlerDef))
u8 atkGender = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality); score -= 10;
u8 defGender = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality);
if (atkGender == MON_GENDERLESS || defGender == MON_GENDERLESS || atkGender == defGender)
score -= 10;
}
break; break;
// other // other
case EFFECT_HAZE: case EFFECT_HAZE:
@ -1592,9 +1588,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 2; // mainly to prevent looping between hail and snow score -= 2; // mainly to prevent looping between hail and snow
break; break;
case EFFECT_ATTRACT: case EFFECT_ATTRACT:
if (!AI_CanBeInfatuated(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], if (!AI_CanBeInfatuated(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef]))
GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality),
GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality)))
score -= 10; score -= 10;
break; break;
case EFFECT_SAFEGUARD: case EFFECT_SAFEGUARD:

View file

@ -2967,14 +2967,12 @@ bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 batt
return TRUE; return TRUE;
} }
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender) bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility)
{ {
if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION) if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
|| AI_GetMoveEffectiveness(AI_THINKING_STRUCT->moveConsidered, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 || AI_GetMoveEffectiveness(AI_THINKING_STRUCT->moveConsidered, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| defAbility == ABILITY_OBLIVIOUS || defAbility == ABILITY_OBLIVIOUS
|| atkGender == defGender || !AreBattlersOfOppositeGender(battlerAtk, battlerDef)
|| atkGender == MON_GENDERLESS
|| defGender == MON_GENDERLESS
|| AI_IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL)) || AI_IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL))
return FALSE; return FALSE;
return TRUE; return TRUE;

View file

@ -12758,26 +12758,6 @@ static void Cmd_tryinfatuating(void)
{ {
CMD_ARGS(const u8 *failInstr); CMD_ARGS(const u8 *failInstr);
struct Pokemon *monAttacker, *monTarget;
u16 speciesAttacker, speciesTarget;
u32 personalityAttacker, personalityTarget;
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
monAttacker = &gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]];
else
monAttacker = &gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]];
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
monTarget = &gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]];
else
monTarget = &gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]];
speciesAttacker = GetMonData(monAttacker, MON_DATA_SPECIES);
personalityAttacker = GetMonData(monAttacker, MON_DATA_PERSONALITY);
speciesTarget = GetMonData(monTarget, MON_DATA_SPECIES);
personalityTarget = GetMonData(monTarget, MON_DATA_PERSONALITY);
if (GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS) if (GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS)
{ {
gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp; gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp;
@ -12786,10 +12766,8 @@ static void Cmd_tryinfatuating(void)
} }
else else
{ {
if (GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) if (gBattleMons[gBattlerTarget].status2 & STATUS2_INFATUATION
|| gBattleMons[gBattlerTarget].status2 & STATUS2_INFATUATION || !AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
|| GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS
|| GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS)
{ {
gBattlescriptCurrInstr = cmd->failInstr; gBattlescriptCurrInstr = cmd->failInstr;
} }
@ -16103,10 +16081,7 @@ static void Cmd_jumpifoppositegenders(void)
{ {
CMD_ARGS(const u8 *jumpInstr); CMD_ARGS(const u8 *jumpInstr);
u32 atkGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerAttacker].species, gBattleMons[gBattlerAttacker].personality); if (AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
u32 defGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerTarget].species, gBattleMons[gBattlerTarget].personality);
if ((atkGender == MON_MALE && defGender == MON_FEMALE) || (atkGender == MON_FEMALE && defGender == MON_MALE))
gBattlescriptCurrInstr = cmd->jumpInstr; gBattlescriptCurrInstr = cmd->jumpInstr;
else else
gBattlescriptCurrInstr = cmd->nextInstr; gBattlescriptCurrInstr = cmd->nextInstr;

View file

@ -4183,7 +4183,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
{ {
u8 effect = 0; u8 effect = 0;
u32 speciesAtk, speciesDef; u32 speciesAtk, speciesDef;
u32 pidAtk, pidDef;
u32 moveType, move; u32 moveType, move;
u32 i, j; u32 i, j;
@ -4194,10 +4193,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
gBattlerAttacker = battler; gBattlerAttacker = battler;
speciesAtk = gBattleMons[gBattlerAttacker].species; speciesAtk = gBattleMons[gBattlerAttacker].species;
pidAtk = gBattleMons[gBattlerAttacker].personality;
speciesDef = gBattleMons[gBattlerTarget].species; speciesDef = gBattleMons[gBattlerTarget].species;
pidDef = gBattleMons[gBattlerTarget].personality;
if (special) if (special)
gLastUsedAbility = special; gLastUsedAbility = special;
@ -5515,16 +5511,14 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerAttacker].hp != 0 && gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg && !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& (IsMoveMakingContact(move, gBattlerAttacker))
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
&& gBattleMons[gBattlerTarget].hp != 0 && gBattleMons[gBattlerTarget].hp != 0
&& RandomWeighted(RNG_CUTE_CHARM, 2, 1) && RandomWeighted(RNG_CUTE_CHARM, 2, 1)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_OBLIVIOUS
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
&& GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef)
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
&& GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != MON_GENDERLESS && AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget)
&& GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != MON_GENDERLESS) && GetBattlerAbility(gBattlerAttacker) != ABILITY_OBLIVIOUS
&& IsMoveMakingContact(move, gBattlerAttacker)
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL))
{ {
gBattleMons[gBattlerAttacker].status2 |= STATUS2_INFATUATED_WITH(gBattlerTarget); gBattleMons[gBattlerAttacker].status2 |= STATUS2_INFATUATED_WITH(gBattlerTarget);
BattleScriptPushCursor(); BattleScriptPushCursor();
@ -8753,15 +8747,10 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
MulModifier(&modifier, UQ_4_12(1.3)); MulModifier(&modifier, UQ_4_12(1.3));
break; break;
case ABILITY_RIVALRY: case ABILITY_RIVALRY:
if (GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality) != MON_GENDERLESS if (AreBattlersOfOppositeGender(battlerAtk, battlerDef))
&& GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality) != MON_GENDERLESS) MulModifier(&modifier, UQ_4_12(1.25));
{ else
if (GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality) MulModifier(&modifier, UQ_4_12(0.75));
== GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality))
MulModifier(&modifier, UQ_4_12(1.25));
else
MulModifier(&modifier, UQ_4_12(0.75));
}
break; break;
case ABILITY_ANALYTIC: case ABILITY_ANALYTIC:
if (GetBattlerTurnOrderNum(battlerAtk) == gBattlersCount - 1 && move != MOVE_FUTURE_SIGHT && move != MOVE_DOOM_DESIRE) if (GetBattlerTurnOrderNum(battlerAtk) == gBattlersCount - 1 && move != MOVE_FUTURE_SIGHT && move != MOVE_DOOM_DESIRE)
@ -10923,3 +10912,16 @@ static bool8 CanBeInfinitelyConfused(u8 battlerId)
return TRUE; return TRUE;
} }
u8 GetBattlerGender(u8 battlerId)
{
return GetGenderFromSpeciesAndPersonality(gBattleMons[battlerId].species,
gBattleMons[battlerId].personality);
}
bool8 AreBattlersOfOppositeGender(u8 battler1, u8 battler2)
{
u8 gender1 = GetBattlerGender(battler1);
u8 gender2 = GetBattlerGender(battler2);
return (gender1 != MON_GENDERLESS && gender2 != MON_GENDERLESS && gender1 != gender2);
}