View Full Version : [EDITING] Body Armour for players

30-12-2011, 12:32 AM
It sucks when you get winged and have to sit out for ten minutes.

The default medical module is nice, but it's not ideal.

Norrin's revive is very hard to follow, adds hundreds of kilobytes to mission sizes and is very fiddly to set up without it making death a non-issue.

The solution? Give the players Body Armour (AKA Ansob's Shameful Setting). They'll be able to take a handful of 5.56 rounds to the chest, even at close range. Grenades, tank shells and anti-material rifles will still ruin their day, though.

What it does
Body Armour modifies the damage event handlers, scaling down certain types of damage.

Wiki info

Create bodyarmourfunc.sqf in your mission folder:

private ["_unit","_damage","_ammo","_gethit","_damMults"];
// Stolen from Celery, modifications by Nullkigan

_unit=_this select 0; //Unit taking damage
_damage=_this select 2; //Amount of damage dealt to unit
_ammo=_this select 4; //Type of damage unit takes

_damMults=[0.1,0.2,0.2,0.3,0.4]; //Structural, Head, Body, Hands, Legs

//player sideChat format ["%1 isKindOf BulletCore = %2, dealt %3 damage",_ammo,(_ammo isKindOf "BulletCore"),_damage];//Debug; tells you what hit the player and how much base damage it did

if (!(_ammo isKindOf "BulletCore")) then {_damMults=[1.0,1.0,1.0,1.0,1.0];}; // Only modify damage if from a bullet; grenades and stuff still hurt! NB: .50 at point blank just kills instead of doing damage.
//Comment out the above IF statement for resistance to ALL damage types. NB: As well as instakills, some weapons do tens or more damage per hit, which even after scaling can still kill units outright.

if (isNil {_unit getVariable "gethit"}) then {_unit setVariable ["gethit",[0,0,0,0]]}; // Fresh unit starts at full health
_gethit=_unit getVariable "gethit"; // load health of each part of body

switch (_this select 1) do { // Depending on which part of body is damaged
case "":{ // Overall structure damage
_damage=damage _unit+_damage*(_damMults select 0) // Total damage to unit + percentage of incoming damage

case "head_hit":{ // Damage applied to head
_damage=(_gethit select 0)+(_damage-(_gethit select 0))*(_damMults select 1);_gethit set [0,_damage] // Damage dealt to head so far + damage from current shot (minus existing damage) * factor; essentially, damage accumulates with the number of shots you take

case "body":{
_damage=(_gethit select 1)+(_damage-(_gethit select 1))*(_damMults select 2);_gethit set [1,_damage] //As previously

case "hands":{ // cannot kill a unit on own, only affect aim
_damage=(_gethit select 2)+(_damage-(_gethit select 2))*(_damMults select 3);_gethit set [2,_damage]

case "legs":{ // cannot kill a unit on own, only affect movement
_damage=(_gethit select 3)+(_damage-(_gethit select 3))*(_damMults select 4);_gethit set [3,_damage]

// Do not put a semicolon or comment after the next line otherwise the script will not output the correct result

To give a player Body Armour, put the following in init.sqf:

BodyArmourFunc = compile preprocessFileLineNumbers "bodyarmourfunc.sqf"; // players are partially bullet resistant
player addEventHandler ["HandleDamage",{call bodyarmourfunc;}];

Whenever a player connects, they run a local copy of init.sqf. These lines tell them to compile the script called bodyarmourfunc.sqf, and the use that to calculate the results of events that cause damage to that player. If you wanted to add Body Armour to an AI, you'd simply replace put the second line of the script in the Init of the unit, replacing player with this or the name of said unit. Try to avoid doing that with players, playable units, or units that players can command. Locality makes things messy.

If you wish to use Body Armour with Norrin's Revive, place the above chunk of code before the following entry in init.sqf:

server execVM "revive_init.sqf";

If you find the Body Armour effect wears off after a player has been killed or revived (I haven't tested it that much yet, but it seems to stick) try going to the bottom of Norrin's revive_init.sqf and edit the following lines:

NORRNCustomExec1 ="_name setVariable ['gethit',[0,0,0,0]];"; // Exec1 occurs following being revived
NORRNCustomExec2 =""; // Exec2 occurs when you team kill
NORRNCustomExec3 ="_name setVariable ['gethit',[0,0,0,0]];"; // Exec3 occurs when you spawn at base
NORRNCustomExec4 =""; // Exec4 occurs when you try and spawn at base but it is still occupied
NORRNCustomExec5 =""; // Must use variables: MAP_r_rejoin (false - first time,
// true - rejoining the server, and
// MAP_r_no_lives - number of lives if you rejoin server)