Jump to content
Matthew10_28

custom function doesn't work on dedi / nearly identical function does

Recommended Posts

Thanks to Killzone Kid I've discovered functions.  fnc_lightToggle won't work on a dedicated server while fnc_HeliPadLightToggle does.  As you can see its functionally identical.  What am I missing?

 

Light toggle is called via an add action:

this addAction ["Base Lights On/Off", {remoteExec ["fnc_lightToggle", 2]}];

HeliPadLightToggle is also done via an add action:

this addAction ["Pause/Resume Heli Pad Lights", {remoteExec ["fnc_HeliPadLightToggle", 2]}];

init.sqf

enableSaving[false,false];

//TFAR Settings\\
TF_give_personal_radio_to_regular_soldier = true;
tf_no_auto_long_range_radio = true;
TF_give_microdagr_to_soldier = false;

waituntil {!isnil "bis_fnc_init"};

[] execVM "scripts\Functions.sqf";

Functions.sqf

fnc_lightToggle = 
{
missionNamespace setVariable [
"LightSwitch", 
!(missionNamespace getVariable ["LightSwitch", true]), 
true
];


if (LightSwitch) exitWith 
{
_LampList = nearestObjects[BaseCargoHouse, [
"Lamps_base_F",
"PowerLines_base_F",
"PowerLines_Small_base_F"
], 600];
{
_x setHit ["light_1_hitpoint", 0];
_x setHit ["light_2_hitpoint", 0];
_x setHit ["light_3_hitpoint", 0];
_x setHit ["light_4_hitpoint", 0];
} forEach _LampList;
};
_LampList = nearestObjects[BaseCargoHouse, [
"Lamps_base_F",
"PowerLines_base_F",
"PowerLines_Small_base_F"
], 600];
{
_x setHit ["light_1_hitpoint", 0.97];
_x setHit ["light_2_hitpoint", 0.97];
_x setHit ["light_3_hitpoint", 0.97];
_x setHit ["light_4_hitpoint", 0.97];
} forEach _LampList;
};


fnc_HeliPadLightToggle =
{
missionNamespace setVariable [
"HeliPadLightSwitch", 
!(missionNamespace getVariable ["HeliPadLightSwitch", true]), 
true
];


if (HeliPadLightSwitch) exitWith 
{
_HeliPadLampList = nearestObjects[BaseCargoHouse, [
"Land_PortableHelipadLight_01_F","FloatingStructure_F"
], 600];
{
_x enableSimulationGlobal true;
} forEach _HeliPadLampList;
};
_HeliPadLampList = nearestObjects[BaseCargoHouse, [
"Land_PortableHelipadLight_01_F","FloatingStructure_F"
], 600];  
{
_x enableSimulationGlobal false;
} forEach _HeliPadLampList;
};

 

Share this post


Link to post
Share on other sites

SetHit needs to be done for each client, not the server. Change your remoteExec for "Base Lights On/Off" from 2 to 0.

  • Like 1

Share this post


Link to post
Share on other sites

SetHit needs to be done for each client, not the server. Change your remoteExec for "Base Lights On/Off" from 2 to 0.

 

 

 

Arg.  It's always the simple things.  Here I was looking for goofy syntax.

I'm a little fuzzy on how this will work for joining players.  From reading the wiki on remoteExec, I'm not sure if I need to use JIP or if the current state of the lights damage will be picked up when a new player joins.

Share this post


Link to post
Share on other sites

I'm a little fuzzy on how this will work for joining players.  From reading the wiki on remoteExec, I'm not sure if I need to use JIP or if the current state of the lights damage will be picked up when a new player joins.

There are several ways this could be accomplished either remoteExec or PVEH. Here im going to use remoteExec.

Yes you will need to use JIP and give it a unique JIP string so as to overwrite any previous messages every time it is used.

And you will want to change it up a bit so as your not using remoteExec JIP and the PV from setVariable.

 

Maybe something like..

 

//Object with action
this addAction ["Base Lights On/Off", {
    
    //Get state of light stored on BaseCargoHouse
    _lightsOn = !( BaseCargoHouse getVariable [ "LightsOn", true ] );    

    //Pass state and use unique JIP queue name
    [ _lightsOn ] remoteExec [ "fnc_lightToggle", 0, "BaseLights" ];
}];
 

//init.sqf would be better set as function library

fnc_lightToggle = {
    params[ [ "_lightsOn", true ] ];

    //Set variable on object that holds lights state
    BaseCargoHouse setVariable [ "LightsOn", _lightsOn ];    

    //Get the lights
    _LampList = nearestObjects[ BaseCargoHouse, [
        "Lamps_base_F",
        "PowerLines_base_F",
        "PowerLines_Small_base_F"
    ], 600 ];

    {
        _x setHit ["light_1_hitpoint", [ 0.97, 0 ] select _lightsOn ]; //set hit based on light state
        _x setHit ["light_2_hitpoint", [ 0.97, 0 ] select _lightsOn ];
        _x setHit ["light_3_hitpoint", [ 0.97, 0 ] select _lightsOn ];
        _x setHit ["light_4_hitpoint", [ 0.97, 0 ] select _lightsOn ];
    } forEach _LampList;

};
So each client holds the current state of the lights on BaseCargoHouse.

When ever anyone uses the action they pass the state the lights need to change to and call it on all clients and JIP.

JIP uses a unique JIP queue name "BaseLights" so that each use overwrites the same message.

Share this post


Link to post
Share on other sites

In an effort to edify my own understanding, allow me to restate what you've just presented.

 

I understand you've modified some basic framework of my code to get it to be more accommodating with JIP.  The "LightsOn" variable is globally stored and accessible to everyone.  Within the addAction before it gets passed to the remoteExec, you get the variable or assign it if it doesn't already exist.  Then you pass that Parameter to the function using remoteExec and you're storing "BaseLights" as a JIP "message" (perhaps thought of as an ad hoc, slip streamed, variable).  That message being the last parameter somone ran through remoteExec so they get the correct state upon startup.

 

Rather than calling a seperate functions library within Init.sqf, we just allow the init.sqf to be the functions library for reasons of compactness & perhaps code optimization with respect to timing.  We set the global variable state of the lights based on what got passed to it within the addAction, which almost seems like a circular reference but its really not.  We generate the _LampList as before.  Then we fix/damage the lights in a more compact manner based on the internally used _lightsOn variable which is basically the current global state of the "LightsOn" global variable stored within the BaseCargoHouse object.

 

If there is anything not precisely correct about my understanding, please let me know.

Share this post


Link to post
Share on other sites

The "LightsOn" variable is globally stored and accessible to everyone

No, the variable is stored locally for each client. Thats why we pass the variable in the remoteExec so clients can update their copy.

"which almost seems like a circular reference but its really not"

Its not the variable is stored on each clients copy of BaseCargoHouse locally/independant.

 

(perhaps thought of as an ad hoc, slip streamed, variable)

Sorry neither of those references mean anything to me, other than ad hoc is as needed and slipstream is the process of issuing an update with no version change.

Basically when you request JIP the server keeps a data structure of the function and variables passed under a unique name. Even if you use TRUE a unique name is generated for you.

When a new client joins the list is sent to the client to process.

By giving it a unique name you ensure that there is only ever one change lights command queued up for joining clients, as it gets overwritten each time remoteExec is used.

If you didn't specify a unique name and for instance the lights had been turned on/off 20 times, a joining client would have to process the function 20 times.

Infact you can see this for yourself by using exportJIPMessages and using my method above and then redo it using TRUE for the JIP in remoteExec.

But other than those two points yes youve got 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

×