Making Custom Trigger Members
From AgeofWiki
The ability to create custom conditions and effects to be used in your scenarios is one of the things that contributes to the power of the AoE3 scenario editor. Before starting to make these conditions and effects, make sure you have read Adding Custom Triggers because all of creating conditions and effects is done in the typetest document. "Custom trigger" will be used to mean "custom trigger members."
| Table of contents |
|
|
Introduction
Almost all of making custom triggers is copy-paste. Looking for another trigger member that does a similar thing is the easiest way to make these. In fact, almost all of the custom triggers are variations of already existing ones. If you want to be making some custom triggers as you read this, open typetest.xml in notepad or any other word processor now.
Making Custom Conditions
Every condition in the typetest.xml will look something like this:
<Condition name="name"> <Param name="PName" dispName="$$a number$$DName" varType="vType">default</Param> <Command>Tells the scenario to do something;</Command> <Expression>an expression that will either return true or false</Expression> </Condition>
What does all this mean?
<Condition>
This tells the editor that this is a condition. The name="name" part is what you will see when you are looking at the list of conditions.
<Param ...></Param>
Param is short for parameter. This tells the editor to put in a place for a value or to select something. This is what creates the boxes for how many resources to tribute, as well as the buttons to select a unit. The default in between the opening and closing tags is what the editor will display before you select everything. This is like how when you use the conditions dealing with someones resources it starts on player 1. I do not know what the number is for, so simply copy-paste the number already used for that Param.
<Command></Command>
These are mainly used in effects, but conditions can use them too. They are vary rarely in conditions, however, so just ignore them for a while.
<Expression></Expression>
This is the meat of the condition. What this does is it tells the scenario when to fire the trigger. The output of this line is always either true or false, and it comes at the end of the condition.
</Condition>
This ends the condition and is required right after the expression. Do not forget it or else there will be problems.
Putting it together
Before we start making our own conditions, we should look at some that already exist. For example
<Condition name="Player Population"> <Param name="PlayerID" dispName="$$22301$$Player" VarType="player">1</Param> <Param name="Op" dispName="$$22297$$Operator" VarType="operator">==</Param> <Param name="Count" dispName="$$22321$$Number" VarType="long">1</Param> <Expression>trPlayerGetPopulation(%PlayerID%) %Op% %Count%</Expression> </Condition>
This condition looks at someones population and compares it to a value. Look at the first <Param>. It is referenced as PlayerID and it is shown as "Player". The type of variable (VarType) is a player. It will automatically select player 1 from the start.
The next one is referenced as Op. It is shown as Operator and the variable type os an operator. The default is == (is equal to). The different Operators are
== (is equal to) != (is not equal to) < (is less than) > (is greater than) <= (is less than or equal to) >= (is greater than or equal to)
These compare two values and return whether it is true or false. For example
1 >= 1 TRUE 1 > 1 FALSE 0 <= 1 TRUE
The last one is referenced to as Count. It is displayed as "Number." The type is a long - an integer. The default is 1.
Lastly, we look at the expression. trPlayerGetPopulation(%PlayerID%) is a function. It tells the scenario to get the population of the player number entered for PlayerID (the first param). %Op% is the operator the person put in and %Count% is the number that they put in. So for example, say they put in player 1, >=, 60.
This would say. Player 1's population is greater than or equal to 60. True or false?
Making the condition
The moment you've all been waiting for. Actually designing a condition!
Step 1
Start by deciding what you want the condition to test and decide on a name for it. Your condition now looks like this:
<Condition name="Your name here"> </Condition>
Step 2
Say that you wanted to make one that compared a stat value to a Quest Var. This one has already been made by other people, but it was not included in the game so it is a good one to start with. So you need to pull out the following Param. Ones to retrieve a stat value, one that retrieves an Operator, and one that retrieves a QV. Your condition will now look something like this.
<Condition name="Compare Stat Value to QV"> <Param name="PlayerID" dispName="$$22534$$Fake Player" VarType="player">1</Param> <Param name="StatID" dispName="$$25424$$Stat Type" VarType="kbstat">0</Param> <Param name="Op" dispName="$$22297$$Operator" VarType="operator">==</Param> <Param name="QuestVar" dispName="$$32955$$Var Name 1" varType="string">QV1</Param> </Condition>
Step 3
All that's left is the expression! To put this in, we need to get the function that returns a stat value and the function that returns a QV. Then we just put %Op% between them and enclose it in <Expression></Expression> tags. This means your final condition will look like this:
<Condition name="Compare Stat Value to QV">
<Param name="PlayerID" dispName="$$22534$$Fake Player" VarType="player">1</Param>
<Param name="StatID" dispName="$$25424$$Stat Type" VarType="kbstat">0</Param>
<Param name="Op" dispName="$$22297$$Operator" VarType="operator">==</Param>
<Param name="QuestVar" dispName="$$32955$$Var Name 1" varType="string">QV1</Param>
<Expression>trGetStatValue(%PlayerID%, %StatID%) %Op% trQuestVarGet("%QuestVar%")</Expression>
</Condition>
Step 4
You thought we were done, huh? Well there's one more crucial step to this. You must test it! You need to test it to see if there are any bugs and fix the ones you find. If you don't, it could be messed up without you knowing and that would not be good. Do not rely on internet explorer to point out every error. It only points out errors in the code. It will not read your mind and tell you if it doesn't do what you want.
Making Custom Effects
This is very similar to making custom condition, but almost a bit easier.
Structure
Effects look like this:
<Effect name="effectName"> <Param name="PName" dispName="$$a number$$DName" VarType="type">default</Param> <Command>What the effect should do;</Command> </Effect>
The first and last lines do the same thing as in conditions, but instead of condition it says effect. The Params also work in the same way. The difference is that effects end with commands and can have more than one. Note that they always have a semicolon (;) right before the </Command> tag. This tells the scenario that it is the end of a command.
Putting it together
Let's look at one of the already made effects.
<Effect name="Send Chat"> <Param name="PlayerID" dispName="$$22444$$From Player" VarType="player">1</Param> <Param name="Message" dispName="$$20056$$Message" VarType="stringid">default</Param> <Command>trChatSend(%PlayerID%, "%Message%");</Command> </Effect>
This effect is called Send Chat. You input a player and a message and it will send chat though the trChatSend() function. Notice that the second parameter for the trChatSend() function is in quotes. This makes it a string, but it still takes the value from %Message% because it is a stringid variable (look at the VarType). Now we can continue.
Making the Effects
If you do not feel ready for this part because you skipped past the conditions part, go ahead and take some time to read over it. Now, let's Go through making an effect.
Step 1
Think of what you want it to do and come up with a name. Let's use "Quest Var Set to Stat Value." This will retrieve a stat value and put in into a quest variable. The effect looks like this so far:
<Effect name="Quest Var Set to Stat Value"> </Effect>
Step 2
Now get the required Params. The name of the QV and the Player and the Stat type to get the stat value. The effect will look like this:
<Effect name="Quest Var Set to Stat Value"> <Param name="QVName" dispName="$$32954$$Var Name" VarType="string">QV1</Param> <Param name="PlayerID" dispName="$$22534$$Fake Player" VarType="player">1</Param> <Param name="StatID" dispName="$$25424$$Stat Type" VarType="kbstat">0</Param> </Effect>
Step 3
Now for the command. We want it to set the QV to the value retrieved from the stat value. This requires nesting some functions. Before putting it all together, let's look at the command by itself.
<Command>trQuestVarSet("%QVName%", trGetStatValue(%PlayerID%, %StatID%));</Command>
The first part, trQuestVarSet( , is a function that will set a quest variable. The first parameter "%QVName%" is the name that the user put in and the QV that will be set to the value. Then, the second parameter is another function. What will happen is the inside function will execute first, then the returned value will put run through the outside function. This occurs in every programming language so if you have experience, it helps. So the inside function takes in two parameters as well. It takes in the player number and which stat to get, then gets it. So this will do the job.
So, putting it all together you will get:
<Effect name="Quest Var Set to Stat Value">
<Param name="QVName" dispName="$$32954$$Var Name" VarType="string">QV1</Param>
<Param name="PlayerID" dispName="$$22534$$Fake Player" VarType="player">1</Param>
<Param name="StatID" dispName="$$25424$$Stat Type" VarType="kbstat">0</Param>
<Command>trQuestVarSet("%QVName%", trGetStatValue(%PlayerID%, %StatID%));</Command>
</Effect>
Step 4
This is the same as conditions. TEST! When you are experimenting with these things, a lot of times you can get them the first time, but there are times when there are bugs. This step is very important. Do not rely on internet explorer to point out every error. It only points out errors in the code. It will not read your mind and tell you if it doesn't do what you want.
Conclusion
This tool is one of the most powerful in the area of scenario design. If you can't find something you need, then you can now make it. Even though there are other people who can make custom effects, they may not always have made the one you want and so you may not be able to rely on them 100% of the time.
