mirror of
https://github.com/pret/pokeemerald.git
synced 2026-09-25 19:37:27 -05:00
Fixes octolock not ending after user switched out (#7556)
Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
This commit is contained in:
@@ -12,36 +12,33 @@ In general, `gBattlescriptCurrInstr` tracks the current battle script position a
|
||||
```
|
||||
`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.
|
||||
|
||||
Now, how might we add a custom `callnative` command? Here are the steps. We will use `BS_TrySetOctolock` as an example.
|
||||
Now, how might we add a custom `callnative` command? Here are the steps. We will use `BS_JumpIfTerrainAffected` as an example.
|
||||
### 1. Create a macro in `asm/macros/battle_script.inc`. For example:
|
||||
```c
|
||||
.macro trysetoctolock battler:req, failInstr:req
|
||||
callnative BS_TrySetOctolock
|
||||
.macro jumpifterrainaffected battler:req, terrainFlags:req, jumpInstr:req
|
||||
callnative BS_JumpIfTerrainAffected
|
||||
.byte \battler
|
||||
.4byte \failInstr
|
||||
.4byte \terrainFlags
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
```
|
||||
### 2. Add your new callnative command ID to `src/battle_script_commands.c`. For example:
|
||||
```c
|
||||
void BS_TrySetOctolock(void)
|
||||
void BS_JumpIfTerrainAffected(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler, const u8 *failInstr);
|
||||
NATIVE_ARGS(u8 battler, u32 flags, const u8 *jumpInstr);
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
|
||||
if (gDisableStructs[battler].octolock)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
if (IsBattlerTerrainAffected(battler, cmd->flags))
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
else
|
||||
{
|
||||
gDisableStructs[battler].octolock = TRUE;
|
||||
gBattleMons[battler].status2 |= STATUS2_ESCAPE_PREVENTION;
|
||||
gDisableStructs[battler].battlerPreventingEscape = gBattlerAttacker;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
```
|
||||
Each of the arguments defined in the macro (`battler`, `failInstr`) need to be called at the start of the command using `NATIVE_ARGS`.
|
||||
Each of the arguments defined in the macro (`battler`, `flags`, `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.
|
||||
These arguments can then be accessed as `cmd->battler`, `cmd->flags` and `cmd->failInstr`.
|
||||
Note that for `cmd->battler` we need to use `GetBattlerForBattleScript` to fetch the correct battler because with the macro we are accessing a scripting command that doesn't corresponds to `gBattlerTarget`, `gBattlerAttacker`, etc.
|
||||
For the battler argument specifically, most of the time the battler is accessed through `gBattlerAttacker`, `gBattlerTarget` and the battler argument left out.
|
||||
In the majority of cases, this is fine since the script commands are mostly used for moves and the interaction is usually between an attacker and target.
|
||||
A script command usually ends with either a jump or next instruction `gBattlescriptCurrInstr = cmd->nextInstr / cmd->nextInstr;` advancing to the next instruction.
|
||||
|
||||
Reference in New Issue
Block a user