c functions for ai roamers/safari/first battle

This commit is contained in:
Evan 2020-12-10 22:10:21 -07:00
parent eac8135687
commit aad3a800c3
5 changed files with 108 additions and 87 deletions

View File

@ -21,29 +21,7 @@ gBattleAI_ScriptsTable:: @ 82DBEF8
.4byte AI_PreferBatonPass @ AI_SCRIPT_PREFER_BATON_PASS
.4byte AI_DoubleBattle @ AI_SCRIPT_DOUBLE_BATTLE
.4byte AI_HPAware @ AI_SCRIPT_HP_AWARE
.4byte AI_Unknown @ AI_SCRIPT_UNKNOWN
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Ret
.4byte AI_Roaming @ AI_SCRIPT_ROAMING
.4byte AI_Safari @ AI_SCRIPT_SAFARI
.4byte AI_FirstBattle @ AI_SCRIPT_FIRST_BATTLE
AI_CheckBadMove:
if_target_is_ally AI_Ret
@ -4140,47 +4118,7 @@ AI_HPAware_DiscouragedEffectsWhenTargetLowHP: @ 82DE2B1
.byte EFFECT_DRAGON_DANCE
.byte -1
AI_Unknown:
if_target_is_ally AI_TryOnAlly
if_not_effect EFFECT_SUNNY_DAY, AI_Unknown_End
if_equal 0, AI_Unknown_End
is_first_turn_for AI_USER
if_equal 0, AI_Unknown_End
score +5
AI_Unknown_End: @ 82DE308
end
AI_Roaming:
if_status2 AI_USER, STATUS2_WRAPPED, AI_Roaming_End
if_status2 AI_USER, STATUS2_ESCAPE_PREVENTION, AI_Roaming_End
get_ability AI_TARGET
if_equal ABILITY_SHADOW_TAG, AI_Roaming_End
get_ability AI_USER
if_equal ABILITY_LEVITATE, AI_Roaming_Flee
get_ability AI_TARGET
if_equal ABILITY_ARENA_TRAP, AI_Roaming_End
AI_Roaming_Flee: @ 82DE335
flee
AI_Roaming_End: @ 82DE336
end
AI_Safari:
if_random_safari_flee AI_Safari_Flee
watch
AI_Safari_Flee:
flee
AI_FirstBattle:
if_hp_equal AI_TARGET, 20, AI_FirstBattle_Flee
if_hp_less_than AI_TARGET, 20, AI_FirstBattle_Flee
end
AI_FirstBattle_Flee:
flee
AI_Ret:
end

8
include/battle_ai_util.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef GUARD_BATTLE_AI_UTIL_H
#define GUARD_BATTLE_AI_UTIL_H
u32 GetHealthPercentage(u8 battler);
bool32 IsBattlerTrapped(u8 battler, bool8 switching);
#endif //GUARD_BATTLE_AI_UTIL_H

View File

@ -214,6 +214,7 @@ SECTIONS {
src/slot_machine.o(.text);
src/contest_painting.o(.text);
src/battle_ai_script_commands.o(.text);
src/battle_ai_util.o(.text);
src/trader.o(.text);
src/starter_choose.o(.text);
src/wallclock.o(.text);

View File

@ -2,6 +2,7 @@
#include "malloc.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_ai_util.h"
#include "battle_ai_script_commands.h"
#include "battle_factory.h"
#include "battle_setup.h"
@ -187,18 +188,18 @@ EWRAM_DATA static u8 sBattler_AI = 0;
// const rom data
typedef void (*BattleAICmdFunc)(void);
static u8 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability);
static u8 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalScore);
static u8 (*const sBattleAiFuncTable[])(u8, u8, u16, u8) =
{
@ -2933,53 +2934,79 @@ static void Cmd_if_has_move_with_accuracy_lt(void)
// AI Functions
static u8 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
}
static u8 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static void AI_Flee(void)
{
AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK);
}
static u8 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static void AI_Watch(void)
{
AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK);
}
static u8 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 originalMove, u8 originalViability)
static u8 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
if (IsBattlerTrapped(battlerAtk, FALSE))
return originalScore;
AI_Flee();
return originalScore;
}
static u8 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
u8 safariFleeRate = gBattleStruct->safariEscapeFactor * 5; // Safari flee rate, from 0-20.
if ((Random() % 100) < safariFleeRate)
AI_Flee();
else
AI_Watch();
return originalScore;
}
static u8 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 move, u8 originalScore)
{
if (GetHealthPercentage(battlerDef) <= 20)
AI_Flee();
return originalScore;
}

47
src/battle_ai_util.c Normal file
View File

@ -0,0 +1,47 @@
#include "global.h"
#include "malloc.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_ai_util.h"
#include "battle_ai_script_commands.h"
#include "battle_factory.h"
#include "battle_setup.h"
#include "data.h"
#include "item.h"
#include "pokemon.h"
#include "random.h"
#include "recorded_battle.h"
#include "util.h"
#include "constants/abilities.h"
#include "constants/battle_ai.h"
#include "constants/battle_move_effects.h"
#include "constants/hold_effects.h"
#include "constants/moves.h"
// Functions
u32 GetHealthPercentage(u8 battlerId)
{
return (u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP);
}
bool32 IsBattlerTrapped(u8 battler, bool8 switching)
{
u8 holdEffect = GetBattlerHoldEffect(battler, TRUE);
if (IS_BATTLER_OF_TYPE(battler, TYPE_GHOST)
|| (switching && holdEffect == HOLD_EFFECT_SHED_SHELL)
|| (!switching && GetBattlerAbility(battler) == ABILITY_RUN_AWAY)
|| (!switching && holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN))
{
return FALSE;
}
else
{
if (gBattleMons[battler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED)
|| IsAbilityPreventingEscape(battler)
|| gStatuses3[battler] & (STATUS3_ROOTED) // TODO: sky drop target in air
|| (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK))
return TRUE;
}
return FALSE;
}