Jump to content
Sign in to follow this  
kremator

Heart of the action .... how could I visualise a battlefield to know the 'front'?

Recommended Posts

"Blood Drops" still needs some attention. Work in progress...

Share this post


Link to post
Share on other sites

Excellent work mate. This is just great. I love seeing these spots appearing, and when you have 300 units in a battle there are a LOT :)

Share this post


Link to post
Share on other sites

"MEMENTO MORI, or a sad story about life, death and veng... and miserable life of scripter"

As is known, each unit after death becomes civilian side. :o:

So how to determine, to which side belonged unit before?

Had only one idea: to give all units "dog tags", means setVariable with hardcoded side to retrive by getVariable from the body, and this seems to be enough for vehicles in "KIA Sparks" (script works) but...

...after some tests with "Blood Drops" I noticed, that units of proud names such as "O 1-1-A:1" and similar shortly after death remain only as pitiful remnants kind of "1e5a6900# 17507: soldier_light.p3d". :o: :o:

In this moment value stored by setVariable seems to be gone... :o: :o: :o:

Ergo there is no known to me method of retrieving initial side of dead unit from its body... :don7:

So what to do with side filter in "Blood Drops"? I see five possibilities:

1. To sift units of chosen side at the beginning and to store them in an separate array. But this is bad idea, because then all spawned later units will be ignored;

2. To change sides with factions (filtering by faction, not by side). But this is bad idea, because then will be excluded non-generic factions (from unofficial addons);

3. To count damage of only wounded, and ignore dead;

4. To count wounded of chosen side and all dead, regardless of side;

5. To use procedure described by me yesterday, and to make, that every just spawned unit will be somehow added to array of counted by script units, if is of chosen side - but here method is dependent of used spawning script (code must be added to the spawner, not to the counter).

Last one combined with first looks best for me, but if this should be universal visualiser, then 4th option becomes most promising.

Share this post


Link to post
Share on other sites

Does it matter who dies ? A death is a death, and needs to be investigated. The idea is to find the heart of the action, so from my point of view number 4 is the winner mate.

Share this post


Link to post
Share on other sites

There is also sixth option: bodies will be counted as long, as they not turn into ".p3d" remnants (about 20-30 sec. ?) here is same demo as above with rewritten in a such way "Blood Drops":

BD&KIASdemo

and here is with option 4:

BD&KIASdemoB

(more blood and more long lasting spots)

Note: users of OA 1.57 and above will probably (I can't check) see slightly better effect, because script utilizes for "blood cleaning" additional loop with AllDead command, introduced in OA 1.57.

Share this post


Link to post
Share on other sites

Man ... you are a coding machine !

Thanks ... testing now.

Share this post


Link to post
Share on other sites

Awesome idea and script, more toys for missions :)

so the big red markers signal a death? small orange ones injury?

The only issue i have is it kills a respawn script from demonized - SP_respawn.sqf:

/*
Single Player Respawn v1.3
for player and AI.

by Demonized.

Script collects name, custom loadouts, vanilla backpacks with content, and optional respawn markers for player or AI, pluss much more.
and then respawns unit or player as desired, look below for more info.

1: place a marker named SPR_respawn in editor, this is default respawn point if the optionals is not used.

2: place in unit initline: extra options are described below. this is used when placed directly in unit init line, or replace it with unitname.
_null = ["SPR_start",this] execVM "SP_respawn.sqf";

3: save this file as SP_respawn.sqf and place in your mission folder.

DONE!

optional:
* all optionals can be place in after "SPR_start",this in any order or place, as long as its after "SPR_start",this/unitname,place here.
* they can all be randomly placed, no order needed, exept for the 2 first "SPR_start",this/unitname, they can also be combined in any way.
* ALL THE OPTIONS HAVE SPR_ IN FRONT OF THEM, TO MAKE SURE THAT THE OPTIONS ARE NOT CONFUSED WITH OPTIONAL MARKER OPTIONS, SEVERAL CAN BE MANUALLY SET BELOW THIS INFO.

	* use "SPR_forall" in init line after "SPR_start",this/unitname to run the script for all iunits in group with same parameters.
	_null = ["SPR_start",this,"SPR_forall"] execVM "SP_respawn.sqf";  // all in group will respawn.
	_null = ["SPR_start",this,"SPR_forall","SPR_lives",15] execVM "SP_respawn.sqf";  // all in group will respawn and have 15 lives/respawns total available for unit.

	* set amount of lives for this specific unit only, default is not used, 0 is unlimited. add "SPR_lives",x after this where x is amount of lives total.
	_null = ["SPR_start",this,"SPR_lives",15] execVM "SP_respawn.sqf";  // 15 lives/respawns total available for unit.

	* set respawn timer for this specific unit only. add "SPR_timer",x after this, where x is respawn time in seconds.
	_null = ["SPR_start",this,"SPR_timer",15] execVM "SP_respawn.sqf";  // 15 seconds until respawns for this unit.

	* set delete timer for this specific unit only, 0 is never. add "SPR_delete",x after this, where x is delete time in seconds after death.
	_null = ["SPR_start",this,"SPR_delete",15] execVM "SP_respawn.sqf";  // 15 seconds until delete for this unit after death.

	* another marker or multiple random markers to respawn at. add any amount of "markername" after this somewhere, default marker will not be used if this.
	_null = ["SPR_start",this,"west_marker"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"east_marker1","east_marker2"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"someMarker","someothermarker"] execVM "SP_respawn.sqf";

	* instead of using markers to respawn at, use position unit is starting the script at and direction set then. add "SPR_pos" after this.
	_null = ["SPR_start",this,"SPR_pos"] execVM "SP_respawn.sqf";

	* custom loadouts with respawn. add "SPR_load" after this somewhere.
	_null = ["SPR_start",this,"SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"someMarker","SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load","someMarker","someothermarker"] execVM "SP_respawn.sqf";

	* add init for the specific unit. add array with init inside after this as shown below. important, use ""double"" or 'single' inside the outer set of "qoutes"
	_null = ["SPR_start",this,["this allowDammage false"]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["this allowDammage false"],"SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["_null = this execVM ""scriptname.sqf"""]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load",["_null = this execVM 'scriptname.sqf'"],"somemarker","anothermarker"] execVM "SP_respawn.sqf";

	* group respawn. add "SPR_group" after this. Ai will only resapwn once whole group is dead. and group will respawn together at same marker if using random markers.
	_null = ["SPR_start",this,"SPR_group"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load","SPR_group"] execVM "SP_respawn.sqf";

	* group will resume waypoints from waypoint nr 1 upon respawn. add "SPR_wp" after this same effect as "SPR_group" option, but with restart of the initial waypoints..
	_null = ["SPR_start",this,"SPR_wp"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"vehicle","SPR_wp"] execVM "SP_respawn.sqf";

	* group delete, delete units after timer after all units in group is dead. add "SPR_groupdelete" after this.
	_null = ["SPR_start",this,"SPR_groupdelete"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load","SPR_groupdelete"] execVM "SP_respawn.sqf";

	* player switch to next alive unit in group. add "SPR_switch" after this, once all is dead in group including player, whole group will respawn same as with "SPR_group" option.
	_null = ["SPR_start",this,"SPR_switch"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_switch","SPR_load"] execVM "SP_respawn.sqf";

	* add init for the specific unit. add array with init inside after this as shown below. important, use ""double"" or 'single' inside the outer set of "qoutes"
	_null = ["SPR_start",this,["this allowDammage false"]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["this allowDammage false"],"SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["_null = this execVM ""scriptname.sqf"""]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_wp","vehicle",["_null = this execVM 'scriptname.sqf'"],"somemarker","anothermarker"] execVM "SP_respawn.sqf";

	not yet implemented.
	* vehicle respawn. AI or player will respawn with same vehicle and same crew they died in. add "vehicle" after this.
	_null = ["SPR_start",this,"vehicle"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_group","vehicle"] execVM "SP_respawn.sqf";


save this as SP_respawn.sqf
*/


_timer = 10;  			// timer until respawn, default is 10 seconds.
_lives = 4;  			// total amount of lives / number of respawns a unit has. 0 means unlimited.
_delete = 0;  			// timer until delete of old dead unit, 0 = never.
_deathCam = true;  		// show camera view of dying player only. true/false = on/off == camera/black screen.
_spawnPos = "SPR_respawn";  	// default respawn marker, if not the optional is used.

// these are some options that can be activated by all instead of using the various "optionals" above. true/false = on/off.

_grpDel = false;			// default false, delete dead units after x time when all in units group is dead.
_group = false;			// default false, respawn only when all in units group is dead, collective respawn.
_wp = false;			// default false, same as _group with added start on first waypoint on respawn instead of continuing on last.
_switch = false;			// default false, for player only, if player should teamswitch upon death if there is someone alive in player group.
_unLim = false;			// default false,  unlimited lives/respawns, same as setting _lives to 0.
_alwLead = false;			// default false, for player only, if player always should be team leader when teamswitcing if _switch option is enabled.

// DO NOT EDIT PAST THIS LINE //


if ("SPR_start" in _this) then {
sleep 0.1;  		// make sure unit is up and running.
_unit = _this select 1;

// if running line on all units in group.
if ("SPR_forall" in _this) then {
	_var1 = _this - ["SPR_start",_unit,"SPR_forall"];
	{
		if (_x != _unit) then {
			_var2 = ["SPR_start",_x] + _var1;
			_null = _var2 execVM "SP_respawn.sqf";
		};
	} foreach units group _unit;
};

// collect info on unit.
_side = side _unit;
_grp = group _unit;
_player = false;
if (_unit == player) then {_player = true};
if ("SPR_lives" in _this) then {
	_sel = _this find "SPR_lives";
	_lives = _this select (_sel + 1);
};
if ("SPR_timer" in _this) then {
	_sel = _this find "SPR_timer";
	_timer = _this select (_sel + 1);
};
if ("SPR_delete" in _this) then {
	_sel = _this find "SPR_delete";
	_delete = _this select (_sel + 1);
};
_startPos = [];
if ("SPR_pos" in _this) then {_startPos = [(getPos _unit),(getDir _unit)]};
if ("SPR_groupdelete" in _this) then {_grpDel = true};
if ("SPR_group" in _this) then {_group = true};
if ("SPR_wp" in _this) then {_wp = true; _group = true};
if ("SPR_switch" in _this AND _unit == player) then {_switch = true};
if (_lives == 0) then {_unLim = true};
_load = [];
if ("SPR_load" in _this) then {
	_wep = weapons _unit;
	_mag = magazines _unit;
	_load = [_wep,_mag];
	if (!isNull (unitBackpack _unit)) then {
		_bag = (typeOf (unitBackpack _unit));
		_bagW = getWeaponCargo (unitBackpack _unit);
		_bagM = getMagazineCargo (unitBackpack _unit);
		_load = _load + [_bag,_bagW,_bagM];
	};
};
_mark = [];
_init = [];
{
	if ((typeName _x) == "ARRAY") then {_init = _x};
	if ((typeName _x) == "STRING" AND !(_x in ["SPR_start","SPR_load","SPR_switch","SPR_groupdelete","SPR_pos","SPR_group","SPR_wp","SPR_lives","SPR_timer","SPR_delete","SPR_forall"])) then {_mark = _mark + [_x]};
} foreach _this;
_lead = false;
if ((leader (group _unit)) == _unit) then {_lead = true};

_unit setVariable ["DMZ_SPR_respawn", [_load,_mark,_lead,_player,_side,_grp,(_lives - 1),_unLim,_switch,_startPos,_group,_wp,_init,_timer,_delete,_alwLead], true];
_unit addEventHandler ["killed", {_null = _this execVM "SP_respawn.sqf";}];
} else {
_dead = _this select 0;
_ret = (_dead getVariable ["DMZ_SPR_respawn", ["none"]]);
_type = typeOf _dead;
_pos = getPos _dead;
_vName = vehicleVarName _dead;
_orgV = cameraView;

// if player create a unit imediatly to avoid end menu.
_fastUnit = {
	// _temp = [_side,_type,_dead] call _fastUnit;
	if (isNil ("DMZ_SPR_All_Dead_grp")) then {DMZ_SPR_All_Dead_grp = createGroup (_this select 0)};
	_temp = DMZ_SPR_All_Dead_grp createUnit [(_this select 1), (getPos (_this select 2)), [], 0, "NONE"];
	_temp allowDammage false;
	hideObject _temp;
	addSwitchableUnit _temp;
	selectPlayer _temp;

	// delete the new unit after player is in control of team unit with switch.
	_null = [_temp,(_this select 2)] spawn {
		_temp = _this select 0;
		_dead = _this select 1;
		_temp enableSimulation false;
		_temp setCaptive true;
		_temp setPos (getPos _dead);
		waitUntil {sleep 2; _temp != player};
		removeSwitchableUnit _temp;
		waitUntil {sleep 1; !(_temp in switchableUnits)};
		deleteVehicle _temp;
		waitUntil {sleep 1; isNull _temp};
		_temp = nil;
	};
	_temp
};

_load = _ret select 0;
_mark = _ret select 1;
_lead = _ret select 2;
_player = _ret select 3;
_side = _ret select 4;
_grp = _ret select 5;
_lives = _ret select 6;
_unLim = _ret select 7;
_switch = _ret select 8;
_startPos = _ret select 9;
_group = _ret select 10;
_wp = _ret select 11;
_init = _ret select 12;
_timer = _ret select 13;
_delete = _ret select 14;
_alwLead = _ret select 15;

//variable to set on respawn   [_load,_mark,_lead,_player,_side,_grp,_lives,_unLim,_switch,_startPos,_group,_wp,_init,_timer,_delete,_alwLead]

// show timer.
_showTimer = {
	//_showT = [_timer,_deathCam,_lives] spawn _showTimer;
	_timer = _this select 0;
	_type = "PLAIN";
	if (!(_this select 1)) then {_type = "BLACK FADED"};
	while {_timer != 0} do {
		_text = "";
		if ("ts" in _this) then {
			_text = format["TEAM SWITCH IN %1",_timer];
		} else {
			_text = format["RESPAWN IN %1 \n \n LIVES LEFT IS %2",_timer,((_this select 2)-1)];
		};
		cutText [_text,_type,0];
		_timer = _timer - 1;
		sleep 1;
	};
	if ("ts" in _this) then {
		titlecut ["TEAM SWITCHING NOW","black in",3];
	} else {
		titlecut ["RESPAWNING NOW","black in",3];
	};
};

// create a temp unit for player only.
if (_player) then {
	_temp = [_side,_type,_dead] call _fastUnit;
	waitUntil {alive _temp AND _temp == player};
};

_cameraFunction = {
	//_cam = [_timer,_dead,_unit,_orgV] spawn _cameraFunction;
	_timer = _this select 0;
	_dead = _this select 1;
	_unit = _this select 2;
	_orgV = _this select 3;

	if ("group" in _this) then {titlecut ["Waiting for rest of team to die - group spawn activated","PLAIN",5]};

	// internal cam movement function.
	_camMove = {
		_cam = _this select 0;
		_cam camSetTarget vehicle (_this select 1);
		_cam camSetRelPos (_this select 2);
		_cam camSetFOV (_this select 3);
		_cam camCommit (_this select 4);
		waituntil {(camCommitted _cam)};
	};

	_camTime = _timer/2;

	// camera initialisation
	_camera = "camera" camCreate getpos _dead;
	_camera cameraEffect ["internal","back"];

	_runLoop = true;
	while {_runLoop} do {
		if ("group" in _this) then {
			{if (alive _x) then {_unit = _x}} foreach units (_this select 4);
		};
		// camera look at player
		_cam = [_camera,_dead,[0.2,0.4,2],0.143,0] spawn _camMove;
		waitUntil {scriptDone _cam};

		// camera zooms out over 5 seconds
		_cam = [_camera,_dead,[0,8,3.5],0.7,_camTime] spawn _camMove;
		waitUntil {scriptDone _cam};

		// quick fade-in on internal point of view of the next unit
		_camera camSetTarget _unit;

		// set camera above new unit.
		_cam = [_camera,_unit,[0,8,3.5],0.7,0] spawn _camMove;
		waitUntil {scriptDone _cam};

		// camera zooms in over 5 seconds
		_cam = [_camera,_unit,[0.2,0.4,2],0.7,_camTime] spawn _camMove;
		waitUntil {scriptDone _cam};

		if ("group" in _this) then {
			if (player getVariable ["DMZ_SPR_respawn_group", false]) then {_runLoop = false};
		} else {
			_runLoop = false;
		};
	};

	// end camera part.
	_unit cameraEffect ["terminate","back"];

	// destroy camera.
	camDestroy _camera;

	// wait until unit is in player control then switxh camera back to org view (1st / 3rd person) on death.
	if (!("group" in _this)) then {
		_null = [_unit,_orgV] spawn {
			_unit = _this select 0;
			waitUntil {!alive _unit OR player == _unit};
			if (alive _unit) then {
				vehicle player switchCamera (_this select 1);
			};
		};
	};
};

// show the timer.
if (_player) then {
	if (_switch AND ({alive _x} count units _grp) != 0) then {
		_showT = [_timer,_deathCam,"ts"] spawn _showTimer;
	} else {
		if (!_group) then {
			_showT = [_timer,_deathCam,_lives] spawn _showTimer;
		};
	};
};

// join the dead unit to a holder group incase of switch option.
if (_switch) then {
	if (isNil ("DMZ_SPR_All_Dead_grp")) then {DMZ_SPR_All_Dead_grp = createGroup _side};
	removeSwitchableUnit _dead;
	_null = [_dead,_grp] spawn {
		_dead = _this select 0;
		waitUntil {sleep 1; ({alive _x} count units (_this select 1)) != 0 OR isNull _dead};
		if (!isNull _dead) then {[_dead] joinSilent DMZ_SPR_All_Dead_grp};
	};
};

// delete the dead unit if selected.
if (_delete != 0 OR _grpDel) then {
	_null = [_dead,_delete,_grpDel,_grp] spawn {
		if ((_this select 2)) then {
			waitUntil {({alive _x} count units (_this select 3)) == 0};
		};
		sleep (_this select 1);
		deleteVehicle (_this select 0);
	};
};

_mDir = 0;
_spawn = [];
// if default marker is selected.
if (_spawnPos != "") then {
	_spawn = getMarkerPos _spawnPos;
	_mDir = markerDir _spawnPos;
};

// if random marker/s option is used.
if ((count _mark) != 0) then {
	_spawnPos = _mark select (floor (random (count _mark)));
	_spawn = getMarkerPos _spawnPos;
	_mDir = markerDir _spawnPos;
};

if ((count _startPos) != 0) then {
	_spawn = _startPos select 0;
	_mDir = _startPos select 1;
};

if (_switch) then {
	_switchedUnit = player;
	_switchedDead = _dead;
	_switchActive = true;
	while {({alive _x} count units _grp) != 0 AND _switchActive} do {
		{
			if (alive _x) then {_switchedUnit = _x};
		} foreach units _grp;

		_showT = [_timer,_deathCam,"ts"] spawn _showTimer;
		if (_deathCam) then {
			_cam = [_timer,_switchedDead,_switchedUnit,_orgV] spawn _cameraFunction;
			waitUntil {scriptDone _cam};
			//vehicle player switchCamera _orgV;
		} else {
			sleep _timer;
		};

		if (alive _switchedUnit AND (group _switchedUnit) == _grp) then {
			addSwitchableUnit _switchedUnit;
			selectPlayer _switchedUnit;
			waitUntil {_switchedUnit == player};

			// if always leader option is selected.
			if (_alwLead) then {
				_null = _switchedUnit spawn {
					_grp = group _this;
					while {alive _this} do {
						waitUntil {sleep 1; !alive _this OR (leader _grp) != player};
						if (alive _this) then {_grp selectLeader _this};
					};
				};
			};

			// wait for player to die again before new switch if any available in group.
			waitUntil {!alive _switchedUnit};
			_orgV = cameraView;
			_null = [_switchedUnit,_grp] spawn {
				_unit = _this select 0;
				_grp = _this select 1;
				waitUntil {_unit != player};
				removeSwitchableUnit _unit;
				waitUntil {sleep 1; ({alive _x} count units _grp) != 0 OR isNull _unit};
				if (!isNull _unit) then {
					[_switchedUnit] joinSilent DMZ_SPR_All_Dead_grp;
				};
			};
			_temp = [_side,_type,_switchedUnit] call _fastUnit;
			_switchedDead = _switchedUnit;
			waitUntil {_temp == player};
		} else {
			titlecut ["TEAM MEMBER DEAD","PLAIN",3];
		};
		if (({alive _x} count units _grp) == 0) then {
			_switchActive = false;
			player setVariable ["DMZ_SPR_nomore_group", true, true];
			titlecut ["ALL UNITS IN GROUP ARE DEAD","BLACK FADED",3];
			_dead = _switchedUnit;
			if (!_group) then {sleep 3};
			if (_lives == 0 AND !_unLim) then {
				titlecut ["NO MORE LIVES \n \n END GAME","black out",3];
				sleep 3;
				player setDammage 1;
			};
		};
	};
};

// group option.
_form = "NONE";
if (_group OR _wp) then {
	if (_player) then {
		_null = _grp spawn {
			waitUntil {({alive _x} count units _this) == 0};
			player setVariable ["DMZ_SPR_respawn_group", true, true];
		};
		_cam = [_timer,_dead,_dead,_orgV,_grp,"group"] spawn _cameraFunction;
	};
	if (_player) then {
		waitUntil {sleep 1; ({alive _x} count units _grp) == 0 OR (player getVariable ["DMZ_SPR_nomore_group", false])};
	} else {
		waitUntil {sleep 1; ({alive _x} count units _grp) == 0};
	};
	if (_wp AND _lead) then {
		_null = _grp spawn {
			waitUntil {({alive _x} count units _this) != 0};
			_this setCurrentWaypoint [_this, 0];
		};
	};
	if (!_lead) then {
		waitUntil {({alive _x} count units _grp) != 0};
		if ((count _startPos) == 0) then {_form = "FORM"};
	};
};

if (!_player) then {sleep _timer};
_unit = _grp createUnit [_type, _spawn, [], 0, _form];

// set init.
if ((count _init) != 0) then {
	_unit setVehicleInit (_init select 0);
	processInitCommands;
};

if (_player) then {
	if (_timer != 0) then {
		// show timer.
		_showT = [_timer,_deathCam,_lives] spawn _showTimer;

		// if on death camera.
		if (_deathCam) then {_cam = [_timer,_dead,_unit,_orgV] spawn _cameraFunction};
	};

	addSwitchableUnit _unit;
	selectPlayer _unit;
	waitUntil {_unit == player};
	vehicle _unit switchCamera _orgV;
};

if (!_switch) then {
	if (isNil ("DMZ_SPR_All_Dead_grp")) then {DMZ_SPR_All_Dead_grp = createGroup _side};
	[_dead] joinSilent DMZ_SPR_All_Dead_grp;
	if (_dead in switchAbleUnits) then {removeSwitchableUnit _dead};
};

if (_vName != "") then {
	_rName = "DMZ_SPR_Dead_unit";
	_dead SetVehicleVarName _rName;
	_dead Call Compile Format ["%1=_This ; PublicVariable ""%1""",_rName];
	waitUntil {(vehicleVarName _dead) == _rName};
	_unit SetVehicleVarName _vName;
	_unit Call Compile Format ["%1=_This ; PublicVariable ""%1""",_vName];
};

if (_unLim) then {_lives = 1} else {_lives = _lives - 1};
if (_lives != 0) then {
	_unit setVariable ["DMZ_SPR_respawn", [_load,_mark,_lead,_player,_side,_grp,_lives,_unLim,_switch,_startPos,_group,_wp,_init,_timer,_delete,_alwLead], true];
	_idx = _unit addEventHandler ["killed", {_null = _this execVM "SP_respawn.sqf";}];
};

_unit setPos _spawn;
_unit setDir _mDir;

// if custom loadouts.
if ((count _load) != 0) then {
	_null = [_unit,_load] spawn {
		_unit = _this select 0;
		_load = _this select 1;

		waitUntil {alive _unit};
		removeAllWeapons _unit;
		{if (_unit hasWeapon _x) then {_unit removeWeapon _x}} foreach (weapons _unit);
		{_unit addMagazine _x} foreach (_load select 1);
		{_unit addweapon _x} foreach (_load select 0);
		if ((count _load) > 2) then {
			_unit addBackpack _back;
			_backPack = unitBackpack _unit;
			_bpWepArr = _load select 3;
			_bpMagArr = _load select 4;

			// clear backpack of any content.
			clearMagazineCargo _backPack;
			clearWeaponCargo _backPack;

			// add all pre selected items.
			_sel = 0;
			_bpWep = _bpWepArr select 0;
			_wepCnt = _bpWepArr select 1;
			while {_sel != (count _bpWep)} do {
				_wep = _bpWep select _sel;
				_cnt = _wepCnt select _sel;
				_backPack addWeaponCargo [_wep,_cnt];
				_sel = _sel + 1;
			};
			_sel = 0;
			_bpMag = _bpMagArr select 0;
			_magCnt = _bpMagArr select 1;
			while {_sel != (count _bpMag)} do {
				_mag = _bpMag select _sel;
				_cnt = _magCnt select _sel;
				_backPack addMagazineCargo [_mag,_cnt];
				_sel = _sel + 1;
			};
		};
		_unit selectWeapon (primaryWeapon _unit);
	};
};

//if (player in (units _grp)) then {_grp selectLeader player};
if (_lead) then {
	_grp selectLeader _unit;
	if (!_player) then {
		_pos = getPos _unit;
		_unit doMove [(_pos select 0) + 1,(_pos select 1) + 1,0];
	};
};

// add here any custom scripts to be run at unit after resapwning, if you dont want to use the init option.
// _null = _unit execVM "example_custom_script.sqf";
// _unit addAction ["Switch on generator", "activate_generator.sqs"];
};

Could there be a work around?

Share this post


Link to post
Share on other sites

Big, persistent red markings are "Blood Drops" - means area, where blood spilled and where is someone nearby to tell about this (alive unit of chosen side(s)). Their radius and intensity depends on sum of damage from units in radius of checked area (with some limits of course). Orange dots are "KIA Sparks" - apperas when someone is just died. Bigger red, but quickly disappearing dots are sparks for just destroyed vehicles.

Checked Demoznized's code, and all seems to be clear. As was probably said (?) this KIA Sparks will badly interefere with any script, that uses "Killed" EH. It just removes every cycle all "Killed" EH's from units. It is neccessary part of making KIA spawn-friendly. It is hard to talk about "workaround" for this, rather need to be fundamentally rewritten to avoid usage of "Killed" EH. There is some hope, I can try something...

Share this post


Link to post
Share on other sites
Awesome idea and script, more toys for missions :)

so the big red markers signal a death? small orange ones injury?

The only issue i have is it kills a respawn script from demonized - SP_respawn.sqf:

/*
Single Player Respawn v1.3
for player and AI.

by Demonized.

Script collects name, custom loadouts, vanilla backpacks with content, and optional respawn markers for player or AI, pluss much more.
and then respawns unit or player as desired, look below for more info.

1: place a marker named SPR_respawn in editor, this is default respawn point if the optionals is not used.

2: place in unit initline: extra options are described below. this is used when placed directly in unit init line, or replace it with unitname.
_null = ["SPR_start",this] execVM "SP_respawn.sqf";

3: save this file as SP_respawn.sqf and place in your mission folder.

DONE!

optional:
* all optionals can be place in after "SPR_start",this in any order or place, as long as its after "SPR_start",this/unitname,place here.
* they can all be randomly placed, no order needed, exept for the 2 first "SPR_start",this/unitname, they can also be combined in any way.
* ALL THE OPTIONS HAVE SPR_ IN FRONT OF THEM, TO MAKE SURE THAT THE OPTIONS ARE NOT CONFUSED WITH OPTIONAL MARKER OPTIONS, SEVERAL CAN BE MANUALLY SET BELOW THIS INFO.

	* use "SPR_forall" in init line after "SPR_start",this/unitname to run the script for all iunits in group with same parameters.
	_null = ["SPR_start",this,"SPR_forall"] execVM "SP_respawn.sqf";  // all in group will respawn.
	_null = ["SPR_start",this,"SPR_forall","SPR_lives",15] execVM "SP_respawn.sqf";  // all in group will respawn and have 15 lives/respawns total available for unit.

	* set amount of lives for this specific unit only, default is not used, 0 is unlimited. add "SPR_lives",x after this where x is amount of lives total.
	_null = ["SPR_start",this,"SPR_lives",15] execVM "SP_respawn.sqf";  // 15 lives/respawns total available for unit.

	* set respawn timer for this specific unit only. add "SPR_timer",x after this, where x is respawn time in seconds.
	_null = ["SPR_start",this,"SPR_timer",15] execVM "SP_respawn.sqf";  // 15 seconds until respawns for this unit.

	* set delete timer for this specific unit only, 0 is never. add "SPR_delete",x after this, where x is delete time in seconds after death.
	_null = ["SPR_start",this,"SPR_delete",15] execVM "SP_respawn.sqf";  // 15 seconds until delete for this unit after death.

	* another marker or multiple random markers to respawn at. add any amount of "markername" after this somewhere, default marker will not be used if this.
	_null = ["SPR_start",this,"west_marker"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"east_marker1","east_marker2"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"someMarker","someothermarker"] execVM "SP_respawn.sqf";

	* instead of using markers to respawn at, use position unit is starting the script at and direction set then. add "SPR_pos" after this.
	_null = ["SPR_start",this,"SPR_pos"] execVM "SP_respawn.sqf";

	* custom loadouts with respawn. add "SPR_load" after this somewhere.
	_null = ["SPR_start",this,"SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"someMarker","SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load","someMarker","someothermarker"] execVM "SP_respawn.sqf";

	* add init for the specific unit. add array with init inside after this as shown below. important, use ""double"" or 'single' inside the outer set of "qoutes"
	_null = ["SPR_start",this,["this allowDammage false"]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["this allowDammage false"],"SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["_null = this execVM ""scriptname.sqf"""]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load",["_null = this execVM 'scriptname.sqf'"],"somemarker","anothermarker"] execVM "SP_respawn.sqf";

	* group respawn. add "SPR_group" after this. Ai will only resapwn once whole group is dead. and group will respawn together at same marker if using random markers.
	_null = ["SPR_start",this,"SPR_group"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load","SPR_group"] execVM "SP_respawn.sqf";

	* group will resume waypoints from waypoint nr 1 upon respawn. add "SPR_wp" after this same effect as "SPR_group" option, but with restart of the initial waypoints..
	_null = ["SPR_start",this,"SPR_wp"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"vehicle","SPR_wp"] execVM "SP_respawn.sqf";

	* group delete, delete units after timer after all units in group is dead. add "SPR_groupdelete" after this.
	_null = ["SPR_start",this,"SPR_groupdelete"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_load","SPR_groupdelete"] execVM "SP_respawn.sqf";

	* player switch to next alive unit in group. add "SPR_switch" after this, once all is dead in group including player, whole group will respawn same as with "SPR_group" option.
	_null = ["SPR_start",this,"SPR_switch"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_switch","SPR_load"] execVM "SP_respawn.sqf";

	* add init for the specific unit. add array with init inside after this as shown below. important, use ""double"" or 'single' inside the outer set of "qoutes"
	_null = ["SPR_start",this,["this allowDammage false"]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["this allowDammage false"],"SPR_load"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,["_null = this execVM ""scriptname.sqf"""]] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_wp","vehicle",["_null = this execVM 'scriptname.sqf'"],"somemarker","anothermarker"] execVM "SP_respawn.sqf";

	not yet implemented.
	* vehicle respawn. AI or player will respawn with same vehicle and same crew they died in. add "vehicle" after this.
	_null = ["SPR_start",this,"vehicle"] execVM "SP_respawn.sqf";
	_null = ["SPR_start",this,"SPR_group","vehicle"] execVM "SP_respawn.sqf";


save this as SP_respawn.sqf
*/


_timer = 10;  			// timer until respawn, default is 10 seconds.
_lives = 4;  			// total amount of lives / number of respawns a unit has. 0 means unlimited.
_delete = 0;  			// timer until delete of old dead unit, 0 = never.
_deathCam = true;  		// show camera view of dying player only. true/false = on/off == camera/black screen.
_spawnPos = "SPR_respawn";  	// default respawn marker, if not the optional is used.

// these are some options that can be activated by all instead of using the various "optionals" above. true/false = on/off.

_grpDel = false;			// default false, delete dead units after x time when all in units group is dead.
_group = false;			// default false, respawn only when all in units group is dead, collective respawn.
_wp = false;			// default false, same as _group with added start on first waypoint on respawn instead of continuing on last.
_switch = false;			// default false, for player only, if player should teamswitch upon death if there is someone alive in player group.
_unLim = false;			// default false,  unlimited lives/respawns, same as setting _lives to 0.
_alwLead = false;			// default false, for player only, if player always should be team leader when teamswitcing if _switch option is enabled.

// DO NOT EDIT PAST THIS LINE //


if ("SPR_start" in _this) then {
sleep 0.1;  		// make sure unit is up and running.
_unit = _this select 1;

// if running line on all units in group.
if ("SPR_forall" in _this) then {
	_var1 = _this - ["SPR_start",_unit,"SPR_forall"];
	{
		if (_x != _unit) then {
			_var2 = ["SPR_start",_x] + _var1;
			_null = _var2 execVM "SP_respawn.sqf";
		};
	} foreach units group _unit;
};

// collect info on unit.
_side = side _unit;
_grp = group _unit;
_player = false;
if (_unit == player) then {_player = true};
if ("SPR_lives" in _this) then {
	_sel = _this find "SPR_lives";
	_lives = _this select (_sel + 1);
};
if ("SPR_timer" in _this) then {
	_sel = _this find "SPR_timer";
	_timer = _this select (_sel + 1);
};
if ("SPR_delete" in _this) then {
	_sel = _this find "SPR_delete";
	_delete = _this select (_sel + 1);
};
_startPos = [];
if ("SPR_pos" in _this) then {_startPos = [(getPos _unit),(getDir _unit)]};
if ("SPR_groupdelete" in _this) then {_grpDel = true};
if ("SPR_group" in _this) then {_group = true};
if ("SPR_wp" in _this) then {_wp = true; _group = true};
if ("SPR_switch" in _this AND _unit == player) then {_switch = true};
if (_lives == 0) then {_unLim = true};
_load = [];
if ("SPR_load" in _this) then {
	_wep = weapons _unit;
	_mag = magazines _unit;
	_load = [_wep,_mag];
	if (!isNull (unitBackpack _unit)) then {
		_bag = (typeOf (unitBackpack _unit));
		_bagW = getWeaponCargo (unitBackpack _unit);
		_bagM = getMagazineCargo (unitBackpack _unit);
		_load = _load + [_bag,_bagW,_bagM];
	};
};
_mark = [];
_init = [];
{
	if ((typeName _x) == "ARRAY") then {_init = _x};
	if ((typeName _x) == "STRING" AND !(_x in ["SPR_start","SPR_load","SPR_switch","SPR_groupdelete","SPR_pos","SPR_group","SPR_wp","SPR_lives","SPR_timer","SPR_delete","SPR_forall"])) then {_mark = _mark + [_x]};
} foreach _this;
_lead = false;
if ((leader (group _unit)) == _unit) then {_lead = true};

_unit setVariable ["DMZ_SPR_respawn", [_load,_mark,_lead,_player,_side,_grp,(_lives - 1),_unLim,_switch,_startPos,_group,_wp,_init,_timer,_delete,_alwLead], true];
_unit addEventHandler ["killed", {_null = _this execVM "SP_respawn.sqf";}];
} else {
_dead = _this select 0;
_ret = (_dead getVariable ["DMZ_SPR_respawn", ["none"]]);
_type = typeOf _dead;
_pos = getPos _dead;
_vName = vehicleVarName _dead;
_orgV = cameraView;

// if player create a unit imediatly to avoid end menu.
_fastUnit = {
	// _temp = [_side,_type,_dead] call _fastUnit;
	if (isNil ("DMZ_SPR_All_Dead_grp")) then {DMZ_SPR_All_Dead_grp = createGroup (_this select 0)};
	_temp = DMZ_SPR_All_Dead_grp createUnit [(_this select 1), (getPos (_this select 2)), [], 0, "NONE"];
	_temp allowDammage false;
	hideObject _temp;
	addSwitchableUnit _temp;
	selectPlayer _temp;

	// delete the new unit after player is in control of team unit with switch.
	_null = [_temp,(_this select 2)] spawn {
		_temp = _this select 0;
		_dead = _this select 1;
		_temp enableSimulation false;
		_temp setCaptive true;
		_temp setPos (getPos _dead);
		waitUntil {sleep 2; _temp != player};
		removeSwitchableUnit _temp;
		waitUntil {sleep 1; !(_temp in switchableUnits)};
		deleteVehicle _temp;
		waitUntil {sleep 1; isNull _temp};
		_temp = nil;
	};
	_temp
};

_load = _ret select 0;
_mark = _ret select 1;
_lead = _ret select 2;
_player = _ret select 3;
_side = _ret select 4;
_grp = _ret select 5;
_lives = _ret select 6;
_unLim = _ret select 7;
_switch = _ret select 8;
_startPos = _ret select 9;
_group = _ret select 10;
_wp = _ret select 11;
_init = _ret select 12;
_timer = _ret select 13;
_delete = _ret select 14;
_alwLead = _ret select 15;

//variable to set on respawn   [_load,_mark,_lead,_player,_side,_grp,_lives,_unLim,_switch,_startPos,_group,_wp,_init,_timer,_delete,_alwLead]

// show timer.
_showTimer = {
	//_showT = [_timer,_deathCam,_lives] spawn _showTimer;
	_timer = _this select 0;
	_type = "PLAIN";
	if (!(_this select 1)) then {_type = "BLACK FADED"};
	while {_timer != 0} do {
		_text = "";
		if ("ts" in _this) then {
			_text = format["TEAM SWITCH IN %1",_timer];
		} else {
			_text = format["RESPAWN IN %1 \n \n LIVES LEFT IS %2",_timer,((_this select 2)-1)];
		};
		cutText [_text,_type,0];
		_timer = _timer - 1;
		sleep 1;
	};
	if ("ts" in _this) then {
		titlecut ["TEAM SWITCHING NOW","black in",3];
	} else {
		titlecut ["RESPAWNING NOW","black in",3];
	};
};

// create a temp unit for player only.
if (_player) then {
	_temp = [_side,_type,_dead] call _fastUnit;
	waitUntil {alive _temp AND _temp == player};
};

_cameraFunction = {
	//_cam = [_timer,_dead,_unit,_orgV] spawn _cameraFunction;
	_timer = _this select 0;
	_dead = _this select 1;
	_unit = _this select 2;
	_orgV = _this select 3;

	if ("group" in _this) then {titlecut ["Waiting for rest of team to die - group spawn activated","PLAIN",5]};

	// internal cam movement function.
	_camMove = {
		_cam = _this select 0;
		_cam camSetTarget vehicle (_this select 1);
		_cam camSetRelPos (_this select 2);
		_cam camSetFOV (_this select 3);
		_cam camCommit (_this select 4);
		waituntil {(camCommitted _cam)};
	};

	_camTime = _timer/2;

	// camera initialisation
	_camera = "camera" camCreate getpos _dead;
	_camera cameraEffect ["internal","back"];

	_runLoop = true;
	while {_runLoop} do {
		if ("group" in _this) then {
			{if (alive _x) then {_unit = _x}} foreach units (_this select 4);
		};
		// camera look at player
		_cam = [_camera,_dead,[0.2,0.4,2],0.143,0] spawn _camMove;
		waitUntil {scriptDone _cam};

		// camera zooms out over 5 seconds
		_cam = [_camera,_dead,[0,8,3.5],0.7,_camTime] spawn _camMove;
		waitUntil {scriptDone _cam};

		// quick fade-in on internal point of view of the next unit
		_camera camSetTarget _unit;

		// set camera above new unit.
		_cam = [_camera,_unit,[0,8,3.5],0.7,0] spawn _camMove;
		waitUntil {scriptDone _cam};

		// camera zooms in over 5 seconds
		_cam = [_camera,_unit,[0.2,0.4,2],0.7,_camTime] spawn _camMove;
		waitUntil {scriptDone _cam};

		if ("group" in _this) then {
			if (player getVariable ["DMZ_SPR_respawn_group", false]) then {_runLoop = false};
		} else {
			_runLoop = false;
		};
	};

	// end camera part.
	_unit cameraEffect ["terminate","back"];

	// destroy camera.
	camDestroy _camera;

	// wait until unit is in player control then switxh camera back to org view (1st / 3rd person) on death.
	if (!("group" in _this)) then {
		_null = [_unit,_orgV] spawn {
			_unit = _this select 0;
			waitUntil {!alive _unit OR player == _unit};
			if (alive _unit) then {
				vehicle player switchCamera (_this select 1);
			};
		};
	};
};

// show the timer.
if (_player) then {
	if (_switch AND ({alive _x} count units _grp) != 0) then {
		_showT = [_timer,_deathCam,"ts"] spawn _showTimer;
	} else {
		if (!_group) then {
			_showT = [_timer,_deathCam,_lives] spawn _showTimer;
		};
	};
};

// join the dead unit to a holder group incase of switch option.
if (_switch) then {
	if (isNil ("DMZ_SPR_All_Dead_grp")) then {DMZ_SPR_All_Dead_grp = createGroup _side};
	removeSwitchableUnit _dead;
	_null = [_dead,_grp] spawn {
		_dead = _this select 0;
		waitUntil {sleep 1; ({alive _x} count units (_this select 1)) != 0 OR isNull _dead};
		if (!isNull _dead) then {[_dead] joinSilent DMZ_SPR_All_Dead_grp};
	};
};

// delete the dead unit if selected.
if (_delete != 0 OR _grpDel) then {
	_null = [_dead,_delete,_grpDel,_grp] spawn {
		if ((_this select 2)) then {
			waitUntil {({alive _x} count units (_this select 3)) == 0};
		};
		sleep (_this select 1);
		deleteVehicle (_this select 0);
	};
};

_mDir = 0;
_spawn = [];
// if default marker is selected.
if (_spawnPos != "") then {
	_spawn = getMarkerPos _spawnPos;
	_mDir = markerDir _spawnPos;
};

// if random marker/s option is used.
if ((count _mark) != 0) then {
	_spawnPos = _mark select (floor (random (count _mark)));
	_spawn = getMarkerPos _spawnPos;
	_mDir = markerDir _spawnPos;
};

if ((count _startPos) != 0) then {
	_spawn = _startPos select 0;
	_mDir = _startPos select 1;
};

if (_switch) then {
	_switchedUnit = player;
	_switchedDead = _dead;
	_switchActive = true;
	while {({alive _x} count units _grp) != 0 AND _switchActive} do {
		{
			if (alive _x) then {_switchedUnit = _x};
		} foreach units _grp;

		_showT = [_timer,_deathCam,"ts"] spawn _showTimer;
		if (_deathCam) then {
			_cam = [_timer,_switchedDead,_switchedUnit,_orgV] spawn _cameraFunction;
			waitUntil {scriptDone _cam};
			//vehicle player switchCamera _orgV;
		} else {
			sleep _timer;
		};

		if (alive _switchedUnit AND (group _switchedUnit) == _grp) then {
			addSwitchableUnit _switchedUnit;
			selectPlayer _switchedUnit;
			waitUntil {_switchedUnit == player};

			// if always leader option is selected.
			if (_alwLead) then {
				_null = _switchedUnit spawn {
					_grp = group _this;
					while {alive _this} do {
						waitUntil {sleep 1; !alive _this OR (leader _grp) != player};
						if (alive _this) then {_grp selectLeader _this};
					};
				};
			};

			// wait for player to die again before new switch if any available in group.
			waitUntil {!alive _switchedUnit};
			_orgV = cameraView;
			_null = [_switchedUnit,_grp] spawn {
				_unit = _this select 0;
				_grp = _this select 1;
				waitUntil {_unit != player};
				removeSwitchableUnit _unit;
				waitUntil {sleep 1; ({alive _x} count units _grp) != 0 OR isNull _unit};
				if (!isNull _unit) then {
					[_switchedUnit] joinSilent DMZ_SPR_All_Dead_grp;
				};
			};
			_temp = [_side,_type,_switchedUnit] call _fastUnit;
			_switchedDead = _switchedUnit;
			waitUntil {_temp == player};
		} else {
			titlecut ["TEAM MEMBER DEAD","PLAIN",3];
		};
		if (({alive _x} count units _grp) == 0) then {
			_switchActive = false;
			player setVariable ["DMZ_SPR_nomore_group", true, true];
			titlecut ["ALL UNITS IN GROUP ARE DEAD","BLACK FADED",3];
			_dead = _switchedUnit;
			if (!_group) then {sleep 3};
			if (_lives == 0 AND !_unLim) then {
				titlecut ["NO MORE LIVES \n \n END GAME","black out",3];
				sleep 3;
				player setDammage 1;
			};
		};
	};
};

// group option.
_form = "NONE";
if (_group OR _wp) then {
	if (_player) then {
		_null = _grp spawn {
			waitUntil {({alive _x} count units _this) == 0};
			player setVariable ["DMZ_SPR_respawn_group", true, true];
		};
		_cam = [_timer,_dead,_dead,_orgV,_grp,"group"] spawn _cameraFunction;
	};
	if (_player) then {
		waitUntil {sleep 1; ({alive _x} count units _grp) == 0 OR (player getVariable ["DMZ_SPR_nomore_group", false])};
	} else {
		waitUntil {sleep 1; ({alive _x} count units _grp) == 0};
	};
	if (_wp AND _lead) then {
		_null = _grp spawn {
			waitUntil {({alive _x} count units _this) != 0};
			_this setCurrentWaypoint [_this, 0];
		};
	};
	if (!_lead) then {
		waitUntil {({alive _x} count units _grp) != 0};
		if ((count _startPos) == 0) then {_form = "FORM"};
	};
};

if (!_player) then {sleep _timer};
_unit = _grp createUnit [_type, _spawn, [], 0, _form];

// set init.
if ((count _init) != 0) then {
	_unit setVehicleInit (_init select 0);
	processInitCommands;
};

if (_player) then {
	if (_timer != 0) then {
		// show timer.
		_showT = [_timer,_deathCam,_lives] spawn _showTimer;

		// if on death camera.
		if (_deathCam) then {_cam = [_timer,_dead,_unit,_orgV] spawn _cameraFunction};
	};

	addSwitchableUnit _unit;
	selectPlayer _unit;
	waitUntil {_unit == player};
	vehicle _unit switchCamera _orgV;
};

if (!_switch) then {
	if (isNil ("DMZ_SPR_All_Dead_grp")) then {DMZ_SPR_All_Dead_grp = createGroup _side};
	[_dead] joinSilent DMZ_SPR_All_Dead_grp;
	if (_dead in switchAbleUnits) then {removeSwitchableUnit _dead};
};

if (_vName != "") then {
	_rName = "DMZ_SPR_Dead_unit";
	_dead SetVehicleVarName _rName;
	_dead Call Compile Format ["%1=_This ; PublicVariable ""%1""",_rName];
	waitUntil {(vehicleVarName _dead) == _rName};
	_unit SetVehicleVarName _vName;
	_unit Call Compile Format ["%1=_This ; PublicVariable ""%1""",_vName];
};

if (_unLim) then {_lives = 1} else {_lives = _lives - 1};
if (_lives != 0) then {
	_unit setVariable ["DMZ_SPR_respawn", [_load,_mark,_lead,_player,_side,_grp,_lives,_unLim,_switch,_startPos,_group,_wp,_init,_timer,_delete,_alwLead], true];
	_idx = _unit addEventHandler ["killed", {_null = _this execVM "SP_respawn.sqf";}];
};

_unit setPos _spawn;
_unit setDir _mDir;

// if custom loadouts.
if ((count _load) != 0) then {
	_null = [_unit,_load] spawn {
		_unit = _this select 0;
		_load = _this select 1;

		waitUntil {alive _unit};
		removeAllWeapons _unit;
		{if (_unit hasWeapon _x) then {_unit removeWeapon _x}} foreach (weapons _unit);
		{_unit addMagazine _x} foreach (_load select 1);
		{_unit addweapon _x} foreach (_load select 0);
		if ((count _load) > 2) then {
			_unit addBackpack _back;
			_backPack = unitBackpack _unit;
			_bpWepArr = _load select 3;
			_bpMagArr = _load select 4;

			// clear backpack of any content.
			clearMagazineCargo _backPack;
			clearWeaponCargo _backPack;

			// add all pre selected items.
			_sel = 0;
			_bpWep = _bpWepArr select 0;
			_wepCnt = _bpWepArr select 1;
			while {_sel != (count _bpWep)} do {
				_wep = _bpWep select _sel;
				_cnt = _wepCnt select _sel;
				_backPack addWeaponCargo [_wep,_cnt];
				_sel = _sel + 1;
			};
			_sel = 0;
			_bpMag = _bpMagArr select 0;
			_magCnt = _bpMagArr select 1;
			while {_sel != (count _bpMag)} do {
				_mag = _bpMag select _sel;
				_cnt = _magCnt select _sel;
				_backPack addMagazineCargo [_mag,_cnt];
				_sel = _sel + 1;
			};
		};
		_unit selectWeapon (primaryWeapon _unit);
	};
};

//if (player in (units _grp)) then {_grp selectLeader player};
if (_lead) then {
	_grp selectLeader _unit;
	if (!_player) then {
		_pos = getPos _unit;
		_unit doMove [(_pos select 0) + 1,(_pos select 1) + 1,0];
	};
};

// add here any custom scripts to be run at unit after resapwning, if you dont want to use the init option.
// _null = _unit execVM "example_custom_script.sqf";
// _unit addAction ["Switch on generator", "activate_generator.sqs"];
};

Could there be a work around?

Hey Rydygier it works fine for me. I am using a script that Demonized also work out for me that allows me to recruit and or spawn in any unit/object in the game. I think the issue maybe the original script was not for spawn units only editor placed units and when you rework it for us to allow to use for spawn units . The script he his using seems directed towards SP not MP could that be the issue. I am no scripter but that would make sense to me. He should try a different respawn script to see if it works.

I also changed the kill marker to a black color. I am using the Destroy marker symbol (cross) and it looks really cool to have a large red blood area of combat and little black cross's fading away within the red area.i am looking to replace the DOT marker for the vehicle with a small triangle marker but no luck. Avibird

Edited by AVIBIRD 1

Share this post


Link to post
Share on other sites

OK. Here you go, both previously uploaded versions (less and more blood drops) with non-EH based KIA Sparks. Works, but perhaps is a bit heavier for CPU.

BD&KIASdemoCD

EDIT:

i am looking to replace the DOT marker for the vehicle

Something like this perhaps (new KIAVmark.sqf code):

_veh = _this select 0;
_pos = getPosASL _veh;

_i = "markVKill" + (str _veh);

_i = createMarker [_i,_pos];
_i setMarkerColor "ColorBlack";
_i setMarkerShape "ICON";
_i setMarkerType "mil_triangle";
_i setMarkerSize [1,1];
_alpha = 1;
_size = 1;

while {(_alpha > 0)} do
{
sleep 0.2;
_i setmarkerAlpha _alpha;
_i setMarkerSize [_size,_size];
_size = _size - 0.008;
_alpha = _alpha - 0.01;
};

deleteMarker _i;

Edited by Rydygier

Share this post


Link to post
Share on other sites

Excellent mate. I tried the previous version and it works very well. I just need to check exactly how much CPU power it requires (as it polls AllUnits). I did turn the frequency of polling down to 20 seconds for the adding of the EH, which will help quite a bit.

It was wonderful last night, to see these drops litter the landscape and I was able to position myself right in the middle of the battle (and NOT become a blood drop statistic !) and watch how they got on.

Thankyou so much for doing this.

Share this post


Link to post
Share on other sites
...with non-EH based KIA Sparks. Works,

Thank you, adds a lot to the game.

He should try a different respawn script to see if it works/I am using a script that Demonized also work out for me that allows me to recruit and or spawn in any unit/object in the game.

Can i look at the one your using from Demonized, sounds good

Share this post


Link to post
Share on other sites

^^ Or you could use VTS or MCC or even look at Battlezone to spawn anything :)

I will look at the non-EH ones tonight but I wondered about your comment about removing the KilledEH every cycle. Removing the EH from everything living and dead? Surely we only need to remove it from the dead ones :)

Edited by Kremator

Share this post


Link to post
Share on other sites

Here is another sad scripter's story about EH for spawned during gameplay units:

Every new units should have single EH "Killed" containing KIA script. And there are only three usable here commands known to me: addEventHandler, removeEventHandler and removeAllEventHandlers. There is no command for checking, if there is some EH on unit, so can't implement nothing in kind of "only, if there is no EH "Killed" on unit then give it such EH".

Next logical option should be to use every cycle for allUnits "remove-add new" procedure.

For alive only. To count also dead I need AllDead command, and this command is available only in OA, so at the moment can use it only blindly, without testing. If you want to try, then replace code of AddKMark.sqf in EH version of KIA with this:

_markedSides = [];

if ("W" in _this) then {_markedSides = _markedSides + [west]};
if ("E" in _this) then {_markedSides = _markedSides + [east]};
if ("R" in _this) then {_markedSides = _markedSides + [resistance]};
if ("C" in _this) then {_markedSides = _markedSides + [civilian]};

while {(true)} do
{

	{
	if ((side _x) in _markedSides) then 
		{
		_x removeAllEventHandlers "killed";			
		}
	}
foreach (AllUnits + AllDead);

	{
	if ((side _x) in _markedSides) then 
		{
		_KilledEH = _x addEventHandler ["Killed", {nul = _this spawn KilledMark}]
		}
	}
foreach AllUnits;

sleep 5;
};

This will every cycle remove EHs from all, alive and dead, and then will add new one EH only for alive.

So should be to use for each unit removeEventHandler command (of given index - each EH of given type on unit has own index number) and just then addEventHandler. But... For some weird reason index number of EH for given unit changes, when another EH of this type with lower index number is removed. For exapmle if I have on unit two EHs "Killed" (eg first from respawn script and second from KIA), first has index of 0, and second - of 1. Now if I remove first EH, then index of second will not stay 1, alas, but become 0, so if I try to remove EH of index, that was given previously to that EH, there may be another EH removed instead, or none, because of this index change.

Only option, that is available is to remove every cycle all EHs of given type every cycle for every unit and then to add new one for each of unit...

Edited by Rydygier

Share this post


Link to post
Share on other sites

You could setVar something on the unit to indicate it already has the event handler. Then you won't need to recreate it everytime.

If you use CBA an even simpler solution would be to use extended event handlers in the description.ext:

class Extended_Init_Eventhandlers
{
   class CAManBase
   {
       class XEH_RespawnInitMan
       {
           onRespawn = 1;                    // Run this even after respawn
           init      = "if (isServer) then {(_this select 0) addEventHandler ['killed', ........]};";
       };
   };
};

By using removeAllEventHandlers you prevent any other scripts from doing something useful when a unit is killed too.

Share this post


Link to post
Share on other sites
By using removeAllEventHandlers you prevent any other scripts from doing something useful when a unit is killed too.

Yep, that is the problem. setVar, you say? You mean setVarialbe? Hmm. Indeed, I can hold there info, that EH was added, as I do with other info and then to add new EH only for units without this info. Why I did not think about this? Thanks for an advices! :)

Share this post


Link to post
Share on other sites

I am a little lost when it comes to EH . I am using the second to last script post above with EH intact and it works fine. I am using the script in a mission that uses a lot of other scripts within the mission. What is the good thing using a EH and what is the bad thing using a EH in a script. Avibird.

Share this post


Link to post
Share on other sites

I'm not sure, how heavy for CPU are EHs when added, but I know, that without EH method additional cyclic loop with short sleep is needed to catch moment of death of every unit, and this makes script heavier for sure. Using of EH here is simply, how to say this, more elegant?

---------- Post added at 19:30 ---------- Previous post was at 19:03 ----------

Again then, thanks to muzzleflash, better, not interfering EH versions.

BD&KIAS-EH

So now we have four versions: two because of Blood Drops (less or more intensive) and two because of implemetation method and CPU load of "KIA Sparks": with and without EH "Killed". In this versions, as Kremator did, checking for EH is less frequent (every 20 sec, so this is maximal time needed for spawned units to become considered by KIA Sparks).

Edited by Rydygier

Share this post


Link to post
Share on other sites

Ryd, you deserve a medal mate ! Thanks very much !

These scripts will be finding their way into my mashup mission.

Share this post


Link to post
Share on other sites

Just one last question mate. Everything seems to be working well, but I would like the script to NOT run on players. Where would I put the !isPlayer (or other code!)?

Share this post


Link to post
Share on other sites

To make KIA Sparks not show player's deaths you can try this in AddKMark.sqf for EH version:

_markedSides = [];

if ("W" in _this) then {_markedSides = _markedSides + [west]};
if ("E" in _this) then {_markedSides = _markedSides + [east]};
if ("R" in _this) then {_markedSides = _markedSides + [resistance]};
if ("C" in _this) then {_markedSides = _markedSides + [civilian]};

while {(true)} do
{

	{
[color="#FF0000"]		if not (isPlayer _x) then
		{[/color]
		_isEH = _x getVariable ("isEH" + (str _x));
		if (isNil ("_isEH")) then {_isEH = false};

		if (((side _x) in _markedSides) and not (_isEH)) then 
			{
			_KilledEH = _x addEventHandler ["Killed", {nul = _this spawn KIAUnMark}];
			_x setVariable [("isEH" + (str _x)),true,false];
			}
		[color="#FF0000"]}[/color]
	}
foreach AllUnits;

_ad = AllDead;
if (isNil ("_ad")) then {_ad = []};

	{
	_x removeAllEventhandlers "Killed";
	}
foreach _ad;

sleep 20;
};

To make Blood Drops ("more blood" version, "less blood" - similar) not considering players as valid witnessess:

_markedSides = [];

if ("W" in _this) then {_markedSides = _markedSides + [west]};
if ("E" in _this) then {_markedSides = _markedSides + [east]};
if ("R" in _this) then {_markedSides = _markedSides + [resistance]};
if ("C" in _this) then {_markedSides = _markedSides + [civilian]};

while {(true)} do
{
sleep 5;
_freshWound = [];
_blood = 0;

	{
	_bm = _x getVariable ("BloodMarked" + (str _x));
	if (isNil ("_bm")) then {_bm = false};
	_i = "markBlood" + (str _x);

	_blood = 0;
	_posX = 0;
	_posY = 0;
	_cnt = 0;

	[color="#FF0000"]if not (isPlayer _x) then
		{[/color]
		_AllM = nearestObjects [(vehicle _x), ["CAManBase"], 500];

			{
			_wound = damage _x;
			if (not (_x in _freshWound) and (_wound > 0)) then
				{
				_freshWound = _freshWound + [_x];
				_blood = _blood + _wound;
				_posX = _posX + ((getPosASL _x) select 0);
				_posY = _posY + ((getPosASL _x) select 1);
				_cnt = _cnt + 1;
				if not (alive _x) then
					{
					_bm2 = _x getVariable ("BloodMarked" + (str _x));
					if (isNil ("_bm2")) then {_bm2 = false};
					if (_bm2) then 
						{
						deleteMarker ("markBlood" + (str _x));
						_x setVariable [("BloodMarked" + (str _x)),false,false];
						}
					}
				}
			}
		foreach _AllM
		[color="#FF0000"]};[/color]

	if (_cnt > 0) then 
		{
		_posX = _posX/_cnt;
		_posY = _posY/_cnt;
		};

	if (_blood >= 1) then
		{		
		_x setVariable [("BloodMarked" + (str _x)),true,false];

		if not (_bm) then 
			{
			_i = createMarker [_i,[_posX,_posY]];
			_i setMarkerColor "ColorRed";
			_i setMarkerShape "ICON";
			_i setMarkerType "DOT"
			};

		_amount = _blood/2;
		if (_amount > 8) then {_amount = 8};
		_alpha = 0.3 + (_blood/50);
		if (_alpha > 0.9) then {_alpha = 0.9};

		_i setMarkerPos [_posX,_posY];
		_i setMarkerSize [_amount,_amount];
		_i setMarkerAlpha _alpha;
		};

	if ((_bm) and (_blood < 1)) then
		{
		_x setVariable [("BloodMarked" + (str _x)),false,false];
		deleteMarker _i;
		}
	}	
foreach AllUnits;

_ad = AllDead;
if (isNil ("_ad")) then {_ad = []};

	{
	_bm3 = _x getVariable ("BloodMarked" + (str _x));
	if (isNil ("_bm3")) then {_bm3 = false};
	if (_bm3) then {deleteMarker ("markBlood" + (str _x))};
	}
foreach _ad;
};

and for disabling only counting player's wounds, but players still may be a witnessess:

_markedSides = [];

if ("W" in _this) then {_markedSides = _markedSides + [west]};
if ("E" in _this) then {_markedSides = _markedSides + [east]};
if ("R" in _this) then {_markedSides = _markedSides + [resistance]};
if ("C" in _this) then {_markedSides = _markedSides + [civilian]};

while {(true)} do
{
sleep 5;
_freshWound = [];
_blood = 0;

	{
	_bm = _x getVariable ("BloodMarked" + (str _x));
	if (isNil ("_bm")) then {_bm = false};
	_i = "markBlood" + (str _x);

	_AllM = nearestObjects [(vehicle _x), ["CAManBase"], 500];
	_blood = 0;
	_posX = 0;
	_posY = 0;
	_cnt = 0;
		{
		_wound = damage _x;
		if (not (_x in _freshWound) and (_wound > 0)[color="#FF0000"] and not (isPlayer _x)[/color]) then
			{
			_freshWound = _freshWound + [_x];
			_blood = _blood + _wound;
			_posX = _posX + ((getPosASL _x) select 0);
			_posY = _posY + ((getPosASL _x) select 1);
			_cnt = _cnt + 1;
			if not (alive _x) then
				{
				_bm2 = _x getVariable ("BloodMarked" + (str _x));
				if (isNil ("_bm2")) then {_bm2 = false};
				if (_bm2) then 
					{
					deleteMarker ("markBlood" + (str _x));
					_x setVariable [("BloodMarked" + (str _x)),false,false];
					}
				}
			}
		}
	foreach _AllM;

	if (_cnt > 0) then 
		{
		_posX = _posX/_cnt;
		_posY = _posY/_cnt;
		};

	if (_blood >= 1) then
		{		
		_x setVariable [("BloodMarked" + (str _x)),true,false];

		if not (_bm) then 
			{
			_i = createMarker [_i,[_posX,_posY]];
			_i setMarkerColor "ColorRed";
			_i setMarkerShape "ICON";
			_i setMarkerType "DOT"
			};

		_amount = _blood/2;
		if (_amount > 8) then {_amount = 8};
		_alpha = 0.3 + (_blood/50);
		if (_alpha > 0.9) then {_alpha = 0.9};

		_i setMarkerPos [_posX,_posY];
		_i setMarkerSize [_amount,_amount];
		_i setMarkerAlpha _alpha;
		};

	if ((_bm) and (_blood < 1)) then
		{
		_x setVariable [("BloodMarked" + (str _x)),false,false];
		deleteMarker _i;
		}
	}	
foreach AllUnits;

_ad = AllDead;
if (isNil ("_ad")) then {_ad = []};

	{
	_bm3 = _x getVariable ("BloodMarked" + (str _x));
	if (isNil ("_bm3")) then {_bm3 = false};
	if (_bm3) then {deleteMarker ("markBlood" + (str _x))};
	}
foreach _ad;


};

Both above my be combined - no players as witnesses and not counting player's wounds. NTBSW (not tested, but should work)

Edited by Rydygier

Share this post


Link to post
Share on other sites

Once again.... you are a star mate! I knew it was something like that .. just didn't know how to format it ! Will get it into the mission and see how she rolls :)

Share this post


Link to post
Share on other sites

Getting a recurring error in my mission. Any idea why this keeps coming up?

Bad conversion: array

Error in expression <0;

if not (isPlayer _x) then

{

_AllM = nearestObjects [(vehicle _x), ["CAManBas>

Error position: <nearestObjects [(vehicle _x), ["CAManBas>

Error 0 elements provided, 3 expected

File mpmissions\__cur_mp.Takistan\scripts\DeathMark\ShowMeBlood.sqf, line 26

Share this post


Link to post
Share on other sites

Quite strange. And known to me also from other scripts... Though AllUnits here sometimes return null objects or given unit from last AllUnits array is destroyed between AllUnits collecting and nearestObjects collecting, so haven't a position attribute, when needed (so this error is generated, as nearestObjects need a position or object, that have a position)... Maybe this back-up will help:

_AllM = [];
if not (isNull (vehicle _x)) then {_AllM = nearestObjects [(vehicle _x), ["CAManBase"], 500]};

instead of:

_AllM = nearestObjects [(vehicle _x), ["CAManBase"], 500];

Give ma a word, if this helped, I'm curious...

Share this post


Link to post
Share on other sites

Bingo ! That has seemed to kill the error Rydygier ! Well done mate. I've had a server running my mission now where I guesstimate that over 5000 troops/vehicles have died over 24 hours without one error :) You should see the map :)

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  

×