Jump to content
Sign in to follow this  
whiztler

initPlayerLocal.sqf - JIP

Recommended Posts

I want to query if a player has JIP-ed. I have tried the following:

initPlayerLocal.sqf

According to https://community.bistudio.com/wiki/Event_Scripts Executed locally when player joins mission (includes both mission start and JIP). [player:Object, didJIP:Boolean]

ADF_didJIP = _this select 1;

In my init.sqf I query if ADF_didJIP = true and if so wait till the player has initialized:

if (!isDedicated && isMultiplayer) then {
   if (ADF_didJIP) then {
       waitUntil {player == player}
   }
}; 

The init order according to https://community.bistudio.com/wiki/Functions_Library_%28Arma_3%29#Initialization_Order is as follows:

  1. Functions with recompile param set to 1 are recompiled
  2. Functions with preInit param set to 1 are called (client + server)
  3. Object Init Event Handlers are called
  4. Object initialization fields are called
  5. init.sqs is executed in singleplayer
  6. init.sqf is executed in singleplayer
  7. Persistent multiplayer functions are called (client only)
  8. Modules are initialized
  9. initServer.sqf is executed (server only)
  10. initPlayerLocal.sqf is executed
  11. initPlayerServer.sqf is executed (server only)
  12. Functions with postInit param set to 1 are called (client + server)
  13. "BIS_fnc_init" variable is set to true
  14. init.sqs is executed in multiplayer
  15. init.sqf is executed in multiplayer

When joining the server (not JIP) a script error is thrown: error undefined variable in expression: adf_didjip in init.sqf.

When I query ADF_didjip in game (hint str ADF_didjip) it returns 'FALSE'

Anyone got an idea?

Share this post


Link to post
Share on other sites

Hey !

Why don't you only use initPlayerLocal ? In addition with initServer, you can do the same as init.sqf.

Nice day !

Share this post


Link to post
Share on other sites
Hey !

Why don't you only use initPlayerLocal ? In addition with initServer, you can do the same as init.sqf.

Nice day !

Please read the first post. I am using initPlayerLocal. Wondering why the ADF_did variable is not picked up in init.sqf

Edited by whiztler

Share this post


Link to post
Share on other sites

The initialization order is not guaranteed for various reasons.

You don't actually need to wait until player == player as the initialization script (the one which executes most of the event scripts - Functions_F\initFunctions.sqf) already does.

Edit: Which means you can just run whatever you want for JIP players from the initPlayerLocal script by checking the second argument.

Edit2: Just a heads up. The initialization script I mentioned does not execute init.sqf and that is done by the engine itself - so it's not safe to assume the player has loaded in within that script.

Edited by SilentSpike

Share this post


Link to post
Share on other sites
Please read the first post. I am using initPlayerLocal. Wondering why the ADF_did variable is not picked up in init.sqf

How are you testing this? Are you testing on an actual/virtual dedicated server? Starting a 'New' session in the MP server browser is not a dedicated server.

If not, then that error may be thrown by the server element, if you are loading as both player and server (non-dedi). If you aren't on a dedicated server, then !isDedicated will return true.

Try !isServer instead of !isDedicated.

Share this post


Link to post
Share on other sites
Please read the first post. I am using initPlayerLocal. Wondering why the ADF_did variable is not picked up in init.sqf

I have read the first post but it is a workaroud. Instead of using initPlayerLocal + init.sqf, you could unse initPlayerLocal + initServer

Share this post


Link to post
Share on other sites
The initialization order is not guaranteed for various reasons.

You don't actually need to wait until player == player as the initialization script (the one which executes most of the event scripts - Functions_F\initFunctions.sqf) already does.

Edit: Which means you can just run whatever you want for JIP players from the initPlayerLocal script by checking the second argument.

Edit2: Just a heads up. The initialization script I mentioned does not execute init.sqf and that is done by the engine itself - so it's not safe to assume the player has loaded in within that script.

So what's the point of (quote):

[h=3]Initialization Order[/h] When mission is starting, its components are initialized in the following order:

How are you testing this? Are you testing on an actual/virtual dedicated server? Starting a 'New' session in the MP server browser is not a dedicated server.

If not, then that error may be thrown by the server element, if you are loading as both player and server (non-dedi). If you aren't on a dedicated server, then !isDedicated will return true.

Try !isServer instead of !isDedicated.

Running/testing on a dedi server, 1 player (so no JIP). Tried 'if (!isServer) then {if (ADF_didJIP) then {waitUntil {player == player}}}; but no joy

I have read the first post but it is a workaroud. Instead of using initPlayerLocal + init.sqf, you could unse initPlayerLocal + initServer

I know, but the initPlayerLocal.sqf + init.sfq combi should work. One of those things :)

Share this post


Link to post
Share on other sites

It doesn't work because the initialization order isn't guaranteed. The reason it's written in that order is because that's the order in which things are theoretically executed (as you can see by looking at the script I mentioned before).

The reason it's not guaranteed is because of the way the scheduled and unscheduled environments work. Again, just run your code from initPlayerLocal.sqf inside of:

if (_this select 1) then {

};

Share this post


Link to post
Share on other sites
You don't actually need to wait until player == player as the initialization script (the one which executes most of the event scripts - Functions_F\initFunctions.sqf) already does.

initFunctions.sqf only checks getClientState, which as far as I understand doesn't serve quite the same purpose as player == player or !isNull player. If it's enough or not depends on what you're doing with the script, I think.

Also important to note that it's only responsible for executing the new Arma 3 init event scripts (initServer, initPlayerLocal and initPlayerServer), not init.sqf.

Share this post


Link to post
Share on other sites

Dont know if this is of any interest. After this discussion and the one a couple of days ago involving whether BIS_fnc_init was worth checking i thought i would put a quick little test mission together.

I have not put alot of major thought behind it to weed out any timing issues my scripts may cause. That being said the results seem pretty consistent for each test so i will only post A set of results for each one.

Files used..

description.ext

class CfgFunctions
{
class LARs
{
	class Test
	{
		class main {
			file = "main.sqf";
			preInit = 1;
		};
		class post {
			file = "post.sqf";
			postInit = 1;
		};
	};
};
};

main.sqf

LARs_early = true;

playerDone = false;
fncInitDone = false;
cameraDone = false;
logicDone = false;
JIPDone = false;
MPinitDone = false;


diag_log format[ "LAR : Functions preInit : %1", diag_tickTime];
h = [] spawn {

while { true } do {
	switch ( true ) do {
		case ( !isNull player && !playerDone ) : {
			diag_log format [ "LAR : Player is available : %1", diag_tickTime];
			playerDone = true;
		};
		case ( !isNil "BIS_fnc_init" && { BIS_fnc_init && !fncInitDone } ) : {
			diag_log format [ "LAR : BIS_fnc_init is true : %1", diag_tickTime];
			fncInitDone = true;
		};
		case ( !isDedicated && { !isNull cameraOn && !cameraDone } ) : {
			diag_log format [ "LAR : Main camera attached : %1", diag_tickTime];
			cameraDone = true;
		};
		case ( !isNil "bis_functions_mainscope" && !logicDone ) : {
			diag_log format [ "LAR : Function logic started : %1", diag_tickTime];
			logicDone = true;
		};
		case ( !isNil { bis_functions_mainscope getVariable [ "didJIP",  nil ] } && !JIPDone ) : {
			diag_log format [ "LAR : DidJIP %2 : %1", diag_tickTime, bis_functions_mainscope getVariable "didJIP"];
			JIPDone = true;
		};
		case ( !isNil "BIS_fnc_MP_packet" && !MPinitDone ) : {
			diag_log format [ "LAR : Multiplayer initialised : %1", diag_tickTime];
			MPinitDone = true;
		};

	};

	if ( !isNil "BIS_fnc_init" && { BIS_fnc_init } ) exitWith {
		diag_log format [ "LAR : initFunctions complete : %1", diag_tickTime ];
		LARs_early = false;
	};
};
diag_log format [ "LAR : exit early : %1 : %2", diag_tickTime, LARs_early ];
};

post.sqf

diag_log format [ "LAR : Function postInit started : %1", diag_tickTime];

initServer.sqf

diag_log format [ "LAR : initServer.sqf called : %1", diag_tickTime];

initPlayerLocal.sqf

diag_log format [ "LAR : iniPlayerLocal/Server called : %1", diag_tickTime];

init.sqf

diag_log format [ "LAR : init.sqf called : %1", diag_tickTime ];

MISSION FILES

Results

Preview from SP editor

11:19:02 "LAR : Functions preInit : 3352.02"
11:19:02 "LAR : Player object init called : 3352.27"
11:19:02 "LAR : init.sqf called : 3352.28"
11:19:02 "LAR : Player is available : 3352.38"
11:19:02 "LAR : Main camera attached : 3352.38"
11:19:02 "LAR : Function logic started : 3352.38"
11:19:02 "LAR : Function postInit started : 3352.73"
11:19:03 "LAR : BIS_fnc_init is true : 3352.73"
11:19:03 "LAR : initFunctions complete : 3352.73"
11:19:03 "LAR : exit early : 3352.73 : false"
11:19:03 "LAR : initServer.sqf called : 3352.73"
11:19:03 "LAR : iniPlayerLocal/Server called : 3352.73"



SP scenario

11:26:08 "LAR : Functions preInit : 3778.19"
11:26:08 "LAR : Player object init called : 3778.43"
11:26:08 "LAR : init.sqf called : 3778.43"
11:26:08 "LAR : Player is available : 3778.49"
11:26:08 "LAR : Main camera attached : 3778.49"
11:26:08 "LAR : Function logic started : 3778.49"
11:26:09 "LAR : Function postInit started : 3778.81"
11:26:09 "LAR : BIS_fnc_init is true : 3778.81"
11:26:09 "LAR : initFunctions complete : 3778.81"
11:26:09 "LAR : exit early : 3778.81 : false"
11:26:09 "LAR : initServer.sqf called : 3778.81"
11:26:09 "LAR : iniPlayerLocal/Server called : 3778.81"
11:26:12 c:\w\stable\futura\lib\ui\uimap.cpp DisplayGetReady::Destroy:NOT IMPLEMENTED - briefing!


MP hosted server

( main RPT )
11:23:43 "LAR : Functions preInit : 3633.24"
11:23:43 "LAR : Player object init called : 3633.39"
11:23:43 c:\w\stable\futura\lib\network\networkserver.cpp NetworkServer::OnClientStateChanged:NOT IMPLEMENTED - briefing!
11:23:43 "LAR : Player is available : 3633.59"
11:23:43 "LAR : Main camera attached : 3633.59"
11:23:43 "LAR : Function logic started : 3633.59"
11:23:44 "LAR : Function postInit started : 3633.95"
11:23:44 "LAR : BIS_fnc_init is true : 3633.95"
11:23:44 "LAR : initFunctions complete : 3633.95"
11:23:44 "LAR : exit early : 3633.95 : false"
11:23:44 "LAR : initServer.sqf called : 3633.95"
11:23:44 "LAR : iniPlayerLocal/Server called : 3633.95"
11:23:44 "LAR : init.sqf called : 3634.19"




MP dedicated server

( main RPT ) 
11:28:20 "LAR : Functions preInit : 3910.29"
11:28:25 "LAR : Player object init called : 3915.59"
11:28:26 "LAR : Main camera attached : 3915.79"
11:28:26 "LAR : Player is available : 3915.79"
11:28:26 "LAR : Function logic started : 3915.79"
11:28:26 "LAR : init.sqf called : 3916.07"
11:28:28 "LAR : Function postInit started : 3918.46"
11:28:28 "LAR : BIS_fnc_init is true : 3918.46"
11:28:28 "LAR : initFunctions complete : 3918.46"
11:28:28 "LAR : exit early : 3918.46 : false"
11:28:28 "LAR : iniPlayerLocal/Server called : 3918.46"

Share this post


Link to post
Share on other sites
initFunctions.sqf only checks getClientState, which as far as I understand doesn't serve quite the same purpose as player == player or !isNull player. If it's enough or not depends on what you're doing with the script, I think.

This line here:

waituntil {!isnull cameraon && getClientState != "MISSION RECEIVED" && getClientState != "GAME LOADED"};

As far as I'm aware and in all my testing after the "GAME LOADED" state the player has loaded in. Which is why there's a comment "//--- Call postInit functions once player is present" (And I trust Moricky's script to do what it says it does).

Edit: Would be nice to confirm this however and then add that information to the biki page.

Edited by SilentSpike

Share this post


Link to post
Share on other sites
This line here:

waituntil {!isnull cameraon && getClientState != "MISSION RECEIVED" && getClientState != "GAME LOADED"};

As far as I'm aware and in all my testing after the "GAME LOADED" state the player has loaded in. Which is why there's a comment "//--- Call postInit functions once player is present" (And I trust Moricky's script to do what it says it does).

Edit: Would be nice to confirm this however and then add that information to the biki page.

I assumed that the player in that comment just referred to the client, but after testing I stand corrected:

Loaded the mission on a dedicated server:
18:37:04 "init.sqf:            tick: 642.903. player null: false. clientState: GAME LOADED."
18:37:04 "initPlayerLocal.sqf: tick: 642.965. player null: false. clientState: BRIEFING SHOWN."

Quit and return as JIP:
18:37:43 "init.sqf:            tick: 681.851. player null: true.  clientState: GAME LOADED."
18:37:44 "initPlayerLocal.sqf: tick: 682.213. player null: false. clientState: BRIEFING READ."

So player is null in init.sqf on JIP, but not in the new Arma 3 event scripts.

Share this post


Link to post
Share on other sites

EDIT: Only saying stupid things as I had a syntax error don't ask me why didn't see on rpt....

Edited by barbolani

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  

×