granQ 293 Posted July 10, 2009 I (and hopefully everyone that reads this thread) has basic knowledge of mission editing, scripting and local/client stuff. We can do the operation flashpoint editing perfectly but the Join in progress is confusing for atleast me. So people, feel free to post lessons learn, stuff that doesn't work, stuff that works and explinations on what is best. For instance what I noticed is that if you change markercolor ingame and then a JIP player comes, markers will reset to its orginall color. Share this post Link to post Share on other sites
nominesine 0 Posted July 10, 2009 I'm in a similar situation. Agree completely. Share this post Link to post Share on other sites
sickboy 13 Posted July 10, 2009 Some of my findings; http://community.bistudio.com/wiki/6thSense.eu:EG#Join_in_Progress Probably not entirely what you are looking for, but I hope at least something on the page does help :) Share this post Link to post Share on other sites
TurokGMT 0 Posted July 10, 2009 The main concern about JIP is to remember WHAT IS RUNNING ON WHAT MACHINE in terms of scripts and commands. For example, say you have a mission where you want to attack a town and as you get within say 500, a bunch of badguys spawn. Typically this would be done with a trigger that fires when west is present and fires a script (or single use of the bis_fnc_spawngroup function) that makes 20 dudes to shoot at. The problem is that this trigger will exist for every player that joins the server on their machine AND WILL BE ACTIVATED ONCE FOR EVERY MACHINE eg if 5 players are in the game, 100 dudes would get spawned! To get around this, and similar problems, you have to understand the concept of LOCALITY - ie is a script being run on the server, on client machines or both. To continue the example above, to ensure that only 20 dudes are spawned, no matter how many players join, we have to work with the game. We can't stop the trigger being activated on both server and client machines, but we CAN prevent certain lines of code being executed on client machines. Compare the following lines of code which we could put in the trigger's on activation field: 1. dudes = [(getmarkerpos "town"),east,20] call bis_fnc_spawnGroup; 2. if (isServer) then {dudes = [(getmarkerpos town),east,20] call bis_fnc_spawnGroup;}; The first example would spawn 20 east soldiers PER PLAYER at a marker called town. The second example would only create the 20 soldiers on the server (but all players would be able to see and shoot them). Check out Mr. Murrays editing guide, there are some further discussions of MP compatability contained therein. Or you could do what I did to learn ARMA scripting - depbo the domination! mission and spend 3 weeks figuring out how it all works =] I'm still not an expert by any means, but I can follow other people's code quite well, I also comment the buggery out of anything I write to enable others to follow it more easily. Try looking at my operation magpie mission (linked in my sig) for some fairly simple examples of getting JIP to work properly - note I haven't solved ALL my problems, eg, I haven't implemented a way of getting the current state of mission tasks passed to respawned or JIP players yet (ie on JIP, players don't know what tasks have been completed yet). Read, read and read some more! Then try out some ideas on simple test maps. Then spend 3 days debugging your scripts. Rinse and repeat for a few weeks and you have your own domination! beater =] Share this post Link to post Share on other sites
Carpaazi 0 Posted July 11, 2009 question on JIP and tasks_fix i got from "he longest day" mission: I made a coop helicopter mission that has 10 objectives, but you can only see the first 3 objectives,and once those 3 objectives are done, JIP.sqf should give 4 objectives more... We tested this mission with a friend of my yesterday, and the first 3 objectives worked well, but when the next set of objectives should have come, i didn't recieve them, and my friend DID, so this somehow seems to mean that the script thinked that im a dedicated server then? I changed the mission a bit and i now have a trigger that check (= true) conditions from the first 3 objectives like obj1 && obj2 && obj3 and on the same triggers "on activation" i have if (isServer) then {first_round_done=true; publicvariable "first_round_done"} , but it still won't give me new set of objectives when i test this in editor. Im going crazy with this because im not sure when the script is written so that it only works properly on dedicated server, and when it works for client server. I try to use http://www.ofpec.com/tutorials/index.php?action=show&id=44&page=9 to help me understand all this but its for armed assault and i don't know if this can help me as much as other people. Would be great if someone could post your own JIP.sqf (NOT USED FOR DEDICATED) script here or send it to my hotmail so i could compare it to my, because i learn much better by checking it that way =) Share this post Link to post Share on other sites
xeno 230 Posted July 11, 2009 Would be great if someone could post your own JIP.sqf (NOT USED FOR DEDICATED) script here or send it to my hotmail so i could compare it to my, because i learn much better by checking it that way =) You just have to execute the code from the publicVariableEventhandlers on the host "server" too. The difference between a hosted environment and a dedicated environment is that in a hosted environment the host is server and client at once. addPublicVariableEventhandler doesn't get fired where the publicVariable command gets executed so you have to run the code from those handlers on the host "server" too. Concerning JIP, it's totally easy (it really is, no kidding). Basically all you have to do is to update a JIP client to what allready happened in the mission. This mostly means update markers, add or change tasks. What I allmost never do is to change those things (markers) or write some text ( hints, sidechat, whatever) in a trigger activation field simply because when a client joins all those triggers get activated again. That's why I use isServer &&... in trigger condition fields and then publicVariable a variable which tells all clients that something happened and that they have to react to it, mainly done with addPublicVariableEventhandler (JIP clients simply check such a variable and set things to the correct state when they connect, no chat or hint commands executed then). Make use of setMarkerXXXLocal instead of setMarkerXXX. The difference is that setMarkerXXXLocal changes markers only on one client and contrary to setMarkerXXX it doesn't get transfered over the network. Try to learn what locality in MP means. That's allmost the most important part. Understand why things have to be run on the server only or on a client only. Xeno Share this post Link to post Share on other sites
Carpaazi 0 Posted July 11, 2009 Sorry! Forgot to mention that i DID use isServer &&... first, but when it didn't seem to work i tried If (isServer) THEN {... I made a test mission where i blow up 2 trucks (Task1) , and the next objective should become active (blow up 2 x uaz), but nothing =( . Task1 gets completed, but it won't change it to green in the tasklist... Something doesn't work here. I could send the example mission to you xeno if you could see what is the problem? Share this post Link to post Share on other sites
TurokGMT 0 Posted July 11, 2009 try an if statement like this one: if (isServer || (isServer && !isnil player)) then { code...} the first is Server checks for dedicated server, the and statement looks for a hosted server where a player exists. Share this post Link to post Share on other sites
Carpaazi 0 Posted July 12, 2009 Tried this if (isServer || (isServer && !isnil player)) then {code} but got message "inil: type object, expected string, code" =/ Share this post Link to post Share on other sites
Bad Pilot 0 Posted July 12, 2009 change "!isnil player" to "isPlayer" maybe? Share this post Link to post Share on other sites
Carpaazi 0 Posted July 12, 2009 if (isServer || (isServer && isplayer)) then {code} got message: Unexpected ) xD Share this post Link to post Share on other sites
xeno 230 Posted July 12, 2009 i_am_a_server = false; i_am_a_client = false; player_initialized = false; if (isServer) then { i_am_a_server = true; if (!isDedicated) then { // either we are in SP/editor or in a hosted environment i_am_a_client = true; [] spawn { waitUntil {!isNull player}; player_initialized = true; }; }; } else { // I'm a client but the player object may not be initialized yet i_am_a_client = true; [] spawn { waitUntil {!isNull player}; player_initialized = true; }; }; Xeno Share this post Link to post Share on other sites
Carpaazi 0 Posted July 12, 2009 This goes to a init.sqf? do i replace this code from the original: X_INIT = false; X_Server = false; X_Client = false; X_JIP = false;X_SPE = false; X_MP = isMultiplayer; if (isServer) then { X_Server = true; if (!(isNull player)) then {X_Client = true;X_SPE = true;}; X_INIT = true; } else { X_Client = true; if (isNull player) then { X_JIP = true; [] spawn {waitUntil {!(isNull player)};X_INIT = true}; } else { X_INIT = true; }; }; Because if i do i can't see tasks nor notes =) Share this post Link to post Share on other sites
Impavido 0 Posted September 10, 2009 (edited) I am attempting to make a JIP.sqf, and this is both the first time I've trie to use one AND I am very fuzzy on sqf format. I have tried to adapt Xeno's example to my own needs. I have a map in which each player receives a score as the game proceeds. I would like that score to be reset to 10000 when they JIP. Will this butcher-job syntax work? i_am_a_server = false; i_am_a_client = false; player_initialized = false; if (player==General) then { Wgencash=10000; publicvariable "Wgencash"; }; }; } else { // I'm a client but the player object may not be initialized yet i_am_a_client = true; [] spawn { waitUntil {!isNull player}; player_initialized = true; }; }; if (player==WENG) then { WENGcash=10000; publicvariable "Wengcash"; }; }; } else { // I'm a client but the player object may not be initialized yet i_am_a_client = true; [] spawn { waitUntil {!isNull player}; player_initialized = true; }; }; if (player==pilot1) then { WPIL1cash=10000; publicvariable "Wpil1cash"; }; }; } else { // I'm a client but the player object may not be initialized yet i_am_a_client = true; [] spawn { waitUntil {!isNull player}; player_initialized = true; }; }; if (player==w1) then { W1cash=10000; publicvariable "W1cash"; }; }; } else { // I'm a client but the player object may not be initialized yet i_am_a_client = true; [] spawn { waitUntil {!isNull player}; player_initialized = true; }; }; Edited September 10, 2009 by Impavido Share this post Link to post Share on other sites
shuko 59 Posted September 10, 2009 JIP = (!isServer && isNull player); if (JIP) then { [] spawn { waitUntil {!isNull player}; ...do whatever needs to be done for jip... }; }; Share this post Link to post Share on other sites
Impavido 0 Posted September 10, 2009 JIP = (!isServer && isNull player); Forgive my poor SQF syntax knowledge but I want to make sure I follow this part: The above code essentially defines JIP as a variable that becomes TRUE if the client is not the server and the player slot chosen is empty. Then the following part waits until the slot is filled. Am I correct in this? Share this post Link to post Share on other sites
shuko 59 Posted September 10, 2009 Forgive my poor SQF syntax knowledge but I want to make sure I follow this part:The above code essentially defines JIP as a variable that becomes TRUE if the client is not the server and the player slot chosen is empty. Yes, it's basically: if (not server and player unit hasnt initialized yet) then jip=true else jip=false Then the following part waits until the slot is filled. Am I correct in this? Yep, it spawns (creates a new thread/process, since waiting inside init.sqf isn't always a good thing) that waits for the player unit to initialize before doing anything, that is to make sure there is an unit to exec commands for. Share this post Link to post Share on other sites
whisper 0 Posted September 10, 2009 The above code essentially defines JIP as a variable that becomes TRUE if the client is not the server and the player slot chosen is empty. The code checks that the player is Joining in Progress instead of being present at mission start, difference being that the JiP player is not yet "in game" before the initialization scripts start, whereas a player present at mission start is "in game" during initialization phase. Therefore, there's a whole moment during JiP process where the function "player" will return objNull even though init scripts are running. That's the way to detect if a player is JiP or not. Now, that have another impact : if your normal init scripts (not the ones dedicated to JiP, but the normal init.sqf and scripts spawned from there) are using at any time the function "player" (to retrieve player's name, or class, or side, for example), they will fail for JiP players because function "player" returns objNull. So you may have to wait for player to return a valid object even in your usual init scripts Share this post Link to post Share on other sites
Impavido 0 Posted September 10, 2009 Thanks for the clarification shk and whisper. ---------- Post added at 10:05 PM ---------- Previous post was at 09:51 PM ---------- Oh, and this is a minor detail evading me: JIP.sqf is run on the server automatically when a player connects? Share this post Link to post Share on other sites
whisper 0 Posted September 11, 2009 (edited) JIP.sqf is not run automatically, you have to run it yourself, from the init.sqf mainly, after having checked that the player is JiP (otherwise, you don't launch JIP.sqf ;) ) A very handy snippet by Sickboy : http://community.bistudio.com/wiki/6thSense.eu:EG#Determining_if_machine_is_Ingame_Server.2C_Ded_Server.2C_Player_or_JIP_Player. (I'd advise you to carefully read the whole page, a few times, btw ;) ) This will set a few variables which will tell if the current PC where the init.sqf is running on is a server, dedicated or not dedicated, or a client present from start or JiP, all in one :) This, in turn, means that JIP.sqf launched this way is launched only on the PC of the JiPing player! It is made mainly to fix all the annoying things that are not synchronized automatically when a player join in progress. that means 2 things mainly in arma2 : marker state changes (color, position, text, etc...) after mission start, are not synchronized, and tasks updates are not synchronized either. To execute a script on server upon player connection, use onPlayerConnected statement in the init.sqf for example. Edited September 11, 2009 by whisper Share this post Link to post Share on other sites
Benny. 15 Posted September 11, 2009 (edited) Since A2, you can use setVariable / getVariable for JIP, quite efficient, add a Function module to your mission (iniside editor) and add a initJIPCompatible.sqf at your mission root, then you can just add a waitUntil{_var = object getVariable "varName";!isNil "_var"}, it's one of the most efficient way to get a quick JIP. Quick Ex: An object or a logic is placed in editor, the variable is assigned to it. //--- A place is captured by allies. //--- Object setVariable [Variable Name, Value, Broadcasted]. //--- Server sided. myLogic setVariable["markerColor","ColorGreen",true]; initJIPcompatible.sqf is ran whenever a player connect. Player lambda join. //--- initJIPCompatible.sqf ---// //--- local to the client. _var = ""; waitUntil {_var = myLogic getVariable "markerColor";!isNil "_var"}; _marker setMarkerColorLocal _var; Edited September 11, 2009 by Benny. Share this post Link to post Share on other sites
Impavido 0 Posted September 13, 2009 should it be: onplayerconnected [] exec "JIP.sqf" or onplayerconnected "[] exec ""JIP.sqf""" Share this post Link to post Share on other sites
shuko 59 Posted September 14, 2009 onplayerconnected "[] exec ""JIP.sqf""" That one Share this post Link to post Share on other sites
.kju 3239 Posted September 14, 2009 (edited) use this :) onPlayerConnected "[] execVM 'JIP.sqf'" Edited September 14, 2009 by kju Share this post Link to post Share on other sites
shuko 59 Posted September 14, 2009 ' or "", doesn't matter. But change exec to execvm :P Share this post Link to post Share on other sites