mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master'
Conflicts: addons/medical/ACE_Settings.hpp addons/medical/XEH_postInit.sqf addons/medical/XEH_preInit.sqf addons/medical/functions/fnc_actionDiagnose.sqf addons/medical/functions/fnc_actionLoadUnit.sqf addons/medical/functions/fnc_addDamageToUnit.sqf addons/medical/functions/fnc_createLitter.sqf addons/medical/functions/fnc_displayPatientInformation.sqf addons/medical/functions/fnc_handleCreateLitter.sqf addons/medical/functions/fnc_handleDamage.sqf addons/medical/functions/fnc_handleDamage_advanced.sqf addons/medical/functions/fnc_handleDamage_airway.sqf addons/medical/functions/fnc_handleDamage_caching.sqf addons/medical/functions/fnc_handleDamage_internalInjuries.sqf addons/medical/functions/fnc_handleDamage_wounds.sqf addons/medical/functions/fnc_isBeingCarried.sqf addons/medical/functions/fnc_isBeingDragged.sqf addons/medical/functions/fnc_litterCleanupLoop.sqf addons/medical/functions/fnc_moduleAssignMedicRoles.sqf addons/medical/functions/fnc_moduleAssignMedicalVehicle.sqf addons/medical/functions/fnc_setCardiacArrest.sqf addons/medical/functions/fnc_showBloodEffect.sqf addons/medical/functions/fnc_treatmentAdvanced_fullHealLocal.sqf addons/medical/functions/fnc_treatmentAdvanced_surgicalKit_onProgress.sqf addons/medical/functions/fnc_treatmentBasic_epipen.sqf addons/medical/functions/fnc_treatmentIV.sqf addons/medical/functions/fnc_treatmentIVLocal.sqf
This commit is contained in:
commit
0c43c83b3d
.github
.lgtm.travis.ymlREADME.mdaddons
advanced_ballistics/functions
fnc_calculateAmmoTemperatureVelocityShift.sqffnc_calculateAtmosphericCorrection.sqffnc_calculateStabilityFactor.sqffnc_handleFirePFH.sqffnc_readWeaponDataFromConfig.sqf
advanced_fatigue
$PBOPREFIX$ACE_Settings.hppCfgEden.hppCfgEventHandlers.hppCfgMovesMaleSdr.hppCfgSounds.hppCfgVehicles.hppDialog.hppREADME.md
UI
XEH_PREP.hppXEH_postInit.sqfXEH_preInit.sqfXEH_preStart.sqfconfig.cppfunctions
fnc_addDutyFactor.sqffnc_createStaminaBar.sqffnc_getAnimDuty.sqffnc_getMetabolicCosts.sqffnc_handleEffects.sqffnc_handlePlayerChanged.sqffnc_handleStaminaBar.sqffnc_moduleSettings.sqffnc_pfhMain.sqffnc_removeDutyFactor.sqfscript_component.hpp
initSettings.sqfscript_component.hppstringtable.xmladvanced_throwing
$PBOPREFIX$ACE_Settings.hppCfgEventHandlers.hppCfgVehicles.hppREADME.md
UI
XEH_PREP.hppXEH_postInitClient.sqfXEH_preInit.sqfXEH_preStart.sqfconfig.cppfunctions
fnc_canPrepare.sqffnc_canThrow.sqffnc_drawArc.sqffnc_drawThrowable.sqffnc_exitThrowMode.sqffnc_getMuzzle.sqffnc_moduleInit.sqffnc_onKeyDown.sqffnc_onMouseButtonDown.sqffnc_onMouseScroll.sqffnc_pickUp.sqffnc_prepare.sqffnc_prime.sqffnc_renderPickUpInteraction.sqffnc_throw.sqffnc_throwFiredXEH.sqffnc_updateControlsHint.sqfscript_component.hpp
script_component.hppstringtable.xmlapl
atragmx
XEH_postInit.sqf
functions
attach/functions
ballistics
captives
XEH_postInit.sqf
functions
cargo
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,4 +1,5 @@
|
||||
**When merged this pull request will:**
|
||||
- Describe what this pull request will do
|
||||
- Each change in a separate line
|
||||
- Include documentation if applicable
|
||||
- Respect the [Development Guidelines](http://ace3mod.com/wiki/development/)
|
||||
|
3
.lgtm
Normal file
3
.lgtm
Normal file
@ -0,0 +1,3 @@
|
||||
approvals = 1
|
||||
pattern = "(?i)LGTM|(?i):\\+1:|(?i):shipit:"
|
||||
self_approval_off = true
|
@ -18,7 +18,7 @@ script:
|
||||
fi
|
||||
env:
|
||||
global:
|
||||
- secure: KcJQbknBOdC5lA4nFGKPXVRVIGLDXDRzC8XkHuXJCE9pIR/wbxbkvx8fHKcC6SC9eHgzneC3+o4m4+CjIbVvIwDgslRbJ8Y59i90ncONmdoRx1HUYHwuYWVZm9HJFjCsIbrEqhSyyKS+PB3WZVOLbErtNHsgS8f43PTh5Ujg7Vg=
|
||||
- secure: cdxkn5cAx+s1C9Ne5m+odEhde1uuSg6XGMDgepN4DwSAJwtMnUv3ZmDebd5YJC1raZJdep+n09Cj0GoTNICQRkco50DxHKHYNad41wetY0tn0cs9gmPYzyFE5q4vuWiQ47dlGhQQ7IJDyX0nU++gG5E50/PhlZfebdedGSprN/4=
|
||||
notifications:
|
||||
slack:
|
||||
rooms:
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/acemod/ACE3/releases/latest">
|
||||
<img src="https://img.shields.io/badge/Version-3.6.2-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||
<img src="https://img.shields.io/badge/Version-3.7.0-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||
</a>
|
||||
<a href="https://github.com/acemod/ACE3/issues">
|
||||
<img src="https://img.shields.io/github/issues-raw/acemod/ACE3.svg?style=flat-square&label=Issues" alt="ACE3 Issues">
|
||||
|
@ -14,24 +14,22 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_muzzleVelocityShiftTableUpperLimit", "_temperatureIndexFunction",
|
||||
"_temperatureIndexA", "_temperatureIndexB", "_interpolationRatio"];
|
||||
params["_muzzleVelocityShiftTable", "_temperature"];
|
||||
params ["_muzzleVelocityShiftTable", "_temperature"];
|
||||
|
||||
// Check if muzzleVelocityShiftTable is Less Than 11 Entrys
|
||||
if ((count _muzzleVelocityShiftTable) < 11) exitWith {0};
|
||||
_muzzleVelocityShiftTableUpperLimit = _muzzleVelocityShiftTable select 10;
|
||||
private _muzzleVelocityShiftTableUpperLimit = _muzzleVelocityShiftTable select 10;
|
||||
if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith { 0 };
|
||||
|
||||
// Find exact data index required for given temperature
|
||||
_temperatureIndexFunction = (_temperature + 15) / 5;
|
||||
private _temperatureIndexFunction = (_temperature + 15) / 5;
|
||||
|
||||
// lower and upper data index used for interpolation
|
||||
_temperatureIndexA = (0 max (floor(_temperatureIndexFunction))) min 10;
|
||||
_temperatureIndexB = (0 max (ceil(_temperatureIndexFunction))) min 10;
|
||||
private _temperatureIndexA = (0 max (floor(_temperatureIndexFunction))) min 10;
|
||||
private _temperatureIndexB = (0 max (ceil(_temperatureIndexFunction))) min 10;
|
||||
|
||||
// Interpolation ratio
|
||||
_interpolationRatio = _temperatureIndexFunction - floor(_temperatureIndexFunction);
|
||||
private _interpolationRatio = _temperatureIndexFunction - floor(_temperatureIndexFunction);
|
||||
|
||||
// Interpolation
|
||||
(_muzzleVelocityShiftTable select _temperatureIndexA) * (1 - _interpolationRatio) + (_muzzleVelocityShiftTable select _temperatureIndexB) * _interpolationRatio // Return
|
||||
|
@ -17,11 +17,9 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private "_airDensity";
|
||||
|
||||
params ["_ballisticCoefficient", "_temperature"/*in C*/, "_pressure"/*in hPa*/, "_relativeHumidity"/*as ratio 0-1*/, "_atmosphereModel"/*"ICAO" or "ASM"*/];
|
||||
|
||||
_airDensity = [_temperature, _pressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity);
|
||||
private _airDensity = [_temperature, _pressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity);
|
||||
|
||||
if (_atmosphereModel == "ICAO") then {
|
||||
(STD_AIR_DENSITY_ICAO / _airDensity) * _ballisticCoefficient
|
||||
|
@ -19,14 +19,13 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_twist", "_length", "_stabilityFactor"];
|
||||
params ["_caliber", "_bulletLength", "_bulletMass", "_barrelTwist", "_muzzleVelocity", "_temperature", "_barometricPressure"];
|
||||
|
||||
// Source: http://www.jbmballistics.com/ballistics/bibliography/articles/miller_stability_1.pdf
|
||||
_twist = _barrelTwist / _caliber;
|
||||
_length = _bulletLength / _caliber;
|
||||
private _twist = _barrelTwist / _caliber;
|
||||
private _length = _bulletLength / _caliber;
|
||||
|
||||
_stabilityFactor = 7587000 * _bulletMass / (_twist^2 * _caliber^3 * _length * (1 + _length^2));
|
||||
private _stabilityFactor = 7587000 * _bulletMass / (_twist^2 * _caliber^3 * _length * (1 + _length^2));
|
||||
|
||||
if (_muzzleVelocity > 341.376) then {
|
||||
(_stabilityFactor * (_muzzleVelocity / 853.44) ^ (1/3)) * KELVIN(_temperature) / KELVIN(15) * 1013.25 / _barometricPressure
|
||||
|
@ -15,17 +15,16 @@
|
||||
private _aceTimeSecond = floor CBA_missionTime;
|
||||
|
||||
{
|
||||
private ["_bulletVelocity", "_bulletPosition", "_bulletSpeed"];
|
||||
_x params["_bullet","_caliber","_bulletTraceVisible","_index"];
|
||||
_x params ["_bullet","_caliber","_bulletTraceVisible","_index"];
|
||||
|
||||
_bulletVelocity = velocity _bullet;
|
||||
private _bulletVelocity = velocity _bullet;
|
||||
|
||||
_bulletSpeed = vectorMagnitude _bulletVelocity;
|
||||
private _bulletSpeed = vectorMagnitude _bulletVelocity;
|
||||
|
||||
if (!alive _bullet || _bulletSpeed < 100) then {
|
||||
GVAR(allBullets) deleteAt (GVAR(allBullets) find _x);
|
||||
} else {
|
||||
_bulletPosition = getPosASL _bullet;
|
||||
private _bulletPosition = getPosASL _bullet;
|
||||
|
||||
if (_bulletTraceVisible && _bulletSpeed > 500) then {
|
||||
drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""];
|
||||
|
@ -15,11 +15,10 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_weaponConfig", "_barrelTwist", "_twistDirection", "_barrelLength", "_result"];
|
||||
_weaponConfig = (configFile >> "CfgWeapons" >> _this);
|
||||
private _weaponConfig = (configFile >> "CfgWeapons" >> _this);
|
||||
|
||||
_barrelTwist = getNumber(_weaponConfig >> "ACE_barrelTwist");
|
||||
_twistDirection = 1;
|
||||
private _barrelTwist = getNumber(_weaponConfig >> "ACE_barrelTwist");
|
||||
private _twistDirection = 1;
|
||||
if (isNumber (_weaponConfig >> "ACE_twistDirection")) then {
|
||||
_twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection");
|
||||
if !(_twistDirection in [-1, 0, 1]) then {
|
||||
@ -27,9 +26,9 @@ if (isNumber (_weaponConfig >> "ACE_twistDirection")) then {
|
||||
};
|
||||
};
|
||||
|
||||
_barrelLength = getNumber(_weaponConfig >> "ACE_barrelLength");
|
||||
private _barrelLength = getNumber(_weaponConfig >> "ACE_barrelLength");
|
||||
|
||||
_result = [_barrelTwist, _twistDirection, _barrelLength];
|
||||
private _result = [_barrelTwist, _twistDirection, _barrelLength];
|
||||
|
||||
uiNamespace setVariable [format[QGVAR(%1), _weapon], _result];
|
||||
|
||||
|
1
addons/advanced_fatigue/$PBOPREFIX$
Normal file
1
addons/advanced_fatigue/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\advanced_fatigue
|
45
addons/advanced_fatigue/ACE_Settings.hpp
Normal file
45
addons/advanced_fatigue/ACE_Settings.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
class ACE_Settings {
|
||||
class GVAR(enabled) {
|
||||
category = "Advanced Fatigue";
|
||||
displayName = CSTRING(Enabled);
|
||||
description = CSTRING(Enabled_Description);
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
};
|
||||
class GVAR(enableStaminaBar) {
|
||||
category = "Advanced Fatigue";
|
||||
displayName = CSTRING(EnableStaminaBar);
|
||||
description = CSTRING(EnableStaminaBar_Description);
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
isClientSettable = 1;
|
||||
};
|
||||
class GVAR(performanceFactor) {
|
||||
category = "Advanced Fatigue";
|
||||
displayName = CSTRING(PerformanceFactor);
|
||||
description = CSTRING(PerformanceFactor_Description);
|
||||
typeName = "SCALAR";
|
||||
value = 1;
|
||||
};
|
||||
class GVAR(recoveryFactor) {
|
||||
category = "Advanced Fatigue";
|
||||
displayName = CSTRING(RecoveryFactor);
|
||||
description = CSTRING(RecoveryFactor_Description);
|
||||
typeName = "SCALAR";
|
||||
value = 1;
|
||||
};
|
||||
class GVAR(loadFactor) {
|
||||
category = "Advanced Fatigue";
|
||||
displayName = CSTRING(LoadFactor);
|
||||
description = CSTRING(LoadFactor_Description);
|
||||
typeName = "SCALAR";
|
||||
value = 1;
|
||||
};
|
||||
class GVAR(terrainGradientFactor) {
|
||||
category = "Advanced Fatigue";
|
||||
displayName = CSTRING(TerrainGradientFactor);
|
||||
description = CSTRING(TerrainGradientFactor_Description);
|
||||
typeName = "SCALAR";
|
||||
value = 1;
|
||||
};
|
||||
};
|
28
addons/advanced_fatigue/CfgEden.hpp
Normal file
28
addons/advanced_fatigue/CfgEden.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
class Cfg3DEN {
|
||||
class Attributes {
|
||||
class Slider;
|
||||
class GVAR(slider): Slider {
|
||||
attributeLoad = "params [""_ctrlGroup""]; private _slider = _ctrlGroup controlsGroupCtrl 100; private _edit = _ctrlGroup controlsGroupCtrl 101; _slider sliderSetPosition _value; _edit ctrlSetText ([_value, 1, 1] call CBA_fnc_formatNumber); ";
|
||||
attributeSave = "params [""_ctrlGroup""]; sliderPosition (_ctrlGroup controlsGroupCtrl 100); ";
|
||||
onLoad = "params [""_ctrlGroup""]; private _slider = _ctrlGroup controlsGroupCtrl 100; private _edit = _ctrlGroup controlsGroupCtrl 101; _slider sliderSetRange [0, 2]; _slider ctrlAddEventHandler [""SliderPosChanged"", { params [""_slider""]; private _edit = (ctrlParentControlsGroup _slider) controlsGroupCtrl 101; private _value = sliderPosition _slider; _edit ctrlSetText ([_value, 1, 1] call CBA_fnc_formatNumber); }]; _edit ctrlAddEventHandler [""KillFocus"", { params [""_edit""]; private _slider = (ctrlParentControlsGroup _edit) controlsGroupCtrl 100; private _value = ((parseNumber ctrlText _edit) min 2) max 0; _slider sliderSetPosition _value; _edit ctrlSetText str _value; }];";
|
||||
};
|
||||
};
|
||||
class Object {
|
||||
class AttributeCategories {
|
||||
class ace_attributes {
|
||||
class Attributes {
|
||||
class GVAR(performanceFactor) {
|
||||
property = QGVAR(performanceFactor);
|
||||
control = QGVAR(slider);
|
||||
displayName = CSTRING(PerformanceFactor);
|
||||
tooltip = CSTRING(PerformanceFactor_EdenDescription);
|
||||
expression = QUOTE(_this setVariable [ARR_3(QQGVAR(performanceFactor),_value,true)]);
|
||||
typeName = "NUMBER";
|
||||
condition = "objectControllable";
|
||||
defaultValue = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
23
addons/advanced_fatigue/CfgEventHandlers.hpp
Normal file
23
addons/advanced_fatigue/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
class Extended_PreStart_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PreInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_DisplayLoad_EventHandlers {
|
||||
class RscDisplayMission {
|
||||
ADDON = QUOTE(call FUNC(createStaminaBar));
|
||||
};
|
||||
};
|
62
addons/advanced_fatigue/CfgMovesMaleSdr.hpp
Normal file
62
addons/advanced_fatigue/CfgMovesMaleSdr.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
class CfgMovesBasic;
|
||||
class CfgMovesMaleSdr: CfgMovesBasic {
|
||||
class States {
|
||||
// Jog speed adjustment: 12km/h
|
||||
class AmovPercMstpSlowWrflDnon;
|
||||
class AmovPercMrunSlowWrflDf: AmovPercMstpSlowWrflDnon {
|
||||
speed = 0.634570;
|
||||
};
|
||||
class AmovPercMrunSlowWrflDfl: AmovPercMrunSlowWrflDf {
|
||||
speed = 0.634570;
|
||||
};
|
||||
class AmovPercMrunSlowWrflDl: AmovPercMrunSlowWrflDfl {
|
||||
speed = 0.691626;
|
||||
};
|
||||
class AmovPercMrunSlowWrflDr: AmovPercMrunSlowWrflDfl {
|
||||
speed = 0.727404;
|
||||
};
|
||||
|
||||
// Jog + raised weapon speed adjustment: 13km/h
|
||||
class AmovPercMstpSrasWrflDnon;
|
||||
class AmovPercMrunSrasWrflDf: AmovPercMstpSrasWrflDnon {
|
||||
speed = 0.677068;
|
||||
};
|
||||
|
||||
// Tactical Jog animation replacement and speed adjustment: 10km/h
|
||||
class AmovPercMwlkSlowWrflDf_ver2;
|
||||
class AmovPercMwlkSlowWrflDfl_ver2;
|
||||
class AmovPercMtacSlowWrflDf_ver2: AmovPercMwlkSlowWrflDf_ver2 {
|
||||
speed = 0.528808;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDf";
|
||||
};
|
||||
class AmovPercMtacSlowWrflDfl_ver2: AmovPercMwlkSlowWrflDfl_ver2 {
|
||||
speed = 0.528808;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDfl";
|
||||
};
|
||||
class AmovPercMtacSlowWrflDfr_ver2: AmovPercMtacSlowWrflDf_ver2 {
|
||||
speed = 0.528808;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDfr";
|
||||
};
|
||||
class AmovPercMtacSlowWrflDr_ver2: AmovPercMtacSlowWrflDf_ver2 {
|
||||
speed = 0.528808;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDr";
|
||||
};
|
||||
class AmovPercMtacSlowWrflDl_ver2: AmovPercMtacSlowWrflDf_ver2 {
|
||||
speed = 0.528808;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDl";
|
||||
};
|
||||
class AmovPercMtacSlowWrflDb_ver2: AmovPercMtacSlowWrflDf_ver2 {
|
||||
speed = 0.684541;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDb";
|
||||
soundEdge[] = {0.25,0.5,0.75,1};
|
||||
};
|
||||
class AmovPercMtacSlowWrflDbl_ver2: AmovPercMtacSlowWrflDb_ver2 {
|
||||
speed = 0.684541;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDbl";
|
||||
};
|
||||
class AmovPercMtacSlowWrflDbr_ver2: AmovPercMtacSlowWrflDb_ver2 {
|
||||
speed = 0.684541;
|
||||
file = "\A3\anims_f\Data\Anim\Sdr\Mov\Erc\run\low\Rfl\AmovPercMrunSlowWrflDbr";
|
||||
};
|
||||
};
|
||||
};
|
76
addons/advanced_fatigue/CfgSounds.hpp
Normal file
76
addons/advanced_fatigue/CfgSounds.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
class CfgSounds {
|
||||
class GVAR(breathLow0) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Low_1", 0.6, 1, 7};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathLow1) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Low_2", 0.6, 1, 7};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathLow2) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Low_3", 0.6, 1, 7};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathLow3) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Low_4", 0.6, 1, 7};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathLow4) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Low_5", 0.6, 1, 7};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathLow5) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Low_6", 0.6, 1, 7};
|
||||
titles[] = {};
|
||||
};
|
||||
|
||||
class GVAR(breathMid0) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Mid_1", 0.8, 1, 13};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMid1) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Mid_2", 0.8, 1, 13};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMid2) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Mid_3", 0.8, 1, 13};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMid3) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Mid_4", 0.8, 1, 13};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMid4) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Mid_5", 0.8, 1, 13};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMid5) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Mid_6", 0.8, 1, 13};
|
||||
titles[] = {};
|
||||
};
|
||||
|
||||
class GVAR(breathMax0) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Max_1", 1, 1, 17};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMax1) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Max_2", 1, 1, 17};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMax2) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Max_3", 1, 1, 17};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMax3) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Max_4", 1, 1, 17};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMax4) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Max_5", 1, 1, 17};
|
||||
titles[] = {};
|
||||
};
|
||||
class GVAR(breathMax5) {
|
||||
sound[] = {"A3\sounds_f\characters\human-sfx\P04\Breath_Max_6", 1, 1, 17};
|
||||
titles[] = {};
|
||||
};
|
||||
};
|
45
addons/advanced_fatigue/CfgVehicles.hpp
Normal file
45
addons/advanced_fatigue/CfgVehicles.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
class CfgVehicles {
|
||||
class ACE_Module;
|
||||
class GVAR(moduleSettings): ACE_Module {
|
||||
author = ECSTRING(common,ACETeam);
|
||||
category = "ACE";
|
||||
displayName = "Advanced Fatigue";
|
||||
function = QFUNC(moduleSettings);
|
||||
scope = 2;
|
||||
isGlobal = 1;
|
||||
isTriggerActivated = 0;
|
||||
icon = QPATHTOF(UI\Icon_Module.paa);
|
||||
class Arguments {
|
||||
class Enabled {
|
||||
displayName = CSTRING(Enabled);
|
||||
description = CSTRING(Enabled_Description);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class PerformanceFactor {
|
||||
displayName = CSTRING(PerformanceFactor);
|
||||
description = CSTRING(PerformanceFactor_Description);
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class RecoveryFactor {
|
||||
displayName = CSTRING(RecoveryFactor);
|
||||
description = CSTRING(RecoveryFactor_Description);
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class LoadFactor {
|
||||
displayName = CSTRING(LoadFactor);
|
||||
description = CSTRING(LoadFactor_Description);
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class TerrainGradientFactor {
|
||||
displayName = CSTRING(TerrainGradientFactor);
|
||||
description = CSTRING(TerrainGradientFactor_Description);
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
20
addons/advanced_fatigue/Dialog.hpp
Normal file
20
addons/advanced_fatigue/Dialog.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
class RscControlsGroupNoScrollbars;
|
||||
class RscPicture;
|
||||
|
||||
class GVAR(StaminaBarContainer): RscControlsGroupNoScrollbars {
|
||||
x = "(profilenamespace getvariable [""IGUI_GRID_STAMINA_X"", ((safezoneX + safezoneW) - (10 * (((safezoneW / safezoneH) min 1.2) / 40)) - 4.3 * (((safezoneW / safezoneH) min 1.2) / 40))])";
|
||||
y = "(profilenamespace getvariable [""IGUI_GRID_STAMINA_Y"", (safezoneY + 4.05 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))])";
|
||||
w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)";
|
||||
h = "0.15 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
|
||||
class Controls {
|
||||
class StaminaBar: RscPicture {
|
||||
idc = 10;
|
||||
x = 0;
|
||||
y = 0;
|
||||
w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)";
|
||||
h = "0.15 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
text = "\A3\Ui_f\data\IGUI\RscIngameUI\RscUnitInfo\stamina_ca.paa";
|
||||
};
|
||||
};
|
||||
};
|
10
addons/advanced_fatigue/README.md
Normal file
10
addons/advanced_fatigue/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
ace_advanced_fatigue
|
||||
==========
|
||||
|
||||
An in depth stamina and fatigue simulation.
|
||||
|
||||
## Maintainers
|
||||
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [BaerMitUmlaut](https://github.com/BaerMitUmlaut)
|
BIN
addons/advanced_fatigue/UI/Icon_Module.paa
Normal file
BIN
addons/advanced_fatigue/UI/Icon_Module.paa
Normal file
Binary file not shown.
10
addons/advanced_fatigue/XEH_PREP.hpp
Normal file
10
addons/advanced_fatigue/XEH_PREP.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
PREP(addDutyFactor);
|
||||
PREP(createStaminaBar);
|
||||
PREP(getAnimDuty);
|
||||
PREP(getMetabolicCosts);
|
||||
PREP(handleEffects);
|
||||
PREP(handlePlayerChanged);
|
||||
PREP(handleStaminaBar);
|
||||
PREP(moduleSettings);
|
||||
PREP(pfhMain);
|
||||
PREP(removeDutyFactor);
|
50
addons/advanced_fatigue/XEH_postInit.sqf
Normal file
50
addons/advanced_fatigue/XEH_postInit.sqf
Normal file
@ -0,0 +1,50 @@
|
||||
#include "script_component.hpp"
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
["ace_settingsInitialized", {
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
// - Post process effect ------------------------------------------------------
|
||||
GVAR(ppeBlackout) = ppEffectCreate ["ColorCorrections", 4220];
|
||||
GVAR(ppeBlackout) ppEffectEnable true;
|
||||
GVAR(ppeBlackout) ppEffectForceInNVG true;
|
||||
GVAR(ppeBlackout) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[10,10,0,0,0,0.1,0.5]];
|
||||
GVAR(ppeBlackout) ppEffectCommit 0.4;
|
||||
|
||||
// - GVAR updating and initialization -----------------------------------------
|
||||
if !(isNull ACE_player) then {
|
||||
[ACE_player, objNull] call FUNC(handlePlayerChanged);
|
||||
};
|
||||
["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
// - Duty factors -------------------------------------------------------------
|
||||
[QEGVAR(medical,pain), {
|
||||
1 + (((_this getVariable [QEGVAR(medical,pain), 0]) min 1) / 10)
|
||||
}] call FUNC(addDutyFactor);
|
||||
[QEGVAR(medical,bloodVolume), {
|
||||
2 - (((_this getVariable [QEGVAR(medical,bloodVolume), 100]) min 100) / 100)
|
||||
}] call FUNC(addDutyFactor);
|
||||
[QEGVAR(dragging,isCarrying), {
|
||||
if (_this getVariable [QEGVAR(dragging,isCarrying), false]) then {
|
||||
3
|
||||
} else {
|
||||
1
|
||||
};
|
||||
}] call FUNC(addDutyFactor);
|
||||
[QEGVAR(weather,temperature), {
|
||||
(((missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]) - 35) / 10) max 2 min 1
|
||||
}] call FUNC(addDutyFactor);
|
||||
|
||||
// - Add main PFH -------------------------------------------------------------
|
||||
[FUNC(pfhMain), 1, []] call CBA_fnc_addPerFrameHandler;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
["ace_settingChanged", {
|
||||
params ["_name", "_value"];
|
||||
|
||||
if (_name == QGVAR(enableStaminaBar) && {!_value}) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
11
addons/advanced_fatigue/XEH_preInit.sqf
Normal file
11
addons/advanced_fatigue/XEH_preInit.sqf
Normal file
@ -0,0 +1,11 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
//#include "initSettings.sqf"
|
||||
|
||||
GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40);
|
||||
GVAR(dutyList) = [[], []];
|
||||
|
||||
ADDON = true;
|
3
addons/advanced_fatigue/XEH_preStart.sqf
Normal file
3
addons/advanced_fatigue/XEH_preStart.sqf
Normal file
@ -0,0 +1,3 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "XEH_PREP.hpp"
|
23
addons/advanced_fatigue/config.cpp
Normal file
23
addons/advanced_fatigue/config.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
name = COMPONENT_NAME;
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common"};
|
||||
author = ECSTRING(common,ACETeam);
|
||||
authors[] = {"BaerMitUmlaut"};
|
||||
url = ECSTRING(main,URL);
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "ACE_Settings.hpp"
|
||||
#include "CfgEden.hpp"
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgMovesMaleSdr.hpp"
|
||||
#include "CfgSounds.hpp"
|
||||
#include "CfgVehicles.hpp"
|
||||
#include "Dialog.hpp"
|
18
addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf
Normal file
18
addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Adds a duty factor.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Factor ID <STRING>
|
||||
* 1: Factor <NUMBER> or <CODE>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params [["_id", "", [""]], ["_factor", 1, [0, {}]]];
|
||||
if (_id == "" || {_factor isEqualTo 1}) exitWith {};
|
||||
|
||||
GVAR(dutyList) params ["_idList", "_factorList"];
|
||||
_idList pushBack _id;
|
||||
_factorList pushBack _factor,
|
18
addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf
Normal file
18
addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Creates the stamina bar.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Display <DISPLAY>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_display"];
|
||||
|
||||
private _staminaBar = _display ctrlCreate [QGVAR(StaminaBarContainer), -1];
|
||||
uiNamespace setVariable [QGVAR(staminaBarContainer), _staminaBar];
|
||||
|
||||
_staminaBar ctrlSetFade 1;
|
||||
_staminaBar ctrlCommit 0;
|
56
addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf
Normal file
56
addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Calculates the duty of the current animation.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Animation name <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* Duty <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [player, "AidlPercMstpSlowWrflDnon_G05"] call ace_advanced_fatigue_fnc_getAnimDuty
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit", "_animName"];
|
||||
|
||||
private _duty = 1;
|
||||
private _animType = _animName select [1, 3];
|
||||
|
||||
GVAR(isSwimming) = false;
|
||||
|
||||
if (_animType in ["idl", "mov"]) then {
|
||||
switch (_animName select [5, 3]) do {
|
||||
case ("knl"): {
|
||||
_duty = 1.5;
|
||||
};
|
||||
case ("pne"): {
|
||||
_duty = 12;
|
||||
};
|
||||
default {
|
||||
_duty = 1;
|
||||
};
|
||||
};
|
||||
|
||||
if (currentWeapon _unit != handgunWeapon _unit) then {
|
||||
if (_animName select [13, 3] == "ras") then {
|
||||
// low ready jog
|
||||
_duty = _duty * 1.2;
|
||||
if (_animName select [9, 3] == "tac") then {
|
||||
// high ready jog/walk
|
||||
_duty = _duty * 1.5;
|
||||
};
|
||||
};
|
||||
};
|
||||
} else {
|
||||
// swimming and diving
|
||||
if (_animType in ["swm", "ssw", "bsw", "dve", "sdv", "bdv"]) then {
|
||||
_duty = 5;
|
||||
GVAR(isSwimming) = true;
|
||||
};
|
||||
};
|
||||
|
||||
_duty
|
61
addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf
Normal file
61
addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Calculates the current metabolic costs for a unit.
|
||||
* Calculation is done according to the Pandolf/Wojtowicz formulas.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Speed <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* Metabolic cost <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [player, 3.3] call ace_advanced_fatigue_fnc_getMetabolicCosts
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit", "_velocity"];
|
||||
|
||||
private _virtualLoad = 0;
|
||||
{
|
||||
_virtualLoad = _virtualLoad + (_x getVariable [QEGVAR(movement,vLoad), 0]);
|
||||
} forEach [
|
||||
_unit,
|
||||
uniformContainer _unit,
|
||||
vestContainer _unit,
|
||||
backpackContainer _unit
|
||||
];
|
||||
|
||||
private _gearMass = ((loadAbs _unit + _virtualLoad) * 0.1 / 2.2046) * GVAR(loadFactor);
|
||||
private _terrainFactor = 1;
|
||||
private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2));
|
||||
private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor);
|
||||
private _duty = GVAR(animDuty);
|
||||
|
||||
{
|
||||
if (_x isEqualType 0) then {
|
||||
_duty = _duty * _x;
|
||||
} else {
|
||||
_duty = _duty * (_unit call _x);
|
||||
};
|
||||
} forEach (GVAR(dutyList) select 1);
|
||||
|
||||
if (GVAR(isSwimming)) then {
|
||||
_terrainGradient = 0;
|
||||
};
|
||||
|
||||
if (_velocity > 2) then {
|
||||
(
|
||||
2.10 * SIM_BODYMASS
|
||||
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||
) * 0.23 * _duty
|
||||
} else {
|
||||
(
|
||||
1.05 * SIM_BODYMASS
|
||||
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||
) * 0.23 * _duty
|
||||
};
|
90
addons/advanced_fatigue/functions/fnc_handleEffects.sqf
Normal file
90
addons/advanced_fatigue/functions/fnc_handleEffects.sqf
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles any audible, visual and physical effects of fatigue.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Fatigue <NUMBER>
|
||||
* 2: Speed <NUMBER>
|
||||
* 3: Overexhausted <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [_player, 0.5, 3.3, true] call ace_advanced_fatigue_fnc_handleEffects
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_unit", "_fatigue", "_speed", "_overexhausted"];
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat str _fatigue;
|
||||
systemChat str vectorMagnitude velocity _unit;
|
||||
#endif
|
||||
|
||||
// - Audible effects ----------------------------------------------------------
|
||||
GVAR(lastBreath) = GVAR(lastBreath) + 1;
|
||||
if (_fatigue > 0.4 && {GVAR(lastBreath) > (_fatigue * -10 + 9)} && {!underwater _unit}) then {
|
||||
switch (true) do {
|
||||
case (_fatigue < 0.6): {
|
||||
playSound (QGVAR(breathLow) + str(floor random 6));
|
||||
};
|
||||
case (_fatigue < 0.85): {
|
||||
playSound (QGVAR(breathMid) + str(floor random 6));
|
||||
};
|
||||
default {
|
||||
playSound (QGVAR(breathMax) + str(floor random 6));
|
||||
};
|
||||
};
|
||||
GVAR(lastBreath) = 0;
|
||||
};
|
||||
|
||||
// - Visual effects -----------------------------------------------------------
|
||||
GVAR(ppeBlackoutLast) = GVAR(ppeBlackoutLast) + 1;
|
||||
if (GVAR(ppeBlackoutLast) == 1) then {
|
||||
GVAR(ppeBlackout) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[10,10,0,0,0,0.1,0.5]];
|
||||
GVAR(ppeBlackout) ppEffectCommit 1;
|
||||
} else {
|
||||
if (_fatigue > 0.85) then {
|
||||
if (GVAR(ppeBlackoutLast) > (100 - _fatigue * 100) / 3) then {
|
||||
GVAR(ppeBlackout) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[2,2,0,0,0,0.1,0.5]];
|
||||
GVAR(ppeBlackout) ppEffectCommit 1;
|
||||
GVAR(ppeBlackoutLast) = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// - Physical effects ---------------------------------------------------------
|
||||
if (GVAR(isSwimming)) exitWith {
|
||||
_unit setAnimSpeedCoef (1 - _fatigue / 3);
|
||||
};
|
||||
|
||||
if (_overexhausted) then {
|
||||
[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if (isForcedWalk _unit && {_fatigue < 0.7}) then {
|
||||
[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then {
|
||||
[_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if ((!isSprintAllowed _unit) && {_fatigue < 0.6}) then {
|
||||
[_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
switch (stance _unit) do {
|
||||
case ("CROUCH"): {
|
||||
_unit setCustomAimCoef (1.0 + _fatigue ^ 2 * 0.1);
|
||||
};
|
||||
case ("PRONE"): {
|
||||
_unit setCustomAimCoef (1.0 + _fatigue ^ 2 * 2.0);
|
||||
};
|
||||
default {
|
||||
_unit setCustomAimCoef (1.5 + _fatigue ^ 2 * 3.0);
|
||||
};
|
||||
};
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles switching units (once on init and afterwards via Zeus).
|
||||
*
|
||||
* Arguments:
|
||||
* 0: New Unit <OBJECT>
|
||||
* 1: Old Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_newUnit", "_oldUnit"];
|
||||
|
||||
if !(isNull _oldUnit) then {
|
||||
_oldUnit enableStamina true;
|
||||
_oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]];
|
||||
|
||||
_oldUnit setVariable [QGVAR(ae1Reserve), GVAR(ae1Reserve)];
|
||||
_oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)];
|
||||
_oldUnit setVariable [QGVAR(anReserve), GVAR(anReserve)];
|
||||
_oldUnit setVariable [QGVAR(anFatigue), GVAR(anFatigue)];
|
||||
_oldUnit setVariable [QGVAR(muscleDamage), GVAR(muscleDamage)];
|
||||
};
|
||||
|
||||
_newUnit enableStamina false;
|
||||
|
||||
// Don't add a new EH if the unit respawned
|
||||
if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then {
|
||||
private _animHandler = _newUnit addEventHandler ["AnimChanged", {
|
||||
GVAR(animDuty) = _this call FUNC(getAnimDuty);
|
||||
}];
|
||||
_newUnit setVariable [QGVAR(animHandler), _animHandler];
|
||||
};
|
||||
|
||||
GVAR(ae1Reserve) = _newUnit getVariable [QGVAR(ae1Reserve), AE1_MAXRESERVE];
|
||||
GVAR(ae2Reserve) = _newUnit getVariable [QGVAR(ae2Reserve), AE2_MAXRESERVE];
|
||||
GVAR(anReserve) = _newUnit getVariable [QGVAR(anReserve), AN_MAXRESERVE];
|
||||
GVAR(anFatigue) = _newUnit getVariable [QGVAR(anFatigue), 0];
|
||||
GVAR(muscleDamage) = _newUnit getVariable [QGVAR(muscleDamage), 0];
|
||||
|
||||
// Clean variables for respawning units
|
||||
{
|
||||
_newUnit setVariable [_x, nil];
|
||||
} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage)];
|
||||
|
||||
GVAR(VO2Max) = 35 + 20 * (_newUnit getVariable [QGVAR(performanceFactor), GVAR(performanceFactor)]);
|
||||
GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * 0.23 * JOULES_PER_ML_O2 / 60;
|
||||
GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower);
|
||||
|
||||
GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362;
|
||||
GVAR(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362;
|
||||
GVAR(anPathwayPower) = GVAR(peakPower) - _ae1PathwayPower - _ae2PathwayPower;
|
||||
|
||||
GVAR(ppeBlackoutLast) = 100;
|
||||
GVAR(lastBreath) = 0;
|
||||
GVAR(animDuty) = [_newUnit, animationState _newUnit] call FUNC(getAnimDuty);
|
44
addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf
Normal file
44
addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles visual changes of the stamina bar.
|
||||
*
|
||||
* Arguments:
|
||||
* Percent of stamina remaining <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_stamina"];
|
||||
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
|
||||
// - Size ---------------------------------------------------------------------
|
||||
// Shrink the container to cut off the image (other wise it would just get stretched)
|
||||
private _posAndSize = ctrlPosition _staminaBarContainer;
|
||||
_posAndSize set [2, _stamina * GVAR(staminaBarWidth)];
|
||||
_staminaBarContainer ctrlSetPosition _posAndSize;
|
||||
|
||||
// - Opacity ------------------------------------------------------------------
|
||||
if (_stamina >= 0.8) then {
|
||||
_staminaBarContainer ctrlSetFade (0.9 + 0.1 * (_stamina - 0.8) / 0.2);
|
||||
} else {
|
||||
_staminaBarContainer ctrlSetFade (0.9 * _stamina / 0.8);
|
||||
};
|
||||
|
||||
// - Color --------------------------------------------------------------------
|
||||
// 1.0 - 0.8: White
|
||||
// 0.6 - 0.4: Orange
|
||||
// 0.4 - 0.2: Red
|
||||
private _color = [1, 1, 1];
|
||||
if (_stamina < 0.6) then {
|
||||
if (_stamina < 0.4) then {
|
||||
_color = [1, 0, 0] vectorAdd ([0, 0.65, 0] vectorMultiply ((_stamina - 0.2) / 0.2));
|
||||
} else {
|
||||
_color = [1, 0.65, 0] vectorAdd ([0, 0.35, 1] vectorMultiply ((_stamina - 0.4) / 0.2));
|
||||
};
|
||||
};
|
||||
_color pushBack 1;
|
||||
(_staminaBarContainer controlsGroupCtrl 10) ctrlSetTextColor _color;
|
||||
|
||||
_staminaBarContainer ctrlCommit 1;
|
18
addons/advanced_fatigue/functions/fnc_moduleSettings.sqf
Normal file
18
addons/advanced_fatigue/functions/fnc_moduleSettings.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Initializes the module settings.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Module <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params ["_logic"];
|
||||
|
||||
[_logic, QGVAR(enabled), "Enabled"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(performanceFactor), "PerformanceFactor"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(recoveryFactor), "RecoveryFactor"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(loadFactor), "LoadFactor"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(terrainGradientFactor), "TerrainGradientFactor"] call EFUNC(common,readSettingFromModule);
|
63
addons/advanced_fatigue/functions/fnc_pfhMain.sqf
Normal file
63
addons/advanced_fatigue/functions/fnc_pfhMain.sqf
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Main perFrameHandler that updates fatigue values.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
if (!alive ACE_player) exitWith {}; // Dead people don't breath, Will also handle null (Map intros)
|
||||
|
||||
private _currentWork = REE;
|
||||
private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6;
|
||||
if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then {
|
||||
_currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts);
|
||||
_currentWork = _currentWork max REE;
|
||||
};
|
||||
|
||||
// Calculate muscle damage increase
|
||||
// Note: Muscle damage recovery is ignored as it takes multiple days
|
||||
GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004;
|
||||
private _muscleIntegrity = 1 - GVAR(muscleDamage);
|
||||
|
||||
// Calculate available power
|
||||
private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * sqrt _muscleIntegrity;
|
||||
private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * sqrt _muscleIntegrity;
|
||||
|
||||
// Calculate how much power is consumed from each reserve
|
||||
private _ae1Power = _currentWork min _ae1PathwayPowerFatigued;
|
||||
private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued;
|
||||
private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0;
|
||||
|
||||
// Remove ATP from reserves for current work
|
||||
GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP;
|
||||
GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP;
|
||||
GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP;
|
||||
// Increase anearobic fatigue
|
||||
GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1;
|
||||
|
||||
// Aerobic ATP reserve recovery
|
||||
GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0;
|
||||
GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0;
|
||||
|
||||
// Anaerobic ATP reserver and fatigue recovery
|
||||
GVAR(anReserve) = ((GVAR(anReserve)
|
||||
+ (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) / GVAR(VO2MaxPower) * 56.7 * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||
) min AN_MAXRESERVE) max 0;
|
||||
|
||||
GVAR(anFatigue) = ((GVAR(anFatigue)
|
||||
- (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||
) min 1) max 0;
|
||||
|
||||
private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2;
|
||||
private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE;
|
||||
private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage);
|
||||
|
||||
[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects);
|
||||
|
||||
if (GVAR(enableStaminaBar)) then {
|
||||
[GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar);
|
||||
};
|
20
addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf
Normal file
20
addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Removes a duty factor.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Factor ID <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
params [["_id", "", [""]]];
|
||||
|
||||
GVAR(dutyList) params ["_idList", "_factorList"];
|
||||
private _index = _idList find _id;
|
||||
|
||||
if (_index != -1) then {
|
||||
_idList deleteAt _index;
|
||||
_factorList deleteAt _index;
|
||||
};
|
1
addons/advanced_fatigue/functions/script_component.hpp
Normal file
1
addons/advanced_fatigue/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\advanced_fatigue\script_component.hpp"
|
59
addons/advanced_fatigue/initSettings.sqf
Normal file
59
addons/advanced_fatigue/initSettings.sqf
Normal file
@ -0,0 +1,59 @@
|
||||
[
|
||||
QGVAR(enabled),
|
||||
"CHECKBOX",
|
||||
[LSTRING(Enabled), LSTRING(Enabled_Description)],
|
||||
"ACE3 Advanced Fatigue",
|
||||
true,
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(enableStaminaBar),
|
||||
"CHECKBOX",
|
||||
[LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)],
|
||||
"ACE3 Advanced Fatigue",
|
||||
true,
|
||||
true, {
|
||||
if (!_this) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
}
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(performanceFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)],
|
||||
"ACE3 Advanced Fatigue",
|
||||
[0, 2, 1, 1],
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(recoveryFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)],
|
||||
"ACE3 Advanced Fatigue",
|
||||
[0, 2, 1, 1],
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(loadFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(LoadFactor), LSTRING(LoadFactor_Description)],
|
||||
"ACE3 Advanced Fatigue",
|
||||
[0, 2, 1, 1],
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
||||
|
||||
[
|
||||
QGVAR(terrainGradientFactor),
|
||||
"SLIDER",
|
||||
[LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)],
|
||||
"ACE3 Advanced Fatigue",
|
||||
[0, 2, 1, 1],
|
||||
true
|
||||
] call CBA_Settings_fnc_init;
|
30
addons/advanced_fatigue/script_component.hpp
Normal file
30
addons/advanced_fatigue/script_component.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#define COMPONENT advanced_fatigue
|
||||
#define COMPONENT_BEAUTIFIED Advanced Fatigue
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
// #define CBA_DEBUG_SYNCHRONOUS
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
#ifdef DEBUG_ENABLED_ADVANCED_FATIGUE
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_ADVANCED_FATIGUE
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_ADVANCED_FATIGUE
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define ANTPERCENT 0.8
|
||||
#define SIM_BODYMASS 70
|
||||
#define JOULES_PER_ML_O2 20.9
|
||||
#define VO2MAX_STRENGTH 4.1
|
||||
#define REE 18.83 //((0.5617 * SIM_BODYMASS + 42.57) * 0.23)
|
||||
#define OXYGEN 0.9
|
||||
#define WATTSPERATP 7
|
||||
|
||||
#define AE1_MAXRESERVE 4000000
|
||||
#define AE2_MAXRESERVE 84000
|
||||
#define AN_MAXRESERVE 2300
|
57
addons/advanced_fatigue/stringtable.xml
Normal file
57
addons/advanced_fatigue/stringtable.xml
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="Advanced_Fatigue">
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor">
|
||||
<English>Performance Factor</English>
|
||||
<German>Leistungsfaktor</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor_Description">
|
||||
<English>Influences the overall performance of all players with no custom factor. Higher means better.</English>
|
||||
<German>Beinflusst die Leistungsfähigkeit aller Spieler ohne eigenen Leistungsfaktor. Ein höherer Wert bedeutet bessere Leistung.</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_PerformanceFactor_EdenDescription">
|
||||
<English>Influences the overall performance of this unit. Higher means better.</English>
|
||||
<German>Beinflusst die Leistungsfähigkeit dieser Einheit. Ein höherer Wert bedeutet bessere Leistung.</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_RecoveryFactor">
|
||||
<English>Recovery Factor</English>
|
||||
<German>Erholungsfaktor</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_RecoveryFactor_Description">
|
||||
<English>Changes how fast the player recovers when resting. Higher is faster.</English>
|
||||
<German>Ändert, wie schnell ein Spieler Ausdauer regeneriert. Ein höherer Wert bedeutet eine schnellere Regeneration.</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_LoadFactor">
|
||||
<English>Load Factor</English>
|
||||
<German>Gewichtsfaktor</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_LoadFactor_Description">
|
||||
<English>Increases or decreases how much weight influences the players performance. Zero means equipment weight has no performance influence.</English>
|
||||
<German>Erhöht oder verringert, wie viel Einfluss das Ausrüstungsgewicht auf die Leistung hat. Null heißt, dass es keinen Einfluss hat.</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_TerrainGradientFactor">
|
||||
<English>Terrain Gradient Factor</English>
|
||||
<German>Terrainsteigungsfaktor</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_TerrainGradientFactor_Description">
|
||||
<English>Sets how much steep terrain increases stamina loss. Higher means higher stamina loss.</English>
|
||||
<German>Beeinflusst, wie stark Steigungen den Ausdauerverbrauch erhöhen. Ein höherer Wert erhöht den Ausdauerverbrauch.</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_Enabled">
|
||||
<English>Enabled</English>
|
||||
<German>Aktiv</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_Enabled_Description">
|
||||
<English>Enables/disables Advanced Fatigue.</English>
|
||||
<German>Aktiviert/deaktiviert Advanced Fatigue.</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_EnableStaminaBar">
|
||||
<English>Show stamina bar</English>
|
||||
<German>Zeige Ausdauerleiste</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Fatigue_EnableStaminaBar_Description">
|
||||
<English>Shows the stamina bar.</English>
|
||||
<German>Zeigt die Ausdauerleiste an.</German>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
1
addons/advanced_throwing/$PBOPREFIX$
Normal file
1
addons/advanced_throwing/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\advanced_throwing
|
40
addons/advanced_throwing/ACE_Settings.hpp
Normal file
40
addons/advanced_throwing/ACE_Settings.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
class ACE_Settings {
|
||||
class GVAR(enabled) {
|
||||
category = CSTRING(Category);
|
||||
displayName = CSTRING(Enable_DisplayName);
|
||||
description = CSTRING(Enable_Description);
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
isClientSettable = 1;
|
||||
};
|
||||
class GVAR(showThrowArc) {
|
||||
category = CSTRING(Category);
|
||||
displayName = CSTRING(ShowThrowArc_DisplayName);
|
||||
description = CSTRING(ShowThrowArc_Description);
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
isClientSettable = 1;
|
||||
};
|
||||
class GVAR(showMouseControls) {
|
||||
category = CSTRING(Category);
|
||||
displayName = CSTRING(ShowMouseControls_DisplayName);
|
||||
description = CSTRING(ShowMouseControls_Description);
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
isClientSettable = 1;
|
||||
};
|
||||
class GVAR(enablePickUp) {
|
||||
category = CSTRING(Category);
|
||||
displayName = CSTRING(EnablePickUp_DisplayName);
|
||||
description = CSTRING(EnablePickUp_Description);
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
};
|
||||
class GVAR(enablePickUpAttached) {
|
||||
category = CSTRING(Category);
|
||||
displayName = CSTRING(EnablePickUpAttached_DisplayName);
|
||||
description = CSTRING(EnablePickUpAttached_Description);
|
||||
typeName = "BOOL";
|
||||
value = 1;
|
||||
};
|
||||
};
|
17
addons/advanced_throwing/CfgEventHandlers.hpp
Normal file
17
addons/advanced_throwing/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
class Extended_PreStart_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PreInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient));
|
||||
};
|
||||
};
|
72
addons/advanced_throwing/CfgVehicles.hpp
Normal file
72
addons/advanced_throwing/CfgVehicles.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
class CBA_Extended_EventHandlers;
|
||||
|
||||
class CfgVehicles {
|
||||
class ACE_Module;
|
||||
class GVAR(Module): ACE_Module {
|
||||
author = ECSTRING(common,ACETeam);
|
||||
category = "ACE";
|
||||
displayName = CSTRING(Category);
|
||||
function = QFUNC(moduleInit);
|
||||
scope = 2;
|
||||
isGlobal = 1;
|
||||
icon = QPATHTOF(UI\Icon_Module_AdvancedThrowing_ca.paa);
|
||||
class Arguments {
|
||||
class enabled {
|
||||
displayName = CSTRING(Enable_DisplayName);
|
||||
description = CSTRING(Enable_Description);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class showThrowArc {
|
||||
displayName = CSTRING(ShowThrowArc_DisplayName);
|
||||
description = CSTRING(ShowThrowArc_Description);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class showMouseControls {
|
||||
displayName = CSTRING(ShowMouseControls_DisplayName);
|
||||
description = CSTRING(ShowMouseControls_Description);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class enablePickUp {
|
||||
displayName = CSTRING(EnablePickUp_DisplayName);
|
||||
description = CSTRING(EnablePickUp_Description);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class enablePickUpAttached {
|
||||
displayName = CSTRING(EnablePickUpAttached_DisplayName);
|
||||
description = CSTRING(EnablePickUpAttached_Description);
|
||||
typeName = "BOOL";
|
||||
defaultValue = 1;
|
||||
};
|
||||
};
|
||||
class ModuleDescription {
|
||||
description = CSTRING(Module_Description);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Items_base_F;
|
||||
class GVAR(pickUpHelper): Items_base_F {
|
||||
author = ECSTRING(common,ACETeam);
|
||||
displayName = "ACE Throwable Pick Up Helper";
|
||||
model = "\a3\weapons_f\dummyweapon.p3d";
|
||||
scope = 1;
|
||||
|
||||
class ACE_Actions {
|
||||
class GVAR(pickUp) {
|
||||
displayName = CSTRING(PickUp);
|
||||
condition = QUOTE([ARR_2(_player,true)] call FUNC(canPrepare));
|
||||
statement = QUOTE(_this call FUNC(pickUp));
|
||||
distance = 1.8; // Requires >1.7 to work when standing with weapon on back
|
||||
icon = "\a3\ui_f\data\igui\cfg\actions\obsolete\ui_action_takemine_ca.paa";
|
||||
};
|
||||
};
|
||||
|
||||
class EventHandlers {
|
||||
class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};
|
||||
};
|
||||
};
|
||||
};
|
11
addons/advanced_throwing/README.md
Normal file
11
addons/advanced_throwing/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
ace_advanced_throwing
|
||||
===================
|
||||
|
||||
Integrates advanced throwing by [Dslyecxi](https://github.com/dslyecxi).
|
||||
|
||||
|
||||
## Maintainers
|
||||
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [Jonpas](https://github.com/jonpas)
|
BIN
addons/advanced_throwing/UI/Icon_Module_AdvancedThrowing_ca.paa
Normal file
BIN
addons/advanced_throwing/UI/Icon_Module_AdvancedThrowing_ca.paa
Normal file
Binary file not shown.
17
addons/advanced_throwing/XEH_PREP.hpp
Normal file
17
addons/advanced_throwing/XEH_PREP.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
PREP(canPrepare);
|
||||
PREP(canThrow);
|
||||
PREP(drawArc);
|
||||
PREP(drawThrowable);
|
||||
PREP(exitThrowMode);
|
||||
PREP(getMuzzle);
|
||||
PREP(moduleInit);
|
||||
PREP(onKeyDown);
|
||||
PREP(onMouseButtonDown);
|
||||
PREP(onMouseScroll);
|
||||
PREP(pickUp);
|
||||
PREP(prepare);
|
||||
PREP(prime);
|
||||
PREP(renderPickUpInteraction);
|
||||
PREP(throw);
|
||||
PREP(throwFiredXEH);
|
||||
PREP(updateControlsHint);
|
114
addons/advanced_throwing/XEH_postInitClient.sqf
Normal file
114
addons/advanced_throwing/XEH_postInitClient.sqf
Normal file
@ -0,0 +1,114 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
// Exit on HC
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
// Ammo/Magazines look-up hash for correctness of initSpeed
|
||||
GVAR(ammoMagLookup) = call CBA_fnc_createNamespace;
|
||||
{
|
||||
{
|
||||
private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
||||
GVAR(ammoMagLookup) setVariable [_ammo, _x];
|
||||
} count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"));
|
||||
nil
|
||||
} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles");
|
||||
|
||||
|
||||
// Add keybinds
|
||||
["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), {
|
||||
// Condition
|
||||
if (!([ACE_player] call FUNC(canPrepare))) exitWith {false};
|
||||
|
||||
// Statement
|
||||
[ACE_player] call FUNC(prepare);
|
||||
|
||||
true
|
||||
}, {false}, [34, [true, false, false]], false] call CBA_fnc_addKeybind; // Shift + G
|
||||
|
||||
["ACE3 Weapons", QGVAR(dropModeToggle), localize LSTRING(DropModeToggle), {
|
||||
// Condition
|
||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||
|
||||
// Statement
|
||||
private _currentDropMode = ACE_player getVariable [QGVAR(dropMode), false];
|
||||
ACE_player setVariable [QGVAR(dropMode), !_currentDropMode];
|
||||
|
||||
ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening
|
||||
call FUNC(updateControlsHint); // Change controls hint for MMB
|
||||
true
|
||||
}, {false}, [34, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + G
|
||||
|
||||
["ACE3 Weapons", QGVAR(dropModeHold), localize LSTRING(DropModeHold), {
|
||||
// Condition
|
||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||
|
||||
// Statement
|
||||
ACE_player setVariable [QGVAR(dropMode), true];
|
||||
ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening
|
||||
call FUNC(updateControlsHint); // Change controls hint for MMB
|
||||
true
|
||||
}, {
|
||||
// Condition
|
||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||
|
||||
// Statement
|
||||
ACE_player setVariable [QGVAR(dropMode), false];
|
||||
call FUNC(updateControlsHint); // Change controls hint for MMB
|
||||
true
|
||||
}, [0, [false, false, false]], false] call CBA_fnc_addKeybind; // Empty
|
||||
|
||||
|
||||
// Event handlers
|
||||
["unit", {
|
||||
[_this select 1, "Player changed"] call FUNC(exitThrowMode);
|
||||
}] call CBA_fnc_addPlayerEventhandler;
|
||||
|
||||
["ace_interactMenuOpened", {
|
||||
// Exit if advanced throwing is disabled (pick up only supports advanced throwing)
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
if (ACE_player getVariable [QGVAR(inHand), false]) then {
|
||||
[ACE_player, "Interact menu opened"] call FUNC(exitThrowMode);
|
||||
} else {
|
||||
params ["_interactionType"];
|
||||
// Ignore self-interaction menu, when in vehicle and when pick up is disabled
|
||||
if (GVAR(enablePickUp) && {_interactionType == 0} && {vehicle ACE_player == ACE_player}) then {
|
||||
// Show pick up actions on CfgAmmo's
|
||||
call FUNC(renderPickUpInteraction);
|
||||
};
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
|
||||
// Fired XEH
|
||||
[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Set last thrown time on Vanilla Throwing and Advanced Throwing
|
||||
["ace_firedPlayer", {
|
||||
if (_weapon == "Throw") then {
|
||||
_unit setVariable [QGVAR(lastThrownTime), CBA_missionTime];
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
|
||||
// Display handlers
|
||||
["KeyDown", {_this call FUNC(onKeyDown)}] call CBA_fnc_addDisplayHandler;
|
||||
["MouseButtonDown", {_this call FUNC(onMouseButtonDown)}] call CBA_fnc_addDisplayHandler;
|
||||
["MouseZChanged", {_this call FUNC(onMouseScroll)}] call CBA_fnc_addDisplayHandler;
|
||||
|
||||
|
||||
#ifdef DRAW_THROW_PATH
|
||||
GVAR(predictedPath) = [];
|
||||
GVAR(flightPath) = [];
|
||||
|
||||
addMissionEventHandler ["Draw3D", { // Blue is predicted before throw, red is real
|
||||
{
|
||||
_x params ["", "_newTrajAGL"];
|
||||
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [0,0,1,1], _newTrajAGL, 1, 1, 0, "", 2];
|
||||
} forEach GVAR(predictedPath);
|
||||
{
|
||||
_newTrajAGL = _x;
|
||||
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _newTrajAGL, 1, 1, 0, "", 2];
|
||||
} forEach GVAR(flightPath)
|
||||
}];
|
||||
#endif
|
7
addons/advanced_throwing/XEH_preInit.sqf
Normal file
7
addons/advanced_throwing/XEH_preInit.sqf
Normal file
@ -0,0 +1,7 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
|
||||
ADDON = true;
|
3
addons/advanced_throwing/XEH_preStart.sqf
Normal file
3
addons/advanced_throwing/XEH_preStart.sqf
Normal file
@ -0,0 +1,3 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "XEH_PREP.hpp"
|
19
addons/advanced_throwing/config.cpp
Normal file
19
addons/advanced_throwing/config.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
name = COMPONENT_NAME;
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common", "ace_weaponselect"};
|
||||
author = ECSTRING(common,ACETeam);
|
||||
authors[] = {"Jonpas", "Dslyecxi", "Zapat"};
|
||||
url = ECSTRING(main,URL);
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "ACE_Settings.hpp"
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgVehicles.hpp"
|
37
addons/advanced_throwing/functions/fnc_canPrepare.sqf
Normal file
37
addons/advanced_throwing/functions/fnc_canPrepare.sqf
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Checks if a throwable can be prepared.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Ignore Last Thrown Time <BOOL> (default: false)
|
||||
*
|
||||
* Return Value:
|
||||
* Can Prepare <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [unit] call ace_advanced_throwing_fnc_canPrepare
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", ["_ignoreLastThrownTime", false]];
|
||||
|
||||
// Don't delay when picking up
|
||||
if (_ignoreLastThrownTime) then {
|
||||
_unit setVariable [QGVAR(lastThrownTime), -1];
|
||||
};
|
||||
|
||||
GVAR(enabled) &&
|
||||
|
||||
#ifdef ALLOW_QUICK_THROW
|
||||
{true} &&
|
||||
#else
|
||||
{_unit getVariable [QGVAR(lastThrownTime), CBA_missionTime - 3] < CBA_missionTime - 2} && // Prevent throwing in quick succession
|
||||
#endif
|
||||
|
||||
{!(call EFUNC(common,isFeatureCameraActive))} &&
|
||||
{!EGVAR(common,isReloading)} &&
|
||||
{[_unit, objNull, ["isNotInside", "isNotSitting"/*, "isNotOnLadder"*/]] call EFUNC(common,canInteractWith)} && // Ladder needs positioning fixes on throw
|
||||
{_unit call CBA_fnc_canUseWeapon} // Disable in non-FFV seats due to surface detection issues
|
31
addons/advanced_throwing/functions/fnc_canThrow.sqf
Normal file
31
addons/advanced_throwing/functions/fnc_canThrow.sqf
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Checks if a throwable can be thrown.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Throw <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [unit] call ace_advanced_throwing_fnc_canThrow
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
if !(_unit getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||
|
||||
if (vehicle _unit != _unit) exitWith {
|
||||
private _startPos = eyePos _unit;
|
||||
private _aimLinePos = AGLToASL (positionCameraToWorld [0, 0, 1]);
|
||||
private _intersections = lineIntersectsSurfaces [_startPos, _aimLinePos, _unit, objNull, false];
|
||||
//TRACE_1("Intersections",_intersections);
|
||||
|
||||
(_intersections select {(vehicle _unit) in (_x select 3)}) isEqualTo []
|
||||
};
|
||||
|
||||
true
|
88
addons/advanced_throwing/functions/fnc_drawArc.sqf
Normal file
88
addons/advanced_throwing/functions/fnc_drawArc.sqf
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Author: Zapat, Dslyecxi, Jonpas
|
||||
* Draws throw arc.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* Flight path (just for debug) <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* call ace_advanced_throwing_fnc_drawArc
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
// Disable drawing when intersecting with the vehicle
|
||||
if !([ACE_player] call FUNC(canThrow)) exitWith {
|
||||
drawIcon3D ["\a3\ui_f\data\igui\cfg\actions\obsolete\ui_action_cancel_manualfire_ca.paa", [1, 0, 0, 1], positionCameraToWorld [0, 0, 1], 1, 1, 0, "", 1];
|
||||
};
|
||||
|
||||
private _activeThrowable = ACE_player getVariable [QGVAR(activeThrowable), objNull];
|
||||
|
||||
// Exit during switches and similar where object can be null for a very short amount of time
|
||||
if (isNull _activeThrowable) exitWith {};
|
||||
|
||||
private _dropMode = ACE_player getVariable [QGVAR(dropMode), false];
|
||||
private _throwType = ACE_player getVariable [QGVAR(throwType), THROW_TYPE_DEFAULT];
|
||||
private _throwSpeed = ACE_player getVariable [QGVAR(throwSpeed), THROW_SPEED_DEFAULT];
|
||||
|
||||
private _direction = [THROWSTYLE_NORMAL_DIR, THROWSTYLE_HIGH_DIR] select (_throwType == "high" || {_dropMode});
|
||||
private _velocity = [_throwSpeed, _throwSpeed / THROWSTYLE_HIGH_VEL_COEF / 1.25] select (_throwType == "high");
|
||||
_velocity = [_velocity, THROWSTYLE_DROP_VEL] select _dropMode;
|
||||
|
||||
private _viewStart = AGLToASL (positionCameraToWorld [0, 0, 0]);
|
||||
private _viewEnd = AGLToASL (positionCameraToWorld _direction);
|
||||
|
||||
private _initialVelocity = (vectorNormalized (_viewEnd vectorDiff _viewStart)) vectorMultiply (_velocity);
|
||||
private _prevTrajASL = getPosASLVisual _activeThrowable;
|
||||
|
||||
private _pathData = [];
|
||||
|
||||
for "_i" from 0.05 to 1.45 step 0.1 do {
|
||||
private _newTrajASL = (getPosASLVisual _activeThrowable) vectorAdd (_initialVelocity vectorMultiply _i) vectorAdd ([0, 0, -4.9] vectorMultiply (_i * _i));
|
||||
private _cross = 0;
|
||||
|
||||
if (_newTrajASL distance (getPosASLVisual ACE_player) <= 20) then {
|
||||
if ((ASLToATL _newTrajASL) select 2 <= 0) then {
|
||||
_cross = 1
|
||||
} else {
|
||||
// Even vanilla throwables go through glass, only "GEOM" LOD will stop it but that will also stop it when there is glass in a window
|
||||
if (lineIntersects [_prevTrajASL, _newTrajASL]) then {
|
||||
_cross = 2;
|
||||
};
|
||||
};
|
||||
|
||||
private _iDim = linearConversion [20, 0, _newTrajASL distance (getPosASLVisual ACE_player), 0.3, 2.5, true];
|
||||
private _alpha = linearConversion [20, 0, _newTrajASL distance (getPosASLVisual ACE_player), 0.05, 0.7, true];
|
||||
private _movePerc = linearConversion [3, 0, vectorMagnitude (velocity ACE_player), 0, 1, true];
|
||||
_alpha = _alpha * _movePerc;
|
||||
|
||||
private _col = [ [1, 1, 1, _alpha], [0, 1, 0, _alpha], [1, 0, 0, _alpha] ] select _cross;
|
||||
|
||||
if (_cross != 2 && {lineIntersects [eyePos ACE_player, _newTrajASL]}) then {
|
||||
_col set [3, 0.1]
|
||||
};
|
||||
|
||||
_pathData pushBack [_col, ASLToAGL _newTrajASL, _iDim];
|
||||
};
|
||||
|
||||
if (_cross > 0) exitWith {};
|
||||
|
||||
_prevTrajASL = _newTrajASL;
|
||||
};
|
||||
|
||||
reverse _pathData;
|
||||
// To get the sort order correct from our POV, particularly when using outlined dots
|
||||
{
|
||||
_x params ["_col", "_newTrajAGL", "_iDim"];
|
||||
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", _col, _newTrajAGL, _iDim, _iDim, 0, "", 2];
|
||||
|
||||
#ifdef DRAW_THROW_PATH
|
||||
drawIcon3D ["", _col, _newTrajAGL, _iDim, _iDim, 0, str (ACE_player distance _newTrajAGL), 2, 0.05, "RobotoCondensed"];
|
||||
#endif
|
||||
} forEach _pathData;
|
||||
|
||||
_pathData
|
149
addons/advanced_throwing/functions/fnc_drawThrowable.sqf
Normal file
149
addons/advanced_throwing/functions/fnc_drawThrowable.sqf
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas, SilentSpike
|
||||
* Handles drawing the currently selected or cooked throwable.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call ace_advanced_throwing_fnc_drawThrowable
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (dialog || {!(ACE_player getVariable [QGVAR(inHand), false])} || {!([ACE_player, true] call FUNC(canPrepare))}) exitWith {
|
||||
[ACE_player, "In dialog or no throwable in hand or cannot prepare throwable"] call FUNC(exitThrowMode);
|
||||
};
|
||||
|
||||
private _primed = ACE_player getVariable [QGVAR(primed), false];
|
||||
private _activeThrowable = ACE_player getVariable [QGVAR(activeThrowable), objNull];
|
||||
|
||||
// Exit if throwable died primed in hand
|
||||
if (isNull _activeThrowable && {_primed}) exitWith {
|
||||
[ACE_player, "Throwable died primed in hand"] call FUNC(exitThrowMode);
|
||||
};
|
||||
|
||||
private _throwable = currentThrowable ACE_player;
|
||||
|
||||
// Inventory check
|
||||
if (_throwable isEqualTo [] && {!_primed}) exitWith {
|
||||
[ACE_player, "No valid throwables"] call FUNC(exitThrowMode);
|
||||
};
|
||||
|
||||
private _throwableMag = _throwable param [0, "#none"];
|
||||
|
||||
// Get correct throw power for primed grenade
|
||||
if (_primed) then {
|
||||
private _ammoType = typeOf _activeThrowable;
|
||||
_throwableMag = GVAR(ammoMagLookup) getVariable _ammoType;
|
||||
if (isNil "_throwableMag") then {
|
||||
// What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke)
|
||||
// Just use HandGrenade as it has an average initSpeed value
|
||||
_throwableMag = "HandGrenade";
|
||||
};
|
||||
};
|
||||
|
||||
// Some throwables have different classname for magazine and ammo
|
||||
// Primed magazine may be different, read speed before checking primed magazine!
|
||||
private _throwSpeed = getNumber (configFile >> "CfgMagazines" >> _throwableMag >> "initSpeed");
|
||||
|
||||
// Reduce power of throw over shoulder and to sides
|
||||
private _unitDirVisual = getDirVisual ACE_player;
|
||||
private _cameraDir = getCameraViewDirection ACE_player;
|
||||
_cameraDir = (_cameraDir select 0) atan2 (_cameraDir select 1);
|
||||
|
||||
private _phi = abs (_cameraDir - _unitDirVisual) % 360;
|
||||
_phi = [_phi, 360 - _phi] select (_phi > 180);
|
||||
|
||||
private _power = linearConversion [0, 180, _phi - 30, 1, 0.3, true];
|
||||
ACE_player setVariable [QGVAR(throwSpeed), _throwSpeed * _power];
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format ["Heading: %1\nPower: %2\nSpeed: %3\nThrowMag: %4\nMuzzle: %5", _phi, _power, _throwSpeed * _power, _throwableMag, ACE_player getVariable [QGVAR(activeMuzzle), ""]];
|
||||
#endif
|
||||
|
||||
private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo");
|
||||
|
||||
if (!([ACE_player] call FUNC(canThrow)) && {!_primed}) exitWith {
|
||||
if (!isNull _activeThrowable) then {
|
||||
deleteVehicle _activeThrowable;
|
||||
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||
ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||
};
|
||||
};
|
||||
|
||||
if (isNull _activeThrowable || {(_throwableType != typeOf _activeThrowable) && {!_primed}}) then {
|
||||
if (!isNull _activeThrowable) then {
|
||||
deleteVehicle _activeThrowable;
|
||||
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||
ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||
};
|
||||
_activeThrowable = _throwableType createVehicleLocal [0, 0, 0];
|
||||
_activeThrowable enableSimulation false;
|
||||
ACE_player setVariable [QGVAR(activeThrowable), _activeThrowable];
|
||||
|
||||
// Set muzzle ammo to 0 to block vanilla throwing (can only be 0 or 1)
|
||||
private _muzzle = _throwableMag call FUNC(getMuzzle);
|
||||
ACE_player setAmmo [_muzzle, 0];
|
||||
ACE_player setVariable [QGVAR(activeMuzzle), _muzzle];
|
||||
};
|
||||
|
||||
// Exit in case of explosion in hand
|
||||
if (isNull _activeThrowable) exitWith {
|
||||
[ACE_player, "No active throwable (explosion in hand)"] call FUNC(exitThrowMode);
|
||||
};
|
||||
|
||||
// Exit if locality changed (someone took the throwable from hand)
|
||||
if (!local _activeThrowable && {ACE_player getVariable [QGVAR(localityChanged), true]}) exitWith {
|
||||
[ACE_player, "Throwable locality changed"] call FUNC(exitThrowMode);
|
||||
};
|
||||
|
||||
// Set position
|
||||
private _posHeadRel = ACE_player selectionPosition "head";
|
||||
|
||||
private _leanCoef = (_posHeadRel select 0) - 0.15; // 0.15 counters the base offset
|
||||
// Don't take leaning into account when weapon is lowered due to jiggling when walking side-ways (bandaid)
|
||||
if (abs _leanCoef < 0.15 || {vehicle ACE_player != ACE_player} || {weaponLowered ACE_player}) then {
|
||||
_leanCoef = 0;
|
||||
};
|
||||
|
||||
private _posCameraWorld = AGLToASL (positionCameraToWorld [0, 0, 0]);
|
||||
_posHeadRel = _posHeadRel vectorAdd [-0.03, 0.01, 0.15]; // Bring closer to eyePos value
|
||||
private _posFin = AGLToASL (ACE_player modelToWorldVisual _posHeadRel);
|
||||
|
||||
private _throwType = ACE_player getVariable [QGVAR(throwType), THROW_TYPE_DEFAULT];
|
||||
|
||||
// Orient it nicely, point towards player
|
||||
_activeThrowable setDir (_unitDirVisual + 90);
|
||||
|
||||
private _pitch = [-30, -90] select (_throwType == "high");
|
||||
[_activeThrowable, _pitch, 0] call BIS_fnc_setPitchBank;
|
||||
|
||||
|
||||
if (ACE_player getVariable [QGVAR(dropMode), false]) then {
|
||||
_posFin = _posFin vectorAdd (AGLToASL (positionCameraToWorld [_leanCoef, 0, ACE_player getVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]]));
|
||||
|
||||
// Even vanilla throwables go through glass, only "GEOM" LOD will stop it but that will also stop it when there is no glass in a window
|
||||
if (lineIntersects [_posCameraWorld, _posFin vectorDiff _posCameraWorld]) then {
|
||||
ACE_player setVariable [QGVAR(dropDistance), ((ACE_player getVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]) - 0.1) max DROP_DISTANCE_DEFAULT];
|
||||
};
|
||||
} else {
|
||||
private _xAdjustBonus = [0, -0.075] select (_throwType == "high");
|
||||
private _yAdjustBonus = [0, 0.1] select (_throwType == "high");
|
||||
private _cameraOffset = [_leanCoef, 0, 0.3] vectorAdd [-0.1, -0.15, -0.03] vectorAdd [_xAdjustBonus, _yAdjustBonus, 0];
|
||||
|
||||
_posFin = _posFin vectorAdd (AGLToASL (positionCameraToWorld _cameraOffset));
|
||||
|
||||
if (vehicle ACE_player != ACE_player) then {
|
||||
// Counteract vehicle velocity including acceleration
|
||||
private _vectorDiff = (velocity (vehicle ACE_player)) vectorMultiply (time - (ACE_player getVariable [QGVAR(lastTick), time]) + 0.01);
|
||||
_posFin = _posFin vectorAdd _vectorDiff;
|
||||
ACE_player setVariable [QGVAR(lastTick), time];
|
||||
};
|
||||
};
|
||||
|
||||
_activeThrowable setPosASL (_posFin vectorDiff _posCameraWorld);
|
59
addons/advanced_throwing/functions/fnc_exitThrowMode.sqf
Normal file
59
addons/advanced_throwing/functions/fnc_exitThrowMode.sqf
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Exits throw mode.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Reason <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [unit, "reason"] call ace_advanced_throwing_fnc_exitThrowMode
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", "_reason"];
|
||||
TRACE_2("params",_unit,_reason);
|
||||
|
||||
if !(_unit getVariable [QGVAR(inHand), false]) exitWith {};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat format ["Exit Throw Mode: %1", _reason];
|
||||
#endif
|
||||
|
||||
private _activeThrowable = _unit getVariable [QGVAR(activeThrowable), objNull];
|
||||
if !(_unit getVariable [QGVAR(primed), false]) then {
|
||||
deleteVehicle _activeThrowable;
|
||||
} else {
|
||||
_unit setVariable [QGVAR(lastThrownTime), CBA_missionTime];
|
||||
// Fix floating for throwables without proper physics (eg. IR Grenade)
|
||||
_activeThrowable setVelocity [0, 0, -0.1];
|
||||
};
|
||||
|
||||
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||
_unit setAmmo [_unit getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||
|
||||
_unit setVariable [QGVAR(inHand), false];
|
||||
_unit setVariable [QGVAR(primed), false];
|
||||
_unit setVariable [QGVAR(activeThrowable), objNull];
|
||||
_unit setVariable [QGVAR(activeMuzzle), ""];
|
||||
_unit setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT];
|
||||
_unit setVariable [QGVAR(throwSpeed), THROW_SPEED_DEFAULT];
|
||||
_unit setVariable [QGVAR(dropMode), false];
|
||||
_unit setVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT];
|
||||
|
||||
// Remove controls hint (check if ever enabled is inside the function)
|
||||
call EFUNC(interaction,hideMouseHint);
|
||||
|
||||
// Remove throw action
|
||||
[_unit, "DefaultAction", _unit getVariable [QGVAR(throwAction), -1]] call EFUNC(common,removeActionEventHandler);
|
||||
|
||||
// Remove throw arc draw
|
||||
if (!isNil QGVAR(draw3DHandle)) then {
|
||||
removeMissionEventHandler ["Draw3D", GVAR(draw3DHandle)];
|
||||
GVAR(draw3DHandle) = nil;
|
||||
};
|
25
addons/advanced_throwing/functions/fnc_getMuzzle.sqf
Normal file
25
addons/advanced_throwing/functions/fnc_getMuzzle.sqf
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Retrieve muzzle name from config.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Magazine Classname <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* "magazine" call ace_advanced_throwing_fnc_getMuzzle
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_magazineClassname"];
|
||||
|
||||
_magazineClassname = toLower _magazineClassname;
|
||||
private _throwMuzzles = getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles");
|
||||
|
||||
_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLower _x})};
|
||||
|
||||
[_throwMuzzles select 0, ""] select (_throwMuzzles isEqualTo [])
|
33
addons/advanced_throwing/functions/fnc_moduleInit.sqf
Normal file
33
addons/advanced_throwing/functions/fnc_moduleInit.sqf
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Initializes the Advanced Throwing module.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Logic <OBJECT>
|
||||
* 1: Synchronized Units <ARRAY>
|
||||
* 2: Module Activated <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [logic, [unit1, unit2], true] call ace_advanced_throwing_fnc_moduleInit
|
||||
*
|
||||
* Public:
|
||||
* No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (!isServer) exitWith {};
|
||||
|
||||
params ["_logic", "_units", "_activated"];
|
||||
|
||||
if (!_activated) exitWith {};
|
||||
|
||||
[_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(showThrowArc), "showThrowArc"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(showMouseControls), "showMouseControls"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(enablePickUp), "enablePickUp"] call EFUNC(common,readSettingFromModule);
|
||||
[_logic, QGVAR(enablePickUpAttached), "enablePickUpAttached"] call EFUNC(common,readSettingFromModule);
|
||||
|
||||
ACE_LOGINFO_1("Advanced Throwing Module Initialized. Enabled: %1",GVAR(enabled));
|
45
addons/advanced_throwing/functions/fnc_onKeyDown.sqf
Normal file
45
addons/advanced_throwing/functions/fnc_onKeyDown.sqf
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Key down event.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Control <CONTROL>
|
||||
* 1: Key <NUMBER>
|
||||
* 2: Shift <BOOL>
|
||||
* 3: Ctrl <BOOL>
|
||||
* 4: Alt <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [control, 5, false, true, false] call ace_advanced_throwing_fnc_onKeyDown
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false};
|
||||
|
||||
params ["", "_key", "_shift", "_ctrl", "_alt"];
|
||||
|
||||
// Exit if any of the action keys is pressed
|
||||
{
|
||||
if (_key in _x) exitWith {
|
||||
[ACE_player, "Pressed a key that cycles us out of throwables"] call FUNC(exitThrowMode);
|
||||
};
|
||||
} forEach [
|
||||
actionKeys "ReloadMagazine",
|
||||
actionKeys "Handgun",
|
||||
actionKeys "Binoculars",
|
||||
actionKeys "SwitchWeapon",
|
||||
actionKeys "Optics",
|
||||
actionKeys "NextWeapon",
|
||||
actionKeys "PrevWeapon",
|
||||
actionKeys "OpticsTemp",
|
||||
actionKeys "SwitchPrimary",
|
||||
actionKeys "SwitchHandgun",
|
||||
actionKeys "SwitchSecondary"
|
||||
];
|
||||
|
||||
false
|
46
addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf
Normal file
46
addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Mouse button down event.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_advanced_throwing_fnc_onMouseButtonDown
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {};
|
||||
|
||||
params ["", "_key"];
|
||||
|
||||
// Left mouse button
|
||||
// "DefaultAction" doesn't get executed when in driver seat or in FFV seat with weapon lowered
|
||||
if (_key == 0) exitWith {
|
||||
if (!isNull (ACE_player getVariable [QGVAR(activeThrowable), objNull])) then {
|
||||
// Look gets automatically pointed at weapon direction on first LMB press when in FFV seat, require weapon to be up if in vehicle
|
||||
private _inVehicle = vehicle ACE_player != ACE_player;
|
||||
if (!_inVehicle || {_inVehicle && {!weaponLowered ACE_player}}) then {
|
||||
[ACE_player] call FUNC(throw);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
private _primed = ACE_player getVariable [QGVAR(primed), false];
|
||||
|
||||
// Right mouse button
|
||||
if (_key == 1) exitWith {
|
||||
if (!_primed) then {
|
||||
[ACE_player, "Storing throwable"] call FUNC(exitThrowMode);
|
||||
};
|
||||
};
|
||||
|
||||
// Middle mouse button
|
||||
if (_key == 2 && {!_primed}) exitWith {
|
||||
[ACE_player, true] call FUNC(prime);
|
||||
};
|
48
addons/advanced_throwing/functions/fnc_onMouseScroll.sqf
Normal file
48
addons/advanced_throwing/functions/fnc_onMouseScroll.sqf
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Mouse scroll wheel changed event.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_advanced_throwing_fnc_onMouseScroll
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {};
|
||||
|
||||
params ["", "_amount"];
|
||||
|
||||
if (ACE_player getVariable [QGVAR(dropMode), false]) then {
|
||||
private _dropDistance = ACE_player getVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT];
|
||||
if (_amount < 0) then {
|
||||
// Move closer
|
||||
ACE_player setVariable [QGVAR(dropDistance), (_dropDistance - 0.1) max DROP_DISTANCE_DEFAULT];
|
||||
} else {
|
||||
// Move further
|
||||
ACE_player setVariable [QGVAR(dropDistance), (_dropDistance + 0.1) min 1];
|
||||
};
|
||||
|
||||
// Limit distance in vehicle
|
||||
if (vehicle ACE_player != ACE_player) then {
|
||||
ACE_player setVariable [QGVAR(dropDistance), (ACE_player getVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]) min 0.5];
|
||||
};
|
||||
} else {
|
||||
private _throwType = ACE_player getVariable [QGVAR(throwType), THROW_TYPE_DEFAULT];
|
||||
if (_amount < 0) then {
|
||||
if (_throwType == "high") then {
|
||||
ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT];
|
||||
};
|
||||
} else {
|
||||
if (_throwType == "normal") then {
|
||||
ACE_player setVariable [QGVAR(throwType), "high"];
|
||||
};
|
||||
};
|
||||
TRACE_2("Change Throw Type",_amount,ACE_player getVariable QGVAR(throwType));
|
||||
};
|
61
addons/advanced_throwing/functions/fnc_pickUp.sqf
Normal file
61
addons/advanced_throwing/functions/fnc_pickUp.sqf
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Picks up a throwable from the ground.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Pick Up Helper <OBJECT>
|
||||
* 1: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [helper, player] call ace_advanced_throwing_fnc_pickUp
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_helper", "_unit"];
|
||||
TRACE_2("params",_helper,_unit);
|
||||
|
||||
private _activeThrowable = _helper getVariable [QGVAR(throwable), objNull];
|
||||
|
||||
if (isNull _activeThrowable) exitWith {TRACE_2("throwable is null",_helper,_activeThrowable);};
|
||||
|
||||
// Detach if attached (to vehicle for example or another player)
|
||||
private _attachedTo = attachedTo _activeThrowable;
|
||||
if (!isNull _attachedTo) then {
|
||||
private _attachedList = _attachedTo getVariable [QEGVAR(attach,attached), []];
|
||||
{
|
||||
_x params ["_xObject"];
|
||||
if (_activeThrowable == _xObject) exitWith {
|
||||
TRACE_2("removing from ace_attach",_attachedTo,_attachedList);
|
||||
_attachedList deleteAt _forEachIndex;
|
||||
_attachedTo setVariable [QEGVAR(attach,attached), _attachedList, true];
|
||||
};
|
||||
} forEach _attachedList;
|
||||
detach _activeThrowable;
|
||||
};
|
||||
|
||||
// Change locality for manipulation (some commands require local object, such as setVelocity)
|
||||
if (!local _activeThrowable) then {
|
||||
["ace_setOwner", [_activeThrowable, CBA_clientID]] call CBA_fnc_serverEvent;
|
||||
|
||||
// Mark when it's safe to exit throw mode (locality change has delay)
|
||||
_unit setVariable [QGVAR(localityChanged), false];
|
||||
[{
|
||||
// Becomes local or times out
|
||||
local (_this select 0) || {(_this select 1) + 5 < CBA_missionTime}
|
||||
}, {
|
||||
(_this select 2) setVariable [QGVAR(localityChanged), true];
|
||||
}, [_activeThrowable, CBA_missionTime, _unit]] call CBA_fnc_waitUntilAndExecute;
|
||||
};
|
||||
|
||||
// Invoke listenable event
|
||||
["ace_throwablePickedUp", [_activeThrowable, _unit, _attachedTo]] call CBA_fnc_localEvent;
|
||||
|
||||
_unit setVariable [QGVAR(primed), true];
|
||||
_unit setVariable [QGVAR(activeThrowable), _activeThrowable];
|
||||
|
||||
_unit call FUNC(prepare);
|
53
addons/advanced_throwing/functions/fnc_prepare.sqf
Normal file
53
addons/advanced_throwing/functions/fnc_prepare.sqf
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Prepares throwable or selects the next.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [unit] call ace_advanced_throwing_fnc_prepare
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit"];
|
||||
TRACE_1("params",_unit);
|
||||
|
||||
// Select next throwable if one already in hand
|
||||
if (_unit getVariable [QGVAR(inHand), false]) exitWith {
|
||||
TRACE_1("inHand",_unit);
|
||||
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
||||
TRACE_1("not primed",_unit);
|
||||
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||
// selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles)
|
||||
ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1];
|
||||
[_unit] call EFUNC(weaponselect,selectNextGrenade);
|
||||
};
|
||||
};
|
||||
|
||||
// Try selecting next throwable if none currently selected
|
||||
if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThrowable _unit) isEqualTo []} && {!([_unit] call EFUNC(weaponselect,selectNextGrenade))}) exitWith {
|
||||
TRACE_1("no throwables",_unit);
|
||||
};
|
||||
|
||||
|
||||
_unit setVariable [QGVAR(inHand), true];
|
||||
|
||||
// Add controls hint
|
||||
call FUNC(updateControlsHint);
|
||||
|
||||
// Add throw action to suppress weapon firing (not possible to suppress mouseButtonDown event)
|
||||
_unit setVariable [QGVAR(throwAction), [_unit, "DefaultAction", {true}, {true}] call EFUNC(common,addActionEventHandler)];
|
||||
|
||||
// Draw throwable and throw arc if enabled
|
||||
GVAR(draw3DHandle) = addMissionEventHandler ["Draw3D", {
|
||||
call FUNC(drawThrowable);
|
||||
if (GVAR(showThrowArc)) then {
|
||||
call FUNC(drawArc);
|
||||
};
|
||||
}];
|
60
addons/advanced_throwing/functions/fnc_prime.sqf
Normal file
60
addons/advanced_throwing/functions/fnc_prime.sqf
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Primes the throwable, creates global throwable vehicle and throws Fired XEH.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Show Hint <BOOL> (default: false)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [unit] call ace_advanced_throwing_fnc_prime
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit", ["_showHint", false]];
|
||||
TRACE_2("params",_unit,_showHint);
|
||||
|
||||
_unit setVariable [QGVAR(primed), true];
|
||||
|
||||
// Remove item before cooking to prevent weaponselect showing more throwables than there actually are in inventory
|
||||
private _throwableMag = (currentThrowable _unit) select 0;
|
||||
_unit removeItem _throwableMag;
|
||||
|
||||
private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo");
|
||||
private _muzzle = _unit getVariable [QGVAR(activeMuzzle), ""];
|
||||
|
||||
// Set muzzle ammo to 0 to block vanilla throwing (can only be 0 or 1), removeItem above resets it
|
||||
_unit setAmmo [_muzzle, 0];
|
||||
|
||||
// Create actual throwable globally
|
||||
private _activeThrowableOld = _unit getVariable [QGVAR(activeThrowable), objNull];
|
||||
private _activeThrowable = createVehicle [_throwableType, _activeThrowableOld, [], 0, "CAN_COLLIDE"];
|
||||
_unit setVariable [QGVAR(activeThrowable), _activeThrowable];
|
||||
deleteVehicle _activeThrowableOld;
|
||||
|
||||
// Throw Fired XEH
|
||||
[QGVAR(throwFiredXEH), [
|
||||
_unit, // unit
|
||||
"Throw", // weapon
|
||||
_muzzle, // muzzle
|
||||
_muzzle, // mode
|
||||
_throwableType, // ammo
|
||||
_throwableMag, // magazine
|
||||
_activeThrowable // projectile
|
||||
]] call CBA_fnc_globalEvent;
|
||||
|
||||
if (_showHint) then {
|
||||
// Show primed hint
|
||||
private _displayNameShort = getText (configFile >> "CfgMagazines" >> _throwableMag >> "displayNameShort");
|
||||
private _picture = getText (configFile >> "CfgMagazines" >> _throwableMag >> "picture");
|
||||
|
||||
[[_displayNameShort, localize LSTRING(Primed)] joinString " ", _picture] call EFUNC(common,displayTextPicture);
|
||||
|
||||
// Change controls hint for RMB
|
||||
call FUNC(updateControlsHint);
|
||||
};
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Author: PabstMirror, Jonpas
|
||||
* When interact_menu starts rendering (from "interact_keyDown" event).
|
||||
* Add pick up helpers to all nearby throwables and keep setting them to their position (setVariable and attachTo does not work on CfgAmmo).
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* Nothing
|
||||
*
|
||||
* Example:
|
||||
* call ace_advanced_throwing_fnc_renderPickUpInteraction
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
[{
|
||||
params ["_args", "_idPFH"];
|
||||
_args params ["_setPosition", "_addedPickUpHelpers", "_throwablesHelped", "_nearThrowables"];
|
||||
|
||||
// isNull is necessarry to prevent rare error when ending mission with interact key down
|
||||
if (EGVAR(interact_menu,keyDown) && {!isNull ACE_player}) then {
|
||||
// Rescan when player moved >5 meters from last pos, nearObjects can be costly with a lot of objects around
|
||||
if ((getPosASL ACE_player) distance _setPosition > 5) then {
|
||||
// Grenades inherit from GrenadeHand, IR throwbles from IRStrobeBase, IR Chemlights are special snowflakes
|
||||
// nearEntities does not see throwables
|
||||
_nearThrowables = ACE_player nearObjects ["GrenadeHand", PICK_UP_DISTANCE];
|
||||
_nearThrowables append (ACE_player nearObjects ["IRStrobeBase", PICK_UP_DISTANCE]);
|
||||
_nearThrowables append (ACE_player nearObjects ["ACE_Chemlight_IR_Dummy", PICK_UP_DISTANCE]);
|
||||
|
||||
{
|
||||
if (!(_x in _throwablesHelped) &&
|
||||
{!(_x isKindOf "SmokeShellArty")} && {!(_x isKindOf "G_40mm_Smoke")} && // All smokes inherit from "GrenadeHand" >> "SmokeShell"
|
||||
{GVAR(enablePickUpAttached) || {!GVAR(enablePickUpAttached) && {isNull (attachedTo _x)}}}
|
||||
) then {
|
||||
TRACE_2("Making PickUp Helper",_x,typeOf _x);
|
||||
private _pickUpHelper = QGVAR(pickUpHelper) createVehicleLocal [0, 0, 0];
|
||||
|
||||
_pickUpHelper attachTo [_x, [0, 0, 0]];
|
||||
_pickUpHelper setVariable [QGVAR(throwable), _x];
|
||||
|
||||
_addedPickUpHelpers pushBack _pickUpHelper;
|
||||
_throwablesHelped pushBack _x;
|
||||
};
|
||||
nil
|
||||
} count _nearThrowables;
|
||||
|
||||
_args set [0, getPosASL ACE_player];
|
||||
_args set [3, _nearThrowables];
|
||||
};
|
||||
|
||||
// Make sure helper is on correct location as it will not automatically move
|
||||
// attachTo is not supported with CfgAmmo, it is only used to get location
|
||||
{
|
||||
// Only handling with attachTo works nicely
|
||||
_x attachTo [_x getVariable [QGVAR(throwable), objNull], [0, 0, 0]];
|
||||
nil
|
||||
} count _addedPickUpHelpers;
|
||||
} else {
|
||||
TRACE_1("Cleaning Pick Up Helpers",count _addedPickUpHelpers);
|
||||
{deleteVehicle _x} count _addedPickUpHelpers;
|
||||
[_idPFH] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
}, 0, [(getPosASL ACE_player) vectorAdd [-100, 0, 0], [], [], []]] call CBA_fnc_addPerFrameHandler;
|
83
addons/advanced_throwing/functions/fnc_throw.sqf
Normal file
83
addons/advanced_throwing/functions/fnc_throw.sqf
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Author: Dslyecxi, Jonpas
|
||||
* Throw selected throwable.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* unit call ace_advanced_throwing_fnc_throw
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unit"];
|
||||
TRACE_1("params",_unit);
|
||||
|
||||
// Prime the throwable if it hasn't been cooking already
|
||||
// Next to proper simulation this also has to happen before delay for orientation of the throwable to be set
|
||||
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
||||
[_unit] call FUNC(prime);
|
||||
};
|
||||
|
||||
[_unit, "ThrowGrenade"] call EFUNC(common,doGesture);
|
||||
|
||||
// Pass position to reset later because animation may change it in certain stances
|
||||
[{
|
||||
params ["_unit", "_activeThrowable", "_posThrown", "_throwType", "_throwSpeed", "_dropMode"];
|
||||
TRACE_6("delayParams",_unit,_activeThrowable,_posThrown,_throwType,_throwSpeed,_dropMode);
|
||||
|
||||
// Reset position in case animation changed it
|
||||
_activeThrowable setPosASL _posThrown;
|
||||
|
||||
// Launch actual throwable
|
||||
private _direction = [THROWSTYLE_NORMAL_DIR, THROWSTYLE_HIGH_DIR] select (_throwType == "high" || {_dropMode});
|
||||
private _velocity = [_throwSpeed, _throwSpeed / THROWSTYLE_HIGH_VEL_COEF / 1.25] select (_throwType == "high");
|
||||
_velocity = [_velocity, THROWSTYLE_DROP_VEL] select _dropMode;
|
||||
|
||||
private _p2 = (eyePos _unit) vectorAdd (AGLToASL (positionCameraToWorld _direction)) vectorDiff (AGLToASL (positionCameraToWorld [0, 0, 0]));
|
||||
private _p1 = AGLtoASL (_activeThrowable modelToWorldVisual [0, 0, 0]);
|
||||
|
||||
private _newVelocity = (_p1 vectorFromTo _p2) vectorMultiply _velocity;
|
||||
|
||||
// Adjust for throwing from inside vehicles, where we have a vehicle-based velocity that can't be compensated for by a human
|
||||
if (vehicle _unit != _unit) then {
|
||||
_newVelocity = _newVelocity vectorAdd (velocity (vehicle _unit));
|
||||
};
|
||||
|
||||
// Drop if unit dies during throw process
|
||||
if (alive _unit) then {
|
||||
_activeThrowable setVelocity _newVelocity;
|
||||
};
|
||||
|
||||
// Invoke listenable event
|
||||
["ace_throwableThrown", [_unit, _activeThrowable]] call CBA_fnc_localEvent;
|
||||
}, [
|
||||
_unit,
|
||||
_unit getVariable [QGVAR(activeThrowable), objNull],
|
||||
getPosASLVisual (_unit getVariable [QGVAR(activeThrowable), objNull]),
|
||||
_unit getVariable [QGVAR(throwType), THROW_TYPE_DEFAULT],
|
||||
_unit getVariable [QGVAR(throwSpeed), THROW_SPEED_DEFAULT],
|
||||
_unit getVariable [QGVAR(dropMode), false]
|
||||
], 0.3] call CBA_fnc_waitAndExecute;
|
||||
|
||||
|
||||
#ifdef DRAW_THROW_PATH
|
||||
GVAR(predictedPath) = call FUNC(drawArc); // save the current throw arc
|
||||
GVAR(flightPath) = [];
|
||||
[_unit getVariable QGVAR(activeThrowable)] spawn {
|
||||
params ["_grenade"];
|
||||
while {!isNull _grenade} do {
|
||||
GVAR(flightPath) pushBack ASLtoAGL getPosASL _grenade;
|
||||
sleep 0.05;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// Stop rendering arc and doing rendering magic while throw is happening
|
||||
[_unit, "Completed a throw fully"] call FUNC(exitThrowMode);
|
28
addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf
Normal file
28
addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Author: CBA Team
|
||||
* Throws Fired XEH.
|
||||
*
|
||||
* Arguments:
|
||||
* 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
|
||||
*
|
||||
* Example:
|
||||
* [unit, "weapon", "muzle", "mode", "ammo", "magazine", projectile] call ace_advanced_throwing_fnc_throwFiredXEH
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
TRACE_1("Fired",_this);
|
||||
|
||||
{
|
||||
_this call _x;
|
||||
} forEach ((_this select 0) getVariable "cba_xeh_fired");
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Author: Jonpas
|
||||
* Updates controls hints based on current state.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call ace_advanced_throwing_fnc_updateControlsHint
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (!GVAR(showMouseControls)) exitWith {};
|
||||
|
||||
private _primed = ACE_player getVariable [QGVAR(primed), false];
|
||||
|
||||
private _mmb = [localize LSTRING(ChangeMode), localize LSTRING(Extend)] select (ACE_player getVariable [QGVAR(dropMode), false]);
|
||||
|
||||
if (!_primed) then {
|
||||
_mmb = [_mmb, localize LSTRING(Cook)] joinString " / ";
|
||||
};
|
||||
|
||||
[
|
||||
localize LSTRING(Throw),
|
||||
[localize ELSTRING(common,Cancel), ""] select _primed,
|
||||
_mmb
|
||||
] call EFUNC(interaction,showMouseHint);
|
1
addons/advanced_throwing/functions/script_component.hpp
Normal file
1
addons/advanced_throwing/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\advanced_throwing\script_component.hpp"
|
32
addons/advanced_throwing/script_component.hpp
Normal file
32
addons/advanced_throwing/script_component.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#define COMPONENT advanced_throwing
|
||||
#define COMPONENT_BEAUTIFIED Advanced Throwing
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DRAW_THROW_PATH
|
||||
// #define ALLOW_QUICK_THROW
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
// #define CBA_DEBUG_SYNCHRONOUS
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
#ifdef DEBUG_ENABLED_ADVANCED_THROWING
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_ADVANCED_THROWING
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_ADVANCED_THROWING
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
|
||||
#define THROWSTYLE_NORMAL_DIR [0, 70, 500]
|
||||
#define THROWSTYLE_HIGH_DIR [0, 200, 500]
|
||||
#define THROWSTYLE_HIGH_VEL_COEF 2
|
||||
#define THROWSTYLE_DROP_VEL 2
|
||||
|
||||
#define THROW_TYPE_DEFAULT "normal"
|
||||
#define THROW_SPEED_DEFAULT 18
|
||||
#define DROP_DISTANCE_DEFAULT 0.2
|
||||
|
||||
#define PICK_UP_DISTANCE 10
|
89
addons/advanced_throwing/stringtable.xml
Normal file
89
addons/advanced_throwing/stringtable.xml
Normal file
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="Advanced_Throwing">
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Category">
|
||||
<English>Advanced Throwing</English>
|
||||
<Russian>Улучшенный бросок гранат</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Module_Description">
|
||||
<English>Allows changing advanced throwing behaviour.</English>
|
||||
<Russian>Позволяет настраивать поведение улучшенного броска гранат.</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Enable_DisplayName">
|
||||
<English>Enable Advanced Throwing</English>
|
||||
<Russian>Включить улучшенный бросок</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Enable_Description">
|
||||
<English>Enables advanced throwing system.</English>
|
||||
<Russian>Включает систему улучшенного броска.</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_ShowThrowArc_DisplayName">
|
||||
<English>Show Throw Arc</English>
|
||||
<Russian>Показать траекторию броска</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_ShowThrowArc_Description">
|
||||
<English>Enables visualization of the throw arc (where throwable will fly).</English>
|
||||
<Russian>Включает визуализацию траектории броска (как полетит граната).</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_ShowMouseControls_DisplayName">
|
||||
<English>Show Throwing Mouse Controls</English>
|
||||
<Russian>Показывать управление мышью</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_ShowMouseControls_Description">
|
||||
<English>Enables visual cues for mouse controls when throwable is prepared.</English>
|
||||
<Russian>Включает отображение подсказок по управлению мышью, когда граната подготовлена.</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUp_DisplayName">
|
||||
<English>Enable Throwables Pick Up</English>
|
||||
<Russian>Включить подбор гранат</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUp_Description">
|
||||
<English>Enables ability to pick up throwables from the ground.</English>
|
||||
<Russian>Включает возможность подбирать гранаты с земли.</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUpAttached_DisplayName">
|
||||
<English>Enable Attached Throwables Pick Up</English>
|
||||
<Russian>Включить подбор прикрепленных гранат</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_EnablePickUpAttached_Description">
|
||||
<English>Enables ability to pick up throwables from attached objects.</English>
|
||||
<Russian>Включает возможность подбирать гранаты, прикрепленные к объектам.</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Prepare">
|
||||
<English>Prepare/Change Throwable</English>
|
||||
<Russian>Подготовить/заменить гранату</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_dropModeHold">
|
||||
<English>Throwable Drop Mode (Hold)</English>
|
||||
<Russian>Режим броска гранаты (удерживать)</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_DropModeToggle">
|
||||
<English>Throwable Drop Mode (Toggle)</English>
|
||||
<Russian>Режим броска гранаты (переключить)</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Primed">
|
||||
<English>Primed</English>
|
||||
<Russian>Подготовлена</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Throw">
|
||||
<English>Throw</English>
|
||||
<Russian>Бросить</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_ChangeMode">
|
||||
<English>(Scroll) Change Mode</English>
|
||||
<Russian>(Скролл) Изменить режим</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Extend">
|
||||
<English>(Scroll) Extend</English>
|
||||
<Russian>(Скролл) Увеличить</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_Cook">
|
||||
<English>(Click) Cook</English>
|
||||
<Russian>(Клик) Подготовить</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Advanced_Throwing_PickUp">
|
||||
<English>Pick Up</English>
|
||||
<Russian>Подобрать</Russian>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
Binary file not shown.
20
addons/apl/model.cfg
Normal file
20
addons/apl/model.cfg
Normal file
@ -0,0 +1,20 @@
|
||||
class CfgSkeletons {
|
||||
class Default {
|
||||
isDiscrete = 1;
|
||||
skeletonInherit = "";
|
||||
skeletonBones[] = {};
|
||||
};
|
||||
};
|
||||
|
||||
class CfgModels {
|
||||
class Default {
|
||||
sectionsInherit="";
|
||||
sections[] = {""};
|
||||
skeletonName = "";
|
||||
};
|
||||
class ace_bodybag: Default {
|
||||
sectionsInherit = "";
|
||||
sections[] = {"camo"};
|
||||
skeletonName = "";
|
||||
};
|
||||
};
|
@ -10,10 +10,11 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) ==
|
||||
|
||||
["12.7x99mm AMAX" , 860, 100, 0.0611565, -0.00036645, 3.81, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 38.10, 1.050, 1, "ASM" ],
|
||||
["12.7x99mm" , 900, 100, 0.0582418, -0.00057503, 3.81, 0, 2, 10, 120, 0, 0, 41.92, 12.7, 38.10, 0.670, 1, "ASM" ],
|
||||
["12.7x99mm API" , 900, 100, 0.0582418, -0.00057503, 3.81, 0, 2, 10, 120, 0, 0, 41.99, 12.9, 38.10, 0.670, 1, "ASM" ],
|
||||
|
||||
["12.7x54mm" , 300, 100, 0.3394630, -0.00019268, 3.81, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 24.13, 1.050, 1, "ASM" ],
|
||||
|
||||
[".408 Chey Tac" , 910, 100, 0.0569400, -0.00038944, 3.81, 0, 2, 10, 120, 0, 0, 27.15, 10.4, 33.02, 0.970, 1, "ASM" ],
|
||||
[".408 Chey Tac" , 910, 100, 0.0569400, -0.00038944, 3.81, 0, 2, 10, 120, 0, 0, 26.57, 10.4, 33.02, 0.970, 1, "ASM" ],
|
||||
|
||||
["9.3×64mm" , 870, 100, 0.0619295, -0.00108571, 3.81, 0, 2, 10, 120, 0, 0, 14.90, 9.30, 35.56, 0.368, 1, "ASM" ],
|
||||
|
||||
@ -21,14 +22,15 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) ==
|
||||
[".338LM 300gr" , 800, 100, 0.0677343, -0.00052190, 3.81, 0, 2, 10, 120, 0, 0, 19.44, 8.58, 25.40, 0.381, 7, "ICAO"],
|
||||
[".338LM API526" , 895, 100, 0.0588865, -0.00069611, 3.81, 0, 2, 10, 120, 0, 0, 16.39, 8.58, 25.40, 0.560, 1, "ASM" ],
|
||||
|
||||
[".300WM Mk248 Mod 0", 900, 100, 0.0584442, -0.00070530, 3.81, 0, 2, 10, 120, 0, 0, 13.31, 7.80, 25.40, 0.268, 7, "ICAO"],
|
||||
[".300WM Mk248 Mod 1", 867, 100, 0.0610738, -0.00061188, 3.81, 0, 2, 10, 120, 0, 0, 14.26, 7.80, 25.40, 0.310, 7, "ICAO"],
|
||||
[".300WM Mk248 Mod0" , 900, 100, 0.0584442, -0.00070530, 3.81, 0, 2, 10, 120, 0, 0, 12.31, 7.80, 25.40, 0.268, 7, "ICAO"],
|
||||
[".300WM Mk248 Mod1" , 867, 100, 0.0610738, -0.00061188, 3.81, 0, 2, 10, 120, 0, 0, 14.26, 7.80, 25.40, 0.310, 7, "ICAO"],
|
||||
[".300WM Berger OTM" , 853, 100, 0.0622179, -0.00053733, 3.81, 0, 2, 10, 120, 0, 0, 14.90, 7.80, 25.40, 0.368, 7, "ICAO"],
|
||||
|
||||
["7.62x54mmR" , 800, 100, 0.0691878, -0.00100023, 3.81, 0, 2, 10, 120, 0, 0, 9.849, 7.92, 24.13, 0.400, 1, "ICAO"],
|
||||
|
||||
["7.62x51mm M80" , 810, 100, 0.0679374, -0.00100957, 3.81, 0, 2, 10, 120, 0, 0, 9.525, 7.82, 25.40, 0.200, 7, "ICAO"],
|
||||
["7.62x51mm M80" , 810, 100, 0.0679374, -0.00100957, 3.81, 0, 2, 10, 120, 0, 0, 9.461, 7.82, 25.40, 0.200, 7, "ICAO"],
|
||||
["7.62x51mm M118LR" , 780, 100, 0.0710319, -0.00082828, 3.81, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.243, 7, "ICAO"],
|
||||
["7.62x51mm Mk316" , 780, 100, 0.0710319, -0.00082029, 3.81, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.243, 7, "ICAO"],
|
||||
["7.62x51mm Mk319" , 910, 100, 0.0584524, -0.00102338, 3.81, 0, 2, 10, 120, 0, 0, 8.424, 7.82, 25.40, 0.377, 1, "ICAO"],
|
||||
["7.62x51mm M993" , 930, 100, 0.0570316, -0.00107148, 3.81, 0, 2, 10, 120, 0, 0, 8.230, 7.82, 25.40, 0.359, 1, "ICAO"],
|
||||
["7.62x51mm Subsonic", 320, 100, 0.3059680, -0.00049899, 3.81, 0, 2, 10, 120, 0, 0, 12.96, 7.82, 25.40, 0.235, 7, "ICAO"],
|
||||
|
@ -15,11 +15,9 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_gunName", "_gunProfileEntry"];
|
||||
|
||||
_gunName = ctrlText 11001;
|
||||
private _gunName = ctrlText 11001;
|
||||
if (_gunName != "") then {
|
||||
_gunProfileEntry = [_gunName, 810, 100, 0.0679, -0.0010350, 3.81, 0, 2, 10, 120, 0, 0, 9.525, 7.82, 25.40, 0.393, 1, "ICAO"],
|
||||
private _gunProfileEntry = [_gunName, 810, 100, 0.0679, -0.0010350, 3.81, 0, 2, 10, 120, 0, 0, 9.525, 7.82, 25.40, 0.393, 1, "ICAO"],
|
||||
|
||||
GVAR(gunList) = GVAR(gunList) + [_gunProfileEntry];
|
||||
|
||||
|
@ -17,21 +17,20 @@
|
||||
|
||||
[] call FUNC(parse_input);
|
||||
|
||||
private ["_scopeBaseAngle"];
|
||||
_scopeBaseAngle = (GVAR(workingMemory) select 3);
|
||||
GVAR(workingMemory) params ["",
|
||||
"_muzzleVelocity", "",
|
||||
"_scopeBaseAngle",
|
||||
"_airFriction",
|
||||
"_boreHeight", "", "", "", "", "", "",
|
||||
"_bulletMass",
|
||||
"_bulletDiameter",
|
||||
"_barrelTwist",
|
||||
"_bc",
|
||||
"_dragModel",
|
||||
"_atmosphereModel"
|
||||
];
|
||||
|
||||
private ["_bulletMass", "_bulletDiameter", "_boreHeight", "_airFriction", "_barrelTwist", "_muzzleVelocity", "_bc", "_dragModel", "_atmosphereModel", "_twistDirection"];
|
||||
_bulletMass = GVAR(workingMemory) select 12;
|
||||
_bulletDiameter = GVAR(workingMemory) select 13;
|
||||
_boreHeight = GVAR(workingMemory) select 5;
|
||||
_airFriction = GVAR(workingMemory) select 4;
|
||||
_barrelTwist = GVAR(workingMemory) select 14;
|
||||
_muzzleVelocity = GVAR(workingMemory) select 1;
|
||||
_bc = GVAR(workingMemory) select 15;
|
||||
_dragModel = GVAR(workingMemory) select 16;
|
||||
_atmosphereModel = GVAR(workingMemory) select 17;
|
||||
|
||||
_twistDirection = 0;
|
||||
private _twistDirection = 0;
|
||||
if (_barrelTwist > 0) then {
|
||||
_twistDirection = 1;
|
||||
} else {
|
||||
@ -39,42 +38,38 @@ if (_barrelTwist > 0) then {
|
||||
_twistDirection = -1;
|
||||
};
|
||||
};
|
||||
_barrelTwist = abs(_barrelTwist);
|
||||
_barrelTwist = abs _barrelTwist;
|
||||
|
||||
private ["_altitude", "_temperature", "_barometricPressure", "_relativeHumidity"];
|
||||
_altitude = GVAR(altitude);
|
||||
_temperature = GVAR(temperature);
|
||||
_barometricPressure = GVAR(barometricPressure);
|
||||
_relativeHumidity = GVAR(relativeHumidity);
|
||||
private _altitude = GVAR(altitude);
|
||||
private _temperature = GVAR(temperature);
|
||||
private _barometricPressure = GVAR(barometricPressure);
|
||||
private _relativeHumidity = GVAR(relativeHumidity);
|
||||
if (!GVAR(atmosphereModeTBH)) then {
|
||||
_barometricPressure = 1013.25 * (1 - (0.0065 * _altitude) / (273.15 + _temperature + 0.0065 * _altitude)) ^ 5.255754495;
|
||||
_relativeHumidity = 50;
|
||||
};
|
||||
|
||||
private ["_bulletLength", "_stabilityFactor"];
|
||||
_bulletLength = 45.72;
|
||||
_stabilityFactor = 1.5;
|
||||
private _bulletLength = 45.72;
|
||||
private _stabilityFactor = 1.5;
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
if (_bulletDiameter > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then {
|
||||
_stabilityFactor = [_bulletDiameter, _bulletLength, _bulletMass, _barrelTwist * 10, _muzzleVelocity, _temperature, _barometricPressure] call EFUNC(advanced_ballistics,calculateStabilityFactor);
|
||||
};
|
||||
};
|
||||
|
||||
private ["_latitude", "_directionOfFire", "_windSpeed1", "_windSpeed2", "_windDirection", "_inclinationAngle", "_targetSpeed", "_targetRange"];
|
||||
_latitude = GVAR(latitude) select GVAR(currentTarget);
|
||||
_directionOfFire = GVAR(directionOfFire) select GVAR(currentTarget);
|
||||
_windSpeed1 = (GVAR(windSpeed1) select GVAR(currentTarget));
|
||||
_windSpeed2 = (GVAR(windSpeed2) select GVAR(currentTarget));
|
||||
_windDirection = (GVAR(windDirection) select GVAR(currentTarget));
|
||||
_inclinationAngle = (GVAR(inclinationAngle) select GVAR(currentTarget));
|
||||
_targetSpeed = (GVAR(targetSpeed) select GVAR(currentTarget));
|
||||
_targetRange = GVAR(rangeCardEndRange);
|
||||
private _latitude = GVAR(latitude) select GVAR(currentTarget);
|
||||
private _directionOfFire = GVAR(directionOfFire) select GVAR(currentTarget);
|
||||
private _windSpeed1 = (GVAR(windSpeed1) select GVAR(currentTarget));
|
||||
private _windSpeed2 = (GVAR(windSpeed2) select GVAR(currentTarget));
|
||||
private _windDirection = (GVAR(windDirection) select GVAR(currentTarget));
|
||||
private _inclinationAngle = (GVAR(inclinationAngle) select GVAR(currentTarget));
|
||||
private _targetSpeed = (GVAR(targetSpeed) select GVAR(currentTarget));
|
||||
private _targetRange = GVAR(rangeCardEndRange);
|
||||
if (GVAR(currentUnit) == 1) then {
|
||||
_targetRange = _targetRange / 1.0936133;
|
||||
};
|
||||
|
||||
GVAR(rangeCardData) = [];
|
||||
|
||||
private ["_result"];
|
||||
_result = [_scopeBaseAngle, _bulletMass, _boreHeight, _airFriction, _muzzleVelocity, _temperature, _barometricPressure, _relativeHumidity, 1000,
|
||||
private _result = [_scopeBaseAngle, _bulletMass, _boreHeight, _airFriction, _muzzleVelocity, _temperature, _barometricPressure, _relativeHumidity, 1000,
|
||||
[_windSpeed1, _windSpeed2], _windDirection, _inclinationAngle, _targetSpeed, _targetRange, _bc, _dragModel, _atmosphereModel, true, _stabilityFactor, _twistDirection, _latitude, _directionOfFire] call FUNC(calculate_solution);
|
||||
|
@ -15,10 +15,8 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_targetSize", "_imageSize", "_angle", "_estRange"];
|
||||
|
||||
_angle = parseNumber(ctrlText 7012);
|
||||
_targetSize = parseNumber(ctrlText 7010);
|
||||
private _angle = parseNumber(ctrlText 7012);
|
||||
private _targetSize = parseNumber(ctrlText 7010);
|
||||
if (GVAR(rangeAssistUseTargetHeight)) then {
|
||||
_targetSize = _targetSize * cos(_angle);
|
||||
};
|
||||
@ -33,7 +31,7 @@ switch (GVAR(rangeAssistTargetSizeUnit)) do {
|
||||
_targetSize = _targetSize * 0.01;
|
||||
};
|
||||
};
|
||||
_imageSize = parseNumber(ctrlText 7011);
|
||||
private _imageSize = parseNumber(ctrlText 7011);
|
||||
switch (GVAR(rangeAssistImageSizeUnit)) do {
|
||||
case 0: {
|
||||
_imageSize = _imageSize / 6400 * 360;
|
||||
@ -45,7 +43,7 @@ switch (GVAR(rangeAssistImageSizeUnit)) do {
|
||||
_imageSize = _imageSize / 60 / 1.047;
|
||||
};
|
||||
};
|
||||
_estRange = parseNumber(ctrlText 7013);
|
||||
private _estRange = parseNumber(ctrlText 7013);
|
||||
if (GVAR(currentUnit) == 1) then {
|
||||
_estRange = _estRange / 1.0936133;
|
||||
};
|
||||
|
@ -15,8 +15,7 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_target"];
|
||||
_target = 0 max _this min 3;
|
||||
private _target = 0 max _this min 3;
|
||||
|
||||
call FUNC(parse_input);
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_index"];
|
||||
_index = lbCurSel 6000;
|
||||
private _index = lbCurSel 6000;
|
||||
|
||||
if (_index == -1) exitWith {};
|
||||
|
||||
|
@ -23,9 +23,8 @@ if !(ctrlVisible 9000) then {
|
||||
ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 9002);
|
||||
|
||||
[{
|
||||
private ["_args", "_startTime"];
|
||||
_args = _this select 0;
|
||||
_startTime = _args select 0;
|
||||
params ["_args"];
|
||||
_args params ["_startTime"];
|
||||
|
||||
if (!(GVAR(speedAssistTimer))) exitWith {
|
||||
GVAR(speedAssistTimer) = true;
|
||||
|
@ -68,7 +68,7 @@ if (_unit == _attachToVehicle) then { //Self Attachment
|
||||
((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetModel _model;
|
||||
|
||||
[{
|
||||
private["_angle", "_dir", "_screenPos", "_realDistance", "_up", "_virtualPos", "_virtualPosASL", "_lineInterection"];
|
||||
private ["_angle", "_dir", "_screenPos", "_realDistance", "_up", "_virtualPos", "_virtualPosASL", "_lineInterection"];
|
||||
params ["_args","_idPFH"];
|
||||
_args params ["_unit","_attachToVehicle","_itemClassname","_itemVehClass","_onAtachText","_actionID"];
|
||||
|
||||
|
@ -64,6 +64,12 @@ if (toLower _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then
|
||||
// Delete attached item after 0.5 seconds
|
||||
[{deleteVehicle (_this select 0)}, [_attachedObject], 2] call CBA_fnc_waitAndExecute;
|
||||
} else {
|
||||
//handle any objects that may be attached to the object
|
||||
{
|
||||
detach _x;
|
||||
deleteVehicle _x;
|
||||
} forEach (attachedObjects _attachedObject);
|
||||
|
||||
// Delete attached item
|
||||
detach _attachedObject;
|
||||
deleteVehicle _attachedObject;
|
||||
|
@ -22,10 +22,8 @@ TRACE_1("params",_unit);
|
||||
|
||||
if (!local _unit) exitWith {};
|
||||
|
||||
private ["_attachedList"];
|
||||
|
||||
_attachedList = _unit getVariable [QGVAR(attached), []];
|
||||
if ((count _attachedList) == 0) exitWith {};
|
||||
private _attachedList = _unit getVariable [QGVAR(attached), []];
|
||||
if (_attachedList isEqualTo []) exitWith {};
|
||||
|
||||
(_attachedList select 0) params ["_xObject"];
|
||||
if (!isNull _xObject) then {
|
||||
|
@ -22,10 +22,8 @@ TRACE_1("params",_unit);
|
||||
|
||||
if (!local _unit) exitWith {};
|
||||
|
||||
private ["_attachedList"];
|
||||
|
||||
_attachedList = _unit getVariable [QGVAR(attached), []];
|
||||
if ((count _attachedList) == 0) exitWith {};
|
||||
private _attachedList = _unit getVariable [QGVAR(attached), []];
|
||||
if (_attachedList isEqualTo []) exitWith {};
|
||||
|
||||
(_attachedList select 0) params ["_xObject", "_xItemName"];
|
||||
if (isNull _xObject) then {
|
||||
|
@ -19,11 +19,9 @@
|
||||
params ["_deadUnit"];
|
||||
TRACE_1("params",_deadUnit);
|
||||
|
||||
private ["_attachedList"];
|
||||
private _attachedList = _deadUnit getVariable [QGVAR(attached), []];
|
||||
|
||||
_attachedList = _deadUnit getVariable [QGVAR(attached), []];
|
||||
|
||||
if ((count _attachedList) == 0) exitWith {};
|
||||
if (_attachedList isEqualTo []) exitWith {};
|
||||
|
||||
{
|
||||
_x params ["_xObject"];
|
||||
|
@ -127,6 +127,33 @@ class CfgWeapons {
|
||||
/* Katiba */
|
||||
class arifle_katiba_Base_F: Rifle_Base_F {};
|
||||
|
||||
/* SPAR */
|
||||
class arifle_SPAR_01_base_F: Rifle_Base_F {
|
||||
magazines[] = {
|
||||
"30Rnd_556x45_Stanag",
|
||||
"30Rnd_556x45_Stanag_green",
|
||||
"30Rnd_556x45_Stanag_red",
|
||||
"30Rnd_556x45_Stanag_Tracer_Red",
|
||||
"30Rnd_556x45_Stanag_Tracer_Green",
|
||||
"30Rnd_556x45_Stanag_Tracer_Yellow",
|
||||
"ACE_30Rnd_556x45_Stanag_M995_AP_mag",
|
||||
"ACE_30Rnd_556x45_Stanag_Mk262_mag",
|
||||
"ACE_30Rnd_556x45_Stanag_Mk318_mag",
|
||||
"ACE_30Rnd_556x45_Stanag_Tracer_Dim"
|
||||
};
|
||||
};
|
||||
class arifle_SPAR_03_base_F: Rifle_Base_F {
|
||||
magazines[] = {
|
||||
"20Rnd_762x51_Mag",
|
||||
"ACE_20Rnd_762x51_Mag_Tracer",
|
||||
"ACE_20Rnd_762x51_Mag_Tracer_Dim",
|
||||
"ACE_20Rnd_762x51_Mk316_Mod_0_Mag",
|
||||
"ACE_20Rnd_762x51_M118LR_Mag",
|
||||
"ACE_20Rnd_762x51_Mk319_Mod_0_Mag",
|
||||
"ACE_20Rnd_762x51_M993_AP_Mag",
|
||||
"ACE_20Rnd_762x51_Mag_SD"
|
||||
};
|
||||
};
|
||||
|
||||
/* Other */
|
||||
class LMG_Mk200_F: Rifle_Long_Base_F {
|
||||
|
@ -1,12 +1,10 @@
|
||||
// by commy2
|
||||
#include "script_component.hpp"
|
||||
|
||||
private "_paper";
|
||||
|
||||
params ["_wall"];
|
||||
|
||||
if (local _wall) then {
|
||||
_paper = "UserTexture_1x2_F" createVehicle position _wall;
|
||||
private _paper = "UserTexture_1x2_F" createVehicle position _wall;
|
||||
|
||||
_paper attachTo [_wall, [0,-0.02,0.6]];
|
||||
_paper setDir getDir _wall;
|
||||
|
@ -13,8 +13,7 @@
|
||||
if (isServer) then {
|
||||
addMissionEventHandler ["HandleDisconnect", {
|
||||
params ["_disconnectedPlayer"];
|
||||
private "_escortedUnit";
|
||||
_escortedUnit = _disconnectedPlayer getVariable [QGVAR(escortedUnit), objNull];
|
||||
private _escortedUnit = _disconnectedPlayer getVariable [QGVAR(escortedUnit), objNull];
|
||||
if ((!isNull _escortedUnit) && {(attachedTo _escortedUnit) == _disconnectedPlayer}) then {
|
||||
detach _escortedUnit;
|
||||
};
|
||||
|
@ -16,11 +16,9 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private "_returnValue";
|
||||
|
||||
params ["_unit", "_newSurrenderState"];
|
||||
|
||||
_returnValue = if (_newSurrenderState) then {
|
||||
private _returnValue = if (_newSurrenderState) then {
|
||||
//no weapon equiped AND not currently surrendering and
|
||||
GVAR(allowSurrender) && {(currentWeapon _unit) == ""} && {!(_unit getVariable [QGVAR(isSurrendering), false])}
|
||||
} else {
|
||||
|
@ -16,8 +16,6 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_cargo"];
|
||||
|
||||
params ["_player", "_unit"];
|
||||
|
||||
((vehicle _unit) != _unit) && {_unit getVariable [QGVAR(isHandcuffed), false]}
|
||||
|
@ -16,20 +16,18 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_weapon", "_listedItemClasses", "_actions", "_allGear"];
|
||||
|
||||
params ["_player", "_unit"];
|
||||
|
||||
_weapon = currentWeapon _player;
|
||||
private _weapon = currentWeapon _player;
|
||||
if (_weapon == primaryWeapon _player && {_weapon != ""}) then {
|
||||
[_player, "AmovPercMstpSlowWrflDnon", 0] call EFUNC(common,doAnimation);
|
||||
};
|
||||
|
||||
_listedItemClasses = [];
|
||||
private _listedItemClasses = [];
|
||||
|
||||
_actions = [localize LSTRING(FriskMenuHeader), ""] call ACE_Interaction_fnc_prepareSelectMenu;
|
||||
private _actions = [localize LSTRING(FriskMenuHeader), ""] call ACE_Interaction_fnc_prepareSelectMenu;
|
||||
|
||||
_allGear = [];
|
||||
private _allGear = [];
|
||||
|
||||
if ((handgunWeapon _unit) != "") then {
|
||||
_allGear pushBack (handgunWeapon _unit);
|
||||
@ -54,8 +52,7 @@ if (count (assignedItems _unit) > 0) then {
|
||||
// Assigned Items
|
||||
{
|
||||
if (!(_x in _listedItemClasses)) then {
|
||||
private "_item";
|
||||
_item = configFile >> "CfgMagazines" >> _x;
|
||||
private _item = configFile >> "CfgMagazines" >> _x;
|
||||
if (isNil "_item" || str _item == "") then { //str _item ?
|
||||
_item = configFile >> "CfgWeapons" >> _x;
|
||||
};
|
||||
|
@ -27,7 +27,7 @@ if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then {
|
||||
};
|
||||
} forEach (attachedObjects _unit);
|
||||
};
|
||||
if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {ERROR("");};
|
||||
if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {WARNING("");};
|
||||
|
||||
if (isNull _vehicle) then {
|
||||
//Looking at a captive unit, search for nearby vehicles with valid seats:
|
||||
@ -44,7 +44,7 @@ if (isNull _vehicle) then {
|
||||
};
|
||||
};
|
||||
|
||||
if (isNull _vehicle) exitWith {ERROR("");};
|
||||
if (isNull _vehicle) exitWith {WARNING("Could not find vehicle to load captive");};
|
||||
|
||||
_unit setVariable [QGVAR(isEscorting), false, true];
|
||||
[QGVAR(moveInCaptive), [_target, _vehicle], [_target]] call CBA_fnc_targetEvent;
|
||||
|
@ -18,50 +18,22 @@
|
||||
params ["_vehicle"];
|
||||
TRACE_1("params", _vehicle);
|
||||
|
||||
_vehicleConfig = configFile >> "CfgVehicles" >> (typeOf _vehicle);
|
||||
private _vehicleConfig = configFile >> "CfgVehicles" >> (typeOf _vehicle);
|
||||
|
||||
_proxyOrder = getArray (_vehicleConfig >> "getInProxyOrder");
|
||||
_transportSoldier = getNumber (_vehicleConfig >> "transportSoldier");
|
||||
_realCargoCount = if (isArray (_vehicleConfig >> "getInProxyOrder")) then {count _proxyOrder} else {_transportSoldier};
|
||||
scopeName "main";
|
||||
|
||||
//Find FFV turrets:
|
||||
_ffvCargoIndexes = [];
|
||||
{
|
||||
_turretConfig = [_vehicleConfig, _x] call EFUNC(common,getTurretConfigPath);
|
||||
_isCargoProxy = ((getText (_turretConfig >> "proxyType")) == "CPCargo") && {isNumber (_turretConfig >> "proxyIndex")};
|
||||
|
||||
if (_isCargoProxy) then {
|
||||
_proxyCargoIndex = getNumber (_turretConfig >> "proxyIndex");
|
||||
_cargoIndex = _proxyOrder find _proxyCargoIndex;
|
||||
_ffvCargoIndexes pushBack _cargoIndex;
|
||||
_x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"];
|
||||
if ((isNull _unit) && {_role == "cargo"} && {_cargoIndex > -1} && {!_isPersonTurret}) then {
|
||||
[_cargoIndex, false] breakOut "main";
|
||||
};
|
||||
} forEach (allTurrets [_vehicle, true]);
|
||||
} forEach (fullCrew [_vehicle, "", true]);
|
||||
|
||||
//Find Empty Seats:
|
||||
_occupiedSeats = [];
|
||||
{
|
||||
_x params ["", "", "_xIndex"];
|
||||
if (_xIndex > -1) then {_occupiedSeats pushBack _xIndex;};
|
||||
} forEach (fullCrew _vehicle);
|
||||
|
||||
TRACE_3("Searching for empty seat",_realCargoCount,_ffvCargoIndexes,_occupiedSeats);
|
||||
|
||||
_emptyCargoSeatReturn = [-1, false];
|
||||
|
||||
//First seach for non-ffv seats:
|
||||
for "_index" from 0 to (_realCargoCount - 1) do {
|
||||
if ((!(_index in _ffvCargoIndexes)) && {!(_index in _occupiedSeats)}) exitWith {
|
||||
_emptyCargoSeatReturn = [_index, false];
|
||||
_x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"];
|
||||
if ((isNull _unit) && {_cargoIndex > -1}) then {
|
||||
[_cargoIndex, true] breakOut "main";
|
||||
};
|
||||
};
|
||||
} forEach (fullCrew [_vehicle, "", true]);
|
||||
|
||||
//Only use FFV if none found:
|
||||
if (_emptyCargoSeatReturn isEqualTo [-1, false]) then {
|
||||
for "_index" from 0 to (_realCargoCount - 1) do {
|
||||
if (!(_index in _occupiedSeats)) exitWith {
|
||||
_emptyCargoSeatReturn = [_index, true];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
_emptyCargoSeatReturn
|
||||
[-1, false]
|
||||
|
@ -21,9 +21,7 @@ params ["_vehicle", "", "_unit"];
|
||||
TRACE_2("params",_vehicle,_unit);
|
||||
|
||||
if ((local _unit) && {_unit getVariable [QGVAR(isHandcuffed), false]}) then {
|
||||
private ["_cargoIndex"];
|
||||
|
||||
_cargoIndex = _unit getVariable [QGVAR(CargoIndex), -1];
|
||||
private _cargoIndex = _unit getVariable [QGVAR(CargoIndex), -1];
|
||||
|
||||
if (_cargoIndex != -1) then {
|
||||
//If captive was not "unloaded", then move them back into the vehicle.
|
||||
|
@ -23,8 +23,7 @@ if (!local _unit) exitWith {};
|
||||
// Group and side respawn can potentially respawn you as a captive unit
|
||||
// Base and instant respawn cannot, so captive should be entirely reset
|
||||
// So we explicity account for the respawn type
|
||||
private ["_respawn"];
|
||||
_respawn = [0] call BIS_fnc_missionRespawnType;
|
||||
private _respawn = [0] call BIS_fnc_missionRespawnType;
|
||||
|
||||
if (_respawn > 3) then {
|
||||
if (_unit getVariable [QGVAR(isHandcuffed), false]) then {
|
||||
|
@ -20,7 +20,7 @@ params ["_unit","_state"];
|
||||
TRACE_2("params",_unit,_state);
|
||||
|
||||
if (!local _unit) exitWith {
|
||||
ERROR("running setHandcuffed on remote unit");
|
||||
WARNING("running setHandcuffed on remote unit");
|
||||
};
|
||||
|
||||
if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith {
|
||||
@ -35,7 +35,7 @@ if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith {
|
||||
};
|
||||
|
||||
if ((_unit getVariable [QGVAR(isHandcuffed), false]) isEqualTo _state) exitWith {
|
||||
ERROR("setHandcuffed: current state same as new");
|
||||
WARNING("setHandcuffed: current state same as new");
|
||||
};
|
||||
|
||||
if (_state) then {
|
||||
|
@ -20,7 +20,7 @@ params ["_unit","_state"];
|
||||
TRACE_2("params",_unit,_state);
|
||||
|
||||
if (!local _unit) exitWith {
|
||||
ERROR("running surrender on remote unit");
|
||||
WARNING("running surrender on remote unit");
|
||||
};
|
||||
|
||||
if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith {
|
||||
@ -35,12 +35,12 @@ if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith {
|
||||
};
|
||||
|
||||
if ((_unit getVariable [QGVAR(isSurrendering), false]) isEqualTo _state) exitWith {
|
||||
ERROR("Surrender: current state same as new");
|
||||
WARNING("Surrender: current state same as new");
|
||||
};
|
||||
|
||||
if (_state) then {
|
||||
if ((vehicle _unit) != _unit) exitWith {ERROR("Cannot surrender while mounted");};
|
||||
if (_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {ERROR("Cannot surrender while handcuffed");};
|
||||
if ((vehicle _unit) != _unit) exitWith {WARNING("Cannot surrender while mounted");};
|
||||
if (_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {WARNING("Cannot surrender while handcuffed");};
|
||||
|
||||
_unit setVariable [QGVAR(isSurrendering), true, true];
|
||||
|
||||
|
@ -19,12 +19,10 @@
|
||||
params ["_target","_vehicle"];
|
||||
TRACE_2("params",_target,_vehicle);
|
||||
|
||||
private ["_cargoIndex"];
|
||||
|
||||
_getSeat = [_vehicle] call FUNC(findEmptyNonFFVCargoSeat);
|
||||
private _getSeat = [_vehicle] call FUNC(findEmptyNonFFVCargoSeat);
|
||||
TRACE_1("free cargo seat",_getSeat);
|
||||
_cargoIndex = _getSeat select 0;
|
||||
if (_cargoIndex == -1) exitWith {ERROR("cargo index -1");};
|
||||
_getSeat params ["_cargoIndex"];
|
||||
if (_cargoIndex == -1) exitWith {WARNING("cargo index -1");};
|
||||
|
||||
_target moveInCargo [_vehicle, _cargoIndex];
|
||||
_target assignAsCargoIndex [_vehicle, _cargoIndex];
|
||||
|
@ -222,6 +222,8 @@ class CfgVehicles {
|
||||
};
|
||||
|
||||
class Heli_Transport_04_base_F: Helicopter_Base_H {
|
||||
// note the double brackets are because loadmasterTurrets is an array of arrays / turret paths
|
||||
GVAR(loadmasterTurrets)[] = {{1}};
|
||||
GVAR(space) = 0;
|
||||
GVAR(hasCargo) = 0;
|
||||
};
|
||||
@ -263,6 +265,16 @@ class CfgVehicles {
|
||||
GVAR(hasCargo) = 0;
|
||||
};
|
||||
|
||||
class VTOL_Base_F;
|
||||
class VTOL_01_base_F: VTOL_Base_F {
|
||||
GVAR(space) = 4;
|
||||
GVAR(hasCargo) = 1;
|
||||
};
|
||||
class VTOL_02_base_F: VTOL_Base_F {
|
||||
GVAR(space) = 4;
|
||||
GVAR(hasCargo) = 1;
|
||||
};
|
||||
|
||||
// autonomus
|
||||
class UAV_01_base_F: Helicopter_Base_F {
|
||||
GVAR(space) = 0;
|
||||
@ -403,6 +415,36 @@ class CfgVehicles {
|
||||
};
|
||||
};
|
||||
};
|
||||
class Constructions_base_F;
|
||||
class Land_WoodenBox_F: Constructions_base_F {
|
||||
class EventHandlers {
|
||||
class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};
|
||||
};
|
||||
|
||||
GVAR(space) = 2;
|
||||
GVAR(hasCargo) = 2;
|
||||
GVAR(size) = 3;
|
||||
GVAR(canLoad) = 1;
|
||||
|
||||
maximumLoad = 2000;
|
||||
transportMaxBackpacks = 12;
|
||||
transportMaxMagazines = 64;
|
||||
transportMaxWeapons = 12;
|
||||
};
|
||||
class Land_WoodenCrate_01_F: ThingX {
|
||||
class EventHandlers {
|
||||
class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};
|
||||
};
|
||||
GVAR(space) = 3;
|
||||
GVAR(hasCargo) = 3;
|
||||
GVAR(size) = 3;
|
||||
GVAR(canLoad) = 1;
|
||||
|
||||
maximumLoad = 2000;
|
||||
transportMaxBackpacks = 12;
|
||||
transportMaxMagazines = 64;
|
||||
transportMaxWeapons = 12;
|
||||
};
|
||||
|
||||
class Cargo_base_F: ThingX {
|
||||
GVAR(space) = 4;
|
||||
|
@ -14,6 +14,7 @@ PREP(makeLoadable);
|
||||
PREP(moduleMakeLoadable);
|
||||
PREP(moduleSettings);
|
||||
PREP(onMenuOpen);
|
||||
PREP(paradropItem);
|
||||
PREP(startLoadIn);
|
||||
PREP(startUnload);
|
||||
PREP(unloadItem);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
["ace_addCargo", {_this call FUNC(addCargoItem)}] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(paradropItem), {_this call FUNC(paradropItem)}] call CBA_fnc_addEventHandler;
|
||||
|
||||
["ace_loadCargo", {
|
||||
params ["_item", "_vehicle"];
|
||||
|
@ -25,9 +25,8 @@ if (getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(hasCargo)) != 1) ex
|
||||
if (isServer) then {
|
||||
{
|
||||
if (isClass _x) then {
|
||||
private ["_cargoClassname", "_cargoCount"];
|
||||
_cargoClassname = getText (_x >> "type");
|
||||
_cargoCount = getNumber (_x >> "amount");
|
||||
private _cargoClassname = getText (_x >> "type");
|
||||
private _cargoCount = getNumber (_x >> "amount");
|
||||
TRACE_3("adding ACE_Cargo", (configName _x), _cargoClassname, _cargoCount);
|
||||
["ace_addCargo", [_cargoClassname, _vehicle, _cargoCount]] call CBA_fnc_localEvent;
|
||||
};
|
||||
@ -48,6 +47,7 @@ private _condition = {
|
||||
};
|
||||
private _statement = {
|
||||
GVAR(interactionVehicle) = _target;
|
||||
GVAR(interactionParadrop) = false;
|
||||
createDialog QGVAR(menu);
|
||||
};
|
||||
private _text = localize LSTRING(openMenu);
|
||||
@ -55,3 +55,24 @@ private _icon = "";
|
||||
|
||||
private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction);
|
||||
[_type, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToClass);
|
||||
|
||||
// Add the paradrop self interaction for planes and helicopters
|
||||
if (_vehicle isKindOf "Air") then {
|
||||
private _condition = {
|
||||
GVAR(enable) && {[_player, _target, []] call EFUNC(common,canInteractWith)} && {
|
||||
private _turretPath = _player call CBA_fnc_turretPath;
|
||||
(_player == (driver _target)) || // pilot
|
||||
{(getNumber (([_target, _turretPath] call CBA_fnc_getTurret) >> "isCopilot")) == 1} || // coPilot
|
||||
{_turretPath in (getArray (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(loadmasterTurrets)))}} // loadMaster turret from config
|
||||
};
|
||||
private _statement = {
|
||||
GVAR(interactionVehicle) = _target;
|
||||
GVAR(interactionParadrop) = true;
|
||||
createDialog QGVAR(menu);
|
||||
};
|
||||
private _text = localize LSTRING(openMenu);
|
||||
private _icon = "";
|
||||
|
||||
private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction);
|
||||
[_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); // self action on the vehicle
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user