AVP2 Messages and Commands
In the properties of a Trigger object, you'll come across a list of targets and messages. It looks something like this:
Target1:
Message1:
Target2:
Message2:
Target3:
Message3:
Obviously, the simplest way to approach this is by just filling in the fields like so:
Target1: door_7
Message1: trigger
Target2: door_8
Message2: triggerclose
Target3: keyframer_9248773
Message3: pause
When this trigger object is triggered (either by receiving a "trigger" message from another object, or by 19519i88t being moved into by a player or AI if the trigger is set up to pay attention to players and/or AI) it will immediately send each target object its corresponding message.
This, however, is only scratching the surface. There is another way to enter commands, which is by nullifying the target field and entering a message string into the message field. You do this by using the Msg command. The Msg command looks like:
msg Target Message;
The same example as above, using this method, would turn out like this:
Target1: [NULL]
Message1: msg door_7 trigger; msg door_8 triggerclose; msg keyframer_9248773
pause;
This will do the exact same thing as the simple trigger in the previous example.
You must put [NULL] in the target field so the engine knows to ignore that field and just execute the string in the message field. (You can also write 'bogus' or whatever, as long as you don't put the name of an actual object in the map. you must put something other than blank space here though.)
The syntax is "msg Target Message" where target is the name of the object to receive the message, and message is what you are telling the object to do. Keep in mind you can click the little button next to the message field to look at the whole message if it starts getting too long to fit in the 1-line text box. (There is a limit to the length, though, so watch out.)
If you are sending a multi-part message to a target, that message must be in parentheses. For example:
msg AI_Bob (active 1);
This will send AI_Bob the message "active 1". If you write this message as:
msg AI_Bob active 1;
you will only be sending AI_Bob the message "active", and the 1 will be thrown out and/or invalidate the entire message. Always use parentheses.
Successive messages in the same text field must be separated with a semicolon. For example:
msg AI_Bob (active 1); msg Plants_Group (animloop wind); msg Glass_Wall destroy; msg Door_9 lock;
There are spaces after the semicolons here for clarity but spaces are not required.
With this approach you can do much more. Here are some additional commands.
Delay is very useful, and looks like this:
delay X (message);
X is a number. When this message is processed, the engine will wait X number of seconds before processing the message within the parentheses. For example:
delay 4.3 (msg AI_Bob (ag attack; trg player;));
When this message is processed the engine will wait 4.3 seconds, then tell AI_Bob to add 'attack' to his list of goals and target the player.
DelayID is like delay, but gives you the ability to abort the delayed message using the Abort command. The DelayID command looks like this:
delayid N X (message);
N is a string and X is a number. When this message is processed, the engine will wait X number of seconds before processing the message within the parentheses. If the message is aborted before the delay elapses, the message will not be processed. The message is aborted by using the Abort command like this:
abort N;
N is a string. Using these commands together can be very powerful. For example, one trigger could have:
delayid Countdown1 30.0 (msg explosion_group on);
While another trigger could be set up to stop this with:
abort Countdown1;
Another useful command is Rand. This command can be used to randomly send one of two commands based on a specified percentage. It looks like this:
rand X (message) (message);
X is a number between 0 and 1 that specifies the probability of the 1st command being executed. For example:
rand 0.25 (msg prop0 destroy) (msg door0 trigger);
With this message there is a 25% chance of prop0 getting destroyed, and a 75% chance of door0 triggering.
You can also randomly pick between a wider number of messages using the Rand2, Rand3, Rand4, Rand5, Rand6, Rand7, and Rand8 commands. These commands give an equal probability to each message. For example, using Rand4:
rand4 (msg prop0 destroy) (msg door0 trigger) (msg window0 destroy) (msg keyframer0 on);
This would give a 25% chance to each of these commands, randomly pick one of them, and execute it.
Loop continuously repeats a specific command. It looks like this:
loop X Y (message);
X and Y are numbers defining the minimum and maximum delay times, respectively. For example:
loop 1.5 22.0 (msg sparks0 trigger);
This will wait a random duration (between 1.5 and 22 seconds) and then process the message telling sparks0 to trigger - then it will do it all again, over and over. The loop duration is recalculated every time the command is processed. What this means is the delays will be something like this:
1.7 21.8 14.3 19.2
Instead of something like this:
17.2 17.2 17.2 17.2
If you want a constant delay duration with no randomness, you can set the minimum and maximum values to be equal. For example:
loop 2.0 2.0 (msg sparks0 trigger);
This will tell sparks0 to trigger every two seconds, on the dot.
LoopID is like loop, but can be terminated using the Abort command. It looks like this:
loopid N X Y (message);
N is a string, and X and Y are numbers defining the minimum and maximum delay times, respectively. For example:
loopid Crazyloop0 20.0 60.0 (msg crazy_group trigger);
This loop would be stopped by sending an Abort command like this:
abort Crazyloop0;
Repeat does things over and over. It looks like this:
repeat A B X Y (message);
A and B are numbers defining the minimum and maximum number of times to repeat the message, and X and Y are numbers defining the minimum and maximum delay times, respectively. For example:
repeat 10 20 5.0 7.0 (msg group0 trigger);
This would trigger group0 every 5 to 7 seconds, a total of 10 to 20 times. If you wanted a specific number of repeats or a specific delay duration, you could make the values equal. For example:
repeat 150 150 1.0 1.0 (msg sparks0 trigger);
This would trigger sparks0 once per second, 150 times.
RepeatID works like Repeat, but can be aborted. It looks like:
repeatid N A B X Y (message);
N is a string, A and B are numbers defining the minimum and maximum number of times to repeat the message, and X and Y are numbers defining the minimum and maximum delay times, respectively. For example:
repeatid Dull_Repetition 1200 1400 80.0 90.0 (msg watercooler0 trigger);
This would trigger watercoolor0 every 80 to 90 seconds, a total of 1200 to 1400 times, unless the following command was sent:
abort Dull_Repetition;
Triggers and EventCounters
In the trigger object, there is a property called ActivationCount. This determines how many times the trigger must receive a 'trigger' message before it activates. (This defaults to 1.) If you need to use this property for a critical purpose, you should be aware that there is a limitation in the engine: a trigger object that receives two 'trigger' messages very quickly may only process that as 1 message, and therefore (if it has an ActivationCount of 2) not activate when you want it to. You should use the EventCounter object instead, and set the EventCounter object up to activate the trigger (which is set to ActivationCount = 1.)
The EventCounter object has a starting value which defaults to 0. When the EventCounter receives an increment or decrement command, that counter value will go up or down. Under Event1, Event2, etc. you will find 3 properties for each event. The first is EventXValue, which is the target value that the counter value needs to reach to send a message. The second is EventXIncToValCmd, which is the message which will get sent when the counter value reaches the target value from a value lower than the target value. The third is EventXDecToValCmd, which is the message which will get sent when the counter value reaches the target value from a value higher than the target value.
To increment or decrement the value in an EventCounter, just send it the message 'increment' or 'decrement.'
Additional Notes:
Note that ID's don't exist until they are used in a command. You can't abort a command ID before you've started it, for example.
Commands and object names are not case sensitive.
There are many objects in AVP2 that have message fields. For example, in a TranslucentWorldModel's damage properties are messages which get sent when the object is damaged, destroyed, etc. You can use these commands in any of these fields. Look around and experiment - the system can be used to do many interesting things.
|