Jump to content
Sign in to follow this  
celery

CLY Remove Dead script

Recommended Posts

A simple serverside script for cleaning up the mess. You can set the removal time for bodies and vehicles, and prevent either type from being removed with the value 0.

Just put [60,120] execVM "cly_removedead.sqf" in your init script and corpses will vanish after one minute and vehicle wrecks after two. If you want to exclude an individual unit or vehicle from this script, give it the good old this setVariable ["CLY_removedead",false,true]. If you want to remove it immediately upon death through this script, use this setVariable ["CLY_removedead",true,true].

An option to prevent the removal of units with any or specific gear has been added, instructions in script.

cly_removedead.sqf

/*
CLY Remove Dead by Celery
Removes dead units and vehicles from the battlefield.
Version 2011.10.28

The script is less functional in plain Arma 2 because it lacks the allDead command. In plain Arma 2 the script...
- is probably a little heavier
- doesn't remove vehicles or animals
- lacks the hideBody transition due to its bugged nature in Arma 2 Free

Execute in init script:
[60,0,true] execVM "cly_removedead.sqf";
[wait time for men,wait time for vehicles,remove units with gear (optional, default true)] execVM "cly_removedead.sqf";
A wait time of 0 prevents that type from being removed.
Prevent an individual unit from being removed:  this setVariable ["CLY_removedead",false,true]
Remove an individual unit immediately upon death:  this setVariable ["CLY_removedead",true,true]

Use the CLY_ignoregear array to define gear classnames that don't prevent a unit's removal when only gearless bodies are removed.
Alternatively, use CLY_keepgear to define gear that prevents removal when geared unit removal is enabled.
Remember correct upper and lower case in classnames or it won't work! Check config browsers if not sure.
*/

if (!isServer) exitWith {};

CLY_ignoregear=["ItemRadio","ItemCompass","ItemWatch","ItemMap","ItemGPS"];
CLY_keepgear=[];
CLY_noremovegear=[];
_oa=isClass (configFile/"CfgPatches"/"CA_E");

_manwait=_this select 0;
_vehiclewait=if (count _this>1) then {_this select 1} else {_manwait};
CLY_removegeared=if (count _this>2) then {_this select 2} else {true};
CLY_removedeadpending=[];
CLY_dontremovedead=[];
CLY_dontremovedeadremove=[];
publicVariable "CLY_dontremovedeadremove";

//Spawnable script
_removedead={
_unit=_this select 0;
_wait=_this select 1;
sleep _wait;
waitUntil {isNull flag _unit};
_gear=if (_unit isKindOf "Man") then {(magazines _unit+weapons _unit)-CLY_ignoregear} else {[]};
if (isNull _unit or _unit in CLY_dontremovedead or (CLY_removegeared and {_x in CLY_keepgear} count _gear>0) or (!CLY_removegeared and count _gear>0)) exitWith {
	CLY_removedeadpending=CLY_removedeadpending-[_unit];
};
if (_unit isKindOf "Man" and isClass (configFile/"CfgPatches"/"CA_E")) then {
	hideBody _unit;
	_removetime=time+8;
	while {getPos _unit select 2<0.2 and time<_removetime} do {sleep 0.1};
};
CLY_removedeadpending=CLY_removedeadpending-[_unit];
deleteVehicle _unit;
};

//Loop
_allunits=[];
_alldead=[];
while {true} do {
if (!_oa) then {_allunits=allUnits};
sleep 1;
if (!_oa) then {
	{if (!alive _x) then {_alldead set [count _alldead,_x]}} forEach _allunits;
	{if (isNull _x) then {_alldead=_alldead-[_x]}} forEach _alldead;
} else {_alldead=allDead};
{
	if (isNil {_x getVariable "CLY_removedead"}) then {
		if !(_x in CLY_removedeadpending) then {
			_wait=if (_x isKindOf "Man") then {_manwait} else {_vehiclewait};
			_gear=if (_x isKindOf "Man") then {(magazines _x+weapons _x)-CLY_ignoregear} else {[]};
			if (_wait>0 and ((CLY_removegeared and {_x in CLY_keepgear} count _gear==0) or (!CLY_removegeared and count _gear==0))) then {
				[_x,_wait] spawn _removedead;
				CLY_removedeadpending set [count CLY_removedeadpending,_x];
			};
		};
	} else {
		if (_x getVariable "CLY_removedead") then {
			if (vehicle _x==_x) then {
				CLY_removedeadpending set [count CLY_removedeadpending,_x];
				[_x,0] spawn _removedead;
				_x setVariable ["CLY_removedead",nil];
			};
		} else {
			CLY_dontremovedead set [count CLY_dontremovedead,_x];
			_x setVariable ["CLY_removedead",nil];
		};
	};
} forEach _alldead-CLY_dontremovedead;
if (count CLY_dontremovedeadremove>0) then {
	CLY_dontremovedead=CLY_dontremovedead-CLY_dontremovedeadremove;
	CLY_dontremovedeadremove=[];
	publicVariable "CLY_dontremovedeadremove";
};
};

Edited by Celery

Share this post


Link to post
Share on other sites

Updated the script to wait until unit has no flag.

Share this post


Link to post
Share on other sites

Hey Celery, question for you for the script, when the bodies are removed, do they just delete, or do they do that

action like when you hide a body a slow sinking into the ground?

I have a cleaner script i already run but the bodies just delete, and dont have that sinking inground look to them,

like it really matters but just really wondering why the bodies dlete versus sink and then delete, is there a difference in coding?

Share this post


Link to post
Share on other sites

The script deletes "Man" class units that includes animals by sinking them first unless they're far from the actual ground, preventing sinking to a lower floor in buildings.

It's in the if (getPosATL _unit select 2<1.5 and _unit isKindOf "Man") then {hideBody _unit;sleep 6} part.

Share this post


Link to post
Share on other sites

Thanks Celery for this script, tested it out and works like a charm, I like the sinking in the ground part to when you catch a body being deleted.

Was wondering is there another way to call the script like maybe an area trigger that anything killed inside the area of the trigger the script then gets called?

Share this post


Link to post
Share on other sites
Was wondering is there another way to call the script like maybe an area trigger that anything killed inside the area of the trigger the script then gets called?

Well, you could make a trigger and add a check in the script whether the unit is inside it, or change allDead to list triggername and add an alive check.

Share this post


Link to post
Share on other sites

Sounds like it could work. So for the trigger what would I put would be this:

from the end of the script:

forEach list dead

dead is the (list triggername)

and the alive check I do like this:

!alive name

name is the name of the trigger to be checked?

edit

I cant get it to work i put a trigger in the mission in the activation line I have !alive dead

then I have another trigger that has a large radius and have it set to anybody present, repeatedly, and then the name of the trigger is dead.

in the script at the end I changed forEach allDead to forEach list dead

I take it something is wrong somewhere, your thoughts.

Edited by Gnter Severloh

Share this post


Link to post
Share on other sites

Actually it might be better if you just place an invisible H or logic because triggers are bad at detecting dead people.

if (isNil {_x getVariable "cly_removedead"}) -> if (isNil {_x getVariable "cly_removedead"} and _x distance deadcenter<100)

Adjust the distance limit according to how far from the object you want bodies to vanish.

Share this post


Link to post
Share on other sites

Oh ok, so if I put an game logic down and then put

if (isNil {_x getVariable "cly_removedead"} and _x distance deadcenter<100)

in its init line that would do it, and the number 100 for example is that a radius around the logic?

edit

if i did this i get a "local variable in global space" message

Edited by Gnter Severloh

Share this post


Link to post
Share on other sites
Oh ok, so if I put an game logic down and then put

if (isNil {_x getVariable "cly_removedead"} and _x distance deadcenter<100)

in its init line that would do it, and the number 100 for example is that a radius around the logic?

edit

if i did this i get a "local variable in global space" message

No, I meant you to replace the first segment with the second in the script, and name the logic deadcenter.

Share this post


Link to post
Share on other sites

Ok,

This is what i got:

script:

?!isServer:exit
_manwait=_this select 0
_vehiclewait=_this select 1
?isNil "_vehiclewait":_vehiclewait=_manwait

#loop
~1
if (isNil {_x getVariable "cly_removedead"} and _x distance deadcenter<1000) then {_wait=_manwait;if !(_x isKindOf "Man") then {_wait=_vehiclewait};if (_wait>0) then {_x setVariable ["cly_removedead",true,false];[_x,_wait] spawn {_unit=_this select 0;sleep (_this select 1);waitUntil {isNull flag _unit};if (getPosATL _unit select 2<1.5 and _unit isKindOf "Man") then {hideBody _unit;sleep 6};deleteVehicle _unit}}}} forEach allDead
goto "loop"

i have a game logic its a location logic with the name deadcenter in the center of the mission i set it to a 1000

and the script in the mission and that it.

bodies dont delete though and i played the mission for about 5 min, am i missing something somewhere?

Share this post


Link to post
Share on other sites

I tried it myself in the editor and it should work if the script has been executed properly. I'm not sure what the problem could be.

Share this post


Link to post
Share on other sites

Dont know, I have the script in the mission folder, but im not running an init script, and then i have the game logic name deadcenter

and I changed the script like u pointed out but the bodies dont delete. what i do is go in game I respawned, which leaved my body and i watch it and it dont dissapeer.

how is the script executed in this method with a gamelogic, as I am not using the init script to start the main script?

Share this post


Link to post
Share on other sites

I hope you're executing the removal script somewhere else if you're not using an init script to do it. You can see whether the script works by placing a dead unit somewhere, no need to go online.

Share this post


Link to post
Share on other sites

no im not using an init script, that was the point, thats why i asked about the trigger before. Im testing the mission I built on a mp hosted game,

I build all my missions in mp as i have friends I play with regularly and I have a gameserver.

its just a small mission on the desert map with an enemy squad and a couple of vehicles, no objective, just shoot em and see if the bodies dissapear.

script works np with an init script, but i wanted to not have an init script if possible thats

why i asked about the trigger, and its the same mission I used the script initally on.

Edited by Gnter Severloh

Share this post


Link to post
Share on other sites

Make a trigger with condition true and On act: [30,0] exec "cly_removedead.sqs"

Share this post


Link to post
Share on other sites

Ok, will give it a go, be right back after the test.

---------- Post added at 07:35 PM ---------- Previous post was at 07:26 PM ----------

It works!

question so how do i get the vehicles to delete?

and

in the code i know 30 is the time as in 30 sec what is the 2nd number:[30,0]

2nd number is for the vehicles I would presume?

Ok was playing around with it, and got it to work 2nd number if you put like 30 like this [30,30] exec "cly_removedead.sqs"

removes the vehicles too, well that solves it then.

I appreciate your patience and help, and your great script, I will be using this for now on!

Edited by Gnter Severloh

Share this post


Link to post
Share on other sites

Oh dude, you spend 1,5 hours trying to find a right code snippet to delete dead bodies, then you stumble upon Celery's signature... :rolleyes:

This is just perfect, thanks a lot! :286:

Btw. I love your simple scripts! They are what most of people need: SIMPLE, without lots of fancy pancy stuff! :) Thanks a lot, man, keep it up!

Edited by Undeceived

Share this post


Link to post
Share on other sites

Script updated

Removal will no longer fire for units inside a vehicle. Also expanded functionality of the "CLY_removedead" variable as explained in the first post.

Edited by Celery

Share this post


Link to post
Share on other sites

Script updated

Fixed prevention of removal. The engine's removal of set variables from dead units after 30 seconds was causing the problem.

Share this post


Link to post
Share on other sites

If I put [60,120] exec "cly_removedead.sqs" in my init I get an showscripterror:

"error generic code in expression"

path\init.sqf, line 12

[60,120] exec "cly_removedead.sqs"

Share this post


Link to post
Share on other sites
if ((!isServer) && (player != player)) then
{
 waitUntil {player == player};
};

//Init UPSMON scritp (must be run on all clients)
call compile preprocessFileLineNumbers "scripts\Init_UPSMON.sqf";	

[60,120] exec "cly_removedead.sqs"

//Process statements stored using setVehicleInit
processInitCommands;
//Finish world initialization before mission is launched. 
finishMissionInit;

setviewdistance 1800;

Share this post


Link to post
Share on other sites

You have no semi-colon ; after the execution of the script. Every line in SQF must be ended with a semi-colon. :)

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  

×