Jump to content
thestuntman

Passing variables to an event handler without using globals

Recommended Posts

Basically, i'm trying to make a heli evac script that can be called by group leaders. I need the script to be able to be called by more than one leader, as each group will have it's own chopper that is dynamically spawned.

This is what I have for the function to add the EH so far.

EVAC_Heli_addEventHandler = {
args = _this;
_heli = _this select 1;
_helicaller = _this select 0;


_idx = _helicaller addEventHandler ["Fired", {
	if ((_this select 4) != "SmokeShell") exitWith {};

       _null = (_this select 6) spawn {

           _posg = getPos _this;
           sleep 0.5;

           while {(_posg distance (getPos _this)) > 0} do {
               _posg = getPos _this;
               sleep 0.5;
           };
		_heli sideChat "Smoke seen. Landing now";
       };
   }];
};

_heli sideChat "Smoke seen. Landing now";

does not work as _heli is out of the EH's scope. I can use globals to get the actual "name" of the the chopper, but

Alpha 3-2 sideChat "Smoke seen. Landing now"

obviously doesn't work either. I ahve tried using set\getVariable with the group leader and this works to the same extent. I can pass the variable values (such as the chopper name) onto the EH, but that is not what I need.

Basically the script allows group leaders to call in a chopper, it will move to an area and await smoke until actually landing on the smoke's location for pickup

I have the rest of the script working fine (the pickup function etc) but it gets a bit wonky when called by more than one group leader at the same time. I am trying to avoid globals as this will also not work if it is called more than once.

I have also tried using format when creating the EH to write the variables into the actual EH when it is first created but this has also had limited success.

The whole script so far is viewable HERE

Share this post


Link to post
Share on other sites

I'm real tired atm, but here's one way to pass the arguments to the function. Sorry if I'm way of base accessing your problem lol.

init.sqf

call compile preProcessFile "evac.sqf";
_idx = whatever addEventHandler ["Fired", {[(_this select 0),(_this select 1)] spawn TAG_fnc_Evac;}];

evac.sqf

TAG_fnc_Evac = {
   _helicaller = _this select 0;
   _heli = _this select 1;
  if ((_this select 4) != "SmokeShell") exitWith {};

       _null = (_this select 6) spawn {

           _posg = getPos _this;
           sleep 0.5;

           while {(_posg distance (getPos _this)) > 0} do {
               _posg = getPos _this;
               sleep 0.5;
           };
           _heli sideChat "Smoke seen. Landing now";
};

---------- Post added at 17:24 ---------- Previous post was at 17:21 ----------

It's best not to write the code directly into the eventhandler's code space anyhow, so you'd be better off spawning a function that contains the code.

---------- Post added at 17:29 ---------- Previous post was at 17:24 ----------

So yeah you'd need to pass any of the eventhandler's stuff you needed to access. Including _this select 4 (ammo) and _this select 6 (projectile)etc.

Share this post


Link to post
Share on other sites
So you want basically the helicopter that gets spawned to say the message?

I need to be able to access a few variables defined outside the EH inside the EH. Once the EH fires and gets the location of the smoke, I am creating WP's that need to be assigned to the heli.

As the heli is spawned outside the scope of the EH, i was having difficulty getting to it inside the EH itself.

Basically, when a group leader calls in an evac, they "own" that heli, and I need to the heli to only respond to smoke thrown by that group leader (or member of that group)

@Iceman77. Ill give something like that a shot. Thanks!

Share this post


Link to post
Share on other sites

I don't think that is it possible without using some sort of global variable. In the init.sqf of Iceman's example, the _this variable will be set by the event handler, and so _this select 0 refers to the unit that fired and _this select 1 refers to the weapon. Those two things are passed into the function TAG_fnc_Evac, but in that function it makes a reference to _this select 4 which is out of range since _this contains only two elements.

You can use setVariable that may be nicer than using global variables. For example, _group_leader setVariable ["helipocter", _helipocter];. This way you can assign a variable in the variable space of the particular object. When the event handler triggers, you can check "helicopter" variable in the variable space of the unit that fired using getVariable. If that variable exists, you can do whatever you need to with it. For example, you can use this inside the event handler to get the helicopter:

_helicopter = (_this select 0) getVariable "helicopter";
if (isNil "_helicopter") exitWith {};

Try something like this:

EVAC_Heli_FiredEH = {
   if ((_this select 4) != "SmokeShell") exitWith {};
   _heli = (_this select 0) getVariable "EVAC_Heli_Helicopter";
   if (isNil "_heli") exitWith {};

   _null = ([_this select 6, _heli]) spawn {
       _projectile = _this select 0;
       _heli = _this select 1;

       _posg = getPos _projectile ;
       sleep 0.5;

       while {(_posg distance (getPos _projectile )) > 0} do {
           _posg = getPos _projectile ;
           sleep 0.5;
       };
       _heli sideChat "Smoke seen. Landing now";
   };
};

EVAC_Heli_addEventHandler = {
   _helicaller = _this select 0;
   _heli = _this select 1;

   _helicaller setVariable ["EVAC_Heli_Helicopter", _heli];

   _idx = _helicaller addEventHandler ["Fired", EVAC_Heli_FiredEH];
};  

Edited by albertfish

Share this post


Link to post
Share on other sites

OK so I have everything working now (Thanks for the tip albertfish) apart from a couple of things.

Sometimes the heli has issues when moving from it's hover position into the landing position. Depending on where the smoke is thrown, sometimes it will not land at all, or will land and then takeoff again and land somewhere else.

I think this has more to do with pathing and AI flying than anything else.

Also the heli seems to spawn mid air, any way to make it spawn on the ground?

Edited by thestuntman

Share this post


Link to post
Share on other sites
OK so I have everything working now (Thanks for the tip albertfish) apart from a couple of things.

Sometimes the heli has issues when moving from it's hover position into the landing position. Depending on where the smoke is thrown, sometimes it will not land at all, or will land and then takeoff again and land somewhere else.

I think this has more to do with pathing and AI flying than anything else.

Also the heli seems to spawn mid air, any way to make it spawn on the ground?

I remember dealing with AI landing before and I would see it do some of these things in certain circumstances. The pilot will land when there is a large enough clearing, so if there are objects in the way it might not be able to find a landing zone properly. Another thing is when landing on a hill sometimes the AI would take off right after landing. This was something I noticed back in Arma 2, so I am not sure if it is the same currently.

As far as the helicopter spawning in the air, when you use createVehicle, the "special" parameter should be set to NONE instead of FLY. FLY will spawn the helicopter in flight.

Share this post


Link to post
Share on other sites

I've changed from using BIS_fnc_spawngroup to using CreateVehicle and spawned the pilots an copilot with createUnit and got them in the chopper manually.

Works great now.

Still a few things i'd like to tweak to make it work better in MP so each group leader can call their own chopper.

Share this post


Link to post
Share on other sites
... you'd need to pass any of the eventhandler's stuff you needed to access. Including _this select 4 (ammo) and _this select 6 (projectile)etc.
but in that function it makes a reference to _this select 4 which is out of range since _this contains only two elements.

Directly after I posted the function, I made it pretty clear that he'd also need to pass over the ammo and the projectile aswell. My post was just a rough concept of what needed to be done, as I was very tired and didn't feel like re-writing the entire function for the guy.

-------------------------------------------------

In any case, something along these lines is what I would have posted if I hadn't been dead tired at the time.

TAG_fnc_Evac = {
   _helicaller = _this select 0;
   _heli = _this select 1;
_ammo = _this select 4;
_projectile = _this select 6;

  if ((_ammo) != "SmokeShell") exitWith {};

       _null = [_helicaller]  spawn {

           _posg = getPos (_this select 0);
           sleep 0.5;

           while {(_posg distance (getPos (_this select 0))) > 0} do {
               _posg = getPos (_this select 0);
               sleep 0.5;
           };
        (_this select 0) sideChat "Smoke seen. Landing now";
     };     
};  

//passed everything over to the function for giggles. Never know when you may want to access one in any case ...
_idx = this addEventHandler ["Fired", {[(_this select 0),(_this select 1),(_this select 2),(_this select 3),(_this select 4),(_this select 5),(_this select 6)] spawn TAG_fnc_Evac;}];  

---------- Post added at 13:32 ---------- Previous post was at 12:58 ----------

Edit: passed _heliCaller over to the newly spawned thread in the function.

Edited by Iceman77

Share this post


Link to post
Share on other sites

Ha! Just wanted to clear some things up regarding my initial post.

Edited by Iceman77

Share this post


Link to post
Share on other sites

Thanks for all the info guys. I have it working well now. All I need to do now is to get rid of a couple more global variables that control whether or not a heli has been called by a particular leader so they can not have 2 in action at once.

I will probably use set\getVariable on the group leader for this as it seems to be the easiest way.

Share this post


Link to post
Share on other sites
Directly after I posted the function, I made it pretty clear that he'd also need to pass over the ammo and the projectile aswell. My post was just a rough concept of what needed to be done, as I was very tired and didn't feel like re-writing the entire function for the guy.

-------------------------------------------------

In any case, something along these lines is what I would have posted if I hadn't been dead tired at the time.

TAG_fnc_Evac = {
   _helicaller = _this select 0;
   _heli = _this select 1;
_ammo = _this select 4;
_projectile = _this select 6;

  if ((_ammo) != "SmokeShell") exitWith {};

       _null = [_helicaller]  spawn {

           _posg = getPos (_this select 0);
           sleep 0.5;

           while {(_posg distance (getPos (_this select 0))) > 0} do {
               _posg = getPos (_this select 0);
               sleep 0.5;
           };
        (_this select 0) sideChat "Smoke seen. Landing now";
     };     
};  

//passed everything over to the function for giggles. Never know when you may want to access one in any case ...
_idx = this addEventHandler ["Fired", {[(_this select 0),(_this select 1),(_this select 2),(_this select 3),(_this select 4),(_this select 5),(_this select 6)] spawn TAG_fnc_Evac;}];  

---------- Post added at 13:32 ---------- Previous post was at 12:58 ----------

Edit: passed _heliCaller over to the newly spawned thread in the function.

However, in that example would _this select 1 be the weapon that was fired and not the helicopter, as defined by the event handler?

Also, glad you got everything working.

Share this post


Link to post
Share on other sites

Yes it will be the weapon (_this select 1) that was fired. _heli could be any name you like. ie; _weapon instead.. or w/e. _heli is what the OP had _this select 1 defined as in any case. Was just using the name he posted :) Not sure the OP's true intentions (who or what is firing the weapon to generate the smoke etc)

Share this post


Link to post
Share on other sites
Yes it will be the weapon (_this select 1) that was fired. _heli could be any name you like. ie; _weapon instead.. or w/e. _heli is what the OP had _this select 1 defined as in any case. Was just using the name he posted :) Not sure the OP's true intentions (who or what is firing the weapon to generate the smoke etc)

Ah, got you now. I think he wanted the _heli variable to reference an actual helicopter so that is why your post confused me slightly.

Share this post


Link to post
Share on other sites

Yep correct. I needed the actual heli so only the helicopter that is assigned to the group who dropped smoked responds to it

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×