Jump to content
-ami- mofo

damage handling scripts broken since 1.66 update

Recommended Posts

Hi guys I had two scripts working fine in MP before the update and now neither works.

One in the init.sqf file which kept the player in revive mode and not able to be killed until the revive timer ran out...

// Stay in revive until bleed out
 if (hasInterface) then {

	player addEventHandler ["Dammaged", {
    
        params ["_unit"];
 
        
            if (lifeState _unit == "INCAPACITATED") then {
                
                _unit allowDamage false;
                
                null = [_unit] spawn {
                
                    params ["_guy"];
					
			waitUntil {sleep 1; lifeState _guy != "INCAPACITATED" || isNull _guy || !alive _guy};
						
			if (!isNull _guy && alive _guy) then {
				_guy allowDamage true;
			};
                };
 
            };
 
	}];
};

And I had an initplayerlocal.sqf that reduced the player damage a bit...

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"];
	
		
	//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;
	};
	
		
	//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;
	};
	
		
	_damage
	
}];

I thought I'd better give them a MP test since the new update because.. ya know. And unfortunately both aren't working.

The update log mentioned a couple of things regarding the game's damage / revive...

Tweaked: The damage model for the 'Basic' Revive setting was changed 

Fixed: The "onPlayerKilled.sqf" and the "Killed" Event Handlers were not fired when players would bleed out in Revive

Tweaked: The damage model for the 'Basic' Revive setting was changed

Not being a scripter or game tech savvy I'm not sure whether these have something to do with it or whether all that's needed is a tweak to the scripts to get them working again?

 

Any help would be terrific though.

 

Thanks.

Share this post


Link to post
Share on other sites

Second script is working fine as i just test the original i gave you with the debug systemChats added back in.

I think the problem is with the first, although you have allowDamage false revive still adds up the damage taken and likely applies it to the unit via setDamage which will bypass allowDamage false.

 

Get rid of your first script and update the second to...

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 ];
    
    if ( lifeState _unit != "INCAPACITATED" ) then {
        
        //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;
        };
        
            
        //Only players respond to REVIVE
        if ( isPlayer _unit ) then {
            systemChat format[ "Damage to REVIVE: %1", _damage ];
            _this set[ 2, _damage ];
            //Call BI REVIVE HandleDamage EH passing new _damage value
            _damage = _this call BIS_fnc_reviveOnPlayerHandleDamage;
        };
    }else{
        _damage = 0;
    };
    
    systemChat format[ "Damage to engine: %1", _damage ];
    
    _damage
    
}];
Combining the two, this way the revive BIS_fnc_reviveOnPlayerHandleDamage is never called if the player is incapacitated so no damage for selections is saved.

Share this post


Link to post
Share on other sites

Am trying to create a mission where it's not possible to kill the players, only incapacitate them.

 

The mission is only failed if the entire team is incapacitated.

 

Have tried using the script from this and another thread (placed in initPlayerLocal.sqf.)

 

//initPlayerLocal.sqf
params[ "_unit" ];

//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", {
    private[ "_damage" ];
    params [ "_unit" ];
    
    //If we are not incapacitated
    if ( lifeState _unit != "INCAPACITATED" ) then {
        //Get revives handle damage
        _damage = _this call BIS_fnc_reviveOnPlayerHandleDamage;
    }else{
        //if we are incapacitated
        _damage = 0;
    };
    
    _damage
    
}];

However on testing it on a multiplayer server, a friend was able to incapacitate me (fine) and then able to kill me while incapacitated (not so fine.)

 

Is there something in the setup that I may have done wrong, or something further that should be added?

 

Link to another relevant thread: https://forums.bistudio.com/forums/topic/200447-how-to-disable-damage-when-unconscious/

 

Share this post


Link to post
Share on other sites


Having looked into this a bit further it seems the script above is stalling at:

waitUntil{ !isNil { _unit getVariable "bis_revive_ehDamage" } };

Has the name of "bis_revive_ehDamage" changed?

Share this post


Link to post
Share on other sites

OK, have just done some tests and this new script appears to work as intended. Big thanks to Larrow for creating it in the first place, and Bohemia for their fantastic new functions library in the Eden Editor.

 

Turns out it was just some changed function names.

 

//initPlayerServer.sqf
params[ "_unit" ];

//Waituntil REVIVE handleDamage EH has been applied
waitUntil{ !isNil { _unit getVariable "bis_revive_ehHandleDamage" } };

//Remove REVIVE HandleDamage EH
_unit removeEventHandler[ "HandleDamage", _unit getVariable "bis_revive_ehHandleDamage" ];

//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", {
    private[ "_damage" ];
    params [ "_unit" ];
    
    //If we are not incapacitated
    if ( lifeState _unit != "INCAPACITATED" ) then {
        //Get revives handle damage
        _damage = _this call bis_fnc_reviveEhHandleDamage;
    } else {
        //if we are incapacitated
        _damage = 0;
    };

    _damage
    
}];

 

Share this post


Link to post
Share on other sites

@caddrel

 

It works when I run my multiplayer mission locally through the eden editor as "test multiplayer" and the script is in the  initPlayerServer.sqf

 

But as soon as I push it to the dedicated server, it doesn't matter wether its in initPlayerLocal.sqf or initPlayerServer.sqf

It won't work either way.

 

Any advise?

 

Regards,

Whip

Share this post


Link to post
Share on other sites

use initPlayerLocal.sqf, not initPlayerServer.sqf

 

also remove these lines

 

//Waituntil REVIVE handleDamage EH has been applied
waitUntil{ !isNil { _unit getVariable "bis_revive_ehHandleDamage" } };

//Remove REVIVE HandleDamage EH
_unit removeEventHandler[ "HandleDamage", _unit getVariable "bis_revive_ehHandleDamage" ];

insert instead

_unit removeAllEventHandlers 'HandleDamage';

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Playing a Coop mission on a hosted/listen server, I managed with just this:

player addEventHandler ["HandleDamage",{
    private["_damage"];
    if (lifeState player == "INCAPACITATED") then {
		_damage = 0;
    };    
    _damage    
}];

 

Executed that in a function from initPlayerLocal.sqf and no one got "executed" using the vanilla revive.

  • Like 1

Share this post


Link to post
Share on other sites

There's a bug in the damage reduction code above.  Namely that "private _damageRecieved = (_damage - _selectionDamage) max 0;" is not accurate when _selection is "".  Here's some useful updated info on HandleDamage:

 

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"];
	
	private _incomingDamage = _damage;
	private _oldDamage = 0;
	if (_hitSelection isEqualTo "") then {_oldDamage = damage _unit} else {_oldDamage = _unit getHit _hitSelection};
	private _newDamage = _damage - _oldDamage max 0;
	private _playerHealth = damage _unit;

	// 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
	if (_newDamage > 0) then {
		// Reduce the new damage to 1/4 the amount
		_damage = _oldDamage + (_newDamage * 0.25);
	};
	
	// 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 damage
			_damage = 0;
		} 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 prevDmg: %3 incomingDmg: %4 appliedDmg: %5", _playerHealth, _hitSelection, _oldDamage, _incomingDamage, _damage];

	_damage
	
}];
systemChat format[ "Damage reduction applied to %1", _unit ];

// End damage reduction

 

Place this at the end of your mission initPlayerLocal.sqf and just change 0.25 to be whatever multiplier 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.

 

 

  • Thanks 1

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

×