So, with no further ado, I'll stick a basic script here!
Code:
#dynamic 0x720000
#freespacebyte 0xFF
#include moves.bsh
#org @start
attackcanceler
accuracycheck 0x1D695E 0x0
attackstring
ppreduce
calculatedamage
attackanimation
waitanimation
cmd5c 0x0
waitstate
datahpupdate 0x0
graphicalhpupdate 0x0
critmessage
waitmessage 0x40
resultmessage
waitmessage 0x40
goto 0x1D6947
Now, that looks really nasty, so lets break it down line by line and explain why each line is in the script and why (in some cases) it is where it is.
Just like XSE, you can define a dynamic position to search for free space from. The tool will search for enough free space for each script fragment (explained later) and insert it into the free space. Defines the start location for the search to 0x720000. Speaking of free space...
Code:
#freespacebyte 0xFF
This defines what is regarded as free space by the tool. If you skip this definition, the tool assumes the Free Space Byte is 0xFF.
Includes the header file moves.bsh. This header file is full of definitions for the moves, which lets you refer to a move by "MOVE_POUND" instead of having to remember its index number.
The header files which come bundled with the tool are:
moves.bsh
pokemon.bsh
abilities.bsh
items.bsh
Note: there is a special header file called commands.bsh which I will get to later.
Note 2: You can define custom header files if you so desire.
Note 3: std.bsh is included (that is, the definitions in it are loaded into memory) by default, you don't need to #include it
This line contains 2 important things. Firstly, the #org, which defines that this is the start of a script fragment. What is a script fragment, you ask? Well, it's simply the part of a script between the opening command and the "ending" command.
A whole script is usually made up of several script fragments which occur due to conditional branches.
Secondly, @start. This, like XSE, is a dynamic pointer, in that it allows you to dynamically assign the offsets to script fragments and branches. Certainly makes writing scripts easier, IMO.
The name given to this command is very unfair as it really underplays what it actually does. Long story short, it checks for attack canceling statuses (like paralysis, being frozen, being asleep and such) and runs the calculations which cancel the attack. It silently branches to a completely separate script if needed.
It ALSO checks things like Protect/Detect, Turns of sleep (waking the user up if there are 0 turns of sleep left) and runs a chanced calculation on whether or not to defrost a frozen user.
As you can see, it does a LOT. Due to its nature, you MUST only include this command once in the script's lifetime, as by its nature, if you have it twice, it becomes twice as likely to be paralysed, in love etc.
Code:
accuracycheck 0x1D695E 0x0
This command does what it says on the tin. If you want your attack to never miss, you must NOT put this command in. There is a completely alternative method for moves which never miss (except for missing when the target is in the semi-invulnerable states).
0x1D695E is the address of the alternate script which gets branched to IF the attack misses.
0x0 is an unknown half-word. It
may control the likelihood of missing or something, I dunno.
This prints "Pokémon used Attack!" to the screen. Does nothing else.
As the name implies, reduces PP of used attack. Note that the effect of Pressure is calculated here.
This is an alias/super command. What that means is that on compilation, it compiles out to several commands which have the effect named. As the name suggests, it calculates the damage the attack will do to the opponent, including type effectiveness, special/physical effects, base damage (excluding only a handful of attacks), and stat increases/decreases.
Plays the animation of the attack. Simple as that.
Waits for the animation started above to complete.
Not entirely sure what this command does. I think it applies the effectiveness noise plus the little flash to indicate that damage has happened.
The 0x0 signifies which banked Pokémon to apply this to. (Wait, what? What does "Banked Pokémon mean?)
In battle scripting there are several banks, used to refer to the battling Pokémon. That is, there are a handful of memory locations which contain references to the battling Pokémon. The banks (as used here) refer to those memory locations. Convoluted, eh?
Anyway, to use them, know that:
So what this means is "Apply the damage noise/animation to the target".
Simply pauses script execution and waits for the previous command to finish. Only works for certain commands.
Physically updates the data behind to have the new HP value.
The 0x0 is the bank again.
Code:
graphicalhpupdate 0x0
Updates the HP bar on screen, scrolling it down towards the value stored in the data. Note that this MUST go AFTER the datahpupdate command (or equivalent ASM), otherwise, nothing will happen.
The 0x0 is, once again, the bank.
Displays a message saying the attack was a critical hit if the attack was a critical hit.
Without this, the message would flash on screen and then the script would continue. This simply delays the script's execution so that the message can be read.
The 0x40 equates to about 1 second in real time.
This picks the relevant message to display and displays it.
Messages can be like:
"It had no effect!"
"It wasn't very effective..."
and so on.
Now, you might be wondering why I didn't end the script with an "end" command like most scripting languages would. There is a very simple reason for this, and that is, everything you need to handle after this point can be handled by the "regular" script.
In fact, this whole script is pointless (as the "regular" script has all of these commands and more), but for demonstration purposes, it's a good start.
Anyway, the goto does what its name implies, it simply jumps, no questions asked, to the given address.
0x1D6947 is (in FireRed) where you would want to jump to in order to have an additional effect executed. Note that, if you supply a hardcoded address like this, the tool will add 0x08000000 to it IFF (if and only if) the address you supply is LESS than 0x02000000.
This means that ROM addresses can be referenced by the 6 digit location and do not require the 8 in front of them. However, if you include the 8 it still works. It also means that RAM addresses are unaffected by this logic, so if you refer to 0x02023D4A, then it compiles it verbatim.
So, I've walked you through the basic damage structure, but we haven't done anything particularly interesting yet!