Skip to content

Commit

Permalink
Changes Various defines to an Enum (#5840)
Browse files Browse the repository at this point in the history
Co-authored-by: Bassoonian <[email protected]>
Co-authored-by: Alex <[email protected]>
  • Loading branch information
3 people authored Dec 21, 2024
1 parent c313319 commit e175c5a
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 173 deletions.
76 changes: 36 additions & 40 deletions docs/tutorials/how_to_battle_script_command_macro.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,47 @@
## How to add new Battle Script Commands/Macros

To preface this tutorial, the battle engine upgrade has exhausted all battle script command IDs, and instead uses the `various` command to effectively add new commands. This is preferential to creating a secondary battle script command table like is done in the CFRU.
To preface this tutorial, the battle engine upgrade has exhausted all battle script command IDs. Historically, we've used the `various` command to effectively add new commands. However, this has caused issues of maintainability and readability due to the massive switch needed for it. Thanks to the cleanup made by the team and contributors, we now are able to call an infinite amount of commands by using `callnative`. This is preferential to creating a secondary battle script command table like is done in the CFRU.

In general, `gBattlescriptCurrInstr` tracks the current battle script position as a ROM address. Fortunately, we don't need to worry about ROM addresses when using the decomps, but it is important to understand because of how the `various` command is set up.
In general, `gBattlescriptCurrInstr` tracks the current battle script position as a ROM address. Fortunately, we don't need to worry about ROM addresses when using the decomps, but it is important to understand because of how the `callnative` command is set up.

```
.macro various battler:req, param1:req
.byte 0x76
.byte \battler
.byte \param1
.endm
.macro callnative func:req
.byte 0xff
.4byte \func
.endm
```
`callnative` uses the last battle script command ID in order to pass a native function as an argument. Additional optional arguments are added recursively via a macro, so no need to worry about how they need to align to the amount of instructions to skip.

`various` is 3 bytes in size, so if we wanted to advance to the next battle script command, we would write `gBattlescriptCurrInstr += 3`. Coincidentally, this is found at the end of `Cmd_Various` in `src/battle_script_commands.c`.

Now, how might we add a custom various command case? Here are the steps. We will use `VARIOUS_SET_SIMPLE_BEAM` as an example.
### 1. Add a definition to `include/constants/battle_script_commands.h`.

For example, `#define VARIOUS_SET_SIMPLE_BEAM 39`

### 2. Create a macro in `asm/macros/battle_script.inc`. For example:
Now, how might we add a custom `callnative` command? Here are the steps. We will use `BS_TrySetOctolock` as an example.
### 1. Create a macro in `asm/macros/battle_script.inc`. For example:
```c
.macro setabilitysimple battler:req, ptr:req
various \battler VARIOUS_SET_SIMPLE_BEAM
.4byte \ptr
.endm
.macro trysetoctolock battler:req, failInstr:req
callnative BS_TrySetOctolock
.byte \battler
.4byte \failInstr
.endm
```

### 3. Add your new various command ID to `Cmd_Various`. For example:
### 2. Add your new callnative command ID to `src/battle_script_commands.c`. For example:
```c
case VARIOUS_SET_SIMPLE_BEAM:
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)
|| gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
}
else
{
gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE;
RecordAbilityBattle(gActiveBattler, ABILITY_SIMPLE);
gBattlescriptCurrInstr += 7;
}
return;
void BS_TrySetOctolock(void)
{
NATIVE_ARGS(u8 battler, const u8 *failInstr);
u32 battler = GetBattlerForBattleScript(cmd->battler);

if (gDisableStructs[battler].octolock)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
gDisableStructs[battler].octolock = TRUE;
gBattleMons[battler].status2 |= STATUS2_ESCAPE_PREVENTION;
gDisableStructs[battler].battlerPreventingEscape = gBattlerAttacker;
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
```
The macros' `battler` argument is the battler who will be affected/considered by your command. In our case, which battler we will try to give `ABILITY_SIMPLE`. Note that `gActiveBattler` is always set to this battler at the beginning of `Cmd_Various`.
The `ptr` argument is an extra argument that, in this case, provides a battle script to jump to in the event that we fail to set `ABILITY_SIMPLE`. We must add the `.4byte \ptr` inside our macro. So now when we want to advance to the next battle script command in our script, we must increment `gBattlescriptCurrInstr` by `7` because our overall macro is 3 bytes for the various command, and 4 bytes for the pointer. *IMPORTANT* the `return` at the end of the switch case is required because remember that `various` always defaults to `gBattlescriptCurrInstr += 3` at the very end of the function, so if we included `gBattlescriptCurrInstr += 7` with a `break`, we would end up effectively doing `gBattlescriptCurrInstr += 10`.
This behavior can be found under the `else` statement in the example above, corresponding to `ABILITY_SIMPLE` being correctly applied. If we are unable to set `ABILITY_SIMPLE`, however, notice the following `gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);`. This means we are jumping to the battle script provided by the pointer 3 bytes after our various command (which is the `ptr` argument described previously). We still must `return` or else we would actually jump to 3 bytes after the `ptr` battle script begins.
Each of the arguments defined in the macro (`battler`, `failInstr`) need to be called at the start of the command using `NATIVE_ARGS`.
The byte count in the macro should correspond to the type that will be used for the command (eg, `u8` is `byte`, while the pointer are `4byte`).
These arguments can then be accessed as `cmd->battler` and `cmd->battler`.
`gBattlescriptCurrInstr = cmd->nextInstr;` advances to the next instruction.
264 changes: 132 additions & 132 deletions include/constants/battle_script_commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,138 +88,138 @@
#define CMP_COMMON_BITS 4
#define CMP_NO_COMMON_BITS 5

// Cmd_various
#define VARIOUS_CANCEL_MULTI_TURN_MOVES 0
#define VARIOUS_IS_RUNNING_IMPOSSIBLE 1
#define VARIOUS_GET_MOVE_TARGET 2
#define VARIOUS_GET_BATTLER_FAINTED 3
#define VARIOUS_RESET_SWITCH_IN_ABILITY_BITS 4
#define VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP 5
#define VARIOUS_RESET_PLAYER_FAINTED 6
#define VARIOUS_PALACE_FLAVOR_TEXT 7
#define VARIOUS_ARENA_JUDGMENT_WINDOW 8
#define VARIOUS_ARENA_OPPONENT_MON_LOST 9
#define VARIOUS_ARENA_PLAYER_MON_LOST 10
#define VARIOUS_ARENA_BOTH_MONS_LOST 11
#define VARIOUS_EMIT_YESNOBOX 12
#define VARIOUS_DRAW_ARENA_REF_TEXT_BOX 13
#define VARIOUS_ERASE_ARENA_REF_TEXT_BOX 14
#define VARIOUS_ARENA_JUDGMENT_STRING 15
#define VARIOUS_ARENA_WAIT_STRING 16
#define VARIOUS_WAIT_CRY 17
#define VARIOUS_RETURN_OPPONENT_MON1 18
#define VARIOUS_RETURN_OPPONENT_MON2 19
#define VARIOUS_VOLUME_DOWN 20
#define VARIOUS_VOLUME_UP 21
#define VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT 22
#define VARIOUS_PALACE_TRY_ESCAPE_STATUS 23
#define VARIOUS_SET_TELEPORT_OUTCOME 24
#define VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC 25
#define VARIOUS_STAT_TEXT_BUFFER 26
#define VARIOUS_SWITCHIN_ABILITIES 27
#define VARIOUS_INSTANT_HP_DROP 28
#define VARIOUS_CLEAR_STATUS 29
#define VARIOUS_RESTORE_PP 30
#define VARIOUS_TRY_ACTIVATE_MOXIE 31
#define VARIOUS_TRY_ACTIVATE_FELL_STINGER 32
#define VARIOUS_PLAY_MOVE_ANIMATION 33
#define VARIOUS_SET_LUCKY_CHANT 34
#define VARIOUS_SUCKER_PUNCH_CHECK 35
#define VARIOUS_SET_SIMPLE_BEAM 36
#define VARIOUS_TRY_ENTRAINMENT 37
#define VARIOUS_SET_LAST_USED_ABILITY 38
#define VARIOUS_INVERT_STAT_STAGES 39
#define VARIOUS_TRY_ME_FIRST 40
#define VARIOUS_JUMP_IF_BATTLE_END 41
#define VARIOUS_TRY_ELECTRIFY 42
#define VARIOUS_TRY_REFLECT_TYPE 43
#define VARIOUS_TRY_SOAK 44
#define VARIOUS_HANDLE_MEGA_EVO 45
#define VARIOUS_TRY_LAST_RESORT 46
#define VARIOUS_SET_ARG_TO_BATTLE_DAMAGE 47
#define VARIOUS_TRY_AUTOTOMIZE 48
#define VARIOUS_ABILITY_POPUP 49
#define VARIOUS_JUMP_IF_TARGET_ALLY 50
#define VARIOUS_TRY_SYNCHRONOISE 51
#define VARIOUS_PSYCHO_SHIFT 52
#define VARIOUS_CURE_STATUS 53
#define VARIOUS_POWER_TRICK 54
#define VARIOUS_AFTER_YOU 55
#define VARIOUS_BESTOW 56
#define VARIOUS_JUMP_IF_NOT_GROUNDED 57
#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 58
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 59
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 60
#define VARIOUS_SET_AURORA_VEIL 61
#define VARIOUS_TRY_THIRD_TYPE 62
#define VARIOUS_ACUPRESSURE 63
#define VARIOUS_SET_POWDER 64
#define VARIOUS_SPECTRAL_THIEF 65
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 66
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 67
#define VARIOUS_JUMP_IF_ROAR_FAILS 68
#define VARIOUS_TRY_INSTRUCT 69
#define VARIOUS_JUMP_IF_NOT_BERRY 70
#define VARIOUS_TRACE_ABILITY 71
#define VARIOUS_UPDATE_NICK 72
#define VARIOUS_TRY_ILLUSION_OFF 73
#define VARIOUS_SET_SPRITEIGNORE0HP 74
#define VARIOUS_HANDLE_FORM_CHANGE 75
#define VARIOUS_GET_STAT_VALUE 76
#define VARIOUS_JUMP_IF_FULL_HP 77
#define VARIOUS_LOSE_TYPE 78
#define VARIOUS_TRY_ACTIVATE_SOULHEART 79
#define VARIOUS_TRY_ACTIVATE_RECEIVER 80
#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 81
#define VARIOUS_TRY_FRISK 82
#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 83
#define VARIOUS_TRY_FAIRY_LOCK 84
#define VARIOUS_JUMP_IF_NO_ALLY 85
#define VARIOUS_POISON_TYPE_IMMUNITY 86
#define VARIOUS_JUMP_IF_HOLD_EFFECT 87
#define VARIOUS_INFATUATE_WITH_BATTLER 88
#define VARIOUS_SET_LAST_USED_ITEM 89
#define VARIOUS_PARALYZE_TYPE_IMMUNITY 90
#define VARIOUS_JUMP_IF_ABSENT 91
#define VARIOUS_DESTROY_ABILITY_POPUP 92
#define VARIOUS_TOTEM_BOOST 93
#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 94
#define VARIOUS_MOVEEND_ITEM_EFFECTS 95
#define VARIOUS_TERRAIN_SEED 96
#define VARIOUS_MAKE_INVISIBLE 97
#define VARIOUS_ROOM_SERVICE 98
#define VARIOUS_EERIE_SPELL_PP_REDUCE 99
#define VARIOUS_JUMP_IF_TEAM_HEALTHY 100
#define VARIOUS_TRY_HEAL_QUARTER_HP 101
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 102
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 103
#define VARIOUS_GET_ROTOTILLER_TARGETS 104
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 105
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 106
#define VARIOUS_CONSUME_BERRY 107
#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 108
#define VARIOUS_JUMP_IF_SPECIES 109
#define VARIOUS_UPDATE_ABILITY_POPUP 110
#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 111
#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 112
#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 113
#define VARIOUS_TRY_NO_RETREAT 114
#define VARIOUS_CHECK_POLTERGEIST 115
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 116
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 117
#define VARIOUS_JUMP_IF_UNDER_200 118
#define VARIOUS_SET_SKY_DROP 119
#define VARIOUS_CLEAR_SKY_DROP 120
#define VARIOUS_SKY_DROP_YAWN 121
#define VARIOUS_CURE_CERTAIN_STATUSES 122
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 123
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 124
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 125
#define VARIOUS_SAVE_BATTLER_ITEM 126
#define VARIOUS_RESTORE_BATTLER_ITEM 127
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 128
#define VARIOUS_SWAP_SIDE_STATUSES 129
#define VARIOUS_SWAP_STATS 130
enum CmdVarious
{
VARIOUS_CANCEL_MULTI_TURN_MOVES,
VARIOUS_IS_RUNNING_IMPOSSIBLE,
VARIOUS_GET_MOVE_TARGET,
VARIOUS_GET_BATTLER_FAINTED,
VARIOUS_RESET_SWITCH_IN_ABILITY_BITS,
VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP,
VARIOUS_RESET_PLAYER_FAINTED,
VARIOUS_PALACE_FLAVOR_TEXT,
VARIOUS_ARENA_JUDGMENT_WINDOW,
VARIOUS_ARENA_OPPONENT_MON_LOST,
VARIOUS_ARENA_PLAYER_MON_LOST,
VARIOUS_ARENA_BOTH_MONS_LOST,
VARIOUS_EMIT_YESNOBOX,
VARIOUS_DRAW_ARENA_REF_TEXT_BOX,
VARIOUS_ERASE_ARENA_REF_TEXT_BOX,
VARIOUS_ARENA_JUDGMENT_STRING,
VARIOUS_ARENA_WAIT_STRING,
VARIOUS_WAIT_CRY,
VARIOUS_RETURN_OPPONENT_MON1,
VARIOUS_RETURN_OPPONENT_MON2,
VARIOUS_VOLUME_DOWN,
VARIOUS_VOLUME_UP,
VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT,
VARIOUS_PALACE_TRY_ESCAPE_STATUS,
VARIOUS_SET_TELEPORT_OUTCOME,
VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC,
VARIOUS_STAT_TEXT_BUFFER,
VARIOUS_SWITCHIN_ABILITIES,
VARIOUS_INSTANT_HP_DROP,
VARIOUS_CLEAR_STATUS,
VARIOUS_RESTORE_PP,
VARIOUS_TRY_ACTIVATE_MOXIE,
VARIOUS_TRY_ACTIVATE_FELL_STINGER,
VARIOUS_PLAY_MOVE_ANIMATION,
VARIOUS_SET_LUCKY_CHANT,
VARIOUS_SUCKER_PUNCH_CHECK,
VARIOUS_SET_SIMPLE_BEAM,
VARIOUS_TRY_ENTRAINMENT,
VARIOUS_SET_LAST_USED_ABILITY,
VARIOUS_INVERT_STAT_STAGES,
VARIOUS_TRY_ME_FIRST,
VARIOUS_JUMP_IF_BATTLE_END,
VARIOUS_TRY_ELECTRIFY,
VARIOUS_TRY_SOAK,
VARIOUS_TRY_LAST_RESORT,
VARIOUS_SET_ARG_TO_BATTLE_DAMAGE,
VARIOUS_TRY_AUTOTOMIZE,
VARIOUS_ABILITY_POPUP,
VARIOUS_JUMP_IF_TARGET_ALLY,
VARIOUS_TRY_SYNCHRONOISE,
VARIOUS_PSYCHO_SHIFT,
VARIOUS_CURE_STATUS,
VARIOUS_POWER_TRICK,
VARIOUS_AFTER_YOU,
VARIOUS_BESTOW,
VARIOUS_JUMP_IF_NOT_GROUNDED,
VARIOUS_HANDLE_TRAINER_SLIDE_MSG,
VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF,
VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON,
VARIOUS_SET_AURORA_VEIL,
VARIOUS_TRY_THIRD_TYPE,
VARIOUS_ACUPRESSURE,
VARIOUS_SET_POWDER,
VARIOUS_SPECTRAL_THIEF,
VARIOUS_GRAVITY_ON_AIRBORNE_MONS,
VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS,
VARIOUS_JUMP_IF_ROAR_FAILS,
VARIOUS_TRY_INSTRUCT,
VARIOUS_JUMP_IF_NOT_BERRY,
VARIOUS_TRACE_ABILITY,
VARIOUS_UPDATE_NICK,
VARIOUS_TRY_ILLUSION_OFF,
VARIOUS_SET_SPRITEIGNORE0HP,
VARIOUS_HANDLE_FORM_CHANGE,
VARIOUS_GET_STAT_VALUE,
VARIOUS_JUMP_IF_FULL_HP,
VARIOUS_LOSE_TYPE,
VARIOUS_TRY_ACTIVATE_SOULHEART,
VARIOUS_TRY_ACTIVATE_RECEIVER,
VARIOUS_TRY_ACTIVATE_BEAST_BOOST,
VARIOUS_TRY_FRISK,
VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED,
VARIOUS_TRY_FAIRY_LOCK,
VARIOUS_JUMP_IF_NO_ALLY,
VARIOUS_POISON_TYPE_IMMUNITY,
VARIOUS_JUMP_IF_HOLD_EFFECT,
VARIOUS_INFATUATE_WITH_BATTLER,
VARIOUS_SET_LAST_USED_ITEM,
VARIOUS_PARALYZE_TYPE_IMMUNITY,
VARIOUS_JUMP_IF_ABSENT,
VARIOUS_DESTROY_ABILITY_POPUP,
VARIOUS_TOTEM_BOOST,
VARIOUS_TRY_ACTIVATE_GRIM_NEIGH,
VARIOUS_MOVEEND_ITEM_EFFECTS,
VARIOUS_TERRAIN_SEED,
VARIOUS_MAKE_INVISIBLE,
VARIOUS_ROOM_SERVICE,
VARIOUS_EERIE_SPELL_PP_REDUCE,
VARIOUS_JUMP_IF_TEAM_HEALTHY,
VARIOUS_TRY_HEAL_QUARTER_HP,
VARIOUS_JUMP_IF_PRANKSTER_BLOCKED,
VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER,
VARIOUS_GET_ROTOTILLER_TARGETS,
VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED,
VARIOUS_TRY_ACTIVATE_BATTLE_BOND,
VARIOUS_CONSUME_BERRY,
VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL,
VARIOUS_JUMP_IF_SPECIES,
VARIOUS_UPDATE_ABILITY_POPUP,
VARIOUS_JUMP_IF_WEATHER_AFFECTED,
VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED,
VARIOUS_SET_ATTACKER_STICKY_WEB_USER,
VARIOUS_TRY_NO_RETREAT,
VARIOUS_CHECK_POLTERGEIST,
VARIOUS_CUT_1_3_HP_RAISE_STATS,
VARIOUS_TRY_END_NEUTRALIZING_GAS,
VARIOUS_JUMP_IF_UNDER_200,
VARIOUS_SET_SKY_DROP,
VARIOUS_CLEAR_SKY_DROP,
VARIOUS_SKY_DROP_YAWN,
VARIOUS_CURE_CERTAIN_STATUSES,
VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES,
VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY,
VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT,
VARIOUS_SAVE_BATTLER_ITEM,
VARIOUS_RESTORE_BATTLER_ITEM,
VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM,
VARIOUS_SWAP_SIDE_STATUSES,
VARIOUS_SWAP_STATS,
};

// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0
Expand Down
3 changes: 2 additions & 1 deletion src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -9146,13 +9146,14 @@ static void Cmd_various(void)
s32 i;
u8 data[10];
u32 battler, bits;
enum CmdVarious variousId = cmd->id;

if (gBattleControllerExecFlags)
return;

battler = GetBattlerForBattleScript(cmd->battler);

switch (cmd->id)
switch (variousId)
{
// Roar will fail in a double wild battle when used by the player against one of the two alive wild mons.
// Also when an opposing wild mon uses it againt its partner.
Expand Down

0 comments on commit e175c5a

Please sign in to comment.