Browse Source

Add basic shield health, manually init onto only sigma

m3ales 3 years ago
parent
commit
ece1826118

+ 13 - 0
addons - Copy/RD501_Main/XEH_postinit.sqf

@@ -140,4 +140,17 @@ if(hasInterface) then {
 
 ["rd501_volatile_create", {
 	_this call rd501_fnc_volatile_create;
+}] call CBA_fnc_addEventHandler;
+
+// Shield
+["rd501_shield_destroy", {
+	_this call rd501_fnc_shield_onDestroy;
+}] call CBA_fnc_addEventHandler;
+
+["rd501_shield_lowHealth", {
+	_this call rd501_fnc_shield_onLowHealth;
+}] call CBA_fnc_addEventHandler;
+
+["rd501_shield_normalHealth", {
+	_this call rd501_fnc_shield_onNormalHealth;
 }] call CBA_fnc_addEventHandler;

+ 10 - 0
addons - Copy/RD501_Main/XEH_preInit.sqf

@@ -160,4 +160,14 @@ macro_prep_xeh(volatile\fnc_volatile_handleDamage.sqf,volatile_handleDamage)
 // Map Markers
 macro_prep_xeh(map_markers\fnc_placeDotMarkerAtSelf.sqf,placeDotMarkerAtSelf)
 
+// Shield
+macro_prep_xeh(shield\fnc_shield_checkState.sqf,shield_checkState)
+macro_prep_xeh(shield\fnc_shield_getTextureSet.sqf,shield_getTextureSet)
+macro_prep_xeh(shield\fnc_shield_init.sqf,shield_init)
+macro_prep_xeh(shield\fnc_shield_onDestroy.sqf,shield_onDestroy)
+macro_prep_xeh(shield\fnc_shield_onHit.sqf,shield_onHit)
+macro_prep_xeh(shield\fnc_shield_onLowHealth.sqf,shield_onLowHealth)
+macro_prep_xeh(shield\fnc_shield_onNormalHealth.sqf,shield_onNormalHealth)
+macro_prep_xeh(shield\fnc_shield_regenPerFrameHandler.sqf,shield_regenPerFrameHandler)
+
 diag_log "RD501 PREP Complete";

+ 48 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_checkState.sqf

@@ -0,0 +1,48 @@
+params["_shield"];
+
+if(_shield isEqualTo objNull) exitWith {
+	diag_log format["[RD501][Shield] Specified shield is null while checking state"];
+};
+
+private _maxHealth = _shield getVariable ["rd501_shield_maxHealth", false];
+private _currentHealth = _shield getVariable ["rd501_shield_currentHealth", false];
+private _isLowHealth = _shield getVariable ["rd501_shield_isLowHealth", false];
+private _lowHealthPercentage = _shield getVariable ["rd501_shield_lowHealthPercentage", 20];
+private _threshold = _maxHealth * (_lowHealthPercentage/100);
+private _type = _shield getVariable ["rd501_shield_type", "REPUBLIC"];
+
+if(_isLowHealth) exitWith {
+	if(_currentHealth >= _threshold) then {
+		_shield setVariable["rd501_shield_isLowHealth", false];
+		
+		private _jipId = _shield getVariable ["rd501_shield_stateJipId", false];
+		if(_jipId isEqualTo false) then {
+			_jipId = ["rd501_shield_normalHealth",[_shield, _type]] call CBA_fnc_globalEventJIP;
+			_shield setVariable ["rd501_shield_stateJipId", _jipId, true];
+			[_jipId, _shield] call CBA_fnc_removeGlobalEventJIP;
+		}
+		else
+		{
+			["rd501_shield_normalHealth",[_shield, _type], _jipId] call CBA_fnc_globalEventJIP;
+			[_jipId, _shield] call CBA_fnc_removeGlobalEventJIP;
+		};
+	};
+};
+
+if!(_isLowHealth) exitWith {
+	if(_currentHealth < _threshold) then {
+		_shield setVariable["rd501_shield_isLowHealth", true];
+
+		private _jipId = _shield getVariable ["rd501_shield_stateJipId", false];
+		if(_jipId isEqualTo false) then {
+			_jipId = ["rd501_shield_normalHealth",[_shield, _type]] call CBA_fnc_globalEventJIP;
+			_shield setVariable ["rd501_shield_stateJipId", _jipId, true];
+			[_jipId, _shield] call CBA_fnc_removeGlobalEventJIP;
+		}
+		else
+		{
+			["rd501_shield_lowHealth",[_shield, _type], _jipId] call CBA_fnc_globalEventJIP;
+			[_jipId, _shield] call CBA_fnc_removeGlobalEventJIP;
+		};
+	};
+};

+ 27 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_getTextureSet.sqf

@@ -0,0 +1,27 @@
+params["_type"];
+
+#define REPUBLIC_LOW_HEALTH_TEXTURE "\RD501_Vehicles\static\shields\bubble\deka_shield.paa"
+#define REPUBLIC_NORMAL_TEXTURE "\RD501_Vehicles\static\shields\bubble\shield.paa"
+#define CIS_LOW_HEALTH_TEXTURE "\RD501_Vehicles\static\shields\bubble\shield.paa"
+#define CIS_NORMAL_TEXTURE "\RD501_Vehicles\static\shields\bubble\deka_shield.paa"
+
+private _lowHealthTexture = "";
+private _normalHealthTexture = "";
+
+switch (_type) do {
+	case "REPUBLIC": {
+		_lowHealthTexture = REPUBLIC_LOW_HEALTH_TEXTURE;
+		_normalHealthTexture = REPUBLIC_NORMAL_TEXTURE;
+	};
+	case "CIS": {
+		_lowHealthTexture = CIS_LOW_HEALTH_TEXTURE;
+		_normalHealthTexture = CIS_NORMAL_TEXTURE;
+	};
+	default {
+		diag_log format["[RD501][Shield] Invalid type '%1' specified, defaulting to 'REPUBLIC'", _type];
+		_lowHealthTexture = REPUBLIC_LOW_HEALTH_TEXTURE;
+		_normalHealthTexture = REPUBLIC_NORMAL_TEXTURE;
+	};
+};
+
+[_lowHealthTexture, _normalHealthTexture];

+ 85 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_init.sqf

@@ -0,0 +1,85 @@
+params["_target"];
+if(_target isEqualTo objNull) exitWith {
+	diag_log format["[RD501][Shield] Unable to create shield on '%1'", _target]; 
+};
+if!(local _target) exitWith {
+	diag_log format["[RD501][Shield] Unable to create shield on '%1' :: It is not local", _target]; 
+};
+
+diag_log format["[RD501][Shield] Creating shield for '%1'", _target];
+private _className = typeOf _target;
+private _config = configFile >> "CfgVehicles" >> _className; 
+if!(isClass _config) exitWith { 
+	diag_log format["[RD501][Shield] Unable to find class '%1' in CfgVehicles", _className]; 
+}; 
+
+#define DEFAULT_HEALTH 1000
+#define DEFAULT_REGEN_PER_SECOND 10
+#define DEFAULT_REGEN_DELAY_SECONDS 5
+#define DEFAULT_SIDE "REPUBLIC"
+#define LOW_HEALTH_PERCENTAGE 20
+
+private _isValid = getNumber (_config >> "rd501_shield_isShield");
+
+if!(_isValid isEqualTo 1) exitWith {
+	diag_log format["[RD501][Shield] Shield is not activated (rd501_shield_isShield=1 is not specified on '%1')", _className]; 
+};
+
+private _hasHealth = isNumber (_config >> "rd501_shield_health");
+private _health = DEFAULT_HEALTH;
+if(_hasHealth) then {
+	_health = getNumber (_config >> "rd501_shield_health");
+};
+
+private _hasLowHealthPercentage = isNumber (_config >> "rd501_shield_lowHealthPercentage");
+private _lowHealthPercentage = LOW_HEALTH_PERCENTAGE;
+if(_hasLowHealthPercentage) then {
+	_lowHealthPercentage = getNumber (_config >> "rd501_shield_lowHealthPercentage");
+};
+
+private _hasRegenAmount = isNumber (_config >> "rd501_shield_regenPerSecond");
+private _regenAmount = DEFAULT_REGEN_PER_SECOND;
+if(_hasRegenAmount) then {
+	_regenAmount = getNumber (_config >> "rd501_shield_regenPerSecond");
+};
+
+private _hasRegenDelay = isNumber (_config >> "rd501_shield_regenDelay");
+private _regenDelay = DEFAULT_REGEN_DELAY_SECONDS;
+if(_hasRegenDelay) then {
+	_regenDelay = getNumber (_config >> "rd501_shield_regenDelay");
+};
+
+private _hasType = isText (_config >> "rd501_shield_type");
+private _type = DEFAULT_SIDE;
+if(_hasType) then {
+	_type = getText (_config >> "rd501_shield_type");
+};
+
+diag_log format["[RD501][Shield] Loading '%1' texture set", _side];
+
+private _textures = [_type] call rd501_fnc_shield_getTextureSet;
+_textures params["_lowHealthTexture", "_normalHealthTexture"];
+
+_target setVariable ["rd501_shield_maxHealth", _health];
+_target setVariable ["rd501_shield_currentHealth", _health];
+_target setVariable ["rd501_shield_regenPerSecond", _regenAmount];
+_target setVariable ["rd501_shield_regenDelay", _regenDelay];
+_target setVariable ["rd501_shield_type", _type];
+_target setVariable ["rd501_shield_lowHealthPercentage", _lowHealthPercentage];
+_target setVariable ["rd501_shield_isLowHealth", false];
+_target setVariable ["rd501_shield_regenStartsAt", diag_tickTime];
+_target setVariable ["rd501_shield_stateJipId", false];
+
+_pfhId = [
+	{
+		params["_shield"];
+		[_shield] call rd501_fnc_shield_regenPerFrameHandler;
+	},
+	1,
+	[_target]
+] call CBA_fnc_addPerFrameHandler;
+_target setVariable["rd501_shield_pfhId", _pfhId];
+
+private _ehId = _target addEventHandler["HitPart", {
+	_this call rd501_fnc_shield_onHit;
+}];

+ 2 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_onDestroy.sqf

@@ -0,0 +1,2 @@
+params["_shield"];
+deleteVehicle _shield;

+ 26 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_onHit.sqf

@@ -0,0 +1,26 @@
+(_this select 0) params ["_target", "_shooter", "_projectile", "_position", "_velocity", "_selection", "_ammo", "_vector", "_radius", "_surfaceType", "_isDirect"];
+
+if(_target isEqualTo objNull) exitWith { systemChat "Target is null idk why"; }; 
+
+private _health = _target getVariable ["rd501_shield_currentHealth", false];
+
+if(_health isEqualTo false) exitWith { systemChat "Health not found"; };
+
+_ammo params ["_directHit", "_indirectHit", "_indirectRange", "_explosionHit", "_ammoClass"];
+private _hit = _directHit + (_indirectHit/(_indirectRange max 0.1)) + _explosionHit;
+private _result = _health - _hit;
+
+if(_result <= 0) then {
+	_target setVariable ["rd501_shield_currentHealth", _result, true];
+	private _ehId = _target getVariable ["rd501_shield_ehId", -1];
+	["rd501_shield_destroy", [_target], _target] call cba_fnc_targetEvent;
+	_target  removeEventHandler ["HitPart", _ehId];
+}
+else
+{
+	// Set locally only to reduce network traffic
+	_target setVariable ["rd501_shield_currentHealth", _result];
+	[_shield] call rd501_fnc_shield_checkState;
+	private _delay = _target getVariable["rd501_shield_regenDelay", 5];
+	_target setVariable ["rd501_shield_regenStartsAt", diag_tickTime + _delay];
+};

+ 4 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_onLowHealth.sqf

@@ -0,0 +1,4 @@
+params["_shield", "_type"];
+
+private _textures = [_type] call rd501_fnc_shield_getTextureSet;
+_shield setObjectTexture [0, _textures select 0];

+ 4 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_onNormalHealth.sqf

@@ -0,0 +1,4 @@
+params["_shield", "_type"];
+
+private _textures = [_type] call rd501_fnc_shield_getTextureSet;
+_shield setObjectTexture [0, _textures select 1];

+ 21 - 0
addons - Copy/RD501_Main/functions/shield/fnc_shield_regenPerFrameHandler.sqf

@@ -0,0 +1,21 @@
+params["_args", "_handle"];
+_args params["_shield"];
+
+if(_shield isEqualTo objNull || !alive _shield) exitWith {
+	[_handle] call CBA_fnc_removePerFrameHandler;
+};
+
+private _regenDelayTime = _shield getVariable ["rd501_shield_regenStartsAt", diag_tickTime];;
+if(diag_tickTime < _regenDelayTime) exitWith { };
+
+private _maxHealth = _shield getVariable["rd501_shield_maxHealth", 100];
+private _currentHealth = _shield getVariable["rd501_shield_currentHealth", 100];
+private _regenAmount = _shield getVariable ["rd501_shield_regenPerSecond", 0];
+
+if(_currentHealth isEqualTo _maxHealth) exitWith { };
+
+private _newHealth = (_currentHealth + _regenAmount) min _maxHealth;
+
+_shield setVariable["rd501_shield_currentHealth", _newHealth];
+
+[_shield] call rd501_fnc_shield_checkState;

+ 1 - 0
addons - Copy/RD501_Vehicles/static/shields/config.cpp

@@ -57,6 +57,7 @@ class CfgVehicles
 		rd501_fired_deployable_endSound = "rd501_squad_shield_end";
 		rd501_fired_deployable_endDuration = 1;
 		rd501_fired_deployable_soundDistance = 300;
+		rd501_shield_isShield=1;
 		vehicleClass = macro_editor_vehicle_type(statics)
 		editorCategory =  macro_editor_cat(statics)
 		editorSubcategory = macro_editor_cat(static_msc)