Tom507 0 Posted February 14, 2017 I'm making a guerilla style coop mission the code works well in single player but as soon as i go on a Server not verry much happens I plan on having a persistent server witch initializes with the start so i only have JIPs I have been trying to just execute code on new Players either by 1. writing them in a list and updating it every 0.1 sec. or (and looping thrue them later) 2. by (Player) execVM ... i tried playing with waitUntil it doesnt seem to have any effect (apart from delying the script) i failed with both attempts there must be something im missing maybe locality? here is my code (you can also Just answer my question im shure its a simple one for some of you) : 1. : while {true} do { for "_thisPlayerNum" from 0 to (count allPlayers) do { _thisPlayer = (allPlayers select _thisPlayerNum); if (!isNil "_thisPlayer") then { if (alive _thisPlayer) then { if (!(_thisPlayer in myLivePlayers)) then { // executed on Player spawn //waitUntil {alive _thisPlayer}; myLivePlayers = (myLivePlayers + [_thisPlayer]); _thisPlayer setCaptive true; } else { if (!(alive _thisPlayer)) then { // executed on Player death myLivePlayers = (myLivePlayers - [_thisPlayer]); if (_thisPlayer in HostilePlayers) then { TimeLastShot = TimeLastShot - [(TimeLastShot select (HostilePlayers find _thisPlayer))]; HostilePlayers = HostilePlayers - [_thisPlayer]; }; }; }; if ((_checkNewPlayer != (count allPlayers)) and (_thisPlayer in myLivePlayers)) then { _thisPlayer execVM "GW_3_0_PlayerConnected.sqf"; }; _checkNewPlayer = (count allPlayers); }; }; }; sleep 0.1; }; 2. : while {true} do { if ((count allPlayers) > 0) then { if (_checkNewPlayer < (count allPlayers)) then { waitUntil{isNull (allPlayers select ((count allPlayers)-1))} (allPlayers select ((count allPlayers)-1)) execVM "GW_3_1_Main.sqf"; } _checkNewPlayer = (count allPlayers); }; sleep 0.1; }; I would verry much appreciate your help this holds me back for a week now THX in advance Share this post Link to post Share on other sites
mrcurry 470 Posted February 14, 2017 If you're looking for away to execute code when a player connects: https://community.bistudio.com/wiki/addMissionEventHandler And: https://community.bistudio.com/wiki/Arma_3:_Event_Handlers/addMissionEventHandler#PlayerConnected Share this post Link to post Share on other sites
Tom507 0 Posted February 14, 2017 I saw that but how do i get the Players in to the executed script the ids that that command gives you are as i read in this forum useless if i were searching for the profile name there is the simple: name (object) I am searching for a way to reliably get the (object) that is the player into an execVm without delaying the connect handler. Share this post Link to post Share on other sites
Tom507 0 Posted February 14, 2017 btw i know my code is a mess its by far not final i was just trying things Share this post Link to post Share on other sites
igneous01 19 Posted February 14, 2017 The last argument of PlayerConnected is owner ID, which is the same value returned from clientOwner. Depending on what scripts you have being execVM in that loop, may not work like that. You would need to remoteExec the script on that players machine using the owner ID that PlayerConnected returned. The other problem is that loop you have above doesn't handle the JIP queue. It's better to use remoteExec in this case and specify which commands should be added to JIP queue and which ones should not. 1 Share this post Link to post Share on other sites
Tom507 0 Posted February 14, 2017 OMG thakns I think thats the exact thing im looking for but it still doesnt work for me shouldn't i be able to access the owner with: _this select 5 like so : if (isServer) then { addMissionEventHandler["PlayerConnected",{_this execVM "GW_3_1_Main.sqf"}]; }; this is in GW_3_1_Main.sqf : thisPlayer = _this select 5; publicVariable "thisPlayer"; if I watch thisPlayer it returns nothing I'm now even looping the public variable even though it should be JIP proof (so i read) while {true} do { sleep 0.5; publicVariable "thisPlayer"; }; still doesn't work Share this post Link to post Share on other sites
Tom507 0 Posted February 14, 2017 I want to get rid of this problem because im annoyed that i can't move on and do the way more interesting stuff that i have planned for my mission please HELP !!!!!!!! THANKS IN ADVANCE Share this post Link to post Share on other sites
mrcurry 470 Posted February 15, 2017 Ok so using the PlayerConnected eventhandler, note that the owner ID is a number. As it's param #5 it is retrieved using _this select 4, 0-based index and all that. //Add eventhandler addMissionEventhandler [ "PlayerConnected", { (_this select 4) execVM "yourNameHere.sqf"; } ]; //yourNameHere.sqf private _ownerId = _this; private _player = objNull; { if(owner _x == _ownerId) exitWith { _player = _x; }; } forEach allPlayers; //Do your stuff Another method would be to just use remoteExec in initPlayerLocal.sqf: [player, "yourNameHere.sqf"] remoteExec ["execVM", 2]; 1 Share this post Link to post Share on other sites
Tom507 0 Posted February 15, 2017 (edited) I could punch myself for making such a basic mistake . Sorry that i got so emotional but this basic stuff stopped my advance for a lot of ours. Thank you so much now i can finally work on the fun stuff. What does this do tho? 8 hours ago, mrcurry said: { if(owner _x == _ownerId) exitWith { _player = _x; }; } forEach allPlayers; Why would the server ever have to deal with clients that have the same ID? isn't the ID given by the server and should therefor be unique? Edited February 15, 2017 by Tom507 another question Share this post Link to post Share on other sites
Tom507 0 Posted February 15, 2017 (edited) nevermind i looked it up https://community.bistudio.com/wiki/exitWith Edited February 15, 2017 by Tom507 stupidity Share this post Link to post Share on other sites
Tom507 0 Posted February 15, 2017 don't get confused by the previous posts just read this one. I think i spoke too soon because i can't get yours to work Im confused since it doesn't work either when i do it any other way for example: handler: if (isServer) then { addMissionEventHandler["PlayerConnected",{_this execVM "GW_3_1_Main.sqf"}]; }; script: playerId = (_this select 4); for "_x" from 0 to (count allPlayers) -1 step 1 do { if (owner _x == playerId) then { thisplayer = (allPlayers select _x); }; }; sleep 0.5; publicVariable "thisplayer"; publicVariable "playerId"; it does everything (theoretically) that yours does except stopping the loop playerId returs the correct 3 but thisPlayer returns nothing for some reason i believe the evaluation doesn't work neither in mine nor in yours since if i do this: private _ownerId = _this; private _player = objNull; { if(owner _x == _ownerId) exitWith { _player = _x; }; } forEach allPlayers; playerId = _ownerId ; thisplayer = _player ; thisPlayer returns your initialization "<NULL-object>" so the condition never returned true or your exitWith didn't set the variable correctly (yes i changed (_this select 4) every time in the other script) this doesn't work at all in the init.sqf: if (!isServer) then { [player, "GW_3_1_Main.sqf"] remoteExec ["execVM", 2]; }; Main: thisPlayer = _this publicVariable "thisplayer"; publicVariable "playerId"; i have no idea what could be wrong with that stil thanks for the response! Share this post Link to post Share on other sites
mrcurry 470 Posted February 20, 2017 The isServer check is redundant when adding the PlayerConnected eventhandler. The EH only fires server-side anyhow. From the biki on PlayerConnected: Quote If dedicated server was started without '-autoInit' option and this EH was created on server, on first GUI client this EH also fires against server, but after first client. The reason why you are getting odd results is because of the server overwriting your global var. If you use _player from what I wrote instead of assigning it to a global variable you will have the correct result for each connecting player. Preferably you should test if it's a proper player before continuing. This also helps avoid executing code unnecessarily: addMissionEventHandler [ "PlayerConnected", { params ["_id", "_uid", "_name", "_jip", "_owner"]; if !(_owner isEqualTo 2 || _uid find "HC" == 0) then { private _player = objNull; { if(owner _x isEqualTo _owner) exitWith { _player = _x; }; } forEach allPlayers; //Do your stuff with _player here but remember that assigning it to a global var will cause it to be overwritten by the next player. }; } ]; Share this post Link to post Share on other sites
Tom507 0 Posted February 21, 2017 thanks for your answer! i have to admit i was to impatient, to wait for it tho, and started a new thread I'm sorry and by the way the Reason why the stuff didn't work was not because of global vars(i was alone on my Server anyway), but because of the Player not beeing correctly initialized (thats what you probably ment) https://community.bistudio.com/wiki/player KK and Larrow pointed me at the initPlayerServer.sqf wich I got to work in an instant: (code in initPlayerServer.sqf) params[ "_player", "_didJIP" ]; thisPlayer = _player; publicvariable "thisPlayer"; // works as smooth as a babys skin and is less expansive (calc time) than what we were attempting still thanks for your Efforts Share this post Link to post Share on other sites