Advertiser Content

Pokeemerald Scripting Tutorial

Started by Avara January 2nd, 2019 4:09 PM
  • 3887 views
  • 23 replies

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Scripting Tutorial for Pokéemerald



NOTE: If you are using binary hacking tools and methods, this tutorial is not relevant to you. This is for those who are using the pokéemerald decomp.
If you're using XSE, this tutorial is where you want to look!


-----------------------------------------------------------------------------------------------------------------------------------------------------

If you already know XSE scripting from binary hacking, you should be able to pick up scripting in the decomps without too much trouble. However, if you're totally new to ROM hacking and want to begin with Pokéemerald, this guide will hopefully be of some use to you! If you're struggling with a script even after reading about a topic, feel free to leave a comment, PM me here or on Discord @Artemisia and I will be happy to try and help you out!

What are the differences between scripting in binary hacking vs scripting in pokéemerald?
There are several advantages I'm keen to share with you! First of all, you don't need any special scripting tools such as XSE - all you need is a text editor such as Notepad++. Second, it's easy to modify existing scripts - you simply edit the “scripts.inc” file as needed and hit "Save". Binary would require you to repoint your script, which brings me to my next advantage. There's no need to think about free space and offsets because the building process takes care of everything for you. Worries about free space or accidentally overwriting something are a thing of the past!

-----------------------------------------------------------------------------------------------------------------------------------------------------

This thread is a work in progress and might look a little dishevelled or incomplete as of right now, but I'm committed to finishing it quickly. At the time of writing this, Pokéemerald is around 80% decompiled, so file locations and labels might change in the future - I'll do my best to make sure this is updated accordingly as development goes on.

To set up Pokéemerald read this. After you've got everything set up, all you need is a decent text editor like Notepad++ and PoryMap to get started!

-----------------------------------------------------------------------------------------------------------------------------------------------------

Table Of Contents

*to be expanded upon*

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Labelling

If you look in “data\maps”, you'll find folders pertaining to each in-game map. Each of these map folders has their own “scripts.inc” file, where the scripts for each map are contained. You can also open a map's scripts by clicking "Open Map Scripts" in the top right corner of PoryMap's Events tab.



You can technically name your labels whatever you like so long as they are unique, but it's recommended that you stick to some kind of pattern when you're naming them so you don't confuse yourself. In this guide, I'll be using "Script_Something" for script labels and "Text_Something" for text labels for simplicity's sake, but if you have a look at existing scripts, you'll notice that a lot of labels are along the lines of "MapName_Something"/"MapName_SomethingText" (at the time of writing this).
To assign a script to a map object, you'll want to highlight it and put the script's label in the "Script" box outlined in red above.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Simple Text Scripts

I'll show you an example of a simple text script, and we can break it down.
Script_SimpleMsgScript::
	lock
	faceplayer
	msgbox Text_SimpleMsgScript, MSGBOX_DEFAULT
	release
	end

Text_SimpleMsgScript:
	.string "Hi!\n"
	.string "My name is Adam.\l"
	.string "What's your name?\p"
	.string "Nice to meet you, {PLAYER}!$"
A few things to explain:
  • lock prevents the player from moving.
  • Alternatively, lockall stops all NPCs on the map from moving.
  • faceplayer is fairly self explanatory; it just makes the NPC face the player before talking.
  • release lets the player move again.
  • If you used lockall instead, you'll have to use releaseall.
  • end indicates the end of the script (obviously).
For the text part, an explanation of line spacings etc:
  • .string indicates a new line of text.
  • \n moves to the next line.
  • \l is only used after the initial use of \n, scrolling down to display the next line.
  • \p will display the following line of text without scrolling, good for new sentences.
  • $ indicates the end of the text.

The msgbox line contains our label for the text to be displayed, as well as the type of msgbox - in the above case, MSGBOX_DEFAULT. As you probably guessed, {PLAYER} displays the player's name.
-----------------------------------------------------------------------------------------------------------------------------------------------------
We'll have some examples for the other types of msgbox:
Script_SimpleNPCScript::
	msgbox Text_SimpleNPCScript, MSGBOX_NPC
	end

Text_SimpleNPCScript:
	.string "Hi!\n"
	.string "My name is Adam.$"
MSGBOX_NPC doesn't require use of lock, faceplayer or release, whereas MSGBOX_DEFAULT does. Obviously enough, it's generally used for NPC text.
-----------------------------------------------------------------------------------------------------------------------------------------------------
Script_SignpostScript::
	msgbox Text_SignpostScript, MSGBOX_SIGN
	end

Text_SignpostScript:
	.string "Pokémon Herb Shop\n"
	.string "Bitter taste, better cure!$"
MSGBOX_SIGN is used for signposts; like MSGBOX_NPC, you don't need the lock, faceplayer or release commands.
-----------------------------------------------------------------------------------------------------------------------------------------------------
Next, we'll look at the types of message which prompt the player to give a "YES" or "NO" answer; good for a multitude of things.
Script_SimpleYesNoScript::
	lock
	faceplayer
	msgbox Text_SimpleYesNoScriptQuestion, MSGBOX_YESNO
	compare VAR_RESULT, 0
	goto_if_eq Script_PlayerAnsweredNo
	msgbox Text_PlayerAnsweredYes, MSGBOX_DEFAULT
	release
	end

Script_PlayerAnsweredNo::
	msgbox Text_PlayerAnsweredNo, MSGBOX_DEFAULT
	release
	end

Text_SimpleYesNoScriptQuestion:
	.string "Dragon-type Pokémon are the best!\n"
	.string "Wouldn't you agree?$"

Text_PlayerAnsweredYes:
	.string "Yeah! Dragons rule!$"

Text_PlayerAnsweredNo:
	.string "I guess you've never raised one.$"
Okay, so there are a few new points here. The compare VAR_RESULT line checks the result of the player's answer - 0 for "No" (1 would be "Yes"). More about vars later!
The goto_if_eq line means the script will go to a new section if the result is equal to what we specified above, in this case, 0. If it's not equal to that, the script will continue as normal.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Buffers

Let's start with bufferleadmonspeciesname, which displays the species of your player's first party member - just like it says on the tin!
bufferleadmonspeciesname [NUMBER]
The [NUMBER] part is where you choose the string display number to assign the lead Pokémon's name to. As an example, for {STR_VAR_1} this would be 0, for {STR_VAR_2} it would be 1, etc. The {STR_VAR_1} part is what you'll be using in your text to display the name like so:
Script_LeadPartyMemberIsCute::
bufferleadmonspeciesname 0
msgbox Text_LeadPartyMemberIsCute, MSGBOX_NPC
end

Text_LeadPartyMemberIsCute:
.string "Aww, your {STR_VAR_1} is so cute!$"

The bufferleadmonspeciesname line has to come before the msgbox that uses it, otherwise it won't be known which name to display in your text and you'll get a weird looking glitch. It's the same for all buffer commands, including the next one, bufferspeciesname:
bufferspeciesname [NUMBER], [SPECIES_]
Same as before, only you're adding a comma and the name of the species you want to display.
Let's combine both bufferleadmonspeciesname and bufferspeciesname in a script:
Script_CombiningBufferCommands::
bufferleadmonspeciesname 0
bufferspeciesname 1, SPECIES_TOTODILE
msgbox Text_CombiningBufferCommands, MSGBOX_NPC
end

Text_CombiningBufferCommands:
.string "Your {STR_VAR_1} is cool, but I\n"
.string "bet my {STR_VAR_2} is stronger!$"

All we've done here is store the player's lead Pokémon in {STR_VAR_1} and Totodile's name in {STR_VAR_2}. Should you need them, the list of defines for Pokémon is in “include\constants\species.h”. Starting to follow? I hope so!

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Flags

Think of a flag as an on or off switch - it can be either set ("ON") or cleared ("OFF"). They can be used to track progress, whether the player has completed a certain event or to control visibility of objects on a map.

Setting and clearing flags is nice and simple; all we have to do is:
setflag [Flag]
To set a flag, and to clear one:
clearflag [Flag]
To check if a flag is set, we'd do:
goto_if_set [Flag], [Script Label]
If you navigate through your Pokéemerald directory and open “include\constants\flags.h”, you'll find a list of all the in-game flags. Some flags have special uses, e.g. for the activation of the Running Shoes or certain menus. In this demo script, we'll set the flag that activates the Pokédex menu:
Script_CheckDexFlag::
	lock
	faceplayer
	goto_if_set FLAG_SYS_POKEDEX_GET, Script_DexFlagSet
	msgbox Text_DexFlagClear, MSGBOX_DEFAULT
	setflag FLAG_SYS_POKEDEX_GET
	release
	end
	
Script_DexFlagSet::
	msgbox Text_DexFlagSet, MSGBOX_DEFAULT
	release
	end
	
Text_DexFlagClear:
	.string "Pokédex flag is cleared.$"
	
Text_DexFlagSet:
	.string "Pokédex flag is set.$"
If the flag is set, the script jumps ahead to the Script_DexFlagSet label and the string "Pokédex flag is set" will display. If the flag is cleared, the script continues, displays "Pokédex flag is cleared" and then sets the flag before the end.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Gender Dependency

As the title suggests, we'll be looking at how to make conditional messages appear depending on player gender. You could use this for gender-dependent events!
checkplayergender
compare VAR_RESULT, [Gender]
goto_if_eq [Script Label]
A more fleshed out example:
Script_GenderDependencyExample::
	checkplayergender
	compare VAR_RESULT, MALE
	goto_if_eq Script_MaleExample
	msgbox Text_FemaleExample, MSGBOX_NPC
	end

Script_MaleExample::
	msgbox Text_MaleExample, MSGBOX_NPC
	end

Text_FemaleExample:
	.string "You are playing as a girl.$"
	
Text_MaleExample:
	.string "You are playing as a boy.$"
You could also have the opposite, of course:
Script_GenderDependencyExample::
	checkplayergender
	compare VAR_RESULT, FEMALE
	goto_if_eq Script_FemaleExample
	msgbox Text_MaleExample, MSGBOX_NPC
	end

Script_FemaleExample::
	msgbox Text_FemaleExample, MSGBOX_NPC
	end

Text_MaleExample:
	.string "You are playing as a boy.$"

Text_FemaleExample:
	.string "You are playing as a girl.$"

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Hide/Show Map Objects

Do you need to make a NPC or other OW sprite disappear?
removeobject [Event Object ID]
One line is all you need! To find the "Event Object ID", look under PoryMap's Events tab, highlight the OW and look at this section:

To make a previously hidden sprite visible, we'd use showobjectat:
showobjectat [Event Object ID], [Map]
Slightly different - as well as the object ID, you also need to add the map on which the sprite will appear.
If you want to make the sprite disappear permanently, there's an extra little thing to do. If you're still on the Objects section of the Events tab in PoryMap as shown above, you'll notice the Event Flag section.

What you want to do here is assign a flag to your NPC/OW, so you'd do:
...
removeobject [Event Object ID]
setflag [Flag]
...
Alternatively, to show a previously hidden sprite, in reverse order:
...
clearflag [Flag]
showobjectat [Event Object ID], [Map]
...

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Variables

The list of variables can be found in “include\constants\vars.h”.
setvar [Variable], [Value To Set To]
As you could probably guess, the setvar command sets your chosen variable to your chosen value. If you wanted to add to a variable's existing value, you'd use addvar:
addvar [Variable], [Value To Add To Var]
Let's say I wanted to increase the value of VAR_ASH_GATHER_COUNT by 500 - I'd have addvar VAR_ASH_GATHER_COUNT, 500. Similarly, if I wanted to subtract from a variable's existing value, I'd use subvar, which is set up exactly the same:
subvar [Variable], [Value To Subtract From Var]
To check the value of a variable, we'd use the following:
compare [Variable], [Value]
goto_if_[Condition] [Script Label]
A list of the different conditions for goto_if/call_if:
goto_if_lt = Less Than
goto_if_eq = Equal To
goto_if_gt = Greater Than
goto_if_le = Less Than or Equal To
goto_if_ge = Greater Than or Equal To

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Give, Take & Check For Items

Before you think about the multitude of free items you can give your players, you should always make sure they can actually take the item first! There are two ways of doing this.
checkitemspace [Item], [Quantity]
compare VAR_RESULT, 0
goto_if_eq [Script Label]
This neat little command checks if the player has enough room in their bag for the amount of the desired item. If there's no room in the bag, the last line redirects to a new script snippet. Let's say we wanted to check if the player has room in their bag for five Poké Balls.
checkitemspace ITEM_POKE_BALL, 5
compare VAR_RESULT, 0
goto_if_eq Script_NotEnoughSpaceInBag
Not using this prior to giving items can cause the player to "lose" them if they've got no space in their bag to take it. Now, onto actually giving the items!
giveitem_std [Item], [Quantity]
All you need is the above line, super simple. It even automatically generates a little notification that the player has obtained an item! Now, remember when I was saying that there are two ways of checking if the player has room in their bag for the item(s) you want to give them?
You can actually kill two birds with one stone:
giveitem_std ITEM_POKE_BALL, 5
compare VAR_RESULT, 0
goto_if_eq Script_BagIsFull
We're trying to give the player five Poké Balls, but if they haven't got enough space for them, the script will jump to the label Script_BagIsFull.
To remove an item:
takeitem [Item], [Quantity]
Checking whether or not the player has an item in their bag is done with the checkitem command:
checkitem [Item], [Quantity]
compare VAR_RESULT, 1
goto_if_eq [Script Label]
Let's see a proper example script. It will check if the player has any Potions, and if they don't, it will give them one.
Script_ItemDemonstration::
	lock
	faceplayer
	msgbox Text_ItemGiveaway, MSGBOX_DEFAULT
	checkitem ITEM_POTION, 1
	compare VAR_RESULT, 1
	goto_if_ge Script_HasPotionsAlready
	msgbox Text_GivingPotion, MSGBOX_DEFAULT
	giveitem_std ITEM_POTION, 1
	compare VAR_RESULT, 0
	goto_if_eq Script_BagIsFull
	release
	end

Script_HasPotionsAlready::
	msgbox Text_HasPotionsAlready, MSGBOX_DEFAULT
	release
	end

Script_BagIsFull::
	msgbox Text_BagIsFull, MSGBOX_DEFAULT
	release
	end

Text_ItemGiveaway:
	.string "Our POKéMART is running a\n"
	.string "POTION giveaway today.$"

Text_GivingPotion:
	.string "Here you go!$"

Text_HasPotionsAlready:
	.string "You already have a POTION.\n"
	.string "Don't be greedy!$"

Text_BagIsFull:
	.string "Your BAG is full.$"
I used goto_if_ge instead of goto_if_eq when checking for the Potions because this time, we're checking not that the player has exactly one - we're checking that they have more than or exactly one before we go to our label Script_HasPotionsAlready. The ge stands for greater than or equal to. If the player hasn't got enough room in their bag to take the Potion, the script will go to our label Script_BagIsFull. Should the player have the bag space and no Potions, the script will carry on and give them the Potion.
In case you missed it from the variables section, here's the list of different conditions for goto_if/call_if:
goto_if_lt = Less Than
goto_if_eq = Equal To
goto_if_gt = Greater Than
goto_if_le = Less Than or Equal To
goto_if_ge = Greater Than or Equal To
Finally, the items list is in “include\constants\items.h”.

Trev

i gave you everything...

Age 22
Male
Seen 4 Weeks Ago
Posted March 27th, 2019
1,617 posts
7.4 Years
Sorry to interrupt your space-reserving posts. I just wanted to say that your work on creating tutorials for the disassemblies is super helpful! I'm delighted to see that scripting looks a lot easier than it does in binary hacking - the labels are much clearer.
voltaic pair: aaron rpdr club css shop

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Giving Pokémon

Wondering how to give your player a gift Pokémon or Egg? In order to do this effectively, we'll need to make use of two commands.
The first is getpartysize.
getpartysize
compare VAR_RESULT, [Number]
goto_if_eq [Script Label]
The compare VAR_RESULT line checks if there are the specified number of Pokémon in your player's party. For example, compare VAR_RESULT, 6 would check if there were six. If you've been reading the other sections of this tutorial, you'll have caught on that the goto_if_eq line means that if the player has the specified number of Pokémon in their party, it'll redirect to a new script label. Why do we do this? If the player has a full party already (6), they won't be able to fit the "gift" Pokémon in their party; it'll just go straight to their PC storage (in Emerald version, anyway, can't comment on the others as not sure). Either way, it's up to you how you use this - if you want to give a Pokémon while your player has six Pokémon in their party already, you could just have your new label contain a message that notifies the player that the gift Pokémon will be sent to their PC. If you don't want the gift Pokémon to be given unless the player has room for it in their party, you can display a message such as "Oh, you don't have room in your party for this Pokémon." which may break immersion depending on your game - it's really up to you and what you want!

Anyway, onto the command for giving the Pokémon:
givemon [Pokémon], [Level], [Held Item], 0x0, 0x0, 0
Open “include\constants\species.h” for Pokémon species and “include\constants\items.h” for a list of items. If you don't want the Pokémon you're giving to be holding an item, just use ITEM_NONE. Here's an example of how to use both getpartysize and givemon:
Script_GivePokemonDemo::
	lock
	faceplayer
	msgbox Text_TakeDratini, MSGBOX_DEFAULT
	getpartysize
	compare VAR_RESULT, 6
	goto_if_eq Script_PlayerHasFullParty
	givemon SPECIES_DRATINI, 5, ITEM_DRAGON_FANG, 0x0, 0x0, 0
	playfanfare MUS_FANFA4
	msgbox Text_ReceivedDratini, MSGBOX_DEFAULT
	waitfanfare
	release
	end

Script_PlayerHasFullParty::
	msgbox Text_PlayerHasFullParty, MSGBOX_DEFAULT
	release
	end

Text_TakeDratini:
	.string "Please, take this Dratini.$"

Text_ReceivedDratini:
	.string "{PLAYER} received a Dratini!$"

Text_PlayerHasFullParty:
	.string "Ah, your party is full.$"
With the getpartysize command, we've checked if the player already has a full party, and if they do, the script will jump to the label Script_PlayerHasFullParty and the Pokémon won't be given. In the case that the player's party is not full, it'll give a level 5 Dratini holding a Dragon Fang. If you know what you're doing, you'll notice that this script will keep giving infinite Dratini if the player's party isn't full due to the fact that a flag isn't set. I figured that if people have read the flags section, they should be able to figure out how to rectify that on their own ;)

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Giving Eggs

This section will cover how to give your player a Pokémon Egg.
giveegg [Pokémon]
Super easy.
Script_GiveEggDemo::
	lock
	faceplayer
	msgbox Text_EggQuestion, MSGBOX_YESNO
	compare VAR_RESULT, 0
	goto_if_eq Script_PlayerAnsweredNo
	getpartysize
	compare VAR_RESULT, 6
	goto_if_eq Script_PlayerHasFullParty
	giveegg SPECIES_LARVITAR
	playfanfare MUS_FANFA4
	msgbox Text_ReceivedEgg, MSGBOX_DEFAULT
	waitfanfare
	release
	end

Script_PlayerHasFullParty::
	msgbox Text_PlayerHasFullParty, MSGBOX_DEFAULT
	release
	end

Script_PlayerAnsweredNo::
	msgbox Text_PlayerAnsweredNo, MSGBOX_DEFAULT
	release
	end

Text_EggQuestion:
	.string "Will you take this Egg?$"

Text_PlayerAnsweredNo:
	.string "Oh, that's too bad.$"

Text_ReceivedEgg:
	.string "{PLAYER} received the Egg!$"

Text_PlayerHasFullParty:
	.string "Your party is full.\n"
	.string "There's no room for this Egg.$"
If you've read the other sections of the tutorial, you'll see that this script asks the player whether or not they would like to accept the Egg. After that, if the player responds with "YES", it'll check if they have space in their party before giving it to them. I also already explained how to use getpartysize in the Giving Pokémon section, so I won't bother going over that again.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Give & Check For PC Items

Adding an item to the player's PC is just as easy with a single line:
givepcitem [Item], [Quantity]
Useful in cases where a player's bag might be full, but you want them to receive an item anyway. The items list is in “include\constants\items.h”.
In order to check if a player has a particular item in their PC, we'd do:
checkpcitem [Item], [Quantity]
compare VAR_RESULT, 1
goto_if_[Condition] [Script Label]
For the [Condition] part, I'll refer back to an earlier section of the tutorial.
goto_if_lt = Less Than
goto_if_eq = Equal To
goto_if_gt = Greater Than
goto_if_le = Less Than or Equal To
goto_if_ge = Greater Than or Equal To
A more fleshed-out demonstration:
checkpcitem ITEM_POTION, 1
compare VAR_RESULT, 1
goto_if_ge Script_HasPotionInPC
Should the player have one or more Potions in their PC's item storage, the script will go to the label Script_HasPotionInPC.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Movements

How to make the player/NPCs move in a script? We use the applymovement command like this:
applymovement [Event Object ID], [Movements Label]
waitmovement 0
The waitmovement line ensures that the movements are finished before the script continues. To find the "Event Object ID", look under PoryMap's Events tab, highlight the OW and look at this section:

I'll show you a better example and explain a bit more. Let's say we wanted the player to move three steps upwards along with the NPC they're talking to:
Script_MovementsDemonstration::
	lock
	faceplayer
	msgbox Text_MovementsDemonstration, MSGBOX_DEFAULT
	applymovement 1, Movement_Example
	applymovement EVENT_OBJ_ID_PLAYER, Movement_Example
	waitmovement 0
	release
	end

Text_MovementsDemonstration:
	.string "Hey!\n"
	.string "Let's walk three steps up.$"

Movement_Example:
	walk_up
	walk_up
	walk_up
	step_end
EVENT_OBJ_ID_PLAYER is used as the player's object ID. I've used 1 for my NPC's ID just for example purposes. A list of movements can currently be seen in “asm\macros\movement.inc”. Don't forget to add step_end to indicate that your movements are finished!

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Random

The random command can be used to generate a random number within the range you set, and then have the script go to various labels depending on the number. Let's say we wanted a range of 5:
random 5
switch VAR_RESULT
case 0, [Script Label 1]
case 1, [Script Label 2]
case 2, [Script Label 3]
case 3, [Script Label 4]
case 4, [Script Label 5]
We'll look at an example script next - a NPC who has three different things to say.
Script_RandomDemonstration::
	lock
	faceplayer
	random 3
	switch VAR_RESULT
	case 0, Script_RandomOption1
	case 1, Script_RandomOption2
	case 2, Script_RandomOption3
	end

Script_RandomOption1::
	msgbox Text_RandomOption1, MSGBOX_DEFAULT
	release
	end

Script_RandomOption2::
	msgbox Text_RandomOption2, MSGBOX_DEFAULT
	release
	end

Script_RandomOption3::
	msgbox Text_RandomOption3, MSGBOX_DEFAULT
	release
	end

Text_RandomOption1:
	.string "Option 1.$"

Text_RandomOption2:
	.string "Option 2.$"

Text_RandomOption3:
	.string "Option 3.$"
There are a whole bunch of things you could use this for! I like using it for my generic city/town population NPCs to make them a little bit more interesting, but you can use it for a lot more than that.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Pokémarts

Creating your own shops is straightforward enough with the pokemart command.
pokemart [Mart Label]
All you have to do is choose what you'd like your shop to sell! The list of items can be seen in “include\constants\items.h”. Once you've decided on the items you want your mart to stock, just follow the example below. Let's say we wanted to make a herb shop, we'd have:
	.align 2
Pokemart_HerbShop:
	.2byte ITEM_ENERGY_POWDER
	.2byte ITEM_ENERGY_ROOT
	.2byte ITEM_HEAL_POWDER
	.2byte ITEM_REVIVAL_HERB
	.2byte ITEM_NONE
	release
	end
Make sure you remember to add the “.2byte ITEM_NONE” line before your “release” and “end” to indicate the end of the list of goods. A full length example:
Script_PokemartExample::
	lock
	faceplayer
	message Text_HerbShopGreeting
	waitmessage
	pokemart Pokemart_HerbShop
	msgbox Text_HerbShopEnd, MSGBOX_DEFAULT
	release
	end

	.align 2
Pokemart_HerbShop:
	.2byte ITEM_ENERGY_POWDER
	.2byte ITEM_ENERGY_ROOT
	.2byte ITEM_HEAL_POWDER
	.2byte ITEM_REVIVAL_HERB
	.2byte ITEM_NONE
	release
	end

Text_HerbShopGreeting:
	.string "Welcome to our Herb Shop.\n"
	.string "How can I help you?$"

Text_HerbShopEnd:
	.string "Please come again!$"

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Weather

Manipulating weather in the overworld is easy; all you need are these two lines in your script:
setweather [Weather Type]
doweather
We use setweather to choose the weather we'd like and doweather to activate it. For instance, here's the kind of script we'd need to start a storm:
Script_ExampleWeatherScript::
	lock
	faceplayer
	msgbox Text_ExampleWeatherScriptPreRain, MSGBOX_DEFAULT
	setweather WEATHER_RAIN_HEAVY
	doweather
	msgbox Text_ExampleWeatherScriptPostRain, MSGBOX_DEFAULT
	release
	end

Text_ExampleWeatherScriptPreRain:
	.string "What a lovely day!$"

Text_ExampleWeatherScriptPostRain:
	.string "Aww, I spoke too soon.$"

The weather list can be found in “include\constants\weather.h”.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
I can't thank you less for these scripting tutorials x
Aw, thank you Delta! <3 x

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Door Commands


Another short section, but if you need a script that involves having the player or NPCs enter/exit a building, you'll need to know how to manipulate the door animations.
opendoor [X Co-ordinate of Door Tile] [Y Co-ordinate of Door Tile]
waitdooranim
The first line, opendoor, is where we specify that we want the door to use its opening animation and its location on the map. This line should always be followed by waitdooranim, which activates the door's animation. The X/Y co-ordinates refer to the position of your door in your map. You'll need to make sure this is a proper door tile (has the appropriate animation when interacted with).
To close the door again, it's pretty similar:
closedoor [X Co-ordinate of Door Tile] [Y Co-ordinate of Door Tile]
waitdooranim
Fairly self-explanatory. It's more or less the same as earlier, only this time we're saying that we want the door to display its closing animation.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Display Pokémon Sprite

You might not use it too often throughout your hack, but showing a Pokémon's sprite can add a little something extra to scripts where the Pokémon is being discussed.
drawmonpic [Pokémon], [X-Co-ord], [Y-Co-ord]
So you need to specify the sprite you want to display and the X/Y co-ordinates of the screen where you want the box containing the sprite to be drawn. The Pokémon species list is in “include\constants\species.h” if you need it. And to hide the box again:
erasemonpic
Nice and straight forward. A full script example:
Script_DisplaySpriteDemo::
	lock
	faceplayer
	drawmonpic SPECIES_DRATINI, 10, 3
	msgbox Text_DisplaySpriteDemo, MSGBOX_DEFAULT
	erasemonpic
	release
	end

Text_DisplaySpriteDemo:
	.string "Have you seen this Pokémon?$"
Co-ordinates of 10, 3 will display the box containing the specified sprite in the middle of the screen. And that's pretty much it!

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Screen Fading Effects

It's easy to give the overworld a "fading out" effect - useful for cutscenes and such - by using the fadescreen command which looks like this:
fadescreen [Fade Type Number]
What do I mean by "fade type number"? Here are the numbers for fading out to black and then reverting to normal:
fadescreen 1 – Screen fades to black.
fadescreen 0 - Screen fades from black back to normal.
Time for an example script and gif so you can see how it looks in-game!
Script_FadescreenExample::
	msgbox Text_FadescreenExample, MSGBOX_DEFAULT
	fadescreen 1
	fadescreen 0
	end

Text_FadescreenExample:
	.string "Screen fading to black.$"

It's also possible to create a white version of the same effect by swapping out the 1 and 0 for 3 and 2 respectively.
Script_FadescreenExample::
	msgbox Text_FadescreenExample, MSGBOX_DEFAULT
	fadescreen 3
	fadescreen 2
	end

Text_FadescreenExample:
	.string "Screen fading to white.$"

To serve as a reminder, here is a list of all the fadescreen types for quick reference:
fadescreen 3 – Screen fades to white.
fadescreen 2 – Screen fades from white back to normal.

fadescreen 1 – Screen fades to black.
fadescreen 0 - Screen fades from black back to normal.

Avara

Female
Izantine
Seen 1 Day Ago
Posted 1 Day Ago
1,085 posts
7.9 Years
Play Pokémon Cry

Using Pokémon cries as a sound effect is another super easy thing to do, all you need is the playmoncry command:
playmoncry [Pokémon], 0
Followed by waitmoncry, which doesn't have any arguments. Just as it looks, it simply means the script will continue after the cry has finished playing.
Script_CryDemo::
	lock
	faceplayer
	playmoncry SPECIES_ARBOK, 0
	msgbox Text_CryDemo, MSGBOX_DEFAULT
	waitmoncry
        closemessage
	release
	end

Text_CryDemo:
	.string "Arbok: Hisssss!$"
Shouldn't need much explanation, but I'll break it down just in case: Arbok's cry will play, a message box will appear as the cry plays and will close once the cry has finished playing.
Advertiser Content