Update XSE To Latest Version And Extract All Files Or Else This Tutorial May Not Be Compatible
I want to say thanks to thethethethe for letting me take this tutorial and modify it for XSE compatibility. Also, I want to thank HackMew for making XSE in the first place, and for Irish Witch and PokeScript for getting me started on scripting. I also want to thank zel for making the hack (ShinyGold) that started me on the road to hacking. Since this is just a modification to thethethethe's original tutorial, you'll see very many similarities.
XSE is a program created by Hackmew, as I've already said. This program is, in my opinion, the best scripting program there is, having many advantages over ScriptED, PokeScript, Diamond Cutter, and the likes.
Some of the important features of XSE are:
Dynamic Offsets
All you need to find is the starting offset. XSE will find the rest.
Less Raws, More Commands
It's to make it easier. Instead of having to use #raw 0x53 0x07, you can just use hidesprite 0x07.
This tutorial is going to cover a lot.
I'll show a script at the beginning and then explain everything "new" after it.
Please note that because I hack Fire Red, most scripts are written to suit Fire Red/Leaf Green, and NOT Ruby/Sapphire/Emerald.
I think I'll start with pointers.
Pointers
XSE is great in the way that it uses dynamic offsets. You just put the starting offset (found in FSF {Free Space Finder}) and XSE will do the rest.
You can use any random name for the pointer. It could be, for example...
@blah ; @iliketoeatcheese ; @1234567890
As long as there are no spaces in it, and there aren't two exact same pointers, the pointer will work.
So, for example, these won't work
@mr potato head ; @i like mews ; @pikachu rocks.
Message Scripts
Now I can move onto a normal message script.
Code:
#dynamic 0x(FSF Offset)
#org @start
lock
faceplayer
msgbox @1 0x6
release
end
#org @1
= Hi.\nMy name is Diego.
I'll begin at the top of the script and work my way down. #dynamic 0x(FSF Offset) is the starting offset for your script. XSE will do the rest. #org @start marks the start of the script, obviously. It shows that it's the beginning. lock will lock your player so that while this script is "in motion" the player won't be able to move. faceplayer is used to make the sprite you are talking with face you. message is used when you want a message to display on the screen. It's followed by a pointer that will be placed at the bottom as shown.
The actual message will appear like this.
Quote:
Hi.
My name is Diego.
I'll explain the other types, like \p and \l and others, a little later.
Now the number after the pointer. That number MUST follow a msgbox pointer. Without this, the message box won't appear. In this case, I've used 0x6. I'll cover more numbers later.
Now we use release. This will release the locked player. end will end the script, stopping it from reading any bytes past it that could crash your game when used.
Extra Message Info
There are lots of other little add-ons that can be used with the message. Here's a short list of them:
Quote:
\c \h \n \l \p \v
I'll go in order of this list. \c usually refers to a color.
This message:
Quote:
\c\h01\h02You received a Pokémon!
will appear in a black text. There's also a new way to write colors.
Here's a short list of the new ones: Fire Red/Leaf Green
Spoiler:
Code:
White - [white_fr]
Black - [black_fr]
Gray - [grey_fr]
Red - [red_fr]
Orange - [orange_fr]
Green - [green_fr]
Light Green - [lightgreen_fr]
Blue - [blue_fr]
Light Blue - [lightblue_fr]
Light Blue 2 - [lightblue2_fr]
Cyan - [cyan_fr]
Light Blue 3 - [lightblue3_fr]
Navy Blue - [navyblue_fr]
Dark Navy Blue - [darknavyblue_fr]
Ruby/Sapphire
Spoiler:
Code:
Transparent - [transp_rs]
Dark Gray - [darkgrey_rs]
Red - [red_rs]
Light Green - [lightgreen_rs]
Blue - [blue_rs]
Yellow - [yellow_rs]
Cyan - [cyan_rs]
Magenta - [magenta_rs]
Gray - [grey_rs]
Black - [black_rs]
Light Gray - [lightgrey_rs]
White - [white_rs]
Sky Blue - [skyblue_rs]
Dark Sky Blue - [darkskyblue_rs]
Emerald
Spoiler:
Code:
White - [white_em]
Dark Gray - [darkgrey_em]
Gray - [grey_em]
Red - [red_em]
Orange - [orange_em]
Green - [green_em]
Light Green - [lightgreen_em]
Blue - [blue_em]
Light Blue - [lightblue_em]
White 4 - [white4_em]
Lime Green- [limegreen_em]
Aqua - [aqua_em]
Navy - [navy_em]
\h is used with hex values. Here's an example:
Quote:
Here's \hB7100!
That \hB7 is the currency sign of the Pokemon world.
So in this example, I'm going to use "$":
Quote:
Here's $100!
Here's a table of all the hex codes for each symbol:
Instead of using the codes below, I recommend using the Text Adjuster, found under Tools>Text Adjuster. Just type it in, press "Convert", and paste it in. It's that simple!
\n is used when we want to go to a new line. So this message:
Quote:
Hi.\nWelcome.
would appear like this:
Quote:
Hi.
Welcome.
\l is used in text for a new line, but it can only be used after \n has already been used.
So this message:
Quote:
Hi.\nI love my bed!\lDon't you dare sleep in\lit!
will appear like this:
Quote:
Hi.
I love my bed!
Don't you dare sleep in
it!
\p is used when we want the text to continue in a new box. This message:
Quote:
...\p...\p...\pYup!
will appear like this: ------------ means a new box.
\v is used when we want display stored text. Here's an example:
Quote:
Hello, \v\h01!\n\v\h06 is looking for you.
This would appear like this.
Quote:
Hello, [PLAYER's name]!
[RIVAL's name] is looking for you.
You could also do it like this:
Quote:
Hello, [player]!\n[rival] is looking for you.
Msgbox Numbers
Here are the many different types, taken directly from The ROM Hacking Newsletter, also located in the ROM Hacking section. This week's tip comes from HackMew. This time, it's all about msgboxes. Below is a description, script example and in-game shot of the different msgbox types.
0x2
Spoiler:
Description:
This is the msgbox used for normal people. Using this type means that you don't need to use the lock, faceplayer or release commands.
Script:
#dynamic 0x800000
#org @start
msgbox @hello 0x2
end
#org @hello
= Hello, my name is dshayabusa.
In-Game:
0x3
Spoiler:
Description:
Used for signs etc. No lock or faceplayer effect. Only shows the sign textbox when used on an actual sign.
Script:
#dynamic 0x800000
#org @start
msgbox @sign 0x3
end
#org @hello
= You are here
In-Game:
0x4
Spoiler:
Description:
A normal msgbox except for the fact that it does not close. Command closeonkeypress must be used to close it. No lock or faceplayer effect.
Script:
#org @start
msgbox @hello 0x4
end
#org @hello
= Hello, my name is dshayabusa.
In-Game:
0x5
Spoiler:
Description:
Used for Yes/No questions. No lock or faceplayer effect.
Script:
#dynamic 0x800000
#org @start
msgbox @question 0x5
end
#org @hello
= Is this statement false?
In-game:
0x6
Spoiler:
Description:
Normal textbox. Has no lock or faceplayer effect.
Script: #dynamic 0x800000
#org @start
msgbox @Hello 0x6
end
#org @hello
= Hello, my name is dshayabusa.
In-game:
Flags
Flags are very useful when you need an event to only occur once or if you want a person to disappear.
Let's say you set flag 0x200. If you want an overworld to disappear, we have to assign the set flag (in this example, 0x200) to the overworld's people ID in Advance-Map. I'll go into more detail on that later.
Many flags are used within the game already. If you plan on leaving scripts that are already in the ROM, you'll need to be more careful on what flags you use, because flags can only really be used once.
If you want some flags that are used in the ROM already, here's a list: Taken directly from the XSE Comprehensive Scripting Guide, found here: Help>Guide
I'll have to do a bit of explaining here, so I'll start with preventing events to happen. I'll use #dynamic 0x800000 for the rest of my examples.
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
checkflag 0x200
if 0x1 goto @done
msgbox @1 0x6
setflag 0x200
release
end
#org @done
msgbox @2 0x6
clearflag 0x200
release
end
We've already covered lock and faceplayer, so we'll go to checkflag. checkflag checks if a flag has been set. Checkflag is always followed by an if line.
When using the if line after checkflag, it contains either a 0x1 or 0x0. 0x1, means that if the flag is set goto @(pointer), and if it's not set, it will continue with the script. Similarly, 0x0 checks if the flag is not set, and if it isn't, it will goto @(pointer), and if the flag is set, the script will continue normally.
As you can see, the if 0x1 goto @done points to a different part of a script, as shown with the #org @done .
At #org @done, we have both a message and a new command, clearflag.
Once flags are set they can be "cleared" with the command clearflag. Clearflag has to be followed by the flag number, which in this case is 0x200.
There is more than one way to use a flag. Some flags have some sort of game function, like these: Flags
0x800 - Activates Pokemon Menu
0x801 - Activates Pokedex Menu
0x802 - Activates Pokenav Menu
0x807 - Activates First Badge
0x808 - Activates Second Badge
0x809 - Activates Third Badge
0x80A - Activates Fourth Badge
0x80B - Activates Fifth Badge
0x80C - Activates Sixth Badge
0x80D - Activates Seventh Badge
0x80E - Activates Eighth Badge
0x860 - Activates Running Shoes
Emerald:
Spoiler:
0x860 - Activates Pokemon Menu
0x861 - Activates Pokedex Menu
0x862 - Activates Pokenav Menu
0x867 - Activates First Badge
0x868 - Activates Second Badge
0x869 - Activates Third Badge
0x86A - Activates Fourth Badge
0x86B - Activates Fifth Badge
0x86C - Activates Sixth Badge
0x86D - Activates Seventh Badge
0x86E - Activates Eighth Badge
0x8C0 - Activates Running Shoes
Badge flags and the running shoes flag found by Crocky.
I'll explain these in the next part.
Givepokemon
Givepokemon does exactly what it says. It gives the player a Pokemon. Here's my example script. There are lots of new commands to look at here.
Code:
#dynamic 0x800000
#org @start
checkflag 0x828
if 0x1 goto @done
msgbox @1 0x5
compare LASTRESULT 0x1
if 0x1 goto @take
msgbox @2 0x6
release
end
#org @take
givepokemon 0x4 0x5 0x0 0x0 0x0 0x0
fanfare 0x13E
msgbox @3 0x4
waitfanfare
closeonkeypress
setflag 0x828
msgbox @4 0x5
compare LASTRESULT 0x1
if 0x1 gosub @name
msgbox @5 0x6
release
end
#org @name
call 0x1A74EB
return
#org @done
msgbox @6 0x6
release
end
#org @1
= Hello.\nSorry to trouble you.\nI can't take care\nof my Charmander.\pCan you take care of\nit for me?
#org @2
= That's okay.\pI'm sure someone else will\ntake it.
#org @3
= [black_fr]You received a Charmander!
#org @4
= [black_fr]Would you like to give a\nnickname to Charmander?
#org @5
= Please take care of\nCharmander.
#org @6
= Are you taking good care\nof Charmander?
Okay. There's a lot here I need to explain.
I'll start from the top.
We've already covered checkflag and the if line, as well as msgbox.
For info on 0x5, read the section labeled Msgbox Numbers. 0x5 is always followed by a compare line. compare needs a variable, which in this case is 0x800D, and a value, which in this case is 0x1. 0x800D is a useful variable that most commands store values in.
When using compare after a msgbox @(text) 0x5 line, you only have two options for the value. They're 0x0, which is the value set to 0x800D when you choose NO, and 0x1, which is the value set to 0x800D when you choose YES.
A compare 0x800D 0x1 line will check if you pressed YES and, of course, compare 0x800D 0x0 will check if you pressed NO.
The if line that follows the compare line does the same thing as what it does for checkflag. if 0x1 will check if the button pressed matches the compared value. If it matches, it will goto @(pointer). If not, it will continue the script.
Then we have a normal msgbox.
The first new command here is givepokemon. givepokemon uses six values. The first is the Pokemon, the second being the level, the third being the Item Held, and the last three being buffers.
So in the script above, mine shows....
Master Ball 1
Ultra Ball 2
Great Ball 3
Poké Ball 4
Safari Ball 5
Net Ball 6
Dive Ball 7
Nest Ball 8
Repeat Ball 9
Timer Ball 10
Luxury Ball 11
Premier Ball 12
Potion 13
Antidote 14
Burn Heal 15
Ice Heal 16
Awakening 17
Parlyz Heal 18
Full Restore 19
Max Potion 20
Hyper Potion 21
Super Potion 22
Full Heal 23
Revive 24
Max Revive 25
Fresh Water 26
Soda Pop 27
Lemonade 28
Moomoo Milk 29
Energypowder 30
Energy Root 31
Heal Powder 32
Revival Herb 33
Ether 34
Max Ether 35
Elixir 36
Max Elixir 37
Lava Cookie 38
Blue Flute 39
Yellow Flute 40
Red Flute 41
Black Flute 42
White Flute 43
Berry Juice 44
Sacred Ash 45
Shoal Salt 46
Shoal Shell 47
Red Shard 48
Blue Shard 49
Yellow Shard 50
Green Shard 51
HP Up 63
Protein 64
Iron 65
Carbos 66
Calcium 67
Rare Candy 68
PP Up 69
Zinc 70
PP Max 71
Guard Spec. 73
Dire Hit 74
X Attack 75
X Defend 76
X Speed 77
X Accuracy 78
X Special 79
Poké Doll 80
Fluffy Tail 81
Super Repel 83
Max Repel 84
Escape Rope 85
Repel 86
Sun Stone 93
Moon Stone 94
Fire Stone 95
Thunderstone 96
Water Stone 97
Leaf Stone 98
Tinymushroom 103
Big Mushroom 104
Pearl 106
Big Pearl 107
Stardust 108
Star Piece 109
Nugget 110
Heart Scale 111
Orange Mail 121
Harbor Mail 122
Glitter Mail 123
Mech Mail 124
Wood Mail 125
Wave Mail 126
Bead Mail 127
Shadow Mail 128
Tropic Mail 129
Dream Mail 130
Fab Mail 131
Retro Mail 132
Cheri Berry 133
Chesto Berry 134
Pecha Berry 135
Rawst Berry 136
Aspear Berry 137
Leppa Berry 138
Oran Berry 139
Persim Berry 140
Lum Berry 141
Sitrus Berry 142
Figy Berry 143
Wiki Berry 144
Mago Berry 145
Aguav Berry 146
Iapapa Berry 147
Razz Berry 148
Bluk Berry 149
Nanab Berry 150
Wepear Berry 151
Pinap Berry 152
Pomeg Berry 153
Kelpsy Berry 154
Qualot Berry 155
Hondew Berry 156
Grepa Berry 157
Tamato Berry 158
Cornn Berry 159
Magost Berry 160
Rabuta Berry 161
Nomel Berry 162
Spelon Berry 163
Pamtre Berry 164
Watmel Berry 165
Durin Berry 166
Belue Berry 167
Liechi Berry 168
Ganlon Berry 169
Salac Berry 170
Petaya Berry 171
Apicot Berry 172
Lansat Berry 173
Starf Berry 174
Enigma Berry 175
Brightpowder 179
White Herb 180
Macho Brace 181
Exp. Share 182
Quick Claw 183
Soothe Bell 184
Mental Herb 185
Choice Band 186
King's Rock 187
Silverpowder 188
Amulet Coin 189
Cleanse Tag 190
Soul Dew 191
Deepseatooth 192
Deepseascale 193
Smoke Ball 194
Everstone 195
Focus Band 196
Lucky Egg 197
Scope Lens 198
Metal Coat 199
Leftovers 200
Dragon Scale 201
Light Ball 202
Soft Sand 203
Hard Stone 204
Miracle Seed 205
Blackglasses 206
Black Belt 207
Magnet 208
Mystic Water 209
Sharp Beak 210
Poison Barb 211
Nevermeltice 212
Spell Tag 213
Twistedspoon 214
Charcoal 215
Dragon Fang 216
Silk Scarf 217
Up-grade 218
Shell Bell 219
Sea Incense 220
Lax Incense 221
Lucky Punch 222
Metal Powder 223
Thick Club 224
Stick 225
Red Scarf 254
Blue Scarf 255
Pink Scarf 256
Green Scarf 257
Yellow Scarf 258
Mach Bike 259
Coin Case 260
Itemfinder 261
Old Rod 262
Good Rod 263
Super Rod 264
S.S. Ticket 265
Contest Pass 266
Wailmer Pail 268
Devon Goods 269
Soot Sack 270
Basement Key 271
Acro Bike 272
PokéBlock Case 273
Letter 274
Eon Ticket 275
Red Orb 276
Blue Orb 277
Scanner 278
Go-goggles 279
Meteorite 280
Rm. 1 Key 281
Rm. 2 Key 282
Rm. 4 Key 283
Rm. 6 Key 284
Storage Key 285
Root Fossil 286
Claw Fossil 287
Devon Scope 288
TM01 289
TM02 290
TM03 291
TM04 292
TM05 293
TM06 294
TM07 295
TM08 296
TM09 297
TM10 298
TM11 299
TM12 300
TM13 301
TM14 302
TM15 303
TM16 304
TM17 305
TM18 306
TM19 307
TM20 308
TM21 309
TM22 310
TM23 311
TM24 312
TM25 313
TM26 314
TM27 315
TM28 316
TM29 317
TM30 318
TM31 319
TM32 320
TM33 321
TM34 322
TM35 323
TM36 324
TM37 325
TM38 326
TM39 327
TM40 328
TM41 329
TM42 330
TM43 331
TM44 332
TM45 333
TM46 334
TM47 335
TM48 336
TM49 337
TM50 338
HM01 339
HM02 340
HM03 341
HM04 342
HM05 343
HM06 344
HM07 345
HM08 346
Oak's Parcel 349
Poké Flute 350
Secret Key 351
Bike Voucher 352
Gold Teeth 353
Old Amber 354
Card Key 355
Lift Key 356
Helix Fossil 357
Dome Fossil 358
Silph Scope 359
Bicycle 360
Town Map 361
VS Seeker 362
Fame Checker 363
TM Case 364
Berry Pouch 365
Teachy TV 366
Tri-pass 367
Rainbow Pass 368
Tea 369
Mysticticket 370
Auroraticket 371
Powder Jar 372
Ruby 373
Sapphire 374
Now, we have fanfare 0x13E. This is a jingle. It's a short bit of music that's played when you receive something, like a Pokemon or an item.
Then we have a msgbox. The only difference here is that we have used 0x4. But if it doesn't close, why would I use it? You'll just have to keep reading to find out. waitfanfare will do what it's name displays. It will wait for the fanfare to finish before it allows the script to continue. 0x4 left the box open while the fanfare plays. closeonkeypress is a very useful command. This is extremely useful when bundled with 0x4. It will basically make the 0x4 act as an 0x6, which allows for it to be closed with the press of a button. setflag 0x828... Do you remember what it's for? In Fire Red and Leaf Green, it activates the Pokemon Menu.
Now, here's this part:
Code:
msgbox @4 0x5
compare LASTRESULT 0x1
if 0x1 gosub @name
We have something slightly different there. Instead of, if 0x1 goto @name, we have if 0x1 gosub @name.
If you use ScriptED, this would just be if2 to you. Gosub is somthing used in other programming languages and is just used to say, "go to @offset, but you have to return."
Let's look at what we have there. gosub @name. That means that we're going to go look at @name.
Here, we have call 0x1A74EB. Call is used to call some other script within a ROM. It can also call a part of your script. In that case, it would appear like this:
Code:
call @(pointer)
I know what you're asking. What's at 0x1A74EB? The offset 0x1A74EB contains a script which is used to name a Pokemon.
Now we have return. It makes the script return to wherever it was called from or gosubed from. I didn't mention it earlier, but call should have a return to wherever it is called from.
That return has brought us back to msgbox @50x6. The rest is already explained, so now we can move onto the next part.
I think we'll move onto something similar and go to...
I'll just start straight with cry, since you already know about everything before it.
I have to get a little "advanced" here. Hopefully, I'll explain it well enough so that it sounds simple. When we script cry, it takes 6 bytes: cry [pkmn #] 0x0
First we have the command. That's followed by the Pokemon number, which in this case is a Charizard. The last 0x0 is supposed to determine the "effect number", but play it safe and stick with 0x0.
Now, we have the command wildbattle. In my script, we have:
From there, I can explain. The first two bytes are the Pokemon's numbers, the second is the level, and finally, the third is the item. fadescreen is a command that is used to make the screen fade to black or white and back. fadescreen 0x1 will fade the screen out to black. There are some more fadescreens, listed here:
Spoiler:
0x0 - fade from black to normal
0x1 – fade from normal to black
0x2 – fade from white to normal
0x3 – fade from normal to white
Now we can move onto hidesprite 0x800F. This is very useful, as it makes the overworld you're interacting with disappear. Here's some in-depth info on hidesprite 0x800F:
Spoiler:
When we interact/talk with an OW, the people number is assigned to the variable 0x800F. In the case of hidesprite 0x800F, it's saying, "hide sprite, (variable) 0x800F" It isn't actually a people no. 0x800F is just the variable that's assigned to the sprite currently being interacted with.
hidesprite can also be used a little differently. I'll explain that a little later in the tutorial.
Remember how I mentioned something about the People ID in Advance-Map? This is where I'll be explaining that. Let's say you set flag number 0x200. We are going to change the script's overworld's People ID to 0200. The People ID is used to make sure that the overworld doesn't continue to re-appear.
That's it! I guess we can move onto something else now.
Checkgender
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
checkgender
compare 0x800D 0x0
if 0x1 goto @boy
compare 0x800D 0x1
if 0x1 goto @girl
end
#org @boy
msgbox @1 0x6
release
end
#org @girl
msgbox @2 0x6
release
end
#org @1
= Hello, Mr. \v\h01!
#org @2
= Hello, Ms. \v\h01!
checkgender, huh? I guess there isn't too much for me to explain here.
So we have the command checkgender. Like most commands, it assigns a value to 0x800D. We check what this value is with compare 0x800D 0x*. The asterisk just stands for what we are checking for. checkgender assigns 0x0 to 0x800D for a male, and assigns 0x1 to 0x800D for a female.
I've used two compares but it could have alternatively been written like this:
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
checkgender
compare 0x800D 0x0
if 0x1 goto @boy
msgbox @2 0x6
release
end
#org @boy
msgbox @1 0x6
release
end
#org @1
= Hello, Mr. \v\h01!
#org @2
= Hello, Ms. \v\h01!
Or like this...
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
checkgender
compare 0x800D 0x1
if 0x1 goto @girl
msgbox @1 0x6
release
end
#org @girl
msgbox @2 0x6
release
end
#org @1
= Hello, Mr. \v\h01!
#org @2
= Hello, Ms. \v\h01!
It really just comes down to preference. Almost nothing is set in stone when it comes to scripting. There's almost always more than one way to do something, and I'll show some more examples of this later.
I think that's all that I need to explain for this.
Giveitem
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
checkflag 0x200
if 0x1 goto @done
msgbox @1 0x5
compare 0x800D 0x1
if 0x1 goto @take
msgbox @2 0x6
release
end
#org @done
msgbox @3 0x6
release
end
#org @take
giveitem 0xD 0x1 MSG_OBTAIN
msgbox @3 0x6
setflag 0x200
release
end
#org @1
= Hi!\pI'm from the Cherrygrove\nPokeMart.\pWhy don't you take this\nfree sample?
#org @2
= That's okay. I'm sure someone\nelse will enjoy it.
#org @3
= If you want more, you'll\nhave to go to the PokeMart\nto buy them.
One thing you may notice about this script is that I've pointed different parts of the script to the same pointer. This is not a mistake! You can do this. I added that here because I think it's a good thing for someone to know about.
Now, onto the new things in this script. We have the giveitem command.
Giveitem uses three values, the item no., the amount, and the message type. The message type can be either MSG_FIND or MSG_OBTAIN.
In my script, I used these:
Code:
giveitem 0xD (Potion) 0x1 (One of them) MSG_OBTAIN (Obtaining from a person message)
That's actually all you need to do for this command. It will automatically play a jingle and display a message saying "[PLAYER] received ............". That's actually all I need to explain.
Let's move onto some simple specials now.
Special
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
msgbox @10 0x4
closeonkeypress
fadescreen 0x1
fanfare 0x100
special 0x0
waitfanfare
fadescreen 0x0
msgbox @11 0x6
release
end
#org @10
= What wonderful Pokèmon you\nhave there!\pThey look like\nthey could use a long rest.
#org @11
= Now they look better!\nDon't forget to visit!
Looks like I've used 0x4 and closeonkeypress again. I've also used fadescreen 0x1 as well as fadescreen 0x0, another fanfare and special 0x0.
I'm going to do something different here. I'm going to start with the fadescreens. Do you still remember what fadescreen 0x0 does?
Spoiler:
It fades from black to normal.
Now, we can move backwards and look at, “Why I used 0x4 instead of 0x6.”
For some reason that I can't explain, if we use 0x6 before we use fadescreen 0x1, the box will remain open until we return to our normal screen with fadescreen 0x0. Once we are there, we will see it close, but we don't want that, do we? It doesn't look very good. We want it to close before we come back from our black screen. I also can't explain this, but for some reason, when we use 0x4 and closeonkeypress, it does just that. So whenever you have a script like this, use 0x4 and closeonkeypress before a fadescreen.
The fanfare is very useful in this script. In theory, I could have used pause (which is a command I haven't covered yet), but I wanted to use the combination of fanfare 0x100 and waitfanfare.
For those of you who don't know, fanfare 0x100 is the healing jingle that is played when someone heals your Pokemon. So with the help of waitfanfare, the screen will not return to normal until that jingle is completed.
Now all that's left is, of course, special 0x0. This is a special command that will fully heal the Pokemon within your party. Useful, isn't it?
I'm also going to include a short list of specials in a spoiler right here, for whoever may want it. Specials
Spoiler:
special 0x0 - Heal Pokemon
special 0x3C - Access Bill's PC (FR/LG)
special 0x98 - Going up to Mountain (R/S)
special 0x9C - Wally Catch (R/S)
special 0x9F - choose A Pokemon (R/S)
special 0xE0 - PokeBlock Case (R/S)
special 0x10F - Restart Game
special 0x110 - Hall of Fame and Credits
special 0x111 - Elevator Animation
special 0x119 - Groudon's Orb effect (R/S)
special 0x131 - Earthquake (R/S)
special 0x132 - Show Floors
special 0x133 - Long Earthquake (Emerald)
special 0x136 - Earthquake (FR/LG)
special 0x137 - Lava Battle
special 0x13D - Short Earthquake (Emerald)
special 0x156 - Battle with Ghost (FR/LG)
special 0x157 - Get on Bike (FR/LG)
special 0x161 - Start Surfing (FR/LG)
special 0x166 - Nickname
special 0x16F - Activate National Dex (FR/LG)
special 0x17B - Seagallop Animation
special 0x191 - SS. Anne Leaving
special 0x1F3 - Activate National Dex (Emerald)
For all of you who can't seem to get the earthquake to work, here's a little bit on it, from Pokepal17:
A few variables can affect the power.
What's new here? Applymovement, waitmovement, pause, playsong and fadesong. I guess I'll explain them all in that order. Applymovement is a very useful command that allows to show an overworld walking or running depending on what we want.
When we use applymovement, it has to be followed by a People Number, which is found here:
It also needs a pointer to where our movements are. An overworld with a people number of "4" seems normal, doesn't it? But what about one with 0xFF (255). There's almost never 255 overworlds on one map. 0xFF is the “hero's” people number.
Now, let's look at this movements list: (credit to HackMew for finding them and including them in XSE) Ruby/Sapphire/Emerald
Spoiler:
#raw 0x00 = Face Down
#raw 0x01 = Face Up
#raw 0x02 = Face Left
#raw 0x03 = Face Right
#raw 0x04 = Step Down (Slow)
#raw 0x05 = Step Up (Slow)
#raw 0x06 = Step Left (Slow)
#raw 0x07 = Step Right (Slow)
#raw 0x08 = Step Down (Normal)
#raw 0x09 = Step Up (Normal)
#raw 0x0A = Step Left (Normal)
#raw 0x0B = Step Right (Normal)
#raw 0x0C = Jump2 Down
#raw 0x0D = Jump2 Up
#raw 0x0E = Jump2 Left
#raw 0x0F = Jump2 Right
#raw 0x10 = Delay1
#raw 0x11 = Delay2
#raw 0x12 = Delay3
#raw 0x13 = Delay4
#raw 0x14 = Delay5
#raw 0x15 = Step Down (Fast)
#raw 0x16 = Step Up (Fast)
#raw 0x17 = Step Left (Fast)
#raw 0x18 = Step Right (Fast)
#raw 0x19 = Step on the Spot Down (Slow)
#raw 0x1A = Step on the Spot Up (Slow)
#raw 0x1B = Step on the Spot Left (Slow)
#raw 0x1C = Step on the Spot Right (Slow)
#raw 0x1D = Step on the Spot Down (Normal)
#raw 0x1E = Step on the Spot Up (Normal)
#raw 0x1F = Step on the Spot Left (Normal)
#raw 0x20 = Step on the Spot Right (Normal)
#raw 0x21 = Step on the Spot Down (Faster)
#raw 0x22 = Step on the Spot Up (Faster)
#raw 0x23 = Step on the Spot Left (Faster)
#raw 0x24 = Step on the Spot Right (Faster)
#raw 0x25 = Step on the Spot Down (Fastest)
#raw 0x26 = Step on the Spot Up (Fastest)
#raw 0x27 = Step on the Spot Left (Fastest)
#raw 0x28 = Step on the Spot Right (Fastest)
#raw 0x29 = Slide Down
#raw 0x2A = Slide Up
#raw 0x2B = Slide Left
#raw 0x2C = Slide Right
#raw 0x2D = Slide Down
#raw 0x2E = Slide Up
#raw 0x2F = Slide Left
#raw 0x30 = Slide Right
#raw 0x31 = Slide Down
#raw 0x32 = Slide Up
#raw 0x33 = Slide Left
#raw 0x34 = Slide Right
#raw 0x35 = Slide Running Down
#raw 0x36 = Slide Running Up
#raw 0x37 = Slide Running Left
#raw 0x38 = Slide Running Right
#raw 0x3A = Jump Facing Left (Down)
#raw 0x3B = Jump Facing Down (Up)
#raw 0x3C = Jump Facing Up (Left)
#raw 0x3D = Jump Facing Left (Right)
#raw 0x3E = Face Player
#raw 0x3F = Face Against Player
#raw 0x40 = Lock Sprite Facing
#raw 0x41 = Release Sprite Facing
#raw 0x42 = Jump Down
#raw 0x43 = Jump Up
#raw 0x44 = Jump Left
#raw 0x45 = Jump Right
#raw 0x46 = Jump in Place (Facing Down)
#raw 0x47 = Jump in Place (Facing Up)
#raw 0x48 = Jump in Place (Facing Left)
#raw 0x49 = Jump in Place (Facing Right)
#raw 0x4A = Jump in Place (Facing Down/Up)
#raw 0x4B = Jump in Place (Facing Up/Down)
#raw 0x4C = Jump in Place (Facing Left/Right)
#raw 0x4D = Jump in Place (Facing Right/Left)
#raw 0x4E = Face Left
#raw 0x54 = Hide Sprite
#raw 0x55 = Show Sprite
#raw 0x56 = Exclamation Mark (!)
#raw 0x57 = Question Mark (?)
#raw 0x58 = Love (<3)
#raw 0x62 = Walk Down
#raw 0x63 = Walk Down
#raw 0x64 = Face Down (Delayed)
#raw 0x65 = Face Up (Delayed)
#raw 0x66 = Face Left (Delayed)
#raw 0x67 = Face Right (Delayed)
#raw 0x70 = Jump in Place (Facing Down)
#raw 0x71 = Jump in Place (Facing Up)
#raw 0x72 = Jump in Place (Facing Left)
#raw 0x73 = Jump in Place (Facing Right)
#raw 0x74 = Jump Down Running
#raw 0x75 = Jump Up Running
#raw 0x76 = Jump Left Running
#raw 0x77 = Jump Right Running
#raw 0x78 = Jump2 Down Running
#raw 0x79 = Jump2 Up Running
#raw 0x7A = Jump2 Left Running
#raw 0x7B = Jump2 Right Running
#raw 0x7C = Walk on the Spot (Down)
#raw 0x7D = Walk on the Spot (Up)
#raw 0x7E = Walk on the Spot (Left)
#raw 0x7F = Walk on the Spot (Right)
#raw 0x80 = Slide Down Running
#raw 0x81 = Slide Up Running
#raw 0x82 = Slide Left Running
#raw 0x83 = Slide Right Running
#raw 0x84 = Slide Down
#raw 0x85 = Slide Up
#raw 0x86 = Slide Left
#raw 0x87 = Slide Right
#raw 0x88 = Slide Down on Left Foot
#raw 0x89 = Slide Up on Left Foot
#raw 0x8A = Slide Left on Left Foot
#raw 0x8B = Slide Right on Left Foot
#raw 0x8C = Slide Left diagonally (Facing Up)
#raw 0x8D = Slide Right diagonally (Facing Up)
#raw 0x8E = Slide Left diagonally (Facing Down)
#raw 0x8F = Slide Right diagonally (Facing Down)
#raw 0x90 = Slide2 Left diagonally (Facing Up)
#raw 0x91 = Slide2 Right diagonally (Facing Up)
#raw 0x92 = Slide2 Left diagonally (Facing Down)
#raw 0x93 = Slide2 Right diagonally (Facing Down)
#raw 0x96 = Walk Left
#raw 0x97 = Walk Right
#raw 0x98 = Levitate
#raw 0x99 = Stop Levitating
#raw 0x9C = Fly Up Vertically
#raw 0x9D = Land
#raw 0xFE = End of Movements
Fire Red/Leaf Green
Spoiler:
#raw 0x0 = Face Down
#raw 0x1 = Face Up
#raw 0x2 = Face Left
#raw 0x3 = Face Right
#raw 0x4 = Face Down (Faster)
#raw 0x5 = Face Up (Faster)
#raw 0x6 = Face Left (Faster)
#raw 0x7 = Face Right (Faster)
#raw 0x8 = Step Down (Very Slow)
#raw 0x9 = Step Up (Very Slow)
#raw 0xA = Step Left (Very Slow)
#raw 0xB = Step Right (Very Slow)
#raw 0xC = Step Down (Slow)
#raw 0xD = Step Up (Slow)
#raw 0xE = Step Left (Slow)
#raw 0xF = Step Right (Slow)
#raw 0x10 = Step Down (Normal)
#raw 0x11 = Step Up (Normal)
#raw 0x12 = Step Left (Normal)
#raw 0x13 = Step Right (Normal)
#raw 0x14 = Jump2 Down
#raw 0x15 = Jump2 Up
#raw 0x16 = Jump2 Left
#raw 0x17 = Jump2 Right
#raw 0x18 = Delay1
#raw 0x19 = Delay2
#raw 0x1A = Delay3
#raw 0x1B = Delay4
#raw 0x1C = Delay5
#raw 0x1D = Step Down (Fast)
#raw 0x1E = Step Up (Fast)
#raw 0x1F = Step Left (Fast)
#raw 0x20 = Step Right (Fast)
#raw 0x21 = Step on the Spot Down (Normal)
#raw 0x22 = Step on the Spot Up (Normal)
#raw 0x23 = Step on the Spot Left (Normal)
#raw 0x24 = Step on the Spot Right (Normal)
#raw 0x25 = Step on the Spot Down (Faster)
#raw 0x26 = Step on the Spot Up (Faster)
#raw 0x27 = Step on the Spot Left (Faster)
#raw 0x28 = Step on the Spot Right (Faster)
#raw 0x29 = Step on the Spot Down (Fastest)
#raw 0x2A = Step on the Spot Up (Fastest)
#raw 0x2B = Step on the Spot Left (Fastest)
#raw 0x2C = Step on the Spot Right (Fastest)
#raw 0x2D = Face Down (Delayed)
#raw 0x2E = Face Up (Delayed)
#raw 0x2F = Face Left (Delayed)
#raw 0x30 = Face Right (Delayed)
#raw 0x31 = Slide Down (Slow)
#raw 0x32 = Slide Up (Slow)
#raw 0x33 = Slide Left (Slow)
#raw 0x34 = Slide Right (Slow)
#raw 0x35 = Slide Down (Normal)
#raw 0x36 = Slide Up (Normal)
#raw 0x37 = Slide Left (Normal)
#raw 0x38 = Slide Right (Normal)
#raw 0x39 = Slide Down (Fast)
#raw 0x3A = Slide Up (Fast)
#raw 0x3B = Slide Left (Fast)
#raw 0x3C = Slide Right (Fast)
#raw 0x3D = Slide Running on Right Foot (Down)
#raw 0x3E = Slide Running on Right Foot (Up)
#raw 0x3F = Slide Running on Right Foot (Left)
#raw 0x40 = Slide Running on Right Foot (Right)
#raw 0x41 = Slide Running on Left Foot (Down)
#raw 0x42 = Slide Running on Left Foot (Up)
#raw 0x43 = Slide Running on Left Foot (Left)
#raw 0x44 = Slide Running on Left Foot (Right)
#raw 0x46 = Jump Facing Left (Down)
#raw 0x47 = Jump Facing Down (Up)
#raw 0x48 = Jump Facing Up (Left)
#raw 0x49 = Jump Facing Left (Right)
#raw 0x4A = Face Player
#raw 0x4B = Face Against Player
#raw 0x4C = Lock Sprite Facing
#raw 0x4D = Release Sprite Facing
#raw 0x4E = Jump Down
#raw 0x4F = Jump Up
#raw 0x50 = Jump Left
#raw 0x51 = Jump Right
#raw 0x52 = Jump in Place (Facing Down)
#raw 0x53 = Jump in Place (Facing Up)
#raw 0x54 = Jump in Place (Facing Left)
#raw 0x55 = Jump in Place (Facing Right)
#raw 0x56 = Jump in Place (Facing Down/Up)
#raw 0x57 = Jump in Place (Facing Up/Down)
#raw 0x58 = Jump in Place (Facing Left/Right)
#raw 0x59 = Jump in Place (Facing Right/Left)
#raw 0x60 = Hide Sprite
#raw 0x61 = Show Sprite
#raw 0x62 = Exclamation Mark (!)
#raw 0x63 = Question Mark (?)
#raw 0x64 = Cross (X)
#raw 0x65 = Double Exclamation Mark (!!)
#raw 0x66 = Happy ()
#raw 0xFE = End of Movements
Before we look at the movements in a different view, I should explain the layout of the movements at the pointer. It's set out in a similar way to a message. We have #org @pointer first and what's being written to the ROM below that. You put #raw, then the movement that you want. You have to put #raw 0xFE at the end of the movements, or else the movements won't work.
Now, we're going to look at waitmovement and pause. waitmovement is one of the best commands that you will ever find. It's the "perfect pause"! When used as waitmovement 0x0, it will wait for the exact amount of time that it takes for the movements to move the sprite. Really helpful, isn't it?
Now, we have pause. pause will wait for a set amount of time. You have to add the amount that it will wait for. If you want to calculate pause time vs. seconds, here's a (not very good) conversion thingy: 0x20 Pause time = approx. 1 sec. real time
I don't use this very often. I prefer to use waitmovement almost all of the time.
Okay now, no more sidetracking. Let's look at the movements. Let's look at the script without anything but the applymovements, pause and waitmovements. This leaves us with this:
The first two applymovements are in a completely normal setup. ie. applymovement 0xXX @YYYYYY
waitmovement/pause
But let's look at the next set of movements. It's set up differently. We have two applymovements before we have some sort of pause. What would happen if I did that? They would both move at the same time. This is sometimes referred to as "follow-me." With a "follow-me", we can use as many applymovements before the pause as we want. This can be useful if we wanted a "group" to walk together. We can have three, four, five, six, or however many you want in a "group". I think that's all there is to the applymovement command.
Now we can move onto that playsong.
When we script playsong, we need a few bytes to get it to work. Here's a short summary of what we need: playsong [song #] 0x0
That 0x0 is a buffer. We need it in order for the command to work.
Whatever game you're hacking, you can find the song numbers in A-Map.
Now we have fadesong. What's that do? It's set up similar to playsong and will fade into the sound displayed. If you want more detail on how it works, just refer back to playsong. The only thing different is that it does not need that extra buffer.
I thought I might point out something about the checkflag in this script. We actually have nosetflag in this script. So why do I have a checkflag? In one script, we can check if a flag was set in a different script. In this section, we check if the Pokemon menu has been activated before the script will end (@done).
Okay. Compile the script, assign it to a script tile (green with an S) and not a person.
Now test it in the ROM. Then look at this spoiler.
Spoiler:
Didn't work, did it? Froze on the spot. You're going to need to change this...
to this....
Try it now. Worked perfectly, didn't it?
So, what's next?
Countpokemon
I'm not going to show just one script. There's too much to explain in just one script.
Here's the most basic example.
Code:
countpokemon
compare 0x800D 0x6
if 0x1 goto @continue
This is the most basic form.
Before I explain this fragment of a script, I should go into a little more detail on the command countpokemon itself. countpokemon checks how many Pokemon are in your party and assigns the value to 0x800D. If we have six Pokemon in our party, it would assign 0x06 to 0x800D, and if we had 3 Pokemon in our party, it would assign 0x03 to 0x800D.
Now back to that part of a script. compare 0x800D 0x6 checks to see if there are six Pokemon in the player's party. Then, with if 0x1 goto @continue, it says, "if there are six Pokemon in your party, go to @continue".
That's the simplest and easiest form of countpokemon.
I'll add one more example just to help the information sink in.
Code:
countpokemon
compare 0x800D 0x2
if 0x1 goto @continue
In this example, it checks if you have two Pokemon. If you have a number of Pokemon other than two, the script won't continue to @continue.
Trainerbattle 0x0
Just a simple trainerbattle script:
Code:
#dynamic 0x800000
#org @start
trainerbattle 0x0 0x001 0x0 @before @after
msgbox @beaten 0x6
release
end
#org @before
= Go, all my PIKACHUs!
#org @after
= Nooo! My PIKACHUs!!!!!
#org @beaten
= My PIKACHUs can be used to\ncharge my Nintendo DS Lite.
t
rainerbattle is a battle with a trainer. trainerbattle is great because the game keeps track of whether you have beaten a trainer or not. In this script, we have no need for a checkflag/setflag situation.
Now to explaining these values after the trainerbattle. These are: trainerbattle0x0 [Type of battle] 0x001 [Trainer ID] 0x0 [Reserved Byte (normally 0x0)] @before [Pointer to Message When Seen] @after [Pointer to Winning Message]
I guess I'll explain the type of battle. This byte determines whether it's a double battle, Gym Leader Battle, or another type. A normal trainerbattle is 0x0. The trainer will "see you", then go to the beginning message, then the battle, and then goes to the message when you win.
Now we'll move onto the Trainer ID. This is the ID of a trainer that's found in PET. For example, Brock can be found with with a Trainer ID of 0x19E, and Blaine can be found with 0x1A3.
Now, there are two pointers, @before & @after. I've labeled these to help display what they are used for. The first pointer, @before, shows the pointer to the message displayed before the battle.
Now onto @after. It's the pointer to the message after the battle, obviously! This message appears while we are still in the battle itself. Remember the colors that were mentioned towards the beginning of this tutorial? Well, we can use colors with this too! They're different, though. Sadly, I don't have a list for those values.
Now, if I were to test it in a ROM, what would happen after the trainerbattle? Nothing. The script ends. So why do I have a msgbox after it?
Remember how I talked about trainerbattle keeping track of whether you have beaten them or not? Well, once you beat the trainer, the trainerbattle will be skipped, so when you speak to them after beating them in a battle, it'll be treated like a normal message script.
Wait! Why don't I have a lock and faceplayer after the trainerbattle? The reason is that once you have beaten that trainer, trainerbattle will also act as the lock/faceplayer combo, and you don't have to worry about them in this script.
That's the scripting side of this command done. Now the A-Map side. Now compile this script, and test it in a ROM. Did it work like a normal in-game trainer battle? I bet your answer is no.
You'll need to fill in these boxes:
Trainerbattle 0x1
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
checkflag 0x820
if 0x1 goto @done
msgbox @2 0x6
trainerbattle 0x1 0x001 0x0 @before @after @later
end
#org @before
= Show me what ya got!
#org @after
= What the-?
#org @later
msgbox @3 0x6
fanfare 0x13E
msgbox @4 0x4
waitfanfare
closeonkeypress
msgbox @5 0x6
giveitem 0x147 0x1
setflag 0x820
release
end
#org @done
msgbox @1 0x6
release
end
#org @1
= You should travel to Cerulean City\nto get your next badge.
#org @2
= Welcome to Pewter City Gym.\nYou want to challenge me?
#org @3
= Congratulations!\pFor beating me, you get\nthis badge!
#org @4
= \v\h01 recieved a badge!
#org @5
= Oh, and please take this.
Remember that image that was used with the previous script? Ignore that. For this kind of script, the "Trainer" box doesn't need to be checked and the “View radius” box doesn't need to have a value in it.
This script is a little longer than the previous trainerbattle script.
You'll see that the "0x0" from the previous script has become a "0x1." There's also a third pointer.
If the “Battle type” box says "0x1", it means that it needs three pointers after the trainerbattle command. The first two are the same as in the previous script: one for before the battle, and one for after the battle. But the third pointer doesn't go to a message! It points to @later. It's a separate part of the script. This is where the script continues after you've won the battle.
If you refer to the flag section, you'll be able to see what the setflag 0x820 is.
Spoiler:
It's to activate the first badge on the trainer card.
I think that's about all I need to add on trainerbattles.
Warp
I think I'm at the stage in this tutorial where I don't need to show an example script for every command. This is one of those cases.
So now we have warp. warp is there to allow the player to warp to a different map or location. warp is used like this: warp [map bank] [map number] [warp number] [extra, for now] [extra, for now]
Let's say we wanted to warp to the door of Oak's Lab in Pallet Town.
Open a Fire Red/Leaf Green Rom in Advance-Map and open the Pallet Town map. To the far left of the program's window, you should see an orange box next to the current open map. If you've clicked Pallet Town, it should say “Pallet Town (3.0)”.
The "3" is the map bank and the "0" is the map number. Now, we need to click on the Warp on the door of Oak's Lab. It should say "Event Number: 2" on an unmodified Pallet Town. Now, we have our three values.
Now, we write our warp command.
Code:
warp 0x3 0x0 0x2 0x0 0x0
There's our warp! The only thing is, there's a problem with warping. Once you use warp, the script ends. You're probably saying, "How come when Prof. Oak takes you to his lab in Fire Red, the script still continues?" That involves some of the more difficult parts of scripting, Level Scripts. Since these are a little difficult, I'll explain these towards the end of the tutorial.
Warp to Position
Code:
#dynamic 0x800000
#org @start
msgbox @1 0x6
warp 0x4 0x1 0xFF 0x02 0x06
end
#org @1
= I'm going to teleport you\nto your bed.
This is something that quite a few people don't know about. It's something that a lot of scripters were 'in the dark' about.
Well, this should warp you straight to your bed in your room. This is in map PALLET TOWN (4.1). So, what's the 0xFF for? The 0xFF is what tells the command that it's going to warp to a certain position. What are the last values for?
Let's look at the locations of the bed in your room. The values are: (X=2) (Y=6). They are actually 02 & 06. Now, just plug the numbers into the script.
It's that simple! We can now warp to a certain position.
Weather Commands
When we want to change the weather in a script, there are two commands that we need to know about: setweather and doweather.
setweather will set a certain type of weather to be activated by doweather.
This is how we set up our setweather command: setweather [weather type, 2 bytes]
A list of the different weather types is in A-Map.
If we wanted to have rainy weather, we would have:
Code:
setweather 0x3
doweather is used to activate the weather. So let's show a script to display these in use:
Code:
#dynamic 0x800000
#org @start
checkflag 0x200
if 0x1 goto @next
setweather 0x3
doweather
setflag 0x200
release
end
#org @next
setweather 0x2
doweather
clearflag 0x200
release
end
There is also one more somewhat useful command: resetweather.
This command will prepare the game to return back to its default map weather. Since this only prepares the ROM for it, it still must be followed by doweather.
Pokemart
Here's a basic script showing the pokemart command. By now, you should be able to add to it pretty easily:
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
pokemart @values
release
end
#org @values
#raw word 0x1
#raw word 0x2
#raw word 0x3
#raw word 0x4
#raw word 0x5
#raw word 0x6
#raw word 0x7
#raw word 0x8
#raw word 0x9
#raw word 0xA
#raw word 0xB
#raw word 0xC
#raw word 0x13
#raw word 0x14
#raw word 0x0
Well, here we have the pokemart command. It's simply followed by a pointer. This will point to the values of the items that will appear in the PokeMart screen. The #raw words are set up differently. They're set up like this: #raw word 0x(value)
In this case, we have the these items, respectively:
Master Ball 0x1
Ultra Ball 0x2
Great Ball 0x3
Poké Ball 0x4
Safari Ball 0x5
Net Ball 0x6
Dive Ball 0x7
Nest Ball 0x8
Repeat Ball 0x9
Timer Ball 0xA
Luxury Ball 0xB
Premier Ball 0xC
Parlyz Heal 0x13
Full Restore 0x14
But why did I put #raw word 0x0 at the end if there isn't an 0x0 item? 0x0 marks the end of the item line. Without this, the command will NOT work.
#raw's
I think I should go into a little detail on these. When we script in #raw, we're just scripting in hex. Here's an example script:
hidesprite is the command that we covered a little in detail earlier. We used it like this: hidesprite 0x800F . It makes the last person we talked to disappear. But what if we wanted a certain person to disappear?
A common mistake is confusing the People ID with the Event ID. Make sure you get the People ID. This is how you set out the command: hidesprite 0x(people no.)
So let's use an example: People ID. = 4. Here's how it will appear: hidesprite 0x04
One more: People ID = 12.
hidesprite 0x0C
By now, you should have a pretty good understanding of the hidesprite command, so let's move onto showsprite.
showsprite can make an OW re-appear once it has been hidden with hidesprite. showsprite is set out in the exact same way as hidesprite.
Here's some complimentary examples from when I explained hidesprite: Example 1. People No. = 4. showsprite 0x04 Example 2. People No = 12. showsprite 0x0C
If you remember back to wildbattle, you'll see that you need to use setflag to keep the person hidden. If we wanted to keep them viewable after using showsprite, we would need to use clearflag.
Giveegg
giveegg is a relatively simple command to use. All we need is to add the Pokemon species number after it.
As an example, let's give a Pikachu Egg. Pikachu's Pokemon number is 25. Converting that to hex gives us 0x19.
Our giveegg command would appear like this:
Code:
giveegg 0x19
Just in case you need some more explanation, let's use Treecko as an extra example. Treecko is number 277. Converting it to hex gives us 0x115. Our line appears like this:
Code:
giveegg 0x115
Pretty easy, huh?
Textcolor
We have three useful colors here:
Blue = 0x00
Red = 0x01
Black = 0x02
Since they're short, I'll show examples of all three of them: Black Text
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
textcolor 0x02
msgbox @1 0x6
release
end
#org @1
= This is black text.
Blue Text
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
textcolor 0x00
msgbox @1 0x6
release
end
#org @1
= This is blue text.
Red Text
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
textcolor 0x01
msgbox @1 0x6
release
end
#org @1
= This is red text.
Setmaptile
I'll show a script and explain it for this one:
Code:
#dynamic 0x800000
#org @start
setmaptile 0xA 0xD 0x1 0x0
special 0x8E
release
end
Nice and short. setmaptile is set out like this: setmaptile [X Coordinate] [Y Coordinate] [Tile Number] [Movement allowed?]
So in my short script, we have:
X Co-ordinate = 10 or 0xA
Y-Co-ordinate = 13 or 0xD
Tile = Normal Grass (in tileset 0 [Fire Red]) or 0x1
Movement Allowed = Yes or 0x0
We can find our X and Y coordinates in Advance-Map, which has been shown earlier. We can also find our tile number in Advance-Map. The number also depends on what tileset we are using. Hold your mouse over a tile in the right pane. In the little status bar at the bottom on the far left, you should have Block: XX Offset: XXXXXX
Movement allowed has two possible options:
0x0 = Passable
0x1 = Blocked off
So, what's the special there for?
This special will reset the map so that it allows the tile to set. Without this, you'll have to leave the screen and come back before it will actually work.
Special Trainer Commands
We've got three commands here, all #raw's.
First is checktrainerflag.
Second is cleartrainerflag.
Last is is settrainerflag.
All three commands are set out in the same way:
[command] [PET ID]
For all three examples, I'm going to use the trainer "Leader Brock", with a PET ID of 0x19E.
Now let's work with checktrainerflag. Since we're checking for something, the answer or result is going to have to be stored somewhere. Like most commands, the result is stored into 0x800D. Here's an example:
Code:
checktrainerflag 0x19E
compare 0x800D 0x1
if 0x1 goto @alreadybattled
Pretty straightforward, isn't it? It's simply followed by the compare and if statements. If you thought this was easy, the next two are even easier.
Here's cleartrainerflag. Again, we'll be using Brock for the example:
Code:
cleartrainerflag 0x19E
That's it. If were supposed to battle Brock, we couldn't battle him anymore. The trainerbattle is disabled.
But if we want to re-enable the trainerbattle what command do we use? settrainerflag! I'm still using Brock.
Code:
settrainerflag 0x19E
The trainerbattle 0x19E has now been re-enabled.
Checkitem/removeitem
These are probably easier to view through an example:
Code:
#dynamic 0x800000
#org @start
lock
faceplayer
msgbox @1
boxset 0x5
compare 0x800D 0x1
if 0x1 goto @check
msgbox @2 0x6
release
end
#org @check
checkitem 0xD 0x1
compare 0x800D 0x1
if 0x4 goto @got
msgbox @2 0x6
release
end
#org @got
removeitem 0xD 0x1
giveitem 0x4 0x1
msgbox @3 0x6
release
end
#org @1
= Would you like to trade this\nPOKE BALL for your POTION?
#org @2
= Oh. That's too bad.
#org @3
= Yay! Thanks a lot!
We've got a few new things here. We've got:
checkitem 0xD 0x1
if 0x4 goto @pointer
removeitem 0x4 0x1
I'll start at the top of my list.
if 0x4 goto @pointer is different. Why have I used 0x4 instead of 0x1?
Other than what we have here, we can also use values, like 0x1, 0x2, 0x3 etc. I'll propose a "table".
Code:
Lower Than (0x0)
Equals (0x1)
Greater Than (0x2)
Lower than or Equal to (0x3)
Greater than or Equal to (0x4)
Not exactly equal to (0x5)
Now we can see what each value represents.
Pretty useful, huh? From this point on, I'll only be using 0xX with the if line. I thought I'd warn you just so it doesn't look like I've totally changed the way I script without notice.
Now checkitem. checkitem is scripted like this:
Code:
checkitem [item number] [amount of item]
As an example, let's say we want to check for 10 MASTERBALLs. It would appear like this:
Code:
checkitem 0x1 0xA
compare 0x800D 0x1
if 0x4 goto @got
I haven't explained the compare yet, have I? This compare checks for "Yes, you've got the item (0x1)" or "No, you don't have the item (0x0)"
By now, you should be able to tell what the if should do.
Now, we go into removeitem. Obviously, it removes an item from your bag. It's set out in the same way as giveitem and checkitem.
Code:
removeitem [item number] [amount to remove]
Do I need to give any more explanation? This should be enough info on it.
Copyvar
A little command that's pretty easy to explain. It just copies what's stored in one variable to another. We will use this more and more often as we progress through the tutorial.
Here's the explanation:
Let 0x8008 be "A" and 0x800D be "B"
Code:
copyvar 0x8008 0x800D
Variable "B" copies onto variable "A".
I know that it's backwards, but that's just the way that copyvar is.
Pretty easy, don't you think?
Copyvarifnotzero
This is what some might call a little "add-on" to the copyvar command. The name says it all, doesn't it? It says, “copy variables, if not equal to zero”.
Code:
copyvarifnotzero 0x800D 0x8004
That's about it. Pretty basic, don't you think?
Setvar
This is a pretty complicated command and has a lot of uses, so I'm just going to give an explanation of the command but not give examples of the different ways to use it. In the following few sections, you'll see some ways of using it. Setvar is pretty simple naming. It says “set to variable”. It sets a certain value, ranging from 0x0 to 0xFFFF, to a certain valuable. It's set out like this:
Code:
setvar [variable] [value]
Here's just a sample view of how the command appears:
Code:
setvar 0x8008 0x1
If it's still hard to think about, try thinking of it as a msgbox @(text) 0x5. Depending on whether or not we choose "Yes" or "No", it assigns a certain value to 0x800D. With setvar, we can choose the variable and the value that is assigned.
You'll see more of this from this point on.
Random
With this command, the ROM will choose a random number within the range of 0x0 to the value you set with the argument, and then assign it to 0x800D. Here's a little example:
Code:
random 0x03
compare 0x800D 0x0
if 0x1 goto @option1
compare 0x800D 0x1
if 0x1 goto @option2
compare 0x800D 0x2
if 0x1 goto @option3
That should be about it. I'll show an extra example if you need it, but I shouldn't need to explain any more:
Code:
random 0x0A
compare 0x800D 0x0
if 0x1 goto @1
compare 0x800D 0x1
if 0x1 goto @2
compare 0x800D 0x2
if 0x1 goto @3
compare 0x800D 0x3
if 0x1 goto @4
compare 0x800D 0x4
if 0x1 goto @5
compare 0x800D 0x5
if 0x1 goto @6
compare 0x800D 0x6
if 0x1 goto @7
compare 0x800D 0x7
if 0x1 goto @8
compare 0x800D 0x8
if 0x1 goto @9
compare 0x800D 0x9
if 0x1 goto @10
That should be about it.
Special2
I'll show an example script fragment. This is a "checkpokemon" only usable for Fire Red.
First, we assign the value to the variable 0x8004. Using this command, the value is the Pokemon we want to check for. In this case, it's Pikachu.
Now, we have special2. special2 is set out like this:
Code:
special2 [Variable to store value] [event to call]
The event we use is 0x17C; this checks if the Pokemon that we have set to 0x8004 is in our party. If it is in our party, 0x1 is assigned to the variable, which in this case is 0x800D. If it's not in our party, 0x0 is assigned to the variable.
The following compare and if act in the same way as the compare and if used with the checkitem. If you've forgotten, here's a quote of myself to help you:
Quote:
Originally Posted by diegoisawesome
This compare checks for "Yes, you've got the item (0x1)" or "No, you don't have the item (0x0)"
By now, you should be able to tell what the if should do.
There you go. Lesson 1 on setvar and special2 under your belt.
Special, Part 2
We're adding to the special command. Well, not really. I'm just going to tell you about the waitstate command.
Let's just use special 0x9D, which in Fire Red, shows the "Old Man Catches Weedle" scene. Look at how we're going to use it:
Code:
special 0x9D
waitstate
Simple as that. No arguments, just waitstate.
Movesprite
This will obviously move a sprite from one place to another instantaneously.
It's set out like this:
Code:
movesprite [People Number] [X coordinate to move sprite to] [Y coordinate to move sprite to]
The people number is the same as it has been since the beginning of this tutorial.
The X coordinate is the X coordinate of the tile that we want to move the overworld sprite to.
Obviously, the Y coordinate is the Y coordinate of the tile that we want to move the overworld sprite to.
Here's just a simple example of the command. We'll use People number = 4; X co-ordinate = 12; Y co-ordinate = 5.
Code:
movesprite 0x4 0xC 0x5
If you want another example, here's one with People Number = 9; X coordinate = 3; Y coordinate = 10.
Code:
movesprite 0x9 0x3 0xA
That's all there is to it!
Setvar Lesson 2
I'll show an example of this command that thethethethe used in his hack, Legend of Dragons. It's actually three scripts. Script 1, right tile
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x2
goto 0x8017CC
end
#org @script
checkflag 0x20A
if 0x1 goto @done
compare 0x4003 0x0
if 0x1 goto @left
compare 0x4003 0x1
if 0x1 goto @middle
compare 0x4003 0x2
if 0x1 goto @right
end
#org @left
applymovement 0xFF @move
applymovement 0x08 @move4
waitmovement 0x0
applymovement 0xFF @move3
goto @cont
end
#org @middle
applymovement 0xFF @move
applymovement 0x08 @move5
waitmovement 0x0
applymovement 0xFF @move3
goto @cont
end
#org @right
applymovement 0xFF @move
applymovement 0x08 @move2
waitmovement 0x0
applymovement 0xFF @move3
goto @cont
end
#org @cont
msgbox @1 0x5
compare 0x800D 0x1
if 0x1 goto @100
msgbox @2 0x6
goto @100
end
#org @100
msgbox @3 0x5
compare 0x800D 0x1
if 0x1 goto @101
msgbox @4 0x6
goto @102
end
#org @101
msgbox @5 0x6
goto @102
end
#org @102
setflag 0x20A
setflag 0x20B
applymovement 0x08 @move6
waitmovement 0x0
hidesprite 0x08
release
end
#org @done
release
end
#org @move
#raw 0x62
#raw 0x03
#raw 0xFE
#org @move2
#raw 0x62
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x10
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x01
#raw 0xFE
#org @move3
#raw 0x04
#raw 0xFE
#org @move4
#raw 0x62
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x10
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x01
#raw 0xFE
#org @move5
#raw 0x62
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x10
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x12
#raw 0x01
#raw 0xFE
#org @move6
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0x11
#raw 0x13
#raw 0x13
#raw 0x13
#raw 0xFE
#org @1
= [blue_fr]I see you're up early this\nmorning. I guess this means\lyou're excited.\pI need to tell you something.\nIs that okay?
#org @2
= [blue_fr]Too bad. I'm going to tell\nyou anyway.
#org @3
= [blue_fr]Unfortunately, I'm going to be a\nbit late.\pI need to take care of a few\nthings before I can go to the\lthe Dragon's Den.\pWhy don't you go ahead\nand I'll meet you there?
#org @4
= [blue_fr]Well, you have no choice\nin this.
#org @5
= [blue_fr]I'll meet you at the front\nof the room.
Script 2, middle tile
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x1
goto 8017CC
end
Script 3, left tile
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x0
goto 0x8017CC
end
You'll see that at the beginning of every script is this:
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x[value]
goto @pointer
end
What we're doing here is we are assigning a certain value depending on which tile we stand on that we will be able to call upon later.
I'll explain the goto a little later. But for now, let's look at what's in Script 1 under @script. We've got the usual checkflag 0x[flag] to prevent the event from repeating itself.
Now, we've got some compare lines:
Code:
compare 0x4003 0x0
if 0x1 goto @left
compare 0x4003 0x1
if 0x1 goto @middle
compare 0x4003 0x2
if 0x1 goto @right
The pointers give away what they're there for, don't they? They're saying, “depending on which value was set, go to a different set of movements”. This is a great way to save space, and instead of compiling that big ugly script 3 times, with slightly altered movements, we can compile that jumbo script once, and then we have two clean scripts. Also, a variable's value will not change until you set a different value to that variable. The rest of Script 1 is pretty straightforward. Let's get back to that goto.
I haven't actually explained goto yet, have I? We've only seen it with if. Well, at this point, if you've followed the rest of this tutorial, it should be obvious what the command does. It will goto a specified point, whether is be a @pointer or a 0x[hex address]. The command is set out like this:
Code:
goto [pointer]
Now we've covered that, let's get back to what we were looking at, which were the beginnings of scripts 1, 2 and 3.
Look at the similarities between each one:
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x0
goto 0x8017CC
end
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x1
goto 0x8017CC
end
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x2
goto 0x8017CC
end
Obviously, 0x8017CC is @script. How did I get that pointer?
Let's compile Script 1 into the ROM. After it's been burnt to the ROM, we should see a list of the different names of the pointers.
We should have something like this:
We need to take that pointer that is after @script. That is our pointer that we will use with Scripts 2 and 3.
If I were to use these pointers as an example, my Script 2 would be something like this:
Code:
#dynamic 0x800000
#org @start
setvar 0x4003 0x2
goto 0x80083C
end
I'd say that's all on setvar.... for now.
Resetvars
This command doesn't reset every variable, just 0x8000, 0x8001 and 0x8002.
It's just command resetvars. It doesn't need any extra arguments. All it needs it this:
finally! an XSE tutorial based on thethethethe's pokescript tutorial. I have been waiting for ages for a tutorial. thanks for making this with thethethethe's approval.
also, I disagree with the warp part...
your example there is warp 0x3 0x0 0x2...
why, every time I open a script with a warp command, it has a fifth value, for instance, warp 0xA 0x10 0x2 0xFA9C...?
I wish to know that, even if it has already been answered in the old Script Help Thread...
Also, can you include the usages of nop and nop1, for those commands mess my scripts if I play with No$GBA... :\
finally! an XSE tutorial based on thethethethe's pokescript tutorial. I have been waiting for ages for a tutorial. thanks for making this with thethethethe's approval.
also, I disagree with the warp part...
your example there is warp 0x3 0x0 0x2...
why, every time I open a script with a warp command, it has a fifth value, for instance, warp 0xA 0x10 0x2 0xFA9C...?
I wish to know that, even if it has already been answered in the old Script Help Thread...
Also, can you include the usages of nop and nop1, for those commands mess my scripts if I play with No$GBA... :\
anyways, thanks again for this tutorial.
When 0xA 0x10 0x2 0xFA9C, appears when you decompile the script, it's most likely that the command mixed up with the flag you set after it (or even with the release command).
I am not sure, but the warp command posted is wrong. When you try to compile warp 0x3 0x0 0x2, XSE says, "Too less parameter". It needs X/Y co-ordinates.
I did something that really bad.But made all Chinese can hack Pokemon, too.If you guys hate me, I totally understand,but cannot do anything but force to keep everything.
If there must be someone to undertake all spit and curse, it must be me.
Boxsets are no longer boxsets. They're just numbers after a message pointer now.
Yeah, that's just one example. But also flags from 0x200 to 0x2FF aren't that good anyway... If you check the Used Flags section on the guide you'll understand why.
I suggest the author downloading latest XSE and adjusting the whole post to adjust or remove anything that's outdated, wrong or misleading. Thanks in advance.
This is a pretty big section, so I'll split it up into 6 sections for each of the money related commands.
givemoney
paymoney
checkmoney
showmoney
hidemoney
updatemoney
I'll explain them in the order they were listed.
Givemoney
The name gives it away. This command will give the player a designated amount of money. The command is set out like this.
Let XX be the money value: givemoney [XX] 0x00
The final 0x00 actually determines whether it updates your money account. If it were changed to 0x01, the money balance does not change and therefore defeats the purpose of the giving the player money. I'll move onto explaining the money now.
I'll give you an example to show what's happening. We'll use the amount 10,000. so let's convert 10000 to Hex, which gives us 0x2710.
Here's our line of code:
Code:
givemoney 0x2710 0x00
You should be able to understand what's happening. I'll give another example, just in case you need it:
Money amount = 500 [hex = 0x1F4]
Code:
givemoney 0x1F4 0x00
]I'd say that's enough information on givemoney.
Paymoney
Like givemoney, the name gives the function away. This command takes money from the player.
The command is set up in an almost identical manner to givemoney. I'll show the setup again, just in case you forgot already:
Let XX, be the money value: paymoney [XX] 0x00
The final 0x00 has the same function as what it does with givemoney.
Just in case you wanted it, here's an example:
Money amount = 600 [Hex = 258]
Code:
paymoney 0x258 0x00
Ta-dah! You've now learned the givemoney and paymoney commands.
Checkmoney
This command, obviously, checks if your account for a designated amount of money. It's set up in the same way as the previous two commands, but there is a difference. I'll show you how it's set up. checkmoney [XX] 0x00
Looks the same, doesn't it? That's because it is exactly the same. The difference is that the reason for the 0x00 at the end is for something different than the other two. 0x00 means "Check Money account", and 0x01 would mean "Don't check Money account", so if you were to use 0x01, it would defeat the purpose of the command.
Now, how do we check the amount? Remember the countpokemon command? We check in that same way, using the compare and if lines.
Here's also a little example, just in case that wasn't explained very well:
Conditions:
Money amount = 1000 [Hex = 3E8] ;
Need at least 1000 to continue in script
Just in case you feel that you need another example, here's one more:
Conditions:
Money amount = 20,000 [Hex = 4E20] ;
Need less than 20,000 to continue in script
This breaks away from the style that the other money commands are written in. It's set out like this:
Code:
showmoney [X coordinate] [Y coordinate] 0x00
Okay. The first byte is showmoney, obviously, followed by the X coordinate and the Y coordinate on the screen. Personally, I just the co-ordinates (0,0). I think that by now you can just trust me and just use 0x00 for that last byte. There's a reason, but if you remember the reasons for the previous commands, just use the 0x00.
Here's a little example of what how it is set out:
X and Y co-ordinates - (0,0)
Code:
showmoney 0x00 0x00 0x00
This box will appear in the top left hand corner of the screen.
Hidemoney
This one is also different from the rest of them. This command is set out like this:
Code:
hidemoney [X coordinate] [Y coordinate]
The second and third arguments are just the co-ordinates of the shown money box.
If I were to write this to counter-act the effect of my previously shown script, my hidemoney line would appear like this:
Code:
hidemoney 0x00 0x00
Nice and simple.
Updatemoney
This is the last money command. It's simply set out like this:
Code:
updatemoney [X-Co-ordinate] [Y-co-ordinate] 0x00
Like the hidemoney command, the X & Y co-ordinates need to compliment the co-ordinates of the showmoney. Well, I'll just show an example, I guess.
Code:
updatemoney 0x00 0x00 0x00
I guess now I can move onto some different commands now.
Addvar
The name says it all. It says "Add to Variable". Before I explain what it does, I'll show you how it's set out.
Code:
addvar [Variable] [Value]
addvar will add the designated value to the value that is already stored within the designated variable. What a mouthful. If that's a little complicated, I'll simplify it.
As an example, let's say the variable 0x4036 already has the value 0x1 stored into it, and we want to add 0x3 to it to make it 0x4.
I'll put it into an example:
Code:
setvar 0x4036 0x1
addvar 0x4036 0x3
That's pretty much all there is to it. It's up to you to find a use for it.
Subvar
Of course, since we can add to a variable, we must be able to subtract from the variable. It's set out in the exact same way as addvar:
Code:
subvar [Variable] [Value]
Since it's just the opposing function to addvar, I think I can just go straight through to the example:
Code:
setvar 0x4004 0x6
subvar 0x4004 0x03
In the example, it takes 0x3 from what is stored in the variable 0x4004.
Lockall
It's just lockall. There's no other arguments. It's used when you want to lock all the people in the map, instead of locking just the person you're talking to. It's pretty useful.
Showpokepic
The name may be a little misleading. This command can bring up an image of a designated Pokemon. The command is set out like this:
We obviously need to begin with the command. Then, it's followed by the Pokemon number, which needs to be in hex. This is then followed by the X and Y coordinates of where you want the image of the Pokemon to appear. Here's a little example to help clarify things:
Conditions:
Pokemon = Dratini
Coordinates = (10,3) Center of Screen.
Code:
showpokepic 0x93 0x0A 0x03
I'd say that's about it for now, but I'll show a bigger example in the next section.
Hidepokepic
Without using this, your showpokepic box will remain open until you leave the map.
The command is just hidepokepic. There's no need for any arguments.
Well, here's an example of the two commands combined in a fragment of a script.
Code:
showpokepic 0x01 0x0A 0x03
msgbox @1 0x5
compare 0x800D 0x1
if 0x1 goto @seen
hidepokepic
msgbox @2 0x6
..... .....etc.
#org @seen
hidepokepic
msgbox @3 0x6
......... .........etc.
#org @1
= Have you seen this Pokemon?
#org @2
= That's too bad.
#org @3
= That's cool. I wish I could\nsee it.
The hidepokepic just closes the pokepic box.
Door Commands
There are three door related commands.
setdooropened [prepare to open door]
setdoorclosed [prepare to close door]
doorchange [activate door animation]
I guess we'll start with setdooropened.
Setdooropened
Obviously, this opens doors on a map. It's set out like this:
Code:
setdooropened [X coordinate] [Y coordinate]
Here's an example. Oak's Lab's Door in Pallet Town's coordinates are (10,0D).
Code:
setdooropened 0x10 0x0D
So try it in a ROM. Did it work?
It didn't, did it?
Here's the reason why. It need to be followed by this command.
Doorchange
This command needs to follow both setdooropened and setdoorclosed. Without this command following, they don't work. This command doesn't need any arguments. Here's an example, with the setdooropened command:
Code:
setdooropened 0x10 0x0D
doorchange
Setdoorclosed
It's set out in the same way as the setdooropened command. I'll show you the set-up again, just in case you've already forgotten.
Code:
setdoorclosed [X coordinate] [Y coordinate]
I'm going to show an example using all three commands:
There are 6 coin commands, and they are very closely "related" to the money commands, as they have similiar arguments. Here's a list of the different commands:
checkcoins
givecoins
removecoins
showcoins
hidecoins
updatecoins
I'll work my way from the top down, I guess.
Checkcoins
This is a pretty simple command, and isn't as difficult or as long as checkmoney. It checks to see if you have a certain amount of coins. It's set out like this:
Code:
checkcoins [Amount]
Here's a short little example:
Check for 3000 coins; if higher than, continue
Code:
checkcoins 0xBB8
compare 0x800D 0x1
if 0x4 goto @continue
Givecoins/removecoins
Since they have similiar aguments, I thought I'd put these two together.
This is how they are set out:
[command] [Amount]
I guess I'll give an example of both so we can move onto the other three commands: givecoins
Give 1000 coins
Code:
givecoins 0x3E8
removecoins
Take 1000 coins
Code:
removecoins 0x3E8
Showcoins
This command will display a little box with your coin count. It's set out in a similiar way to showmoney, except you drop off the last argument. This is how the command is set out:
Code:
showcoins [X Coordinate] [Y Coordinate]
As an example, the co-ordinates (0,0) will appear like this:
Code:
showcoins 0x00 0x00
Not hard, is it?
Hidecoins
Obviously, this command hides the coin counter that was brought up with the showcoins command. It's set out in the same way as showcoins, but if you want to see it again, here it is:
Code:
hidecoins [X Coordinate] [Y Coordinate]
Just remember that without this command, the counter will remain until the map is reset.
Updatecoins
Of course, this will update the coin counter and show any changes within your "coin balance". How's this set out? I bet you would be able to guess correctly. It's set up the same way as the showcoins and hidecoins, and just for the heck of it, I'll show the example again.
Code:
updatecoins [X Coordinate] [Y Coordinate]
Here's what I promised. I'll make it a little bigger than what I normally do. I shouldn't have to explain this script because you should be able to understand it:
Code:
showcoins 0x00 0x00
givecoins 0x3E8
updatecoins 0x00 0x00
msgbox @1 0x5
compare 0x800D 0x1
if 0x1 goto @begin
hidecoins 0x00 0x00
msgbox @2 0x6
release
end
#org @1
= Is there anything else?
#org @2
= Thank you! Please come\nagain!
There! I've used four of the six commands in a few lines of one script.
Displaying Names/Values
The title may be a little hard to understand. This section is dedicated to assigning names of Pokemon, names of Items and numbers to \v\h02 and others of the sort.
Here's a list of the commands that we will go over.
bufferpokemon
bufferfirstpokemon
bufferitem
bufferattack
buffernumber
Like always, I'll start at the top and work my way down.
Bufferpokemon
With this, we will assign a certain Pokemon's name to a \v\hXX variable.
It's set out like this.
Code:
bufferpokemon [buffer#] [PKMN Number]
We have to subtract two from the end of the [buffer#] and use that number.
Here's an example. We're going to assign Charizard's name to [buffer1].
bufferpokemon 0x00 0x06
msgbox @1 0x6
release
end
#org @1
= How is [buffer1]?[/code]Nice and basic. Just in case you want a second example, I'll 'chuck' one more below.
Pokemon = Chikorita; Storing to? = \v\h03
This command is set out a little differently to the one above. We just set it out like this:
Code:
bufferfirstpokemon [buffer#]
There's just two bytes needed for it to work.
Since it's such a short command, I'll just show an example. In the example, we're going to show how to assign the first Pokemon in the party's name to [buffer1].
Code:
bufferfirstpokemon 0x00
msgbox @1 0x6
.... ....
#org @1
= Let me give \v\h02 a haircut.
Bufferitem
It's set out in the exact same way that bufferpokemon is, but it's still worth showing. In case you've forgotten how bufferpokemon was set out, here's how bufferitem is set out. bufferitem [buffer#] [item #]
Since there really isn't too much need for a second explanation, I'll move straight into the example:
Code:
bufferitem 0x00 0x04
msgbox @doyou 0x5
.... .... ....
#org @doyou
= Do you have any [buffer1]s?
Notice how I've added "s" straight after [buffer1]. If you don't know why, it's so that the message will appear like this:
Quote:
Do you have any POKe BALLs?
Bufferattack
I bet you could probably guess how this command is set out. It's done the same way as bufferitem and bufferpokemon. It's set out like this.
Code:
bufferattack [buffer#] [attack #]
I think the only thing is that I haven't given you a list of the attacks yet, have I?
Anyway, here's the list. This will come in handy a little later: HEX Values
Now I guess I could jump into an example now, couldn't I?
Code:
bufferattack 0x00 0x13B
bufferpokemon 0x01 0x06
msgbox @1 0x5
... ...
#org @1
= Can [buffer2] use [buffer1]?
I just thought I'd make it a little more confusing.
The message actually says:
Quote:
Can Charizard use Overheat?
Buffernumber
This is just used to display a number stored in a variable. It's set up like this: buffernumber [buffer#] [Variable]
The downside of this command is that it can only display numbers from 0-65535 [Hex = 0x0 - I'll show an example. We're going to put the number 50000 in [buffer1].
Try this in a ROM.
The first message should appear as a normal boxset 0x6. But when we used msgboxsign, our second boxset 0x6 became a signpost box. But what's this msgboxnormal doing here? msgboxnormal converts the box back into a normal boxset 0x6. This is just a little playful command that gave us a break from the commands that are having four and five arguments.
Callasm
This command is used to call an ASM function that you have added to the ROM. I'm not going to write an example. I'm going to use the example of the command used with Mastermind X's "Shiny Hack".
This is his hex script:
Now here's my version of his script in XSE language:
Code:
#dynamic 0x800000
#org @start
callasm 0x71B771
wildbattle 0x82 0x1E 0x0
special 0x138
pause 0x101
callasm 0x71B771
end
with a bit more of an explanation.
He's called the ASM function twice: once to turn it on, and once to turn it off.
I think he's explained everything else.
Getplayerpos
getplayerpos can be used to store the player's X and Y positions on the map into designated variables.
The command is set out like this:
Quote:
getplayerpos [xxxx] [yyyy]
xxxx: Variable for x position
yyyy: Variable for y position
Here's an example. With this, we'll store the Player's X Position to 0x4000, and the Player's Y position into 0x4001.
Code:
....
getplayerpos 0x4000 0x4001
....
Repeattrainerbattle
This is a simple command that will begin the Last Trainer battle commenced. It's done simply with command repeattrainerbattle.
We can easily use this in a script by simply doing:
Code:
repeattrainerbattle
Releaseall
This command is used as the opposite to 'lockall''. This command will release all sprites on the current map.
Here's how it can be used:
Code:
releaseall
Waitkeypress
This command can be used as a pause. The command waitkeypress is used to wait until a key is pressed before it continues.
It's used like this:
Code:
waitkeypress
It doesn't need any arguments.
Yesnobox
This command is somewhat pointless when there is msgbox @text 0x5. It acts in the same way as 0x5 where when you use compare, yes = 1 and no = 0. Its only reason for use might be to have some flexibility as to where you want the box to be placed.
The command is set out like this:
Quote:
yesnobox [xx] [yy]
xx: X co-ordinate
yy: Y co-ordinate
In a script, we can use it like this:
Yes, it's something people want to use, so here's a brief guide on multichoice and two other commands that normally accompany it.
I'll show an example first, which will make it easier for me to explain how it's used:
Code:
preparemsg 0x161232
waitmsg
multichoice 0xE 0x0 0x1E 0x0
copyvar 0x8000 0x800D
compare 0x8000 0x0
if 0x1 goto @option1
compare 0x8000 0x1
if 0x1 goto @option2
compare 0x8000 0x2
if 0x1 goto @option3
compare 0x8000 0x3
if 0x1 goto @option4
compare 0x8000 0x4
if 0x1 goto @option5
compare 0x8000 0x5
if 0x1 goto @option6
compare 0x8000 0x7F
if 0x1 goto @canceled
end
First, I'll explain preparemsg. The following four bytes refer to the pointer to text. waitmsg is similar to closeonkeypress. This command is special and is used with preparemsg to close it.
Now onto the multichoice command. YAY! Well, it's set out like this:
Quote:
multichoice [xx] [yy] [zz] [aa]
xx: X co-ordinate
yy: Y co-ordinate
zz: Multi ID. Refer to Multi List
aa: Determines if B can cancel. 0x0 means B can cancel.
The first two parameters are easy to use. Like other commands, they are just the X and Y co-ordinates on the screen.
The third parameter is the options that appear on the multi list. It's for Fire Red, so sorry to Ruby hackers.
Spoiler:
[00] - Yes
No
[01] - Eevee
Flareon
Jolteon
Vaporeon
Quit looking.
[02] - Normal
Black
Pink
Sepia
[03] - Hall of Fame
Quit
[04] - Eggs
Quit
[05] - Victories
Quit
[06] - Hall of Fame
Eggs
Quit
[07] - Hall of Fame
Victories
Quit
[08] - Eggs
Victories
Quit
[09] - Hall of Fame
Eggs
Victories
Quit
[0A] - Exit
[0B] - Exit
[0C] - Exit
[0D] - Bicycle $1,000,000
No Thanks
[0E] - Abra 180 coins
Clefairy 500 coins
Dratini 2,800 coins
Scyther 5,500 coins
Porygon 9,999 coins
No Thanks
[0F] - SLP
PSN
PAR
BRN
FRZ
EXIT
[10] - Yes
No
Info
[11] - Single battle
Double battle
Multi battle
Info
Exit
[12] - Yes
No
Info
[13] - Make a Challenge
Info
Exit
[14] - Rooftop
B1F
Exit
[15] - Helix Fossil
Exit
[16] - Dome Fossil
Exit
[17] - Old Amber
Exit
[18] - Helix Fossil
Old Amber
Exit
[19] - Dome Fossil
Old Amber
Exit
[1A] - Fresh Water $200
Soda Pop $300
Lemonade $350
Exit
[1B] - 50 coins $1,000
500 coins $10,000
Exit
[1C] - Excellent
Not So Bad
[1D] - Right
Left
[1E] - TM13 4,000 coins
TM23 3,500 coins
TM24 4,000 coins
TM30 4,500 coins
TM35 4,000 coins
No Thanks
[1F] - 5F
4F
3F
2F
1F
Exit
[20] - Fresh Water
Exit
[21] - Soda Pop
Exit
[22] - Fresh Water
Soda Pop
Exit
[23] - Lemonade
Exit
[24] - Fresh Water
Lemonade
Exit
[25] - Soda Pop
Lemonade
Exit
[26] - Fresh Water
Soda Pop
Lemonade
Exit
[27] - Trade Center
Colosseum
Exit
[28] - Game Link Cable
Wireless
Exit
[29] - Smoke Ball 800 coins
Miracle Seed 1,000 coins
Charcoal 1,000 coins
Mystic water 1,000 coins
Yellow flute 1,600 coins
No Thanks
[2A] - B1F
B2F
B4F
Exit
[2B] - Linked game play
Direct Corner
Union Room
Quit
[2C] - Two Island
Three Island
Exit
[2D] - One Island
Three Island
Exit
[2E] - One Island
Two Island
Exit
[2F] - Trade Center
Colosseum
Berry Crush
Exit
[30] - Nada
Nada
Exit
[31] - Pokemon Jump
Dodrio Berry-Picking
Exit
[32] - Trade Center
Colosseum
Exit
[33] - 2 Tinymushrooms
1 Big Mushroom
[34] - Trade Center
Colosseum
Berry Crush
Exit
[35] - Trade Center
Colosseum
Exit
[36] - Sevii Islands
Navel Rock
Exit
[37] - Sevii Islands
Birth Island
Exit
[38] - Sevii Islands
Navel Rock
Birth Island
Exit
[39] - One Island
Two Island
Three Island
Exit
[3A] - Vermilion
Two Island
Three Island
Exit
[3B] - Vermilion
One Island
Three Island
Exit
[3C] - Vermilion
One Island
Two Island
Exit
[3D] - Vermilion
Exit
[3E] - Blank
Blank
Exit
[3F] - Join Group
Become Leader
Exit
[40] - Single
Double
Knockout
Mixed
Exit
From the example script, you should be able to tell that the selected result from multichoice is stored into the variable 0x800D.
You should be able to see I copied it to variable 0x8000 to see if it would confuse anyone. I hope it didn't. The copyvar was not needed. You can just compare with 0x800D, but by now, you should already know that.
The following compares should be fairly obvious as to what they do. They compare what option has been selected. 0x0 is the top option, 0x1 is the second to the top, and so on until the final option.
Name Pokemon
Here's another working Name Pokemon sequence, although this one will only work if the Pokemon is given into the party and not a PC box. Here's a script where it can be used. I'll explain it in the code.
But before I do that, Pokemon's party position is [Position] - 1. First in line is 0x0. And sixth would be 0x5. Now the script...
Code:
countpokemon
compare 0x800D 0x6 'If you have 6 Pokemon, don't continue.
if 0x1 goto @toomany
givepokemon 0x1 0x5 0x0 'Gives a Pokemon
msgbox @2 0x5 'the obligatory, "Would you like to rename....
compare 0x800D 0x1
if 0x1 gosub @name 'If yes call .... ....'
Who cares about this part?
#org @name
countpokemon 'Counts Pokemon
subvar 0x800D 0x1 'Takes one away from 0x800D. Reason Above.
copyvar 0x8004 0x800D 'copies over to 0x8004 which is used by special 0x166
fadescreen 0x1 'Fades screen to black
special 0x166 'Name Pokemon, Party number at 0x8004
waitstate 'Wait for Special
return 'Returns
#org @toomany
msgbox @1 0x6
release
end
#org @1
= Your party is full.\nPlease deposit one to\nmake room.
#org @2
= Would you like to give a\nnickname to this Pokemon?
Hope that helped.
Store Pokemon to Pokedex
Okay, so here's another string like the Name Pokemon above. It simply adds a Pokemon to the 'Seen' section of your Pokedex.
This one is fairly easy to do. Here's the script. It'll make it easier for me to explain.
Code:
setvar 0x8004 0x97
special 0x163
See? Nice and short.
Pretty basic too. We put the Pokemon number of the Pokemon we want to set to 'Seen' to 0x8004. In this case, I'm preparing Mew to appear as Seen.
Special 0x163 only finishes the job and actually sets it as Seen in your Pokedex.
That was a very extensive and in-detail scripting tutorial. Hope you enjoyed it!
If you see any bugs, feel free to tell me about them.
P.S. It took me about a week to convert to XSE style.
So how can you keep the sprite hidden with hidesprite? Setting the flag doens't work, if I walk away the sprite pop ups again, even if I set a flag right after the hidesprite command.
What I do is: a person blocks the entrence to a cave, but if you have the first badge he will walk away and and the sprite has to be hidden after that (so the player can enter the cave).
What should I do to make it work?
Edot: Never mind, didn't saw the sentence where you explain it a bit more. It works now.
Last edited by iTeruri; December 29th, 2008 at 04:36 PM.
I am sorry but this is a blatant copy of THeTheTheThe's tutorial put in to XSE. WIthout even doing it correcty shame on you, your name should be DiegoIsAThief
Even with credits did you ask him, he said not to take without perm.'s if you did show us a chat log
Do you even know how to script? I'm just asking...
Anyways, I found a mistake in your "script" the one about giving Pokemon..And that's only because I scrolled upward from the last post
Spoiler:
countpokemon
compare 0x800D 0x6
if 0x1 goto @toomany 'If you do have 6 Pokémon then don't give any
givepokemon 0x1 0x5 0x0 0x0 0x0 0x0 'Gives a Pokemon msgbox @2 0x5 'the obligatory, "Would you like to rename....
compare 0x800D 0x1
if 0x1 gosub @name 'If yes call .... ....' release 'If it's a person you're talking to, it should return to a release/end
end
Who cares about this part?
#org @name
countpokemon 'Counts Pokemon
subvar 0x800D 0x1 'Takes one away from 0x800D. Reason Above.
copyvar 0x8004 0x800D 'copies over to 0x8004 which is used by special 0x166
fadescreen 0x1 'Fades screen to black
special 0x166 'Name Pokemon, Party number at 0x8004
waitstate 'Wait for Special
return 'Returns
#org @toomany msgbox @1 0x6
release
end
#org @1
= Your party is full.\nPlease deposit one to\nmake room.
#org @2
= Would you like to give a\nnickname to this Pokemon?
Oh and By the way, XSE uses "msgbox @1 0x6" Not boxset or callstd any more
Do you even know how to script? I'm just asking...
Anyways, I found a mistake in your "script" the one about giving Pokemon..And that's only because I scrolled upward from the last post
Spoiler:
countpokemon
compare 0x800D 0x6
if 0x1 goto @toomany 'If you do have 6 Pokémon then don't give any
givepokemon 0x1 0x5 0x0 0x0 0x0 0x0 'Gives a Pokemon msgbox @2 0x5 'the obligatory, "Would you like to rename....
compare 0x800D 0x1
if 0x1 gosub @name 'If yes call .... ....'
Who cares about this part?
#org @name
countpokemon 'Counts Pokemon
subvar 0x800D 0x1 'Takes one away from 0x800D. Reason Above.
copyvar 0x8004 0x800D 'copies over to 0x8004 which is used by special 0x166
fadescreen 0x1 'Fades screen to black
special 0x166 'Name Pokemon, Party number at 0x8004
waitstate 'Wait for Special
return 'Returns
#org @toomany msgbox @1 0x6
release
end
#org @1
= Your party is full.\nPlease deposit one to\nmake room.
#org @2
= Would you like to give a\nnickname to this Pokemon?
Oh and By the way, XSE uses "msgbox @1 0x6" Not boxset or callstd any more
The words, "Who cares about this part?" means that that's the rest of the script.
Thanks for the heads-up, though.
This was a very helpful tutorial! Good job, thanks for putting in the effort to remake thethethethe's tutorial XSE style!
You mentioned that you'd do level scripts later on, and those are something that I've been having problems with. I haven't been able to find any info on those, I was wondering if you were planning on adding that?
hey thanks bra, every one says use boxset but u had that other thing i dont wann look right now and now it works thanks man also the whole 0x0 at the end of the msgbox also helped so thanks alot good tutorial im book markign this **** cause no way ima remeber it all
Also when using the callasm after inserting the shiny data you need to have the offset as the same on that you used.
__________________
I'm looking for some good (When I say good,
I mean you can hold your own by yourself)
N**i Zombies players, to form a team or even a
clan, to play with casually.
Send me a PM with your Highest Level and your PSN,
and I'll get back to you.