Home   Help Search Login Register  

Author Topic: Remove specific eventhandlers?  (Read 921 times)

0 Members and 1 Guest are viewing this topic.

cornhelium

  • Guest
Remove specific eventhandlers?
« on: 19 Jun 2006, 23:00:17 »
Hi,

I'm working on a wildlife sounds system for Tonal island, using authentic SE African bird and animal sounds.

There were three main elements I wanted:

1. Many different ambient loops running from a single fauna.sqs script, that start only when the player is within audible distance, cannot be re-triggered once the script is running, and exit when the player goes out of range.
2. Inner trigger areas for each loop area, where an alarm call will play rather than the main sound, or the sound will just stop, until the inner area is clear.
3. Wildlife will "flee" from unsilenced gunshots or explosions in their area, giving panic alarm calls and not returning to the area for 5-10 minutes.

Parts 1 and 2 are now working nicely, but I'm out of my depth with 3...

Background

Each ambient loop needs a set of 1 logic and 2 triggers, all with unique names. I've load tested with 100 of these sets on the map and plan to have about 50 running without excessive lag. I'll probably optimise it all later by moving the conditions from the triggers to a looping checker script.

_logic is just a gamelogic. It is a reference to check the player's distance so the script can be initialised. Once the script is initalised for the set, the script moves _logic away to [0,0,0] so the script can't be initialised for that set again until the player has moved away and it has exited.

_innertrigger is a small trigger that the script uses to check whether any men have entered the "alarm call/stop singing" area.
It is also the trigger that starts the fauna.sqs when the player gets near _logic,
condition field: player distance uniquelogicname < 500   (the triggering part)
Anybody, present, repeatedly   (so the script can detect units in the trigger area)

_innertrigger is the only element in the set which is not moved around by the script at some point. Thus it is also an anchorpoint for returning the other elements to their original position.

_main is a larger trigger. It's main purpose is to actually emit the ambient sound. The script also uses its distance from the player and from _innertrigger to determine whether the player is still in the area and/or whether "flyoff.sqs" has been triggered for the set (more on that later).

_main's other purpose is to add a fired eventhandler to all units within its radius.  In order to catch any new units that have entered the area and add the EH to them, fauna.sqs zaps _main to [0,0,0] and back at the end of each ambient loop.

condition field: "man" countType thislist > 0   So the trigger can deactivate/reactivate when moved back and forth
Anybody, present, repeatedly
activation field:    the addingEH part
Code: [Select]
FlyOffReady1 = true; {_x addEventHandler ["fired",{if (FlyOffReady1) then {[uniquemainname, uniquelogicname, uniqueinnertrigname,"creaturetype"] exec "flyoff.sqs",FlyOffReady1 = false}}]} forEach thislist

Thus, when a unit fires, the set will be passed to flyoff.sqs which will make _main play a panic alarm sound then zap it to [0,0,0], closely followed by _logic (which will probably be there anyway).

_main and _logic will be held at [0,0,0] for, say, 5 minutes. In that time, fauna.sqs detects that _main is abnormally far from the _innertrigger anchorpoint and exits.

When the 5 minutes are up, flyoff.sqs repositions _main and _logic back at _innertrigger's location, leaving the full set in place and ready to start fauna.sqs again, if the player is still in the area.

The Problem

I can't find a way to remove the fired eventhandlers that _main adds to its array, without removing any other firedEHs the mission maker has given the units.

I can start the flyoff.sqs with

A:
Code: [Select]
{_x removeallEventHandlers "fired"} forEach list _main

or B:

Code: [Select]
{_x removeEventHandler ["fired",0]} forEach list _main

or C:

Code: [Select]
{_x removeEventHandler ["fired",1]} forEach list _main

...but none of these give predictable or desirable results, as you can imagine.

As you can see from _main's activation field, I've worked around this by using variables to make that firedEH ineffectual once one unit has fired. The moment one of the units in the trigger area fires, flyoff.sqs execs and FlyOffReady1 is set to false. As FlyOffReady1 is a condition of the firedEH, flyoff.sqs cannot be triggered again until the 5 minute period is up and flyoff.sqs returns _main to its original position. Once that has happened, FlyOffReady1 will be reset and new firedEHs will be added to all units in the trigger area, so the process can happen again.

This works fine at the moment, but with 50 sets and many units on the map, all firing happily away, I worry about the firedEHs piling up. Even though they only actually do anything once or twice for every hundred shots, they're never being removed and could stack up into the thousands over the course of a mission.

Is there anything I can/should do about this?

The ideal solution would be to be able to give each firedEH a unique identity and thus be able to remove it after first use. However, I don't think this is possible  ???

Thanks in advance for any advice, and thank you for keeping this great resource going 8)
CH
« Last Edit: 19 Jun 2006, 23:03:34 by cornhelium »

Offline Wadmann

  • OFPEC Patron
  • ****
  • I'm the next evolutionary step after a llama!
Re: Remove specific eventhandlers?
« Reply #1 on: 20 Jun 2006, 23:53:45 »
Quote
The ideal solution would be to be able to give each firedEH a unique identity and thus be able to remove it after first use. However, I don't think this is possible 

I am no expert on the subject, but IIRC event handlers are numbered sequentially starting with "0" for each instance that the eventhandler has been added. If you added them to five units, the first eventhandler in #0 and the last one is #4.

As the returned value of an added EH is the index of the added handler, I suppose that you could query and track them some way. I will let you figure that one out. Source: AddEH ComRef

The problem is when you start to remove the added EHs, for any handler that is removed, all handler indices higher than the deleted one should be decremented. Source: RemoveEH ComRef

This is as far as I go. I know when I am about to get in over my head and I have reached that point. As your script is far more complicated than one that I have ever attempted, I can only hope that this little bit of info will get you going in the right direction.

Wadmann
Check out my Camouflage Collection! New items added 31 July 2005.

cornhelium

  • Guest
Re: Remove specific eventhandlers?
« Reply #2 on: 21 Jun 2006, 01:13:58 »
Hey Wadmann,

Thanks for your reply.

Quote
IIRC event handlers are numbered sequentially starting with "0" for each instance that the eventhandler has been added. If you added them to five units, the first eventhandler in #0 and the last one is #4.

Yeah. Thing is, I was reading the thread below, and ColonelSandersLite seemed to be talking about assigning specific identities to EHs in the init.sqs, eg.: eventHandlerAIndex = wSoldier1 addEventHandler ["fired",{_this exec "eventHandlerA.sqs"}]

http://www.flashpoint1985.com/cgi-bin/ikonboard311/ikonboard.cgi?s=98ce34e8facb3cf52f1b073b185e776f;act=ST;f=7;t=51583;hl=eventhandlers

...which I interpreted to mean they could be removed likewise. I even tried to remove the EH via the EH itself. :-[

I've got that sinking feeling that part 3 of my script just Ain't Gonna Happen, unless there's another way to detect if certain weapons have been fired.

Alternatively, would it be possible to trigger part 3 by checking if, say, counttype "bullet" was in a trigger area? 'Get nearest object' would be another approach, but would be limited to a 25m radius whereas I'm thinking more of 250m :-\

Thanks friends,
CH

cornhelium

  • Guest
Re: Remove specific eventhandlers?
« Reply #3 on: 21 Jun 2006, 01:51:18 »
Hi again.

It's the beer talking now, so bear with me ;)

Quote
The problem is when you start to remove the added EHs, for any handler that is removed, all handler indices higher than the deleted one should be decremented

Hmm. So they aren't automatically decremented? In that case, could I simply wait until the my triggers have done their work, before adding any other EHs that the mission needs? Then, firedEH 0 would always be "the fauna EH" for every unit, and could easily be removed.

Might this leave fired EH 0 as a permanent "space" in the index from where my EHs might be deleted/added back/deleted again?

Cheers,
CH