Merge pull request #1890 from kleeenexfeu/battle_engine

Bypassing screens and protections correctly
This commit is contained in:
Eduardo Quezada D'Ottone 2021-11-13 10:11:02 -03:00 committed by GitHub
commit bcb0f1b915
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 45 deletions

View File

@ -102,6 +102,7 @@ u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability);
u32 IsAbilityOnField(u32 ability);
u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability);
u32 IsAbilityPreventingEscape(u32 battlerId);
bool32 IsBattlerProtected(u8 battlerId, u16 move);
bool32 CanBattlerEscape(u32 battlerId); // no ability check
void BattleScriptExecute(const u8* BS_ptr);
void BattleScriptPushCursorAndCallback(const u8* BS_ptr);

View File

@ -1313,47 +1313,6 @@ static const u8 sBattlePalaceNatureToFlavorTextId[NUM_NATURES] =
[NATURE_QUIRKY] = B_MSG_EAGER_FOR_MORE,
};
bool32 IsBattlerProtected(u8 battlerId, u16 move)
{
// Decorate bypasses protect and detect, but not crafty shield
if (move == MOVE_DECORATE)
{
if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD)
return TRUE;
else if (gProtectStructs[battlerId].protected)
return FALSE;
}
if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED))
return FALSE;
else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT)
return FALSE;
else if (gProtectStructs[battlerId].protected)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD
&& gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
return TRUE;
else if (gProtectStructs[battlerId].banefulBunkered)
return TRUE;
else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move))
return TRUE;
else if (gProtectStructs[battlerId].spikyShielded)
return TRUE;
else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD
&& GetChosenMovePriority(gBattlerAttacker) > 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD
&& IS_MOVE_STATUS(move))
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK
&& !IS_MOVE_STATUS(move))
return TRUE;
else
return FALSE;
}
static bool32 NoTargetPresent(u32 move)
{
if (!IsBattlerAlive(gBattlerTarget))

View File

@ -7450,6 +7450,48 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk)
}
}
bool32 IsBattlerProtected(u8 battlerId, u16 move)
{
// Decorate bypasses protect and detect, but not crafty shield
if (move == MOVE_DECORATE)
{
if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD)
return TRUE;
else if (gProtectStructs[battlerId].protected)
return FALSE;
}
if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED))
return FALSE;
else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT)
return FALSE;
else if (gProtectStructs[battlerId].protected)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD
&& gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
return TRUE;
else if (gProtectStructs[battlerId].banefulBunkered)
return TRUE;
else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move))
return TRUE;
else if (gProtectStructs[battlerId].spikyShielded)
return TRUE;
else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD
&& GetChosenMovePriority(gBattlerAttacker) > 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD
&& IS_MOVE_STATUS(move))
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK
&& !IS_MOVE_STATUS(move))
return TRUE;
else
return FALSE;
}
bool32 IsBattlerGrounded(u8 battlerId)
{
if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL)
@ -8609,7 +8651,9 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move))
|| (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move))
|| (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL))
&& abilityAtk != ABILITY_INFILTRATOR)
&& abilityAtk != ABILITY_INFILTRATOR
&& !(isCrit)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
MulModifier(&finalModifier, UQ_4_12(0.66));
@ -8781,9 +8825,6 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt
if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot)
mod = UQ_4_12(2.0);
if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT)
mod = UQ_4_12(1.0);
// WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS)
{