diff --git a/hooks b/hooks index 3cf893188..e0bb83443 100644 --- a/hooks +++ b/hooks @@ -486,3 +486,5 @@ arm9 form_evo_hook_2 0207641C 0 0002 PlayerStepEvent_RepelCounterDecrement 0224BAE4 2 0015 BagApp_GetRepelStepCountAddr 021F993C 3 #endif + +0012 BattleContext_Main 022486B0 2 diff --git a/include/battle.h b/include/battle.h index 4dc65bc67..55f1a933f 100644 --- a/include/battle.h +++ b/include/battle.h @@ -170,6 +170,7 @@ #define BATTLE_TYPE_ROAMER 0x100 #define BATTLE_TYPE_POKE_PARK 0x200 #define BATTLE_TYPE_CATCHING_DEMO 0x400 +#define BATTLE_TYPE_BUG_CONTEST 0x1000 #define BATTLE_TYPE_NO_EXPERIENCE (BATTLE_TYPE_WIRELESS | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_POKE_PARK) @@ -965,6 +966,28 @@ typedef struct { } TerrainOverlay; +typedef enum BattleSelectState { + SSI_STATE_SELECT_COMMAND_INIT, + SSI_STATE_1, + SSI_STATE_2, + SSI_STATE_3, + SSI_STATE_4, + SSI_STATE_5, + SSI_STATE_6, + SSI_STATE_7, + SSI_STATE_8, + SSI_STATE_9, + SSI_STATE_10, + SSI_STATE_11, + SSI_STATE_12, + SSI_STATE_13, + SSI_STATE_14, + SSI_STATE_15, + SSI_STATE_NO_MOVES, + SSI_STATE_END +} BattleSelectState; + + /** * @brief enum for command field from BattleStruct */ diff --git a/include/battle_controller_player.h b/include/battle_controller_player.h new file mode 100644 index 000000000..ae9111cd8 --- /dev/null +++ b/include/battle_controller_player.h @@ -0,0 +1,14 @@ +#ifndef BATTLE_CONTROLLER_PLAYER_H +#define BATTLE_CONTROLLER_PLAYER_H + +#include "battle.h" + +typedef void (*ControllerFunction)(struct BattleSystem *, struct BattleStruct *); + +extern const ControllerFunction sPlayerBattleCommands[]; + +void LONG_CALL ov12_022639B8(struct BattleSystem *bsys, int battlerId, MESSAGE_PARAM msg); +u8 LONG_CALL BattleSystem_GetBattleOutcomeFlags(struct BattleSystem *bsys); +BOOL LONG_CALL BattleContext_Main(struct BattleSystem *bsys, struct BattleStruct *ctx); + +#endif diff --git a/include/config.h b/include/config.h index fd32d3875..5f045c2df 100644 --- a/include/config.h +++ b/include/config.h @@ -105,4 +105,7 @@ // IMPLEMENT_REUSABLE_REPELS defines whether or not a prompt to use another repel automatically appears upon the previous repel being used up #define IMPLEMENT_REUSABLE_REPELS +// DISABLE_ITEMS_IN_TRAINER_BATTLE will disable the usage of items in trainer battles. This is also true for the AI. +//#define DISABLE_ITEMS_IN_TRAINER_BATTLE + #endif diff --git a/include/constants/battle_message_constants.h b/include/constants/battle_message_constants.h index faa2549bc..1be1d4d9a 100644 --- a/include/constants/battle_message_constants.h +++ b/include/constants/battle_message_constants.h @@ -12,6 +12,8 @@ #define BATTLE_MSG_MON_KNOCKED_OFF_ITEM (552) +#define BATTLE_MSG_ITEMS_CANT_BE_USED_HERE (593) + #define BATTLE_MSG_CANNOT_USE_MOVE_DISABLED (609) #define BATTLE_MSG_CANNOT_USE_MOVE_TORMENT (612) #define BATTLE_MSG_CANNOT_USE_MOVE_TAUNT (613) diff --git a/rom.ld b/rom.ld index c2cfbf6f2..3e62c4a86 100644 --- a/rom.ld +++ b/rom.ld @@ -665,3 +665,7 @@ BattleContext_CheckMoveHealBlocked = 0x02252DF8 | 1; CanUseItemOnPokemon = 0x0208FD9C | 1; BagApp_GetSaveRoamers = 0x021F992C | 1; + +sPlayerBattleCommands = 0x0226CA90; +BattleSystem_GetBattleOutcomeFlags = 0x0223BD14 | 1; +ov12_022639B8 = 0x022639B8 | 1; diff --git a/src/battle/battle_controller_player.c b/src/battle/battle_controller_player.c new file mode 100644 index 000000000..70fe34af2 --- /dev/null +++ b/src/battle/battle_controller_player.c @@ -0,0 +1,49 @@ +#include "../../include/battle.h" +#include "../../include/battle_controller_player.h" +#include "../../include/constants/battle_message_constants.h" + +#if defined (DISABLE_ITEMS_IN_TRAINER_BATTLE) +void overrideItemUsage(struct BattleSystem *bsys, struct BattleStruct *ctx) +{ + MESSAGE_PARAM mp; + int battlerId; + u32 fight_type = BattleTypeGet(bsys); + + for (battlerId = 0; battlerId < bsys->maxBattlers; battlerId++) + { + if (ctx->playerActions[battlerId][0] == CONTROLLER_COMMAND_ITEM_INPUT && ctx->com_seq_no[battlerId] == 7) + { + if (fight_type & BATTLE_TYPE_TRAINER) + { + mp.msg_id = BATTLE_MSG_ITEMS_CANT_BE_USED_HERE; //msg.id = msg_0197_00593; // Items can't be used here + mp.msg_tag = TAG_NONE; + ov12_022639B8(bsys, battlerId, mp); + ctx->com_seq_no[battlerId] = SSI_STATE_15; + ctx->ret_seq_no[battlerId] = SSI_STATE_SELECT_COMMAND_INIT; + } + } + } +} +#endif + +BOOL LONG_CALL BattleContext_Main(struct BattleSystem *bsys, struct BattleStruct *ctx) +{ + if (!ctx->fight_end_flag) + { + if (BattleSystem_GetBattleOutcomeFlags(bsys) && !(BattleSystem_GetBattleOutcomeFlags(bsys) & 0x40)) + { + ctx->server_seq_no = CONTROLLER_COMMAND_42; + } + } + + sPlayerBattleCommands[ctx->server_seq_no](bsys, ctx); +#if defined (DISABLE_ITEMS_IN_TRAINER_BATTLE) + overrideItemUsage(bsys, ctx); +#endif + + if (ctx->server_seq_no == CONTROLLER_COMMAND_45) + { + return TRUE; + } + return FALSE; +}