Decomp & Disassembly Guides and resources to help you develop your decompilation or disassembly-based hack can be found here.

Ad Content
Reply
 
Thread Tools
  #1   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (4:09 PM). Edited 5 Days Ago by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
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 - I can be found in the PC server, pret's server or the RHH server - 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*
__________________
Reply With Quote
  #2   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (4:49 PM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
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.
Reply With Quote
  #3   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (4:50 PM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Simple Text Scripts

I'll show you an example of a simple text script, and we can break it down.
Code:
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:
Code:
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.
-----------------------------------------------------------------------------------------------------------------------------------------------------
Code:
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.
Code:
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.
Reply With Quote
  #4   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (4:51 PM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Buffers

Let's start with bufferleadmonspeciesname, which displays the species of your player's first party member - just like it says on the tin!
Code:
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:
Code:
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:
Code:
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:
Code:
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!
Reply With Quote
  #5   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (4:52 PM). Edited January 4th, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
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:
Code:
setflag [Flag]
To set a flag, and to clear one:
Code:
clearflag [Flag]
To check if a flag is set, we'd do:
Code:
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:
Code:
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.
Reply With Quote
  #6   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (4:52 PM). Edited January 2nd, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
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!
Code:
checkplayergender
compare VAR_RESULT, [Gender]
goto_if_eq [Script Label]
A more fleshed out example:
Code:
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:
Code:
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.$"
Reply With Quote
  #7   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (4:57 PM). Edited January 2nd, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Hide/Show Map Objects

Do you need to make a NPC or other OW sprite disappear?
Code:
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:
Code:
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:
Code:
...
removeobject [Event Object ID]
setflag [Flag]
...
Alternatively, to show a previously hidden sprite, in reverse order:
Code:
...
clearflag [Flag]
showobjectat [Event Object ID], [Map]
...
Reply With Quote
  #8   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (5:13 PM). Edited January 4th, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Variables

The list of variables can be found in “include\constants\vars.h”.
Code:
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:
Code:
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:
Code:
subvar [Variable], [Value To Subtract From Var]
To check the value of a variable, we'd use the following:
Code:
compare [Variable], [Value]
goto_if_[Condition] [Script Label]
A list of the different conditions for goto_if/call_if:
Code:
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
Reply With Quote
  #9   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (6:01 PM). Edited January 19th, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
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.
Code:
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.
Code:
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!
Code:
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:
Code:
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:
Code:
takeitem [Item], [Quantity]
Checking whether or not the player has an item in their bag is done with the checkitem command:
Code:
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.
Code:
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:
Quote:
Originally Posted by Avara
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”.
__________________
Reply With Quote
  #10   Link to this post, but load the entire thread.  
Old January 2nd, 2019 (7:07 PM).
Trev's Avatar
Trev Trev is offline
i gave you everything...
 
Join Date: May 2012
Age: 22
Gender: Male
Nature: Sassy
Posts: 1,615
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
Reply With Quote
  #11   Link to this post, but load the entire thread.  
Old January 4th, 2019 (8:09 AM). Edited January 5th, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
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.
Code:
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:
Code:
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:
Code:
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 ;)
Reply With Quote
  #12   Link to this post, but load the entire thread.  
Old January 4th, 2019 (8:09 AM). Edited January 10th, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Giving Eggs

This section will cover how to give your player a Pokémon Egg.
Code:
giveegg [Pokémon]
Super easy.
Code:
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.
Reply With Quote
  #13   Link to this post, but load the entire thread.  
Old January 19th, 2019 (9:17 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Give & Check For PC Items

Adding an item to the player's PC is just as easy with a single line:
Code:
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:
Code:
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.
Quote:
Originally Posted by Avara
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:
Code:
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.
Reply With Quote
  #14   Link to this post, but load the entire thread.  
Old January 19th, 2019 (9:18 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Movements

How to make the player/NPCs move in a script? We use the applymovement command like this:
Code:
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:
Code:
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!
Reply With Quote
  #15   Link to this post, but load the entire thread.  
Old February 1st, 2019 (8:03 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
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:
Code:
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.
Code:
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.
__________________
Reply With Quote
  #16   Link to this post, but load the entire thread.  
Old February 1st, 2019 (1:14 PM). Edited February 2nd, 2019 by Avara.
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Pokémarts

Creating your own shops is straightforward enough with the pokemart command.
Code:
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:
Code:
	.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:
Code:
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!$"
__________________
Reply With Quote
  #17   Link to this post, but load the entire thread.  
Old February 6th, 2019 (9:30 AM).
Avara's Avatar
Avara Avara is offline
Author Of Tales
 
Join Date: Dec 2011
Location: Izantine
Gender: Female
Nature: Calm
Posts: 944
Weather

Manipulating weather in the overworld is easy; all you need are these two lines in your script:
Code:
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:
Code:
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”.
__________________
Reply With Quote
  #18   Link to this post, but load the entire thread.  
Old February 7th, 2019 (12:56 AM).
Delta231's Avatar
Delta231 Delta231 is offline
A noob
     
    Join Date: May 2016
    Location: India
    Gender: Male
    Nature: Bold
    Posts: 676
    I can't thank you less for these scripting tutorials x
    __________________
    HGSS OWs in FR Style
    Fire Red NSE Bookmarks


    A supporter of


    Reply With Quote
      #19   Link to this post, but load the entire thread.  
    Old February 9th, 2019 (3:54 PM).
    Avara's Avatar
    Avara Avara is offline
    Author Of Tales
     
    Join Date: Dec 2011
    Location: Izantine
    Gender: Female
    Nature: Calm
    Posts: 944
    Quote:
    Originally Posted by Delta231 View Post
    I can't thank you less for these scripting tutorials x
    Aw, thank you Delta! <3 x
    __________________
    Reply With Quote
      #20   Link to this post, but load the entire thread.  
    Old February 9th, 2019 (3:58 PM).
    Avara's Avatar
    Avara Avara is offline
    Author Of Tales
     
    Join Date: Dec 2011
    Location: Izantine
    Gender: Female
    Nature: Calm
    Posts: 944
    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.
    Code:
    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:
    Code:
    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.
    __________________
    Reply With Quote
      #21   Link to this post, but load the entire thread.  
    Old 2 Weeks Ago (11:05 AM).
    Inmortal's Avatar
    Inmortal Inmortal is offline
       
      Join Date: Jan 2017
      Posts: 7
      Your way to explain is pretty good.

      I'm not a native English speaker, and I've understood everything. I know how to script in binary hacking, but read this is very useful to introduce myself to the decomp scripting. I hope you will continue writing this tutorials. A loop tutorial would be great :)
      Reply With Quote
      Reply

      Quick Reply

      Join the conversation!

      Create an account to post a reply in this thread, participate in other discussions, and more!

      Create a PokéCommunity Account
      Ad Content
      Thread Tools

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

      BB code is On
      Smilies are On
      [IMG] code is On
      HTML code is Off

      Forum Jump


      All times are GMT -8. The time now is 7:40 AM.