dump trainer ai scripts

This commit is contained in:
DizzyEggg 2017-12-30 16:04:31 +01:00
parent 9bad1921df
commit ca29ad22e8
4 changed files with 4083 additions and 104 deletions

View File

@ -0,0 +1,619 @@
.macro if_random_less_than param0, param1
.byte 0x0
.byte \param0
.4byte \param1
.endm
.macro if_random_greater_than param0, param1
.byte 0x1
.byte \param0
.4byte \param1
.endm
.macro if_random_equal param0, param1
.byte 0x2
.byte \param0
.4byte \param1
.endm
.macro if_random_not_equal param0, param1
.byte 0x3
.byte \param0
.4byte \param1
.endm
.macro score param0
.byte 0x4
.byte \param0
.endm
.macro if_hp_less_than bank, param1, param2
.byte 0x5
.byte \bank
.byte \param1
.4byte \param2
.endm
.macro if_hp_more_than bank, param1, param2
.byte 0x6
.byte \bank
.byte \param1
.4byte \param2
.endm
.macro if_hp_equal bank, param1, param2
.byte 0x7
.byte \bank
.byte \param1
.4byte \param2
.endm
.macro if_hp_not_equal bank, param1, param2
.byte 0x8
.byte \bank
.byte \param1
.4byte \param2
.endm
.macro if_status bank, status1, param2
.byte 0x9
.byte \bank
.4byte \status1
.4byte \param2
.endm
.macro if_not_status bank, status1, param2
.byte 0xa
.byte \bank
.4byte \status1
.4byte \param2
.endm
.macro if_status2 bank, status2, param2
.byte 0xb
.byte \bank
.4byte \status2
.4byte \param2
.endm
.macro if_not_status2 bank, status2, param2
.byte 0xc
.byte \bank
.4byte \status2
.4byte \param2
.endm
.macro if_status3 bank, status3, param2
.byte 0xd
.byte \bank
.4byte \status3
.4byte \param2
.endm
.macro if_not_status3 bank, status3, param2
.byte 0xe
.byte \bank
.4byte \status3
.4byte \param2
.endm
.macro if_side_affecting bank, sidestatus, param2
.byte 0xf
.byte \bank
.4byte \sidestatus
.4byte \param2
.endm
.macro if_not_side_affecting bank, sidestatus, param2
.byte 0x10
.byte \bank
.4byte \sidestatus
.4byte \param2
.endm
.macro if_less_than param0, param1
.byte 0x11
.byte \param0
.4byte \param1
.endm
.macro if_more_than param0, param1
.byte 0x12
.byte \param0
.4byte \param1
.endm
.macro if_equal param0, param1
.byte 0x13
.byte \param0
.4byte \param1
.endm
.macro if_not_equal param0, param1
.byte 0x14
.byte \param0
.4byte \param1
.endm
.macro if_less_than_ptr param0, param1
.byte 0x15
.4byte \param0
.4byte \param1
.endm
.macro if_more_than_ptr param0, param1
.byte 0x16
.4byte \param0
.4byte \param1
.endm
.macro if_equal_ptr param0, param1
.byte 0x17
.4byte \param0
.4byte \param1
.endm
.macro if_not_equal_ptr param0, param1
.byte 0x18
.4byte \param0
.4byte \param1
.endm
.macro if_move param0, param1
.byte 0x19
.2byte \param0
.4byte \param1
.endm
.macro if_not_move param0, param1
.byte 0x1a
.2byte \param0
.4byte \param1
.endm
.macro if_in_bytes param0, param1
.byte 0x1b
.4byte \param0
.4byte \param1
.endm
.macro if_not_in_bytes param0, param1
.byte 0x1c
.4byte \param0
.4byte \param1
.endm
.macro if_in_hwords param0, param1
.byte 0x1d
.4byte \param0
.4byte \param1
.endm
.macro if_not_in_hwords param0, param1
.byte 0x1e
.4byte \param0
.4byte \param1
.endm
.macro if_user_has_attacking_move param0
.byte 0x1f
.4byte \param0
.endm
.macro if_user_has_no_attacking_moves param0
.byte 0x20
.4byte \param0
.endm
.macro get_turn_count
.byte 0x21
.endm
.macro get_type param0
.byte 0x22
.byte \param0
.endm
.macro get_considered_move_power
.byte 0x23
.endm
.macro get_how_powerful_move_is
.byte 0x24
.endm
.macro get_last_used_bank_move bank
.byte 0x25
.byte \bank
.endm
.macro if_equal_ param0, param1
.byte 0x26
.byte \param0
.4byte \param1
.endm
.macro if_not_equal_ param0, param1
.byte 0x27
.byte \param0
.4byte \param1
.endm
.macro if_user_goes param0, param1
.byte 0x28
.byte \param0
.4byte \param1
.endm
.macro if_user_doesnt_go param0, param1
.byte 0x29
.byte \param0
.4byte \param1
.endm
.macro nullsub_2A
.byte 0x2a
.endm
.macro nullsub_2B
.byte 0x2b
.endm
.macro count_usable_party_mons bank
.byte 0x2c
.byte \bank
.endm
.macro get_considered_move
.byte 0x2d
.endm
.macro get_considered_move_effect
.byte 0x2e
.endm
.macro get_ability bank
.byte 0x2f
.byte \bank
.endm
.macro get_highest_type_effectiveness
.byte 0x30
.endm
.macro if_type_effectiveness param0, param1
.byte 0x31
.byte \param0
.4byte \param1
.endm
.macro nullsub_32
.byte 0x32
.endm
.macro nullsub_33
.byte 0x33
.endm
.macro if_status_in_party bank, status1, param2
.byte 0x34
.byte \bank
.4byte \status1
.4byte \param2
.endm
.macro if_status_not_in_party bank, status1, param2
.byte 0x35
.byte \bank
.4byte \status1
.4byte \param2
.endm
.macro get_weather
.byte 0x36
.endm
.macro if_effect param0, param1
.byte 0x37
.byte \param0
.4byte \param1
.endm
.macro if_not_effect param0, param1
.byte 0x38
.byte \param0
.4byte \param1
.endm
.macro if_stat_level_less_than bank, stat, param2, param3
.byte 0x39
.byte \bank
.byte \stat
.byte \param2
.4byte \param3
.endm
.macro if_stat_level_more_than bank, stat, param2, param3
.byte 0x3a
.byte \bank
.byte \stat
.byte \param2
.4byte \param3
.endm
.macro if_stat_level_equal bank, stat, param2, param3
.byte 0x3b
.byte \bank
.byte \stat
.byte \param2
.4byte \param3
.endm
.macro if_stat_level_not_equal bank, stat, param2, param3
.byte 0x3c
.byte \bank
.byte \stat
.byte \param2
.4byte \param3
.endm
.macro if_can_faint param0
.byte 0x3d
.4byte \param0
.endm
.macro if_cant_faint param0
.byte 0x3e
.4byte \param0
.endm
.macro if_has_move bank, param1, param2
.byte 0x3f
.byte \bank
.2byte \param1
.4byte \param2
.endm
.macro if_doesnt_have_move bank, param1, param2
.byte 0x40
.byte \bank
.2byte \param1
.4byte \param2
.endm
.macro if_has_move_with_effect bank, param1, param2
.byte 0x41
.byte \bank
.byte \param1
.4byte \param2
.endm
.macro if_doesnt_have_move_with_effect bank, param1, param2
.byte 0x42
.byte \bank
.byte \param1
.4byte \param2
.endm
.macro if_any_move_disabled_or_encored bank, param1, param2
.byte 0x43
.byte \bank
.byte \param1
.4byte \param2
.endm
.macro if_curr_move_disabled_or_encored param0, param1
.byte 0x44
.byte \param0
.4byte \param1
.endm
.macro flee
.byte 0x45
.endm
.macro if_random_safari_flee param0
.byte 0x46
.4byte \param0
.endm
.macro watch
.byte 0x47
.endm
.macro get_hold_effect bank
.byte 0x48
.byte \bank
.endm
.macro get_gender bank
.byte 0x49
.byte \bank
.endm
.macro is_first_turn_for bank
.byte 0x4a
.byte \bank
.endm
.macro get_stockpile_count bank
.byte 0x4b
.byte \bank
.endm
.macro is_double_battle
.byte 0x4c
.endm
.macro get_used_held_item bank
.byte 0x4d
.byte \bank
.endm
.macro get_move_type_from_result
.byte 0x4e
.endm
.macro get_move_power_from_result
.byte 0x4f
.endm
.macro get_move_effect_from_result
.byte 0x50
.endm
.macro get_protect_count bank
.byte 0x51
.byte \bank
.endm
.macro nullsub_52
.byte 0x52
.endm
.macro nullsub_53
.byte 0x53
.endm
.macro nullsub_54
.byte 0x54
.endm
.macro nullsub_55
.byte 0x55
.endm
.macro nullsub_56
.byte 0x56
.endm
.macro nullsub_57
.byte 0x57
.endm
.macro call param0
.byte 0x58
.4byte \param0
.endm
.macro goto param0
.byte 0x59
.4byte \param0
.endm
.macro end
.byte 0x5a
.endm
.macro if_level_cond param0, param1
.byte 0x5b
.byte \param0
.4byte \param1
.endm
.macro if_target_taunted param0
.byte 0x5c
.4byte \param0
.endm
.macro if_target_not_taunted param0
.byte 0x5d
.4byte \param0
.endm
.macro if_target_is_ally param0
.byte 0x5e
.4byte \param0
.endm
.macro is_of_type bank, type
.byte 0x5f
.byte \bank
.byte \type
.endm
.macro check_ability bank, ability
.byte 0x60
.byte \bank
.byte \ability
.endm
.macro if_flash_fired bank, param1
.byte 0x61
.byte \bank
.4byte \param1
.endm
.macro if_holds_item bank, param1, param2
.byte 0x62
.byte \bank
.2byte \param1
.4byte \param2
.endm
@ useful script macros
.macro get_curr_move_type
get_type AI_TYPE_MOVE
.endm
.macro get_user_type1
get_type AI_TYPE1_USER
.endm
.macro get_user_type2
get_type AI_TYPE2_USER
.endm
.macro get_target_type1
get_type AI_TYPE1_TARGET
.endm
.macro get_target_type2
get_type AI_TYPE2_TARGET
.endm
.macro if_ability bank, ability, ptr
check_ability \bank, \ability
if_equal 1, \ptr
.endm
.macro if_no_ability bank, ability, ptr
check_ability \bank, \ability
if_equal 0, \ptr
.endm
.macro if_type bank, type, ptr
is_of_type \bank, \type
if_equal 1, \ptr
.endm
.macro if_no_type bank, type, ptr
is_of_type \bank, \type
if_equal 0, \ptr
.endm
.macro if_target_faster ptr
if_user_goes 1, \ptr
.endm
.macro if_user_faster ptr
if_user_goes 0, \ptr
.endm
.macro if_double_battle ptr
is_double_battle
if_equal 1, \ptr
.endm
.macro if_not_double_battle ptr
is_double_battle
if_equal 0, \ptr
.endm
.macro if_any_move_disabled bank, ptr
if_any_move_disabled_or_encored \bank, 0, \ptr
.endm
.macro if_any_move_encored bank, ptr
if_any_move_disabled_or_encored \bank, 1, \ptr
.endm

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
#ifndef GUARD_BATTLE_AI_H
#define GUARD_BATTLE_AI_H
// banks enum
#define AI_TARGET 0
#define AI_USER 1
#define AI_TARGET_PARTNER 2
#define AI_USER_PARTNER 3
// get_type command
#define AI_TYPE1_TARGET 0
#define AI_TYPE1_USER 1
#define AI_TYPE2_TARGET 2
#define AI_TYPE2_USER 3
#define AI_TYPE_MOVE 4
// type effectiveness
#define AI_EFFECTIVENESS_x4 160
#define AI_EFFECTIVENESS_x2 80
#define AI_EFFECTIVENESS_x1 40
#define AI_EFFECTIVENESS_x0_5 20
#define AI_EFFECTIVENESS_x0_25 10
#define AI_EFFECTIVENESS_x0 0
// ai weather enum
#define AI_WEATHER_SUN 0
#define AI_WEATHER_RAIN 1
#define AI_WEATHER_SANDSTORM 2
#define AI_WEATHER_HAIL 3
// get_how_powerful_move_is
#define MOVE_POWER_DISCOURAGED 0
#define MOVE_NOT_MOST_POWERFUL 1
#define MOVE_MOST_POWERFUL 2
// script's table id to bit
#define AI_SCRIPT_CHECK_BAD_MOVE (1 << 0)
#define AI_SCRIPT_CHECK_VIABILITY (1 << 1)
#define AI_SCRIPT_TRY_TO_FAINT (1 << 2)
#define AI_SCRIPT_SETUP_FIRST_TURN (1 << 3)
#define AI_SCRIPT_RISKY (1 << 4)
#define AI_SCRIPT_PREFER_STRONGEST_MOVE (1 << 5)
#define AI_SCRIPT_PREFER_BATON_PASS (1 << 6)
#define AI_SCRIPT_DOUBLE_BATTLE (1 << 7)
#define AI_SCRIPT_HP_AWARE (1 << 8)
#define AI_SCRIPT_UNKNOWN (1 << 9)
// 10 - 28 are not used
#define AI_SCRIPT_ROAMING (1 << 29)
#define AI_SCRIPT_SAFARI (1 << 30)
#define AI_SCRIPT_FIRST_BATTLE (1 << 31)
#endif // GUARD_BATTLE_AI_H

View File

@ -9,6 +9,7 @@
#include "constants/battle_move_effects.h"
#include "constants/moves.h"
#include "util.h"
#include "constants/battle_ai.h"
#define AIScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24)
#define AIScriptRead16(ptr) ((ptr)[0] | (ptr)[1] << 8)
@ -26,14 +27,6 @@
#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai))
#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory))
enum
{
AI_TARGET,
AI_USER,
AI_TARGET_PARTNER,
AI_USER_PARTNER
};
// AI states
enum
{
@ -374,32 +367,34 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves)
// decide a random target bank in doubles
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
gBankTarget = (Random() & 2) + (GetBankSide(gActiveBank) ^ 1);
gBankTarget = (Random() & BIT_MON) + (GetBankSide(gActiveBank) ^ BIT_SIDE);
if (gAbsentBankFlags & gBitTable[gBankTarget])
gBankTarget ^= 2;
gBankTarget ^= BIT_MON;
}
// in singles there's only one choice
else
gBankTarget = sBank_AI ^ 1;
{
gBankTarget = sBank_AI ^ BIT_SIDE;
}
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
AI_THINKING_STRUCT->aiFlags = GetAiScriptsInRecordedBattle();
else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
AI_THINKING_STRUCT->aiFlags = 0x40000000;
AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_SAFARI;
else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER)
AI_THINKING_STRUCT->aiFlags = 0x20000000;
AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_ROAMING;
else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
AI_THINKING_STRUCT->aiFlags = 0x80000000;
AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_FIRST_BATTLE;
else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY)
AI_THINKING_STRUCT->aiFlags = GetAiScriptsInBattleFactory();
else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x4000000 | BATTLE_TYPE_SECRET_BASE))
AI_THINKING_STRUCT->aiFlags = 7; // the smartest possible set
AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_TRY_TO_FAINT;
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags;
else
AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
AI_THINKING_STRUCT->aiFlags |= 0x80; // act smart in doubles and don't attack your partner
AI_THINKING_STRUCT->aiFlags |= AI_SCRIPT_DOUBLE_BATTLE; // act smart in doubles and don't attack your partner
}
u8 BattleAI_ChooseMoveOrAction(void)
@ -1127,19 +1122,19 @@ static void BattleAICmd_get_type(void)
switch (typeVar)
{
case 1: // player primary type
case AI_TYPE1_USER: // AI user primary type
AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type1;
break;
case 0: // enemy primary type
case AI_TYPE1_TARGET: // target primary type
AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type1;
break;
case 3: // player secondary type
case AI_TYPE2_USER: // AI user secondary type
AI_THINKING_STRUCT->funcResult = gBattleMons[sBank_AI].type2;
break;
case 2: // enemy secondary type
case AI_TYPE2_TARGET: // target secondary type
AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type2;
break;
case 4: // type of move being pointed to
case AI_TYPE_MOVE: // type of move being pointed to
AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].type;
break;
}
@ -1236,13 +1231,13 @@ static void BattleAICmd_get_how_powerful_move_is(void)
}
if (checkedMove == 4)
AI_THINKING_STRUCT->funcResult = 2; // is the most powerful
AI_THINKING_STRUCT->funcResult = MOVE_MOST_POWERFUL; // is the most powerful
else
AI_THINKING_STRUCT->funcResult = 1; // not most powerful
AI_THINKING_STRUCT->funcResult = MOVE_NOT_MOST_POWERFUL; // not most powerful
}
else
{
AI_THINKING_STRUCT->funcResult = 0; // highly discouraged in terms of power
AI_THINKING_STRUCT->funcResult = MOVE_POWER_DISCOURAGED; // highly discouraged in terms of power
}
gAIScriptPtr++;
@ -1493,7 +1488,7 @@ static void BattleAICmd_get_highest_type_effectiveness(void)
for (i = 0; i < 4; i++)
{
gBattleMoveDamage = 40;
gBattleMoveDamage = AI_EFFECTIVENESS_x1;
gCurrentMove = gBattleMons[sBank_AI].moves[i];
if (gCurrentMove)
@ -1502,16 +1497,16 @@ static void BattleAICmd_get_highest_type_effectiveness(void)
// reduce by 1/3.
if (gBattleMoveDamage == 120)
gBattleMoveDamage = 80;
gBattleMoveDamage = AI_EFFECTIVENESS_x2;
if (gBattleMoveDamage == 240)
gBattleMoveDamage = 160;
gBattleMoveDamage = AI_EFFECTIVENESS_x4;
if (gBattleMoveDamage == 30)
gBattleMoveDamage = 20;
gBattleMoveDamage = AI_EFFECTIVENESS_x0_5;
if (gBattleMoveDamage == 15)
gBattleMoveDamage = 10;
gBattleMoveDamage = AI_EFFECTIVENESS_x0_25;
if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED)
gBattleMoveDamage = 0;
gBattleMoveDamage = AI_EFFECTIVENESS_x0;
if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage)
AI_THINKING_STRUCT->funcResult = gBattleMoveDamage;
@ -1530,22 +1525,22 @@ static void BattleAICmd_if_type_effectiveness(void)
gBattleMoveFlags = 0;
gCritMultiplier = 1;
gBattleMoveDamage = 40;
gBattleMoveDamage = AI_EFFECTIVENESS_x1;
gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
TypeCalc(gCurrentMove, sBank_AI, gBankTarget);
if (gBattleMoveDamage == 120)
gBattleMoveDamage = 80;
gBattleMoveDamage = AI_EFFECTIVENESS_x2;
if (gBattleMoveDamage == 240)
gBattleMoveDamage = 160;
gBattleMoveDamage = AI_EFFECTIVENESS_x4;
if (gBattleMoveDamage == 30)
gBattleMoveDamage = 20;
gBattleMoveDamage = AI_EFFECTIVENESS_x0_5;
if (gBattleMoveDamage == 15)
gBattleMoveDamage = 10;
gBattleMoveDamage = AI_EFFECTIVENESS_x0_25;
if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED)
gBattleMoveDamage = 0;
gBattleMoveDamage = AI_EFFECTIVENESS_x0;
// store gBattleMoveDamage in a u8 variable because gAIScriptPtr[1] is a u8.
damageVar = gBattleMoveDamage;
@ -1618,7 +1613,7 @@ static void BattleAICmd_if_status_not_in_party(void)
break;
}
party = (GetBankSide(bank) == 0) ? gPlayerParty : gEnemyParty;
party = (GetBankSide(bank) == SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2);
@ -1640,13 +1635,13 @@ static void BattleAICmd_if_status_not_in_party(void)
static void BattleAICmd_get_weather(void)
{
if (gBattleWeather & WEATHER_RAIN_ANY)
AI_THINKING_STRUCT->funcResult = 1;
AI_THINKING_STRUCT->funcResult = AI_WEATHER_RAIN;
if (gBattleWeather & WEATHER_SANDSTORM_ANY)
AI_THINKING_STRUCT->funcResult = 2;
AI_THINKING_STRUCT->funcResult = AI_WEATHER_SANDSTORM;
if (gBattleWeather & WEATHER_SUN_ANY)
AI_THINKING_STRUCT->funcResult = 0;
AI_THINKING_STRUCT->funcResult = AI_WEATHER_SUN;
if (gBattleWeather & WEATHER_HAIL_ANY)
AI_THINKING_STRUCT->funcResult = 3;
AI_THINKING_STRUCT->funcResult = AI_WEATHER_HAIL;
gAIScriptPtr += 1;
}
@ -1904,7 +1899,7 @@ static void BattleAICmd_if_has_move_with_effect(void)
case AI_USER_PARTNER:
for (i = 0; i < 4; i++)
{
if(gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2])
if (gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBank_AI].moves[i]].effect == gAIScriptPtr[2])
break;
}
if (i == 4)
@ -1916,6 +1911,7 @@ static void BattleAICmd_if_has_move_with_effect(void)
case AI_TARGET_PARTNER:
for (i = 0; i < 4; i++)
{
// UB: checks sBank_AI instead of gBankTarget
if (gBattleMons[sBank_AI].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[gBankTarget].moves[i]].effect == gAIScriptPtr[2])
break;
}