CptBBQ 10 Posted December 27, 2009 Hi there! I´m new to scripting and I tried to do something what I thought would be really easy: Have a team of AI´s spawn with me, delete it whenever I die and respawn them at my location. Also my gear is spawned by this script. All this works just fine in single player. But now when I want to host my map on a dedi, the problems start. Most of the time to many units are spawned, some of them don´t belong to my team (cannot give any orders to them) but they follow me like a shadow... I´ve read a few times that some scripts should only be executed by the server and some by clients only. In fact, throwing in a "if (isServer)..." helped, but still, the script is acting weird in multiplayer. It looks as if the timing is completely fubar. Delays are ignored and things just don´t happen in the correct order. And at least when respawning there are still to many AI´s created. Maybe some of you experienced modders can have a look at it. So here´s what I´ve got: // respawn1.sqf sleep 3; waitUntil {alive myplayer}; _unit = myplayer; removeAllWeapons _unit; _unit addWeapon "M107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addMagazine "ACE_10Rnd_127x99_T_m107"; _unit addWeapon "ACE_Glock18"; _unit addMagazine "ACE_33Rnd_9x19_G18"; _unit addMagazine "ACE_33Rnd_9x19_G18"; _unit addMagazine "ACE_33Rnd_9x19_G18"; _unit addMagazine "ACE_33Rnd_9x19_G18"; _unit addMagazine "HandGrenade_West"; _unit addMagazine "HandGrenade_West"; _unit addMagazine "HandGrenade_West"; _unit addWeapon "Binocular"; _unit addWeapon "NVGoggles"; //Team1 incl. gear is spawned at player position "spawn1" setMarkerPos getpos myplayer; deleteVehicle ai2; deleteVehicle ai3; deleteVehicle ai4; deleteVehicle ai5; deleteVehicle ai6; deleteVehicle ai7; deleteVehicle ai8; deleteVehicle ai9; deleteVehicle ai10; if (isServer) then { sleep 3; ai2 = alpha createUnit ["USMC_Soldier_HAT", getMarkerPos "spawn1", [], 10, "FORM"]; ai3 = alpha createUnit ["USMC_Soldier_HAT", getMarkerPos "spawn1", [], 10, "FORM"]; ai4 = alpha createUnit ["USMC_Soldier_HAT", getMarkerPos "spawn1", [], 10, "FORM"]; ai5 = alpha createUnit ["USMC_Soldier_Medic", getMarkerPos "spawn1", [], 10, "FORM"]; ai6 = alpha createUnit ["USMC_SoldierS_SniperH", getMarkerPos "spawn1", [], 10, "FORM"]; ai7 = alpha createUnit ["USMC_Soldier_MG", getMarkerPos "spawn1", [], 10, "FORM"]; ai8 = alpha createUnit ["USMC_SoldierM_Marksman", getMarkerPos "spawn1", [], 10, "FORM"]; ai9 = alpha createUnit ["USMC_Soldier_AR", getMarkerPos "spawn1", [], 10, "FORM"]; ai10 = alpha createUnit ["USMC_Soldier_AR", getMarkerPos "spawn1", [], 10, "FORM"]; // arm javelingunner1 _unit2 = ai2; removeAllWeapons _unit2; _unit2 addWeapon "M16A4"; _unit2 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit2 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit2 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit2 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit2 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit2 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit2 addWeapon "Javelin"; _unit2 addMagazine "Javelin"; _unit2 addWeapon "ACE_Glock18"; _unit2 addMagazine "ACE_33Rnd_9x19_G18"; _unit2 addMagazine "ACE_33Rnd_9x19_G18"; _unit2 addMagazine "ACE_33Rnd_9x19_G18"; _unit2 addMagazine "ACE_33Rnd_9x19_G18"; _unit2 addMagazine "HandGrenade_West"; _unit2 addMagazine "HandGrenade_West"; _unit2 addMagazine "HandGrenade_West"; _unit2 addMagazine "HandGrenade_West"; _unit2 addWeapon "Binocular"; _unit2 addWeapon "NVGoggles"; // arm javelingunner2 _unit3 = ai3; removeAllWeapons _unit3; _unit3 addWeapon "M16A4"; _unit3 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit3 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit3 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit3 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit3 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit3 addMagazine "ACE_30Rnd_556x45_T_Stanag"; _unit3 addWeapon "Javelin"; _unit3 addMagazine "Javelin"; _unit3 addWeapon "ACE_Glock18"; _unit3 addMagazine "ACE_33Rnd_9x19_G18"; _unit3 addMagazine "ACE_33Rnd_9x19_G18"; _unit3 addMagazine "ACE_33Rnd_9x19_G18"; _unit3 addMagazine "ACE_33Rnd_9x19_G18"; _unit3 addMagazine "HandGrenade_West"; _unit3 addMagazine "HandGrenade_West"; _unit3 addMagazine "HandGrenade_West"; _unit3 addMagazine "HandGrenade_West"; _unit3 addWeapon "Binocular"; _unit3 addWeapon "NVGoggles"; // same with ai4 to ai10 }; exit; // init.sqs: execVM "respawn1.sqf"; //for initial gear and ai alpha = group myplayer; And a trigger: Condition: (!alive myplayer) On act.: myplayer exec "respawn1.sqf"; Also, there is a second player using an identical script called respawn2.sqf, only with different unit names and gear. Any advice would be appreciated. Thanks in advance! Cheers, Bbq. Share this post Link to post Share on other sites
Reimann 10 Posted December 27, 2009 Call it from a 'killed' event handler, rather than a trigger: if ( isNil{player getVariable "mk_killedEHadded"} ) then { player addEventHandler ["killed", { [] spawn { waitUntil { alive player }; execVM "script.sqf"; }; }]; player setVariable ["mk_killedEHadded", true]; }; Share this post Link to post Share on other sites
McArcher 0 Posted December 27, 2009 (edited) CptBBQ, for me, actually, arma's "local/global" scripts is the biggest pain when making a mission. If not that, I would have done all the scripts, I am making now, long ago. If Reimann didn't help me some time ago with this "onPlayerRespawn" scipt and many other people that I ask in the forum with other scripts, I wouldn't do any progress in my mission :) I wish, arma was simplier... and in BIS wiki there's only a piece of all information and only few examples... btw, I started learning arma's scripting a few days ago, so I am unexperienced like you =) so, let's hope we will know everything about arma's scripting soon :) Edited December 27, 2009 by McArcher Share this post Link to post Share on other sites
Reimann 10 Posted December 27, 2009 McArcher, I think you're biggest problem has been confusing 'server' with 'all clients'. That's the impression I've been getting, anyway. Running local commands on server will not show for anyone. For connecting players, use onPlayerConnected and refresh local commands (keep them in a handy script). When using variables, make sure to broadcast the change with publicVariable "myVar". So when myVar changes, run publicVariable "myVar" to make public what the variable has become. So if you make a vehicle (global), you do it on server. But if you name it you have to make it public (publicVariable "varName"). It gets confusing when some scripts work without making it public but others don't, so can throw off your searching for the answer. But this isn't much to do with CptBBQ's locality issues. It may well help someone though, as the biki and most help is geared toward SP or non-JIP co-op. And as McArcher mentioned me in relation to that script, I must reference mikey, in whose breifing I first saw it. It is in hundreds of missions now, but I didn't write it myself. Share this post Link to post Share on other sites
McArcher 0 Posted December 27, 2009 then, mikey is a great guy :) :pc: (i have been asking for this respawn script and nobody gave right answer) Share this post Link to post Share on other sites
CptBBQ 10 Posted December 27, 2009 Thanks for the kind replies =) I already feared things wouldn´t stay that simple...^^ So, I have a few questions about that 'Event Handler' thing... - well, first of all where would I add it? ;) - I guess, I´ll have to replace 'player' with 'myplayer' in this case? - will my script then behave as nicely as it does in single player? ^^ Luckily I won´t be scripting for more than two players, so JIP won´t be an issue. Hope that makes things a little easier. Thanks again! Cheers, Bbq. Share this post Link to post Share on other sites
Reimann 10 Posted December 27, 2009 'player' is a 'reserved' variable for the human controlled unit in Arma. So it's fine as is (MP-compatible). Though it may be easier to use the player varName unless you want to learn about 'if == var' or 'switch' later on (which you may need to anyway, depending on your plans). Share this post Link to post Share on other sites
shuko 59 Posted December 27, 2009 Couple of things to remember about player variable in MP is that 1) it refers to the unit which that client is controlling, thus it will be different unit for different players 2) player is always null in dedicated server (for example triggers with player in the condition will never go off etc) Share this post Link to post Share on other sites
CptBBQ 10 Posted December 27, 2009 (edited) hmmm, as my scripts work right now, every player calls his own respawn script (i.e. respawn1.sqf and respawn2.sqf). So I think I´ll have to use the player names and make one eventhandler for each player. So I´ve deleted the trigger and now call this .sqf from the init.sqs (also I removed the if (isServer) line from my script): if ( isNil{myplayer getVariable "mk_killedEHadded"} ) then { myplayer addEventHandler ["killed", { [] spawn { waitUntil { alive myplayer }; execVM "respawn1.sqf"; }; }]; myplayer setVariable ["mk_killedEHadded", true]; }; Wich again works fine when hosted locally. On the dedi the units aren´t deleted, so I get 9 new Ai´s but still have the old ones in my team after respawn. I think if I can get around this everything would work. Thanks for your help so far. And yes, I would love to learn about those other things you mentioned, but on another occasion. I have a feeling that I´ll stay for a while ;) Edited December 27, 2009 by CptBBQ Share this post Link to post Share on other sites
McArcher 0 Posted December 27, 2009 (edited) I have a problem again... not to flood with new topics, let me write here... how can I make inventory of a crate JIP compatible. The script, that puts ammo in it is run on all clients and they see contents, but... 1. if someone takes someting from that crate, will other clients see that that thing disappeared from crate? (i don't have two armas to test it) 2. how to make JIP players see current (up to date) inventory of a crate ? how to syncronize it? Edited December 28, 2009 by McArcher Share this post Link to post Share on other sites
CptBBQ 10 Posted December 29, 2009 * bump * Come on guys, this can´t be to hard, can it? Reimann´s event handler works, but the "deletevehicle" part of my script isn´t executed. What could be the reason for this? How could one fix this? Please help. Thanks in advance, Bbq. Share this post Link to post Share on other sites
CptBBQ 10 Posted December 29, 2009 Ok, I figured out the problem is that respawn1.sqf is called once via init.sqf. When I skip it no errors occour but I start without my gear or my team. So I´d have to respawn once on the beginning of a game. What would be the right way to trigger the function once at gamestart without causing troubles in multiplayer? Please help =) Share this post Link to post Share on other sites
snkman 351 Posted December 30, 2009 Check if a Global variable already was created. If (isNil "My_Global_Variable") then { My_Global_Variable = True; // Do what ever you want here this will be executed once only. ( In multiplayer this will be executed once by the server and once by the player ) }; Share this post Link to post Share on other sites
CptBBQ 10 Posted December 30, 2009 (edited) ahh, I see. Reimann used that line on the event handler too. I guess it also only has to be added once. Im only starting to understand this stuff, so thank you. Unfortunately I have to correct my last post: the script is executed correctly, but only for player1. There also is a player2 and I made sure the scripts are identical exept for unit names and variables of course. But he is still spawning loads of unsolicited AI´s at respawn. Any ideas how this can be? Cheers, Bbq. Edited December 30, 2009 by CptBBQ Share this post Link to post Share on other sites
CptBBQ 10 Posted December 30, 2009 (edited) Alright, fixed it so far. It was just my stupidity getting in my way ^^ @SNKMAN: if I wanted it to be executed by the server only, could I just add this at the top? if (!isServer) exitWith {}; EDIT: I just tried and it dind´t work. But how would I ensure, that a script is executed once and only once? And if thats not possible, how else would one spawn team members at the beginning of a multiplayer game in an orderly manner? Edited December 30, 2009 by CptBBQ Share this post Link to post Share on other sites
CptBBQ 10 Posted January 1, 2010 sorry for the triple post... but this has become a general problem for me. When scripting for multiplayer (dedicated server), creating AI´s and vehicles is a pain in the a##. Most of the time, I get more units then ordered... Event handlers seem to do the job, but I doubt there´s one EH for every situation... For example, I need to spawn friendly AI and player gear at gamestart. And I need to spawn enemy AI when a certain trigger area is reached by blufor. How do you guys get around such issues? Are there any existing threads about this I´ve missed searching the forum (which I did quite a lot)? Can someone refer me to any example scripts (scripted for multiplayer) that achieve the things I´ve mentioned above? Is there a complete list of event handlers or is there an EH-Addon that could help? I know, thats a lot of questions.. but I´d be happy to get an answer for any one of them. Please, help me to help myself ;) Cheers, CptBBQ. Share this post Link to post Share on other sites
shuko 59 Posted January 1, 2010 Whenever you use createunit/vehicle, do it in one machine only. Simplest is to do it in server only. So, use the isserver check. Share this post Link to post Share on other sites
CptBBQ 10 Posted January 1, 2010 well, that is actually one of the first things I´ve tried. I tried "if (!isServer) exitWith {}" and "if (isServer) then { ...myscript}". In some cases it had no effect, in others parts of the script weren´t executed at all while even the "extra spawns" continued. Thats when I came here ;) So, what am I doing wrong? Share this post Link to post Share on other sites
shuko 59 Posted January 1, 2010 Well, its quite simple: if (isserver) then { "USMC_Soldier" createUnit [getpos someObject, groupToWhichItJoins]; }; Share this post Link to post Share on other sites
CptBBQ 10 Posted January 1, 2010 (edited) I´ve got this if (isServer) then { Grp1 = Creategroup EAST; _Leader="RU_Soldier" createUnit [getMarkerPos "Marker1", Grp1, "Grp1=this", 1, "Sergeant"]; _Unit2="RU_Soldier" createUnit [getMarkerPos "Marker1", Grp1, "", 1, "Corporal"]; _Unit3="RU_Soldier" createUnit [getMarkerPos "Marker1", Grp1, "", 1, "Corporal"]; _Unit4="RU_Soldier" createUnit [getMarkerPos "Marker1", Grp1, "", 1, "Corporal"]; _Unit5="RU_Soldier" createUnit [getMarkerPos "Marker1", Grp1, "", 1, "Corporal"]; _Unit6="RU_Soldier" createUnit [getMarkerPos "Marker1", Grp1, "", 1, "Corporal"]; _Unit7="RU_Soldier" createUnit [getMarkerPos "Marker1", Grp1, "", 1, "Corporal"]; exit; }; Called by a trigger (which is placed in the editor). Strangely, resulting in 13 (if I haven´t miscounted) enemy AI´s spawning at Marker1... EDIT: in case it matters... the trigger fires on BluFor, present, once. On Act.: [] exec "opfor1.sqf" Edited January 1, 2010 by CptBBQ Share this post Link to post Share on other sites
Reimann 10 Posted January 1, 2010 It's fine. I tried it. Check the rest of the mission. Some things about .sqf: http://community.bistudio.com/wiki/exit http://community.bistudio.com/wiki/Category:Scripting_Topics Share this post Link to post Share on other sites
shuko 59 Posted January 1, 2010 exit doesnt work, nor is it needed in sqf. You execute sqf script with execvm not exec. Share this post Link to post Share on other sites
CptBBQ 10 Posted January 2, 2010 @Reimann: Did you host it on a dedicated server? Because for me it work´s fine hosted locally but not on a dedi. I just made a test where I placed only the trigger and the marker on the map (and me as a player). When I enter the trigger area exactly 13 enemies are created (note that the script only calls for 7). @shk: when I try to enter "execVM" in the OnAct line of a trigger the editor won't let me close it. It says "Type Script, expected Nothing". I found [] exec "script.sqf" to be the only working syntax (within the editor). Besides, the script obviously gets called. This is starting to get frustrating... I really have no idea what I´m doing wrong, or what else to try :( Share this post Link to post Share on other sites
Murklor 10 Posted January 2, 2010 try nul = [] execVM "script.sqf" (assuming you have no return variable) Share this post Link to post Share on other sites
CptBBQ 10 Posted January 2, 2010 Wohooo! It works :bounce3: Thanks Murklor. Just out of curiosity: what does "nul = " do? ;) Share this post Link to post Share on other sites