Let's assume you want to have any player who joins the mission be able to use an object to do something. That something should be doable only once, and will send a bit of information to all clients on the server. That information should also synch with clients who have joined the server after the action has been performed.
I'm assuming that the variable in question is a public variable (available to all clients instead of just the server or calling client), which is named PV_MyToggle and defaults to 0. When the action is performed, it should equal 1, then after a short delay equal 2. This might be useful for updating briefings/tasks or other clientside effects.
The example works on two objects called ActionBarrel and FakeBarrel. These can be pretty much any object you want from the editor. I used empty barrels, hence the names.
In your init.sqf place the following:
Code:
if (isNil "PV_MyToggle") then { //if the PublicVariable does not yet exist, then we'll create a local copy. But if it DOES, we won't.
PV_MyToggle = 0;
if (isServer) then {publicVariable "PV_MyToggle";}; // make the server propogate the value to all clients, clients should keep local copies until the propogation happens.
};
//player SideChat format ["PV_MyToggle = %1", PV_MyToggle]; // Debug, should return 0 during briefing *unless JIP*
//player SideChat format ["PV_Whatever = %1", PV_Whatever]; // Debug, should return ANY during briefing
// Requires: ActionBarrel (object to have action), FakeBarrel (object to replace Object after removal (edit toggle.sqf if undesirable)
if (isNil "myAct") then { //AddAction is local, therefore connecting clients should be the only ones to get the action but let's be paranoid
if (PV_MyToggle==0) then { // If action has not already been performed, then clients get the action added on connect
Fer_Delay=10; //delay between states
myAct = ActionBarrel addAction ["Send two states with delay between them", "toggle.sqf", [Fer_Delay,FakeBarrel,"PV_MyToggle"]]; // if using Norrin's revive, this should be called when player is revived too
};
};
In the same directory, create toggle.sqf:
Code:
private ["_obj","_caller","_id","_params","_FerDelay","_OtherObj","_PubVar"];
_obj = _this select 0; // E.g. ActionBarrel
_caller = _this select 1; // E.g. Player
_id = _this select 2; // ID of action
_params = _this select 3; // Params passed to this script.
_FerDelay = _params select 0; // Delay (seconds)
_OtherObj = _params select 1; // Dummy object to replace this object (object)
_PubVar = _params select 2; // name of Public Variable to update (string)
// -- ASSUMES PUBLIC VARIABLE IS DEFAULT 0, INCREMENTING TO 1 THEN 2
//_caller SideChat format ["PV_MyToggle = %1", PV_MyToggle]; // Debug (PV_MyToggle is directly referenced PublicVariable)
//_caller SideChat format ["Public Variable is called: %1", _PubVar]; // Debug (PV_MyToggle is directly referenced PublicVariable)
_OtherObj setPos (getPos _obj); //Replace object with dummy (so if player JIPs, they don't get to fire the event again; also prevents action from being called mulitple times whilst the wait is running)
_obj setPos [-200,-200]; //Move object to nether regions
_obj removeAction _id; //Remove the action from this client once it is activated (not useful; will only remove action from this client and we're moving the object away anyway)
call compile format ["%1 = 1;",_PubVar]; //Set value
publicVariable _PubVar; //Broadcast to all clients
//_caller SideChat format ["PV_MyToggle = %1", PV_MyToggle]; // Debug (PV_MyToggle is directly referenced PublicVariable)
sleep _FerDelay; //Wait
call compile format ["%1 = 2;",_PubVar]; //Set second value
publicVariable _PubVar; //Broadcast to all clients
//_caller SideChat format ["PV_MyToggle = %1", PV_MyToggle]; // Debug (PV_MyToggle is directly referenced PublicVariable)
Now, when a player gets within about 5 m of the object, they'll have the option to perform an action. When they do, the action will disappear, the object swapped with another object (pref. of the same type so they don't notice), and the script will update the public variables on all clients as previously outlined.
There's another way to do this that doesn't involve init.sqf and lets you specify how close the player must be. Create a trigger (note that as Fer_Delay was only defined in the init.sqf I have replaced it with a value here):
Code:
Condition: (player distance ActionBarrel ) <= 1.5
On Activation: myAct= ActionBarrel addAction ["Send two states with delay between them", "toggle.sqf", [10,FakeBarrel,"PV_MyToggle"]];
On Deactivation: ActionBarrel removeAction myAct;
Now the action only appears when the player is within 1.5 meters of the object instead of the usual 5 m. When the player is too far away, the action disappears again.
The disadvantage of not using the init.sqf approach is that there is no default value at the start of the mission; until the publicVariable "PV_MyToggle" is called by a script clients will return ANY instead of 0. This might be fine for your mission, if not then simply add the first four lines (first IF statement) of the init.sqf example to your own init.sqf.