zParserExtender also implements cyclical functions called triggers - not to be confused with triggers in ZEN files, similar to a part of the functionality implemented in LeGo AI_Functions. These functions are called independently after a specified period of time. These triggers can also store user information. Up to 16 int variables can be stored in each trigger as well as self, other and victim instances.
/// Union zParserExtender Trigger classclassC_Trigger{varintDelay;// defines the frequency (in milliseconds) at which the function will be called.varintEnabled;// determines if the trigger is active. If the value is equal to zero, the trigger is destroyed.varintAIVariables[16];// user data, which can be set independently when creating trigger (yes, you can write there absolutely everything you want).// Hidden variable members/* - Func - The function that the trigger will call. - Self - The NPC that will be placed in `self` when the function is called. - Other - An NPC that will be placed in `other` when the function is called. - Victim - The NPC that will be placed in `victim` when the function is called. */};
Creating instances
There are two external functions that are used to create C_Trigger instance.
// function returns a trigger with no NPC (self, other or victim) bound to itfuncC_TriggerAI_StartTriggerScript(varstringfuncName,varintdelay){};// function is extended, if certain participants need to be assigned to itfuncC_TriggerAI_StartTriggerScriptEx(varstringfuncName,varintdelay,varC_Npcslf,varC_Npcoth,varC_Npcvct){};
Both of these functions return an instance of C_Trigger instance. You can of course configure the instance after its creation. You can, for example, fill in the AIVariables with relevant data. The trigger function has the required signature if 'func int f()'. It must return a value indicating the state of the loop. If the function returns LOOP_END the trigger will be stopped and the instance deleted. If LOOP_CONTINUE is returned, the function will be called again after Delay ms have passed.
// Implement a trigger to simulate the effect of poison debuff:// Let's create a trigger on function `c_loop` with a call interval of 1 second.// When the function is called, the instance hero will be placed in self (although it can be any other NPC if desired).// The rest of the instances are left null (not used).varC_Triggertrigger;trigger=AI_StartTriggerScriptEx("c_loop",1000,hero,null,null);trigger.AIVariables[0]=15;// how many times the function should be calledtrigger.AIVariables[1]=5;// how much damage to deal each iteration
funcintc_loop(){// Create a loop end check, if the number of// available iterations has reached 0. If it did// we stop the trigger by returning the LOOP_END value.if(SelfTrigger.AIVariables[0]<=0){returnLoop_end;};SelfTrigger.Delay-=20;// Accelerate loop each call by 20 msSelfTrigger.AIVariables[0]-=1;// Reduce number of remaining repeatsself.Attribute[ATR_HITPOINTS]-=SelfTrigger.AIVariables[1];// Take health from selfreturnLOOP_CONTINUE;};
Trigger scope
Triggers can be divided into two types:
Global trigger ( AI_StartTriggerScript ) trigger created using this function works in all worlds. A trigger is considered global by default if neither self nor other nor victim has been provided for it.
Local trigger ( AI_StartTriggerScriptEx) trigger created with this function only works in the world in which it was created. A trigger is considered local if it has been presented with at least one NPC in self, other or victim (not null). If you want to create a trigger without linking it to any NPC, it is recommended to simply pass hero as self to the trigger.
Saving
The plugin creates a new save archive to save the information of the triggers that does not conflict with any of the built-in save files.
// This way you can disable all triggers running on the `hero` instancevarC_Triggertrigger=FirstTrigger;varC_Triggertrigger_saved;while(!Hlp_IsNULL(trigger)){trigger_saved=trigger;trigger=AI_GetNextTriggerBySelf(hero);trigger_saved.Enabled=false;};