mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge pull request #3082 from acemod/deterministicOverheatingX
Deterministic overheating (updated)
This commit is contained in:
commit
cbafe05f76
@ -154,6 +154,7 @@ PREP(selectWeaponMode);
|
||||
PREP(sendRequest);
|
||||
PREP(serverLog);
|
||||
PREP(setAllGear);
|
||||
PREP(setApproximateVariablePublic);
|
||||
PREP(setCaptivityStatus);
|
||||
PREP(setDefinedVariable);
|
||||
PREP(setDisableUserInputStatus);
|
||||
|
42
addons/common/functions/fnc_setApproximateVariablePublic.sqf
Normal file
42
addons/common/functions/fnc_setApproximateVariablePublic.sqf
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Author: esteldunedain
|
||||
* Publish a variable if it's different enough from the previously published value.
|
||||
*
|
||||
* Argument:
|
||||
* 0: Object the variable should be assigned to <OBJECT>
|
||||
* 1: Name of the variable <STRING>
|
||||
* 2: Value of the variable <ANY>
|
||||
* 3: Absolute tolerance <NUMBER>
|
||||
*
|
||||
* Return value:
|
||||
* Nothing.
|
||||
*
|
||||
* Example:
|
||||
* [player, "balls", 2, 0.1] call ace_common_fnc_setApproximateVariablePublic;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
// #define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_object", "_varName", "_value", "_tolerance"];
|
||||
TRACE_4("params",_object,_varName,_value,_tolerance);
|
||||
|
||||
// Set exact new value locally
|
||||
_object setVariable [_varName, _value];
|
||||
|
||||
// Exit if in SP - "duh"
|
||||
if (!isMultiplayer) exitWith {};
|
||||
|
||||
// If new value is not different
|
||||
private _oldVarName = format ["ACE_oldValue_%1", _varName];
|
||||
private _oldValue = _object getVariable [_oldVarName, -100000];
|
||||
|
||||
// Exit if new value is not different enough from the old onedifferent
|
||||
if (abs(_value - _oldValue) < _tolerance) exitWith {};
|
||||
|
||||
// Publish the new value:
|
||||
_object setVariable [_varName, _value, true];
|
||||
_object setVariable [_oldVarName, _value];
|
||||
|
||||
TRACE_2("Published variable:", _varName, _value);
|
@ -1,54 +1,53 @@
|
||||
/*
|
||||
* Author: commy2 and joko // Jonas
|
||||
* Sets a public variable, but wait a certain amount of time to transfer the value over the network. Changing the value by calling this function again resets the windup timer.
|
||||
* Author: commy2 and CAA-Picard and joko and PabstMirror
|
||||
* Publish a variable, but wait a certain amount of time before allowing it to be published it again.
|
||||
*
|
||||
* Arguments:
|
||||
* Argument:
|
||||
* 0: Object the variable should be assigned to <OBJECT>
|
||||
* 1: Name of the variable <STRING>
|
||||
* 2: Value of the variable <ANY>
|
||||
* 3: Windup time <NUMBER> (default: 1)
|
||||
* 3: Embargo delay <NUMBER> (Optional. Default: 1)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
* Return value:
|
||||
* Nothing.
|
||||
*
|
||||
* Example:
|
||||
* [player, "balls", 2, 1] call ace_common_fnc_setVariablePublic;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
// #define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_object", "_varName", "_value", ["_sync", 1]];
|
||||
params ["_object", "_varName", "_value", ["_delay", 1]];
|
||||
TRACE_4("params",_object,_varName,_value,_delay);
|
||||
|
||||
// set value locally
|
||||
_object setVariable [_varName, _value];
|
||||
|
||||
// Exit if in SP
|
||||
// Exit if in SP - "duh"
|
||||
if (!isMultiplayer) exitWith {};
|
||||
|
||||
private _idName = format ["ACE_setVariablePublic_%1", _varName];
|
||||
// If we are on embargo, exit
|
||||
if (_object isEqualTo (_object getVariable [format ["ACE_onEmbargo_%1", _varName], objNull])) exitWith {};
|
||||
|
||||
if (_idName in GVAR(setVariableNames)) exitWith {};
|
||||
// Publish Now and set last update time:
|
||||
_object setVariable [_varName, _value, true];
|
||||
_object setVariable [format ["ACE_onEmbargo_%1", _varName], _object];
|
||||
|
||||
private _syncTime = ACE_diagTime + _sync;
|
||||
TRACE_2("Starting Embargo", _varName, _delay);
|
||||
|
||||
GVAR(setVariableNames) pushBack _idName;
|
||||
[{
|
||||
params ["_object", "_varName", "_value"];
|
||||
if (isNull _object) exitWith {TRACE_1("objNull",_this);};
|
||||
|
||||
GVAR(setVariablePublicArray) pushBack [_object, _varName, _syncTime, _idName];
|
||||
_object setVariable [format ["ACE_onEmbargo_%1", _varName], nil]; //Remove Embargo
|
||||
private _curValue = _object getVariable _varName;
|
||||
|
||||
if (isNil QGVAR(setVariablePublicPFH)) exitWith {};
|
||||
TRACE_4("End of embargo", _object, _varName, _value, _curValue);
|
||||
|
||||
GVAR(setVariablePublicPFH) = [{
|
||||
{
|
||||
_x params ["_object", "_varName", "_syncTime", "_idName"];
|
||||
if (ACE_diagTime > _syncTime) then {
|
||||
// set value public
|
||||
_object setVariable [_varName, _object getVariable _varName, true];
|
||||
GVAR(setVariablePublicArray) deleteAt (GVAR(setVariablePublicArray) find _x);
|
||||
GVAR(setVariableNames) deleteAt (GVAR(setVariableNames) find _x);
|
||||
};
|
||||
nil
|
||||
} count +GVAR(setVariablePublicArray);
|
||||
|
||||
if (GVAR(setVariablePublicArray) isEqualTo []) then {
|
||||
[GVAR(setVariablePublicPFH)] call CBA_fnc_removePerFrameHandler;
|
||||
GVAR(setVariablePublicPFH) = nil;
|
||||
//If value at start of embargo doesn't equal current, then broadcast and start new embargo
|
||||
if (!(_value isEqualTo _curValue)) then {
|
||||
_this call FUNC(setVariablePublic);
|
||||
};
|
||||
}, 0, []] call CBA_fnc_addPerFrameHandler;
|
||||
}, _this, _delay] call FUNC(waitAndExecute);
|
||||
|
@ -3,7 +3,27 @@ class ACE_Settings {
|
||||
typeName = "BOOL";
|
||||
isClientSettable = 1;
|
||||
value = 1;
|
||||
displayName = CSTRING(SettingDisplayTextName);
|
||||
description = CSTRING(SettingDisplayTextDesc);
|
||||
displayName = CSTRING(DisplayTextOnJam_displayName);
|
||||
description = CSTRING(DisplayTextOnJam_description);
|
||||
};
|
||||
class GVAR(showParticleEffects) {
|
||||
typeName = "BOOL";
|
||||
isClientSettable = 1;
|
||||
value = 1;
|
||||
displayName = CSTRING(showParticleEffects_displayName);
|
||||
description = CSTRING(showParticleEffects_description);
|
||||
};
|
||||
class GVAR(showParticleEffectsForEveryone) {
|
||||
typeName = "BOOL";
|
||||
isClientSettable = 1;
|
||||
value = 0;
|
||||
displayName = CSTRING(showParticleEffectsForEveryone_displayName);
|
||||
description = CSTRING(showParticleEffectsForEveryone_description);
|
||||
};
|
||||
class GVAR(overheatingDispersion) {
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
displayName = CSTRING(overheatingDispersion_displayName);
|
||||
description = CSTRING(overheatingDispersion_description);
|
||||
};
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
class Extended_PreInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE( call COMPILE_FILE(XEH_preInit) );
|
||||
};
|
||||
class ADDON {
|
||||
init = QUOTE( call COMPILE_FILE(XEH_preInit) );
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
@ -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)}; );
|
||||
clientFiredBIS = QUOTE(_this call FUNC(firedEH));
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -21,7 +21,7 @@ class Extended_FiredBIS_EventHandlers {
|
||||
class Extended_Take_EventHandlers {
|
||||
class CAManBase {
|
||||
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) );
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -13,133 +13,43 @@ class CfgWeapons {
|
||||
};
|
||||
};
|
||||
|
||||
class Rifle;
|
||||
class Rifle_Base_F : Rifle {
|
||||
// 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.
|
||||
class RifleCore;
|
||||
class Rifle: RifleCore {
|
||||
//Mean Rounds Between Stoppages (this will be scaled based on the barrel temp)
|
||||
GVAR(mrbs) = 3000;
|
||||
|
||||
// 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};
|
||||
//Dispersion Factor (this will be scaled based on the barrel temp)
|
||||
GVAR(dispersion) = 1;
|
||||
|
||||
//Slowdown Factor (this will be scaled based on the barrel temp)
|
||||
GVAR(slowdownFactor) = 1;
|
||||
};
|
||||
|
||||
class Rifle_Base_F : Rifle {};
|
||||
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};
|
||||
GVAR(dispersion) = 0.75;
|
||||
};
|
||||
|
||||
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};
|
||||
// Custom jam clearing action. Default uses reload animation.
|
||||
ACE_clearJamAction = "GestureReloadMX";
|
||||
};
|
||||
|
||||
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};
|
||||
// Custom jam clearing action. Use empty string to undefine.
|
||||
ACE_clearJamAction = "";
|
||||
// 1 to enable barrel swap. 0 to disable. Meant for machine guns where you can easily swap the barrel without dismantling the whole weapon.
|
||||
GVAR(allowSwapBarrel) = 1;
|
||||
GVAR(dispersion) = 0.75;
|
||||
};
|
||||
|
||||
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 MMG_01_base_F: Rifle_Long_Base_F {
|
||||
GVAR(allowSwapBarrel) = 1;
|
||||
};
|
||||
|
||||
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 MMG_02_base_F: Rifle_Long_Base_F {
|
||||
GVAR(allowSwapBarrel) = 1;
|
||||
};
|
||||
|
||||
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};
|
||||
GVAR(allowSwapBarrel) = 1;
|
||||
};
|
||||
|
||||
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};
|
||||
class LMG_Mk200_F : Rifle_Long_Base_F {
|
||||
GVAR(allowSwapBarrel) = 1;
|
||||
};
|
||||
};
|
||||
|
@ -1,7 +1,20 @@
|
||||
// by esteldunedain
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (!hasInterface) exitWith {};
|
||||
if (isServer) then {
|
||||
GVAR(pseudoRandomList) = [];
|
||||
// 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 {};
|
||||
|
||||
GVAR(cacheWeaponData) = createLocation ["ACE_HashLocation", [-10000,-10000,-10000], 0, 0];
|
||||
GVAR(cacheWeaponData) setText QGVAR(cacheWeaponData);
|
||||
|
||||
// Add keybinds
|
||||
["ACE3 Weapons", QGVAR(unjamWeapon), localize LSTRING(UnjamWeapon),
|
||||
@ -18,4 +31,8 @@ if (!hasInterface) exitWith {};
|
||||
true
|
||||
},
|
||||
{false},
|
||||
[19, [true, false, false]], false] call CBA_fnc_addKeybind; //R Key
|
||||
[19, [true, false, false]], false] call CBA_fnc_addKeybind; //SHIFT + R Key
|
||||
|
||||
|
||||
// Schedule cool down calculation of player weapons at (infrequent) regular intervals
|
||||
[] call FUNC(updateTemperatureThread);
|
||||
|
@ -4,11 +4,15 @@ ADDON = false;
|
||||
|
||||
PREP(checkTemperature);
|
||||
PREP(clearJam);
|
||||
PREP(cooldown);
|
||||
PREP(displayTemperature);
|
||||
PREP(firedEH);
|
||||
PREP(getWeaponData);
|
||||
PREP(handleTakeEH);
|
||||
PREP(jamWeapon);
|
||||
PREP(overheat);
|
||||
PREP(swapBarrel);
|
||||
PREP(swapBarrelCallback);
|
||||
PREP(updateTemperature);
|
||||
PREP(updateTemperatureThread);
|
||||
|
||||
ADDON = true;
|
||||
|
@ -22,3 +22,29 @@ class CfgPatches {
|
||||
|
||||
#include "ACE_Settings.hpp"
|
||||
|
||||
class CfgMovesBasic {
|
||||
class ManActions {
|
||||
GVAR(GestureMountMuzzle) = QGVAR(GestureMountMuzzle);
|
||||
GVAR(GestureDismountMuzzle) = QGVAR(GestureDismountMuzzle);
|
||||
};
|
||||
|
||||
class Actions {
|
||||
class NoActions: ManActions {
|
||||
GVAR(GestureMountMuzzle)[] = {QGVAR(GestureMountMuzzle), "Gesture"};
|
||||
GVAR(GestureDismountMuzzle)[] = {QGVAR(GestureDismountMuzzle), "Gesture"};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class CfgGesturesMale {
|
||||
class States {
|
||||
class GestureMountMuzzle;
|
||||
class GVAR(GestureMountMuzzle): GestureMountMuzzle {
|
||||
speed = 0.3;
|
||||
};
|
||||
class GestureDismountMuzzle;
|
||||
class GVAR(GestureDismountMuzzle): GestureDismountMuzzle {
|
||||
speed = 0.3;
|
||||
};
|
||||
};
|
||||
};
|
@ -10,24 +10,23 @@
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* None
|
||||
* [player, currentWeapon player] call ace_overheating_fnc_checkTemperature
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "\z\ace\addons\overheating\script_component.hpp"
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_2_PVT(_this,_player,_weapon);
|
||||
|
||||
private ["_action"];
|
||||
params ["_player", "_weapon"];
|
||||
TRACE_2("params",_player,_weapon);
|
||||
|
||||
// Play animation and report temperature
|
||||
_action = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_checkTemperatureAction");
|
||||
private _action = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_checkTemperatureAction");
|
||||
|
||||
if (_action == "") then {
|
||||
_action = "Gear";
|
||||
_action = "Gear";
|
||||
};
|
||||
|
||||
_player playActionNow _action;
|
||||
|
||||
// Launch a PFH that waits a sec before displaying the temperature
|
||||
[FUNC(displayTemperature), [_player, _weapon], 1.0, 0] call EFUNC(common,waitAndExecute);
|
||||
// Waits a sec before displaying the temperature
|
||||
[FUNC(displayTemperature), [_player, _weapon], 1.0] call EFUNC(common,waitAndExecute);
|
||||
|
@ -10,48 +10,48 @@
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, currentWeapon player, false] call ace_overheating_fnc_clearJam
|
||||
*
|
||||
* 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"];
|
||||
_jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
|
||||
private _jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
|
||||
|
||||
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 {
|
||||
private "_id";
|
||||
|
||||
_id = _unit getVariable [QGVAR(JammingActionID), -1];
|
||||
[_unit, "DefaultAction", _id] call EFUNC(common,removeActionEventHandler);
|
||||
_unit setVariable [QGVAR(JammingActionID), -1];
|
||||
};
|
||||
|
||||
if !(_skipAnim) then {
|
||||
private "_clearJamAction";
|
||||
|
||||
_clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_clearJamAction");
|
||||
|
||||
if (_clearJamAction == "") then {
|
||||
_clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "reloadAction");
|
||||
if (_jammedWeapons isEqualTo []) then {
|
||||
private _id = _unit getVariable [QGVAR(JammingActionID), -1];
|
||||
[_unit, "DefaultAction", _id] call EFUNC(common,removeActionEventHandler);
|
||||
_unit setVariable [QGVAR(JammingActionID), -1];
|
||||
};
|
||||
|
||||
_unit playActionNow _clearJamAction;
|
||||
if (_weapon == primaryWeapon _unit) then {
|
||||
playSound QGVAR(fixing_rifle);
|
||||
} else {
|
||||
if (_weapon == secondaryWeapon _unit) then {
|
||||
playSound QGVAR(fixing_pistol);
|
||||
};
|
||||
};
|
||||
};
|
||||
if !(_skipAnim) then {
|
||||
|
||||
if (GVAR(DisplayTextOnJam)) then {
|
||||
[localize LSTRING(WeaponUnjammed)] call EFUNC(common,displayTextStructured);
|
||||
};
|
||||
private _clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "ACE_clearJamAction");
|
||||
|
||||
if (_clearJamAction == "") then {
|
||||
_clearJamAction = getText (configFile >> "CfgWeapons" >> _weapon >> "reloadAction");
|
||||
};
|
||||
|
||||
_unit playActionNow _clearJamAction;
|
||||
if (_weapon == primaryWeapon _unit) then {
|
||||
playSound QGVAR(fixing_rifle);
|
||||
} else {
|
||||
if (_weapon == secondaryWeapon _unit) then {
|
||||
playSound QGVAR(fixing_pistol);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if (GVAR(DisplayTextOnJam)) then {
|
||||
[localize LSTRING(WeaponUnjammed)] call EFUNC(common,displayTextStructured);
|
||||
};
|
||||
};
|
||||
|
@ -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 };
|
||||
};
|
@ -9,57 +9,40 @@
|
||||
* Return Values:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, currentWeapon player] call ace_overheating_fnc_displayTemperature
|
||||
*
|
||||
* 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);
|
||||
|
||||
// Calculate cool down of weapon since last shot
|
||||
private ["_string", "_overheat", "_temperature", "_time", "_barrelMass", "_a"];
|
||||
_string = format [QGVAR(%1), _weapon];
|
||||
_overheat = _player getVariable [_string, [0, 0]];
|
||||
_temperature = _overheat select 0;
|
||||
_time = _overheat select 1;
|
||||
private _temperature = [_player, _weapon, 0] call FUNC(updateTemperature);
|
||||
private _scaledTemperature = (_temperature / 1000) min 1;
|
||||
|
||||
// Get physical parameters
|
||||
_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);
|
||||
|
||||
// Store new temperature
|
||||
_time = ACE_time;
|
||||
_player setVariable [_string, [_temperature, _time], false];
|
||||
|
||||
|
||||
|
||||
private ["_scaledTemperature", "_action", "_color", "_count", "_string", "_text", "_picture"];
|
||||
_scaledTemperature = (_temperature / 1000) min 1;
|
||||
|
||||
_color = [
|
||||
2 * _scaledTemperature min 1,
|
||||
2 * (1 - _scaledTemperature) min 1,
|
||||
00
|
||||
private _color = [
|
||||
2 * (_scaledTemperature * 2 min 1) min 1,
|
||||
2 * (1 - (_scaledTemperature * 2 min 1)) min 1,
|
||||
00
|
||||
];
|
||||
|
||||
_count = round (12 * _scaledTemperature);
|
||||
_string = "";
|
||||
private _count = round (12 * _scaledTemperature);
|
||||
private _string = "";
|
||||
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 = "";
|
||||
for "_a" from (_count + 1) to 12 do {
|
||||
_string = _string + "|";
|
||||
_string = _string + "|";
|
||||
};
|
||||
|
||||
_text = composeText [
|
||||
_text,
|
||||
[_string, [0.5, 0.5, 0.5]] call EFUNC(common,stringToColoredText)
|
||||
];
|
||||
_text = composeText [_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);
|
||||
|
121
addons/overheating/functions/fnc_firedEH.sqf
Normal file
121
addons/overheating/functions/fnc_firedEH.sqf
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Author: Commy2 and esteldunedain
|
||||
* Handle weapon fire
|
||||
*
|
||||
* Argument:
|
||||
* 0: unit - Object the event handler is assigned to <OBJECT>
|
||||
* 1: weapon - Fired weapon <STRING>
|
||||
* 2: muzzle - Muzzle that was used <STRING>
|
||||
* 3: mode - Current mode of the fired weapon <STRING>
|
||||
* 4: ammo - Ammo used <STRING>
|
||||
* 5: magazine - magazine name which was used <STRING>
|
||||
* 6: projectile - Object of the projectile that was shot <OBJECT>
|
||||
*
|
||||
* Return value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
BEGIN_COUNTER(firedEH);
|
||||
|
||||
params ["_unit", "_weapon", "_muzzle", "", "_ammo", "", "_projectile"];
|
||||
TRACE_5("params",_unit,_weapon,_muzzle,_ammo,_projectile);
|
||||
|
||||
if (((!GVAR(overheatingDispersion)) && {_unit != ACE_player}) //If no dispersion, only run when local
|
||||
|| {!([_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
|
||||
if (_unit == ACE_player) then {
|
||||
_this call FUNC(overheat);
|
||||
};
|
||||
|
||||
// Get current temperature from the unit variable
|
||||
private _temperature = _unit getVariable [format [QGVAR(%1_temp), _weapon], 0];
|
||||
private _scaledTemperature = linearConversion [0, 1000, _temperature, 0, 1, true];
|
||||
|
||||
TRACE_2("Unit fired with temp:",_unit,_temperature);
|
||||
|
||||
//Get weapon data from cache:
|
||||
([_weapon] call FUNC(getWeaponData)) params ["_dispersion", "_slowdownFactor", "_jamChance"];
|
||||
TRACE_4("weapon data from cache",_weapon,_dispersion,_slowdownFactor,_jamChance);
|
||||
|
||||
// Dispersion and bullet slow down
|
||||
if (GVAR(overheatingDispersion)) then {
|
||||
// Exit if GVAR(pseudoRandomList) isn't synced yet
|
||||
if (isNil QGVAR(pseudoRandomList)) exitWith {ACE_LOGERROR("No pseudoRandomList sync");};
|
||||
|
||||
//Dispersion: 0 mils @ 0°C, 0.5 mils @ 333°C, 2.2 mils @ 666°C, 5 mils at 1000°C
|
||||
_dispersion = _dispersion * 0.28125 * (_scaledTemperature^2);
|
||||
|
||||
_slowdownFactor = _slowdownFactor * linearConversion [0.666, 1, _scaledTemperature, 0, -0.1, true];
|
||||
|
||||
// Get the pseudo random values for dispersion from the remaining ammo count
|
||||
(GVAR(pseudoRandomList) select ((_unit ammo _weapon) mod (count GVAR(pseudoRandomList)))) params ["_dispersionX", "_dispersionY"];
|
||||
|
||||
TRACE_4("change",_dispersion,_slowdownFactor,_dispersionX,_dispersionY);
|
||||
|
||||
TRACE_PROJECTILE_INFO(_projectile);
|
||||
[_projectile, _dispersionX * _dispersion, _dispersionY * _dispersion, _slowdownFactor * vectorMagnitude (velocity _projectile)] call EFUNC(common,changeProjectileDirection);
|
||||
TRACE_PROJECTILE_INFO(_projectile);
|
||||
};
|
||||
|
||||
|
||||
// ------ LOCAL AND NEARBY PLAYERS DEPENDING ON SETTINGS ------------
|
||||
// Particle effects only apply to the local player and, depending on settings, to other nearby players
|
||||
if (_unit != ACE_player && (!GVAR(showParticleEffectsForEveryone) || {_unit distance ACE_player > 20})) exitWith {
|
||||
END_COUNTER(firedEH);
|
||||
};
|
||||
|
||||
//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°C and maxs out at 500°C
|
||||
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°C
|
||||
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, "", "", ""];
|
||||
};
|
||||
};
|
||||
|
||||
// ------ LOCAL PLAYER ONLY ------------
|
||||
// Only compute jamming for the local player
|
||||
if (_unit != ACE_player) exitWith {END_COUNTER(firedEH);};
|
||||
|
||||
_jamChance = _jamChance * ([[0.5, 1.5, 7.5, 37.5], 3 * _scaledTemperature] call EFUNC(common,interpolateFromArray));
|
||||
|
||||
// increase jam chance on dusty grounds if prone (and at ground level)
|
||||
if ((stance _unit == "PRONE") && {((getPosATL _unit) select 2) < 1}) then {
|
||||
private _surface = configFile >> "CfgSurfaces" >> ((surfaceType getPosASL _unit) select [1]);
|
||||
if (isClass _surface) then {
|
||||
TRACE_1("dust",getNumber (_surface >> "dust"));
|
||||
_jamChance = _jamChance + (getNumber (_surface >> "dust")) * _jamChance;
|
||||
};
|
||||
};
|
||||
|
||||
TRACE_3("check for random jam",_unit,_weapon,_jamChance);
|
||||
if ((random 1) < _jamChance) then {
|
||||
[_unit, _weapon] call FUNC(jamWeapon);
|
||||
};
|
||||
|
||||
END_COUNTER(firedEH);
|
68
addons/overheating/functions/fnc_getWeaponData.sqf
Normal file
68
addons/overheating/functions/fnc_getWeaponData.sqf
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Author: PabstMirror and esteldunedain
|
||||
* Get weapon data with caching
|
||||
*
|
||||
* Argument:
|
||||
* 0: weapon type <STRING>
|
||||
*
|
||||
* Return value:
|
||||
* 0: dispresion <NUMBER>
|
||||
* 1: slowdownFactor <NUMBER>
|
||||
* 2: jamChance <NUMBER>
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
// Look in the cache first
|
||||
private _weaponData = GVAR(cacheWeaponData) getVariable _weapon;
|
||||
if (!isNil "_weaponData") exitWith {_weaponData};
|
||||
|
||||
// Search the config
|
||||
// The old and new properties have the same name for dispersion, so read whichever is closer to the children
|
||||
private _property = configFile >> "CfgWeapons" >> _weapon >> QGVAR(dispersion);
|
||||
private _dispersion = if (isNumber _property) then {
|
||||
getNumber _property;
|
||||
} else {
|
||||
if (isArray _property) then {
|
||||
// Map old array property to new number property
|
||||
((getArray _property) select 3) / 0.004;
|
||||
} else {
|
||||
1;
|
||||
};
|
||||
};
|
||||
|
||||
// The old and new properties have the same name for slowdownFactor, so read whichever is closer to the children
|
||||
_property = configFile >> "CfgWeapons" >> _weapon >> QGVAR(slowdownFactor);
|
||||
private _slowdownFactor = if (isNumber _property) then {
|
||||
getNumber _property;
|
||||
} else {
|
||||
if (isArray _property) then {
|
||||
// Map old array property to new number property
|
||||
((getArray _property) select 3) / 0.9;
|
||||
} else {
|
||||
1;
|
||||
};
|
||||
};
|
||||
|
||||
// For jam chance, try reading the legacy property first (ace_overheating_jamChance).
|
||||
private _jamChance = 1 / 3000;
|
||||
_property = configFile >> "CfgWeapons" >> _weapon >> QGVAR(JamChance);
|
||||
// If it exists read it, as the weapon is probably third party and not updated to the new properties
|
||||
if (isArray _property) then {
|
||||
// Map old array property to new number property
|
||||
_jamChance = (getArray _property) select 1;
|
||||
} else {
|
||||
// No legacy property was found, look for the new one
|
||||
_property = configFile >> "CfgWeapons" >> _weapon >> QGVAR(mrbs);
|
||||
if (isNumber _property) then {
|
||||
_jamChance = 1 / getNumber _property;
|
||||
};
|
||||
};
|
||||
|
||||
// Cache the values
|
||||
_weaponData = [_dispersion, _slowdownFactor, _jamChance];
|
||||
TRACE_2("building cache",_weapon,_weaponData);
|
||||
GVAR(cacheWeaponData) setVariable [_weapon, _weaponData];
|
||||
|
||||
_weaponData
|
28
addons/overheating/functions/fnc_handleTakeEH.sqf
Normal file
28
addons/overheating/functions/fnc_handleTakeEH.sqf
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Author: 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)
|
||||
|
||||
};
|
@ -9,74 +9,58 @@
|
||||
* Return value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, currentWeapon player] call ace_overheating_fnc_jamWeapon
|
||||
*
|
||||
* 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
|
||||
if (_unit ammo _weapon == 0) exitWith {};
|
||||
private _ammo = _unit ammo _weapon;
|
||||
if (_ammo == 0) exitWith {};
|
||||
|
||||
private ["_jammedWeapons"];
|
||||
_jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
|
||||
private _jammedWeapons = _unit getVariable [QGVAR(jammedWeapons), []];
|
||||
_jammedWeapons pushBack _weapon;
|
||||
|
||||
_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
|
||||
_ammo = _unit ammo _weapon;
|
||||
if (_ammo > 0) then {
|
||||
_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
|
||||
GVAR(knowAboutJam) = false;
|
||||
|
||||
if (_unit getVariable [QGVAR(JammingActionID), -1] == -1) then {
|
||||
private ["_condition", "_statement", "_condition2", "_statement2", "_id"];
|
||||
|
||||
_condition = {
|
||||
[_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 [QEGVAR(safemode,safedWeapons), []]))}
|
||||
};
|
||||
|
||||
_statement = {
|
||||
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 {
|
||||
[localize LSTRING(WeaponJammed)] call EFUNC(common,displayTextStructured);
|
||||
GVAR(knowAboutJam) = true;
|
||||
private _condition = {
|
||||
[_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 [QEGVAR(safemode,safedWeapons), []]))}
|
||||
};
|
||||
};
|
||||
|
||||
_condition2 = {
|
||||
currentWeapon (_this select 1) in ((_this select 1) getVariable [QGVAR(jammedWeapons), []])
|
||||
};
|
||||
private _statement = {
|
||||
playSound3D ["a3\sounds_f\weapons\Other\dry9.wss", _this select 0];
|
||||
|
||||
_statement2 = {
|
||||
[_this select 1, currentWeapon (_this select 1), false] call FUNC(clearJam);
|
||||
};
|
||||
if (!(missionNamespace getVariable [QGVAR(knowAboutJam), false]) && {(_this select 1) ammo currentWeapon (_this select 1) > 0} && {GVAR(DisplayTextOnJam)}) then {
|
||||
[localize LSTRING(WeaponJammed)] call EFUNC(common,displayTextStructured);
|
||||
GVAR(knowAboutJam) = true;
|
||||
};
|
||||
};
|
||||
|
||||
//_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);
|
||||
private _id = [_unit, "DefaultAction", _condition, _statement] call EFUNC(common,addActionEventHandler);
|
||||
|
||||
_unit setVariable [QGVAR(JammingActionID), _id];
|
||||
_unit setVariable [QGVAR(JammingActionID), _id];
|
||||
};
|
||||
|
@ -15,156 +15,29 @@
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "\z\ace\addons\overheating\script_component.hpp"
|
||||
#include "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"];
|
||||
params ["_unit", "_weapon", "", "", "_ammo", "", "_projectile"];
|
||||
TRACE_4("params",_unit,_weapon,_ammo,_projectile);
|
||||
|
||||
_unit = _this select 0;
|
||||
_weapon = _this select 1;
|
||||
_ammo = _this select 4;
|
||||
_projectile = _this select 6;
|
||||
//Only do heat calculations every 3 bullets
|
||||
if (((_unit ammo _weapon) % 3) != 0) exitWith {};
|
||||
|
||||
_velocity = velocity _projectile;
|
||||
|
||||
// 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];
|
||||
|
||||
// get old values
|
||||
_overheat = _unit getVariable [_variableName, [0, 0]];
|
||||
_temperature = _overheat select 0;
|
||||
_time = _overheat select 1;
|
||||
BEGIN_COUNTER(overheat);
|
||||
|
||||
// Get physical parameters
|
||||
_bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass");
|
||||
private _bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass");
|
||||
if (_bulletMass == 0) then {
|
||||
// If the bullet mass is not configured, estimate it directly in grams
|
||||
_bulletMass = 3.4334 + 0.5171 * (getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"));
|
||||
// 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;
|
||||
//https://en.wikipedia.org/wiki/Physics_of_firearms - Projectile motion is roughly equal to Barrel heat
|
||||
//Muzzle Engergy = 1/2 * m * v^2 (1/2 * 0.001 g/kg * bulletMass (grams) * v^2)
|
||||
//Multiple by 3 becase we only calc every 3rd bullet: (3 * 1/2 * 0.001) = 0.0015
|
||||
private _energyIncrement = 0.0015 * _bulletMass * (vectorMagnitudeSqr velocity _projectile);
|
||||
|
||||
// Calculate cooling
|
||||
_temperature = [_temperature, _barrelMass, ACE_time - _time] call FUNC(cooldown);
|
||||
// Calculate heating
|
||||
_temperature = _temperature + _energyIncrement / (_barrelMass * 466); // Steel Heat Capacity = 466 J/(Kg.K)
|
||||
TRACE_2("heat",_bulletMass,_energyIncrement);
|
||||
|
||||
// set updated values
|
||||
_time = ACE_time;
|
||||
_unit setVariable [_variableName, [_temperature, _time], false];
|
||||
_scaledTemperature = (_temperature / 1000) min 1 max 0;
|
||||
[_unit, _weapon, _energyIncrement] call FUNC(updateTemperature);
|
||||
|
||||
// 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);
|
||||
};
|
||||
END_COUNTER(overheat);
|
||||
|
@ -9,17 +9,23 @@
|
||||
* Return value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, currentWeapon player] call ace_overheating_fnc_swapBarrel
|
||||
*
|
||||
* 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);
|
||||
|
||||
// Make the standing player kneel down
|
||||
if (stance _player != "PRONE") then {
|
||||
[_player, "amovpknlmstpsraswrfldnon", 1] call EFUNC(common,doAnimation);
|
||||
[_player, "amovpknlmstpsraswrfldnon", 1] call EFUNC(common,doAnimation);
|
||||
};
|
||||
_player playActionNow "GestureDismountMuzzle";
|
||||
_player playAction "GestureMountMuzzle";
|
||||
|
||||
// Barrel dismount gesture
|
||||
_player playActionNow QGVAR(GestureDismountMuzzle);
|
||||
playSound "ACE_BarrelSwap";
|
||||
|
||||
[10, [_player, _weapon], {(_this select 0) call FUNC(swapBarrelCallback)}, {}, (localize LSTRING(SwappingBarrel))] call EFUNC(common,progressBar);
|
||||
[5, [_player, _weapon], {(_this select 0) call FUNC(swapBarrelCallback)}, {}, (localize LSTRING(SwappingBarrel))] call EFUNC(common,progressBar);
|
||||
|
@ -9,13 +9,24 @@
|
||||
* Return value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, currentWeapon player] call ace_overheating_fnc_swapBarrelCallback
|
||||
*
|
||||
* 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);
|
||||
|
||||
// Barrel mount gesture
|
||||
_player playAction QGVAR(GestureMountMuzzle);
|
||||
playSound "ACE_BarrelSwap";
|
||||
|
||||
// don't consume the barrel, but rotate through them.
|
||||
[localize LSTRING(SwappedBarrel), QUOTE(PATHTOF(UI\spare_barrel_ca.paa))] call EFUNC(common,displayTextPicture);
|
||||
|
||||
_player setVariable [format [QGVAR(%1), _weapon], [0, 0], false];
|
||||
// Publish the temperature variable
|
||||
_player setVariable [format [QGVAR(%1_temp), _weapon], 0, true];
|
||||
// Store the update time
|
||||
_player setVariable [format [QGVAR(%1_time), _weapon], ACE_time];
|
||||
|
86
addons/overheating/functions/fnc_updateTemperature.sqf
Normal file
86
addons/overheating/functions/fnc_updateTemperature.sqf
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Author: esteldunedain
|
||||
* Update temperature of a weapon.
|
||||
*
|
||||
* Argument:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Weapon <STRING>
|
||||
* 2: Heat increment (J) <NUMBER>
|
||||
*
|
||||
* Return value:
|
||||
* Current temperature <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [player, currentWeapon player, 2000] call ace_overheating_fnc_updateTemperature
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", "_weapon", "_heatIncrement"];
|
||||
TRACE_3("params",_unit,_weapon,_heatIncrement);
|
||||
|
||||
// get old values
|
||||
// each weapon has it's own variable. Can't store the temperature in the weapon since they are not objects unfortunately.
|
||||
private _tempVarName = format [QGVAR(%1_temp), _weapon];
|
||||
private _timeVarName = format [QGVAR(%1_time), _weapon];
|
||||
private _temperature = _unit getVariable [_tempVarName, 0];
|
||||
private _lastTime = _unit getVariable [_timeVarName, 0];
|
||||
|
||||
private _barrelMass = 0.50 * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0;
|
||||
|
||||
_fnc_cooling = {
|
||||
params ["_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};
|
||||
|
||||
//AR-15 (0.00570m bullet diameter) (barrel diameter usually 0.75" or 0.008255m radius)
|
||||
//Steel Denisty = 7850 m^3 / kg
|
||||
//Area of a cylinder (2/r)*(Pi * r^3 + V) - for a 0.008255m radius barrel -> Area = 210(1/meters) * Volume
|
||||
//Adjusted volume for being hollowed out is ~1.1x
|
||||
//So Area = 210 * 1.1 * (mass / 7850) = mass * 0.029427 (for steel near that diameter)
|
||||
|
||||
private _barrelSurface = _barrelMass * 0.029427;
|
||||
|
||||
TRACE_4("cooling",_temperature,_totalTime,_barrelMass,_barrelSurface);
|
||||
|
||||
private _time = 0;
|
||||
while {true} do {
|
||||
private _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 {
|
||||
diag_log text format ["[ACE] ERROR: _totalTime = %1; _time = %2; _deltaTime = %3;", _totalTime, _time, _deltaTime];
|
||||
0
|
||||
};
|
||||
|
||||
_time = _time + _deltaTime;
|
||||
if (_time >= _totalTime) exitWith { _temperature max 0 };
|
||||
};
|
||||
};
|
||||
|
||||
// Calculate cooling
|
||||
_temperature = [_temperature, _barrelMass, ACE_time - _lastTime] call _fnc_cooling;
|
||||
TRACE_1("cooledTo",_temperature);
|
||||
// Calculate heating
|
||||
// Steel Heat Capacity = 466 J/(Kg.K)
|
||||
_temperature = _temperature + _heatIncrement / (_barrelMass * 466);
|
||||
|
||||
// Publish the temperature variable
|
||||
[_unit, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic);
|
||||
// Store the update time locally
|
||||
_unit setVariable [_timeVarName, ACE_time];
|
||||
|
||||
_temperature
|
25
addons/overheating/functions/fnc_updateTemperatureThread.sqf
Normal file
25
addons/overheating/functions/fnc_updateTemperatureThread.sqf
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Author: esteldunedain
|
||||
* Update cooldown calculation of all player weapons at regular intervals.
|
||||
*
|
||||
* Argument:
|
||||
* None
|
||||
*
|
||||
* Return value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_overheating_fnc_updateTemperatureThread
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
private _currentWeapon = currentWeapon ACE_player;
|
||||
if ((_currentWeapon != "") && {_currentWeapon == primaryWeapon ACE_player || {_currentWeapon == handgunWeapon ACE_player}}) then {
|
||||
[ACE_player, _currentWeapon, 0] call FUNC(updateTemperature);
|
||||
};
|
||||
|
||||
// Schedule for execution again after 5 seconds
|
||||
[DFUNC(updateTemperatureThread), [], 5] call EFUNC(common,waitAndExecute);
|
1
addons/overheating/functions/script_component.hpp
Normal file
1
addons/overheating/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\overheating\script_component.hpp"
|
@ -14,4 +14,12 @@
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_OVERHEATING
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define TEMP_TOLERANCE 50
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
#define TRACE_PROJECTILE_INFO(BULLET) _vdir = vectorNormalized velocity BULLET; _dir = (_vdir select 0) atan2 (_vdir select 1); _up = asin (_vdir select 2); _mv = vectorMagnitude velocity BULLET; TRACE_3("adjusted projectile",_dir,_up,_mv);
|
||||
#else
|
||||
#define TRACE_PROJECTILE_INFO(BULLET) /* noDebug */
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="Overheating">
|
||||
<Key ID="STR_ACE_Overheating_SettingDisplayTextName">
|
||||
<Key ID="STR_ACE_Overheating_DisplayTextOnJam_displayName">
|
||||
<English>Display text on jam</English>
|
||||
<German>Zeige Text bei Ladehemmung</German>
|
||||
<Spanish>Mostrar texto al encasquillarse</Spanish>
|
||||
@ -13,7 +13,7 @@
|
||||
<Portuguese>Mostrar texto quando trava acontecer</Portuguese>
|
||||
<Italian>Visualizza testo in caso di inceppamento</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Overheating_SettingDisplayTextDesc">
|
||||
<Key ID="STR_ACE_Overheating_DisplayTextOnJam_description">
|
||||
<English>Display a notification whenever your weapon gets jammed</English>
|
||||
<German>Zeige einen Hinweis, wenn die Waffe eine Ladehemmung hat.</German>
|
||||
<Spanish>Mostrar notificación cada vez que el arma se encasquille</Spanish>
|
||||
@ -25,6 +25,24 @@
|
||||
<Portuguese>Mostra uma notificação quando sua arma sofre um travamento.</Portuguese>
|
||||
<Italian>Visualizza una notifica in caso la tua arma si inceppasse</Italian>
|
||||
</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_showParticleEffectsForEveryone_displayName">
|
||||
<English>Overheating Particle Effects for everyone</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_showParticleEffectsForEveryone_description">
|
||||
<English>Show particle effects when other players 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">
|
||||
<English>Spare barrel</English>
|
||||
<German>Ersatzlauf</German>
|
||||
|
@ -115,31 +115,31 @@ class CfgWeapons
|
||||
class rhs_weap_mk18: rhs_weap_m4a1 {
|
||||
ACE_barrelTwist = 177.8;
|
||||
ACE_barrelLength = 261.62;
|
||||
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};
|
||||
ACE_Overheating_dispersion = 1;
|
||||
ACE_Overheating_slowdownFactor = 1;
|
||||
ACE_Overheating_mrbs = 3000;
|
||||
};
|
||||
class rhs_weap_m16a4: rhs_weap_m4_Base {
|
||||
ACE_barrelTwist = 177.8;
|
||||
ACE_barrelLength = 508.0;
|
||||
};
|
||||
class rhs_weap_lmg_minimipara;
|
||||
class rhs_weap_lmg_minimipara;
|
||||
class rhs_weap_lmg_minimi_railed : rhs_weap_lmg_minimipara {
|
||||
ACE_barrelLength = 465.0;
|
||||
ACE_barrelTwist = 177.8;
|
||||
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};
|
||||
ACE_Overheating_dispersion = 0.75;
|
||||
ACE_Overheating_slowdownFactor = 1;
|
||||
ACE_Overheating_mrbs = 3000;
|
||||
};
|
||||
class rhs_weap_m240_base;
|
||||
class rhs_weap_m240B: rhs_weap_m240_base {
|
||||
ACE_barrelTwist = 304.8;
|
||||
ACE_barrelLength = 629.92;
|
||||
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};
|
||||
ACE_Overheating_dispersion = 1;
|
||||
ACE_Overheating_slowdownFactor = 1;
|
||||
ACE_Overheating_mrbs = 3000;
|
||||
};
|
||||
class rhs_weap_m14ebrri: srifle_EBR_F {
|
||||
ACE_barrelTwist = 304.8;
|
||||
|
Loading…
Reference in New Issue
Block a user