Author Topic: Function triggers / Function of the Day  (Read 29916 times)

0 Members and 1 Guest are viewing this topic.

Offline erwin

  • Sr. Member
  • ****
  • Posts: 314
    • View Profile
Function triggers / Function of the Day
« on: February 20, 2017, 03:22:49 pm »
Function triggers are something special in 4 Dimensions MUD, as they provide many opportunities to builders and scripters alike. Unlike specific type triggers, eg MOB triggers, OBJ triggers, and ROOM triggers, function triggers can be attached to MOBs, ROOMs, and OBJs without any errors.

The most common usage of function triggers is to "extend" a script. For example, we have a mob that tells a super long story (trigger modified):

Code: [Select]
Name: 'story',  VNum: [ 2350], RNum: [  706]
Trigger Intended Assignment: Mobiles
Trigger Type: Speech , Numeric Arg: 1, Arg list: story stories
Commands:
if %actor.is_pc%
  wait 5s
  %send% %actor% The mob tells a story...
  * ...
  * ...
  * some time later
  function 2356
endif

What does function 2356 do? Well, it continues the story

Code: [Select]
Name: 'Story Conclusion',  VNum: [ 2356], RNum: [  712]
Trigger Intended Assignment: Mobiles
Trigger Type: FUNCTION , Numeric Arg: 0, Arg list:
Commands:

emote takes a deep breath.  Will he finally finish?
wait 10s
%send% %actor% blah blah blah
*...
*...

So you could replace "function 2356" in trigger 2350 by the entire DG script in 2356.

For those with some background in programming, you might say: "That's not all functions can do", and you'd be right. So we'll give examples on how to use functions in this forum post

Offline erwin

  • Sr. Member
  • ****
  • Posts: 314
    • View Profile
Re: Function triggers / Function of the Day
« Reply #1 on: February 20, 2017, 03:24:38 pm »
A function to avoid repetition

Here's an example. In Fenizia, the mobs are extremely interactive, and some of them accept gifts. If you kill a particular mob in Fenizia, and present its head to all the other NPCs, they will kill you.

So for example, we would have many different RECEIVE triggers that look like this:

Code: [Select]
if %obj.vnum% == 12345
  * do stuff
elseif %obj.vnum% == 12346
  * do more stuff
elseif %obj.vnum% = 22222
  wait 1
  drop %object%
  wait 1 s
  widee %actor%
  emote exclaims, 'Oh, my God! Are you mad?
  %echo% Do you have ANY idea what consequences this might lead to?'
  wait 1 s
  emote says, 'This is a total disaster, you moron!
  %echo% He was not a man that wouldn't make some precautions either...
  eval am (%actor.level%*(2000+%random.200%)))
  nop %actor.exp(-50000)%
  mkill %actor%
endif

These twelve lines are repeated across several different triggers. Which is great, unless there are errors in these lines. So a much cleaner way is to do this.

Code: [Select]
Name: 'Kill Mob Function',  VNum: [ 7958], RNum: [ 2982]
Trigger Intended Assignment: Mobiles
Trigger Type: FUNCTION , Numeric Arg: 100, Arg list: None
Commands:
wait 1
drop %object%
wait 1 s
widee %actor.name%
emote exclaims, 'Oh, my God! Are you mad?
%echo% Do you have ANY idea what consequences this might lead to?'
wait 1 s
emote says, 'This is a total disaster, you moron!
%echo% He was not a man that wouldn't make some precautions either...
eval am (%actor.level%*(2000+%random.200%))
nop %actor.exp(-50000)%
mkill %actor%

And then we can replace the above code with

Code: [Select]
if %obj.vnum% == 12345
  * do stuff
elseif %obj.vnum% == 12346
  * do more stuff
elseif %obj.vnum% = 22222
  function 7958
endif

Now, you might say that it's only twelve lines - we don't need a function trigger. However, did you notice we made two changes? We changed widee %actor% to widee %actor.name%, and we fixed a bracketing issue in when evaluating the experience points to deduct from the player.

Imagine making this change across all NPCs :( -> eg, you can type tsearch all 7958 to see the impact of this.

It becomes a bigly issue when there are longer chunks of scripts repeated throughout, which means lots and lots of changes. This not just becomes terribly annoying to fix, but introduces more chance of errors (what if we delete an extra line? or delete an else? or we didn’t catch a word wrap, and cut off part of what a mob is supposed to say / do?)

So - if you're a builder, and you find yourself repeating large chunks of code, consider using functions! Errors can be fixed in the function trigger itself, rather than fixing the same error across many scripts.

This is especially important if the script you are repeating does things which may have a great impact on players, such as giving them experience points, setting questflags, etc.

So if you repeat a chunk of code lots of times - use functions!
« Last Edit: February 20, 2017, 03:26:16 pm by erwin »

Offline erwin

  • Sr. Member
  • ****
  • Posts: 314
    • View Profile
Re: Function triggers / Function of the Day
« Reply #2 on: February 20, 2017, 03:30:58 pm »
and of course...someone told me that widee should be wide e (oops) ; plus the line

Code: [Select]
nop %actor.exp(-50000)%
probably should be

Code: [Select]
nop %actor.exp(-%am%)%
isn't it lucky we use triggers?