The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > ROM Hacking > Tools, Tutorials & Resources
Sign Up Rules/FAQ Live Battle Blogs Mark Forums Read

Notices

Tools, Tutorials & Resources Various tools to help you develop your hacks can be found here.
New threads in this forum are to be approved by a moderator before they are displayed.


Reply
 
Thread Tools
  #1    
Old March 25th, 2013, 02:14 AM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Hello there, as you may have noticed recently, I released a Battle Script Editor called Battle Script Pro. The problem is, apart from myself, no-one really knows how to use it, or even what most of the commands do!

Here, I will walk through the basics of making basic attacks, and how to get basic added effects working.

Before we get started, I should make this clear. Battle Script Pro will support, and parse, any number formatted in Binary, Octal, Decimal, Hexadecimal and Thornal.
Spoiler:
Binary (Base 2) Formatting:
Code:
[XXXXXXXX]
{XXXXXXXX}
0bXXXXXXXX
XXXXXXXXb
Octal (Base 8) Formatting:
Code:
0oXX
Decimal (Base 10) Formatting:
Code:
XX
Hexadecimal (Base 16) Formatting:
Code:
0xXX
$XX
&HXX
XXh
Thornal (Base 32) Formatting:
Code:
0tXX
XXt
Where the XX's stand for any given digit valid in the number set you are using. The maximum length of any value you put in is 32 bits long (0xFFFFFFFF), so don't use a value higher than that.

Code:
0b1000001000 = 0o1010 = 520 = 0x208 = 0tG8
For reference on using thornal and octal, if you're unsure and are curious, Wikipedia has some good articles about them. Thornal in BSP uses the "Extended Hex Character Set".


Basic Damaging Attack:
Spoiler:
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.

Code:
#dynamic 0x720000
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.

Code:
#include moves.bsh
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

Code:
#org @start
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.

Code:
attackcanceler
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.

Code:
attackstring
This prints "Pokémon used Attack!" to the screen. Does nothing else.

Code:
ppreduce
As the name implies, reduces PP of used attack. Note that the effect of Pressure is calculated here.

Code:
damagecalculation
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.

Code:
attackanimation
Plays the animation of the attack. Simple as that.

Code:
waitanimation
Waits for the animation started above to complete.

Code:
cmd5c 0x0
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:
Spoiler:
0x0 - Target
0x1 - User



So what this means is "Apply the damage noise/animation to the target".

Code:
waitstate
Simply pauses script execution and waits for the previous command to finish. Only works for certain commands.

Code:
datahpupdate 0x0
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.

Code:
critmessage
Displays a message saying the attack was a critical hit if the attack was a critical hit.

Code:
waitmessage 0x40
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.

Code:
resultmessage
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.

Code:
goto 0x1D6947
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!



Status Inflicting Moves:
Spoiler:
This is actually relatively simple compared to doing damage, especially as I've already explained a lot of the commands above!

Code:
#dynamic 0x720000
#freespacebyte 0xFF

#include moves.bsh

#org @start
attackcanceler
accuracycheck 0x1D695E 0x0
setbyte 0x02023E85 0xX
attackstring
ppreduce
attackanimation
waitanimation
seteffectwithchancetarget
goto 0x1D694E
So, what's changed? Well, obviously, Damage calculation has been removed, as the move does no direct damage, as have the HP updating commands. However, there are two brand new commands here, as well as the branch having changed.

Code:
setbyte 0x02023E85 0xX
This command is equivalent to strb in ASM. It literally stores the byte (0xX) into memory location 0x02023E85. Needless to say, it will store any given byte into any given RAM Address, not just the ones I used.

0x02023E85 is the effect chooser in FireRed. The byte stored in here is used later to determine the move's primary effect.

The 0xX is what you change! You put here the relevant byte for inflicting a status on the target. Possible bytes are:
Spoiler:
0x1 - Sleep
0x2 - Poison
0x3 - Burn
0x4 - Freeze
0x5 - Paralysis
0x6 - Badly Poison


Note, I need to check these, but I do know that sleep is right.


Code:
seteffectwithchancetarget
Catchy name for a command, huh? This, as the name implies, runs a random calculation against the likelihood stored in the move's data for the effect to happen, and if that check passes, checks if the target can get the status, and if so, applies the status to the target. Note, however, that it is better practice to explicitly check earlier in the script for whether it can get the status or not!

It reads 0x02023E85 to get which effect to execute, hence our storing of a value to there earlier in the script.

This command takes care of calling the scripts necessary to display the symbol on the HP bars, and putting text on the screen, so don't concern yourself with that!

The location of the goto has changed once again, this is simply because we are skipping a few commands from the "regular" script as they are unnecessary.



Damage AND Status Inflicting Moves:
Spoiler:
This is quite simple, as it's just the first script plus two commands!

Code:
#dynamic 0x720000
#freespacebyte 0xFF

#include moves.bsh

#org @start
setbyte 0x02023E85 0xX
attackcanceler
accuracycheck 0x1D695E 0x0
attackstring
ppreduce
calculatedamage
attackanimation
waitanimation
cmd5c 0x0
waitstate
datahpupdate 0x0
graphicalhpupdate 0x0
critmessage
waitmessage 0x40
resultmessage
waitmessage 0x40
seteffectwithchancetarget
goto 0x1D694E
Incredibly easy, eh?

Note that you can replace seteffectwithchancetarget with seteffecttarget and seteffectuser. The commands have the same effect (giving a Pokémon a status), it simply changes whether there's random chance involved, and who the status will actually effect.

OK, so far, I've equipped you with the very basics of battle scripting. There's still a long way to go, though, as I've only covered about 20 commands, when there are nearly 250!


Attacks That Don't Miss and Special Status Flags:
Spoiler:
This is quite easy, as you're simply replacing a single command with another, less obvious, command. I'll use the basic attack as an example.

Code:
#dynamic 0x720000
#freespacebyte 0xFF

#include moves.bsh

#org @start
attackcanceler
jumpifspecialstatusflag 0x0 0x400C0 0x0 0x1D695E
attackstring
ppreduce
calculatedamage
attackanimation
waitanimation
cmd5c 0x0
waitstate
datahpupdate 0x0
graphicalhpupdate 0x0
critmessage
waitmessage 0x40
resultmessage
waitmessage 0x40
goto 0x1D6947
You probably noticed, I directly replaced accuracycheck with something called jumpifspecialstatusflag. Confused? Can't say I blame you if you are! So, some background information is probably required here.

A Special Status bit is simply a bit in memory assigned to a given Pokémon which indicates that the Pokémon is currently undergoing some form of special status. This includes things like the semi-invulnerable bits (which I am checking here). A full list of the known bits is quoted at the end of this section.

Now that we know that, we understand why we are checking the special status, yeah?

Now, to explain the numbers used.

The first 0x0 is the bank, once again.

The 0x400C0 isn't particularly obvious, unless you understand bitwise checks. In 32-bit binary, that number is:
Code:
00000000000001000000000011000000
What we are actually doing with this command is checking if any of these bits I specified are set. If they ARE set, then we do something. That something is defined by the next parameter.
This command ANDs the special status bits for the Pokémon with the value you supply, hence why we have to think in Binary!

The second 0x0 is a byte telling the command what to do after it does the bitwise operation.
Spoiler:
0x0 - Branch if ANY set
0x1 - Branch if none set


The final parameter is where to branch to if the command returns true.

By removing the accuracycheck command, we have removed any chance of the attack missing (ignoring things like Protect and such). Now, this move would only miss if the target was in the middle phase of Dive, Fly, Bounce or Dig.

If you wanted to leave one of those out, say you wanted to have the move still hit Pokémon in the middle phase of Dive, you would simply zero the relevant bit in the special status check.

Code:
jumpifspecialstatusflag 0x0 0xC0 0x0 0x1D695E
This above would hit a Pokémon in the middle phase of dive, but miss those in the middle phase of Fly, Bounce and Dig, understand?

This is a list of the known Special Status Flags, quoted verbatim from JPAN from his thread on here about Battle Scripts:
Quote:
Special (status) flags
Code:
0x00000001 --> ??
0x00000002 --> ??
0x00000004 --> leech seed affected
0x00000010 --> always hit 
0x00000020 --> perish song affected 
0x00000040 --> on air (fly, bounce) 
0x00000080 --> underground (dig)
0x00000100 --> minimized
0x00000200 --> charged up
0x00000400 --> rooted 
0x00000800 --> sleep this turn(yawn)
0x00001000 --> sleep in one turn(yawn)
0x00002000 --> cannot use attacks from target(imprision)
0x00004000 --> foe loses all pp on last used atk if user faints (grudge)
0x00010000 --> elec attacks cause half damage (mud sport)
0x00020000 --> fire attacks cause half damage (water sport)
0x00040000 --> underwater (dive)



Scalar Multiplication of Attack Damage and Using Keywords:
Spoiler:
We're doubling the attack power of a move if used on a Pokémon which is in the middle phase of Dive!

Code:
#org @start
jumpifspecialstatusflag 0x0 0x40000 0x1 @later
setbyte damagemultiplier 0x2
goto @later

#org @later
//script continues
Whoa! Whoa! Whoa! "damagemultiplier"? I thought we had to refer to RAM addresses by their actual numerical value!

Well, thankfully not. I put a bunch of the main ram locations used in Battle Scripting and made them into keywords which refer to the RAM Location. It's much easier than trying to remember the location, wouldn't you agree?

Ignoring that, the script is fairly self explanatory.

Note, you can use any scalar multiplier up to 0xFF. You can only use whole numbers here, so no manipulation of damage for more clever purposes.



Raising/Lowering Stat Buffs:
Spoiler:
Spoiler:
You'll have noticed I have danced around the more common status moves and their effects so far, that is, the effects which simply lower/raise the stat levels.

Well, here's some background to it to begin with. There are 8 stat buffs for each Pokémon in battle. They are located at (Base Location + 0x18) + (0x58 * battler ID). However, we don't need to refer to them directly, as Battle Scripting has a helpful command which refers to them for us!

As you may have guessed by now, it follows the same bank structure as many of these such commands. The command is as follows:

Code:
jumpifstat 0x0 0x0 0x1 0x6 @later
The parameters are:

0x0 - The bank

0x0 - The second 0x0 is a byte telling the command what to do after it does the comparison

0x1 - Stat Index
Spoiler:
0x0 - HP (Note, this has no actual effect in game)
0x1 - Attack
0x2 - Defence
0x3 - Speed
0x4 - Special Attack
0x5 - Special Defence
0x6 - Accuracy
0x7 - Evasion


0x6 - What to compare the requested stat against


@later - the address to jump to if the command returns true.

So far, though, all I've told you is how to check the stats, not how to manipulate them. Well, the thing is, they go hand in hand. You don't want to be raising an already maxed stat, or lowering an already minimised stat. Or perhaps you only want it to work if the target/user has a certain stat level? Either way, the stat checks are a good place to start.

Now, to actually raise or lower stats is relatively simple.

Here is a script fragment that will actually change a stat:
Code:
playstatchangeanimation 0x0 0x2 0x0
statbuffchange 0x1 true @alt
jumpifbyte 0x0 statchange 0x2 @alt
printfromtable 0x83FE57C
waitmessage 0x40

#org @alt
//rest of code
Wait, what's this madness? TRUE? A word that is NOT a keyword as a parameter?

Well, let's break down the new commands and all will be explained!

Code:
playstatchangeanimation 0x0 0x2 0x0
The name is pretty self explanatory, to be honest, so I won't bother explaining that.

The first 0x0 is, once again, the bank (see how that crops up all the time?)

The 0x2 is the colour of the animation. This parameter is treated as a bitfield by the game's engine, and what's more, it works out which ones it should and should not show! That is to say, if you were to pass it a value of 0x6 (which in binary is 0000 0110), it will check each stat you have identified and work out if that part of the animation is at all necessary. If it isn't, it only displays the ones which are necessary.

Spoiler:
0x1 - HP
0x2 - Attack
0x4 - Defence
0x8 - Speed
0x10 - Special Attack
0x20 - Special Defence
0x40 - Accuracy
0x80 - Evasion


The second 0x0 is a byte defining which direction the animation should go. I am unsure what the least significant bits stand for, but the most significant bit in the lower nibble stands for the direction of the animation.

Spoiler:
0000 0XXX - Up
0000 1XXX - Down


Code:
statbuffchange 0x0 TRUE 0x0
Well, this is the command which physically executes the stat change, if it can.

The first parameter defines a lot. It defines the target, as well as various other unknown things.
What you place here can be:
Spoiler:
0x0 - Affects target (Opponent, or yourself, depends what the move targets)
0x80 - Affects user (Always yourself)



Now, the interesting and unusual one. The ONLY command in the entire engine which takes a word as a parameter. Note that keywords simply stand for numbers, and don't count as words.

This stands for the possibility for the stat change to fail. There are certain circumstances which can cause a stat change to fail, and this word (TRUE or FALSE) can override that.

Note that this parameter does NOT exist after compilation, as it gets merged with the previous parameter.

The 0x0 is meant to be a ROM address to jump to if the stat change fails. However, in my honest opinion, it looks better to check the failure conditions before you ever reach this point, as the stat change animation will already have played by this point.

Now, the one thing I skipped over was the 0xX in the setbyte command. Well, here's a list of what bytes do what when stored into the stat change ram location.
Spoiler:
Raising One Level:
0x11 - Attack
0x12 - Defense
0x13 - Speed
0x14 - Special Attack
0x15 - Special Defense
0x16 - Accuracy
0x17 - Evasion

Raising Two Levels:
0x21 - Attack
0x22 - Defense
0x23 - Speed
0x24 - Special Attack
0x25 - Special Defense
0x26 - Accuracy
0x27 - Evasion

Lowering One Level:
0x91 - Attack
0x92 - Defense
0x93 - Speed
0x94 - Special Attack
0x95 - Special Defense
0x96 - Accuracy
0x97 - Evasion

Lowering Two Levels:
0xA1 - Attack
0xA2 - Defense
0xA3 - Speed
0xA4 - Special Attack
0xA5 - Special Defense
0xA6 - Accuracy
0xA7 - Evasion


You should note that, while the game isn't designed to deal with triple stat increases, it is capable of doing so. All that happens is that you don't get an amount sensitive message after the stat change. I know this is the case, as I have such a triple stat increase in one of my moves. I haven't tried anything higher than that, but you certainly can't go any higher than a change of +/- 7, because the highest bit controls whether the stat rises or falls.


More to follow.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!

Last edited by Jambo51; May 26th, 2013 at 06:52 PM.
Reply With Quote
  #2    
Old March 25th, 2013, 05:19 PM
karatekid552's Avatar
karatekid552
What happens if I push it?....
 
Join Date: Nov 2012
Location: Do you really want to know? Really?
Gender: Male
Nature: Bold
Send a message via AIM to karatekid552 Send a message via Windows Live Messenger to karatekid552 Send a message via Skype™ to karatekid552
This is a great tut, I read it over at RHO before it got shut down, I even downloaded it for later reading. Eventually, could we use this knowledge to code entire new custom battles? Possibly implement the dual trainers from Emerald in FR? Just some thoughts, it deffinalely is nice to have a tut to go along with your BSP.
__________________

Paired with Simba
Reply With Quote
  #3    
Old April 3rd, 2013, 08:54 AM
GoGoJJTech's Avatar
GoGoJJTech
GoGo
 
Join Date: Nov 2012
Location: Earth
Age: 15
Gender: Male
Nature: Quiet
Is there a way for the sandstorm/hail to go before the end of the turn like in d p p hg ss b w?
in gen 3 the sandstorm and burn and poison happen after your pokemon faints.
__________________
I believe in Jesus Christ my Savior. If you do too, and aren't scared to admit it, then copy and paste this into your signature.
Proof that I'm the third best Temple Run player in the Universe
The SoulSilver Music Patch - The Black Music Patch - Mega-Huge Sappy Tutorial - Time-Based Events - Yet Another Sprite Resource

Pokémon Platinum Red and Blue

Join me in the chat! Get help or just talk, I really don't care :D | Click here: http://chat.linkandzelda.com:9090/?c...omhacking,GoGo
Reply With Quote
  #4    
Old April 5th, 2013, 05:16 AM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Of course it's possible, it all comes down to implementation and whether or not you could implement it cleanly enough for it to work.

I wouldn't honestly know where to start in terms of rewriting the BS routine for this though. By routine, I don't mean ASM (although there would no doubt be some ASM involved), I simply mean the routine the engine follows when in battle.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #5    
Old April 5th, 2013, 08:23 AM
GoGoJJTech's Avatar
GoGoJJTech
GoGo
 
Join Date: Nov 2012
Location: Earth
Age: 15
Gender: Male
Nature: Quiet
Could we search in A-text for "the sandstorm rages" then find a pointer to it, go back a few bytes and we should have the script?
__________________
I believe in Jesus Christ my Savior. If you do too, and aren't scared to admit it, then copy and paste this into your signature.
Proof that I'm the third best Temple Run player in the Universe
The SoulSilver Music Patch - The Black Music Patch - Mega-Huge Sappy Tutorial - Time-Based Events - Yet Another Sprite Resource

Pokémon Platinum Red and Blue

Join me in the chat! Get help or just talk, I really don't care :D | Click here: http://chat.linkandzelda.com:9090/?c...omhacking,GoGo
Reply With Quote
  #6    
Old April 12th, 2013, 02:54 PM
robin22gongon's Avatar
robin22gongon
 
Join Date: Sep 2012
Location: Want to know? VM me.
Age: 16
Gender: Male
Nature: Quirky
Send a message via Windows Live Messenger to robin22gongon
So I can use battle scripts to make new move effects am I right?
How do I really use it? In your new moves tut, we can do new move effects by creating codes, how about this one?
__________________
LET'S PARTY!
Reply With Quote
  #7    
Old April 25th, 2013, 02:23 PM
Shadowraze's Avatar
Shadowraze
Love and Peace
 
Join Date: Apr 2013
Location: Philippines
Age: 15
Gender: Male
Nature: Adamant
Send a message via Skype™ to Shadowraze
This is a very awesome tutorial Jambo.

Although I think you have forgotten to explain some moves, especially the string that appears when the stats are changed from the current code you had given us. I've only been able to raise the stats but, no text appears that says "Pokemon Stat Rose". :/

Also jambo is there a code that is like the random code in XSE? :3
__________________
Reply With Quote
  #8    
Old July 21st, 2013, 12:03 AM
MrDollSteak's Avatar
MrDollSteak
Formerly known as 11bayerf1
 
Join Date: Dec 2008
Location: Hong Kong
Age: 19
Gender: Male
I can't help but notice that there are commands above FF, that seem to be for Gen 4 moves.
I take it these only work in the 649 patch? How would one go about getting them to work in
other roms.
__________________
Reply With Quote
  #9    
Old July 22nd, 2013, 05:03 AM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Quote:
Originally Posted by 11bayerf1 View Post
I can't help but notice that there are commands above FF, that seem to be for Gen 4 moves.
I take it these only work in the 649 patch? How would one go about getting them to work in
other roms.
I'm sure you won't be surprised to hear that it requires custom ASM. The way the script runner is built, you physically cannot use commands with an index greater than 0xFF, because a script command's ID can only be a byte in size.

What I did was turn command 0xFF into a command which takes 1 parameter, that parameter being the "extended script ID".

The code reads the ID, and then jumps (in ASM) to the code associated with the ID based on a table built into command 0xFF. It then executes as normal. If the extended ID command has parameters, these parameters follow on directly from the extended script ID, as they would in any normal circumstances.

Basically, command 0xFF in my ROM is a bit like Callstd in overworld scripting.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #10    
Old July 24th, 2013, 12:52 AM
MrDollSteak's Avatar
MrDollSteak
Formerly known as 11bayerf1
 
Join Date: Dec 2008
Location: Hong Kong
Age: 19
Gender: Male
Quote:
Originally Posted by Jambo51 View Post
I'm sure you won't be surprised to hear that it requires custom ASM. The way the script runner is built, you physically cannot use commands with an index greater than 0xFF, because a script command's ID can only be a byte in size.

What I did was turn command 0xFF into a command which takes 1 parameter, that parameter being the "extended script ID".

The code reads the ID, and then jumps (in ASM) to the code associated with the ID based on a table built into command 0xFF. It then executes as normal. If the extended ID command has parameters, these parameters follow on directly from the extended script ID, as they would in any normal circumstances.

Basically, command 0xFF in my ROM is a bit like Callstd in overworld scripting.
Hrm that's very interesting I must say. Yeah I figured it wasn't something found normally in the rom.
That's a creative solution, because I was wondering how you'd be able to create extended IDs as FF to me was the biggest an ID could go. I was hoping initially that there'd be some sort of table to extend but that makes sense.

Thanks for your response!
__________________
Reply With Quote
  #11    
Old July 24th, 2013, 06:43 PM
Kurapika's Avatar
Kurapika
Grudgebearer
 
Join Date: Feb 2013
Location: Lavendar Town - Morocco
Gender: Male
Nature: Naughty
Wow, I'm so proud of myself I did something like you Jambo. XD
Please, do you thínk that stuff like Prankster and Sucker Punch is possible to do??
__________________
Reply With Quote
  #12    
Old July 25th, 2013, 12:32 AM
MrDollSteak's Avatar
MrDollSteak
Formerly known as 11bayerf1
 
Join Date: Dec 2008
Location: Hong Kong
Age: 19
Gender: Male
Quote:
Originally Posted by Kurapika View Post
Wow, I'm so proud of myself I did something like you Jambo. XD
Please, do you thínk that stuff like Prankster and Sucker Punch is possible to do??
Looking at BSP, Jambo's already got Sucker Punch working. It's one of those extra bytes he
was talking about. It's listed as 'jumpiftargetisusingstatusmove'.

My guess would be that if the target is using a status move, it jumps to a new priority check.
I suppose that Prankster is built in a similar way, where it would check if the user was using
a status move. I have no idea about the actual implementation of this or how to replicate it.
You may want to ask Jambo for that.
__________________
Reply With Quote
  #13    
Old July 25th, 2013, 06:05 AM
Kurapika's Avatar
Kurapika
Grudgebearer
 
Join Date: Feb 2013
Location: Lavendar Town - Morocco
Gender: Male
Nature: Naughty
Oh!! :o
Yeah, I just found that the game stores what move every pokemon is about to use, so Sucker Punch and Me First are totally possible, Prankster and Stall are still in doubt... -.-
The problem is that Sucker Punch has a static priority, while Prankster and Stall abilities need to alter the priorities...
__________________
Reply With Quote
  #14    
Old July 25th, 2013, 09:00 AM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Quote:
Originally Posted by Kurapika View Post
Oh!! :o
Yeah, I just found that the game stores what move every pokemon is about to use, so Sucker Punch and Me First are totally possible, Prankster and Stall are still in doubt... -.-
The problem is that Sucker Punch has a static priority, while Prankster and Stall abilities need to alter the priorities...
Stall doesn't alter priority. It makes the Pokémon go last in its priority bracket.

http://bulbapedia.bulbagarden.net/wiki/Stall_(Ability)

Prankster needs to be handled by ASM exclusively. This is because the code which orders attackers is all ASM. The same applies to Stall.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #15    
Old August 14th, 2013, 12:15 AM
TorNyan
Hacker
 
Join Date: Feb 2012
Location: Sweden
Age: 19
Gender: Female
Nature: Calm
I want to make a custom battle that is very similiar to "old man catches a weedle" tutorial. Tried BSP out. Don't understand much. Tried to compile the basic battle script (copy pasted) in order to test things out. It returned an error. The same with debugging (only if there's no error in my script) and Command Directory (F1). The error transcribes as follows.
Quote:
Battle Script Pro
Unhandled exception has occurred in your application. If you click Continue, the application will ignore this error and attempt to continue. If you click Quit, the application will close immediately.

SQL logic error or missing database
no such table: commands.
Details:
Spoiler:
Quote:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.Data.SQLite.SQLiteException (0x80004005): SQL logic error or missing database
no such table: commands
at System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn, String strSql, SQLiteStatement previous, UInt32 timeoutMS, String& strRemain)
at System.Data.SQLite.SQLiteCommand.BuildNextCommand()
at System.Data.SQLite.SQLiteCommand.GetStatement(Int32 index)
at System.Data.SQLite.SQLiteDataReader.NextResult()
at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)
at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SQLite.SQLiteCommand.ExecuteReader()
at Battle_Script_Pro.Form1.DebugCommands()
at Battle_Script_Pro.Form1.DebugWrittenScript()
at Battle_Script_Pro.Form1.btnDebug_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
Battle Script Pro
Assembly Version: 0.9.2.0
Win32 Version: 0.9.2.0
CodeBase: file:///C:/Pok%E9-Haxxor%20%5E%5E/Battle%20Script%20Pro%20(BSP)/Battle%20Script%20Pro.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
Accessibility
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Accessibility/v4.0_4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
System.Data.SQLite
Assembly Version: 1.0.84.0
Win32 Version: 1.0.84.0
CodeBase: file:///C:/Pok%E9-Haxxor%20%5E%5E/Battle%20Script%20Pro%20(BSP)/System.Data.SQLite.DLL
----------------------------------------
System.Data
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
----------------------------------------
System.Transactions
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.Transactions/v4.0_4.0.0.0__b77a5c561934e089/System.Transactions.dll
----------------------------------------
System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 built by: RTMRel
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.EnterpriseServices
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_32/System.EnterpriseServices/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.


If one is to click "Continue", the application continues as normal, but if one hovers over the bar with compile button and all that, it shows the hourglass pointer. If one is to click "Quit". It quits as regular and asks to save.

Good night.
Reply With Quote
  #16    
Old August 14th, 2013, 09:23 AM
GoGoJJTech's Avatar
GoGoJJTech
GoGo
 
Join Date: Nov 2012
Location: Earth
Age: 15
Gender: Male
Nature: Quiet
You need to update the database before you open a script. It's in the settings in the program I think.
__________________
I believe in Jesus Christ my Savior. If you do too, and aren't scared to admit it, then copy and paste this into your signature.
Proof that I'm the third best Temple Run player in the Universe
The SoulSilver Music Patch - The Black Music Patch - Mega-Huge Sappy Tutorial - Time-Based Events - Yet Another Sprite Resource

Pokémon Platinum Red and Blue

Join me in the chat! Get help or just talk, I really don't care :D | Click here: http://chat.linkandzelda.com:9090/?c...omhacking,GoGo
Reply With Quote
  #17    
Old August 14th, 2013, 09:46 PM
TorNyan
Hacker
 
Join Date: Feb 2012
Location: Sweden
Age: 19
Gender: Female
Nature: Calm
Quote:
Originally Posted by gogojjtech View Post
You need to update the database before you open a script. It's in the settings in the program I think.
Thank you very much, it solved my problem (though it was from the Help menu).


Now that I've gotten that out the way, I have a few open questions.

How do I implement a battle script in my hack?
Does it work with both trainer battles and wild battles (and legendary battles)?
Where and how do I find the already implemented battles in the game?

Thanks in advance.

Last edited by TorNyan; August 17th, 2013 at 04:46 PM.
Reply With Quote
  #18    
Old August 22nd, 2013, 05:25 AM
jrmsweitzer712
 
Join Date: Aug 2008
Gender:
Would it be possible to check the levels at the beginning of any wild battle, and if your level is a certain amount higher, it automatically wins the battle?

For instance, I'm running around with a level 62 Charizard. I run into a wild Caterpie at level 4. I want to be able to automatically win the battle and gain the experience, without actually battling the Pokémon. Is this at all possible?
Reply With Quote
  #19    
Old August 22nd, 2013, 12:39 PM
Jambo51's Avatar
Jambo51
Glory To Arstotzka
 
Join Date: Jun 2009
Gender: Male
Nature: Quiet
Quote:
Originally Posted by jrmsweitzer712 View Post
Would it be possible to check the levels at the beginning of any wild battle, and if your level is a certain amount higher, it automatically wins the battle?

For instance, I'm running around with a level 62 Charizard. I run into a wild Caterpie at level 4. I want to be able to automatically win the battle and gain the experience, without actually battling the Pokémon. Is this at all possible?
Not using this, no. What you want to do would require ASM to implement, and would be exceedingly complex.
__________________
Hey guys, please check out my recreations of the gen 1 and 2 music on my custom engine at my SoundCloud! - Here!
Reply With Quote
  #20    
Old September 13th, 2013, 10:26 PM
daniilS's Avatar
daniilS
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 14
Gender: Male
Nature: Relaxed
Is it possible to call a battle script from an asm routine?
Reply With Quote
  #21    
Old September 14th, 2013, 02:14 PM
karatekid552's Avatar
karatekid552
What happens if I push it?....
 
Join Date: Nov 2012
Location: Do you really want to know? Really?
Gender: Male
Nature: Bold
Send a message via AIM to karatekid552 Send a message via Windows Live Messenger to karatekid552 Send a message via Skype™ to karatekid552
Quote:
Originally Posted by daniilS View Post
Is it possible to call a battle script from an asm routine?
How do you think they get called in the first place? You do realize that all scripting is just a higher level of ASM right? It is basically a macro ASM language.
__________________

Paired with Simba
Reply With Quote
  #22    
Old September 15th, 2013, 01:36 AM
daniilS's Avatar
daniilS
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 14
Gender: Male
Nature: Relaxed
Quote:
Originally Posted by karatekid552 View Post
How do you think they get called in the first place? You do realize that all scripting is just a higher level of ASM right? It is basically a macro ASM language.
Yes, I know, but how? I don't think a simple jump is enough, because the game has to know it should execute a battle script. How do I do this?
Reply With Quote
  #23    
Old September 15th, 2013, 09:19 AM
karatekid552's Avatar
karatekid552
What happens if I push it?....
 
Join Date: Nov 2012
Location: Do you really want to know? Really?
Gender: Male
Nature: Bold
Send a message via AIM to karatekid552 Send a message via Windows Live Messenger to karatekid552 Send a message via Skype™ to karatekid552
Quote:
Originally Posted by daniilS View Post
Yes, I know, but how? I don't think a simple jump is enough, because the game has to know it should execute a battle script. How do I do this?
The battle script loader. If you set a break on loading of the first command, it should be the battle script loader which does this. You will have to work backwards to the top of the routine. Now, my question is, why?
__________________

Paired with Simba
Reply With Quote
  #24    
Old September 15th, 2013, 10:13 AM
daniilS's Avatar
daniilS
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 14
Gender: Male
Nature: Relaxed
Quote:
Originally Posted by karatekid552 View Post
The battle script loader. If you set a break on loading of the first command, it should be the battle script loader which does this. You will have to work backwards to the top of the routine. Now, my question is, why?
I'm trying to add a check for the opponent pokemon's type and status ailment to implement in the code for a custom ball. Thank you for the tip, I'm going to try it.

Last edited by daniilS; September 15th, 2013 at 10:58 AM.
Reply With Quote
  #25    
Old September 28th, 2013, 12:55 PM
daniilS's Avatar
daniilS
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 14
Gender: Male
Nature: Relaxed
Another question: what do call and goto execute? Do they jump to another battle script, or to an asm routine?
__________________

Thanks to JPAN, Jambo51, Shiny Quagsire and knizz for teaching me almost everything I know about hacking, through tutorials or in person.
Reply With Quote
Reply
Quick Reply

Sponsored Links
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Minimum Characters Per Post: 25



All times are UTC -8. The time now is 10:59 AM.


Style by Nymphadora, artwork by Sa-Dui.
Like our Facebook Page Follow us on Twitter © 2002 - 2014 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2014 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.