-ami- mofo 13 Posted November 19, 2016 Hi guys I have this script that I put in a units init.. this addeventhandler ["HandleDamage", { _unit = _this select 0; _selection = _this select 1; _passedDamage = _this select 2; _source = _this select 3; _projectile = _this select 4; _oldDamage = 0; _damageMultiplier = 0.5; switch(_selection)do{ case("head") :{_oldDamage = _unit getHitPointDamage "HitHead";}; case("body") :{_oldDamage = _unit getHitPointDamage "HitBody";}; case("hands") :{_oldDamage = _unit getHitPointDamage "HitHands";}; case("legs") :{_oldDamage = _unit getHitPointDamage "HitLegs";}; case("") :{_oldDamage = damage _unit;}; default{}; }; _return = _oldDamage + ((_passedDamage - _oldDamage) *_damageMultiplier); _return }]; And it works a treat on AI but it doesn't work for players. Is there a tweak to get it so it works on players? (MP co-op hosted on my machine). Thanks. Share this post Link to post Share on other sites
Grumpy Old Man 3546 Posted November 19, 2016 How did you come to the conclusion that this doesn't work for players? Cheers Share this post Link to post Share on other sites
-ami- mofo 13 Posted November 19, 2016 I have two computers both with arma so tried it out in MP. Didn't make any difference like it does to AI. Share this post Link to post Share on other sites
-ami- mofo 13 Posted November 19, 2016 Just read that player handle damage in arma 3 isn't working but nobody knows why. It worked in Arma 2. So until BIS fix it (if they fix it) then I guess I'd better always wear a special carrier rig lol. Share this post Link to post Share on other sites
bad benson 1733 Posted November 19, 2016 do you have a source for that? i'd be interested to read up on that. Share this post Link to post Share on other sites
-ami- mofo 13 Posted November 20, 2016 Not an official source, just read in several places where ppl are trying to find other ways of achieving it as they say that it's not working like it used to. Google arma 3 player reduce damage and you'll find a few bits and pieces. Share this post Link to post Share on other sites
-ami- mofo 13 Posted November 20, 2016 After a little more testing it seems that the culprit is Arma's own revive system. Seems like it and damage handler won't work together. Turn arma's revive off and that script does work in MP. But we use revive so unfortunately no reducing player damage for us. May just have to make the enemy a little less accurate lol. 1 Share this post Link to post Share on other sites
Larrow 2822 Posted November 20, 2016 Just read that player handle damage in arma 3 isn't working but nobody knows why. After a little more testing it seems that the culprit is Arma's own revive system.This is correct Revive adds a HandleDamage EH to the player. As per the wiki.. Multiple "HandleDamage" event handlers can be added to the same unit. If multiple EHs return damage value for custom damage handling, only last returned value will be considered by the engine. EHs that do not return value can be safely added after EHs that do return value.So all you should need to do is wait until the Revive HandleDamage EH has been applied.Remove the EH. Add your own that manipulates the damage recieved. Call the Revives HandleDamage function. Pass result back to engine at the end of the EH. Something like.. params[ "_unit" ]; //Exit if we are a player and not local //Otherwise add EH for AI every where just incase their locality //changes due to moving into a players group //the EH will only fire where the AI is local if ( isPlayer _unit && { !local _unit } ) exitWith {}; if ( isPlayer _unit ) then { //Waituntil REVIVE handleDamage EH has been applied waitUntil{ !isNil { _unit getVariable "bis_revive_ehDamage" } }; //Remove REVIVE HandleDamage EH _unit removeEventHandler[ "HandleDamage", _unit getVariable "bis_revive_ehDamage" ]; }; //Only damage from last applied handleDamage EH is taken into consideration by the engine //Apply a new EH so as we can override the damage applied _unit addEventHandler [ "HandleDamage", { params ["_unit", "_selection", "_damage","_source","","_index"]; systemChat format[ "Damage recieved: %1", _damage ]; //Do any other damage calculations here //_damage is the total damage the unit has for this selection once this EH returns //e.g lets change the damage recieved for each selection if ( _index > -1 ) then { private _selectionDamage = _unit getHit _selection; private _damageRecieved = (_damage - _selectionDamage) max 0; _damageRecieved = _damageRecieved / 4; _damage = _damageRecieved + _selectionDamage; }; systemChat format[ "Damage to REVIVE: %1", _damage ]; //Only players respond to REVIVE if ( isPlayer _unit ) then { _this set[ 2, _damage ]; //Call BI REVIVE HandleDamage EH passing new _damage value _damage = _this call BIS_fnc_reviveOnPlayerHandleDamage; }; systemChat format[ "Damage to engine: %1", _damage ]; _damage }]; systemChat format[ "Override REVIVE EH applied to %1", _unit ];Either in the initPlayerLocal or called from somewhere where you can pass the player in.Ive been over cautious with the player checks but you can quite easily remove them from the start of the script to apply this for AI as well and then the EH only applies Revive damage handling if its a player. EDIT: Changed the script so you can pass either a player or AI and it will apply the damage changes and handle Revive if its a player. 2 Share this post Link to post Share on other sites
-ami- mofo 13 Posted November 20, 2016 Hi mate I'm a newb when it comes to scripting, I don't even understand all that.. I went to paste that (minus all the stuff after the //) in the units init (that's what you meant by initplayer local?) and got a type bool expected nothing error. You may have to guide me a little more on getting this to work. Share this post Link to post Share on other sites
bad benson 1733 Posted November 20, 2016 by initplayerlocal he meant the hard coded event script. so in practice what you do is create a file called InitPlayerLocal.sqf inside your mission folder and then paste the code in there. arma has several event scripts like this one. most commonly known one is the Init.sqf. you can read up on it here: https://community.bistudio.com/wiki/Event_Scripts https://community.bistudio.com/wiki/Initialization_Order Share this post Link to post Share on other sites
-ami- mofo 13 Posted November 22, 2016 Thank you Larrow and Bad Benson :) That did indeed work. Tested in MP with Arma's revive plus a little script I have that keeps players in revive mode until time out. Worked perfect! The only question I have left is that when somebody takes any kind of damage even if small damage (ie- jumps off a wall) it lists all the damage info on the screen (bottom left). Is there a way to remove that? Share this post Link to post Share on other sites
Larrow 2822 Posted November 22, 2016 Remove all the lines that start with systemChat as they are there exactly for that reason to show debug info about damage. Share this post Link to post Share on other sites
-ami- mofo 13 Posted November 22, 2016 Thanks mate.. working perfectly :) Share this post Link to post Share on other sites
misterpete 15 Posted July 19, 2017 There is some outdated information here (some bis name changes) and a bug (namely that _damageRecieved is inaccurate if _selection is ""). There is some helpful updated info here: Here's an updated version of the reduce damage script: params[ "_unit" ]; // Damage reduction from https://forums.bistudio.com/forums/topic/198136-reducing-player-damage/ // Exit if we are a player and not local // Otherwise add EH for AI every where just in case their locality // changes due to moving into a players group // the EH will only fire where the AI is local if ( isPlayer _unit && { !local _unit } ) exitWith {}; if ( isPlayer _unit ) then { _unit removeAllEventHandlers 'HandleDamage'; }; // Only damage from last applied handleDamage EH is taken into consideration by the engine // Apply a new EH so as we can override the damage applied _unit addEventHandler [ "HandleDamage", { params ["_unit", "_hitSelection", "_damage","_source","_projectile","_hitPartIndex", "_instigator", "_hitPoint"]; // Damage multipliers. The damage of each projectile will be multiplied by this number. private _damageMultiplierHead = 0.3; private _damageMultiplierBody = 0.25; private _damageMultiplierLimbs = 0.15; private _damageMultiplierOverall = 0.25; // Damage limits. Each projectile will be limited to a max of this much damage. private _limitHead = 1.0; private _limitBody = 0.25; private _limitLimbs = 0.1; private _limitOverall = 0.25; private _oldDamage = 0; if (_hitSelection isEqualTo "") then {_oldDamage = damage _unit} else {_oldDamage = _unit getHit _hitSelection}; private _newDamage = _damage - _oldDamage max 0; private _incomingDamage = _newDamage; private _playerHealth = damage _unit; // Infantry selections // Keep in mind that if revive is enabled then incapacitation may occur at around 0.7 damage. // "": The overall damage that determines the damage value of the unit. Unit dies at damage equal to or above 1 // "face_hub": Unit dies at damage equal to or above 1 // "neck": Unit dies at damage equal to or above 1 // "head": Unit dies at damage equal to or above 1 // "pelvis": Unit dies at damage equal to or above 1 // "spine1": Unit dies at damage equal to or above 1 // "spine2": Unit dies at damage equal to or above 1 // "spine3": Unit dies at damage equal to or above 1 // "body": Unit dies at damage equal to or above 1 // "arms": Unit doesn't die with damage to this part // "hands": Unit doesn't die with damage to this part // "legs": Unit doesn't die with damage to this part // Do any other damage calculations here // _damage is the previous damage plus any new damage and will be applied // as the total damage the unit has for this selection once this EH returns // Only modify damage if it is a known projectile (leave falling damage etc alone) if (_newDamage > 0 && !(_projectile isEqualTo "")) then { // Reduce damage by damage multiplier private _damageMultiplier = _damageMultiplierBody; private _upperLimit = _limitBody; switch (_hitSelection) do { case "face_hub"; case "head": { _damageMultiplier = _damageMultiplierHead; _upperLimit = _limitHead; }; case "arms"; case "hands"; case "legs": { _damageMultiplier = _damageMultiplierLimbs; _upperLimit = _limitLimbs; }; case "": { _damageMultiplier = _damageMultiplierOverall; _upperLimit = _limitOverall; }; default { _damageMultiplier = _damageMultiplierBody; _upperLimit = _limitBody; }; }; _newDamage = _newDamage * _damageMultiplier; // Place an upper limit on projectile damage done at once if (_newDamage > _upperLimit) then { _newDamage = _upperLimit; }; _damage = _oldDamage + _newDamage; }; // For players ignore damage if they are incapacitated and pass damage to bis revive handler if ( isPlayer _unit ) then { if ( lifeState _unit == "INCAPACITATED" ) then { //if we are incapacitated take no additional damage _damage = _oldDamage; } else { _this set[ 2, _damage ]; //Call BI REVIVE HandleDamage EH passing new _damage value _damage = _this call bis_fnc_reviveEhHandleDamage; }; }; systemChat format[ "pHealth: %1 selection: %2 oldTotal: %3 newTotal: %4 incomingDmg: %6 appliedDmg: %6", _playerHealth, _hitSelection, _oldDamage, _damage, _incomingDamage, _newDamage]; _damage }]; systemChat format[ "Damage reduction applied to %1", _unit ]; Place this at the end of your mission initPlayerLocal.sqf and just change the multipliers you would like for the damage and remove the systemChat lines which are there for debugging. You can also remove the if statement with "INCAPACITATED" if you want players to be able to be killed while incapacitated. EDIT: Added in location based multipliers and upper limits of damage per projectile and a check for _projectile not "" to avoid modifying falling damage etc. You can set limits to 1 if you don't want an upper limit or fractions to ensure a number of shots to kill/incapacitate, keep in mind that players die at 1.0 damage but may be incapacitated at around 0.7 depending on the revive system. 2 2 Share this post Link to post Share on other sites