some ai updates, recycle + ripen logic

This commit is contained in:
ghoulslash 2021-11-08 11:37:41 -05:00
parent 4f56d0a2b5
commit 8f320a8d33
3 changed files with 70 additions and 1 deletions

View File

@ -52,6 +52,8 @@ bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent);
bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect); bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect);
bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex); bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex);
bool32 IsRecycleEncouragedItem(u16 item); bool32 IsRecycleEncouragedItem(u16 item);
bool32 IsHpRestoringBerry(u16 item);
bool32 IsStatBoostingBerry(u16 item);
bool32 CanKnockOffItem(u8 battler, u16 item); bool32 CanKnockOffItem(u8 battler, u16 item);
bool32 IsAbilityOfRating(u16 ability, s8 rating); bool32 IsAbilityOfRating(u16 ability, s8 rating);
s8 GetAbilityRating(u16 ability); s8 GetAbilityRating(u16 ability);

View File

@ -2969,6 +2969,10 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
{ {
case ABILITY_MOXIE: case ABILITY_MOXIE:
case ABILITY_BEAST_BOOST: case ABILITY_BEAST_BOOST:
case ABILITY_CHILLING_NEIGH:
case ABILITY_GRIM_NEIGH:
case ABILITY_AS_ONE_ICE_RIDER:
case ABILITY_AS_ONE_SHADOW_RIDER:
if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first
{ {
if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))
@ -2980,7 +2984,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// move effect checks // move effect checks
switch (moveEffect) switch (moveEffect)
{ {
case EFFECT_HIT: case EFFECT_HIT:
break; break;
case EFFECT_SLEEP: case EFFECT_SLEEP:
@ -4101,6 +4104,14 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score++; score++;
if (IsRecycleEncouragedItem(GetUsedHeldItem(battlerAtk))) if (IsRecycleEncouragedItem(GetUsedHeldItem(battlerAtk)))
score++; score++;
if (AI_DATA->atkAbility == ABILITY_RIPEN)
{
u16 item = GetUsedHeldItem(battlerAtk);
if (IsStatBoostingBerry(item) && atkHpPercent > 60)
score++;
else if (IsHpRestoringBerry(item) && atkHpPercent < 60)
score++; // TODO check if player can still faint us after we heal
}
break; break;
case EFFECT_BRICK_BREAK: case EFFECT_BRICK_BREAK:
if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_REFLECT) if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_REFLECT)

View File

@ -3368,6 +3368,44 @@ static const u16 sRecycleEncouragedItems[] =
// TODO expand this // TODO expand this
}; };
// Its assumed that the berry is strategically given, so no need to check benefits of the berry
bool32 IsStatBoostingBerry(u16 item)
{
switch (item)
{
case ITEM_LIECHI_BERRY:
case ITEM_GANLON_BERRY:
case ITEM_SALAC_BERRY:
case ITEM_PETAYA_BERRY:
case ITEM_APICOT_BERRY:
//case ITEM_LANSAT_BERRY:
case ITEM_STARF_BERRY:
#ifdef ITEM_EXPANSION
case ITEM_MICLE_BERRY:
#endif
return TRUE;
default:
return FALSE;
}
}
bool32 IsHpRestoringBerry(u16 item)
{
switch (item)
{
case ITEM_ORAN_BERRY:
case ITEM_SITRUS_BERRY:
case ITEM_FIGY_BERRY:
case ITEM_WIKI_BERRY:
case ITEM_MAGO_BERRY:
case ITEM_AGUAV_BERRY:
case ITEM_IAPAPA_BERRY:
return TRUE;
default:
return FALSE;
}
}
bool32 IsRecycleEncouragedItem(u16 item) bool32 IsRecycleEncouragedItem(u16 item)
{ {
u32 i; u32 i;
@ -3389,6 +3427,9 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
if (GetHealthPercentage(battlerAtk) < 80 && AI_RandLessThan(128)) if (GetHealthPercentage(battlerAtk) < 80 && AI_RandLessThan(128))
return; return;
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
return; // Damaging moves would get a score boost from AI_TryToFaint or PreferStrongestMove so we don't consider them here
switch (statId) switch (statId)
{ {
@ -3461,6 +3502,9 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
{ {
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
return;
if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove) && GetHealthPercentage(battlerDef) > 20) if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove) && GetHealthPercentage(battlerDef) > 20)
{ {
if (!HasDamagingMove(battlerDef)) if (!HasDamagingMove(battlerDef))
@ -3481,6 +3525,9 @@ void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
{ {
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
return;
if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove))
{ {
(*score)++; // burning is good (*score)++; // burning is good
@ -3497,6 +3544,9 @@ void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
{ {
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
return;
if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove))
{ {
u8 atkSpeed = GetBattlerTotalSpeedStat(battlerAtk); u8 atkSpeed = GetBattlerTotalSpeedStat(battlerAtk);
@ -3515,6 +3565,9 @@ void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
{ {
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
return;
if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove))
*score += 2; *score += 2;
else else
@ -3530,6 +3583,9 @@ void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
{ {
if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
return;
if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)
&& AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_CONFUSION && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_CONFUSION
&& AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_STATUS) && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_STATUS)