Modernize code

This commit is contained in:
PabstMirror 2015-12-15 01:09:26 -06:00
parent 3020023f58
commit e587a6e6e3
20 changed files with 303 additions and 470 deletions

View File

@ -3,7 +3,20 @@ class ACE_Settings {
typeName = "BOOL"; typeName = "BOOL";
isClientSettable = 1; isClientSettable = 1;
value = 1; value = 1;
displayName = CSTRING(SettingDisplayTextName); displayName = CSTRING(DisplayTextOnJam_displayName);
description = CSTRING(SettingDisplayTextDesc); description = CSTRING(DisplayTextOnJam_description);
};
class GVAR(showParticleEffects) {
typeName = "BOOL";
isClientSettable = 1;
value = 0;
displayName = CSTRING(showParticleEffects_displayName);
description = CSTRING(showParticleEffects_description);
};
class GVAR(overheatingDispersion) {
typeName = "BOOL";
value = 1;
displayName = CSTRING(overheatingDispersion_displayName);
description = CSTRING(overheatingDispersion_description);
}; };
}; };

View File

@ -21,7 +21,7 @@ class Extended_FiredBIS_EventHandlers {
class Extended_Take_EventHandlers { class Extended_Take_EventHandlers {
class CAManBase { class CAManBase {
class GVAR(UnjamReload) { class GVAR(UnjamReload) {
clientTake = QUOTE( if (_this select 0 == ACE_player && {(_this select 1) in [ARR_3(uniformContainer (_this select 0), vestContainer (_this select 0), backpackContainer (_this select 0))]} && {_this select 2 == currentMagazine (_this select 0)}) then {_vehicle = vehicle (_this select 0); [ARR_3(_vehicle, currentWeapon _vehicle, true)] call FUNC(clearJam)}; ); clientTake = QUOTE( _this call FUNC(handleTakeEH) );
}; };
}; };
}; };

View File

@ -13,137 +13,15 @@ class CfgWeapons {
}; };
}; };
class Rifle; class RifleCore;
class Rifle_Base_F : Rifle { class Rifle: RifleCore {
//Mean Rounds Between Stoppages (this will be scaled based on the barrel temp)
ACE_MRBS = 3000; ACE_MRBS = 3000;
ACE_Dispersion = 0;
//Dispersion Factor (this will be scaled based on the barrel temp)
ACE_Dispersion = 1;
//Slowdown Factor (this will be scaled based on the barrel temp)
ACE_SlowdownFactor = 1; ACE_SlowdownFactor = 1;
// Dispersion, SlowdownFactor and JamChance arrays have 4 values for different temperatures, which are interpolated between.
// These values correspond to temperatures Converted to real life values: 0: 0°C, 1: 333°C, 2: 666°C, 3: 1000°C.
// Dispersion in radians. First value is for temp. 0, second for temp. 1 and so on. Values inbetween get interpolated. Negative values get ignored and can be used to move the starting point to hotter temperatures.
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
// How much the projectile gets slowed down before leaving the barrel. 0.9 means the bullet will lose 10% velocity. Values inbetween get interpolated. Numbers greater 1 increase the velocity, smaller 1 decrease it.
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
// Chance to jam the weapon. 0.0003 means 3 malfunctions on 10,000 rounds fired at this temperature. Values inbetween get interpolated. Negative values get ignored and can be used to move the starting point to hotter temperatures.
// When no reliable data exists for temperature vs. jam chance except MRBS, the following uniform criteria was adopted: [0, 1/MRBS, 5/MRBS, 25/MRBS].
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class Rifle_Long_Base_F : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class arifle_MX_Base_F : Rifle_Base_F {
ACE_clearJamAction = "GestureReloadMX"; // Custom jam clearing action. Default uses reload animation.
ACE_checkTemperatureAction = "Gear"; // Custom check temperature action. Default uses gear animation.
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class MMG_02_base_F: Rifle_Long_Base_F {
ACE_Overheating_allowSwapBarrel = 1;
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class MMG_01_base_F: Rifle_Long_Base_F {
ACE_Overheating_allowSwapBarrel = 1;
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class arifle_MX_SW_F : arifle_MX_Base_F {
ACE_clearJamAction = ""; // Custom jam clearing action. Use empty string to undefine.
ACE_Overheating_allowSwapBarrel = 1; // 1 to enable barrel swap. 0 to disable. Meant for machine guns where you can easily swap the barrel without dismantling the whole weapon.
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class arifle_Katiba_Base_F : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class mk20_base_F : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class Tavor_base_F : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class SDAR_base_F : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class EBR_base_F : Rifle_Long_Base_F {
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class DMR_01_base_F : Rifle_Long_Base_F {
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class GM6_base_F : Rifle_Long_Base_F {
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class LRR_base_F : Rifle_Long_Base_F {
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class LMG_Mk200_F : Rifle_Long_Base_F {
ACE_Overheating_allowSwapBarrel = 1;
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class LMG_Zafir_F : Rifle_Long_Base_F {
ACE_Overheating_allowSwapBarrel = 1;
ACE_Overheating_Dispersion[] = {0, -0.001, 0.001, 0.003};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class SMG_01_Base : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class SMG_02_base_F : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
};
class pdw2000_base_F : Rifle_Base_F {
ACE_Overheating_Dispersion[] = {0, 0.001, 0.002, 0.004};
ACE_Overheating_SlowdownFactor[] = {1, 1, 1, 0.9};
ACE_Overheating_JamChance[] = {0, 0.0003, 0.0015, 0.0075};
}; };
}; };

View File

@ -1,8 +1,8 @@
// by CAA-Picard // by esteldunedain
#include "script_component.hpp" #include "script_component.hpp"
GVAR(pseudoRandomList) = [];
if (isServer) then { if (isServer) then {
GVAR(pseudoRandomList) = [];
// Construct a list of pseudo random 2D vectors // Construct a list of pseudo random 2D vectors
for "_i" from 0 to 30 do { for "_i" from 0 to 30 do {
GVAR(pseudoRandomList) pushBack [-1 + random 2, -1 + random 2]; GVAR(pseudoRandomList) pushBack [-1 + random 2, -1 + random 2];
@ -14,12 +14,10 @@ if (isServer) then {
if !(hasInterface) exitWith {}; if !(hasInterface) exitWith {};
// Add keybinds // Add keybinds
["ACE3", ["ACE3 Weapons", QGVAR(unjamWeapon), localize LSTRING(UnjamWeapon),
localize "STR_ACE_Overheating_UnjamWeapon",
{ {
// Conditions: canInteract // Conditions: canInteract
_exceptions = []; if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false};
if !(_exceptions call EGVAR(common,canInteract)) exitWith {false};
// Conditions: specific // Conditions: specific
if !([ACE_player] call EFUNC(common,canUseWeapon) && if !([ACE_player] call EFUNC(common,canUseWeapon) &&
{currentWeapon ACE_player in (ACE_player getVariable [QGVAR(jammedWeapons), []])} {currentWeapon ACE_player in (ACE_player getVariable [QGVAR(jammedWeapons), []])}
@ -29,7 +27,5 @@ if !(hasInterface) exitWith {};
[ACE_player, currentMuzzle ACE_player, false] call FUNC(clearJam); [ACE_player, currentMuzzle ACE_player, false] call FUNC(clearJam);
true true
}, },
[19, [true, false, false]], {false},
false, [19, [true, false, false]], false] call CBA_fnc_addKeybind; //SHIFT + R Key
"keydown"
] call cba_fnc_registerKeybind;

View File

@ -6,6 +6,7 @@ PREP(checkTemperature);
PREP(clearJam); PREP(clearJam);
PREP(displayTemperature); PREP(displayTemperature);
PREP(firedEH); PREP(firedEH);
PREP(handleTakeEH);
PREP(jamWeapon); PREP(jamWeapon);
PREP(overheat); PREP(overheat);
PREP(swapBarrel); PREP(swapBarrel);

View File

@ -20,17 +20,5 @@ class CfgPatches {
#include "CfgWeapons.hpp" #include "CfgWeapons.hpp"
class ACE_Settings { #include "ACE_Settings.hpp"
class GVAR(DisplayTextOnJam) {
typeName = "BOOL";
isClientSettable = 1;
value = 1;
displayName = "$STR_ACE_overheating_SettingDisplayTextName";
description = "$STR_ACE_overheating_SettingDisplayTextDesc";
};
class GVAR(enableRefractEffect) {
typeName = "BOOL";
value = 0;
};
};

View File

@ -10,18 +10,17 @@
* None * None
* *
* Example: * Example:
* None * [player, currentWeapon player] call ace_overheating_fnc_checkTemperature
* *
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
EXPLODE_2_PVT(_this,_player,_weapon); params ["_player", "_weapon"];
TRACE_2("params",_player,_weapon);
private ["_action"];
// Play animation and report temperature // Play animation and report temperature
_action = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_checkTemperatureAction"); private _action = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_checkTemperatureAction");
if (_action == "") then { if (_action == "") then {
_action = "Gear"; _action = "Gear";
@ -29,5 +28,5 @@ if (_action == "") then {
_player playActionNow _action; _player playActionNow _action;
// Launch a PFH that waits a sec before displaying the temperature // Waits a sec before displaying the temperature
[FUNC(displayTemperature), [_player, _weapon], 1.0, 0] call EFUNC(common,waitAndExecute); [FUNC(displayTemperature), [_player, _weapon], 1.0] call EFUNC(common,waitAndExecute);

View File

@ -10,32 +10,32 @@
* Return Value: * Return Value:
* None * None
* *
* Example:
* [player, currentWeapon player, false] call ace_overheating_fnc_clearJam
*
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
EXPLODE_3_PVT(_this,_unit,_weapon,_skipAnim); params ["_unit", "_weapon", "_skipAnim"];
TRACE_3("params",_unit,_weapon,_skipAnim);
private ["_jammedWeapons"]; private _jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
_jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
if (_weapon in _jammedWeapons) then { if (_weapon in _jammedWeapons) then {
_jammedWeapons = _jammedWeapons - [_weapon]; _jammedWeapons = _jammedWeapons - [_weapon];
_unit setVariable [QGVAR(jammedWeapons), _jammedWeapons]; _unit setVariable [QGVAR(jammedWeapons), _jammedWeapons];
if (count _jammedWeapons == 0) then { if (_jammedWeapons isEqualTo []) then {
private "_id"; private _id = _unit getVariable [QGVAR(JammingActionID), -1];
_id = _unit getVariable [QGVAR(JammingActionID), -1];
[_unit, "DefaultAction", _id] call EFUNC(common,removeActionEventHandler); [_unit, "DefaultAction", _id] call EFUNC(common,removeActionEventHandler);
_unit setVariable [QGVAR(JammingActionID), -1]; _unit setVariable [QGVAR(JammingActionID), -1];
}; };
if !(_skipAnim) then { if !(_skipAnim) then {
private "_clearJamAction";
_clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_clearJamAction"); private _clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_clearJamAction");
if (_clearJamAction == "") then { if (_clearJamAction == "") then {
_clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "reloadAction"); _clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "reloadAction");

View File

@ -1,48 +0,0 @@
/*
* Author: esteldunedain
* Calculate cooling down of the weapon.
*
* Argument:
* 0: Last temperature <NUMBER>
* 1: Barrel mass <NUMBER>
* 2: Time <NUMBER>
*
* Return value:
* New temperature <NUMBER>
*
* Public: No
*/
#include "\z\ace\addons\overheating\script_component.hpp"
EXPLODE_3_PVT(_this,_temperature,_barrelMass,_totalTime);
// If a long time passed since the last shot, there's no need to calculate anything; the weapon should be cool
if (_totalTime > 1800) exitWith {0};
private ["_barrelSurface", "_time", "_deltaTime"];
_barrelSurface = _barrelMass / 7850 / 0.003;
_time = 0;
while {true} do {
_deltaTime = (_totalTime - _time) min 20;
_temperature = _temperature - (
// Convective cooling
25 * _barrelSurface * _temperature
// Radiative cooling
+ 0.4 * 5.67e-8 * _barrelSurface *
( (_temperature + 273.15)*(_temperature + 273.15)
* (_temperature + 273.15)*(_temperature + 273.15)
- 273.15 * 273.15 * 273.15 *273.15 )
) * _deltaTime / (_barrelMass * 466);
if (_temperature < 1) exitWith {0};
if (isNil "_temperature") exitWith {
ACE_LOGERROR_3("_totalTime = %1; _time = %2; _deltaTime = %3;",_totalTime,_time,_deltaTime);
0
};
_time = _time + _deltaTime;
if (_time >= _totalTime) exitWith { _temperature max 0 };
};

View File

@ -9,41 +9,40 @@
* Return Values: * Return Values:
* None * None
* *
* Example:
* [player, currentWeapon player] call ace_overheating_fnc_displayTemperature
*
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
EXPLODE_2_PVT(_this,_player,_weapon); params ["_player", "_weapon"];
TRACE_2("params",_player,_weapon);
private ["_temperature", "_scaledTemperature", "_color", "_count", "_string", "_text", "_picture"];
// Calculate cool down of weapon since last shot // Calculate cool down of weapon since last shot
_temperature = [_player, _weapon, 0] call FUNC(updateTemperature); private _temperature = [_player, _weapon, 0] call FUNC(updateTemperature);
_scaledTemperature = (_temperature / 1000) min 1; private _scaledTemperature = (_temperature / 1000) min 1;
_color = [ private _color = [
2 * (_scaledTemperature * 2 min 1) min 1, 2 * (_scaledTemperature * 2 min 1) min 1,
2 * (1 - (_scaledTemperature * 2 min 1)) min 1, 2 * (1 - (_scaledTemperature * 2 min 1)) min 1,
00 00
]; ];
_count = round (12 * _scaledTemperature); private _count = round (12 * _scaledTemperature);
_string = ""; private _string = "";
for "_a" from 1 to _count do { for "_a" from 1 to _count do {
_string = _string + "|"; _string = _string + "|";
}; };
_text = [_string, _color] call EFUNC(common,stringToColoredText); private _text = [_string, _color] call EFUNC(common,stringToColoredText);
_string = ""; _string = "";
for "_a" from (_count + 1) to 12 do { for "_a" from (_count + 1) to 12 do {
_string = _string + "|"; _string = _string + "|";
}; };
_text = composeText [ _text = composeText [_text, [_string, [0.5, 0.5, 0.5]] call EFUNC(common,stringToColoredText)];
_text,
[_string, [0.5, 0.5, 0.5]] call EFUNC(common,stringToColoredText)
];
_picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture");
[_text, _picture] call EFUNC(common,displayTextPicture); [_text, _picture] call EFUNC(common,displayTextPicture);

View File

@ -3,29 +3,32 @@
* Handle weapon fire * Handle weapon fire
* *
* Argument: * Argument:
* 0: Unit <OBJECT> * 0: unit - Object the event handler is assigned to <OBJECT>
* 1: Weapon <STRING> * 1: weapon - Fired weapon <STRING>
* 3: Muzzle <STRING> * 2: muzzle - Muzzle that was used <STRING>
* 4: Ammo <STRING> * 3: mode - Current mode of the fired weapon <STRING>
* 5: Magazine <STRING> * 4: ammo - Ammo used <STRING>
* 6: Projectile <OBJECT> * 5: magazine - magazine name which was used <STRING>
* 6: projectile - Object of the projectile that was shot <OBJECT>
* *
* Return value: * Return value:
* None * None
* *
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
private ["_unit", "_weapon", "_ammo", "_projectile"]; BEGIN_COUNTER(firedEH);
_unit = _this select 0; params ["_unit", "_weapon", "_muzzle", "", "_ammo", "", "_projectile"];
_weapon = _this select 1; TRACE_5("params",_unit,_weapon,_muzzle,_ammo,_projectile);
_ammo = _this select 4;
_projectile = _this select 6;
// Exit if the unit isn't a player if (((!GVAR(overheatingDispersion)) && {_unit != ACE_player}) //If no dispersion, only run when local
if !([_unit] call EFUNC(common,isPlayer)) exitWith {}; || {!([_unit] call EFUNC(common,isPlayer))} //Ignore AI
|| {(_unit distance ACE_player) > 3000} //Ignore far away shots
|| {(_muzzle != (primaryWeapon _unit)) && {_muzzle != (handgunWeapon _unit)}}) exitWith { // Only rifle or pistol muzzles (ignore grenades / GLs)
END_COUNTER(firedEH);
};
// Compute new temperature if the unit is the local player // Compute new temperature if the unit is the local player
if (_unit == ACE_player) then { if (_unit == ACE_player) then {
@ -33,118 +36,81 @@ if (_unit == ACE_player) then {
}; };
// Get current temperature from the unit variable // Get current temperature from the unit variable
_variableName = format [QGVAR(%1), _weapon]; private _variableName = format [QGVAR(%1), _weapon];
_scaledTemperature = (((_unit getVariable [_variableName, [0,0]]) select 0) / 1000) min 1 max 0; (_unit getVariable [_variableName, [0, 0]]) params ["_temperature"];
private _scaledTemperature = linearConversion [0, 1000, _temperature, 0, 1, true];
systemChat str(_scaledTemperature);
if (time > (_unit getVariable [QGVAR(lastDrop), -1000]) + 0.40 && _scaledTemperature > 0.1) then {
_unit setVariable [QGVAR(lastDrop), time];
private ["_position", "_direction","_intensity"];
_direction = (_unit weaponDirection _weapon) vectorMultiply 0.25;
_position = (position _projectile) vectorAdd (_direction vectorMultiply (4*(random 0.30)));
if (GVAR(enableRefractEffect)) then {
// Refract SFX, beginning at temp 100º and maxs out at 500º
_intensity = (_scaledTemperature - 0.10) / 0.40 min 1;
drop [
"\A3\data_f\ParticleEffects\Universal\Refract",
"",
"Billboard",
10,
2,
_position,
_direction,
0,
1.2,
1.0,
0.1,
[0.10,0.25],
[[0.6,0.6,0.6,0.3*_intensity],[0.2,0.2,0.2,0.05*_intensity]],
[0,1],
0.1,
0.05,
"",
"",
""
];
};
// Smoke SFX, beginning at temp 150º
_intensity = (_scaledTemperature - 0.15) / 0.85;
if (_intensity > 0) then {
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 12, 1, 16],
"",
"Billboard",
10,
1.2,
_position,
[0,0,0.15],
100 + random 80,
1.275,
1,
0.025,
[0.15,0.43],
[[0.6,0.6,0.6,0.5*_intensity],[0.2,0.2,0.2,0.15*_intensity]],
[0,1],
1,
0.04,
"",
"",
""
];
};
};
TRACE_3("",_variableName,_temperature,_scaledTemperature);
// Dispersion and bullet slow down // Dispersion and bullet slow down
private ["_dispersion", "_slowdownFactor", "_count"]; if (GVAR(overheatingDispersion)) then {
private _dispersion = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ACE_Dispersion");
_dispersion = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ACE_Dispersion"); _dispersion = (_dispersion * ([[0,1,2,4], 3 * _scaledTemperature] call EFUNC(common,interpolateFromArray))) max 0;
_dispersion = ([[0*_dispersion,1*_dispersion,2*_dispersion,4*_dispersion], 3 * _scaledTemperature] call EFUNC(common,interpolateFromArray)) max 0;
_slowdownFactor = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ACE_SlowdownFactor");
private _slowdownFactor = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ACE_SlowdownFactor");
if (_slowdownFactor == 0) then {_slowdownFactor = 1}; if (_slowdownFactor == 0) then {_slowdownFactor = 1};
_slowdownFactor = _slowdownFactor * linearConversion [0.666, 1, _scaledTemperature, 0, -0.1, true];
_slowdownFactor = ([[1*_slowdownFactor,1*_slowdownFactor,1*_slowdownFactor,0.9*_slowdownFactor], 3 * _scaledTemperature] call EFUNC(common,interpolateFromArray)) max 0;
// Exit if GVAR(pseudoRandomList) isn't synced yet // Exit if GVAR(pseudoRandomList) isn't synced yet
if (count GVAR(pseudoRandomList) == 0) exitWith {}; if (isNil QGVAR(pseudoRandomList)) exitWith {ACE_LOGERROR("No pseudoRandomList sync");};
// Get the pseudo random values for dispersion from the remaining ammo count // Get the pseudo random values for dispersion from the remaining ammo count
private "_pseudoRandomPair"; (GVAR(pseudoRandomList) select ((_unit ammo _weapon) mod (count GVAR(pseudoRandomList)))) params ["_dispersionX", "_dispersionY"];
_pseudoRandomPair = GVAR(pseudoRandomList) select ((_unit ammo _weapon) mod count GVAR(pseudoRandomList));
[_projectile, (_pseudoRandomPair select 0) * _dispersion, (_pseudoRandomPair select 1) * _dispersion, (_slowdownFactor - 1) * vectorMagnitude (velocity _projectile)] call EFUNC(common,changeProjectileDirection); TRACE_4("change",_dispersion,_slowdownFactor,_dispersionX,_dispersionY);
[_projectile, _dispersionX * _dispersion, _dispersionY * _dispersion, _slowdownFactor * vectorMagnitude (velocity _projectile)] call EFUNC(common,changeProjectileDirection);
};
// ------ LOCAL PLAYER ONLY ------------
// Only compute jamming and show Visual Effects for the local player
if (_unit != ACE_player) exitWith {END_COUNTER(firedEH);};
// Only compute jamming for the local player private _jamChance = if (isNumber (configFile >> "CfgWeapons" >> _weapon >> "ACE_MRBS")) then {
if (_unit != ACE_player) exitWith {}; 1 / getNumber (configFile >> "CfgWeapons" >> _weapon >> "ACE_MRBS");
} else {
1 / 3000;
};
_jamChance = _jamChance * ([[0.5, 1.5, 7.5, 37.5], 3 * _scaledTemperature] call EFUNC(common,interpolateFromArray));
private "_jamChance"; // increase jam chance on dusty grounds if prone (and at ground level)
_jamChance = 1 / getNumber (configFile >> "CfgWeapons" >> _weapon >> "ACE_MRBS"); // arma handles division by 0 if ((stance _unit == "PRONE") && {((getPosATL _unit) select 2) < 1}) then {
private _surface = configFile >> "CfgSurfaces" >> ((surfaceType getPosASL _unit) select [1]);
_jamChance = [[0.5*_jamChance,1.5*_jamChance,7.5*_jamChance,37.5*_jamChance], 3 * _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 { if (isClass _surface) then {
TRACE_1("dust",getNumber (_surface >> "dust"));
_jamChance = _jamChance + (getNumber (_surface >> "dust")) * _jamChance; _jamChance = _jamChance + (getNumber (_surface >> "dust")) * _jamChance;
}; };
}; };
if (random 1 < _jamChance) then { TRACE_3("check for random jam",_unit,_weapon,_jamChance);
if ((random 1) < _jamChance) then {
[_unit, _weapon] call FUNC(jamWeapon); [_unit, _weapon] call FUNC(jamWeapon);
}; };
//Particle Effects:
if (GVAR(showParticleEffects) && {(ACE_time > ((_unit getVariable [QGVAR(lastDrop), -1000]) + 0.40)) && {_scaledTemperature > 0.1}}) then {
_unit setVariable [QGVAR(lastDrop), ACE_time];
private _direction = (_unit weaponDirection _weapon) vectorMultiply 0.25;
private _position = (position _projectile) vectorAdd (_direction vectorMultiply (4*(random 0.30)));
// Refract SFX, beginning at temp 100º and maxs out at 500º
private _intensity = linearConversion [0.1, 0.5, _scaledTemperature, 0, 1, true];
TRACE_3("refract",_direction,_position,_intensity);
if (_intensity > 0) then {
drop [
"\A3\data_f\ParticleEffects\Universal\Refract", "", "Billboard", 10, 2, _position, _direction, 0, 1.2, 1.0,
0.1, [0.10,0.25], [[0.6,0.6,0.6,0.3*_intensity],[0.2,0.2,0.2,0.05*_intensity]], [0,1], 0.1, 0.05, "", "", ""];
};
// Smoke SFX, beginning at temp 150º
private _intensity = linearConversion [0.15, 1, _scaledTemperature, 0, 1, true];
TRACE_3("smoke",_direction,_position,_intensity);
if (_intensity > 0) then {
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 12, 1, 16], "", "Billboard", 10, 1.2, _position,
[0,0,0.15], 100 + random 80, 1.275, 1, 0.025, [0.15,0.43], [[0.6,0.6,0.6,0.5*_intensity],[0.2,0.2,0.2,0.15*_intensity]],
[0,1], 1, 0.04, "", "", ""];
};
};
END_COUNTER(firedEH);

View File

@ -0,0 +1,28 @@
/*
* Author: ??? probably CAA-Picard / Commy2
* Handle "take" event
* I think it fixs jams when manually dragging a new magazine in from player's inventory
*
* Argument:
* 0: unit - Object the event handler is assigned to <OBJECT>
* 1: container <OBJECT>
* 2: item <STRING>
*
* Return value:
* None
*
* Public: No
*/
#include "script_component.hpp"
params ["_unit", "_container", "_item"];
TRACE_3("params",_unit,_container,_item);
if ((_unit == ACE_player)
&& {_container in [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]}
&& {_item == currentMagazine _unit}) then { //Todo: should this be any valid magazine for any jammed gun?
TRACE_1("clearing jam",currentWeapon _unit);
[_unit, currentWeapon _unit, true] call FUNC(clearJam)
};

View File

@ -9,56 +9,49 @@
* Return value: * Return value:
* None * None
* *
* Example:
* [player, currentWeapon player] call ace_overheating_fnc_jamWeapon
*
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
EXPLODE_2_PVT(_this,_unit,_weapon); params ["_unit", "_weapon"];
TRACE_2("params",_unit,_weapon);
// don't jam a weapon with no rounds left // don't jam a weapon with no rounds left
if (_unit ammo _weapon == 0) exitWith {}; private _ammo = _unit ammo _weapon;
if (_ammo == 0) exitWith {};
private ["_jammedWeapons"]; private _jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
_jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
_jammedWeapons pushBack _weapon; _jammedWeapons pushBack _weapon;
_unit setVariable [QGVAR(jammedWeapons), _jammedWeapons]; _unit setVariable [QGVAR(jammedWeapons), _jammedWeapons];
// this is to re-activate the 'DefaultAction', so you can jam a weapon while full auto shooting
_fnc_stopCurrentBurst = {
EXPLODE_2_PVT(_this,_params,_pfhId);
EXPLODE_4_PVT(_params,_unit,_weapon,_ammo,_startFrame);
// Skip the first execution of the PFH
if (diag_frameno == _startFrame) exitWith {};
// Remove the PFH on the second execution
[_pfhId] call CBA_fnc_removePerFrameHandler;
_unit setAmmo [_weapon, _ammo];
};
// Stop current burst // Stop current burst
_ammo = _unit ammo _weapon;
if (_ammo > 0) then { if (_ammo > 0) then {
_unit setAmmo [_weapon, 0]; _unit setAmmo [_weapon, 0];
[_fnc_stopCurrentBurst, 0, [_unit, _weapon, _ammo, diag_frameno]] call CBA_fnc_addPerFrameHandler; // this is to re-activate the 'DefaultAction', so you can jam a weapon while full auto shootin
[{
params ["_unit", "_weapon", "_ammo"];
_unit setAmmo [_weapon, _ammo];
}, [_unit, _weapon, _ammo]] call EFUNC(common,execNextFrame);
}; };
// only display the hint once, after you try to shoot an already jammed weapon // only display the hint once, after you try to shoot an already jammed weapon
GVAR(knowAboutJam) = false; GVAR(knowAboutJam) = false;
if (_unit getVariable [QGVAR(JammingActionID), -1] == -1) then { if (_unit getVariable [QGVAR(JammingActionID), -1] == -1) then {
private ["_condition", "_statement", "_condition2", "_statement2", "_id"];
_condition = { private _condition = {
[_this select 1] call EFUNC(common,canUseWeapon) [_this select 1] call EFUNC(common,canUseWeapon)
&& {currentMuzzle (_this select 1) in ((_this select 1) getVariable [QGVAR(jammedWeapons), []])} && {currentMuzzle (_this select 1) in ((_this select 1) getVariable [QGVAR(jammedWeapons), []])}
&& {!(currentMuzzle (_this select 1) in ((_this select 1) getVariable [QEGVAR(safemode,safedWeapons), []]))} && {!(currentMuzzle (_this select 1) in ((_this select 1) getVariable [QEGVAR(safemode,safedWeapons), []]))}
}; };
_statement = { private _statement = {
playSound3D ["a3\sounds_f\weapons\Other\dry9.wss", _this select 0]; playSound3D ["a3\sounds_f\weapons\Other\dry9.wss", _this select 0];
if (!(missionNamespace getVariable [QGVAR(knowAboutJam), false]) && {(_this select 1) ammo currentWeapon (_this select 1) > 0} && {GVAR(DisplayTextOnJam)}) then { if (!(missionNamespace getVariable [QGVAR(knowAboutJam), false]) && {(_this select 1) ammo currentWeapon (_this select 1) > 0} && {GVAR(DisplayTextOnJam)}) then {
@ -67,16 +60,7 @@ if (_unit getVariable [QGVAR(JammingActionID), -1] == -1) then {
}; };
}; };
_condition2 = { private _id = [_unit, "DefaultAction", _condition, _statement] call EFUNC(common,addActionEventHandler);
currentWeapon (_this select 1) in ((_this select 1) getVariable [QGVAR(jammedWeapons), []])
};
_statement2 = {
[_this select 1, currentWeapon (_this select 1), false] call FUNC(clearJam);
};
//_id = [_unit, format ["<t color=""#FFFF00"" >%1</t>", localize LSTRING(UnjamWeapon)], "DefaultAction", _condition, _statement, _condition2, _statement2, 10] call EFUNC(common,addActionMenuEventHandler);
_id = [_unit, "DefaultAction", _condition, _statement] call EFUNC(common,addActionEventHandler);
_unit setVariable [QGVAR(JammingActionID), _id]; _unit setVariable [QGVAR(JammingActionID), _id];
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Author: Commy2 and CAA-Picard * Author: Commy2 and esteldunedain
* Handle weapon fire, heat up the weapon * Handle weapon fire, heat up the weapon
* *
* Argument: * Argument:
@ -15,22 +15,26 @@
* *
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
private ["_unit", "_weapon", "_ammo", "_projectile"]; params ["_unit", "_weapon", "", "", "_ammo", "", "_projectile"];
_unit = _this select 0; TRACE_4("params",_unit,_weapon,_ammo,_projectile);
_weapon = _this select 1;
_ammo = _this select 4;
_projectile = _this select 6;
private ["_bulletMass","_energyIncrement"]; //Only do heat calculations every 3 bullets
if (((_unit ammo _weapon) % 3) != 0) exitWith {};
BEGIN_COUNTER(overheat);
// Get physical parameters // Get physical parameters
_bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass"); private _bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass");
if (_bulletMass == 0) then { if (_bulletMass == 0) then {
// If the bullet mass is not configured, estimate it // If the bullet mass is not configured, estimate it
_bulletMass = 3.4334 + 0.5171 * (getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber")); _bulletMass = 3.4334 + 0.5171 * (getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"));
}; };
_energyIncrement = 0.75 * 0.0005 * _bulletMass * (vectorMagnitudeSqr velocity _projectile); private _energyIncrement = 3 * 0.000375 * _bulletMass * (vectorMagnitudeSqr velocity _projectile);
[_unit, _weapon, _energyIncrement] call FUNC(updateTemperature) TRACE_2("heat",_bulletMass,_energyIncrement);
[_unit, _weapon, _energyIncrement] call FUNC(updateTemperature);
END_COUNTER(overheat);

View File

@ -9,11 +9,15 @@
* Return value: * Return value:
* None * None
* *
* Example:
* [player, currentWeapon player] call ace_overheating_fnc_swapBarrel
*
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
EXPLODE_2_PVT(_this,_player,_weapon); params ["_player", "_weapon"];
TRACE_2("params",_player,_weapon);
if (stance _player != "PRONE") then { if (stance _player != "PRONE") then {
[_player, "amovpknlmstpsraswrfldnon", 1] call EFUNC(common,doAnimation); [_player, "amovpknlmstpsraswrfldnon", 1] call EFUNC(common,doAnimation);

View File

@ -9,11 +9,15 @@
* Return value: * Return value:
* None * None
* *
* Example:
* [player, currentWeapon player] call ace_overheating_fnc_swapBarrelCallback
*
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
EXPLODE_2_PVT(_this,_player,_weapon); params ["_player", "_weapon"];
TRACE_2("params",_player,_weapon);
// don't consume the barrel, but rotate through them. // don't consume the barrel, but rotate through them.
[localize LSTRING(SwappedBarrel), QUOTE(PATHTOF(UI\spare_barrel_ca.paa))] call EFUNC(common,displayTextPicture); [localize LSTRING(SwappedBarrel), QUOTE(PATHTOF(UI\spare_barrel_ca.paa))] call EFUNC(common,displayTextPicture);

View File

@ -10,36 +10,36 @@
* Return value: * Return value:
* Current temperature <NUMBER> * Current temperature <NUMBER>
* *
* Example:
* [player, currentWeapon player, 2000] call ace_overheating_fnc_updateTemperature
*
* Public: No * Public: No
*/ */
#include "\z\ace\addons\overheating\script_component.hpp" #include "script_component.hpp"
EXPLODE_3_PVT(_this,_unit,_weapon,_heatIncrement); params ["_unit", "_weapon", "_heatIncrement"];
TRACE_3("params",_unit,_weapon,_heatIncrement);
private ["_variableName", "_oldHeat", "_temperature", "_time", "_barrelMass"];
// each weapon has it's own variable. Can't store the temperature in the weapon since they are not objects unfortunately. // 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]; private _variableName = format [QGVAR(%1), _weapon];
// get old values // get old values
_oldHeat = _unit getVariable [_variableName, [0, 0]]; (_unit getVariable [_variableName, [0, 0]]) params ["_temperature", "_time"];
_temperature = _oldHeat select 0;
_time = _oldHeat select 1;
_barrelMass = 0.50 * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; private _barrelMass = 0.50 * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0;
_fnc_cooling = { _fnc_cooling = {
EXPLODE_3_PVT(_this,_temperature,_barrelMass,_totalTime); params ["_temperature", "_barrelMass", "_totalTime"];
TRACE_3("cooling",_temperature,_barrelMass,_totalTime);
// If a long time passed since the last shot, there's no need to calculate anything; the weapon should be cool // If a long time passed since the last shot, there's no need to calculate anything; the weapon should be cool
if (_totalTime > 1800) exitWith {0}; if (_totalTime > 1800) exitWith {0};
private ["_barrelSurface", "_time", "_deltaTime"]; private _barrelSurface = _barrelMass / 7850 / 0.003;
_barrelSurface = _barrelMass / 7850 / 0.003;
_time = 0; private _time = 0;
while {true} do { while {true} do {
_deltaTime = (_totalTime - _time) min 20; private _deltaTime = (_totalTime - _time) min 20;
_temperature = _temperature - ( _temperature = _temperature - (
// Convective cooling // Convective cooling
@ -64,12 +64,13 @@ _fnc_cooling = {
}; };
// Calculate cooling // Calculate cooling
_temperature = [_temperature, _barrelMass, time - _time] call _fnc_cooling; _temperature = [_temperature, _barrelMass, ACE_time - _time] call _fnc_cooling;
TRACE_1("cooledTo",_temperature);
// Calculate heating // Calculate heating
// Steel Heat Capacity = 466 J/(Kg.K) // Steel Heat Capacity = 466 J/(Kg.K)
_temperature = _temperature + _heatIncrement / (_barrelMass * 466); _temperature = _temperature + _heatIncrement / (_barrelMass * 466);
// Publish the variable // Publish the variable
[_unit, _variableName, [_temperature, time], 2.0] call EFUNC(common,setVariablePublic); [_unit, _variableName, [_temperature, ACE_time], 2.0] call EFUNC(common,setVariablePublic);
_temperature _temperature

View File

@ -0,0 +1 @@
#include "\z\ace\addons\overheating\script_component.hpp"

View File

@ -1,6 +1,9 @@
#define COMPONENT overheating #define COMPONENT overheating
#include "\z\ace\addons\main\script_mod.hpp" #include "\z\ace\addons\main\script_mod.hpp"
// #define ENABLE_PERFORMANCE_COUNTERS
// #define DEBUG_MODE_FULL
#ifdef DEBUG_ENABLED_OVERHEATING #ifdef DEBUG_ENABLED_OVERHEATING
#define DEBUG_MODE_FULL #define DEBUG_MODE_FULL
#endif #endif

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project name="ACE"> <Project name="ACE">
<Package name="Overheating"> <Package name="Overheating">
<Key ID="STR_ACE_Overheating_SettingDisplayTextName"> <Key ID="STR_ACE_Overheating_DisplayTextOnJam_displayName">
<English>Display text on jam</English> <English>Display text on jam</English>
<German>Zeige Text bei Ladehemmung</German> <German>Zeige Text bei Ladehemmung</German>
<Spanish>Mostrar texto al encasquillarse</Spanish> <Spanish>Mostrar texto al encasquillarse</Spanish>
@ -13,7 +13,7 @@
<Portuguese>Mostrar texto quando trava acontecer</Portuguese> <Portuguese>Mostrar texto quando trava acontecer</Portuguese>
<Italian>Visualizza testo in caso di inceppamento</Italian> <Italian>Visualizza testo in caso di inceppamento</Italian>
</Key> </Key>
<Key ID="STR_ACE_Overheating_SettingDisplayTextDesc"> <Key ID="STR_ACE_Overheating_DisplayTextOnJam_description">
<English>Display a notification whenever your weapon gets jammed</English> <English>Display a notification whenever your weapon gets jammed</English>
<German>Zeige einen Hinweis, wenn die Waffe eine Ladehemmung hat.</German> <German>Zeige einen Hinweis, wenn die Waffe eine Ladehemmung hat.</German>
<Spanish>Mostrar notificación cada vez que el arma se encasquille</Spanish> <Spanish>Mostrar notificación cada vez que el arma se encasquille</Spanish>
@ -25,6 +25,18 @@
<Portuguese>Mostra uma notificação quando sua arma sofre um travamento.</Portuguese> <Portuguese>Mostra uma notificação quando sua arma sofre um travamento.</Portuguese>
<Italian>Visualizza una notifica in caso la tua arma si inceppasse</Italian> <Italian>Visualizza una notifica in caso la tua arma si inceppasse</Italian>
</Key> </Key>
<Key ID="STR_ACE_Overheating_showParticleEffects_displayName">
<English>Overheating Particle Effects</English>
</Key>
<Key ID="STR_ACE_Overheating_showParticleEffects_description">
<English>Show particle effects when weapon overheats</English>
</Key>
<Key ID="STR_ACE_Overheating_overheatingDispersion_displayName">
<English>Overheating Dispersion</English>
</Key>
<Key ID="STR_ACE_Overheating_overheatingDispersion_description">
<English>Overheated weapons will be less accurate and have decreased muzzle velocity. Applys for all players.</English>
</Key>
<Key ID="STR_ACE_Overheating_SpareBarrelName"> <Key ID="STR_ACE_Overheating_SpareBarrelName">
<English>Spare barrel</English> <English>Spare barrel</English>
<German>Ersatzlauf</German> <German>Ersatzlauf</German>