Merge pull request #2120 from ghoulslash/be/healblock

Heal Block AI and Pollen Puff Selection Prevention
This commit is contained in:
Eduardo Quezada D'Ottone 2022-05-07 19:29:24 -04:00 committed by GitHub
commit 989ec641f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 5 deletions

View File

@ -172,6 +172,7 @@ void TryToApplyMimicry(u8 battlerId, bool8 various);
void TryToRevertMimicry(void); void TryToRevertMimicry(void);
void RestoreBattlerOriginalTypes(u8 battlerId); void RestoreBattlerOriginalTypes(u8 battlerId);
u32 GetBattlerMoveTargetType(u8 battlerId, u16 move); u32 GetBattlerMoveTargetType(u8 battlerId, u16 move);
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move);
// Ability checks // Ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability); bool32 IsRolePlayBannedAbilityAtk(u16 ability);
bool32 IsRolePlayBannedAbility(u16 ability); bool32 IsRolePlayBannedAbility(u16 ability);

View File

@ -438,6 +438,9 @@ static u8 ChooseMoveOrAction_Doubles(void)
{ {
if (gBattleMons[sBattler_AI].moves[j] != 0) if (gBattleMons[sBattler_AI].moves[j] != 0)
{ {
if (!CanTargetBattler(sBattler_AI, i, gBattleMons[sBattler_AI].moves[j]))
continue;
if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j]) if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j])
{ {
mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j]; mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j];
@ -2296,6 +2299,8 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_HIT_ENEMY_HEAL_ALLY: // pollen puff case EFFECT_HIT_ENEMY_HEAL_ALLY: // pollen puff
if (IsTargetingPartner(battlerAtk, battlerDef)) if (IsTargetingPartner(battlerAtk, battlerDef))
{ {
if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK)
return 0;
if (AtMaxHp(battlerDef)) if (AtMaxHp(battlerDef))
score -= 10; score -= 10;
else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2) else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2)
@ -4902,6 +4907,9 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|| (moveType == TYPE_ELECTRIC && AI_DATA->atkPartnerAbility == ABILITY_VOLT_ABSORB) || (moveType == TYPE_ELECTRIC && AI_DATA->atkPartnerAbility == ABILITY_VOLT_ABSORB)
|| (moveType == TYPE_WATER && (AI_DATA->atkPartnerAbility == ABILITY_DRY_SKIN || AI_DATA->atkPartnerAbility == ABILITY_WATER_ABSORB))) || (moveType == TYPE_WATER && (AI_DATA->atkPartnerAbility == ABILITY_DRY_SKIN || AI_DATA->atkPartnerAbility == ABILITY_WATER_ABSORB)))
{ {
if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK)
return 0;
if (CanTargetFaintAi(FOE(battlerAtk), AI_DATA->battlerAtkPartner) if (CanTargetFaintAi(FOE(battlerAtk), AI_DATA->battlerAtkPartner)
|| (CanTargetFaintAi(BATTLE_PARTNER(FOE(battlerAtk)), AI_DATA->battlerAtkPartner))) || (CanTargetFaintAi(BATTLE_PARTNER(FOE(battlerAtk)), AI_DATA->battlerAtkPartner)))
score--; score--;

View File

@ -1605,6 +1605,7 @@ static void OpponentHandleChooseMove(void)
else // Wild pokemon - use random move else // Wild pokemon - use random move
{ {
u16 move; u16 move;
u8 target;
do do
{ {
chosenMoveId = Random() & 3; chosenMoveId = Random() & 3;
@ -1615,6 +1616,10 @@ static void OpponentHandleChooseMove(void)
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gActiveBattler << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gActiveBattler << 8));
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{ {
do {
target = GetBattlerAtPosition(Random() & 2);
} while (!CanTargetBattler(gActiveBattler, target, move));
#if B_WILD_NATURAL_ENEMIES == TRUE #if B_WILD_NATURAL_ENEMIES == TRUE
// Don't bother to loop through table if the move can't attack ally // Don't bother to loop through table if the move can't attack ally
if (!(gBattleMoves[move].target & MOVE_TARGET_BOTH)) if (!(gBattleMoves[move].target & MOVE_TARGET_BOTH))
@ -1641,14 +1646,14 @@ static void OpponentHandleChooseMove(void)
break; break;
} }
} }
if (isPartnerEnemy) if (isPartnerEnemy && CanTargetBattler(gActiveBattler, target, move))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler)) << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler)) << 8));
else else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(Random() & 2) << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8));
} }
else else
#endif #endif
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(Random() & 2) << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8));
} }
else else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) << 8));

View File

@ -436,7 +436,8 @@ static void HandleInputChooseTarget(void)
break; break;
} }
if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]) if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]
|| !CanTargetBattler(gActiveBattler, gMultiUsePlayerCursor, move))
i = 0; i = 0;
} while (i == 0); } while (i == 0);
} }
@ -485,7 +486,8 @@ static void HandleInputChooseTarget(void)
break; break;
} }
if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]) if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor]
|| !CanTargetBattler(gActiveBattler, gMultiUsePlayerCursor, move))
i = 0; i = 0;
} while (i == 0); } while (i == 0);
} }

View File

@ -10103,3 +10103,12 @@ u32 GetBattlerMoveTargetType(u8 battlerId, u16 move)
else else
return gBattleMoves[move].target; return gBattleMoves[move].target;
} }
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move)
{
if (gBattleMoves[move].effect == EFFECT_HIT_ENEMY_HEAL_ALLY
&& GetBattlerSide(battlerAtk) == GetBattlerSide(battlerDef)
&& gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK)
return FALSE; // Pokémon affected by Heal Block cannot target allies with Pollen Puff
return TRUE;
}