d3nn16 3 Posted January 27, 2009 I made this script to remove any kind of dead objects : <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> if (isServer) then {    [] spawn    {        while {true} do        {           sleep 1;                     {               if (!alive _x) then               {                  _var = _x getVariable "timeleft";                  if (isNil "_var") then                  {                      if (_x isKindOf "man") then                      {                         if (isNull flag _x) then {_x setVariable ["timeleft", TIMEOUT_RMVBODY]} else {_x setVariable ["timeleft", TIMEOUT_RMVFLAGBODY]};                      }                      else                      {                         _x setVariable ["timeleft", TIMEOUT_RMVVEHICLE];                      };                  }                  else                  {                      if (_var - 1 == 0) then {deleteVehicle _x} else {_x setVariable ["timeleft", _var - 1]};                  };               };           } forEach nearestObjects [getArray (configFile >> "cfgworlds" >> worldname >> "centerposition"), ["allvehicles"], 30000];        };    }; }; If anyone knows a better way of doing this post about it. What I noticed using a dedicated server and a client on the same PC : After I start arma server for first time and play a test map with a M1030 motorcycle, when I try to get in the motorcycle there's the black out effect starting (like when you get in any vehicle) but then it stops and I am not on the motorcycle. After 47 seconds my character is moved onto the motorcycle. When I reselect the test mission and play it (without restarting server) it doesn't happen anymore. Anyone experienced something similar ? any explanations ? Share this post Link to post Share on other sites
d3nn16 3 Posted January 27, 2009 When I test the same mission without a dedicated server and as the hosting player at the start of the mission and immediately after the briefing the screen freezes for about 30 seconds and the hard disk led is lit during all this time. The same could be happening for the dedicated server and explain why I lagged 47 seconds before getting on the motorcycle. And as for the server this thing doesn't happen when reloading the mission but only after arma is restarted. Share this post Link to post Share on other sites
d3nn16 3 Posted January 27, 2009 I noticed that reducing the area for nearestObjects command from 30000 to 3000 and testing on the dedicated server reduces lag between the moment I choose to get on the motorcycle and the moment my character is moved onto it to 15 seconds against 50 seconds before. Share this post Link to post Share on other sites
i0n0s 0 Posted January 27, 2009 nearestObjects is too slow. Share this post Link to post Share on other sites
d3nn16 3 Posted January 27, 2009 I found something that still uses nearestObject command but on a reduced area. The script will use a trigger that covers whole world and for each alive unit (that is detected by the trigger) the script looks at dead objects near it at 200 meters and puts them in a DEAD_OBJ variable and in a DEAD_TIME variable puts the time to delete the object then another thread decrements each second all the time values and checks which reached 0 then deletes the corresponding object. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> if (isServer) then { [] spawn { _trig = createTrigger ["emptydetector", getArray (configFile >> "cfgworlds" >> worldname >> "centerposition")]; _trig setTriggerArea [30000, 30000, 0, false]; _trig setTriggerActivation ["any", "present", false]; _trig setTriggerStatements ["this", "", ""]; while {true} do { sleep 1; { _near_vehicles = nearestObjects [position _x, ["allvehicles"], 200]; { if (!alive _x && (DEAD_OBJ find _x) == -1) then { DEAD_OBJ = DEAD_OBJ + [_x]; if (_x isKindOf "man") then { if (isNull flag _x) then { DEAD_TIME = DEAD_TIME + [TIMEOUT_RMVBODY] } else { DEAD_TIME = DEAD_TIME + [TIMEOUT_RMVFLAGBODY]; }; } else { DEAD_TIME = DEAD_TIME + [TIMEOUT_RMVVEHICLE]; }; }; } forEach _near_vehicles; } forEach list _trig; }; }; [] spawn { while {true} do { sleep 1; _i = 0; { DEAD_TIME set [_i, (DEAD_TIME select _i) - 1]; if (DEAD_TIME select _i == 0) then { DEAD_OBJ = DEAD_OBJ - [_x]; DEAD_TIME = DEAD_TIME - [0]; deleteVehicle _x; }; _i = _i + 1; } forEach DEAD_OBJ; }; }; }; Share this post Link to post Share on other sites
.kju 3245 Posted January 27, 2009 Use killedEH instead Share this post Link to post Share on other sites
d3nn16 3 Posted January 27, 2009 I retested the EH way and now it works. A few days ago it didn't work (and now I understand why : I used a variable initialized in the init.sqf in the init line in the editor). A simple way to use EH to do this is to add : <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> this respawnVehicle [10, 0]; this addEventHandler ["killed", {_this spawn {sleep 15; deleteVehicle (_this select 0)}}] in the init line of each unit and vehicle when placing them in the editor. Doing it by script gives sth like this : <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> if (!DEDICATED_MACHINE) then { [] spawn { waitUntil {!isNull player}; player addEventHandler [ "killed", { _this spawn { if (isNull flag (_this select 0)) then {sleep TIMEOUT_RMVBODY} else {TIMEOUT_RMVFLAGBODY}; deleteVehicle (_this select 0); }; } ]; }; }; if (isServer) then { _onact = " { if (_x isKindOf "motorcycle") then {_x respawnVehicle [60, 0]}; if (_x isKindOf "man") then { _x addEventHandler [ 'killed', { _this spawn { if (isNull flag (_this select 0)) then {sleep TIMEOUT_RMVBODY} else {TIMEOUT_RMVFLAGBODY}; deleteVehicle (_this select 0); }; } ] } else { _x addEventHandler ['killed', {_this spawn {sleep TIMEOUT_RMVVEHICLE; deleteVehicle (_this select 0)}}]; }; } forEach thisList; "; _trig = createTrigger ["emptydetector", getArray (configFile >> "cfgworlds" >> worldname >> "centerposition")]; _trig setTriggerArea [30000, 30000, 0, false]; _trig setTriggerActivation ["any", "present", false]; _trig setTriggerStatements ["this", _onact, ""]; }; Share this post Link to post Share on other sites
d3nn16 3 Posted January 28, 2009 Important note : If the deleteVehicle command is executed before the vehicle / playable AI unit respawns then the vehicle / playable AI unit will not respawn. In the case a human player the dead body will not be removed. So the respawn delay must be smaller than the delay before the dead object is removed. Share this post Link to post Share on other sites
xeno 234 Posted January 28, 2009 Please be aware that the killed eventhandler gets only fired where the unit is local. For example, if you add a killed eventhandler to an empty vehicle on the server and a player is the driver of that vehicle when it gets destroyed the locality of the vehicle is no longer on the server but on the player machine. That means, the destroyed vehicle will not get deleted. Furthermore, handling vehicles with an AI crew when it gets destroyed should be different. Delete the vehicle and the crew and replace the vehicle with a new empty one (otherwise you'll see for example crew members hanging in the air which looks really ugly). Oh, and one more Your current implementation doesn't add eventhandlers to AI in vehicles. So if they jump out of a damaged vehicle and you shoot them they won't get deleted. Xeno Share this post Link to post Share on other sites
.kju 3245 Posted January 28, 2009 if you use the inbuilt vehicle respawn, where does the vehicle respawn? at its game start position? what about flying units (at mission start)? overall i think a FIFO system to handle cleanup on the server is better instead of creating a new thread for each. Share this post Link to post Share on other sites
xeno 234 Posted January 28, 2009 if you use the inbuilt vehicle respawn, where does the vehiclerespawn? You have to use markers to set a respawn position. http://community.bistudio.com/wiki/respawnVehicle Though I haven't seen many missions using it. Custom respawn handlers are more flexible. Xeno Share this post Link to post Share on other sites
.kju 3245 Posted January 28, 2009 Right. Thanks nevertheless Xeno! Share this post Link to post Share on other sites
d3nn16 3 Posted January 28, 2009 I'm going to use the solution with the nearestObject command but there is a problem : I did a test with a BMP. At start I kill the BMP then I use a hint to show me the objects around me at 100m of "man" class type. With a non dedicated server (as the hosting player): After the dead BMP is removed only one crew member is ejected (and it's not hanging in the air  ) and after some time it is removed as well. The hint shows this :  EAST 1-1-B:3 With a dedicated server (as a client player): The BMP is removed and this time 3 dead crew members eject out of it and only one crew member is removed by the script. The hint on the client side shows : 143fec00# 637881: np_soldier_crew.p3d REMOTE, 143b7000# 637880: np_soldier_crew.p3d REMOTE, EAST 1-1-B:3 REMOTE The hint on the server side shows : EAST 1-1-B:3 The body that is removed is EAST 1-1-B:3 REMOTE I suppose the 2 other crew members are not removed by the server because they are not present for it. Anyone knows why ? and is there a simple way of removing them ? The remove dead objects scripts : <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> if (isServer) then {   CLEAN_RMVBODY = 15;   CLEAN_RMVFLAGBODY = 30;   CLEAN_RMVVEHICLE = 70;   DEAD_OBJ = [];   DEAD_TIME = [];   [] spawn   {      _onact = "{if (_x isKindOf 'motorcycle') then {_x respawnVehicle [60, 0]}} forEach thisList";      _trig = createTrigger ["emptydetector", getArray (configFile >> "cfgworlds" >> worldname >> "centerposition")];      _trig setTriggerArea [30000, 30000, 0, false];      _trig setTriggerActivation ["any", "present", false];      _trig setTriggerStatements ["this", _onact, ""];           while {true} do      {        sleep 1;               {           _near_vehicles = nearestObjects [position _x, ["allvehicles"], 200];                     {             if (!alive _x && (DEAD_OBJ find _x) == -1) then             {                DEAD_OBJ = DEAD_OBJ + [_x];                               if (_x isKindOf "man") then                {                  if (isNull flag _x) then                  {                     DEAD_TIME = DEAD_TIME + [CLEAN_RMVBODY]                  }                  else                  {                     DEAD_TIME = DEAD_TIME + [CLEAN_RMVFLAGBODY];                  };                }                else                {                  DEAD_TIME = DEAD_TIME + [CLEAN_RMVVEHICLE];                };             };           } forEach _near_vehicles;        } forEach list _trig;      };   };     [] spawn   {      while {true} do      {        sleep 1;               _i = 0;        {           DEAD_TIME set [_i, (DEAD_TIME select _i) - 1];                     if (DEAD_TIME select _i == 0) then           {             DEAD_OBJ = DEAD_OBJ - [_x];             DEAD_TIME = DEAD_TIME - [0];             deleteVehicle _x;           };                     _i = _i + 1;        } forEach DEAD_OBJ;      };   }; }; I forgot to post what commands I used to see the nearestobjects : aP is the player character. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> _trig = createTrigger ["emptydetector", [0,0,0]]; _trig setTriggerArea [0, 0, 0, false]; _trig setTriggerActivation ["foxtrot", "present", true]; _trig setTriggerText "debug"; _trig setTriggerStatements ["this", "hint str [nearestObjects [player, ['man'], 100]]", ""]; _trig = createTrigger ["emptydetector", [0,0,0]]; _trig setTriggerArea [0, 0, 0, false]; _trig setTriggerActivation ["golf", "present", true]; _trig setTriggerText "debug2"; _trig setTriggerStatements ["this", "mytest = true; publicVariable 'mytest'", ""]; if (isServer) then { "mytest" addpublicvariableeventhandler { myres = str [nearestObjects [ap, ['man'], 100]]; publicVariable "myres"; }; } else { "myres" addpublicvariableeventhandler { hint myres; }; }; Share this post Link to post Share on other sites
d3nn16 3 Posted January 28, 2009 I found something interesting while testing here are the scripts i modified ("allvehicles" instead of "man") <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">      _trig = createTrigger ["emptydetector", [0,0,0]];      _trig setTriggerArea [0, 0, 0, false];      _trig setTriggerActivation ["foxtrot", "present", true];      _trig setTriggerText "debug";      _trig setTriggerStatements ["this", "hint str [nearestObjects [player, ['allvehicles'], 100]]", ""];      _trig = createTrigger ["emptydetector", [0,0,0]];      _trig setTriggerArea [0, 0, 0, false];      _trig setTriggerActivation ["golf", "present", true];      _trig setTriggerText "debug2";      _trig setTriggerStatements ["this", "mytest = true; publicVariable 'mytest'", ""];      _trig = createTrigger ["emptydetector", [0,0,0]];      _trig setTriggerArea [0, 0, 0, false];      _trig setTriggerActivation ["hotel", "present", true];      _trig setTriggerText "debug3";      _trig setTriggerStatements ["this", "{deleteVehicle _x} forEach nearestObjects [player, ['allvehicles'], 100]", ""]; if (isServer) then {   "mytest" addpublicvariableeventhandler   {      myres = str [nearestObjects [ap, ['allvehicles'], 100]];      publicVariable "myres";   }; } else {   "myres" addpublicvariableeventhandler   {      hint myres;   }; }; I start with a Javelin and get close to the bmp from behind it so it doesn't notice me. When I am at 20 meters or so I shoot it. Then I call all the time radio foxtrot (0-0-6) and I get a hint with EAST 1-1-B:1 REMOTE for 30 seconds, then I get EAST 1-1-B:2 REMOTE for the other 30 seconds, then EAST 1-1-B:3 REMOTE for 30 seconds and at last I have 140d4800# 637878: bmp2.p3d REMOTE until the BMP is removed. And after the dead BMP is removed 3 dead crew members are ejected and radio trigger foxtrot (0-0-6) shows : 13a91400# 637880: np_soldier_crew.p3d REMOTE, 14490800# 637879: np_soldier_crew.p3d REMOTE, 140cb000# 637881: np_soldier_crew.p3d REMOTE Calling radio trigger hotel to remove these dead crew members has no effect. So I set the time of vehicle removal to 20 seconds and guess what the dead crew members are deleted (body removal set to 15 seconds). I suppose the reason is that they were ejected while they didn't transform from EAST 1-1-B:1 REMOTE (I guess it means 'alive' to 13a91400# 637880: np_soldier_crew.p3d REMOTE ('dead'. Anyone can clear out this story ?  Share this post Link to post Share on other sites
xeno 234 Posted January 29, 2009 and is there a simple way of removing them ? Like I allready wrote... When the vehicle gets killed remove the vehicle and the complete crew and replace the killed vehicle with a new (destroyed) one. Something like this (getting called from a killed eventhandler attached to the vehicle): <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> _aunit = _this select 0; _type = typeOf _aunit; _direction = direction _aunit; _position = position _aunit; _velocity = velocity _aunit; {deleteVehicle _x} forEach ([_aunit] + crew _aunit); _dummyvehicle = _type createVehicle _position; _dummyvehicle setDir _direction; _dummyvehicle setPos _position; _dummyvehicle setVelocity _velocity; _dummyvehicle setFuel 0.0; _dummyvehicle setDamage 1.1; sleep 30; // whatever value you want deleteVehicle _dummyvehicle; Instead of deleting _dummyvehicle you can also add it to a FIFO routine that will delete it after some time. Works fine on a dedicated server. You can still add a check for the crew, they may jump out of the vehicle if it is only damaged. What I do is, I'm adding a killed eventhandler to all AI units and add them to a FIFO when they get killed. The same for all vehicles. But I also add (enemy) vehicles that are not locked to a second routine on the server that slowly checks if a vehicle is destroyed or not. If it is null (it might allready got deleted by the code above) the vehicle gets removed from the array that holds all vehicles that are accessible for the player. If it is destroyed it gets added to the FIFO. The problem simply is, that when a player enteres a vehicle the locality of the vehicle changes to the client. Now if the vehicle gets destroyed while the locality is still on the client side, the initial killed eventhandler doesn't get fired because it was added on the server. But with this little "trick" those vehicles will get deleted too. There may be better ways but at least it works. Xeno Share this post Link to post Share on other sites
d3nn16 3 Posted January 29, 2009 Thx _Xeno_ for your solution. Does anyone know why it is not possible to delete the crew members that are ejected when the vehicle is deleted ? Is it a bug ? I called deleteVehicle on them and it only works for 30 seconds after the vehicle was destroyed and deleted. setPos command works on them but not deleteVehicle. Share this post Link to post Share on other sites
Namikaze 0 Posted January 29, 2009 Depending on how you're referencing the units, you might have a problem if you don't delete them asap after deleting the vehicle. For example: <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> deleteVehicle driver car1; or <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> deleteVehicle unit1; car1 and unit1 are unique names for the vehicle and the unit you want to delete, respectively. If you're trying to delete the unit by referencing the vehicle, you'll have a short window of opportunity to delete the unit as the vehicle will no longer exist. You might try deleting the units before deleting the vehicle. Share this post Link to post Share on other sites
d3nn16 3 Posted January 30, 2009 The server checks all nearby objects (using nearestObjects command) at 200 meters  around alive units detected by a trigger that covers all map. These are the instructions: {{if (!alive _x) then {deleteVehicle _x}} forEach nearestObjects [position _x, ["man"], 200]} forEach (list WORLD_TRIGGER). The problem is that when a vehicle is destroyed its crew (from what I've tested with a bmp) will still be somewhat alive for 30 seconds (if I look at what hint str nearestObjects [position player ["allvehicles"], 100] shows : EAST 1-1-A:1 for 30 seconds, then EAST 1-1-A:2 for 30 seconds and EAST 1-1-A:3 for another 30 seconds then the hint shows something like this xxxxxx# 880464 bmp2.p3d and if from this moment on the client or server deletes the dead crew members using references returned by nearestObjects command (I suppose it is the same with any other type of reference) then on the client's side there will be 3 crew members "ejected" that can't be deleted using references returned by nearestObjects and on the server's side there are no cremembers "ejected". The question I'm asking is for which reason those crew members can't be deleted after that 30 seconds interval. Share this post Link to post Share on other sites
.kju 3245 Posted January 30, 2009 while i can understand that you want to understand your approach, you should really look into the better way of doing it after that. if you can delete the crew, depends if you want it and what type it is. basically you can delete AI units, as long as they no respawnable / switchable units. if they are, you need to kill them first, wait for them to respawn and remove then after that time. again most simple IMO. added killedEH to all vehicles and all inf units. handle crew inside killed vehicles by killing them via setDamage and handle the infs removal via their killedEH. if you have a respawn type mission, you may have to remember the units name via setVariable or sth. Share this post Link to post Share on other sites
d3nn16 3 Posted January 30, 2009 Q what I was looking for is a way to avoid EHs (but seems impossible to remove all dead bodies without them). I guess I'll have to find a solution using EHs. What I would like to understand (as I said before) is the reason why those dead crew members can't be removed on client side and they can on server side. So nobody knows the reason ? I forgot to say the crew members in the BMP are not respawnable / switchable (I just put a normal AI BMP on the map for testing) Share this post Link to post Share on other sites
.kju 3245 Posted January 30, 2009 why do you want to avoid EH? they are most efficient from what i know. that said you can make a FIFO system even without EH. just save all entities and check the alive status in a reasonable cycle. you did read the notes here? http://community.bistudio.com/wiki/deleteVehicle > seems impossible to remove all dead bodies without them very unlikely. you are checking for man class. maybe the engine changes their type to sth different after some time to reduce calc / memory use. Share this post Link to post Share on other sites
UNN 0 Posted January 30, 2009 Quote[/b] ]What I would like to understand (as I said before) is the reason why those dead crew members can't be removed on client side and they can on server side.So nobody knows the reason ? Because it makes sense. Why continue to sync dead infantry across server and clients. That in the majority of cases, won’t every move again? Sure there are exceptions, I ran into the same problem myself. But 90% of the time you may as well have dead bodies local to just the server. Perhaps I've misread your problem. But if you want to remove dead bodies (or crew) from a destroyed vehicle, then event handlers are fine. Can't you just flag the crew for removal and deletion before the killed event has finished? <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">This AddEventHandler ["killed",{[_x] Spawn {_Unit=(_This Select 0); _Unit SetPos [0,0,0]; WaitUntil {(Vehicle _Unit)==_Unit}; DeleteVehicle _Unit} ForEach (Crew (_This Select 0))}] Share this post Link to post Share on other sites
d3nn16 3 Posted January 30, 2009 I did some more testing and this time I placed the BMP in my group so it isn't local to the server anymore. What happened was exactly the same as before except that the server/client roles were inverted. This time as soon as I declared AIs in my group dead on the server side hint str nearestObject ... showed xxxxx# 888000 np_crew_soldier.p3d  instead of the EAST 1-1-C:4 REMOTE that it showed before declaring them dead. So it could mean that 30 seconds is the time for server to "declare" AI units dead one by one. I can also guess that as crew members (or vehicle) were/was local to me I could delete them at the same time I was declaring them dead (while they were still inside the BMP). But for some reason calling deleteVehicle on units inside a vehicle that is not local keeps the crew members that will be ejected when vehicle is deleted. I did 3 tests (where bmp is local to the client) that support this idea : In the first test I modified the removal scripts which are executed on the server while the BMP is local to the client. BMP is removed 1 second after it's destroyed. <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE"> ... if (DEAD_TIME select _i == 0) then {    DEAD_OBJ = DEAD_OBJ - [_x];    DEAD_TIME = DEAD_TIME - [0];    {_x setPos (position aP); deleteVehicle _x} forEach (crew _x);    deleteVehicle _x; }; ... As soon as I kill the BMP the server calls deleteVehicle on the crew members inside the destroyed BMP. For the client no crew members are ejected but they are for the server. If BMP is local to server this actually works (no crew members ejected at all). For the second test I deleted {_x setPos (position aP); deleteVehicle _x} forEach (crew _x); The BMP is removed 1 second after it's destroyed. What happens is that the BMP is removed before I start declaring my AI dead and after the BMP is removed the crew members are ejected and deleted normally by the script. The third test I did is to call deleteVehicle on the crew members in the BMP and then destroy the BMP. As expected they were removed for me the client where the BMP was local but the crew members were still ejected for server after the BMP was removed. Share this post Link to post Share on other sites
d3nn16 3 Posted February 1, 2009 After a few tests I found out that rspawnVehicle also removes destroyed vehicles from map. I placed 5 UAZs and 1 HMMWV (with vehicle respawn markers for both sides). After I destroy the 5 UAZs I shoot the HMMWV. When the HMMWV respawned the first UAZ I destroyed was removed. It seems it leaves 5 destroyed vehicles on map at any time from any side. But I also did a test and put 5 UAZs with AI in them (non playable AI local to server). And the same problem of dead bodies ejected after the vehicle is removed is present, body appearing on client side and not on server side. Share this post Link to post Share on other sites
UNN 0 Posted February 1, 2009 Quote[/b] ]And the same problem of dead bodies ejected after the vehicle is removed is present, body appearing on client side and not on server side. What method do you use to detect ejected bodies server side? Share this post Link to post Share on other sites