Jump to content
Sign in to follow this  
Rellikplug

Make addAction added to players persist for JIP players.

Recommended Posts

I have added an addAction to all players at mission start, made it so the addAction is removed from the player's corps, and made the addAction persist after player respawn. I am having some difficulty making the addAction exist for JIP players. Below is what I have. How do I make the addAction exist for JIP players?

init.sqf

//SOF

//disable saving and teamswitch
enableSaving [false,false];

// Turn off voice and radio
//enableRadio false;
enableSentences false;

//29th Actions: Salute, Surrender/Leave Captivity, Push-ups and RP Arsenal Drop
execVM "scripts\29th Actions\29thActions.sqf";

// EOF

29thActions.sqf

// SOF

[] spawn
{
waitUntil {!isNull player && player == player};
waitUntil{!isNil "BIS_fnc_init"};
};
//MP chat functions: side and global
RP_fnc_mpGlobalChat = {
    (_this select 0) globalChat (_this select 1);
};
publicVariable "RP_fnc_mpGlobalChat";

RP_fnc_mpSideChat = {
    (_this select 0) sideChat (_this select 1);
};
publicVariable "RP_fnc_mpSideChat";

// global variable counter for supply drop
supplyCrateCounter = 0;
publicVariable "supplyCrateCounter";

//Salute
RP_fnc_salute = {
	player addAction [
		"<img image='Pictures\yinyang.paa' /><t color='#4cccd1'>*Salute*</t>",
		"scripts\29th Actions\salute.sqf",
		"",
		-95,
		false,
		true,
		"Salute",
		""
	];
};
publicVariable "RP_fnc_salute";

// Init
[] spawn RP_fnc_salute;
player addEventHandler ["Respawn", {
	[] spawn {
//			sleep 1;
		waitUntil {alive player};
		[] spawn RP_fnc_salute;
	};
}];

// event handler removes actions from players dead body. (_this select 0)=killed, (_this select 1)=Killer

		player addEventHandler ["Killed", {
			removeAllActions (_this select 0);
		}];

// EOF

salute.sqf

// SOF

Private ["_target","_caller","_ID","_nameCaller","_msg"];

_target 	= _this select 0; //Object that had the action
_caller 	= _this select 1; //Unit that used the action
_ID			= _this select 2;
_nameCaller = name _caller;

_caller action ["Salute", _caller];
//_caller globalChat "*Salute*";

//_msg = format ["%1: *Salute*",_nameCaller];
_msg = "*Salute*";
[[_caller,_msg], "RP_fnc_mpGlobalChat"] spawn BIS_fnc_MP;

// EOF

Share this post


Link to post
Share on other sites

Well, that appears to have done it. Thank you. It's always the simple things I miss...

Share this post


Link to post
Share on other sites

I actually keep forgetting to use the initPlayerLocal/Server.sqf files myself, but they sure do make script locality easy, especially for JIP.

Share this post


Link to post
Share on other sites
I am having some difficulty making the addAction exist for JIP players. How do I make the addAction exist for JIP players?

In the 29thActions.sqf you are waiting until the player variable is initialized, but in an entirely separate thread.

[] spawn // -- Spawn a new thread and continue the script. Do not wait here.
{
waitUntil {!isNull player && player == player};
waitUntil{!isNil "BIS_fnc_init"};
};

// -- Thus you're trying to add actions prematurely to jip clients.  

Should be

if (isServer) exitWith {};

waitUntil { // -- Wait here until player variable is initialized on the (jip) client's machine. 
   !(isNull player) && 
   {(player == player)} &&
   {!isNil "BIS_fnc_init"}
}; 

// -- Store your functions into local (non-public) global variables for the client. 
// -- Call function that add's the addaction to the player controlled object 
// -- Add your Ehs to the player controlled object

Additional information

This EH can be cut down to the following. No need to waituntil the player is alive. The respawn Eh (should) only fires when the unit respawns and has control over the unit.

player addEventHandler ["Respawn", {[] spawn RP_fnc_salute;}];

All of those publicVariables also seem redundant. Each client will automatically receive the global variables (functions) when they run the script.

To sum it all up, your 29thActions.sqf could look something like this:

if (isServer) exitWith {};

waitUntil {
   !(isNull player) && 
   {(player == player)} &&
   {!isNil "BIS_fnc_init"}
}; 

RP_fnc_mpGlobalChat = {(_this select 0) globalChat (_this select 1);};
RP_fnc_mpSideChat = {(_this select 0) sideChat (_this select 1);};
supplyCrateCounter = 0; // -- Only need to PV when it's updated (if applicable). Initially, it's set to 0 for every client that runs the script.

RP_fnc_salute = {
   player addAction [
"<img image='Pictures\yinyang.paa' /><t color='#4cccd1'>*Salute*</t>",
"scripts\29th Actions\salute.sqf",
"",
-95,
false,
true,
"Salute",
""
   ];

   nil  // -- This (now) called function doesn't need to return anything. So lets return "void" so we know exactly what the return is (or isn't in our case). 
};

_nul = call RP_fnc_salute; // -- No need to spawn a new thread. Though it wouldn't "hurt" to use spawn, it's good practice to use call if possible.
player addEventHandler ["Respawn", {_nul = call RP_fnc_salute;}];
player addEventHandler ["Killed", {removeAllActions (_this select 0);}];

Anyhow, those are some things that stuck out to me. I hope that clears a few things up. If I missed anything hopefully some other knowledgeable forum goer can catch it. Cheers.

Edited by Iceman77

Share this post


Link to post
Share on other sites

Though I've never had any issues using BI functions in A3 without it. I thought it was an obsolete check now with A3? Meh. In A2 I always placed a function's module and made sure bis_fnc_init wasn't nil before using any bi functions. I know we don't need the module now, but do we still advise a nil check (bis_fnc_init) in A3? He isn't even utilizing any BI functions in any case. bis_fnc_mp :p

Edited by Iceman77

Share this post


Link to post
Share on other sites

That was only needed in A2, it would compile the functions if it detected the module. In A3 functions are always compiled, way before the mission is started

https://community.bistudio.com/wiki/Functions_Library_%28Arma_3%29#Initialization_Order

Here you can see that BIS_fnc_init is set to true late. The functions are available way before that tho.

Share this post


Link to post
Share on other sites
In the 29thActions.sqf you are waiting until the player variable is initialized, but in an entirely separate thread.

I actually was going to bring that up as well, but wasn't too sure if my thoughts were correct :p. I was also going to bring up the point of publicVariabling the functions, as it made no sense, because every client was going to run through this script.

But eh, he did it for whatever reason, so I wasn't going to contest it :D.

Share this post


Link to post
Share on other sites
That was only needed in A2, it would compile the functions if it detected the module. In A3 functions are always compiled, way before the mission is started

https://community.bistudio.com/wiki/Functions_Library_%28Arma_3%29#Initialization_Order

Here you can see that BIS_fnc_init is set to true late. The functions are available way before that tho.

That's what I had thought. After I went to the wiki link he provided and seen there was nothing regarding A3 and the function being obsolete, I just went with it. Cheers. :cool:

---------- Post added at 13:16 ---------- Previous post was at 13:08 ----------

But eh, he did it for whatever reason, so I wasn't going to contest it :D.

Yes well he is the one here asking for help after all. If you see mistakes, or what you think are mistakes, then tell him. If you are wrong then you are wrong. Big deal. If you are right, then you are right. hurray. At the very least, if you are wrong, you can rest assured you'll have a good grasp on the subject after forum goers get through with letting you know just how wrong you are. But atleast you'll have upped your knowledge a bit. And the OP gets help. More help than they bargained for :)

Edited by Iceman77

Share this post


Link to post
Share on other sites
cuel

That was only needed in A2, it would compile the functions if it detected the module. In A3 functions are always compiled, way before the mission is started

https://community.bistudio.com/wiki/...lization_Order

Here you can see that BIS_fnc_init is set to true late. The functions are available way before that tho.

Im not so sure that this is entirely true. The player seems to be connected to his camera before

final postInit functions,

Multiplayer frame work is initialised,

Modules are initialsed,

initServer,

initPlayerLocal,

initPlayerServer,

They seem to be just disabled behind the loading screen.

Have a read though "\a3\functions_f\initFunctions.sqf", especially starting around line 470 onwards.

Even going by the Initialization Order from the Wiki it would seem like a good idea to wait for BIS_fnc_init as it says object init EH's, init fields and init.sqf SP are called before alot of other things are ready like modules and Event Scripts.

Maybe it would be worth checking with a preInit script and diag_logs placed in player/object inits, event scripts and init.sqf and a final one when BIS_fnc_Init actually becomes true, to see what is accessed when?

Just interesting to note after reading through initFunctions, is that everything is held in UInamespace and MissionNamespace variables seem to be just shortcuts to UInamespace. Not related to this discussion just thought it was interesting :/

Share this post


Link to post
Share on other sites

This is actually very interesting :). I think it is safe to say that without further investigation, it certainly wouldn't hurt to check bis_fnc_init. Better safe then sorry. On the other hand, I would like to know for sure and I think we all would. We need some test(s) and break down how it's actually working and edit the wiki to reflect the truth lol.

Share this post


Link to post
Share on other sites
Im not so sure that this is entirely true. The player seems to be connected to his camera before

final postInit functions,

Multiplayer frame work is initialised,

Modules are initialsed,

initServer,

initPlayerLocal,

initPlayerServer,

They seem to be just disabled behind the loading screen.

Have a read though "\a3\functions_f\initFunctions.sqf", especially starting around line 470 onwards.

Even going by the Initialization Order from the Wiki it would seem like a good idea to wait for BIS_fnc_init as it says object init EH's, init fields and init.sqf SP are called before alot of other things are ready like modules and Event Scripts.

Maybe it would be worth checking with a preInit script and diag_logs placed in player/object inits, event scripts and init.sqf and a final one when BIS_fnc_Init actually becomes true, to see what is accessed when?

Just interesting to note after reading through initFunctions, is that everything is held in UInamespace and MissionNamespace variables seem to be just shortcuts to UInamespace. Not related to this discussion just thought it was interesting :/

(only talking about MP atm)

All of the functions are still compiled tho? That would happen when the addon is loaded / mission is loaded/saved/restarted (editor) or you press "Start" in MP. as far as I can tell.

I'm trying to think of a situation when you would have to use it, the only thing I can think of right now is when you're trying to change module related stuff in object init fields

Considering init.sqf is that last thing to run and most people put their stuff inside of that, you'd never have to wait for bis_fnc_init. Especially regarding OP since he is executing his script from init.sqf.

When doing stuff that doesn't need JiP compability I'd like it to run early and fast, the loading screen is still there when init.sqf runs. And at least back in A2, scripts ran really fast when the loading screen was enabled (simulation disabled).

On a sort of related note I'm giving units their loading using objects fields, like this

Object init field

[this,"PLT"] call CUL_fnc_getKit;

_unit = [_this,0,objNull,[objNull]] call BIS_fnc_param;
_kit = toUpper ([_this,1,"",[""]] call BIS_fnc_param);
_unit setVariable ["CUL_kit_type", _kit]; // for respawn

if (local _unit) then {
 diag_log "local!"
 // calls related gear code scripts
};

I noticed the diag_log actually runs on the server, even for non-JiPs. So the server is giving objects their loadout, and sometime in the future the control is transferred to the player machine. So being attached to the camera might not mean that the client is in control of the unit

Edited by cuel

Share this post


Link to post
Share on other sites

I am glad to see a discussion sparked and curious to see the results. @JShock and Iceman77, thanks for the corrections.

Share this post


Link to post
Share on other sites
All of those publicVariables also seem redundant. Each client will automatically receive the global variables (functions) when they run the script.

Only need to PV when it's updated (if applicable). Initially, it's set to 0 for every client that runs the script.

So... I need to update the PVs when they change in a script. Do I have to update them every change or only once at the end of the script run?

After some more thought... I guess that would depend on what I am doing with the variables or functions?

Edited by Rellikplug

Share this post


Link to post
Share on other sites

He is saying it's pointless to pV a function (or at least in your case) because every client is going to run through this script and get those functions anyhow. And yes any time a pV's value is changed, it needs to be re-pVed.

Share this post


Link to post
Share on other sites

Yeah. Your functions will be defined for whatever machine run's that script. You would only need to PV those initial variables if you ran the script on the server or any one machine instead. The variables would be defined on the server or the machine where the script was ran. Then you would need to sync the variables with the clients with PV. This isn't the case with your script and also it's better to work locally with the clients here anyhow, to cut down on network traffic.

Edited by Iceman77

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  

×