Jump to content
Sign in to follow this  
jedra

MP - Local action to fire a server side trigger - help request

Recommended Posts

Hi,

It is hair pulling time again and I am trying to yet again get my head round locality.

I have a multiplayer mission where one player has an action to drop an object. This object should then have a trigger area around it, so when any WEST player goes into that area, a script fires. This is what I have so far...

Rifleman placed in the editor with the following init...

nul = [this] execvm "JedScripts\initRifleman.sqf";

initRifleman.sqf

private ["_unit"];
_unit = _this select 0;

if (!local _unit) exitWith {};

// Add Rifleman Actions

ammoBoxAction = [["Drop Ammo", "JedScripts\dropAmmoBox.sqf"]] call CBA_fnc_addPlayerAction;

I am using a CBA function to help keep the action persistant across re-spawns.

dropAmmoBox.sqf

private ["_target","_caller","_id","_args","_trig","_AmmoBoxDr"];

_target= _this select 0;
_caller = _this select 1;
_id = _this select 2;
_args = _this select 3;

hint "Ammo Box Dropped";

// Create an ammo box and drop it near who dropped it.
_AmmoBoxDr = "AmmoCrate_NoInteractive_" createVehicle (getPos _target);

// Create a trigger around the box - I KNOW THIS WILL ONLY ADD THE TRIGGER TO THE CLIENT - THIS IS MY PROBLEM!
_trig = createTrigger ["EmptyDetector", (getpos _AmmoBoxDr)]; 
_trig setTriggerArea [5, 5, 0, false];
_trig setTriggerActivation ["WEST", "present", true];
_trig setTriggerStatements ["this", "hint 'Near Ammo Box'; nul = [] execVM 'jedscripts\pickupammo.sqf'" , "hint 'Not Near Ammo Box'"];

//Remove the action
[ammoBoxAction] call CBA_fnc_removePlayerAction;

//Wait a while    
sleep 30;

// Add the action back again
ammoBoxAction = [["Drop Ammo", "JedScripts\dropAmmoBox.sqf"]] call CBA_fnc_addPlayerAction;

Basically the ammo box is a dummy box, and the idea it that any other player standing near the box will have their ammo refilled. Got to get that pesky trigger working first though...

This is the bit I know is wrong. Dropping the box is fine, because createVehicle syncs the box across all clients. However, what I need to do with the following trigger is run it on the server. As the script stands it will only add the trigger to the client who is playing the rifleman.

For the life of me I cannot work out how to initiate a server run script from within a script that only runs on a client. I have searched around and cannot find anything helpful. Maybe I am looking at this from the wrong angle? Maybe the answer is simple? Can anyone assist?

Share this post


Link to post
Share on other sites

Edit: Scratch my idea. Read you wrong.

Edit2: Pre-create the trigger, throw it in a corner. Then setPos it onto the ammo box when it's dropped, then setPos it back to a marker in a random corner when the box is gone. Rusty, but it'll do it.

Edited by Grimes [3rd ID]

Share this post


Link to post
Share on other sites
;1986061']Edit2: Pre-create the trigger' date=' throw it in a corner. Then setPos it onto the ammo box when it's dropped, then setPos it back to a marker in a random corner when the box is gone. Rusty, but it'll do it.[/quote']

Sounds like it would work. I'll give that a go...

Cheers for the reply.

Share this post


Link to post
Share on other sites

As you are already using CBA, try the following:

Add this to init.sqf:

if (!isDedicated) then {
["run_pickup", {
	if (player in _this) then {
		hint "Near Ammo Box";
		execVM "jedscripts\pickupammo.sqf"
	};
}] call CBA_fnc_addEventHandler;
};

And change your trigger statement to this:

_trig setTriggerStatements ["this", "['run_pickup', thislist] call CBA_fnc_globalEvent" , ""];

What it does is, it sends a global event with the trigger thislist to all clients which checks if they are in the trigger list (the trigger is still local on the client who dropped the box).

Though it would be better to create the trigger on all clients and simply check if player is in thislist. It's just one solution of many.

Ammo and weapon stuff is a local thing.

Edit: A little change so that the server handles the trigger instead:

Add this to init.sqf too:

if (isServer) then {
["create_trigger", {
	_trig = createTrigger ["EmptyDetector", _this]; 
	_trig setTriggerArea [5, 5, 0, false];
	_trig setTriggerActivation ["WEST", "present", true];
	_trig setTriggerStatements ["this", "['run_pickup', thislist] call CBA_fnc_globalEvent" , ""];
}] call CBA_fnc_addEventHandler;
};

And replace the part in your script which creates the trigger with the following:

["create_trigger", getpos _AmmoBoxDr] call CBA_fnc_globalEvent:

Now the trigger gets created on the server and not on the client who drops the box.

Xeno

Edited by Xeno

Share this post


Link to post
Share on other sites

@ Grimes - your solution worked, however I realise that for another task, there will be multiple of these 'drops' and pre-creating triggers would be difficult. As I did not say how many would be created, I can forgive you for not being psychic ;-)

@Xeno - thanks for that solution I will give it a try. Something you said interests me and may help clear up some theory for me...

'Though it would be better to create the trigger on all clients and simply check if player is in thislist'

My triggers are created as a result of an addAction attached to a player (which IS local to a machine I believe). Say I wanted to create a trigger on each client as you suggest, how would I do this from the resultant action of a local addaction?

Share this post


Link to post
Share on other sites

You don't need the first !isDedicated code snippet anymore that I've posted.

Change

if (isServer) then {
["create_trigger", {
	_trig = createTrigger ["EmptyDetector", _this]; 
	_trig setTriggerArea [5, 5, 0, false];
	_trig setTriggerActivation ["WEST", "present", true];
	_trig setTriggerStatements ["this", "['run_pickup', thislist] call CBA_fnc_globalEvent" , ""];
}] call CBA_fnc_addEventHandler;
};

to

if (!isDedicated) then {
["create_trigger", {
	_trig = createTrigger ["EmptyDetector", _this]; 
	_trig setTriggerArea [5, 5, 0, false];
	_trig setTriggerActivation ["WEST", "present", true];
	_trig setTriggerStatements ["player in thislist", "hint 'Near Ammo Box';0=[] execVM 'jedscripts\pickupammo.sqf'" , "hint 'Not Near Ammo Box'"];
}] call CBA_fnc_addEventHandler;
};

You can still use

["create_trigger", getpos _AmmoBoxDr] call CBA_fnc_globalEvent;

in your drop script.

The trigger gets only created on clients plus the client who called the event.

But be aware in that case it is not JIP aware anymore and you have to take care of that yourself (if you need to).

Edit: CBA events are a nice way to get around locality issues. If you add an eventhandler and trigger an event the event will be executed on all machines (where the event was added).

Only the parameters are broadcasted. And you are totally free to add whatever code you like to an event.

Edit2: Beside global events there are some other events in CBA like:

  • CBA_fnc_localEvent, raises a CBA event only on the local machine
  • CBA_fnc_remoteEvent, does only execute an event on remote machines
  • CBA_fnc_remoteLocalEvent, raises a CBA event only on the machine where parameter one is local
  • CBA_fnc_whereLocalEvent, raises a CBA event only on the machine where parameter one is local

There are more commands for networking stuff in CBA.

Edit3: :D

One thing I totally forgot about CBA, you can use all Extended Eventhandlers from XEH in description.ext, means, what you normally can only achieve with an extra addon is possible with CBA and XEH in a misson too!

http://dev-heaven.net/projects/cca/wiki/Extended_Eventhandlers

Xeno

Edited by Xeno

Share this post


Link to post
Share on other sites

That's brilliant mate. Thanks for your time.

Thanks for the heads up on JIP.

Share this post


Link to post
Share on other sites

I have not used this yet, but it seems like it could make things easy "RSL" Remote Script Launcher.

Share this post


Link to post
Share on other sites

  • cba_fnc_remotelocalevent, raises a cba event only on the machine where parameter one is local

Could someone please explain this for dummies? :o

I´ve recently started experimenting with XEH´s and I´m still wondering how to put them to best use...

thanks

Share this post


Link to post
Share on other sites
Could someone please explain this for dummies? :o

I´ve recently started experimenting with XEH´s and I´m still wondering how to put them to best use...

thanks

Its used to "fire" an event on other clients or the server. So for instance if you wanted to check a condition, lets say we want to check if there are enough Pilots on to fly someone to a mission.

We could run that check on the server. Now we found out that yes we have 3 pilots in the mission, now we want to send those pilots a message to return to base to pick up the ground forces, with cba_fnc_remotelocalevent we could check on the server(to keep from running this needlessly on everyone elses machine) and then raise an event on only our pilots clients so that they will see a message to return to base.

Of course this is just a small example, there are hundreds if not thousands of things you could do with them, I hope that explains it better.

Edited by Riouken

Share this post


Link to post
Share on other sites

Thanks, Riouken!

I´m starting to get the hang of it.

Also, at first I thought 'parameter one' would be the name of the EH - after all it´s a parameter, too :o

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

EDIT:

Wait... that made me think. What if the EH contains more complex code, accessing several parameters via "_this select x".

Now, depending on the kind of event that is raised the number of parameters might vary.

So my question would be, what will "_this select 0" return, if the event is raised with CBA_fnc_remoteLocalEvent?

Edited by CptBBQ

Share this post


Link to post
Share on other sites
Thanks, Riouken!

I´m starting to get the hang of it.

Also, at first I thought 'parameter one' would be the name of the EH - after all it´s a parameter, too :o

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

EDIT:

Wait... that made me think. What if the EH contains more complex code, accessing several parameters via "_this select x".

Now, depending on the kind of event that is raised the number of parameters might vary.

So my question would be, what will "_this select 0" return, if the event is raised with CBA_fnc_remoteLocalEvent?

Just take a look at the syntax for CBA_fnc_remoteLocalEvent

You can pass what ever data you need to onto the function.

example from above with extra parameters .

["create_trigger",[getpos _AmmoBoxDr,[25,37,0],"Get to the Choppa","etc"]] call CBA_fnc_globalEvent;

You could then make the triggers more flexable.

if (isServer) then {
["create_trigger", {

               [color="Red"]_trigpos = _this select 0;
               _trigarea = _this select 1;
               _commmsg = _this select 2;[/color]
	_trig = createTrigger ["EmptyDetector", [color="red"]_trigpos[/color]]; 
	_trig setTriggerArea [[color="red"]_trigarea[/color], false];
	_trig setTriggerActivation ["WEST", "present", true];
	_trig setTriggerStatements ["this", "['run_pickup', thislist] call CBA_fnc_globalEvent" , ""];
               hint [color="red"]_commmsg[/color] ;
}] call CBA_fnc_addEventHandler;

Share this post


Link to post
Share on other sites

I once enquired about the difference between CBA_fnc_whereLocalEvent and CBA_fnc_remoteLocalEvent and the response what that removeLocalEvent was not meant to be public and whereLocalEvent should be used instead.

Share this post


Link to post
Share on other sites
I once enquired about the difference between CBA_fnc_whereLocalEvent and CBA_fnc_remoteLocalEvent and the response what that removeLocalEvent was not meant to be public and whereLocalEvent should be used instead.
That's right ;-)

Verifying it with Xeno again.

Anyway here's the whereLocalEvent ;) http://dev-heaven.net/docs/cba/files/events/fnc_whereLocalEvent-sqf.html

Cleared up in the meantime for next update ;)

Edited by Sickboy

Share this post


Link to post
Share on other sites

Well, the description for both events says "First param must be the object to check".

So I suppose the example given by Riouken wouldn´t work with whereLocalEvent because the first parameter is a position...?

Share this post


Link to post
Share on other sites
Well, the description for both events says "First param must be the object to check".

So I suppose the example given by Riouken wouldn´t work with whereLocalEvent because the first parameter is a position...?

Correct, change it up so it includes the object, also perhaps not needed to send the position of the object, if you already send the object reference, can just getPos _obj on the receiving end :)

Also didn't read / know all details about the intent, but vehicles/units can change locality in several situations - so creating a trigger on the machine where the unit is currently local is perhaps not the way to go..

Perhaps better is a trigger on each machine, and only process local units within the trigger :)

Share this post


Link to post
Share on other sites

Thanks, Sickboy.

This was more about the general use of XEH´s than about triggers.

Now I know I can´t use the same eventhandler for global events and where-local events, because the parameters will differ.

Share this post


Link to post
Share on other sites

You are in control of how to setup the eventHandlers / functions, so sure you can use them in global and where-local; as long as you design (/adjust) it that way :)

No matter if you use whereLocalEvent, globalEvent, etc, your eventhandler receives the parameters as you input them when raising the events.

If you want to have the parameters work with both global and whereLocal at the same time, the first parameter in the array will have to be the object (as that is required by whereLocal).

btw CBA events != XEH.

Edited by Sickboy

Share this post


Link to post
Share on other sites

Thanks again.

Is there some kind of "howTo:cba"-thread I haven´t found yet? I don´t want to stray even more off-topic.

Share this post


Link to post
Share on other sites

Discussions about Mods should occur in their thread in the A&M Complete section, that's where you will find the CBA thread :)

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
Sign in to follow this  

×