From ac67e45098233b30ef678731307537a0d47f74ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Sat, 14 Feb 2015 16:22:02 -0300 Subject: [PATCH] overheating: sync weapon temperature across the net, deterministic pseudo-random bullet dispersion --- addons/overheating/CfgEventHandlers.hpp | 2 +- addons/overheating/XEH_postInit.sqf | 46 +++-- addons/overheating/XEH_preInit.sqf | 1 + addons/overheating/functions/fnc_firedEH.sqf | 163 ++++++++++++++++++ addons/overheating/functions/fnc_overheat.sqf | 132 +------------- 5 files changed, 204 insertions(+), 140 deletions(-) create mode 100644 addons/overheating/functions/fnc_firedEH.sqf diff --git a/addons/overheating/CfgEventHandlers.hpp b/addons/overheating/CfgEventHandlers.hpp index f06e95788e..f419ff8d06 100644 --- a/addons/overheating/CfgEventHandlers.hpp +++ b/addons/overheating/CfgEventHandlers.hpp @@ -13,7 +13,7 @@ class Extended_PostInit_EventHandlers { class Extended_FiredBIS_EventHandlers { class CAManBase { class GVAR(Overheat) { - clientFiredBIS = QUOTE( if (_this select 0 == ACE_player) then {_this call FUNC(overheat)}; ); + firedBIS = QUOTE(_this call FUNC(firedEH)); }; }; }; diff --git a/addons/overheating/XEH_postInit.sqf b/addons/overheating/XEH_postInit.sqf index c1212af0e8..cf7005e385 100644 --- a/addons/overheating/XEH_postInit.sqf +++ b/addons/overheating/XEH_postInit.sqf @@ -1,21 +1,35 @@ -// by esteldunedain +// by CAA-Picard #include "script_component.hpp" -if (!hasInterface) exitWith {}; +GVAR(pseudoRandomList) = []; +if (isServer) then { + // Construct a list of pseudo random 2D vectors + for "_i" from 0 to 30 do { + GVAR(pseudoRandomList) pushBack [-1 + random 2, -1 + random 2]; + }; + publicVariable QGVAR(pseudoRandomList); +}; + + +if !(hasInterface) exitWith {}; // Add keybinds -["ACE3 Weapons", QGVAR(unjamWeapon), localize LSTRING(UnjamWeapon), -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if !([ACE_player] call EFUNC(common,canUseWeapon) && - {currentWeapon ACE_player in (ACE_player getVariable [QGVAR(jammedWeapons), []])} - ) exitWith {false}; +["ACE3", + localize "STR_ACE_Overheating_UnjamWeapon", + { + // Conditions: canInteract + _exceptions = []; + if !(_exceptions call EGVAR(common,canInteract)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call EFUNC(common,canUseWeapon) && + {currentWeapon ACE_player in (ACE_player getVariable [QGVAR(jammedWeapons), []])} + ) exitWith {false}; - // Statement - [ACE_player, currentMuzzle ACE_player, false] call FUNC(clearJam); - true -}, -{false}, -[19, [true, false, false]], false] call CBA_fnc_addKeybind; //R Key + // Statement + [ACE_player, currentMuzzle ACE_player, false] call FUNC(clearJam); + true + }, + [19, [true, false, false]], + false, + "keydown" +] call cba_fnc_registerKeybind; diff --git a/addons/overheating/XEH_preInit.sqf b/addons/overheating/XEH_preInit.sqf index 2bd256087b..36a2c86b7e 100644 --- a/addons/overheating/XEH_preInit.sqf +++ b/addons/overheating/XEH_preInit.sqf @@ -6,6 +6,7 @@ PREP(checkTemperature); PREP(clearJam); PREP(cooldown); PREP(displayTemperature); +PREP(firedEH); PREP(jamWeapon); PREP(overheat); PREP(swapBarrel); diff --git a/addons/overheating/functions/fnc_firedEH.sqf b/addons/overheating/functions/fnc_firedEH.sqf new file mode 100644 index 0000000000..d3254306cc --- /dev/null +++ b/addons/overheating/functions/fnc_firedEH.sqf @@ -0,0 +1,163 @@ +/* + * Author: Commy2 and CAA-Picard + * Handle weapon fire + * + * Argument: + * 0: Unit + * 1: Weapon + * 3: Muzzle + * 4: Ammo + * 5: Magazine + * 6: Projectile + * + * Return value: + * None + * + * Public: No + */ +#include "\z\ace\addons\overheating\script_component.hpp" + +private ["_unit", "_weapon", "_ammo", "_projectile"]; +_unit = _this select 0; + +// Exit if the unit isn't a player +if !([_unit] call EFUNC(common,isPlayer)) exitWith {}; + +_weapon = _this select 1; + +// Compute new temperature if the unit is the local player +if (_unit == ACE_player) then { + _this call FUNC(overheat); +}; + +// Get current temperature from the unit variable +_variableName = format [QGVAR(%1), _weapon]; +_scaledTemperature = (((_unit getVariable [_variableName, [0,0]]) select 0) / 1000) min 1 max 0; + +// Smoke SFX, beginning at TEMP 0.15 +private "_intensity"; + +_intensity = (_scaledTemperature - 0.2) * 1.25; +if (_intensity > 0) then { + private ["_position", "_direction"]; + + _position = position _projectile; + _direction = (_unit weaponDirection _weapon) vectorMultiply 0.25; + + drop [ + "\A3\data_f\ParticleEffects\Universal\Refract", + "", + "Billboard", + 1.1, + 2, + _position, + _direction, + 1, + 1.2, + 1.0, + 0.1, + [0.1,0.15], + [[0.06,0.06,0.06,0.32*_scaledTemperature], [0.3,0.3,0.3,0.28*_scaledTemperature], [0.3,0.3,0.3,0.25*_scaledTemperature], [0.3,0.3,0.3,0.22*_scaledTemperature], [0.3,0.3,0.3,0.1*_scaledTemperature]], + [1,0], + 0.1, + 0.05, + "", + "", + "" + ]; + + _intensity = (_scaledTemperature - 0.5) * 2; + if (_intensity > 0) then { + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 12, 1, 16], + "", + "Billboard", + 1, + 1.2, + _position, + [0,0,0.25], + 0, + 1.275, + 1, + 0.025, + [0.28,0.33,0.37], + [[0.6,0.6,0.6,0.3*_intensity]], + [0.2], + 1, + 0.04, + "", + "", + "" + ]; + }; +}; + + +// Dispersion and bullet slow down +private ["_dispersion", "_slowdownFactor", "_count"]; + +_dispersion = getArray (configFile >> "CfgWeapons" >> _weapon >> "ACE_Overheating_Dispersion"); + +_count = count _dispersion; +if (_count > 0) then { + _dispersion = ([_dispersion, (_count - 1) * _scaledTemperature] call EFUNC(common,interpolateFromArray)) max 0; +} else { + _dispersion = 0; +}; + +_slowdownFactor = getArray (configFile >> "CfgWeapons" >> _weapon >> "ACE_Overheating_slowdownFactor"); + +_count = count _slowdownFactor; +if (_count > 0) then { + _slowdownFactor = ([_slowdownFactor, (_count - 1) * _scaledTemperature] call EFUNC(common,interpolateFromArray)) max 0; +} else { + _slowdownFactor = 1; +}; + + +// Exit if GVAR(pseudoRandomList) isn't synced yet +if (count GVAR(pseudoRandomList) == 0) exitWith {}; + +// Get the pseudo random values for dispersion from the remaining ammo count +private "_pseudoRandomPair"; +_pseudoRandomPair = GVAR(pseudoRandomList) select ((_unit ammo _weapon) mod count GVAR(pseudoRandomList)); + +[_projectile, (_pseudoRandomPair select 0) * _dispersion, (_pseudoRandomPair select 1) * _dispersion, (_slowdownFactor - 1) * vectorMagnitude _velocity] call EFUNC(common,changeProjectileDirection); + + + +// Only compute jamming for the local player +if (_unit != ACE_player) exitWith {}; + +private "_jamChance"; +_jamChance = getArray (configFile >> "CfgWeapons" >> _weapon >> "ACE_Overheating_jamChance"); + +_count = count _jamChance; +if (_count == 0) then { + _jamChance = [0]; + _count = 1; +}; + +_jamChance = [_jamChance, (_count - 1) * _scaledTemperature] call EFUNC(common,interpolateFromArray); + +// increase jam chance on dusty grounds if prone +if (stance _unit == "PRONE") then { + private "_surface"; + _surface = toArray (surfaceType getPosASL _unit); + _surface deleteAt 0; + + _surface = configFile >> "CfgSurfaces" >> toString _surface; + if (isClass _surface) then { + _jamChance = _jamChance + (getNumber (_surface >> "dust")) * _jamChance; + }; +}; + +if ("Jam" in (missionNamespace getvariable ["ACE_Debug", []])) then { + _jamChance = 0.5; +}; + +["Overheating", [_temperature, _jamChance], {format ["Temperature: %1 - JamChance: %2", _this select 0, _this select 1]}] call EFUNC(common,log); + +if (random 1 < _jamChance) then { + [_unit, _weapon] call FUNC(jamWeapon); +}; diff --git a/addons/overheating/functions/fnc_overheat.sqf b/addons/overheating/functions/fnc_overheat.sqf index 6680b759c4..37c5e3ab29 100644 --- a/addons/overheating/functions/fnc_overheat.sqf +++ b/addons/overheating/functions/fnc_overheat.sqf @@ -1,5 +1,5 @@ /* - * Author: Commy2 and esteldunedain + * Author: Commy2 and CAA-Picard * Handle weapon fire, heat up the weapon * * Argument: @@ -17,8 +17,7 @@ */ #include "\z\ace\addons\overheating\script_component.hpp" -private ["_unit", "_weapon", "_ammo", "_projectile", "_velocity", "_variableName", "_overheat", "_temperature", "_time", "_bulletMass", "_energyIncrement", "_barrelMass", "_scaledTemperature", "_intensity", "_position", "_direction", "_dispersion", "_count", "_slowdownFactor", "_jamChance", "_surface"]; - +private ["_unit", "_weapon", "_ammo", "_projectile"]; _unit = _this select 0; _weapon = _this select 1; _ammo = _this select 4; @@ -26,6 +25,8 @@ _projectile = _this select 6; _velocity = velocity _projectile; +private ["_variableName", "_overheat", "_temperature", "_time", "_energyIncrement", "_barrelMass"]; + // each weapon has it's own variable. Can't store the temperature in the weapon since they are not objects unfortunately. _variableName = format [QGVAR(%1), _weapon]; @@ -37,134 +38,19 @@ _time = _overheat select 1; // Get physical parameters _bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass"); if (_bulletMass == 0) then { - // If the bullet mass is not configured, estimate it directly in grams + // If the bullet mass is not configured, estimate it _bulletMass = 3.4334 + 0.5171 * (getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber")); }; _energyIncrement = 0.75 * 0.0005 * _bulletMass * (vectorMagnitudeSqr _velocity); _barrelMass = 0.50 * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; // Calculate cooling -_temperature = [_temperature, _barrelMass, ACE_time - _time] call FUNC(cooldown); +_temperature = [_temperature, _barrelMass, time - _time] call FUNC(cooldown); // Calculate heating _temperature = _temperature + _energyIncrement / (_barrelMass * 466); // Steel Heat Capacity = 466 J/(Kg.K) // set updated values -_time = ACE_time; -_unit setVariable [_variableName, [_temperature, _time], false]; -_scaledTemperature = (_temperature / 1000) min 1 max 0; +_time = time; -// Smoke SFX, beginning at TEMP 0.15 -private "_intensity"; - -_intensity = (_scaledTemperature - 0.2) * 1.25; -if (_intensity > 0) then { - private ["_position", "_direction"]; - - _position = position _projectile; - _direction = (_unit weaponDirection _weapon) vectorMultiply 0.25; - - drop [ - "\A3\data_f\ParticleEffects\Universal\Refract", - "", - "Billboard", - 1.1, - 2, - _position, - _direction, - 1, - 1.2, - 1.0, - 0.1, - [0.1,0.15], - [[0.06,0.06,0.06,0.32*_scaledTemperature], [0.3,0.3,0.3,0.28*_scaledTemperature], [0.3,0.3,0.3,0.25*_scaledTemperature], [0.3,0.3,0.3,0.22*_scaledTemperature], [0.3,0.3,0.3,0.1*_scaledTemperature]], - [1,0], - 0.1, - 0.05, - "", - "", - "" - ]; - - _intensity = (_scaledTemperature - 0.5) * 2; - if (_intensity > 0) then { - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 12, 1, 16], - "", - "Billboard", - 1, - 1.2, - _position, - [0,0,0.25], - 0, - 1.275, - 1, - 0.025, - [0.28,0.33,0.37], - [[0.6,0.6,0.6,0.3*_intensity]], - [0.2], - 1, - 0.04, - "", - "", - "" - ]; - }; -}; - - -// dispersion and bullet slow down -private ["_dispersion", "_slowdownFactor", "_count"]; - -_dispersion = getArray (configFile >> "CfgWeapons" >> _weapon >> "ACE_Overheating_Dispersion"); - -_count = count _dispersion; -if (_count > 0) then { - _dispersion = ([_dispersion, (_count - 1) * _scaledTemperature] call EFUNC(common,interpolateFromArray)) max 0; -} else { - _dispersion = 0; -}; - -_slowdownFactor = getArray (configFile >> "CfgWeapons" >> _weapon >> "ACE_Overheating_slowdownFactor"); - -_count = count _slowdownFactor; -if (_count > 0) then { - _slowdownFactor = ([_slowdownFactor, (_count - 1) * _scaledTemperature] call EFUNC(common,interpolateFromArray)) max 0; -} else { - _slowdownFactor = 1; -}; - -[_projectile, _dispersion - 2 * random _dispersion, _dispersion - 2 * random _dispersion, (_slowdownFactor - 1) * vectorMagnitude _velocity] call EFUNC(common,changeProjectileDirection); - - -// jamming -private "_jamChance"; - -_jamChance = getArray (configFile >> "CfgWeapons" >> _weapon >> "ACE_Overheating_jamChance"); - -_count = count _jamChance; -if (_count == 0) then { - _jamChance = [0]; - _count = 1; -}; - -_jamChance = [_jamChance, (_count - 1) * _scaledTemperature] call EFUNC(common,interpolateFromArray); - -// increase jam chance on dusty grounds if prone -if (stance _unit == "PRONE") then { - private "_surface"; - _surface = toArray (surfaceType getPosASL _unit); - _surface deleteAt 0; - - _surface = configFile >> "CfgSurfaces" >> toString _surface; - if (isClass _surface) then { - _jamChance = _jamChance + (getNumber (_surface >> "dust")) * _jamChance; - }; -}; - -if ("Jam" in (missionNamespace getVariable ["ACE_Debug", []])) then { - _jamChance = 0.5; -}; - -if (random 1 < _jamChance) then { - [_unit, _weapon] call FUNC(jamWeapon); -}; +// Publish the variable +[_unit, _variableName, [_temperature, _time], 2.0] call EFUNC(common,setVariablePublic);