diff --git a/.gibot.yml b/.gibot.yml index 194d376713..b3a565a5e4 100644 --- a/.gibot.yml +++ b/.gibot.yml @@ -2,13 +2,13 @@ stages: mark_for_closing: days: 30 labels: - - need more info - - invalid - - can't reproduce - - wontfix - - information required + - status/need more info + - status/invalid + - status/can't reproduce + - status/wontfix exclude: - - marked for cleanup + - status/marked for cleanup + - status/accepting-pr comment: - 'Hello @{author}! There has been no activity on this ticket for over a period of {days} days. I am automatically replying to let you know we will close this ticket within 1 week due to inactivity and consider this resolved.' - 'If you believe this is in error, please reply with the requested information.' @@ -17,11 +17,11 @@ stages: close: false comment: true assign_label: - - marked for cleanup + - status/marked for cleanup clean_up: days: 7 labels: - - marked for cleanup + - status/marked for cleanup comment: - 'Hello @{author}! We have detected no activity for {days} days on this ticket. We therefore assume that the original reporter has lost interest or the issue has been resolved.' - 'Since we have marked this ticket for deletion, we will be closing it.' @@ -31,25 +31,26 @@ stages: close: true comment: true assign_label: - - closed by bot + - status/closed by bot remove_label: - - marked for cleanup + - status/marked for cleanup remind_about_old_ticket: - days: 160 + days: 365 labels: - - bug - - critical bug + - kind/bug + - kind/critical bug exclude: - - need more info - - invalid - - can't reproduce - - wontfix - - information required - - marked for cleanup - - inactive + - status/need more info + - status/invalid + - status/can't reproduce + - status/wontfix + - status/marked for cleanup + - status/inactive + - status/stale + - status/accepting-pr comment: - 'Hello @acemod/maintainers. This ticket has been open for over {days} days without any activity.' action: comment: true assign_label: - - inactive + - status/inactive diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a333dc08fe..b56ddb134a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -22,4 +22,4 @@ **RPT log file:** - Add a link ([gist](https://gist.github.com) or [pastebin](http://pastebin.com)) to the client and/or server RPT file. An instruction to find your RPT files can be found [here](https://community.bistudio.com/wiki/Crash_Files#Arma_3). -- If possible at the time the bug is encountered, go to ACE Options and select "Debug To Clipboard", this will print extensive debug information to the RPT file. +- If possible at the time the bug is encountered, go to Options and select "ACE Debug To Clipboard", this will print extensive debug information to the RPT file and copy it to clipboard. diff --git a/.travis.yml b/.travis.yml index 2345640c8c..02a490b663 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ branches: - release language: python python: -- '3.4' +- '3.6' before_install: - sudo add-apt-repository ppa:koffeinflummi/armake -y - sudo apt-get update -qq @@ -18,7 +18,7 @@ before_script: pip install pygithub3; fi script: -- make +- make -j 3 - python3 tools/sqf_validator.py - python3 tools/config_style_checker.py - if [ -n "${GH_TOKEN}" ] && [ "${TRAVIS_BRANCH}" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then diff --git a/AUTHORS.txt b/AUTHORS.txt index 43e1eeb21e..378419fcdb 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -40,6 +40,7 @@ Aleksey EpMAK Yermakov Alganthe Andrea "AtixNeon" Verano Anthariel +Anton Arkhir Asgar Serran BaerMitUmlaut @@ -51,6 +52,8 @@ Brakoviejo Brisse Brostrom.A | Evul BullHorn +chris579 +classicarma Clon1998 Codingboy Coren @@ -61,6 +64,7 @@ dixon13 Drill Dudakov aka [OMCB]Kaban Dslyecxi +ElTyranos eRazeri evromalarkey F3 Project @@ -85,8 +89,10 @@ havena Hawkins Head Hybrid V +john681611 Karneck Kavinsky +Keithen Kllrt legman Legolasindar "Viper" @@ -96,6 +102,7 @@ Luigi "Luigium" Myrini Macusercom MarcBook meat +mharis001 Michail Nikolaev MikeMatrix nic547 @@ -107,6 +114,7 @@ PaxJaromeMalues Phyma pokertour Professor +QuickDagger rakowozz ramius86 Raspu86 @@ -123,8 +131,10 @@ Tessa Elieff Toaster Tonic Tourorist +Tuupertunut Valentin Torikian voiper VyMajoris(W-Cephei) Winter +xrufix zGuba diff --git a/README.md b/README.md index 747d01bb42..779202d258 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

- ACE3 Version + ACE3 Version ACE3 Issues @@ -18,8 +18,8 @@ ACE3 License - - ACE3 Slack + + ACE3 Slack ACE3 Build Status @@ -28,7 +28,7 @@

Requires the latest version of CBA A3.
- Visit us on Twitter | Facebook | YouTube | Reddit
+ Visit us on Twitter | Facebook | YouTube | Reddit

**ACE3** is a joint effort by the teams behind **ACE2**, **AGM** and **CSE** to improve the realism and authenticity of Arma 3. @@ -37,7 +37,8 @@ The project is entirely **open-source** and all contributions are welcome. Feel The mod is **built modularly**, so almost any included PBO can be easily removed from the configuration. This way, a team can maintain its own tailored version of ACE3 by simply excluding any components they don't need, or those possibly in conflict with other mods. Modules themselves, e.g. the medical system, also include various customization options, allowing mission designers to tweak the overall experience. -### Core features +## Core features + - Brand new 3D interaction/action system - Performance and reliability framework - Focus on modularity and customization @@ -51,7 +52,8 @@ The mod is **built modularly**, so almost any included PBO can be easily removed - Logistics - Advanced missile guidance and laser designation -#### Additional features +### Additional features + - Carrying and dragging - Realistic names for vehicles and weapons - A fire control system (FCS) for armored vehicles and helicopters @@ -72,18 +74,56 @@ The mod is **built modularly**, so almost any included PBO can be easily removed - Vector, MicroDAGR and Kestrel devices
***and much more...*** -### Guides & how-tos -If you installed ACE3 but have trouble understanding how it all works, or where to start, read this first: -- [Installation guide](http://ace3mod.com/wiki/user/installation-guide.html) -- [Information center](http://ace3mod.com/wiki/user/information-center.html) +## Getting started -#### Contributing -You can help out with the ongoing development by looking for potential bugs in our code base, or by contributing new features. To contribute something to ACE3, simply fork this repository and submit your pull requests for review by other collaborators. Remember to add yourself to the author array of any PBO you will be editing and the [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) file; including a valid email address. +ACE3 requires Arma 3 and the latest version of CBA A3. See the following pages for help and information on how to get started with ACE3: + +- [Installation guide](https://ace3mod.com/wiki/user/installation-guide.html) +- [Information center](https://ace3mod.com/wiki/user/information-center.html) + +## Contributing + +You can help out with the ongoing development by looking for potential bugs in our code base, or by contributing new features. We are always welcoming new pull requests containing bug fixes, refactors and new features. We have a list of tasks and bugs on our issue tracker on Github. Please comment on issues if you want to contribute with, to avoid duplicating effort. + +### Contribution guidelines + +To contribute something to ACE3, simply fork this repository and submit your pull requests for review by other collaborators. Remember to add yourself to the author array of any PBO you will be editing and the [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) file; including a valid email address. + +### Submitting issues and requesting features Please, use our [Issue Tracker](https://github.com/acemod/ACE3/issues) to report a bug, propose a feature, or suggest changes to the existing ones. See also: -- [How to report an issue](http://ace3mod.com/wiki/user/how-to-report-an-issue.html) -- [How to make a feature request](http://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) +- [How to report an issue](https://ace3mod.com/wiki/user/how-to-report-an-issue.html) +- [How to make a feature request](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) + +### Testing & building -#### Testing & building To help us test the latest development changes, download our master branch ([directly](https://github.com/acemod/ACE3/archive/master.zip), or [with git](https://help.github.com/articles/fetching-a-remote/)), then assemble a test build: -- [Setting up the development environment](http://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – step-by-step instructions on how to properly setup and build a version of ACE3 for testing purposes. + +- [Setting up the development environment](https://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – step-by-step instructions on how to properly setup and build a version of ACE3 for testing purposes. + +### Get in touch + + + + + + + + + + + + + + + + + + + + +
SlackWe have a public Slack team that anyone can join. This is where all our developers and contributors hang out and where we make announcements
TwitterYou can follow our Twitter account to get updates and various links to guides
FacebookYou can follow our Facebook account to get updates and various links to guides
Bohemia ForumWe have a dedicated thread on the Bohemia Forums for the ACE3 project
+ +## License + +ACE3 is licensed under the GNU General Public License ([GPLv2](https://github.com/acemod/ACE3/blob/master/LICENSE)). diff --git a/ace_advanced_ballistics.dll b/ace_advanced_ballistics.dll index 7b1d952b12..f5686a5a3f 100644 Binary files a/ace_advanced_ballistics.dll and b/ace_advanced_ballistics.dll differ diff --git a/ace_advanced_ballistics_x64.dll b/ace_advanced_ballistics_x64.dll index d50c374fc7..f1802ce5e8 100644 Binary files a/ace_advanced_ballistics_x64.dll and b/ace_advanced_ballistics_x64.dll differ diff --git a/addons/advanced_ballistics/ACE_Settings.hpp b/addons/advanced_ballistics/ACE_Settings.hpp index 0c2265619a..c25592eb5d 100644 --- a/addons/advanced_ballistics/ACE_Settings.hpp +++ b/addons/advanced_ballistics/ACE_Settings.hpp @@ -6,43 +6,13 @@ class ACE_Settings { typeName = "BOOL"; value = 0; }; - class GVAR(simulateForSnipers) { + class GVAR(muzzleVelocityVariationEnabled) { category = CSTRING(DisplayName); - displayName = CSTRING(simulateForSnipers_DisplayName); - description = CSTRING(simulateForSnipers_Description); + displayName = CSTRING(muzzleVelocityVariationEnabled_DisplayName); + description = CSTRING(muzzleVelocityVariationEnabled_Description); typeName = "BOOL"; value = 1; - }; - class GVAR(simulateForGroupMembers) { - category = CSTRING(DisplayName); - displayName = CSTRING(simulateForGroupMembers_DisplayName); - description = CSTRING(simulateForGroupMembers_Description); - typeName = "BOOL"; - value = 0; - }; - class GVAR(simulateForEveryone) { - category = CSTRING(DisplayName); - displayName = CSTRING(simulateForEveryone_DisplayName); - description = CSTRING(simulateForEveryone_Description); - typeName = "BOOL"; - value = 0; - }; - class GVAR(disabledInFullAutoMode) { - category = CSTRING(DisplayName); - displayName = CSTRING(disabledInFullAutoMod_DisplayName); - description = CSTRING(disabledInFullAutoMod_Description); - typeName = "BOOL"; - value = 0; - }; - /* // TODO: We currently do not have firedEHs on vehicles - class GVAR(vehicleGunnerEnabled) { - category = CSTRING(DisplayName); - displayName = "Enabled For Vehicle Gunners"; - description = "Enables advanced ballistics for vehicle gunners"; - typeName = "BOOL"; - value = 0; - }; - */ + }; class GVAR(ammoTemperatureEnabled) { category = CSTRING(DisplayName); displayName = CSTRING(ammoTemperatureEnabled_DisplayName); @@ -70,12 +40,6 @@ class ACE_Settings { description = CSTRING(simulationInterval_Description); typeName = "SCALAR"; value = 0.05; - }; - class GVAR(simulationRadius) { - category = CSTRING(DisplayName); - displayName = CSTRING(simulationRadius_DisplayName); - description = CSTRING(simulationRadius_Description); - typeName = "SCALAR"; - value = 3000; + sliderSettings[] = {0, 0.2, 0.05, 2}; }; }; diff --git a/addons/advanced_ballistics/CfgVehicles.hpp b/addons/advanced_ballistics/CfgVehicles.hpp index 151972ea02..c3a2650150 100644 --- a/addons/advanced_ballistics/CfgVehicles.hpp +++ b/addons/advanced_ballistics/CfgVehicles.hpp @@ -1,7 +1,7 @@ class CfgVehicles { class ACE_Module; class GVAR(ModuleSettings): ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(DisplayName); icon = QPATHTOF(UI\Icon_Module_Wind_ca.paa); category = "ACE"; @@ -17,38 +17,12 @@ class CfgVehicles { typeName = "BOOL"; defaultValue = 0; }; - class simulateForSnipers { - displayName = CSTRING(simulateForSnipers_DisplayName); - description = CSTRING(simulateForSnipers_Description); + class muzzleVelocityVariationEnabled { + displayName = CSTRING(muzzleVelocityVariationEnabled_DisplayName); + description = CSTRING(muzzleVelocityVariationEnabled_Description); typeName = "BOOL"; defaultValue = 1; }; - class simulateForGroupMembers { - displayName = CSTRING(simulateForGroupMembers_DisplayName); - description = CSTRING(simulateForGroupMembers_Description); - typeName = "BOOL"; - defaultValue = 0; - }; - class simulateForEveryone { - displayName = CSTRING(simulateForEveryone_DisplayName); - description = CSTRING(simulateForEveryone_Description); - typeName = "BOOL"; - defaultValue = 0; - }; - class disabledInFullAutoMode { - displayName = CSTRING(disabledInFullAutoMod_DisplayName); - description = CSTRING(disabledInFullAutoMod_Description); - typeName = "BOOL"; - defaultValue = 0; - }; - /* // TODO: We currently do not have firedEHs on vehicles - class vehicleGunnerEnabled { - displayName = "Enabled For Vehicle Gunners"; - description = "Enables advanced ballistics for vehicle gunners"; - typeName = "BOOL"; - defaultValue = 0; - }; - */ class ammoTemperatureEnabled { displayName = CSTRING(ammoTemperatureEnabled_DisplayName); description = CSTRING(ammoTemperatureEnabled_Description); @@ -73,15 +47,9 @@ class CfgVehicles { typeName = "NUMBER"; defaultValue = 0.05; }; - class simulationRadius { - displayName = CSTRING(simulationRadius_DisplayName); - description = CSTRING(simulationRadius_Description); - typeName = "NUMBER"; - defaultValue = 3000; - }; }; class ModuleDescription { description = CSTRING(Description); }; }; -}; \ No newline at end of file +}; diff --git a/addons/advanced_ballistics/XEH_postInit.sqf b/addons/advanced_ballistics/XEH_postInit.sqf index d60feb8311..1e0e6860da 100644 --- a/addons/advanced_ballistics/XEH_postInit.sqf +++ b/addons/advanced_ballistics/XEH_postInit.sqf @@ -9,19 +9,6 @@ GVAR(ProtractorStart) = CBA_missionTime; GVAR(allBullets) = []; GVAR(currentGrid) = 0; -GVAR(extensionAvailable) = true; -/* @TODO: Remove this until versioning is in sync with cmake/build versioning -GVAR(extensionVersion) = ("ace_advanced_ballistics" callExtension "version"); -GVAR(extensionAvailable) = (GVAR(extensionVersion) == EXTENSION_REQUIRED_VERSION); -if (!GVAR(extensionAvailable)) exitWith { - if (GVAR(extensionVersion) == "") then { - diag_log text "[ACE] ERROR: ace_advanced_ballistics.dll is missing"; - } else { - diag_log text "[ACE] ERROR: ace_advanced_ballistics.dll is incompatible"; - }; -}; -*/ - if (!hasInterface) exitWith {}; ["ace_settingsInitialized", { @@ -54,4 +41,4 @@ if (!hasInterface) exitWith {}; #ifdef DEBUG_MODE_FULL call FUNC(diagnoseWeapons); -#endif \ No newline at end of file +#endif diff --git a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf index fd086d65d1..d988d5f8ed 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf @@ -19,20 +19,16 @@ params ["_muzzleVelocityShiftTable", "_temperature"]; -// Check if muzzleVelocityShiftTable is Less Than 11 Entrys +// Check if muzzleVelocityShiftTable is less than 11 Entrys if ((count _muzzleVelocityShiftTable) < 11) exitWith {0}; private _muzzleVelocityShiftTableUpperLimit = _muzzleVelocityShiftTable select 10; -if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith { 0 }; +if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith {0}; // Find exact data index required for given temperature -private _temperatureIndexFunction = (_temperature + 15) / 5; +private _temperatureIndexFunction = 0 max ((_temperature + 15) / 5) min 10; -// lower and upper data index used for interpolation -private _temperatureIndexA = (0 max (floor(_temperatureIndexFunction))) min 10; -private _temperatureIndexB = (0 max (ceil(_temperatureIndexFunction))) min 10; +// Lower and upper data index used for interpolation +private _temperatureIndexA = floor(_temperatureIndexFunction); +private _temperatureIndexB = ceil(_temperatureIndexFunction); -// Interpolation ratio -private _interpolationRatio = _temperatureIndexFunction - floor(_temperatureIndexFunction); - -// Interpolation -(_muzzleVelocityShiftTable select _temperatureIndexA) * (1 - _interpolationRatio) + (_muzzleVelocityShiftTable select _temperatureIndexB) * _interpolationRatio // Return +linearConversion [_temperatureIndexA, _temperatureIndexB, _temperatureIndexFunction, _muzzleVelocityShiftTable select _temperatureIndexA, _muzzleVelocityShiftTable select _temperatureIndexB, true] // Return diff --git a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf index 98912b96e7..4c5cd47a29 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf @@ -19,22 +19,17 @@ */ #include "script_component.hpp" -scopeName "main"; - -private ["_muzzleVelocityTableCount", "_barrelLengthTableCount", "_lowerDataIndex", - "_upperDataIndex", "_lowerBarrelLength", "_upperBarrelLength", "_lowerMuzzleVelocity", - "_upperMuzzleVelocity", "_interpolationRatio"]; params ["_barrelLength", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocity"]; TRACE_4("params",_barrelLength,_muzzleVelocityTable,_barrelLengthTable,_muzzleVelocity); // If barrel length is not defined, then there is no point in calculating muzzle velocity if (_barrelLength == 0) exitWith { 0 }; -_muzzleVelocityTableCount = count _muzzleVelocityTable; -_barrelLengthTableCount = count _barrelLengthTable; +private _muzzleVelocityTableCount = count _muzzleVelocityTable; +private _barrelLengthTableCount = count _barrelLengthTable; // Exit if tables are different sizes, have no elements or have only one element -if (_muzzleVelocityTableCount != _barrelLengthTableCount || _muzzleVelocityTableCount == 0 || _barrelLengthTableCount == 0) exitWith { 0 }; +if (_muzzleVelocityTableCount != _barrelLengthTableCount || _muzzleVelocityTableCount == 0) exitWith { 0 }; if (_muzzleVelocityTableCount == 1) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity }; // If we have the precise barrel length value, return result immediately @@ -46,29 +41,15 @@ if (_barrelLength in _barrelLengthTable) exitWith { if (_barrelLength <= (_barrelLengthTable select 0)) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity }; if (_barrelLength >= (_barrelLengthTable select _barrelLengthTableCount - 1)) exitWith { (_muzzleVelocityTable select _barrelLengthTableCount - 1) - _muzzleVelocity }; +private _upperDataIndex = 0; +private _lowerDataIndex = 1; + // Find closest bordering values for barrel length { - if (_barrelLength <= _x) then { + if (_barrelLength <= _x) exitWith { _upperDataIndex = _forEachIndex; _lowerDataIndex = _upperDataIndex - 1; - breakTo "main"; }; } forEach _barrelLengthTable; -// Worst case scenario -if (isNil "_lowerDataIndex" || isNil "_upperDataIndex") exitWith {0}; - -_lowerBarrelLength = _barrelLengthTable select _lowerDataIndex; -_upperBarrelLength = _barrelLengthTable select _upperDataIndex; -_lowerMuzzleVelocity = _muzzleVelocityTable select _lowerDataIndex; -_upperMuzzleVelocity = _muzzleVelocityTable select _upperDataIndex; - -// Calculate interpolation ratio -_interpolationRatio = if (abs (_lowerBarrelLength - _upperBarrelLength) > 0) then { - (_upperBarrelLength - _barrelLength) / (_upperBarrelLength - _lowerBarrelLength) -} else { - 0 -}; - -// Calculate interpolated muzzle velocity shift -(_lowerMuzzleVelocity + ((_upperMuzzleVelocity - _lowerMuzzleVelocity) * (1 - _interpolationRatio))) - _muzzleVelocity // Return +(linearConversion [_barrelLengthTable select _lowerDataIndex, _barrelLengthTable select _upperDataIndex, _barrelLength, _muzzleVelocityTable select _lowerDataIndex, _muzzleVelocityTable select _upperDataIndex]) - _muzzleVelocity // Return diff --git a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf index 40d065198c..4c929ac22d 100644 --- a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf +++ b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf @@ -18,14 +18,23 @@ #define DEBUG_MODE_FULL #include "script_component.hpp" +private _diagnoseStartTime = diag_tickTime; +#ifdef DEBUG_INIT_SPEEDS + private _data = []; + private _weapons = []; + private _magazines = []; + private _weaponInitSpeeds = []; + private _magazineInitSpeeds = []; +#endif + private _cfgWeapons = configFile >> "CfgWeapons"; for "_i" from 0 to (count _cfgWeapons)-1 do { private _weaponConfig = _cfgWeapons select _i; if (isClass _weaponConfig) then { private _weapon = configName _weaponConfig; private _weaponType = getNumber (_weaponConfig >> "Type"); - if (_weaponType == 1) then { - // The weapon is a primary weapon + if (_weaponType in [1, 2]) then { + // The weapon is a primary weapon or a handgun weapon private _weaponInitSpeed = getNumber (_weaponConfig >> "initSpeed"); private _magazines = getArray (_weaponConfig >> "magazines"); @@ -47,16 +56,78 @@ for "_i" from 0 to (count _cfgWeapons)-1 do { // AB initial speed -------------------------------- // Get Weapon and Ammo Configurations - private _AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig); - private _WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig); - _AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable"]; + private _AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo]; + if (isNil "_AmmoCacheEntry") then { + _AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig); + }; + private _WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon]; + if (isNil "_WeaponCacheEntry") then { + _WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig); + }; + _AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"]; _WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"]; private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _vanillaInitialSpeed] call FUNC(calculateBarrelLengthVelocityShift); private _abInitialSpeed = _vanillaInitialSpeed + _barrelVelocityShift; // -------------------------------------------------- - diag_log text format ["ABDiagnose,%1,%2,%3,%4,%5,%6,%7",_weapon,_magazine,_ammo,_magazineInitSpeed,_weaponInitSpeed,_vanillaInitialSpeed,_abInitialSpeed]; + + if (_weapon find "_base" == -1 && _weapon find "_Base" == -1) then { +#ifdef DEBUG_INIT_SPEEDS + _data pushBack [-_forEachIndex, _abInitialSpeed, _magazine, _weapon]; +#endif + if (_barrelLength > 0 && abs(_vanillaInitialSpeed - _abInitialSpeed) > abs(_abInitialSpeed) * 0.0025) then { + diag_log text format ["AB_Diagnose_initSpeed,%1,%2,%3,%4,%5,%6,%7,%8",_weapon,_magazine,_ammo,_magazineInitSpeed,_weaponInitSpeed,_vanillaInitialSpeed,_abInitialSpeed,_abInitialSpeed/_vanillaInitialSpeed]; + }; + if (_barrelTwist == 0) then { + diag_log text format ["AB_Diagnose_barrelTwist,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_twistDirection,_barrelTwist]; + }; + if (_barrelLength == 0) then { + diag_log text format ["AB_Diagnose_barrelLength,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_barrelLength]; + }; + }; } forEach _magazines; }; }; }; + +#ifdef DEBUG_INIT_SPEEDS + _data sort false; + { + _x params ["_magazineIndex", "_abInitialSpeed", "_magazine", "_weapon"]; + if (_magazines find _magazine == -1) then { + private _magSpeed = _abInitialSpeed; + private _ammoRef = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); + if (_ammoRef != "") then { + { + private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); + if (_ammo == _ammoRef) exitWith { + _magSpeed = _magazineInitSpeeds select _forEachIndex; + }; + } forEach _magazines; + }; + _magazines pushBack _magazine; + _magazineInitSpeeds pushBack round(_magSpeed); + }; + if (_weapons find _weapon == -1) then { + _weapons pushBack _weapon; + _magIndex = _magazines find _magazine; + _magSpeed = _magazineInitSpeeds select _magIndex; + _weaponInitSpeeds pushBack (_abInitialSpeed / _magSpeed); + }; + } forEach _data; + { + _x params ["_magazineIndex", "_abInitialSpeed", "_magazine", "_weapon"]; + _magIndex = _magazines find _magazine; + _magSpeed = _magazineInitSpeeds select _magIndex; + _wepIndex = _weapons find _weapon; + _wepSpeed = _weaponInitSpeeds select _wepIndex; + } forEach _data; + { + diag_log text format ["AB_WeaponInitSpeed,%1,%2", _x, _weaponInitSpeeds select _forEachIndex]; + } forEach _weapons; + { + diag_log text format ["AB_MagazineInitSpeed,%1,%2", _x, _magazineInitSpeeds select _forEachIndex]; + } forEach _magazines; +#endif + +diag_log format["AdvancedBallistics: Finished 'diagnoseWeapons' in %1 seconds", (diag_tickTime - _diagnoseStartTime) toFixed 2]; diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index db85efe137..af13926893 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -15,25 +15,20 @@ */ #include "script_component.hpp" -private _aceTimeSecond = floor CBA_missionTime; - { _x params ["_bullet","_caliber","_bulletTraceVisible","_index"]; - private _bulletVelocity = velocity _bullet; - - private _bulletSpeed = vectorMagnitude _bulletVelocity; - - if (!alive _bullet || _bulletSpeed < 100) then { + if (!alive _bullet) then { GVAR(allBullets) deleteAt (GVAR(allBullets) find _x); } else { + private _bulletVelocity = velocity _bullet; private _bulletPosition = getPosASL _bullet; - if (_bulletTraceVisible && _bulletSpeed > 500) then { + if (_bulletTraceVisible && {vectorMagnitude _bulletVelocity > BULLET_TRACE_MIN_VELOCITY}) 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,"","",""]; }; - call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, CBA_missionTime - _aceTimeSecond]); + _bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6", _index, _bulletVelocity, _bulletPosition, wind, ASLToATL(_bulletPosition) select 2, CBA_missionTime toFixed 6]))); }; nil } count +GVAR(allBullets); diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index a4f55adc3d..e77aad33ad 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -19,102 +19,108 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); -// Parameterization -private ["_abort", "_AmmoCacheEntry", "_WeaponCacheEntry", "_opticsName", "_opticType", "_bulletTraceVisible", "_temperature", "_barometricPressure", "_bulletMass", "_bulletLength", "_muzzleVelocity", "_muzzleVelocityShift", "_bulletVelocity", "_bulletLength", "_barrelTwist", "_stabilityFactor", "_aceTimeSecond", "_barrelVelocityShift", "_ammoTemperatureVelocityShift"]; - -_abort = false; - if (!(_ammo isKindOf "BulletBase")) exitWith {}; if (!alive _projectile) exitWith {}; -if (_unit distance ACE_player > GVAR(simulationRadius)) exitWith {}; if (underwater _unit) exitWith {}; -if (!GVAR(simulateForEveryone) && !(local _unit)) then { - // The shooter is non local - _abort = true; - if (GVAR(simulateForSnipers)) then { - if (currentWeapon _unit == primaryWeapon _unit && count primaryWeaponItems _unit > 2) then { - _opticsName = (primaryWeaponItems _unit) select 2; - _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType"); - _abort = _opticType != 2; // We only abort if the non local shooter is not a sniper + +private _abort = !local _unit; +if (_abort) then { + private _bulletVelocity = velocity _projectile; + private _muzzleVelocity = vectorMagnitude _bulletVelocity; + + private _maxRange = uiNamespace getVariable format[QGVAR(maxRange_%1), _ammo]; + if (isNil "_maxRange") then { + private _airFriction = getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction"); + private _maxRange = if (_airFriction < 0) then { + private _maxTime = ((_vanillaInitialSpeed - BULLET_TRACE_MIN_VELOCITY) / (BULLET_TRACE_MIN_VELOCITY * -_airFriction * _vanillaInitialSpeed)) max getNumber(configFile >> "CfgAmmo" >> _ammo >> "tracerEndTime"); + -ln(1 - _airFriction * _vanillaInitialSpeed * _maxTime) / _airFriction + } else { + _vanillaInitialSpeed * getNumber(configFile >> "CfgAmmo" >> _ammo >> "tracerEndTime") + }; + uiNamespace setVariable [format[QGVAR(maxRange_%1), _ammo], _maxRange]; + }; + if (ACE_player distance _unit > _maxRange && {ACE_player distance ((getPosASL _unit) vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply _maxRange)) > _maxRange}) exitWith {}; + + private _ammoCount = (_unit ammo _muzzle) + 1; + private _tracersEvery = getNumber(configFile >> "CfgMagazines" >> _magazine >> "tracersEvery"); + private _lastRoundsTracer = getNumber(configFile >> "CfgMagazines" >> _magazine >> "lastRoundsTracer"); + if (_ammoCount <= _lastRoundsTracer || {_tracersEvery > 0 && {(_ammoCount - _lastRoundsTracer) % _tracersEvery == 0}}) exitWith { _abort = false }; + + if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then { + if (currentWeapon ACE_player == binocular ACE_player) exitWith { _abort = false }; + if (currentWeapon ACE_player == primaryWeapon ACE_player && {count primaryWeaponItems ACE_player > 2}) then { + private _opticsName = (primaryWeaponItems ACE_player) select 2; + private _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType"); + if (_opticType == 2) exitWith { _abort = false }; }; }; - if (GVAR(simulateForGroupMembers) && _abort) then { - _abort = (group ACE_player) != (group _unit); - }; }; -//if (!GVAR(vehicleGunnerEnabled) && !(_unit isKindOf "Man")) then { _abort = true; }; // We currently do not have firedEHs on vehicles -if (GVAR(disabledInFullAutoMode) && getNumber(configFile >> "CfgWeapons" >> _weapon >> _mode >> "autoFire") == 1) then { _abort = true; }; +if (_abort) exitWith {}; // Get Weapon and Ammo Configurations -_AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo]; +private _AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo]; if (isNil "_AmmoCacheEntry") then { _AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig); }; -_WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon]; +private _WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon]; if (isNil "_WeaponCacheEntry") then { _WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig); }; -_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable"]; +_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"]; _WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"]; +private _temperature = nil; // We need the variable in this scope. So we need to init it here. -_bulletVelocity = velocity _projectile; -_muzzleVelocity = vectorMagnitude _bulletVelocity; +private _ammoCount = _unit ammo _muzzle; +private _bulletVelocity = velocity _projectile; +private _muzzleVelocity = vectorMagnitude _bulletVelocity; -_barrelVelocityShift = 0; if (GVAR(barrelLengthInfluenceEnabled)) then { - _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift); + _muzzleVelocity = _muzzleVelocity + ([_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift)); }; - -_ammoTemperatureVelocityShift = 0; if (GVAR(ammoTemperatureEnabled)) then { _temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight); - _ammoTemperatureVelocityShift = ([_ammoTempMuzzleVelocityShifts, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift)); + _muzzleVelocity = _muzzleVelocity + ([_ammoTempMuzzleVelocityShifts, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift)); +}; +if (GVAR(muzzleVelocityVariationEnabled)) then { + private _time = round (CBA_missionTime / 2); + // Generate seed from publicly known values (via Cantor pairing function) + private _seed = 0.5 * (_time + _ammoCount) * (_time + _ammoCount + 1) + _ammoCount; + // Generate normally distributed random number (via Box–Muller transform) + private _z = sqrt(-2.0 * ln(0.00000001 max (-_seed random 1))) * cos(_seed random 360); + + _muzzleVelocity = _muzzleVelocity * (_z * _muzzleVelocityVariationSD + 1); }; -if (GVAR(ammoTemperatureEnabled) || GVAR(barrelLengthInfluenceEnabled)) then { - _muzzleVelocityShift = _barrelVelocityShift + _ammoTemperatureVelocityShift; - TRACE_4("shift",_muzzleVelocity,_muzzleVelocityShift, _barrelVelocityShift, _ammoTemperatureVelocityShift); - if (_muzzleVelocityShift != 0) then { - _muzzleVelocity = _muzzleVelocity + _muzzleVelocityShift; - _bulletVelocity = _bulletVelocity vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply (_muzzleVelocityShift)); - _projectile setVelocity _bulletVelocity; - }; -}; +_bulletVelocity = (vectorNormalized _bulletVelocity) vectorMultiply _muzzleVelocity; +_projectile setVelocity _bulletVelocity; -if (_abort || !(GVAR(extensionAvailable))) exitWith { - if (missionNamespace getVariable [QEGVAR(windDeflection,enabled), false]) then { - EGVAR(windDeflection,trackedBullets) pushBack [_projectile, getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction")]; - }; -}; - -_bulletTraceVisible = false; -if (GVAR(bulletTraceEnabled) && cameraView == "GUNNER") then { +private _bulletTraceVisible = false; +if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then { if (currentWeapon ACE_player == binocular ACE_player) then { _bulletTraceVisible = true; } else { if (currentWeapon ACE_player == primaryWeapon ACE_player && count primaryWeaponItems ACE_player > 2) then { - _opticsName = (primaryWeaponItems ACE_player) select 2; - _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType"); + private _opticsName = (primaryWeaponItems ACE_player) select 2; + private _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType"); _bulletTraceVisible = _opticType == 2; }; }; }; -_stabilityFactor = 1.5; -if (_caliber > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then { +private _stabilityFactor = 1.5; +if (_caliber * _bulletLength * _bulletMass * _barrelTwist > 0) then { if (isNil "_temperature") then { _temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight); }; - _barometricPressure = ((getPosASL _projectile) select 2) call EFUNC(weather,calculateBarometricPressure); + private _barometricPressure = ((getPosASL _projectile) select 2) call EFUNC(weather,calculateBarometricPressure); _stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor); }; GVAR(currentbulletID) = (GVAR(currentbulletID) + 1) % 10000; -_aceTimeSecond = floor CBA_missionTime; -"ace_advanced_ballistics" callExtension format["new:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:%17:%18", GVAR(currentbulletID), _airFriction, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _stabilityFactor, _twistDirection, _muzzleVelocity, _transonicStabilityCoef, getPosASL _projectile, EGVAR(common,mapLatitude), EGVAR(weather,currentTemperature), EGVAR(common,mapAltitude), EGVAR(weather,currentHumidity), overcast, _aceTimeSecond, CBA_missionTime - _aceTimeSecond]; +"ace_advanced_ballistics" callExtension format["new:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:%17:%18", GVAR(currentbulletID), _ammoCount, _airFriction, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _stabilityFactor, _twistDirection, _transonicStabilityCoef, getPosASL _projectile, _bulletVelocity, EGVAR(common,mapLatitude), EGVAR(weather,currentTemperature), EGVAR(common,mapAltitude), EGVAR(weather,currentHumidity), EGVAR(weather,currentOvercast), CBA_missionTime toFixed 6]; GVAR(allBullets) pushBack [_projectile, _caliber, _bulletTraceVisible, GVAR(currentbulletID)]; diff --git a/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf b/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf index ced2ffbf4e..a92982db21 100644 --- a/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf +++ b/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf @@ -22,14 +22,10 @@ params ["_logic","_units", "_activated"]; if !(_activated) exitWith {}; [_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(muzzleVelocityVariationEnabled), "muzzleVelocityVariationEnabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(ammoTemperatureEnabled), "ammoTemperatureEnabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(barrelLengthInfluenceEnabled), "barrelLengthInfluenceEnabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(bulletTraceEnabled), "bulletTraceEnabled"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(simulateForEveryone), "simulateForEveryone"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(disabledInFullAutoMode), "disabledInFullAutoMode"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(simulateForSnipers), "simulateForSnipers"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(simulateForGroupMembers), "simulateForGroupMembers"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(simulationInterval), "simulationInterval"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(simulationRadius), "simulationRadius"] call EFUNC(common,readSettingFromModule); GVAR(simulationInterval) = 0 max GVAR(simulationInterval) min 0.2; diff --git a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf index 04be6a77db..4b522656ff 100644 --- a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf +++ b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf @@ -17,12 +17,9 @@ if (!hasInterface) exitWith {}; if (!GVAR(enabled)) exitWith {}; -if (!GVAR(extensionAvailable)) exitWith {}; -private ["_initStartTime", "_mapSize", "_mapGrids", "_gridCells", "_x", "_y", "_gridCenter", "_gridHeight", "_gridNumObjects", "_gridSurfaceIsWater"]; - -_initStartTime = CBA_missionTime; -_mapSize = getNumber (configFile >> "CfgWorlds" >> worldName >> "MapSize"); +private _initStartTime = diag_tickTime; +private _mapSize = getNumber (configFile >> "CfgWorlds" >> worldName >> "MapSize"); if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith { INFO_1("Terrain already initialized [world: %1]", worldName); @@ -31,8 +28,8 @@ if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _ma #endif }; -_mapGrids = ceil(_mapSize / 50) + 1; -_gridCells = _mapGrids * _mapGrids; +private _mapGrids = ceil(_mapSize / 50) + 1; +private _gridCells = _mapGrids * _mapGrids; GVAR(currentGrid) = 0; @@ -43,20 +40,20 @@ INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldNa _args params ["_mapGrids", "_gridCells", "_initStartTime"]; if (GVAR(currentGrid) >= _gridCells) exitWith { - INFO_2("Finished terrain initialization in %1 seconds [world: %2]", ceil(CBA_missionTime - _initStartTime), worldName); + INFO_2("Finished terrain initialization in %1 seconds [world: %2]", (diag_tickTime - _initStartTime) toFixed 2, worldName); #ifdef DEBUG_MODE_FULL - systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", ceil(CBA_missionTime - _initStartTime)]; + systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", (diag_tickTime - _initStartTime) toFixed 2]; #endif [_idPFH] call CBA_fnc_removePerFrameHandler; }; for "_i" from 1 to 50 do { - _x = floor(GVAR(currentGrid) / _mapGrids) * 50; - _y = (GVAR(currentGrid) - floor(GVAR(currentGrid) / _mapGrids) * _mapGrids) * 50; - _gridCenter = [_x + 25, _y + 25]; - _gridHeight = round(getTerrainHeightASL _gridCenter); - _gridNumObjects = count (_gridCenter nearObjects ["Building", 50]); - _gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0}; + private _x = floor(GVAR(currentGrid) / _mapGrids) * 50; + private _y = (GVAR(currentGrid) - floor(GVAR(currentGrid) / _mapGrids) * _mapGrids) * 50; + private _gridCenter = [_x + 25, _y + 25]; + private _gridHeight = round(getTerrainHeightASL _gridCenter); + private _gridNumObjects = count (_gridCenter nearObjects ["Building", 50]); + private _gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0}; "ace_advanced_ballistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater]; GVAR(currentGrid) = GVAR(currentGrid) + 1; if (GVAR(currentGrid) >= _gridCells) exitWith {}; diff --git a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf index 9971c99d85..2a5ccb4dfa 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -28,30 +28,34 @@ #include "script_component.hpp" TRACE_1("Reading Ammo Config",_this); -private ["_ammo", "_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_result"]; + private _ammoConfig = configFile >> "CfgAmmo" >> _this; -_airFriction = getNumber(_ammoConfig >> "airFriction"); -_caliber = getNumber(_ammoConfig >> "ACE_caliber"); -_bulletLength = getNumber(_ammoConfig >> "ACE_bulletLength"); -_bulletMass = getNumber(_ammoConfig >> "ACE_bulletMass"); -_transonicStabilityCoef = getNumber(_ammoConfig >> "ACE_transonicStabilityCoef"); +private _airFriction = getNumber(_ammoConfig >> "airFriction"); +private _caliber = 0 max getNumber(_ammoConfig >> "ACE_caliber"); +private _bulletLength = 0 max getNumber(_ammoConfig >> "ACE_bulletLength"); +private _bulletMass = 0 max getNumber(_ammoConfig >> "ACE_bulletMass"); +private _transonicStabilityCoef = 0 max getNumber(_ammoConfig >> "ACE_transonicStabilityCoef") min 1; if (_transonicStabilityCoef == 0) then { _transonicStabilityCoef = 0.5; }; -_dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); -if (_dragModel == 0 || !(_dragModel in [1, 2, 5, 6, 7, 8])) then { +private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); +if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then { _dragModel = 1; }; -_ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); -_velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries"); -_atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere"); +private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); +private _velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries"); +private _atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere"); if (_atmosphereModel isEqualTo "") then { _atmosphereModel = "ICAO"; }; -_ammoTempMuzzleVelocityShifts = getArray(_ammoConfig >> "ACE_ammoTempMuzzleVelocityShifts"); -_muzzleVelocityTable = getArray(_ammoConfig >> "ACE_muzzleVelocities"); -_barrelLengthTable = getArray(_ammoConfig >> "ACE_barrelLengths"); +private _muzzleVelocityVariationSD = DEFAULT_MUZZLE_VELOCITY_VARIATION_SD; +if (isNumber (_ammoConfig >> "ACE_muzzleVelocityVariationSD")) then { + _muzzleVelocityVariationSD = getNumber(_ammoConfig >> "ACE_muzzleVelocityVariationSD") / 100; +}; +private _ammoTempMuzzleVelocityShifts = getArray(_ammoConfig >> "ACE_ammoTempMuzzleVelocityShifts"); +private _muzzleVelocityTable = getArray(_ammoConfig >> "ACE_muzzleVelocities"); +private _barrelLengthTable = getArray(_ammoConfig >> "ACE_barrelLengths"); //Handle subsonic ammo that would have a huge muzzle velocity shift (when ballistic configs not explicitly defined) private _typicalSpeed = getNumber (_ammoConfig >> "typicalSpeed"); @@ -89,7 +93,7 @@ if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then { }; }; -_result = [_airFriction, _caliber, _bulletLength, _bulletMass, _transonicStabilityCoef, _dragModel, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _ammoTempMuzzleVelocityShifts, _muzzleVelocityTable, _barrelLengthTable]; +private _result = [_airFriction, _caliber, _bulletLength, _bulletMass, _transonicStabilityCoef, _dragModel, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _ammoTempMuzzleVelocityShifts, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocityVariationSD]; uiNamespace setVariable [format[QGVAR(%1), _this], _result]; diff --git a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf index af31a67fca..a0fa193b6f 100644 --- a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf @@ -20,8 +20,8 @@ private _weaponConfig = (configFile >> "CfgWeapons" >> _this); -private _barrelTwist = getNumber(_weaponConfig >> "ACE_barrelTwist"); -private _twistDirection = 1; +private _barrelTwist = 0 max getNumber(_weaponConfig >> "ACE_barrelTwist"); +private _twistDirection = [0, 1] select (_barrelTwist != 0); if (isNumber (_weaponConfig >> "ACE_twistDirection")) then { _twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection"); if !(_twistDirection in [-1, 0, 1]) then { @@ -29,7 +29,7 @@ if (isNumber (_weaponConfig >> "ACE_twistDirection")) then { }; }; -private _barrelLength = getNumber(_weaponConfig >> "ACE_barrelLength"); +private _barrelLength = 0 max getNumber(_weaponConfig >> "ACE_barrelLength"); private _result = [_barrelTwist, _twistDirection, _barrelLength]; diff --git a/addons/advanced_ballistics/script_component.hpp b/addons/advanced_ballistics/script_component.hpp index 48344f8ca3..bbd659670f 100644 --- a/addons/advanced_ballistics/script_component.hpp +++ b/addons/advanced_ballistics/script_component.hpp @@ -6,6 +6,8 @@ // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS +#define DEBUG_INIT_SPEEDS + #ifdef DEBUG_ENABLED_ADVANCEDBALLISTICS #define DEBUG_MODE_FULL #endif @@ -16,7 +18,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define GRAVITY 9.80665 #define ABSOLUTE_ZERO_IN_CELSIUS -273.15 #define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS) #define CELSIUS(t) (t + ABSOLUTE_ZERO_IN_CELSIUS) @@ -27,4 +28,9 @@ #define STD_AIR_DENSITY_ICAO 1.22498 #define STD_AIR_DENSITY_ASM 1.20885 + // Standard deviation of the default muzzle velocity variation (0.3%) +#define DEFAULT_MUZZLE_VELOCITY_VARIATION_SD 0.003 + +#define BULLET_TRACE_MIN_VELOCITY 500 + #define EXTENSION_REQUIRED_VERSION "1.0" diff --git a/addons/advanced_ballistics/stringtable.xml b/addons/advanced_ballistics/stringtable.xml index 631acc92c7..7abec780da 100644 --- a/addons/advanced_ballistics/stringtable.xml +++ b/addons/advanced_ballistics/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -76,170 +76,24 @@ Engedélyezi a fejlett ballisztikát Включает продвинутую баллистику Abilita Balistica Avanzata - アドバンスド バリスティックスを有効化 + アドバンスド バリスティックス 고급 탄도학을 적용합니다 啟用先進彈道系統 启用先进弹道系统 - - Enabled For Snipers - Activada para francotiradores - Akt. dla snajperów - Für Scharfschützen aktiviert - Povoleno pro odstřelovače - Ativar para caçadores - Activé pour les snipers - Mesterlövészeknek engedélyezve - Включена для снайперов - Abilita per Tiratori Scelti - 狙撃手へ有効化 - 저격수만 적용 - 啟用給狙擊手 - 启用给狙击手 + + Enable Muzzle Velocity Variation + Variation der Mündungsgeschwindigkeit aktivieren + 銃口初速の変化 + Abilita Variazione Velocità Volata + 총구속도 변화적용 - - Enables advanced ballistics for non local snipers (when using high power optics) - Activa la balística avanzada para francotiradores no locales (cuando se usa una mira telescópica) - Aktywuje zaawansowaną balistykę dla nielokalnych snajperów (kiedy używają optyki) - Aktiviert die erweiterte Ballistik für nicht lokale Scharfschützen (bei Benutzung von Optiken mit starker Vergrößerung) - Aktivuje pokročilou balistiku pro nelokální odstřelovače (při použití optiky) - Ativa balística avançada para caçadores não locais (quando usando miras telescópicas) - Active la balistique avancée pour les snipers non locaux (en utilisant les optiques avancées) - Engedélyezi a fejlett ballisztikát nem-helyi mesterlövészeknek (nagy-teljesítményű optika használatakor) - Включает продвинутую баллистику для нелокальных снайперов (при использовании мощной оптики) - Abilita Balistica Avanzata per Tiratori Scelti non locali (con ottiche ad alto potenziale) - 非ローカルの狙撃手 (高倍率スコープを使っている場合)へアドバンスド バリスティックスを有効化します - 고급 탄도학을 비-저격수 인원에게도 적용합니다(고성능 조준경을 사용시) - 啟用先進彈道系統給非本地狙擊手(當使用高倍率光學瞄鏡時) - 启用先进弹道系统给非本地狙击手(当使用高倍率光学瞄镜时) - - - Enabled For Group Members - Activada para miembros de grupo - Akt. dla czł. grupy - Für Gruppenmitglieder aktiviert - Povoleno pro členy skupiny - Ativada para membros do grupo - Activé pour les membres groupés - Csoporttagoknak engedélyezve - Включена для группы - Abilita per Membri del Gruppo - グループ メンバーへ有効化 - 그룹 멤버도 적용 - 啟用給小隊成員 - 启用给小队成员 - - - Enables advanced ballistics for non local group members - Activada la balística avanzada para miembros de grupo no locales - Aktywuje zaawansowaną balistykę dla nielokalnych członków grupy - Aktiviert die erweiterte Ballistik für nicht lokale Gruppenmitglieder - Aktivuje pokročilou balistiku pro nelokální členy skupiny - Ativa balística avançada para membros de grupo não locais - Active la balistique avancée pour les membres du groupe non locaux - Engedélyezi a fejlett ballisztikát nem-helyi csoporttagoknak - Включает продвинутую баллистику для нелокальных членов группы - Abilita Balistica Avanzata per Membri non locali del Gruppo - 非ローカルのグループ メンバーへアドバンスド バリスティックスを有効化します - 고급 탄도학을 비-그룹멤버에게도 적용합니다 - 啟用先進彈道系統給非本地小隊成員 - 启用先进弹道系统给非本地小队成员 - - - Enabled For Everyone - Activada para todos - Akt. dla wszystkich - Für jeden aktiviert - Povoleno pro všechny - Ativada para todos - Activé pour tout le monde - Mindenkinek engedélyezve - Включена для всех - Abilita per tutti - 全員に有効化 - 모두에게 적용 - 啟用給所有人 - 启用给所有人 - - - Enables advanced ballistics for all non local players (enabling this may degrade performance during heavy firefights in multiplayer) - Activada la balística avanzada para todos los jugadores no locales (activarlo puede degradar el rendimiento durante grandes tiroteos en multijugador). - Aktywuje zaawansowaną balistykę dla wszystkich nielokalnych graczy (aktywacja tej opcji może spodowować spory spadek wydajności podczas ciężkiej wymiany ognia) - Aktiviert die erweiterte Ballistik für alle nicht lokalen Spieler (das Aktivieren dieser Funktion kann zur Beeinträchtigung des Spielerlebnisses im Multiplayer führen) - Aktivuje pokročilou balistiku pro všechny nelokální hráče (aktivace této možnosti způsobuje pokles FPS během velké přestřelky v multiplayeru) - Ativa balística avançada para todos os jogadores não locais (ativando isso pode degradar a performance durante troca de tiros intensas no multiplayer) - Active la balistique avancée pour tous les joueurs non locaux (activer cette option peut avoir un impact sur les performance en multi durant les grands échanges de tirs) - Engedélyezi a fejlett ballisztikát az összes nem-helyi játékosnak (ez a funkció leronthatja a teljesítményt intenzív többjátékos tűzharcok alatt) - Включает продвинутую баллистику для всех нелокальных игроков (включение этой опции может снизить производительность при массовых перестрелках в мультиплеере) - Abilita Balistica Avanzata per tutti i giocatori non locali (abilitare questo parametro potrebbe ridurre le prestazioni durante scontri intensi in multiplayer) - 非ローカルの全プレイヤーへアドバンスド バリスティックスを有効化します (マルチプレイで大規模な銃撃戦がおこなわれると、動作の低下を招きます) - 고급 탄도학을 모든 비-로컬그룹에게도 적용합니다(적용 후 대규모 전투시 성능하락을 유발할 수 있습니다) - 啟用先進彈道系統給所有非本地玩家 (啟用此功能後,在多人連線大量交火時可能會降低效能) - 启用先进弹道系统给所有非本地玩家 (启用此功能后,在多人连线大量交火时可能会降低效能) - - - Always Enabled For Group Members - Zawsze akt. dla czł. grupy - Siempre activada para miembros de grupo - Für Gruppenmitglieder immer aktiviert - Vždy povoleno pro členy skupiny - Sempre ativada para membros do grupo - Toujours activer pour les membres du groupe - Mindig engedélyezve csoporttagoknak - Всегда включена для членов группы - Sempre abilitato per Membri del Gruppo - 常にグループ メンバーへ有効化 - 그룹 멤버에게 항상 적용 - 永遠啟用給小隊成員 - 永远启用给小队成员 - - - Always enables advanced ballistics when a group member fires - Aktywuje zaawansowaną balistykę dla wszystkich członków grupy - Activada la balística avanzada siempre cuando miembros de grupo disparan - Aktiviert die erweiterte Ballistik immer, wenn ein Gruppenmitglied schießt - Aktivuje pokročilou balistiku pro členy skupiny - Sempre ative balística avançada quando um membro do grupo disparar - Active tout le temps la balistique avancée quand un membre du groupe ouvre le feu - Mindig engedélyezi a fejlett ballisztikát, ha egy csoporttag tüzel - Всегда включает продвинутую баллистику когда стреляет член группы - Abilita sempre Balistica Avanzata quando un membro del gruppo spara - グループ メンバーが射撃した時、常にアドバンスド バリスティックスを有効化します - 그룹 멤버가 발사시 항상 고급 탄도학을 적용합니다 - 當小隊成員開火時,永遠啟用先進彈道系統 - 当小队成员开火时,永远启用先进弹道系统 - - - Disabled In FullAuto Mode - Wył. podczas ognia auto. - Desactivada en modo automático - Beim vollautomatischen Feuern deaktiviert - Zakázáno v automatickém režimu střelby - Desabilitar no modo automático - Désactiver en mode automatique - Automata módban letiltva - Выкл. для автомат. режима - Disabilita in modalità di fuoco automatico - フルオートでは無効化 - 조정간 자동시 비활성화 - 在全自動模式時關閉 - 在全自动模式时关闭 - - - Disables the advanced ballistics during full auto fire - Dezaktywuje zaawansowaną balistykę podczas ognia automatycznego - Desactivada la balística avanzada durante el fuego automático - Deaktiviert die erweiterte Ballistik beim vollautomatischen Feuern - Zákáže pokročilou balistiku během střelby v režimu automat - Desabilitar a balística avançada durante fogo automático - Désactive la balistique avancée pour les tirs en automatique - Letiltja a fejlett ballisztikát automata tüzelés folyamán - Выключает продвинутую баллистику при стрельбе в полностью автоматическом режиме - Disabilita Balistica Avanzata durante fuoco automatico - フルオートで射撃中ではアドバンスド バリスティックスを無効化します - 조정간 자동시 고급 탄도학을 비활성화 합니다 - 在全自動模式開火時,關閉先進彈道系統 - 在全自动模式开火时,关闭先进弹道系统 + + Simulates slight variations in muzzle velocity between each shot + Simuliert leichte Variationen der Mündungsgeschwindigkeit zwischen jedem Schuss. + 発射毎に僅かな銃口初速の変化をシミュレートします。 + Simula lievi variazioni della velocità della volata tra un colpo e l'altro + 각 사격 사이에 총구속도 변화를 시뮬레이션 합니다. Enable Ammo Temperature Simulation @@ -252,7 +106,7 @@ Lőszer-hő szimuláció engedélyezése Симуляция температуры для боеприпасов Abilita simulazione della temperatura delle munizioni - 弾薬の温度シミュレーションを有効化 + 弾薬温度シミュレーション 탄약 온도 구현 적용 啟用彈藥溫度模擬系統 启用弹药温度模拟系统 @@ -268,7 +122,7 @@ A kezdősebesség a lőszer hőmérsékletétől függően változó Начальная скорость пули зависит от температуры La velocità dello sparo varia a seconda della temperatura delle munizioni - 弾薬の温度により初速値を変化させます + 弾薬の温度により銃口初速を変化させます 탄약 온도에 비례해 총구 속도가 달라집니다 子彈初速將隨彈藥溫度而有所變化 子弹初速将随弹药温度而有所变化 @@ -284,7 +138,7 @@ Csőhossz-szimuláció engedélyezése Симуляция длины ствола Abilita simulazione della lunghezza della canna - 銃身長のシミュレーションを有効化 + 銃身長シミュレーション 총열 길이 구현 적용 啟用槍管長度模擬系統 启用枪管长度模拟系统 @@ -300,7 +154,7 @@ A kezdősebesség a cső hosszától függően változó Начальная скорость пули зависит от длины ствола La velocità di sparo varia a seconda della lunghezza della canna - 銃身長により初速値を変化させます + 銃身長により銃口初速を変化させます 총구 속도가 총열에 비례해 달라집니다 子彈初速將隨槍管長度而有所變化 子弹初速将随枪管长度而有所变化 @@ -316,7 +170,7 @@ Nyomkövető-effekt engedélyezése Следы пуль Abilita effetto dei Proiettili Traccianti - 弾丸の痕跡表示を有効化 + 弾丸の痕跡表示 예광탄 효과 적용 啟用曳光彈效果 启用曳光弹效果 @@ -354,10 +208,10 @@ 模拟间隔 - Defines the interval between every calculation step + Defines the interval between each calculation step Określa interwał pomiędzy każdym krokiem kalkulacji Define el intervalo entre cada cálculo - Legt das Intervall zwischen den Berechnungsschritten fest + Definiert das Intervall zwischen den einzelnen Simulationsschritten Určuje interval mezi každým výpočtem Define o intervalo entre cada cálculo Définit un intervalle de calcul entre deux simulations @@ -380,7 +234,7 @@ Szimuláció hatóköre Радиус симуляции Raggio Simulazione - シミュレーションの適用範囲 + シミュレーション適用範囲 구현 범위 模擬半徑 模拟半径 @@ -414,8 +268,8 @@ Questo modulo abilita la simulazione della Balistica Avanzata - cioè la traiettoria dei proiettili è influenzata da variabili come la temperatura dell'aria, pressione atmosferica, umidità, gravità, il tipo di munizione e l'arma da cui è sparata このモジュールはアドバンスド バリスティックスを有効化します。弾道は気温や気圧、湿度、重力、弾薬の種類、発射する武器から影響を受けるようになります。 이 모듈은 고급 탄도학을 적용시킵니다 - 이는 발사체의 궤적이 기온, 대기압, 습도, 중력, 탄환의 종류와 어느 무기에서 발사되는지에 따라 영향을 받습니다. - 該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響. - 该模块实现先进的弹道仿真 - 这意味着子弹的轨迹是由空气温度、大气压力、湿度、重力、弹药类型以及射击的武器所影响. + 該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響 + 该模块实现先进的弹道仿真 - 这意味着子弹的轨迹是由空气温度、大气压力、湿度、重力、弹药类型以及射击的武器所影响 diff --git a/addons/advanced_fatigue/ACE_Settings.hpp b/addons/advanced_fatigue/ACE_Settings.hpp index 8242e16111..2d46fd5eb3 100644 --- a/addons/advanced_fatigue/ACE_Settings.hpp +++ b/addons/advanced_fatigue/ACE_Settings.hpp @@ -1,13 +1,13 @@ class ACE_Settings { class GVAR(enabled) { - category = "Advanced Fatigue"; + category = CSTRING(DisplayName); displayName = CSTRING(Enabled); description = CSTRING(Enabled_Description); typeName = "BOOL"; value = 1; }; class GVAR(enableStaminaBar) { - category = "Advanced Fatigue"; + category = CSTRING(DisplayName); displayName = CSTRING(EnableStaminaBar); description = CSTRING(EnableStaminaBar_Description); typeName = "BOOL"; @@ -15,31 +15,35 @@ class ACE_Settings { isClientSettable = 1; }; class GVAR(performanceFactor) { - category = "Advanced Fatigue"; + category = CSTRING(DisplayName); displayName = CSTRING(PerformanceFactor); description = CSTRING(PerformanceFactor_Description); typeName = "SCALAR"; value = 1; + sliderSettings[] = {0, 5, 1, 1}; }; class GVAR(recoveryFactor) { - category = "Advanced Fatigue"; + category = CSTRING(DisplayName); displayName = CSTRING(RecoveryFactor); description = CSTRING(RecoveryFactor_Description); typeName = "SCALAR"; value = 1; + sliderSettings[] = {0, 5, 1, 1}; }; class GVAR(loadFactor) { - category = "Advanced Fatigue"; + category = CSTRING(DisplayName); displayName = CSTRING(LoadFactor); description = CSTRING(LoadFactor_Description); typeName = "SCALAR"; value = 1; + sliderSettings[] = {0, 5, 1, 1}; }; class GVAR(terrainGradientFactor) { - category = "Advanced Fatigue"; + category = CSTRING(DisplayName); displayName = CSTRING(TerrainGradientFactor); description = CSTRING(TerrainGradientFactor_Description); typeName = "SCALAR"; value = 1; + sliderSettings[] = {0, 5, 1, 1}; }; }; diff --git a/addons/advanced_fatigue/CfgVehicles.hpp b/addons/advanced_fatigue/CfgVehicles.hpp index 922322b588..f6cead81e1 100644 --- a/addons/advanced_fatigue/CfgVehicles.hpp +++ b/addons/advanced_fatigue/CfgVehicles.hpp @@ -3,9 +3,9 @@ class CfgVehicles { class GVAR(moduleSettings): ACE_Module { author = ECSTRING(common,ACETeam); category = "ACE"; - displayName = "Advanced Fatigue"; + displayName = CSTRING(DisplayName); function = QFUNC(moduleSettings); - scope = 2; + scope = 1; isGlobal = 1; isTriggerActivated = 0; icon = QPATHTOF(UI\Icon_Module.paa); diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index 9aba5d1a04..95b30d3c57 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -1,6 +1,15 @@ - + + + Advanced Fatigue + Erweiterte Ausdauer + 進階疲勞 + 进阶疲劳 + アドバンスド疲労 + Fatica Avanzata + 고급 피로도 + Performance Factor Leistungsfaktor @@ -15,24 +24,24 @@ Influences the overall performance of all players with no custom factor. Higher means better. Beinflusst die Leistungsfähigkeit aller Spieler ohne eigenen Leistungsfaktor. Ein höherer Wert bedeutet bessere Leistung. - 非カスタム要因をもつ全プレイヤーへ全体的に動作を影響させます。高いほど影響がでます。 + 非カスタム要因をもつ全プレイヤーへ全体的に動作を影響させます。高いほど良い効果があります。 Wpływa na ogólną wydolność organizmu u wszystkich graczy bez ustawionego niestandardowego współczynnika. Więcej znaczy lepiej. 모든 성능이 임의로 설정된 값 없이 영향받습니다. 값이 클수록 더 나은 성능을 발휘합니다 Influence les performances générales de tous les joueurs sans facteurs personalisés. Une valeur plus élevée implique de meilleures performances. Influenza qualsiasi prestazione di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore. - 影響所有玩家的體力表現. 值越高代表體力越好. - 影响所有玩家的体力表现. 值越高代表体力越好. + 影響所有玩家的體力表現,值越高代表體力越好 + 影响所有玩家的体力表现,值越高代表体力越好 Influences the overall performance of this unit. Higher means better. Beinflusst die Leistungsfähigkeit dieser Einheit. Ein höherer Wert bedeutet bessere Leistung. - 非カスタム要因をもつ全プレイヤーへ全体的に動作を影響させます。高いほど影響がでます。 + このユニットの全体的な動作に影響させます。高いほど良い効果があります。 Wpływa na ogólną wydolność tej jednostki. Więcej znaczy lepiej. 모든 성능이 이 단위로 영향을 받습니다. 값이 클수록 더 나은 성능을 발휘합니다 Influence les performances générales de cette unité. Une valeur plus élevée implique de meilleures performances. Influenza qualsiasi prestazione di questa unità. Maggiore significa migliore. - 影響這個單位的體力表現. 值越高代表體力越好. - 影响这个单位的体力表现. 值越高代表体力越好. + 影響這個單位的體力表現,值越高代表體力越好 + 影响这个单位的体力表现,值越高代表体力越好 Recovery Factor @@ -48,13 +57,13 @@ Changes how fast the player recovers when resting. Higher is faster. Ändert, wie schnell ein Spieler Ausdauer regeneriert. Ein höherer Wert bedeutet eine schnellere Regeneration. - 休憩時は、プレイヤーが早く回復します。高いほど早くなります。 + 休憩時はプレイヤーが早く回復します。高いほど早くなります。 Wpływa na czas regeneracji podczas postoju. Więcej znaczy szybciej. 얼마나 빨리 회복하는지를 바꿉니다. 값이 클수록 더 나은 성능을 발휘합니다 Change la vitesse à laquelle les joueurs récupèrent leur endurance lorsqu'ils se reposent. Une valeur plus élevée implique une récupération plus rapide. Determina in quanto tempo il giocatore recupera quando rilassato. Maggiore significa migliore. - 決定玩家休息多久就能回復體力. 值越高恢復越快. - 决定玩家休息多久就能回复体力. 值越高恢复越快. + 決定玩家休息多久就能回復體力,值越高恢復越快 + 决定玩家休息多久就能回复体力,值越高恢复越快 Load Factor @@ -70,13 +79,13 @@ Increases or decreases how much weight influences the players performance. Zero means equipment weight has no performance influence. Erhöht oder verringert, wie viel Einfluss das Ausrüstungsgewicht auf die Leistung hat. Null heißt, dass es keinen Einfluss hat. - 重量によりプレイヤーの動作への影響下増加したり、低下します。装備を持っていない場合、影響はしません。 + 重量の増減によりプレイヤーの動作へ影響を与えます。装備を持っていない場合、影響はしません。 Zmniejsza lub zwiększa wpływ ciężaru ekwipunku na wydolność gracza. Zero oznacza kompletny brak wpływu na wydolność. 플레이어가 무게에 따라 얼마나 영향받는지를 증가시키거나 감소시킵니다. 0의 경우 플레이어가 장비 무게에 영향받지 않습니다. Augmente ou réduit l'influence que le poids à sur les performances des joueurs. Zéro implique que le poids de l'équipement n'a pas d'influence sur les performances. Incrementa o decrementa quanto il peso influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non ha alcuna influenza nelle prestazioni. - 增加或降低玩家所能承受的負重量. 如設定值為0, 代表裝備的重量將不會影響到玩家的體力表現. - 增加或降低玩家所能承受的负重量. 如设定值为0, 代表装备的重量将不会影响到玩家的体力表现. + 增加或降低玩家所能承受的負重量. 如設定值為0, 代表裝備的重量將不會影響到玩家的體力表現 + 增加或降低玩家所能承受的负重量. 如设定值为0, 代表装备的重量将不会影响到玩家的体力表现 Terrain Gradient Factor @@ -97,8 +106,8 @@ 경사도에 따라 얼마나 피로해지는지를 정합니다. 값이 클수록 더 많은 피로를 유발합니다. Configure l'influence de l'inclinaison du terrain sur la perte d'endurance. Une valeur plus élevée implique une perte d'endurance plus importante. Stabilisce quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa. - 設定陡峭的地形將會影響多少體力的流失. 值越高代表體力流失越快. - 设定陡峭的地形将会影响多少体力的流失. 值越高代表体力流失越快. + 設定陡峭的地形將會影響多少體力的流失,值越高代表體力流失越快 + 设定陡峭的地形将会影响多少体力的流,失值越高代表体力流失越快 Enabled @@ -141,8 +150,8 @@ 피로도 막대를 보여줍니다. Affiche la barre d'endurance. Mostra la barra della stamina. - 顯示體力條. - 显示体力条. + 顯示體力條 + 显示体力条 diff --git a/addons/advanced_throwing/CfgAmmo.hpp b/addons/advanced_throwing/CfgAmmo.hpp new file mode 100644 index 0000000000..51f5d08a31 --- /dev/null +++ b/addons/advanced_throwing/CfgAmmo.hpp @@ -0,0 +1,11 @@ +class CfgAmmo { + class Default; + class Grenade: Default { + GVAR(torqueDirection)[] = {1, 1, 0}; + GVAR(torqueMagnitude) = "(50 + random 100) * selectRandom [1, -1]"; + }; + class GrenadeCore: Default { + GVAR(torqueDirection)[] = {1, 1, 0}; + GVAR(torqueMagnitude) = "(50 + random 100) * selectRandom [1, -1]"; + }; +}; diff --git a/addons/advanced_throwing/CfgVehicles.hpp b/addons/advanced_throwing/CfgVehicles.hpp index 043de34bdb..c3ee134968 100644 --- a/addons/advanced_throwing/CfgVehicles.hpp +++ b/addons/advanced_throwing/CfgVehicles.hpp @@ -7,7 +7,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Category); function = QFUNC(moduleInit); - scope = 2; + scope = 1; isGlobal = 1; icon = QPATHTOF(UI\Icon_Module_AdvancedThrowing_ca.paa); class Arguments { @@ -60,6 +60,7 @@ class CfgVehicles { displayName = CSTRING(PickUp); condition = QUOTE([ARR_2(_player,true)] call FUNC(canPrepare)); statement = QUOTE(_this call FUNC(pickUp)); + exceptions[] = {"isNotSwimming"}; 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"; }; diff --git a/addons/advanced_throwing/XEH_postInit.sqf b/addons/advanced_throwing/XEH_postInit.sqf index 96cb92801e..7c0a194267 100644 --- a/addons/advanced_throwing/XEH_postInit.sqf +++ b/addons/advanced_throwing/XEH_postInit.sqf @@ -31,7 +31,7 @@ GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; ["ACE3 Weapons", QGVAR(dropModeToggle), localize LSTRING(DropModeToggle), { // Condition - if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false}; + if (!(ACE_player getVariable [QGVAR(inHand), false]) || {underwater ACE_player}) exitWith {false}; // Statement private _currentDropMode = ACE_player getVariable [QGVAR(dropMode), false]; @@ -117,7 +117,9 @@ addMissionEventHandler ["Draw3D", { // Blue is predicted before throw, red is re 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); { - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _x, 1, 1, 0, "", 2]; - } forEach GVAR(flightPath) + _x params ["_pos", "_vectorUp"]; + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _pos, 1, 1, 0, "", 2]; + drawLine3D [_pos, _pos vectorAdd _vectorUp, [1,0,1,1]]; + } forEach GVAR(flightPath); }]; #endif diff --git a/addons/advanced_throwing/config.cpp b/addons/advanced_throwing/config.cpp index 021a57bea6..10ca7f642c 100644 --- a/addons/advanced_throwing/config.cpp +++ b/addons/advanced_throwing/config.cpp @@ -15,5 +15,6 @@ class CfgPatches { }; #include "ACE_Settings.hpp" +#include "CfgAmmo.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" diff --git a/addons/advanced_throwing/functions/fnc_canPrepare.sqf b/addons/advanced_throwing/functions/fnc_canPrepare.sqf index 9256993788..3c3d3e47b7 100644 --- a/addons/advanced_throwing/functions/fnc_canPrepare.sqf +++ b/addons/advanced_throwing/functions/fnc_canPrepare.sqf @@ -32,5 +32,8 @@ GVAR(enabled) && #endif {!(call EFUNC(common,isFeatureCameraActive))} && -{[_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 +{[_unit, objNull, ["isNotInside", "isNotSwimming", "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 +{"" == currentWeapon _unit || {currentWeapon _unit != secondaryWeapon _unit}} && +{0 >= _unit getVariable [QEGVAR(common,effect_blockThrow), 0]} && +{isNull (ACE_controlledUAV select 0)} diff --git a/addons/advanced_throwing/functions/fnc_drawArc.sqf b/addons/advanced_throwing/functions/fnc_drawArc.sqf index 0935b75ab5..eef326750d 100644 --- a/addons/advanced_throwing/functions/fnc_drawArc.sqf +++ b/addons/advanced_throwing/functions/fnc_drawArc.sqf @@ -67,7 +67,7 @@ for "_i" from 0.05 to 1.45 step 0.1 do { private _col = [ [1, 1, 1, _alpha], [0, 1, 0, _alpha], [1, 0, 0, _alpha], [1, 1, 0, _alpha] ] select _cross; if (_cross != 2 && {lineIntersects [eyePos ACE_player, _newTrajASL]}) then { - _col set [3, 0.1] + _col set [3, 0.1]; }; _pathData pushBack [_col, ASLToAGL _newTrajASL, _iDim]; diff --git a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf index 4f7a27ec65..0e6a6dea99 100644 --- a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf +++ b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf @@ -128,6 +128,10 @@ _activeThrowable setDir (_unitDirVisual + 90); private _pitch = [-30, -90] select (_throwType == "high"); [_activeThrowable, _pitch, 0] call BIS_fnc_setPitchBank; +// Force drop mode if underwater +if (underwater player) then { + ACE_player setVariable [QGVAR(dropMode), true]; +}; if (ACE_player getVariable [QGVAR(dropMode), false]) then { _posFin = _posFin vectorAdd (AGLToASL (positionCameraToWorld [_leanCoef, 0, ACE_player getVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]])); diff --git a/addons/advanced_throwing/functions/fnc_moduleInit.sqf b/addons/advanced_throwing/functions/fnc_moduleInit.sqf index fe380d2bb5..2e7ae18e42 100644 --- a/addons/advanced_throwing/functions/fnc_moduleInit.sqf +++ b/addons/advanced_throwing/functions/fnc_moduleInit.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -if (!isServer) exitWith {}; - params ["_logic", "_units", "_activated"]; if (!_activated) exitWith {}; diff --git a/addons/advanced_throwing/functions/fnc_throw.sqf b/addons/advanced_throwing/functions/fnc_throw.sqf index a3273eb034..038390ee74 100644 --- a/addons/advanced_throwing/functions/fnc_throw.sqf +++ b/addons/advanced_throwing/functions/fnc_throw.sqf @@ -49,9 +49,26 @@ if (!(_unit getVariable [QGVAR(primed), false])) then { _newVelocity = _newVelocity vectorAdd (velocity (vehicle _unit)); }; + // Calculate torque of thrown grenade + private _config = configFile >> "CfgAmmo" >> typeOf _activeThrowable; + private _torqueDir = getArray (_config >> QGVAR(torqueDirection)); + _torqueDir = if (_torqueDir isEqualTypeArray [0,0,0]) then { vectorNormalized _torqueDir } else { [0,0,0] }; + private _torqueMag = getNumber (_config >> QGVAR(torqueMagnitude)); + + if (_dropMode) then { + _torqueMag = _torqueMag * THROWSTYLE_DROP_TORQUE_COEF; + } else { + if (_throwType == "high") then { + _torqueMag = _torqueMag * THROWSTYLE_HIGH_TORQUE_COEF; + }; + }; + + private _torque = _torqueDir vectorMultiply _torqueMag; + // Drop if unit dies during throw process if (alive _unit) then { _activeThrowable setVelocity _newVelocity; + _activeThrowable addTorque (_unit vectorModelToWorld _torque); }; // Invoke listenable event @@ -67,12 +84,12 @@ if (!(_unit getVariable [QGVAR(primed), false])) then { #ifdef DRAW_THROW_PATH -GVAR(predictedPath) = call FUNC(drawArc); // save the current throw arc +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; +GVAR(flightRotation) = []; +(_unit getVariable QGVAR(activeThrowable)) spawn { + while {!isNull _this && {(getPosATL _this) select 2 > 0.05}} do { + GVAR(flightPath) pushBack [ASLtoAGL (getPosASL _this), vectorUp _this]; sleep 0.05; }; }; diff --git a/addons/advanced_throwing/script_component.hpp b/addons/advanced_throwing/script_component.hpp index 4beb0ee342..c6ce7dcb84 100644 --- a/addons/advanced_throwing/script_component.hpp +++ b/addons/advanced_throwing/script_component.hpp @@ -23,6 +23,8 @@ #define THROWSTYLE_HIGH_DIR [0, 200, 500] #define THROWSTYLE_HIGH_VEL_COEF 2 #define THROWSTYLE_DROP_VEL 2 +#define THROWSTYLE_HIGH_TORQUE_COEF .6 +#define THROWSTYLE_DROP_TORQUE_COEF .2 #define THROW_TYPE_DEFAULT "normal" #define THROW_SPEED_DEFAULT 18 diff --git a/addons/advanced_throwing/stringtable.xml b/addons/advanced_throwing/stringtable.xml index 66dbd8e500..3157e767e5 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -22,13 +22,13 @@ 고급 투척 행위를 허가합니다 Permet de changer la configuration du lancé amélioré. Permette il cambiamento della modalità di tiro. - 允許使用更多不同的投擲方式. - 允许使用更多不同的投掷方式. + 允許使用更多不同的投擲方式 + 允许使用更多不同的投掷方式 Enable Advanced Throwing Включить улучшенный бросок - アドバンスド投てきを有効化 + アドバンスド投てき Aktywuj zaawansowane rzucanie Aktiviere erweitertes Wurfsystem 고급 투척 활성화 @@ -46,8 +46,8 @@ 고급 투척을 활성화 합니다 Active le système de lancé amélioré. Abilita il sistema di lancio avanzato. - 啟用進階投擲系統. - 启用进阶投掷系统. + 啟用進階投擲系統 + 启用进阶投掷系统 Show Throw Arc @@ -70,8 +70,8 @@ 투척 궤도를 시각화 합니다(투척물이 어디로 갈지) Active la visualisation de l'arc de lancé (où l'objet lancé va atterrir). Abilita la visualizzazione dell'arco del tiro (dove l'oggetto lanciabile volerà). - 顯示投擲軌道幫助投擲. - 显示投掷轨道帮助投掷. + 顯示投擲軌道幫助投擲 + 显示投掷轨道帮助投掷 Show Throwing Mouse Controls @@ -94,13 +94,13 @@ 투척물을 준비시 마우스 조작을 시각화해서 보여줍니다 Active les aides visuels pour les controles à la souris lorsqu'un lancé est préparé. Abilita la visualizzazione dei controlli del mouse quando l'oggetto lanciabile è pronto. - 開啟後會在準備投擲時, 顯示滑鼠相關操作. - 开启后会在准备投掷时, 显示滑鼠相关操作. + 開啟後會在準備投擲時, 顯示滑鼠相關操作 + 开启后会在准备投掷时, 显示滑鼠相关操作 Enable Throwables Pick Up Включить подбор гранат - 投てき物の拾い上げを有効化 + 投てき物の拾い上げ Zezwól na podnoszenie obiektów miotanych Aktiviere Aufheben von Wurfobjekten 투척물 줍기 활성화 @@ -118,13 +118,13 @@ 땅에 떨어진 투척물을 주울 수 있게 해줍니다. Active la capacité de récupérer les objets lancés sur le sol. Abilita la possibilità di raccogliere un oggetto lanciabile da terra. - 啟用後, 可撿取地面上的投擲物. - 启用后, 可捡取地面上的投掷物. + 啟用後, 可撿取地面上的投擲物 + 启用后, 可捡取地面上的投掷物 Enable Attached Throwables Pick Up Включить подбор прикрепленных гранат - 拾い上げた投てき物の取り付けを有効化 + 拾った投てき物の取り付け Zezwól na podnoszenie przyczepionych obiektów miotanych Aktiviere erneute Aufnahme befestigter Wurfobjekte 부착 투척물 줍기 활성화 @@ -142,13 +142,13 @@ 부착된 투척물을 주울 수 있게 해줍니다. Active la capacité à ramasser les objets lançables attaché à d'autres objets. Abilita la possibilità di raccogliere gli oggetti lanciabili dagli altri oggetti. - 啟用後, 可撿取附著在物件上的投擲物. - 启用后, 可捡取附着在物件上的投掷物. + 啟用後, 可撿取附著在物件上的投擲物 + 启用后, 可捡取附着在物件上的投掷物 Prepare/Change Throwable Подготовить/заменить гранату - 機能の起動/変更 + 投てき物の準備/変更 Przygotuj/zmień ob. miotany Wurfobjekt vorbereiten/wechseln 투척물 준비/변경 @@ -172,7 +172,7 @@ Throwable Drop Mode (Toggle) Режим броска гранаты (переключить) - 投てきモード (トグル) + 投てきモード (切替) Tryb upuszczania ob. miotanego (przełącz) Wurfobjekt Fallmodus (umschalten) 투척물 떨어뜨리기 모드(토글) @@ -184,7 +184,7 @@ Primed Подготовлена - 起動した + 作動させた Odbezpieczony Scharf gemacht 뇌관 작동 diff --git a/addons/ai/CfgEventHandlers.hpp b/addons/ai/CfgEventHandlers.hpp new file mode 100644 index 0000000000..becf395052 --- /dev/null +++ b/addons/ai/CfgEventHandlers.hpp @@ -0,0 +1,18 @@ + +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)); + }; +}; diff --git a/addons/ai/XEH_PREP.hpp b/addons/ai/XEH_PREP.hpp new file mode 100644 index 0000000000..d3a61e3012 --- /dev/null +++ b/addons/ai/XEH_PREP.hpp @@ -0,0 +1,3 @@ +PREP(garrison); +PREP(unGarrison); +PREP(garrisonMove); diff --git a/addons/ai/XEH_postInit.sqf b/addons/ai/XEH_postInit.sqf new file mode 100644 index 0000000000..cf0ab8e49d --- /dev/null +++ b/addons/ai/XEH_postInit.sqf @@ -0,0 +1,84 @@ +#include "script_component.hpp" + +[QGVAR(AISection), { + params [["_units", [], [[]]], ["_sections", [], [[]]], ["_bool", true, [true]]]; + { + private _section = _x; + { + if (_bool) then { + _x enableAI _section; + } else { + _x disableAI _section; + }; + LOG(format [ARR_4("XEH_postInit: %1 disableAI %2 | ID %3", _x, _section, clientOwner)]); + } foreach (_units select {local _x}); + } foreach _sections +}] call CBA_fnc_addEventHandler; + +[QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler; +[QGVAR(doMove), { + params ["_unitsArray"]; + { + _x params ["_unit", "_pos"]; + //_unit doFollow leader _unit; + _unit setDestination [_pos, "LEADER PLANNED", true]; + _unit doMove _pos; + LOG(format [ARR_4("XEH_postInit: %1 doMove %2 | ID %3", _unit, _pos, clientOwner)]); + } foreach _unitsArray +}] call CBA_fnc_addEventHandler; +[QGVAR(setBehaviour), { + params ["_groupsArray", "_behaviour"]; + { + _x params ["_group"]; + _group setBehaviour _behaviour; + LOG(format [ARR_4("XEH_postInit: %1 setBehaviour %2 | ID %3", _group, _behaviour, clientOwner)]); + } foreach _groupsArray +}] call CBA_fnc_addEventHandler; +[QGVAR(enableAttack), { + params ["_unitsArray", "_mode"]; + { + _x params ["_unit"]; + _unit enableAttack _mode; + LOG(format [ARR_4("XEH_postInit: %1 enableAttack %2 | ID %3", _unit, _mode, clientOwner)]); + } foreach _unitsArray +}] call CBA_fnc_addEventHandler; + +#ifdef DEBUG_MODE_FULL + addMissionEventHandler ["Draw3D", { + private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; + + { + _x params ["_unit", "_pos"]; + + switch true do { + case (surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisualWorld [0,0,1], (AGLtoASL _pos), [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; + }; + + case (!surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisual [0,0,1], _pos, [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; + }; + + case (!surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisual [0,0,1], (AGLToASL _pos), [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; + }; + + case (surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisualWorld [0,0,1], _pos, [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; + }; + }; + } foreach _unitMoveList; + }]; +#endif \ No newline at end of file diff --git a/addons/ai/XEH_preInit.sqf b/addons/ai/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/ai/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/ai/XEH_preStart.sqf b/addons/ai/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/ai/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/ai/config.cpp b/addons/ai/config.cpp index a269bdcdbc..bc3b2df4ac 100644 --- a/addons/ai/config.cpp +++ b/addons/ai/config.cpp @@ -15,3 +15,4 @@ class CfgPatches { }; #include "CfgWeapons.hpp" +#include "CfgEventHandlers.hpp" diff --git a/addons/ai/functions/fnc_garrison.sqf b/addons/ai/functions/fnc_garrison.sqf new file mode 100644 index 0000000000..c303d2b90c --- /dev/null +++ b/addons/ai/functions/fnc_garrison.sqf @@ -0,0 +1,278 @@ +/* + * Author: alganthe + * Garrison function used to garrison AI inside buildings. + * + * Arguments: + * 0: The building(s) nearest this position are used + * 1: Limit the building search to those type of building + * 2: Units that will be garrisoned + * 3: Radius to fill building(s) (default: 50) + * 4: 0: even filling, 1: building by building, 2: random filling (default: 0) + * 5: True to fill building(s) from top to bottom (default: false) (note: only works with filling mode 0 and 1) + * 6: Teleport units (default: false) + + * Return Value: + * Units not garrisoned + * + * Example: + * [position, nil, [unit1, unit2, unit3, unitN], 200, 1, false, false] call ace_ai_fnc_garrison + * + * Public: Yes +*/ +#include "script_component.hpp" + +params [["_startingPos",[0,0,0], [[]], 3], ["_buildingTypes", ["Building"], [[]]], ["_unitsArray", [], [[]]], ["_fillingRadius", 50, [0]], ["_fillingType", 0, [0]], ["_topDownFilling", false, [true]], ["_teleport", false, [true]]]; + +TRACE_6("fnc_garrison: Start",_startingPos,_buldingTypes,count _unitsArray,_fillingRadius,_fillingTYpe,_topDownFilling); + +_unitsArray = _unitsArray select {alive _x && {!isPlayer _x}}; + +if (_startingPos isEqualTo [0,0,0]) exitWith { + TRACE_1("fnc_garrison: StartingPos error",_startingPos); + [LSTRING(GarrisonInvalidPosition)] call EFUNC(common,displayTextStructured); +}; + +if (count _unitsArray == 0 || {isNull (_unitsArray select 0)}) exitWith { + TRACE_1("fnc_garrison: Units error",_unitsArray); + [LSTRING(GarrisonNoUnits)] call EFUNC(common,displayTextStructured); +}; + +private _buildings = nearestObjects [_startingPos, _buildingTypes, ([_fillingRadius, 50] select (_fillingRadius < 50))]; +if (_fillingRadius >= 50) then { + _buildings = [_buildings] call CBA_fnc_shuffle; +}; + +if (count _buildings == 0) exitWith { + TRACE_1("fnc_garrison: Building error",_buildings); + [LSTRING(GarrisonNoBuilding)] call EFUNC(common,displayTextStructured); +}; + +private _buildingsIndex = []; + +if (_topDownFilling) then { + { + private _buildingPos = _x buildingPos -1; + + // Those reverse are necessary, as dumb as it is there's no better way to sort those subarrays in sqf + { + reverse _x; + } foreach _buildingPos; + + _buildingPos sort false; + + { + reverse _x; + } foreach _buildingPos; + + _buildingsIndex pushBack _buildingPos; + } foreach _buildings; +} else { + { + _buildingsIndex pushBack (_x buildingPos -1); + } foreach _buildings; +}; + +// Remove buildings without positions +{ + _buildingsIndex deleteAt (_buildingsIndex find _x); +} foreach (_buildingsIndex select {count _x == 0}); + +//Remove positions units are already pathing to +_buildingsIndex = _buildingsIndex apply { + private _testedBuilding = _x; + + _testedBuilding select { + private _testedPos = _x; + (({(_x select 1) isEqualTo _testedPos} count (missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []])) == 0) + } +}; + +// Warn the user that there's not enough positions to place all units +private _count = 0; +{_count = _count + count _x} foreach _buildingsIndex; +if ( (count _unitsArray) - _count > 0) then { + TRACE_4("fnc_garrison: Not enough spots to place all units",_unitsArray,count _unitsArray,_count,((count _unitsArray) - _count > 0)); + [LSTRING(GarrisonNotEnoughPos)] call EFUNC(common,displayTextStructured); +}; + +private _placedUnits = []; +private _unitMoveList = []; + +// Force all units to un-garrison +[QGVAR(unGarrison), [_unitsArray], _unitsArray] call CBA_fnc_targetEvent; + +private _fnc_comparePos = { + params ["_nearestUnits", "_pos"]; + ({ + if (surfaceIsWater getPos _x) then { + floor ((getPosASL _x) select 2) == floor ((AGLtoASL _pos) select 2) + } else { + floor ((getPosATL _x) select 2) == floor (_pos select 2) + }; + } count _nearestUnits) > 0 +}; + +// Do the placement +switch (_fillingType) do { + + // Even filling + case 0: { + + while {count _unitsArray > 0} do { + if (count _buildingsIndex == 0) exitWith {}; + private _building = _buildingsIndex select 0; + + if (_building isEqualTo []) then { + LOG(format [ARR_2("fnc_garrison: Empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]); + _buildingsIndex deleteAt 0; + + } else { + private _pos = _building select 0; + private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + + if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { + LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); + _buildingsIndex set [0, _building - [_pos]]; + + } else { + private _unit = _unitsArray select 0; + private _posSurface = surfaceIsWater _pos; + + if (_teleport) then { + doStop _unit; + if (_posSurface) then { + _unit setPosASL (AGLtoASL _pos); + } else { + _unit setPosATL _pos; + }; + + } else { + _unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)]; + }; + + _placedUnits pushBack _unit; + _unitsArray deleteAt (_unitsArray find _unit); + _building deleteAt 0; + _buildingsIndex deleteAt 0; + _buildingsIndex pushBackUnique _building; + _unit setVariable [QGVAR(garrisonned), true, true]; + }; + }; + }; + }; + + // Building by building + case 1: { + + while {count _unitsArray > 0} do { + if (count _buildingsIndex == 0) exitWith {}; + private _building = _buildingsIndex select 0; + + if (_building isEqualTo []) then { + LOG(format [ARR_2("fnc_garrison: empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]); + _buildingsIndex deleteAt 0; + + } else { + private _pos = _building select 0; + private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + + if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { + LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); + _buildingsIndex set [0, _building - [_pos]]; + + } else { + private _unit = _unitsArray select 0; + private _posSurface = surfaceIsWater _pos; + + if (_teleport) then { + doStop _unit; + if (_posSurface) then { + _unit setPosASL (AGLtoASL _pos); + } else { + _unit setPosATL _pos; + }; + + } else { + _unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)]; + }; + + _placedUnits pushBack _unit; + _unitsArray deleteAt (_unitsArray find _unit); + _buildingsIndex set [0, _building - [_pos]]; + _unit setVariable [QGVAR(garrisonned), true, true]; + }; + }; + }; + }; + + // Random + case 2: { + + while {count _unitsArray > 0} do { + if (count _buildingsIndex == 0) exitWith {}; + private _building = selectRandom _buildingsIndex; + + if (_building isEqualTo []) then { + LOG(format [ARR_2("fnc_garrison: empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]); + _buildingsIndex deleteAt (_buildingsIndex find _building); + + } else { + private _pos = selectRandom _building; + private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + + if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { + LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); + _buildingsIndex set [(_buildingsIndex find _building), _building - [_pos]]; + + } else { + private _unit = _unitsArray select 0; + private _posSurface = surfaceIsWater _pos; + + if (_teleport) then { + doStop _unit; + if (_posSurface) then { + _unit setPosASL (AGLtoASL _pos); + } else { + _unit setPosATL _pos; + }; + + } else { + _unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)]; + }; + + _placedUnits pushBack _unit; + _unitsArray deleteAt (_unitsArray find _unit); + _buildingsIndex set [(_buildingsIndex find _building), _building - [_pos]]; + _unit setVariable [QGVAR(garrisonned), true, true]; + }; + }; + }; + }; +}; + +TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)], _teleport); + +// Update the unit list and remove duplicate positions and units +private _garrison_unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; + +_garrison_unitMoveList = _garrison_unitMoveList select { + _x params ["_testedUnit", "_testedPos"]; + ({(_x select 0) isEqualTo _testedUnit} count _unitMoveList == 0) +}; + +_garrison_unitMoveList append _unitMoveList; + +missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _garrison_unitMoveList, true]; + +if (_teleport) then { + [QGVAR(AISection), [_placedUnits, ["PATH"], false], _placedUnits] call CBA_fnc_targetEvent; + +} else { + [_unitMoveList] call FUNC(garrisonMove); +}; + +TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left", count _unitsArray, count _buildingsIndex)], _unitsArray); +_unitsArray diff --git a/addons/ai/functions/fnc_garrisonMove.sqf b/addons/ai/functions/fnc_garrisonMove.sqf new file mode 100644 index 0000000000..fc9f09b6ce --- /dev/null +++ b/addons/ai/functions/fnc_garrisonMove.sqf @@ -0,0 +1,149 @@ +/* + * Author: alganthe + * Internal function used by ace_ai_fnc_garrison to make the units move to the positions it picked. + * + * Arguments: + * 0: Array of arrays + * 0: Unit needing to be placed + * 1: Position the unit need to be placed at + * + * Return Value: + * Nothing + * + * Example: + * [ [unit1, [10, 10, 10]], [unit2, [30, 30, 30]], [unitN, getPos player] ] call ace_ai_fnc_garrisonMove + * + * Public: No +*/ +#include "script_component.hpp" + +params [ ["_unitMoveList", nil, [[]]] ]; + +if (isNil "_unitMoveList") exitWith {}; + +// Start initial movement +private _unitMoveListUnits = (_unitMoveList apply {_x select 0}); +[QGVAR(setBehaviour), [(_unitMoveListUnits select {leader _x == _x}), "AWARE"], _unitMoveListUnits] call CBA_fnc_targetEvent; +[QGVAR(AISection), [_unitMoveListUnits, ["FSM"], false], _unitMoveListUnits] call CBA_fnc_targetEvent; +[QGVAR(doMove), [_unitMoveList], _unitMoveListUnits] call CBA_fnc_targetEvent; +[QGVAR(enableAttack), [_unitMoveListUnits select {leader _x == _x}, false], _unitMoveListUnits] call CBA_fnc_targetEvent; + +{ + _x setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _x setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; +} foreach _unitMoveListUnits; + +// Avoid duplicate PFHs +if (isNil QGVAR(garrison_moveUnitPFH)) then { + missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), true, true]; + + // PFH checking if the units have reached their destination + [{ + params ["_args", "_pfhID"]; + + private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; + + // End PFH if all units are placed / unable to reach position + if (_unitMoveList isEqualTo []) then { + missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), nil, true]; + LOG("garrisonMove PFH: PFH finished it's job | deleting PFH"); + _pfhID call CBA_fnc_removePerFrameHandler; + + } else { + { + _x params ["_unit", "_pos"]; + + // Check if unit is alive or even existing + if (!alive _unit) then { + _unitMoveList deleteAt (_unitMoveList find _x); + LOG(format [ARR_2("garrisonMove PFH: unit dead or deleted | %1 units left", count _unitMoveList)]); + + } else { + private _unitPos = getPos _unit; + if (surfaceisWater _unitPos) then { + _unitPos = getPosASL _unit; + } else { + _unitPos = getPosATL _unit; + }; + + if (unitReady _unit) then { + // Check for distance, doMove and AI are moody and may stop for no reason, within 6 meters and ready should be fine + if (_unitPos distance _pos < 3) then { + _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; + _unit setVariable [QGVAR(garrisonned), true, true]; + _unitMoveList deleteAt (_unitMoveList find _x); + + [QGVAR(AISection), [[_unit], ["PATH"], false], _unit] call CBA_fnc_targetEvent; + [QGVAR(AISection), [[_unit], ["FSM"], true], _unit] call CBA_fnc_targetEvent; + + if ({(_x select 0) in units _unit && {!isPlayer (_x select 0)}} count _unitMoveList == 0) then { + [QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent; + }; + + LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left", count _unitMoveList)]); + + } else { + // Tell the unit to move if an order wasn't given within 30s, avoid doMove spam + (_unit getVariable [QGVAR(garrisonMove_failSafe), [CBA_missionTime, 5]]) params ["_failSafeTimer", "_failSafeRemainingAttemps"]; + + if (_failSafeTimer <= CBA_missionTime) then { + if (_failSafeRemainingAttemps == 0 ) then { + _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; + [QGVAR(unGarrison), [[_unit]], _unit] call CBA_fnc_targetEvent; + _unitMoveList deleteAt (_unitMoveList find _x); + LOG("garrisonMove PFH unitReady: all moving commands failed | restoring AI capabilities"); + + } else { + _unit setVariable [QGVAR(garrisonMove_failSafe), [_failSafeTimer + 15, _failSafeRemainingAttemps - 1]]; + [QGVAR(doMove), [[[_unit, _pos]]], _unit] call CBA_fnc_targetEvent; + LOG("garrisonMove PFH unitReady: unit not close enough | Sending another doMove command"); + }; + }; + }; + } else { + (_unit getVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, [0,0,0]]]) params ["_unitPosTimer", "_unitOldPos"]; + + // AI may sometimes not be able to report unitReady, this is to avoid the PFH running forever + switch true do { + case ((_unitPosTimer + 15) < CBA_missionTime && {(_unitPos distance _pos) < 3}) : { + TRACE_1("case 1",_unit); + _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; + _unit setVariable [QGVAR(garrisonned), true, true]; + _unitMoveList deleteAt (_unitMoveList find _x); + + [QGVAR(AISection), [[_unit], ["PATH"], false], _unit] call CBA_fnc_targetEvent; + [QGVAR(AISection), [[_unit], ["FSM"], true], _unit] call CBA_fnc_targetEvent; + + if ({(_x select 0) in units _unit && {!isPlayer (_x select 0)}} count _unitMoveList == 0) then { + [QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent; + }; + + LOG(format [ARR_2("garrisonMove PFH unitNotReady: unit in position | %1 units left", count _unitMoveList)]); + }; + + case ((_unitPosTimer + 15) < CBA_missionTime && {_unitOldPos distance _unitPos < 0.5}) : { + TRACE_3("case 2",_unit, ((_unitPosTimer + 15) < CBA_missionTime), (_unitOldPos distance _unitPos < 0.5)); + _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; + [QGVAR(unGarrison), [[_unit]], _unit] call CBA_fnc_targetEvent; + _unitMoveList deleteAt (_unitMoveList find _x); + LOG("garrisonMove PFH unitNotReady: all moving commands failed | restoring AI capabilities"); + }; + + case (_unitOldPos distance _unitPos < 0.5) : {}; + + default { + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, _unitPos]]; + }; + }; + }; + }; + } foreach _unitMoveList; + + missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _unitMoveList, true]; + }; + }, 0.5, []] call CBA_fnc_addPerFrameHandler; +}; diff --git a/addons/ai/functions/fnc_unGarrison.sqf b/addons/ai/functions/fnc_unGarrison.sqf new file mode 100644 index 0000000000..6174a840bd --- /dev/null +++ b/addons/ai/functions/fnc_unGarrison.sqf @@ -0,0 +1,57 @@ +/* + * Author: alganthe + * Used to un-garrison units. + * + * Arguments: + * 0: Units to un-garrison + * + * Return Value: + * None + * + * Example: + * [unit1, unit2, unit3] call ace_ai_fnc_unGarrison + * + * Public: Yes + * +*/ +#include "script_component.hpp" + +params [["_units", [], [[]]]]; + +_units = _units select {local _x}; + +{ + if (!isPlayer _x && {local _x}) then { + _x enableAI "PATH"; + _x enableAI "FSM"; + + private _leader = leader _x; + + TRACE_3("fnc_ungarrison: unit and leader",_x , _leader, (_leader == _x)); + + _x setVariable [QGVAR(garrisonned), false, true]; + + if (_leader != _x) then { + doStop _x; + _x doFollow _leader; + + } else { + _x doMove ((nearestBuilding (getPos _x)) buildingExit 0); + }; + + private _fnc_countGarrisonnedUnits = { + params ["_unit", "_bool"]; + if (_bool) then { + ({(_x getVariable [QGVAR(garrisonned), false]) && {!isPlayer _x}} count units _unit) + } else { + ({!(_x getVariable [QGVAR(garrisonned), false]) && {!isPlayer _x}} count units _unit) + }; + + }; + + if ([_x, true] call _fnc_countGarrisonnedUnits == ({!isPlayer _x} count (units _x)) - 1 || {[_x, false] call _fnc_countGarrisonnedUnits == {!isPlayer _x} count (units _x)}) then { + LOG("fnc_ungarrison: enableAttack true"); + (group _x) enableAttack true; + }; + }; +} foreach _units; diff --git a/addons/ai/functions/script_component.hpp b/addons/ai/functions/script_component.hpp new file mode 100644 index 0000000000..91e8ec0809 --- /dev/null +++ b/addons/ai/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\ai\script_component.hpp" diff --git a/addons/ai/script_component.hpp b/addons/ai/script_component.hpp index 9a0afcf434..3a05db6896 100644 --- a/addons/ai/script_component.hpp +++ b/addons/ai/script_component.hpp @@ -2,8 +2,8 @@ #define COMPONENT_BEAUTIFIED AI #include "\z\ace\addons\main\script_mod.hpp" -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE +//#define DEBUG_MODE_FULL +//#define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_AI diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml new file mode 100644 index 0000000000..f4d2a816b2 --- /dev/null +++ b/addons/ai/stringtable.xml @@ -0,0 +1,41 @@ + + + + + Invalid position provided. + Position invalide fourni + 位置が無効です。 + Posizione invalida fornita. + 提供的位置無效。 + 提供的位置无效。 + 위치가 잘못되었습니다. + + + No units provided. + Aucune unité fourni + ユニットがありません。 + Nessuna unità fornita. + 找不到可用的單位。 + 找不到可用的单位。 + 병력이 없습니다. + + + There aren't enough positions to place all units. + Il n'y a pas assez de positions pour placer toutes les unités + 全ユニットを置くために十分な位置がありません。 + Non ci sono abbastanza posizioni per piazzare tutte le unità. + 沒有足夠的位置能擺放所有單位。 + 没有足够的位置能摆放所有单位。 + 모든 병력을 배치 할 공간이 없습니다. + + + No building found. + Aucun bâtiment trouvé + 建物がありません。 + Nessun edificio trovato. + 沒找到建築物。 + 没找到建筑物。 + 건물이 없습니다. + + + diff --git a/addons/aircraft/CfgEventHandlers.hpp b/addons/aircraft/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9426fa861e --- /dev/null +++ b/addons/aircraft/CfgEventHandlers.hpp @@ -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)); + }; +}; diff --git a/addons/aircraft/CfgVehicles.hpp b/addons/aircraft/CfgVehicles.hpp index 3279d35f71..5d3d705db6 100644 --- a/addons/aircraft/CfgVehicles.hpp +++ b/addons/aircraft/CfgVehicles.hpp @@ -37,11 +37,9 @@ class CfgVehicles { class Heli_Light_01_base_F: Helicopter_Base_H { incomingMissileDetectionSystem = 16; // Vanilla: 0 - driverCanEject = 1; class Turrets: Turrets { class CopilotTurret: CopilotTurret { - canEject = 1; showHMD = 1; }; }; @@ -49,22 +47,13 @@ class CfgVehicles { class Heli_Light_01_armed_base_F: Heli_Light_01_base_F { incomingMissileDetectionSystem = 16; // Vanilla: 0 - driverCanEject = 1; - - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - }; }; class Heli_Light_02_base_F: Helicopter_Base_H { - driverCanEject = 1; incomingMissileDetectionSystem = 16; // Vanilla: 24 magazines[] = {"2000Rnd_762x51_Belt_T_Green", "12Rnd_PG_missiles", "168Rnd_CMFlare_Chaff_Magazine"}; // Switch gun magazine to 7.62mm from 6.5mm class Turrets: Turrets { class CopilotTurret: CopilotTurret { - canEject = 1; showHMD = 1; }; }; @@ -80,44 +69,31 @@ class CfgVehicles { class Heli_Attack_02_base_F: Helicopter_Base_F { incomingMissileDetectionSystem = 16; // Vanilla: 24 - driverCanEject = 1; - - class Turrets: Turrets { - class MainTurret: MainTurret { - canEject = 1; - }; - }; }; class Heli_Transport_01_base_F: Helicopter_Base_H { incomingMissileDetectionSystem = 16; // Vanilla: 24 - driverCanEject = 1; class Turrets: Turrets { class CopilotTurret: CopilotTurret { - canEject = 1; showHMD = 1; }; class MainTurret: MainTurret { magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; // Switch gun magazine to 7.62mm from 6.5mm - canEject = 1; }; class RightDoorGun: MainTurret { magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; // Switch gun magazine to 7.62mm from 6.5mm - canEject = 1; }; }; }; class Heli_Transport_02_base_F: Helicopter_Base_H { incomingMissileDetectionSystem = 16; // Vanilla: 24 - driverCanEject = 1; class Turrets: Turrets { class CopilotTurret: CopilotTurret { - canEject = 1; showHMD = 1; }; }; @@ -126,11 +102,9 @@ class CfgVehicles { class Heli_light_03_base_F: Helicopter_Base_F { lockDetectionSystem = 0; // Vanilla: 12 incomingMissileDetectionSystem = 16; // Vanilla: 24 - driverCanEject = 1; class Turrets: Turrets { class MainTurret: MainTurret { - canEject = 1; showHMD = 1; weapons[] = {"Laserdesignator_mounted"}; // Add Laser Designator magazines[] = {"Laserbatteries"}; @@ -166,26 +140,8 @@ class CfgVehicles { class Heli_Transport_03_base_F: Helicopter_Base_H { incomingMissileDetectionSystem = 16; // Vanilla: 24 - driverCanEject = 1; - - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - }; }; class Heli_Transport_04_base_F: Helicopter_Base_H { incomingMissileDetectionSystem = 16; // Vanilla: 24 - driverCanEject = 1; - - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - - class LoadmasterTurret: MainTurret { - canEject = 1; - }; - }; }; }; diff --git a/addons/aircraft/CfgWeapons.hpp b/addons/aircraft/CfgWeapons.hpp index 2d16223e1d..5543925b5b 100644 --- a/addons/aircraft/CfgWeapons.hpp +++ b/addons/aircraft/CfgWeapons.hpp @@ -105,10 +105,5 @@ class CfgWeapons { dispersion = 0.0064; //0.0023; multiplier = 1; }; - - class close: HighROF {}; - class short: close {}; - class medium: LowROF {}; - class far: medium {}; }; }; diff --git a/addons/aircraft/Heli_Attack_01_base_F.hpp b/addons/aircraft/Heli_Attack_01_base_F.hpp index 90a417000a..7e59abad48 100644 --- a/addons/aircraft/Heli_Attack_01_base_F.hpp +++ b/addons/aircraft/Heli_Attack_01_base_F.hpp @@ -1,6 +1,5 @@ class Heli_Attack_01_base_F: Helicopter_Base_F { incomingMissileDetectionSystem = 16; // Vanilla: 24 - driverCanEject = 1; class Turrets: Turrets { class MainTurret: MainTurret { diff --git a/addons/aircraft/XEH_PREP.hpp b/addons/aircraft/XEH_PREP.hpp new file mode 100644 index 0000000000..65407a32f0 --- /dev/null +++ b/addons/aircraft/XEH_PREP.hpp @@ -0,0 +1,2 @@ +PREP(initEjectAction); +PREP(canShowEject); diff --git a/addons/aircraft/XEH_postInitClient.sqf b/addons/aircraft/XEH_postInitClient.sqf new file mode 100644 index 0000000000..e468602dbc --- /dev/null +++ b/addons/aircraft/XEH_postInitClient.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +private _cfgAction = configFile >> "CfgActions" >> "Eject"; +GVAR(ejectActionParams) = [ + [ + "", // will be set with setUserActionText + { + params ["_vehicle", "_unit"]; + private _preserveEngineOn = (_unit == driver _vehicle) && {isEngineOn _vehicle}; + moveOut _unit; + if (_preserveEngineOn) then { + // vehicle is local to last driver, no need to care + _vehicle engineOn true; + }; + }, + nil, + getNumber (_cfgAction >> "priority"), + false, + true, + getText (_cfgAction >> "shortcut"), + '[_this, _target] call DFUNC(canShowEject)' + ], + getText (_cfgAction >> "text"), + getText (_cfgAction >> "textDefault") +]; + +["Helicopter", "initPost", LINKFUNC(initEjectAction)] call CBA_fnc_addClassEventHandler; diff --git a/addons/aircraft/XEH_preInit.sqf b/addons/aircraft/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/aircraft/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/aircraft/XEH_preStart.sqf b/addons/aircraft/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/aircraft/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/aircraft/config.cpp b/addons/aircraft/config.cpp index 48bf2c054e..21b8d9b3c9 100644 --- a/addons/aircraft/config.cpp +++ b/addons/aircraft/config.cpp @@ -18,6 +18,7 @@ class CfgPatches { }; #include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" #include "CfgMagazines.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/aircraft/functions/fnc_canShowEject.sqf b/addons/aircraft/functions/fnc_canShowEject.sqf new file mode 100644 index 0000000000..b0803a49df --- /dev/null +++ b/addons/aircraft/functions/fnc_canShowEject.sqf @@ -0,0 +1,35 @@ +/* + * Author: Dystopian + * Check if Eject action can be shown. + * + * Arguments: + * 0: Unit who calls action + * 1: Vehicle which action is attached to + * + * Return Value: + * Can show + * + * Example: + * [player, vehicle player] call ace_aircraft_fnc_canShowEject + * + * Public: No + */ +#include "script_component.hpp" + +#define FULLCREW_UNIT 0 +#define FULLCREW_ROLE 1 +#define FULLCREW_TURRETPATH 3 + +params ["_unit", "_vehicle"]; + +_vehicle == vehicle _unit +&& {2 > locked _vehicle} +&& { + private _ejectVarName = ""; + { + if (_unit == _x select FULLCREW_UNIT) exitWith { + _ejectVarName = format [QGVAR(ejectAction_%1_%2), _x select FULLCREW_ROLE, _x select FULLCREW_TURRETPATH]; + }; + } count fullCrew _vehicle; + _vehicle getVariable [_ejectVarName, false] +} diff --git a/addons/aircraft/functions/fnc_initEjectAction.sqf b/addons/aircraft/functions/fnc_initEjectAction.sqf new file mode 100644 index 0000000000..94b72099ee --- /dev/null +++ b/addons/aircraft/functions/fnc_initEjectAction.sqf @@ -0,0 +1,48 @@ +/* + * Author: Dystopian + * Add Eject action to vehicle if needed. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_aircraft_fnc_initEjectAction + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicle"]; + +if (unitIsUAV _vehicle) exitWith {}; + +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; + +private _addAction = false; + +if (0 == getNumber (_config >> "driverCanEject")) then { + TRACE_2("eject action",typeOf _vehicle,"driver"); + _vehicle setVariable [QGVAR(ejectAction_driver_[]), true]; + _addAction = true; +}; + +{ + { + _x params ["", "_role", "", "_turretPath"]; + if (0 == getNumber (([_config, _turretPath] call CBA_fnc_getTurret) >> "canEject")) then { + TRACE_2("eject action",typeOf _vehicle,_turretPath); + _vehicle setVariable [format [QGVAR(ejectAction_%1_%2), _role, _turretPath], true]; + _addAction = true; + }; + } forEach fullCrew [_vehicle, _x, true]; +} forEach ["gunner", "commander", "turret"]; + +if (!_addAction) exitWith {}; + +GVAR(ejectActionParams) params ["_params", "_text", "_picture"]; +private _actionID = _vehicle addAction _params; +_vehicle setUserActionText [_actionID, _text, "", _picture]; +_vehicle setVariable [QGVAR(ejectAction), _actionID]; diff --git a/addons/aircraft/functions/script_component.hpp b/addons/aircraft/functions/script_component.hpp new file mode 100644 index 0000000000..8614d199c3 --- /dev/null +++ b/addons/aircraft/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\aircraft\script_component.hpp" diff --git a/addons/apl/functions/script_component.hpp b/addons/apl/functions/script_component.hpp deleted file mode 100644 index a25cdfebcc..0000000000 --- a/addons/apl/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\apl\script_component.hpp" \ No newline at end of file diff --git a/addons/arsenal/$PBOPREFIX$ b/addons/arsenal/$PBOPREFIX$ new file mode 100644 index 0000000000..fea3434f4b --- /dev/null +++ b/addons/arsenal/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\arsenal \ No newline at end of file diff --git a/addons/arsenal/CfgEventHandlers.hpp b/addons/arsenal/CfgEventHandlers.hpp new file mode 100644 index 0000000000..becf395052 --- /dev/null +++ b/addons/arsenal/CfgEventHandlers.hpp @@ -0,0 +1,18 @@ + +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)); + }; +}; diff --git a/addons/arsenal/RscDisplayMain.hpp b/addons/arsenal/RscDisplayMain.hpp new file mode 100644 index 0000000000..b20b99e31e --- /dev/null +++ b/addons/arsenal/RscDisplayMain.hpp @@ -0,0 +1,36 @@ +class RscStandardDisplay; +class RscDisplayMain: RscStandardDisplay { + class controls { + class GroupSingleplayer: RscControlsGroupNoScrollbars { + class Controls; + }; + class GroupTutorials: GroupSingleplayer { + h = "(6 * 1.5) * (pixelH * pixelGrid * 2)"; + + class Controls: Controls { + class Bootcamp; + class VRTraining; + class Arsenal; + class GVAR(mission): Arsenal { + idc = -1; + text = CSTRING(Mission); + tooltip = CSTRING(Mission_tooltip); + y = "(3 * 1.5) * (pixelH * pixelGrid * 2) + (pixelH)"; + onbuttonclick = QUOTE(playMission [ARR_2('','PATHTOF(missions\Arsenal.VR)')]); + animTextureNormal = QPATHTOF(data\buttonMissionMainMenu_ca.paa); + animTextureDisabled = QPATHTOF(data\buttonMissionMainMenu_ca.paa); + animTextureOver = QPATHTOF(data\buttonMissionMainMenuHover_ca.paa); + animTextureFocused = QPATHTOF(data\buttonMissionMainMenuHover_ca.paa); + animTexturePressed = QPATHTOF(data\buttonMissionMainMenu_ca.paa); + animTextureDefault = QPATHTOF(data\buttonMissionMainMenu_ca.paa); + }; + class FieldManual: Bootcamp { + y = "(4 * 1.5) * (pixelH * pixelGrid * 2) + (pixelH)"; + }; + class CommunityGuides: Bootcamp { + y = "(5 * 1.5) * (pixelH * pixelGrid * 2) + (pixelH)"; + }; + }; + }; + }; +}; diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp new file mode 100644 index 0000000000..7596b769d8 --- /dev/null +++ b/addons/arsenal/XEH_PREP.hpp @@ -0,0 +1,47 @@ +PREP(addListBoxItem); +PREP(addVirtualItems); +PREP(buttonCargo); +PREP(buttonClearAll); +PREP(buttonExport); +PREP(buttonHide); +PREP(buttonImport); +PREP(buttonLoadoutsDelete); +PREP(buttonLoadoutsLoad); +PREP(buttonLoadoutsRename); +PREP(buttonLoadoutsSave); +PREP(buttonLoadoutsShare); +PREP(clearSearchbar); +PREP(fillLeftPanel); +PREP(fillLoadoutsList); +PREP(fillRightPanel); +PREP(handleLoadoutsSearchbar); +PREP(handleMouse); +PREP(handleScrollWheel); +PREP(handleSearchbar); +PREP(initBox); +PREP(itemInfo); +PREP(loadoutsChangeTab); +PREP(message); +PREP(onArsenalClose); +PREP(onArsenalOpen); +PREP(onKeyDown); +PREP(onLoadoutsClose); +PREP(onLoadoutsOpen); +PREP(onMouseButtonDown); +PREP(onMouseButtonUp); +PREP(onSelChangedLeft); +PREP(onSelChangedLoadouts); +PREP(onSelChangedRight); +PREP(onSelChangedRightListnBox); +PREP(open3DEN); +PREP(openBox); +PREP(portVALoadouts); +PREP(removeBox); +PREP(removeVirtualItems); +PREP(scanConfig); +PREP(showItem); +PREP(sortPanel); +PREP(updateCamPos); +PREP(updateRightPanel); +PREP(updateUniqueItemsList); +PREP(verifyLoadout); diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf new file mode 100644 index 0000000000..dcc5c7c7b5 --- /dev/null +++ b/addons/arsenal/XEH_postInit.sqf @@ -0,0 +1,83 @@ +#include "script_component.hpp" +#include "defines.hpp" + +GVAR(EH_ID) = 0; +GVAR(lastSearchTextLeft) = ""; +GVAR(lastSearchTextRight) = ""; +GVAR(lastSearchTextLoadouts) = ""; + +[QGVAR(initBox), {_this call FUNC(initBox)}] call CBA_fnc_addEventHandler; +[QGVAR(removeBox), {_this call FUNC(removeBox)}] call CBA_fnc_addEventHandler; + +[QGVAR(broadcastFace), { + params ["_unit", "_face"]; + + _unit setFace _face; +}] call CBA_fnc_addEventHandler; + +[QGVAR(broadcastVoice), { + params ["_unit", "_voice"]; + + _unit setSpeaker _voice; +}] call CBA_fnc_addEventHandler; + +[QGVAR(loadoutUnshared), { + params ["_contentPanelCtrl" , "_playerName", "_loadoutName"]; + + if (!(isNil QGVAR(currentLoadoutsTab)) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { + + private _dataToCheck = _playerName + _loadoutName; + + for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbData [_i, 1]) == _dataToCheck) exitwith {_contentPanelCtrl lnbDeleteRow _i}; + }; + } else { + + if ( + profileName == _playerName && + {!(isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts})} + ) then { + + for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbText [_i, 1]) == _loadoutName) exitwith { + _contentPanelCtrl lnbSetPicture [[_i, 0], QPATHTOF(data\iconPublicBlank.paa)]; + _contentPanelCtrl lnbSetValue [[_i, 0], 0]; + }; + }; + }; + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(loadoutShared), { + params ["_contentPanelCtrl" ,"_loadoutArgs"]; + _loadoutArgs params ["_playerName", "_loadoutName", "_loadoutData"]; + + if (!(isNil QGVAR(currentLoadoutsTab)) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { + + private _curSelData =_contentPanelCtrl lnbData [(lnbCurSelRow _contentPanelCtrl), 1]; + ([_loadoutData] call FUNC(verifyLoadout)) params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount"]; + + private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; + + ADD_LOADOUTS_LIST_PICTURES + + _contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName]; + + if (_nullItemsAmount > 0) then { + + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; + } else { + + if (_unavailableItemsAmount > 0) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + }; + }; + + _contentPanelCtrl lnbSort [1, false]; + + // Select previously selected loadout + for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbText [_i, 1]) == _curSelData) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + }; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf new file mode 100644 index 0000000000..537af9c11d --- /dev/null +++ b/addons/arsenal/XEH_preInit.sqf @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +// Arsenal +GVAR(modList) = ["","curator","kart","heli","mark","expansion","expansionpremium"]; + +[QGVAR(camInverted), "CHECKBOX", localize LSTRING(invertCameraSetting), localize LSTRING(settingCategory), false] call CBA_Settings_fnc_init; +[QGVAR(enableModIcons), "CHECKBOX", [LSTRING(modIconsSetting), LSTRING(modIconsTooltip)], localize LSTRING(settingCategory), true] call CBA_Settings_fnc_init; +[QGVAR(fontHeight), "SLIDER", [LSTRING(fontHeightSetting), LSTRING(fontHeightTooltip)], localize LSTRING(settingCategory), [1, 10, 4.5, 1]] call CBA_Settings_fnc_init; + +// Arsenal loadouts +[QGVAR(allowDefaultLoadouts), "CHECKBOX", [LSTRING(allowDefaultLoadoutsSetting), LSTRING(defaultLoadoutsTooltip)], localize LSTRING(settingCategory), true, true] call CBA_Settings_fnc_init; +[QGVAR(allowSharedLoadouts), "CHECKBOX", localize LSTRING(allowSharingSetting), localize LSTRING(settingCategory), true, true] call CBA_Settings_fnc_init; +[QGVAR(EnableRPTLog), "CHECKBOX", [LSTRING(printToRPTSetting), LSTRING(printToRPTTooltip)], localize LSTRING(settingCategory), false, false] call CBA_Settings_fnc_init; + +ADDON = true; diff --git a/addons/arsenal/XEH_preStart.sqf b/addons/arsenal/XEH_preStart.sqf new file mode 100644 index 0000000000..ed7f4f0345 --- /dev/null +++ b/addons/arsenal/XEH_preStart.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" + +call FUNC(scanConfig); diff --git a/addons/arsenal/config.cpp b/addons/arsenal/config.cpp new file mode 100644 index 0000000000..0c3000ab3c --- /dev/null +++ b/addons/arsenal/config.cpp @@ -0,0 +1,41 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"alganthe"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +class Cfg3DEN { + class Mission { + class GVAR(DummyCategory) { + displayName="Dummy attribute, should never show up"; + class AttributeCategories { + class ACE3_Arsenal { + class Attributes { + class GVAR(DefaultLoadoutsListAttribute) { + property = QGVAR(DefaultLoadoutsListAttribute); + value=0; + expression="if !(is3DEN) then {ace_arsenal_defaultLoadoutsList = _value};"; + defaultValue="[]"; + validate="none"; + wikiType="[[Array]]"; + }; + }; + }; + }; + }; + }; +}; + +#include "ui\RscAttributes.hpp" +#include "CfgEventHandlers.hpp" +#include "RscDisplayMain.hpp" diff --git a/addons/arsenal/data/buttonMissionMainMenuHover_ca.paa b/addons/arsenal/data/buttonMissionMainMenuHover_ca.paa new file mode 100644 index 0000000000..5592939ea8 Binary files /dev/null and b/addons/arsenal/data/buttonMissionMainMenuHover_ca.paa differ diff --git a/addons/arsenal/data/buttonMissionMainMenu_ca.paa b/addons/arsenal/data/buttonMissionMainMenu_ca.paa new file mode 100644 index 0000000000..9f84cefcdf Binary files /dev/null and b/addons/arsenal/data/buttonMissionMainMenu_ca.paa differ diff --git a/addons/arsenal/data/iconClearContainer.paa b/addons/arsenal/data/iconClearContainer.paa new file mode 100644 index 0000000000..cf3ad52815 Binary files /dev/null and b/addons/arsenal/data/iconClearContainer.paa differ diff --git a/addons/arsenal/data/iconPublic.paa b/addons/arsenal/data/iconPublic.paa new file mode 100644 index 0000000000..d92675e8e2 Binary files /dev/null and b/addons/arsenal/data/iconPublic.paa differ diff --git a/addons/arsenal/data/iconPublicBlank.paa b/addons/arsenal/data/iconPublicBlank.paa new file mode 100644 index 0000000000..cf37c88b02 Binary files /dev/null and b/addons/arsenal/data/iconPublicBlank.paa differ diff --git a/addons/arsenal/data/iconSecondaryMuzzle.paa b/addons/arsenal/data/iconSecondaryMuzzle.paa new file mode 100644 index 0000000000..5cc7f17daa Binary files /dev/null and b/addons/arsenal/data/iconSecondaryMuzzle.paa differ diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp new file mode 100644 index 0000000000..ca5e7ed6a2 --- /dev/null +++ b/addons/arsenal/defines.hpp @@ -0,0 +1,342 @@ +// Pixel grid +#define pixelScale 0.25 +#define GRID_W (pixelW * pixelGridNoUIScale * pixelScale) +#define GRID_H (pixelH * pixelGridNoUIScale * pixelScale) + +#define WIDTH_TOTAL (safezoneW - 2 * (93 * GRID_W)) +#define WIDTH_GAP (WIDTH_TOTAL / 100) +#define WIDTH_SINGLE ((WIDTH_TOTAL - 6 * WIDTH_GAP) / 5) + +// IDCs +#define IDD_ace_arsenal 1127001 +#define IDC_mouseArea 0 +#define IDC_arrowMinus 101 +#define IDC_arrowPlus 102 +#define IDC_blockLeftFrame 3 +#define IDC_blockLeftBackground 4 +#define IDC_blockRightFrame 5 +#define IDC_blockRighttBackground 6 +#define IDC_loadIndicator 7 +#define IDC_loadIndicatorBar 701 +#define IDC_totalWeight 8 +#define IDC_totalWeightText 801 +#define IDC_message 9 +#define IDC_menuBar 10 +#define IDC_menuBarClose 1001 +#define IDC_buttonHide 1002 +#define IDC_buttonLoadouts 1003 +#define IDC_buttonExport 1004 +#define IDC_buttonImport 1005 +#define IDC_infoBox 11 +#define IDC_infoBackground 1101 +#define IDC_infoName 1102 +#define IDC_infoAuthor 1103 +#define IDC_DLCBackground 1104 +#define IDC_DLCIcon 1105 +#define IDC_mouseBlock 12 +#define IDC_leftTabContent 13 +#define IDC_rightTabContent 14 +#define IDC_rightTabContentListnBox 15 +#define IDC_sortLeftTab 16 +#define IDC_sortRightTab 17 +#define IDC_leftSearchbar 18 +#define IDC_leftSearchbarButton 41 +#define IDC_rightSearchbar 19 +#define IDC_rightSearchbarButton 42 +#define IDC_tabLeft 20 +#define IDC_iconBackgroundPrimaryWeapon 2001 +#define IDC_buttonPrimaryWeapon 2002 +#define IDC_iconBackgroundHandgun 2003 +#define IDC_buttonHandgun 2004 +#define IDC_iconBackgroundSecondaryWeapon 2005 +#define IDC_buttonSecondaryWeapon 2006 +#define IDC_iconBackgroundHeadgear 2007 +#define IDC_buttonHeadgear 2008 +#define IDC_iconBackgroundUniform 2009 +#define IDC_buttonUniform 2010 +#define IDC_iconBackgroundVest 2011 +#define IDC_buttonVest 2012 +#define IDC_iconBackgroundBackpack 2013 +#define IDC_buttonBackpack 2014 +#define IDC_iconBackgroundGoggles 2015 +#define IDC_buttonGoggles 2016 +#define IDC_iconBackgroundNVG 2017 +#define IDC_buttonNVG 2018 +#define IDC_iconBackgroundBinoculars 2019 +#define IDC_buttonBinoculars 2020 +#define IDC_iconBackgroundMap 2021 +#define IDC_buttonMap 2022 +#define IDC_iconBackgroundGPS 2023 +#define IDC_buttonGPS 2024 +#define IDC_iconBackgroundRadio 2025 +#define IDC_buttonRadio 2026 +#define IDC_iconBackgroundCompass 2028 +#define IDC_buttonCompass 2029 +#define IDC_iconBackgroundWatch 2030 +#define IDC_buttonWatch 2031 +#define IDC_iconBackgroundFace 2032 +#define IDC_buttonFace 2033 +#define IDC_iconBackgroundVoice 2034 +#define IDC_buttonVoice 2035 +#define IDC_iconBackgroundInsigna 2036 +#define IDC_buttonInsigna 2037 +#define IDC_iconBackgroundOptic 21 +#define IDC_buttonOptic 22 +#define IDC_iconBackgroundItemAcc 23 +#define IDC_buttonItemAcc 24 +#define IDC_iconBackgroundMuzzle 25 +#define IDC_buttonMuzzle 26 +#define IDC_iconBackgroundBipod 27 +#define IDC_buttonBipod 28 +#define IDC_iconBackgroundCurrentMag 3001 +#define IDC_buttonCurrentMag 3002 +#define IDC_iconBackgroundCurrentMag2 3003 +#define IDC_buttonCurrentMag2 3004 +#define IDC_iconBackgroundMag 29 +#define IDC_buttonMag 30 +#define IDC_iconBackgroundMagALL 31 +#define IDC_buttonMagALL 32 +#define IDC_iconBackgroundThrow 33 +#define IDC_buttonThrow 34 +#define IDC_iconBackgroundPut 35 +#define IDC_buttonPut 36 +#define IDC_iconBackgroundMisc 37 +#define IDC_buttonMisc 38 +#define IDC_buttonRemoveAllSelected 39 +#define IDC_buttonRemoveAll 40 + +#define IDD_loadouts_display 1127002 +#define IDC_centerBox 3 +#define IDC_centerTitle 301 +#define IDC_contentPanel 302 +#define IDC_textEditBox 303 +#define IDC_buttonSave 304 +#define IDC_buttonLoad 305 +#define IDC_buttonShare 306 +#define IDC_buttonDelete 307 +#define IDC_buttonRename 308 +#define IDC_loadoutsSearchbar 309 +#define IDC_buttonMyLoadoutsBackground 401 +#define IDC_buttonMyLoadouts 402 +#define IDC_buttonDefaultLoadoutsBackground 403 +#define IDC_buttonDefaultLoadouts 404 +#define IDC_buttonSharedLoadoutsBackground 405 +#define IDC_buttonSharedLoadouts 406 + +#define FADE_DELAY 0.15 +#define CAM_DIS_MAX 5 + +#define RIGHT_PANEL_ACC_IDCS IDC_buttonOptic, IDC_buttonItemAcc, IDC_buttonMuzzle, IDC_buttonBipod +#define RIGHT_PANEL_ACC_BACKGROUND_IDCS IDC_iconBackgroundOptic, IDC_iconBackgroundItemAcc, IDC_iconBackgroundMuzzle, IDC_iconBackgroundBipod +#define RIGHT_PANEL_ITEMS_IDCS IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut, IDC_buttonMisc +#define RIGHT_PANEL_ITEMS_BACKGROUND_IDCS IDC_iconBackgroundMag, IDC_iconBackgroundMagALL, IDC_iconBackgroundThrow, IDC_iconBackgroundPut, IDC_iconBackgroundMisc +#define ARROWS_IDCS IDC_arrowMinus, IDC_arrowPlus + +#define GETDLC\ + {\ + private _dlc = "";\ + private _addons = configsourceaddonlist _this;\ + if (count _addons > 0) then {\ + private _mods = configsourcemodlist (configfile >> "CfgPatches" >> _addons select 0);\ + if (count _mods > 0) then {\ + _dlc = _mods select 0;\ + };\ + };\ + _dlc\ + } + +#define ADDMODICON\ + {\ + private _dlcName = _this call GETDLC;\ + if (_dlcName != "") then {\ + _ctrlPanel lbsetpictureright [_lbAdd,(modParams [_dlcName,["logo"]]) param [0,""]];\ + _modID = GVAR(modList) find _dlcName;\ + if (_modID < 0) then {_modID = GVAR(modList) pushback _dlcName;};\ + _ctrlPanel lbsetvalue [_lbAdd,_modID];\ + };\ + }; + +#define ADDBINOCULARSMAG\ + private _magazines = getarray (configfile >> "cfgweapons" >> _item >> "magazines");\ + if (count _magazines > 0) then {GVAR(center) addmagazine (_magazines select 0)}; + +#define TOGGLE_RIGHT_PANEL_WEAPON\ +{\ + _x = _display displayCtrl _x;\ + _x ctrlSetFade 0;\ + _x ctrlShow true;\ + _x ctrlEnable true;\ + _x ctrlCommit FADE_DELAY;\ +} foreach [\ + IDC_blockRightFrame,\ + IDC_blockRighttBackground,\ + IDC_rightTabContent,\ + IDC_sortRightTab,\ + RIGHT_PANEL_ACC_IDCS,\ + IDC_rightSearchbar,\ + IDC_rightSearchbarButton,\ + IDC_buttonCurrentMag\ +];\ +private _buttonCurrentMag2Ctrl = _display displayCtrl IDC_buttonCurrentMag2;\ +if (GVAR(currentLeftPanel) == IDC_buttonPrimaryWeapon) then {\ + _buttonCurrentMag2Ctrl ctrlSetFade 0;\ + _buttonCurrentMag2Ctrl ctrlShow true;\ + _buttonCurrentMag2Ctrl ctrlEnable true;\ +} else {\ + _buttonCurrentMag2Ctrl ctrlSetFade 1;\ + _buttonCurrentMag2Ctrl ctrlShow false;\ + _buttonCurrentMag2Ctrl ctrlEnable false;\ +};\ +_buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ +{\ + _x = _display displayCtrl _x;\ + _x ctrlSetFade 1;\ + _x ctrlShow false;\ + _x ctrlEnable false;\ + _x ctrlCommit FADE_DELAY;\ +} foreach [\ + IDC_loadIndicator,\ + RIGHT_PANEL_ITEMS_IDCS,\ + IDC_rightTabContentListnBox,\ + RIGHT_PANEL_ITEMS_BACKGROUND_IDCS,\ + IDC_buttonRemoveAll\ +]; + +#define TOGGLE_RIGHT_PANEL_CONTAINER\ +{\ + _x = _display displayCtrl _x;\ + _x ctrlSetFade 0;\ + _x ctrlShow true;\ + _x ctrlEnable true;\ + _x ctrlCommit FADE_DELAY;\ +} foreach [\ + IDC_blockRightFrame, \ + IDC_blockRighttBackground,\ + IDC_loadIndicator,\ + IDC_rightTabContentListnBox,\ + IDC_sortRightTab,\ + IDC_tabRight,\ + RIGHT_PANEL_ACC_IDCS,\ + RIGHT_PANEL_ITEMS_IDCS,\ + IDC_rightSearchbar,\ + IDC_rightSearchbarButton\ +];\ +{\ + _x = _display displayCtrl _x;\ + _x ctrlSetFade 1;\ + _x ctrlShow false;\ + _x ctrlEnable false;\ + _x ctrlCommit FADE_DELAY;\ +} foreach [\ + IDC_buttonCurrentMag,\ + IDC_buttonCurrentMag2,\ + IDC_iconBackgroundCurrentMag,\ + IDC_iconBackgroundCurrentMag2\ +]; + +#define TOGGLE_RIGHT_PANEL_HIDE\ +{\ + _x = _display displayCtrl _x;\ + _x ctrlSetFade 1;\ + _x ctrlShow false;\ + _x ctrlEnable false;\ + _x ctrlCommit FADE_DELAY;\ +} foreach [\ + IDC_blockRightFrame,\ + IDC_blockRighttBackground,\ + IDC_loadIndicator,\ + IDC_rightTabContent,\ + IDC_rightTabContentListnBox,\ + IDC_sortRightTab,\ + RIGHT_PANEL_ACC_BACKGROUND_IDCS,\ + RIGHT_PANEL_ACC_IDCS,\ + RIGHT_PANEL_ITEMS_BACKGROUND_IDCS,\ + RIGHT_PANEL_ITEMS_IDCS,\ + IDC_buttonRemoveAll,\ + IDC_rightSearchbar,\ + IDC_rightSearchbarButton,\ + IDC_buttonCurrentMag,\ + IDC_buttonCurrentMag2,\ + IDC_iconBackgroundCurrentMag,\ + IDC_iconBackgroundCurrentMag2\ +]; + +#define LIST_DEFAULTS\ + [\ + [\ + (primaryweapon GVAR(center) call bis_fnc_baseWeapon),\ + (secondaryweapon GVAR(center) call bis_fnc_baseWeapon),\ + (handgunweapon GVAR(center) call bis_fnc_baseWeapon)\ + ],\ + [\ + [primaryWeaponItems GVAR(center), secondaryWeaponItems GVAR(center), handgunItems GVAR(center)],\ + [primaryWeaponMagazine GVAR(center), secondaryWeaponMagazine GVAR(center), handgunMagazine GVAR(center)]\ + ],\ + uniformItems GVAR(center) + vestItems GVAR(center) + backpackItems GVAR(center),\ + [headgear GVAR(center)],\ + [uniform GVAR(center)],\ + [vest GVAR(center)],\ + [backpack GVAR(center)],\ + [goggles GVAR(center)],\ + [hmd GVAR(center)],\ + [binocular GVAR(center)]\ +] + +#define CHECK_WEAPON_OR_ACC\ + _item in (_weaponsArray select 0) ||\ + {_item in (_weaponsArray select 1)} ||\ + {_item in (_weaponsArray select 2)} ||\ + {_item in (GVAR(virtualItems) select 9)} ||\ + {_item in (_accsArray select 0)} ||\ + {_item in (_accsArray select 1)} ||\ + {_item in (_accsArray select 2)} ||\ + {_item in (_accsArray select 3)} + +#define CHECK_ASSIGNED_ITEMS\ + _item in (GVAR(virtualItems) select 10) ||\ + {_item in (GVAR(virtualItems) select 11)} ||\ + {_item in (GVAR(virtualItems) select 12)} ||\ + {_item in (GVAR(virtualItems) select 13)} ||\ + {_item in (GVAR(virtualItems) select 14)} ||\ + {_item in (GVAR(virtualItems) select 8)} + +#define CHECK_CONTAINER\ + _item in (GVAR(virtualItems) select 4) ||\ + {_item in (GVAR(virtualItems) select 5)} ||\ + {_item in (GVAR(virtualItems) select 6)} + +#define CLASS_CHECK_ITEM\ + isClass (_weaponCfg >> _item) ||\ + {isClass (_vehcCfg >> _item)} ||\ + {isClass (_glassesCfg >> _item)} ||\ + {isClass (_magCfg >> _item)} + +#define CHECK_CONTAINER_ITEMS\ + _item in (GVAR(virtualItems) select 3) ||\ + {_item in (_accsArray select 0)} ||\ + {_item in (_accsArray select 1)} ||\ + {_item in (_accsArray select 2)} ||\ + {_item in (_accsArray select 3)} ||\ + {_item in (GVAR(virtualItems) select 4)} ||\ + {_item in (GVAR(virtualItems) select 5)} ||\ + {_item in (GVAR(virtualItems) select 6)} ||\ + {_item in (GVAR(virtualItems) select 7)} ||\ + {_item in (GVAR(virtualItems) select 8)} ||\ + {_item in (GVAR(virtualItems) select 10)} ||\ + {_item in (GVAR(virtualItems) select 11)} ||\ + {_item in (GVAR(virtualItems) select 12)} ||\ + {_item in (GVAR(virtualItems) select 13)} ||\ + {_item in (GVAR(virtualItems) select 14)} ||\ + {_item in (GVAR(virtualItems) select 15)} ||\ + {_item in (GVAR(virtualItems) select 16)} ||\ + {_item in (GVAR(virtualItems) select 17)} + +#define ADD_LOADOUTS_LIST_PICTURES\ + _contentPanelCtrl lnbSetPicture [[_newRow, 2], getText (configFile >> "cfgWeapons" >> ((_loadout select 0) select 0) >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 3], getText (configFile >> "cfgWeapons" >> ((_loadout select 1) select 0) >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 4], getText (configFile >> "cfgWeapons" >> ((_loadout select 2) select 0) >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 5], getText (configFile >> "cfgWeapons" >> ((_loadout select 3) select 0) >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 6], getText (configFile >> "cfgWeapons" >> ((_loadout select 4) select 0) >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "cfgVehicles" >> ((_loadout select 5) select 0) >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (configFile >> "cfgWeapons" >> (_loadout select 6) >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "cfgGlasses" >> (_loadout select 7) >> "picture")]; diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf new file mode 100644 index 0000000000..815e3511a8 --- /dev/null +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -0,0 +1,63 @@ +/* + * Author: Dedmen + * Add a listbox row. + * + * Arguments: + * 0: Config category (must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice") + * 1: Classname + * 2: Panel control + * 3: Name of the picture entry in that Cfg class + * + * Return Value: + * None + * + * Public: Yes +*/ + +#include "script_component.hpp" +params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]]]; + +private _cacheNamespace = _ctrlPanel; //For better readability. + +private _cachedItemInfo = _cacheNamespace getVariable [_configCategory+_className, []]; + +//_cachedItemInfo == [_displayName, _itemPicture, _modPicture, _modID] +if (_cachedItemInfo isEqualTo []) then {//Not in cache. So get info and put into cache. + + private _configPath = configFile >> _configCategory >> _className; + + _cachedItemInfo set [0, getText (_configPath >> "displayName")]; + //if _pictureEntryName is empty then this item has no Icons. (Faces) + _cachedItemInfo set [1, if (_pictureEntryName isEqualTo "") then {""} else {getText (_configPath >> _pictureEntryName)}]; + + //get name of DLC + private _dlcName = ""; + private _addons = configsourceaddonlist _configPath; + if !(_addons isEqualTo []) then { + private _mods = configsourcemodlist (configfile >> "CfgPatches" >> _addons select 0); + if !(_mods isEqualTo []) then { + _dlcName = _mods select 0; + }; + }; + + if (_dlcName != "") then { + _cachedItemInfo set [2, (modParams [_dlcName,["logo"]]) param [0,""]];//mod picture + _modID = GVAR(modList) find _dlcName; + if (_modID < 0) then {_modID = GVAR(modList) pushback _dlcName;};//We keep a ordered list of all mods for sorting later. + _cachedItemInfo set [3, _modID];//mod ID + } else { + _cachedItemInfo set [2, ""];//mod picture + _cachedItemInfo set [3, 0];//mod ID + }; + _cacheNamespace setVariable [_configCategory+_className, _cachedItemInfo]; +}; + +_cachedItemInfo params ["_displayName", "_itemPicture", "_modPicture", "_modID"]; + +private _lbAdd = _ctrlPanel lbAdd _displayName; + +_ctrlPanel lbSetData [_lbAdd, _className]; +_ctrlPanel lbSetPicture [_lbAdd, _itemPicture]; +_ctrlPanel lbSetPictureRight [_lbAdd,["",_modPicture] select (GVAR(enableModIcons))]; +_ctrlPanel lbSetValue [_lbAdd,_modID]; +_ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf new file mode 100644 index 0000000000..bfe17761c2 --- /dev/null +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -0,0 +1,225 @@ +/* + * Author: Alganthe, Dedmen + * Add virtual items to the provided target. + * + * Arguments: + * 0: Target + * 1: Items + * 2: Add globally + * + * Return Value: + * None + * + * Example: + * [_box, ["item1", "item2", "itemN"]] call ace_arsenal_fnc_addVirtualItems + * [_box, true, false] call ace_arsenal_fnc_addVirtualItems + * + * Public: Yes +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params [["_object", objNull, [objNull]], ["_items", [], [true, []]], ["_global", false, [false]]]; + +if (_object == objNull) exitWith {}; +if (_items isEqualType [] && {count _items == 0}) exitWith {}; + +private _cargo = _object getVariable [QGVAR(virtualItems), [ + [[], [], []], // Weapons 0, primary, secondary, handgun + [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod + [ ], // Magazines 2 + [ ], // Headgear 3 + [ ], // Uniform 4 + [ ], // Vest 5 + [ ], // Backpacks 6 + [ ], // Goggles 7 + [ ], // NVGs 8 + [ ], // Binoculars 9 + [ ], // Map 10 + [ ], // Compass 11 + [ ], // Radio slot 12 + [ ], // Watch slot 13 + [ ], // Comms slot 14 + [ ], // WeaponThrow 15 + [ ], // WeaponPut 16 + [ ] // InventoryItems 17 +]]; + +private _configCfgWeapons = configFile >> "CfgWeapons"; //Save this lookup in variable for perf improvement + +if (_items isEqualType true) then { + if (_items) then { + private _configItems = uiNamespace getVariable QGVAR(configItems); + + { + (_x select 0) append (_x select 1); + (_x select 2) set [(_x select 3), (_x select 0) arrayIntersect (_x select 0)]; + } forEach [ + [(_cargo select 0 select 0),(_configItems select 0 select 0), _cargo select 0, 0], + [(_cargo select 0 select 1),(_configItems select 0 select 1), _cargo select 0, 1], + [(_cargo select 0 select 2),(_configItems select 0 select 2), _cargo select 0, 2], + [(_cargo select 1 select 0),(_configItems select 1 select 0), _cargo select 1, 0], + [(_cargo select 1 select 1),(_configItems select 1 select 1), _cargo select 1, 1], + [(_cargo select 1 select 2),(_configItems select 1 select 2), _cargo select 1, 2], + [(_cargo select 1 select 3),(_configItems select 1 select 3), _cargo select 1, 3] + ]; + + for "_index" from 2 to 17 do { + (_cargo select _index) append (_configItems select _index); + _cargo set [_index, (_cargo select _index) arrayIntersect (_cargo select _index)]; + }; + }; + +} else { + { + if (_x isEqualType "") then { + private _configItemInfo = _configCfgWeapons >> _x >> "ItemInfo"; + private _simulationType = getText (_configCfgWeapons >> _x >> "simulation"); + switch true do { + case (isClass (_configCfgWeapons >> _x)): { + switch true do { + /* Weapon acc */ + case ( + isClass (_configItemInfo) && + {(getNumber (_configItemInfo >> "type")) in [101, 201, 301, 302]} && + {!(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])} + ): { + switch (getNumber (_configItemInfo >> "type")) do { + case 201: { + (_cargo select 1) select 0 pushBackUnique _x; + }; + case 301: { + (_cargo select 1) select 1 pushBackUnique _x; + }; + case 101: { + (_cargo select 1) select 2 pushBackUnique _x; + }; + case 302: { + (_cargo select 1) select 3 pushBackUnique _x; + }; + }; + }; + /* Headgear */ + case (isClass (_configItemInfo) && + {getNumber (_configItemInfo >> "type") == 605}): { + (_cargo select 3) pushBackUnique _x; + }; + /* Uniform */ + case (isClass (_configItemInfo) && + {getNumber (_configItemInfo >> "type") == 801}): { + (_cargo select 4) pushBackUnique _x; + }; + /* Vest */ + case (isClass (_configItemInfo) && + {getNumber (_configItemInfo >> "type") == 701}): { + (_cargo select 5) pushBackUnique _x; + }; + /* NVgs */ + case (_simulationType == "NVGoggles"): { + (_cargo select 8) pushBackUnique _x; + }; + /* Binos */ + case (_simulationType == "Binocular" || + {(_simulationType == 'Weapon') && {(getNumber (_configCfgWeapons >> _x >> 'type') == 4096)}}): { + (_cargo select 9) pushBackUnique _x; + }; + /* Map */ + case (_simulationType == "ItemMap"): { + (_cargo select 10) pushBackUnique _x; + }; + /* Compass */ + case (_simulationType == "ItemCompass"): { + (_cargo select 11) pushBackUnique _x; + }; + /* Radio */ + case (_simulationType == "ItemRadio"): { + (_cargo select 12) pushBackUnique _x; + }; + /* Watch */ + case (_simulationType == "ItemWatch"): { + (_cargo select 13) pushBackUnique _x; + }; + /* GPS */ + case (_simulationType == "ItemGPS"): { + (_cargo select 14) pushBackUnique _x; + }; + /* UAV terminals */ + case (isClass (_configItemInfo) && + {getNumber (_configItemInfo >> "type") == 621}): { + (_cargo select 14) pushBackUnique _x; + }; + /* Weapon, at the bottom to avoid adding binos */ + case (isClass (_configCfgWeapons >> _x >> "WeaponSlotsInfo") && + {getNumber (_configCfgWeapons >> _x >> 'type') != 4096}): { + switch (getNumber (_configCfgWeapons >> _x >> "type")) do { + case 1: { + (_cargo select 0) select 0 pushBackUnique ([_x] call bis_fnc_baseWeapon); + }; + case 2: { + (_cargo select 0) select 2 pushBackUnique ([_x] call bis_fnc_baseWeapon); + }; + case 4: { + (_cargo select 0) select 1 pushBackUnique ([_x] call bis_fnc_baseWeapon); + }; + }; + }; + /* Misc items */ + case ( + isClass (_configItemInfo) && + ((getNumber (_configItemInfo >> "type")) in [101, 201, 301, 302] && + {(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])}) || + {(getNumber (_configItemInfo >> "type")) in [401, 619, 620]} || + {(getText (_configCfgWeapons >> _x >> "simulation")) == "ItemMineDetector"} + ): { + (_cargo select 17) pushBackUnique _x; + }; + }; + }; + case (isClass (configFile >> "CfgMagazines" >> _x)): { + // Lists to check against + private _grenadeList = []; + { + _grenadeList append getArray (_configCfgWeapons >> "Throw" >> _x >> "magazines"); + false + } count getArray (_configCfgWeapons >> "Throw" >> "muzzles"); + + private _putList = []; + { + _putList append getArray (_configCfgWeapons >> "Put" >> _x >> "magazines"); + false + } count getArray (_configCfgWeapons >> "Put" >> "muzzles"); + + // Check what the magazine actually is + switch true do { + // Rifle, handgun, secondary weapons mags + case ( + (getNumber (configFile >> "CfgMagazines" >> _x >> "type") in [256,512,1536,16]) && + {!(_x in _grenadeList)} && + {!(_x in _putList)} + ): { + (_cargo select 2) pushBackUnique _x; + }; + // Grenades + case (_x in _grenadeList): { + (_cargo select 15) pushBackUnique _x; + }; + // Put + case (_x in _putList): { + (_cargo select 16) pushBackUnique _x; + }; + }; + }; + case (isClass (configFile >> "CfgVehicles" >> _x)): { + if (getNumber (configFile >> "CfgVehicles" >> _x >> "isBackpack") == 1) then { + (_cargo select 6) pushBackUnique _x; + }; + }; + case (isClass (configFile >> "CfgGlasses" >> _x)): { + (_cargo select 7) pushBackUnique _x; + }; + }; + }; + } foreach _items; +}; + +_object setVariable [QGVAR(virtualItems), _cargo, _global]; diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf new file mode 100644 index 0000000000..1af4008caf --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -0,0 +1,92 @@ +/* + * Author: Alganthe + * Add or remove item(s) when the + or - button is pressed in the right panel. + * + * Arguments: + * 0: Arsenal display + * 1: Add or remove (-1: remove, 1: Add) + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_addOrRemove"]; + +private _load = 0; +private _maxLoad = ""; +private _items = []; +private _ctrlList = (_display displayCtrl IDC_rightTabContentListnBox); +private _lnbCurSel = lnbCurSelRow _ctrlList; +private _item = _ctrlList lnbData [_lnbCurSel, 0]; + +if ((_ctrlList lnbValue [_lnbCurSel, 2]) == 1 && {_addOrRemove == 1}) exitWith {}; + +// Update item count and currentItems array +switch GVAR(currentLeftPanel) do { + + case IDC_buttonUniform : { + if (_addOrRemove > 0) then { + for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + GVAR(center) addItemToUniform _item; + }; + } else { + for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + GVAR(center) removeItemFromUniform _item; + }; + }; + + _load = loadUniform GVAR(center); + _maxLoad = gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass"); + _items = uniformItems GVAR(center); + GVAR(currentItems) set [15 ,_items]; + }; + + case IDC_buttonVest : { + if (_addOrRemove > 0) then { + for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + GVAR(center) addItemToVest _item; + }; + } else { + for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + GVAR(center) removeItemFromVest _item; + }; + }; + + _load = loadVest GVAR(center); + _maxLoad = gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass"); + _items = vestItems GVAR(center); + GVAR(currentItems) set [16,_items]; + }; + + case IDC_buttonBackpack : { + if (_addOrRemove > 0) then { + for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + GVAR(center) addItemToBackpack _item; + }; + } else { + for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { + GVAR(center) removeItemFromBackpack _item; + }; + }; + + _load = loadBackpack GVAR(center); + _maxLoad = backpack GVAR(center); + _items = backpackItems GVAR(center); + GVAR(currentItems) set [17,_items]; + }; +}; + +// Update progress bar status, weight info +private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; +_loadIndicatorBarCtrl progressSetPosition _load; + +private _value = {_x == _item} count _items; +_ctrlList lnbSetText [[_lnbCurSel, 2],str _value]; + +[QGVAR(cargoChanged), [_display, _item, _addOrRemove, GVAR(shiftState)]] call CBA_fnc_localEvent; + +[_ctrlList, _maxLoad] call FUNC(updateRightPanel); diff --git a/addons/arsenal/functions/fnc_buttonClearAll.sqf b/addons/arsenal/functions/fnc_buttonClearAll.sqf new file mode 100644 index 0000000000..d73d777ace --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonClearAll.sqf @@ -0,0 +1,62 @@ +/* + * Author: Alganthe + * Clear the current container. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display"]; + +// Clear container +switch (GVAR(currentLeftPanel)) do { + case IDC_buttonUniform: { + {GVAR(center) removeItemFromUniform _x} foreach (uniformItems GVAR(center)); + GVAR(currentItems) set [15, []]; + }; + case IDC_buttonVest: { + {GVAR(center) removeItemFromVest _x} foreach (vestItems GVAR(center)); + GVAR(currentItems) set [16, []]; + }; + case IDC_buttonBackpack: { + {GVAR(center) removeItemFromBackpack _x} foreach (backpackItems GVAR(center)); + GVAR(currentItems) set [17, []]; + }; +}; + +// Clear number of owned items +private _ctrlList = _display displayCtrl IDC_rightTabContentListnBox; + +for "_l" from 0 to (lbSize _ctrlList - 1) do { + _ctrlList lnbSetText [[_l, 2], str 0]; +}; + +private _removeAllCtrl = _display displayCtrl IDC_buttonRemoveAll; +_removeAllCtrl ctrlSetFade 1; +_removeAllCtrl ctrlCommit FADE_DELAY; + +// Update load bar +private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; +_loadIndicatorBarCtrl progressSetPosition 0; + +private _maxLoad = switch (GVAR(currentLeftPanel)) do { + case IDC_buttonUniform: { + gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass") + }; + case IDC_buttonVest: { + gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass") + }; + case IDC_buttonBackpack: { + backpack GVAR(center) + }; +}; + +private _control = _display displayCtrl IDC_rightTabContentListnBox; +[_control, _maxLoad] call FUNC(updateRightPanel); diff --git a/addons/arsenal/functions/fnc_buttonExport.sqf b/addons/arsenal/functions/fnc_buttonExport.sqf new file mode 100644 index 0000000000..7bcac4c8ba --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonExport.sqf @@ -0,0 +1,51 @@ +/* + * Author: Alganthe + * Export current loadout / default loadouts list to clipboard. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" + +params ["_display"]; + +if (GVAR(shiftState)) then { + + if (isNil QGVAR(defaultLoadoutsList) || {GVAR(defaultLoadoutsList) isEqualTo []}) exitWith { + [_display, localize LSTRING(exportDefaultError)] call FUNC(message); + }; + + private _listLength = count GVAR(defaultLoadoutsList); + for "_index" from -1 to _listLength do { + + switch true do { + case (_index == -1): { + "ace_clipboard" callExtension (format ["[%1", endl]); + }; + + case (_index == _listLength): { + "ace_clipboard" callExtension "];"; + }; + + default { + "ace_clipboard" callExtension ([" ",str (GVAR(defaultLoadoutsList) select _index), [",", ""] select (_index == _listLength - 1), endl] joinString ""); + }; + }; + }; + + "ace_clipboard" callExtension "--COMPLETE--"; + + [_display, localize LSTRING(exportDefault)] call FUNC(message); +} else { + + private _export = str getUnitLoadout GVAR(center); + "ace_clipboard" callExtension (_export + ";"); + "ace_clipboard" callExtension "--COMPLETE--"; + + [_display, localize LSTRING(exportCurrent)] call FUNC(message); +}; diff --git a/addons/arsenal/functions/fnc_buttonHide.sqf b/addons/arsenal/functions/fnc_buttonHide.sqf new file mode 100644 index 0000000000..d79ff779d1 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonHide.sqf @@ -0,0 +1,52 @@ +/* + * Author: Alganthe + * Hide / show arsenal interface. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display"]; + +private _showToggle = !ctrlShown (_display displayCtrl IDC_menuBar); + +{ + private _ctrl = _display displayctrl _x; + _ctrl ctrlshow _showToggle; + _ctrl ctrlcommit 0.15; +} foreach [ + IDC_blockLeftFrame, + IDC_blockLeftBackground, + IDC_blockRightFrame, + IDC_blockRighttBackground, + IDC_loadIndicator, + IDC_totalWeight, + IDC_menuBar, + IDC_infoBox, + IDC_leftTabContent, + IDC_rightTabContent, + IDC_rightTabContentListnBox, + IDC_sortLeftTab, + IDC_sortRightTab, + IDC_leftSearchbarButton, + IDC_rightSearchbarButton, + IDC_leftSearchbar, + IDC_rightSearchbar, + IDC_tabLeft, + RIGHT_PANEL_ACC_BACKGROUND_IDCS, + RIGHT_PANEL_ACC_IDCS, + RIGHT_PANEL_ITEMS_BACKGROUND_IDCS, + RIGHT_PANEL_ITEMS_IDCS, + IDC_buttonRemoveAll, + IDC_buttonCurrentMag, + IDC_buttonCurrentMag2, + IDC_iconBackgroundCurrentMag, + IDC_iconBackgroundCurrentMag2 +]; diff --git a/addons/arsenal/functions/fnc_buttonImport.sqf b/addons/arsenal/functions/fnc_buttonImport.sqf new file mode 100644 index 0000000000..76cd2f3a75 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonImport.sqf @@ -0,0 +1,111 @@ +/* + * Author: Alganthe + * Import loadout / default loadouts list from clipboard. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display"]; + +private _data = call (compile copyFromClipboard); + +if (isNil "_data" || {!(_data isEqualType [])}) exitWith { + [_display, localize LSTRING(importFormatError)] call FUNC(message); +}; + +if (GVAR(shiftState) && {is3DEN}) then { + + { + if ( + count _x == 2 && + {_x select 0 isEqualType ""} && + {_x select 0 != ""} && + {_x select 1 isEqualType []} && + {count (_x select 1) == 10} + ) then { + + _x params ["_loadoutName", "_loadout"]; + + private _sameNameLoadoutsList = GVAR(defaultLoadoutsList) select {_x select 0 == _loadoutName}; + + if (count _sameNameLoadoutsList == 0) then { + GVAR(defaultLoadoutsList) pushBack [_loadoutName, _loadout]; + } else { + GVAR(defaultLoadoutsList) set [GVAR(defaultLoadoutsList) find (_sameNameLoadoutsList select 0), _loadoutName, _loadout]; + }; + }; + } foreach _data; + + [_display, localize LSTRING(importedDefault)] call FUNC(message); + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + +} else { + if (count _data == 10) then { + GVAR(center) setUnitLoadout _data; + + GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; + for "_index" from 0 to 15 do { + switch (_index) do { + case 0; + case 1; + case 2:{ + GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; + }; + case 3; + case 4; + case 5; + case 6; + case 7; + case 8; + case 9: { + GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; + + }; + case 10: { + {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); + }; + case 11: { + {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); + }; + case 12: { + {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); + }; + case 13: { + GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; + }; + case 14: { + GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; + }; + case 15: { + GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; + }; + }; + }; + + + { + private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); + private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch", "itemgps"] find (tolower _simulationType)); + + GVAR(currentItems) set [_index, _x]; + } foreach (assignedItems GVAR(center)); + + call FUNC(updateUniqueItemsList); + + // Reapply insignia + [GVAR(center), ""] call bis_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + + [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); + + [_display, localize LSTRING(importedCurrent)] call FUNC(message); + }; +}; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf new file mode 100644 index 0000000000..d3621f5826 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf @@ -0,0 +1,55 @@ +/* + * Author: Alganthe + * Delete / unshare loadout currently selected. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +if !(ctrlEnabled _control) exitWith {}; + +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _contentPanelCursSel = lnbCurSelRow _contentPanelCtrl; +private _loadoutName = _contentPanelCtrl lnbText [_contentPanelCursSel, 1]; + +if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { + + if (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}) then { + GVAR(defaultLoadoutsList) deleteAt (GVAR(defaultLoadoutsList) find ((GVAR(defaultLoadoutsList) select {_x select 0 == _loadoutName}) select 0)); + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + } else { + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; + _data deleteAt (_data find ((_data select {_x select 0 == _loadoutName}) select 0)); + }; + + _contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), nil]; + _contentPanelCtrl lnbDeleteRow _contentPanelCursSel; + _contentPanelCtrl lnbSetCurSelRow (_contentPanelCursSel); + + [(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutDeleted), _loadoutName] joinString " "] call FUNC(message); +} else { + + private _profileName = profileName; // GVAR(center) could be a remote unit + private _loadoutVar = _profileName + _loadoutName; + private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); + + GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; + GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars - [_loadoutVar], true]; + + _contentPanelCtrl lnbDeleteRow _contentPanelCursSel; + _contentPanelCtrl lnbSetCurSelRow (_contentPanelCursSel); + + [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; + + [(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutUnshared), _loadoutName] joinString " "] call FUNC(message); +}; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf new file mode 100644 index 0000000000..9d413a233c --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf @@ -0,0 +1,90 @@ +/* + * Author: Alganthe + * Load selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +if !(ctrlEnabled _control) exitWith {}; + +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _curSel = lnbCurSelRow _contentPanelCtrl; +private _loadoutName = _contentPanelCtrl lnbText [_curSel, 1]; + +private _loadout = switch GVAR(currentLoadoutsTab) do { + + case IDC_buttonMyLoadouts; + case IDC_buttonDefaultLoadouts:{ + (_contentPanelCtrl getVariable _loadoutName + str GVAR(currentLoadoutsTab)) select 0 + }; + + case IDC_buttonSharedLoadouts:{ + (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_curSel, 0]) + (_contentPanelCtrl lnbText [_curSel, 1]))) select 2 + }; +}; + +GVAR(center) setUnitLoadout [_loadout, true]; + +GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; +for "_index" from 0 to 15 do { + switch (_index) do { + case 0; + case 1; + case 2:{ + GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; + }; + case 3; + case 4; + case 5; + case 6; + case 7; + case 8; + case 9: { + GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; + + }; + case 10: { + {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); + }; + case 11: { + {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); + }; + case 12: { + {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); + }; + case 13: { + GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; + }; + case 14: { + GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; + }; + case 15: { + GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; + }; + }; +}; +{ + private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); + private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch", "itemgps"] find (tolower _simulationType)); + + GVAR(currentItems) set [_index, _x]; +} foreach (assignedItems GVAR(center)); + +call FUNC(updateUniqueItemsList); + +// Reapply insignia +[GVAR(center), ""] call bis_fnc_setUnitInsignia; +[GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + +[(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutLoaded), _loadoutName] joinString " "] call FUNC(message); diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf new file mode 100644 index 0000000000..5435d07279 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf @@ -0,0 +1,70 @@ +/* + * Author: Alganthe + * Rename selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +if !(ctrlEnabled _control) exitWith {}; + +// Retrieve panel data +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _curSelRow = lnbCurSelRow _contentPanelCtrl; +private _loadoutName = _contentPanelCtrl lnbText [_curSelRow, 1]; + +private _editBoxCtrl = _display displayCtrl IDC_textEditBox; +private _editBoxContent = ctrlText _editBoxCtrl; + +private _data = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts && {is3DEN}); +private _similarLoadouts = _data select {_x select 0 == _editBoxContent}; + +if (count _similarLoadouts > 0) exitWith { + [(findDisplay IDD_ace_arsenal), localize LSTRING(renameExistError)] call FUNC(message); +}; + +// Update loadout info in profile / 3DEN and list namespaces +private _loadoutToRename = (_data select {_x select 0 == _loadoutName}) select 0; +(_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; + +_data set [_data find _loadoutToRename, [_editBoxContent, (_loadoutToRename select 1)]]; +_contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), nil]; +_contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_loadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]]; + +// Add new row +_contentPanelCtrl lnbDeleteRow _curSelRow; +private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; + +ADD_LOADOUTS_LIST_PICTURES + +if (_nullItemsAmount > 0) then { + + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; +} else { + + if (_unavailableItemsAmount > 0) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + }; +}; + +// Sort and select the current row +_contentPanelCtrl lnbSort [1, false]; +for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; +}; + +if (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}) then { + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; +}; + +[(findDisplay IDD_ace_arsenal), [_loadoutName, localize LSTRING(loadoutRenamed) ,_editBoxContent] joinString " "] call FUNC(message); diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf new file mode 100644 index 0000000000..fecb6300e3 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf @@ -0,0 +1,288 @@ +/* + * Author: Alganthe + * Save selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +if !(ctrlEnabled _control) exitWith {}; + +private _editBoxCtrl = _display displayCtrl IDC_textEditBox; +private _editBoxContent = ctrlText _editBoxCtrl; + +if (_editBoxContent == "") exitWith { + [(findDisplay IDD_ace_arsenal), localize LSTRING(saveEmptyNameBox)] call FUNC(message); +}; + +private _data = [+(profileNamespace getVariable [QGVAR(saved_loadouts),[]]), +(GVAR(defaultLoadoutsList))] select (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts && {is3DEN}); +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _cursSelRow = lnbCurSelRow _contentPanelCtrl; + +private _loadoutName = _contentPanelCtrl lnbText [_cursSelRow, 1]; +private _curSelLoadout = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; +private _loadout = getUnitLoadout GVAR(center); + +private _sameNameLoadoutsList = _data select {_x select 0 == _editBoxContent}; +private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); + +// Make sure the loadout isn't yours (public tab) or being shared (my loadouts tab) +private _similarSharedLoadout = (profileName + _editBoxContent) in _sharedLoadoutsVars; +if ((_contentPanelCtrl lnbText [_cursSelRow, 0]) == profileName) exitWith { + [(findDisplay IDD_ace_arsenal), localize LSTRING(saveAuthorError)] call FUNC(message); +}; + +if (_similarSharedLoadout) exitWith { + [(findDisplay IDD_ace_arsenal), localize LSTRING(saveSharedError)] call FUNC(message); +}; + +switch (GVAR(currentLoadoutsTab)) do { + case IDC_buttonMyLoadouts:{ + + for "_dataIndex" from 0 to 10 do { + switch (_dataIndex) do { + + case 0; + case 1; + case 2; + case 8: { + if (count (_loadout select _dataIndex) > 0) then { + + private _weapon = (_loadout select _dataIndex) select 0; + if (_weapon != "") then { + + private _baseWeapon = _weapon call BIS_fnc_baseWeapon; + if (_weapon != _baseWeapon) then { + (_loadout select _dataIndex) set [0, _baseWeapon]; + }; + }; + }; + }; + + case 3; + case 4; + case 5: { + if (count (_loadout select _dataIndex) > 0) then { + private _containerContents = (_loadout select _dataIndex) select 1; + + if (count _containerContents > 0) then { + + { + if (count _x == 2) then { + + if ((_x select 0) isEqualType "") then { + + private _item = (_x select 0); + if (_item != "") then { + + private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); + if (_uniqueBaseCfgText != "") then { + + _x set [0, _uniqueBaseCfgText]; + }; + }; + } else { + private _weapon = (_x select 0) select 0; + if (_weapon != "") then { + + private _baseWeapon = _weapon call BIS_fnc_baseWeapon; + if (_weapon != _baseWeapon) then { + (_x select 0)set [0, _baseWeapon]; + }; + }; + }; + }; + } foreach _containerContents; + }; + }; + }; + + case 9: { + for "_subIndex" from 0 to 4 do { + private _item = (_loadout select _dataIndex) select _subIndex; + + if (_item != "") then { + + private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); + if (_uniqueBaseCfgText != "") then { + + (_loadout select _dataIndex) set [_subIndex, _uniqueBaseCfgText]; + }; + }; + }; + }; + }; + }; + + if (count _sameNameLoadoutsList == 0) then { + _data pushBack [_editBoxContent, _loadout]; + } else { + _data set [_data find (_sameNameLoadoutsList select 0), [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _loadout]]; + }; + + // Delete "old" loadout row + for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbDeleteRow _i}; + }; + + private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; + + ADD_LOADOUTS_LIST_PICTURES + + _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_loadout] call FUNC(verifyLoadout)]; + + _contentPanelCtrl lnbSort [1, false]; + + // Select newly saved loadout + for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + }; + + profileNamespace setVariable [QGVAR(saved_loadouts), _data]; + }; + + case IDC_buttonDefaultLoadouts:{ + + if (is3DEN) then { + + private _sameNameLoadoutsList = _data select {_x select 0 == _editBoxContent}; + + for "_dataIndex" from 0 to 10 do { + switch (_dataIndex) do { + + case 0; + case 1; + case 2; + case 8: { + if (count (_loadout select _dataIndex) > 0) then { + + private _weapon = (_loadout select _dataIndex) select 0; + if (_weapon != "") then { + + private _baseWeapon = _weapon call BIS_fnc_baseWeapon; + if (_weapon != _baseWeapon) then { + (_loadout select _dataIndex) set [0, _baseWeapon]; + }; + }; + }; + }; + + case 3; + case 4; + case 5: { + if (count (_loadout select _dataIndex) > 0) then { + private _containerContents = (_loadout select _dataIndex) select 1; + + if (count _containerContents > 0) then { + + { + if (count _x == 2) then { + + if ((_x select 0) isEqualType "") then { + + private _item = (_x select 0); + if (_item != "") then { + + private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); + if (_uniqueBaseCfgText != "") then { + + _x set [0, _uniqueBaseCfgText]; + }; + }; + } else { + private _weapon = (_x select 0) select 0; + if (_weapon != "") then { + + private _baseWeapon = _weapon call BIS_fnc_baseWeapon; + if (_weapon != _baseWeapon) then { + (_x select 0)set [0, _baseWeapon]; + }; + }; + }; + }; + } foreach _containerContents; + }; + }; + }; + + case 9: { + for "_subIndex" from 0 to 4 do { + private _item = (_loadout select _dataIndex) select _subIndex; + + if (_item != "") then { + + private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); + if (_uniqueBaseCfgText != "") then { + + (_loadout select _dataIndex) set [_subIndex, _uniqueBaseCfgText]; + }; + }; + }; + }; + }; + }; + + if (count _sameNameLoadoutsList == 0) then { + GVAR(defaultLoadoutsList) pushBack [_editBoxContent, _loadout]; + } else { + GVAR(defaultLoadoutsList) set [GVAR(defaultLoadoutsList) find (_sameNameLoadoutsList select 0), [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _loadout]]; + }; + + for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbDeleteRow _i}; + }; + + private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; + + ADD_LOADOUTS_LIST_PICTURES + + _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_loadout] call FUNC(verifyLoadout)]; + + _contentPanelCtrl lnbSort [1, false]; + + // Select newly saved loadout + for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { + if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + }; + + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + } else { + + if (count _sameNameLoadoutsList == 0) then { + _data pushBack [_editBoxContent, _curSelLoadout]; + } else { + _data set [_data find (_sameNameLoadoutsList select 0), [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _curSelLoadout]]; + _contentPanelCtrl setVariable [_editBoxContent + str IDC_buttonMyLoadouts, [_curSelLoadout] call FUNC(verifyLoadout)]; + }; + + profileNamespace setVariable [QGVAR(saved_loadouts), _data]; + }; + }; + + case IDC_buttonSharedLoadouts :{ + + _loadout = (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_cursSelRow, 0]) + (_contentPanelCtrl lnbText [_cursSelRow, 1]))) select 2; + + if (count _sameNameLoadoutsList == 0) then { + _data pushBack [_editBoxContent, _loadout]; + } else { + _data set [_data find (_sameNameLoadoutsList select 0), [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _loadout]]; + _contentPanelCtrl setVariable [_editBoxContent + str IDC_buttonMyLoadouts, [_loadout] call FUNC(verifyLoadout)]; + }; + + profileNamespace setVariable [QGVAR(saved_loadouts), _data]; + }; +}; +[(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutSaved), _editBoxContent] joinString " "] call FUNC(message); +private _savedLoadout = (_data select {_x select 0 == _editBoxContent}) select 0; +[QGVAR(onLoadoutSave), [_data find _savedLoadout, _savedLoadout]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf new file mode 100644 index 0000000000..d167522823 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf @@ -0,0 +1,55 @@ +/* + * Author: Alganthe + * Share selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +if !(ctrlEnabled _control) exitWith {}; + +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _contentPanelCursSel = lnbCurSelRow _contentPanelCtrl; +private _loadoutName = _contentPanelCtrl lnbText [_contentPanelCursSel, 1]; +private _profileName = profileName; // GVAR(center) could be a remote unit +private _loadoutVar = _profileName + _loadoutName; +private _sharedLoadoutsVars = +(GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars)); + +private _loadoutIndex = _sharedLoadoutsVars find _loadoutVar; +private _loadoutData = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; + +// Loadout set to private +if (_loadoutIndex > -1) then { + GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; + GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars - [_loadoutVar], true]; + + _contentPanelCtrl lnbSetPicture [[_contentPanelCursSel, 0], QPATHTOF(data\iconPublicBlank.paa)]; + _contentPanelCtrl lnbSetValue [[_contentPanelCursSel, 0], 0]; + [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; + +// Loadout set to public +} else { + GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, [_profileName ,_loadoutName , _loadoutData], true]; + _sharedLoadoutsVars pushBackUnique _loadoutVar; + GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars, true]; + + _contentPanelCtrl lnbSetPicture [[_contentPanelCursSel, 0], QPATHTOF(data\iconPublic.paa)]; + _contentPanelCtrl lnbSetValue [[_contentPanelCursSel, 0], 1]; + [QGVAR(loadoutShared), [_contentPanelCtrl, [_profileName ,_loadoutName , _loadoutData]]] call CBA_fnc_remoteEvent; +}; + +// Update share button text +_control ctrlSetText ( [ + localize LSTRING(buttonSharePrivateText), + localize LSTRING(buttonSharePublicText) +] select ((_contentPanelCtrl lnbValue [_contentPanelCursSel, 0]) == 1)); diff --git a/addons/arsenal/functions/fnc_clearSearchbar.sqf b/addons/arsenal/functions/fnc_clearSearchbar.sqf new file mode 100644 index 0000000000..c417b6d1a4 --- /dev/null +++ b/addons/arsenal/functions/fnc_clearSearchbar.sqf @@ -0,0 +1,28 @@ +/* + * Author: Alganthe + * Clear the provided searchbar. + * + * Arguments: + * 0: Arsenal display + * 1: Searchbar control + * 2: Right button state + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control", "_rightButton"]; + +if (_rightButton != 1) exitWith {}; + +_control ctrlSetText ''; + +if (ctrlIDC _control == IDC_leftSearchbar) then { + [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); +} else { + [_display, _display displayCtrl GVAR(currentRightPanel)] call FUNC(fillRightPanel); +}; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf new file mode 100644 index 0000000000..83a4336ea0 --- /dev/null +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -0,0 +1,189 @@ +/* + * Author: Alganthe + * Fill left panel. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +private _ctrlIDC = ctrlIDC _control; + +if !(isNil QGVAR(currentLeftPanel)) then { + private _previousCtrlBackground = _display displayCtrl (GVAR(currentLeftPanel) - 1); + _previousCtrlBackground ctrlSetFade 1; + _previousCtrlBackground ctrlCommit FADE_DELAY; +}; + +private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1); +private _ctrlPanel = _display displayCtrl IDC_leftTabContent; +_ctrlBackground ctrlSetFade 0; +_ctrlBackground ctrlCommit FADE_DELAY; + +_ctrlPanel lbSetCurSel -1; + +// Handle icons and filling +switch true do { + case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]) : { + // Purge old data + lbClear _ctrlPanel; + private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; + _ctrlPanel lbsetvalue [_addEmpty, -1]; + + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach ((GVAR(virtualItems) select 0) select ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find _ctrlIDC)); + }; + + case (_ctrlIDC in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) : { + + lbClear _ctrlPanel; + private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; + _ctrlPanel lbsetvalue [_addEmpty, -1]; + + // Filling + switch (_ctrlIDC) do { + case IDC_buttonUniform : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 4); + }; + + case IDC_buttonVest : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 5); + }; + + case IDC_buttonBackpack : { + { + ["CfgVehicles", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 6); + }; + }; + }; + + default { + GVAR(currentRightPanel) = nil; + + lbClear _ctrlPanel; + + if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then { + private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; + _ctrlPanel lbsetvalue [_addEmpty, -1]; + }; + + switch (_ctrlIDC) do { + case IDC_buttonHeadgear: { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 3); + }; + case IDC_buttonGoggles : { + { + ["CfgGlasses", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 7); + }; + case IDC_buttonNVG : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 8); + }; + case IDC_buttonBinoculars : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 9); + }; + case IDC_buttonMap : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 10); + }; + case IDC_buttonCompass : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 11); + }; + case IDC_buttonRadio : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 12); + }; + case IDC_buttonWatch : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 13); + }; + case IDC_buttonGPS : { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (GVAR(virtualItems) select 14); + }; + case IDC_buttonFace : { + { + { + if ( + getnumber (_x >> "disabled") == 0 && + {getText (_x >> "head") != ""} && + {configName _x != "Default"} + ) then { + private _configName = configName _x; + private _displayName = getText (_x >> "displayName"); + private _lbAdd = _ctrlPanel lbAdd _displayName; + _ctrlPanel lbSetData [_lbAdd, _configName]; + _ctrlPanel lbSetTooltip [_lbAdd,format ["%1\n%2",_displayName, _configName]]; + _x call ADDMODICON; + }; + } foreach ("isClass _x" configClasses _x); + } foreach ("isClass _x" configClasses (configfile >> "cfgfaces")); + }; + case IDC_buttonVoice : { + private _voices = (configProperties [(configFile >> "CfgVoice"), "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [(configfile >> "CfgVoice" >> "NoVoice")]; + { + ["CfgVoice", configName _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); + } foreach _voices; + }; + case IDC_buttonInsigna : { + { + ["CfgUnitInsignia", configName _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); + } foreach ("true" configClasses (configFile >> "CfgUnitInsignia")); + }; + }; + }; +}; + +// Done +if (GVAR(currentLeftPanel) != _ctrlIDC) then { + (_display displayCtrl IDC_leftSearchbar) ctrlSetText ""; + (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +}; + +GVAR(currentLeftPanel) = _ctrlIDC; +[QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent; + +// Sort +private _sortLeftCtrl = _display displayCtrl IDC_sortLeftTab; +[_sortLeftCtrl, _sortLeftCtrl lbValue (lbCurSel _sortLeftCtrl)] call FUNC(sortPanel); + +//Select current item +private _itemsToCheck = ((GVAR(currentItems) select [0,15]) + [GVAR(currentFace), GVAR(currentVoice), GVAR(currentInsignia)]) apply {tolower _x}; + +for "_lbIndex" from 0 to (lbSize _ctrlPanel - 1) do { + private _currentData = _ctrlPanel lbData _lbIndex; + + if (!(_currentData isEqualTo "") && {tolower _currentData in _itemsToCheck}) exitWith { + _ctrlPanel lbSetCurSel _lbIndex; + }; +}; +if (lbCurSel _ctrlPanel < 0) then { + _ctrlPanel lbSetCurSel 0; +}; diff --git a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf new file mode 100644 index 0000000000..118581c160 --- /dev/null +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -0,0 +1,118 @@ +/* + * Author: Alganthe + * Fill loadouts list. + * + * Arguments: + * 0: Loadouts display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _textEditBoxCtrl= _display displayCtrl IDC_textEditBox; +_textEditBoxCtrl ctrlSetText ""; +private _sharingEnabled = (GVAR(allowSharedLoadouts) && {isMultiplayer}); +private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); + +_contentPanelCtrl lnbSetCurSelRow -1; +lnbClear _contentPanelCtrl; + +private _data = +(profileNamespace getvariable [QGVAR(saved_loadouts),[]]); + +if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { + + { + _x params ["_loadoutName", "_loadoutData"]; + + private _loadoutCachedInfo = _contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab)); + + if (isNil "_loadoutCachedInfo") then { + [_loadoutData] call FUNC(verifyLoadout) + } else { + _loadoutCachedInfo + } params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; + + // Log missing / nil items to RPT + if (GVAR(EnableRPTLog) && {isNil "_loadoutCachedInfo"} && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then { + + private _printComponent = "ACE_Arsenal - Loadout:"; + private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " "; + private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " "; + + diag_log text (format ["%1%5 %2%5 %3%5 %4", _printComponent, "Name: " + _loadoutName, _printNullItemsList, _printUnavailableItemsList, endl]); + }; + + if (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts || {!_sharingEnabled}) then { + _contentPanelCtrl lnbSetColumnsPos [0, 0, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; + } else { + _contentPanelCtrl lnbSetColumnsPos [0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; + }; + + private _newRow = _contentPanelCtrl lnbAddRow ["",_loadoutName]; + + ADD_LOADOUTS_LIST_PICTURES + + if (_nullItemsAmount > 0) then { + + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; + } else { + + if (_unavailableItemsAmount > 0) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + }; + }; + + _contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), [_loadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]]; + + if ((profileName + _loadoutName) in _sharedLoadoutsVars && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts}) then { + _contentPanelCtrl lnbSetPicture [[_newRow, 0], QPATHTOF(data\iconPublic.paa)]; + _contentPanelCtrl lnbSetValue [[_newRow, 0], 1]; + }; + } foreach ([_data, +GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts)); +} else { + + { + _x params ["_playerName", "_loadoutName", "_loadoutData"]; + + if ((allPlayers apply {name _x}) find _playerName == -1) then { + + private _loadoutVar = _playerName + _loadoutName; + + GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; + _sharedLoadoutsVars = _sharedLoadoutsVars - [_loadoutVar]; + GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsNamespace), _sharedLoadoutsVars, true]; + + [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; + } else { + + ([_loadoutData] call FUNC(verifyLoadout)) params ["_loadout", "_nullItemsAmount", "_unavailableItemsAmount"]; + + _contentPanelCtrl lnbSetColumnsPos [0, 0.15, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; + private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; + + ADD_LOADOUTS_LIST_PICTURES + + _contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName]; + + if (_nullItemsAmount > 0) then { + + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; + } else { + + if (_unavailableItemsAmount > 0) then { + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + }; + }; + }; + } foreach (_sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x}); +}; + +_contentPanelCtrl lnbSort [1, false]; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf new file mode 100644 index 0000000000..c62ea3cab8 --- /dev/null +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -0,0 +1,361 @@ +/* + * Author: Alganthe + * Fill right panel. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +private _ctrlIDC = ctrlIDC _control; + +// Fade old control background +if !(isNil QGVAR(currentRightPanel)) then { + private _previousCtrlBackground = _display displayCtrl (GVAR(currentRightPanel) - 1); + _previousCtrlBackground ctrlSetFade 1; + _previousCtrlBackground ctrlCommit FADE_DELAY; +}; + +// Show new control background +private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1); +_ctrlBackground ctrlShow true; +_ctrlBackground ctrlSetFade 0; +_ctrlBackground ctrlCommit FADE_DELAY; + +private _searchbarCtrl = _display displayCtrl IDC_rightSearchbar; + +if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { + _searchbarCtrl ctrlShow true; + _searchbarCtrl ctrlSetFade 0; + _searchbarCtrl ctrlCommit 0; +}; + +private _fnc_fill_right_Container = { + params ["_configCategory", "_className", "_isMagazine", ["_isUnique", false, [false]]]; + + private _cacheNamespace = _ctrlPanel; + private _cachedItemInfo = _cacheNamespace getVariable [_configCategory+_className, []]; + + // Not in cache. So get info and put into cache + if (_cachedItemInfo isEqualTo []) then { + private _configPath = configFile >> _configCategory >> _className; + + _cachedItemInfo set [0, getText (_configPath >> "displayName")]; + _cachedItemInfo set [1, getText (_configPath >> "picture")]; + _cachedItemInfo set [2, [getNumber (_configPath >> "itemInfo" >> "mass"), getNumber (_configPath >> "mass")] select _isMagazine]; + + _cacheNamespace setVariable [_configCategory+_className, _cachedItemInfo]; + }; + + _cachedItemInfo params ["_displayName","_picture", "_mass"]; + + private _lbAdd = _ctrlPanel lnbAddRow ["", _displayName, "0"]; + private _columns = count lnbGetColumnsPosition _ctrlPanel; + + _ctrlPanel lnbSetData [[_lbAdd, 0], _x]; + _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; + _ctrlPanel lnbSetValue [[_lbAdd, 0], _mass]; + _ctrlPanel setVariable [_x, _mass]; + _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select (_isUnique)]; + _ctrlPanel lbSetTooltip [_lbAdd * _columns,format ["%1\n%2", _displayName, _x]]; +}; + +// Retrieve compatible mags +private _compatibleItems = []; +private _compatibleMagazines = [[[], []], [[], []], [[], []]]; +{ + if (_x != "") then { + private _weaponConfig = (configFile >> "CfgWeapons" >> _x); + private _index = _forEachIndex; + + { + private _subIndex = _forEachIndex; + { + // Magazine group + if !(isClass (configFile >> "CfgMagazines" >> _x)) then { + private _magazineGroups = uiNamespace getVariable [QGVAR(magazineGroups),["#CBA_HASH#",[],[],[]]]; + private _magArray = [_magazineGroups, _x] call CBA_fnc_hashGet; + {((_compatibleMagazines select _index) select _subIndex) pushBackUnique _x} forEach _magArray; + } else { + ((_compatibleMagazines select _index) select _subIndex) pushBackUnique (configName (configFile >> "CfgMagazines" >> _x)) + } + } foreach ([getArray (_weaponConfig >> _x >> "magazines"), getArray (_weaponConfig >> "magazines")] select (_x == "this")); + } foreach getArray (_weaponConfig >> "muzzles"); + }; +} foreach [primaryWeapon GVAR(center), handgunWeapon GVAR(center), secondaryWeapon GVAR(center)]; + +private _itemsToCheck = []; +private _compatibleMagsPrimaryMuzzle = []; +private _compatibleMagsSecondaryMuzzle = []; + +private _allCompatibleMags = []; +{ + _allCompatibleMags append (_x select 0); + _allCompatibleMags append (_x select 1); +} foreach _compatibleMagazines; + +private _ctrlPanel = _display displayCtrl IDC_rightTabContent; + +switch (GVAR(currentLeftPanel)) do { + case IDC_buttonPrimaryWeapon : { + _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 0 select 0; + _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 0 select 1; + _compatibleItems = (primaryWeapon GVAR(center)) call bis_fnc_compatibleItems; + _itemsToCheck = GVAR(currentItems) select 18; + }; + + case IDC_buttonHandgun : { + _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 1 select 0; + _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 1 select 1; + _compatibleItems = (handgunWeapon GVAR(center)) call bis_fnc_compatibleItems; + _itemsToCheck = GVAR(currentItems) select 20; + }; + + case IDC_buttonSecondaryWeapon : { + _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 2 select 0; + _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 2 select 1; + _compatibleItems = (secondaryWeapon GVAR(center)) call bis_fnc_compatibleItems; + _itemsToCheck = GVAR(currentItems) select 19; + }; + + case IDC_buttonUniform; + case IDC_buttonVest; + case IDC_buttonBackpack : { + _ctrlPanel = _display displayCtrl IDC_rightTabContentListnBox; + }; +}; + +_itemsToCheck = _itemsToCheck apply {toLower _x}; +_compatibleItems = _compatibleItems apply {toLower _x}; + +lbClear (_display displayCtrl IDC_rightTabContentListnBox); +lbClear (_display displayCtrl IDC_rightTabContent); + +(_display displayCtrl IDC_rightTabContentListnBox) lbSetCurSel -1; +(_display displayCtrl IDC_rightTabContent) lbSetCurSel -1; + +private _leftPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]; + +if (_ctrlIDC in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] && {_leftPanelState}) then { + private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; + _ctrlPanel lbsetvalue [_addEmpty, -1]; +}; + +switch (_ctrlIDC) do { + + case IDC_buttonOptic : { + if (_leftPanelState) then { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 0) apply {toLower _x})); + } else { + { + ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 1) select 0); + { + ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 22) select 0); + }; + }; + + case IDC_buttonItemAcc : { + if (_leftPanelState) then { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 1) apply {toLower _x})); + } else { + { + ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 1) select 1); + { + ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 22) select 1); + }; + }; + + case IDC_buttonMuzzle : { + if (_leftPanelState) then { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 2) apply {toLower _x})); + } else { + { + ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 1) select 2); + { + ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 22) select 2); + }; + }; + + case IDC_buttonBipod : { + if (_leftPanelState) then { + { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 3) apply {toLower _x})); + } else { + { + ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 1) select 3); + { + ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 22) select 3); + }; + }; + + case IDC_buttonCurrentMag : { + if (_leftPanelState) then { + { + ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach ((GVAR(virtualItems) select 2) arrayIntersect _compatibleMagsPrimaryMuzzle); + }; + }; + + case IDC_buttonCurrentMag2 : { + if (_leftPanelState) then { + { + ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); + } foreach ((GVAR(virtualItems) select 2) arrayIntersect _compatibleMagsSecondaryMuzzle); + }; + }; + + case IDC_buttonMag : { + { + ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 2) arrayIntersect _allCompatibleMags); + { + ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + } foreach ((GVAR(virtualItems) select 19) arrayIntersect _allCompatibleMags); + }; + + case IDC_buttonMagALL : { + { + ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 2); + { + ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 19); + }; + + case IDC_buttonThrow : { + { + ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 15); + { + ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 20); + }; + + case IDC_buttonPut : { + { + ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 16); + { + ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 21); + }; + + case IDC_buttonMisc : { + { + ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 17); + { + ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 18); + { + ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 23); + { + ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; + } foreach (GVAR(virtualItems) select 24); + }; +}; + +if (GVAR(currentRightPanel) != _ctrlIDC) then { + (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +}; + +GVAR(currentRightPanel) = _ctrlIDC; + +[QGVAR(rightPanelFilled), [_display, GVAR(currentLeftPanel), _ctrlIDC]] call CBA_fnc_localEvent; + +// Add current items and change progress bar +if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) then { + + private _maxLoad = 0; + private _container = switch (GVAR(currentLeftPanel)) do { + case IDC_buttonUniform : { + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadUniform GVAR(center)); + _maxLoad = gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass"); + uniformItems GVAR(center) + }; + case IDC_buttonVest : { + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadVest GVAR(center)); + _maxLoad = gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass"); + vestItems GVAR(center) + }; + case IDC_buttonBackpack : { + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadBackpack GVAR(center)); + _maxLoad = backpack GVAR(center); + backpackItems GVAR(center) + }; + }; + + for "_l" from 0 to ((lnbsize _ctrlPanel select 0) - 1) do { + private _class = _ctrlPanel lnbData [_l, 0]; + _ctrlPanel lnbSetText [[_l, 2], ["0", str ({_x == _class} count _container)] select (_class in _container)]; + }; + + [_ctrlPanel, _maxLoad] call FUNC(updateRightPanel); +}; + +// Sorting +private _sortRightCtrl = _display displayCtrl IDC_sortRightTab; +private _sortRightCurSel = lbCurSel _sortRightCtrl; + +if (lbSize _sortRightCtrl == 3) then { + _sortRightCtrl lbDelete 2; +}; + +if (_leftPanelState) then { + _sortRightCtrl lbDelete 1; + _sortRightCtrl lbAdd (localize "STR_a3_rscdisplayarsenal_sort_mod"); + _sortRightCtrl lbSetValue [1, 1]; + + _sortRightCtrl lbSetCurSel ([0, _sortRightCurSel] select (_sortRightCurSel != 2)); +} else { + _sortRightCtrl lbDelete 1; + _sortRightCtrl lbAdd localize LSTRING(sortByWeightText); + _sortRightCtrl lbSetValue [1, 1]; + + _sortRightCtrl lbAdd localize LSTRING(sortByAmountText); + _sortRightCtrl lbSetValue [2, 2]; + + _sortRightCtrl lbSetCurSel _sortRightCurSel; +}; + +[_sortRightCtrl, _sortRightCtrl lbValue (lbCurSel _sortRightCtrl)] call FUNC(sortPanel); + +// Select current data if not in a container +if !(_itemsToCheck isEqualTo []) then { + for "_lbIndex" from 0 to (lbSize _ctrlPanel - 1) do { + private _currentData = _ctrlPanel lbData _lbIndex; + + if ((_currentData != "") && {tolower _currentData in _itemsToCheck}) exitWith { + _ctrlPanel lbSetCurSel _lbIndex; + }; + }; + + if (lbCurSel _ctrlPanel < 0) then { + _ctrlPanel lbSetCurSel 0; + }; +}; diff --git a/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf b/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf new file mode 100644 index 0000000000..07a42c4fd5 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf @@ -0,0 +1,45 @@ +/* + * Author: Alganthe + * Handles keyboard inputs inside the searchbars text boxes. + * + * Arguments: + * 0: Loadouts display + * 1: Searchbar control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +private _textString = ctrlText _control; + +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; + +if !(GVAR(lastSearchTextLoadouts) isEqualTo "" || {(_textString find GVAR(lastSearchTextLoadouts)) == 0}) then {//don't refill if there is no need + [_display, _display displayCtrl GVAR(currentLoadoutsTab)] call FUNC(fillLoadoutsList); +}; + +GVAR(lastSearchTextLoadouts) = _textString; +if (count _textString == 0) exitWith {}; + +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; + +private _itemsToGo = (lnbSize _contentPanelCtrl) select 0; +private _lbIndex = 0; +while {_itemsToGo > 0} do { + private _currentData = _contentPanelCtrl lnbText [_lbIndex, 1]; + private _currentClassname = _contentPanelCtrl lnbData [_lbIndex, 0]; + + if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + _contentPanelCtrl lnbDeleteRow _lbIndex; + } else { + _lbIndex = _lbIndex + 1; + }; + _itemsToGo = _itemsToGo - 1; +}; +_contentPanelCtrl lnbSetCurSelRow -1; diff --git a/addons/arsenal/functions/fnc_handleMouse.sqf b/addons/arsenal/functions/fnc_handleMouse.sqf new file mode 100644 index 0000000000..16548f3985 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleMouse.sqf @@ -0,0 +1,73 @@ +/* + * Author: Karel Moricky, modified by Alganthe + * Update the camera position and pitch/bank. + * Modernized a bit, modified to fit the rewrite. + * + * Arguments: + * 0: Not used + * 1: Arguments + * 1.1: Mouse area control + * 1.2: Mouse X position + * 1.3: Mouse Y position + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["", "_args"]; + +_args params ["_control", "_mouseX", "_mouseY"]; +GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV", "_helperPos"]; +GVAR(mouseButtonState) params ["_LMB", "_RMB"]; + +if (count _LMB > 0) then { + _LMB params ["_LMBcursorX", "_LMBcursorY"]; + private _dX = [(_mouseX - _LMBcursorX), (_LMBcursorX - _mouseX)] select GVAR(camInverted); + private _dY = [(_mouseY -_LMBcursorY), (_LMBcursorY - _mouseY)] select GVAR(camInverted); + GVAR(mouseButtonState) set [0,[_mouseX,_mouseY]]; + + private _centerBox = boundingboxreal GVAR(center); + private _centerSizeBottom = _centerBox select 0 select 2; + private _centerSizeUp = _centerBox select 1 select 2; + private _centerSize = sqrt ([_centerBox select 0 select 0,_centerBox select 0 select 1] distance [_centerBox select 1 select 0,_centerBox select 1 select 1]); + + _helperPos = [_helperPos, _dX * _centerSize, _dirH - 90] call bis_fnc_relpos; + _helperPos = [ + [0,0,((_helperPos select 2) - _dY * _centerSize) max _centerSizeBottom min _centerSizeUp], + ([0,0,0] distance2D _helperPos) min _centerSize, + [0,0,0] getDir _helperPos + ] call bis_fnc_relpos; + + _helperPos set [2,(_helperPos select 2) max ((boundingboxreal GVAR(center) select 0 select 2) + 0.2)]; + + //--- Do not let target go below ground + private _posZmin = 0.1; + private _targetWorldPosZ = (GVAR(center) modeltoworldvisual _helperPos) select 2; + if (_targetWorldPosZ < _posZmin) then {_helperPos set [2,(_helperPos select 2) - _targetWorldPosZ + _posZmin];}; + + GVAR(cameraPosition) set [3,_helperPos]; +}; + +if (count _RMB > 0) then { + _RMB params ["_RMBcursorX", "_RMBcursorY"]; + private _dX = (_RMBcursorX - _mouseX) * 0.75; + private _dY = (_RMBcursorY - _mouseY) * 0.75; + _helperPos = [ + [0,0,_helperPos select 2], + [0,0,0] distance2D _helperPos, + ([0,0,0] getDir _helperPos) - _dX * 360 + ] call bis_fnc_relpos; + + GVAR(cameraPosition) set [1,(_dirH - _dX * 360)]; + GVAR(cameraPosition) set [2,(_dirV - _dY * 100) max -89 min 89]; + GVAR(cameraPosition) set [3,_helperPos]; + GVAR(mouseButtonState) set [1,[_mouseX,_mouseY]]; +}; + +if (!alive (GVAR(center)) || isnull GVAR(center)) then { + (ctrlParent _control) closeDisplay 2; +}; diff --git a/addons/arsenal/functions/fnc_handleScrollWheel.sqf b/addons/arsenal/functions/fnc_handleScrollWheel.sqf new file mode 100644 index 0000000000..e7dc3bbc1e --- /dev/null +++ b/addons/arsenal/functions/fnc_handleScrollWheel.sqf @@ -0,0 +1,25 @@ +/* + * Author: Alganthe + * Handle the mouse wheel. + * + * Arguments: + * 0: Not used + * 1: Mousewheel Z position + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["", "_args"]; +_args params ["", "_zPos"]; + +private _distanceMax = ((boundingboxreal GVAR(center) select 0) vectordistance (boundingboxreal GVAR(center) select 1)) * 1.5; +private _distanceMin = _distanceMax * 0.15; +private _distance = GVAR(cameraPosition) select 0; + +_distance = (_distance - (_zPos / 10)) max _distanceMin min _distanceMax; +GVAR(cameraPosition) set [0, _distance]; diff --git a/addons/arsenal/functions/fnc_handleSearchbar.sqf b/addons/arsenal/functions/fnc_handleSearchbar.sqf new file mode 100644 index 0000000000..87b03d8c57 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleSearchbar.sqf @@ -0,0 +1,92 @@ +/* + * Author: Alganthe + * Handles keyboard inputs inside the searchbars text boxes. + * + * Arguments: + * 0: Arsenal display + * 1: Searchbar control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +private _textString = ctrlText _control; + +if ((ctrlIDC _control) == IDC_rightSearchbar) then { + if !(GVAR(lastSearchTextRight) isEqualTo "" || {(_textString find GVAR(lastSearchTextRight)) == 0}) then {//don't refill if there is no need + [_display, _display displayCtrl GVAR(currentRightPanel)] call FUNC(fillRightPanel); + }; + GVAR(lastSearchTextRight) = _textString; + if (count _textString == 0) exitWith {}; + + private _rightPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]; + private _rightPanelCtrl = [_display displayCtrl IDC_rightTabContentListnBox, _display displayCtrl IDC_rightTabContent] select (_rightPanelState); + + if (_rightPanelState) then { + + private _itemsToGo = lbSize _rightPanelCtrl; + private _lbIndex = 0; + while {_itemsToGo > 0} do { + private _currentData = _rightPanelCtrl lbText _lbIndex; + private _currentClassname = _rightPanelCtrl lbData _lbIndex; + + if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + _rightPanelCtrl lbDelete _lbIndex; + } else { + _lbIndex = _lbIndex + 1; + }; + _itemsToGo = _itemsToGo - 1; + }; + _rightPanelCtrl lbSetCurSel -1; + } else { + + private _itemsToGo = (lnbSize _rightPanelCtrl) select 0; + private _lbIndex = 0; + while {_itemsToGo > 0} do { + private _currentData = _rightPanelCtrl lnbText [_lbIndex, 1]; + private _currentClassname = _rightPanelCtrl lnbData [_lbIndex, 0]; + + if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + _rightPanelCtrl lnbDeleteRow _lbIndex; + } else { + _lbIndex = _lbIndex + 1; + }; + _itemsToGo = _itemsToGo - 1; + }; + _rightPanelCtrl lnbSetCurSelRow -1; + }; + + [_display, nil, nil, configNull] call FUNC(itemInfo); +} else { + + if !(GVAR(lastSearchTextLeft) isEqualTo "" || {(_textString find GVAR(lastSearchTextLeft)) == 0}) then {//don't refill if there is no need + [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); + }; + GVAR(lastSearchTextLeft) = _textString; + if (count _textString == 0) exitWith {}; + + private _leftPanelCtrl = _display displayCtrl IDC_leftTabContent; + + + private _itemsToGo = (lbSize _leftPanelCtrl); + private _lbIndex = 0; + while {_itemsToGo > 0} do { + private _currentData = _leftPanelCtrl lbText _lbIndex; + private _currentClassname = _leftPanelCtrl lbData _lbIndex; + + if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + _leftPanelCtrl lbDelete _lbIndex; + } else { + _lbIndex = _lbIndex + 1; + }; + _itemsToGo = _itemsToGo - 1; + }; + _leftPanelCtrl lbSetCurSel -1; + [_display, nil, nil, configNull] call FUNC(itemInfo); +}; diff --git a/addons/arsenal/functions/fnc_initBox.sqf b/addons/arsenal/functions/fnc_initBox.sqf new file mode 100644 index 0000000000..adf122ddbe --- /dev/null +++ b/addons/arsenal/functions/fnc_initBox.sqf @@ -0,0 +1,61 @@ +/* + * Author: Alganthe + * Initialize a box / object for arsenal. + * + * Arguments: + * 0: Target + * 1: Items or + * 2: Initialize globally + * + * Return Value: + * None + * + * Example: + * [_box, ["MyItem1", "MyItem2", "MyItemN"]] call ace_arsenal_fnc_initBox + * [_box, true] call ace_arsenal_fnc_initBox + * + * Public: Yes +*/ +#include "script_component.hpp" + +params [["_object", objNull, [objNull]], ["_items", true, [[], true]], ["_global", true, [true]]]; + +if (isNull _object) exitWith {}; + +if (isNil QGVAR(EHIDArray)) then { + GVAR(EHIDArray) = []; +}; + +if (_global && {isMultiplayer} && {{_object in _x} count GVAR(EHIDArray) == 0}) then { + + private _ID = [QGVAR(initBox), [_object, _items, false]] call CBA_fnc_globalEventJIP; + [_ID, _object] call CBA_fnc_removeGlobalEventJIP; + + GVAR(EHIDArray) pushBack [_ID, _object]; + publicVariable QGVAR(EHIDArray); +} else { + + if ({(_x select 0) select 0 isEqualTo QGVAR(interaction)} count (_object getVariable [QEGVAR(interact_menu,actions), []]) == 0) then { + + private _action = [ + QGVAR(interaction), + localize "STR_A3_Arsenal", + "", + { + params ["_target", "_player"]; + + [_target, _player] call FUNC(openBox); + }, + { + params ["_target", "_player"]; + + [_player, _target, ["isNotSwimming", "isNotCarrying", "isNotDragging", "notOnMap", "isNotEscorting", "isNotOnLadder"]] call EFUNC(common,canInteractWith) + }, + {}, + [] + ] call EFUNC(interact_menu,createAction); + [_object, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); + + [_object, _items, false] call FUNC(addVirtualItems); + }; +}; diff --git a/addons/arsenal/functions/fnc_itemInfo.sqf b/addons/arsenal/functions/fnc_itemInfo.sqf new file mode 100644 index 0000000000..9dcfe2ea86 --- /dev/null +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -0,0 +1,75 @@ +/* + * Author: Alganthe + * Update arsenal's info box. + * + * Arguments: + * 0: Arsenal display + * 1: Current panel control + * 2: Current panel selection + * 3: Item config entry + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control", "_curSel" ,"_itemCfg"]; + +private _ctrlInfo = _display displayCtrl IDC_infoBox; + +if (isClass _itemCfg) then { + + _ctrlInfo ctrlSetFade 0; + _ctrlInfo ctrlCommit FADE_DELAY; + + // Name + author + private _ctrlInfoName = _display displayCtrl IDC_infoName; + _ctrlInfoName ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == 102)); + + private _ctrlInfoAuthor = _display displayctrl IDC_infoAuthor; + _ctrlInfoAuthor ctrlSetText ""; + + private _itemAuthor = getText (_itemCfg >> "author"); + _ctrlInfoAuthor ctrlSetText ([localize "STR_AUTHOR_UNKNOWN", format [localize "STR_FORMAT_AUTHOR_SCRIPTED",_itemAuthor]] select (_itemAuthor != "")); + + // DLC / mod icon + private _ctrlDLC = _display displayctrl IDC_DLCIcon; + private _ctrlDLCBackground = _display displayctrl IDC_DLCBackground; + private _dlc = _itemCfg call GETDLC; + if (_dlc != "") then { + + private _dlcParams = modParams [_dlc, ["name", "logo", "logoOver"]]; + _dlcParams params ["_name", "_logo", "_logoOver"]; + private _appId = getnumber (configfile >> "CfgMods" >> _dlc >> "appId"); + + _ctrlDLC ctrlsettooltip _name; + _ctrlDLC ctrlsettext _logo; + _ctrlDLCBackground ctrlsetfade 0; + _ctrlDLC ctrlsetfade 0; + if (_appId > 0) then { + _ctrlDLC ctrlseteventhandler ["mouseexit",format ["(_this select 0) ctrlsettext '%1';",_logo]]; + _ctrlDLC ctrlseteventhandler ["mouseenter",format ["(_this select 0) ctrlsettext '%1';",_logoOver]]; + _ctrlDLC ctrlseteventhandler [ + "buttonclick", + format ["uiNamespace setvariable ['RscDisplayDLCPreview_dlc','%1']; ctrlparent (_this select 0) createDisplay 'RscDisplayDLCPreview';", _dlc] + ]; + } else { + _ctrlDLC ctrlRemoveAllEventHandlers "buttonclick"; + _ctrlDLC ctrlRemoveAllEventHandlers "mouseexit"; + _ctrlDLC ctrlRemoveAllEventHandlers "mouseenter"; + }; + } else { + _ctrlDLC ctrlsetfade 1; + _ctrlDLCBackground ctrlsetfade 1; + }; + + _ctrlDLC ctrlcommit 0; + _ctrlDLCBackground ctrlcommit 0; + +} else { + _ctrlInfo ctrlSetFade 1; + _ctrlInfo ctrlCommit FADE_DELAY; +}; diff --git a/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf new file mode 100644 index 0000000000..7842df8704 --- /dev/null +++ b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf @@ -0,0 +1,77 @@ +/* + * Author: Alganthe + * Handles tab changing for the loadouts display. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control"]; + +if !(ctrlEnabled _control || {GVAR(currentLoadoutsTab) == ctrlIDC _control}) exitWith {}; + +private _centerBoxTitleCtrl = _display displayCtrl IDC_centerTitle; +private _shareButtonCtrl = _display displayCtrl IDC_buttonShare; +private _saveButtonCtrl = _display displayCtrl IDC_buttonSave; +private _loadButtonCtrl = _display displayCtrl IDC_buttonLoad; +private _deleteButtonCtrl = _display displayCtrl IDC_buttonDelete; +private _renameButtonCtrl = _display displayCtrl IDC_buttonRename; + +// Update UI visual elements +if (GVAR(currentLoadoutsTab) != -1) then { + + private _previousCtrlBackground = _display displayCtrl (GVAR(currentLoadoutsTab) - 1); + _previousCtrlBackground ctrlSetBackgroundColor [0, 0, 0, 0.8]; + _previousCtrlBackground ctrlCommit 0; + + private _previousCtrl = _display displayCtrl GVAR(currentLoadoutsTab); + _previousCtrl ctrlSetTextColor [1, 1, 1, 1]; + _previousCtrl ctrlCommit 0; +}; + +private _ctrlBackground = _display displayCtrl ((ctrlIDC _control) - 1); +_ctrlBackground ctrlSetBackgroundColor [1, 1, 1, 0.8]; +_ctrlBackground ctrlCommit 0; + +_control ctrlSetTextColor [0, 0, 0, 1]; +_control ctrlCommit 0; + +switch (ctrlIDC _control) do { + case IDC_buttonMyLoadouts: { + _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabMyLoadoutsText)); + + _saveButtonCtrl ctrlEnable true; + _saveButtonCtrl ctrlCommit 0; + }; + + case IDC_buttonDefaultLoadouts: { + _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabDefaultLoadoutsText)); + + _saveButtonCtrl ctrlEnable (is3DEN); + _saveButtonCtrl ctrlCommit 0; + }; + + case IDC_buttonSharedLoadouts: { + _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabSharedLoadoutsText)); + + _saveButtonCtrl ctrlEnable false; + _saveButtonCtrl ctrlCommit 0; + }; +}; + +{ + _x ctrlEnable false; + _x ctrlCommit 0; +} foreach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; + +GVAR(currentLoadoutsTab) = ctrlIDC _control; + +[_display, _control] call FUNC(fillLoadoutsList); diff --git a/addons/arsenal/functions/fnc_message.sqf b/addons/arsenal/functions/fnc_message.sqf new file mode 100644 index 0000000000..92f922d7f9 --- /dev/null +++ b/addons/arsenal/functions/fnc_message.sqf @@ -0,0 +1,54 @@ +/* + * Author: Alganthe + * Displays messages in arsenal. + * + * Arguments: + * 0: Arsenal display + * 1: Message + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_message"]; + +private _messageBoxCtrl = _display displayCtrl IDC_message; +private _handle = _messageBoxCtrl getVariable QGVAR(messageBoxHandle); + +if !(isNil "_handle") then { + terminate _handle; +}; + +_handle = [_display, _messageBoxCtrl, time + 5, _message, FADE_DELAY] spawn { + disableSerialization; + + _this params ["_display", "_control", "_timer", "_message", "_delay"]; + + while {_timer >= time} do { + switch true do { + case (_display isEqualTo displayNull): { + terminate _thisScript; + }; + + case (round (_timer - time) == 5): { + _control ctrlSetText _message; + _control ctrlSetFade 1; + _control ctrlCommit 0; + + _control ctrlSetFade 0; + _control ctrlCommit _delay; + }; + }; + + uiSleep 1; + }; + + _control ctrlSetFade 1; + _control ctrlCommit _delay; + terminate _thisScript; +}; +_messageBoxCtrl setVariable [QGVAR(messageBoxHandle), _handle]; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf new file mode 100644 index 0000000000..f9d2e2f2c5 --- /dev/null +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -0,0 +1,103 @@ +/* + * Author: Alganthe + * onUnLoad EH for arsenal. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" + +(_this select 1) params ["", "_exitCode"]; + +GVAR(camera) cameraEffect ["terminate", "back"]; +private _cameraData = [getposAtl GVAR(camera), (getposAtl GVAR(camera)) vectorFromTo (getposAtl GVAR(cameraHelper))]; + +[QGVAR(displayClosed), []] call CBA_fnc_localEvent; + +removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; + +GVAR(camera) cameraEffect ["terminate","back"]; +player switchCamera GVAR(cameraView); + +deleteVehicle GVAR(cameraHelper); +camDestroy GVAR(camera); + +if (is3DEN) then { + + private _centerOriginParent = objectParent GVAR(centerOrigin); + + if !(isNull _centerOriginParent) then { + _centerOriginParent hideObject false; + }; + + GVAR(centerOrigin) hideObject false; + + // Apply the loadout from the dummy to all selected units + if (_exitCode == 1) then { + { + _x setUnitLoadout (getUnitLoadout GVAR(center)); + } foreach (get3DENSelected "object"); + + save3DENInventory (get3DENSelected "object"); + }; + + deleteVehicle GVAR(light); + deleteVehicle GVAR(center); + + GVAR(centerOrigin) = nil; + GVAR(light) = nil; + + get3DENCamera cameraEffect ["internal","back"]; + ["ShowInterface",true] call bis_fnc_3DENInterface; + GVAR(visionMode) call bis_fnc_3DENVisionMode; +} else { + // Select correct weapon + switch GVAR(selectedWeaponType) do { + case 0: {GVAR(center) selectWeapon primaryWeapon GVAR(center);}; + case 1: {GVAR(center) selectWeapon secondaryWeapon GVAR(center);}; + case 2: {GVAR(center) selectWeapon handgunWeapon GVAR(center);}; + }; +}; + +if (isMultiplayer) then { + + [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(center) + "_face"] call CBA_fnc_globalEventJIP; + [QGVAR(center) + "_face", GVAR(center)] call CBA_fnc_removeGlobalEventJIP; + + [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(center) + "_voice"] call CBA_fnc_globalEventJIP; + [QGVAR(center) + "_voice", GVAR(center)] call CBA_fnc_removeGlobalEventJIP; +}; + +if !(isnull curatorCamera) then { + curatorcamera cameraEffect ["internal","back"]; +}; + +GVAR(camera) = nil; +GVAR(cameraHelper) = nil; + +GVAR(mouseButtonState) = nil; +GVAR(currentLeftPanel) = nil; +GVAR(currentRightPanel) = nil; +GVAR(leftSearchbarFocus) = nil; +GVAR(rightSearchbarFocus) = nil; +GVAR(shiftState) = nil; +GVAR(leftTabFocus) = nil; +GVAR(rightTabFocus) = nil; +GVAR(rightTabLnBFocus) = nil; + +GVAR(selectedWeaponType) = nil; +GVAR(virtualItems) = nil; +GVAR(currentItems) = nil; +GVAR(currentFace) = nil; +GVAR(currentVoice) = nil; +GVAR(currentInsignia) = nil; +GVAR(currentAction) = nil; + +GVAR(center) = nil; + +showHUD true; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf new file mode 100644 index 0000000000..c5d1cc0104 --- /dev/null +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -0,0 +1,308 @@ +/* + * Author: Alganthe + * onLoad EH for arsenal. + * + * Arguments: + * 0: Ignored + * 1: Arguments + * 1.1: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["", "_args"]; +_args params ["_display"]; + +//--------------- General vars +if (isNil QGVAR(center)) then { + GVAR(center) = player; +}; + +GVAR(mouseButtonState) = [[],[]]; + +if (isNil QGVAR(sharedLoadoutsNamespace)) then { + GVAR(sharedLoadoutsNamespace) = true call CBA_fnc_createNamespace; + publicVariable QGVAR(sharedLoadoutsNamespace); +}; + +if (isNil {GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars)}) then { + GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), [], true]; +}; + +if (isNil QGVAR(defaultLoadoutsList)) then { + if (is3DEN) then { + GVAR(defaultLoadoutsList) = (QGVAR(DummyCategory) get3DENMissionAttribute QGVAR(DefaultLoadoutsListAttribute)); + } else { + GVAR(defaultLoadoutsList) = []; + }; +}; + +if (isNil QGVAR(virtualItems)) then { + GVAR(virtualItems) = [[[], [], []], [[], [], [], []], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]; +}; + +GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; + +GVAR(currentFace) = face GVAR(center); +GVAR(currentVoice) = speaker GVAR(center); +GVAR(currentInsignia) = GVAR(center) param [0, objNull, [objNull]] getVariable ["BIS_fnc_setUnitInsignia_class", ""]; + +GVAR(currentAction) = "Stand"; +GVAR(shiftState) = false; + +// Add the items the player has to virtualItems +for "_index" from 0 to 10 do { + switch (_index) do { + // primary, secondary, handgun weapons + case 0: { + private _array = LIST_DEFAULTS select _index; + + if !((_array select 0) isEqualTo "") then { + ((GVAR(virtualItems) select _index) select 0) pushBackUnique (_array select 0); + }; + + if !((_array select 1) isEqualTo "") then { + ((GVAR(virtualItems) select _index) select 1) pushBackUnique (_array select 1); + }; + + if !((_array select 2) isEqualTo "") then { + ((GVAR(virtualItems) select _index) select 2) pushBackUnique (_array select 2); + }; + }; + + // Accs for the weapons above + case 1: { + private _array = LIST_DEFAULTS select _index; + _array params ["_accsArray", "_magsArray"]; + + { + private _subIndex = _forEachIndex; + + { + if (_x != "") then { + (GVAR(virtualItems) select _index) select ([2, 1, 0, 3] select _forEachIndex) pushBackUnique _x; + }; + } foreach _x; + } foreach _accsArray; + + { + if !(_x isEqualTo []) then { + + if (_x select 0 != "") then { + (GVAR(virtualItems) select 2) pushBackUnique (_x select 0); + }; + + if (count _x > 1 && {_x select 1 != ""}) then { + (GVAR(virtualItems) select 2) pushBackUnique (_x select 1); + }; + }; + } foreach _magsArray; + }; + + // Inventory items + case 2: { + call FUNC(updateUniqueItemsList); + }; + + // The rest + default { + private _array = (LIST_DEFAULTS select _index) select {!(_x isEqualTo "")}; + if !(_array isEqualTo []) then { + {(GVAR(virtualItems) select _index) pushBackUnique _x} foreach _array; + }; + }; + }; +}; + +// Fill current items +for "_index" from 0 to 15 do { + switch (_index) do { + case 0; + case 1; + case 2:{ + GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; + }; + case 3; + case 4; + case 5; + case 6; + case 7; + case 8; + case 9: { + GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; + + }; + case 10: { + {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); + }; + case 11: { + {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); + }; + case 12: { + {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); + }; + case 13: { + GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; + }; + case 14: { + GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; + }; + case 15: { + GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; + }; + }; +}; + +{ + private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); + private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch", "itemgps"] find (tolower _simulationType)); + + GVAR(currentItems) set [_index, _x]; +} foreach (assignedItems GVAR(center)); + +GVAR(currentWeaponType) = switch true do { + case (currentWeapon GVAR(center) == GVAR(currentItems) select 0): {0}; + case (currentWeapon GVAR(center) == GVAR(currentItems) select 1): {1}; + case (currentWeapon GVAR(center) == GVAR(currentItems) select 2): {2}; + default {-1}; +}; + +[QGVAR(displayOpened), []] call CBA_fnc_localEvent; + +//--------------- Fade out unused elements +private _mouseBlockCtrl = _display displayCtrl IDC_mouseBlock; +_mouseBlockCtrl ctrlEnable false; + +{ + _x = _display displayCtrl _x; + + _x ctrlSetFade 1; + _x ctrlShow false; + _x ctrlCommit 0; +} foreach [ + IDC_blockRightFrame, + IDC_blockRighttBackground, + IDC_loadIndicator, + IDC_rightTabContent, + IDC_rightTabContentListnBox, + IDC_sortRightTab, + RIGHT_PANEL_ACC_BACKGROUND_IDCS, + RIGHT_PANEL_ACC_IDCS, + RIGHT_PANEL_ITEMS_BACKGROUND_IDCS, + RIGHT_PANEL_ITEMS_IDCS, + IDC_buttonRemoveAll, + IDC_rightSearchbar +]; + +if (isMultiplayer) then { + private _importButtonCtrl = _display displayCtrl IDC_buttonImport; + _importButtonCtrl ctrlEnable false; + _importButtonCtrl ctrlSetFade 0.6; + _importButtonCtrl ctrlCommit 0; +}; + +//--------------- Camera prep +cutText ["","plain"]; +showCommandingMenu ""; + +GVAR(cameraView) = cameraView; +GVAR(center) switchCamera "internal"; +showHUD false; + +private _mouseAreaCtrl = _display displayCtrl IDC_mouseArea; +ctrlSetFocus _mouseAreaCtrl; + +// 3DEN support, lifted from BIS_fnc_arsenal +if (is3DEN) then { + + GVAR(centerOrigin) = GVAR(center); + GVAR(centerOrigin) hideObject true; + + private _centerOriginParent = objectParent GVAR(centerOrigin); + if !(isNull _centerOriginParent) then { + _centerOriginParent hideObject true; + }; + + private _centerPos = position GVAR(centerOrigin); + + GVAR(center) = createAgent [typeOf GVAR(centerOrigin), position GVAR(centerOrigin), [], 0, "none"]; + GVAR(center) setPosAtl getPosAtl GVAR(centerOrigin); + GVAR(center) setDir (getDir GVAR(centerOrigin)); + GVAR(center) switchMove animationState GVAR(centerOrigin); + GVAR(center) switchAction "playerstand"; + GVAR(center) enableSimulation false; + + GVAR(center) setUnitLoadout (getUnitLoadout GVAR(centerOrigin)); + GVAR(center) setFace GVAR(currentFace); + GVAR(center) setSpeaker GVAR(currentVoice); + + //--- Create light for night editing (code based on BIS_fnc_3DENFlashlight) + private _intensity = 1; + GVAR(light) = "#lightpoint" createVehicle _centerPos; + GVAR(light) setLightBrightness _intensity; + GVAR(light) setLightAmbient [1,1,1]; + GVAR(light) setLightColor [0,0,0]; + GVAR(light) lightAttachObject [GVAR(centerOrigin), [0, 0, -_intensity * 7]]; + + //--- Use the same vision mode as in Eden + GVAR(visionMode)= -2 call bis_fnc_3DENVisionMode; + ["ShowInterface",false] spawn bis_fnc_3DENInterface; + if (get3denactionstate "togglemap" > 0) then {do3DENAction "togglemap";}; + + { + private _ctrl = _display displayctrl _x; + _ctrl ctrlEnable false; + _ctrl ctrlSetFade 0.6; + _ctrl ctrlcommit 0; + } foreach [ + IDC_buttonFace, + IDC_buttonVoice, + IDC_buttonInsigna + ]; + + _buttonCloseCtrl = _display displayCtrl IDC_menuBarClose; + _buttonCloseCtrl ctrlSetText (localize "str_ui_debug_but_apply"); +}; + +//--------------- Prepare the left panel +GVAR(currentLeftPanel) = nil; +GVAR(currentRightPanel) = nil; +GVAR(leftSearchbarFocus) = false; +GVAR(rightSearchbarFocus) = false; +GVAR(leftTabFocus) = false; +GVAR(rightTabFocus) = false; +GVAR(rightTabLnBFocus) = false; + +{ + private _panel = _display displayCtrl _x; + _panel ctrlSetFontHeight (GVAR(fontHeight) * GRID_H); + _panel ctrlCommit 0; +} foreach [IDC_leftTabContent, IDC_rightTabContent, IDC_rightTabContentListnBox]; + +[_display, _display displayCtrl IDC_buttonPrimaryWeapon] call FUNC(fillLeftPanel); + +//--------------- Init camera +if (isNil QGVAR(cameraPosition)) then { + GVAR(cameraPosition) = [5,0,0,[0,0,0.85]]; +}; + +GVAR(cameraHelper) = createAgent ["Logic", position GVAR(center) ,[] ,0 ,"none"]; +GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; + +GVAR(camera) = "camera" camCreate position GVAR(center); +GVAR(camera) cameraEffect ["internal","back"]; +GVAR(camera) camPrepareFocus [-1,-1]; +GVAR(camera) camPrepareFov 0.35; +GVAR(camera) camCommitPrepared 0; + +showCinemaBorder false; +["#(argb,8,8,3)color(0,0,0,1)",false,nil,0,[0,0.5]] call bis_fnc_textTiles; + +//--------------- Reset camera pos +[nil, [controlNull,0,0]] call FUNC(handleMouse); +GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D",{ [] call FUNC(updateCamPos) }]; diff --git a/addons/arsenal/functions/fnc_onKeyDown.sqf b/addons/arsenal/functions/fnc_onKeyDown.sqf new file mode 100644 index 0000000000..b963974033 --- /dev/null +++ b/addons/arsenal/functions/fnc_onKeyDown.sqf @@ -0,0 +1,188 @@ +/* + * Author: Alganthe + * Handles keyboard inputs in arsenal. + * + * Arguments: + * 0: Arsenal display + * 1: Key being pressed + * 2: Shift state + * 3: Ctrl state + * 4: Alt state + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" + +params ["", "_args"]; +_args params ["_display", "_keyPressed", "_shiftState", "_ctrlState", "_altState"]; + +GVAR(shiftState) = _shiftState; +private _return = true; +private _loadoutsDisplay = findDisplay IDD_loadouts_display; + +if !(_loadoutsDisplay isEqualTo displayNull) then { + if !(GVAR(loadoutsSearchbarFocus)) then { + switch true do { + // Close button + case (_keyPressed == DIK_ESCAPE): { + _display closeDisplay 2; + }; + // Search field + case (_keyPressed == DIK_F && {_ctrlState}): { + ctrlSetFocus (_loadoutsDisplay displayCtrl IDC_loadoutsSearchbar); + }; + }; + } else { + switch true do { + case (_keyPressed == DIK_ESCAPE): { + _display closeDisplay 2; + }; + case (_keyPressed == DIK_BACKSPACE): { + _return = false; + }; + case (_keyPressed == DIK_NUMPADENTER); + case (_keyPressed == DIK_RETURN): { + [_loadoutsDisplay, _loadoutsDisplay displayCtrl IDC_loadoutsSearchbar] call FUNC(handleLoadoutsSearchBar); + }; + case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { + _return = false; + }; + }; + }; + + switch true do { + case (_keyPressed == DIK_C && {_ctrlState}): { + _return = false; + }; + case (_keyPressed == DIK_V && {_ctrlState}): { + _return = false; + }; + case (_keyPressed == DIK_A && {_ctrlState}): { + _return = false; + }; + case (_keyPressed == DIK_X && {_ctrlState}): { + _return = false; + }; + case (GVAR(loadoutsPanelFocus) && {_keyPressed in [DIK_UP, DIK_DOWN]}): { + _return = false; + }; + }; +} else { + + if (!GVAR(leftSearchbarFocus) && {!GVAR(rightSearchbarFocus)}) then { + + switch true do { + // Close button + case (_keyPressed == DIK_ESCAPE): { + _display closeDisplay 2; + }; + // Hide button + case (_keyPressed == DIK_BACKSPACE): { + [_display] call FUNC(buttonHide); + }; + // Export button + case (_keyPressed == DIK_C && {_ctrlState}): { + [_display] call FUNC(buttonExport); + }; + // Import button + case (_keyPressed == DIK_V && {_ctrlState}): { + [_display] call FUNC(buttonImport); + }; + // Search fields + case (_keyPressed == DIK_F && {_ctrlState}): { + ctrlSetFocus (_display displayCtrl IDC_leftSearchbar); + }; + // Switch vision mode + case (_keyPressed in (actionkeys "nightvision")): { + if (isNil QGVAR(visionMode)) then { + GVAR(visionMode) = 0; + }; + GVAR(visionMode) = (GVAR(visionMode) + 1) % 3; + + switch GVAR(visionMode) do { + //--- Normal + case 0: { + camusenvg false; + false setCamUseTi 0; + }; + //--- NVG + case 1: { + camusenvg true; + false setCamUseTi 0; + }; + //--- TI + default { + camusenvg false; + true setCamUseTi 0; + }; + }; + + playsound ["RscDisplayCurator_visionMode",true]; + }; + }; + } else { + switch true do { + case (_keyPressed == DIK_ESCAPE): { + _display closeDisplay 2; + }; + case (_keyPressed == DIK_BACKSPACE): { + _return = false; + }; + case (_keyPressed == DIK_NUMPADENTER); + case (_keyPressed == DIK_RETURN): { + if (GVAR(leftSearchbarFocus)) then { + [_display, _display displayCtrl IDC_leftSearchbar] call FUNC(handleSearchBar); + }; + if (GVAR(rightSearchbarFocus)) then { + [_display, _display displayCtrl IDC_rightSearchbar] call FUNC(handleSearchBar); + }; + }; + case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { + _return = false; + }; + case (_keyPressed == DIK_C && {_ctrlState}): { + _return = false; + }; + case (_keyPressed == DIK_V && {_ctrlState}): { + _return = false; + }; + case (_keyPressed == DIK_A && {_ctrlState}): { + _return = false; + }; + case (_keyPressed == DIK_X && {_ctrlState}): { + _return = false; + }; + // Search fields + case (_keyPressed == DIK_F && {_ctrlState}): { + if (GVAR(rightSearchbarFocus)) then { + ctrlSetFocus (_display displayCtrl IDC_leftSearchbar); + } else { + ctrlSetFocus (_display displayCtrl IDC_rightSearchbar); + }; + }; + }; + }; + + if (GVAR(leftTabFocus) && {_keyPressed in [DIK_UP, DIK_DOWN]}) then { + _return = false; + }; + + if (GVAR(rightTabFocus) && {_keyPressed in [DIK_UP, DIK_DOWN]}) then { + _return = false; + }; + + if (GVAR(rightTabLnBFocus) && {_keyPressed in [DIK_UP, DIK_DOWN]}) then { + _return = false; + }; + + if (GVAR(rightTabLnBFocus) && {_keyPressed in [DIK_LEFT, DIK_RIGHT]}) then { + [_display, [1, 0] select (_keyPressed == DIK_LEFT)] call FUNC(buttonCargo); + }; +}; + +_return diff --git a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf new file mode 100644 index 0000000000..777af3aed1 --- /dev/null +++ b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf @@ -0,0 +1,31 @@ +/* + * Author: Alganthe + * onUnLoad EH for arsenal loadouts display. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +GVAR(currentLoadoutsTab) = nil; + +private _arsenalDisplay = findDisplay IDD_ace_arsenal; +private _mouseBlockCtrl = _arsenalDisplay displayCtrl IDC_mouseBlock; + +GVAR(cameraPosition) = GVAR(previousCameraPos); +GVAR(previousCameraPos) = nil; +GVAR(loadoutsSearchbarFocus) = nil; +GVAR(loadoutsPanelFocus) = nil; + +_mouseBlockCtrl ctrlEnable false; +_mouseBlockCtrl ctrlCommit 0; + +[_arsenalDisplay] call FUNC(buttonHide); + +[_arsenalDisplay , _arsenalDisplay displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf new file mode 100644 index 0000000000..ec025b0bc1 --- /dev/null +++ b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf @@ -0,0 +1,60 @@ +/* + * Author: Alganthe + * onLoad EH for arsenal loadouts display. + * + * Arguments: + * 0: Ignored + * 1: Arguments + * 1.1: Loadouts display + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["", "_args"]; +_args params ["_display"]; + +private _arsenalDisplay = findDisplay IDD_ace_arsenal; +private _mouseBlockCtrl = _arsenalDisplay displayCtrl IDC_mouseBlock; + +_mouseBlockCtrl ctrlEnable true; +_mouseBlockCtrl ctrlCommit 0; + +[_arsenalDisplay] call FUNC(buttonHide); + +GVAR(currentLoadoutsTab) = -1; +GVAR(loadoutsSearchbarFocus) = false; +GVAR(loadoutsPanelFocus) = false; + +GVAR(previousCameraPos) = GVAR(cameraPosition); +GVAR(cameraPosition) = [5,0,20,[-0.85,0,0.85]]; + +private _panelContentCtrl = _display displayCtrl IDC_contentPanel; +_panelContentCtrl ctrlSetFontHeight (4.5 * GRID_H); +_panelContentCtrl ctrlCommit 0; + +if !(GVAR(allowDefaultLoadouts)) then { + private _buttonDefaultLoadoutsCtrl = _display displayCtrl IDC_buttonDefaultLoadouts; + _buttonDefaultLoadoutsCtrl ctrlEnable false; + _buttonDefaultLoadoutsCtrl ctrlCommit 0; + + private _buttonDefaultLoadoutsBackgroundCtrl = _display displayCtrl IDC_buttonDefaultLoadoutsBackground; + _buttonDefaultLoadoutsBackgroundCtrl ctrlShow false; + _buttonDefaultLoadoutsBackgroundCtrl ctrlCommit 0; +}; + +if !(GVAR(allowSharedLoadouts) && {isMultiplayer}) then { + private _buttonShareLoadoutsCtrl = _display displayCtrl IDC_buttonSharedLoadouts; + _buttonShareLoadoutsCtrl ctrlEnable false; + _buttonShareLoadoutsCtrl ctrlCommit 0; + + private _buttonShareLoadoutsBackgroundCtrl = _display displayCtrl IDC_buttonSharedLoadoutsBackground; + _buttonShareLoadoutsBackgroundCtrl ctrlShow false; + _buttonShareLoadoutsBackgroundCtrl ctrlCommit 0; +}; + +[_display, _display displayCtrl IDC_buttonMyLoadouts] call FUNC(loadoutsChangeTab); diff --git a/addons/arsenal/functions/fnc_onMouseButtonDown.sqf b/addons/arsenal/functions/fnc_onMouseButtonDown.sqf new file mode 100644 index 0000000000..0cb2c856a4 --- /dev/null +++ b/addons/arsenal/functions/fnc_onMouseButtonDown.sqf @@ -0,0 +1,6 @@ +#include "script_component.hpp" + +params ["", "_args"]; +_args params ["", "_buttonPressed", "_xPos", "_yPos"]; + +GVAR(mouseButtonState) set [_buttonPressed, [_xPos, _yPos]]; diff --git a/addons/arsenal/functions/fnc_onMouseButtonUp.sqf b/addons/arsenal/functions/fnc_onMouseButtonUp.sqf new file mode 100644 index 0000000000..53848a4f8e --- /dev/null +++ b/addons/arsenal/functions/fnc_onMouseButtonUp.sqf @@ -0,0 +1,6 @@ +#include "script_component.hpp" + +params ["", "_args"]; +_args params ["", "_buttonPressed"]; + +GVAR(mouseButtonState) set [_buttonPressed, []]; diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf new file mode 100644 index 0000000000..5c4d49b5d1 --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -0,0 +1,413 @@ +/* + * Author: Alganthe + * Handles selection changes on the left panel. + * + * Arguments: + * 0: Left panel control + * 1: Left panel selection + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_control", "_curSel"]; + +if (_curSel < 0) exitwith {}; + +private _ctrlIDC = ctrlIDC _control; +private _display = ctrlParent _control; +private _item = [_control lnbData [_curSel, 0], _control lbData _curSel] select !(ctrlType _control == 102); + +private _weaponDefaultRightPanel = _display displayCtrl IDC_buttonOptic; +private _selectCorrectPanelWeapon = [_weaponDefaultRightPanel, _display displayCtrl GVAR(currentRightPanel)] select (!(isNil QGVAR(currentRightPanel)) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}); + +private _containerDefaultRightPanel = _display displayCtrl IDC_buttonMisc; +private _selectCorrectPanelContainer = [_containerDefaultRightPanel, _display displayCtrl GVAR(currentRightPanel)] select (!(isNil QGVAR(currentRightPanel)) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ITEMS_IDCS]}); + +switch (GVAR(currentLeftPanel)) do { + + case IDC_buttonPrimaryWeapon : { + private _baseWeapon = ((GVAR(currentItems) select 0) call bis_fnc_baseWeapon); + + if ((GVAR(currentItems) select 0) != _item && {_baseWeapon != _item}) then { + + private _compatibleMags = getArray (configfile >> "cfgweapons" >> _baseWeapon >> "magazines"); + { + GVAR(center) removeMagazines _x; + } foreach _compatibleMags; + + GVAR(currentItems) set [15, uniformItems GVAR(center)]; + GVAR(currentItems) set [16, vestItems GVAR(center)]; + GVAR(currentItems) set [17, backpackItems GVAR(center)]; + + if (_item == "") then { + + GVAR(center) removeWeapon (primaryWeapon GVAR(center)); + GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [0, _item]; + } else { + + private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; + GVAR(center) addWeapon _item; + GVAR(center) addWeaponItem [_item, [(getArray (configfile >> "cfgweapons" >> _item >> "magazines")) select 0]]; + + { + if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { + GVAR(center) addPrimaryWeaponItem _x; + }; + } foreach (GVAR(currentItems) select 18); + + private _primaryMags = primaryWeaponMagazine GVAR(center); + GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; + GVAR(currentItems) set [0, _item]; + }; + }; + + if (_item == "") then { + TOGGLE_RIGHT_PANEL_HIDE + } else { + TOGGLE_RIGHT_PANEL_WEAPON + [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); + }; + + call FUNC(showItem); + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonHandgun : { + private _baseWeapon = ((GVAR(currentItems) select 2) call bis_fnc_baseWeapon); + + if ((GVAR(currentItems) select 2) != _item && {_baseWeapon != _item}) then { + + private _compatibleMags = getArray (configfile >> "cfgweapons" >> _baseWeapon >> "magazines"); + { + GVAR(center) removeMagazines _x; + } foreach _compatibleMags; + + GVAR(currentItems) set [15, uniformItems GVAR(center)]; + GVAR(currentItems) set [16, vestItems GVAR(center)]; + GVAR(currentItems) set [17, backpackItems GVAR(center)]; + + if (_item == "") then { + + GVAR(center) removeWeapon (handgunWeapon GVAR(center)); + GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [2, _item]; + } else { + + private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; + GVAR(center) addWeapon _item; + GVAR(center) addWeaponItem [_item, [(getArray (configfile >> "cfgweapons" >> _item >> "magazines")) select 0]]; + + { + if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { + GVAR(center) addHandgunItem _x; + }; + } foreach (GVAR(currentItems) select 20); + + private _handgunMags = handgunMagazine GVAR(center); + GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; + GVAR(currentItems) set [2, _item]; + }; + }; + + if (_item == "") then { + TOGGLE_RIGHT_PANEL_HIDE + } else { + TOGGLE_RIGHT_PANEL_WEAPON + [_display, [_selectCorrectPanelWeapon, _weaponDefaultRightPanel] select (GVAR(currentRightPanel) == IDC_buttonCurrentMag2)] call FUNC(fillRightPanel); + }; + + call FUNC(showItem); + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonSecondaryWeapon : { + private _baseWeapon = ((GVAR(currentItems) select 1) call bis_fnc_baseWeapon); + + if ((GVAR(currentItems) select 1) != _item && {_baseWeapon != _item}) then { + + private _compatibleMags = getArray (configfile >> "cfgweapons" >> _baseWeapon >> "magazines"); + { + GVAR(center) removeMagazines _x; + } foreach _compatibleMags; + + GVAR(currentItems) set [15, uniformItems GVAR(center)]; + GVAR(currentItems) set [16, vestItems GVAR(center)]; + GVAR(currentItems) set [17, backpackItems GVAR(center)]; + + if (_item == "") then { + + GVAR(center) removeWeapon (secondaryWeapon GVAR(center)); + GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [1, _item]; + } else { + + private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; + GVAR(center) addWeapon _item; + GVAR(center) addWeaponItem [_item, [(getArray (configfile >> "cfgweapons" >> _item >> "magazines")) select 0]]; + + { + if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { + GVAR(center) addSecondaryWeaponItem _x; + }; + } foreach (GVAR(currentItems) select 19); + + private _secondaryMags = secondaryWeaponMagazine GVAR(center); + GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; + GVAR(currentItems) set [1, _item]; + }; + }; + + if (_item == "") then { + TOGGLE_RIGHT_PANEL_HIDE + } else { + TOGGLE_RIGHT_PANEL_WEAPON + [_display, [_selectCorrectPanelWeapon, _weaponDefaultRightPanel] select (GVAR(currentRightPanel) == IDC_buttonCurrentMag2)] call FUNC(fillRightPanel); + }; + + call FUNC(showItem); + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonHeadgear : { + if (_item == "") then { + removeHeadgear GVAR(center); + GVAR(currentItems) set [3, _item]; + } else { + GVAR(center) addHeadgear _item; + GVAR(currentItems) set [3, _item]; + }; + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonUniform : { + if (_item == "") then { + + removeuniform GVAR(center); + GVAR(currentItems) set [15, []]; + GVAR(currentItems) set [4, _item]; + TOGGLE_RIGHT_PANEL_HIDE + } else { + + GVAR(center) forceAddUniform _item; + + while {count uniformItems GVAR(center) > 0} do { + GVAR(center) removeItemFromUniform (uniformItems GVAR(center) select 0); + }; //--- Remove default config contents + + {GVAR(center) addItemtoUniform _x} foreach (GVAR(currentItems) select 15); + GVAR(currentItems) set [4, _item]; + + [GVAR(center), ""] call bis_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + + TOGGLE_RIGHT_PANEL_CONTAINER + [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); + }; + + call FUNC(showItem); + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonVest: { + if (_item == "") then { + + removeVest GVAR(center); + GVAR(currentItems) set [16, []]; + GVAR(currentItems) set [5, _item]; + TOGGLE_RIGHT_PANEL_HIDE + } else { + + GVAR(center) addVest _item; + while {count vestItems GVAR(center) > 0} do { + GVAR(center) removeItemFromVest (VestItems GVAR(center) select 0); + }; //--- Remove default config contents + {GVAR(center) addItemToVest _x} foreach (GVAR(currentItems) select 16); + + GVAR(currentItems) set [5, _item]; + + TOGGLE_RIGHT_PANEL_CONTAINER + [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); + }; + + call FUNC(showItem); + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonBackpack : { + if (_item == "") then { + + removeBackpack GVAR(center); + GVAR(currentItems) set [17, []]; + GVAR(currentItems) set [6, _item]; + TOGGLE_RIGHT_PANEL_HIDE + } else { + + removeBackpack GVAR(center); + GVAR(center) addBackpack _item; + while {count backpackItems GVAR(center) > 0} do { + GVAR(center) removeItemFromBackpack (backpackItems GVAR(center) select 0); + }; //--- Remove default config contents + {GVAR(center) addItemToBackpack _x} foreach (GVAR(currentItems) select 17); + + GVAR(currentItems) set [6, _item]; + + TOGGLE_RIGHT_PANEL_CONTAINER + [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); + }; + + call FUNC(showItem); + [_display, _control, _curSel, (configFile >> "CfgVehicles" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonGoggles : { + if (_item == "") then { + removeGoggles GVAR(center); + GVAR(currentItems) set [7, _item]; + } else { + GVAR(center) addGoggles _item; + GVAR(currentItems) set [7, _item]; + }; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgGlasses" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonNVG : { + if (_item == "") then { + GVAR(center) unlinkItem (GVAR(currentItems) select 8); + GVAR(currentItems) set [8, _item]; + } else { + GVAR(center) linkItem _item; + GVAR(currentItems) set [8, _item]; + }; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonBinoculars : { + if (_item == "") then { + GVAR(center) removeWeapon (binocular GVAR(center)); + GVAR(currentItems) set [9, _item]; + } else { + GVAR(center) addWeapon _item; + GVAR(currentItems) set [9, _item]; + call FUNC(showItem); + ADDBINOCULARSMAG + }; + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonMap : { + if (_item == "") then { + GVAR(center) unlinkItem (GVAR(currentItems) select 10) select 0; + GVAR(currentItems) set [10, _item]; + } else { + GVAR(center) linkItem _item; + GVAR(currentItems) set [10, _item]; + }; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonCompass : { + if (_item == "") then { + GVAR(center) unlinkItem (GVAR(currentItems) select 11) select 0; + GVAR(currentItems) set [11, _item]; + } else { + GVAR(center) linkItem _item; + GVAR(currentItems) set [11, _item]; + }; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonRadio : { + if (_item == "") then { + GVAR(center) unlinkItem (GVAR(currentItems) select 12) select 0; + GVAR(currentItems) set [12, _item]; + } else { + GVAR(center) linkItem _item; + GVAR(currentItems) set [12, _item]; + }; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonWatch : { + if (_item == "") then { + GVAR(center) unlinkItem (GVAR(currentItems) select 13); + GVAR(currentItems) set [13, _item]; + } else { + GVAR(center) linkItem _item; + GVAR(currentItems) set [13, _item]; + }; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonGPS : { + if (_item == "") then { + GVAR(center) unlinkItem (GVAR(currentItems) select 14) select 0; + GVAR(currentItems) set [14, _item]; + } else { + GVAR(center) linkItem _item; + GVAR(currentItems) set [14, _item]; + }; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonFace : { + private _face = [_item, "Default"] select (_item == ""); + + GVAR(center) setFace _face; + GVAR(currentFace) = _face; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgFaces" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonVoice : { + GVAR(center) setSpeaker _item; + GVAR(currentVoice) = _item; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgVoice" >> _item)] call FUNC(itemInfo); + }; + + case IDC_buttonInsigna : { + [GVAR(center), _item] call bis_fnc_setUnitInsignia; + GVAR(currentInsignia) = _item; + + call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE + [_display, _control, _curSel, (configFile >> "CfgUnitInsignia" >> _item)] call FUNC(itemInfo); + }; +}; + +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); diff --git a/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf new file mode 100644 index 0000000000..3f4d508ae0 --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf @@ -0,0 +1,103 @@ +/* + * Author: Alganthe + * Handles selection changes on loadouts panel. + * + * Arguments: + * 0: Loadouts panel control + * 1: Loadouts panel selection + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_display", "_control", "_curSel"]; + +private _shareButtonCtrl = _display displayCtrl IDC_buttonShare; +private _saveButtonCtrl = _display displayCtrl IDC_buttonSave; +private _loadButtonCtrl = _display displayCtrl IDC_buttonLoad; +private _deleteButtonCtrl = _display displayCtrl IDC_buttonDelete; +private _renameButtonCtrl = _display displayCtrl IDC_buttonRename; +private _textEditBoxCtrl= _display displayCtrl IDC_textEditBox; + +if (_curSel == -1) exitWith { + + if (GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts) then { + _saveButtonCtrl ctrlEnable false; + _saveButtonCtrl ctrlCommit 0; + }; + + _shareButtonCtrl ctrlSetText (localize LSTRING(buttonSharePrivateText)); + + { + _x ctrlEnable false; + _x ctrlCommit 0; + } foreach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; +}; + +switch (GVAR(currentLoadoutsTab)) do { + + case IDC_buttonMyLoadouts: { + + _shareButtonCtrl ctrlEnable (GVAR(allowSharedLoadouts) && {isMultiplayer}); + _shareButtonCtrl ctrlCommit 0; + + _loadButtonCtrl ctrlEnable true; + _loadButtonCtrl ctrlCommit 0; + + _shareButtonCtrl ctrlSetText ( [ + localize LSTRING(buttonSharePrivateText), + localize LSTRING(buttonSharePublicText) + ] select ((_control lnbValue [_curSel, 0]) == 1)); + + { + _x ctrlEnable true; + _x ctrlCommit 0; + } foreach [_renameButtonCtrl, _deleteButtonCtrl]; + + _textEditBoxCtrl ctrlSetText (_control lnbText [_curSel, 1]); + }; + + case IDC_buttonDefaultLoadouts: { + + { + _x ctrlEnable true; + _x ctrlCommit 0; + } foreach [_saveButtonCtrl, _loadButtonCtrl]; + + _shareButtonCtrl ctrlEnable false; + _shareButtonCtrl ctrlCommit 0; + + { + _x ctrlEnable (is3DEN); + _x ctrlCommit 0; + } foreach [_deleteButtonCtrl, _renameButtonCtrl]; + + _textEditBoxCtrl ctrlSetText (_control lnbText [_curSel, 1]); + }; + + case IDC_buttonSharedLoadouts: { + + { + _x ctrlEnable true; + _x ctrlCommit 0; + } foreach [_saveButtonCtrl, _loadButtonCtrl]; + + _shareButtonCtrl ctrlEnable false; + _shareButtonCtrl ctrlCommit 0; + + if ((serverCommandAvailable "#logout") || {(_control lnbText [_curSel, 0]) == profileName}) then { + + _deleteButtonCtrl ctrlEnable true; + _deleteButtonCtrl ctrlCommit 0; + } else { + _deleteButtonCtrl ctrlEnable false; + _deleteButtonCtrl ctrlCommit 0; + }; + + _textEditBoxCtrl ctrlSetText (_control lnbText [_curSel, 1]); + }; +}; diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf new file mode 100644 index 0000000000..7a565cd14d --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -0,0 +1,77 @@ +/* + * Author: Alganthe + * Handles selection changes on the right panel. + * + * Arguments: + * 0: Right panel control + * 1: Right panel selection + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_control", "_curSel"]; + +if (_curSel < 0) exitwith {}; + +private _ctrlIDC = ctrlIDC _control; +private _display = ctrlParent _control; +private _item = _control lbData _curSel; + + +private _fnc_selectItem = { + params ["_item", "_currentItemsIndex", "_itemIndex"]; + + switch (_currentItemsIndex) do { + case 18: { + if (_item == "") then { + GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select 18) select _itemIndex); + private _primaryMags = primaryWeaponMagazine GVAR(center); + GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; + } else { + GVAR(center) addPrimaryWeaponItem _item; + private _primaryMags = primaryWeaponMagazine GVAR(center); + GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; + }; + [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); + }; + + case 19: { + if (_item == "") then { + GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select 19) select _itemIndex); + private _secondaryMags = secondaryWeaponMagazine GVAR(center); + GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; + } else { + GVAR(center) addSecondaryWeaponItem _item; + private _secondaryMags = secondaryWeaponMagazine GVAR(center); + GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; + }; + [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); + }; + + case 20: { + if (_item == "") then { + GVAR(center) removeHandgunItem ((GVAR(currentItems) select 20) select _itemIndex); + private _handgunMags = handgunMagazine GVAR(center); + GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; + } else { + GVAR(center) addHandgunItem _item; + private _handgunMags = handgunMagazine GVAR(center); + GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; + }; + [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); + }; + }; +}; + +[ + _item, + 18 + ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find GVAR(currentLeftPanel)), + [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find GVAR(currentRightPanel) +] call _fnc_selectItem; + +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); diff --git a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf new file mode 100644 index 0000000000..29c66a79f9 --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf @@ -0,0 +1,51 @@ +/* + * Author: Alganthe + * Handles selection changes on the right panel (listnbox). + * + * Arguments: + * 0: Right panel control + * 1: Right panel selection + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_control", "_curSel"]; + +if (_curSel < 0) exitwith {}; + +private _ctrlIDC = ctrlIDC _control; +private _display = ctrlParent _control; +private _item = [_control lnbData [_curSel, 0], _control lbData _curSel] select !(ctrlType _control == 102); + +private _fnc_selectRight = { + params ["_item", "_cfgEntry"]; + + // Load remaining + private _maxLoad = switch (GVAR(currentLeftPanel)) do { + case IDC_buttonUniform: { + gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass") + }; + case IDC_buttonVest: { + gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass") + }; + case IDC_buttonBackpack: { + backpack GVAR(center) + }; + }; + + [_control, _maxLoad] call FUNC(updateRightPanel); + [_display, _control, _curSel, (configFile >> _cfgEntry >> _item)] call FUNC(itemInfo); +}; + +if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) then { + + [ + _item, + ["CfgWeapons", "CfgMagazines"] select (GVAR(currentRightPanel) in [IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut]) + ] call _fnc_selectRight; +}; diff --git a/addons/arsenal/functions/fnc_open3DEN.sqf b/addons/arsenal/functions/fnc_open3DEN.sqf new file mode 100644 index 0000000000..6bb0adcaa3 --- /dev/null +++ b/addons/arsenal/functions/fnc_open3DEN.sqf @@ -0,0 +1,17 @@ +/* + * Author: Alganthe + * Replace the 3DEN "edit loadout" menu action + * + * Arguments: + * None + * + * Return Value: + * None + * + * + * Public: No +*/ +#include "script_component.hpp" + +private _entity = (uinamespace getvariable ["bis_fnc_3DENEntityMenu_data",[]]) param [1, objnull]; +[_entity, _entity, true] call FUNC(openBox); diff --git a/addons/arsenal/functions/fnc_openBox.sqf b/addons/arsenal/functions/fnc_openBox.sqf new file mode 100644 index 0000000000..a4d45edac7 --- /dev/null +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -0,0 +1,58 @@ +/* + * Author: Alganthe + * Open arsenal. + * + * Arguments: + * 0: Box + * 1: Unit to open the arsenal on + * 2: Ignore virtual items and fill arsenal + * + * Return Value: + * None + * + * Example: + * [_box, player] call ace_arsenal_fnc_openBox + * + * Public: Yes +*/ +#include "script_component.hpp" + +params [["_object", objNull, [objNull]], ["_center", objNull, [objNull]], ["_mode", false, [false]]]; + +if ( + isNull _object || + {isNull _center} || + {!(_center isKindOf "Man")} || + {!(isNull objectParent _center) && {!is3DEN}} +) exitWith {}; + +if (isNil {_object getVariable [QGVAR(virtualItems), nil]} && {!_mode}) exitWith { + [localize LSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); +}; + +if (canSuspend) exitWith { + [{_this call FUNC(openBox)}, _this] call CBA_fnc_directCall; +}; + +private _displayToUse = [findDisplay 46, findDIsplay 312] select (!isNull findDisplay 312); +_displayToUse = [_displayToUse, findDisplay 313] select (is3DEN); + +if (isNil "_displayToUse" || {!isnil QGVAR(camera)}) exitWith { + [localize LSTRING(CantOpenDisplay), false, 5, 1] call EFUNC(common,displayText); +}; + +if (_mode) then { + GVAR(virtualItems) = +(uiNamespace getVariable QGVAR(configItems)); +} else { + GVAR(virtualItems) = +(_object getVariable [QGVAR(virtualItems), [ + [[], [], []], [[], [], [], []], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] + ]]); +}; + +GVAR(center) = _center; + +if (is3DEN) then { + _displayToUse createDisplay QGVAR(display); +} else { + [{(_this select 0) createDisplay (_this select 1)}, [_displayToUse, QGVAR(display)]] call CBA_fnc_execNextFrame; +}; diff --git a/addons/arsenal/functions/fnc_portVALoadouts.sqf b/addons/arsenal/functions/fnc_portVALoadouts.sqf new file mode 100644 index 0000000000..7ad141819d --- /dev/null +++ b/addons/arsenal/functions/fnc_portVALoadouts.sqf @@ -0,0 +1,43 @@ +/* + * Author: alganthe + * Port VA loadouts to ACE Arsenal. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: Yes +*/ +#include "script_component.hpp" + +private _VALoadouts = +(profilenamespace getvariable ["bis_fnc_saveInventory_data",[]]); +private _aceLoadouts = +(profileNamespace getVariable [QGVAR(saved_loadouts),[]]); + +if (isNull player) exitWith { + [localize LSTRING(portLoadoutsPlayerError)] call BIS_fnc_error; +}; + +if (_VALoadouts isEqualTo []) exitWith { + [localize LSTRING(portLoadoutsLoadoutError)] call BIS_fnc_error; +}; + +for "_i" from 0 to (count _VALoadouts - 1) step 2 do { + _name = _VALoadouts select _i; + _inventory = _VALoadouts select (_i + 1); + + private _sameNameLoadoutsList = _aceLoadouts select {_x select 0 == _name}; + [player, [profilenamespace, _name]] call bis_fnc_loadinventory; + + private _loadout = getUnitLoadout player; + + if (count _sameNameLoadoutsList > 0) then { + _aceLoadouts set [_aceLoadouts find (_sameNameLoadoutsList select 0), [_name, _loadout]]; + + } else { + _aceLoadouts pushBack [_name, _loadout]; + }; +}; + +profileNamespace setVariable [QGVAR(saved_loadouts), _aceLoadouts]; diff --git a/addons/arsenal/functions/fnc_removeBox.sqf b/addons/arsenal/functions/fnc_removeBox.sqf new file mode 100644 index 0000000000..43fa903ca4 --- /dev/null +++ b/addons/arsenal/functions/fnc_removeBox.sqf @@ -0,0 +1,35 @@ +/* + * Author: Alganthe + * Remove arsenal from target. + * + * Arguments: + * 0: Target + * 1: Remove globally + * + * Return Value: + * None + * + * Example: + * [_box, true] call ace_arsenal_fnc_removeBox + * + * Public: Yes +*/ +#include "script_component.hpp" + +params [["_object", objNull, [objNull]], ["_global", true, [true]]]; + +if (isNull _object || {isNil QGVAR(EHIDArray)}) exitWith {}; + +if (_global && {isMultiplayer}) then { + private _ID = (GVAR(EHIDArray) select {_x select 1 == _object}) select 0; + + if !(isNil "_ID") then { + [_ID select 0] call CBA_fnc_removeGlobalEventJIP; + GVAR(EHIDArray) deleteAt (GVAR(EHIDArray) find _ID); + publicVariable QGVAR(EHIDArray); + [QGVAR(removeBox), [_object, false]] call CBA_fnc_globalEvent; + }; +} else { + _object setVariable [QGVAR(virtualItems), nil, false]; + [_object, 0, ["ACE_MainActions", QGVAR(interaction)]] call EFUNC(interact_menu,removeActionFromObject); +}; diff --git a/addons/arsenal/functions/fnc_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf new file mode 100644 index 0000000000..f6fed970f9 --- /dev/null +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -0,0 +1,82 @@ +/* + * Author: Alganthe + * Remove virtual items to the provided target. + * + * Arguments: + * 0: Target + * 1: Items + * 2: Add globally + * + * Return Value: + * None + * + * Example: + * [_box, ["item1", "item2", "itemN"]] call ace_arsenal_fnc_removeVirtualItems + * [_box, true, false] call ace_arsenal_fnc_removeVirtualItems + * + * Public: Yes +*/ +#include "script_component.hpp" + +params [ ["_object", objNull, [objNull]], ["_items", [], [true, [""]]], ["_global", false, [false]] ]; + +if (_object == objNull) exitWith {}; +if (_items isEqualType [] && {count _items == 0}) exitWith {}; + +private _cargo = _object getVariable [QGVAR(virtualItems), [ + [[], [], []], // Weapons 0, primary, handgun, secondary + [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod + [ ], // Magazines 2 + [ ], // Headgear 3 + [ ], // Uniform 4 + [ ], // Vest 5 + [ ], // Backpacks 6 + [ ], // Goggles 7 + [ ], // NVGs 8 + [ ], // Binoculars 9 + [ ], // Map 10 + [ ], // Compass 11 + [ ], // Radio slot 12 + [ ], // Watch slot 13 + [ ], // Comms slot 14 + [ ], // WeaponThrow 15 + [ ], // WeaponPut 16 + [ ] // InventoryItems 17 +]]; + +if (_items isEqualType true) then { + if (_items) then { + [_object, _global] call FUNC(removeBox); + _object setVariable [QGVAR(virtualItems), nil, _global]; + }; +} else { + + // Make sure all items are in string form + _items = _items select {_x isEqualType "" && {_x != ""}}; + + { + if (_forEachIndex isEqualTo 0) then { + _cargo set [_forEachIndex, [(_x select 0) - _items, (_x select 1) - _items, (_x select 2) - _items]]; + } else { + if (_forEachIndex isEqualTo 1) then { + _cargo set [_forEachIndex, [(_x select 0) - _items, (_x select 1) - _items, (_x select 2) - _items, (_x select 3) - _items]]; + } else { + _cargo set [_cargo find _x, _x - _items]; + }; + }; + } foreach _cargo; + + private _itemCount = { + if (_x isEqualTo (_cargo select 0) || {_x isEqualTo (_cargo select 1)}) then { + !(_x isEqualTo [[],[],[]] || {_x isEqualTo [[],[],[],[]]}) + } else { + !(_x isEqualTo []) + }; + } count _cargo; + + if (_itemCount == 0) then { + [_object, _global] call FUNC(removeBox); + } else { + _object setVariable [QGVAR(virtualItems), _cargo, _global]; + }; +}; diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf new file mode 100644 index 0000000000..c7457ae4ec --- /dev/null +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -0,0 +1,182 @@ +/* + * Author: Dedmen + * Cache an array of all the compatible items for arsenal. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" + +private _cargo = [ + [[], [], []], // Weapons 0, primary, secondary, handgun + [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod + [ ], // Magazines 2 + [ ], // Headgear 3 + [ ], // Uniform 4 + [ ], // Vest 5 + [ ], // Backpacks 6 + [ ], // Goggles 7 + [ ], // NVGs 8 + [ ], // Binoculars 9 + [ ], // Map 10 + [ ], // Compass 11 + [ ], // Radio slot 12 + [ ], // Watch slot 13 + [ ], // Comms slot 14 + [ ], // WeaponThrow 15 + [ ], // WeaponPut 16 + [ ] // InventoryItems 17 +]; + +private _configCfgWeapons = configFile >> "CfgWeapons"; //Save this lookup in variable for perf improvement +private _magazineGroups = [[],[]] call CBA_fnc_hashCreate; + +{ + private _configItemInfo = _x >> "ItemInfo"; + private _simulationType = getText (_x >> "simulation"); + private _className = configName _x; + private _hasItemInfo = isClass (_configItemInfo); + private _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; + + switch true do { + /* Weapon acc */ + case ( + _hasItemInfo && + {_itemInfoType in [101, 201, 301, 302]} && + {!(configName _x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])} + ): { + + //Convert type to array index + (_cargo select 1) select ([201,301,101,302] find _itemInfoType) pushBackUnique _className; + }; + /* Headgear */ + case (_hasItemInfo && {_itemInfoType == 605}): { + (_cargo select 3) pushBackUnique _className; + }; + /* Uniform */\ + case (_hasItemInfo && {_itemInfoType == 801}): { + (_cargo select 4) pushBackUnique _className; + }; + /* Vest */ + case (_hasItemInfo && {_itemInfoType == 701}): { + (_cargo select 5) pushBackUnique _className; + }; + /* NVgs */ + case (_simulationType == "NVGoggles"): { + (_cargo select 8) pushBackUnique _className; + }; + /* Binos */ + case (_simulationType == "Binocular" || + ((_simulationType == 'Weapon') && {(getNumber (_x >> 'type') == 4096)})): { + (_cargo select 9) pushBackUnique _className; + }; + /* Map */ + case (_simulationType == "ItemMap"): { + (_cargo select 10) pushBackUnique _className; + }; + /* Compass */ + case (_simulationType == "ItemCompass"): { + (_cargo select 11) pushBackUnique _className; + }; + /* Radio */ + case (_simulationType == "ItemRadio"): { + (_cargo select 12) pushBackUnique _className; + }; + /* Watch */ + case (_simulationType == "ItemWatch"): { + (_cargo select 13) pushBackUnique _className; + }; + /* GPS */ + case (_simulationType == "ItemGPS"): { + (_cargo select 14) pushBackUnique _className; + }; + /* UAV terminals */ + case (_hasItemInfo && {_itemInfoType == 621}): { + (_cargo select 14) pushBackUnique _className; + }; + /* Weapon, at the bottom to avoid adding binos */ + case (isClass (_x >> "WeaponSlotsInfo") && + {getNumber (_x >> 'type') != 4096}): { + switch (getNumber (_x >> "type")) do { + case 1: { + (_cargo select 0) select 0 pushBackUnique (_className call bis_fnc_baseWeapon); + }; + case 2: { + (_cargo select 0) select 2 pushBackUnique (_className call bis_fnc_baseWeapon); + }; + case 4: { + (_cargo select 0) select 1 pushBackUnique (_className call bis_fnc_baseWeapon); + }; + }; + }; + /* Misc items */ + case ( + _hasItemInfo && + (_itemInfoType in [101, 201, 301, 302] && + {(_className isKindOf ["CBA_MiscItem", (_configCfgWeapons)])}) || + {_itemInfoType in [401, 619, 620]} || + {(getText ( _x >> "simulation")) == "ItemMineDetector"} + ): { + (_cargo select 17) pushBackUnique _className; + }; + }; +} foreach configProperties [_configCfgWeapons, "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; + +private _grenadeList = []; +{ + _grenadeList append getArray (_configCfgWeapons >> "Throw" >> _x >> "magazines"); +} foreach getArray (_configCfgWeapons >> "Throw" >> "muzzles"); + +private _putList = []; +{ + _putList append getArray (_configCfgWeapons >> "Put" >> _x >> "magazines"); +} foreach getArray (_configCfgWeapons >> "Put" >> "muzzles"); + +{ + private _className = configName _x; + + switch true do { + // Rifle, handgun, secondary weapons mags + case ( + (getNumber (_x >> "type") in [256,512,1536,16]) && + {!(_className in _grenadeList)} && + {!(_className in _putList)} + ): { + (_cargo select 2) pushBackUnique _className; + }; + // Grenades + case (_className in _grenadeList): { + (_cargo select 15) pushBackUnique _className; + }; + // Put + case (_className in _putList): { + (_cargo select 16) pushBackUnique _className; + }; + }; + + if (isArray (_x >> "magazineGroup")) then { + { + private _entry = [_magazineGroups, _x] call CBA_fnc_hashGet; + _entry pushBackUnique _className; + [_magazineGroups, _x, _entry] call CBA_fnc_hashSet; + } forEach getArray (_x >> "magazineGroup") + }; +} foreach configProperties [(configFile >> "CfgMagazines"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; + +{ + if (getNumber (_x >> "isBackpack") == 1) then { + (_cargo select 6) pushBackUnique (configName _x); + }; +} foreach configProperties [(configFile >> "CfgVehicles"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; + +{ + (_cargo select 7) pushBackUnique (configName _x); +} foreach configProperties [(configFile >> "CfgGlasses"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; + +uiNamespace setVariable [QGVAR(configItems), _cargo]; +uiNamespace setVariable [QGVAR(magazineGroups), _magazineGroups]; diff --git a/addons/arsenal/functions/fnc_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf new file mode 100644 index 0000000000..e97ebd8dd5 --- /dev/null +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -0,0 +1,75 @@ +/* + * Author: Alganthe + * Change unit animation / play sound preview. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + + + +private _nextAction = switch (GVAR(currentLeftPanel)) do { + + case IDC_buttonPrimaryWeapon : { + ["Civil", "PrimaryWeapon"] select ((GVAR(currentItems) select 0) != "") + }; + case IDC_buttonSecondaryWeapon : { + ["Civil", "SecondaryWeapon"] select (GVAR(currentItems) select 1 != "") + }; + case IDC_buttonHandgun : { + ["Civil", "HandGunOn"] select (GVAR(currentItems) select 2 != "") + }; + case IDC_buttonHeadgear; + case IDC_buttonUniform; + case IDC_buttonVest; + case IDC_buttonBackpack; + case IDC_buttonGoggles; + case IDC_buttonMap; + case IDC_buttonGPS; + case IDC_buttonRadio; + case IDC_buttonCompass; + case IDC_buttonWatch; + case IDC_buttonFace; + case IDC_buttonNVG : { + "Civil" + }; + case IDC_buttonBinoculars : { + ["Civil", "Binoculars"] select (GVAR(currentItems) select 9 != "") + }; + case IDC_buttonInsigna : { + "Salute" + }; + case IDC_buttonVoice : { + GVAR(center) directSay "CuratorObjectPlaced"; + "Civil" + }; +}; + +if (_nextAction != GVAR(currentAction)) then { + switch (_nextAction) do { + case "PrimaryWeapon": { + GVAR(selectedWeaponType) = 0; + }; + case "SecondaryWeapon": { + GVAR(selectedWeaponType) = 1; + }; + case "HandGunOn": { + GVAR(selectedWeaponType) = 2; + }; + }; + + if (simulationEnabled GVAR(center)) then { + GVAR(center) playActionNow _nextAction; + } else { + GVAR(center) switchAction _nextAction; + }; + + GVAR(currentAction) = _nextAction; +}; diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf new file mode 100644 index 0000000000..c8bf02777f --- /dev/null +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -0,0 +1,64 @@ +/* + * Author: Alganthe, Dedmen + * Sort arsenal panel. + * + * Arguments: + * 0: Panel's control to sort + * 1: Sorting mode + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_control", "_mode"]; + +private _display = ctrlParent _control; +private ["_panel", "_curSel", "_selected"]; + +// Right panel +if (ctrlIDC _control == 17 && {GVAR(currentLeftPanel) in [IDC_buttonUniform ,IDC_buttonVest, IDC_buttonBackpack]}) then { + _panel = _display displayCtrl IDC_rightTabContentListnBox; + _curSel = lnbCurSelRow _panel; + _selected = _panel lnbData [_curSel, 0]; + + switch (_mode) do { + case 0: { + _panel lnbSort [1, false]; + }; + + case 1: { + _panel lnbSortByValue [0, false]; + }; + + case 2: { + _panel lnbSort [2, true]; + }; + }; + + if (_cursel >= 0) then { + for '_i' from 0 to (((lnbsize _panel) select 0) - 1) do { + if ((_panel lnbdata [_i, 0]) == _selected) exitwith {_panel lnbSetCurSelRow _i}; + }; + }; +// Left panel +} else { + _panel = _display displayCtrl ([IDC_leftTabContent, IDC_rightTabContent] select (ctrlIDC _control == 17)); + _curSel = lbCurSel _panel; + _selected = _panel lbData _curSel; + + if (_mode > 0) then { + lbSortByValue _panel; + } else { + lbsort _panel; + }; + + if (_cursel >= 0) then { + for '_i' from 0 to (lbsize _panel - 1) do { + if ((_panel lbdata _i) == _selected) exitwith {_panel lbSetCurSel _i}; + }; + }; +}; diff --git a/addons/arsenal/functions/fnc_updateCamPos.sqf b/addons/arsenal/functions/fnc_updateCamPos.sqf new file mode 100644 index 0000000000..f8b6b91a15 --- /dev/null +++ b/addons/arsenal/functions/fnc_updateCamPos.sqf @@ -0,0 +1,27 @@ +/* + * Author: Karel Moricky, modified by Alganthe + * Update camera position + * Modernized a bit, modified vars to fit arsenal rewrite. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: Yes +*/ +#include "script_component.hpp" + +GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV"]; +[GVAR(cameraHelper), [_dirH + 180, - _dirV, 0]] call bis_fnc_setobjectrotation; +GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; //--- Reattach for smooth movement + +GVAR(camera) setPos (GVAR(cameraHelper) modelToWorld [0, -_distance, 0]); +GVAR(camera) setVectorDirAndUp [vectorDir GVAR(cameraHelper), vectorUp GVAR(cameraHelper)]; + +//--- Make sure the camera is not underground +if ((getPosAsl GVAR(camera) select 2) < (getPosAsl GVAR(center) select 2)) then { + private _disCoef = ((getPosAsl GVAR(cameraHelper) select 2) - (getPosAsl GVAR(center) select 2)) / ((getPosAsl GVAR(cameraHelper) select 2) - (getPosAsl GVAR(camera) select 2) + 0.001); + GVAR(camera) setPos (GVAR(cameraHelper) modelToWorldVisual [0, -_distance * _disCoef, 0]); +}; diff --git a/addons/arsenal/functions/fnc_updateRightPanel.sqf b/addons/arsenal/functions/fnc_updateRightPanel.sqf new file mode 100644 index 0000000000..41c7c68483 --- /dev/null +++ b/addons/arsenal/functions/fnc_updateRightPanel.sqf @@ -0,0 +1,57 @@ +/* + * Author: Alganthe + * Update the right panel (listnbox). + * + * Arguments: + * 0: Right panel control + * 1: Max load of the current container + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_control", "_maxLoad"]; + +private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; +private _curSel = lnbCurSelRow _control; + +(lnbSize _control) params ["_rows"]; + +_maxLoad = getnumber (configfile >> "CfgVehicles" >> _maxLoad >> "maximumLoad"); +_maxLoad = _maxLoad * (1 - (progressPosition _loadIndicatorBarCtrl)); +_maxLoad = parseNumber (_maxLoad toFixed 2); // Required to avoid an issue where even though the typename returns "SCALAR" it doesn't act as one. + +// Grey out items too big +for "_r" from 0 to (_rows - 1) do { + private _mass = _control getVariable (_control lnbData [_r, 0]); + private _class = _control lnbText [_r, 1]; + + private _alpha = [0.25, 1.0] select (_mass <= _maxLoad); + private _color = [1, 1, 1, _alpha]; + _control lnbSetColor [[_r, 1],_color]; + _control lnbSetColor [[_r, 2],_color]; +}; + +// Remove all from container show / hide +private _removeAllCtrl = _display displayCtrl IDC_buttonRemoveAll; + +if (progressPosition _loadIndicatorBarCtrl > 0) then { + + _removeAllCtrl ctrlSetFade 0; + _removeAllCtrl ctrlShow true; + _removeAllCtrl ctrlEnable true; + _removeAllCtrl ctrlCommit FADE_DELAY; +}; + +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); + +// change button color if unique or too big +if (_curSel != -1) then { + private _plusButtonCtrl = _display displayCtrl IDC_arrowPlus; + _plusButtonCtrl ctrlEnable !((_control lnbValue [_curSel, 2]) == 1 || {(_control getVariable (_control lnbData [_curSel, 0])) > _maxLoad}); + _plusButtonCtrl ctrlCommit FADE_DELAY; +}; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf new file mode 100644 index 0000000000..7a037d987d --- /dev/null +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -0,0 +1,118 @@ +/* + * Author: Alganthe + * Update the list of unique items. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +GVAR(virtualItems) set [18, []]; +GVAR(virtualItems) set [19, []]; +GVAR(virtualItems) set [20, []]; +GVAR(virtualItems) set [21, []]; +GVAR(virtualItems) set [22, [[], [], [], []]]; +GVAR(virtualItems) set [23, []]; +GVAR(virtualItems) set [24, []]; + +private _array = LIST_DEFAULTS select 2; +private _itemsCache = uiNamespace getVariable QGVAR(configItems); + +private _configCfgWeapons = configFile >> "CfgWeapons"; +private _configMagazines = configFile >> "CfgMagazines"; +private _configVehicles = configFile >> "CfgVehicles"; +private _configGlasses = configFile >> "CfgGlasses"; + +{ + switch true do { + // Weapon mag + case ( + isClass (_configMagazines >> _x) && + {_x in (_itemsCache select 2)} && + {!(_x in (GVAR(virtualItems) select 2))} + ): { + (GVAR(virtualItems) select 19) pushBackUnique _x; + }; + + // Mag throw + case ( + isClass (_configMagazines >> _x) && + {_x in (_itemsCache select 15)} && + {!(_x in (GVAR(virtualItems) select 15))} + ): { + (GVAR(virtualItems) select 20) pushBackUnique _x; + }; + + // Mag put + case ( + isClass (_configMagazines >> _x) && + {_x in (_itemsCache select 16)} && + {!(_x in (GVAR(virtualItems) select 16))} + ): { + (GVAR(virtualItems) select 21) pushBackUnique _x; + }; + + // acc + case ( + isClass (_configCfgWeapons >> _x) && + {!(_x in ((GVAR(virtualItems) select 1) select 0))} && + {_x in ((_itemsCache select 1) select 0)} + ): { + ((GVAR(virtualItems) select 22) select 0) pushBackUnique _x; + }; + + // acc + case ( + isClass (_configCfgWeapons >> _x) && + {!(_x in ((GVAR(virtualItems) select 1) select 1))} && + {_x in ((_itemsCache select 1) select 1)} + ): { + ((GVAR(virtualItems) select 22) select 1) pushBackUnique _x; + }; + + // acc + case ( + isClass (_configCfgWeapons >> _x) && + {!(_x in ((GVAR(virtualItems) select 1) select 2))} && + {_x in ((_itemsCache select 1) select 2)} + ): { + ((GVAR(virtualItems) select 22) select 2) pushBackUnique _x; + }; + // acc + case ( + isClass (_configCfgWeapons >> _x) && + {!(_x in ((GVAR(virtualItems) select 1) select 3))} && + {_x in ((_itemsCache select 1) select 3)} + ): { + ((GVAR(virtualItems) select 22) select 3) pushBackUnique _x; + }; + + // Misc + case ( + isClass (_configCfgWeapons >> _x) && + {!(_x in (GVAR(virtualItems) select 17))} && + {!(_x in ((_itemsCache select 1) select 0))} && + {!(_x in ((_itemsCache select 1) select 1))} && + {!(_x in ((_itemsCache select 1) select 2))} && + {!(_x in ((_itemsCache select 1) select 3))} + ): { + (GVAR(virtualItems) select 18) pushBackUnique _x; + }; + + // Backpacks + case (isClass (_configVehicles >> _x)): { + (GVAR(virtualItems) select 23) pushBackUnique _x; + }; + + // Facewear + case (isClass (_configGlasses >> _x)): { + (GVAR(virtualItems) select 24) pushBackUnique _x; + }; + }; +} foreach _array; diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf new file mode 100644 index 0000000000..e7946b8b10 --- /dev/null +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -0,0 +1,239 @@ +/* + * Author: Alganthe + * Verify the provided loadout. + * + * Arguments: + * 0: Loadout (getUnitLoadout format) + * + * Return Value: + * Verified loadout and missing / unavailable items list and count + * + * Public: No +*/ +#include "script_component.hpp" +#include "..\defines.hpp" + +params ["_loadout"]; + +private _weaponCfg = configFile >> "CfgWeapons"; +private _magCfg = configFile >> "CfgMagazines"; +private _vehcCfg = configFile >> "CfgVehicles"; +private _glassesCfg = configFile >> "CfgGlasses"; +private _weaponsArray = GVAR(virtualItems) select 0; +private _accsArray = GVAR(virtualItems) select 1; + +private _nullItemsAmount = 0; +private _unavailableItemsAmount = 0; +private _nullItemsList = []; +private _unavailableItemsList = []; + +private _fnc_weaponCheck = { + params ["_dataPath"]; + + if (count _dataPath != 0) then { + { + if (_x isEqualType "") then { + + private _item = _x; + + if (_item != "") then { + if (isClass (_weaponCfg >> _item)) then { + if !(CHECK_WEAPON_OR_ACC) then { + + _unavailableItemsList pushBackUnique _item; + _dataPath set [_forEachIndex, ""]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _item; + _dataPath set [_forEachIndex, ""]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + }; + + } else { + + if (count _x != 0) then { + private _mag = _x select 0; + + if (isClass (_magCfg >> _mag)) then { + if !(_mag in (GVAR(virtualItems) select 2)) then { + + _unavailableItemsList pushBackUnique _item; + _dataPath set [_forEachIndex, []]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _item; + _dataPath set [_forEachIndex, []]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + }; + }; + } foreach _dataPath; + }; +}; + +for "_dataIndex" from 0 to 9 do { + switch (_dataIndex) do { + case 0; + case 1; + case 2; + case 8: { + [_loadout select _dataIndex] call _fnc_weaponCheck; + }; + + case 3; + case 4; + case 5: { + private _containerArray = (_loadout select _dataIndex); + + if (count _containerArray != 0) then { + + _containerArray params ["_item", "_containerItems"]; + + if (isClass (_vehcCfg >> _item) || {isClass (_weaponCfg >> _item)}) then { + if !(CHECK_CONTAINER) then { + + _unavailableItemsList pushBackUnique _item; + _loadout set [_dataIndex, []]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + } else { + + if (count _containerItems != 0) then { + { + private _currentIndex = _forEachIndex; + + switch (count _x) do { + case 2: { + + if ((_x select 0) isEqualType "") then { + + private _item = _x select 0; + + if (CLASS_CHECK_ITEM) then { + if !(CHECK_CONTAINER_ITEMS) then { + + _unavailableItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + } else { + + [(((_loadout select _dataIndex) select 1) select _currentIndex) select 0] call _fnc_weaponCheck; + }; + }; + + case 3: { + private _item = _x select 0; + + if (isClass (_magCfg >> _item)) then { + if !( + _item in (GVAR(virtualItems) select 2) || + _item in (GVAR(virtualItems) select 15) || + _item in (GVAR(virtualItems) select 16) + ) then { + + _unavailableItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + }; + }; + } foreach _containerItems; + }; + }; + } else { + + _nullItemsList pushBackUnique _item; + _loadout set [_dataIndex, []]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + }; + }; + + case 6: { + private _item = _loadout select _dataIndex; + + if (_item != "") then { + + if (isClass (_weaponCfg >> _item)) then { + + if !(_item in (GVAR(virtualItems) select 3)) then { + + _unavailableItemsList pushBackUnique _item; + _loadout set [_dataIndex, ""]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _item; + _loadout set [_dataIndex, ""]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + }; + }; + + case 7: { + private _item = _loadout select _dataIndex; + + if (_item != "") then { + + if (isClass (_glassesCfg >> _item)) then { + + if !(_item in (GVAR(virtualItems) select 7)) then { + + _unavailableItemsList pushBackUnique _item; + _loadout set [_dataIndex, ""]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _item; + _loadout set [_dataIndex, ""]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + }; + }; + + case 9: { + for "_subIndex" from 0 to 4 do { + private _item = (_loadout select _dataIndex) select _subIndex; + + if (_item != "") then { + + if (isClass (_weaponCfg >> _item)) then { + + if !(CHECK_ASSIGNED_ITEMS) then { + + _unavailableItemsList pushBackUnique _item; + (_loadout select _dataIndex) set [_subIndex, ""]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _item; + (_loadout select _dataIndex) set [_subIndex, ""]; + _nullItemsAmount = _nullItemsAmount + 1; + }; + }; + }; + }; + }; +}; + +[_loadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList] diff --git a/addons/arsenal/functions/script_component.hpp b/addons/arsenal/functions/script_component.hpp new file mode 100644 index 0000000000..523addf768 --- /dev/null +++ b/addons/arsenal/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\arsenal\script_component.hpp" \ No newline at end of file diff --git a/addons/arsenal/missions/Arsenal.VR/CfgEventHandlers.hpp b/addons/arsenal/missions/Arsenal.VR/CfgEventHandlers.hpp new file mode 100644 index 0000000000..0f36260026 --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call compile preprocessFileLineNumbers 'XEH_preInit.sqf'); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call compile preprocessFileLineNumbers 'XEH_postInit.sqf'); + }; +}; diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf new file mode 100644 index 0000000000..3a36faa6a2 --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf @@ -0,0 +1,113 @@ +#include "script_component.hpp" +#include "\z\ace\addons\arsenal\defines.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +enableSaving [false, false]; +cba_diagnostic_projectileMaxLines = 10; + +[QGVAR(displayOpened), { + private _player = player; + + // player pose + [{ + switch (true) do { + case (primaryWeapon _this != ""): { + _this switchMove "amovpercmstpslowwrfldnon"; + }; + case (handgunWeapon _this != ""): { + _this switchMove "amovpercmstpslowwpstdnon"; + }; + default { + _this switchMove "amovpercmstpsnonwnondnon"; + }; + }; + }, _player] call CBA_fnc_execNextFrame; + + // hide everything except the player + { + _x enableSimulation false; + _x hideObject true; + } forEach (allMissionObjects "" - [_player]); + + _player call CBA_fnc_removeUnitTrackProjectiles; + _player setFatigue 0; + + // Esc to close mission + { + private _display = findDisplay IDD_ace_arsenal; + + _display displayAddEventHandler ["KeyDown", { + params ["_display", "_key", "_shift"]; + + if (_key isEqualTo DIK_ESCAPE && {!_shift}) then { + [_display] spawn { + disableSerialization; + params ["_display"]; + + private _return = [ + localize "str_sure", + localize "str_a3_rscdisplaymain_buttonexit", + true, true, + _display, false, true + ] call BIS_fnc_GUImessage; + + if (_return) then { + profileNamespace setVariable [QGVAR(missionLastLoadout), getUnitLoadout player]; + _display closeDisplay 2; + findDisplay 46 closeDisplay 0; + }; + }; + true + }; + }]; + + private _buttonClose = _display displayCtrl IDC_menuBarClose; + _buttonClose ctrlSetText localize "str_a3_rscdisplayarsenal_buttonok"; + } call CBA_fnc_execNextFrame; +}] call CBA_fnc_addEventHandler; + +[QGVAR(displayClosed), { + private _player = player; + + // unhide everthing + { + _x enableSimulation true; + _x hideObject false; + } forEach allMissionObjects ""; + + // update VR unit gear + { + private _unit = _x; + + removeVest _unit; + _unit addVest vest _player; + + removeBackpack _unit; + _unit addBackpack backpack _player; + + removeHeadgear _unit; + _unit addHeadgear headgear _player; + + removeGoggles _unit; + _unit addGoggles goggles _player; + + removeAllWeapons _unit; + _unit addWeapon primaryWeapon _player; + { + _unit addPrimaryWeaponItem _x; + } forEach primaryWeaponItems _player; + + _unit addWeapon secondaryWeapon _player; + + { + _unit addSecondaryWeaponItem _x; + } forEach secondaryWeaponItems _player; + + _unit addWeapon handgunWeapon _player; + { + _unit addHandgunItem _x; + } forEach handgunItems _player; + } forEach (entities [["B_Soldier_VR_F", "O_Soldier_VR_F", "I_Soldier_VR_F"], [], true]); + + _player call CBA_fnc_addUnitTrackProjectiles; +}] call CBA_fnc_addEventHandler; diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_preInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_preInit.sqf new file mode 100644 index 0000000000..329d5fd1a5 --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/XEH_preInit.sqf @@ -0,0 +1,4 @@ +#include "script_component.hpp" + +PREP(onPause); +PREP(createTarget); diff --git a/addons/arsenal/missions/Arsenal.VR/description.ext b/addons/arsenal/missions/Arsenal.VR/description.ext new file mode 100644 index 0000000000..b548cb933e --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/description.ext @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +dev = "commy2"; +author = ECSTRING(common,ACETeam); + +onLoadName = CSTRING(Mission); +overviewText = CSTRING(Mission_overview); +overviewPicture = "logo_ca.paa"; + +briefing = 0; +debriefing = 0; +enableDebugConsoleSP = 1; + +doneKeys[] = {"BIS_Arsenal.Map_VR_done"}; +onPauseScript[] = {QFUNC(onPause)}; + +#include "CfgEventHandlers.hpp" diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf new file mode 100644 index 0000000000..7ff1ea58e6 --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf @@ -0,0 +1,66 @@ +#include "script_component.hpp" + +params ["_type", "_position", ["_group", grpNull], "_varName"]; +private _player = player; + +if (isNull _group) then { + _group = creategroup east; +}; + +private _target = _group createUnit [_type, [10,10,0], [], 0, "NONE"]; + +if (isNil "_varName") then { + _varName = _target call BIS_fnc_netId; +}; + +_target setPos _position; +_target setDir (_position getDir _player); +_target doWatch position _player; +_target addRating -10e10; +_target setUnitPos "UP"; +_target setBehaviour "CARELESS"; +_target setCombatMode "BLUE"; +_target setSpeedMode "LIMITED"; +_target disableAI "TARGET"; +_target disableAI "AUTOTARGET"; +_target allowFleeing 0; +_target setSpeaker "BASE"; + +[{ + params ["_target", "_time"]; + + if (speaker _target == "BASE") exitWith {time > _time}; + _target setSpeaker "BASE"; + false +}, {}, [_target, time + 1]] call CBA_fnc_waitUntilAndExecute; + +_player reveal [_target, 4]; + +_target addVest vest _player; +_target addBackpack backpack _player; +_target addHeadgear headgear _player; +_target addGoggles goggles _player; +_target addWeapon primaryWeapon _player; +_target addWeapon secondaryWeapon _player; +_target addWeapon handgunWeapon _player; + +_target setVehicleVarName _varName; +missionNamespace setvariable [_varName, _target]; + +_target switchMove "amovpercmstpslowwrfldnon"; +_target setVariable ["origin", _position]; + +_target addEventHandler ["killed", { + params ["_target"]; + private _position = _target getVariable ["origin", position _target]; + private _varName = vehicleVarName _target; + + [_target, true] spawn BIS_fnc_VREffectKilled; + + [{isNull (_this select 0)}, { + (_this select 1) call FUNC(createTarget); + }, [_target, [typeOf _target, _position, group _target, _varName]]] call CBA_fnc_waitUntilAndExecute; +}]; + +_target call BIS_fnc_VRHitpart; +_target diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf new file mode 100644 index 0000000000..25e49405bf --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf @@ -0,0 +1,16 @@ +#include "script_component.hpp" + +params ["_display"]; + +private _ctrlButtonAbort = _display displayCtrl 104; +_ctrlButtonAbort ctrlSetText localize LSTRING(Mission); +_ctrlButtonAbort ctrlSetTooltip localize LSTRING(ReturnToArsenal); + +_ctrlButtonAbort ctrlSetEventHandler ["ButtonClick", { + params ["_control"]; + ctrlParent _control closeDisplay 2; + {[player, player, true] call FUNC(openBox)} call CBA_fnc_execNextFrame; + true +} call EFUNC(common,codeToString)]; + +true diff --git a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf new file mode 100644 index 0000000000..111202d04e --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf @@ -0,0 +1,175 @@ +#include "script_component.hpp" + +params ["_unit"]; + +private _loadout = profileNamespace getVariable QGVAR(missionLastLoadout); + +if (!isNil "_loadout") then { + _unit setUnitLoadout _loadout; +}; + +_unit allowDamage false; + +//--- Static targets in various distance +{ + private _position = _unit getRelPos [_x, _forEachIndex]; + ["O_Soldier_VR_F", _position] call FUNC(createTarget); +} forEach [10, 20, 30, 40, 50, 100, 500, 1000, 2000]; + +//--- Target line +private _position = _unit getRelPos [20, -90]; + +for "_i" from 0 to 5 do { + private _position = _position vectorAdd [0, -3 + _i, 0]; + ["O_Soldier_VR_F", _position] call FUNC(createTarget); +}; + +//--- Target cluster +_position = _unit getRelPos [20, 90]; + +for "_i" from 0 to 8 do { + private _index = floor (_i / 3); + private _position = _position vectorAdd [_index * 1.5, 1.5 + (_i % 3), 0]; + + private _target = ["O_Soldier_VR_F", _position] call FUNC(createTarget); + + _target switchMove (["aidlpercmstpslowwrfldnon", "aidlpknlmstpslowwrfldnon_ai", "aidlppnemstpsraswrfldnon_ai"] select _index); + _target setUnitPos (["UP", "MIDDLE", "DOWN"] select _index); +}; + +//--- Target patrol +private _group = createGroup east; + +{ + private _position = _unit getRelPos [10, _x]; + private _waypoint = _group addWaypoint [_position, 0]; + + if (_forEachIndex == 4) then { + _waypoint setWaypointType "CYCLE"; + }; +} forEach [0, 90, 180, 270, 0]; + +_position = _unit getRelPos [10, 180]; + +for "_i" from 0 to 1 do { + private _target = ["O_Soldier_VR_F", _position] call FUNC(createTarget); + + [_target] join _group; + _target stop false; + _target enableAI "MOVE"; + _target setSpeedMode "LIMITED"; +}; + +//--- Armored vehicles +private _vehicles = []; + +private _step = 15; +_position = [position _unit select 0,(position _unit select 1) + 30,0]; + +{ + private _row = _forEachIndex; + private _rowCount = (count _x - 1) * 0.5; + + { + private _position = _position vectorAdd [(-_rowCount + _forEachIndex) * _step, _row * _step, 0]; + + private _vehicle = createVehicle [_x, _position, [], 0, "NONE"]; + _vehicle setPos _position; + _vehicle setDir 180; + _vehicle setVelocity [0,0,-1]; + _vehicle call BIS_fnc_VRHitpart; + + private _marker = _vehicle call BIS_fnc_boundingBoxMarker; + _marker setMarkerColor "ColorOrange"; + _vehicles pushBack _vehicle; + } forEach _x; +} forEach [[ + "Land_VR_Target_MRAP_01_F", + "Land_VR_Target_APC_Wheeled_01_F", + "Land_VR_Target_MBT_01_cannon_F" +], [ + "Land_VR_Target_MRAP_01_F", + "Land_VR_Target_APC_Wheeled_01_F", + "Land_VR_Target_MBT_01_cannon_F" +]]; + +_vehicles spawn { + waituntil { + private _allDisabled = true; + + { + _hitAlive = _x getVariable ["bis_fnc_VRHitParts_hitalive", []]; + _allDisabled = _allDisabled && ({!_x} count _hitAlive >= 2); + sleep 0.1; + } forEach _this; + + _allDisabled + }; + + setStatValue ["MarkMassVirtualDestruction", 1]; +}; + +//--- Cover objects +private _coverObjects = [ + "Land_VR_CoverObject_01_kneel_F", + "Land_VR_CoverObject_01_kneelHigh_F", + "Land_VR_CoverObject_01_kneelLow_F", + "Land_VR_CoverObject_01_stand_F", + "Land_VR_CoverObject_01_standHigh_F" +]; + +for "_i" from 5 to 11 do { + private _direction = 180 + _i * 45; + private _position = _unit getRelPos [(abs sin _direction + abs cos _direction) * 3, _direction]; + private _block = createVehicle [_coverObjects select (_i % count _coverObjects), _position, [], 0, "NONE"]; + _block setPos _position; +}; + +//--- Starting point +private _square = createVehicle ["VR_Area_01_square_1x1_grey_F", position _unit, [], 0, "NONE"]; +_square setPosASL getPosASL _unit; + +private _marker = createMarker [QGVAR(start), getPosWorld _unit]; +_marker setMarkerType "mil_start"; + +//--- Open Arsenal +[_unit, true, false] call FUNC(initBox); + +[{!isNull findDisplay 46}, { + [_this, _this, true] call FUNC(openBox); +}, _unit] call CBA_fnc_waitUntilAndExecute; + +//--- Salute +_unit addEventHandler ["AnimChanged", { + params ["_unit", "_anim"]; + _anim = _anim splitString "_"; + + if ("salute" in _anim) then { + { + _x playAction "salute"; + } forEach ((_unit nearObjects ["CAManBase", 10]) - [_unit]); + }; +}]; + +["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0.1, [0,0.5]] spawn BIS_fnc_textTiles; + +//--- Target markers +private _markers = []; + +{ + private _marker = createMarker [vehicleVarName _x, position _x]; + _marker setMarkerType "mil_dot"; + _marker setMarkerColor "ColorOrange"; + + _markers pushBack _marker; +} forEach (allMissionObjects "CAManBase" - [_unit]); + +_markers spawn { + while {true} do { + { + private _target = missionNamespace getVariable _x; + _x setMarkerPos position _target; + } forEach _this; + sleep 0.1; + }; +}; diff --git a/addons/arsenal/missions/Arsenal.VR/logo_ca.paa b/addons/arsenal/missions/Arsenal.VR/logo_ca.paa new file mode 100644 index 0000000000..0ad1e2dd0f Binary files /dev/null and b/addons/arsenal/missions/Arsenal.VR/logo_ca.paa differ diff --git a/addons/arsenal/missions/Arsenal.VR/mission.sqm b/addons/arsenal/missions/Arsenal.VR/mission.sqm new file mode 100644 index 0000000000..c43d901f6e --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/mission.sqm @@ -0,0 +1,163 @@ +version=12; +class Mission +{ + addOns[]= + { + "A3_Map_VR", + "A3_Characters_F_BLUFOR", + "a3_characters_f_beta", + "a3_characters_f" + }; + addOnsAuto[]= + { + "A3_Characters_F_BLUFOR", + "a3_characters_f", + "A3_Map_VR" + }; + randomSeed=5486937; + class Intel + { + briefingName="@STR_A3_Arsenal"; + startWeather=0; + startWind=0.099999994; + startWaves=0.099999994; + forecastWeather=0; + forecastWind=0.099999994; + forecastWaves=0.099999994; + forecastLightnings=0.099999994; + year=2035; + month=2; + day=24; + hour=12; + minute=0; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; + class Groups + { + items=1; + class Item0 + { + side="CIV"; + class Vehicles + { + items=1; + class Item0 + { + position[]={4256,5,4192}; + azimut=180; + id=0; + side="CIV"; + vehicle="C_man_1"; + player="PLAYER COMMANDER"; + leader=1; + skill=0.60000002; + }; + }; + }; + }; + class Sensors + { + items=1; + class Item0 + { + position[]={4271.2827,5,4170.251}; + a=0; + b=0; + interruptable=1; + age="UNKNOWN"; + expCond="cheat1"; + expActiv="endmission ""end1"""; + class Effects + { + }; + }; + }; +}; +class Intro +{ + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=12455686; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; +}; +class OutroWin +{ + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=9312504; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; +}; +class OutroLoose +{ + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=15192082; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; +}; diff --git a/addons/arsenal/missions/Arsenal.VR/script_component.hpp b/addons/arsenal/missions/Arsenal.VR/script_component.hpp new file mode 100644 index 0000000000..e1e6528a49 --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/script_component.hpp @@ -0,0 +1,4 @@ +#include "\z\ace\addons\arsenal\script_component.hpp" + +#undef PREP // make.py can't redefine already defined macros +#define PREP(var) FUNC(var) = compileFinal preprocessFileLineNumbers format ["fnc_%1.sqf", QUOTE(var)] diff --git a/addons/arsenal/script_component.hpp b/addons/arsenal/script_component.hpp new file mode 100644 index 0000000000..2eb9c3f170 --- /dev/null +++ b/addons/arsenal/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT arsenal +#define COMPONENT_BEAUTIFIED Arsenal +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_ARSENAL + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_ARSENAL + #define DEBUG_SETTINGS DEBUG_SETTINGS_ARSENAL +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml new file mode 100644 index 0000000000..e4c19a07b4 --- /dev/null +++ b/addons/arsenal/stringtable.xml @@ -0,0 +1,556 @@ + + + + + Hide + Cacher + Verstecken + Ukryj + 非表示 + Nascondere + 숨김 + + + Hide interface + Cache l'interface + Oberfläche verstecken + Ukryj interfejs + インターフェイスを隠す + Nascondi interfaccia + 인터페이스 숨기기 + + + Loadouts + Équipements + Ausrüstungen + Zestawy wyposażenia + 装備 + Equipaggiamenti + 로드아웃 + + + Export + Exporter + Exportieren + Eksportuj + 出力 + Esporta + 내보내기 + + + Import + Importer + Importieren + Importuj + 取込 + Importa + 가져오기 + + + Close + Fermer + Schließen + Zamknij + 閉じる + Chiudi + 닫기 + + + No virtual item available + Aucun objet virtuel disponible + Kein virtuelles Objekt verfügbar + Brak dostępnych przedmiotów wirtualnych + 利用可能なバーチャル アイテムは無し + Nessun oggetto virtuale disponibile + 가상장비 사용 불가 + + + Save + Enregister + Speichern + Zapisz + 保存 + Salva + 저장 + + + Save the current loadout + Enregistre l'équipement actuel + Ausgewählte Ausrüstung speichern + Zapisz obecny zestaw + 現在の装備を保存します + Salva l'equipaggiamento corrente + 현재 로드아웃 저장 + + + Rename + Renommer + Umbenennen + Zmień nazwę + 改名 + Rinomina + 이름바꾸기 + + + Rename the selected loadout + Renomme l'équipement sélectionné + Ausgewählte Ausrüstung umbenennen + Zmień nazwę wybranego zestawu + 現在選択中の装備を改名します + Rinomina l'equipaggiamento selezionato + 선택한 로드아웃의 이름 바꾸기 + + + Load + Charger + Laden + Wczytaj + 読み込む + Carica + 불러오기 + + + Load the selected loadout + Charger l'équipement sélectionné + Ausgewählte Ausrüstung laden + Wczytaj wybrany zestaw + 現在選択中の装備を読み込みます + Carica l'equipaggiamento selezionato + 선택한 로드아웃 불러오기 + + + Delete + Supprimer + Entfernen + Skasuj + 削除 + Elimina + 삭제 + + + Delete the selected loadout + Supprimer l'équipement sélectionné + Ausgewählte Ausrüstung entfernen + Skasuj wybrany zestaw + 現在選択中の装備を削除します + Elimina l'equipaggiamento selezionato + 선택한 로드아웃 삭제하기 + + + My loadouts + Mes équipements + Meine Ausrüstungen + Moje zestawy + 自分の装備 + I miei equipaggiamenti + 내 로드아웃 + + + Loadouts saved in your profile + Équipements enregistrés dans votre profil + Ausrüstungen, die in deinem Profil gespeichert sind + Zestawy zapisane w Twoim profilu + 自プロフィールに保存された装備です + Gli equipaggiamenti salvati nel tuo profilo + 프로필에 저장된 로드아웃 + + + Default loadouts + Équipements de base + Standard-Ausrüstungen + Domyślne zestawy + 標準の装備 + Equipaggiamenti standard + 기본 로드아웃 + + + Loadouts made available by the mission maker + Équipements faits par l'auteur de la mission + Ausrüstungen, die durch den Missionsersteller zur Verfügung gestellt worden sind + Zestawy udostępnione przez twórcę misji + 装備はミッション著者によって利用できます + Equipaggiamenti resi disponibili dal creatore della missione + 미션메이커가 허용한 로드아웃 + + + Public loadouts + Équipements publics + Veröffentlichte Ausrüstungen + Publiczne zestawy + 公開装備 + Equipaggiamenti pubblici + 공용 로드아웃 + + + Loadouts shared by you and other players + Équipements mis à disposition par vous ou les autres joueurs + Ausrüstungen, die von dir und anderen Spielern geteilt wurden + Zestawy udostępnione przez Ciebie i innych graczy + 自分か他人によって共有された装備です + Equipaggiamenti condivisi da te e da altri giocatori + 플레이어들이 공유하는 로드아웃 + + + Sort by weight + Trier par poids + Nach Gewicht sortieren + Sortuj wg wagi + 重量で並び替え + Ordina per peso + 무게로 정렬 + + + Sort by amount + Trier par quantité + Nach Menge sortieren + Sortuj wg ilości + 量で並び替え + Ordina per quantitativo + 갯수로 정렬 + + + Share or stop sharing the selected loadout + Partager ou arrêter de partager cet équipement + Ausgewählte Ausrüstung teilen oder nicht mehr teilen + Udostępnij lub przestań udostępniać wybrany zestaw + 選択した装備の共有設定 + Condividi o smetti di condividere l'equipaggiamento selezionato + 선택한 로드아웃 공유 혹은 공유중지 + + + Private + Privé + Privat + Prywatny + 非公開 + Privato + 개인 + + + Public + Public + Öffentlich + Publiczny + 公開 + Pubblico + 공용 + + + The default loadouts list is empty! + La liste d'équipements de base est vide ! + Die Standard-Ausrüstungen-Liste ist leer! + Lista domyślnych zestawów jest pusta! + 標準の装備一欄が空です! + La lista degli equipaggiamenti standard è vuota! + 기본 로드아웃 목록이 비어있습니다! + + + Default loadouts list exported to clipboard + Liste d'équipements de base exportée dans le presse papier + Standard-Ausrüstungen-Liste in die Zwischenablage exportiert + Lista domyślnych zestawów została eksportowana do schowka + 標準の装備一欄はクリップボードへ出力されました + La lista degli equipaggiamenti standard è stata esportata negli appunti + 클립보드에 기본 로드아웃 목록 내보내기 + + + Current loadout exported to clipboard + Équipement actuel exporté dans le presse papier + Derzeitige Ausrüstung in die Zwischenablage exportiert + Obecny zestaw został eksportowany do schowka + 現在の装備はクリップボードへ出力されました + Equipaggiamento corrente esportato negli appunti + 현재 로드아웃을 클립보드로 내보냈습니다. + + + Wrong format provided + Mauvais format fourni + Falsches Format verwendet + Podano zły format + 間違ったフォーマットが入力されました + Formato fornito sbagliato + 잘못된 형식 입력됨 + + + Default loadouts list imported from clipboard + Liste d'équipements de base importée depuis le presse papier + Standard-Ausrüstungen-Liste aus der Zwischenablage importiert + Lista domyślnych zestawów została importowana ze schowka + 標準の装備一欄はクリップボードから取込されました + La lista degli equipaggiamenti standard è stata importata dagli appunti + 클립보드에서 기본 로드아웃 가져오기 + + + Loadout imported from clipboard + Équipement importé depuis le presse papier + Ausrüstung aus der Zwischenablage importiert + Zestaw został importowany ze schowka + 装備はクリップボードから取込されました + Equipaggiamento importato dagli appunti + 클립보드에서 로드아웃을 가져왔습니다. + + + The following loadout was deleted: + L'équipement suivant fut supprimé: + Folgende Ausrüstung wurde entfernt: + Następujący zestaw został skasowany: + 次の装備は削除されました: + Il seguente equipaggiamento è stato eliminato: + 다음 로드아웃이 삭제됨 : + + + The following loadout is not public anymore: + L'équipement suivant n'est plus public: + Folgende Ausrüstung ist nicht mehr öffentlich: + Następujący zestaw nie jest już publiczny: + 次の装備は非公開になりました: + Il seguente eequipaggiamento non è più pubblico: + 다음 로드아웃이 더이상 공용이 아님: + + + The name field is empty! + Le champ nom est vide ! + Das Feld "Name" ist leer! + Pole nazwy jest puste! + 名前欄が空白です! + Il campo del nome è vuoto! + 이름칸이 비었습니다! + + + You are the author of this loadout + Vous êtes l'auteur de cet équipement + Du bist der Ersteller dieser Ausrüstung + Jesteś autorem tego zestawu + あなたはこの装備の作者です + Sei l'autore di questo equipaggiamento + 이 로드아웃의 제작자입니다. + + + A loadout of yours with the same name is public + Un de vos équipements avec le même nom est public + Eine deiner Ausrüstungen mit dem gleichen Namen ist öffentlich + Jeden z Twoich zestawów nazwany tak samo jest już publiczny + あなたの装備は既に公開されているものと同名です + Un tuo equipaggiamento con lo stesso nome è pubblico + 같은 이름의 로드아웃이 공용에 있습니다. + + + The following loadout was saved: + L'équipement suivant fut enregistré: + Folgende Ausrüstung wurde gespeichert: + Następujący zestaw został zapisany: + 次の装備は保存されました: + Il seguente equipaggiamento è stato salvato: + 다음 로드아웃이 저장됨: + + + The following loadout was loaded: + L'équipement suivant fut chargé: + Folgene Ausrüstung wurde geladen: + Następujący zestaw został wczytany: + 次の装備が読み込みされました: + Il seguente equipaggiamento è stato caricato: + 다음 로드아웃을 불러옴: + + + A loadout with the same name already exist! + Un équipement avec le même nom existe déjà ! + Eine Ausrüstung mit dem gleichen Namen existiert bereits! + Zestaw z tą nazwą już istnieje! + 既にその名前は装備に使われています! + Un equipaggiamento con lo stesso nome è gia esistente! + 같은 이름의 로드아웃이 이미 존재합니다! + + + was renamed to + fut renommé en + wurde umbenannt in + zmienił nazwę na + 次の名前に改名されました + E' stato rinominato in + 이름이 다음과 같이 변경됨: + + + Invert camera controls + Inverser les contrôles de la caméra + Kamerasteuerung invertieren + Odwróć sterowanie kamerą + カメラ操作を反転 + Inverti comandi camera + 카메라 조종 반전 + + + Enable mod icons + Afficher les icônes de mod + Aktiviert Mod-Icons + Włącz ikony modów + MOD アイコンを表示 + Abilita icone mod + 모드 아이콘 허가 + + + Panel font height + taille de police des panneaux + Schrifthöhe für die linke und rechte Liste + Wysokość czcionki + パネルにあるフォントの高さ + Altezza carattere del pannello + 패널 폰트 높이 + + + Allow default loadouts + Activer l'onglet équipement de base + Erlaubt die Benutzung der Standardausrüstungen + Zezwól na użycie domyślnych zestawów + 標準の装備を許可 + Consenti equipaggiamenti standard + 기본 로드아웃 허용 + + + Allow loadout sharing + Autoriser le partage d'équipement + Erlaubt das Teilen von Ausrüstungen + Zezwól na udostępnianie zestawów + 装備の共有を許可 + Consenti condivisione equipaggiamenti + 로드아웃 공유 허용 + + + Log missing / unavailable items + Enregistrer les objets manquants + Aktiviert die Aufzeichnung fehlender Gegenstände in der RPT + Rejestruj brakujące / niedostępne przedmioty + 欠落 / 利用不可アイテムを記録 + Log mancante / oggetto non disponibile + 누락 된 항목 / 사용 할 수 없는 항목 기록 + + + Primary magazine + Chargeur principal + Główny magazynek + プライマリ弾倉 + Caricatore primario + 주무기 탄약 + Primärmagazin + + + Secondary magazine + Chargeur secondaire + Dodatkowy magazynek + セカンダリ弾倉 + Caricatore secondario + 보조무기 탄약 + Sekundärmagazin + + + ACE Arsenal + ACE Arsenal + ACE-Arsenal + ACE Arsenał + ACE 武器庫 + Arsenale ACE + ACE 아스날 + + + Allow the use of the default loadouts tab + Autorise l'usage de l'onglet équipements de base + Zezwól na użycie zakładki domyślnych zestawów + 標準の装備タブの使用を許可します + Consenti l'uso della sezione per gli equipaggiamenti standard + 기본 로드아웃 탭 사용 허가 + Erlaube die Nutzung des Standardausrüstungsreiters + + + Show / hide mod icons for the left panel + Montrer / cacher les icones de mod pour le panneau de gauche + Pokaż / ukryj ikony modów w lewym panelu + 左パネルにある MOD アイコンの表示 / 非表示をします + Mostra / nascondi le icone delle mod dal pannello sinistro + 왼쪽 패널의 모드 아이콘 표시 / 숨기기 + Zeigt/Versteckt Mod-Symbole in der linken Leiste + + + Change the font height for text in the left / right panels + Change la taille de police du texte des panneaux gauche / droite + Zmień wysokość czcionki dla tekstu lewego i prawego panelu + 右か左パネルにあるフォントの高さを変更します。 + Cambia l'altezza del font per il testo sul pannello sinistro / destro + 왼쪽 / 오른쪽 패널 텍스트의 글꼴 높이 변경 + Ändert die Schriftgröße für die linke/rechte Leiste + + + Log missing / unavailable items in the RPT + Enregistre les objets manquants / indisponibles dans le RPT + Rejestruj brakujące / niedostępne przedmioty do pliku RPT + PRT で欠落 / 利用不可アイテムを記録します + Log mancante / oggetto non disponibile nell' RPT + RPT에 누락 된 항목 / 사용할 수없는 항목 기록 + Fehlende Gegenstände werden in der RPT aufgezeichnet + + + Unable to open ACE arsenal + Impossible d'ouvrir ACE arsenal + Kann ACE-Arsenal nicht anzeigen + Impossibile aprire l'arsenale ACE + ACE 武器庫を開けません + ACE 아스날을 열 수 없음 + + + Import BI VA loadouts to ACE Arsenal + Importe les loadouts de BI VA dans ACE Arsenal + Importiert die BI-VA-Ausrüstungen in das ACE-Arsenal + 標準の VA 装備から ACE 武器庫へ取り込み + 바닐라 로드아웃을 ace 아스날로 가져오기 + + + No player unit available! Place a unit and mark it as "Player". + Aucune unité joueur disponible ! Placez une unité et marquez la en tant que "joueur". + Keine Spielereinheit verfügbar. Setze eine Einheit und markiere sie als "Spieler". + プレイヤー ユニットがありません!ユニットを設置しそれを"Player"と名付けてください。 + 플레이어 유닛을 사용할 수 없습니다! 유닛을 놓고 "플레이어"라고 표시하십시오. + + + No loadouts to import. + Aucun loadout à importer. + Keine Ausrüstungen zum Importieren + 取り込みする装備がありません。 + 가져올 로드 아웃이 없습니다. + + + ACE Arsenal + ACE-Arsenal + ACE 武器庫 + ACE 아스날 + + + Return to ACE Arsenal. + Zurück zum ACE-Arsenal. + ACE 武器庫へ戻ります。 + ACE 아스날로 돌아가기 + + + Use ACE Arsenal to try out different weapons and equipment. + Verwende ACE-Arsenal und sieh dir verschiedene Waffen und Ausrüstung an und probiere sie aus. + さまざまな武器と装備を試せるよう ACE 武器庫を使用します。 + ACE Arsenal을 사용하여 다른 무기와 장비를 시험해보십시오. + + + Try weapons and equipment and create your own loadouts. + Probiere verschiedene Waffen und Ausrüstung aus und stelle dir eigene Ausrüstungsprofile zusammen. + さまざまな武器と装備を試して、あなただけの装備を作成してください。 + 무기와 장비를 사용해보고 자신의 로드아웃을 만듭니다. + + + Open the loadouts screen + Affiche la page des équipements + + + Export current / default loadouts + Exporte l'équipement actuel ou la liste d'équipements de base + + + Import current / default loadouts + Importer l'équipement actuel ou la liste d'équipements de base + + + diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp new file mode 100644 index 0000000000..e9c4f1f6b4 --- /dev/null +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -0,0 +1,928 @@ +#include "RscCommon.hpp" +#include "..\defines.hpp" + +class GVAR(display) { + idd = IDD_ace_arsenal; + enableSimulation=1; + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(display))] call FUNC(onArsenalOpen)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(display))] call FUNC(onArsenalClose)); + onKeyDown = QUOTE([ARR_3('onKeyDown', _this, QQGVAR(display))] call FUNC(onKeyDown)); + onKeyUp = QUOTE(GVAR(shiftState) = _this select 2); + onMouseButtonDown = QUOTE([ARR_3('onMouseButtonDown', _this, QQGVAR(display))] call FUNC(onMouseButtonDown)); + onMouseButtonUp = QUOTE([ARR_3('onMouseButtonUp', _this, QQGVAR(display))] call FUNC(onMouseButtonUp)); + icon="\A3\Ui_f\data\Logos\a_64_ca.paa"; + logo="\A3\Ui_f\data\Logos\arsenal_1024_ca.paa"; + class ControlsBackground { + class blackLeft: ctrlStatic { + colorBackground[]={0,0,0,1}; + x = QUOTE(safezoneXAbs); + y = QUOTE(safezoneY); + w = QUOTE(safezoneXAbs - safezoneX); + h = QUOTE(safezoneH); + }; + + class blackRight: blackLeft { + x = QUOTE(safezoneX + safezoneW); + }; + + class mouseArea: ctrlStatic { + idc = IDC_mouseArea; + style = 16; + onMouseMoving = QUOTE([ARR_3('onMouseMoving', _this, GVAR(display))] call FUNC(handleMouse)); + onMouseHolding = QUOTE([ARR_3('onMouseHolding', _this, GVAR(display))] call FUNC(handleMouse)); + onMouseZChanged = QUOTE([ARR_3('onMouseZChanged', _this, GVAR(display))] call FUNC(handleScrollWheel)); + x = QUOTE(safezoneX); + y = QUOTE(safezoneY); + w = QUOTE(safezoneW); + h = QUOTE(safezoneH); + }; + }; + class controls { + class ArrowLeft: ctrlButton { + idc = IDC_arrowMinus; + text = "-"; + colorBackground[]={0,0,0,0.8}; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), -1)] call FUNC(buttonCargo)); + fade = 1; + enable = 0; + x = 0.5; + y = 0.5; + w = QUOTE(1 * GRID_W); + h = QUOTE(1 * GRID_H); + sizeEx = QUOTE(7 * GRID_H); + }; + class ArrowRight: ArrowLeft { + idc = IDC_arrowPlus; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), 1)] call FUNC(buttonCargo)); + text="+"; + }; + class blockLeftFrame: RscFrame { + idc = IDC_blockLeftFrame; + x = QUOTE(safezoneX + 13 * GRID_W); + y = QUOTE(safezoneY + 14 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(safezoneH - 24 * GRID_H); + colorText[] = {0,0,0,1}; + }; + class blockLeftBackground: ctrlStaticBackground { + idc = IDC_blockLeftBackground; + x = QUOTE(safezoneX + 13 * GRID_W); + y = QUOTE(safezoneY + 14 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(safezoneH - 24 * GRID_H); + colorBackground[] = {0,0,0,0.5}; + }; + class blockRightFrame: blockLeftFrame { + idc = IDC_blockRightFrame; + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + h = QUOTE(safezoneH - 34 * GRID_H); + }; + class blockRighttBackground: blockLeftBackground { + idc = IDC_blockRighttBackground; + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + h = QUOTE(safezoneH - 34 * GRID_H); + }; + class loadIndicator: RscControlsGroupNoScrollbars { + idc = IDC_loadIndicator; + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + y = QUOTE(safeZoneH + safezoneY - 20 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(6 * GRID_H); + class controls { + class loadIndicatorBackground: ctrlStaticBackground { + idc = -1; + colorBackground[] = {0,0,0,0.5}; + x = 0; + y = 0; + w = QUOTE(80 * GRID_W); + h = QUOTE(6 * GRID_H); + }; + class loadIndicatorBar: ctrlProgress { + idc = IDC_loadIndicatorBar; + style = 0; + texture = "#(argb,8,8,3)color(1,1,1,1)"; + colorBar[] = {1,1,1,1}; + colorFrame[] = {0,0,0,1}; + x = 0; + y = 0; + w = QUOTE(80 * GRID_W); + h = QUOTE(6 * GRID_H); + }; + }; + }; + class totalWeight: RscControlsGroupNoScrollbars { + idc = IDC_totalWeight; + x = QUOTE(safezoneX + 13 * GRID_W); + y = QUOTE(safeZoneH + safezoneY - 10 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(8 * GRID_H); + class controls { + class totalWeightBackground: ctrlStaticBackground { + idc = -1; + colorBackground[] = {0,0,0,0.8}; + x = 0; + y = 0; + w = QUOTE(80 * GRID_W); + h = QUOTE(8 * GRID_H); + }; + class totalWeightTitle: RscText { + idc = -1; + text = ECSTRING(common,Weight); + x = 0; + y = 0; + w = QUOTE(30 * GRID_W); + h = QUOTE(8 * GRID_H); + sizeEx = QUOTE(7 * GRID_H); + }; + class totalWeightText: RscText { + idc = IDC_totalWeightText; + style = ST_RIGHT; + text = ""; + x = QUOTE(30 * GRID_W); + y = 0; + w = QUOTE(50 * GRID_W); + h = QUOTE(8 * GRID_H); + sizeEx = QUOTE(7 * GRID_H); + }; + }; + }; + class message: RscText { + idc = IDC_message; + fade = 1; + style=2; + shadow=0; + colorBackground[]={0,0,0,0.69999999}; + text=""; + x = QUOTE(0.5 - WIDTH_TOTAL / 2); + y = QUOTE(safeZoneH + safezoneY - 25 * GRID_H); + w = QUOTE(WIDTH_TOTAL); + h = QUOTE(10 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + }; + class menuBar: RscControlsGroupNoScrollbars { + idc = IDC_menuBar; + x = QUOTE(0.5 - WIDTH_TOTAL / 2); + y = QUOTE(safezoneH + safezoneY - 9 * GRID_H); + w = QUOTE(WIDTH_TOTAL); + h = QUOTE(7 * GRID_H); + class controls { + class buttonHide: ctrlButton { + idc = IDC_buttonHide; + colorBackground[] = {0,0,0,0.8}; + x = QUOTE(1 * WIDTH_GAP + 0 * WIDTH_SINGLE); + y = QUOTE(0); + w = QUOTE(WIDTH_SINGLE); + h = QUOTE(7 * GRID_H); + text = CSTRING(buttonHideText); + sizeEx = QUOTE(5 * GRID_H); + shortcuts[] = {"0x0E"}; + tooltip = CSTRING(buttonHideTooltip); + onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonHide)); + }; + class buttonLoadouts: buttonHide { + idc = IDC_buttonLoadouts; + x = QUOTE(2 * WIDTH_GAP + 1 * WIDTH_SINGLE); + text = CSTRING(buttonLoadoutsText); + tooltip = CSTRING(buttonLoadoutsTooltip); + onButtonClick = QUOTE(createDialog QQGVAR(loadoutsDisplay)); + }; + class buttonExport: buttonHide { + idc = IDC_buttonExport; + x = QUOTE(3 * WIDTH_GAP + 2 * WIDTH_SINGLE); + text = CSTRING(buttonExportText); + tooltip = CSTRING(buttonExportTooltip); + onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonExport)); + }; + class buttonImport: buttonHide { + idc = IDC_buttonImport; + x = QUOTE(4 * WIDTH_GAP + 3 * WIDTH_SINGLE); + text = CSTRING(buttonImportText); + tooltip = CSTRING(buttonImportTooltip); + onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonImport)); + }; + class buttonClose: ctrlButtonOK { + idc = IDC_menuBarClose; + colorBackground[] = {0,0,0,0.8}; + x = QUOTE(5 * WIDTH_GAP + 4 * WIDTH_SINGLE); + y = QUOTE(0); + w = QUOTE(WIDTH_SINGLE); + h = QUOTE(7 * GRID_H); + text = CSTRING(buttonCloseText); + sizeEx = QUOTE(5 * GRID_H); + onButtonClick = QUOTE(ctrlparent (_this select 0) closeDisplay 1); + }; + }; + }; + class infoBox: RscControlsGroupNoScrollbars { + idc = IDC_infoBox; + fade = 1; + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + y = QUOTE(safeZoneH + safezoneY - 14 * GRID_H); + w = QUOTE(92 * GRID_W); + h = QUOTE(12 * GRID_H); + class controls { + class infoBackground: ctrlStaticBackground { + idc = IDC_infoBackground; + x = QUOTE(0 * GRID_W); + y = QUOTE(0); + w = QUOTE(80 * GRID_W); + h = QUOTE(12 * GRID_H); + colorBackground[] = {0,0,0,0.8}; + }; + class infoName: RscText { + idc = IDC_infoName; + x = QUOTE(0 * GRID_W); + y = QUOTE(0); + w = QUOTE(80 * GRID_W); + h = QUOTE(7 * GRID_H); + sizeEx = QUOTE(5.5 * GRID_H); + }; + class infoAuthor: RscText { + idc = IDC_infoAuthor; + colorText[] = {1,1,1,0.5}; + x = QUOTE(0 * GRID_W); + y = QUOTE(6 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(5 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + }; + class DLCBackground: ctrlStaticBackground { + idc = IDC_DLCBackground; + fade = 1; + x = QUOTE(80 * GRID_W); + y = QUOTE(0); + w = QUOTE(12 * GRID_W); + h = QUOTE(12 * GRID_H); + }; + class DLCIcon: RscActivePicture { + idc = IDC_DLCIcon; + enabled = 0; + fade = 1; + color[] = {1,1,1,1}; + colorActive[] = {1,1,1,1}; + text="#(argb,8,8,3)color(1,1,1,1)"; + x = QUOTE(80 * GRID_W); + y = QUOTE(0); + w = QUOTE(12 * GRID_W); + h = QUOTE(12 * GRID_H); + }; + }; + }; + class mouseBlock: RscText { + idc = IDC_mouseBlock; + style = 16; + x = QUOTE(safezoneX); + y = QUOTE(safezoneY); + w = QUOTE(safezoneW); + h = QUOTE(safezoneH); + }; + class leftTabContent: RscListBox { + idc = IDC_leftTabContent; + colorBackground[]={0,0,0,0}; + colorSelectBackground[]={1,1,1,0.5}; + colorSelectBackground2[]={1,1,1,0.5}; + colorPictureSelected[]={1,1,1,1}; + colorSelect[]={1,1,1,1}; + colorSelect2[]={1,1,1,1}; + colorPictureRightSelected[]={1,1,1,1}; + onLBSelChanged = QUOTE(_this call FUNC(onSelChangedLeft)); + onSetFocus = QUOTE(GVAR(leftTabFocus) = true); + onKillFocus = QUOTE(GVAR(leftTabFocus) = false); + x = QUOTE(safezoneX + 13 * GRID_W); + y = QUOTE(safezoneY + 14 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(safezoneH - 24.5 * GRID_H); + sizeEx = QUOTE(7 * GRID_H); + }; + class rightTabContent: leftTabContent { + idc = IDC_rightTabContent; + drawSideArrows=1; + disableOverflow=1; + onLBSelChanged = QUOTE(_this call FUNC(onSelChangedRight)); + onSetFocus = QUOTE(GVAR(rightTabFocus) = true); + onKillFocus = QUOTE(GVAR(rightTabFocus) = false); + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + h = QUOTE(safezoneH - 34.5 * GRID_H); + }; + class rightTabContentListnBox : RscListNBox { + idc = IDC_rightTabContentListnBox; + colorBackground[]={0,0,0,0}; + colorSelectBackground[]={1,1,1,0.5}; + colorSelectBackground2[]={1,1,1,0.5}; + colorPictureSelected[]={1,1,1,1}; + colorSelect[]={1,1,1,1}; + colorSelect2[]={1,1,1,1}; + colorPictureRightSelected[]={1,1,1,1}; + columns[]={0.07, 0.15, 0.75}; + idcLeft = IDC_arrowMinus; + idcRIght = IDC_arrowPlus; + drawSideArrows=1; + disableOverflow=1; + onLBSelChanged = QUOTE(_this call FUNC(onSelChangedRightListnBox)); + onSetFocus = QUOTE(GVAR(rightTabLnBFocus) = true); + onKillFocus = QUOTE(GVAR(rightTabLnBFocus) = false); + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + y = QUOTE(safezoneY + 14 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(safezoneH - 34.5 * GRID_H); + sizeEx = QUOTE(7 * GRID_H); + }; + class sortLeftTab: RscCombo { + idc = IDC_sortLeftTab; + x = QUOTE(safezoneX + 13 * GRID_W); + y = QUOTE(safezoneY + 8 * GRID_H); + w = QUOTE(80 * GRID_W); + h = QUOTE(6 * GRID_H); + onLBSelChanged = QUOTE(_this call FUNC(sortPanel)); + sizeEx = QUOTE(5 * GRID_H); + class Items { + class Alphabet { + text="$STR_a3_rscdisplayarsenal_sort_alphabet"; + default=1; + value= 0; + }; + class Mod { + text="$STR_a3_rscdisplayarsenal_sort_mod"; + value= 1; + }; + }; + }; + class sortRightTab: sortLeftTab { + idc = IDC_sortRightTab; + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + class Items { + class Alphabet { + text="$STR_a3_rscdisplayarsenal_sort_alphabet"; + default=1; + value= 0; + }; + class Weight { + text="$STR_a3_rscdisplayarsenal_sort_mod"; + value= 1; + }; + }; + }; + class leftSearchbar: ctrlEdit { + idc = IDC_leftSearchbar; + onSetFocus = QUOTE(GVAR(leftSearchbarFocus) = true); + onKillFocus = QUOTE(GVAR(leftSearchbarFocus) = false); + onMouseButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(clearSearchbar)); + x = QUOTE(safezoneX + 13 * GRID_W); + y = QUOTE(safezoneY + 1.8 * GRID_H); + w = QUOTE(74 * GRID_W); + h = QUOTE(6 * GRID_H); + }; + class leftSearchbarButton: ctrlButtonPicture { + idc = IDC_leftSearchbarButton; + text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; + colorBackground[]={0,0,0,0.5}; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), ctrlparent (_this select 0) displayCtrl IDC_leftSearchbar)] call FUNC(handleSearchbar)); + x = QUOTE(safezoneX + 87 * GRID_W); + y = QUOTE(safezoneY + 1.8 * GRID_H); + w = QUOTE(6 * GRID_W); + h = QUOTE(6 * GRID_H); + }; + class rightSearchbar: leftSearchBar { + idc = IDC_rightSearchbar; + onSetFocus = QUOTE(GVAR(rightSearchbarFocus) = true); + onKillFocus = QUOTE(GVAR(rightSearchbarFocus) = false); + x = QUOTE(safezoneX + safezoneW - 87 * GRID_W); + }; + class rightSearchbarButton: leftSearchbarButton { + idc = IDC_rightSearchbarButton; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), ctrlparent (_this select 0) displayCtrl IDC_rightSearchbar)] call FUNC(handleSearchbar)); + x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); + }; + class tabLeft: RscControlsGroupNoScrollbars { + idc = IDC_tabLeft; + x = QUOTE(safezoneX + 1 * GRID_W); + y = QUOTE(safezoneY + 8 * GRID_H); + w = QUOTE(12 * GRID_W); + h = QUOTE(200 * GRID_H); + class controls { + class iconBackgroundPrimaryWeapon: ctrlStaticBackground { + idc = IDC_iconBackgroundPrimaryWeapon; + fade=1; + enable=0; + colorBackground[]={0,0,0,1}; + x = QUOTE(0); + y = QUOTE(0 * GRID_H); + w = QUOTE(12 * GRID_W); + h = QUOTE(9 * GRID_H); + }; + class buttonPrimaryWeapon: RscButtonArsenal { + idc = IDC_buttonPrimaryWeapon; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_PrimaryWeapon"; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(fillLeftPanel)); + colorBackground[]={0,0,0,0.5}; + x = QUOTE(0 * GRID_W); + y = QUOTE(0 * GRID_H); + w = QUOTE(9 * GRID_W); + h = QUOTE(9 * GRID_H); + }; + class iconBackgroundHandgun: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundHandgun; + y = QUOTE(10 * GRID_H); + }; + class buttonHandgun: buttonPrimaryWeapon { + idc = IDC_buttonHandgun; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Handgun_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_Handgun"; + y = QUOTE(10 * GRID_H); + }; + class iconBackgroundSecondaryWeapon: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundSecondaryWeapon; + y = QUOTE(20 * GRID_H); + }; + class buttonSecondaryWeapon: buttonPrimaryWeapon { + idc = IDC_buttonSecondaryWeapon; + tooltip="$STR_A3_RscDisplayArsenal_tab_SecondaryWeapon"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\SecondaryWeapon_ca.paa"; + y = QUOTE(20 * GRID_H); + }; + class iconBackgroundHeadgear: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundHeadgear; + y = QUOTE(30 * GRID_H); + }; + class buttonHeadgear: buttonPrimaryWeapon { + idc = IDC_buttonHeadgear; + tooltip="$STR_A3_RscDisplayArsenal_tab_Headgear"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Headgear_ca.paa"; + y = QUOTE(30 * GRID_H); + }; + class iconBackgroundUniform: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundUniform; + y = QUOTE(40 * GRID_H); + }; + class buttonUniform: buttonPrimaryWeapon { + idc = IDC_buttonUniform; + tooltip="$STR_A3_RscDisplayArsenal_tab_Uniform"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Uniform_ca.paa"; + y = QUOTE(40 * GRID_H); + }; + class iconBackgroundVest: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundVest; + y = QUOTE(50 * GRID_H); + }; + class buttonVest: buttonPrimaryWeapon { + idc = IDC_buttonVest; + tooltip="$STR_A3_RscDisplayArsenal_tab_Vest"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Vest_ca.paa"; + y = QUOTE(50 * GRID_H); + }; + class iconBackgroundBackpack: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundBackpack; + y = QUOTE(60 * GRID_H); + }; + class buttonBackpack: buttonPrimaryWeapon { + idc = IDC_buttonBackpack; + tooltip="$STR_A3_RscDisplayArsenal_tab_Backpack"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Backpack_ca.paa"; + y = QUOTE(60 * GRID_H); + }; + class iconBackgroundGoggles: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundGoggles; + y = QUOTE(70 * GRID_H); + }; + class buttonGoggles: buttonPrimaryWeapon { + idc = IDC_buttonGoggles; + tooltip="$STR_A3_RscDisplayArsenal_tab_Goggles"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Goggles_ca.paa"; + y = QUOTE(70 * GRID_H); + }; + class iconBackgroundNVG: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundNVG; + y = QUOTE(80 * GRID_H); + }; + class buttonNVG: buttonPrimaryWeapon { + idc = IDC_buttonNVG; + tooltip="$STR_A3_RscDisplayArsenal_tab_NVGs"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\NVGs_ca.paa"; + y = QUOTE(80 * GRID_H); + }; + class iconBackgroundBinoculars: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundBinoculars; + y = QUOTE(90 * GRID_H); + }; + class buttonBinoculars: buttonPrimaryWeapon { + idc = IDC_buttonBinoculars; + tooltip="$STR_A3_RscDisplayArsenal_tab_Binoculars"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Binoculars_ca.paa"; + y = QUOTE(90 * GRID_H); + }; + class iconBackgroundMap: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundMap; + y = QUOTE(100 * GRID_H); + }; + class buttonMap: buttonPrimaryWeapon { + idc = IDC_buttonMap; + tooltip="$STR_A3_RscDisplayArsenal_tab_Map"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Map_ca.paa"; + y = QUOTE(100 * GRID_H); + }; + class iconBackgroundGPS: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundGPS; + y = QUOTE(110 * GRID_H); + }; + class buttonGPS: buttonPrimaryWeapon { + idc = IDC_buttonGPS; + tooltip="$STR_A3_RscDisplayArsenal_tab_GPS"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\GPS_ca.paa"; + y = QUOTE(110 * GRID_H); + }; + class iconBackgroundRadio: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundRadio; + y = QUOTE(120 * GRID_H); + }; + class buttonRadio: buttonPrimaryWeapon { + idc = IDC_buttonRadio; + tooltip="$STR_A3_RscDisplayArsenal_tab_Radio"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Radio_ca.paa"; + y = QUOTE(120 * GRID_H); + }; + class iconBackgroundCompass: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundCompass; + y = QUOTE(130 * GRID_H); + }; + class buttonCompass: buttonPrimaryWeapon { + idc = IDC_buttonCompass; + tooltip="$STR_A3_RscDisplayArsenal_tab_Compass"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Compass_ca.paa"; + y = QUOTE(130 * GRID_H); + }; + class iconBackgroundWatch: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundWatch; + y = QUOTE(140 * GRID_H); + }; + class buttonWatch: buttonPrimaryWeapon { + idc = IDC_buttonWatch; + tooltip="$STR_A3_RscDisplayArsenal_tab_Watch"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Watch_ca.paa"; + y = QUOTE(140 * GRID_H); + }; + class iconBackgroundFace: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundFace; + y = QUOTE(150 * GRID_H); + }; + class buttonFace: buttonPrimaryWeapon { + idc = IDC_buttonFace; + tooltip="$STR_A3_RscDisplayArsenal_tab_Face"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Face_ca.paa"; + y = QUOTE(150 * GRID_H); + }; + class iconBackgroundVoice: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundVoice; + y = QUOTE(160 * GRID_H); + }; + class buttonVoice: buttonPrimaryWeapon { + idc = IDC_buttonVoice; + tooltip="$STR_A3_RscDisplayArsenal_tab_Voice"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Voice_ca.paa"; + y = QUOTE(160 * GRID_H); + }; + class iconBackgroundInsigna: IconBackgroundPrimaryWeapon { + idc = IDC_iconBackgroundInsigna; + y = QUOTE(170 * GRID_H); + }; + class buttonInsigna: buttonPrimaryWeapon { + idc = IDC_buttonInsigna; + tooltip="$STR_A3_RscDisplayArsenal_tab_Insignia"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Insignia_ca.paa"; + y = QUOTE(170 * GRID_H); + }; + }; + }; + class iconBackgroundOptic: ctrlStaticBackground { + idc = IDC_iconBackgroundOptic; + colorBackground[]={0,0,0,1}; + fade=1; + enable=0; + x = QUOTE(safezoneW + safezoneX - 13 * GRID_W); + y = QUOTE(safezoneY + 8 * GRID_H); + w = QUOTE(12 * GRID_W); + h = QUOTE(9 * GRID_H); + }; + class buttonOptic: RscButtonArsenal { + idc = IDC_buttonOptic; + tooltip="$STR_A3_RscDisplayArsenal_tab_ItemOptic"; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemOptic_ca.paa"; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(fillRightPanel)); + colorBackground[]={0,0,0,0.5}; + x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); + y = QUOTE(safezoneY + 8 * GRID_H); + w = QUOTE(9 * GRID_W); + h = QUOTE(9 * GRID_H); + }; + class iconBackgroundItemAcc: iconBackgroundOptic { + idc = IDC_iconBackgroundItemAcc; + y = QUOTE(safezoneY + 18 * GRID_H); + }; + class buttonItemAcc: buttonOptic { + idc = IDC_buttonItemAcc; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemAcc_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_ItemAcc"; + y = QUOTE(safezoneY + 18 * GRID_H); + }; + class iconBackgroundMuzzle: iconBackgroundOptic { + idc = IDC_iconBackgroundMuzzle; + y = QUOTE(safezoneY + 28 * GRID_H); + }; + class buttonMuzzle: buttonOptic { + idc = IDC_buttonMuzzle; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemMuzzle_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_ItemMuzzle"; + y = QUOTE(safezoneY + 28 * GRID_H); + }; + class iconBackgroundBipod: iconBackgroundOptic { + idc = IDC_iconBackgroundBipod; + y = QUOTE(safezoneY + 38 * GRID_H); + }; + class buttonBipod: buttonOptic { + idc = IDC_buttonBipod; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemBipod_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_ItemBipod"; + y = QUOTE(safezoneY + 38 * GRID_H); + }; + class iconBackgroundCurrentMag: iconBackgroundOptic { + idc = IDC_iconBackgroundCurrentMag; + y = QUOTE(safezoneY + 48 * GRID_H); + }; + class buttonCurrentMag: buttonOptic { + idc = IDC_buttonCurrentMag; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; + tooltip= CSTRING(buttonCurrentMagTooltip); + y = QUOTE(safezoneY + 48 * GRID_H); + }; + class iconBackgroundCurrentMag2: iconBackgroundOptic { + idc = IDC_iconBackgroundCurrentMag2; + y = QUOTE(safezoneY + 58 * GRID_H); + }; + class buttonCurrentMag2: buttonOptic { + idc = IDC_buttonCurrentMag2; + text= QPATHTOF(data\iconSecondaryMuzzle); + tooltip= CSTRING(buttonCurrentMag2Tooltip); + y = QUOTE(safezoneY + 58 * GRID_H); + }; + class iconBackgroundMag: iconBackgroundOptic { + idc = IDC_iconBackgroundMag; + y = QUOTE(safezoneY + 48 * GRID_H); + }; + class buttonMag: buttonOptic { + idc = IDC_buttonMag; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMag"; + y = QUOTE(safezoneY + 48 * GRID_H); + }; + class iconBackgroundMagALL: iconBackgroundOptic { + idc = IDC_iconBackgroundMagALL; + y = QUOTE(safezoneY + 58 * GRID_H); + }; + class buttonMagALL: buttonOptic { + idc = IDC_buttonMagALL; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMagAll_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMagAll"; + y = QUOTE(safezoneY + 58 * GRID_H); + }; + class iconBackgroundThrow: iconBackgroundOptic { + idc = IDC_iconBackgroundThrow; + y = QUOTE(safezoneY + 68 * GRID_H); + }; + class buttonThrow: buttonOptic { + idc = IDC_buttonThrow; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoThrow_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_CargoThrow"; + y = QUOTE(safezoneY + 68 * GRID_H); + }; + class iconBackgroundPut: iconBackgroundOptic { + idc = IDC_iconBackgroundPut; + y = QUOTE(safezoneY + 78 * GRID_H); + }; + class buttonPut: buttonOptic { + idc = IDC_buttonPut; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoPut_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_CargoPut"; + y = QUOTE(safezoneY + 78 * GRID_H); + }; + class iconBackgroundMisc: iconBackgroundOptic { + idc = IDC_iconBackgroundMisc; + y = QUOTE(safezoneY + 88 * GRID_H); + }; + class buttonMisc: buttonOptic { + idc = IDC_buttonMisc; + text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMisc_ca.paa"; + tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMisc"; + y = QUOTE(safezoneY + 88 * GRID_H); + }; + class buttonRemoveAll: ctrlButtonPicture { + idc = IDC_buttonRemoveAll; + text = QPATHTOF(data\iconClearContainer.paa); + colorBackground[]={0,0,0,0.5}; + onButtonClick = QUOTE(ctrlParent (_this select 0) call FUNC(buttonClearAll)); + fade=1; + enable=0; + x = QUOTE(safezoneW + safezoneX - 11 * GRID_W); + y = QUOTE(safeZoneH + safezoneY - 29 * GRID_H); + w = QUOTE(9 * GRID_W); + h = QUOTE(9 * GRID_H); + }; + }; +}; + +class GVAR(loadoutsDisplay) { + idd = IDD_loadouts_display; + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(loadoutsDisplay))] call FUNC(onLoadoutsOpen)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(loadoutsDisplay))] call FUNC(onLoadoutsClose)); + class controls { + class centerBox: ctrlControlsGroupNoScrollbars { + idc = IDC_centerBox; + x = QUOTE(safezoneW + safezoneX - (180 * GRID_W)); + y = QUOTE(safezoneY + (5 * GRID_H)); + w = QUOTE(160 * GRID_W); + h = QUOTE(safezoneH - (34 * GRID_H)); + class controls { + class centerFrame: RscFrame { + idc = -1; + x = QUOTE(0 * GRID_W); + y = QUOTE(0 * GRID_H); + w = QUOTE(160 * GRID_W); + h = QUOTE(safezoneH - (45 * GRID_H)); + colorText[] = {0,0,0,1}; + }; + class centerBackground: ctrlStaticBackground { + idc = -1; + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(160 * GRID_W); + h = QUOTE(safezoneH - (45 * GRID_H)); + colorBackground[] = {0.13,0.13,0.13,0.9}; + }; + class centerTitle: ctrlStaticTitle { + idc = IDC_centerTitle; + style = ST_CENTER; + text = ""; + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(160 * GRID_W); + h = QUOTE(5 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + }; + class contentPanel: RscListnBox { + idc = IDC_contentPanel; + columns[]={0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90}; + drawSideArrows=0; + disableOverflow=1; + onSetFocus = QUOTE(GVAR(loadoutsPanelFocus) = true); + onKillFocus = QUOTE(GVAR(loadoutsPanelFocus) = false); + onLBSelChanged = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(onSelChangedLoadouts)); + onLBDblClick = QUOTE([ARR_2(ctrlparent (_this select 0), (ctrlParent (_this select 0)) displayCtrl IDC_buttonLoad)] call FUNC(buttonLoadoutsLoad)); + x = QUOTE(0); + y = QUOTE(5 * GRID_H); + w = QUOTE(160 * GRID_W); + h = QUOTE(safezoneH - (57 * GRID_H)); + sizeEx = QUOTE(7 * GRID_H); + }; + class textTitle: RscText { + idc= -1; + text="$STR_DISP_GAME_NAME"; + x = QUOTE(0 * GRID_W); + y = QUOTE(safezoneH - (51 * GRID_H)); + w = QUOTE(15 * GRID_W); + h = QUOTE(5 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + colorBackground[]={0,0,0,0.2}; + }; + class textEditBox: ctrlEdit { + idc= IDC_textEditBox; + x = QUOTE(15 * GRID_W); + y = QUOTE(safezoneH - (51 * GRID_H)); + w = QUOTE(65 * GRID_W); + h = QUOTE(5 * GRID_H); + }; + class loadoutsSearchbar: ctrlEdit { + idc = IDC_loadoutsSearchbar; + onSetFocus = QUOTE(GVAR(loadoutsSearchbarFocus) = true); + onKillFocus = QUOTE(GVAR(loadoutsSearchbarFocus) = false); + onMouseButtonClick = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(clearSearchbar)); + x = QUOTE(83 * GRID_W); + y = QUOTE(safezoneH - (51 * GRID_H)); + w = QUOTE(72 * GRID_W); + h = QUOTE(5 * GRID_H); + }; + class loadoutsSearchbarButton: ctrlButtonPicture { + idc = -1; + text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; + colorBackground[]={0,0,0,0.5}; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), ctrlparent (_this select 0) displayCtrl IDC_loadoutsSearchbar)] call FUNC(handleLoadoutsSearchbar)); + x = QUOTE(155 * GRID_W); + y = QUOTE(safezoneH - (51 * GRID_H)); + w = QUOTE(5 * GRID_W); + h = QUOTE(5 * GRID_H); + }; + class buttonSave: ctrlButton { + idc = IDC_buttonSave; + x = QUOTE(0 * GRID_W); + y = QUOTE(safezoneH - (44 * GRID_H)); + w = QUOTE(30 * GRID_W); + h = QUOTE(10 * GRID_H); + text= CSTRING(buttonSaveText); + tooltip= CSTRING(buttonSaveTooltip); + sizeEx = QUOTE(5 * GRID_H); + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsSave)); + colorBackground[] = {0,0,0,0.8}; + }; + class buttonRename: buttonSave { + idc = IDC_buttonRename; + x = QUOTE(32.5 * GRID_W); + text= CSTRING(buttonRenameText); + tooltip= CSTRING(buttonRenameTooltip); + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsRename)); + }; + class buttonLoad: buttonSave { + idc = IDC_buttonLoad; + x = QUOTE(65 * GRID_W); + text= CSTRING(buttonLoadText); + tooltip= CSTRING(buttonLoadTooltip); + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsLoad)); + }; + class buttonShare: buttonSave { + idc = IDC_buttonShare; + x = QUOTE(97.5 * GRID_W); + text= CSTRING(buttonSharePrivateText); + tooltip= CSTRING(buttonShareTooltip); + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsShare)); + }; + class buttonDelete: buttonSave { + idc = IDC_buttonDelete; + x = QUOTE(130 * GRID_W); + text= CSTRING(buttonDeleteText); + tooltip= CSTRING(buttonDeleteTooltip); + colorBackgroundActive[] = {0.5,0,0,1}; + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsDelete)); + }; + }; + }; + + class buttonClose: ctrlButton { + idc = -1; + x = QUOTE(safezoneW + safezoneX - 32 * GRID_W); + y = QUOTE(safezoneH + safezoneY - 9 * GRID_H); + w = QUOTE(30 * GRID_W); + h = QUOTE(7 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + text= CSTRING(buttonCloseText); + shortcuts[]= {"0x01"}; + tooltip= ""; + onButtonClick = QUOTE(ctrlparent (_this select 0) closeDisplay 2); + }; + class buttonBar: ctrlControlsGroupNoScrollbars { + idc = -1; + x = QUOTE((safezoneW * 0.5) + safezoneX - (80.5 * GRID_W)); + y = QUOTE(safezoneH + safezoneY - 9 * GRID_H); + w = QUOTE(161 * GRID_W); + h = QUOTE(7 * GRID_H); + class controls { + class buttonMyLoadoutsBackground: ctrlStaticBackground { + idc = IDC_buttonMyLoadoutsBackground; + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(52 * GRID_W); + h = QUOTE(7 * GRID_H); + colorBackground[] = {0,0,0,0.7}; + }; + class buttonMyLoadouts: ctrlButton { + idc = IDC_buttonMyLoadouts; + colorBackground[] = {0,0,0,0}; + x = QUOTE(0 * GRID_W); + y = QUOTE(0 * GRID_H); + w = QUOTE(52 * GRID_W); + h = QUOTE(7 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + text= CSTRING(tabMyLoadoutsText); + tooltip= CSTRING(tabMyLoadoutsTooltip); + onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(loadoutsChangeTab)); + }; + class buttonDefaultLoadoutsBackground: buttonMyLoadoutsBackground { + idc = IDC_buttonDefaultLoadoutsBackground; + x = QUOTE(54.5 * GRID_W); + }; + class buttonDefaultLoadouts: buttonMyLoadouts { + idc = IDC_buttonDefaultLoadouts; + x = QUOTE(54.5 * GRID_W); + text= CSTRING(tabDefaultLoadoutsText); + tooltip= CSTRING(tabDefaultLoadoutsTooltip); + }; + class buttonSharedLoadoutsBackground: buttonMyLoadoutsBackground { + idc = IDC_buttonSharedLoadoutsBackground; + x = QUOTE(109 * GRID_W); + }; + class buttonSharedLoadouts: buttonMyLoadouts { + idc = IDC_buttonSharedLoadouts; + x = QUOTE(109 * GRID_W); + text= CSTRING(tabSharedLoadoutsText); + tooltip= CSTRING(tabSharedLoadoutsTooltip); + }; + }; + }; + }; +}; diff --git a/addons/arsenal/ui/RscCommon.hpp b/addons/arsenal/ui/RscCommon.hpp new file mode 100644 index 0000000000..60bceeaec3 --- /dev/null +++ b/addons/arsenal/ui/RscCommon.hpp @@ -0,0 +1,292 @@ +// Control types +#define CT_STATIC 0 +#define CT_BUTTON 1 +#define CT_EDIT 2 +#define CT_SLIDER 3 +#define CT_COMBO 4 +#define CT_LISTBOX 5 +#define CT_TOOLBOX 6 +#define CT_CHECKBOXES 7 +#define CT_PROGRESS 8 +#define CT_HTML 9 +#define CT_STATIC_SKEW 10 +#define CT_ACTIVETEXT 11 +#define CT_TREE 12 +#define CT_STRUCTURED_TEXT 13 +#define CT_CONTEXT_MENU 14 +#define CT_CONTROLS_GROUP 15 +#define CT_SHORTCUTBUTTON 16 +#define CT_HITZONES 17 +#define CT_XKEYDESC 40 +#define CT_XBUTTON 41 +#define CT_XLISTBOX 42 +#define CT_XSLIDER 43 +#define CT_XCOMBO 44 +#define CT_ANIMATED_TEXTURE 45 +#define CT_OBJECT 80 +#define CT_OBJECT_ZOOM 81 +#define CT_OBJECT_CONTAINER 82 +#define CT_OBJECT_CONT_ANIM 83 +#define CT_LINEBREAK 98 +#define CT_USER 99 +#define CT_MAP 100 +#define CT_MAP_MAIN 101 +#define CT_LISTNBOX 102 +#define CT_ITEMSLOT 103 +#define CT_CHECKBOX 77 + +// Static styles +#define ST_POS 0x0F +#define ST_HPOS 0x03 +#define ST_VPOS 0x0C +#define ST_LEFT 0x00 +#define ST_RIGHT 0x01 +#define ST_CENTER 0x02 +#define ST_DOWN 0x04 +#define ST_UP 0x08 +#define ST_VCENTER 0x0C + +#define ST_TYPE 0xF0 +#define ST_SINGLE 0x00 +#define ST_MULTI 0x10 +#define ST_TITLE_BAR 0x20 +#define ST_PICTURE 0x30 +#define ST_FRAME 0x40 +#define ST_BACKGROUND 0x50 +#define ST_GROUP_BOX 0x60 +#define ST_GROUP_BOX2 0x70 +#define ST_HUD_BACKGROUND 0x80 +#define ST_TILE_PICTURE 0x90 +#define ST_WITH_RECT 0xA0 +#define ST_LINE 0xB0 +#define ST_UPPERCASE 0xC0 +#define ST_LOWERCASE 0xD0 + +#define ST_SHADOW 0x100 +#define ST_NO_RECT 0x200 +#define ST_KEEP_ASPECT_RATIO 0x800 + +// Slider styles +#define SL_DIR 0x400 +#define SL_VERT 0 +#define SL_HORZ 0x400 + +#define SL_TEXTURES 0x10 + +// progress bar +#define ST_VERTICAL 0x01 +#define ST_HORIZONTAL 0 + +// Listbox styles +#define LB_TEXTURES 0x10 +#define LB_MULTI 0x20 + +// Tree styles +#define TR_SHOWROOT 1 +#define TR_AUTOCOLLAPSE 2 + +// Default grid +#define GUI_GRID_WAbs ((safezoneW / safezoneH) min 1.2) +#define GUI_GRID_HAbs (GUI_GRID_WAbs / 1.2) +#define GUI_GRID_W (GUI_GRID_WAbs / 40) +#define GUI_GRID_H (GUI_GRID_HAbs / 25) +#define GUI_GRID_X (safezoneX) +#define GUI_GRID_Y (safezoneY + safezoneH - GUI_GRID_HAbs) + +// Default text sizes +#define GUI_TEXT_SIZE_SMALL (GUI_GRID_H * 0.8) +#define GUI_TEXT_SIZE_MEDIUM (GUI_GRID_H * 1) +#define GUI_TEXT_SIZE_LARGE (GUI_GRID_H * 1.2) + +class ScrollBar; +class RscObject; +class RscText; +class RscTextSmall; +class RscTitle; +class RscProgress; +class RscProgressNotFreeze; +class RscPicture; +class RscLadderPicture; +class RscPictureKeepAspect; +class RscHTML; +class RscButton; +class RscShortcutButton; +class RscButtonSmall; +class RscEdit; +class RscCombo; +class RscListBox; +class RscListNBox; +class RscXListBox; +class RscTree; +class RscSlider; +class RscSliderH; +class RscXSliderH; +class RscActiveText; +class RscStructuredText; +class RscControlsGroup; +class RscToolbox; +class RscMapControl; +class RscCheckBox; +class RscFrame; +class ctrlDefault; +class ctrlControlsGroup; +class ctrlDefaultText; +class ctrlDefaultButton; +class RscBackgroundStripeTop; +class RscBackgroundStripeBottom; +class RscIGText; +class RscIGProgress; +class RscListBoxKeys; +class RscControlsGroupNoScrollbars; +class RscControlsGroupNoHScrollbars; +class RscControlsGroupNoVScrollbars; +class RscLine; +class RscActivePicture; +class RscButtonTextOnly; +class RscShortcutButtonMain; +class RscButtonEditor; +class RscIGUIShortcutButton; +class RscGearShortcutButton; +class RscButtonMenu; +class RscButtonMenuOK; +class RscButtonMenuCancel; +class RscButtonMenuSteam; +class RscLoadingText; +class RscIGUIListBox; +class RscIGUIListNBox; +class RscBackground; +class RscBackgroundGUI; +class RscBackgroundGUILeft; +class RscBackgroundGUIRight; +class RscBackgroundGUIBottom; +class RscBackgroundGUITop; +class RscBackgroundGUIDark; +class RscBackgroundLogo; +class RscMapControlEmpty; +class RscVignette; +class CA_Mainback; +class CA_Back; +class CA_Title_Back; +class CA_Black_Back; +class CA_Title; +class CA_Logo; +class CA_Logo_Small; +class CA_RscButton; +class CA_RscButton_dialog; +class CA_Ok; +class CA_Ok_image; +class CA_Ok_image2; +class CA_Ok_text; +class ctrlCheckbox; +class ctrlCheckboxBaseline; +class ctrlStatic; +class ctrlControlsGroupNoScrollbars; +class ctrlStructuredText; +class RscTextMulti; +class RscTreeSearch; +class RscVideo; +class RscVideoKeepAspect; +class RscActivePictureKeepAspect; +class RscEditMulti; +class RscMapSignalBackground; +class RscMapSignalPicture; +class RscMapSignalText; +class RscColorPicker; +class RscInterlacingScreen; +class RscFeedback; +class RscTrafficLight; +class RscButtonSearch; +class RscIGUIText; +class RscOpticsText; +class RscOpticsValue; +class RscIGUIValue; +class RscButtonMenuMain; +class RscButtonTestCentered; +class RscDisplaySingleMission_ChallengeOverviewGroup; +class RscDisplayDebriefing_RscTextMultiline; +class RscDisplayDebriefing_ListGroup; +class RscButtonArsenal; +class RscTextNoShadow; +class RscButtonNoColor; +class RscToolboxButton; +class ctrlStaticPicture; +class ctrlStaticPictureKeepAspect; +class ctrlStaticPictureTile; +class ctrlStaticFrame; +class ctrlStaticLine; +class ctrlStaticMulti; +class ctrlStaticBackground; +class ctrlStaticOverlay; +class ctrlStaticTitle; +class ctrlStaticFooter; +class ctrlStaticBackgroundDisable; +class ctrlStaticBackgroundDisableTiles; +class ctrlButton; +class ctrlButtonPicture; +class ctrlButtonPictureKeepAspect; +class ctrlButtonOK; +class ctrlButtonCancel; +class ctrlButtonClose; +class ctrlButtonToolbar; +class ctrlButtonSearch; +class ctrlButtonExpandAll; +class ctrlButtonCollapseAll; +class ctrlButtonFilter; +class ctrlEdit; +class ctrlEditMulti; +class ctrlSliderV; +class ctrlSliderH; +class ctrlCombo; +class ctrlComboToolbar; +class ctrlListbox; +class ctrlToolbox; +class ctrlToolboxPicture; +class ctrlToolboxPictureKeepAspect; +class ctrlCheckboxes; +class ctrlCheckboxesCheckbox; +class ctrlProgress; +class ctrlHTML; +class ctrlActiveText; +class ctrlActivePicture; +class ctrlActivePictureKeepAspect; +class ctrlTree; +class ctrlControlsGroupNoHScrollbars; +class ctrlControlsGroupNoVScrollbars; +class ctrlShortcutButton; +class ctrlShortcutButtonOK; +class ctrlShortcutButtonCancel; +class ctrlShortcutButtonSteam; +class ctrlXListbox; +class ctrlXSliderV; +class ctrlXSliderH; +class ctrlMenu; +class ctrlMenuStrip; +class ctrlMap; +class ctrlMapEmpty; +class ctrlMapMain; +class ctrlListNBox; +class ctrlCheckboxToolbar; + +class Display3DEN { + class ContextMenu :ctrlMenu { + class Items { + class Arsenal { + action= QUOTE(call FUNC(open3DEN)); + }; + }; + }; + class Controls { + class MenuStrip: ctrlMenuStrip { + class Items { + class Tools { + items[] += {"ACE_arsenal_portVALoadouts"}; + }; + class ACE_arsenal_portVALoadouts { + text = CSTRING(portLoadoutsText); + picture = QPATHTOEF(common,data\logo_ace3_ca.paa); + action = "call ace_arsenal_fnc_portVALoadouts;"; + }; + }; + }; + }; +}; diff --git a/addons/arsenal/ui/script_component.hpp b/addons/arsenal/ui/script_component.hpp new file mode 100644 index 0000000000..523addf768 --- /dev/null +++ b/addons/arsenal/ui/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\arsenal\script_component.hpp" \ No newline at end of file diff --git a/addons/atragmx/CfgWeapons.hpp b/addons/atragmx/CfgWeapons.hpp index af5e1a9955..2fa31fc628 100644 --- a/addons/atragmx/CfgWeapons.hpp +++ b/addons/atragmx/CfgWeapons.hpp @@ -1,7 +1,7 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_ATragMX: ACE_ItemCore { author = "Ruthberg"; @@ -13,7 +13,7 @@ class CfgWeapons { icon = "iconObject_circle"; mapSize = 0.034; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; }; }; diff --git a/addons/atragmx/RscTitles.hpp b/addons/atragmx/RscTitles.hpp index ba03785427..834c4eb8af 100644 --- a/addons/atragmx/RscTitles.hpp +++ b/addons/atragmx/RscTitles.hpp @@ -52,7 +52,6 @@ class ATragMX_RscButton { shadow=0; }; class ATragMX_RscEdit { - access=0; type=2; style=ST_RIGHT; x=0; diff --git a/addons/atragmx/XEH_PREP.hpp b/addons/atragmx/XEH_PREP.hpp index c77b7e0655..b61258c008 100644 --- a/addons/atragmx/XEH_PREP.hpp +++ b/addons/atragmx/XEH_PREP.hpp @@ -27,6 +27,7 @@ PREP(init); PREP(initGunList); PREP(insert_c1_ballistic_coefficient_data); PREP(insert_muzzle_velocity_data); +PREP(lookup_c1_ballistic_coefficient); PREP(parse_input); PREP(read_gun_list_entries_from_config); PREP(recalculate_c1_ballistic_coefficient); diff --git a/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf index 450ecc8ab3..cbb78df8e7 100644 --- a/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf +++ b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf @@ -29,7 +29,8 @@ private _distance = 0; while {_velocity > _thresholdVelocity} do { private _bc = GVAR(targetSolutionInput) select 14; private _dragModel = GVAR(targetSolutionInput) select 15; - private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _velocity])); + private _temperature = GVAR(targetSolutionInput) select 5; + private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3:%4", _dragModel, _bc, _velocity, _temperature])); _distance = _distance + _velocity * __DELTA_T; _velocity = _velocity - (_drag * __DELTA_T); }; diff --git a/addons/atragmx/functions/fnc_calculate_range_card.sqf b/addons/atragmx/functions/fnc_calculate_range_card.sqf index 837a46079f..9201861351 100644 --- a/addons/atragmx/functions/fnc_calculate_range_card.sqf +++ b/addons/atragmx/functions/fnc_calculate_range_card.sqf @@ -27,4 +27,9 @@ _solutionInput set [ 8, round(_solutionInput select 4)]; _solutionInput set [13, _targetRange]; _solutionInput set [17, true]; +if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + private _c1 = [_targetRange] call FUNC(lookup_c1_ballistic_coefficient); + _solutionInput set [14, _c1]; +}; + private _result = _solutionInput call FUNC(calculate_solution); diff --git a/addons/atragmx/functions/fnc_calculate_solution.sqf b/addons/atragmx/functions/fnc_calculate_solution.sqf index 836d785242..a7928d1ef0 100644 --- a/addons/atragmx/functions/fnc_calculate_solution.sqf +++ b/addons/atragmx/functions/fnc_calculate_solution.sqf @@ -51,37 +51,34 @@ params [ ]; _windSpeed params ["_windSpeed1", "_windSpeed2"]; -private ["_tx", "_tz", "_lastBulletPos", "_bulletPos", "_bulletVelocity", "_bulletAccel", "_bulletSpeed", "_gravity", "_deltaT"]; -_tx = 0; -_tz = 0; -_lastBulletPos = [0, 0, 0]; -_bulletPos = [0, 0, 0]; -_bulletVelocity = [0, 0, 0]; -_bulletAccel = [0, 0, 0]; -_bulletSpeed = 0; -_gravity = [0, sin(_scopeBaseAngle + _inclinationAngle) * -9.80665, cos(_scopeBaseAngle + _inclinationAngle) * -9.80665]; -_deltaT = 1 / _simSteps; +private _tx = 0; +private _tz = 0; +private _lastBulletPos = [0, 0, 0]; +private _bulletPos = [0, 0, 0]; +private _bulletVelocity = [0, 0, 0]; +private _bulletAccel = [0, 0, 0]; +private _bulletSpeed = 0; +private _gravity = [0, sin(_scopeBaseAngle + _inclinationAngle) * -GRAVITY, cos(_scopeBaseAngle + _inclinationAngle) * -GRAVITY]; +private _deltaT = 1 / _simSteps; -private ["_elevation", "_windage1", "_windage2", "_lead", "_TOF", "_trueVelocity", "_trueSpeed", "_kineticEnergy", "_verticalCoriolis", "_verticalDeflection", "_horizontalCoriolis", "_horizontalDeflection", "_spinDrift", "_spinDeflection"]; -_elevation = 0; -_windage1 = 0; -_windage2 = 0; -_lead = 0; -_TOF = 0; -_trueVelocity = [0, 0, 0]; -_trueSpeed = 0; -_verticalCoriolis = 0; -_verticalDeflection = 0; -_horizontalCoriolis = 0; -_horizontalDeflection = 0; -_spinDrift = 0; -_spinDeflection = 0; +private _elevation = 0; +private _windage1 = 0; +private _windage2 = 0; +private _lead = 0; +private _TOF = 0; +private _trueVelocity = [0, 0, 0]; +private _trueSpeed = 0; +private _verticalCoriolis = 0; +private _verticalDeflection = 0; +private _horizontalCoriolis = 0; +private _horizontalDeflection = 0; +private _spinDrift = 0; +private _spinDeflection = 0; -private ["_n", "_range", "_trueRange", "_rangeFactor"]; -_n = 0; -_range = 0; -_trueRange = 0; -_rangeFactor = 1; +private _n = 0; +private _range = 0; +private _trueRange = 0; +private _rangeFactor = 1; if (_storeRangeCardData) then { if (GVAR(currentUnit) == 1) then { _rangeFactor = 1.0936133; @@ -89,18 +86,16 @@ if (_storeRangeCardData) then { GVAR(rangeCardData) = []; }; -private ["_wind1", "_wind2", "_windDrift"]; -_wind1 = [cos(270 - _windDirection * 30) * _windSpeed1, sin(270 - _windDirection * 30) * _windSpeed1, 0]; -_wind2 = [cos(270 - _windDirection * 30) * _windSpeed2, sin(270 - _windDirection * 30) * _windSpeed2, 0]; -_windDrift = 0; +private _wind1 = [cos(270 - _windDirection * 30) * _windSpeed1, sin(270 - _windDirection * 30) * _windSpeed1, 0]; +private _wind2 = [cos(270 - _windDirection * 30) * _windSpeed2, sin(270 - _windDirection * 30) * _windSpeed2, 0]; +private _windDrift = 0; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { _bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel])); }; -private ["_eoetvoesMultiplier"]; -_eoetvoesMultiplier = 0; +private _eoetvoesMultiplier = 0; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - _eoetvoesMultiplier = 2 * (0.0000729 * _muzzleVelocity / -9.80665) * cos(_latitude) * sin(_directionOfFire); + _eoetvoesMultiplier = 2 * (0.0000729 * _muzzleVelocity / -GRAVITY) * cos(_latitude) * sin(_directionOfFire); }; _bulletPos set [0, 0]; @@ -118,7 +113,7 @@ while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { _trueSpeed = vectorMagnitude _trueVelocity; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed])); + private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3:%4", _dragModel, _bc, _trueSpeed, _temperature])); _bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag); } else { _bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction); @@ -144,7 +139,7 @@ while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { _windage1 = - atan(_tx / _trueRange); _windDrift = (_wind2 select 0) * (_TOF - _trueRange / _muzzleVelocity); _windage2 = - atan(_windDrift / _trueRange); - _lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _trueRange); + _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _trueRange); }; _kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); _kineticEnergy = _kineticEnergy * 0.737562149; @@ -179,7 +174,7 @@ if (_targetRange != 0) then { _windage1 = - atan(_tx / _targetRange); _windDrift = (_wind2 select 0) * (_TOF - _targetRange / _muzzleVelocity); _windage2 = - atan(_windDrift / _targetRange); - _lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _targetRange); + _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _targetRange); }; _kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); diff --git a/addons/atragmx/functions/fnc_calculate_target_solution.sqf b/addons/atragmx/functions/fnc_calculate_target_solution.sqf index f7a4750223..4477025618 100644 --- a/addons/atragmx/functions/fnc_calculate_target_solution.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_solution.sqf @@ -17,21 +17,19 @@ [] call FUNC(parse_input); -private ["_scopeBaseAngle"]; -_scopeBaseAngle = (GVAR(workingMemory) select 3); +private _scopeBaseAngle = (GVAR(workingMemory) select 3); -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; +private _bulletMass = GVAR(workingMemory) select 12; +private _bulletDiameter = GVAR(workingMemory) select 13; +private _boreHeight = GVAR(workingMemory) select 5; +private _airFriction = GVAR(workingMemory) select 4; +private _barrelTwist = GVAR(workingMemory) select 14; +private _muzzleVelocity = GVAR(workingMemory) select 1; +private _bc = GVAR(workingMemory) select 15; +private _dragModel = GVAR(workingMemory) select 16; +private _atmosphereModel = GVAR(workingMemory) select 17; -_twistDirection = 0; +private _twistDirection = 0; if (_barrelTwist > 0) then { _twistDirection = 1; } else { @@ -41,34 +39,31 @@ if (_barrelTwist > 0) then { }; _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; + _relativeHumidity = 0.5; }; -private ["_bulletLength", "_stabilityFactor"]; -_bulletLength = 50 * _bulletMass / ((_bulletDiameter/2)^2); -_stabilityFactor = 1.5; +private _bulletLength = 50 * _bulletMass / ((_bulletDiameter/2)^2); +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(targetRange) select GVAR(currentTarget); +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(targetRange) select GVAR(currentTarget); GVAR(targetSolutionInput) = [_scopeBaseAngle, _bulletMass, _boreHeight, _airFriction, _muzzleVelocity, _temperature, _barometricPressure, _relativeHumidity, round(_muzzleVelocity), [_windSpeed1, _windSpeed2], _windDirection, _inclinationAngle, _targetSpeed, _targetRange, _bc, _dragModel, _atmosphereModel, false, _stabilityFactor, _twistDirection, _latitude, _directionOfFire]; diff --git a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf index 7b18559b77..eacefc9833 100644 --- a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf @@ -15,12 +15,10 @@ */ #include "script_component.hpp" -private ["_targetRange", "_numTicks", "_timeSecs", "_estSpeed"]; - -_targetRange = parseNumber(ctrlText 8004); -_numTicks = parseNumber(ctrlText 8005); -_timeSecs = parseNumber(ctrlText 8006); -_estSpeed = 0; +private _targetRange = parseNumber(ctrlText 8004); +private _numTicks = parseNumber(ctrlText 8005); +private _timeSecs = parseNumber(ctrlText 8006); +private _estSpeed = 0; if (GVAR(currentUnit) == 1) then { _targetRange = _targetRange / 1.0936133; diff --git a/addons/atragmx/functions/fnc_calculate_truing_drop.sqf b/addons/atragmx/functions/fnc_calculate_truing_drop.sqf index d60f5b50e3..fa43ac73c2 100644 --- a/addons/atragmx/functions/fnc_calculate_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_calculate_truing_drop.sqf @@ -46,8 +46,8 @@ if (_parseInput) then { }; switch (_dropUnit) do { case 0: { - _transonicDrop = _transonicDrop * 3.38; - _subsonicDrop = _subsonicDrop * 3.38; + _transonicDrop = MRAD_TO_MOA(_transonicDrop); + _subsonicDrop = MRAD_TO_MOA(_subsonicDrop); }; case 2: { _transonicDrop = _transonicDrop / 1.047; diff --git a/addons/atragmx/functions/fnc_change_target_slot.sqf b/addons/atragmx/functions/fnc_change_target_slot.sqf index 158e31ad87..6fd3889309 100644 --- a/addons/atragmx/functions/fnc_change_target_slot.sqf +++ b/addons/atragmx/functions/fnc_change_target_slot.sqf @@ -15,10 +15,9 @@ */ #include "script_component.hpp" -private _target = 0 max _this min 3; +GVAR(currentTarget) = 0 max _this min 3; -[] call FUNC(parse_input); +GVAR(targetRangeDirtyFlag) = true; -GVAR(currentTarget) = _target; call FUNC(update_target_selection); call FUNC(calculate_target_solution); diff --git a/addons/atragmx/functions/fnc_init.sqf b/addons/atragmx/functions/fnc_init.sqf index 48401acb4c..28b5202670 100644 --- a/addons/atragmx/functions/fnc_init.sqf +++ b/addons/atragmx/functions/fnc_init.sqf @@ -51,7 +51,7 @@ GVAR(atmosphereModeTBH) = true; GVAR(altitude) = 0; GVAR(temperature) = 15; GVAR(barometricPressure) = 1013.25; -GVAR(relativeHumidity) = 0.5; +GVAR(relativeHumidity) = 0.0; GVAR(latitude) = [38, 38, 38, 38]; GVAR(directionOfFire) = [0, 0, 0, 0]; @@ -84,6 +84,8 @@ GVAR(truingDropMuzzleVelocity) = 0; GVAR(targetSolutionInput) = nil; +GVAR(targetRangeDirtyFlag) = false; + GVAR(showMainPage) = true; GVAR(showAddNewGun) = false; GVAR(showAtmoEnvData) = false; diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf index 69efdc68ef..2e2bbd15bd 100644 --- a/addons/atragmx/functions/fnc_initGunList.sqf +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -32,51 +32,51 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == if (_resetGunList) then { WARNING("Reseting Profile Gunlist"); // Profile Name, Muzzle Velocity, Zero Range, Scope Base Angle, AirFriction, Bore Height, Scope Unit, Scope Click Unit, Scope Click Number, Maximum Elevation, Dialed Elevation, Dialed Windage, Mass, Bullet Diameter, Rifle Twist, BC, Drag Model, Atmosphere Model, Muzzle Velocity vs. Temperature Interpolation, C1 Ballistic Coefficient vs. Distance Interpolation, Persistent - GVAR(gunList) = [["12.7x108mm" , 812, 100, 0.0666557, -0.00063800, 3.81, 0, 2, 10, 120, 0, 0, 48.28, 12.7, 38.10, 0.630, 1, "ASM" , [[-15,793],[0,800],[10,807],[15,812],[25,826],[30,835],[35,846]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + GVAR(gunList) = [["12.7x108mm" , 812, 100, 0.0958029, -0.00063800, 8.89, 0, 2, 10, 120, 0, 0, 48.28, 12.7, 38.10, 0.630, 1, "ASM" , [[-15,793],[0,800],[10,807],[15,812],[25,826],[30,835],[35,846]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["12.7x99mm AMAX" , 852, 100, 0.0615965, -0.00036645, 3.81, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 38.10, 1.050, 1, "ASM" , [[-15,833],[0,840],[10,847],[15,852],[25,866],[30,875],[35,886]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["12.7x99mm" , 892, 100, 0.0588284, -0.00057503, 3.81, 0, 2, 10, 120, 0, 0, 41.92, 12.7, 38.10, 0.670, 1, "ASM" , [[-15,873],[0,880],[10,887],[15,892],[25,906],[30,915],[35,926]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["12.7x99mm AMAX" , 852, 100, 0.0907214, -0.00037397, 8.89, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 38.10, 1.050, 1, "ASM" , [[-15,833],[0,840],[10,847],[15,852],[25,866],[30,875],[35,886]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["12.7x99mm" , 892, 100, 0.0879633, -0.00058679, 8.89, 0, 2, 10, 120, 0, 0, 41.92, 12.7, 38.10, 0.670, 1, "ASM" , [[-15,873],[0,880],[10,887],[15,892],[25,906],[30,915],[35,926]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["12.7x54mm" , 299, 100, 0.3406920, -0.00019268, 3.81, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 24.13, 1.050, 1, "ASM" , [[-15,297],[0,298],[10,299],[15,299],[25,301],[30,302],[35,303]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["12.7x54mm" , 299, 100, 0.3567550, -0.00019568, 6.60, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 24.13, 1.050, 1, "ASM" , [[-15,297],[0,298],[10,299],[15,299],[25,301],[30,302],[35,303]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".50 Beowulf" , 562, 100, 0.1262000, -0.00202645, 3.81, 0, 2, 10, 120, 0, 0, 21.71, 12.7, 50.80, 0.210, 1, "ASM" , [[-15,560],[0,561],[10,562],[15,562],[25,564],[30,565],[35,566]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + [".50 Beowulf" , 562, 100, 0.1425100, -0.00205896, 6.60, 0, 2, 10, 120, 0, 0, 21.71, 12.7, 50.80, 0.210, 1, "ASM" , [[-15,560],[0,561],[10,562],[15,562],[25,564],[30,565],[35,566]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".408 CheyTac 305gr", 1059, 100, 0.0482146, -0.00063655, 3.81, 0, 2, 10, 120, 0, 0, 19.76, 10.4, 33.02, 0.569, 1, "ICAO", [[-15,1040],[0,1047],[10,1054],[15,1059],[25,1073],[30,1082],[35,1093]], [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".408 CheyTac 419gr", 859, 100, 0.0611842, -0.00044958, 3.81, 0, 2, 10, 120, 0, 0, 27.15, 10.4, 33.02, 0.866, 1, "ICAO", [[-15,840],[0,847],[10,854],[15,859],[25,873],[30,882],[35,893]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + [".408 CheyTac 305gr", 1059, 100, 0.0686329, -0.00065414, 7.37, 0, 2, 10, 120, 0, 0, 19.76, 10.4, 33.02, 0.569, 1, "ICAO", [[-15,1040],[0,1047],[10,1054],[15,1059],[25,1073],[30,1082],[35,1093]], [[0, 0.605], [1110, 0.569], [1500, 0.560], [1790, 0.551], [1990, 0.547], [2140, 0.545], [2300, 0.544]], true], + [".408 CheyTac 419gr", 859, 100, 0.0816039, -0.00046249, 7.37, 0, 2, 10, 120, 0, 0, 27.15, 10.4, 33.02, 0.866, 1, "ICAO", [[-15,840],[0,847],[10,854],[15,859],[25,873],[30,882],[35,893]] , [[0, 0.872], [1440, 0.862], [1630, 0.859], [1870, 0.852], [2090, 0.843], [2230, 0.838], [2420, 0.833]], true], - ["9.3×64mm" , 862, 100, 0.0627652, -0.00108571, 3.81, 0, 2, 10, 120, 0, 0, 14.90, 9.30, 35.56, 0.368, 1, "ASM" , [[-15,843],[0,850],[10,857],[15,862],[25,876],[30,885],[35,896]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["9.3×64mm" , 862, 100, 0.0875873, -0.00110727, 8.13, 0, 2, 10, 120, 0, 0, 14.90, 9.30, 35.56, 0.368, 1, "ASM" , [[-15,843],[0,850],[10,857],[15,862],[25,876],[30,885],[35,896]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".338LM 250gr" , 872, 100, 0.0604821, -0.00059133, 3.81, 0, 2, 10, 120, 0, 0, 16.20, 8.58, 25.40, 0.645, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".338LM 300gr" , 792, 100, 0.0685883, -0.00052190, 3.81, 0, 2, 10, 120, 0, 0, 19.44, 8.58, 25.40, 0.759, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".338LM API526" , 872, 100, 0.0602535, -0.00069611, 3.81, 0, 2, 10, 120, 0, 0, 16.39, 8.58, 25.40, 0.580, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + [".338LM 250gr" , 872, 100, 0.0809096, -0.00060841, 7.37, 0, 2, 10, 120, 0, 0, 16.20, 8.58, 25.40, 0.645, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0, 0.656], [1300, 0.64], [1460, 0.636], [1770, 0.625], [1920, 0.621], [2030, 0.619], [2190, 0.618]], true], + [".338LM 300gr" , 792, 100, 0.0890193, -0.00055706, 7.37, 0, 2, 10, 120, 0, 0, 19.44, 8.58, 25.40, 0.759, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0, 0.734], [1300, 0.726], [1500, 0.720], [1770, 0.708], [1880, 0.705], [2000, 0.702], [2110, 0.700]], true], + [".338LM API526" , 872, 100, 0.0810834, -0.00069220, 7.37, 0, 2, 10, 120, 0, 0, 16.39, 8.58, 25.40, 0.580, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0, 0.590], [1180, 0.576], [1320, 0.572], [1570, 0.563], [1690, 0.560], [1860, 0.557], [2050, 0.555]], true], - [".300WM Mk248 Mod0" , 857, 100, 0.0621425, -0.00070530, 3.81, 0, 2, 10, 120, 0, 0, 12.31, 7.80, 25.40, 0.537, 1, "ICAO", [[-15,838],[0,845],[10,852],[15,857],[25,871],[30,880],[35,891]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".300WM Mk248 Mod1" , 839, 100, 0.0637038, -0.00061188, 3.81, 0, 2, 10, 120, 0, 0, 14.26, 7.80, 25.40, 0.619, 1, "ICAO", [[-15,820],[0,827],[10,834],[15,839],[25,853],[30,862],[35,873]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - [".300WM Berger OTM" , 792, 100, 0.0686968, -0.00053733, 3.81, 0, 2, 10, 120, 0, 0, 14.90, 7.80, 25.40, 0.715, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + [".300WM Mk248 Mod0" , 857, 100, 0.0825862, -0.00072468, 7.37, 0, 2, 10, 120, 0, 0, 12.31, 7.80, 25.40, 0.537, 1, "ICAO", [[-15,838],[0,845],[10,852],[15,857],[25,871],[30,880],[35,891]] , [[0, 0.546], [1210, 0.529], [1470, 0.520], [1570, 0.518], [1730, 0.515], [1880, 0.513], [1970, 0.513]], true], + [".300WM Mk248 Mod1" , 839, 100, 0.0841417, -0.00063027, 7.37, 0, 2, 10, 120, 0, 0, 14.26, 7.80, 25.40, 0.619, 1, "ICAO", [[-15,820],[0,827],[10,834],[15,839],[25,853],[30,862],[35,873]] , [[0, 0.623], [1150, 0.614], [1330, 0.609], [1620, 0.598], [1770, 0.595], [1970, 0.592], [2030, 0.591]], true], + [".300WM Berger OTM" , 792, 100, 0.0891300, -0.00055262, 7.37, 0, 2, 10, 120, 0, 0, 14.90, 7.80, 25.40, 0.715, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0, 0.721], [1400, 0.708], [1570, 0.703], [1860, 0.692], [1990, 0.689], [2140, 0.686], [2220, 0.685]], true], - ["7.62x54mmR" , 812, 100, 0.0678441, -0.00100023, 3.81, 0, 2, 10, 120, 0, 0, 9.849, 7.92, 24.13, 0.400, 1, "ICAO", [[-15,793],[0,800],[10,807],[15,812],[25,826],[30,835],[35,846]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["7.62x54mmR" , 828, 100, 0.0853677, -0.00103739, 7.11, 0, 2, 10, 120, 0, 0, 9.849, 7.92, 24.13, 0.400, 1, "ICAO", [[-15,809],[0,816],[10,823],[15,828],[25,842],[30,851],[35,862]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["7.62x51mm M80" , 802, 100, 0.0690229, -0.00100957, 3.81, 0, 2, 10, 120, 0, 0, 9.461, 7.82, 25.40, 0.398, 1, "ICAO", [[-15,783],[0,790],[10,797],[15,802],[25,816],[30,825],[35,836]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["7.62x51mm M118LR" , 757, 100, 0.0739989, -0.00082828, 3.81, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.482, 1, "ICAO", [[-15,738],[0,745],[10,752],[15,757],[25,771],[30,780],[35,791]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["7.62x51mm Mk316" , 781, 100, 0.0709422, -0.00082029, 3.81, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.483, 1, "ICAO", [[-15,777],[0,778],[10,779],[15,781],[25,783],[30,785],[35,787]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["7.62x51mm Mk319" , 900, 100, 0.0593025, -0.00102338, 3.81, 0, 2, 10, 120, 0, 0, 8.424, 7.82, 25.40, 0.377, 1, "ICAO", [[-15,898],[0,899],[10,900],[15,900],[25,902],[30,903],[35,904]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["7.62x51mm M993" , 912, 100, 0.0585007, -0.00107148, 3.81, 0, 2, 10, 120, 0, 0, 8.230, 7.82, 25.40, 0.359, 1, "ICAO", [[-15,893],[0,900],[10,907],[15,912],[25,926],[30,935],[35,946]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["7.62x51mm Subsonic", 314, 100, 0.3168140, -0.00049899, 3.81, 0, 2, 10, 120, 0, 0, 12.96, 7.82, 25.40, 0.502, 1, "ICAO", [[-15,312],[0,313],[10,314],[15,314],[25,316],[30,317],[35,318]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["7.62x51mm M80" , 802, 100, 0.0909184, -0.00103711, 7.62, 0, 2, 10, 120, 0, 0, 9.461, 7.82, 25.40, 0.398, 1, "ICAO", [[-15,783],[0,790],[10,797],[15,802],[25,816],[30,825],[35,836]] , [[0, 0.399], [810, 0.392], [1030, 0.383], [1120, 0.381], [1270, 0.380], [1410, 0.379], [1530, 0.379]], true], + ["7.62x51mm M118LR" , 757, 100, 0.0958841, -0.00085157, 7.62, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.482, 1, "ICAO", [[-15,738],[0,745],[10,752],[15,757],[25,771],[30,780],[35,791]] , [[0, 0.483], [790, 0.479], [920, 0.475], [1130, 0.465], [1230, 0.462], [1420, 0.460], [1630, 0.459]], true], + ["7.62x51mm Mk316" , 781, 100, 0.0928267, -0.00084311, 7.62, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.483, 1, "ICAO", [[-15,777],[0,778],[10,779],[15,781],[25,783],[30,785],[35,787]] , [[0, 0.484], [830, 0.479], [950, 0.475], [1130, 0.467], [1260, 0.463], [1430, 0.461], [1660, 0.459]], true], + ["7.62x51mm Mk319" , 900, 100, 0.0811838, -0.00104515, 7.62, 0, 2, 10, 120, 0, 0, 8.424, 7.82, 25.40, 0.377, 1, "ICAO", [[-15,898],[0,899],[10,900],[15,900],[25,902],[30,903],[35,904]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["7.62x51mm M993" , 912, 100, 0.0803840, -0.00109390, 7.62, 0, 2, 10, 120, 0, 0, 8.230, 7.82, 25.40, 0.359, 1, "ICAO", [[-15,893],[0,900],[10,907],[15,912],[25,926],[30,935],[35,946]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["7.62x51mm Subsonic", 314, 100, 0.3344490, -0.00060194, 6.86, 0, 2, 10, 120, 0, 0, 12.96, 7.82, 25.40, 0.502, 1, "ICAO", [[-15,312],[0,313],[10,314],[15,314],[25,316],[30,317],[35,318]] , [[0, 0.303], [250, 0.409], [320, 0.427], [420, 0.445], [550, 0.460], [650, 0.467], [730, 0.470]], true], - ["7.62x39mm" , 708, 100, 0.0846559, -0.00151621, 3.81, 0, 2, 10, 120, 0, 0, 7.970, 7.82, 25.40, 0.275, 1, "ICAO", [[-15,689],[0,696],[10,703],[15,708],[25,722],[30,731],[35,742]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["7.62x39mm" , 708, 100, 0.1066160, -0.00154815, 7.62, 0, 2, 10, 120, 0, 0, 7.970, 7.82, 25.40, 0.275, 1, "ICAO", [[-15,689],[0,696],[10,703],[15,708],[25,722],[30,731],[35,742]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["6.5x39mm" , 766, 100, 0.0725986, -0.00075308, 3.81, 0, 2, 10, 120, 0, 0, 7.970, 6.71, 22.86, 0.524, 1, "ICAO", [[-15,747],[0,754],[10,761],[15,766],[25,780],[30,789],[35,800]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["6.5x47mm Lapua" , 767, 100, 0.0722256, -0.00067037, 3.81, 0, 2, 10, 120, 0, 0, 9.007, 6.71, 22.86, 0.577, 1, "ICAO", [[-15,748],[0,755],[10,762],[15,767],[25,781],[30,790],[35,801]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["6.5mm Creedmor" , 822, 100, 0.0655022, -0.00060887, 3.81, 0, 2, 10, 120, 0, 0, 9.072, 6.71, 22.86, 0.632, 1, "ICAO", [[-15,803],[0,810],[10,817],[15,822],[25,836],[30,845],[35,856]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["6.5x39mm" , 766, 100, 0.0872025, -0.00077363, 6.35, 0, 2, 10, 120, 0, 0, 7.970, 6.71, 22.86, 0.524, 1, "ICAO", [[-15,747],[0,754],[10,761],[15,766],[25,780],[30,789],[35,800]] , [[0, 0.525], [910, 0.520], [1050, 0.515], [1270, 0.506], [1390, 0.503], [1570, 0.500], [1770, 0.498]], true], + ["6.5x47mm Lapua" , 767, 100, 0.0868248, -0.00069003, 6.35, 0, 2, 10, 120, 0, 0, 9.007, 6.71, 22.86, 0.577, 1, "ICAO", [[-15,748],[0,755],[10,762],[15,767],[25,781],[30,790],[35,801]] , [[0, 0.578], [970, 0.574], [1140, 0.569], [1430, 0.557], [1610, 0.553], [1750, 0.551], [1860, 0.550]], true], + ["6.5mm Creedmor" , 822, 100, 0.0800956, -0.00062437, 6.35, 0, 2, 10, 120, 0, 0, 9.072, 6.71, 22.86, 0.632, 1, "ICAO", [[-15,803],[0,810],[10,817],[15,822],[25,836],[30,845],[35,856]] , [[0, 0.635], [1150, 0.627], [1350, 0.621], [1630, 0.611], [1760, 0.607], [1860, 0.606], [2020, 0.604]], true], - ["5.8x42mm DBP87" , 942, 100, 0.0566639, -0.00117956, 3.81, 0, 2, 10, 120, 0, 0, 4.150, 5.99, 24.40, 0.313, 1, "ICAO", [[-15,923],[0,930],[10,937],[15,942],[25,956],[30,965],[35,976]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["5.8x42mm DBP87" , 942, 100, 0.0916742, -0.00121087, 9.91, 0, 2, 10, 120, 0, 0, 4.150, 5.99, 24.40, 0.313, 1, "ICAO", [[-15,923],[0,930],[10,937],[15,942],[25,956],[30,965],[35,976]] , [[0, 0.323], [760, 0.309], [970, 0.303], [1030, 0.302], [1130, 0.301], [1210, 0.300], [1510, 0.299]], true], - ["5.56x45mm M855" , 862, 100, 0.0635456, -0.00126466, 3.81, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.302, 1, "ASM" , [[-15,843],[0,849],[10,857],[15,862],[25,876],[30,885],[35,898]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["5.56x45mm Mk262" , 812, 100, 0.0682606, -0.00109563, 3.81, 0, 2, 10, 120, 0, 0, 4.990, 5.70, 17.78, 0.361, 1, "ASM" , [[-15,793],[0,800],[10,807],[15,812],[25,826],[30,835],[35,846]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["5.56x45mm Mk318" , 872, 100, 0.0624569, -0.00123318, 3.81, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.307, 1, "ASM" , [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["5.56x45mm M995" , 861, 100, 0.0635355, -0.00123272, 3.81, 0, 2, 10, 120, 0, 0, 4.536, 5.70, 17.78, 0.310, 1, "ASM" , [[-15,842],[0,849],[10,856],[15,861],[25,875],[30,884],[35,895]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["5.56x45mm M855" , 862, 100, 0.0825404, -0.00130094, 7.11, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.302, 1, "ASM" , [[-15,843],[0,849],[10,857],[15,862],[25,876],[30,885],[35,898]] , [[0, 0.306], [670, 0.298], [880, 0.291], [1000, 0.289], [1150, 0.288], [1340, 0.288], [1410, 0.288]], true], + ["5.56x45mm Mk262" , 812, 100, 0.0872422, -0.00111805, 7.11, 0, 2, 10, 120, 0, 0, 4.990, 5.70, 17.78, 0.361, 1, "ASM" , [[-15,793],[0,800],[10,807],[15,812],[25,826],[30,835],[35,846]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["5.56x45mm Mk318" , 872, 100, 0.0814490, -0.00125880, 7.11, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.307, 1, "ASM" , [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], + ["5.56x45mm M995" , 861, 100, 0.0825279, -0.00126182, 7.11, 0, 2, 10, 120, 0, 0, 4.536, 5.70, 17.78, 0.310, 1, "ASM" , [[-15,842],[0,849],[10,856],[15,861],[25,875],[30,884],[35,895]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true], - ["5.45x39mm 7N6M" , 727, 100, 0.0801269, -0.00116278, 3.81, 0, 2, 10, 120, 0, 0, 3.428, 5.59, 16.00, 0.336, 1, "ICAO", [[-15,708],[0,715],[10,722],[15,727],[25,741],[30,750],[35,761]], [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true]]; + ["5.45x39mm 7N6M" , 727, 100, 0.0802286, -0.00119458, 3.81, 0, 2, 10, 120, 0, 0, 3.428, 5.59, 16.00, 0.336, 1, "ICAO", [[-15,708],[0,715],[10,722],[15,727],[25,741],[30,750],[35,761]], [[0, 0.339], [730, 0.331], [960, 0.323], [1100, 0.321], [1220, 0.320], [1380, 0.320], [1480, 0.320]], true]]; [] call FUNC(clear_user_data); profileNamespace setVariable ["ACE_ATragMX_gunList", GVAR(gunList)]; diff --git a/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf new file mode 100644 index 0000000000..43b6da006f --- /dev/null +++ b/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf @@ -0,0 +1,43 @@ +/* + * Author: Ruthberg + * Lookup the correct C1 ballistic coefficient in the c1 ballistic coefficient vs. distance interpolation table + * + * Arguments: + * Target Range + * + * Return Value: + * C1 ballistic coefficient 0) then { + _lookupTable pushBack _x; + }; +} forEach (GVAR(workingMemory) select 19); + +private _lookupTableSize = count _lookupTable; +if (_lookupTableSize < 2) exitWith { (GVAR(workingMemory) select 15) }; +_lookupTable sort true; + +private _lowerIndex = 0; +private _upperIndex = 1; + +for "_index" from 1 to (_lookupTableSize - 1) do { + _upperIndex = _index; + _lowerIndex = _upperIndex - 1; + if (((_lookupTable select _index) select 0) >= _targetRange) exitWith {}; +}; + +(_lookupTable select _lowerIndex) params ["_lowerDistance", "_lowerC1"]; +(_lookupTable select _upperIndex) params ["_upperDistance", "_upperC1"]; + +(0.1 max (linearConversion [_lowerDistance, _upperDistance, _targetRange, _lowerC1, _upperC1]) min 2.0) diff --git a/addons/atragmx/functions/fnc_parse_input.sqf b/addons/atragmx/functions/fnc_parse_input.sqf index b2ca70f31f..3ff40bbbcc 100644 --- a/addons/atragmx/functions/fnc_parse_input.sqf +++ b/addons/atragmx/functions/fnc_parse_input.sqf @@ -77,11 +77,10 @@ if (GVAR(currentUnit) != 2) then { GVAR(barometricPressure) = 340 max GVAR(barometricPressure) min 1350; }; -private ["_windSpeed1", "_windSpeed2", "_targetSpeed", "_targetRange", "_inclinationAngleCosine", "_inclinationAngleDegree"]; -_windSpeed1 = parseNumber(ctrlText 140020); -_windSpeed2 = parseNumber(ctrlText 140021); -_targetSpeed = parseNumber(ctrlText 140050); -_targetRange = parseNumber(ctrlText 140060); +private _windSpeed1 = parseNumber(ctrlText 140020); +private _windSpeed2 = parseNumber(ctrlText 140021); +private _targetSpeed = parseNumber(ctrlText 140050); +private _targetRange = parseNumber(ctrlText 140060); if (GVAR(currentUnit) != 2) then { _windSpeed1 = 0 max _windSpeed1 min 50; _windSpeed2 = 0 max _windSpeed2 min 50; @@ -100,6 +99,7 @@ if (GVAR(currentUnit) == 1) then { } else { _targetRange = 25 max _targetRange min 3700; }; +GVAR(targetRangeDirtyFlag) = GVAR(targetRangeDirtyFlag) || {_targetRange != GVAR(targetRange) select GVAR(currentTarget)}; GVAR(latitude) set [GVAR(currentTarget), -90 max Round(parseNumber(ctrlText 140000)) min 90]; GVAR(directionOfFire) set [GVAR(currentTarget), 0 max abs(Round(parseNumber(ctrlText 140010))) min 359]; GVAR(windSpeed1) set [GVAR(currentTarget), _windSpeed1]; @@ -107,8 +107,8 @@ GVAR(windSpeed2) set [GVAR(currentTarget), _windSpeed2]; GVAR(windDirection) set [GVAR(currentTarget), 1 max Round(parseNumber(ctrlText 140030)) min 12]; GVAR(targetSpeed) set [GVAR(currentTarget), _targetSpeed]; GVAR(targetRange) set [GVAR(currentTarget), _targetRange]; -_inclinationAngleCosine = 0.5 max parseNumber(ctrlText 140041) min 1; -_inclinationAngleDegree = -60 max round(parseNumber(ctrlText 140040)) min 60; +private _inclinationAngleCosine = 0.5 max parseNumber(ctrlText 140041) min 1; +private _inclinationAngleDegree = -60 max round(parseNumber(ctrlText 140040)) min 60; if (_inclinationAngleDegree != GVAR(inclinationAngle) select GVAR(currentTarget)) then { GVAR(inclinationAngle) set [GVAR(currentTarget), _inclinationAngleDegree]; } else { @@ -122,19 +122,18 @@ if ((ctrlText 140051) == ">") then { GVAR(targetSpeedDirection) set [GVAR(currentTarget), -1]; }; -private ["_boreHeight", "_bulletMass", "_bulletDiameter", "_airFriction", "_rifleTwist", "_muzzleVelocity", "_zeroRange"]; -_boreHeight = parseNumber(ctrlText 120000); -_bulletMass = parseNumber(ctrlText 120010); -_bulletDiameter = parseNumber(ctrlText 120020); -_airFriction = parseNumber(ctrlText 120030); +private _boreHeight = parseNumber(ctrlText 120000); +private _bulletMass = parseNumber(ctrlText 120010); +private _bulletDiameter = parseNumber(ctrlText 120020); +private _airFriction = parseNumber(ctrlText 120030); if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { _airFriction = 0.1 max _airFriction min 2; } else { _airFriction = _airFriction / -1000; }; -_rifleTwist = parseNumber(ctrlText 120040); -_muzzleVelocity = parseNumber(ctrlText 120050); -_zeroRange = parseNumber(ctrlText 120060); +private _rifleTwist = parseNumber(ctrlText 120040); +private _muzzleVelocity = parseNumber(ctrlText 120050); +private _zeroRange = parseNumber(ctrlText 120060); if (GVAR(currentUnit) != 2) then { _boreHeight = 0.1 max _boreHeight min 5; _bulletMass = 1 max _bulletMass min 1500; @@ -175,6 +174,11 @@ if (_muzzleVelocity != GVAR(workingMemory) select 1) then { GVAR(workingMemory) set [1, _muzzleVelocity]; GVAR(workingMemory) set [2, _zeroRange]; +if (GVAR(targetRangeDirtyFlag) && missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + [false, false] call FUNC(recalculate_c1_ballistic_coefficient); + GVAR(targetRangeDirtyFlag) = false; +}; + [] call FUNC(update_gun); [] call FUNC(update_gun_ammo_data); [] call FUNC(update_atmosphere); diff --git a/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf index e7ec8bf5a2..e8bd219159 100644 --- a/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf +++ b/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf @@ -1,6 +1,6 @@ /* * Author: Ruthberg - * Recalculates the c1 ballistic coefficient based on the c1 ballistic coefficient vs. distance interpolation input + * Recalculates the c1 ballistic coefficient based on the current target range * * Arguments: * parse input @@ -22,35 +22,7 @@ if (_parseInput) then { [] call FUNC(parse_input); }; -private _lookupTable = []; -{ - if ((_x select 1) > 0) then { - _lookupTable pushBack _x; - }; -} forEach (GVAR(workingMemory) select 19); - -private _lookupTableSize = count _lookupTable; -if (_lookupTableSize < 2) exitWith {}; -_lookupTable sort true; - -private ["_lowerIndex", "_upperIndex"]; -for "_index" from 1 to (_lookupTableSize - 1) do { - _upperIndex = _index; - _lowerIndex = _upperIndex - 1; - if (((_lookupTable select _index) select 0) >= (GVAR(targetRange) select GVAR(currentTarget))) exitWith {}; -}; - -private ["_lowerDistance", "_upperDistance", "_lowerC1", "_upperC1", "_c1"]; -_lowerDistance = (_lookupTable select _lowerIndex) select 0; -_upperDistance = (_lookupTable select _upperIndex) select 0; -_lowerC1 = (_lookupTable select _lowerIndex) select 1; -_upperC1 = (_lookupTable select _upperIndex) select 1; -_c1 = _lowerC1; -if (_lowerDistance != _upperDistance) then { - private _slope = (_upperC1 - _lowerC1) / (_upperDistance - _lowerDistance); - _c1 = _lowerC1 + ((GVAR(targetRange) select GVAR(currentTarget)) - _lowerDistance) * _slope; -}; -_c1 = 0.1 max _c1 min 2.0; +private _c1 = [GVAR(targetRange) select GVAR(currentTarget)] call FUNC(lookup_c1_ballistic_coefficient); if (_c1 != GVAR(workingMemory) select 15) then { GVAR(workingMemory) set [15, _c1]; diff --git a/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf index 248c039969..aa1ab6d23f 100644 --- a/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf +++ b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf @@ -33,24 +33,19 @@ private _lookupTableSize = count _lookupTable; if (_lookupTableSize < 2) exitWith {}; _lookupTable sort true; -private ["_lowerIndex", "_upperIndex"]; +private _lowerIndex = 0; +private _upperIndex = 1; + for "_index" from 1 to (_lookupTableSize - 1) do { _upperIndex = _index; _lowerIndex = _upperIndex - 1; if (((_lookupTable select _index) select 0) >= GVAR(temperature)) exitWith {}; }; -private ["_lowerTemperature", "_upperTemperature", "_lowerMuzzleVelocity", "_upperMuzzleVelocity", "_muzzleVelocity"]; -_lowerTemperature = (_lookupTable select _lowerIndex) select 0; -_upperTemperature = (_lookupTable select _upperIndex) select 0; -_lowerMuzzleVelocity = (_lookupTable select _lowerIndex) select 1; -_upperMuzzleVelocity = (_lookupTable select _upperIndex) select 1; -_muzzleVelocity = _lowerMuzzleVelocity; -if (_lowerTemperature != _upperTemperature) then { - private _slope = (_upperMuzzleVelocity - _lowerMuzzleVelocity) / (_upperTemperature - _lowerTemperature); - _muzzleVelocity = _lowerMuzzleVelocity + (GVAR(temperature) - _lowerTemperature) * _slope; -}; -_muzzleVelocity = 100 max _muzzleVelocity min 1400; +(_lookupTable select _lowerIndex) params ["_lowerDistance", "_lowerMuzzleVelocity"]; +(_lookupTable select _upperIndex) params ["_upperDistance", "_upperMuzzleVelocity"]; + +_muzzleVelocity = 100 max (linearConversion [_lowerDistance, _upperDistance, GVAR(temperature), _lowerMuzzleVelocity, _upperMuzzleVelocity]) min 1400; if (_muzzleVelocity != GVAR(workingMemory) select 1) then { GVAR(workingMemory) set [1, _muzzleVelocity]; diff --git a/addons/atragmx/functions/fnc_restore_atmo_default.sqf b/addons/atragmx/functions/fnc_restore_atmo_default.sqf index 560c0da875..d644f81630 100644 --- a/addons/atragmx/functions/fnc_restore_atmo_default.sqf +++ b/addons/atragmx/functions/fnc_restore_atmo_default.sqf @@ -19,7 +19,7 @@ GVAR(atmosphereModeTBH) = true; GVAR(altitude) = 0; GVAR(temperature) = 15; GVAR(barometricPressure) = 1013.25; -GVAR(relativeHumidity) = 0.5; +GVAR(relativeHumidity) = 0.0; [] call FUNC(update_atmo_selection); [] call FUNC(update_atmosphere); diff --git a/addons/atragmx/functions/fnc_restore_user_data.sqf b/addons/atragmx/functions/fnc_restore_user_data.sqf index cf7f2e2bef..a90c537f91 100644 --- a/addons/atragmx/functions/fnc_restore_user_data.sqf +++ b/addons/atragmx/functions/fnc_restore_user_data.sqf @@ -23,7 +23,7 @@ GVAR(atmosphereModeTBH) = profileNamespace getVariable ["ACE_ATragMX_atmosphereM GVAR(altitude) = -1000 max (profileNamespace getVariable ["ACE_ATragMX_altitude", 0]) min 20000; GVAR(temperature) = -50 max (profileNamespace getVariable ["ACE_ATragMX_temperature", 15]) min 160; GVAR(barometricPressure) = 340 max (profileNamespace getVariable ["ACE_ATragMX_barometricPressure", 1013.25]) min 1350; -GVAR(relativeHumidity) = 0 max (profileNamespace getVariable ["ACE_ATragMX_relativeHumidity", 0.5]) min 1; +GVAR(relativeHumidity) = 0 max (profileNamespace getVariable ["ACE_ATragMX_relativeHumidity", 0.0]) min 1; GVAR(showWind2) = profileNamespace getVariable ["ACE_ATragMX_showWind2", false]; GVAR(showCoriolis) = profileNamespace getVariable ["ACE_ATragMX_showCoriolis", true]; diff --git a/addons/atragmx/functions/fnc_save_gun.sqf b/addons/atragmx/functions/fnc_save_gun.sqf index e26187b231..45558d3de3 100644 --- a/addons/atragmx/functions/fnc_save_gun.sqf +++ b/addons/atragmx/functions/fnc_save_gun.sqf @@ -15,8 +15,7 @@ */ #include "script_component.hpp" -private ["_index"]; -_index = 0 max (lbCurSel 6000); +private _index = 0 max (lbCurSel 6000); GVAR(gunList) set [_index, +GVAR(workingMemory)]; diff --git a/addons/atragmx/functions/fnc_sord.sqf b/addons/atragmx/functions/fnc_sord.sqf index 792d727c70..c6f77f748b 100644 --- a/addons/atragmx/functions/fnc_sord.sqf +++ b/addons/atragmx/functions/fnc_sord.sqf @@ -21,6 +21,8 @@ if (!GVAR(initialised)) exitWith {}; params ["_slopeDistance", "_azimuth", "_inclination"]; +GVAR(targetRangeDirtyFlag) = (round(_slopeDistance) != (GVAR(targetRange) select GVAR(currentTarget))); + GVAR(inclinationAngle) set [GVAR(currentTarget), round(_inclination)]; GVAR(directionOfFire) set [GVAR(currentTarget), round(_azimuth)]; GVAR(targetRange) set [GVAR(currentTarget), round(_slopeDistance)]; diff --git a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf index cbeabc48ac..7dadd8be03 100644 --- a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf @@ -21,8 +21,7 @@ if (ctrlVisible 8000) then { if (_this == 1) then { [] call FUNC(calculate_target_speed_assist); - private ["_targetSpeed"]; - _targetSpeed = parseNumber(ctrlText 8007); + private _targetSpeed = parseNumber(ctrlText 8007); if (_targetSpeed != 0) then { ctrlSetText [330, Str(_targetSpeed)]; ctrlSetText [140050, Str(_targetSpeed)]; diff --git a/addons/atragmx/functions/fnc_update_gun.sqf b/addons/atragmx/functions/fnc_update_gun.sqf index ff7de54a1c..5e081b47ee 100644 --- a/addons/atragmx/functions/fnc_update_gun.sqf +++ b/addons/atragmx/functions/fnc_update_gun.sqf @@ -24,7 +24,7 @@ if (GVAR(currentUnit) != 2) then { if (GVAR(currentUnit) != 2) then { ctrlSetText [110, Str(Round((GVAR(workingMemory) select 12) * 15.4323584))]; } else { - ctrlSetText [110, Str(Round(GVAR(workingMemory) select 12))]; + ctrlSetText [110, Str(Round((GVAR(workingMemory) select 12) * 10) / 10)]; }; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { ctrlSetText [120, Str(Round((GVAR(workingMemory) select 15) * 1000) / 1000)]; diff --git a/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf b/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf index 7d29252b28..4beaf53e0d 100644 --- a/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf @@ -25,7 +25,7 @@ if (GVAR(currentUnit) != 2) then { if (GVAR(currentUnit) != 2) then { ctrlSetText [120010, Str(Round((GVAR(workingMemory) select 12) * 15.4323584))]; } else { - ctrlSetText [120010, Str(Round(GVAR(workingMemory) select 12))]; + ctrlSetText [120010, Str(Round((GVAR(workingMemory) select 12) * 10) / 10)]; }; if (GVAR(currentUnit) != 2) then { ctrlSetText [120020, Str(Round((GVAR(workingMemory) select 13) / 10 / 2.54 * 1000) / 1000)]; diff --git a/addons/atragmx/functions/fnc_update_inclination_angle.sqf b/addons/atragmx/functions/fnc_update_inclination_angle.sqf index 223a7ae4d4..82813282f7 100644 --- a/addons/atragmx/functions/fnc_update_inclination_angle.sqf +++ b/addons/atragmx/functions/fnc_update_inclination_angle.sqf @@ -15,9 +15,8 @@ */ #include "script_component.hpp" -private ["_inclinationAngleCosine", "_inclinationAngleDegree"]; -_inclinationAngleCosine = 0.5 max parseNumber(ctrlText 140041) min 1; -_inclinationAngleDegree = -60 max parseNumber(ctrlText 140040) min 60; +private _inclinationAngleCosine = 0.5 max parseNumber(ctrlText 140041) min 1; +private _inclinationAngleDegree = -60 max parseNumber(ctrlText 140040) min 60; if (_this == 0) then { ctrlSetText [140040, Str(round(acos(_inclinationAngleCosine)))]; diff --git a/addons/atragmx/functions/fnc_update_range_card.sqf b/addons/atragmx/functions/fnc_update_range_card.sqf index 5656a45fe5..2f4aa3c7a2 100644 --- a/addons/atragmx/functions/fnc_update_range_card.sqf +++ b/addons/atragmx/functions/fnc_update_range_card.sqf @@ -15,8 +15,7 @@ */ #include "script_component.hpp" -private ["_range", "_elevation", "_windage1", "_windage2", "_clickSize", "_clickNumber", "_clickInterval", "_lead", "_TOF", "_velocity", "_kineticEnergy", "_rangeOutput", "_elevationOutput", "_windageOutput", "_lastColumnOutput", "_speedOfSound"]; -_lastColumnOutput = ""; +private _lastColumnOutput = ""; if (GVAR(showWind2) && GVAR(rangeCardCurrentColumn) == 0) then { ctrlSetText [5006, "Wind2"]; @@ -32,23 +31,23 @@ if (GVAR(currentUnit) == 1) then { lnbClear 5007; -_speedOfSound = GVAR(temperature) call EFUNC(weather,calculateSpeedOfSound); +private _speedOfSound = GVAR(temperature) call EFUNC(weather,calculateSpeedOfSound); { - _range = _x select 0; - _elevation = _x select 1; - _windage1 = (_x select 2) select 0; - _windage2 = (_x select 2) select 1; - _lead = _x select 3; - _TOF = _x select 4; - _velocity = _x select 5; - _kineticEnergy = _x select 6; + private _range = _x select 0; + private _elevation = _x select 1; + private _windage1 = (_x select 2) select 0; + private _windage2 = (_x select 2) select 1; + private _lead = _x select 3; + private _TOF = _x select 4; + private _velocity = _x select 5; + private _kineticEnergy = _x select 6; switch (GVAR(currentScopeUnit)) do { case 0: { - _elevation = _elevation / 3.38; - _windage1 = _windage1 / 3.38; - _windage2 = _windage2 / 3.38; + _elevation = MOA_TO_MRAD(_elevation); + _windage1 = MOA_TO_MRAD(_windage1); + _windage2 = MOA_TO_MRAD(_windage2); }; case 2: { _elevation = _elevation * 1.047; @@ -56,13 +55,9 @@ _speedOfSound = GVAR(temperature) call EFUNC(weather,calculateSpeedOfSound); _windage2 = _windage2 * 1.047; }; case 3: { - switch (GVAR(workingMemory) select 7) do { - case 0: { _clickSize = 1; }; - case 1: { _clickSize = 1 / 1.047; }; - case 2: { _clickSize = 3.38; }; - }; - _clickNumber = GVAR(workingMemory) select 8; - _clickInterval = _clickSize / _clickNumber; + private _clickSize = [1, 1 / 1.047, MRAD_TO_MOA(1)] select (GVAR(workingMemory) select 7); + private _clickNumber = GVAR(workingMemory) select 8; + private _clickInterval = _clickSize / _clickNumber; _elevation = Round(_elevation / _clickInterval); _windage1 = Round(_windage1 / _clickInterval); @@ -70,10 +65,10 @@ _speedOfSound = GVAR(temperature) call EFUNC(weather,calculateSpeedOfSound); }; }; - _elevationOutput = Str(Round(_elevation * 100) / 100); - _windageOutput = Str(Round(_windage1 * 100) / 100); + private _elevationOutput = Str(Round(_elevation * 100) / 100); + private _windageOutput = Str(Round(_windage1 * 100) / 100); - _rangeOutput = Str(_range); + private _rangeOutput = Str(_range); if (_velocity < _speedOfSound) then { _rangeOutput = _rangeOutput + "*"; }; diff --git a/addons/atragmx/functions/fnc_update_result.sqf b/addons/atragmx/functions/fnc_update_result.sqf index 98718e6955..1dc2c6204e 100644 --- a/addons/atragmx/functions/fnc_update_result.sqf +++ b/addons/atragmx/functions/fnc_update_result.sqf @@ -15,15 +15,14 @@ */ #include "script_component.hpp" -private ["_elevationAbs", "_elevationRel", "_elevationCur", "_windageAbs", "_windageRel", "_windageCur", "_wind2", "_lead", "_clickSize", "_clickNumber", "_clickInterval"]; -_elevationAbs = GVAR(elevationOutput) select GVAR(currentTarget); -_elevationRel = 0; -_elevationCur = 0; -_windageAbs = GVAR(windage1Output) select GVAR(currentTarget); -_windageRel = 0; -_windageCur = 0; +private _elevationAbs = GVAR(elevationOutput) select GVAR(currentTarget); +private _elevationRel = 0; +private _elevationCur = 0; +private _windageAbs = GVAR(windage1Output) select GVAR(currentTarget); +private _windageRel = 0; +private _windageCur = 0; -_wind2 = GVAR(windage2Output) select GVAR(currentTarget); +private _wind2 = GVAR(windage2Output) select GVAR(currentTarget); if (GVAR(showCoriolis)) then { _elevationRel = GVAR(verticalCoriolisOutput) select GVAR(currentTarget); @@ -38,20 +37,20 @@ if (GVAR(showCoriolis)) then { _windageRel = _windageAbs - _windageCur; }; -_lead = GVAR(leadOutput) select GVAR(currentTarget); +private _lead = GVAR(leadOutput) select GVAR(currentTarget); switch (GVAR(currentScopeUnit)) do { case 0: { - _elevationAbs = _elevationAbs / 3.38; - _windageAbs = _windageAbs / 3.38; + _elevationAbs = MOA_TO_MRAD(_elevationAbs); + _windageAbs = MOA_TO_MRAD(_windageAbs); - _wind2 = _wind2 / 3.38; + _wind2 = MOA_TO_MRAD(_wind2); - _elevationRel = _elevationRel / 3.38; - _windageRel = _windageRel / 3.38; + _elevationRel = MOA_TO_MRAD(_elevationRel); + _windageRel = MOA_TO_MRAD(_windageRel); - _elevationCur = _elevationCur / 3.38; - _windageCur = _windageCur / 3.38; + _elevationCur = MOA_TO_MRAD(_elevationCur); + _windageCur = MOA_TO_MRAD(_windageCur); }; case 2: { _elevationAbs = _elevationAbs * 1.047; @@ -66,13 +65,9 @@ switch (GVAR(currentScopeUnit)) do { _windageCur = _windageCur * 1.047; }; case 3: { - switch (GVAR(workingMemory) select 7) do { - case 0: { _clickSize = 1; }; - case 1: { _clickSize = 1 / 1.047; }; - case 2: { _clickSize = 3.38; }; - }; - _clickNumber = GVAR(workingMemory) select 8; - _clickInterval = _clickSize / _clickNumber; + private _clickSize = [1, 1 / 1.047, MRAD_TO_MOA(1)] select (GVAR(workingMemory) select 7); + private _clickNumber = GVAR(workingMemory) select 8; + private _clickInterval = _clickSize / _clickNumber; _elevationAbs = Round(_elevationAbs / _clickInterval); _windageAbs = Round(_windageAbs / _clickInterval); diff --git a/addons/atragmx/functions/fnc_update_truing_drop_data.sqf b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf index 161e8877e1..cd1fa9de68 100644 --- a/addons/atragmx/functions/fnc_update_truing_drop_data.sqf +++ b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf @@ -42,9 +42,9 @@ private _dropData = +GVAR(truingDropDropData); switch (_dropUnit) do { case 0: { - _dropData set [0, (_dropData select 0) / 3.38]; - _dropData set [1, (_dropData select 1) / 3.38]; - _dropData set [2, (_dropData select 2) / 3.38]; + _dropData set [0, MOA_TO_MRAD(_dropData select 0)]; + _dropData set [1, MOA_TO_MRAD(_dropData select 1)]; + _dropData set [2, MOA_TO_MRAD(_dropData select 2)]; }; case 2: { _dropData set [0, (_dropData select 0) * 1.047]; diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index f0f787d7cf..8a41e1c38e 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -17,33 +17,29 @@ [] call FUNC(parse_input); -private ["_bulletMass", "_boreHeight", "_airFriction", "_muzzleVelocity", "_bc", "_dragModel", "_atmosphereModel"]; -_bulletMass = GVAR(workingMemory) select 12; -_boreHeight = GVAR(workingMemory) select 5; -_airFriction = GVAR(workingMemory) select 4; -_muzzleVelocity = GVAR(workingMemory) select 1; -_bc = GVAR(workingMemory) select 15; -_dragModel = GVAR(workingMemory) select 16; -_atmosphereModel = GVAR(workingMemory) select 17; +private _bulletMass = GVAR(workingMemory) select 12; +private _boreHeight = GVAR(workingMemory) select 5; +private _airFriction = GVAR(workingMemory) select 4; +private _muzzleVelocity = GVAR(workingMemory) select 1; +private _bc = GVAR(workingMemory) select 15; +private _dragModel = GVAR(workingMemory) select 16; +private _atmosphereModel = GVAR(workingMemory) select 17; +private _zeroRange = GVAR(workingMemory) select 2; +private _altitude = GVAR(altitude); +private _temperature = GVAR(temperature); +private _barometricPressure = GVAR(barometricPressure); +private _relativeHumidity = GVAR(relativeHumidity); -private ["_zeroRange"]; -_zeroRange = GVAR(workingMemory) select 2; - -private ["_altitude", "_temperature", "_barometricPressure", "_relativeHumidity"]; -_altitude = GVAR(altitude); -_temperature = GVAR(temperature); -_barometricPressure = GVAR(barometricPressure); -_relativeHumidity = GVAR(relativeHumidity); if (!GVAR(atmosphereModeTBH)) then { _barometricPressure = 1013.25 * (1 - (0.0065 * _altitude) / (273.15 + _temperature + 0.0065 * _altitude)) ^ 5.255754495; - _relativeHumidity = 50; + _relativeHumidity = 0.5; }; private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; diff --git a/addons/atragmx/initKeybinds.sqf b/addons/atragmx/initKeybinds.sqf index 94704e8132..067f1ba057 100644 --- a/addons/atragmx/initKeybinds.sqf +++ b/addons/atragmx/initKeybinds.sqf @@ -15,11 +15,10 @@ //Add deviceKey entry: -private ["_conditonCode", "_toggleCode", "_closeCode"]; -_conditonCode = { +private _conditonCode = { [] call FUNC(can_show); }; -_toggleCode = { +private _toggleCode = { // Conditions: canInteract if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; if (GVAR(active)) exitWith { @@ -28,7 +27,7 @@ _toggleCode = { // Statement [] call FUNC(create_dialog); }; -_closeCode = { +private _closeCode = { if (GVAR(active)) exitWith { closeDialog 0; }; diff --git a/addons/atragmx/script_component.hpp b/addons/atragmx/script_component.hpp index 8ebc8b445f..ad25ee5b09 100644 --- a/addons/atragmx/script_component.hpp +++ b/addons/atragmx/script_component.hpp @@ -16,4 +16,4 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ATRAGMX_PROFILE_NAMESPACE_VERSION 2.0 +#define ATRAGMX_PROFILE_NAMESPACE_VERSION 2.2 diff --git a/addons/attach/CfgVehicles.hpp b/addons/attach/CfgVehicles.hpp index 5fa75105e7..84ca6ee290 100644 --- a/addons/attach/CfgVehicles.hpp +++ b/addons/attach/CfgVehicles.hpp @@ -6,7 +6,7 @@ displayName = CSTRING(AttachDetach); \ condition = QUOTE(_this call FUNC(canAttach)); \ insertChildren = QUOTE(_this call FUNC(getChildrenAttachActions)); \ - exceptions[] = {}; \ + exceptions[] = {"isNotSwimming"}; \ showDisabled = 0; \ priority = 0; \ icon = QPATHTOF(UI\attach_ca.paa); \ @@ -15,7 +15,7 @@ displayName = CSTRING(Detach); \ condition = QUOTE(_this call FUNC(canDetach)); \ statement = QUOTE(_this call FUNC(detach) ); \ - exceptions[] = {}; \ + exceptions[] = {"isNotSwimming"}; \ showDisabled = 0; \ priority = 0.1; \ icon = QPATHTOF(UI\detach_ca.paa); \ @@ -55,7 +55,7 @@ class CfgVehicles { displayName = CSTRING(AttachDetach); condition = QUOTE(_this call FUNC(canAttach)); insertChildren = QUOTE(_this call FUNC(getChildrenAttachActions)); - exceptions[] = {"isNotDragging"}; + exceptions[] = {"isNotDragging", "isNotSwimming"}; showDisabled = 0; priority = 5; icon = QPATHTOF(UI\attach_ca.paa); @@ -64,7 +64,7 @@ class CfgVehicles { displayName = CSTRING(Detach); condition = QUOTE(_this call FUNC(canDetach)); statement = QUOTE(_this call FUNC(detach)); - exceptions[] = {"isNotDragging"}; + exceptions[] = {"isNotDragging", "isNotSwimming"}; showDisabled = 0; priority = 5; icon = QPATHTOF(UI\detach_ca.paa); diff --git a/addons/attach/CfgWeapons.hpp b/addons/attach/CfgWeapons.hpp index cc50b3be5e..34969d5c14 100644 --- a/addons/attach/CfgWeapons.hpp +++ b/addons/attach/CfgWeapons.hpp @@ -1,6 +1,6 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_IR_Strobe_Item: ACE_ItemCore { ACE_attachable = "ACE_IR_Strobe_Effect"; @@ -11,8 +11,8 @@ class CfgWeapons { model = QPATHTOF(data\ace_IRStrobe.p3d); picture = QPATHTOF(UI\irstrobe_item.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; -}; \ No newline at end of file +}; diff --git a/addons/attach/functions/fnc_attach.sqf b/addons/attach/functions/fnc_attach.sqf index 3bbf085ca4..e7a8630ac9 100644 --- a/addons/attach/functions/fnc_attach.sqf +++ b/addons/attach/functions/fnc_attach.sqf @@ -21,43 +21,42 @@ params ["_attachToVehicle","_unit","_args", ["_silentScripted", false]]; _args params [["_itemClassname","", [""]]]; TRACE_4("params",_attachToVehicle,_unit,_itemClassname,_silentScripted); -private ["_itemVehClass", "_onAtachText", "_selfAttachPosition", "_attachedItem", "_tempObject", "_actionID", "_model"]; - //Sanity Check (_unit has item in inventory, not over attach limit) if ((_itemClassname == "") || {(!_silentScripted) && {!(_this call FUNC(canAttach))}}) exitWith {ERROR("Tried to attach, but check failed");}; -_itemVehClass = getText (configFile >> "CfgWeapons" >> _itemClassname >> "ACE_Attachable"); -_onAtachText = getText (configFile >> "CfgWeapons" >> _itemClassname >> "displayName"); +private _itemVehClass = getText (configFile >> "CfgWeapons" >> _itemClassname >> "ACE_Attachable"); +private _onAttachText = getText (configFile >> "CfgWeapons" >> _itemClassname >> "displayName"); if (_itemVehClass == "") then { _itemVehClass = getText (configFile >> "CfgMagazines" >> _itemClassname >> "ACE_Attachable"); - _onAtachText = getText (configFile >> "CfgMagazines" >> _itemClassname >> "displayName"); + _onAttachText = getText (configFile >> "CfgMagazines" >> _itemClassname >> "displayName"); }; if (_itemVehClass == "") exitWith {ERROR("no ACE_Attachable for Item");}; -_onAtachText = format [localize LSTRING(Item_Attached), _onAtachText]; +private _onAttachText = format [localize LSTRING(Item_Attached), _onAttachText]; if (_unit == _attachToVehicle) then { //Self Attachment - _attachedItem = _itemVehClass createVehicle [0,0,0]; + private _attachedItem = _itemVehClass createVehicle [0,0,0]; _attachedItem attachTo [_unit, [0.05, -0.09, 0.1], "leftshoulder"]; if (!_silentScripted) then { _unit removeItem _itemClassname; // Remove item - [_onAtachText] call EFUNC(common,displayTextStructured); + [_onAttachText, 2] call EFUNC(common,displayTextStructured); }; _unit setVariable [QGVAR(attached), [[_attachedItem, _itemClassname]], true]; } else { GVAR(placeAction) = PLACE_WAITING; [_unit, "forceWalk", "ACE_Attach", true] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", "ACE_Attach", true] call EFUNC(common,statusEffect_set); [{[localize LSTRING(PlaceAction), ""] call EFUNC(interaction,showMouseHint)}, []] call CBA_fnc_execNextFrame; _unit setVariable [QGVAR(placeActionEH), [_unit, "DefaultAction", {true}, {GVAR(placeAction) = PLACE_APPROVE;}] call EFUNC(common,AddActionEventHandler)]; - _actionID = _unit addAction [format ["%1", localize LSTRING(CancelAction)], {GVAR(placeAction) = PLACE_CANCEL}]; + private _actionID = _unit addAction [format ["%1", localize LSTRING(CancelAction)], {GVAR(placeAction) = PLACE_CANCEL}]; //Display to show virtual object: - _model = getText (configFile >> "CfgAmmo" >> _itemVehClass >> "model"); + private _model = getText (configFile >> "CfgAmmo" >> _itemVehClass >> "model"); if (_model == "") then { _model = getText (configFile >> "CfgVehicles" >> _itemVehClass >> "model"); }; @@ -67,27 +66,27 @@ if (_unit == _attachToVehicle) then { //Self Attachment ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetModel _model; [{ - private ["_angle", "_dir", "_screenPos", "_realDistance", "_up", "_virtualPos", "_virtualPosASL", "_lineInterection"]; params ["_args","_idPFH"]; - _args params ["_unit","_attachToVehicle","_itemClassname","_itemVehClass","_onAtachText","_actionID"]; + _args params ["_unit","_attachToVehicle","_itemClassname","_itemVehClass","_onAttachText","_actionID"]; - _virtualPosASL = (eyePos _unit) vectorAdd (positionCameraToWorld [0,0,0.6]) vectorDiff (positionCameraToWorld [0,0,0]); + private _virtualPosASL = (eyePos _unit) vectorAdd (positionCameraToWorld [0,0,0.6]) vectorDiff (positionCameraToWorld [0,0,0]); if (cameraView == "EXTERNAL") then { _virtualPosASL = _virtualPosASL vectorAdd ((positionCameraToWorld [0.3,0,0]) vectorDiff (positionCameraToWorld [0,0,0])); }; - _virtualPos = _virtualPosASL call EFUNC(common,ASLToPosition); - _lineInterection = lineIntersects [eyePos ACE_player, _virtualPosASL, ACE_player]; + private _virtualPos = _virtualPosASL call EFUNC(common,ASLToPosition); + private _lineInterection = lineIntersects [eyePos ACE_player, _virtualPosASL, ACE_player]; //Don't allow placing in a bad position: if (_lineInterection && {GVAR(placeAction) == PLACE_APPROVE}) then {GVAR(placeAction) = PLACE_WAITING;}; if ((GVAR(placeAction) != PLACE_WAITING) || {_unit != ACE_player} || - {!([_unit, _attachToVehicle, []] call EFUNC(common,canInteractWith))} || + {!([_unit, _attachToVehicle, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} || {!([_attachToVehicle, _unit, _itemClassname] call FUNC(canAttach))}) then { [_idPFH] call CBA_fnc_removePerFrameHandler; [_unit, "forceWalk", "ACE_Attach", false] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", "ACE_Attach", false] call EFUNC(common,statusEffect_set); [] call EFUNC(interaction,hideMouseHint); [_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler); _unit removeAction _actionID; @@ -95,7 +94,7 @@ if (_unit == _attachToVehicle) then { //Self Attachment (QGVAR(virtualAmmo) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; if (GVAR(placeAction) == PLACE_APPROVE) then { - [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAtachText, _virtualPos] call FUNC(placeApprove); + [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAttachText, _virtualPos] call FUNC(placeApprove); }; } else { //Show the virtual object: @@ -103,18 +102,18 @@ if (_unit == _attachToVehicle) then { //Self Attachment ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlShow false; } else { ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlShow true; - _screenPos = worldToScreen _virtualPos; + private _screenPos = worldToScreen _virtualPos; if (_screenPos isEqualTo []) exitWith { ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlShow false; }; - _realDistance = (_virtualPos distance (positionCameraToWorld [0,0,0])) / ((call CBA_fnc_getFov) select 1); + private _realDistance = (_virtualPos distance (positionCameraToWorld [0,0,0])) / ((call CBA_fnc_getFov) select 1); _screenPos = [(_screenPos select 0), _realDistance, (_screenPos select 1)]; ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetPosition _screenPos; - _dir = (positionCameraToWorld [0,0,1]) vectorFromTo (positionCameraToWorld [0,0,0]); - _angle = asin (_dir select 2); - _up = [0, cos _angle, sin _angle]; + private _dir = (positionCameraToWorld [0,0,1]) vectorFromTo (positionCameraToWorld [0,0,0]); + private _angle = asin (_dir select 2); + private _up = [0, cos _angle, sin _angle]; ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetModelDirAndUp [[1,0,0], _up]; }; }; - }, 0, [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAtachText, _actionID]] call CBA_fnc_addPerFrameHandler; + }, 0, [_unit, _attachToVehicle, _itemClassname, _itemVehClass, _onAttachText, _actionID]] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/attach/functions/fnc_canAttach.sqf b/addons/attach/functions/fnc_canAttach.sqf index 36264ed628..d862088fcd 100644 --- a/addons/attach/functions/fnc_canAttach.sqf +++ b/addons/attach/functions/fnc_canAttach.sqf @@ -21,10 +21,8 @@ params ["_attachToVehicle","_player","_args"]; _args params [["_itemClassname","", [""]]]; TRACE_3("params",_attachToVehicle,_player,_itemClassname); -private ["_attachLimit", "_attachedObjects"]; - -_attachLimit = [6, 1] select (_player == _attachToVehicle); -_attachedObjects = _attachToVehicle getVariable [QGVAR(attached), []]; +private _attachLimit = [6, 1] select (_player == _attachToVehicle); +private _attachedObjects = _attachToVehicle getVariable [QGVAR(attached), []]; ((_player == _attachToVehicle) || {canStand _player}) && {(_attachToVehicle distance _player) < 10} && diff --git a/addons/attach/functions/fnc_canDetach.sqf b/addons/attach/functions/fnc_canDetach.sqf index a9b6f2deff..bd9d7453cb 100644 --- a/addons/attach/functions/fnc_canDetach.sqf +++ b/addons/attach/functions/fnc_canDetach.sqf @@ -24,9 +24,7 @@ if ((vehicle _unit) != _unit) exitWith {false}; private _attachedList = _attachToVehicle getVariable [QGVAR(attached), []]; if ((count _attachedList) == 0) exitWith {false}; -private ["_inRange"]; - -_inRange = false; +private _inRange = false; { _x params ["_xObject"]; if (isNull _xObject) exitWith { diff --git a/addons/attach/functions/fnc_detach.sqf b/addons/attach/functions/fnc_detach.sqf index 945e399b74..91763c0c4d 100644 --- a/addons/attach/functions/fnc_detach.sqf +++ b/addons/attach/functions/fnc_detach.sqf @@ -19,16 +19,14 @@ params ["_attachToVehicle","_unit"], TRACE_2("params",_attachToVehicle,_unit); -private ["_attachedList", "_itemDisplayName", "_attachedObject", "_attachedIndex", "_itemName", "_minDistance", "_isChemlight"]; +private _attachedList = _attachToVehicle getVariable [QGVAR(attached), []]; -_attachedList = _attachToVehicle getVariable [QGVAR(attached), []]; - -_attachedObject = objNull; -_attachedIndex = -1; -_itemName = ""; +private _attachedObject = objNull; +private _attachedIndex = -1; +private _itemName = ""; //Find closest attached object -_minDistance = 1000; +private _minDistance = 1000; { _x params ["_xObject", "_xItemName"]; @@ -45,7 +43,7 @@ _minDistance = 1000; if (isNull _attachedObject || {_itemName == ""}) exitWith {ERROR("Could not find attached object")}; // Check if item is a chemlight -_isChemlight = _attachedObject isKindOf "Chemlight_base"; +private _isChemlight = _attachedObject isKindOf "Chemlight_base"; // Exit if can't add the item if (!(_unit canAdd _itemName) && {!_isChemlight}) exitWith { @@ -80,9 +78,9 @@ _attachedList deleteAt _attachedIndex; _attachToVehicle setVariable [QGVAR(attached), _attachedList, true]; // Display message -_itemDisplayName = getText (configFile >> "CfgWeapons" >> _itemName >> "displayName"); +private _itemDisplayName = getText (configFile >> "CfgWeapons" >> _itemName >> "displayName"); if (_itemDisplayName == "") then { _itemDisplayName = getText (configFile >> "CfgMagazines" >> _itemName >> "displayName"); }; -[format [localize LSTRING(Item_Detached), _itemDisplayName]] call EFUNC(common,displayTextStructured); +[format [localize LSTRING(Item_Detached), _itemDisplayName], 2] call EFUNC(common,displayTextStructured); diff --git a/addons/attach/functions/fnc_getChildrenAttachActions.sqf b/addons/attach/functions/fnc_getChildrenAttachActions.sqf index 0b2e4e705c..c9bec90aac 100644 --- a/addons/attach/functions/fnc_getChildrenAttachActions.sqf +++ b/addons/attach/functions/fnc_getChildrenAttachActions.sqf @@ -17,21 +17,20 @@ */ #include "script_component.hpp" -private ["_listed", "_actions", "_item", "_displayName", "_picture", "_action"]; params ["_target","_player"]; TRACE_2("params",_target,_player); -_listed = []; -_actions = []; +private _listed = []; +private _actions = []; { if !(_x in _listed) then { _listed pushBack _x; - _item = ConfigFile >> "CfgMagazines" >> _x; + private _item = ConfigFile >> "CfgMagazines" >> _x; if (getText (_item >> "ACE_Attachable") != "") then { - _displayName = getText(_item >> "displayName"); - _picture = getText(_item >> "picture"); - _action = [_x, _displayName, _picture, {[{_this call FUNC(attach)}, _this] call CBA_fnc_execNextFrame}, {_this call FUNC(canAttach)}, {}, [_x]] call EFUNC(interact_menu,createAction); + private _displayName = getText(_item >> "displayName"); + private _picture = getText(_item >> "picture"); + private _action = [_x, _displayName, _picture, {[{_this call FUNC(attach)}, _this] call CBA_fnc_execNextFrame}, {true}, {}, [_x]] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _target]; }; }; @@ -40,11 +39,11 @@ _actions = []; { if !(_x in _listed) then { _listed pushBack _x; - _item = ConfigFile >> "CfgWeapons" >> _x; + private _item = ConfigFile >> "CfgWeapons" >> _x; if (getText (_item >> "ACE_Attachable") != "") then { - _displayName = getText(_item >> "displayName"); - _picture = getText(_item >> "picture"); - _action = [_x, _displayName, _picture, {[{_this call FUNC(attach)}, _this] call CBA_fnc_execNextFrame}, {_this call FUNC(canAttach)}, {}, [_x]] call EFUNC(interact_menu,createAction); + private _displayName = getText(_item >> "displayName"); + private _picture = getText(_item >> "picture"); + private _action = [_x, _displayName, _picture, {[{_this call FUNC(attach)}, _this] call CBA_fnc_execNextFrame}, {true}, {}, [_x]] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _target]; }; }; diff --git a/addons/attach/functions/fnc_placeApprove.sqf b/addons/attach/functions/fnc_placeApprove.sqf index 895f91a7b6..9679e55ad2 100644 --- a/addons/attach/functions/fnc_placeApprove.sqf +++ b/addons/attach/functions/fnc_placeApprove.sqf @@ -25,38 +25,47 @@ */ #include "script_component.hpp" -private ["_startingOffset", "_startDistanceFromCenter", "_closeInUnitVector", "_closeInMax", "_closeInMin", "_closeInDistance", "_endPosTestOffset", "_endPosTest", "_doesIntersect", "_startingPosShifted", "_startASL", "_endPosShifted", "_endASL", "_attachedObject", "_attachList"]; +params ["_unit", "_attachToVehicle", "_itemClassname", "_itemVehClass", "_onAttachText", "_startingPosition"]; +TRACE_6("params",_unit,_attachToVehicle,_itemClassname,_itemVehClass,_onAttachText,_startingPosition); -params ["_unit", "_attachToVehicle", "_itemClassname", "_itemVehClass", "_onAtachText", "_startingPosition"]; -TRACE_6("params",_unit,_attachToVehicle,_itemClassname,_itemVehClass,_onAtachText,_startingPosition); +private _startingOffset = _attachToVehicle worldToModel _startingPosition; -_startingOffset = _attachToVehicle worldToModel _startingPosition; +private _startDistanceFromCenter = vectorMagnitude _startingOffset; +private _closeInUnitVector = vectorNormalized (_startingOffset vectorFromTo [0,0,0]); -_startDistanceFromCenter = vectorMagnitude _startingOffset; -_closeInUnitVector = vectorNormalized (_startingOffset vectorFromTo [0,0,0]); - -_closeInMax = _startDistanceFromCenter; -_closeInMin = 0; +private _closeInMax = _startDistanceFromCenter; +private _closeInMin = 0; while {(_closeInMax - _closeInMin) > 0.01} do { - _closeInDistance = (_closeInMax + _closeInMin) / 2; + private _closeInDistance = (_closeInMax + _closeInMin) / 2; // systemChat format ["Trying %1 from %2 start %3", _closeInDistance, [_closeInMax, _closeInMin], _startDistanceFromCenter]; - _endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); + private _endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); _endPosTestOffset set [2, (_startingOffset select 2)]; - _endPosTest = _attachToVehicle modelToWorldVisual _endPosTestOffset; + private _endPosTest = _attachToVehicle modelToWorldVisual _endPosTestOffset; - _doesIntersect = false; + private _doesIntersect = false; { if (_doesIntersect) exitWith {}; - _startingPosShifted = _startingPosition vectorAdd _x; - _startASL = if (surfaceIsWater _startingPosShifted) then {_startingPosShifted} else {ATLtoASL _startingPosShifted}; + private _startingPosShifted = _startingPosition vectorAdd _x; + private _startASL = if (surfaceIsWater _startingPosShifted) then {_startingPosShifted} else {ATLtoASL _startingPosShifted}; { - _endPosShifted = _endPosTest vectorAdd _x; - _endASL = if (surfaceIsWater _startingPosShifted) then {_endPosShifted} else {ATLtoASL _endPosShifted}; + private _endPosShifted = _endPosTest vectorAdd _x; + private _endASL = if (surfaceIsWater _startingPosShifted) then {_endPosShifted} else {ATLtoASL _endPosShifted}; - //Uncomment to see the lazor show, and see how the scanning works: - // drawLine3D [_startingPosShifted, _endPosShifted, [1,0,0,1]]; - if (_attachToVehicle in lineIntersectsWith [_startASL, _endASL, _unit]) exitWith {_doesIntersect = true}; + #ifdef DRAW_ATTACH_SCAN + [{ + params ["_args", "_idPFH"]; + _args params ["_startingPosShifted", "_endPosShifted", "_timeAdded"]; + drawLine3D [_startingPosShifted, _endPosShifted, [1,0,0,1]]; + if (_timeAdded + 5 < CBA_missionTime) then { + [_idPFH] call CBA_fnc_removePerFrameHandler; + }; + }, 0, [_startingPosShifted, _endPosShifted, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; + #endif + + // Default max results is 1, so take only first subarray and select parentObject (object itself or parent of proxy) + private _intersectObject = ((lineIntersectsSurfaces [_startASL, _endASL, _unit]) param [0, objNull]) param [3, objNull]; + if (_attachToVehicle == _intersectObject) exitWith {_doesIntersect = true}; } forEach [[0,0,0.045], [0,0,-0.045], [0,0.045,0], [0,-0.045,0], [0.045,0,0], [-0.045,0,0]]; } forEach [[0,0,0], [0,0,0.05], [0,0,-0.05]]; @@ -67,7 +76,7 @@ while {(_closeInMax - _closeInMin) > 0.01} do { }; }; -_closeInDistance = (_closeInMax + _closeInMin) / 2; +private _closeInDistance = (_closeInMax + _closeInMin) / 2; //Checks (too close to center or can't attach) if (((_startDistanceFromCenter - _closeInDistance) < 0.1) || {!([_attachToVehicle, _unit, _itemClassname] call FUNC(canAttach))}) exitWith { @@ -79,17 +88,17 @@ if (((_startDistanceFromCenter - _closeInDistance) < 0.1) || {!([_attachToVehicl _closeInDistance = (_closeInDistance - 0.0085); //Create New 'real' Object -_endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); +private _endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); _endPosTestOffset set [2, (_startingOffset select 2)]; -_attachedObject = _itemVehClass createVehicle (getPos _unit); +private _attachedObject = _itemVehClass createVehicle (getPos _unit); _attachedObject attachTo [_attachToVehicle, _endPosTestOffset]; //Remove Item from inventory _unit removeItem _itemClassname; //Add Object to attached array -_attachList = _attachToVehicle getVariable [QGVAR(attached), []]; +private _attachList = _attachToVehicle getVariable [QGVAR(attached), []]; _attachList pushBack [_attachedObject, _itemClassname]; _attachToVehicle setVariable [QGVAR(attached), _attachList, true]; -[_onAtachText] call EFUNC(common,displayTextStructured); +[_onAttachText, 2] call EFUNC(common,displayTextStructured); diff --git a/addons/attach/script_component.hpp b/addons/attach/script_component.hpp index b4fa09f5dd..2b341f106a 100644 --- a/addons/attach/script_component.hpp +++ b/addons/attach/script_component.hpp @@ -2,6 +2,7 @@ #define COMPONENT_BEAUTIFIED Attach #include "\z\ace\addons\main\script_mod.hpp" +// #define DRAW_ATTACH_SCAN // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS diff --git a/addons/attach/stringtable.xml b/addons/attach/stringtable.xml index 39455dedcf..a8e8c23cdf 100644 --- a/addons/attach/stringtable.xml +++ b/addons/attach/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -190,8 +190,8 @@ ИК-маяк позволяет сигнализировать о своём местоположении через пульсирующий свет, видимый только через ПНВ. 赤外線ストロボはあなたの位置を知らせますが、夜間暗視装置を介してでしか見れません。 적외선 스트로브는 자신의 위치를 반짝이면서 표시합니다. 이는 야간투시경으로 밖에 보지 못합니다. - 紅外線閃頻器,藉由紅外線閃頻信號來辨識你的位置,僅能使用夜視系統來辨識紅外線信號 - 红外线闪频器,藉由红外线闪频信号来辨识你的位置,仅能使用夜视系统来辨识红外线信号 + 紅外線閃頻器,藉由紅外線閃頻信號來辨識你的位置,僅能使用夜視系統來辨識紅外線信號 + 红外线闪频器,藉由红外线闪频信号来辨识你的位置,仅能使用夜视系统来辨识红外线信号 Place diff --git a/addons/ballistics/CfgAmmo.hpp b/addons/ballistics/CfgAmmo.hpp index 795a84087d..5b25f70f71 100644 --- a/addons/ballistics/CfgAmmo.hpp +++ b/addons/ballistics/CfgAmmo.hpp @@ -7,7 +7,7 @@ class CfgAmmo { }; class B_556x45_Ball : BulletBase { - airFriction=-0.00126466; + airFriction=-0.00130094; tracerScale = 1; tracerStartTime=0.073; // M856 tracer burns out to 800m tracerEndTime=1.57123; // Time in seconds calculated with ballistics calculator @@ -23,10 +23,11 @@ class CfgAmmo { ACE_barrelLengths[]={210.82, 238.76, 269.24, 299.72, 330.2, 360.68, 391.16, 419.1, 449.58, 480.06, 508.0, 609.6}; }; class ACE_556x45_Ball_Mk262 : B_556x45_Ball { - airFriction=-0.00109563; + airFriction=-0.00111805; ACE_caliber=5.69; ACE_bulletLength=23.012; ACE_bulletMass=4.9896; + ACE_muzzleVelocityVariationSD=0.4; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.361}; ACE_velocityBoundaries[]={}; @@ -36,7 +37,7 @@ class CfgAmmo { ACE_barrelLengths[]={190.5, 368.3, 457.2, 508.0}; }; class ACE_556x45_Ball_Mk318 : B_556x45_Ball { - airFriction=-0.00123318; + airFriction=-0.0012588; ACE_caliber=5.69; ACE_bulletLength=23.012; ACE_bulletMass=4.0176; @@ -49,7 +50,7 @@ class CfgAmmo { ACE_barrelLengths[]={254.0, 393.7, 508.0}; }; class ACE_556x45_Ball_M995_AP : B_556x45_Ball { - airFriction=-0.00123272; + airFriction=-0.00126182; caliber=1.6; ACE_caliber=5.69; ACE_bulletLength=23.012; @@ -67,7 +68,7 @@ class CfgAmmo { nvgOnly = 1; }; class B_545x39_Ball_F : BulletBase { - airFriction=-0.00116278; + airFriction=-0.00119458; ACE_caliber=5.588; ACE_bulletLength=21.59; ACE_bulletMass=3.42792; @@ -83,7 +84,7 @@ class CfgAmmo { tracerScale = 0.5; }; class B_580x42_Ball_F: BulletBase { - airFriction=-0.00117956; + airFriction=-0.00121087; ACE_caliber=5.9944; ACE_bulletLength=24.2; ACE_bulletMass=4.15; @@ -96,7 +97,7 @@ class CfgAmmo { ACE_barrelLengths[]={369.0, 463.0, 600.0}; }; class B_65x39_Caseless : BulletBase { - airFriction=-0.00075308; + airFriction=-0.00077363; tracerScale = 1.1; //1.0; ACE_caliber=6.706; ACE_bulletLength=32.893; @@ -118,11 +119,12 @@ class CfgAmmo { nvgOnly = 1; }; class ACE_65x47_Ball_Scenar: B_65x39_Caseless { - airFriction=-0.00067037; + airFriction=-0.00069003; caliber=0.9; ACE_caliber=6.706; ACE_bulletLength=34.646; ACE_bulletMass=9.0072; + ACE_muzzleVelocityVariationSD=0.35; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.290}; ACE_velocityBoundaries[]={}; @@ -132,11 +134,12 @@ class CfgAmmo { ACE_barrelLengths[]={254.0, 406.4, 508.0, 609.6, 660.4}; }; class ACE_65_Creedmor_Ball: B_65x39_Caseless { - airFriction=-0.00060887; + airFriction=-0.00062437; caliber=1.1; ACE_caliber=6.706; ACE_bulletLength=36.22; ACE_bulletMass=9.072; + ACE_muzzleVelocityVariationSD=0.3; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.317}; ACE_velocityBoundaries[]={}; @@ -150,7 +153,7 @@ class CfgAmmo { tracerScale = 1.1; //1.0; }; class B_762x51_Ball : BulletBase { - airFriction=-0.00100957; + airFriction=-0.00103711; tracerScale = 1.2; //0.6; tracerStartTime=0.073; // Based on the British L5A1 which burns out to 1000m tracerEndTime=2.15957; // Time in seconds calculated with ballistics calculator @@ -170,13 +173,14 @@ class CfgAmmo { nvgOnly = 1; }; class ACE_762x51_Ball_M118LR : B_762x51_Ball { - airFriction=-0.00082828; + airFriction=-0.00085157; caliber=1.8; hit=16; typicalSpeed=790; ACE_caliber=7.823; ACE_bulletLength=31.496; ACE_bulletMass=11.34; + ACE_muzzleVelocityVariationSD=0.4; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.243}; ACE_velocityBoundaries[]={}; @@ -186,13 +190,14 @@ class CfgAmmo { ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; }; class ACE_762x51_Ball_Mk316_Mod_0 : B_762x51_Ball { - airFriction=-0.00082029; + airFriction=-0.00084311; caliber=1.8; hit=16; typicalSpeed=790; ACE_caliber=7.823; ACE_bulletLength=31.496; ACE_bulletMass=11.34; + ACE_muzzleVelocityVariationSD=0.45; ACE_ammoTempMuzzleVelocityShifts[]={-5.3, -5.1, -4.6, -4.2, -3.4, -2.6, -1.4, -0.3, 1.4, 3.0, 5.2}; ACE_ballisticCoefficients[]={0.243}; ACE_velocityBoundaries[]={}; @@ -202,13 +207,14 @@ class CfgAmmo { ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; }; class ACE_762x51_Ball_Mk319_Mod_0 : B_762x51_Ball { - airFriction=-0.00102338; + airFriction=-0.00104515; caliber=1.5; hit=14; typicalSpeed=900; ACE_caliber=7.823; ACE_bulletLength=31.496; ACE_bulletMass=8.424; + ACE_muzzleVelocityVariationSD=0.45; ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619}; ACE_ballisticCoefficients[]={0.377}; ACE_velocityBoundaries[]={}; @@ -218,7 +224,7 @@ class CfgAmmo { ACE_barrelLengths[]={330.2, 406.4, 508.0}; }; class ACE_762x51_Ball_M993_AP : B_762x51_Ball { - airFriction=-0.00107148; + airFriction=-0.0010939; caliber=2.2; hit=11; typicalSpeed=910; @@ -234,7 +240,7 @@ class CfgAmmo { ACE_barrelLengths[]={330.2, 406.4, 508.0}; }; class ACE_762x51_Ball_Subsonic : B_762x51_Ball { - airFriction=-0.00049899; + airFriction=-0.00060194; caliber=1; hit=6; typicalSpeed=320; @@ -250,13 +256,14 @@ class CfgAmmo { ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; }; class ACE_762x67_Ball_Mk248_Mod_0 : B_762x51_Ball { - airFriction=-0.00070530; + airFriction=-0.00072468; caliber=1.8; hit=17; typicalSpeed=900; ACE_caliber=7.823; ACE_bulletLength=34.366; ACE_bulletMass=12.312; + ACE_muzzleVelocityVariationSD=0.45; ACE_ammoTempMuzzleVelocityShifts[]={-5.3, -5.1, -4.6, -4.2, -3.4, -2.6, -1.4, -0.3, 1.4, 3.0, 5.2}; ACE_ballisticCoefficients[]={0.268}; ACE_velocityBoundaries[]={}; @@ -266,13 +273,14 @@ class CfgAmmo { ACE_barrelLengths[]={508.0, 609.6, 660.4}; }; class ACE_762x67_Ball_Mk248_Mod_1 : B_762x51_Ball { - airFriction=-0.00061188; + airFriction=-0.00063027; caliber=1.9; hit=18; typicalSpeed=867; ACE_caliber=7.823; ACE_bulletLength=37.821; ACE_bulletMass=14.256; + ACE_muzzleVelocityVariationSD=0.45; ACE_ammoTempMuzzleVelocityShifts[]={-5.3, -5.1, -4.6, -4.2, -3.4, -2.6, -1.4, -0.3, 1.4, 3.0, 5.2}; ACE_ballisticCoefficients[]={0.310}; ACE_velocityBoundaries[]={}; @@ -282,13 +290,14 @@ class CfgAmmo { ACE_barrelLengths[]={508.0, 609.6, 660.4}; }; class ACE_762x67_Ball_Berger_Hybrid_OTM : B_762x51_Ball { - airFriction=-0.00053733; + airFriction=-0.00055262; caliber=2.0; hit=19; typicalSpeed=853; ACE_caliber=7.823; ACE_bulletLength=40.691; ACE_bulletMass=14.904; + ACE_muzzleVelocityVariationSD=0.35; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.368}; ACE_velocityBoundaries[]={}; @@ -298,7 +307,8 @@ class CfgAmmo { ACE_barrelLengths[]={508.0, 609.6, 660.4}; }; class B_762x54_Ball: B_762x51_Ball { - airFriction=-0.00100023; + airFriction=-0.00101071; + typicalSpeed=835; ACE_caliber=7.925; ACE_bulletLength=28.956; ACE_bulletMass=9.8496; @@ -307,12 +317,12 @@ class CfgAmmo { ACE_velocityBoundaries[]={}; ACE_standardAtmosphere="ICAO"; ACE_dragModel=1; - ACE_muzzleVelocities[]={700, 800, 820, 833}; - ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + ACE_muzzleVelocities[]={760, 795, 835, 865}; + ACE_barrelLengths[]={406.4, 508.0, 604.5, 736.6}; }; class B_762x54_Tracer_Green; class ACE_762x54_Ball_7T2 : B_762x54_Tracer_Green { - airFriction=-0.00103989; + airFriction=-0.00103739; typicalSpeed=800; tracerStartTime=0.073; // Based on the 7T2 which burns three seconds tracerEndTime=3; @@ -324,11 +334,11 @@ class CfgAmmo { ACE_velocityBoundaries[]={}; ACE_standardAtmosphere="ICAO"; ACE_dragModel=1; - ACE_muzzleVelocities[]={680, 750, 798, 800}; - ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; + ACE_muzzleVelocities[]={735, 770, 809, 838}; + ACE_barrelLengths[]={406.4, 508.0, 604.5, 736.6}; }; class B_762x39_Ball_F : BulletBase { - airFriction=-0.00151621; + airFriction=-0.00154815; ACE_caliber=7.823; ACE_bulletLength=28.956; ACE_bulletMass=7.9704; @@ -341,7 +351,7 @@ class CfgAmmo { ACE_barrelLengths[]={254.0, 414.02, 508.0}; }; class B_9x21_Ball : BulletBase { - airFriction=-0.00208292; + airFriction=-0.00211064; tracerScale = 0.5; ACE_caliber=9.042; ACE_bulletLength=15.494; @@ -358,7 +368,7 @@ class CfgAmmo { tracerScale = 0.5; }; class ACE_9x19_Ball : B_9x21_Ball { - airFriction=-0.0019835; + airFriction=-0.00201185; ACE_caliber=9.017; ACE_bulletLength=15.494; ACE_bulletMass=8.0352; @@ -371,10 +381,11 @@ class CfgAmmo { ACE_barrelLengths[]={101.6, 127.0, 228.6}; }; class B_93x64_Ball : BulletBase { - airFriction=-0.00108571; + airFriction=-0.00110727; ACE_caliber=9.296; ACE_bulletLength=34.29; ACE_bulletMass=14.904; + ACE_muzzleVelocityVariationSD=0.4; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.368}; ACE_velocityBoundaries[]={}; @@ -385,12 +396,13 @@ class CfgAmmo { }; class B_408_Ball : BulletBase { timeToLive=10; - airFriction=-0.00044958; + airFriction=-0.00046249; tracerScale = 1.3; ACE_caliber=10.363; ACE_bulletLength=55.1942; ACE_bulletMass=27.1507; // 419 gr ACE_transonicStabilityCoef=1; + ACE_muzzleVelocityVariationSD=0.2; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.434}; ACE_velocityBoundaries[]={}; @@ -401,13 +413,14 @@ class CfgAmmo { }; class ACE_408_Ball : BulletBase { timeToLive=10; - airFriction=-0.00063655; + airFriction=-0.00065414; typicalSpeed=1067; tracerScale = 1.3; ACE_caliber=10.363; ACE_bulletLength=41.4528; ACE_bulletMass=19.7637; // 305 gr ACE_transonicStabilityCoef=1; + ACE_muzzleVelocityVariationSD=0.2; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.279}; ACE_velocityBoundaries[]={}; @@ -418,10 +431,11 @@ class CfgAmmo { }; class B_338_Ball : BulletBase { timeToLive=10; - airFriction=-0.00059133; + airFriction=-0.00060841; ACE_caliber=8.585; ACE_bulletLength=39.573; ACE_bulletMass=16.2; + ACE_muzzleVelocityVariationSD=0.3; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.322}; ACE_velocityBoundaries[]={}; @@ -431,7 +445,7 @@ class CfgAmmo { ACE_barrelLengths[]={508.0, 660.4, 711.2}; }; class B_338_NM_Ball : BulletBase { - airFriction=-0.00052201; + airFriction=-0.00053639; ACE_caliber=8.585; ACE_bulletLength=43.18; ACE_bulletMass=19.44; @@ -445,11 +459,12 @@ class CfgAmmo { }; class ACE_338_Ball : B_338_Ball { timeToLive=10; - airFriction=-0.00052190; + airFriction=-0.00055706; typicalSpeed=826; ACE_caliber=8.585; - ACE_bulletLength=43.18; + ACE_bulletLength=44.0182; ACE_bulletMass=19.44; + ACE_muzzleVelocityVariationSD=0.3; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.368}; ACE_velocityBoundaries[]={}; @@ -460,12 +475,13 @@ class CfgAmmo { }; class ACE_338_Ball_API526 : B_338_Ball { timeToLive=10; - airFriction=-0.00069611; + airFriction=-0.0006922; caliber=2.8; typicalSpeed=895; ACE_caliber=8.585; ACE_bulletLength=38.989; ACE_bulletMass=16.3941242; + ACE_muzzleVelocityVariationSD=0.4; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.290}; ACE_velocityBoundaries[]={}; @@ -478,7 +494,7 @@ class CfgAmmo { tracerScale = 1.3; //1.2; }; class B_127x54_Ball : BulletBase { - airFriction=-0.00019268; + airFriction=-0.00019568; tracerScale = 1.3;// ACE_caliber=12.954; ACE_bulletLength=64.516; @@ -493,11 +509,12 @@ class CfgAmmo { }; class B_127x99_Ball : BulletBase { timeToLive=10; - airFriction=-0.00057503; + airFriction=-0.00058679; tracerScale = 1.3; //1.2; ACE_caliber=12.954; ACE_bulletLength=58.674; ACE_bulletMass=41.9256; + ACE_muzzleVelocityVariationSD=0.35; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.670}; ACE_velocityBoundaries[]={}; @@ -508,13 +525,14 @@ class CfgAmmo { }; class ACE_127x99_API : B_127x99_Ball { timeToLive=10; - airFriction=-0.00057503; + airFriction=-0.00058679; tracerScale = 1.3;// hit=25; caliber=4.0; ACE_caliber=12.954; ACE_bulletLength=58.674; ACE_bulletMass=41.9904; + ACE_muzzleVelocityVariationSD=0.4; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={0.670}; ACE_velocityBoundaries[]={}; @@ -525,11 +543,12 @@ class CfgAmmo { }; class ACE_127x99_Ball_AMAX : B_127x99_Ball { timeToLive=10; - airFriction=-0.00036645; + airFriction=-0.00037397; caliber=3.0; ACE_caliber=12.954; ACE_bulletLength=64.516; ACE_bulletMass=48.6; + ACE_muzzleVelocityVariationSD=0.2; ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19}; ACE_ballisticCoefficients[]={1.050}; ACE_velocityBoundaries[]={}; @@ -540,7 +559,7 @@ class CfgAmmo { }; class B_127x108_Ball : BulletBase { timeToLive=10; - airFriction=-0.00063800; + airFriction=-0.00065098; tracerScale = 1.3; //1.5; ACE_caliber=12.979; ACE_bulletLength=64.008; @@ -553,8 +572,12 @@ class CfgAmmo { ACE_muzzleVelocities[]={820}; ACE_barrelLengths[]={728.98}; }; + class B_127x108_APDS: B_127x108_Ball { + typicalSpeed = 820; + airFriction = -0.00065098; + }; class B_45ACP_Ball : BulletBase { - airFriction=-0.00081221; + airFriction=-0.00082143; tracerScale = 0.6; ACE_caliber=11.481; ACE_bulletLength=17.272; @@ -568,7 +591,7 @@ class CfgAmmo { ACE_barrelLengths[]={101.6, 127.0, 228.6}; }; class B_50BW_Ball_F : BulletBase { - airFriction=-0.00202645; + airFriction=-0.00205896; ACE_caliber=12.7; ACE_bulletLength=24.13; ACE_bulletMass=21.7076; diff --git a/addons/ballistics/CfgMagazines.hpp b/addons/ballistics/CfgMagazines.hpp index 072fedde3c..a89cf7022d 100644 --- a/addons/ballistics/CfgMagazines.hpp +++ b/addons/ballistics/CfgMagazines.hpp @@ -2,24 +2,24 @@ class CfgMagazines { class CA_Magazine; + class VehicleMagazine; + class 30Rnd_580x42_Mag_F: CA_Magazine { - initSpeed = 930; - }; - class 100Rnd_580x42_Mag_F: 30Rnd_580x42_Mag_F { - initSpeed = 930; + initSpeed = 950; }; class 20Rnd_650x39_Cased_Mag_F: CA_Magazine { - initSpeed = 760; + initSpeed = 806; }; class 30Rnd_65x39_caseless_mag: CA_Magazine { - initSpeed = 760; + initSpeed = 774; + }; + class 30Rnd_65x39_caseless_green: 30Rnd_65x39_caseless_mag { + initSpeed = 788; }; class 100Rnd_65x39_caseless_mag: CA_Magazine { - initSpeed = 760; - }; - class 100Rnd_65x39_caseless_mag_Tracer: 100Rnd_65x39_caseless_mag { - initSpeed = 760; + initSpeed = 774; }; + class 100Rnd_65x39_caseless_mag_Tracer; class ACE_100Rnd_65x39_caseless_mag_Tracer_Dim: 100Rnd_65x39_caseless_mag_Tracer { author = ECSTRING(common,ACETeam); ammo = "ACE_65x39_Caseless_Tracer_Dim"; @@ -29,7 +29,7 @@ class CfgMagazines { picture = "\A3\weapons_f\data\ui\m_100rnd_65x39_yellow_ca.paa"; }; class 200Rnd_65x39_cased_Box: 100Rnd_65x39_caseless_mag { - initSpeed = 760; + initSpeed = 743; }; class ACE_200Rnd_65x39_cased_Box_Tracer_Dim: 200Rnd_65x39_cased_Box { author = ECSTRING(common,ACETeam); @@ -38,6 +38,7 @@ class CfgMagazines { displayNameShort = CSTRING(200Rnd_65x39_cased_Box_Tracer_DimNameShort); descriptionShort = CSTRING(200Rnd_65x39_cased_Box_Tracer_DimDescription); picture = "\A3\weapons_f\data\ui\m_200rnd_65x39_yellow_ca.paa"; + initSpeed = 774; }; class 30Rnd_65x39_caseless_mag_Tracer; class ACE_30Rnd_65x39_caseless_mag_Tracer_Dim: 30Rnd_65x39_caseless_mag_Tracer { @@ -61,6 +62,22 @@ class CfgMagazines { }; class 30Rnd_556x45_Stanag: CA_Magazine { + initSpeed = 909; + }; + class 30Rnd_556x45_Stanag_green: 30Rnd_556x45_Stanag { + initSpeed = 869; + }; + class 30Rnd_556x45_Stanag_red: 30Rnd_556x45_Stanag { + initSpeed = 869; + }; + class 30Rnd_556x45_Stanag_Tracer_Red: 30Rnd_556x45_Stanag { + initSpeed = 869; + }; + class 30Rnd_556x45_Stanag_Tracer_Green: 30Rnd_556x45_Stanag { + initSpeed = 869; + }; + class 30Rnd_556x45_Stanag_Tracer_Yellow: 30Rnd_556x45_Stanag { + initSpeed = 889; }; class ACE_30Rnd_556x45_Stanag_M995_AP_mag: 30Rnd_556x45_Stanag { author = ECSTRING(common,ACETeam); @@ -68,7 +85,7 @@ class CfgMagazines { displayName = CSTRING(30Rnd_556x45_Stanag_M995_AP_mag_Name); displayNameShort = CSTRING(30Rnd_556x45_Stanag_M995_AP_mag_NameShort); descriptionShort = CSTRING(30Rnd_556x45_Stanag_M995_AP_mag_Description); - initSpeed = 865; + initSpeed = 875; }; class ACE_30Rnd_556x45_Stanag_Mk262_mag: 30Rnd_556x45_Stanag { author = ECSTRING(common,ACETeam); @@ -84,9 +101,7 @@ class CfgMagazines { displayName = CSTRING(30Rnd_556x45_Stanag_Mk318_mag_Name); displayNameShort = CSTRING(30Rnd_556x45_Stanag_Mk318_mag_NameShort); descriptionShort = CSTRING(30Rnd_556x45_Stanag_Mk318_mag_Description); - initSpeed = 922; - }; - class 30Rnd_556x45_Stanag_Tracer_Red: 30Rnd_556x45_Stanag { + initSpeed = 923; }; class ACE_30Rnd_556x45_Stanag_Tracer_Dim: 30Rnd_556x45_Stanag_Tracer_Red { author = ECSTRING(common,ACETeam); @@ -98,15 +113,18 @@ class CfgMagazines { }; class 200Rnd_556x45_Box_F: CA_Magazine { - initSpeed = 872; + initSpeed = 889; + }; + class 200Rnd_556x45_Box_Red_F: 200Rnd_556x45_Box_F { + initSpeed = 869; }; class 30Rnd_762x39_Mag_F: CA_Magazine { - initSpeed = 715; + initSpeed = 716; }; class 20Rnd_762x51_Mag: CA_Magazine { - initSpeed = 833; + initSpeed = 827; }; class 10Rnd_762x51_Mag: 20Rnd_762x51_Mag { initSpeed = 833; @@ -140,7 +158,7 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x51_mag_SDName); displayNameShort = CSTRING(20Rnd_762x51_mag_SDNameShort); descriptionShort = CSTRING(20Rnd_762x51_mag_SDDescription); - initSpeed = 325; + initSpeed = 330; }; class ACE_10Rnd_762x51_M118LR_Mag: 10Rnd_762x51_Mag { @@ -185,7 +203,7 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x51_M118LR_Mag_Name); displayNameShort = CSTRING(20Rnd_762x51_M118LR_Mag_NameShort); descriptionShort = CSTRING(20Rnd_762x51_M118LR_Mag_Description); - initSpeed = 780; + initSpeed = 785; }; class ACE_20Rnd_762x51_Mk316_Mod_0_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); @@ -194,7 +212,7 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x51_Mk316_Mod_0_Mag_Name); displayNameShort = CSTRING(20Rnd_762x51_Mk316_Mod_0_Mag_NameShort); descriptionShort = CSTRING(20Rnd_762x51_Mk316_Mod_0_Mag_Description); - initSpeed = 790; + initSpeed = 798; }; class ACE_20Rnd_762x51_Mk319_Mod_0_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); @@ -202,7 +220,7 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x51_Mk319_Mod_0_Mag_Name); displayNameShort = CSTRING(20Rnd_762x51_Mk319_Mod_0_Mag_NameShort); descriptionShort = CSTRING(20Rnd_762x51_Mk319_Mod_0_Mag_Description); - initSpeed = 900; + initSpeed = 910; }; class ACE_20Rnd_762x51_M993_AP_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); @@ -211,7 +229,7 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x51_M993_AP_Mag_Name); displayNameShort = CSTRING(20Rnd_762x51_M993_AP_Mag_NameShort); descriptionShort = CSTRING(20Rnd_762x51_M993_AP_Mag_Description); - initSpeed = 920; + initSpeed = 930; }; class ACE_20Rnd_762x67_Mk248_Mod_0_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); @@ -219,7 +237,7 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_Name); displayNameShort = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_NameShort); descriptionShort = CSTRING(20Rnd_762x67_Mk248_Mod_0_Mag_Description); - initSpeed = 900; + initSpeed = 865; }; class ACE_20Rnd_762x67_Mk248_Mod_1_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); @@ -227,7 +245,7 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_Name); displayNameShort = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_NameShort); descriptionShort = CSTRING(20Rnd_762x67_Mk248_Mod_1_Mag_Description); - initSpeed = 880; + initSpeed = 847; }; class ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag: 20Rnd_762x51_Mag { author = ECSTRING(common,ACETeam); @@ -235,12 +253,12 @@ class CfgMagazines { displayName = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_Name); displayNameShort = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_NameShort); descriptionShort = CSTRING(20Rnd_762x67_Berger_Hybrid_OTM_Mag_Description); - initSpeed = 832; + initSpeed = 800; }; class ACE_30Rnd_65x47_Scenar_mag: 30Rnd_65x39_caseless_mag { author = ECSTRING(common,ACETeam); ammo = "ACE_65x47_Ball_Scenar"; - initSpeed = 761; + initSpeed = 826; displayName = CSTRING(30Rnd_65x47_Scenar_mag_Name); displayNameShort = CSTRING(30Rnd_65x47_Scenar_mag_NameShort); descriptionShort = CSTRING(30Rnd_65x47_Scenar_mag_Description); @@ -248,7 +266,7 @@ class CfgMagazines { class ACE_20Rnd_65x47_Scenar_mag: 20Rnd_650x39_Cased_Mag_F { author = ECSTRING(common,ACETeam); ammo = "ACE_65x47_Ball_Scenar"; - initSpeed = 779; + initSpeed = 826; displayName = CSTRING(20Rnd_65x47_Scenar_mag_Name); displayNameShort = CSTRING(20Rnd_65x47_Scenar_mag_NameShort); descriptionShort = CSTRING(20Rnd_65x47_Scenar_mag_Description); @@ -256,7 +274,7 @@ class CfgMagazines { class ACE_30Rnd_65_Creedmor_mag: 30Rnd_65x39_caseless_mag { author = ECSTRING(common,ACETeam); ammo = "ACE_65_Creedmor_Ball"; - initSpeed = 815; + initSpeed = 857; displayName = CSTRING(30Rnd_65_Creedmor_mag_Name); displayNameShort = CSTRING(30Rnd_65_Creedmor_mag_NameShort); descriptionShort = CSTRING(30Rnd_65_Creedmor_mag_Description); @@ -264,12 +282,14 @@ class CfgMagazines { class ACE_20Rnd_65_Creedmor_mag: 20Rnd_650x39_Cased_Mag_F { author = ECSTRING(common,ACETeam); ammo = "ACE_65_Creedmor_Ball"; - initSpeed = 808; + initSpeed = 857; displayName = CSTRING(20Rnd_65_Creedmor_mag_Name); displayNameShort = CSTRING(20Rnd_65_Creedmor_mag_NameShort); descriptionShort = CSTRING(20Rnd_65_Creedmor_mag_Description); }; - class 10Rnd_338_Mag; + class 10Rnd_338_Mag: CA_Magazine { + initSpeed = 880; + }; class ACE_10Rnd_338_300gr_HPBT_Mag: 10Rnd_338_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_338_Ball"; @@ -300,6 +320,9 @@ class CfgMagazines { }; class 5Rnd_127x108_Mag; + class 5Rnd_127x108_APDS_Mag: 5Rnd_127x108_Mag { + initSpeed = 820; + }; class ACE_5Rnd_127x99_Mag: 5Rnd_127x108_Mag { author = ECSTRING(common,ACETeam); ammo = "B_127x99_Ball"; @@ -327,46 +350,47 @@ class CfgMagazines { class 30Rnd_9x21_Mag: CA_Magazine { - initSpeed = 390; + initSpeed = 430; }; - class ACE_30Rnd_9x19_mag: 30Rnd_9x21_Mag { - author = ECSTRING(common,ACETeam); - ammo = "ACE_9x19_Ball"; - displayName = CSTRING(30Rnd_9x19_mag_Name); - displayNameShort = CSTRING(30Rnd_9x19_mag_NameShort); - descriptionShort = CSTRING(30Rnd_9x19_mag_Description); - initSpeed = 370; + class 30Rnd_9x21_Green_Mag: 30Rnd_9x21_Mag { + initSpeed = 402; + }; + class 30Rnd_9x21_Mag_SMG_02: 30Rnd_9x21_Mag { + initSpeed = 430; + }; + class 30Rnd_9x21_Mag_SMG_02_Tracer_Green: 30Rnd_9x21_Mag_SMG_02 { + initSpeed = 402; }; class 10Rnd_50BW_Mag_F: CA_Magazine { initSpeed = 552; }; - + class 11Rnd_45ACP_Mag: CA_Magazine { - initSpeed = 250; + initSpeed = 254; }; class 6Rnd_45ACP_Cylinder : 11Rnd_45ACP_Mag { - initSpeed = 250; + initSpeed = 254; }; class 30Rnd_45ACP_Mag_SMG_01: 30Rnd_9x21_Mag { - initSpeed = 250; + initSpeed = 254; }; class 9Rnd_45ACP_Mag: 30Rnd_45ACP_Mag_SMG_01 { - initSpeed = 250; + initSpeed = 254; }; class 30Rnd_45ACP_Mag_SMG_01_Tracer_Green: 30Rnd_45ACP_Mag_SMG_01 { - initSpeed = 250; + initSpeed = 254; }; class 16Rnd_9x21_Mag: 30Rnd_9x21_Mag { - initSpeed = 390; + initSpeed = 430; }; class 10Rnd_9x21_Mag: 16Rnd_9x21_Mag { - initSpeed = 390; + initSpeed = 430; }; class ACE_16Rnd_9x19_mag: 16Rnd_9x21_Mag { author = ECSTRING(common,ACETeam); @@ -378,7 +402,7 @@ class CfgMagazines { }; class 10Rnd_762x54_Mag: 10Rnd_762x51_Mag { - initSpeed = 800; + initSpeed = 836; }; class ACE_10Rnd_762x54_Tracer_mag: 10Rnd_762x54_Mag { author = ECSTRING(common,ACETeam); @@ -386,19 +410,38 @@ class CfgMagazines { displayName = CSTRING(10Rnd_762x54_Tracer_mag_Name); displayNameShort = CSTRING(10Rnd_762x54_Tracer_mag_NameShort); descriptionShort = CSTRING(10Rnd_762x54_Tracer_mag_Description); - initSpeed = 800; + initSpeed = 810; tracersEvery = 1; }; class 150Rnd_762x54_Box: 150Rnd_762x51_Box { - initSpeed = 750; - }; - - class 150Rnd_93x64_Mag: CA_Magazine { - initSpeed = 860; + initSpeed = 778; }; class 10Rnd_127x54_Mag: CA_Magazine { initSpeed = 300; }; + + class 150Rnd_556x45_Drum_Mag_F: CA_Magazine { + initSpeed = 869; + }; + + class 130Rnd_338_Mag: CA_Magazine { + initSpeed = 807; + }; + + class 200Rnd_65x39_Belt: VehicleMagazine { + initSpeed = 806; + }; + + class 20Rnd_556x45_UW_mag: 30Rnd_556x45_Stanag { + initSpeed = 267; + }; + + class 150Rnd_93x64_Mag: CA_Magazine { + initSpeed = 870; + }; + class 10Rnd_93x64_DMR_05_Mag: 150Rnd_93x64_Mag { + initSpeed = 870; + }; }; diff --git a/addons/ballistics/CfgWeapons.hpp b/addons/ballistics/CfgWeapons.hpp index f95408d6a6..a2a0e0ff1d 100644 --- a/addons/ballistics/CfgWeapons.hpp +++ b/addons/ballistics/CfgWeapons.hpp @@ -11,97 +11,135 @@ class CfgWeapons { class Rifle_Base_F; class Rifle_Short_Base_F: Rifle_Base_F {}; class Rifle_Long_Base_F: Rifle_Base_F {}; - class MuzzleSlot; - - /* Long Rifles */ + // GM6 Lynx class GM6_base_F: Rifle_Long_Base_F { class Single: Mode_SemiAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(0.45); }; }; + // M200 Intervention class LRR_base_F: Rifle_Long_Base_F { class Single: Mode_SemiAuto { - dispersion = 0.00020; // radians. Equal to 0.70 MOA. + dispersion = MOA_TO_RAD(0.50); }; }; - class DMR_07_base_F: Rifle_Long_Base_F { - initSpeed = -1.06051; - ACE_barrelTwist = 228.6; - ACE_barrelLength = 640.0; - magazines[] = { - "20Rnd_650x39_Cased_Mag_F", - "ACE_20Rnd_65x47_Scenar_mag", - "ACE_20Rnd_65_Creedmor_mag" + // MX + class arifle_MX_Base_F: Rifle_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.90); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.90); + }; + }; + + // KH2002 Sama + class arifle_katiba_Base_F: Rifle_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.90); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.90); + }; + }; + + // CTAR-21 + class Tavor_base_F: Rifle_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.12); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(1.12); }; }; - class DMR_06_base_F: Rifle_Long_Base_F { + // F2000 + class mk20_base_F: Rifle_Base_F { class Single: Mode_SemiAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(1.12); }; class FullAuto: Mode_FullAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. - }; - }; - - class DMR_05_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. - }; - - class FullAuto: Mode_FullAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. - }; - }; - - class DMR_04_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. - }; - }; - - class DMR_03_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = 0.00032; // radians. Equal to 1.10 MOA. - }; - - class FullAuto: Mode_FullAuto { - dispersion = 0.00032; // radians. Equal to 1.10 MOA. + dispersion = MOA_TO_RAD(1.12); }; }; + // Noreen "Bad News" ULR class DMR_02_base_F: Rifle_Long_Base_F { class Single: Mode_SemiAuto { - dispersion = 0.000262; // radians. Equal to 0.90 MOA. + dispersion = MOA_TO_RAD(0.61); }; }; + // VS-121 class DMR_01_base_F: Rifle_Long_Base_F { class Single: Mode_SemiAuto { - dispersion = 0.0004; // radians. Equal to 1.375 MOA. - }; - }; - - class EBR_base_F: Rifle_Long_Base_F { - class Single: Mode_SemiAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(0.81); }; class FullAuto: Mode_FullAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(0.81); }; }; - /* MX */ + // Mk14 Mod 1 EBR + class EBR_base_F: Rifle_Long_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.81); + }; - class arifle_MX_Base_F: Rifle_Base_F { - class Single: Mode_SemiAuto {}; - class FullAuto: Mode_FullAuto {}; + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.81); + }; }; + + // SIG 556 + class DMR_03_base_F: Rifle_Long_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.81); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.81); + }; + }; + + // ASP-1 Kir + class DMR_04_base_F: Rifle_Long_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.0); + }; + }; + + // Cyrus + class DMR_05_base_F: Rifle_Long_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.67); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.67); + }; + }; + + // M14 + class DMR_06_base_F: Rifle_Long_Base_F { + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.81); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.81); + }; + }; + + // MX LSW class arifle_MX_SW_F: arifle_MX_Base_F { magazines[] = { "100Rnd_65x39_caseless_mag_Tracer", @@ -111,10 +149,19 @@ class CfgWeapons { "ACE_100Rnd_65x39_caseless_mag_Tracer_Dim", "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" }; - initSpeed = -1.0; + initSpeed = -0.981912; ACE_barrelTwist = 228.6; ACE_barrelLength = 406.4; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.90); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.90); + }; }; + + // MXM class arifle_MXM_F: arifle_MX_Base_F { magazines[] = { "30Rnd_65x39_caseless_mag", @@ -123,23 +170,19 @@ class CfgWeapons { "ACE_30Rnd_65x47_Scenar_mag", "ACE_30Rnd_65_Creedmor_mag" }; - initSpeed = -1.01842; + initSpeed = -1.0; ACE_barrelTwist = 228.6; ACE_barrelLength = 457.2; class Single: Single { - dispersion = 0.000436; // radians. Equal to 1.50 MOA. + dispersion = MOA_TO_RAD(0.90); }; class FullAuto: FullAuto { - dispersion = 0.000436; // radians. Equal to 1.50 MOA. + dispersion = MOA_TO_RAD(0.90); }; }; - - /* Katiba */ - class arifle_katiba_Base_F: Rifle_Base_F {}; - - /* SPAR */ + // HK416A5 11" class arifle_SPAR_01_base_F: Rifle_Base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -153,15 +196,33 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.859238; + initSpeed = -0.869636; ACE_barrelTwist = 177.8; ACE_barrelLength = 264.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.12); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(1.12); + }; }; + + // HK416A5 14.5" class arifle_SPAR_02_base_F: Rifle_Base_F { - initSpeed = -0.934282; + initSpeed = -0.999864; ACE_barrelTwist = 177.8; ACE_barrelLength = 368.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.12); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(1.12); + }; }; + + // HK417A2 20" class arifle_SPAR_03_base_F: Rifle_Base_F { magazines[] = { "20Rnd_762x51_Mag", @@ -173,201 +234,278 @@ class CfgWeapons { "ACE_20Rnd_762x51_M993_AP_Mag", "ACE_20Rnd_762x51_Mag_SD" }; - initSpeed = -0.984394; + initSpeed = -0.991536; ACE_barrelTwist = 279.4; ACE_barrelLength = 508.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.81); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.81); + }; }; - /* Other */ + // Stoner 99 LMG class LMG_Mk200_F: Rifle_Long_Base_F { magazines[] = { "200Rnd_65x39_cased_Box", "200Rnd_65x39_cased_Box_Tracer", "ACE_200Rnd_65x39_cased_Box_Tracer_Dim" }; - initSpeed = -0.976974; + initSpeed = -0.999327; ACE_barrelTwist = 177.8; ACE_barrelLength = 317.5; }; + + // Negev NG7 class LMG_Zafir_F: Rifle_Long_Base_F { - initSpeed = -1.00333; + initSpeed = -1.00048; ACE_barrelTwist = 304.8; ACE_barrelLength = 459.74; }; + + // M249 SPW class LMG_03_base_F: Rifle_Long_Base_F { - initSpeed = -1.02002; + initSpeed = -1.00051; ACE_barrelTwist = 177.8; ACE_barrelLength = 414.02; }; - class Tavor_base_F: Rifle_Base_F {}; - class mk20_base_F: Rifle_Base_F {}; - /* SMGs */ + // RFB SDAR class SDAR_base_F: Rifle_Base_F { - initSpeed = -1.211; class Single: Mode_SemiAuto { - dispersion = 0.0008727; // radians. Equal to 3 MOA. + dispersion = MOA_TO_RAD(3.0); }; class Burst: Mode_Burst { - dispersion = 0.0008727; // radians. Equal to 3 MOA. + dispersion = MOA_TO_RAD(3.0); }; class FullAuto: Mode_FullAuto { - dispersion = 0.0008727; // radians. Equal to 3 MOA. + dispersion = MOA_TO_RAD(3.0); }; }; - /* Pistols */ - class Pistol; class Pistol_Base_F: Pistol {}; + // P99 class hgun_P07_F: Pistol_Base_F { - initSpeed = -1.0; + initSpeed = -0.906977; ACE_barrelTwist = 254.0; ACE_barrelLength = 101.6; }; + // MP-443 Grach class hgun_Rook40_F: Pistol_Base_F { - initSpeed = -1.03077; + initSpeed = -0.934884; ACE_barrelTwist = 254.0; ACE_barrelLength = 111.76; }; + // Custom Covert II class hgun_ACPC2_F: Pistol_Base_F { - initSpeed = -1.0; + initSpeed = -0.984252; ACE_barrelTwist = 406.4; ACE_barrelLength = 127.0; }; + // FNX-45 Tactical class hgun_Pistol_heavy_01_F: Pistol_Base_F { - initSpeed = -0.96; + initSpeed = -0.944882; ACE_barrelTwist = 406.4; ACE_barrelLength = 114.3; }; + // Chiappa Rhino 60DS class hgun_Pistol_heavy_02_F: Pistol_Base_F { - initSpeed = -0.92; + initSpeed = -0.905512; ACE_barrelTwist = 406.4; ACE_barrelLength = 76.2; }; - + + // Makarov PM class hgun_Pistol_01_F: Pistol_Base_F { - initSpeed = -0.974359; + initSpeed = -0.883721; ACE_barrelTwist = 254.0; ACE_barrelLength = 93.5; }; - - class pdw2000_base_F: Rifle_Short_Base_F { - initSpeed = -1.09615; + + class pdw2000_base_F: Rifle_Short_Base_F {}; + + // CPW + class hgun_PDW2000_F: pdw2000_base_F { + initSpeed = -0.994186; ACE_barrelTwist = 228.6; ACE_barrelLength = 177.8; }; - /* Rifles */ + // AKS class arifle_AKS_base_F: Rifle_Base_F { initSpeed = -1.0; ACE_barrelTwist = 160.02; ACE_barrelLength = 206.5; }; + + // AKM class arifle_AKM_base_F: Rifle_Base_F { - initSpeed = -1.0014; + initSpeed = -1.0; ACE_barrelTwist = 199.898; ACE_barrelLength = 414.02; }; + + // AK12 class arifle_AK12_base_F: Rifle_Base_F { - initSpeed = -1.0014; + initSpeed = -1.0; ACE_barrelTwist = 199.898; ACE_barrelLength = 414.02; }; + + // QBZ-95-1 class arifle_CTAR_base_F: Rifle_Base_F { + initSpeed = -0.978947; + ACE_barrelTwist = 244.0; + ACE_barrelLength = 463.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.12); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(1.12); + }; + }; + + // QBU-88 + class DMR_07_base_F: Rifle_Long_Base_F { + initSpeed = -0.99998; + ACE_barrelTwist = 228.6; + ACE_barrelLength = 640.0; + magazines[] = { + "20Rnd_650x39_Cased_Mag_F", + "ACE_20Rnd_65x47_Scenar_mag", + "ACE_20Rnd_65_Creedmor_mag" + }; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.01); + }; + }; + + // QBZ-95-1 LSW + class arifle_CTARS_base_F: Rifle_Base_F { initSpeed = -1.0; ACE_barrelTwist = 244.0; - ACE_barrelLength = 463.0; - }; - class arifle_CTARS_base_F: Rifle_Base_F { - initSpeed = -1.04301; - ACE_barrelTwist = 244.0; ACE_barrelLength = 600.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.12); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(1.12); + }; }; + + // Type 115 class arifle_ARX_base_F: Rifle_Base_F { - initSpeed = -1.02052; + initSpeed = -0.984262; ACE_barrelTwist = 228.6; ACE_barrelLength = 463.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(0.90); + }; + + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(0.90); + }; }; + + // KH2002 Sama class arifle_Katiba_F: arifle_katiba_Base_F { magazines[] = { "30Rnd_65x39_caseless_green", "30Rnd_65x39_caseless_green_mag_Tracer", "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" }; - initSpeed = -1.08355; + initSpeed = -1.0; ACE_barrelTwist = 203.2; ACE_barrelLength = 508.0; }; + + // KH2002C Sama class arifle_Katiba_C_F: arifle_katiba_Base_F { magazines[] = { "30Rnd_65x39_caseless_green", "30Rnd_65x39_caseless_green_mag_Tracer", "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" }; - initSpeed = -1.07105; + initSpeed = -0.961294; ACE_barrelTwist = 203.2; ACE_barrelLength = 393.7; + class Single: Single { + dispersion = MOA_TO_RAD(0.90); + }; + + class FullAuto: FullAuto { + dispersion = MOA_TO_RAD(0.90); + }; }; + + // KH2002 Sama KGL class arifle_Katiba_GL_F: arifle_katiba_Base_F { magazines[] = { "30Rnd_65x39_caseless_green", "30Rnd_65x39_caseless_green_mag_Tracer", "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim" }; - initSpeed = -1.08355; + initSpeed = -1.0; ACE_barrelTwist = 203.2; ACE_barrelLength = 508.0; }; + + // MX class arifle_MX_F: arifle_MX_Base_F { magazines[] = { "30Rnd_65x39_caseless_mag", "30Rnd_65x39_caseless_mag_Tracer", "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" }; - initSpeed = -0.990132; + initSpeed = -0.972222; ACE_barrelTwist = 228.6; ACE_barrelLength = 368.3; }; + + // MX 3GL class arifle_MX_GL_F: arifle_MX_Base_F { magazines[] = { "30Rnd_65x39_caseless_mag", "30Rnd_65x39_caseless_mag_Tracer", "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" }; - initSpeed = -0.99; + initSpeed = -0.972222; ACE_barrelTwist = 228.6; ACE_barrelLength = 368.3; }; - /* - class arifle_MX_SW_F: arifle_MX_Base_F { - ACE_barrelTwist=228.6; - ACE_barrelLength=406.4; - }; - */ + + // MXC class arifle_MXC_F: arifle_MX_Base_F { magazines[] = { "30Rnd_65x39_caseless_mag", "30Rnd_65x39_caseless_mag_Tracer", "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" }; - initSpeed = -0.963816; + initSpeed = -0.946382; ACE_barrelTwist = 203.2; ACE_barrelLength = 266.7; + class Single: Single { + dispersion = MOA_TO_RAD(0.90); + }; + + class FullAuto: FullAuto { + dispersion = MOA_TO_RAD(0.90); + }; }; - /* - class arifle_MXM_F: arifle_MX_Base_F { - ACE_barrelTwist=228.6; - ACE_barrelLength=457.2; - }; - */ + + // RFB SDAR class arifle_SDAR_F: SDAR_base_F { magazines[] = { "20Rnd_556x45_UW_mag", @@ -382,20 +520,28 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.989; + initSpeed = -0.998321; ACE_barrelTwist = 285.75; ACE_barrelLength = 457.2; }; - class SMG_02_base_F: Rifle_Short_Base_F { - initSpeed = -1.10288; + + class SMG_02_base_F: Rifle_Short_Base_F {}; + + // Scorpion Evo 3 A1 + class SMG_02_F: SMG_02_base_F { + initSpeed = -1.00029; ACE_barrelTwist = 254.0; ACE_barrelLength = 195.58; }; + + // MP5K class SMG_05_base_F: Rifle_Short_Base_F { - initSpeed = -1.04058; + initSpeed = -0.943783; ACE_barrelTwist = 254.0; ACE_barrelLength = 115.0; }; + + // CTAR-21 class arifle_TRG20_F: Tavor_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -409,10 +555,12 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.95; + initSpeed = -0.961496; ACE_barrelTwist = 177.8; ACE_barrelLength = 381.0; }; + + // TAR-21 class arifle_TRG21_F: Tavor_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -426,10 +574,19 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.988043; + initSpeed = -1.0; ACE_barrelTwist = 177.8; ACE_barrelLength = 459.74; + class Single: Single { + dispersion = MOA_TO_RAD(1.12); + }; + + class FullAuto: FullAuto { + dispersion = MOA_TO_RAD(1.12); + }; }; + + // TAR-21 EGLM class arifle_TRG21_GL_F: arifle_TRG21_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -443,16 +600,12 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.988043; + initSpeed = -1.0; ACE_barrelTwist = 177.8; ACE_barrelLength = 459.74; }; - /* - class LMG_Zafir_F: Rifle_Long_Base_F { - ACE_barrelTwist=304.8; - ACE_barrelLength=459.74; - }; - */ + + // F2000 class arifle_Mk20_F: mk20_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -466,10 +619,12 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.980978; + initSpeed = -0.992849; ACE_barrelTwist = 177.8; ACE_barrelLength = 441.96; }; + + // F2000 Tactical class arifle_Mk20C_F: mk20_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -483,10 +638,19 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.962648; + initSpeed = -0.974297; ACE_barrelTwist = 177.8; ACE_barrelLength = 406.4; + class Single: Single { + dispersion = MOA_TO_RAD(1.12); + }; + + class FullAuto: FullAuto { + dispersion = MOA_TO_RAD(1.12); + }; }; + + // F2000 EGLM class arifle_Mk20_GL_F: mk20_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -500,24 +664,32 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.962648; + initSpeed = -0.974297; ACE_barrelTwist = 177.8; ACE_barrelLength = 406.4; }; - class SMG_01_Base: Rifle_Short_Base_F { - initSpeed = -1.0175; + + class SMG_01_Base: Rifle_Short_Base_F {}; + + // Vector SMG + class SMG_01_F: SMG_01_Base { + initSpeed = -1.00148; ACE_barrelTwist = 406.4; ACE_barrelLength = 139.7; }; + + // VS-121 class srifle_DMR_01_F: DMR_01_base_F { magazines[] = { "10Rnd_762x54_Mag", "ACE_10Rnd_762x54_Tracer_mag" }; - initSpeed = -1.025; + initSpeed = -1.00019; ACE_barrelTwist = 241.3; ACE_barrelLength = 609.6; }; + + // Mk14 Mod 1 EBR class srifle_EBR_F: EBR_base_F { magazines[] = { "20Rnd_762x51_Mag", @@ -529,17 +701,12 @@ class CfgWeapons { "ACE_20Rnd_762x51_M993_AP_Mag", "ACE_20Rnd_762x51_Mag_SD" }; - initSpeed = -0.972389; + initSpeed = -0.979444; ACE_barrelTwist = 304.8; ACE_barrelLength = 457.2; }; - /* - class LMG_Mk200_F: Rifle_Long_Base_F { - initSpeed = -1.0; - ACE_barrelTwist=177.8; - ACE_barrelLength=317.5; - }; - */ + + // M200 Intervention class srifle_LRR_F: LRR_base_F { magazines[] = { "7Rnd_408_Mag", @@ -549,6 +716,8 @@ class CfgWeapons { ACE_barrelTwist = 330.2; ACE_barrelLength = 736.6; }; + + // GM6 Lynx class srifle_GM6_F: GM6_base_F { magazines[] = { "5Rnd_127x108_Mag", @@ -561,6 +730,8 @@ class CfgWeapons { ACE_barrelTwist = 381.0; ACE_barrelLength = 730; }; + + // Noreen "Bad News" ULR class srifle_DMR_02_F: DMR_02_base_F { magazines[] = { "10Rnd_338_Mag", @@ -570,10 +741,12 @@ class CfgWeapons { "ACE_20Rnd_762x67_Mk248_Mod_1_Mag", "ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag" }; - initSpeed = -0.961749; + initSpeed = -1.0; ACE_barrelTwist = 254.0; ACE_barrelLength = 508.0; }; + + // SIG 556 class srifle_DMR_03_F: DMR_03_base_F { magazines[] = { "20Rnd_762x51_Mag", @@ -585,20 +758,26 @@ class CfgWeapons { "ACE_20Rnd_762x51_M993_AP_Mag", "ACE_20Rnd_762x51_Mag_SD" }; - initSpeed = -0.984394; + initSpeed = -0.991536; ACE_barrelTwist = 254.0; ACE_barrelLength = 508.0; }; + + // ASP-1 Kir class srifle_DMR_04_F: DMR_04_base_F { initSpeed = -1.0; ACE_barrelTwist = 203.2; ACE_barrelLength = 450.088; }; + + // Cyrus class srifle_DMR_05_blk_F: DMR_05_base_F { initSpeed = -1.0; ACE_barrelTwist = 359.918; ACE_barrelLength = 620.014; }; + + // M14 class srifle_DMR_06_camo_F: DMR_06_base_F { magazines[] = { "20Rnd_762x51_Mag", @@ -610,15 +789,19 @@ class CfgWeapons { "ACE_20Rnd_762x51_M993_AP_Mag", "ACE_20Rnd_762x51_Mag_SD" }; - initSpeed = -0.992197; + initSpeed = -0.999395; ACE_barrelTwist = 304.8; ACE_barrelLength = 558.8; }; + + // HK121 class MMG_01_hex_F: MMG_01_base_F { - initSpeed = -0.997073; + initSpeed = -0.985613; ACE_barrelTwist = 359.918; ACE_barrelLength = 549.91; }; + + // LWMMG class MMG_02_camo_F: MMG_02_base_F { initSpeed = -1.0; ACE_barrelTwist = 234.95; diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index ad33b30704..d8c09cbaeb 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -1978,52 +1978,50 @@ 口径: 6.5x47mm Creedmor 狙击专用弹<br />发数: 30<br />使用于: MXM - .338 10Rnd Mag (300gr Sierra MatchKing HPBT) - Ch. .338 10 Cps (300gr Sierra MatchKing HPBT) - Cargador de 10 balas de 8.6x70mm (300gr Sierra MatchKing HPBT) - Magazynek .338 10rd (300gr Sierra MatchKing HPBT) - Магазин из 10-ти .338 (300 гран Sierra MatchKing экспансивные) - .338 10-Patronen-Magazin (300gr Sierra MatchKing HPBT) - .338 10Munizioni Mag (300gr Sierra MatchKing HPBT) - .338 10náb. Zásobník (300gr Sierra MatchKing HPBT) - Carregador .338 (300gr Sierra MatchKing HPBT) com 10 cartuchos - .338 10-lövedékes tár (300gr Sierra MatchKing HPBT) - .338 10発入り 弾倉 (300gr Sierra MatchKing HPBT) - 10발들이 .338 탄창 (300gr Sierra MatchKing HPBT) - .338 10發 彈匣 (300公克 Sierra MatchKing 空尖艇尾比賽專用彈) - .338 10发 弹匣 (300公克 Sierra MatchKing 空尖艇尾比赛专用弹) + .338 10Rnd Mag (300gr Lapua Scenar) + Ch. .338 10 Cps (300gr Lapua Scenar) + Cargador de 10 balas de 8.6x70mm (300gr Lapua Scenar) + Magazynek .338 10rd (300gr Lapua Scenar) + Магазин из 10-ти .338 (300 гран Lapua Scenar) + .338 10-Patronen-Magazin (300gr Lapua Scenar) + .338 10Munizioni Mag (300gr Lapua Scenar) + .338 10náb. Zásobník (300gr Lapua Scenar) + Carregador .338 (300gr Lapua Scenar) com 10 cartuchos + .338 10-lövedékes tár (300gr Lapua Scenar) + .338 10発入り 弾倉 (300gr Lapua Scenar) + 10발들이 .338 탄창 (300gr Lapua Scenar) + .338 10發 彈匣 (300公克 Lapua Scenar) + .338 10发 弹匣 (300公克 Lapua Scenar) - .338 HPBT - .338 HPBT - .338 HPBT - .338 HPBT - .338 экспансивные - .338 HPBT - .338 HPBT - .338 HPBT - .338 HPBT - .338 HPBT - 338 HPBT - .338 HPBT - .338 空尖艇尾比賽專用彈 - .338 空尖艇尾比赛专用弹 + .338 Scenar + .338 Scenar + .338 Scenar + .338 Scenar + .338 Scenar + .338 Scenar + .338 Scenar + .338 Scenar + .338 Scenar + .338 Scenar + 338 Scenar + .338 Scenar - Caliber: 8.6x70mm (300gr Sierra MatchKing HPBT)<br />Rounds: 10 - Calibre: 8,6x70mm (300gr Sierra MatchKing HPBT)<br />Cartouches: 10 - Calibre: 8.6x70mm (300gr Sierra MatchKing HPBT)<br />Balas: 10 - Kaliber: 8,6x70mm (300gr Sierra MatchKing HPBT)<br />Pociski: 10 - Калибр: 8,6x70mm (300 гран Sierra MatchKing экспансивные)<br />Патронов: 10 - Kaliber: 8,6x70mm (300gr Sierra MatchKing HPBT)<br />Patronen: 10 - Calibro: 8.6x70mm (300gr Sierra MatchKing HPBT)<br />Munizioni: 10 - Ráže: 8.6x70mm (300gr Sierra MatchKing HPBT)<br />Nábojů: 10 - Calibre: 8.6x70mm (300gr Sierra MatchKing HPBT)<br/>Cartuchos: 10 - Kaliber: 8,6x70mm (300gr Sierra MatchKing HPBT)<br />Lövedékek: 10 - 口径: 8.6x70mm (300gr Sierra MatchKing HPBT)<br />装填数: 10 - 구경: 8.6x70mm (300gr Sierra MatchKing HPBT)<br />장탄수: 10 - 口徑: 8.6x70mm (300公克 Sierra MatchKing 空尖艇尾比賽專用彈)<br />發數: 10 - 口径: 8.6x70mm (300公克 Sierra MatchKing 空尖艇尾比赛专用弹)<br />发数: 10 + Caliber: 8.6x70mm (300gr Lapua Scenar)<br />Rounds: 10 + Calibre: 8,6x70mm (300gr Lapua Scenar)<br />Cartouches: 10 + Calibre: 8.6x70mm (300gr Lapua Scenar)<br />Balas: 10 + Kaliber: 8,6x70mm (300gr Lapua Scenar)<br />Pociski: 10 + Калибр: 8,6x70mm (300 гран Lapua Scenar)<br />Патронов: 10 + Kaliber: 8,6x70mm (300gr Lapua Scenar)<br />Patronen: 10 + Calibro: 8.6x70mm (300gr Lapua Scenar)<br />Munizioni: 10 + Ráže: 8.6x70mm (300gr Lapua Scenar)<br />Nábojů: 10 + Calibre: 8.6x70mm (300gr Lapua Scenar)<br/>Cartuchos: 10 + Kaliber: 8,6x70mm (300gr Lapua Scenar)<br />Lövedékek: 10 + 口径: 8.6x70mm (300gr Lapua Scenar)<br />装填数: 10 + 구경: 8.6x70mm (300gr Lapua Scenar)<br />장탄수: 10 + 口徑: 8.6x70mm (300公克 Lapua Scenar)<br />發數: 10 + 口径: 8.6x70mm (300公克 Lapua Scenar)<br />发数: 10 .338 10Rnd Mag (API526) diff --git a/addons/captives/ACE_Settings.hpp b/addons/captives/ACE_Settings.hpp index 1d0ebbf491..50d4c17aa7 100644 --- a/addons/captives/ACE_Settings.hpp +++ b/addons/captives/ACE_Settings.hpp @@ -1,11 +1,13 @@ class ACE_Settings { class GVAR(allowHandcuffOwnSide) { + category = CSTRING(DisplayName); displayName = CSTRING(ModuleSettings_handcuffSide_name); description = CSTRING(ModuleSettings_handcuffSide_description); typeName = "BOOL"; value = 1; }; class GVAR(requireSurrender) { + category = CSTRING(DisplayName); displayName = CSTRING(ModuleSettings_requireSurrender_name); description = CSTRING(ModuleSettings_requireSurrender_description); typeName = "SCALAR"; @@ -13,9 +15,17 @@ class ACE_Settings { value = 1; }; class GVAR(allowSurrender) { + category = CSTRING(DisplayName); displayName = CSTRING(ModuleSettings_allowSurrender_name); description = CSTRING(ModuleSettings_allowSurrender_description); typeName = "BOOL"; value = 1; }; + class GVAR(requireSurrenderAi) { + category = CSTRING(DisplayName); + displayName = CSTRING(ModuleSettings_requireSurrenderAi_name); + description = CSTRING(ModuleSettings_requireSurrenderAi_description); + typeName = "BOOL"; + value = 0; + }; }; diff --git a/addons/captives/CfgEventHandlers.hpp b/addons/captives/CfgEventHandlers.hpp index e2e8df28f1..95453fe5d1 100644 --- a/addons/captives/CfgEventHandlers.hpp +++ b/addons/captives/CfgEventHandlers.hpp @@ -63,3 +63,11 @@ class Extended_Local_EventHandlers { }; }; }; + +class Extended_Killed_EventHandlers { + class CAManBase { + class ADDON { + killed = QUOTE(_this call FUNC(handleKilled)); + }; + }; +}; diff --git a/addons/captives/CfgVehicles.hpp b/addons/captives/CfgVehicles.hpp index 2afa1cfea4..8fdb45396e 100644 --- a/addons/captives/CfgVehicles.hpp +++ b/addons/captives/CfgVehicles.hpp @@ -2,14 +2,13 @@ class CfgVehicles { class Man; class CAManBase: Man { class ACE_Actions { - class ACE_ApplyHandcuffs { displayName = CSTRING(SetCaptive); selection = "righthand"; distance = 2; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canApplyHandcuffs)); statement = QUOTE([ARR_2(_player, _target)] call FUNC(doApplyHandcuffs)); - exceptions[] = {}; + exceptions[] = {"isNotSwimming", "isNotInside"}; icon = QPATHTOF(UI\handcuff_ca.paa); }; @@ -20,7 +19,7 @@ class CfgVehicles { distance = 2; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRemoveHandcuffs)); statement = QUOTE([ARR_2(_player, _target)] call FUNC(doRemoveHandcuffs)); - exceptions[] = {}; + exceptions[] = {"isNotSwimming", "isNotInside"}; icon = QPATHTOF(UI\handcuff_ca.paa); }; class ACE_EscortCaptive { @@ -28,7 +27,7 @@ class CfgVehicles { distance = 4; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canEscortCaptive)); statement = QUOTE([ARR_3(_player, _target, true)] call FUNC(doEscortCaptive)); - exceptions[] = {}; + exceptions[] = {"isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\captive_ca.paa); priority = 2.3; @@ -38,7 +37,7 @@ class CfgVehicles { distance = 4; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canStopEscorting)); statement = QUOTE([ARR_3(_player,_target, false)] call FUNC(doEscortCaptive)); - exceptions[] = {"isNotEscorting"}; + exceptions[] = {"isNotEscorting", "isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\captive_ca.paa); priority = 2.3; @@ -48,16 +47,18 @@ class CfgVehicles { distance = 4; condition = QUOTE([ARR_3(_player, _target, objNull)] call FUNC(canLoadCaptive)); statement = QUOTE([ARR_3(_player, _target, objNull)] call FUNC(doLoadCaptive)); - exceptions[] = {"isNotEscorting"}; + exceptions[] = {"isNotEscorting", "isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\captive_ca.paa); priority = 2.2; + insertChildren = QUOTE(call DFUNC(addLoadCaptiveActions)); }; class GVAR(UnloadCaptive) { displayName = CSTRING(UnloadCaptive); distance = 4; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canUnloadCaptive)); statement = QUOTE([ARR_2(_player, _target)] call FUNC(doUnloadCaptive)); + exceptions[] = {"isNotSwimming"}; priority = 1.2; }; }; @@ -68,7 +69,7 @@ class CfgVehicles { displayName = CSTRING(StopEscorting); condition = QUOTE([ARR_2(_player, objNull)] call FUNC(canStopEscorting)); statement = QUOTE([ARR_3(_player,objNull, false)] call FUNC(doEscortCaptive)); - exceptions[] = {"isNotEscorting"}; + exceptions[] = {"isNotEscorting", "isNotSwimming"}; showDisabled = 0; priority = 2.3; }; @@ -76,7 +77,7 @@ class CfgVehicles { displayName = CSTRING(StartSurrendering); condition = QUOTE([ARR_2(_player, true)] call FUNC(canSurrender)); statement = QUOTE([ARR_2(_player, true)] call FUNC(setSurrendered)); - exceptions[] = {}; + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 0; icon = QPATHTOF(UI\Surrender_ca.paa); @@ -85,7 +86,7 @@ class CfgVehicles { displayName = CSTRING(StopSurrendering); condition = QUOTE([ARR_2(_player, false)] call FUNC(canSurrender)); statement = QUOTE([ARR_2(_player, false)] call FUNC(setSurrendered)); - exceptions[] = {"isNotSurrendering"}; + exceptions[] = {"isNotSurrendering", "isNotSwimming"}; showDisabled = 0; priority = 0; icon = QPATHTOF(UI\Surrender_ca.paa); @@ -101,7 +102,7 @@ class CfgVehicles { distance = 4; \ condition = QUOTE([ARR_3(_player, objNull, _target)] call FUNC(canLoadCaptive)); \ statement = QUOTE([ARR_3(_player, objNull, _target)] call FUNC(doLoadCaptive)); \ - exceptions[] = {"isNotEscorting"}; \ + exceptions[] = {"isNotEscorting", "isNotSwimming"}; \ priority = 1.2; \ }; \ }; \ @@ -151,7 +152,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(ModuleSurrender_DisplayName); function = QFUNC(moduleSurrender); - scope = 2; //show in editor + scope = 1; //show in editor isGlobal = 0; //run on server isTriggerActivated = 1; //Wait for triggers icon = QPATHTOF(UI\Icon_Module_Make_Unit_Surrender_ca.paa); @@ -167,7 +168,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(ModuleHandcuffed_DisplayName); function = QFUNC(moduleHandcuffed); - scope = 2; //show in editor + scope = 1; //show in editor isGlobal = 0; //run on server isTriggerActivated = 1; //Wait for triggers icon = QPATHTOF(UI\Icon_Module_Make_Unit_Handcuffed_ca.paa); @@ -185,7 +186,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(ModuleSettings_DisplayName); function = QFUNC(moduleSettings); - scope = 2; + scope = 1; icon = QPATHTOF(UI\Icon_Module_settings_ca.paa); isGlobal = 1; isSingular = 1; @@ -222,6 +223,12 @@ class CfgVehicles { }; }; }; + class requireSurrenderAi { + displayName = CSTRING(ModuleSettings_requireSurrenderAi_name); + description = CSTRING(ModuleSettings_requireSurrenderAi_description); + typeName = "BOOL"; + defaultValue = 0; + }; }; class ModuleDescription: ModuleDescription { description = CSTRING(ModuleSettings_Description); diff --git a/addons/captives/CfgWeapons.hpp b/addons/captives/CfgWeapons.hpp index 1b65a0a4bf..34f7b59e10 100644 --- a/addons/captives/CfgWeapons.hpp +++ b/addons/captives/CfgWeapons.hpp @@ -1,14 +1,15 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_CableTie: ACE_ItemCore { + author = ECSTRING(common,ACETeam); displayName = CSTRING(CableTie); descriptionShort = CSTRING(CableTieDescription); model = QPATHTOF(models\ace_cabletie.p3d); picture = QPATHTOF(UI\ace_cabletie_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; diff --git a/addons/captives/XEH_PREP.hpp b/addons/captives/XEH_PREP.hpp index bfb1ade5e0..bf0b06a1db 100644 --- a/addons/captives/XEH_PREP.hpp +++ b/addons/captives/XEH_PREP.hpp @@ -1,4 +1,4 @@ - +PREP(addLoadCaptiveActions); PREP(canApplyHandcuffs); PREP(canEscortCaptive); PREP(canFriskPerson); @@ -18,6 +18,7 @@ PREP(handleAnimChangedHandcuffed); PREP(handleAnimChangedSurrendered); PREP(handleGetIn); PREP(handleGetOut); +PREP(handleKilled); PREP(handleLocal); PREP(handleOnUnconscious); PREP(handlePlayerChanged); diff --git a/addons/captives/XEH_postInit.sqf b/addons/captives/XEH_postInit.sqf index 25f41d1320..70d708ced2 100644 --- a/addons/captives/XEH_postInit.sqf +++ b/addons/captives/XEH_postInit.sqf @@ -1,4 +1,5 @@ #include "script_component.hpp" +#include "\a3\editor_f\Data\Scripts\dikCodes.h" ["ace_settingsInitialized", { // Hold on a little bit longer to ensure anims will work @@ -35,6 +36,22 @@ if (isServer) then { if (!hasInterface) exitWith {}; -["isNotEscorting", {!(GETVAR(_this select 0,GVAR(isEscorting),false))}] call EFUNC(common,addCanInteractWithCondition); -["isNotHandcuffed", {!(GETVAR(_this select 0,GVAR(isHandcuffed),false))}] call EFUNC(common,addCanInteractWithCondition); -["isNotSurrendering", {!(GETVAR(_this select 0,GVAR(isSurrendering),false))}] call EFUNC(common,addCanInteractWithCondition); +["ACE3 Common", QGVAR(captives), [(localize LSTRING(SetCaptive)), (localize LSTRING(KeyComb_description))], +{ + private _target = cursorObject; + if !([ACE_player, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; + if !(_target isKindOf "CAManBase") exitWith {false}; + if ((_target distance ACE_player) > getNumber (configFile >> "CfgVehicles" >> "CAManBase" >> "ACE_Actions" >> "ACE_ApplyHandcuffs" >> "distance")) exitWith {false}; + + if ([ACE_player, _target] call FUNC(canApplyHandcuffs)) exitWith { + [QGVAR(setHandcuffed), [_target, true], _target] call CBA_fnc_targetEvent; + true + }; + false +}, +{false}, +[DIK_F1, [true, false, false]], true] call CBA_fnc_addKeybind; // Shift + F1 + +["isNotEscorting", {!GETVAR(_this select 0,GVAR(isEscorting),false)}] call EFUNC(common,addCanInteractWithCondition); +["isNotHandcuffed", {!GETVAR(_this select 0,GVAR(isHandcuffed),false)}] call EFUNC(common,addCanInteractWithCondition); +["isNotSurrendering", {!GETVAR(_this select 0,GVAR(isSurrendering),false)}] call EFUNC(common,addCanInteractWithCondition); diff --git a/addons/captives/functions/fnc_addLoadCaptiveActions.sqf b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf new file mode 100644 index 0000000000..0c7adbda7a --- /dev/null +++ b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf @@ -0,0 +1,25 @@ +/* + * Author: 654wak654 + * Adds child actions to the "load captive" action for near vehicles. + * + * Arguments: + * 0: Captive + * + * Return Value: + * Child actions + * + * Example: + * [kevin] call ace_medical_fnc_addLoadCaptiveActions + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target"]; + +private _statement = { + params ["_target", "_player", "_vehicle"]; + [_player, _target, _vehicle] call FUNC(doLoadCaptive); +}; + +[_target call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/captives/functions/fnc_canApplyHandcuffs.sqf b/addons/captives/functions/fnc_canApplyHandcuffs.sqf index f5fa666652..231970255b 100644 --- a/addons/captives/functions/fnc_canApplyHandcuffs.sqf +++ b/addons/captives/functions/fnc_canApplyHandcuffs.sqf @@ -25,7 +25,7 @@ params ["_unit", "_target"]; {!(_target getVariable [QGVAR(isHandcuffed), false])} && { (_target getVariable ["ACE_isUnconscious", false]) || //isUnconscious - {!([_target] call EFUNC(common,isPlayer))} || //is an AI (not a player) + {!GVAR(requireSurrenderAi) && {!([_target] call EFUNC(common,isPlayer))}} || //is an AI (not a player) and doesn't require surrendering {GVAR(requireSurrender) == 0} || //or don't require surrendering {_target getVariable [QGVAR(isSurrendering), false]} || //or is surrendering {(GVAR(requireSurrender) == 2) && {(currentWeapon _target) == ""}} //or "SurrenderOrNoWeapon" and no weapon diff --git a/addons/captives/functions/fnc_canLoadCaptive.sqf b/addons/captives/functions/fnc_canLoadCaptive.sqf index a59c2e3be6..782661ea1c 100644 --- a/addons/captives/functions/fnc_canLoadCaptive.sqf +++ b/addons/captives/functions/fnc_canLoadCaptive.sqf @@ -4,20 +4,23 @@ * * Arguments: * 0: Unit that wants to load a captive - * 1: A captive. ObjNull for the first escorted captive (may be null) - * 2: Vehicle to load the captive into. ObjNull for the nearest vehicle (may be null) + * 1: A captive. objNull for the first escorted captive + * 2: Vehicle to load the captive into. objNull for the nearest vehicle * * Return Value: - * The return value + * Can load captive * * Example: - * [player, bob, car] call ACE_captives_fnc_canLoadCaptive + * [bob, tom, car] call ace_captives_fnc_canLoadCaptive * * Public: No */ #include "script_component.hpp" -params ["_unit", "_target","_vehicle"]; +params ["_unit", "_target", "_vehicle"]; + +// Don't show "Load Captive" if unit is unconscious (already has "Load Patient") +if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false}; if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then { //Looking at a vehicle while escorting, get target from attached objects: @@ -27,20 +30,16 @@ if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then { }; } forEach (attachedObjects _unit); }; -if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {false}; +if (isNull _target || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {false}; if (isNull _vehicle) then { - //Looking at a captive unit, search for nearby vehicles with valid seats: - { - if ((_x emptyPositions "cargo") > 0) exitWith { - _vehicle = _x; - }; - } forEach (nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10]); + // Looking at a captive unit, get nearest vehicle with valid seat: + _vehicle = (_target call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; } else { - //We have a vehicle picked, make sure it has empty seats: - if ((_vehicle emptyPositions "cargo") == 0) then { + // We have a vehicle picked, make sure it has empty seats: + if (_vehicle emptyPositions "cargo" == 0 && {_vehicle emptyPositions "gunner" == 0}) then { _vehicle = objNull; }; }; -(!isNull _vehicle) +!isNull _vehicle diff --git a/addons/captives/functions/fnc_canStopEscorting.sqf b/addons/captives/functions/fnc_canStopEscorting.sqf index cfafb5a0e8..181b16be94 100644 --- a/addons/captives/functions/fnc_canStopEscorting.sqf +++ b/addons/captives/functions/fnc_canStopEscorting.sqf @@ -1,13 +1,13 @@ /* * Author: PabstMirror - * Tests if player can stop escorting + * Tests if player can stop escorting. * * Arguments: - * 0: caller (player) - * 1: target + * 0: Caller (player) + * 1: Target (default: objNull) * * Return Value: - * The return value + * Can unit stop escorting another unit * * Example: * [player, bob] call ACE_captives_fnc_canStopEscorting diff --git a/addons/captives/functions/fnc_canUnloadCaptive.sqf b/addons/captives/functions/fnc_canUnloadCaptive.sqf index 82fc0a8429..0d8ec81b07 100644 --- a/addons/captives/functions/fnc_canUnloadCaptive.sqf +++ b/addons/captives/functions/fnc_canUnloadCaptive.sqf @@ -18,4 +18,5 @@ params ["_player", "_unit"]; -((vehicle _unit) != _unit) && {_unit getVariable [QGVAR(isHandcuffed), false]} +// Don't show "Unload Captive" if unit is unconscious (already has "Unload Patient") +(vehicle _unit != _unit) && {vehicle _player == _player} && {_unit getVariable [QGVAR(isHandcuffed), false]} && {!(_unit getVariable ["ACE_isUnconscious", false])} diff --git a/addons/captives/functions/fnc_doEscortCaptive.sqf b/addons/captives/functions/fnc_doEscortCaptive.sqf index ad57dabcd7..b17a48f7b8 100644 --- a/addons/captives/functions/fnc_doEscortCaptive.sqf +++ b/addons/captives/functions/fnc_doEscortCaptive.sqf @@ -32,7 +32,7 @@ if (_state) then { //Add Actionmenu to release captive private _actionID = _unit addAction [format ["%1", localize LSTRING(StopEscorting)], {[(_this select 0), ((_this select 0) getVariable [QGVAR(escortedUnit), objNull]), false] call FUNC(doEscortCaptive);}, - nil, 20, false, true, "", QUOTE(!isNull (GETVAR(_target,QGVAR(escortedUnit),objNull)))]; + nil, 20, false, true, "", QUOTE(!isNull GETVAR(_target,QGVAR(escortedUnit),objNull))]; [{ params ["_args", "_pfID"]; diff --git a/addons/captives/functions/fnc_doLoadCaptive.sqf b/addons/captives/functions/fnc_doLoadCaptive.sqf index 82e446b460..c47cc389d4 100644 --- a/addons/captives/functions/fnc_doLoadCaptive.sqf +++ b/addons/captives/functions/fnc_doLoadCaptive.sqf @@ -4,42 +4,37 @@ * * Arguments: * 0: Unit that wants to load a captive - * 1: A captive. ObjNull for the first escorted captive - * 2: Vehicle to load the captive into. ObjNull for the nearest vehicle + * 1: A captive. objNull for the first escorted captive + * 2: Vehicle to load the captive into. objNull for the nearest vehicle * * Return Value: * None * * Example: - * [bob, tom, car] call ACE_captives_fnc_doLoadCaptive + * [bob, tom, car] call ace_captives_fnc_doLoadCaptive * * Public: No */ #include "script_component.hpp" -params ["_unit", "_target","_vehicle"]; +params ["_unit", "_target", "_vehicle"]; -if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then { - //Looking at a vehicle while escorting, get target from attached objects: +if (isNull _target && {_unit getVariable [QGVAR(isEscorting), false]}) then { + // Looking at a vehicle while escorting, get target from attached objects: { if (_x getVariable [QGVAR(isHandcuffed), false]) exitWith { _target = _x; }; } forEach (attachedObjects _unit); }; -if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {WARNING("");}; +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: - { - // if (([_x] call FUNC(findEmptyNonFFVCargoSeat)) != -1) exitWith { - if ((_x emptyPositions "cargo") > 0) exitWith { - _vehicle = _x; - }; - } forEach (nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10]); + // Looking at a captive unit, get nearest vehicle with valid seat: + _vehicle = (_target call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; } else { - // if (([_vehicle] call FUNC(findEmptyNonFFVCargoSeat)) == -1) then { - if ((_vehicle emptyPositions "cargo") == 0) then { + // We have a vehicle picked, make sure it has empty seats: + if (_vehicle emptyPositions "cargo" == 0 && {_vehicle emptyPositions "gunner" == 0}) then { _vehicle = objNull; }; }; diff --git a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf index 63792a7c55..91bb800c05 100644 --- a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf +++ b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf @@ -18,20 +18,18 @@ params ["_vehicle"]; TRACE_1("params", _vehicle); -private _vehicleConfig = configFile >> "CfgVehicles" >> (typeOf _vehicle); - scopeName "main"; { _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; - if ((isNull _unit) && {_role == "cargo"} && {_cargoIndex > -1} && {!_isPersonTurret}) then { + if (isNull _unit && {_role == "cargo"} && {_cargoIndex > -1} && {!_isPersonTurret}) then { [_cargoIndex, false] breakOut "main"; }; } forEach (fullCrew [_vehicle, "", true]); { _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; - if ((isNull _unit) && {_cargoIndex > -1}) then { + if (isNull _unit && {_cargoIndex > -1}) then { [_cargoIndex, true] breakOut "main"; }; } forEach (fullCrew [_vehicle, "", true]); diff --git a/addons/captives/functions/fnc_handleKilled.sqf b/addons/captives/functions/fnc_handleKilled.sqf new file mode 100644 index 0000000000..27963e460d --- /dev/null +++ b/addons/captives/functions/fnc_handleKilled.sqf @@ -0,0 +1,24 @@ +/* + * Author: Jonpas + * Called when a unit dies. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [bob] call ace_captives_fnc_handleKilled + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; +TRACE_1("handleKilled",_unit); + +// Remove handcuffs on a dead unit, removing them after unit goes into ragdoll causes a stand-up twitch and restarts the ragdoll +if (_unit getVariable [QGVAR(isHandcuffed), false]) then { + [_unit, false] call FUNC(setHandcuffed); +}; diff --git a/addons/captives/functions/fnc_handleRespawn.sqf b/addons/captives/functions/fnc_handleRespawn.sqf index 98672798fd..2d6618c6d1 100644 --- a/addons/captives/functions/fnc_handleRespawn.sqf +++ b/addons/captives/functions/fnc_handleRespawn.sqf @@ -17,6 +17,7 @@ #include "script_component.hpp" params ["_unit","_dead"]; +TRACE_2("handleRespawn",_unit,_dead); if (!local _unit) exitWith {}; diff --git a/addons/captives/functions/fnc_moduleSettings.sqf b/addons/captives/functions/fnc_moduleSettings.sqf index 6be3fb8d56..04ffc04f45 100644 --- a/addons/captives/functions/fnc_moduleSettings.sqf +++ b/addons/captives/functions/fnc_moduleSettings.sqf @@ -21,3 +21,4 @@ params ["_logic"]; [_logic, QGVAR(allowHandcuffOwnSide), "allowHandcuffOwnSide"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(allowSurrender), "allowSurrender"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(requireSurrender), "requireSurrender"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(requireSurrenderAi), "requireSurrenderAi"] call EFUNC(common,readSettingFromModule); diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 467d06bd83..bf08c2a848 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -1,6 +1,15 @@ - + + + Captives + Gefangene + Prigionieri + 俘虜 + 俘虏 + 捕虜 + 포로설정 + Take Prisoner Gefangen nehmen @@ -13,7 +22,7 @@ Foglyul ejtés Взять в плен 捕虜にする - 사로잡기 + 포박하기 逮捕俘虜 逮捕俘虏 @@ -238,8 +247,8 @@ Sincronizza una unità per farla arrendere. 同期されたユニットを投降させます。 투항시키기 위해 동기화합니다. - 同步此模塊到一個單位, 使該單位投降 - 同步此模块到一个单位, 使该单位投降 + 同步此模塊到一個單位,使該單位投降 + 同步此模块到一个单位,使该单位投降 Make Unit Handcuffed @@ -252,13 +261,13 @@ Hacer que la unidad esté esposada Rendre une unité captive ユニットを拘束する - 수갑을 채우기 + 포박하기 使單位戴上手銬 使单位戴上手铐 Sync a unit to make them handcuffed. - Synchronisiere eine Einheit um sie in Handschellen zu legen. + Synchronisiere eine Einheit, um sie in Handschellen zu legen. Zsynchronizuj z jednostką, aby została skuta. Sincronizar uma unidade para deixá-la algemada. Синхронизируйте с юнитами, чтобы сделать их связанными. @@ -283,7 +292,7 @@ Настройки пленения Impostazioni Prigionieri 拘束の設定 - 포로 설정 + 포박 설정 俘虜設定 俘虏设定 @@ -314,8 +323,8 @@ Saját oldal megbilincselhető Связать союзника Puoi ammanettare unità alleate - 自陣営への拘束を可能に - 자기편에게 수갑을 채울 수 있게 합니다 + 拘束ユニットを自陣営へ + 자기편을 포박 할 수 있습니다. 可以銬住同陣營隊友 可以铐住同阵营队友 @@ -324,13 +333,13 @@ Czy gracze mogą skuwać sojuszników? Pueden los jugadores esposar unidades en su propio bando Mohou hráči spoutat jednotky na své straně - Spieler können eigene Einheiten fesseln. + Spieler können eigene Einheiten fesseln Os jogadores podem algemar unidades do seu lado Les joueurs peuvent utiliser les Serflex sur leur propre camp A játékosok megkötözhetik-e a saját oldalukon lévő egységeket Разрешить игрокам связывать юнитов своей стороны I giocatori possono ammanettare unità alleate - プレイヤーがユニットを拘束し、彼らの陣営に変更できます。 + プレイヤーが拘束したユニットの陣営を自陣営に変更させます。 자기편에게 케이블타이를 사용할 수 있게합니다 玩家可以使用束線帶銬住同陣營隊友 玩家可以使用束线带铐住同阵营队友 @@ -362,7 +371,7 @@ A játékosok megadhatják magukat a fegyverük elrakása után Игроки могут сдаться в плен после того, как уберут оружие I giocatori possono arrendersi dopo aver messo via le proprie armi - プレイヤーは武器を収めたあとに投降できるようにします。 + プレイヤーは武器を収めたあと投降できるようにします。 비무장한 플레이어가 투항할 수 있게 합니다 玩家能在收起自己武器後投降 玩家能在收起自己武器后投降 @@ -393,9 +402,9 @@ I giocatori devono arrendersi prima che possano essere arrestati Requiert la capitulation des joueurs avant qu'ils ne puissent être arrêtés プレイヤーは拘束される前に、投降する必要があります。 - 체포하기 전에 플레이어가 투항을 먼저해야만 합니다 - 玩家須先要求目標投降, 才可以進行逮捕 - 玩家须先要求目标投降, 才可以进行逮捕 + 체포하기 전에 먼저 플레이어가 투항을 해야만 합니다 + 玩家須先要求目標投降,才可以進行逮捕 + 玩家须先要求目标投降,才可以进行逮捕 Surrendering only @@ -427,5 +436,32 @@ 投降或無武器狀態 投降或无武器状态 + + Sets the unit under the cursor captive. + Nimmt die Einheit unter dem Cursor fest. + カーソル先のユニットを拘束 + Imposta l'unità nello stato di prigioniero. + 設置在游標下的單位成俘虜狀態。 + 设置在游标下的单位成俘虏状态。 + 커서의 병력을 포박합니다. + + + Require AI surrendering + Benötigt für KI Kapitulation + Necessita arresa AI + AI の投降を必要とする + 需要AI先行投降 + 需要AI先行投降 + AI 항복 필요 + + + Require AI to surrender before they can be arrested + KI muss sich erst ergeben, bevor sie gefangen genommen werden kann + Necessita che le AI si arrendano prima di essere arrestate + AI の拘束は AI が投降している場合に限り可能にします。 + 在逮捕AI之前該AI必須先進入投降狀態。 + 在逮捕AI之前该AI必须先进入投降状态。 + 포박하기 전에 먼저 AI가 투항해야만 합니다. + diff --git a/addons/cargo/ACE_Settings.hpp b/addons/cargo/ACE_Settings.hpp index 595de28459..e95465e647 100644 --- a/addons/cargo/ACE_Settings.hpp +++ b/addons/cargo/ACE_Settings.hpp @@ -12,5 +12,6 @@ class ACE_Settings { typeName = "SCALAR"; value = 2.5; category = ECSTRING(OptionsMenu,CategoryLogistics); + sliderSettings[] = {0, 10, 2.5, 1}; }; }; diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index b8d5b30415..8588296154 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -8,7 +8,7 @@ class CfgVehicles { }; class ACE_Module: Module_F {}; class ACE_moduleCargoSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(SettingsModule_DisplayName); icon = QPATHTOF(UI\Icon_Module_Cargo_ca.paa); category = "ACE_Logistics"; @@ -39,32 +39,9 @@ class CfgVehicles { sync[] = {}; }; }; - class GVAR(makeLoadable): ACE_Module { - scope = 2; - displayName = CSTRING(makeLoadable_displayName); - icon = QPATHTOF(UI\Icon_Module_makeLoadable_ca.paa); - category = "ACE_Logistics"; - function = QFUNC(moduleMakeLoadable); - isGlobal = 1; - isTriggerActivated = 0; - author = ECSTRING(common,ACETeam); - class Arguments { - class canLoad { - displayName = CSTRING(makeLoadable_displayName); - description = CSTRING(MakeLoadable_description); - typeName = "BOOL"; - defaultValue = 1; - }; - class setSize { - displayName = CSTRING(makeLoadable_setSize_displayName); - typeName = "NUMBER"; - defaultValue = 1; - }; - }; - class ModuleDescription: ModuleDescription { - description = CSTRING(makeLoadable_description); - sync[] = {"AnyStaticObject"}; - }; + class GVAR(makeLoadable): Logic { + scope = 1; + displayName = "Delete (Deprecated in ACE3 3.12.0)"; }; class LandVehicle; @@ -200,6 +177,11 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; + class ParachuteBase: Helicopter { + GVAR(space) = 0; + GVAR(hasCargo) = 0; + }; + class Helicopter_Base_H; class Heli_Light_01_base_F: Helicopter_Base_H { GVAR(space) = 0; @@ -286,11 +268,19 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - // autonomus + // autonomous class UAV_01_base_F: Helicopter_Base_F { GVAR(space) = 0; GVAR(hasCargo) = 0; }; + class UAV_03_base_F: Helicopter_Base_F { + GVAR(space) = 0; + GVAR(hasCargo) = 0; + }; + class UAV_06_base_F: Helicopter_Base_F { + GVAR(space) = 0; + GVAR(hasCargo) = 0; + }; // boats class Ship; @@ -424,7 +414,14 @@ class CfgVehicles { GVAR(size) = 2; // 1 = small, 2 = large }; + // Fuel Canister (ace_refuel) + class Land_CanisterFuel_F: Items_base_F { + GVAR(size) = 1; + GVAR(canLoad) = 1; + }; + // objects + class Lamps_base_F; class RoadCone_F: ThingX { GVAR(size) = 1; GVAR(canLoad) = 1; @@ -432,6 +429,10 @@ class CfgVehicles { class RoadBarrier_F: RoadCone_F { GVAR(size) = 2; }; + class Land_PortableLight_single_F: Lamps_base_F { + GVAR(size) = 1; + GVAR(canLoad) = 1; + }; class Scrapyard_base_F; class Land_PaperBox_closed_F: Scrapyard_base_F { @@ -742,7 +743,7 @@ class CfgVehicles { GVAR(size) = 100; }; - // small + // Small class Land_CargoBox_V1_F: ThingX { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; @@ -763,10 +764,55 @@ class CfgVehicles { }; }; }; + class Land_PaperBox_01_small_closed_base_F: Items_base_F { + GVAR(size) = 1; + GVAR(canLoad) = 1; - class Lamps_base_F; - class Land_PortableLight_single_F: Lamps_base_F { + maximumLoad = 1000; + transportMaxBackpacks = 12; + transportMaxMagazines = 64; + transportMaxWeapons = 12; + }; + class Box_UAV_06_base_F: Items_base_F { GVAR(size) = 1; GVAR(canLoad) = 1; }; + + // Aid items + class Land_FoodSack_01_full_base_F: Items_base_F { + GVAR(size) = 1; + GVAR(canLoad) = 1; + }; + class Land_FoodSack_01_cargo_base_F: Items_base_F { + GVAR(size) = 7; + GVAR(canLoad) = 1; + }; + class Land_FoodSack_01_large_base_F: Items_base_F { + GVAR(size) = 7; + GVAR(canLoad) = 1; + }; + class Land_FoodSack_01_small_base_F: Items_base_F { + GVAR(size) = 2; + GVAR(canLoad) = 1; + }; + class Land_PaperBox_01_open_boxes_F: Items_base_F { + GVAR(size) = 7; + GVAR(canLoad) = 1; + }; + class Land_PaperBox_01_open_water_F: Items_base_F { + GVAR(size) = 7; + GVAR(canLoad) = 1; + }; + class Land_PaperBox_01_open_empty_F: Items_base_F { + GVAR(size) = 7; + GVAR(canLoad) = 1; + }; + class Land_PaperBox_01_small_stacked_F: Items_base_F { + GVAR(size) = 7; + GVAR(canLoad) = 1; + }; + class Land_WaterBottle_01_stack_F: Items_base_F { + GVAR(size) = 7; + GVAR(canLoad) = 1; + }; }; diff --git a/addons/cargo/UI/Icon_Module_makeLoadable_ca.paa b/addons/cargo/UI/Icon_Module_makeLoadable_ca.paa deleted file mode 100644 index 1577116a66..0000000000 Binary files a/addons/cargo/UI/Icon_Module_makeLoadable_ca.paa and /dev/null differ diff --git a/addons/cargo/UI/Icon_load.paa b/addons/cargo/UI/Icon_load.paa deleted file mode 100644 index ccd77761e4..0000000000 Binary files a/addons/cargo/UI/Icon_load.paa and /dev/null differ diff --git a/addons/cargo/XEH_PREP.hpp b/addons/cargo/XEH_PREP.hpp index 8b7d3c5d4f..154956c74a 100644 --- a/addons/cargo/XEH_PREP.hpp +++ b/addons/cargo/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(addCargoItem); PREP(addCargoVehiclesActions); PREP(canLoadItemIn); @@ -9,11 +8,10 @@ PREP(handleDestroyed); PREP(initObject); PREP(initVehicle); PREP(loadItem); -PREP(makeLoadable); -PREP(moduleMakeLoadable); PREP(moduleSettings); PREP(onMenuOpen); PREP(paradropItem); +PREP(removeCargoItem); PREP(setSize); PREP(setSpace); PREP(startLoadIn); diff --git a/addons/cargo/XEH_postInit.sqf b/addons/cargo/XEH_postInit.sqf index 051c77ec9c..9d531a8e1a 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -50,6 +50,11 @@ _item hideObjectGlobal false; _item setPosASL (AGLtoASL _emptyPosAGL); + + if ((getText (configFile >> "CfgVehicles" >> (typeOf _item) >> "simulation")) == "carx") then { + TRACE_1("re-enabling car damage",_item); + [_item, "blockDamage", "ACE_cargo", false] call EFUNC(common,statusEffect_set); + }; }] call CBA_fnc_addEventHandler; // Private events to handle adding actions globally via public functions diff --git a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf index 176b2f31b6..e13cc65542 100644 --- a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf +++ b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf @@ -4,42 +4,29 @@ * * Arguments: * 0: Target - * 1: Player * * Return Value: - * Children actions + * Child actions * * Example: - * [target, player] call ace_cargo_fnc_addCargoVehiclesActions + * [cursorObject] call ace_cargo_fnc_addCargoVehiclesActions * * Public: No */ #include "script_component.hpp" -params ["_target", "_player"]; +params ["_target"]; private _statement = { - params ["_target", "_player", "_params"]; - _params params ["_vehicle"]; + params ["_target", "_player", "_vehicle"]; [_player, _target, _vehicle] call FUNC(startLoadIn); }; -private _actions = []; - -{ - private _config = configFile >> "CfgVehicles" >> typeOf _x; +private _vehicles = (nearestObjects [_target, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]) select { + private _hasCargoConfig = 1 == getNumber (configFile >> "CfgVehicles" >> typeOf _x >> QGVAR(hasCargo)); private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; - private _hasCargoConfig = getNumber (_config >> QGVAR(hasCargo)) == 1; - if ((_hasCargoPublic || _hasCargoConfig) && {_x != _target}) then { - private _name = getText (_config >> "displayName"); - private _ownerName = [_x, true] call EFUNC(common,getName); - if ("" != _ownerName) then { - _name = format ["%1 (%2)", _name, _ownerName]; - }; - private _icon = (getText (_config >> "icon")) call BIS_fnc_textureVehicleIcon; - private _action = [format ["%1", _x], _name, _icon, _statement, {true}, {}, [_x]] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _target]; - }; -} forEach (nearestObjects [_player, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE]); + (_hasCargoConfig || {_hasCargoPublic}) && {_x != _target} && + {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} +}; -_actions +[_vehicles, _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/cargo/functions/fnc_canLoadItemIn.sqf b/addons/cargo/functions/fnc_canLoadItemIn.sqf index 092272f94f..8780689241 100644 --- a/addons/cargo/functions/fnc_canLoadItemIn.sqf +++ b/addons/cargo/functions/fnc_canLoadItemIn.sqf @@ -34,7 +34,7 @@ if (_item isEqualType "") then { } else { _validItem = (alive _item) && - {(_item distance _vehicle) <= MAX_LOAD_DISTANCE}; + {([_item, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}; }; _validItem && diff --git a/addons/cargo/functions/fnc_canUnloadItem.sqf b/addons/cargo/functions/fnc_canUnloadItem.sqf index 1e8753cc27..9f1722ad08 100644 --- a/addons/cargo/functions/fnc_canUnloadItem.sqf +++ b/addons/cargo/functions/fnc_canUnloadItem.sqf @@ -5,7 +5,7 @@ * Arguments: * 0: loaded Object * 1: Object - * 2: Unloader (player) + * 2: Unloader (player) (default: objNull) * * Return Value: * Can be unloaded diff --git a/addons/cargo/functions/fnc_initObject.sqf b/addons/cargo/functions/fnc_initObject.sqf index d59249c31b..d0e1e66a8f 100644 --- a/addons/cargo/functions/fnc_initObject.sqf +++ b/addons/cargo/functions/fnc_initObject.sqf @@ -53,20 +53,21 @@ private _condition = { {(_target getVariable [QGVAR(canLoad), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(canLoad))]) in [true, 1]} && {locked _target < 2} && {alive _target} && - {[_player, _target, []] call EFUNC(common,canInteractWith)} && + {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && {0 < { private _type = typeOf _x; private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; private _hasCargoConfig = getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(hasCargo)) == 1; - (_hasCargoPublic || _hasCargoConfig) && {_x != _target} - } count (nearestObjects [_player, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE])} + (_hasCargoPublic || _hasCargoConfig) && {_x != _target} && + {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} + } count (nearestObjects [_player, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)])} }; private _statement = { params ["_target", "_player"]; [_player, _target] call FUNC(startLoadIn); }; private _text = localize LSTRING(loadObject); -private _icon = QPATHTOF(UI\Icon_load.paa); +private _icon = "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa"; private _action = [QGVAR(load), _text, _icon, _statement, _condition, {call FUNC(addCargoVehiclesActions)}] call EFUNC(interact_menu,createAction); if (_canLoadConfig) then { diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index 6d3709a329..474b1b0d8f 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -71,6 +71,7 @@ private _condition = { GVAR(enable) && {(_target getVariable [QGVAR(hasCargo), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(hasCargo)) == 1])} && {locked _target < 2} && + {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} && {alive _target} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} }; diff --git a/addons/cargo/functions/fnc_loadItem.sqf b/addons/cargo/functions/fnc_loadItem.sqf index bb608ff926..f8b00478e6 100644 --- a/addons/cargo/functions/fnc_loadItem.sqf +++ b/addons/cargo/functions/fnc_loadItem.sqf @@ -36,6 +36,12 @@ if (_item isEqualType objNull) then { detach _item; _item attachTo [_vehicle,[0,0,-100]]; [QEGVAR(common,hideObjectGlobal), [_item, true]] call CBA_fnc_serverEvent; + + // Cars below water will take engine damage over time and eventualy become "water logged" and unfixable (because of negative z attach) + if ((getText (configFile >> "CfgVehicles" >> (typeOf _item) >> "simulation")) == "carx") then { + TRACE_1("disabling car damage",_item); + [_item, "blockDamage", "ACE_cargo", true] call EFUNC(common,statusEffect_set); + }; }; true diff --git a/addons/cargo/functions/fnc_makeLoadable.sqf b/addons/cargo/functions/fnc_makeLoadable.sqf deleted file mode 100644 index 4d2aac21f0..0000000000 --- a/addons/cargo/functions/fnc_makeLoadable.sqf +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Author: PabstMirror - * Makes any object loadable. Needs to be called on all machines. - * - * Arguments: - * 0: Object - * 1: Set as loadable (default: true) - * 2: Size. (default: 1) - * - * Return Value: - * None - * - * Example: - * [cursorTarget, true, 1] call ace_cargo_fnc_makeLoadable - * - * Public: Yes - */ -#include "script_component.hpp" - -// Only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeLoadable), _this]; -}; - -ACE_DEPRECATED(QFUNC(makeLoadable),"3.12.0",QFUNC(setSize)); - -params [["_object", objNull, [objNull]], ["_canLoad", true, [false, 0]], ["_setSize", 1, [0]]]; -TRACE_3("params",_object,_canLoad,_setSize); - -if (isNull _object) exitWith {TRACE_1("null",_object);}; -private _type = typeOf _object; -private _cfgCanLoad = getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(canLoad)); -private _curSize = [_object] call FUNC(getSizeItem); - -_canLoad = [0, 1] select _canLoad; // Convert true/false to scalar - -if ((_canLoad == 1) && {_setSize <= 0}) exitWith { - ERROR("ace_cargo_fnc_makeLoadable (size <= 0) when making loadable"); -}; - -TRACE_2("setVar if different from config",_canLoad,_cfgCanLoad); -if (_canLoad != _cfgCanLoad) then { - _object setVariable [QGVAR(canLoad), _canLoad == 1]; -}; - -TRACE_2("setVar if different from config",_setSize,_curSize); -if (_setSize != _curSize) then { - _object setVariable [QGVAR(size), _setSize]; -}; - -//Add the load actions to the object class if not already added -[_object] call FUNC(initObject); - -nil diff --git a/addons/cargo/functions/fnc_moduleMakeLoadable.sqf b/addons/cargo/functions/fnc_moduleMakeLoadable.sqf deleted file mode 100644 index 9a9e21a22d..0000000000 --- a/addons/cargo/functions/fnc_moduleMakeLoadable.sqf +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Author: PabstMirror - * Module to make an object loadable. - * - * Arguments: - * 0: The module logic - * 1: Synchronized units - * 2: Activated - * - * Return Value: - * None - * - * Example: - * [logic, [box], true] call ace_cargo_fnc_moduleMakeLoadable - * - * Public: No - */ -#include "script_component.hpp" - -params ["_logic", "_objects", "_activated"]; -TRACE_3("params",_logic,_objects,_activated); - -ACE_DEPRECATED(QFUNC(moduleMakeLoadable),"3.12.0","Eden editor object attributes"); - -if ((isNull _logic) || {!_activated}) exitWith {}; -if (_objects isEqualTo []) exitWith { - WARNING_1("ace_cargo_fnc_moduleMakeLoadable has no synced objects [%1]", _logic); -}; - -private _canLoad = _logic getVariable ["canLoad", true]; -private _setSize = _logic getVariable ["setSize", 1]; -TRACE_2("settings",_canLoad,_setSize); - -{ - [_x, _canLoad, _setSize] call FUNC(makeLoadable); -} forEach _objects; diff --git a/addons/cargo/functions/fnc_moduleSettings.sqf b/addons/cargo/functions/fnc_moduleSettings.sqf index b7af19c76a..6712d947fa 100644 --- a/addons/cargo/functions/fnc_moduleSettings.sqf +++ b/addons/cargo/functions/fnc_moduleSettings.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -if (!isServer) exitWith {}; - params ["_logic", "", "_activated"]; if (!_activated) exitWith {}; diff --git a/addons/cargo/functions/fnc_onMenuOpen.sqf b/addons/cargo/functions/fnc_onMenuOpen.sqf index 8b3847993d..e08c7a478a 100644 --- a/addons/cargo/functions/fnc_onMenuOpen.sqf +++ b/addons/cargo/functions/fnc_onMenuOpen.sqf @@ -32,7 +32,7 @@ if (GVAR(interactionParadrop)) then { [_this select 1] call CBA_fnc_removePerFrameHandler; }; - if (isNull GVAR(interactionVehicle) || {(ACE_player distance GVAR(interactionVehicle) >= 10) && {(vehicle ACE_player) != GVAR(interactionVehicle)}}) exitWith { + if (isNull GVAR(interactionVehicle) || {(([ACE_player, GVAR(interactionVehicle)] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE) && {(vehicle ACE_player) != GVAR(interactionVehicle)}}) exitWith { closeDialog 0; [_this select 1] call CBA_fnc_removePerFrameHandler; }; diff --git a/addons/cargo/functions/fnc_paradropItem.sqf b/addons/cargo/functions/fnc_paradropItem.sqf index 0f74787723..4c1929a1dc 100644 --- a/addons/cargo/functions/fnc_paradropItem.sqf +++ b/addons/cargo/functions/fnc_paradropItem.sqf @@ -44,7 +44,7 @@ private _itemObject = if (_item isEqualType objNull) then { [QGVAR(serverUnload), [_item, _posBehindVehicleAGL]] call CBA_fnc_serverEvent; _item } else { - private _newItem = createVehicle [_item, _posBehindVehicleAGL, [], 0, ""]; + private _newItem = createVehicle [_item, _posBehindVehicleAGL, [], 0, "NONE"]; _newItem setPosASL (AGLtoASL _posBehindVehicleAGL); _newItem }; diff --git a/addons/cargo/functions/fnc_removeCargoItem.sqf b/addons/cargo/functions/fnc_removeCargoItem.sqf new file mode 100644 index 0000000000..22d73866f8 --- /dev/null +++ b/addons/cargo/functions/fnc_removeCargoItem.sqf @@ -0,0 +1,70 @@ +/* + * Author: 654wak654 + * Removes a cargo item from the vehicle. + * + * Arguments: + * 0: Item or + * 1: Vehicle + * 2: Amount (default: 1) + * + * Return Value: + * Number of items removed + * + * Example: + * ["ACE_Wheel", vehicle, 2] call ace_cargo_fnc_removeCargoItem + * [crate_7, truck] call ace_cargo_fnc_removeCargoItem + * + * Public: Yes + */ +#include "script_component.hpp" + +params ["_item", "_vehicle", ["_amount", 1]]; +TRACE_3("params",_item,_vehicle,_amount); + +private _loaded = _vehicle getVariable [QGVAR(loaded), []]; + +private _addedSpace = 0; +private _itemClass = _item; +private _itemsRemoved = 0; + +private _continue = if (_item isEqualType objNull) then { + if !(_item in _loaded) exitWith {false}; + _addedSpace = [_item] call FUNC(getSizeItem); + _loaded deleteAt (_loaded find _item); + _itemClass = typeOf _item; + deleteVehicle _item; + _itemsRemoved = 1; + true +} else { + { + if (_itemsRemoved == _amount) exitWith {}; + + if ( + (_x isEqualType "" && {_x == _item}) || // Check for classname, case-insensitive + {_x isEqualType objNull && {typeOf _x isEqualTo _item}} + ) then { + INC(_itemsRemoved); + ADD(_addedSpace,[_x] call FUNC(getSizeItem)); + + if (_x isEqualType objNull) then { + deleteVehicle _x; + }; + _loaded set [_forEachIndex, nil]; + }; + } forEach _loaded; + + FILTER(_loaded,_x != nil); + true +}; + +if (!_continue) exitWith {0}; + +_vehicle setVariable [QGVAR(loaded), _loaded, true]; + +private _space = [_vehicle] call FUNC(getCargoSpaceLeft); +_vehicle setVariable [QGVAR(space), _space + _addedSpace, true]; + +// Invoke listenable event +["ace_cargoRemoved", [_itemClass, _vehicle, _amount, _itemsRemoved]] call CBA_fnc_globalEvent; + +_itemsRemoved diff --git a/addons/cargo/functions/fnc_setSize.sqf b/addons/cargo/functions/fnc_setSize.sqf index 2e5c0aa441..660131045a 100644 --- a/addons/cargo/functions/fnc_setSize.sqf +++ b/addons/cargo/functions/fnc_setSize.sqf @@ -50,6 +50,7 @@ private _jipID = _object getVariable QGVAR(setSize_jipID); // Actions should be added to all future JIP players too if (isNil "_jipID") then { _jipID = [QGVAR(initObject), [_object]] call CBA_fnc_globalEventJIP; + [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; // Store the ID for any future calls to this function _object setVariable [QGVAR(setSize_jipID), _jipID, true]; diff --git a/addons/cargo/functions/fnc_setSpace.sqf b/addons/cargo/functions/fnc_setSpace.sqf index 9f8ab85c68..156b0aa085 100644 --- a/addons/cargo/functions/fnc_setSpace.sqf +++ b/addons/cargo/functions/fnc_setSpace.sqf @@ -49,6 +49,7 @@ private _jipID = _vehicle getVariable QGVAR(setSpace_jipID); // Cargo menu should be added to all future JIP players too if (isNil "_jipID") then { _jipID = [QGVAR(initVehicle), [_vehicle]] call CBA_fnc_globalEventJIP; + [_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; // Store the ID for any future calls to this function _vehicle setVariable [QGVAR(setSpace_jipID), _jipID, true]; diff --git a/addons/cargo/functions/fnc_startLoadIn.sqf b/addons/cargo/functions/fnc_startLoadIn.sqf index 4fa0401772..092440e5d4 100644 --- a/addons/cargo/functions/fnc_startLoadIn.sqf +++ b/addons/cargo/functions/fnc_startLoadIn.sqf @@ -24,7 +24,7 @@ private _vehicle = _cargoVehicle; if (isNull _vehicle) then { { if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_vehicle = _x}; - } forEach (nearestObjects [_player, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE]); + } forEach (nearestObjects [_player, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]); }; if (isNull _vehicle) exitWith { @@ -35,14 +35,20 @@ if (isNull _vehicle) exitWith { private _return = false; // Start progress bar if ([_object, _vehicle] call FUNC(canLoadItemIn)) then { + [_player, _object, true] call EFUNC(common,claim); private _size = [_object] call FUNC(getSizeItem); [ 5 * _size, - [_object,_vehicle], - {["ace_loadCargo", _this select 0] call CBA_fnc_localEvent}, - {}, - localize LSTRING(LoadingItem) + [_object, _vehicle], + { + [objNull, _this select 0 select 0, true] call EFUNC(common,claim); + ["ace_loadCargo", _this select 0] call CBA_fnc_localEvent; + }, + {[objNull, _this select 0 select 0, true] call EFUNC(common,claim)}, + localize LSTRING(LoadingItem), + {true}, + ["isNotSwimming"] ] call EFUNC(common,progressBar); _return = true; } else { diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index 20fde5d631..702f145405 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -55,7 +55,7 @@ if (_item isEqualType objNull) then { // do both on server to ensure they are executed in the correct order [QGVAR(serverUnload), [_item, _emptyPosAGL]] call CBA_fnc_serverEvent; } else { - private _newItem = createVehicle [_item, _emptyPosAGL, [], 0, ""]; + private _newItem = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"]; _newItem setPosASL (AGLtoASL _emptyPosAGL); }; diff --git a/addons/cargo/menu.hpp b/addons/cargo/menu.hpp index 0a32d2bcdb..7496298371 100644 --- a/addons/cargo/menu.hpp +++ b/addons/cargo/menu.hpp @@ -17,7 +17,7 @@ class GVAR(menu) { }; class CenterBackground: HeaderBackground { y = "2.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - h = "14 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + h = "13.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; text = "#(argb,8,8,3)color(0,0,0,0.8)"; colorText[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; colorBackground[] = {0,0,0,"(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; diff --git a/addons/cargo/script_component.hpp b/addons/cargo/script_component.hpp index 3ae6331f91..d5cee60c39 100644 --- a/addons/cargo/script_component.hpp +++ b/addons/cargo/script_component.hpp @@ -16,7 +16,7 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define MAX_LOAD_DISTANCE 10 +#define MAX_LOAD_DISTANCE 5 #define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 05c8d9bc23..0d42954b7f 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -228,78 +228,45 @@ %1<br/>無法被卸載 %1<br/>无法被卸载 - - Make Object Loadable - Füge Objekt zum Frachtsystem hinzu - Ustaw jako ładowalny - Rendi oggetto caricabile - Hacer objeto cargable - Rendre l'objet chargeable - Vytvořit objekt nakladatelným - Fazer objeto carregável - Сделать объект загружаемым - オブジェクトを積載可能に - 물체를 화물화시키기 - 使物件可裝載 - 使物件可装载 - - - Sets the synced object as loadable by the cargo system. - Das synchronisierte Objekt wird dem Frachtsystem hinzugefügt und ist be- und entladbar. - Ustawia zsynchronizowany obiekt jako możliwy do załadowania poprzez system cargo - Imposta l'oggetto sincronizzato come caricabile dal sistema cargo - Sincronizar un objecto para hacerlo cargable. - Rend l'objet synchronisé comme chargeable par le système de cargaison. - Nastaví synchronizované objekty nakladatelnými za pomocí Nákladního systému. - Seta o objeto sincronizado como carregável - Делает синхронизированный объект загружаемым для модуля перевозки грузов. - オブジェクトを同期させると、カーゴ システムによる積載が可能になります。 - 물체를 화물 시스템과 동기화시켜 실을 수 있게 합니다 - 使用同步線來使該物件可被裝載. - 使用同步线来使该物件可被装载. - - - Object's Size - Objektgröße - Rozmiar obiektu - Dimensioni dell'oggetto - Tamaño del objeto - Taille de l'objet - Velikost objektu - Tamanho do objeto - Размер объекта - オブジェクトの大きさ - 물체 크기 - 物件的大小 - 物件的大小 - Cargo Space + Frachtraum Spazio Cargo カーゴ スペース 貨物空間 货物空间 + Przestrzeń ładunkowa + 화물 공간 The cargo space available in this vehicle/container + Verfügbarer Frachtraum in diesem Fahrzeug/Container Lo spazio disponibile in questo veicolo/container この車両/コンテナでカーゴ スペースを使えるようにします 設定此載具/集裝箱可裝載多少貨物 设定此载具/集装箱可装载多少货物 + Dostępna przestrzeń ładunkowa w tym pojeździe/kontenerze + 이 차량/컨테이너에서 사용가능한 화물 공간 Cargo Size + Frachtgröße Dimensioni Cargo カーゴ サイズ 貨物的大小 货物的大小 + Wielkość ładunku + 화물 크기 The cargo space required to hold this object (-1 for unloadable) + Frachtraumgröße, welche zum Einladen dieses Objektes benötigt wird (-1 nicht einladbar) Lo spazio del cargo necessita di mantenere questo oggetto (-1 per scaricabile) このオブジェクトを積載するのに必要なカーゴ スペース (-1 で積載不可) 此貨物會佔掉多少空間(設定-1的話此貨物就不能被裝載) 此货物会占掉多少空间(设定-1的话此货物就不能被装载) + Wymagana przestrzeń ładunkowa dla tego obiektu (-1 dla niemożliwych do załadowania) + 이 화물을 적재하는데 필요한 공간 (-1=무조건 적재가능) Airdrop @@ -325,19 +292,25 @@ Paradrop Time Coffecient + Türlast Zeitfaktor 空中投下までの時間係数 Coefficente Tempo Lancio Paracadute Coefficient Temps de largage de cargaison 空投時間係數 空投时间系数 + Współczynnik czasu zrzutu + 공중 투하 시간 계수 Modifier for how long it takes to paradrop a cargo item. + Beeinflusst die zusätzliche Zeit für Türlastabwürfe. カーゴ アイテムを空中投下するまでの時間を変更します。 Modificato per quanto tempo ci impiega a paracadutare un oggetto cargo. Modifier le temps qu'il faut pour larguer la cargaison. 設定空投所需消耗的時間. 设定空投所需消耗的时间. + Modyfikator wskazujący jak dużo czasu potrzeba by zrzucić przedmiot na spadochronie. + 화물을 공중 투하 하는데 얼마나 걸리는 시간 설정 diff --git a/addons/chemlights/CfgVehicles.hpp b/addons/chemlights/CfgVehicles.hpp index 62aee70724..8e5fe8789e 100644 --- a/addons/chemlights/CfgVehicles.hpp +++ b/addons/chemlights/CfgVehicles.hpp @@ -12,7 +12,7 @@ class CfgVehicles { icon = "\a3\ui_f\data\gui\cfg\Hints\chemlights_ca.paa"; condition = QUOTE(count ([ACE_player] call FUNC(getShieldComponents)) > 0); statement = "true"; - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + exceptions[] = {"isNotDragging", "isNotSwimming", "notOnMap", "isNotInside", "isNotSitting"}; insertChildren = QUOTE(_this call DFUNC(compileChemlightMenu)); showDisabled = 0; priority = 99; @@ -20,10 +20,10 @@ class CfgVehicles { }; }; }; - + class Thing; class ThingX; - + class ACE_Chemlight_IR_Marker: Thing { author = ECSTRING(common,ACETeam); displayName = "ACE Chemlight IR Marker"; @@ -49,7 +49,7 @@ class CfgVehicles { useFlare = 0; }; }; - + class ACE_Chemlight_IR_Dummy: ThingX { ACE_Attachable = "ACE_G_Chemlight_IR"; author = ECSTRING(common,ACETeam); @@ -62,7 +62,7 @@ class CfgVehicles { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; }; - + class Item_Base_F; class ACE_Item_Chemlight_Shield: Item_Base_F { @@ -78,7 +78,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Green: Item_Base_F { scope = 2; scopeCurator = 2; @@ -92,7 +92,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Red: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Red_DisplayName); class TransportItems { @@ -102,7 +102,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Blue: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Blue_DisplayName); class TransportItems { @@ -112,7 +112,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Yellow: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Yellow_DisplayName); class TransportItems { @@ -122,7 +122,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Orange: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Orange_DisplayName); class TransportItems { @@ -132,7 +132,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_White: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_White_DisplayName); class TransportItems { @@ -154,13 +154,13 @@ class CfgVehicles { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class Box_NATO_Support_F: NATO_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class B_supplyCrate_F: ReammoBox_F { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); @@ -172,13 +172,13 @@ class CfgVehicles { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class Box_East_Support_F: EAST_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class O_supplyCrate_F: B_supplyCrate_F { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); @@ -190,13 +190,13 @@ class CfgVehicles { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class Box_IND_Support_F: IND_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class I_supplyCrate_F: B_supplyCrate_F { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); @@ -208,19 +208,19 @@ class CfgVehicles { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class IG_supplyCrate_F: ReammoBox_F { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class C_supplyCrate_F: ReammoBox_F { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); }; }; - + class ACE_Box_Misc: Box_NATO_Support_F { class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,12); @@ -235,7 +235,7 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_Chemlight_IR,20); }; }; - + class ACE_Box_Chemlights: NATO_Box_Base { scope = 2; accuracy = 1; @@ -246,11 +246,11 @@ class CfgVehicles { transportMaxItems = 9002; maximumload = 9002; model = "\A3\weapons_F\AmmoBoxes\WpnsBox_large_F"; - + class TransportItems { MACRO_ADDITEM(ACE_Chemlight_Shield,20); }; - + class TransportMagazines { MACRO_ADDMAGAZINE(Chemlight_red,20); MACRO_ADDMAGAZINE(Chemlight_blue,20); @@ -264,7 +264,7 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_Chemlight_HiWhite,10); MACRO_ADDMAGAZINE(ACE_Chemlight_IR,20); }; - + class AnimationSources { class Ammo_source { source = "user"; diff --git a/addons/chemlights/CfgWeapons.hpp b/addons/chemlights/CfgWeapons.hpp index c182ded34b..de6f3920f5 100644 --- a/addons/chemlights/CfgWeapons.hpp +++ b/addons/chemlights/CfgWeapons.hpp @@ -36,7 +36,7 @@ class CfgWeapons { }; class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_Chemlight_Shield: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -45,7 +45,7 @@ class CfgWeapons { model = "\A3\weapons_F\ammo\mag_univ.p3d"; picture = QPATHTOF(UI\ace_chemlight_shield_x_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; @@ -57,8 +57,9 @@ class CfgWeapons { descriptionShort = CSTRING(Shield_Green_DescriptionShort); model = "\A3\weapons_F\ammo\mag_univ.p3d"; picture = QPATHTOF(UI\ace_chemlight_shield_green_x_ca.paa); + ace_arsenal_uniqueBase = "ACE_Chemlight_Shield"; scope = 1; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "green"; @@ -73,7 +74,7 @@ class CfgWeapons { displayName = CSTRING(Shield_Red_DisplayName); descriptionShort = CSTRING(Shield_Red_DescriptionShort); picture = QPATHTOF(UI\ace_chemlight_shield_red_x_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "red"; @@ -88,7 +89,7 @@ class CfgWeapons { displayName = CSTRING(Shield_Blue_DisplayName); descriptionShort = CSTRING(Shield_Blue_DescriptionShort); picture = QPATHTOF(UI\ace_chemlight_shield_blue_x_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "blue"; @@ -103,7 +104,7 @@ class CfgWeapons { displayName = CSTRING(Shield_Yellow_DisplayName); descriptionShort = CSTRING(Shield_Yellow_DescriptionShort); picture = QPATHTOF(UI\ace_chemlight_shield_yellow_x_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "yellow"; @@ -118,7 +119,7 @@ class CfgWeapons { displayName = CSTRING(Shield_Orange_DisplayName); descriptionShort = CSTRING(Shield_Orange_DescriptionShort); picture = QPATHTOF(UI\ace_chemlight_shield_orange_x_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "orange"; @@ -133,7 +134,7 @@ class CfgWeapons { displayName = CSTRING(Shield_White_DisplayName); descriptionShort = CSTRING(Shield_White_DescriptionShort); picture = QPATHTOF(UI\ace_chemlight_shield_white_x_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "white"; diff --git a/addons/chemlights/functions/fnc_throwIR.sqf b/addons/chemlights/functions/fnc_throwIR.sqf index 7d97c99f8e..5d29ccde67 100644 --- a/addons/chemlights/functions/fnc_throwIR.sqf +++ b/addons/chemlights/functions/fnc_throwIR.sqf @@ -5,13 +5,13 @@ * Arguments: * 0: Original throw projectile * 1: Class of projectile - * 2: Adv throw (default: false) + * 2: Adv throw (default: false) * * Return Value: * None * * Example: - * [_projectile, _ammoType] call ace_chemlights_fnc_throwIR; + * [_projectile, _ammoType] call ace_chemlights_fnc_throwIR * * Public: No */ diff --git a/addons/chemlights/stringtable.xml b/addons/chemlights/stringtable.xml index cd3ee7c894..eeac958a6d 100644 --- a/addons/chemlights/stringtable.xml +++ b/addons/chemlights/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -333,8 +333,8 @@ 초록빛 조명 Lampe d'orientation verte. Luce da lettura Verde. - 綠色閱讀燈. - 绿色阅读灯. + 綠色閱讀燈。 + 绿色阅读灯。 Chemlight Shield (Red) @@ -355,8 +355,8 @@ 빨간색 조명 Lampe d'orientation rouge. Luce da lettura Rossa. - 紅色閱讀燈. - 红色阅读灯. + 紅色閱讀燈。 + 红色阅读灯。 Chemlight Shield (Blue) @@ -377,8 +377,8 @@ 파란색 조명 Lampe d'orientation bleue. Luce da lettura Blu. - 藍色閱讀燈. - 蓝色阅读灯. + 藍色閱讀燈。 + 蓝色阅读灯。 Chemlight Shield (Yellow) @@ -399,8 +399,8 @@ 노란색 조명 Lampe d'orientation jaune. Luce da lettura Gialla. - 黃色閱讀燈. - 黄色阅读灯. + 黃色閱讀燈。 + 黄色阅读灯。 Chemlight Shield (Orange) @@ -421,8 +421,8 @@ 주황색 조명 Lampe d'orientation orange. Luce da lettura Arancione. - 橘色閱讀燈. - 橘色阅读灯. + 橘色閱讀燈。 + 橘色阅读灯。 Chemlight Shield (White) @@ -443,8 +443,8 @@ 주황색 조명 Lampe d'orientation blanche. Luce da lettura Bianca. - 白色閱讀燈. - 白色阅读灯. + 白色閱讀燈。 + 白色阅读灯。 diff --git a/addons/common/ACE_Settings.hpp b/addons/common/ACE_Settings.hpp index 2d8a5d7a27..eeee9c2f37 100644 --- a/addons/common/ACE_Settings.hpp +++ b/addons/common/ACE_Settings.hpp @@ -14,25 +14,27 @@ class ACE_Settings { * values[] = {"Disabled", "Enabled", "Only Cursor", "Only On Keypress", "Only Cursor and KeyPress"}; // Stringtable entries that describe the options * }; */ - class GVAR(forceAllSettings) { - value = 0; - typeName = "BOOL"; - }; class GVAR(checkPBOsAction) { + category = CSTRING(DisplayName); value = 0; typeName = "SCALAR"; isClientSettable = 0; + displayName = CSTRING(CheckPBOsAction); values[] = {CSTRING(CheckPBO_Action_WarnOnce), CSTRING(CheckPBO_Action_WarnPerm), CSTRING(CheckPBO_Action_Kick)}; }; class GVAR(checkPBOsCheckAll) { + category = CSTRING(DisplayName); value = 0; typeName = "BOOL"; isClientSettable = 0; + displayName = CSTRING(CheckPBOsCheckAll); }; class GVAR(checkPBOsWhitelist) { + category = CSTRING(DisplayName); value = "[]"; typeName = "STRING"; isClientSettable = 0; + displayName = CSTRING(CheckPBOsWhitelist); }; /*class GVAR(enableNumberHotkeys) { value = 1; @@ -41,6 +43,7 @@ class ACE_Settings { displayName = CSTRING(EnableNumberHotkeys); };*/ class GVAR(settingFeedbackIcons) { + category = CSTRING(DisplayName); value = 1; typeName = "SCALAR"; force = 0; @@ -50,6 +53,7 @@ class ACE_Settings { values[] = {ECSTRING(optionsmenu,Hide), ECSTRING(optionsmenu,TopRightDown), ECSTRING(optionsmenu,TopRightLeft), ECSTRING(optionsmenu,TopLeftDown), ECSTRING(optionsmenu,TopLeftRight)}; }; class GVAR(settingProgressBarLocation) { + category = CSTRING(DisplayName); value = 0; typeName = "SCALAR"; force = 0; @@ -59,6 +63,7 @@ class ACE_Settings { values[] = {ECSTRING(optionsmenu,Top), ECSTRING(optionsmenu,Bottom)}; }; class GVAR(displayTextColor) { + category = CSTRING(DisplayName); value[] = {0,0,0,0.1}; typeName = "COLOR"; isClientSettable = 1; @@ -66,6 +71,7 @@ class ACE_Settings { description = CSTRING(SettingDisplayTextColorDesc); }; class GVAR(displayTextFontColor) { + category = CSTRING(DisplayName); value[] = {1,1,1,1}; typeName = "COLOR"; isClientSettable = 1; diff --git a/addons/common/CfgVehicles.hpp b/addons/common/CfgVehicles.hpp index 1e958027be..a3ddef155e 100644 --- a/addons/common/CfgVehicles.hpp +++ b/addons/common/CfgVehicles.hpp @@ -33,7 +33,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(CheckPBO_DisplayName); function = QFUNC(moduleCheckPBOs); - scope = 2; + scope = 1; isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_CheckPBO_ca.paa); diff --git a/addons/common/CfgWeapons.hpp b/addons/common/CfgWeapons.hpp index 488d4210c4..09a828e475 100644 --- a/addons/common/CfgWeapons.hpp +++ b/addons/common/CfgWeapons.hpp @@ -1,11 +1,8 @@ class CfgWeapons { - class ItemCore; - class ACE_ItemCore: ItemCore { - type = 4096;//4; - detectRange = -1; - simulation = "ItemMineDetector"; - }; + class CBA_MiscItem; + class CBA_MiscItem_ItemInfo; + class ACE_ItemCore: CBA_MiscItem {}; class Rifle; class Rifle_Base_F: Rifle { @@ -28,7 +25,6 @@ class CfgWeapons { }; }; - class InventoryItem_Base_F; class ACE_Banana: ACE_ItemCore { author = CSTRING(ACETeam); scope = 2; @@ -38,7 +34,7 @@ class CfgWeapons { picture = QPATHTOF(data\icon_banana_ca.paa); icon = "iconObject_circle"; mapSize = 0.034; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; diff --git a/addons/common/CompassControl.hpp b/addons/common/CompassControl.hpp new file mode 100644 index 0000000000..899c609161 --- /dev/null +++ b/addons/common/CompassControl.hpp @@ -0,0 +1,110 @@ +#include "\a3\ui_f\hpp\defineCommonGrids.inc" + +#define TEXTURE_0 "\a3\ui_f_curator\Data\CfgIngameUI\Compass\texture0_ca.paa" +#define TEXTURE_1 "\a3\ui_f_curator\Data\CfgIngameUI\Compass\texture90_ca.paa" +#define TEXTURE_2 "\a3\ui_f_curator\Data\CfgIngameUI\Compass\texture180_ca.paa" +#define TEXTURE_3 "\a3\ui_f_curator\Data\CfgIngameUI\Compass\texture270_ca.paa" + +#define BACKGROUND_COLOR {0.1,0.1,0.1,0.4} +#define POINTER_COLOR {0.1,0.1,0.1,1} +#define POINTER_WIDTH_FACTOR (1/128) + +#define LEFT (0.5 - 8 * GUI_GRID_W) +#define TOP (safezoneY + 1.6 * GUI_GRID_H) +#define WIDTH (16 * GUI_GRID_W) +#define HEIGHT (0.5 * GUI_GRID_H) + +class RscText; +class RscPicture; +class RscControlsGroupNoScrollbars; + +class GVAR(CompassControl): RscControlsGroupNoScrollbars { + onLoad = QUOTE(\ + params ['_control'];\ + private _display = ctrlParent _control;\ + private _fnc_update = {\ + params ['_display'];\ + private _compassControl = _display getVariable 'GVAR(compassControl)';\ + private _view = AGLToASL positionCameraToWorld [ARR_3(0,0,0)] vectorFromTo AGLToASL positionCameraToWorld [ARR_3(0,0,1)];\ + private _viewHorizontal = vectorNormalized (_view vectorCrossProduct [ARR_3(0,0,1)]);\ + private _dir = acos (_viewHorizontal select 0);\ + if (_viewHorizontal select 1 > 0) then {\ + _dir = 360 - _dir;\ + };\ + _compassControl ctrlSetPosition [ARR_2(-(16 * GUI_GRID_W) * (_dir / 360),0)];\ + _compassControl ctrlCommit 0;\ + };\ + _display displayAddEventHandler [ARR_2('MouseMoving',_fnc_update)];\ + _display displayAddEventHandler [ARR_2('MouseHolding',_fnc_update)];\ + ); + x = LEFT; + y = TOP; + w = WIDTH; + h = HEIGHT; + + class controls { + class Background: RscText { + colorBackground[] = BACKGROUND_COLOR; + x = 0; + y = 0; + w = WIDTH; + h = HEIGHT; + }; + class Pointer: RscText { + colorBackground[] = POINTER_COLOR; + x = WIDTH/2 - WIDTH*POINTER_WIDTH_FACTOR/2; + y = 0; + w = WIDTH*POINTER_WIDTH_FACTOR; + h = HEIGHT; + }; + class CompassGroup: RscControlsGroupNoScrollbars { + onLoad = QUOTE(\ + params ['_control'];\ + private _display = ctrlParent _control;\ + _display setVariable [ARR_2('GVAR(compassControl)',_control)];\ + ); + x = 0; + y = 0; + w = 2*WIDTH; + h = 2*HEIGHT; + + class controls { + class Compass0: RscPicture { + text = TEXTURE_0; + x = 0 * (WIDTH / 4); + y = 0; + w = WIDTH/4; + h = HEIGHT; + }; + class Compass1: Compass0 { + text = TEXTURE_1; + x = 1 * (WIDTH / 4); + }; + class Compass2: Compass0 { + text = TEXTURE_2; + x = 2 * (WIDTH / 4); + }; + class Compass3: Compass0 { + text = TEXTURE_3; + x = 3 * (WIDTH / 4); + }; + class Compass4: Compass0 { + text = TEXTURE_0; + x = 4 * (WIDTH / 4); + }; + class Compass5: Compass0 { + text = TEXTURE_1; + x = 5 * (WIDTH / 4); + }; + class Compass6: Compass0 { + text = TEXTURE_2; + x = 6 * (WIDTH / 4); + }; + class Compass7: Compass0 { + text = TEXTURE_3; + x = 7 * (WIDTH / 4); + }; + }; + }; + }; +}; diff --git a/addons/common/ProgressScreen.hpp b/addons/common/ProgressScreen.hpp index 57454dec78..9b55ae33a3 100644 --- a/addons/common/ProgressScreen.hpp +++ b/addons/common/ProgressScreen.hpp @@ -12,7 +12,6 @@ class GVAR(ProgressBar_Dialog) { text = ""; sizeEx = 0; lineSpacing = 0; - access = 0; type = 0; style = 0; size = 1; @@ -64,7 +63,6 @@ class GVAR(DisableMouse_Dialog) { text = ""; sizeEx = 0; lineSpacing = 0; - access = 0; type = 0; style = 0; size = 1; diff --git a/addons/common/UI/blank_CO.paa b/addons/common/UI/blank_CO.paa deleted file mode 100644 index c1109c748c..0000000000 Binary files a/addons/common/UI/blank_CO.paa and /dev/null differ diff --git a/addons/magazinerepack/UI/repack_ca.paa b/addons/common/UI/repack_ca.paa similarity index 100% rename from addons/magazinerepack/UI/repack_ca.paa rename to addons/common/UI/repack_ca.paa diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 5720d31873..8a33997f57 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -1,8 +1,15 @@ +TRACE_1("",QUOTE(ADDON)); + +PREP(cbaSettings); +PREP(cbaSettings_convertHelper); +PREP(cbaSettings_loadFromConfig); +PREP(cbaSettings_settingChanged); +PREP(cbaSettings_transferUserSettings); +PREP(readSettingsFromParamsArray); PREP(actionKeysNamesConverted); PREP(addCanInteractWithCondition); PREP(addLineToDebugDraw); -PREP(addSetting); PREP(addToInventory); PREP(assignedItemFix); PREP(assignObjectsInList); @@ -67,6 +74,7 @@ PREP(getMGRSdata); PREP(getName); PREP(getNumberMagazinesIn); PREP(getPitchBankYaw); +PREP(getPylonTurret); PREP(getSettingData); PREP(getStaminaBarControl); PREP(getTargetAzimuthAndInclination); @@ -77,10 +85,12 @@ PREP(getTurretDirection); PREP(getUavControlPosition); PREP(getVehicleCargo); PREP(getVehicleCodriver); +PREP(getVehicleIcon); PREP(getVersion); PREP(getWeaponAzimuthAndInclination); PREP(getWeaponIndex); PREP(getWeaponState); +PREP(getWeight); PREP(getWindDirection); PREP(getZoom); PREP(goKneeling); @@ -99,20 +109,20 @@ PREP(isEngineer); PREP(isEOD); PREP(isFeatureCameraActive); PREP(isInBuilding); +PREP(isMedic); PREP(isModLoaded); PREP(isPlayer); +PREP(isSwimming); PREP(isUnderwater); PREP(lightIntensityFromObject); PREP(loadPerson); PREP(loadPersonLocal); -PREP(loadSettingsFromProfile); -PREP(loadSettingsOnServer); -PREP(loadSettingsLocalizedText); PREP(moduleCheckPBOs); PREP(moduleLSDVehicles); PREP(muteUnit); PREP(muteUnitHandleInitPost); PREP(muteUnitHandleRespawn); +PREP(nearestVehiclesFreeSeat); PREP(numberToDigits); PREP(numberToDigitsString); PREP(numberToString); @@ -125,7 +135,6 @@ PREP(playerSide); PREP(positionToASL); PREP(progressBar); PREP(readSettingFromModule); -PREP(readSettingsFromParamsArray); PREP(receiveRequest); PREP(removeCanInteractWithCondition); PREP(removeSpecificMagazine); @@ -133,6 +142,7 @@ PREP(requestCallback); PREP(resetAllDefaults); PREP(restoreVariablesJIP); PREP(runAfterSettingsInit); +PREP(runTests); PREP(sanitizeString); PREP(sendRequest); PREP(serverLog); @@ -146,7 +156,6 @@ PREP(setPitchBankYaw); PREP(setPlayerOwner); PREP(setProne); PREP(setSetting); -PREP(setSettingFromConfig); PREP(setVariableJIP); PREP(setVariablePublic); PREP(setVolume); @@ -160,7 +169,7 @@ PREP(statusEffect_sendEffects); PREP(statusEffect_set); PREP(stringCompare); PREP(stringToColoredText); -PREP(stringRemoveWhiteSpace); +PREP(switchPersistentLaser); PREP(switchToGroupSide); PREP(throttledPublicVariable); PREP(toBin); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 51baec47f9..61061a9a1c 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -19,37 +19,63 @@ //Status Effect EHs: [QGVAR(setStatusEffect), {_this call FUNC(statusEffect_set)}] call CBA_fnc_addEventHandler; -["forceWalk", false, ["ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_dragging"]] call FUNC(statusEffect_addType); +["forceWalk", false, ["ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches"]] call FUNC(statusEffect_addType); ["blockSprint", false, []] call FUNC(statusEffect_addType); -["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered), "ace_unconscious"]] call FUNC(statusEffect_addType); -["blockDamage", false, ["fixCollision"]] call FUNC(statusEffect_addType); +["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered)]] call FUNC(statusEffect_addType); +["blockDamage", false, ["fixCollision", "ACE_cargo"]] call FUNC(statusEffect_addType); ["blockEngine", false, ["ACE_Refuel"]] call FUNC(statusEffect_addType); +["blockThrow", false, ["ACE_Attach", "ACE_concertina_wire", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_rearm", "ACE_refuel", "ACE_Sandbag", "ACE_Trenches", "ACE_tripod"]] call FUNC(statusEffect_addType); +["setHidden", true, ["ace_unconscious"]] call FUNC(statusEffect_addType); [QGVAR(forceWalk), { params ["_object", "_set"]; TRACE_2("forceWalk EH",_object,_set); _object forceWalk (_set > 0); }] call CBA_fnc_addEventHandler; + [QGVAR(blockSprint), { //Name reversed from `allowSprint` because we want NOR logic params ["_object", "_set"]; TRACE_2("blockSprint EH",_object,_set); _object allowSprint (_set == 0); }] call CBA_fnc_addEventHandler; + [QGVAR(setCaptive), { params ["_object", "_set"]; TRACE_2("setCaptive EH",_object,_set); _object setCaptive (_set > 0); }] call CBA_fnc_addEventHandler; + +[QGVAR(setHidden), { + params ["_object", "_set"]; + TRACE_2("setHidden EH",_object,_set); + private _vis = _object getUnitTrait "camouflageCoef"; + if (_set > 0) then { + if (_vis != 0) then { + _object setVariable [QGVAR(oldVisibility), _vis]; + _object setUnitTrait ["camouflageCoef", 0]; + { + if (side _x != side group _object) then { + _x forgetTarget _object; + }; + } forEach allGroups; + }; + } else { + _vis = _object getVariable [QGVAR(oldVisibility), _vis]; + _object setUnitTrait ["camouflageCoef", _vis]; + }; +}] call CBA_fnc_addEventHandler; + [QGVAR(blockDamage), { //Name reversed from `allowDamage` because we want NOR logic params ["_object", "_set"]; if ((_object isKindOf "CAManBase") && {(["ace_medical"] call FUNC(isModLoaded))}) then { TRACE_2("blockDamage EH (using medical)",_object,_set); - _object setvariable [QEGVAR(medical,allowDamage), (_set == 0), true]; + _object setVariable [QEGVAR(medical,allowDamage), (_set == 0), true]; } else { TRACE_2("blockDamage EH (using allowDamage)",_object,_set); _object allowDamage (_set == 0); }; }] call CBA_fnc_addEventHandler; + [QGVAR(blockEngine), { params ["_vehicle", "_set"]; _vehicle setVariable [QGVAR(blockEngine), _set > 0, true]; @@ -74,20 +100,6 @@ if (isServer) then { }]; }; -// Listens for global "SettingChanged" events, to update the force status locally -["ace_settingChanged", { - params ["_name", "_value", "_force"]; - - if (_force) then { - private _settingData = [_name] call FUNC(getSettingData); - - if (_settingData isEqualTo []) exitWith {}; - - _settingData set [6, _force]; - }; -}] call CBA_fnc_addEventHandler; - - // Event to log Fix Headbug output [QGVAR(headbugFixUsed), { params ["_profileName", "_animation"]; @@ -123,6 +135,7 @@ if (isServer) then { [QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setVanillaHitPointDamage), {(_this select 0) setHitPointDamage (_this select 1)}] call CBA_fnc_addEventHandler; +[QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler; // Request framework [QGVAR(requestCallback), FUNC(requestCallback)] call CBA_fnc_addEventHandler; @@ -171,8 +184,8 @@ private _previousVersion = profileNamespace getVariable ["ACE_VersionNumberStrin // check previous version number from profile if (_currentVersion != _previousVersion) then { - // do something - + INFO_2("Updating ACE from [%1] to [%2]",_previousVersion,_currentVersion); + [_previousVersion] call FUNC(cbaSettings_transferUserSettings); profileNamespace setVariable ["ACE_VersionNumberString", _currentVersion]; }; @@ -191,60 +204,6 @@ call FUNC(checkFiles); ] call FUNC(checkPBOs) }] call CBA_fnc_addEventHandler; -// Create a pfh to wait until all postinits are ready and settings are initialized -[{ - params ["_args"]; - - _args params ["_waitingMsgSent"]; - - // If post inits are not ready then wait - if !(SLX_XEH_MACHINE select 8) exitWith {}; - - // If settings are not initialized then wait - if (isNil QGVAR(settings) || {!isServer && isNil QEGVAR(modules,serverModulesRead)}) exitWith { - if !(_waitingMsgSent) then { - _args set [0, true]; - INFO("Waiting on settings from server..."); - }; - }; - - [_this select 1] call CBA_fnc_removePerFrameHandler; - - INFO("Settings received from server."); - - if (isServer) then { //read settings from paramsArray - [] call FUNC(readSettingsFromParamsArray); - }; - // Event so that ACE_Modules have their settings loaded: - [QGVAR(initSettingsFromModules), []] call CBA_fnc_localEvent; - - if (isServer) then { - // Publish all settings data after all configs and modules are read - publicVariable QGVAR(settings); - }; - - // Load user settings from profile - if (hasInterface) then { - call FUNC(loadSettingsFromProfile); - call FUNC(loadSettingsLocalizedText); - }; - - INFO("Settings initialized."); - - //Event that settings are safe to use: - ["ace_settingsInitialized", []] call CBA_fnc_localEvent; - - //Set init finished and run all delayed functions: - GVAR(settingsInitFinished) = true; - INFO_1("%1 delayed functions running.",count GVAR(runAtSettingsInitialized)); - - { - (_x select 1) call (_x select 0); - false - } count GVAR(runAtSettingsInitialized); - - GVAR(runAtSettingsInitialized) = nil; //cleanup -}, 0, [false]] call CBA_fnc_addPerFrameHandler; /***************************************************************************/ @@ -317,6 +276,49 @@ GVAR(OldIsCamera) = false; END_COUNTER(stateChecker); }, 0.5, []] call CBA_fnc_addPerFrameHandler; +// Add event handler for UAV control change +ACE_controlledUAV = [objNull, objNull, [], ""]; +addMissionEventHandler ["PlayerViewChanged", { + // On non-server client this command is semi-broken + // arg index 5 should be the controlled UAV, but it will often be objNull (delay from locality switching?) + // On PlayerViewChanged event, start polling for new uav state for a few seconds (should be done within a few frames) + + params ["", "", "", "", "_newCameraOn", "_UAV"]; + TRACE_2("PlayerViewChanged",_newCameraOn,_UAV); + + [{ + if (isNull player) exitWith {true}; + private _UAV = getConnectedUAV player; + if (!alive player) then {_UAV = objNull;}; + private _position = (UAVControl _UAV) param [1, ""]; + private _seatAI = objNull; + private _turret = []; + switch (toLower _position) do { + case (""): { + _UAV = objNull; // set to objNull if not actively controlling + }; + case ("driver"): { + _turret = [-1]; + _seatAI = driver _UAV; + }; + case ("gunner"): { + _turret = [0]; + _seatAI = gunner _UAV; + }; + }; + + private _newArray = [_UAV, _seatAI, _turret, _position]; + if (_newArray isEqualTo ACE_controlledUAV) exitWith {false}; // no change yet + + TRACE_2("Seat Change",_newArray,ACE_controlledUAV); + ACE_controlledUAV = _newArray; + ["ACE_controlledUAV", _newArray] call CBA_fnc_localEvent; + + // stay in the loop as we might switch from gunner -> driver, and there may be a empty position event in-between + false + }, {}, [], 3, {TRACE_1("timeout",_this);}] call CBA_fnc_waitUntilAndExecute; +}]; + ////////////////////////////////////////////////// // Eventhandlers for player controlled machines @@ -355,7 +357,9 @@ GVAR(OldIsCamera) = false; // Players can always interact with his vehicle {vehicle _unit == _target} || // Players can always interact with passengers of the same vehicle - {_unit != _target && {vehicle _unit == vehicle _target}} + {_unit != _target && {vehicle _unit == vehicle _target}} || + // Players can always interact with connected UAV + {!(isNull (ACE_controlledUAV select 0))} }] call FUNC(addCanInteractWithCondition); ["isNotInZeus", {isNull curatorCamera}] call FUNC(addCanInteractWithCondition); diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 355ffb2a7d..c29a0b5df4 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -9,6 +9,7 @@ PREP_RECOMPILE_END; GVAR(syncedEvents) = [] call CBA_fnc_hashCreate; GVAR(showHudHash) = [] call CBA_fnc_hashCreate; +GVAR(vehicleIconCache) = call CBA_fnc_createNamespace; // for getVehicleIcon GVAR(settingsInitFinished) = false; GVAR(runAtSettingsInitialized) = []; @@ -18,10 +19,8 @@ GVAR(runAtSettingsInitialized) = []; //Debug ACE_COUNTERS = []; -// Load settings on the server and broadcast them -if (isServer) then { - call FUNC(loadSettingsOnServer); -}; +// Load ace_settings into CBA Settings +[] call FUNC(cbaSettings); GVAR(statusEffect_Names) = []; GVAR(statusEffect_isGlobal) = []; @@ -42,4 +41,6 @@ isHC = !hasInterface && !isDedicated; // deprecated because no tag missionNamespace setVariable ["ACE_isHC", ACE_isHC]; uiNamespace setVariable ["ACE_isHC", ACE_isHC]; +#include "initSettings.sqf" + ADDON = true; diff --git a/addons/common/config.cpp b/addons/common/config.cpp index 2cddf76bd8..6280f186d8 100644 --- a/addons/common/config.cpp +++ b/addons/common/config.cpp @@ -45,7 +45,6 @@ class ACE_Rsc_Control_Base { idc = 1; type = 0; style = 48; - access = 0; lineSpacing = 0; moving = 1; text = ""; @@ -65,6 +64,7 @@ class ACE_Rsc_Control_Base { #include #include #include +#include "CompassControl.hpp" class CfgUIGrids { class IGUI { @@ -90,3 +90,8 @@ class CfgUIGrids { class ACE_Extensions { extensions[] = {}; }; + +class ACE_Tests { + vehicleTransportInventory = QPATHTOF(dev\test_vehicleInventory.sqf); + mapConfigs = QPATHTOF(dev\test_mapConfigs.sqf); +}; diff --git a/docs/squad/logo_ace3_ca.paa b/addons/common/data/logo_ace3_ca.paa similarity index 100% rename from docs/squad/logo_ace3_ca.paa rename to addons/common/data/logo_ace3_ca.paa diff --git a/addons/common/define.hpp b/addons/common/define.hpp index 6c7a90fea9..f25892b6d7 100644 --- a/addons/common/define.hpp +++ b/addons/common/define.hpp @@ -94,7 +94,6 @@ class ACE_gui_backgroundBase { }; class ACE_gui_editBase { - access = 0; type = 2; x = 0; y = 0; @@ -290,7 +289,6 @@ class ACE_gui_listBoxBase : RscListBox{ class ACE_gui_listNBox { - access = 0; type = CT_LISTNBOX;// 102; style =ST_MULTI; w = 0.4; diff --git a/addons/common/dev/test_mapConfigs.sqf b/addons/common/dev/test_mapConfigs.sqf new file mode 100644 index 0000000000..1b114d79e3 --- /dev/null +++ b/addons/common/dev/test_mapConfigs.sqf @@ -0,0 +1,49 @@ +// PabstMirror +// ["mapConfigs"] call ace_common_fnc_runTests; +// execVM "z\ace\addons\common\dev\test_mapConfigs.sqf"; + +#include "\z\ace\addons\common\script_component.hpp" + +diag_log text format ["--- Checking Map Configs ---"]; + +private _testPass = true; + +private _maps = configProperties [configFile >> "CfgWorldList", "(isClass _x)", true]; +{ + private _mapConfigName = configName _x; + private _worldConfig = configFile >> "CfgWorlds" >> _mapConfigName; + private _mapDescription = getText (_worldConfig >> "description"); + + // Check if custom latitude/elevation in lookup table (ace_common_fnc_getMapData) + private _getMapData = [_mapConfigName] call FUNC(getMapData); + if (_getMapData isEqualTo []) then { + diag_log text format ["%1 [%2] - Not in getMapData",_mapDescription,_mapConfigName]; + diag_log text format [" - Using map's config [latitude: %1] [elevationOffset: %2]", getNumber (_worldConfig >> "latitude"), getNumber (_worldConfig >> "elevationOffset")]; + }; + + // Test MGRS grid step size (from ace_common_fnc_getMapGridData) + private _zoomMax = 1e99; + private _formatX = ""; + private _formatY = ""; + private _stepX = 1e10; + private _stepY = 1e10; + { + private _zoom = getnumber (_x >> "zoomMax"); + if (_zoom < _zoomMax) then { + _zoomMax = _zoom; + _formatX = getText (_x >> "formatX"); + _formatY = getText (_x >> "formatY"); + _stepX = getNumber (_x >> "stepX"); + _stepY = getNumber (_x >> "stepY"); + }; + } forEach configProperties [(_worldConfig >> "Grid"), "isClass _x", false]; + private _stepXat5 = _stepX * 10 ^ ((count _formatX) - 5); + private _stepYat5 = -1 * _stepY * 10 ^ ((count _formatY) - 5); + if (_stepYat5 < 0) then {diag_log text format ["%1 [%2] - Northing is reversed.",_mapDescription,_mapConfigName];}; + if (_stepXat5 != 1) then {diag_log text format ["%1 [%2] - MGRS 10 digit grid does not equal 1 meter: (%3) for x.",_mapDescription,_mapConfigName,_stepXat5];}; + if (_stepYat5 != 1 && {_stepYat5 != -1}) then {diag_log text format ["%1 [%2] - MGRS 10 digit grid does not equal 1 meter: (%3) for y.",_mapDescription,_mapConfigName,_stepXat5];}; + +} forEach _maps; + +// Always return true, these are just warnings +_testPass diff --git a/addons/common/dev/test_vehicleInventory.sqf b/addons/common/dev/test_vehicleInventory.sqf new file mode 100644 index 0000000000..fced35a987 --- /dev/null +++ b/addons/common/dev/test_vehicleInventory.sqf @@ -0,0 +1,47 @@ +// PabstMirror +// ["vehicleTransportInventory"] call ace_common_fnc_runTests; +// execVM "z\ace\addons\common\dev\test_vehicleInventory.sqf"; + +private _testPass = true; + +private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x)", true]; +{ + private _vehType = configName _x; + { + private _name = getText (_x >> "name"); + if (_name != "MineDetector") then { // Vanilla mixes up mineDetector alot? + private _weaponConfig = configFile >> "CfgWeapons" >> _name; + private _glassesConfig = configFile >> "CfgGlasses" >> _name; + if (((!isClass _weaponConfig) || {(getNumber (_weaponConfig >> "type")) in [1,2,4]}) && {!isClass _glassesConfig}) then { + diag_log text format ["%1 -> TransportItems -> %2 = Bad", _vehType, _name]; + _testPass = false; + }; + }; + } forEach (configProperties [_x >> "TransportItems", "isClass _x", true]); + { + private _name = getText (_x >> "weapon"); + private _weaponConfig = configFile >> "CfgWeapons" >> _name; + if ((!isClass _weaponConfig) || {!((getNumber (_weaponConfig >> "type")) in [1,2,4])}) then { + diag_log text format ["%1 -> TransportWeapons -> %2 = Bad", _vehType, _name]; + _testPass = false; + }; + } forEach (configProperties [_x >> "TransportWeapons", "isClass _x", true]); + { + private _name = getText (_x >> "magazine"); + private _magConfig = configFile >> "CfgMagazines" >> _name; + if ((!isClass _magConfig)) then { + diag_log text format ["%1 -> TransportMagazines -> %2 = Bad", _vehType, _name]; + _testPass = false; + }; + } forEach (configProperties [_x >> "TransportMagazines", "isClass _x", true]); + { + private _name = getText (_x >> "backpack"); + private _vehConfig = configFile >> "CfgVehicles" >> _name; + if ((!isClass _vehConfig)) then { + diag_log text format ["%1 -> TransportBackpacks -> %2 = Bad", _vehType, _name]; + _testPass = false; + }; + } forEach (configProperties [_x >> "TransportBackpacks", "isClass _x", true]); +} forEach _vehicles; + +_testPass diff --git a/addons/common/functions/fnc_addSetting.sqf b/addons/common/functions/fnc_addSetting.sqf deleted file mode 100644 index 0e5d391b1a..0000000000 --- a/addons/common/functions/fnc_addSetting.sqf +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Author: esteldunedain - * Adds a new setting at runtime, with all it's metadata. - * If has only local effects. - * - * Arguments: - * 0: name - * 1: typeName - * 2: isClientSetable - * 3: localizedName - * 4: localizedDescription - * 5: possibleValues - * 6: isForced - * 7: defaultValue - * - * Return Value: - * None - * - * Example: - * ["bob", "type", true, "bob", "person", [1,2,3], true, 5] call ace_common_fnc_addSettings - * - * Public: No - */ -#include "script_component.hpp" - -params ["_name", "", "", "", "", "", "", "_value"]; //["_name", "_typeName", "_isClientSetable", "_localizedName", "_localizedDescription", "_possibleValues", "_isForced", "_value"]; - -private _settingData = [_name] call FUNC(getSettingData); - -// Exit if the setting already exists -if (count _settingData > 0) exitWith {}; - -// Update the variable -TRACE_2("Setting added",_name,_value); - -// Init the variable -missionNamespace setVariable [_name, _value]; - -// Add the setting data -GVAR(settings) pushBack _this; - -// Raise event locally -["ace_settingChanged", [_name, _value]] call CBA_fnc_localEvent; diff --git a/addons/common/functions/fnc_addToInventory.sqf b/addons/common/functions/fnc_addToInventory.sqf index 19aea9bcdd..d7193cfd23 100644 --- a/addons/common/functions/fnc_addToInventory.sqf +++ b/addons/common/functions/fnc_addToInventory.sqf @@ -23,7 +23,8 @@ params ["_unit", "_classname", ["_container", ""], ["_ammoCount", -1]]; private _type = _classname call FUNC(getItemType); -private ["_canAdd", "_addedToUnit"]; +private _canAdd = false; +private _addedToUnit = false; switch (_container) do { case "vest": { diff --git a/addons/common/functions/fnc_canDig.sqf b/addons/common/functions/fnc_canDig.sqf index b3cdfd8405..2b0412f730 100644 --- a/addons/common/functions/fnc_canDig.sqf +++ b/addons/common/functions/fnc_canDig.sqf @@ -24,8 +24,14 @@ if ((getPosATL _unit) select 2 > 0.05 || // Walking on objects, such as building ) exitWith {false}; private _surfaceClass = (surfaceType _posASL) select [1]; -private _surfaceType = getText (configFile >> "CfgSurfaces" >> _surfaceClass >> "soundEnviron"); -private _surfaceDust = getNumber (configFile >> "CfgSurfaces" >> _surfaceClass >> "dust"); +private _config = configFile >> "CfgSurfaces" >> _surfaceClass; +private _surfaceType = getText (_config >> "soundEnviron"); +private _surfaceDust = getNumber (_config >> "dust"); + TRACE_2("Surface",_surfaceType,_surfaceDust); -!(_surfaceType in DIG_SURFACE_BLACKLIST) && {_surfaceDust >= 0.1} +if (isNumber (_config >> "ACE_canDig")) then { + getNumber (_config >> "ACE_canDig") // return +} else { + !(_surfaceType in DIG_SURFACE_BLACKLIST) && {(_surfaceDust >= 0.1) || {_surfaceType in DIG_SURFACE_WHITELIST}} // return +}; diff --git a/addons/common/functions/fnc_cbaSettings.sqf b/addons/common/functions/fnc_cbaSettings.sqf new file mode 100644 index 0000000000..2b623e5813 --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -0,0 +1,114 @@ +/* + * Author: PabstMirror + * Called at pre-init: Loads all ace_settings and converts them to CBA Settings. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_common_fnc_cbaSettings; + * + * Public: No + */ +//#define DEBUG_MODE_FULL +#include "script_component.hpp" + +LOG("Adding ACE_Settings to CBA_settings"); + +// Init Vars: +GVAR(cbaSettings_forcedSettings) = []; +GVAR(cbaSettings_missionSettings) = []; +GVAR(settings) = []; // will stay empty - for BWC? + +// Add Event Handlers: +[QGVAR(setSetting), { + params ["_settingName", "_value"]; + TRACE_2("setSettingMission from setSetting",_settingName,_value); + ["CBA_settings_setSettingMission", [_settingName, _value, true]] call CBA_fnc_localEvent; + ["CBA_settings_refreshSetting", [_settingName]] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; + +["CBA_beforeSettingsInitialized", { + TRACE_1("CBA_beforeSettingsInitialized EH",_this); + + // First: Process missionConfig settings: + { + _x params ["_settingName", "_value"]; + TRACE_2("setSettingMission from missionConfig",_settingName,_value); + ["CBA_settings_setSettingMission", [_settingName, _value, true]] call CBA_fnc_localEvent; + } forEach GVAR(cbaSettings_missionSettings); + GVAR(cbaSettings_missionSettings) = nil; + + // Second: Read settings from mission params + [] call FUNC(readSettingsFromParamsArray); + + // Third: Event so that ACE_Modules have their settings loaded: + [QGVAR(initSettingsFromModules), []] call CBA_fnc_localEvent; + + TRACE_1("Finished mission settings",_this); +}] call CBA_fnc_addEventHandler; + +["CBA_settingsInitialized", { + TRACE_1("CBA_settingsInitialized EH",_this); + if !(SLX_XEH_MACHINE select 8) then {WARNING("PostInit not finished");}; + INFO("Settings initialized."); + + //Event that settings are safe to use: + ["ace_settingsInitialized", []] call CBA_fnc_localEvent; + + //Set init finished and run all delayed functions: + GVAR(settingsInitFinished) = true; + INFO_1("%1 delayed functions running.",count GVAR(runAtSettingsInitialized)); + { + (_x select 1) call (_x select 0); + false + } count GVAR(runAtSettingsInitialized); + GVAR(runAtSettingsInitialized) = nil; //cleanup +}] call CBA_fnc_addEventHandler; + +private _start = diag_tickTime; + +private _settingsConfig = configFile >> "ACE_Settings"; +private _countOptions = count _settingsConfig; +TRACE_1("Reading settings from configFile",_countOptions); +for "_index" from 0 to (_countOptions - 1) do { + private _optionEntry = _settingsConfig select _index; + if ((getNumber (_optionEntry >> "movedToSQF")) == 0) then { + if (isNil (configName _optionEntry)) then { + [_optionEntry] call FUNC(cbaSettings_loadFromConfig); + } else { + WARNING_1("Setting [%1] - Already defined from somewhere else??",_varName); + }; + }; +}; + +_settingsConfig = missionConfigFile >> "ACE_Settings"; +_countOptions = count _settingsConfig; +TRACE_1("Reading settings from missionConfigFile",_countOptions); +for "_index" from 0 to (_countOptions - 1) do { + private _optionEntry = _settingsConfig select _index; + private _settingName = configName _optionEntry; + if ((toLower _settingName) in GVAR(cbaSettings_forcedSettings)) then { + WARNING_1("Setting [%1] - Already Forced - ignoring missionConfig",_varName); + } else { + if ((isNil _settingName) && {(getNumber (_settingsConfig >> _settingName >> "movedToSQF")) == 0}) then { + // New setting, that was first defined in missionConfigFile + [_optionEntry] call FUNC(cbaSettings_loadFromConfig); + } else { + private _value = (_optionEntry >> "value") call BIS_fnc_getCfgData; + if (isNil "_value") exitWith {ERROR_1("Setting [%1] - Has bad value",_settingName);}; + TRACE_2("queuing missionConfig setting",_settingName,_value); + GVAR(cbaSettings_missionSettings) pushBack [_settingName, _value]; + }; + }; +}; + +// Warning if using a custom ACE_ServerSettings config +if (isServer && {isClass (configFile >> "ACE_ServerSettings")}) then { + WARNING("ACE_ServerSettings is no longer supported and will be ignored"); +}; + +INFO_1("Parsed Settings Configs [%1 ms]",(1000 * (diag_tickTime - _start)) toFixed 1); diff --git a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf new file mode 100644 index 0000000000..d6ecd38591 --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf @@ -0,0 +1,128 @@ +/* + * Author: PabstMirror + * Dev function: Converts ace_settings to code, outputs to clipboard + * + * Arguments: + * 0: Addon + * + * Return Value: + * None + * + * Example: + * ["ace_weaponselect"] call ace_common_fnc_cbaSettings_convertHelper + * + * Public: No + */ +#define DEBUG_MODE_FULL +#include "script_component.hpp" + +params ["_addon"]; + +private _output = [format ["// CBA Settings [ADDON: %1]:", _addon]]; + +private _addonSearch = _addon + "_"; +private _addonSearchCount = count _addonSearch; +TRACE_2("",_addonSearch, _addonSearchCount); + +private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x) && {((configName _x) select [0, _addonSearchCount]) == _addonSearch}"]; + +{ + private _config = _x; + private _varName = configName _config; + private _typeName = toUpper getText (_config >> "typeName"); + if (_typeName == "") then { + WARNING_1("Setting [%1] Has no typeName",_varName); + _typeName = "SCALAR"; + }; + TRACE_2("loadFromConfig",_varName,_typeName); + + private _isClientSettable = (getNumber (_config >> "isClientSettable")) > 0; + private _localizedName = getText (_config >> "displayName"); + private _localizedDescription = getText (_config >> "description"); + private _isForced = (getNumber (_config >> "force")) > 0; + private _category = getText (_config >> "category"); + + private _cbaIsGlobal = (!_isClientSettable) || _isForced; + if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; + + // Basic handling of setting types CBA doesn't support: + if (_typeName == "ARRAY") exitWith { + WARNING_1("Setting [%1] is type ARRAY - limited support",_varName); + private _value = getArray (_config >> "value"); + if (isServer) then {missionNamespace setVariable [_varName, _value, true];}; + }; + + private _cbaSettingType = ""; + private _cbaValueInfo = []; + _cbaValueInfoHint = "default value"; + switch (_typeName) do { + case ("SCALAR"): { // ACE's Scalar can be a float or an index for a list + if (!isNumber (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing number",_varName,_typeName);}; + if (isArray (_config >> "values")) then { + _cbaSettingType = "LIST"; // [_values, _valueTitles, _defaultIndex] + private _values = []; + private _valueTitles = []; + { + _values pushBack _forEachIndex; + _valueTitles pushBack (if ((_x select [0, 1]) == "$") then {localize (_x select [1]);} else {_x}); + } forEach (getArray (_config >> "values")); + _cbaValueInfo = [_values, _valueTitles, getNumber (_config >> "value")]; + } else { + _cbaSettingType = "SLIDER"; // [_min, _max, _default, _trailingDecimals] + _cbaValueInfo = if (isArray (_config >> "sliderSettings")) then { + getArray (_config >> "sliderSettings"); + } else { + [-1, 5000, 0, 1] + }; + _cbaValueInfo set [2, getNumber (_config >> "value")]; + _cbaValueInfoHint = "[min, max, default value, trailing decimals (-1 for whole numbers only)]"; + }; + }; + case ("BOOL"): { + if (!isNumber (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing number",_varName,_typeName);}; + _cbaSettingType = "CHECKBOX"; + _cbaValueInfo = (getNumber (_config >> "value")) > 0; + }; + case ("COLOR"): { + if (!isArray (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing array",_varName,_typeName);}; + _cbaSettingType = "COLOR"; + _cbaValueInfo = getArray (_config >> "value"); + }; + case ("STRING"): { + if (!isText (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing text",_varName,_typeName);}; + _cbaSettingType = "EDITBOX"; + _cbaValueInfo = getText (_config >> "value"); + }; + }; + + if (_cbaSettingType == "") exitWith {ERROR_3("Setting [%1] - value type [%2] is unknown - %3",_varName,_typeName,_cbaValueInfo);}; + + if (_localizedDescription == "") then {_localizedDescription = _varName}; + if (_category == "") then { + WARNING_1("Setting [%1] - no category",_varName); + _category = "Uncategorized"; + }; + private _uncat = false; + if (((_varName select [0, 4]) == "ACE_") && {(_category select [0, 3]) != "ACE"}) then {_uncat = true; _category = format ["ACE %1", _category];}; + if (((_varName select [0, 5]) == "ACEX_") && {(_category select [0, 4]) != "ACEX"}) then {_uncat = true; _category = format ["ACEX %1", _category];}; + + private _gvarName = _varName select [_addonSearchCount]; + + _output pushBack ""; + _output pushBack format ["["]; + _output pushBack format [" QGVAR(%1), ""%2"",", _gvarName, _cbaSettingType]; + _output pushBack format [" [LSTRING(), LSTRING()], // %1, %2", _localizedName, _localizedDescription]; + _output pushBack format [" ""%1"", // %2", ["localize LSTRING()", _category] select _uncat, _category]; + _output pushBack format [" %1, // %2", _cbaValueInfo, _cbaValueInfoHint]; + _output pushBack format [" %1, // isGlobal", _cbaIsGlobal]; + if ((_varName select [0, 4]) == "ACE_") then { + _output pushBack format [" {[QGVAR(%1), _this] call EFUNC(common,cbaSettings_settingChanged)}] call CBA_settings_fnc_init;", _gvarName]; + } else { + _output pushBack format [" {[""%1"", _this] call ace_common_fnc_cbaSettings_settingChanged}", _varName]; + }; + _output pushBack "] call CBA_settings_fnc_init;"; +} forEach _settings; + +copyToClipboard (_output joinString endl); + +INFO_1("Settings sqf copied to clipboard for %1",_addon); diff --git a/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf new file mode 100644 index 0000000000..1382942732 --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf @@ -0,0 +1,105 @@ +/* + * Author: PabstMirror + * Converts a ace_setting config into a cba setting + * + * Arguments: + * 0: Setting config + * + * Return Value: + * None + * + * Example: + * [] call ace_common_fnc_cbaSettings_loadFromConfig; + * + * Public: No + */ +// #define DEBUG_MODE_FULL +#include "script_component.hpp" + +params ["_config"]; + +private _varName = configName _config; +private _typeName = toUpper getText (_config >> "typeName"); +if (_typeName == "") then { + WARNING_1("Setting [%1] Has no typeName",_varName); + _typeName = "SCALAR"; +}; +TRACE_3("loadFromConfig",_var,_typeName,_config); + +private _isClientSettable = (getNumber (_config >> "isClientSettable")) > 0; +private _localizedName = getText (_config >> "displayName"); +private _localizedDescription = getText (_config >> "description"); +private _isForced = (getNumber (_config >> "force")) > 0; +private _category = getText (_config >> "category"); + +private _cbaIsGlobal = (!_isClientSettable) || _isForced; +if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; + +// Basic handling of setting types CBA doesn't support: +if (_typeName == "ARRAY") exitWith { + WARNING_1("Setting [%1] is type ARRAY - limited support",_varName); + private _value = getArray (_config >> "value"); + if (isServer) then {missionNamespace setVariable [_varName, _value, true];}; +}; + +private _cbaSettingType = ""; +private _cbaValueInfo = []; +switch (_typeName) do { +case ("SCALAR"): { // ACE's Scalar can be a float or an index for a list + if (!isNumber (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing number",_varName,_typeName);}; + if (isArray (_config >> "values")) then { + _cbaSettingType = "LIST"; // [_values, _valueTitles, _defaultIndex] + private _values = []; + private _valueTitles = []; + { + _values pushBack _forEachIndex; + _valueTitles pushBack (if ((_x select [0, 1]) == "$") then {localize (_x select [1]);} else {_x}); + } forEach (getArray (_config >> "values")); + _cbaValueInfo = [_values, _valueTitles, getNumber (_config >> "value")]; + } else { + _cbaSettingType = "SLIDER"; // [_min, _max, _default, _trailingDecimals] + _cbaValueInfo = if (isArray (_config >> "sliderSettings")) then { + getArray (_config >> "sliderSettings"); + } else { + INFO_1("Using auto min/max for [%1]",_varName); + [-1, 5000, 0, 1] + }; + _cbaValueInfo set [2, getNumber (_config >> "value")]; + }; + }; +case ("BOOL"): { + if (!isNumber (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing number",_varName,_typeName);}; + _cbaSettingType = "CHECKBOX"; + _cbaValueInfo = (getNumber (_config >> "value")) > 0; + }; +case ("COLOR"): { + if (!isArray (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing array",_varName,_typeName);}; + _cbaSettingType = "COLOR"; + _cbaValueInfo = getArray (_config >> "value"); + }; +case ("STRING"): { + if (!isText (_config >> "value")) then {WARNING_2("Setting [%1] - value type [%2] is missing text",_varName,_typeName);}; + _cbaSettingType = "EDITBOX"; + _cbaValueInfo = getText (_config >> "value"); + }; +}; + +if (_cbaSettingType == "") exitWith {ERROR_3("Setting [%1] - value type [%2] is unknown - %3",_varName,_typeName,_cbaValueInfo);}; + +if (_localizedDescription == "") then {_localizedDescription = _varName}; +if (_category == "") then { + // WARNING_1("Setting [%1] - no category",_varName); + _category = "Uncategorized"; +}; +if (((_varName select [0, 4]) == "ACE_") && {(_category select [0, 3]) != "ACE"}) then {_category = format ["ACE %1", _category];}; +if (((_varName select [0, 5]) == "ACEX_") && {(_category select [0, 4]) != "ACEX"}) then {_category = format ["ACEX %1", _category];}; + +private _code = compile format ['["%1", _this] call FUNC(cbaSettings_settingChanged)', _varName]; + +TRACE_2("setting",_cbaSettingType,_cbaValueInfo); +TRACE_4("",_isForced,_cbaIsGlobal,_category,_cbaValueInfo); +private _return = [_varName, _cbaSettingType, [_localizedName, _localizedDescription], _category, _cbaValueInfo, _cbaIsGlobal, _code] call CBA_settings_fnc_init; +TRACE_1("returned",_return); +if ((isNil "_return") || {_return != 0}) then {ERROR_1("Setting [%1] - CBA Error",_varName);}; +_return + diff --git a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf new file mode 100644 index 0000000000..6fa99e313d --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf @@ -0,0 +1,33 @@ +/* + * Author: PabstMirror + * Function for handeling a cba setting being changed. + * Adds warning if global setting is changed after ace_settingsInitialized + * + * Arguments: + * 0: Setting Name + * 1: New Value + * 2: Can be changed mid-mission (default: false) + * + * Return Value: + * None + * + * Example: + * ["ace_medical_level", 1, false] call ace_common_fnc_cbaSettings_settingChanged; + * + * Public: No + */ +// #define DEBUG_MODE_FULL +#include "script_component.hpp" + +params ["_settingName", "_newValue", ["_canBeChanged", false]]; +TRACE_2("",_settingName,_newValue); + +["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent; + +if (_canBeChanged) exitWith {}; +if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized +if (CBA_settings_default getVariable [_settingName, []] param [7, 0] == 0) exitWith {}; // Ignore if not a global setting +if ((getNumber (configFile >> "ACE_settings" >> _settingName >> "canBeChanged")) == 1) exitWith {}; // Ignore if flagged as ok to change + +WARNING_1("Global setting [%1] changed mid-mission",_settingName); +[QGVAR(displayTextStructured), [format ["Global setting %1 changed mid-mission. Mission restart may be required to prevent issues", _settingName], 4]] call CBA_fnc_localEvent; diff --git a/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf b/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf new file mode 100644 index 0000000000..8d55f671b7 --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf @@ -0,0 +1,42 @@ +/* + * Author: PabstMirror + * Transfers a client's old ace settings to cba + * + * Arguments: + * 0: Old Version + * + * Return Value: + * None + * + * Example: + * ["3.11.0"] call ace_common_fnc_cbaSettings_transferUserSettings + * + * Public: No + */ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +params [["_lastVersion", "", [""]]]; + +if ((parseNumber _lastVersion) >= 3.12) exitWith {}; + +INFO("-Transfering old ACE_Settings to CBA-"); + +private _aceSettings = configProperties [configFile >> "ACE_Settings", "isClass _x"]; +{ + private _settingName = configName _x; + private _isClientSettable = (getNumber (_x >> "isClientSettable")) > 0; + private _profileVar = profileNamespace getVariable _settingName; + + if (!isNil "_profileVar") then { + private _currentValue = [_settingName, "client"] call CBA_settings_fnc_get; + if (_isClientSettable && {!(_currentValue isEqualTo _profileVar)}) then { + // CBA_settings_fnc_set will do type checking for the old profile var + private _ret = [_settingName, _profileVar, 0, "client", true] call CBA_settings_fnc_set; + INFO_3("Transfering setting [%1: %2] returned %3", _settingName, _profileVar, _ret); + }; + }; +} forEach _aceSettings; + +INFO("-Finished Transfering-"); diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index 480cdab9a9..1a3d34bc86 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -78,7 +78,17 @@ if (toLower (productVersion select 6) in ["linux", "osx"]) then { private _versionEx = _x callExtension "version"; if (_versionEx == "") then { - private _errorMsg = format ["Extension %1.dll not installed.", _x]; + private _extension = ".dll"; + + if (productVersion select 7 == "x64") then { + _extension = "_x64.dll"; + }; + + if (productVersion select 6 == "Linux") then { + _extension = ".so"; + }; + + private _errorMsg = format ["Extension %1%2 not found.", _x, _extension]; ERROR(_errorMsg); diff --git a/addons/common/functions/fnc_claim.sqf b/addons/common/functions/fnc_claim.sqf index 79237d725b..8df41cb241 100644 --- a/addons/common/functions/fnc_claim.sqf +++ b/addons/common/functions/fnc_claim.sqf @@ -30,10 +30,17 @@ _target setVariable [QGVAR(owner), _unit, true]; // lock target object if (_lockTarget) then { + private _canBeDisassembled = !([] isEqualTo getArray (_target call CBA_fnc_getObjectConfig >> "assembleInfo" >> "dissasembleTo")); if (!isNull _unit) then { [QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent; + if (_canBeDisassembled) then { + _target enableWeaponDisassembly false; + }; } else { [QGVAR(unlockVehicle), _target, _target] call CBA_fnc_targetEvent; + if (_canBeDisassembled) then { + _target enableWeaponDisassembly true; + }; }; }; diff --git a/addons/common/functions/fnc_dumpArray.sqf b/addons/common/functions/fnc_dumpArray.sqf index b274f1119e..6c1caf7908 100644 --- a/addons/common/functions/fnc_dumpArray.sqf +++ b/addons/common/functions/fnc_dumpArray.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Array to be dumped - * 1: Depth + * 1: Depth (default: 0) * * Return Value: * None diff --git a/addons/common/functions/fnc_endRadioTransmission.sqf b/addons/common/functions/fnc_endRadioTransmission.sqf index ead1ec29c6..57099afe90 100644 --- a/addons/common/functions/fnc_endRadioTransmission.sqf +++ b/addons/common/functions/fnc_endRadioTransmission.sqf @@ -1,7 +1,7 @@ /* * Author: commy2 * - * End radio transmissions of addons TFAR and ACRE2. TFAR v0.9.7, ACRE Public Beta 2.0.3.571 + * End radio transmissions of addons TFAR and ACRE2. TFAR v0.9.x, ACRE Public Beta 2.0.3.571 * * Arguments: * None @@ -16,6 +16,8 @@ */ #include "script_component.hpp" +["ace_endRadioTransmissions"] call CBA_fnc_localEvent; + // ACRE if (isClass (configFile >> "CfgPatches" >> "acre_main")) then { [-1] call acre_sys_core_fnc_handleMultiPttKeyPressUp; diff --git a/addons/common/functions/fnc_errorMessage.sqf b/addons/common/functions/fnc_errorMessage.sqf index 8ccd7c22fb..1be21e0e58 100644 --- a/addons/common/functions/fnc_errorMessage.sqf +++ b/addons/common/functions/fnc_errorMessage.sqf @@ -38,7 +38,7 @@ if (_textMessage isEqualType "") then { _textMessage = parseText _textMessage; }; -(ARR_SELECT(_this,4,call BIS_fnc_displayMission)) createDisplay "RscDisplayCommonMessagePause"; +ARR_SELECT(_this,4,call BIS_fnc_displayMission) createDisplay "RscDisplayCommonMessagePause"; private _display = uiNamespace getVariable "RscDisplayCommonMessage_display"; private _ctrlRscMessageBox = _display displayCtrl 2351; diff --git a/addons/common/functions/fnc_findUnloadPosition.sqf b/addons/common/functions/fnc_findUnloadPosition.sqf index c3b0dc3f34..85818cbda1 100644 --- a/addons/common/functions/fnc_findUnloadPosition.sqf +++ b/addons/common/functions/fnc_findUnloadPosition.sqf @@ -1,20 +1,20 @@ /* * Author: PabstMirror, ViperMaul - * Find a safe place near a vehicle to unload something - * Handles Normal Terrain, In Water or On Buildings (Pier, StaticShip) + * Find a safe place near a vehicle to unload something. + * Handles Normal Terrain, In Water or On Buildings (Pier, StaticShip). * * Arguments: * 0: Source Vehicle * 1: Cargo Classname - * 2: Unloader (player) - * 3: Max Distance (meters) - * 4: Check Vehicle is Stable + * 2: Unloader (player) (default: objNull) + * 3: Max Distance (meters) (default: 10) + * 4: Check Vehicle is Stable (default: true) * * Return Value: - * Unload PositionAGL (Can Be [] if no valid pos found) + * Unload PositionAGL (can Be [] if no valid pos found) * * Example: - * [theCar, "CAManBase", player, 10, true] call ace_common_fnc_findUnloadPosition; + * [theCar, "CAManBase", player, 10, true] call ace_common_fnc_findUnloadPosition * * Public: No */ diff --git a/addons/common/functions/fnc_fixPosition.sqf b/addons/common/functions/fnc_fixPosition.sqf index fb14141fe2..700d47dc19 100644 --- a/addons/common/functions/fnc_fixPosition.sqf +++ b/addons/common/functions/fnc_fixPosition.sqf @@ -1,6 +1,5 @@ /* - * Author: commy2 - * + * Author: commy2, Jonpas * Fixes position of an object. E.g. moves object above ground and adjusts to terrain slope. Requires local object. * * Arguments: @@ -10,7 +9,7 @@ * None * * Example: - * [bob] call ace_common_fnc_fixPosition + * bob call ace_common_fnc_fixPosition * * Public: No */ @@ -19,25 +18,31 @@ // setVectorUp requires local object if (!local _this) exitWith {}; -if ((getText (configFile >> "CfgVehicles" >> (typeOf _this) >> "simulation")) == "house") then { - //Houses don't have gravity/physics, so make sure they are not floating - private _posAbove = (getPos _this) select 2; - TRACE_2("house",_this,_posAbove); - if (_posAbove > 0.1) then { - private _newPosASL = (getPosASL _this) vectorDiff [0,0,_posAbove]; - _this setPosASL _newPosASL; +// Objects with disabled simulation and objects with simulation type "house" don't have gravity/physics, so make sure they are not floating +private _hasGravity = simulationEnabled _this && {getText (configFile >> "CfgVehicles" >> typeOf _this >> "simulation") != "house"}; + +if (!_hasGravity) then { + private _positionASL = getPosASL _this; + // find height of top surface under object + private _surfaces = lineIntersectsSurfaces [_positionASL, ATLToASL [_positionASL select 0, _positionASL select 1, -1], _this]; + if (_surfaces isEqualTo []) exitWith {}; + private _surfaceHeight = _surfaces select 0 select 0 select 2; + TRACE_2("house",_this,_surfaceHeight); + if (_positionASL select 2 > _surfaceHeight + 0.1) then { + _this setPosASL [_positionASL select 0, _positionASL select 1, _surfaceHeight]; }; }; -private _position = getPos _this; +private _position = getPosATL _this; -// don't place the object below the ground +// Don't place the object below the ground if (_position select 2 < -0.1) then { _position set [2, -0.1]; - _this setPos _position; + _this setPosATL _position; }; -// adjust position to sloped terrain, if placed on ground -if (getPosATL _this select 2 == _position select 2) then { +// Adjust position to sloped terrain, if placed on ground +// Object without gravity/physics may have negative height when placed on slope, but those objects are definitely on the ground +if (!_hasGravity || {getPosATL _this select 2 == _position select 2}) then { _this setVectorUp surfaceNormal _position; }; diff --git a/addons/common/functions/fnc_getMGRSdata.sqf b/addons/common/functions/fnc_getMGRSdata.sqf index 4e0df618e1..4b4906aba3 100644 --- a/addons/common/functions/fnc_getMGRSdata.sqf +++ b/addons/common/functions/fnc_getMGRSdata.sqf @@ -22,7 +22,7 @@ params [["_map", worldName]]; private _long = getNumber (configFile >> "CfgWorlds" >> _map >> "longitude"); -private _lat = getNumber (configFile >> "CfgWorlds" >> _map >> "latitude"); +private _lat = -1 * getNumber (configFile >> "CfgWorlds" >> _map >> "latitude"); // latitude is reversed in arma (negative config values in north) private _altitude = getNumber (configFile >> "CfgWorlds" >> _map >> "elevationOffset"); private _mapData = _map call FUNC(getMapData); diff --git a/addons/common/functions/fnc_getMapData.sqf b/addons/common/functions/fnc_getMapData.sqf index 33f3e09d83..b4cb56d75f 100644 --- a/addons/common/functions/fnc_getMapData.sqf +++ b/addons/common/functions/fnc_getMapData.sqf @@ -31,6 +31,7 @@ if (_map in ["abramia"]) exitWith { [60, 0] }; if (_map in ["af_kandahar_province"]) exitWith { [42, 0] }; if (_map in ["angel"]) exitWith { [38, 0] }; if (_map in ["anim_helvantis_v2"]) exitWith { [50, 0] }; +if (_map in ["anim_starokovka"]) exitWith { [50, 0] }; if (_map in ["australia"]) exitWith { [-25, 0] }; if (_map in ["baranow", "ivachev", "panavo", "staszow"]) exitWith { [50, 148.1] }; // IFA3LITE - default elevationOffset if (_map in ["beketov"]) exitWith { [55, 0] }; diff --git a/addons/common/functions/fnc_getMapGridData.sqf b/addons/common/functions/fnc_getMapGridData.sqf index 60edb8941d..a33e49e7d0 100644 --- a/addons/common/functions/fnc_getMapGridData.sqf +++ b/addons/common/functions/fnc_getMapGridData.sqf @@ -68,15 +68,13 @@ private _stepXat5 = _stepX * 10 ^ ((count _formatX) - 5); private _stepYat5 = -1 * _stepY * 10 ^ ((count _formatY) - 5); if (_stepYat5 < 0) then { - WARNING_1("Map Grid Warning (%1) - Northing is reversed.",worldName); + TRACE_1("Northing is reversed",worldName); }; - if (_stepXat5 != 1) then { - WARNING_2("Map Grid Warning (%1) - MGRS 10 digit grid does not equal 1 meter: (%2) for x.",worldName,_stepXat5); + TRACE_2("MGRS 10 digit grid does not equal 1 meter",_stepXat5,worldName); }; - if (_stepYat5 != 1 && {_stepYat5 != -1}) then { - WARNING_2("Map Grid Warning (%1) - MGRS 10 digit grid does not equal 1 meter: (%2) for y.",worldName,_stepXat5); + TRACE_2("MGRS 10 digit grid does not equal 1 meter",_stepYat5,worldName); }; GVAR(mapGridData) = [_offsetX, _realOffsetY, _stepXat5, _stepYat5]; diff --git a/addons/common/functions/fnc_getPylonTurret.sqf b/addons/common/functions/fnc_getPylonTurret.sqf new file mode 100644 index 0000000000..ff343173dd --- /dev/null +++ b/addons/common/functions/fnc_getPylonTurret.sqf @@ -0,0 +1,64 @@ +/* + * Author: PabstMirror + * Finds turret owner of a pylon. + * + * Arguments: + * 0: Vehicle + * 1: Pylon Index (starting at 0) + * + * Return Value: + * * Turret index (either [-1] or [0]) + * + * Example: + * [cursorObject, 0] call ace_common_fnc_getPylonTurret + * + * Public: No + */ +// #define DEBUG_MODE_FULL +#include "script_component.hpp" + +params ["_vehicle", "_pylonIndex"]; + +// See if index is in ace_pylonTurrets setVar on vehicle +private _pylonTurrets = _vehicle getVariable ["ace_pylonTurrets", []]; +private _returnValue = _pylonTurrets param [_pylonIndex, []]; + +if (!(_returnValue isEqualTo [])) then { + TRACE_1("Using ace_pylonTurrets value",_returnValue); +} else { + // Attempt to determine turret owner based on magazines in the vehicle + private _pyMags = getPylonMagazines _vehicle; + private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> typeOf _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; + if (_pylonIndex >= (count _pyMags)) exitWith {ERROR("out of bounds");}; + if (_pylonIndex >= (count _pylonConfigs)) exitWith {ERROR("out of bounds");}; + + private _targetMag = _pyMags select _pylonIndex; + private _inPilot = _targetMag in (_vehicle magazinesTurret [-1]); + private _inGunner = _targetMag in (_vehicle magazinesTurret [0]); + + if (_inPilot) then { + if (_inGunner) then { + TRACE_3("ambiguous - in both",_targetMag,_inPilot,_inGunner); + } else { + TRACE_3("Pilot Mag",_targetMag,_inPilot,_inGunner); + _returnValue = [-1]; + }; + } else { + if (_inGunner) then { + TRACE_3("Gunner Mag",_targetMag,_inPilot,_inGunner); + _returnValue = [0]; + } else { + TRACE_3("ambiguous - in neither",_targetMag,_inPilot,_inGunner); + }; + }; + + if (_returnValue isEqualTo []) then { // If not sure, just use config value + _returnValue = getArray ((_pylonConfigs select _pylonIndex) >> "turret"); + if (_returnValue isEqualTo []) then { + _returnValue = [-1]; + }; + }; +}; + +TRACE_3("",_vehicle,_pylonIndex,_returnValue); +_returnValue diff --git a/addons/common/functions/fnc_getVehicleIcon.sqf b/addons/common/functions/fnc_getVehicleIcon.sqf new file mode 100644 index 0000000000..fd556ed580 --- /dev/null +++ b/addons/common/functions/fnc_getVehicleIcon.sqf @@ -0,0 +1,48 @@ +/* + * Author: AACO + * Function used to get the vehicle icon for provided object (cached for repeat use) + * + * Arguments: + * 0: Object to get icon of + * + * Return Value: + * Icon of vehicle + * + * Examples: + * ["B_Soldier_F"] call ace_common_fnc_getVehicleIcon; + * + * Public: Yes + */ + +#include "script_component.hpp" +#define DEFAULT_TEXTURE "\A3\ui_f\data\Map\VehicleIcons\iconVehicle_ca.paa" + +params [["_object", objNull, [objNull, ""]]]; + +if ((_object isEqualType objNull && {isNull _object}) || {_object isEqualType "" && {_object == ""}}) exitWith { DEFAULT_TEXTURE }; + +private _objectType = if (_object isEqualType objNull) then { + typeOf _object +} else { + _object +}; +private _cachedValue = GVAR(vehicleIconCache) getVariable _objectType; + +if (isNil "_cachedValue") then { + private _vehicleValue = getText (configfile >> "CfgVehicles" >> _objectType >> "icon"); + private _vehicleIconValue = getText (configfile >> "CfgVehicleIcons" >> _vehicleValue); + + if (_vehicleIconValue == "") then { + if (_vehicleValue != "" && {((toLower _vehicleValue) find ".paa") > -1}) then { + _cachedValue = _vehicleValue; + } else { + _cachedValue = DEFAULT_TEXTURE; + }; + } else { + _cachedValue = _vehicleIconValue; + }; + + GVAR(vehicleIconCache) setVariable [_objectType, _cachedValue]; +}; + +_cachedValue diff --git a/addons/movement/functions/fnc_getWeight.sqf b/addons/common/functions/fnc_getWeight.sqf similarity index 56% rename from addons/movement/functions/fnc_getWeight.sqf rename to addons/common/functions/fnc_getWeight.sqf index b64abc3623..6c3a224582 100644 --- a/addons/movement/functions/fnc_getWeight.sqf +++ b/addons/common/functions/fnc_getWeight.sqf @@ -4,23 +4,24 @@ * * Arguments: * 0: The Unit (usually the player) + * 1: Force a return type * * Return Value: * The return value * * Example: - * [player] call ace_movement_fnc_getWeight + * [player] call ace_common_fnc_getWeight * * Public: No */ #include "script_component.hpp" -params ["_unit"]; +params ["_unit", ["_useImperial", false, [false, 0]]]; private _virtualLoad = 0; { - _virtualLoad = _virtualLoad + (_x getVariable [QGVAR(vLoad), 0]); + _virtualLoad = _virtualLoad + (_x getVariable [QEGVAR(movement,vLoad), 0]); } forEach [ _unit, uniformContainer _unit, @@ -30,10 +31,9 @@ private _virtualLoad = 0; private _weight = (loadAbs _unit + _virtualLoad) * 0.1; -if (GVAR(useImperial)) then { - _weight = format ["%1lb", (round (_weight * 100)) / 100]; +//Return +if (_useImperial in [true, 1]) then { + format ["%1lb", (round (_weight * 100)) / 100] } else { - _weight = format ["%1kg", (round (_weight * FACTOR_POUND_TO_KILOGRAMM * 100)) / 100]; + format ["%1kg", (round (_weight * (1/2.2046) * 100)) / 100] }; - -_weight diff --git a/addons/common/functions/fnc_goKneeling.sqf b/addons/common/functions/fnc_goKneeling.sqf index b838a4f047..5d45a3f400 100644 --- a/addons/common/functions/fnc_goKneeling.sqf +++ b/addons/common/functions/fnc_goKneeling.sqf @@ -1,6 +1,6 @@ /* * Author: commy2 - * Move unit to kneeling position (only if not yet prone). + * Move unit to kneeling position (only if not yet prone and not underwater). * * Arguments: * 0: Unit @@ -18,7 +18,7 @@ params ["_unit"]; // Animation changes even inside vehicle post-1.60 -if (stance _unit == "PRONE" || {vehicle ACE_player != ACE_player}) exitWith {}; +if (stance _unit == "PRONE" || {vehicle _unit != _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; [ _unit, diff --git a/addons/common/functions/fnc_hasItem.sqf b/addons/common/functions/fnc_hasItem.sqf index f77337a5dd..9d5d79b1a5 100644 --- a/addons/common/functions/fnc_hasItem.sqf +++ b/addons/common/functions/fnc_hasItem.sqf @@ -1,23 +1,21 @@ /* * Author: Glowbal - * Check if unit has item + * Check if unit has item. Note: case-sensitive. * * Arguments: * 0: Unit * 1: Item Classname * * Return Value: - * has Item + * Unit has Item * * Example: - * [[bob, "item"] call ace_common_fnc_hasItem + * [bob, "item"] call ace_common_fnc_hasItem * - * Public: yes - * - * Note: Case sensitive + * Public: Yes */ #include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_item", "", [""]]]; -_item in items _unit // return +_item in items _unit diff --git a/addons/common/functions/fnc_isFeatureCameraActive.sqf b/addons/common/functions/fnc_isFeatureCameraActive.sqf index b0870408af..dfe3869905 100644 --- a/addons/common/functions/fnc_isFeatureCameraActive.sqf +++ b/addons/common/functions/fnc_isFeatureCameraActive.sqf @@ -5,6 +5,7 @@ * - Curator * - ACE Spectator * - Arsenal camera (BIS_fnc_arsenal) + * - Nexus Spectator (BIS_fnc_EGSpectator) * - Establishing shot (BIS_fnc_establishingShot) * - Splendid camera (BIS_fnc_camera) * - Animation viewer (BIS_fnc_animViewer) @@ -25,10 +26,11 @@ !( isNull curatorCamera && // Curator - {!(GETMVAR(EGVAR(spectator,isSet),false))} && // ACE Spectator - {isNull (GETUVAR(BIS_fnc_arsenal_cam, objNull))} && // Arsenal camera - {isNull (GETMVAR(BIS_fnc_establishingShot_fakeUAV, objNull))} && // Establishing shot camera - {isNull (GETMVAR(BIS_fnc_camera_cam, objNull))} && // Splendid camera - {isNull (GETUVAR(BIS_fnc_animViewer_cam, objNull))} && // Animation viewer camera - {isNull (GETMVAR(BIS_DEBUG_CAM, objNull))} // Classic camera + {!GETMVAR(EGVAR(spectator,isSet),false)} && // ACE Spectator + {isNull GETMVAR(BIS_EGSpectatorCamera_camera, objNull)} && // BIS Nexus Spectator + {isNull GETUVAR(BIS_fnc_arsenal_cam, objNull)} && // Arsenal camera + {isNull GETMVAR(BIS_fnc_establishingShot_fakeUAV, objNull)} && // Establishing shot camera + {isNull GETMVAR(BIS_fnc_camera_cam, objNull)} && // Splendid camera + {isNull GETUVAR(BIS_fnc_animViewer_cam, objNull)} && // Animation viewer camera + {isNull GETMVAR(BIS_DEBUG_CAM, objNull)} // Classic camera ) // return diff --git a/addons/common/functions/fnc_isMedic.sqf b/addons/common/functions/fnc_isMedic.sqf new file mode 100644 index 0000000000..2a0d0dc520 --- /dev/null +++ b/addons/common/functions/fnc_isMedic.sqf @@ -0,0 +1,23 @@ +/* + * Author: SilentSpike + * Check if a unit is a medic + * + * Arguments: + * 0: The Unit + * + * ReturnValue: + * Unit is medic + * + * Example: + * [player] call ace_common_fnc_isMedic + * + * Public: Yes + */ + +#include "script_component.hpp" + +params ["_unit"]; + +private _isMedic = _unit getVariable [QEGVAR(medical,medicClass), getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "attendant")]; + +_isMedic > 0 diff --git a/addons/common/functions/fnc_isSwimming.sqf b/addons/common/functions/fnc_isSwimming.sqf new file mode 100644 index 0000000000..8aee92ad81 --- /dev/null +++ b/addons/common/functions/fnc_isSwimming.sqf @@ -0,0 +1,20 @@ +/* + * Author: das attorney, Jonpas + * Check if unit is swimming (surface swimming or diving). + * + * Arguments: + * 0: Unit + * + * Return Value: + * If unit is swimming + * + * Example: + * [bob] call ace_common_fnc_isSwimming + * + * Public: Yes + */ +#include "script_component.hpp" + +params [["_unit", objNull, [objNull]]]; + +((animationState _unit) select [1, 3]) in ["bdv","bsw","dve","sdv","ssw","swm"] diff --git a/addons/common/functions/fnc_isUnderwater.sqf b/addons/common/functions/fnc_isUnderwater.sqf index f3f127d75f..0d7d1e50a1 100644 --- a/addons/common/functions/fnc_isUnderwater.sqf +++ b/addons/common/functions/fnc_isUnderwater.sqf @@ -15,6 +15,8 @@ */ #include "script_component.hpp" +ACE_DEPRECATED(QFUNC(isUnderwater),"3.13.0","underwater OBJECT"); + params [["_unit", objNull, [objNull]]]; private _return = false; diff --git a/addons/common/functions/fnc_loadPerson.sqf b/addons/common/functions/fnc_loadPerson.sqf index 59c9af2c20..4fc6245b5a 100644 --- a/addons/common/functions/fnc_loadPerson.sqf +++ b/addons/common/functions/fnc_loadPerson.sqf @@ -1,13 +1,14 @@ /* * Author: Glowbal - * Loads a specified unit into any nearby vehicle + * Loads a specified unit into any nearby vehicle, or _vehicle parameter. * * Arguments: * 0: Unit that will load * 1: Unit to be loaded + * 2: Vehicle that the unit will be loaded in (default: objNull) * * Return Value: - * the vehicle that the unitToBeloaded has been loaded in. Returns ObjNull if function failed + * Vehicle that the unitToBeloaded has been loaded in. Returns objNull if function failed * * Example: * [bob, kevin] call ace_common_fnc_loadPerson @@ -18,20 +19,14 @@ #define GROUP_SWITCH_ID QFUNC(loadPerson) -params ["_caller", "_unit"]; +params ["_caller", "_unit", ["_vehicle", objNull]]; -private _vehicle = objNull; +if (!([_caller, _unit, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle}; -if (!([_caller, _unit, ["isNotDragging", "isNotCarrying"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle}; - -private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F"], 10]; - -{ - TRACE_1("",_x); - if ((_x emptyPositions "cargo" > 0) || {_x emptyPositions "gunner" > 0}) exitWith { - _vehicle = _x; - }; -} forEach _nearVehicles; +// Try to use nearest vehicle if a vehicle hasn't been supplied +if (isNull _vehicle) then { + _vehicle = ([_unit] call FUNC(nearestVehiclesFreeSeat)) param [0, objNull]; +}; if (!isNull _vehicle) then { [_unit, true, GROUP_SWITCH_ID, side group _caller] call FUNC(switchToGroupSide); diff --git a/addons/common/functions/fnc_loadPersonLocal.sqf b/addons/common/functions/fnc_loadPersonLocal.sqf index 90cbd7da03..f6a759add8 100644 --- a/addons/common/functions/fnc_loadPersonLocal.sqf +++ b/addons/common/functions/fnc_loadPersonLocal.sqf @@ -19,9 +19,9 @@ params ["_unit", "_vehicle", "_caller"]; -if (!alive _unit) then { - // _unit = [_unit, _caller] call FUNC(makeCopyOfBody); //func does not exist -}; +// if (!alive _unit) then { +// _unit = [_unit, _caller] call makeCopyOfBody; //func does not exist +// }; private _slotsOpen = false; diff --git a/addons/common/functions/fnc_loadSettingsFromProfile.sqf b/addons/common/functions/fnc_loadSettingsFromProfile.sqf deleted file mode 100644 index 9151d79cce..0000000000 --- a/addons/common/functions/fnc_loadSettingsFromProfile.sqf +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Author: esteldunedain - * Load the user setable settings from the user profile. - * Config < Server UserConfig < Mission Config < Client settings - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_common_fnc_loadSettingsFromProfile - * - * Public: No - */ -#include "script_component.hpp" - -// Iterate through settings -{ - _x params ["_name", "", "_isClientSetable", "", "", "", "_isForced"]; - - // If setting is user setable - if (_isClientSetable) then { - // If setting is not forced - if !(_isForced) then { - private _profileValue = profileNamespace getVariable _name; - - // If the setting is stored on the profile - if !(isNil "_profileValue") then { - // If the profile variable has the correct type - if (_profileValue isEqualType (missionNamespace getVariable _name)) then { - // Load the setting from the profile - missionNamespace setVariable [_name, _profileValue]; - }; - }; - }; - }; - false -} count GVAR(settings); diff --git a/addons/common/functions/fnc_loadSettingsLocalizedText.sqf b/addons/common/functions/fnc_loadSettingsLocalizedText.sqf deleted file mode 100644 index 7ceffa04e7..0000000000 --- a/addons/common/functions/fnc_loadSettingsLocalizedText.sqf +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Author: Glowbal - * Parse all settings and load the localized displayName and description for all text - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_common_fnc_loadSettingsLocalizedText - * - * Public: No - */ -#include "script_component.hpp" - -private _fnc_parseConfigForDisplayNames = { - params ["_optionEntry"]; - - if !(isClass _optionEntry) exitWith {false}; - - private _values = getArray (_optionEntry >> "values"); - - _x set [3, getText (_optionEntry >> "displayName")]; - _x set [4, getText (_optionEntry >> "description")]; - _x set [5, _values]; - _x set [8, getText (_optionEntry >> "category")]; - - { - private _text = _x; - - if (_text isEqualType "" && {count _text > 1} && {_text select [0, 1] == "$"}) then { - _text = localize (_text select [1]); //chop off the leading $ - _values set [_forEachIndex, _text]; - }; - } forEach _values; - - if (!(_values isEqualTo [])) then { - if (_typeOf != "SCALAR") then { - WARNING_2("Setting [%1] has values[] but is not SCALAR (%2)", _name, _typeOf); - } else { - private _value = missionNamespace getVariable [_name, -1]; - if ((_value < 0) || {_value >= (count _values)}) then { - WARNING_3("Setting [%1] out of bounds %2 (values[] count is %3)", _name, _value, count _values); - }; - }; - }; - true -}; - -// Iterate through settings -{ - _x params ["_name", "_typeOf"]; - - if !([configFile >> "ACE_Settings" >> _name] call _fnc_parseConfigForDisplayNames) then { - if !([configFile >> "ACE_ServerSettings" >> _name] call _fnc_parseConfigForDisplayNames) then { - if !([missionConfigFile >> "ACE_Settings" >> _name] call _fnc_parseConfigForDisplayNames) then { - WARNING_1("Setting found, but couldn't localize [%1] (server has but we don't?)",_name); - }; - }; - }; - false -} count GVAR(settings); diff --git a/addons/common/functions/fnc_loadSettingsOnServer.sqf b/addons/common/functions/fnc_loadSettingsOnServer.sqf deleted file mode 100644 index eaeac7d51d..0000000000 --- a/addons/common/functions/fnc_loadSettingsOnServer.sqf +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Author: esteldunedain - * Load the parameters on the server. - * Config < Server UserConfig < Mission Config - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_common_fnc_loadSettingsOnServer - * - * Public: No - */ -#include "script_component.hpp" - -GVAR(settings) = []; - -private _fnc_parseConfigForSettings = { - params ["_config"]; - - private _countOptions = count _config; - - for "_index" from 0 to (_countOptions - 1) do { - private _optionEntry = _config select _index; - [_optionEntry] call FUNC(setSettingFromConfig); - }; - - // Check if all settings should be forced - if (GVAR(forceAllSettings)) then { - { - _x set [6, true]; - false - } count GVAR(settings); - }; -}; - -// Order is this way because: -// ACE_Settings should never force any setting by default. Loading it first ensures that all settings from ACE_Settings exist. -// This way, ACE_ServerSettings will override ACE_Settings, even if no force is used. -// Mission settings will override the server config settings, if no force is used. -// This ensures that all settings are of their correct type, in case an outdated or corrupt server config is used , as well as have their correct localized display name and description - -// Regular config -[configFile >> "ACE_Settings"] call _fnc_parseConfigForSettings; - -// Server config -[configFile >> "ACE_ServerSettings"] call _fnc_parseConfigForSettings; - -// mission side settings -[missionConfigFile >> "ACE_Settings"] call _fnc_parseConfigForSettings; - -// Publish all setting values -{ - publicVariable (_x select 0); - false -} count GVAR(settings); diff --git a/addons/common/functions/fnc_moduleCheckPBOs.sqf b/addons/common/functions/fnc_moduleCheckPBOs.sqf index f3a8c0902c..6cdfd0d811 100644 --- a/addons/common/functions/fnc_moduleCheckPBOs.sqf +++ b/addons/common/functions/fnc_moduleCheckPBOs.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -if !(isServer) exitWith {}; - params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf new file mode 100644 index 0000000000..080499d9cf --- /dev/null +++ b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf @@ -0,0 +1,22 @@ +/* + * Author: 654wak654 + * Returns a list of vehicles near given unit that the unit can be a passenger in. + * + * Arguments: + * 0: Unit + * 1: Distance + * + * Return Value: + * Nearest vehicles with a free seat + * + * Example: + * [bob] call ace_common_fnc_nearestVehiclesFreeSeat + * + * Public: Yes + */ +#include "script_component.hpp" + +params ["_unit", ["_distance", 10]]; + +private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance]; +_nearVehicles select {(_x emptyPositions "cargo" > 0) || {_x emptyPositions "gunner" > 0}} diff --git a/addons/common/functions/fnc_numberToDigits.sqf b/addons/common/functions/fnc_numberToDigits.sqf index d9aceb2426..2cedb2a339 100644 --- a/addons/common/functions/fnc_numberToDigits.sqf +++ b/addons/common/functions/fnc_numberToDigits.sqf @@ -1,5 +1,5 @@ /* - * Author: commy2 + * Author: commy2, SilentSpike * Transforms a number to an array of the correspondending digits. * * Arguments: @@ -18,24 +18,6 @@ params ["_number", "_minLength"]; -_number = _number min 999999; -_number = str _number; +_number = [_number min 999999, _minLength] call CBA_fnc_formatNumber; -private _length = count _number; - -if (isNil "_minLength") then {_minLength = _length}; - -_minLength = _minLength min 6; - -while {_length < _minLength} do { - _number = "0" + _number; - _length = _length + 1; -}; - -private _digits = []; - -for "_x" from 0 to (_length - 1) do { - _digits pushBack parseNumber (_number select [_x, 1]); -}; - -_digits +(_number splitString "") apply { parseNumber _x } diff --git a/addons/common/functions/fnc_numberToDigitsString.sqf b/addons/common/functions/fnc_numberToDigitsString.sqf index 9f19cfe3dc..3b54a4cf0c 100644 --- a/addons/common/functions/fnc_numberToDigitsString.sqf +++ b/addons/common/functions/fnc_numberToDigitsString.sqf @@ -16,20 +16,6 @@ */ #include "script_component.hpp" -params ["_number", "_minLength"]; +ACE_DEPRECATED(QFUNC(numberToDigitsString),"3.14.0","CBA_fnc_formatNumber"); -_number = _number min 999999; -_number = str _number; - -private _length = count _number; - -if (isNil "_minLength") then {_minLength = _length}; - -_minLength = _minLength min 6; - -while {_length < _minLength} do { - _number = "0" + _number; - _length = _length + 1; -}; - -_number +_this call CBA_fnc_formatNumber diff --git a/addons/common/functions/fnc_playConfigSound3D.sqf b/addons/common/functions/fnc_playConfigSound3D.sqf index 2631c30d06..fde3848cf8 100644 --- a/addons/common/functions/fnc_playConfigSound3D.sqf +++ b/addons/common/functions/fnc_playConfigSound3D.sqf @@ -1,38 +1,43 @@ /* * Author: esteldunedain - * Plays a sound defined in CfgSounds using playSound3D, with global effect + * Plays a sound defined in CfgSounds using playSound3D, with global effect. * * Arguments: * 0: Sound class * 1: Position ASL - * 2: Volume - * 3: Distance + * 2: Volume (default: from sound config) + * 3: Distance (default: from sound config) * * Return Value: * None * * Example: - * ["sound", [0,0,0], 5, 5] call ace_common_fnc_playConfigSound3D + * ["hint", getPosASL player, 5, 5] call ace_common_fnc_playConfigSound3D * * Public: Yes */ -#define DEBUG_MODE_FULL #include "script_component.hpp" params ["_soundClass", "_posASL", "_volume", "_distance"]; -private _cfgSound = configFile >> "CfgSounds" >> _soundClass; - -if (!isClass _cfgSound) exitWith { - ERROR_1("CfgSounds class [%1] does not exist", _soundClass); +private _sound = getArray (configFile >> "CfgSounds" >> _soundClass >> "sound"); +if (_sound isEqualTo []) exitWith { + ERROR_1("CfgSounds class [%1] does not exist or contains empty sound array", _soundClass); }; +TRACE_2("sound",_soundClass,_sound); + +_sound params ["_fileName", "_cfgVolume", "_pitch", ["_cfgDistance", 0]]; + +ISNILS(_volume,_cfgVolume); +ISNILS(_distance,_cfgDistance); -private _args = getArray (_cfgSound >> "sound"); -TRACE_1("playConfigSound3D args", _args); -private _pitch = (_args select 2); // Strip the first \ from the filename -private _fileName = _args select 0; -_fileName = _fileName select [1, count _fileName - 1]; -TRACE_1("playConfigSound3D filename", _fileName); +_fileName = _fileName select [1]; + +// add file extension .wss as default +if !(toLower (_fileName select [count _fileName - 4]) in [".wav", ".ogg", ".wss"]) then { + ADD(_fileName,".wss"); +}; +TRACE_5("vars",_fileName,_posASL,_volume,_pitch,_distance); playSound3D [_fileName, objNull, false, _posASL, _volume, _pitch, _distance]; diff --git a/addons/common/functions/fnc_readSettingFromModule.sqf b/addons/common/functions/fnc_readSettingFromModule.sqf index 21e7dc7e4b..0e40f55412 100644 --- a/addons/common/functions/fnc_readSettingFromModule.sqf +++ b/addons/common/functions/fnc_readSettingFromModule.sqf @@ -1,7 +1,7 @@ /* * Author: esteldunedain * Reads a setting value from a module, set it and force it. Logs if the setting is missing from the module. - * Must be called on the server, effect is global. + * Must be called on all machines!!!!!!! * * Arguments: * 0: Module @@ -16,12 +16,16 @@ * * Public: No */ +#define DEBUG_MODE_FULL #include "script_component.hpp" -if !(isServer) exitWith {}; - params ["_logic", "_settingName", "_moduleVariable"]; +// Check if the variable is already defined +if (isNil _settingName) exitWith { + ERROR_1("readSettingFromModule - param [%1] is not an ace_setting", _settingName); +}; + // Check if the parameter is defined in the module if (isNil {_logic getVariable _moduleVariable}) exitWith { WARNING_2("Warning in %1 module: %2 setting is missing. Probably an obsolete version of the module is used in the mission.",typeOf _logic,_moduleVariable); @@ -37,5 +41,10 @@ if (_value isEqualTo -1) then { }; }; -// Set the setting globally and force it -[_settingName, _value, true, true] call FUNC(setSetting); +if ([_settingName, "mission"] call CBA_settings_fnc_isForced) then { + WARNING_1("Setting [%1] - Already Forced",_settingName); +}; + +// Set the setting as a mission setting and force it +TRACE_2("setSettingMission from module",_settingName,_value); +["CBA_settings_setSettingMission", [_settingName, _value, true]] call CBA_fnc_localEvent; diff --git a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf index 5faf1f52cf..d80bd92fb4 100644 --- a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf +++ b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf @@ -14,6 +14,7 @@ * * Public: No */ +#define DEBUG_MODE_FULL #include "script_component.hpp" //paramsArray is a normal variable not a command @@ -35,29 +36,32 @@ TRACE_1("Reading missionConfigFile params",_paramsArray); ERROR_1("readSettingsFromParamsArray - param [%1] is not an ace_setting", _settingName); }; - private _settingData = [_settingName] call FUNC(getSettingData); - _settingData params ["", "_typeName", "", "", "", "", "_isForced"]; - - // Check if it's already forced and quit - if (_isForced) exitWith {WARNING_1("readSettingsFromParamsArray - param [%1] is already set and forced", _settingName);}; - // The setting is not forced, so update the value // Read entry and cast it to the correct type from the existing variable + (cba_settings_default getVariable [_settingName, []]) params ["", "", ["_settingType", ""]]; private _validValue = false; switch (true) do { - case (_typeName == "SCALAR"): {_validValue = true;}; - case (_typeName == "BOOL"): { - _settingValue = _settingValue > 0; - _validValue = true; + case (_settingType == "LIST"); + case (_settingType == "SCALAR"): { + _validValue = [_settingName, _settingValue] call CBA_settings_fnc_check; }; - //TODO: Handle ARRAY,COLOR,STRING??? (bool/scalar covers most important settings) + case (_settingType == "CHECKBOX"): { + _settingValue = _settingValue > 0; + _validValue = [_settingName, _settingValue] call CBA_settings_fnc_check; + }; + // Will not Handle ARRAY,COLOR,STRING??? (bool/scalar covers most important settings) }; if (!_validValue) exitWith { - WARNING_3("readSettingsFromParamsArray - param [%1] type not valid [%2] - expected type [%3]", _settingName,_settingValue,_typeName); + WARNING_3("readSettingsFromParamsArray - param [%1] type not valid [%2] - expected type [%3]", _settingName,_settingValue,_settingType); }; - // Update the variable globaly and Force - [_settingName, _settingValue, true, true] call FUNC(setSetting); + if ([_settingName, "mission"] call CBA_settings_fnc_isForced) then { + WARNING_1("Setting [%1] - Already Forced",_settingName); + }; + + // Set the setting as a mission setting and force it + private _return = ["CBA_settings_setSettingMission", [_settingName, _settingValue, true]] call CBA_fnc_localEvent; + TRACE_3("setSettingMission from paramsArray",_settingName,_settingValue,_return); }; } forEach _paramsArray; diff --git a/addons/common/functions/fnc_runTests.sqf b/addons/common/functions/fnc_runTests.sqf new file mode 100644 index 0000000000..538f321765 --- /dev/null +++ b/addons/common/functions/fnc_runTests.sqf @@ -0,0 +1,48 @@ +/* + * Author: PabstMirror + * Run test functions. + * + * Arguments: + * 0: Specific test to run (default is to run all) (default: #all) + * + * Return Value: + * None + * + * Example: + * [] call ace_common_fnc_runTests + * ["fcs"] call ace_common_fnc_runTests + * + * Public: Yes + */ +#include "script_component.hpp" + +params [["_specificTest", "#all", [""]]]; + +private _startTime = diag_tickTime; +private _fails = []; +private _total = 0; + +INFO_1("ace_common_fnc_runTests starting for [%1]", _specificTest); + +{ + private _testName = configName _x; + if ((_specificTest == "#all") || {_specificTest == _testName}) then { + _total = _total + 1; + private _testFile = getText _x; + diag_log text format ["----- Starting Testing %1 [%2] -----", _testName, _testFile]; + private _return = ([nil] apply (compile preProcessFileLineNumbers _testFile)) select 0; + if ((isNil "_return") || {!(_return isEqualTo true)}) then { + systemChat format ["Test [%1] Failed", _testName]; + diag_log text format ["----- Finished Testing %1 [Failed] -----", _testName]; + _fails pushBack _testName; + } else { + diag_log text format ["----- Finished Testing %1 [Passed] -----", _testName]; + }; + }; +} forEach (configProperties [configFile >> "ACE_Tests"]); + +INFO_1("ace_common_fnc_runTests finished in %1 ms", (1000 * (diag_tickTime - _startTime)) toFixed 1); +INFO_2("[%1 / %2] Tests Passed", (_total - (count _fails)), _total); +if (!(_fails isEqualTo [])) then { + INFO_1("Failed: %1", _fails); +}; diff --git a/addons/common/functions/fnc_setHearingCapability.sqf b/addons/common/functions/fnc_setHearingCapability.sqf index 5b1e7a5a3a..5cfe81cc16 100644 --- a/addons/common/functions/fnc_setHearingCapability.sqf +++ b/addons/common/functions/fnc_setHearingCapability.sqf @@ -47,7 +47,9 @@ if (!_exists && _add) then { // in game sounds 0 fadeSound _lowestVolume; 0 fadeRadio _lowestVolume; -0 fadeMusic _lowestVolume; +if (GVAR(allowFadeMusic)) then { + 0 fadeMusic _lowestVolume; +}; // Set Radio mod variables. ACE_player setVariable ["tf_globalVolume", _lowestVolume]; diff --git a/addons/common/functions/fnc_setSetting.sqf b/addons/common/functions/fnc_setSetting.sqf index fc2dc92339..1d98f613fd 100644 --- a/addons/common/functions/fnc_setSetting.sqf +++ b/addons/common/functions/fnc_setSetting.sqf @@ -18,68 +18,19 @@ * * Public: No */ +#define DEBUG_MODE_FULL #include "script_component.hpp" params ["_name", "_value", ["_force", false], ["_broadcastChanges", false]]; +TRACE_4("setSetting",_name,_value,_force,_broadcastChanges); -private _settingData = [_name] call FUNC(getSettingData); - -// Exit if the setting does not exist -if (_settingData isEqualTo []) exitWith { - ERROR_1("SetSetting [%1] setting does not exist", _name); +if (!isServer) exitWith {}; +if (!_broadcastChanges) exitWith { + ERROR_1("Setting [%1] - SetSetting no longer supports non-global settings",_name); }; -_settingData params ["", "_typeName", "_isClientSetable", "", "", "", "_isForced"]; - -// Exit if the setting is already forced -if (_isForced) exitWith { - INFO_1("SetSetting [%1] Trying to set forced setting", _name); +if ([_settingName, "mission"] call CBA_settings_fnc_isForced) then { + WARNING_1("Setting [%1] - Already mission forced - Ignoring",_settingName); }; -//This does NOT broadcast changes to GVAR(settings), so clients would not get updated force status -if ((missionNamespace getVariable [QEGVAR(modules,serverModulesRead), false]) && {!(_isForced isEqualTo _force)}) then { - WARNING_3("SetSetting [%1] attempting to broadcast a change to force (%2 to %3)", _name, _isForced, _force); -}; - -// If the type is not equal, try to cast it -private _failed = false; -if (typeName _value != _settingData select 1) then { - _failed = true; - if ((_typeName == "BOOL") && {_value isEqualType 0}) then { - // If value is not 0 or 1 consider it invalid and don't set anything - if (_value isEqualTo 0) then { - _value = false; - _failed = false; - }; - if (_value isEqualTo 1) then { - _value = true; - _failed = false; - }; - }; - if ((_typeName == "COLOR") && {_value isEqualType []}) then { - _failed = false; - }; -}; - -if (_failed) exitWith {ERROR_3("SetSetting [%1] bad data type expected %2 got %3", _name, _typeName, typeName _value);}; - -// Force it if it was required -_settingData set [6, _force]; - -// Exit if the value didn't change -if (_value isEqualTo (missionNamespace getVariable _name)) exitWith {}; - -// Update the variable -TRACE_2("Variable Updated",_name,_value); -missionNamespace setVariable [_name, _value]; - -if (isServer && {_broadcastChanges}) then { - // Publicize the new value - publicVariable _name; - - // Raise event globally, this publicizes eventual changes in _force status so clients can update it locally - ["ace_settingChanged", [_name, _value, _force]] call CBA_fnc_globalEvent; -} else { - // Raise event locally - ["ace_settingChanged", [_name, _value, _force]] call CBA_fnc_localEvent; -}; +[QGVAR(setSetting), [_name, _value], (format [QGVAR(setSetting_%1), _name])] call CBA_fnc_globalEventJIP; diff --git a/addons/common/functions/fnc_setSettingFromConfig.sqf b/addons/common/functions/fnc_setSettingFromConfig.sqf deleted file mode 100644 index 6308438ac8..0000000000 --- a/addons/common/functions/fnc_setSettingFromConfig.sqf +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Author: esteldunedain - * Load a setting from config if it was not previosuly forced. Force if neccesary. - * - * Arguments: - * 0: Config entry - * - * Return Value: - * None - * - * Example: - * [CONFIG] call ace_common_fnc_setSettingFromConfig - * - * Public: No - */ -#include "script_component.hpp" - -params ["_optionEntry"]; - -private _fnc_getValueWithType = { - params ["_optionEntry", "_typeName"]; - - private _valueConfig = (_optionEntry >> "value"); - private _value = if (isNumber (_optionEntry >> "value")) then {getNumber (_optionEntry >> "value")} else {0}; - TRACE_3("_fnc_getValueWithType:", configName _optionEntry, _typeName, _value); - if (_typeName == "BOOL") exitWith { - _value > 0 - }; - if (_typeName == "STRING") exitWith { - getText (_optionEntry >> "value") - }; - if (_typeName == "ARRAY") exitWith { - getArray (_optionEntry >> "value") - }; - if (_typeName == "COLOR") exitWith { - getArray (_optionEntry >> "value") - }; - _value -}; - -private _name = configName _optionEntry; - -// Check if the variable is already defined -if (isNil _name) then { - // That setting was not loaded yet - - // Get type from config - private _typeName = getText (_optionEntry >> "typeName"); - if (_typeName == "") then { - _typeName = "SCALAR"; - }; - - // Read entry and cast it to the correct type - private _value = [_optionEntry, _typeName] call _fnc_getValueWithType; - - // Init the variable - missionNamespace setVariable [_name, _value]; - - // Add the setting to a list on the server - // Set the variable to not forced - /*private _settingData = [ - name, - typeName, - isClientSettable, - localizedName, - localizedDescription, - possibleValues, - isForced, - defaultValue, - category - ];*/ - private _settingData = [ - _name, - _typeName, - (getNumber (_optionEntry >> "isClientSettable")) > 0, - "", //getText (_optionEntry >> "displayName"), //No need to broadcast, handeled by fnc_loadSettingsLocalizedText - "", //getText (_optionEntry >> "description"), //No need to broadcast, handeled by fnc_loadSettingsLocalizedText - [], //getArray (_optionEntry >> "values"), //No need to broadcast, handeled by fnc_loadSettingsLocalizedText - getNumber (_optionEntry >> "force") > 0, - _value, - "" //getText (_optionEntry >> "category") //No need to broadcast, handeled by fnc_loadSettingsLocalizedText - ]; - - //Strings in the values array won't be localized from the config, so just do that now: - /*private _values = _settingData select 5; - - { - private _text = _x; - if (((typeName _text) == "STRING") && {(count _text) > 1} && {(_text select [0,1]) == "$"}) then { - _text = localize (_text select [1, ((count _text) - 1)]); //chop off the leading $ - _values set [_forEachIndex, _text]; - }; - } forEach _values;*/ - - - GVAR(settings) pushBack _settingData; - -} else { - // The setting already exists. - - // Check if it's already forced and quit - private _settingData = [_name] call FUNC(getSettingData); - if (_settingData select 6) exitWith {}; - - // The setting is not forced, so update the value - - // Read entry and cast it to the correct type from the existing variable - private _value = [_optionEntry, _settingData select 1] call _fnc_getValueWithType; - - // Update the variable - missionNamespace setVariable [_name, _value]; - - // Force the setting if requested - if (getNumber (_optionEntry >> "force") > 0) then { - _settingData set [6, true]; - }; -}; diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index 7c91ab3592..4fe088d3a8 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -1,11 +1,11 @@ /* * Author: PabstMirror - * Allows multiple sources to not overwrite showHud command - * Bitwise AND Logic (a single false in a mask will make it false) + * Allows multiple sources to not overwrite showHud command. + * Bitwise AND Logic (a single false in a mask will make it false). * * Arguments: - * 0: Source ID - * 1: Show Hud Bool Array (8 to set, empty to remove) + * 0: Source ID (default: "") + * 1: Show Hud Bool Array (8 to set, empty to remove) (default: []) * - [hud, info, radar, compass, direction, menu, group, cursors] * - hud: Boolean - show scripted HUD (same as normal showHUD true/false) * - info: Boolean - show vehicle + soldier info (hides weapon info from the HUD as well) diff --git a/addons/common/functions/fnc_statusEffect_set.sqf b/addons/common/functions/fnc_statusEffect_set.sqf index 4908da5395..27824cfe2e 100644 --- a/addons/common/functions/fnc_statusEffect_set.sqf +++ b/addons/common/functions/fnc_statusEffect_set.sqf @@ -16,7 +16,6 @@ * * Public: Yes */ -// #define DEBUG_MODE_FULL #include "script_component.hpp" params [["_object", objNull, [objNull]], ["_effectName", "", [""]], ["_ID", "", [""]], ["_set", true, [false]]]; @@ -32,7 +31,7 @@ if (isNull _object) exitWith {TRACE_1("null",_object);}; [_object, true] call FUNC(statusEffect_resetVariables); //Check for mismatch, and set object ref -//check ID case and set globaly if not already set: +//check ID case and set globally if not already set: _ID = toLower _ID; private _statusReasons = missionNamespace getVariable [(format [QGVAR(statusEffects_%1), _effectName]), []]; private _statusIndex = _statusReasons find _ID; @@ -62,9 +61,13 @@ if (_set isEqualTo (_effectBoolArray select _statusIndex)) exitWith { TRACE_2("Setting to new value",_set,_effectBoolArray select _statusIndex); _effectBoolArray set [_statusIndex, _set]; -_effectNumber = _effectBoolArray call FUNC(toBitmask); //Convert array back to number +private _newEffectNumber = _effectBoolArray call FUNC(toBitmask); //Convert array back to number -TRACE_2("Saving globaly",_effectVarName,_effectNumber); -_object setVariable [_effectVarName, _effectNumber, true]; +TRACE_2("Saving globally",_effectVarName,_newEffectNumber); +_object setVariable [_effectVarName, _newEffectNumber, true]; -[_object, _effectName] call FUNC(statusEffect_sendEffects); +if (_effectNumber == 0 || {_newEffectNumber == 0}) then { + [_object, _effectName] call FUNC(statusEffect_sendEffects); +} else { + LOG("not sending more than once"); +}; diff --git a/addons/common/functions/fnc_stringRemoveWhiteSpace.sqf b/addons/common/functions/fnc_stringRemoveWhiteSpace.sqf deleted file mode 100644 index 51d43d71a9..0000000000 --- a/addons/common/functions/fnc_stringRemoveWhiteSpace.sqf +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Author: Glowbal - * Removes whitespace from a string. - * - * Arguments: - * 0: String - * - * Return Value: - * String Without Whitespace - * - * Example: - * _stringWithoutWhitespace = ["String with whitespace"] call ace_common_fnc_stringRemoveWhiteSpace - * - * Public: Yes - */ -#include "script_component.hpp" - -params ["_string"]; - -ACE_DEPRECATED(QFUNC(stringRemoveWhiteSpace),"3.10.0","CBA_fnc_removeWhitespace"); - -(_string splitString " ") joinString "" diff --git a/addons/common/functions/fnc_switchPersistentLaser.sqf b/addons/common/functions/fnc_switchPersistentLaser.sqf new file mode 100644 index 0000000000..5ba9d5ce05 --- /dev/null +++ b/addons/common/functions/fnc_switchPersistentLaser.sqf @@ -0,0 +1,65 @@ +/* + * Author: Dystopian + * Controls persistent laser state. + * + * Arguments: + * 0: Enabled + * + * Return Value: + * None + * + * Example: + * true call ace_common_fnc_switchPersistentLaser + * + * Public: No + */ +#include "script_component.hpp" + +params ["_enabled"]; + +if (!_enabled) exitWith { + if (isNil QGVAR(laserKeyDownEH)) exitWith {}; + ["KeyDown", GVAR(laserKeyDownEH)] call CBA_fnc_removeDisplayHandler; + ["weapon", GVAR(laserWeaponEH)] call CBA_fnc_removePlayerEventHandler; + ["turret", GVAR(laserTurretEH)] call CBA_fnc_removePlayerEventHandler; + ["vehicle", GVAR(laserVehicleEH)] call CBA_fnc_removePlayerEventHandler; +}; + +GVAR(laserKeyDownEH) = ["KeyDown", { + if !((_this select 1) in actionKeys "headlights") exitWith {false}; + private _weapon = currentWeapon ACE_player; + [ + { + params ["_weapon", "_laserWasEnabled"]; + private _laserEnabled = ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon}; + if (_laserEnabled && {_laserWasEnabled} || {!_laserEnabled && {!_laserWasEnabled}}) exitWith {}; + private _weaponIndex = [ACE_player, _weapon] call FUNC(getWeaponIndex); + ACE_player setVariable [QGVAR(laserEnabled_) + str _weaponIndex, [nil, true] select _laserEnabled]; + }, + [_weapon, ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon}] + ] call CBA_fnc_execNextFrame; + false +}] call CBA_fnc_addDisplayHandler; + +private _laserEH = { + if (sunOrMoon > 0.5) exitWith {}; + params ["_player"]; + private _weaponIndex = [_player, currentWeapon _player] call FUNC(getWeaponIndex); + if ( + !(_player getVariable [QGVAR(laserEnabled_) + str _weaponIndex, false]) + || {_weaponIndex > 0 && {"" != primaryWeapon _player}} // Arma switches to primary weapon if exists + || {!(_player call CBA_fnc_canUseWeapon)} // ignore in vehicle except FFV + ) exitWith {}; + [ + // wait for weapon in "ready to fire" direction + {0.01 > getCameraViewDirection _this vectorDistance (_this weaponDirection currentWeapon _this)}, + {{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]}, + _player, + 3, + {{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]} + ] call CBA_fnc_waitUntilAndExecute; +}; + +GVAR(laserWeaponEH) = ["weapon", _laserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserTurretEH) = ["turret", _laserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserVehicleEH) = ["vehicle", _laserEH] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/common/functions/fnc_unloadPersonLocal.sqf b/addons/common/functions/fnc_unloadPersonLocal.sqf index ed5b8dc020..762b643bc1 100644 --- a/addons/common/functions/fnc_unloadPersonLocal.sqf +++ b/addons/common/functions/fnc_unloadPersonLocal.sqf @@ -3,12 +3,12 @@ * Unload a person from a vehicle, local * * Arguments: - * 0: unit to unload + * 0: Unit to unload * 1: Vehicle - * 2: Unloader (player) + * 2: Unloader (player) (default: objNull) * * Return Value: - * Returns true if succesfully unloaded person + * Succesfully unloaded person * * Example: * [bob, car, bob] call ace_common_fnc_unloadpersonLocal diff --git a/addons/common/functions/fnc_watchVariable.sqf b/addons/common/functions/fnc_watchVariable.sqf index 300a5ef195..012a726a6c 100644 --- a/addons/common/functions/fnc_watchVariable.sqf +++ b/addons/common/functions/fnc_watchVariable.sqf @@ -1,27 +1,27 @@ /* * Author: PabstMirror - * Shows multiple watched variables on the main display (for easy debugging) + * Shows multiple watched variables on the main display (for easy debugging). * * Arguments: - * 0: Title (var name) - * 1: Code to generate result (passed nothing, can return any) - * 2: Array containing modifiers + * 0: Title (var name) (default: "") + * 1: Code to generate result (passed nothing, can return any) (default: {}) + * 2: Array containing modifiers (default: []) * For Numbers: - * 0: Show Delta change (default: true) - * 1: Slider Min Value (default: 0) - * 1: Slider Max Value (default: 0) + * 0: Show Delta change (default: true) + * 1: Slider Min Value (default: 0) + * 1: Slider Max Value (default: 0) * For Anything else: - * 0: Number of structured text lines (default: 1) + * 0: Number of structured text lines (default: 1) * * Return Value: * None * * Example: - * ["CBA_missionTime"] call ace_common_fnc_watchVariable; // Uses title as code - * ["diag_frameNo", {diag_frameNo}, [false]] call ace_common_fnc_watchVariable; // Won't show delta - * ["blood", {player getVariable "ace_medical_bloodVolume"}, [true, 0, 100]] call ace_common_fnc_watchVariable; // Shows slider - * ["multiLine text", {"Line 1
Line 2"}, [2]] call ace_common_fnc_watchVariable; - * ["player names", {allPlayers apply {name _x}}, [5]] call ace_common_fnc_watchVariable; // handles any data types + * ["CBA_missionTime"] call ace_common_fnc_watchVariable // Uses title as code + * ["diag_frameNo", {diag_frameNo}, [false]] call ace_common_fnc_watchVariable // Won't show delta + * ["blood", {player getVariable "ace_medical_bloodVolume"}, [true, 0, 100]] call ace_common_fnc_watchVariable // Shows slider + * ["multiLine text", {"Line 1
Line 2"}, [2]] call ace_common_fnc_watchVariable + * ["player names", {allPlayers apply {name _x}}, [5]] call ace_common_fnc_watchVariable // handles any data types * * Public: Yes */ diff --git a/addons/common/initSettings.sqf b/addons/common/initSettings.sqf new file mode 100644 index 0000000000..fcaa242ac3 --- /dev/null +++ b/addons/common/initSettings.sqf @@ -0,0 +1,18 @@ +[ + QGVAR(persistentLaserEnabled), + "CHECKBOX", + [LSTRING(SettingPersistentLaserName), LSTRING(SettingPersistentLaserDesc)], + localize LSTRING(ACEKeybindCategoryWeapons), + false, + false, + LINKFUNC(switchPersistentLaser) +] call CBA_settings_fnc_init; + +[ + QGVAR(allowFadeMusic), + "CHECKBOX", + [LSTRING(AllowFadeMusic), LSTRING(AllowFadeMusicTooltip)], + localize LSTRING(ACEKeybindCategoryCommon), + true, + true +] call CBA_settings_fnc_init; diff --git a/addons/common/script_component.hpp b/addons/common/script_component.hpp index 66f7ac63bf..9eb8af601f 100644 --- a/addons/common/script_component.hpp +++ b/addons/common/script_component.hpp @@ -32,3 +32,5 @@ "lino_exp", "int_lino_exp", "int_mat_exp", \ "wood", "wood_int", "int_wood", "softwood_exp", "int_softwood_exp", "int_solidwood_exp" \ ] + +#define DIG_SURFACE_WHITELIST ["grass", "grasstall_exp", "forest_exp"] diff --git a/addons/common/scripts/checkVersionNumber.sqf b/addons/common/scripts/checkVersionNumber.sqf index f407ed57b0..b4858d38bf 100644 --- a/addons/common/scripts/checkVersionNumber.sqf +++ b/addons/common/scripts/checkVersionNumber.sqf @@ -1,9 +1,7 @@ // by commy2 #include "script_component.hpp" -private ["_client", "_clientVersion", "_count", "_error", "_files", "_index", "_missingAddon", "_missingAddonServer", "_missingAddons", "_missingAddonsServer", "_oldVersionClient", "_oldVersionServer", "_oldVersionsClient", "_oldVersionsServer", "_serverFiles", "_serverVersion", "_serverVersions", "_string", "_version", "_versions"]; - -_files = []; +private _files = []; { if (_x find "a3_" != 0 && {_x find "ace_" != 0} && {!(toLower _x in (missionNamespace getVariable ["ACE_Version_Whitelist", []]))}) then { @@ -11,9 +9,9 @@ _files = []; }; } forEach activatedAddons; -_versions = []; +private _versions = []; { - _version = parseNumber getText (configFile >> "CfgPatches" >> _x >> "version"); + private _version = parseNumber getText (configFile >> "CfgPatches" >> _x >> "version"); _versions set [_forEachIndex, _version]; } forEach _files; @@ -32,27 +30,27 @@ if (!isServer) then { !isNil "ACE_Version_ClientVersions" && {!isNil "ACE_Version_ServerVersions"} }; - _client = profileName; + private _client = profileName; _files = ACE_Version_ClientVersions select 0; _versions = ACE_Version_ClientVersions select 1; - _serverFiles = ACE_Version_ServerVersions select 0; - _serverVersions = ACE_Version_ServerVersions select 1; + private _serverFiles = ACE_Version_ServerVersions select 0; + private _serverVersions = ACE_Version_ServerVersions select 1; // Compare client and server files and versions - _missingAddons = []; - _oldVersionsClient = []; - _oldVersionsServer = []; + private _missingAddons = []; + private _oldVersionsClient = []; + private _oldVersionsServer = []; { - _serverVersion = _serverVersions select _forEachIndex; + private _serverVersion = _serverVersions select _forEachIndex; - _index = _files find _x; + private _index = _files find _x; if (_index == -1) then { if (_x != "ace_server") then {_missingAddons pushBack _x;}; } else { - _clientVersion = _versions select _index; + private _clientVersion = _versions select _index; if (_clientVersion < _serverVersion) then { _oldVersionsClient pushBack [_x, _clientVersion, _serverVersion]; @@ -65,9 +63,9 @@ if (!isServer) then { } forEach _serverFiles; // find client files which the server doesn't have - _missingAddonsServer = []; + private _missingAddonsServer = []; { - _index = _serverFiles find _x; + private _index = _serverFiles find _x; if (_index == -1) then { _missingAddonsServer pushBack _x; } @@ -75,10 +73,10 @@ if (!isServer) then { // display and log error messages private _fnc_cutComma = { - _string = _this; + private _string = _this; _string = toArray _string; - _count = count _string; + private _count = count _string; _string set [_count - 2, toArray "." select 0]; _string set [_count - 1, -1]; _string = _string - [-1]; @@ -86,11 +84,11 @@ if (!isServer) then { toString _string; }; - _missingAddon = false; + private _missingAddon = false; if (count _missingAddons > 0) then { _missingAddon = true; - _error = format ["[ACE] %1: ERROR missing addon(s): ", _client]; + private _error = format ["[ACE] %1: ERROR missing addon(s): ", _client]; { _error = _error + format ["%1, ", _x]; @@ -103,11 +101,11 @@ if (!isServer) then { [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; }; - _missingAddonServer = false; + private _missingAddonServer = false; if (count _missingAddonsServer > 0) then { _missingAddonServer = true; - _error = format ["[ACE] %1: ERROR missing server addon(s): ", _client]; + private _error = format ["[ACE] %1: ERROR missing server addon(s): ", _client]; { _error = _error + format ["%1, ", _x]; @@ -120,11 +118,11 @@ if (!isServer) then { [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; }; - _oldVersionClient = false; + private _oldVersionClient = false; if (count _oldVersionsClient > 0) then { _oldVersionClient = true; - _error = format ["[ACE] %1: ERROR outdated addon(s): ", _client]; + private _error = format ["[ACE] %1: ERROR outdated addon(s): ", _client]; { _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; @@ -137,11 +135,11 @@ if (!isServer) then { [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; }; - _oldVersionServer = false; + private _oldVersionServer = false; if (count _oldVersionsServer > 0) then { _oldVersionServer = true; - _error = format ["[ACE] %1: ERROR outdated server addon(s): ", _client]; + private _error = format ["[ACE] %1: ERROR outdated server addon(s): ", _client]; { _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index 94c723567f..bbf71c4eea 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -1,6 +1,15 @@ - + + + Common + Allgemein + Comuni + 全般 + 通用 + 通用 + 일반 + ACE-Team ACE-Team @@ -12,7 +21,7 @@ ACE-Team ACE-Team ACE-Team - ACE-Team + ACE-チーム ACE-Team ACE-製作團隊 ACE-制作团队 @@ -349,7 +358,7 @@ [ACE] Itens diversos [ACE] Egyéb tárgyak [ACE] Oggetti vari - [ACE] その他のアイテム + [ACE] その他アイテム [ACE] 기타 물품. [ACE] 雜項 [ACE] 杂项 @@ -447,8 +456,8 @@ Aceitar pedidos enviados por outros jogadores. Podem ser pedidos para usar/ compartilhar equipamento, realizar certas ações. 他プレイヤからの要求を許可します。他プレイヤは装備を共有し、使うなど特定の動作を行えます。 다른 플레이어가 보내온 요청을 수락합니다. 이것은 장비 사용 / 공유 요청, 특정 작업 수행 등이 될 수 있습니다. - 接受由其他玩家送出的請求. 包含使用/共享裝備與執行特定動作 - 接受由其他玩家送出的请求. 包含使用/共享装备与执行特定动作 + 接受由其他玩家送出的請求。包含使用/共享裝備與執行特定動作。 + 接受由其他玩家送出的请求。包含使用/共享装备与执行特定动作。 Decline Requests send by other players. These can be requests to use / share equipment, perform certain actions. @@ -463,8 +472,32 @@ Rejeita pedidos enviados por outros jogadores. Podem ser pedidos para usar/ compartilhar equipamento, realizar certas ações. 他プレイヤからの要求を拒否します。他プレイヤは装備を共有し、使うなど特定の動作をできません。 다른 플레이어가 보내온 요청을 거부합니다. 이것은 장비 사용 / 공유 요청, 특정 작업 수행 등이 될 수 있습니다. - 拒絕由其他玩家送出的請求. 包含使用/共享裝備與執行特定動作 - 拒绝由其他玩家送出的请求. 包含使用/共享装备与执行特定动作 + 拒絕由其他玩家送出的請求。包含使用/共享裝備與執行特定動作。 + 拒绝由其他玩家送出的请求。包含使用/共享装备与执行特定动作。 + + + Check PBO Action + Controlla Azioni PBO + 檢查PBO動作 + 检查PBO动作 + PBO 検査の挙動 + PBO 검사 + + + Check PBO All + Controlla Tutti i PBO + 檢查所有PBO + 检查所有PBO + PBO 全てを検査 + 모든 PBO 검사 + + + Check PBO Whitelist + Controlla Whitelist PBO + 檢查PBO白名單 + 检查PBO白名单 + 許可リスト内の PBO を検査 + 검사 제외 PBO Feedback icons @@ -495,8 +528,8 @@ Selecione a posição ou disabilite a posição dos ícones de feedback na sua tela. Esses ícones irão aparecer para mostrar feedback extra do status do seu personagem e ações realizadas. 画面上に表示するフィードバック アイコンの位置や無効化を選択できます。このアイコンは自キャラクター状態や動作の状況をフィードバックするために表示されています。 피드백 아이콘의 위치를 설정하거나 비활성화합니다. 피드백 아이콘은 캐릭터의 상세정보와 행동을 보여줍니다. - 選擇位置或取消回饋圖標顯示在螢幕上. 這些圖標將顯示出你角色額外的狀態與行動等資訊. - 选择位置或取消回馈图标显示在荧幕上. 这些图标将显示出你角色额外的状态与行动等资讯. + 選擇位置或取消回饋圖標顯示在螢幕上。這些圖標將顯示出你角色額外的狀態與行動等資訊。 + 选择位置或取消回馈图标显示在荧幕上。这些图标将显示出你角色额外的状态与行动等资讯。 Progress bar location @@ -580,7 +613,7 @@ The color of the text font from the ACE hints. This color is the default color for all text displayed through the ACE Hint system, if the hint text has no other color specified. - Wähle die Textfarbe für ACE-Hinweise. Die gewählte Farbe wird als Standartfarbe der Hinweise angezeigt, wenn der Hinweis selbst keine spezifische Farbe hat. + Wähle die Textfarbe für ACE-Hinweise. Die gewählte Farbe wird als Standardfarbe der Hinweise angezeigt, wenn der Hinweis selbst keine spezifische Farbe hat. El color del texto de las notificaciones del ACE. Este es el color predeterminado para todo el texto que se muestra a través del sistema de notificaciones del ACE, si el texto de notificación no tiene otro color especificado. Il colore del testo dei suggerimenti di ACE. Questo è il colore predefinito per tutto il testo mostrato dal sistema di suggerimenti di ACE quando il colore del testo non ha altro colore specificato. Цвет шрифта текста всплывающих подсказок АСЕ. Этот цвет является стандартным для всего текста, транслирующегося через систему подсказок АСЕ, если не установлено другого цвета для текста подсказок. @@ -591,8 +624,24 @@ A cor do texto das hints do ACE. Essa cor é a cor default para todos os texos exibidos pelo sistema de hints do ACE , caso o texto da hint não tem outra cor especificada. ACE によるヒントの文章へ、色を設定できます。この色は ACE ヒント システムを介して表示される全文章の色と標準でなっており、特定の色を設定していても、標準色になります。 ACE 힌트에 쓰이는 글씨 색입니다. 힌트 글씨의 색이 정해지지 않을경우 모든 힌트의 색은 기본으로 설정됩니다. - 設定ACE提示文字的顏色. 若提示字體並無指定其他顏色, 將會自動選用ACE系統的預設顏色 - 设定ACE提示文字的颜色. 若提示字体并无指定其他颜色, 将会自动选用ACE系统的预设颜色 + 設定ACE提示文字的顏色。若提示字體並無指定其他顏色,將會自動選用ACE系統的預設顏色。 + 设定ACE提示文字的颜色。若提示字体并无指定其他颜色,将会自动选用ACE系统的预设颜色。 + + + Persistent weapon laserpointer/flashlight + Автоматический ЛЦУ/тактический фонарь + 武器のレーザー ポインタ/フラッシュライトの永続 + Laser/torcia dell'arma costantemente accesi + 무기 레이저 포인터 / 손전등 지속 + Kontinuität des Laserpointers/Taktischen Lichts + + + Enable gunlight after weapon switch or vehicle enter/exit if it was previously enabled. + Включать ЛЦУ/тактический фонарь после смены оружия или входа/выхода из машины, если он был до этого включен. + 銃のライト等を点けていると武器を切り替えた後や車両を乗り降りしても、ライト等を点けたままにします。 + Abilita la torcia/laser dopo il cambio dell'arma o l'entrata/uscita del veicolo se precedentemente attiva. + 무기를 바꾸거나 차량에 승하차 할 때 이전에 스위치 켜고 끔을 유지합니다. + Aktiviert Laserpointer/Taktisches Licht nach einem Waffenwechsel oder dem Auf-/Absitzen, falls es zuvor aktiv war. Banana @@ -623,8 +672,8 @@ A banana é uma fruta comestível, botanicamente uma baga, produzida por vários tipos de plantas herbáceas grandes do genero Musa. 甘蕉は食べられる果物でバショウ科バショウ属のうち、果実を食用とする品種群の総称。また、その果実のこと。いくつかの原種から育種された多年草。種によっては熟すまでは毒を持つものもある。 바나나는 식용 과일로써 식물학적으로 열매류이며 여러 종류의 개화가능한 초본의 파초과로 부터 생산됩니다. - 香蕉(學名: Musa × paradisiaca), 為芭蕉科芭蕉屬小果野蕉及野蕉的人工栽培雜交種, 為多年生草本植物. 果實長有棱; 果皮黃色, 果肉白色, 味道香甜. 主要生長在熱帶、亞熱帶地區. 原產於亞洲東南部熱帶、亞熱帶地區. - 香蕉(学名: Musa × paradisiaca), 为芭蕉科芭蕉属小果野蕉及野蕉的人工栽培杂交种, 为多年生草本植物. 果实长有棱; 果皮黄色, 果肉白色, 味道香甜. 主要生长在热带、亚热带地区. 原产于亚洲东南部热带、亚热带地区. + 香蕉(學名: Musa × paradisiaca),為芭蕉科芭蕉屬小果野蕉及野蕉的人工栽培雜交種,為多年生草本植物。果實長有棱; 果皮黃色,果肉白色,味道香甜。主要生長在熱帶、亞熱帶地區。原產於亞洲東南部熱帶、亞熱帶地區。 + 香蕉(学名: Musa × paradisiaca),为芭蕉科芭蕉属小果野蕉及野蕉的人工栽培杂交种,为多年生草本植物。果实长有棱; 果皮黄色,果肉白色,味道香甜。主要生长在热带、亚热带地区。原产于亚洲东南部热带、亚热带地区。 Check PBOs @@ -654,8 +703,8 @@ Controlla l'integrità degli addon con il server ed esegui l'azione selezionata se un addon è mancante サーバがアドオンの整合性を検査し、もし不備があれば実行する動作を選択できます。 서버 에드온의 무결성을 검사하고 사라진 에드온이 있을경우 행동을 선택합니다. - 檢查客戶端與伺服器端的模組清單是否一致且完整, 並提供訊息表示遺失的模組. - 检查客户端与伺服器端的模组清单是否一致且完整, 并提供讯息表示遗失的模组. + 檢查客戶端與伺服器端的模組清單是否一致且完整,並提供訊息表示遺失的模組。 + 检查客户端与伺服器端的模组清单是否一致且完整,并提供讯息表示遗失的模组。 Action @@ -684,10 +733,10 @@ Mi legyen azokkal a személyekkel, akiknek nincsenek meg a helyes PBO-k? Что делать с игроками с неправильными аддонами? Cosa fare con giocatori che non hanno i PBO corretti? - プレイヤーが正しい PBO を持っていない場合は? + プレイヤーが正しい PBO を持っていない場合は? 올바르지 않는 PBO를 가진 사람을 어떻게 할까요? - 若玩家沒有正確的PBO檔時, 將採取何種動作? - 若玩家没有正确的PBO档时, 将采取何种动作? + 若玩家沒有正確的PBO檔時,將採取何種動作? + 若玩家没有正确的PBO档时,将采取何种动作? Warn once @@ -716,7 +765,7 @@ Figyelmeztetés (tartós) Предупреждать (постоянно) Avverti (permanente) - 警告(永久的) + 警告 (永久的) 경고 (영구적) 警告 (持續) 警告 (持续) @@ -764,7 +813,7 @@ Az összes bővítmény ellenőrzése, csak az ACE helyett? Проверять все аддоны, а не только ACE? Controlla tutti gli addon invece dei soli addon ACE? - ACE MOD の代わりに全アドオンを検査しますか? + ACE MOD の代わりに全アドオンを検査しますか? ACE를 제외한 모든 모드를 검사할까요? 檢查包含ACE之外的其他模組? 检查包含ACE之外的其他模组? @@ -796,7 +845,7 @@ Milyen bővítmények vannak feltétlenül engedélyezve? Какие аддоны дополнительно разрешены? Quali addon sono permessi in ogni caso? - どのようなアドオンを許可しますか? + どのようなアドオンを許可しますか? 허가되는 에드온은 어느것입니까? 哪些模組是可被允許/忽略的? 哪些模组是可被允许/忽略的? @@ -830,8 +879,8 @@ Aggiunge effetti LSD ai veicoli sincronizzati 同期されたオブジェクトに LSD の効果を追加します 동기화된 차량에 LSD효과를 추가합니다. - 使被同步的載具產生瘋狂的迷幻效果. (後果自負) - 使被同步的载具产生疯狂的迷幻效果. (后果自负) + 使被同步的載具產生瘋狂的迷幻效果。(後果自負) + 使被同步的载具产生疯狂的迷幻效果。(后果自负) Toggle Handheld Device @@ -974,94 +1023,94 @@ 不要强行 - ACE3 Equipment - ACE-Ausrüstung - ACE3 Wyposażenie - Equipamentos ACE3 - ACE3 Снаряжение - ACE3 Vybavení - ACE3 Equipo - Equipaggiamento ACE3 - ACE3 Equipement - ACE3 装備 - ACE3 장비 - ACE3 裝備按鍵 - ACE3 装备按键 + ACE Equipment + ACE Ausrüstung + ACE Wyposażenie + ACE Equipamentos + ACE Снаряжение + ACE Vybavení + ACE Equipo + ACE Equipaggiamento + ACE Equipement + ACE 装備 + ACE 장비 + ACE 裝備按鍵 + ACE 装备按键 - ACE3 Common - ACE3 Allgemein - ACE3 Ogólne - Comum ACE3 - ACE3 Общие - ACE3 Común - ACE3 Obecné - Comune ACE3 - ACE3 Commun - ACE3 全般 - ACE3 일반 - ACE3 通用按鍵 - ACE3 通用按键 + ACE Common + ACE Allgemein + ACE Ogólne + ACE Comum + ACE Общие + ACE Común + ACE Obecné + ACE Comune + ACE Commun + ACE 全般 + ACE 일반 + ACE 通用按鍵 + ACE 通用按键 - ACE3 Weapons - ACE3 Waffen - ACE3 Broń - Armamento ACE3 - ACE3 Оружие - ACE3 Zbraně - ACE3 Armas - Armi ACE3 - ACE3 Armes - ACE3 武器 - ACE3 무기 - ACE3 武器按鍵 - ACE3 武器按键 + ACE Weapons + ACE Waffen + ACE Broń + ACE Armamento + ACE Оружие + ACE Zbraně + ACE Armas + ACE Armi + ACE Armes + ACE 武器 + ACE 무기 + ACE 武器按鍵 + ACE 武器按键 - ACE3 Movement - ACE3 Bewegung - ACE3 Ruch - Movimento ACE3 - ACE3 Перемещение - ACE3 Movimiento - ACE3 Pohyb - Movimento ACE3 - ACE3 Mouvement - ACE3 移動 - ACE3 움직임 - ACE3 動作按鍵 - ACE3 动作按键 + ACE Movement + ACE Bewegung + ACE Ruch + ACE Movimento + ACE Перемещение + ACE Movimiento + ACE Pohyb + ACE Movimento + ACE Mouvement + ACE 移動 + ACE 움직임 + ACE 動作按鍵 + ACE 动作按键 - ACE3 Scope Adjustment - ACE3 Visiereinstellung - ACE3 Regulacja optyki - Ajuste de luneta ACE3 - ACE3 Прицелы - ACE3 Nastavení optiky - ACE3 Ajuste de miras - Regolazione Ottiche ACE3 - ACE3 Ajustement de la lunette - ACE3 スコープ調節 - ACE3 조준경 조정 - ACE3 瞄準鏡調節按鍵 - ACE3 瞄准镜调节按键 + ACE Scope Adjustment + ACE Visiereinstellung + ACE Regulacja optyki + ACE Ajuste de luneta + ACE Прицелы + ACE Nastavení optiky + ACE Ajuste de miras + ACE Regolazione Ottiche + ACE Ajustement de la lunette + ACE スコープ調節 + ACE 조준경 조정 + ACE 瞄準鏡調節按鍵 + ACE 瞄准镜调节按键 - ACE3 Vehicles - ACE3 Fahrzeuge - ACE3 Pojazdy - Veículos ACE3 - ACE3 Транспорт - ACE3 Vozidla - ACE3 Vehículos - Veicoli ACE3 - ACE3 Vehicules - ACE3 車両 - ACE3 차량 - ACE3 載具按鍵 - ACE3 载具按键 + ACE Vehicles + ACE Fahrzeuge + ACE Pojazdy + ACE Veículos + ACE Транспорт + ACE Vozidla + ACE Vehículos + ACE Veicoli + ACE Vehicules + ACE 車両 + ACE 차량 + ACE 載具按鍵 + ACE 载具按键 No Room to unload @@ -1076,6 +1125,7 @@ 降ろすための空間がありません 沒有空間可卸載 没有空间可卸载 + 언로드 할 공간이 없습니다. Toggle @@ -1088,10 +1138,36 @@ pecek přep. alternar - トグル + 切り替え 토글 切換 切换 + + Weight: + Gewicht: + Peso: + Poids : + Waga: + Váha: + Peso: + Peso: + Súly: + Вес: + 重量: + 무게: + 重量: + 重量: + + + Allow turning down music + Erlaube Musik leiser stellen + 음악 끄기 허용 + + + Allow ACE scripts to turn down the music. + Erlaube ACE-Skripten, die Musik leiser zu stellen. + ACE 스크립트가 음악을 끌 수 있습니다. + diff --git a/addons/concertina_wire/CfgEventHandlers.hpp b/addons/concertina_wire/CfgEventHandlers.hpp index 80711b5390..b0ff603096 100644 --- a/addons/concertina_wire/CfgEventHandlers.hpp +++ b/addons/concertina_wire/CfgEventHandlers.hpp @@ -40,12 +40,12 @@ class Extended_Init_EventHandlers { }; class ACE_ConcertinaWire { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_init)); + init = QUOTE(call FUNC(handleInit)); }; }; class Land_Razorwire_F { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_init)); + init = QUOTE(call FUNC(handleInit)); }; }; }; diff --git a/addons/concertina_wire/XEH_PREP.hpp b/addons/concertina_wire/XEH_PREP.hpp index 34a666a6b9..5fffc24969 100644 --- a/addons/concertina_wire/XEH_PREP.hpp +++ b/addons/concertina_wire/XEH_PREP.hpp @@ -3,5 +3,6 @@ PREP(deploy); PREP(dismount); PREP(dismountSuccess); PREP(handleDamage); +PREP(handleInit); PREP(handleKilled); PREP(vehicleDamage); diff --git a/addons/concertina_wire/XEH_init.sqf b/addons/concertina_wire/XEH_init.sqf deleted file mode 100644 index b24353b4df..0000000000 --- a/addons/concertina_wire/XEH_init.sqf +++ /dev/null @@ -1,3 +0,0 @@ -#include "script_component.hpp" -params ["_wire"]; -_wire addEventHandler ["HandleDamage", {call FUNC(handleDamage)}]; diff --git a/addons/concertina_wire/functions/fnc_deploy.sqf b/addons/concertina_wire/functions/fnc_deploy.sqf index 6dc05b365d..6782f64342 100644 --- a/addons/concertina_wire/functions/fnc_deploy.sqf +++ b/addons/concertina_wire/functions/fnc_deploy.sqf @@ -65,6 +65,7 @@ GVAR(deployPFH) = [{ }, 0, [_wireNoGeo, _wire, _anim, _dir, _wireNoGeoPos]] call CBA_fnc_addPerFrameHandler; [_unit, "DefaultAction", _unit getVariable [QGVAR(Deploy), -1]] call EFUNC(Common,removeActionEventHandler); + [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); call EFUNC(interaction,hideMouseHint); [_idPFH] call CBA_fnc_removePerFrameHandler; @@ -78,6 +79,8 @@ GVAR(deployPFH) = [{ [localize "STR_ACE_ROLLWIRE", "", ""] call EFUNC(interaction,showMouseHint); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + GVAR(placer) setVariable [QGVAR(Deploy), [GVAR(placer), "DefaultAction", {GVAR(deployPFH) != -1}, diff --git a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf index d730fbb4b6..76ee768504 100644 --- a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf +++ b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf @@ -27,12 +27,11 @@ params ["_wire"]; _args params ["_wire"]; if (_wire animationPhase "wire_2" == 1) then { - private ["_dir", "_pos", "_wirecoil"]; - _dir = getDir _wire; - _pos = getPosASL _wire; + private _dir = getDir _wire; + private _pos = getPosASL _wire; - _wirecoil = "ACE_ConcertinaWireCoil" createvehicle [0, 0, 0]; + private _wirecoil = "ACE_ConcertinaWireCoil" createvehicle [0, 0, 0]; deleteVehicle _wire; diff --git a/addons/concertina_wire/functions/fnc_handleInit.sqf b/addons/concertina_wire/functions/fnc_handleInit.sqf new file mode 100644 index 0000000000..d547a09463 --- /dev/null +++ b/addons/concertina_wire/functions/fnc_handleInit.sqf @@ -0,0 +1,18 @@ +/* + * Author: Rocko + * Handles wire Init + * + * Arguments: + * 0: wire + * + * Return Value: + * None + * + * Example: + * [wire] call ace_concertina_wire_fnc_handleInit + * + * Public: No + */ +#include "script_component.hpp" +params ["_wire"]; +_wire addEventHandler ["HandleDamage", {call FUNC(handleDamage)}]; diff --git a/addons/concertina_wire/functions/fnc_vehicleDamage.sqf b/addons/concertina_wire/functions/fnc_vehicleDamage.sqf index 7d84d4b244..dd3504f031 100644 --- a/addons/concertina_wire/functions/fnc_vehicleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_vehicleDamage.sqf @@ -17,10 +17,8 @@ #include "script_component.hpp" params ["_wire", "_vehicle"]; -private ["_type", "_mode", "_anim", "_parts", "_selectionPart", "_selection", "_pos_w", "_dir_w"]; - -_type = typeOf _wire; -_mode = switch (_type) do { +private _type = typeOf _wire; +private _mode = switch (_type) do { case "ACE_ConcertinaWire": { 0 }; case "Land_Razorwire_F": { 1 }; default { -1 }; @@ -38,16 +36,16 @@ if (_mode == -1) exitWith {}; //9.78744 (10) _type = typeOf _wire; -_anim = _wire animationPhase "wire_2"; -_pos_w = getPos _wire; -_dir_w = getDir _wire; +private _anim = _wire animationPhase "wire_2"; +private _pos_w = getPos _wire; +private _dir_w = getDir _wire; if (_mode == 0) then { - private ["_x", "_y", "_found", "_wireCheckPosAr", "_no"]; + private _found = false; _pos_w params ["_x","_y"]; // Check if two Single coils are placed next to each other (i.e playes have built a big wire obstacle) - _wireCheckPosAr = [ + private _wireCheckPosAr = [ [_x + (sin (_dir_w + 90) * 1.5),_y + (cos (_dir_w + 90) * 1.5)], [(_x-(sin _dir_w)) + (sin (_dir_w + 90) * 1.5),(_y-(cos _dir_w)) + (cos (_dir_w + 90) * 1.5)], [_x + (sin (_dir_w - 90) * 1.5),_y + (cos (_dir_w - 90) * 1.5)], @@ -55,7 +53,7 @@ if (_mode == 0) then { ]; { _found = false; - _no = nearestObjects [_x, [typeOf _wire], 3]; //diag_log _no; diag_log "....."; + private _no = nearestObjects [_x, [typeOf _wire], 3]; //diag_log _no; diag_log "....."; _no = _no - [_wire]; //diag_log _no; if (count _no > 0) exitWith { _found = true; //diag_log "found"; @@ -76,6 +74,8 @@ if (_mode == 0) then { }; }; +private _parts = []; + if (_mode == 1) then { switch (true) do { case (_vehicle isKindOf "Tank"): { @@ -95,9 +95,9 @@ if (_mode == 1) then { if (canMove _vehicle) then { { - _selectionPart = "hit" + _x; + private _selectionPart = "hit" + _x; if (isText(configFile >> "CfgVehicles" >> typeOf _vehicle >> "hitpoints" >> _selectionPart >> "name")) then { - _selection = getText(configFile >> "CfgVehicles" >> typeOf _vehicle >> "hitpoints" >> _selectionPart >> "name"); + private _selection = getText(configFile >> "CfgVehicles" >> typeOf _vehicle >> "hitpoints" >> _selectionPart >> "name"); // TODO: Only the tires that have touched the wire should burst. _vehicle setHit [_selection, 1]; }; @@ -107,14 +107,13 @@ if (canMove _vehicle) then { if (_mode == 1) then { if (_vehicle isKindOf "StaticWeapon") exitWith {}; [{ - PARAMS_2(_vehicle,_wire); + params ["_vehicle", "_wire"]; _vehicle setVelocity ((velocity _vehicle) vectorMultiply 0.75); - private ["_vPos", "_vDir"]; // Set vehicle back in front of wire, since the wire will make the vehicle jump, and a wire with no geometry lod is undestructible and not recognizeable - _vPos = getPosASL _vehicle; - _vDir = getDir _vehicle; + private _vPos = getPosASL _vehicle; + private _vDir = getDir _vehicle; _vehicle setPosASL (_vPos vectorAdd [-0.35 * sin(_vDir), -0.35 * cos(_vDir), 0]); // TODO: Needs to be placed in safe distance to wire, so we do not constantly re - spawn new wires }, [_vehicle, _wire], 0.1] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/ACE_Settings.hpp b/addons/cookoff/ACE_Settings.hpp index 13ef915ffb..b06aaf7b9a 100644 --- a/addons/cookoff/ACE_Settings.hpp +++ b/addons/cookoff/ACE_Settings.hpp @@ -1,27 +1,40 @@ class ACE_Settings { class GVAR(enable) { + category = CSTRING(displayName); displayName = CSTRING(enable_name); description = CSTRING(enable_tooltip); value = 1; typeName = "BOOL"; }; class GVAR(enableAmmobox) { + category = CSTRING(displayName); displayName = CSTRING(enableBoxCookoff_name); description = CSTRING(enableBoxCookoff_tooltip); value = 1; typeName = "BOOL"; }; class GVAR(enableAmmoCookoff) { // For CBA Setting Switch: we can eliminate and just use (ammoCookoffDuration == 0) + category = CSTRING(displayName); displayName = CSTRING(enableAmmoCookoff_name); description = CSTRING(enableAmmoCookoff_tooltip); value = 1; typeName = "BOOL"; }; class GVAR(ammoCookoffDuration) { + category = CSTRING(displayName); displayName = CSTRING(ammoCookoffDuration_name); description = CSTRING(ammoCookoffDuration_tooltip); value = 1; typeName = "SCALAR"; + sliderSettings[] = {0, 5, 1, 1}; + }; + class GVAR(probabilityCoef) { + category = CSTRING(displayName); + displayName = CSTRING(probabilityCoef_name); + description = CSTRING(probabilityCoef_tooltip); + value = 1; + typeName = "SCALAR"; + sliderSettings[] = {0, 5, 1, 1}; }; }; diff --git a/addons/cookoff/CfgEden.hpp b/addons/cookoff/CfgEden.hpp index aa550a9228..04e7762a41 100644 --- a/addons/cookoff/CfgEden.hpp +++ b/addons/cookoff/CfgEden.hpp @@ -11,8 +11,18 @@ class Cfg3DEN { tooltip = CSTRING(enable_tooltip); expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); typeName = "BOOL"; + condition = "objectVehicle"; + defaultValue = QUOTE(GETMVAR(QGVAR(enable),true)); + }; + class GVAR(enableAmmoCookoff) { + property = QGVAR(enableAmmoCookoff); + control = "Checkbox"; + displayName = CSTRING(enableAmmoCookoff_name); + tooltip = CSTRING(enableAmmoCookoff_tooltip); + expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + typeName = "BOOL"; condition = "objectHasInventoryCargo"; - defaultValue = "(true)"; // fix pbo project preprocessing bug + defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };); }; }; }; diff --git a/addons/cookoff/CfgVehicles.hpp b/addons/cookoff/CfgVehicles.hpp index 7d82d97c12..7a682ca9d0 100644 --- a/addons/cookoff/CfgVehicles.hpp +++ b/addons/cookoff/CfgVehicles.hpp @@ -37,6 +37,7 @@ class CfgVehicles { class Tank_F: Tank { GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; + GVAR(probability) = 0.5; }; class MBT_02_base_F: Tank_F { GVAR(ammoLocation) = "HitTurret"; @@ -46,11 +47,19 @@ class CfgVehicles { class Wheeled_APC_F: Car_F { GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; + GVAR(probability) = 0.8; // big explosions for wheeled APCs (same as for tanks) explosionEffect = "FuelExplosionBig"; }; + class APC_Wheeled_02_base_F: Wheeled_APC_F { // Otokar ARMA - RCWS Turret + GVAR(ignoreTurret) = 1; + }; + class APC_Tracked_01_base_F: Tank_F { // Namera, Nemmera - RCWS Turret + GVAR(ignoreTurret) = 1; + }; + class B_MBT_01_base_F; class B_MBT_01_cannon_F: B_MBT_01_base_F { GVAR(turret)[] = {QGVAR(Turret_MBT_01),{0,-1,0.5}}; diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index b7bed03475..fad901982d 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -71,7 +71,7 @@ GVAR(cacheTankDuplicates) = call CBA_fnc_createNamespace; ["ReammoBox_F", "init", { (_this select 0) addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enable), GVAR(enableAmmobox)]) then { + if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then { ["box", _this] call FUNC(handleDamage); }; }]; diff --git a/addons/cookoff/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf index 8154217e9d..a86564e74d 100644 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ b/addons/cookoff/functions/fnc_cookOff.sqf @@ -91,7 +91,7 @@ if (local _vehicle) then { } forEach _positions; if (isServer) then { - private _soundName = [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65] call BIS_fnc_selectRandomWeighted; // TODO: replace with script Command in 1.74 + private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; // TODO - Players in the vehicle hear no sound (even after exiting the vehicle) private _sound = createSoundSource [_soundName, position _vehicle, [], 0]; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf index 4e509e3194..1f2c0b3b90 100644 --- a/addons/cookoff/functions/fnc_cookOffBox.sqf +++ b/addons/cookoff/functions/fnc_cookOffBox.sqf @@ -44,11 +44,9 @@ if (local _box) then { // These functions are smart and do all the cooking off work if (local _box) then { - if (_box getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)]) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - [_box, _mags, _total] call FUNC(detonateAmmunition); - }; + if (GVAR(ammoCookoffDuration) == 0) exitWith {}; + ([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; + [_box, _mags, _total] call FUNC(detonateAmmunition); // This shit is busy being on fire, magazines aren't accessible/usable clearMagazineCargoGlobal _box; diff --git a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf index 67c7f6e56e..78d13ee301 100644 --- a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf +++ b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf @@ -28,6 +28,9 @@ private _totalAmmo = 0; { _x params ["_mag", "", "_count"]; if (_count > 0) then { + private _ammo = getText (configFile >> "CfgMagazines" >> _mag >> "ammo"); + private _model = getText (configFile >> "CfgAmmo" >> _ammo >> "model"); + if (_model == "\A3\weapons_f\empty") exitWith {TRACE_3("skipping",_mag,_ammo,_model);}; _ammoToDetonate pushBack [_mag, _count]; _totalAmmo = _totalAmmo + _count; }; @@ -44,7 +47,9 @@ private _totalAmmo = 0; // Get ammo from transportAmmo / ace_rearm private _vehCfg = configFile >> "CfgVehicles" >> typeOf _vehicle; -if (((getNumber (_vehCfg >> "transportAmmo")) > 1000) || {isClass (_vehCfg >> "ACE_Actions" >> "ACE_MainActions" >> QEGVAR(rearm,TakeAmmo))}) then { + +private _configSupply = (getNumber (_vehCfg >> "transportAmmo")) max (getNumber (_vehCfg >> QEGVAR(rearm,defaultSupply))); +if (_vehicle getVariable [QEGVAR(rearm,isSupplyVehicle), (_configSupply > 0)]) then { TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _vehicle); _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000]; diff --git a/addons/cookoff/functions/fnc_handleDamage.sqf b/addons/cookoff/functions/fnc_handleDamage.sqf index f462cbf56c..d9fbaf4cef 100644 --- a/addons/cookoff/functions/fnc_handleDamage.sqf +++ b/addons/cookoff/functions/fnc_handleDamage.sqf @@ -29,7 +29,7 @@ if (_hitIndex != -1) then { }; // get change in damage -private "_oldDamage"; +private _oldDamage = 0; if (_hitpoint isEqualTo "#structural") then { _oldDamage = damage _vehicle; @@ -66,12 +66,23 @@ if (_simulationType == "tank") exitWith { // ammo was hit, high chance for cook-off if (_hitpoint == _ammoLocationHitpoint) then { - if (_damage > 0.5 && {random 1 < 0.7}) then { - _vehicle call FUNC(cookOff); + if (_damage > 0.5) then { + // get cookoff probability for vehicle + private _probability = [_vehicle call CBA_fnc_getObjectConfig >> QGVAR(probability), "number", 0.7] call CBA_fnc_getConfigEntry; + // probability multiplied by coef for global probability control (higher coef = more probable cookoff) + if (GVAR(probabilityCoef) > 1) then { + _probability = 1 - (1 - _probability) / GVAR(probabilityCoef); + } else { + _probability = _probability * GVAR(probabilityCoef); + }; + if (random 1 < _probability) then { + _vehicle call FUNC(cookOff); + }; }; } else { - if (_hitpoint in ["hithull", "hitturret", "#structural"] && {_newDamage > 0.6 + random 0.3}) then { - _vehicle call FUNC(cookOff); + if (_hitpoint in ["hithull", "hitturret", "#structural"] && {_newDamage > 0.8 + random 0.2}) then { + if ((_hitpoint == "hitturret") && {(getNumber (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ignoreTurret))) == 1}) exitWith {}; // ignore turrets like RCWS + _vehicle setDamage 1; }; }; diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index c9c04f86dd..006c433146 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -1,9 +1,18 @@ - + + + Cook off + Esplosione + 殉爆效果 + 殉爆效果 + 誘爆 + 쿡오프 + Durchzündung + Enable cook off - Selbstzündung ermöglichen + Durchzündung ermöglichen Povolit explozi munice Включить воспламенение 誘爆を有効化 @@ -16,7 +25,7 @@ Enables cook off and related vehicle destruction effects. - Ermöglicht Selbstzündung und zugehörige Fahrzeug-Zerstörungseffekte. + Ermöglicht Durchzündung und zugehörige Fahrzeug-Zerstörungseffekte. Povolí explozi munice a její následné ničivé efekty. Включает воспламенение и сопутствующие эффекты повреждения техники. 誘爆を有効化し、車両が誘爆によって破壊されていきます。 @@ -24,8 +33,8 @@ Aktywuje efekt samozapłonu amunicji na zniszczonych pojazdach. Active le cook-off (autocombustion des munitions) et les effets de destruction liés. Abilita l'esplosione e i relativi effetti di distruzione del veicolo. - 開啟此功能後, 將使有關載具在損毀時有殉爆的效果. - 开启此功能后, 将使有关载具在损毁时有殉爆的效果. + 開啟此功能後,將使有關載具在損毀時有殉爆的效果。 + 开启此功能后,将使有关载具在损毁时有殉爆的效果。 Wreck (Turret) @@ -39,14 +48,14 @@ Wreck (Turret) Ruínas (torre) 잔해(포탑) - 残骸(タレット) + 残骸 (砲塔) 殘骸 (砲塔) 残骸 (炮塔) Enable ammo box cook off 弾薬箱に誘爆を有効化 - Selbstzündung für Munitionskisten ermöglichen + Durchzündung für Munitionskisten ermöglichen 탄약 상자 쿡오프 현상 활성화 Aktywuj samozapłon skrzyń z amunicją Cook-off caisses de munitions @@ -57,18 +66,18 @@ Enables cooking off of ammo boxes. 弾薬箱が誘爆するようになります。 - Ermöglicht Selbstzündung von Munitionskisten. + Ermöglicht Durchzündung von Munitionskisten. 탄약 상자에 쿡오프 현상을 적용합니다. Aktywuje samozapłon skrzyń z amunicją Active le cook-off sur toutes les caisses de munitions. Abilita l'esplosione della cassa di munizioni. - 開啟彈藥箱殉爆效果. - 开启弹药箱殉爆效果. + 開啟彈藥箱殉爆效果 + 开启弹药箱殉爆效果 Enable Ammunition cook off 弾薬の誘爆を有効化 - Selbstzündung für Munition ermöglichen + Durchzündung für Munition ermöglichen 탄약 쿡오프 현상 활성화 Aktywuj samozapłon amunicji Active le cook-off des munitions @@ -78,31 +87,48 @@ Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. - 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がりす。 - Ermöglicht Selbstzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt. + 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。 + Ermöglicht Durchzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt. Aktywuje samozapłon amunicji. Wystrzeliwuje pociski podczas gdy pojazd płonie i posiada amunicję. Mets à feu les munitions lorsqu'un véhicule est en feu et contient des munitions. Abilita l'esplosione delle munizioni. Spara munizioni di proiettili quando il veicolo va a fuoco e contiene munizioni. - 開啟彈藥殉爆效果. 當一台載有彈藥的載具起火時, 將會有殉爆的效果. - 开启弹药殉爆效果. 当一台载有弹药的载具起火时, 将会有殉爆的效果. + 開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果。 + 开启弹药殉爆效果。当一台载有弹药的载具起火时, 将会有殉爆的效果。 + 쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어있는 동안 주변에 발사체를 발사합니다. Ammunition cook off duration + Munitionsdurchzündungsdauer Czas trwania samozapłonu amunicji 弾薬の誘爆持続時間 Durée cook-off des munitions Durata esplosione munizioni 彈藥殉爆效果持續時間 弹药殉爆效果持续时间 + 쿡오프 지속 시간 Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff] + Faktor für die Munitionsdurchzündungsdauer [0 zum Deaktivieren] Multiplicateur de la durée du cook-off des munitions [Une valeur de 0 désactive l'effet] Mnożnik decydujący jak długo ma trwać samozapłon amunicji [Ustawienie na 0 spowoduje wyłącznie samozapłonu] 誘爆の持続時間を乗数で設定。[0 に設定で誘爆を無効化] Moltiplicatore della durata dell'esplosione [Impostare 0 disabiliterà l'esplosione delle munizioni] 設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果] 设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果] + 쿡오프 지속 시간의 배수 [0 이면 비활성] + + + Cook-off probability coefficient + 誘爆の可能性係数 + Coefficiente probabilità esplosione + Faktor für Wahrscheinlichkeit der Durchzündung + + + Multiplier for cook-off probability. Higher value results in higher cook-off probability + 誘爆する可能性の乗数。高い値では誘爆する可能性が高まります。 + Moltiplicatore per la probabilità dell'esplosione. Un valore più alto aumenta la probabilità dell'esplosione + Faktor für Wahrscheinlichkeit der Durchzündung. Ein höherer Wert führt zu höherer Durchzündungswahrscheinlichkeit. diff --git a/addons/dagr/CfgWeapons.hpp b/addons/dagr/CfgWeapons.hpp index b6601e094c..55692e7f9a 100644 --- a/addons/dagr/CfgWeapons.hpp +++ b/addons/dagr/CfgWeapons.hpp @@ -1,10 +1,10 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_DAGR: ACE_ItemCore { - author[] = {$STR_ACE_Common_ACETeam, "Ruthberg"}; + author = ECSTRING(common,ACETeam); scope = 2; displayName = CSTRING(Name); model = QPATHTOF(data\DAGR.p3d); @@ -12,7 +12,7 @@ class CfgWeapons { picture = QPATHTOF(UI\DAGR_Icon.paa); icon = "iconObject_circle"; mapSize = 0.034; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; }; diff --git a/addons/dagr/functions/fnc_handleRangeFinderData.sqf b/addons/dagr/functions/fnc_handleRangeFinderData.sqf index 61d8201552..6d932e5e0d 100644 --- a/addons/dagr/functions/fnc_handleRangeFinderData.sqf +++ b/addons/dagr/functions/fnc_handleRangeFinderData.sqf @@ -19,7 +19,7 @@ #define EMP_RF_ACC 5 // Rangefinder Accuracy -PARAMS_3(_slopeDistance,_azimuth,_inclination); +params ["_slopeDistance", "_azimuth", "_inclination"]; if (GVAR(vectorConnected)) then { GVAR(LAZPOS) = (eyePos player) vectorAdd ([_slopeDistance, _azimuth, _inclination] call CBA_fnc_polar2vect); diff --git a/addons/dagr/functions/fnc_outputData.sqf b/addons/dagr/functions/fnc_outputData.sqf index 2208587932..edabf6209c 100644 --- a/addons/dagr/functions/fnc_outputData.sqf +++ b/addons/dagr/functions/fnc_outputData.sqf @@ -31,8 +31,6 @@ __background ctrlSetText QPATHTOF(UI\dagr_gps.paa); if (GVAR(outputPFH) != -1) exitWith {}; GVAR(outputPFH) = [{ - private ["_dagrElevation", "_dagrGrid", "_dagrHeading", "_dagrSpeed", "_dagrTime", "_elevation", "_gridArray", "_speed"]; - // Abort Condition if !(GVAR(run) && [ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith { GVAR(outputPFH) = -1; @@ -41,30 +39,30 @@ GVAR(outputPFH) = [{ }; // GRID - _gridArray = [(getPos ACE_player), false] call EFUNC(common,getMapGridFromPos); + private _gridArray = [(getPos ACE_player), false] call EFUNC(common,getMapGridFromPos); _gridArray params ["_gridArrayX","_gridArrayY"]; - _dagrGrid = format ["%1 %2", ((_gridArrayX) select [0,4]), ((_gridArrayY) select [0,4])]; + private _dagrGrid = format ["%1 %2", ((_gridArrayX) select [0,4]), ((_gridArrayY) select [0,4])]; // SPEED - _speed = speed (vehicle ACE_player); + private _speed = speed (vehicle ACE_player); _speed = floor (_speed * 10) / 10; _speed = abs(_speed); _dagrspeed = str _speed + "kph"; // Elevation - _elevation = getPosASL ACE_player; + private _elevation = getPosASL ACE_player; _elevation = floor ((_elevation select 2) + EGVAR(common,mapAltitude)); - _dagrElevation = str _elevation + "m"; + private _dagrElevation = str _elevation + "m"; // Heading - _dagrHeading = if (!GVAR(useDegrees)) then { + private _dagrHeading = if (!GVAR(useDegrees)) then { floor (DEG_TO_MIL(direction (vehicle ACE_player))) } else { floor (direction (vehicle ACE_player)) }; // Time - _dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; + private _dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; // Output __gridControl ctrlSetText format ["%1", _dagrGrid]; diff --git a/addons/dagr/functions/fnc_outputVector.sqf b/addons/dagr/functions/fnc_outputVector.sqf index 686dbcc407..12716f0e5b 100644 --- a/addons/dagr/functions/fnc_outputVector.sqf +++ b/addons/dagr/functions/fnc_outputVector.sqf @@ -16,8 +16,6 @@ #include "script_component.hpp" -private ["_xGrid", "_yGrid", "_dagrGrid", "_bearing", "_dagrDist", "_dagrElevation", "_dagrTime", "_elevation", "_xCoord", "_yCoord"]; - 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; #define __display (uiNameSpace getVariable "DAGR_DISPLAY") @@ -39,7 +37,7 @@ if (_lazPosX < 0) then { _lazPosX = _lazPosX + 99999;}; if (_lazPosY < 0) then {_lazPosY = _lazPosY + 99999;}; // Find laser position -_xGrid = toArray Str(round _lazPosX); +private _xGrid = toArray Str(round _lazPosX); while {count _xGrid < 5} do { _xGrid = [48] + _xGrid; @@ -48,7 +46,7 @@ _xGrid resize 4; _xGrid = toString _xGrid; _xGrid = parseNumber _xGrid; -_yGrid = toArray Str(round _lazPosY); +private _yGrid = toArray Str(round _lazPosY); while {count _yGrid < 5} do { _yGrid = [48] + _yGrid; }; @@ -56,37 +54,37 @@ _yGrid resize 4; _yGrid = toString _yGrid; _yGrid = parseNumber _yGrid; -_xCoord = switch true do { +private _xCoord = switch true do { case (_xGrid >= 1000): { "" + Str(_xGrid) }; case (_xGrid >= 100): { "0" + Str(_xGrid) }; case (_xGrid >= 10): { "00" + Str(_xGrid) }; default { "000" + Str(_xGrid) }; }; -_yCoord = switch true do { +private _yCoord = switch true do { case (_yGrid >= 1000): { "" + Str(_yGrid) }; case (_yGrid >= 100): { "0" + Str(_yGrid) }; case (_yGrid >= 10): { "00" + Str(_yGrid) }; default { "000" + Str(_yGrid) }; }; -_dagrGrid = _xCoord + " " + _yCoord; +private _dagrGrid = _xCoord + " " + _yCoord; // Find target elevation -_elevation = floor ((_lazPosZ) + EGVAR(common,mapAltitude)); -_dagrElevation = str _elevation + "m"; +private _elevation = floor ((_lazPosZ) + EGVAR(common,mapAltitude)); +private _dagrElevation = str _elevation + "m"; // Time -_dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; +private _dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; // Bearing -_bearing = GVAR(LAZHEADING); +private _bearing = GVAR(LAZHEADING); if (_bearing >= 360) then {_bearing = _bearing - 360;}; if (!GVAR(useDegrees)) then {_bearing = DEG_TO_MIL(_bearing)}; _bearing = floor (_bearing); // Distance -_dagrDist = str GVAR(LAZDIST) + "m"; +private _dagrDist = str GVAR(LAZDIST) + "m"; // Put grid into variable so DAGR menu can access it GVAR(vectorGrid) = _dagrGrid; diff --git a/addons/dagr/functions/fnc_outputWP.sqf b/addons/dagr/functions/fnc_outputWP.sqf index 32e1c2eaa0..0b6a77db7d 100644 --- a/addons/dagr/functions/fnc_outputWP.sqf +++ b/addons/dagr/functions/fnc_outputWP.sqf @@ -31,8 +31,6 @@ __background ctrlSetText QPATHTOF(UI\dagr_wp.paa); if (GVAR(outputPFH) != -1) exitWith {}; GVAR(outputPFH) = [{ - private ["_MYpos", "_WPpos", "_bearing", "_dagrDistance", "_dagrGrid", "_dagrHeading", "_distance", "_gridArray"]; - // Abort Condition if !(GVAR(run) && [ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith { GVAR(outputPFH) = -1; @@ -41,13 +39,13 @@ GVAR(outputPFH) = [{ }; // GRID - _gridArray = [(getPos ACE_player), false] call EFUNC(common,getMapGridFromPos); + private _gridArray = [(getPos ACE_player), false] call EFUNC(common,getMapGridFromPos); _gridArray params ["_gridArrayX","_gridArrayY"]; - _dagrGrid = format ["%1 %2", (_gridArrayX select [0,4]), (_gridArrayY select [0,4])]; + private _dagrGrid = format ["%1 %2", (_gridArrayX select [0,4]), (_gridArrayY select [0,4])]; // WP Grid - _xGrid2 = floor (DAGR_WP_INFO / 10000); - _yGrid2 = DAGR_WP_INFO - _xGrid2 * 10000; + private _xGrid2 = floor (DAGR_WP_INFO / 10000); + private _yGrid2 = DAGR_WP_INFO - _xGrid2 * 10000; _xCoord2 = switch true do { case (_xGrid2 >= 1000): { "" + Str(_xGrid2) }; @@ -66,21 +64,21 @@ GVAR(outputPFH) = [{ _dagrGrid2 = _xCoord2 + " " + _yCoord2; // Distance - _WPpos = [_dagrGrid2, true] call EFUNC(common,getMapPosFromGrid); - _MYpos = [_dagrGrid, true] call EFUNC(common,getMapPosFromGrid); - _distance = _MYpos distance _WPpos; + private _WPpos = [_dagrGrid2, true] call EFUNC(common,getMapPosFromGrid); + private _MYpos = [_dagrGrid, true] call EFUNC(common,getMapPosFromGrid); + private _distance = _MYpos distance _WPpos; _distance = floor (_distance * 10) / 10; - _dagrDistance = str _distance + "m"; + private _dagrDistance = str _distance + "m"; // Heading - _dagrHeading = floor (if (GVAR(useDegrees)) then { + private _dagrHeading = floor (if (GVAR(useDegrees)) then { direction (vehicle ACE_player) } else { DEG_TO_MIL(direction (vehicle ACE_player)) }); // WP Heading - _bearing = floor (if (GVAR(useDegrees)) then { + private _bearing = floor (if (GVAR(useDegrees)) then { ((_WPpos vectorDiff _MYpos) call CBA_fnc_vectDir) } else { DEG_TO_MIL(((_WPpos vectorDiff _MYpos) call CBA_fnc_vectDir)) diff --git a/addons/dagr/initKeybinds.sqf b/addons/dagr/initKeybinds.sqf index 74a522e87f..d99e0f15c7 100644 --- a/addons/dagr/initKeybinds.sqf +++ b/addons/dagr/initKeybinds.sqf @@ -1,5 +1,5 @@ -["ACE3 Equipment", QGVAR(MenuKey), "Configure DAGR", +["ACE3 Equipment", QGVAR(MenuKey), localize LSTRING(ConfigureDAGR), { // Conditions: canInteract if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; @@ -16,7 +16,7 @@ {false}, [0, [false, true, false]], false] call CBA_fnc_addKeybind; // (empty default key) -["ACE3 Equipment", QGVAR(ToggleKey), "Toggle DAGR", +["ACE3 Equipment", QGVAR(ToggleKey), localize LSTRING(ToggleDAGR), { // Conditions: canInteract if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; @@ -30,11 +30,10 @@ [0, [false, false, false]], false] call CBA_fnc_addKeybind; // (empty default key) //Add deviceKey entry: -private ["_conditonCode", "_toggleCode", "_closeCode"]; -_conditonCode = { +private _conditonCode = { ([ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)); }; -_toggleCode = { +private _toggleCode = { // Conditions: canInteract if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {}; @@ -44,7 +43,7 @@ _toggleCode = { [] call FUNC(menuInit); }; }; -_closeCode = { +private _closeCode = { // Statement if (GVAR(run)) then { //If dispaly is open, close it: diff --git a/addons/dagr/stringtable.xml b/addons/dagr/stringtable.xml index 51ca754a82..c364eedabe 100644 --- a/addons/dagr/stringtable.xml +++ b/addons/dagr/stringtable.xml @@ -28,8 +28,8 @@ Configurer le DAGR DAGR を設定 DAGR 설정 - 軍用GPS接收器設定 - 军用GPS接收器设定 + 設定軍用GPS接收器 + 设定军用GPS接收器 Toggle DAGR diff --git a/addons/disarming/CfgVehicles.hpp b/addons/disarming/CfgVehicles.hpp index 1d04bb157c..189c118bce 100644 --- a/addons/disarming/CfgVehicles.hpp +++ b/addons/disarming/CfgVehicles.hpp @@ -8,8 +8,8 @@ class CfgVehicles { distance = 3.5; condition = QUOTE([ARR_2(_player,_target)] call FUNC(canPlayerDisarmUnit)); statement = QUOTE([ARR_2(_player,_target)] call FUNC(openDisarmDialog)); + exceptions[] = {"isNotSwimming"}; icon = QPATHTOF(UI\disarm.paa); - exceptions[] = {}; }; }; }; diff --git a/addons/disarming/CfgWeapons.hpp b/addons/disarming/CfgWeapons.hpp index 4e7122ba41..94f1bd8a2c 100644 --- a/addons/disarming/CfgWeapons.hpp +++ b/addons/disarming/CfgWeapons.hpp @@ -1,13 +1,13 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_DebugPotato: ACE_ItemCore { displayName = "ACE Potato (debug)"; descriptionShort = "Glorious Potato
If you see this in game it means someone fucked up"; picture = QPATHTOF(UI\potato_ca.paa); scope = 1; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; diff --git a/addons/disarming/functions/fnc_canBeDisarmed.sqf b/addons/disarming/functions/fnc_canBeDisarmed.sqf index 9be20db7f4..7e45c42ce0 100644 --- a/addons/disarming/functions/fnc_canBeDisarmed.sqf +++ b/addons/disarming/functions/fnc_canBeDisarmed.sqf @@ -16,16 +16,14 @@ */ #include "script_component.hpp" -private ["_animationStateCfgMoves", "_putDownAnim"]; - params ["_target"]; //Check animationState for putDown anim //This ensures the unit doesn't have to actualy do any animation to drop something //This should always be true for the 3 possible status effects that allow disarming -_animationStateCfgMoves = getText (configFile >> "CfgMovesMaleSdr" >> "States" >> (animationState _target) >> "actions"); +private _animationStateCfgMoves = getText (configFile >> "CfgMovesMaleSdr" >> "States" >> (animationState _target) >> "actions"); if (_animationStateCfgMoves == "") exitWith { false }; -_putDownAnim = getText (configFile >> "CfgMovesBasic" >> "Actions" >> _animationStateCfgMoves >> "PutDown"); +private _putDownAnim = getText (configFile >> "CfgMovesBasic" >> "Actions" >> _animationStateCfgMoves >> "PutDown"); if (_putDownAnim != "") exitWith { false }; diff --git a/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf b/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf index 34f1a10d32..3c375c8ddf 100644 --- a/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf +++ b/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf @@ -20,4 +20,4 @@ params ["_player", "_target"]; ([_target] call FUNC(canBeDisarmed)) && -{([_player, _target, []] call EFUNC(common,canInteractWith))} +{([_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} diff --git a/addons/disarming/functions/fnc_disarmDropItems.sqf b/addons/disarming/functions/fnc_disarmDropItems.sqf index af799e25df..fe362aedd0 100644 --- a/addons/disarming/functions/fnc_disarmDropItems.sqf +++ b/addons/disarming/functions/fnc_disarmDropItems.sqf @@ -4,10 +4,10 @@ * Makes a unit drop items * * Arguments: - * 0: caller (player) - * 1: target - * 2: classnamess - * 3: Do Not Drop Ammo + * 0: Caller (player) + * 1: Target + * 2: Classnames + * 3: Do Not Drop Ammo (default: false) * * Return Value: * None @@ -21,12 +21,10 @@ #define TIME_MAX_WAIT 5 -private ["_fncSumArray", "_return", "_holder", "_dropPos", "_targetMagazinesStart", "_holderMagazinesStart", "_xClassname", "_xAmmo", "_targetMagazinesEnd", "_holderMagazinesEnd", "_holderItemsStart", "_targetItemsStart", "_addToCrateClassnames", "_addToCrateCount", "_index", "_holderItemsEnd", "_targetItemsEnd", "_holderIsEmpty"]; - params ["_caller", "_target", "_listOfItemsToRemove", ["_doNotDropAmmo", false, [false]]]; //By default units drop all weapon mags when dropping a weapon -_fncSumArray = { - _return = 0; +private _fncSumArray = { + private _return = 0; {_return = _return + _x;} count (_this select 0); _return }; @@ -39,7 +37,7 @@ if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) [_caller, _target, "Debug: Trying to drop magazine with _doNotDropAmmo flag"] call FUNC(eventTargetFinish); }; -_holder = objNull; +private _holder = objNull; //If not dropping ammo, don't use an existing container if (!_doNotDropAmmo) then { @@ -52,7 +50,7 @@ if (!_doNotDropAmmo) then { //Create a new weapon holder if (isNull _holder) then { - _dropPos = _target modelToWorld [0.4, 0.75, 0]; //offset someone unconscious isn't lying over it + private _dropPos = _target modelToWorld [0.4, 0.75, 0]; //offset someone unconscious isn't lying over it _dropPos set [2, ((getPosASL _target) select 2)]; _holder = createVehicle [DISARM_CONTAINER, _dropPos, [], 0, "CAN_COLLIDE"]; _holder setPosASL _dropPos; @@ -73,19 +71,19 @@ _holder setVariable [QGVAR(holderInUse), true]; //Remove Magazines -_targetMagazinesStart = magazinesAmmo _target; -_holderMagazinesStart = magazinesAmmoCargo _holder; +private _targetMagazinesStart = magazinesAmmo _target; +private _holderMagazinesStart = magazinesAmmoCargo _holder; { - EXPLODE_2_PVT(_x,_xClassname,_xAmmo); + _x params ["_xClassname", "_xAmmo"]; if ((_xClassname in _listOfItemsToRemove) && {(getNumber (configFile >> "CfgMagazines" >> _xClassname >> "ACE_isUnique")) == 0}) then { _holder addMagazineAmmoCargo [_xClassname, 1, _xAmmo]; _target removeMagazine _xClassname; }; } forEach _targetMagazinesStart; -_targetMagazinesEnd = magazinesAmmo _target; -_holderMagazinesEnd = magazinesAmmoCargo _holder; +private _targetMagazinesEnd = magazinesAmmo _target; +private _holderMagazinesEnd = magazinesAmmoCargo _holder; //Verify Mags dropped from unit: if (({((_x select 0) in _listOfItemsToRemove) && {(getNumber (configFile >> "CfgMagazines" >> (_x select 0) >> "ACE_isUnique")) == 0}} count _targetMagazinesEnd) != 0) exitWith { @@ -100,14 +98,14 @@ if (!([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holde }; //Remove Items, Assigned Items and NVG -_holderItemsStart = getitemCargo _holder; -_targetItemsStart = (assignedItems _target) + (items _target) - (weapons _target); +private _holderItemsStart = getitemCargo _holder; +private _targetItemsStart = (assignedItems _target) + (items _target) - (weapons _target); if ((headgear _target) != "") then {_targetItemsStart pushBack (headgear _target);}; if ((goggles _target) != "") then {_targetItemsStart pushBack (goggles _target);}; -_addToCrateClassnames = []; -_addToCrateCount = []; +private _addToCrateClassnames = []; +private _addToCrateCount = []; { if (_x in _listOfItemsToRemove) then { if (_x in (items _target)) then { @@ -115,7 +113,7 @@ _addToCrateCount = []; } else { _target unlinkItem _x; }; - _index = _addToCrateClassnames find _x; + private _index = _addToCrateClassnames find _x; if (_index != -1) then { _addToCrateCount set [_index, ((_addToCrateCount select _index) + 1)]; } else { @@ -130,8 +128,8 @@ _addToCrateCount = []; _holder addItemCargoGlobal [(_addToCrateClassnames select _forEachIndex), (_addToCrateCount select _forEachIndex)]; } forEach _addToCrateClassnames; -_holderItemsEnd = getitemCargo _holder; -_targetItemsEnd = (assignedItems _target) + (items _target) - (weapons _target); +private _holderItemsEnd = getitemCargo _holder; +private _targetItemsEnd = (assignedItems _target) + (items _target) - (weapons _target); if ((headgear _target) != "") then {_targetItemsEnd pushBack (headgear _target);}; if ((goggles _target) != "") then {_targetItemsEnd pushBack (goggles _target);}; @@ -158,7 +156,7 @@ if (((vest _target) != "") && {(vest _target) in _listOfItemsToRemove} && {(vest //If holder is still empty, it will be 'garbage collected' while we wait for the drop 'action' to take place //So add a dummy item and just remove at the end -_holderIsEmpty = ([_holder] call FUNC(getAllGearContainer)) isEqualTo [[],[]]; +private _holderIsEmpty = ([_holder] call FUNC(getAllGearContainer)) isEqualTo [[],[]]; if (_holderIsEmpty) then { TRACE_1("Debug: adding dummy item to holder",_holder); _holder addItemCargoGlobal [DUMMY_ITEM, 1]; @@ -166,16 +164,14 @@ if (_holderIsEmpty) then { //Start the PFEH to do the actions (which could take >1 frame) [{ - private ["_needToRemoveWeapon", "_needToRemoveMagazines", "_needToRemoveBackpack", "_needToRemoveVest", "_needToRemoveUniform", "_error", "_magsToPickup", "_index", "_magazinesInHolder"]; + params ["_args", "_pfID"]; + _args params ["_caller", "_target", "_listOfItemsToRemove", "_holder", "_holderIsEmpty", "_maxWaitTime", "_doNotDropAmmo", "_startingMagazines"]; - PARAMS_2(_args,_pfID); - EXPLODE_8_PVT(_args,_caller,_target,_listOfItemsToRemove,_holder,_holderIsEmpty,_maxWaitTime,_doNotDropAmmo,_startingMagazines); - - _needToRemoveWeapon = ({_x in _listOfItemsToRemove} count (weapons _target)) > 0; - _needToRemoveMagazines = ({_x in _listOfItemsToRemove} count (magazines _target)) > 0; - _needToRemoveBackpack = ((backPack _target) != "") && {(backPack _target) in _listOfItemsToRemove}; - _needToRemoveVest = ((vest _target) != "") && {(vest _target) in _listOfItemsToRemove}; - _needToRemoveUniform = ((uniform _target) != "") && {(uniform _target) in _listOfItemsToRemove}; + private _needToRemoveWeapon = ({_x in _listOfItemsToRemove} count (weapons _target)) > 0; + private _needToRemoveMagazines = ({_x in _listOfItemsToRemove} count (magazines _target)) > 0; + private _needToRemoveBackpack = ((backPack _target) != "") && {(backPack _target) in _listOfItemsToRemove}; + private _needToRemoveVest = ((vest _target) != "") && {(vest _target) in _listOfItemsToRemove}; + private _needToRemoveUniform = ((uniform _target) != "") && {(uniform _target) in _listOfItemsToRemove}; if ((CBA_missionTime < _maxWaitTime) && {[_target] call FUNC(canBeDisarmed)} && {_needToRemoveWeapon || _needToRemoveMagazines || _needToRemoveBackpack}) then { //action drop weapons (keeps loaded magazine and attachements) @@ -198,18 +194,18 @@ if (_holderIsEmpty) then { [_pfID] call CBA_fnc_removePerFrameHandler; if (_doNotDropAmmo) then { - _error = false; + private _error = false; - _magsToPickup = +_startingMagazines; + private _magsToPickup = +_startingMagazines; { - _index = _magsToPickup find _x; + private _index = _magsToPickup find _x; if (_index == -1) exitWith {_error = true; ERROR("More mags than when we started?")}; _magsToPickup deleteAt _index; } forEach (magazinesAmmo _target); - _magazinesInHolder = magazinesAmmoCargo _holder; + private _magazinesInHolder = magazinesAmmoCargo _holder; { - _index = _magazinesInHolder find _x; + private _index = _magazinesInHolder find _x; if (_index == -1) exitWith {_error = true; ERROR("Missing mag not in holder")}; _magazinesInHolder deleteAt _index; } forEach _magsToPickup; diff --git a/addons/disarming/functions/fnc_getAllGearUnit.sqf b/addons/disarming/functions/fnc_getAllGearUnit.sqf index bdd1ff0bf9..30d263fd27 100644 --- a/addons/disarming/functions/fnc_getAllGearUnit.sqf +++ b/addons/disarming/functions/fnc_getAllGearUnit.sqf @@ -18,9 +18,7 @@ params ["_target"]; -private ["_allItems", "_classnamesCount", "_index", "_uniqueClassnames"]; - -_allItems = (((items _target) + (assignedItems _target)) - (weapons _target)) + (weapons _target) + (magazines _target); +private _allItems = (((items _target) + (assignedItems _target)) - (weapons _target)) + (weapons _target) + (magazines _target); if ((backpack _target) != "") then { _allItems pushBack (backpack _target); @@ -39,11 +37,11 @@ if ((goggles _target) != "") then { _allItems pushBack (goggles _target); }; -_uniqueClassnames = []; -_classnamesCount = []; +private _uniqueClassnames = []; +private _classnamesCount = []; //Filter unique and count { - _index = _uniqueClassnames find _x; + private _index = _uniqueClassnames find _x; if (_index != -1) then { _classnamesCount set [_index, ((_classnamesCount select _index) + 1)]; } else { diff --git a/addons/disarming/functions/fnc_openDisarmDialog.sqf b/addons/disarming/functions/fnc_openDisarmDialog.sqf index 6763f9a9fa..0490598231 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -48,7 +48,6 @@ GVAR(disarmTarget) = _target; //Setup PFEH [{ - private ["_groundContainer", "_targetContainer", "_playerName", "_icon", "_rankPicture", "_targetUniqueItems", "_holderUniqueItems", "_holder"]; disableSerialization; params ["_args", "_idPFH"]; _args params ["_player", "_target", "_display"]; @@ -62,13 +61,13 @@ GVAR(disarmTarget) = _target; if (!isNull _display) then { closeDialog 0; }; //close dialog if still open } else { - _groundContainer = _display displayCtrl 632; - _targetContainer = _display displayCtrl 633; - _playerName = _display displayCtrl 111; - _rankPicture = _display displayCtrl 1203; + private _groundContainer = _display displayCtrl 632; + private _targetContainer = _display displayCtrl 633; + private _playerName = _display displayCtrl 111; + private _rankPicture = _display displayCtrl 1203; //Show rank and name (just like BIS's inventory) - _icon = format [DEFUALTPATH, toLower (rank _target)]; + private _icon = format [DEFUALTPATH, toLower (rank _target)]; if (_icon isEqualTo DEFUALTPATH) then {_icon = ""}; _rankPicture ctrlSetText _icon; _playerName ctrlSetText ([GVAR(disarmTarget), false, true] call EFUNC(common,getName)); @@ -78,11 +77,11 @@ GVAR(disarmTarget) = _target; lbClear _targetContainer; //Show the items in the ground disarmTarget's inventory - _targetUniqueItems = [GVAR(disarmTarget)] call FUNC(getAllGearUnit); + private _targetUniqueItems = [GVAR(disarmTarget)] call FUNC(getAllGearUnit); [_targetContainer, _targetUniqueItems] call FUNC(showItemsInListbox); //Try to find a holder that the target is using to drop items into: - _holder = objNull; + private _holder = objNull; { if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith { _holder = _x; @@ -91,7 +90,7 @@ GVAR(disarmTarget) = _target; //If a holder exists, show it's inventory if (!isNull _holder) then { - _holderUniqueItems = [_holder] call FUNC(getAllGearContainer); + private _holderUniqueItems = [_holder] call FUNC(getAllGearContainer); [_groundContainer, _holderUniqueItems] call FUNC(showItemsInListbox); }; }; diff --git a/addons/disarming/functions/fnc_showItemsInListbox.sqf b/addons/disarming/functions/fnc_showItemsInListbox.sqf index d43dd9b5ca..741a67aa6c 100644 --- a/addons/disarming/functions/fnc_showItemsInListbox.sqf +++ b/addons/disarming/functions/fnc_showItemsInListbox.sqf @@ -26,7 +26,7 @@ params ["_listBoxCtrl", "_itemsCountArray"]; private _count = (_itemsCountArray select 1) select _forEachIndex; if ((_classname != DUMMY_ITEM) && {_classname != "ACE_FakePrimaryWeapon"}) then { //Don't show the dummy potato or fake weapon - private "_configPath"; + private _configPath = configNull; private _displayName = ""; private _picture = ""; switch (true) do { diff --git a/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf b/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf index c324ab5268..5dddec5339 100644 --- a/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf +++ b/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf @@ -21,7 +21,7 @@ */ #include "script_component.hpp" -PARAMS_4(_startA,_endA,_startB,_endB); +params ["_startA", "_endA", "_startB", "_endB"]; //Quick Lazy Count Check if (((count _startA) + (count _startB)) != ((count _endA) + (count _endB))) exitWith { diff --git a/addons/disposable/CfgMagazines.hpp b/addons/disposable/CfgMagazines.hpp index d9ad0508db..dd1b799a0f 100644 --- a/addons/disposable/CfgMagazines.hpp +++ b/addons/disposable/CfgMagazines.hpp @@ -5,7 +5,7 @@ class CfgMagazines { scope = 1; scopeArsenal = 1; displayName = CSTRING(PreloadedMissileDummy); - picture = QPATHTOEF(common,UI\blank_CO.paa); + picture = "a3\ui_f\data\IGUI\Cfg\Targeting\Empty_ca.paa"; weaponPoolAvailable = 0; mass = 0; }; diff --git a/addons/dogtags/CfgVehicles.hpp b/addons/dogtags/CfgVehicles.hpp index f583164b1f..170f1fb074 100644 --- a/addons/dogtags/CfgVehicles.hpp +++ b/addons/dogtags/CfgVehicles.hpp @@ -6,6 +6,7 @@ class CfgVehicles { displayName = CSTRING(itemName); condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeDogtag)); statement = ""; + exceptions[] = {"isNotSwimming", "isNotInside"}; showDisabled = 0; distance = 1.75; icon = QPATHTOF(data\dogtag_icon_ca.paa); @@ -14,6 +15,7 @@ class CfgVehicles { displayName = CSTRING(checkDogtag); condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckDogtag)); statement = QUOTE([ARR_2(_player,_target)] call FUNC(checkDogtag)); + exceptions[] = {"isNotSwimming", "isNotInside"}; showDisabled = 0; priority = 3; icon = QPATHTOF(data\dogtag_icon_ca.paa); @@ -22,6 +24,7 @@ class CfgVehicles { displayName = CSTRING(takeDogtag); condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeDogtag)); statement = QUOTE([ARR_2(_player,_target)] call FUNC(takeDogtag)); + exceptions[] = {"isNotSwimming", "isNotInside"}; showDisabled = 0; priority = 3; icon = QPATHTOF(data\dogtag_icon_ca.paa); @@ -34,7 +37,7 @@ class CfgVehicles { displayName = CSTRING(checkItem); condition = "true"; statement = ""; - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; insertChildren = QUOTE(_this call DFUNC(addDogtagActions)); }; }; diff --git a/addons/dogtags/CfgWeapons.hpp b/addons/dogtags/CfgWeapons.hpp index a0ce4b0132..ec8d9e6ee4 100644 --- a/addons/dogtags/CfgWeapons.hpp +++ b/addons/dogtags/CfgWeapons.hpp @@ -10,7 +10,7 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_dogtag: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -18,7 +18,7 @@ class CfgWeapons { displayName = CSTRING(itemName); model = QUOTE(PATHTOF(data\ace_dogtag.p3d)); picture = QUOTE(PATHTOF(data\dogtagSingle.paa)); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0; //too small to for 1 ? }; }; diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index 6a50ce61cf..02d2db862b 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -46,5 +46,35 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { }; }; +if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(arsenal,rightPanelFilled), { + + params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; + + if (_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) then { + LOG("passed"); + private _rightPanel = _display displayCtrl 15; + (lnbSize _rightPanel) params ["_rows", "_columns"]; + + private _allDogtags = missionNameSpace getVariable [QGVAR(allDogtags), []]; + private _allDogtagDatas = missionNameSpace getVariable [QGVAR(allDogtagDatas), []]; + + for "_r" from 0 to (_rows - 1) do { + private _data = _rightPanel lnbData [_r, 0]; + + if (_data isKindOf ["ACE_dogtag", (configFile >> "CfgWeapons")]) then { + + private _dogtagData = []; + private _index = _allDogtags find _data; + _dogtagData = _allDogtagDatas select _index; + private _dogtagString = [localize LSTRING(itemName), ": ", (_dogtagData select 0)] joinString ""; + + _rightPanel lnbSetText [[_r, 1], _dogtagString]; + }; + }; + }; + }] call CBA_fnc_addEventHandler; +}; + // disable dogtags for civilians "CIV_F" call FUNC(disableFactionDogtags); diff --git a/addons/dogtags/functions/fnc_ssn.sqf b/addons/dogtags/functions/fnc_ssn.sqf index 330d4c00d2..257f47a790 100644 --- a/addons/dogtags/functions/fnc_ssn.sqf +++ b/addons/dogtags/functions/fnc_ssn.sqf @@ -17,8 +17,10 @@ params ["_name"]; -private _length = count _name; private _chars = toArray _name; +private _length = count _chars; +// Warning, for strings containing non-latin characters, `_count _name` != `_count _chars` + _chars pushBack _length; _length = _length + 1; diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index e47a0ae1b7..a60f325652 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -58,7 +58,7 @@ Zabrałeś nieśmiertelnik %1... Жетон снят с %1... Sebral jsem známku od %1... - %1からドッグ タグを取っている・・・ + %1からドッグ タグを取っています・・・ Hundemarke von %1 genommen ... %1로부터 군번줄을 회수했습니다... Plaque d'identification pris sur %1... @@ -71,7 +71,7 @@ Ktoś już zabrał ten nieśmiertelnik... Кто-то уже забрал жетон... Někdo jiný už vzal identifikační známku... - すでに誰かがドッグ タグを取っているようだ・・・ + すでに誰かがドッグ タグを取っていったようだ・・・ Jemand anderes hat bereits die Hundemarke genommen ... 누군가 이미 군번줄을 회수해갔습니다... Quelqu'un d'autre a déjâ pris les plaques d'identification... diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index f5d72fba50..8808ea9030 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -207,7 +207,24 @@ class CfgVehicles { GVAR(dragPosition[]) = {0,1.5,0}; GVAR(dragDirection) = 90; }; + class Land_PaperBox_01_small_closed_base_F: Items_base_F { + GVAR(canCarry) = 1; + GVAR(carryPosition[]) = {0,1,1}; + GVAR(carryDirection) = 0; + GVAR(canDrag) = 1; + GVAR(dragPosition[]) = {0,1.5,0}; + GVAR(dragDirection) = 90; + }; + class Box_UAV_06_base_F: Items_base_F { + GVAR(canCarry) = 1; + GVAR(carryPosition[]) = {0,1,1}; + GVAR(carryDirection) = 0; + + GVAR(canDrag) = 1; + GVAR(dragPosition[]) = {0,1.5,0}; + GVAR(dragDirection) = 0; + }; class ACE_RepairItem_Base: ThingX {}; class ACE_Track: ACE_RepairItem_Base { diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index b45a7d1d14..31c9810aba 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -18,7 +18,7 @@ params ["_unit", "_target"]; -if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // a static weapon has to be empty for dragging (ignore UAV AI) if ((typeOf _target) isKindOf "StaticWeapon" && {{(getText (configFile >> "CfgVehicles" >> (typeOf _x) >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; diff --git a/addons/dragging/functions/fnc_canDrop.sqf b/addons/dragging/functions/fnc_canDrop.sqf index b9a6170bf2..286f6de3a9 100644 --- a/addons/dragging/functions/fnc_canDrop.sqf +++ b/addons/dragging/functions/fnc_canDrop.sqf @@ -18,6 +18,6 @@ params ["_unit", "_target"]; -if !([_unit, _target, ["isNotDragging"]] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([_unit, _target, ["isNotDragging", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; _unit getVariable [QGVAR(draggedObject), objNull] == _target diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index f060c8d088..6553c84929 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -46,6 +46,8 @@ if (_target isKindOf "CAManBase") then { _unit removeWeapon "ACE_FakePrimaryWeapon"; +[_unit, "blockThrow", "ACE_dragging", false] call EFUNC(common,statusEffect_set); + // prevent object from flipping inside buildings if (_inBuilding) then { _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); @@ -58,7 +60,7 @@ if (_inBuilding) then { _unit setVariable [QGVAR(isDragging), false, true]; _unit setVariable [QGVAR(draggedObject), objNull, true]; -// make object accesable for other units +// make object accessible for other units [objNull, _target, true] call EFUNC(common,claim); if !(_target isKindOf "CAManBase") then { diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index c3521bbed0..857e64bb7a 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -51,6 +51,7 @@ _unit removeWeapon "ACE_FakePrimaryWeapon"; _unit selectWeapon primaryWeapon _unit; [_unit, "forceWalk", "ACE_dragging", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_dragging", false] call EFUNC(common,statusEffect_set); // prevent object from flipping inside buildings if (_inBuilding) then { diff --git a/addons/dragging/functions/fnc_getWeight.sqf b/addons/dragging/functions/fnc_getWeight.sqf index ac2db86ad0..2c63d220fa 100644 --- a/addons/dragging/functions/fnc_getWeight.sqf +++ b/addons/dragging/functions/fnc_getWeight.sqf @@ -31,6 +31,7 @@ private _totalWeight = 0; } forEach _item; true } count [ + //IGNORE_PRIVATE_WARNING ["_x"]; [getMagazineCargo _object, {configFile >> "CfgMagazines" >> _x}], [getBackpackCargo _object, {configFile >> "CfgVehicles" >> _x}], [getItemCargo _object, {configFile >> "CfgWeapons" >> _x >> "ItemInfo"}], diff --git a/addons/dragging/functions/fnc_handleAnimChanged.sqf b/addons/dragging/functions/fnc_handleAnimChanged.sqf index c59b088ee0..2a531ea67c 100644 --- a/addons/dragging/functions/fnc_handleAnimChanged.sqf +++ b/addons/dragging/functions/fnc_handleAnimChanged.sqf @@ -30,7 +30,7 @@ if (_unit != _realUnit) exitWith { if (_unit getVariable [QGVAR(isDragging), false]) then { // drop dragged object when not in valid animation - if !(_anim in DRAG_ANIMATIONS) then { + if (!(_anim in DRAG_ANIMATIONS) && {!(_unit call EFUNC(common,isSwimming))}) then { private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; if (!isNull _draggedObject) then { diff --git a/addons/dragging/functions/fnc_handleScrollWheel.sqf b/addons/dragging/functions/fnc_handleScrollWheel.sqf index f82478d531..22a19627c0 100644 --- a/addons/dragging/functions/fnc_handleScrollWheel.sqf +++ b/addons/dragging/functions/fnc_handleScrollWheel.sqf @@ -30,8 +30,8 @@ private _carriedItem = _unit getVariable [QGVAR(carriedObject), objNull]; //disabled for persons if (_carriedItem isKindOf "CAManBase") exitWith {false}; -private _position = getPosATL _carriedItem; -private _maxHeight = (_unit modelToWorldVisual [0,0,0]) select 2; +private _position = getPosASL _carriedItem; +private _maxHeight = (_unit modelToWorldVisualWorld [0, 0, 0]) select 2; _position set [2, ((_position select 2) + _scrollAmount min (_maxHeight + 1.5)) max _maxHeight]; @@ -39,7 +39,7 @@ _position set [2, ((_position select 2) + _scrollAmount min (_maxHeight + 1.5)) detach _carriedItem; // Uses this method of selecting position because setPosATL did not have immediate effect -private _positionChange = _position vectorDiff (getPosATL _carriedItem); +private _positionChange = _position vectorDiff (getPosASL _carriedItem); private _selectionPosition = _unit worldToModel (ASLtoAGL getPosWorld _carriedItem); _selectionPosition = _selectionPosition vectorAdd _positionChange; _carriedItem attachTo [_unit, _selectionPosition]; diff --git a/addons/dragging/functions/fnc_startCarry.sqf b/addons/dragging/functions/fnc_startCarry.sqf index 7a5341b8a8..1a53a06994 100644 --- a/addons/dragging/functions/fnc_startCarry.sqf +++ b/addons/dragging/functions/fnc_startCarry.sqf @@ -58,6 +58,8 @@ if (_target isKindOf "CAManBase") then { }; +[_unit, "blockThrow", "ACE_dragging", true] call EFUNC(common,statusEffect_set); + // prevent multiple players from accessing the same object [_unit, _target, true] call EFUNC(common,claim); diff --git a/addons/dragging/functions/fnc_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index cf08074d94..8cf552e3d1 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -35,13 +35,17 @@ if (primaryWeapon _unit == "") then { // select primary, otherwise the drag animation actions don't work. _unit selectWeapon primaryWeapon _unit; +[_unit, "blockThrow", "ACE_dragging", true] call EFUNC(common,statusEffect_set); + // prevent multiple players from accessing the same object [_unit, _target, true] call EFUNC(common,claim); // can't play action that depends on weapon if it was added the same frame -[{ - [_this, "grabDrag"] call EFUNC(common,doGesture); -}, _unit] call CBA_fnc_execNextFrame; +if !(_unit call EFUNC(common,isSwimming)) then { + [{ + [_this, "grabDrag"] call EFUNC(common,doGesture); + }, _unit] call CBA_fnc_execNextFrame; +}; // move a bit closer and adjust direction when trying to pick up a person if (_target isKindOf "CAManBase") then { diff --git a/addons/dragging/functions/fnc_startDragPFH.sqf b/addons/dragging/functions/fnc_startDragPFH.sqf index c7843cfdc9..a5bab835b7 100644 --- a/addons/dragging/functions/fnc_startDragPFH.sqf +++ b/addons/dragging/functions/fnc_startDragPFH.sqf @@ -50,7 +50,7 @@ if (CBA_missionTime > _timeOut) exitWith { }; // unit is ready to start dragging -if (animationState _unit in DRAG_ANIMATIONS) exitWith { +if (animationState _unit in DRAG_ANIMATIONS || {_unit call EFUNC(common,isSwimming)}) exitWith { TRACE_4("Start Dragging",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dragObject); diff --git a/addons/dragging/script_component.hpp b/addons/dragging/script_component.hpp index 7a82a9ed3a..01b466972f 100644 --- a/addons/dragging/script_component.hpp +++ b/addons/dragging/script_component.hpp @@ -2,7 +2,7 @@ #define COMPONENT_BEAUTIFIED Dragging #include "\z\ace\addons\main\script_mod.hpp" -//#define DEBUG_ENABLED_DRAGGING +// #define DEBUG_ENABLED_DRAGGING // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS diff --git a/addons/explosives/ACE_Settings.hpp b/addons/explosives/ACE_Settings.hpp index e103b6e018..dbde3ea19b 100644 --- a/addons/explosives/ACE_Settings.hpp +++ b/addons/explosives/ACE_Settings.hpp @@ -1,17 +1,20 @@ class ACE_Settings { class GVAR(requireSpecialist) { + category = CSTRING(Menu); displayName = CSTRING(RequireSpecialist_DisplayName); description = CSTRING(RequireSpecialist_Description); value = 0; typeName = "BOOL"; }; class GVAR(punishNonSpecialists) { + category = CSTRING(Menu); displayName = CSTRING(PunishNonSpecialists_DisplayName); description = CSTRING(PunishNonSpecialists_Description); value = 1; typeName = "BOOL"; }; class GVAR(explodeOnDefuse) { + category = CSTRING(Menu); displayName = CSTRING(ExplodeOnDefuse_DisplayName); description = CSTRING(ExplodeOnDefuse_Description); value = 1; diff --git a/addons/explosives/ACE_Triggers.hpp b/addons/explosives/ACE_Triggers.hpp index 145ae0804e..b62e593261 100644 --- a/addons/explosives/ACE_Triggers.hpp +++ b/addons/explosives/ACE_Triggers.hpp @@ -44,7 +44,7 @@ onSetup parameters: isAttachable = 0; displayName = CSTRING(IRSensor); picture = QPATHTOF(Data\UI\PressurePlate.paa); - onPlace = "false"; + onPlace = QUOTE(false); }; class Timer { isAttachable = 1; @@ -57,6 +57,6 @@ onSetup parameters: isAttachable = 0; displayName = CSTRING(TripWire); picture = QPATHTOF(Data\UI\Tripwire.paa); - onPlace = "false"; + onPlace = QUOTE(false); }; }; diff --git a/addons/explosives/CfgAmmo.hpp b/addons/explosives/CfgAmmo.hpp index 355377102a..65b1ca3fad 100644 --- a/addons/explosives/CfgAmmo.hpp +++ b/addons/explosives/CfgAmmo.hpp @@ -94,7 +94,7 @@ class CfgAmmo { class PipeBombBase; class DemoCharge_Remote_Ammo: PipeBombBase { GVAR(magazine) = "DemoCharge_Remote_Mag"; - GVAR(Explosive) = "DemoCharge_Remote_Ammo_Scripted"; + GVAR(Explosive) = "DemoCharge_Remote_Ammo_Scripted"; // can probably remove as base ammo now has triggerWhenDestroyed GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0.07, 0, 0.055}; soundActivation[] = {"", 0, 0, 0}; @@ -105,7 +105,7 @@ class CfgAmmo { }; class SatchelCharge_Remote_Ammo: PipeBombBase { GVAR(magazine) = "SatchelCharge_Remote_Mag"; - GVAR(Explosive) = "SatchelCharge_Remote_Ammo_Scripted"; + GVAR(Explosive) = "SatchelCharge_Remote_Ammo_Scripted"; // can probably remove as base ammo now has triggerWhenDestroyed GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0.1, 0.1, 0.05}; soundActivation[] = {"", 0, 0, 0}; @@ -169,4 +169,18 @@ class CfgAmmo { class ACE_IEDLandSmall_Range_Ammo: IEDLandBig_Remote_Ammo { mineTrigger = "RangeTriggerShort"; }; + + // Orange DLC: + class APERSMineDispenser_Ammo: PipeBombBase { + GVAR(magazine) = "APERSMineDispenser_Mag"; + GVAR(Explosive) = "APERSMineDispenser_Ammo_Scripted"; // triggerWhenDestroyed = 1; + GVAR(size) = 0; + GVAR(defuseObjectPosition)[] = {0.0, -0.05, 0.15}; + }; + class APERSMine_Range_Ammo; + class TrainingMine_Ammo: APERSMine_Range_Ammo { + GVAR(magazine) = "TrainingMine_Mag"; + GVAR(size) = 0; + GVAR(defuseObjectPosition)[] = {0, 0, 0.15}; + }; }; diff --git a/addons/explosives/CfgMagazines.hpp b/addons/explosives/CfgMagazines.hpp index 698ed79fcb..1784e80433 100644 --- a/addons/explosives/CfgMagazines.hpp +++ b/addons/explosives/CfgMagazines.hpp @@ -170,4 +170,29 @@ class CfgMagazines { }; }; }; + + + // Orange DLC: + class APERSMineDispenser_Mag: SatchelCharge_Remote_Mag { + GVAR(SetupObject) = "ACE_Explosives_Place_APERSMineDispenser"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + }; + }; + class TrainingMine_Mag: APERSMine_Range_Mag { + GVAR(SetupObject) = "ACE_Explosives_Place_TrainingMine"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.02; + }; + }; + }; }; diff --git a/addons/explosives/CfgModule.hpp b/addons/explosives/CfgModule.hpp index a4e0d8dbd2..081df5d72d 100644 --- a/addons/explosives/CfgModule.hpp +++ b/addons/explosives/CfgModule.hpp @@ -4,7 +4,7 @@ class ACE_ModuleExplosive: ACE_Module { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(module); - scope = 2; + scope = 1; isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_Explosives_ca.paa); diff --git a/addons/explosives/CfgVehicles.hpp b/addons/explosives/CfgVehicles.hpp index 70499ba809..8d03856e50 100644 --- a/addons/explosives/CfgVehicles.hpp +++ b/addons/explosives/CfgVehicles.hpp @@ -164,6 +164,27 @@ class CfgVehicles { }; }; + // Orange DLC: + class ACE_Explosives_Place_APERSMineDispenser: ACE_Explosives_Place { + displayName = "APERSMineDispenser"; + model = "\A3\Weapons_F_Orange\Explosives\APERSmineDispenser"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.0, -0.05, 0.15]"; + }; + }; + }; + class ACE_Explosives_Place_TrainingMine: ACE_Explosives_Place { + displayName = "TrainingMine"; + model = "\A3\Weapons_F_Orange\Explosives\TrainingMine_F"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 0, 0.15]"; + }; + }; + }; + + class ACE_Explosives_Place_SLAM: ACE_Explosives_Place { displayName = "SLAM"; model = "\A3\Weapons_F\Explosives\mine_SLAM_directional"; diff --git a/addons/explosives/CfgWeapons.hpp b/addons/explosives/CfgWeapons.hpp index a3f3b32d4c..9296813ee5 100644 --- a/addons/explosives/CfgWeapons.hpp +++ b/addons/explosives/CfgWeapons.hpp @@ -1,14 +1,24 @@ class CfgWeapons { - class ACE_ItemCore; - class InventoryItem_Base_f; + class Default; + class Put: Default { + muzzles[] += {QGVAR(muzzle)}; + class PutMuzzle: Default{}; + class GVAR(muzzle): PutMuzzle { + magazines[] = {"ACE_FlareTripMine_Mag"}; + }; + }; - class ACE_ExplosiveItem: InventoryItem_Base_f { + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + class ACE_ExplosiveItem: CBA_MiscItem_ItemInfo { allowedSlots[] = {801,701,901}; //type = 201; }; class ACE_Clacker: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(clacker_displayName); descriptionShort = CSTRING(clacker_description); picture = QPATHTOF(Data\UI\Clacker.paa); @@ -23,6 +33,7 @@ class CfgWeapons { }; }; class ACE_M26_Clacker: ACE_Clacker { + author = ECSTRING(common,ACETeam); displayName = CSTRING(M152_Clacker_displayName); picture = QPATHTOF(Data\UI\MK26_Transmitter_ca.paa); GVAR(Range) = 5000; @@ -30,6 +41,7 @@ class CfgWeapons { }; class ACE_DefusalKit: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(DefusalKit_displayName); descriptionShort = CSTRING(DefusalKit_description); picture = QPATHTOF(Data\UI\Pliers.paa); @@ -42,6 +54,7 @@ class CfgWeapons { }; class ACE_DeadManSwitch: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(DeadManSwitch_displayName); descriptionShort = CSTRING(DeadManSwitch_description); picture = QPATHTOF(Data\UI\DeadmanSwitch.paa); @@ -57,6 +70,7 @@ class CfgWeapons { }; class ACE_Cellphone: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(cellphone_displayName); descriptionShort = CSTRING(cellphone_description); picture = QPATHTOF(Data\UI\Cellphone_UI.paa); diff --git a/addons/explosives/ExplosivesUI.hpp b/addons/explosives/ExplosivesUI.hpp index cf97794d8f..7b0b2c6629 100644 --- a/addons/explosives/ExplosivesUI.hpp +++ b/addons/explosives/ExplosivesUI.hpp @@ -80,7 +80,7 @@ class RscACE_SelectTimeUI { y = 0.06; w = 0.49; h = 0.025; - onSliderPosChanged = "private ['_mins', '_secs'];_mins = floor((_this select 1)/60);_secs=floor((_this select 1) - (_mins*60));ctrlSetText [8870, format[localize 'STR_ACE_Explosives_TimerMenu',_mins, _secs]];"; + onSliderPosChanged = "_mins = floor((_this select 1)/60);_secs=floor((_this select 1) - (_mins*60));ctrlSetText [8870, format[localize 'STR_ACE_Explosives_TimerMenu',_mins, _secs]];"; }; class cancelBtn: RscButton { idc = 8855; diff --git a/addons/explosives/XEH_postInit.sqf b/addons/explosives/XEH_postInit.sqf index 7cc99bf921..d98064cfe1 100644 --- a/addons/explosives/XEH_postInit.sqf +++ b/addons/explosives/XEH_postInit.sqf @@ -41,18 +41,6 @@ if (isServer) then { TRACE_1("Knocked Out, Doing Deadman", _unit); [_unit] call FUNC(onIncapacitated); }] call CBA_fnc_addEventHandler; - - [QGVAR(sendOrientations), { - params ["_logic"]; - TRACE_1("sendOrientations received:",_logic); - // Filter the array before sending it - GVAR(explosivesOrientations) = GVAR(explosivesOrientations) select { - _x params ["_explosive"]; - (!isNull _explosive && {alive _explosive}) - }; - TRACE_1("orientationsSent sent:",GVAR(explosivesOrientations)); - [QGVAR(orientationsSent), [GVAR(explosivesOrientations)], _logic] call CBA_fnc_targetEvent; - }] call CBA_fnc_addEventHandler; }; if (!hasInterface) exitWith {}; @@ -62,27 +50,6 @@ GVAR(Setup) = objNull; GVAR(pfeh_running) = false; GVAR(CurrentSpeedDial) = 0; -// In case we are a JIP client, ask the server for orientation of any previously -// placed mine. -if (didJIP) then { - [QGVAR(orientationsSent), { - params ["_explosivesOrientations"]; - TRACE_1("orientationsSent received:",_explosivesOrientations); - { - _x params ["_explosive","_direction","_pitch"]; - TRACE_3("orientation set:",_explosive,_direction,_pitch); - [_explosive, _direction, _pitch] call FUNC(setPosition); - } forEach _explosivesOrientations; - deleteVehicle GVAR(localLogic); - GVAR(localLogic) = nil; - }] call CBA_fnc_addEventHandler; - - // Create a logic to get the client ID - GVAR(localLogic) = ([sideLogic] call CBA_fnc_getSharedGroup) createUnit ["Logic", [0,0,0], [], 0, "NONE"]; - TRACE_1("sendOrientations sent:",GVAR(localLogic)); - [QGVAR(sendOrientations), [GVAR(localLogic)]] call CBA_fnc_serverEvent; -}; - ["ace_interactMenuOpened", { //Cancel placement if interact menu opened if (GVAR(pfeh_running)) then { diff --git a/addons/explosives/XEH_preInit.sqf b/addons/explosives/XEH_preInit.sqf index 3a4d9a5aea..969b00e784 100644 --- a/addons/explosives/XEH_preInit.sqf +++ b/addons/explosives/XEH_preInit.sqf @@ -21,10 +21,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -if (isServer) then { - GVAR(explosivesOrientations) = [] -}; - GVAR(detonationHandlers) = []; ADDON = true; diff --git a/addons/explosives/functions/fnc_addCellphoneIED.sqf b/addons/explosives/functions/fnc_addCellphoneIED.sqf index df198fafb3..f577490933 100644 --- a/addons/explosives/functions/fnc_addCellphoneIED.sqf +++ b/addons/explosives/functions/fnc_addCellphoneIED.sqf @@ -21,39 +21,35 @@ params ["_unit", "_explosive", "_magazineClass", "_extra"]; TRACE_4("params",_unit,_explosive,_magazineClass,_extra); -private ["_config", "_detonators", "_hasRequired", "_requiredItems", "_code", "_count", "_codeSet"]; - // Config is the last item in the list of passed in items. -_config = (_this select 3) select (count (_this select 3) - 1); +private _config = (_this select 3) select (count (_this select 3) - 1); + +private _requiredItems = getArray (_config >> "requires"); +private _hasRequired = true; +private _detonators = [_unit] call FUNC(getDetonators); -_requiredItems = getArray(_config >> "requires"); -_hasRequired = true; -_detonators = [_unit] call FUNC(getDetonators); { if !(_x in _detonators) exitWith{ _hasRequired = false; }; } count _requiredItems; -_codeSet = false; -while {!_codeSet} do { - _code = str(round (random 9999)); - _count = 4 - count (toArray _code); - while {_count > 0} do { - _code = "0" + _code; - _count = _count - 1; - }; - _codeSet = (count ([_code] call FUNC(getSpeedDialExplosive))) == 0; +private _code = ""; +while {true} do { + _code = [floor(random 10000), 4] call CBA_fnc_formatNumber; + if (([_code] call FUNC(getSpeedDialExplosive)) isEqualTo []) exitWith {}; }; + if (isNil QGVAR(CellphoneIEDs)) then { GVAR(CellphoneIEDs) = []; }; -_count = GVAR(CellphoneIEDs) pushBack [_explosive,_code,GetNumber(ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> "Cellphone" >> "FuseTime")]; + +private _count = GVAR(CellphoneIEDs) pushBack [_explosive, _code, getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> "Cellphone" >> "FuseTime")]; _count = _count + 1; publicVariable QGVAR(CellphoneIEDs); //display IED number message: -[format ["IED %1 code: %2", _count,_code]] call EFUNC(common,displayTextStructured); +[format ["IED %1 code: %2", _count, _code]] call EFUNC(common,displayTextStructured); if !(_hasRequired) exitWith {}; -[format ["IED %1", _count],_code] call FUNC(addToSpeedDial); +[format ["IED %1", _count], _code] call FUNC(addToSpeedDial); diff --git a/addons/explosives/functions/fnc_addClacker.sqf b/addons/explosives/functions/fnc_addClacker.sqf index f8301f73fb..49915dc836 100644 --- a/addons/explosives/functions/fnc_addClacker.sqf +++ b/addons/explosives/functions/fnc_addClacker.sqf @@ -21,14 +21,12 @@ params ["_unit", "_explosive", "_magazineClass"]; TRACE_3("params",_unit,_explosive,_magazineClass); -private ["_clacker", "_config", "_requiredItems", "_hasRequired", "_detonators"]; - // Config is the last item in the list of passed in items. -_config = (_this select 3) select (count (_this select 3) - 1); +private _config = (_this select 3) select (count (_this select 3) - 1); -_requiredItems = getArray(_config >> "requires"); -_hasRequired = true; -_detonators = [_unit] call FUNC(getDetonators); +private _requiredItems = getArray(_config >> "requires"); +private _hasRequired = true; +private _detonators = [_unit] call FUNC(getDetonators); { if !(_x in _detonators) exitWith{ _hasRequired = false; @@ -36,9 +34,9 @@ _detonators = [_unit] call FUNC(getDetonators); } count _requiredItems; if !(_hasRequired) exitWith {}; -_config = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> configName _config; +private _config = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> configName _config; -_clacker = _unit getVariable [QGVAR(Clackers), []]; +private _clacker = _unit getVariable [QGVAR(Clackers), []]; GVAR(PlacedCount) = GVAR(PlacedCount) + 1; _clacker pushBack [_explosive, getNumber(_config >> "FuseTime"), format [localize LSTRING(DetonateCode), diff --git a/addons/explosives/functions/fnc_addDetonateActions.sqf b/addons/explosives/functions/fnc_addDetonateActions.sqf index 5b61de01f4..9c8d632253 100644 --- a/addons/explosives/functions/fnc_addDetonateActions.sqf +++ b/addons/explosives/functions/fnc_addDetonateActions.sqf @@ -19,18 +19,16 @@ params ["_unit", "_detonator"]; TRACE_2("params",_unit,_detonator); -private ["_result", "_item", "_children", "_range", "_required","_explosivesList"]; +private _range = getNumber (ConfigFile >> "CfgWeapons" >> _detonator >> QGVAR(Range)); -_range = getNumber (ConfigFile >> "CfgWeapons" >> _detonator >> QGVAR(Range)); - -_result = [_unit] call FUNC(getPlacedExplosives); -_children = []; -_explosivesList = []; +private _result = [_unit] call FUNC(getPlacedExplosives); +private _children = []; +private _explosivesList = []; { if (!isNull(_x select 0)) then { - _required = getArray (ConfigFile >> "ACE_Triggers" >> (_x select 4) >> "requires"); + private _required = getArray (ConfigFile >> "ACE_Triggers" >> (_x select 4) >> "requires"); if (_detonator in _required) then { - _item = ConfigFile >> "CfgMagazines" >> (_x select 3); + private _item = ConfigFile >> "CfgMagazines" >> (_x select 3); _explosivesList pushBack _x; diff --git a/addons/explosives/functions/fnc_addExplosiveActions.sqf b/addons/explosives/functions/fnc_addExplosiveActions.sqf index 888583b60c..9ef789345a 100644 --- a/addons/explosives/functions/fnc_addExplosiveActions.sqf +++ b/addons/explosives/functions/fnc_addExplosiveActions.sqf @@ -18,15 +18,13 @@ params ["_unit"]; TRACE_1("params",_unit); -private ["_mags", "_item", "_index", "_children", "_itemCount", "_list"]; - -_mags = magazines _unit; -_list = []; -_itemCount = []; +private _mags = magazines _unit; +private _list = []; +private _itemCount = []; { - _item = ConfigFile >> "CfgMagazines" >> _x; + private _item = ConfigFile >> "CfgMagazines" >> _x; if (getNumber(_item >> QGVAR(Placeable)) == 1) then { - _index = _list find _item; + private _index = _list find _item; if (_index != -1) then { _itemCount set [_index, (_itemCount select _index) + 1]; } else { @@ -36,7 +34,7 @@ _itemCount = []; }; } forEach _mags; -_children = []; +private _children = []; { private _name = getText (_x >> "displayNameShort"); diff --git a/addons/explosives/functions/fnc_addToSpeedDial.sqf b/addons/explosives/functions/fnc_addToSpeedDial.sqf index 7ad0fe76da..db0a1c0ca5 100644 --- a/addons/explosives/functions/fnc_addToSpeedDial.sqf +++ b/addons/explosives/functions/fnc_addToSpeedDial.sqf @@ -19,10 +19,8 @@ params ["_name", "_code"]; TRACE_2("params",_name,_code); -private ["_speedDial", "_found"]; - -_speedDial = ace_player getVariable [QGVAR(SpeedDial), []]; -_found = false; +private _speedDial = ace_player getVariable [QGVAR(SpeedDial), []]; +private _found = false; if ((_code) == "") exitWith { [_name] call FUNC(removeFromSpeedDial); diff --git a/addons/explosives/functions/fnc_addTransmitterActions.sqf b/addons/explosives/functions/fnc_addTransmitterActions.sqf index 418d99a0df..f23d7005a6 100644 --- a/addons/explosives/functions/fnc_addTransmitterActions.sqf +++ b/addons/explosives/functions/fnc_addTransmitterActions.sqf @@ -18,12 +18,10 @@ params ["_unit"]; TRACE_1("params",_unit); -private ["_children", "_config", "_detonators"]; - -_detonators = [_unit] call FUNC(getDetonators); -_children = []; +private _detonators = [_unit] call FUNC(getDetonators); +private _children = []; { - _config = ConfigFile >> "CfgWeapons" >> _x; + private _config = ConfigFile >> "CfgWeapons" >> _x; _children pushBack [ [ diff --git a/addons/explosives/functions/fnc_addTriggerActions.sqf b/addons/explosives/functions/fnc_addTriggerActions.sqf index ca444a4e31..cdee713ecb 100644 --- a/addons/explosives/functions/fnc_addTriggerActions.sqf +++ b/addons/explosives/functions/fnc_addTriggerActions.sqf @@ -19,16 +19,14 @@ params ["_magazine", "_explosive"]; TRACE_2("params",_magazine,_explosive); -private ["_hasRequiredItems","_triggerTypes", "_children", "_detonators", "_required", "_magTriggers", "_isAttached"]; - -_isAttached = !isNull (attachedTo _explosive); -_detonators = [ACE_player] call FUNC(getDetonators); -_triggerTypes = [_magazine] call FUNC(triggerType); -_magTriggers = ConfigFile >> "CfgMagazines" >> _magazine >> "ACE_Triggers"; -_children = []; +private _isAttached = !isNull (attachedTo _explosive); +private _detonators = [ACE_player] call FUNC(getDetonators); +private _triggerTypes = [_magazine] call FUNC(triggerType); +private _magTriggers = ConfigFile >> "CfgMagazines" >> _magazine >> "ACE_Triggers"; +private _children = []; { - _required = getArray (_x >> "requires"); - _hasRequiredItems = true; + private _required = getArray (_x >> "requires"); + private _hasRequiredItems = true; { if !(_x in _detonators) exitWith { _hasRequiredItems = false; diff --git a/addons/explosives/functions/fnc_detonateExplosive.sqf b/addons/explosives/functions/fnc_detonateExplosive.sqf index 822a04aeaf..3e0f3bdf6f 100644 --- a/addons/explosives/functions/fnc_detonateExplosive.sqf +++ b/addons/explosives/functions/fnc_detonateExplosive.sqf @@ -24,12 +24,10 @@ params ["_unit", "_range", "_item", ["_triggerClassname", "#unknown", [""]]]; TRACE_4("detonateExplosive",_unit,_range,_item,_triggerClassname); -private ["_result", "_ignoreRange", "_pos"]; - -_ignoreRange = (_range == -1); +private _ignoreRange = (_range == -1); if (!_ignoreRange && {(_unit distance (_item select 0)) > _range}) exitWith {TRACE_1("out of range",_range); false}; -_result = true; +private _result = true; { // Pass [Unit, MaxRange , Explosive , FuzeTime , TriggerItem ] private _handlerResult = [_unit, _range, _item select 0, _item select 1, _triggerClassname] call _x; @@ -38,19 +36,25 @@ _result = true; if (!_result) exitWith {false}; if (getNumber (ConfigFile >> "CfgAmmo" >> typeOf (_item select 0) >> "TriggerWhenDestroyed") == 0) then { - private ["_exp", "_previousExp"]; - _previousExp = _item select 0; - _exp = getText (ConfigFile >> "CfgAmmo" >> typeOf (_previousExp) >> QGVAR(Explosive)); + private _previousExp = _item select 0; + private _exp = getText (ConfigFile >> "CfgAmmo" >> typeOf (_previousExp) >> QGVAR(Explosive)); if (_exp != "") then { _exp = createVehicle [_exp, [0,0,15001], [], 0, "NONE"]; _exp setDir (getDir _previousExp); _item set [0, _exp]; - _pos = getPosASL _previousExp; + private _pos = getPosASL _previousExp; deleteVehicle _previousExp; _exp setPosASL _pos; }; }; +if (isNull (_item select 0)) then { + WARNING_1("Explosive is null [%1]",_this); +}; +if ((getNumber (configFile >> "CfgAmmo" >> (typeOf (_item select 0)) >> "triggerWhenDestroyed")) != 1) then { + WARNING_1("Explosive is not triggerWhenDestroyed [%1]",typeOf (_item select 0)); +}; + [QGVAR(detonate), [_unit, _item select 0, _item select 1]] call CBA_fnc_serverEvent; _result diff --git a/addons/explosives/functions/fnc_dialPhone.sqf b/addons/explosives/functions/fnc_dialPhone.sqf index 7e715c2ac7..f4bdd68279 100644 --- a/addons/explosives/functions/fnc_dialPhone.sqf +++ b/addons/explosives/functions/fnc_dialPhone.sqf @@ -19,23 +19,20 @@ params ["_unit", "_code"]; TRACE_2("params",_unit,_code); -private ["_arr", "_ran", "_i"]; - if (_unit getVariable [QGVAR(Dialing),false]) exitWith {}; if !(alive _unit) exitWith {}; _unit setVariable [QGVAR(Dialing), true, true]; -_ran = (ceil(random 8)) + 1; -_arr = []; -for [{_i=0}, {_i<_ran}, {_i=_i + 1}] do { +private _ran = (ceil(random 8)) + 1; +private _arr = []; +for "_i" from 1 to _ran do { _arr = _arr + ['.','..','...','']; }; if (_unit == ace_player) then { ctrlSetText [1400,"Calling"]; [FUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); } else { - private ["_explosive"]; - _explosive = [_code] call FUNC(getSpeedDialExplosive); + private _explosive = [_code] call FUNC(getSpeedDialExplosive); if ((count _explosive) > 0) then { [{ playSound3D [QUOTE(PATHTO_R(Data\Audio\Cellphone_Ring.wss)),objNull, false, getPosASL (_this select 1),3.16228,1,75]; diff --git a/addons/explosives/functions/fnc_getPlacedExplosives.sqf b/addons/explosives/functions/fnc_getPlacedExplosives.sqf index e2e56824ec..beb24d559d 100644 --- a/addons/explosives/functions/fnc_getPlacedExplosives.sqf +++ b/addons/explosives/functions/fnc_getPlacedExplosives.sqf @@ -21,16 +21,14 @@ params ["_unit"]; TRACE_1("params",_unit); -private ["_clackerList", "_adjustedList", "_list", "_filter"]; - -_filter = nil; +private _filter = nil; if (count _this > 1) then { _filter = ConfigFile >> "ACE_Triggers" >> (_this select 1); }; -_clackerList = []; -_adjustedList = false; +private _clackerList = []; +private _adjustedList = false; _clackerList = _unit getVariable [QGVAR(Clackers), []]; -_list = []; +private _list = []; { if (isNull (_x select 0)) then { _clackerList set [_forEachIndex, "X"]; diff --git a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf index b6bd9b6e6f..1c98ca853d 100644 --- a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf +++ b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf @@ -18,10 +18,8 @@ params ["_code"]; TRACE_1("params",_code); -private ["_explosive"]; - if (isNil QGVAR(CellphoneIEDs)) exitWith {[]}; -_explosive = []; +private _explosive = []; { if ((_x select 1) == _code) exitWith { _explosive = _x; diff --git a/addons/explosives/functions/fnc_hasExplosives.sqf b/addons/explosives/functions/fnc_hasExplosives.sqf index c9da5e59d1..f86c928ca3 100644 --- a/addons/explosives/functions/fnc_hasExplosives.sqf +++ b/addons/explosives/functions/fnc_hasExplosives.sqf @@ -18,10 +18,8 @@ params ["_unit"]; TRACE_1("params",_unit); -private ["_result", "_magazines"]; - -_result = false; -_magazines = magazines _unit; +private _result = false; +private _magazines = magazines _unit; { if (getNumber (ConfigFile >> "CfgMagazines" >> _x >> QGVAR(Placeable)) == 1) exitWith { _result = true; diff --git a/addons/explosives/functions/fnc_interactEH.sqf b/addons/explosives/functions/fnc_interactEH.sqf index eac82bcddb..b42acd5cec 100644 --- a/addons/explosives/functions/fnc_interactEH.sqf +++ b/addons/explosives/functions/fnc_interactEH.sqf @@ -41,12 +41,12 @@ if (!("ACE_DefusalKit" in (items ACE_player))) exitWith {}; //If player moved >5 meters from last pos, then rescan if (((getPosASL ace_player) distance _setPosition) > 5) then { { - if (((_x distance ACE_player) < 15) && {!(_x in _minesHelped)}) then { + if (((_x distance ACE_player) < 15) && {!(_x in _minesHelped)} && {(getModelInfo _x) select 0 != "empty.p3d"}) then { private _config = configFile >> "CfgAmmo" >> typeOf _x; private _size = getNumber (_config >> QGVAR(size)); TRACE_3("Making Defuse Helper",(_x),(typeOf _x),(_size == 1)); - private ["_defuseHelper"]; + private _defuseHelper = objNull; if (_size == 1) then { _defuseHelper = "ACE_DefuseObject_Large" createVehicleLocal (getPos _x); } else { diff --git a/addons/explosives/functions/fnc_module.sqf b/addons/explosives/functions/fnc_module.sqf index cbe7c3e2ad..f6a486591a 100644 --- a/addons/explosives/functions/fnc_module.sqf +++ b/addons/explosives/functions/fnc_module.sqf @@ -15,8 +15,6 @@ */ #include "script_component.hpp" -if !(isServer) exitWith {}; - params ["_logic"]; [_logic, QGVAR(RequireSpecialist), "RequireSpecialist"] call EFUNC(Common,readSettingFromModule); diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index 6f9a9f498a..7e2cb249cc 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -19,6 +19,11 @@ params ["_unit"]; TRACE_1("params",_unit); +if (_unit == ace_player) then { + // close cellphone if open + closeDialog 0; +}; + // Exit if no item: if (({_x == "ACE_DeadManSwitch"} count (items _unit)) == 0) exitWith {}; diff --git a/addons/explosives/functions/fnc_onInventoryChanged.sqf b/addons/explosives/functions/fnc_onInventoryChanged.sqf index f67995b1c9..185fdef6c3 100644 --- a/addons/explosives/functions/fnc_onInventoryChanged.sqf +++ b/addons/explosives/functions/fnc_onInventoryChanged.sqf @@ -25,8 +25,7 @@ if ((_receiver != ace_player) && {_giver != ace_player}) exitWith {}; private _config = ConfigFile >> "CfgWeapons" >> _item; if (isClass _config && {getNumber(_config >> QGVAR(Detonator)) == 1}) then { - private ["_clackerItems"]; - _clackerItems = _giver getVariable [QGVAR(Clackers), []]; + private _clackerItems = _giver getVariable [QGVAR(Clackers), []]; _receiver setVariable [QGVAR(Clackers), (_receiver getVariable [QGVAR(Clackers), []]) + _clackerItems, true]; private _detonators = [_giver] call FUNC(getDetonators); diff --git a/addons/explosives/functions/fnc_placeExplosive.sqf b/addons/explosives/functions/fnc_placeExplosive.sqf index 5114f907ac..d0d93df4c1 100644 --- a/addons/explosives/functions/fnc_placeExplosive.sqf +++ b/addons/explosives/functions/fnc_placeExplosive.sqf @@ -1,6 +1,6 @@ /* * Author: Garth 'L-H' de Wet - * Places an explosive at the requested position + * Places an explosive at the requested position. * * Arguments: * 0: Unit @@ -9,14 +9,13 @@ * 3: Magazine class * 4: Config of trigger * 5: Variables required for the trigger type - * 6: Explosive placeholder + * 6: Explosive placeholder (default: objNull) * * Return Value: * Placed explosive * * Example: - * _explosive = [player, player modelToWorldVisual [0,0.5, 0.1], 134, - * "SatchelCharge_Remote_Mag", "Command", []] call ACE_Explosives_fnc_placeExplosive; + * _explosive = [player, player modelToWorldVisual [0,0.5, 0.1], 134, "SatchelCharge_Remote_Mag", "Command", []] call ace_explosives_fnc_placeExplosive * * Public: Yes */ @@ -25,11 +24,9 @@ params ["_unit", "_pos", "_dir", "_magazineClass", "_triggerConfig", "_triggerSpecificVars", ["_setupPlaceholderObject", objNull]]; TRACE_7("params",_unit,_pos,_dir,_magazineClass,_triggerConfig,_triggerSpecificVars,_setupPlaceholderObject); -private ["_ammo", "_explosive", "_attachedTo", "_magazineTrigger", "_pitch", "_digDistance", "_canDigDown", "_soundEnviron", "_surfaceType"]; - [_unit, "PutDown"] call EFUNC(common,doGesture); -_attachedTo = objNull; +private _attachedTo = objNull; if (!isNull _setupPlaceholderObject) then { _attachedTo = attachedTo _setupPlaceholderObject; deleteVehicle _setupPlaceholderObject; @@ -40,7 +37,7 @@ if (isNil "_triggerConfig") exitWith { objNull }; -_magazineTrigger = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> _triggerConfig; +private _magazineTrigger = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> _triggerConfig; _triggerConfig = ConfigFile >> "ACE_Triggers" >> _triggerConfig; if (isNil "_triggerConfig") exitWith { @@ -48,7 +45,7 @@ if (isNil "_triggerConfig") exitWith { objNull }; -_ammo = getText(ConfigFile >> "CfgMagazines" >> _magazineClass >> "ammo"); +private _ammo = getText(ConfigFile >> "CfgMagazines" >> _magazineClass >> "ammo"); if (isText(_magazineTrigger >> "ammo")) then { _ammo = getText (_magazineTrigger >> "ammo"); }; @@ -56,14 +53,14 @@ _triggerSpecificVars pushBack _triggerConfig; //Dig the explosive down into the ground (usually on "pressurePlate") if (isNumber (_magazineTrigger >> "digDistance")) then { - _digDistance = getNumber (_magazineTrigger >> "digDistance"); + private _digDistance = getNumber (_magazineTrigger >> "digDistance"); //Get Surface Type: - _canDigDown = true; - _surfaceType = surfaceType _pos; + private _canDigDown = true; + private _surfaceType = surfaceType _pos; if ((_surfaceType select [0,1]) == "#") then {_surfaceType = _surfaceType select [1, 99];}; if ((_surfaceType != "") || {isClass (configFile >> "CfgSurfaces" >> _surfaceType >> "soundEnviron")}) then { - _soundEnviron = getText (configFile >> "CfgSurfaces" >> _surfaceType >> "soundEnviron"); + private _soundEnviron = getText (configFile >> "CfgSurfaces" >> _surfaceType >> "soundEnviron"); TRACE_2("Dig Down Surface",_surfaceType,_soundEnviron); _canDigDown = !(_soundEnviron in ["road", "tarmac", "concrete", "concrete_int", "int_concrete", "concrete_ext"]); }; @@ -76,7 +73,7 @@ if (isNumber (_magazineTrigger >> "digDistance")) then { }; }; -_explosive = createVehicle [_ammo, _pos, [], 0, "NONE"]; +private _explosive = createVehicle [_ammo, _pos, [], 0, "NONE"]; _explosive setPosATL _pos; if (!isNull _attachedTo) then { @@ -92,7 +89,7 @@ if (isText(_triggerConfig >> "onPlace") && {[_unit,_explosive,_magazineClass,_tr //TODO: placing explosives on hills looks funny -_pitch = getNumber (_magazineTrigger >> "pitch"); +private _pitch = getNumber (_magazineTrigger >> "pitch"); //Globaly set the position and angle: [QGVAR(place), [_explosive, _dir, _pitch, _unit]] call CBA_fnc_globalEvent; diff --git a/addons/explosives/functions/fnc_scriptedExplosive.sqf b/addons/explosives/functions/fnc_scriptedExplosive.sqf index ff7a2ca1a0..5c27e35e60 100644 --- a/addons/explosives/functions/fnc_scriptedExplosive.sqf +++ b/addons/explosives/functions/fnc_scriptedExplosive.sqf @@ -1,19 +1,18 @@ /* * Author: VKing - * Detonate explosives via script, for use in triggers or mission scripts to - * detonate editor-placed explosives. + * Detonate explosives via script, for use in triggers or mission scripts to detonate editor-placed explosives. * * Arguments: * 0: Explosives objects to detonate - * 1: Fuze delay (for each explosive; use negative number for random time up to value) - * 2: Trigger Item Classname + * 1: Fuze delay (for each explosive; use negative number for random time up to value) (default: 0) + * 2: Trigger Item Classname (default: "#scripted") * * Return Value: * None * * Example: - * [[charge1, charge2, charge3], -1] call ACE_Explosives_fnc_scriptedExplosive; - * [[claymore1, claymore2]] call ACE_Explosives_fnc_scriptedExplosive; + * [[charge1, charge2, charge3], -1] call ace_explosives_fnc_scriptedExplosive + * [[claymore1, claymore2]] call ace_explosives_fnc_scriptedExplosive * * Public: Yes */ diff --git a/addons/explosives/functions/fnc_setPosition.sqf b/addons/explosives/functions/fnc_setPosition.sqf index 430f926138..b19e63ff5a 100644 --- a/addons/explosives/functions/fnc_setPosition.sqf +++ b/addons/explosives/functions/fnc_setPosition.sqf @@ -29,15 +29,3 @@ if (isNull (attachedTo _explosive)) then { //Attaching to a vehicle (dirAndUp based on vehicle) _explosive setVectorDirAndUp [[0,0,1],[(sin _direction),(cos _direction),0]]; }; - -if (isServer) then { - // Store the orientation to broadcast it later to JIP players - GVAR(explosivesOrientations) pushBack [_explosive, _direction, _pitch]; - - // This is a good time to filter the array and remove explosives that no longer exist - GVAR(explosivesOrientations) = GVAR(explosivesOrientations) select { - _x params ["_explosive"]; - (!isNull _explosive && {alive _explosive}) - }; - TRACE_1("setPosition",GVAR(explosivesOrientations)); -}; diff --git a/addons/explosives/functions/fnc_setupExplosive.sqf b/addons/explosives/functions/fnc_setupExplosive.sqf index 47608d03e5..6e356a6f8d 100644 --- a/addons/explosives/functions/fnc_setupExplosive.sqf +++ b/addons/explosives/functions/fnc_setupExplosive.sqf @@ -24,15 +24,14 @@ params ["_vehicle", "_unit", "_magClassname"]; TRACE_3("params",_vehicle,_unit,_magClassname); -private ["_isAttachable", "_setupObjectClass", "_supportedTriggers", "_p3dModel"]; - //Get setup object vehicle and model: -_setupObjectClass = getText(ConfigFile >> "CfgMagazines" >> _magClassname >> QGVAR(SetupObject)); +private _setupObjectClass = getText(ConfigFile >> "CfgMagazines" >> _magClassname >> QGVAR(SetupObject)); if (!isClass (configFile >> "CfgVehicles" >> _setupObjectClass)) exitWith {ERROR("Bad Vehicle");}; -_p3dModel = getText (configFile >> "CfgVehicles" >> _setupObjectClass >> "model"); +private _p3dModel = getText (configFile >> "CfgVehicles" >> _setupObjectClass >> "model"); if (_p3dModel == "") exitWith {ERROR("No Model");}; //"" - will crash game! [_unit, "forceWalk", "ACE_Explosives", true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Explosives", true] call EFUNC(common,statusEffect_set); //Show mouse buttons: [localize LSTRING(PlaceAction), localize LSTRING(CancelAction), localize LSTRING(ScrollAction)] call EFUNC(interaction,showMouseHint); @@ -44,8 +43,8 @@ _unit setVariable [QGVAR(cancelActionEH), [_unit, "zoomtemp", {true}, {GVAR(plac ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetModel _p3dModel; //Make sure it has a trigger that works when attached (eg, no tripwires that only do pressurePlate) -_isAttachable = false; -_supportedTriggers = getArray (configFile >> "CfgMagazines" >> _magClassname >> "ACE_Triggers" >> "SupportedTriggers"); +private _isAttachable = false; +private _supportedTriggers = getArray (configFile >> "CfgMagazines" >> _magClassname >> "ACE_Triggers" >> "SupportedTriggers"); { if ((getNumber (configFile >> "ACE_Triggers" >> _x >> "isAttachable")) == 1) exitWith {_isAttachable = true;}; } forEach _supportedTriggers; @@ -62,10 +61,8 @@ GVAR(TweakedAngle) = 0; params ["_args", "_pfID"]; _args params ["_unit", "_magClassname", "_setupObjectClass", "_isAttachable"]; - private ["_angle", "_attachVehicle", "_badPosition", "_basePosASL", "_cameraAngle", "_distanceFromBase", "_expSetupVehicle", "_index", "_intersectsWith", "_lookDirVector", "_max", "_min", "_modelDir", "_modelOffset", "_modelUp", "_placeAngle", "_realDistance", "_return", "_screenPos", "_testBase", "_testPos", "_testPositionIsValid", "_virtualPosASL"]; - - _lookDirVector = ((positionCameraToWorld [0,0,0]) call EFUNC(common,positionToASL)) vectorFromTo ((positionCameraToWorld [0,0,10]) call EFUNC(common,positionToASL)); - _basePosASL = (eyePos _unit); + private _lookDirVector = ((positionCameraToWorld [0,0,0]) call EFUNC(common,positionToASL)) vectorFromTo ((positionCameraToWorld [0,0,10]) call EFUNC(common,positionToASL)); + private _basePosASL = (eyePos _unit); if (cameraView == "EXTERNAL") then { //If external, show explosive over the right shoulder _basePosASL = _basePosASL vectorAdd ((positionCameraToWorld [0.3,0,0]) vectorDiff (positionCameraToWorld [0,0,0])); }; @@ -74,13 +71,13 @@ GVAR(TweakedAngle) = 0; _basePosASL set [2, ((_basePosASL select 2) - 0.3)]; _lookDirVector = ((positionCameraToWorld [0,0,0]) call EFUNC(common,positionToASL)) vectorFromTo ((positionCameraToWorld [0,3,10]) call EFUNC(common,positionToASL)); }; - _cameraAngle = (_lookDirVector select 0) atan2 (_lookDirVector select 1); + private _cameraAngle = (_lookDirVector select 0) atan2 (_lookDirVector select 1); - _testPositionIsValid = { - _testBase = _basePosASL vectorAdd (_lookDirVector vectorMultiply (_this select 0)); - _return = true; + private _testPositionIsValid = { + private _testBase = _basePosASL vectorAdd (_lookDirVector vectorMultiply (_this select 0)); + private _return = true; { - _testPos = _testBase vectorAdd [0.1 * (_x select 0) * (cos _cameraAngle), 0.1 * (_x select 0) * (sin _cameraAngle), 0.1 * (_x select 1)]; + private _testPos = _testBase vectorAdd [0.1 * (_x select 0) * (cos _cameraAngle), 0.1 * (_x select 0) * (sin _cameraAngle), 0.1 * (_x select 1)]; #ifdef DEBUG_MODE_FULL drawLine3d [(eyePos _unit) call EFUNC(common,ASLToPosition), (_testPos) call EFUNC(common,ASLToPosition), [1,0,0,1]]; #endif @@ -89,22 +86,22 @@ GVAR(TweakedAngle) = 0; _return }; - _distanceFromBase = PLACE_RANGE_MAX; - _badPosition = !([_distanceFromBase] call _testPositionIsValid); - _attachVehicle = objNull; + private _distanceFromBase = PLACE_RANGE_MAX; + private _badPosition = !([_distanceFromBase] call _testPositionIsValid); + private _attachVehicle = objNull; if (_isAttachable && _badPosition) then { _attachVehicle = objNull; - _testBase = _basePosASL vectorAdd _lookDirVector; + private _testBase = _basePosASL vectorAdd _lookDirVector; { - _testPos = _testBase vectorAdd [0.1 * (_x select 0) * (cos _cameraAngle), 0.1 * (_x select 0) * (sin _cameraAngle), 0.1 * (_x select 1)]; - _intersectsWith = lineIntersectsWith [eyePos _unit, _testPos, _unit]; + private _testPos = _testBase vectorAdd [0.1 * (_x select 0) * (cos _cameraAngle), 0.1 * (_x select 0) * (sin _cameraAngle), 0.1 * (_x select 1)]; + private _intersectsWith = lineIntersectsWith [eyePos _unit, _testPos, _unit]; if (count _intersectsWith == 1) exitWith {_attachVehicle = (_intersectsWith select 0);}; } forEach [[0,0], [-1,-1], [1,-1], [-1,1], [1,1]]; if ((!isNull _attachVehicle) && {[PLACE_RANGE_MIN] call _testPositionIsValid} && {(_attachVehicle isKindOf "Car") || {_attachVehicle isKindOf "Tank"} || {_attachVehicle isKindOf "Air"} || {_attachVehicle isKindOf "Ship"}}) then { - _min = PLACE_RANGE_MIN; - _max = PLACE_RANGE_MAX; + private _min = PLACE_RANGE_MIN; + private _max = PLACE_RANGE_MAX; for "_index" from 0 to 6 do { _distanceFromBase = (_min + _max) / 2; if ([_distanceFromBase] call _testPositionIsValid) then { @@ -120,7 +117,7 @@ GVAR(TweakedAngle) = 0; }; }; - _virtualPosASL = _basePosASL vectorAdd (_lookDirVector vectorMultiply _distanceFromBase); + private _virtualPosASL = _basePosASL vectorAdd (_lookDirVector vectorMultiply _distanceFromBase); //Update mouse hint: if (_badPosition) then { @@ -153,6 +150,7 @@ GVAR(TweakedAngle) = 0; GVAR(pfeh_running) = false; [_unit, "forceWalk", "ACE_Explosives", false] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", "ACE_Explosives", false] call EFUNC(common,statusEffect_set); [] call EFUNC(interaction,hideMouseHint); [_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler); [_unit, "zoomtemp", (_unit getVariable [QGVAR(cancelActionEH), -1])] call EFUNC(common,removeActionEventHandler); @@ -160,8 +158,8 @@ GVAR(TweakedAngle) = 0; (QGVAR(virtualAmmo) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; if (GVAR(placeAction) == PLACE_APPROVE) then { - _placeAngle = 0; - _expSetupVehicle = _setupObjectClass createVehicle (_virtualPosASL call EFUNC(common,ASLToPosition)); + private _placeAngle = 0; + private _expSetupVehicle = _setupObjectClass createVehicle (_virtualPosASL call EFUNC(common,ASLToPosition)); TRACE_1("Planting Mass", (getMass _expSetupVehicle)); //If the object is too heavy, it can kill a player if it colides @@ -173,7 +171,7 @@ GVAR(TweakedAngle) = 0; _expSetupVehicle setDir _placeAngle; _placeAngle = _placeAngle + 180; //CfgAmmos seem to be 180 for some reason } else { - _modelOffset = _attachVehicle worldToModel (_virtualPosASL call EFUNC(common,ASLToPosition)); + private _modelOffset = _attachVehicle worldToModel (_virtualPosASL call EFUNC(common,ASLToPosition)); _placeAngle = _cameraAngle - (getDir _attachVehicle) + 180; _expSetupVehicle attachTo [_attachVehicle, _modelOffset]; _expSetupVehicle setVectorDirAndUp [[0,0,-1],[(sin _placeAngle),(cos _placeAngle),0]]; @@ -191,21 +189,21 @@ GVAR(TweakedAngle) = 0; }; } else { - _screenPos = worldToScreen (_virtualPosASL call EFUNC(common,ASLToPosition)); + private _screenPos = worldToScreen (_virtualPosASL call EFUNC(common,ASLToPosition)); if (_badPosition || {_screenPos isEqualTo []}) then { ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlShow false; } else { //Show the model on the hud in aprox the same size/location as it will be placed: ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlShow true; - _realDistance = ((_virtualPosASL call EFUNC(common,ASLToPosition)) distance (positionCameraToWorld [0,0,0])) / ((call CBA_fnc_getFov) select 1); + private _realDistance = ((_virtualPosASL call EFUNC(common,ASLToPosition)) distance (positionCameraToWorld [0,0,0])) / ((call CBA_fnc_getFov) select 1); _screenPos = [(_screenPos select 0), _realDistance, (_screenPos select 1)]; ((uiNamespace getVariable [QGVAR(virtualAmmoDisplay), displayNull]) displayCtrl 800851) ctrlSetPosition _screenPos; - _modelDir = [0,0,-1]; - _modelUp = [0,-1,0]; + private _modelDir = [0,0,-1]; + private _modelUp = [0,-1,0]; if (isNull _attachVehicle) then { - _angle = acos (_lookDirVector select 2); + private _angle = acos (_lookDirVector select 2); _modelUp = [0, (cos _angle), (sin _angle)]; _modelDir = [cos GVAR(TweakedAngle), sin GVAR(TweakedAngle), 0] vectorCrossProduct _modelUp; }; diff --git a/addons/explosives/functions/fnc_startDefuse.sqf b/addons/explosives/functions/fnc_startDefuse.sqf index 375f1562e1..ebc290f4ab 100644 --- a/addons/explosives/functions/fnc_startDefuse.sqf +++ b/addons/explosives/functions/fnc_startDefuse.sqf @@ -19,15 +19,12 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); -private ["_actionToPlay", "_defuseTime", "_isEOD"]; - _target = attachedTo (_target); -_fnc_DefuseTime = { +private _fnc_DefuseTime = { params ["_specialist", "_target"]; TRACE_2("defuseTime",_specialist,_target); - private ["_defuseTime"]; - _defuseTime = 5; + private _defuseTime = 5; if (isNumber(ConfigFile >> "CfgAmmo" >> typeOf (_target) >> QGVAR(DefuseTime))) then { _defuseTime = getNumber(ConfigFile >> "CfgAmmo" >> typeOf (_target) >> QGVAR(DefuseTime)); }; @@ -36,7 +33,7 @@ _fnc_DefuseTime = { }; _defuseTime }; -_actionToPlay = "MedicOther"; +private _actionToPlay = "MedicOther"; if (STANCE _unit == "Prone") then { _actionToPlay = "PutDown"; }; @@ -49,7 +46,7 @@ if (ACE_player != _unit) then { [_unit, _actionToPlay] call EFUNC(common,doGesture); _unit disableAI "MOVE"; _unit disableAI "TARGET"; - _defuseTime = [[_unit] call EFUNC(Common,isEOD), _target] call _fnc_DefuseTime; + private _defuseTime = [[_unit] call EFUNC(Common,isEOD), _target] call _fnc_DefuseTime; [{ params ["_unit", "_target"]; TRACE_2("defuse finished",_unit,_target); @@ -60,8 +57,8 @@ if (ACE_player != _unit) then { }; } else { [_unit, _actionToPlay] call EFUNC(common,doGesture); - _isEOD = [_unit] call EFUNC(Common,isEOD); - _defuseTime = [_isEOD, _target] call _fnc_DefuseTime; + private _isEOD = [_unit] call EFUNC(Common,isEOD); + private _defuseTime = [_isEOD, _target] call _fnc_DefuseTime; if (_isEOD || {!GVAR(RequireSpecialist)}) then { [_defuseTime, [_unit,_target], {(_this select 0) call FUNC(defuseExplosive)}, {}, (localize LSTRING(DefusingExplosive)), {true}, ["isNotSwimming"]] call EFUNC(common,progressBar); }; diff --git a/addons/explosives/functions/fnc_startTimer.sqf b/addons/explosives/functions/fnc_startTimer.sqf index 6694d5dc0d..737e6a6586 100644 --- a/addons/explosives/functions/fnc_startTimer.sqf +++ b/addons/explosives/functions/fnc_startTimer.sqf @@ -5,13 +5,13 @@ * Arguments: * 0: Explosive * 1: Time till detonate - * 2: Trigger Item Classname + * 2: Trigger Item Classname (default: "#timer") * * Return Value: * None * * Example: - * [_explosive, 10] call ACE_Explosives_fnc_startTimer; + * [_explosive, 10] call ace_explosives_fnc_startTimer * * Public: Yes */ diff --git a/addons/explosives/functions/fnc_triggerType.sqf b/addons/explosives/functions/fnc_triggerType.sqf index 7f763dbdea..b704e56466 100644 --- a/addons/explosives/functions/fnc_triggerType.sqf +++ b/addons/explosives/functions/fnc_triggerType.sqf @@ -18,11 +18,9 @@ params ["_magazineClassname"]; TRACE_1("params",_magazineClassname); -private ["_result", "_config", "_count", "_index"]; - -_result = []; -_config = getArray (ConfigFile >> "CfgMagazines" >> _magazineClassname >> "ACE_Triggers" >> "SupportedTriggers"); -_count = count _config; +private _result = []; +private _config = getArray (ConfigFile >> "CfgMagazines" >> _magazineClassname >> "ACE_Triggers" >> "SupportedTriggers"); +private _count = count _config; for "_index" from 0 to (_count - 1) do { _result set [_index, ConfigFile >> "ACE_Triggers" >> (_config select _index)]; diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index f34a160cca..2ca36bcdc1 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -154,7 +154,7 @@ Obrót Rotaciona Bращать - 向きを変える + 回転 회전 旋转 旋轉 @@ -474,7 +474,7 @@ Robbanóanyag hatástalanítása... Desarmando Explosivo... Обезвреживание... - 爆発物を無力化中・・・ + 爆発物を無力化しています・・・ 폭발물 해체중... 炸弹拆除中... 炸彈拆除中... @@ -634,7 +634,7 @@ Infravörös szenzor (Side Attack) Sensor infravermelho (ataque lateral) ИК сенсор (детонация вбок) - 赤外線感知式 (横からの攻撃) + 赤外線感知式 (側面攻撃) 적외선 센서 (측면 공격) 红外线感应器 (侧边攻击) 紅外線感應器 (側邊攻擊) @@ -650,7 +650,7 @@ Mágneses mező érzékelő (Bottom Attack) Influência magnética (ataque inferior) Магнитный сенсор (детонация вверх) - 磁気感知式 (下からの攻撃) + 磁気感知式 (底面攻撃) 자기장 감지센서 (바닥 공격) 磁性感应器 (底部攻击) 磁性感應器 (底部攻擊) @@ -746,7 +746,7 @@ Specialisták igénylése? Требуется специалист? Richiedi specialisti? - 特技兵を必要としますか? + 特技兵を必要としますか? 전문가가 필요합니까? 需要专家? 需要專家? @@ -762,7 +762,7 @@ Szükséges-e egy specialista a robbanóanyagok hatástalanításához? Alapértelmezett: Nem Требуется ли специалист по минному делу для обезвреживания взрывчатки? По-умолчанию: Нет Richiedi specialisti esplosivi per disabilitare esplosivi? Default: No - 爆発物を無効化するには、爆発物の特技兵を必要としますか?標準:いいえ + 爆発物を無効化するには、爆発物の特技兵を必要としますか? 標準: 無効化 폭발물을 해제하기 위해서는 전문가가 필요합니까? 기본설정: 아니요 需要炸弹专家才能拆除炸弹? 预设: 否 需要炸彈專家才能拆除炸彈? 預設: 否 @@ -778,7 +778,7 @@ Nem-specialisták büntetése? Штраф не-специалистам? Punisci non-specialisti? - 非特技兵へ足かせを与えますか? + 非特技兵へ足かせを与えますか? 비-전문가에 불이익을 줍니까? 折磨非专业人员? 折磨非專業人員? @@ -794,7 +794,7 @@ Nem-specialisták esetén több ideig tartson a cselekvés befejezése? Alapértelmezett: Igen Увеличивать время завершения действий для не-специалистов? По-умолчанию: Нет Aumenta il tempo richiesto per completare azioni per non-specialisti? Default: Si - 非特技兵は動作を完了する必要を増加させますか?標準:はい + 非特技兵へ動作完了までの時間を増加させますか? 標準: 有効化 비-전문가가 폭발물을 해제시 더욱 많은 시간을 소요합니까? 기본설정: 예 增加非专业人员相关操作的时间? 预设: 是 增加非專業人員相關操作的時間? 預設: 是 @@ -810,7 +810,7 @@ Robbanás hatástalanításkor? Взрыв при разминир.? Fai esplodere quando disarmato? - 解除時に爆発させますか? + 解除中に爆発させますか? 해제시 폭발합니까? 拆除时引爆? 拆除時引爆? @@ -826,7 +826,7 @@ Meghatározott robbanóanyagok felrobbanjanak-e hatástalanításkor? Alapértelmezett: Igen Разрешить определенным взрывным устройствам взрываться при разминировании? По-умолчанию: Да Abilita alcuni esplosivi per esplosione al disarmo? Default: Si - 特定の爆発物へ、解除時に爆発させますか?標準:はい + 特定の爆発物を解除中に爆発させますか? 標準: 有効化 특정 폭발물이 해제시 폭발하게 합니까? 기본설정: 예 启用后, 某些炸弹会在拆除时引爆? 预设: 是 啟用後, 某些炸彈會在拆除時引爆? 預設: 是 @@ -864,7 +864,7 @@ M6 SLAM (Útok zespoda) Mina M6 SLAM (Ataque Inferior) Мина M6 SLAM (направлена вверх) - M6 SLAM 地雷 (下からの攻撃) + M6 SLAM 地雷 (底面攻撃) M6 SLAM 지뢰 (바닥 공격) M6指向性反装甲地雷 (底部攻击) M6指向性反裝甲地雷 (底部攻擊) @@ -886,7 +886,7 @@ M6 SLAM (Útok do strany) Mina M6 SLAM (Ataque Lateral) Мина M6 SLAM (направлена вбок) - M6 SLAM 地雷 (横からの攻撃) + M6 SLAM 地雷 (側面攻撃) M6 SLAM 지뢰 (측면 공격) M6指向性反装甲地雷 (侧边攻击) M6指向性反裝甲地雷 (側邊攻擊) diff --git a/addons/fastroping/CfgVehicles.hpp b/addons/fastroping/CfgVehicles.hpp index 23517bffca..94992669d9 100644 --- a/addons/fastroping/CfgVehicles.hpp +++ b/addons/fastroping/CfgVehicles.hpp @@ -4,7 +4,7 @@ control = "Checkbox"; \ displayName = CSTRING(Eden_equipFRIES); \ tooltip = CSTRING(Eden_equipFRIES_Tooltip); \ - expression = QUOTE([_this] call FUNC(equipFRIES)); \ + expression = QUOTE(if (_value) then {[_this] call FUNC(equipFRIES)}); \ typeName = "BOOL"; \ condition = "objectVehicle"; \ defaultValue = false; \ @@ -18,7 +18,7 @@ class CfgVehicles { }; class ACE_Module: Module_F {}; class ACE_moduleEquipFRIES: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(Module_FRIES_DisplayName); icon = QPATHTOF(UI\Icon_Module_FRIES_ca.paa); category = "ACE"; @@ -45,6 +45,13 @@ class CfgVehicles { showDisabled = 0; priority = 1; }; + class ACE_stowFRIES { + displayName = CSTRING(Interaction_stowFRIES); + condition = QUOTE([vehicle _player] call FUNC(canStowFRIES)); + statement = QUOTE([vehicle _player] call FUNC(stowFRIES)); + showDisabled = 0; + priority = 1; + }; class ACE_deployRopes { displayName = CSTRING(Interaction_deployRopes); condition = QUOTE([ARR_2(_player, vehicle _player)] call FUNC(canDeployRopes)); @@ -156,6 +163,8 @@ class CfgVehicles { class ACE_Actions {}; class Turrets {}; class TransportItems {}; + EGVAR(cargo,hasCargo) = 0; + EGVAR(cargo,space) = 0; }; class Helicopter_Base_H; diff --git a/addons/fastroping/XEH_PREP.hpp b/addons/fastroping/XEH_PREP.hpp index 99e1c8b817..1ad995c598 100644 --- a/addons/fastroping/XEH_PREP.hpp +++ b/addons/fastroping/XEH_PREP.hpp @@ -3,6 +3,7 @@ PREP(canCutRopes); PREP(canDeployRopes); PREP(canFastRope); PREP(canPrepareFRIES); +PREP(canStowFRIES); PREP(checkVehicleThread); PREP(cutRopes); PREP(deployAI); @@ -16,3 +17,4 @@ PREP(onCutCommon); PREP(onPrepareCommon); PREP(onRopeBreak); PREP(prepareFRIES); +PREP(stowFRIES); diff --git a/addons/fastroping/XEH_postInit.sqf b/addons/fastroping/XEH_postInit.sqf index 1efb204247..72ded1b267 100644 --- a/addons/fastroping/XEH_postInit.sqf +++ b/addons/fastroping/XEH_postInit.sqf @@ -8,7 +8,21 @@ [FUNC(fastRopeServerPFH), 0, _this] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; +// Keybinds +["ACE3 Vehicles", QGVAR(fastRope), localize LSTRING(Interaction_fastRope), { + if ((vehicle ACE_player) == ACE_player) exitWith {false}; + if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if ([ACE_player, vehicle ACE_player] call FUNC(canFastRope)) then { + [ACE_player, vehicle ACE_player] call FUNC(fastRope); + true + } else { + false + }; +}, ""] call CBA_fnc_addKeybind; + ["ACE3 Vehicles", QGVAR(cutRopes), localize LSTRING(Interaction_cutRopes), { + if ((vehicle ACE_player) == ACE_player) exitWith {false}; + if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; if ([vehicle ACE_player] call FUNC(canCutRopes)) then { [vehicle ACE_player] call FUNC(cutRopes); true @@ -18,7 +32,6 @@ }, {false}] call CBA_fnc_addKeybind; - #ifdef DRAW_FASTROPE_INFO addMissionEventHandler ["Draw3D", { if (!(cursorObject isKindOf "Helicopter")) exitWith {}; diff --git a/addons/fastroping/anim/model.cfg b/addons/fastroping/anim/model.cfg new file mode 100644 index 0000000000..be41a523a8 --- /dev/null +++ b/addons/fastroping/anim/model.cfg @@ -0,0 +1,124 @@ +class cfgSkeletons +{ + class OFP2_ManSkeleton + { + isDiscrete = 0; + skeletonInherit = ""; + SkeletonBones[]= + { + "Pelvis","", + "Spine","Pelvis", + "Spine1","Spine", + "Spine2","Spine1", + "Spine3","Spine2", + "camera","Pelvis",// case has changed for arma3 + "weapon","Spine1", + "launcher","Spine1", + //Head skeleton in hierarchy + "Neck","Spine3", + "Neck1","Neck", + "Head","Neck1", + + //Left upper side + "LeftShoulder","Spine3", + "LeftArm","LeftShoulder", + "LeftArmRoll","LeftArm", + "LeftForeArm","LeftArmRoll", + "LeftForeArmRoll","LeftForeArm", + "LeftHand","LeftForeArmRoll", + "LeftHandRing","LeftHand", + "LeftHandRing1","LeftHandRing", + "LeftHandRing2","LeftHandRing1", + "LeftHandRing3","LeftHandRing2", + "LeftHandPinky1","LeftHandRing", + "LeftHandPinky2","LeftHandPinky1", + "LeftHandPinky3","LeftHandPinky2", + "LeftHandMiddle1","LeftHand", + "LeftHandMiddle2","LeftHandMiddle1", + "LeftHandMiddle3","LeftHandMiddle2", + "LeftHandIndex1","LeftHand", + "LeftHandIndex2","LeftHandIndex1", + "LeftHandIndex3","LeftHandIndex2", + "LeftHandThumb1","LeftHand", + "LeftHandThumb2","LeftHandThumb1", + "LeftHandThumb3","LeftHandThumb2", + //Right upper side + "RightShoulder","Spine3", + "RightArm","RightShoulder", + "RightArmRoll","RightArm", + "RightForeArm","RightArmRoll", + "RightForeArmRoll","RightForeArm", + "RightHand","RightForeArmRoll", + "RightHandRing","RightHand", + "RightHandRing1","RightHandRing", + "RightHandRing2","RightHandRing1", + "RightHandRing3","RightHandRing2", + "RightHandPinky1","RightHandRing", + "RightHandPinky2","RightHandPinky1", + "RightHandPinky3","RightHandPinky2", + "RightHandMiddle1","RightHand", + "RightHandMiddle2","RightHandMiddle1", + "RightHandMiddle3","RightHandMiddle2", + "RightHandIndex1","RightHand", + "RightHandIndex2","RightHandIndex1", + "RightHandIndex3","RightHandIndex2", + "RightHandThumb1","RightHand", + "RightHandThumb2","RightHandThumb1", + "RightHandThumb3","RightHandThumb2", + //Left lower side + "LeftUpLeg","Pelvis", + "LeftUpLegRoll","LeftUpLeg", + "LeftLeg","LeftUpLegRoll", + "LeftLegRoll","LeftLeg", + "LeftFoot","LeftLegRoll", + "LeftToeBase","LeftFoot", + //Right lower side + "RightUpLeg","Pelvis", + "RightUpLegRoll","RightUpLeg", + "RightLeg","RightUpLegRoll", + "RightLegRoll","RightLeg", + "RightFoot","RightLegRoll", + "RightToeBase","RightFoot", + + //New facial features arma3 only + "Face_Hub","Head", + "Face_Jawbone","Face_Hub", + "Face_Jowl","Face_Jawbone", + "Face_chopRight","Face_Jawbone", + "Face_chopLeft","Face_Jawbone", + "Face_LipLowerMiddle","Face_Jawbone", + "Face_LipLowerLeft","Face_Jawbone", + "Face_LipLowerRight","Face_Jawbone", + "Face_Chin","Face_Jawbone", + "Face_Tongue","Face_Jawbone", + "Face_CornerRight","Face_Hub", + "Face_CheekSideRight","Face_CornerRight", + "Face_CornerLeft","Face_Hub", + "Face_CheekSideLeft","Face_CornerLeft", + "Face_CheekFrontRight","Face_Hub", + "Face_CheekFrontLeft","Face_Hub", + "Face_CheekUpperRight","Face_Hub", + "Face_CheekUpperLeft","Face_Hub", + "Face_LipUpperMiddle","Face_Hub", + "Face_LipUpperRight","Face_Hub", + "Face_LipUpperLeft","Face_Hub", + "Face_NostrilRight","Face_Hub", + "Face_NostrilLeft","Face_Hub", + "Face_Forehead","Face_Hub", + "Face_BrowFrontRight","Face_Forehead", + "Face_BrowFrontLeft","Face_Forehead", + "Face_BrowMiddle","Face_Forehead", + "Face_BrowSideRight","Face_Forehead", + "Face_BrowSideLeft","Face_Forehead", + "Face_Eyelids","Face_Hub", + "Face_EyelidUpperRight","Face_Hub", + "Face_EyelidUpperLeft","Face_Hub", + "Face_EyelidLowerRight","Face_Hub", + "Face_EyelidLowerLeft","Face_Hub", + "EyeLeft","Face_Hub", + "EyeRight","Face_Hub" + };// end of skeleton array + // location of pivot points (local axes) for hierarchical animation + pivotsModel="Samples_F\TemplateRTM\ManSkeleton_Pivots.p3d"; + }; +}; diff --git a/addons/fastroping/functions/fnc_canCloseRamp.sqf b/addons/fastroping/functions/fnc_canCloseRamp.sqf index 58827cb29b..253cb241b5 100644 --- a/addons/fastroping/functions/fnc_canCloseRamp.sqf +++ b/addons/fastroping/functions/fnc_canCloseRamp.sqf @@ -11,7 +11,7 @@ * Able to close ramp * * Example: - * [_player, _vehicle] call ace_fastroping_fnc_canCloseRamp + * [_vehicle, _door, _turretPaths] call ace_fastroping_fnc_canCloseRamp * * Public: No */ diff --git a/addons/fastroping/functions/fnc_canCutRopes.sqf b/addons/fastroping/functions/fnc_canCutRopes.sqf index 9775b155bb..84239db671 100644 --- a/addons/fastroping/functions/fnc_canCutRopes.sqf +++ b/addons/fastroping/functions/fnc_canCutRopes.sqf @@ -19,4 +19,5 @@ params ["_vehicle"]; private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; -!(_deployedRopes isEqualTo []) +!(_deployedRopes isEqualTo []) && +{{(_x select 5)} count (_deployedRopes) == 0} diff --git a/addons/fastroping/functions/fnc_canDeployRopes.sqf b/addons/fastroping/functions/fnc_canDeployRopes.sqf index 6c8f1d28ed..cfc2aecc8a 100644 --- a/addons/fastroping/functions/fnc_canDeployRopes.sqf +++ b/addons/fastroping/functions/fnc_canDeployRopes.sqf @@ -17,11 +17,10 @@ #include "script_component.hpp" params ["_unit", "_vehicle"]; -private ["_config", "_enabled", "_deploymentStage"]; -_config = configFile >> "CfgVehicles" >> typeOf _vehicle; -_enabled = getNumber (_config >> QGVAR(enabled)); -_deploymentStage = _vehicle getVariable [QGVAR(deploymentStage), 0]; +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _enabled = getNumber (_config >> QGVAR(enabled)); +private _deploymentStage = _vehicle getVariable [QGVAR(deploymentStage), 0]; (driver _vehicle != _unit) && {getPos _vehicle select 2 > 2} && diff --git a/addons/fastroping/functions/fnc_canFastRope.sqf b/addons/fastroping/functions/fnc_canFastRope.sqf index 33c6bc2839..5bf5c07d03 100644 --- a/addons/fastroping/functions/fnc_canFastRope.sqf +++ b/addons/fastroping/functions/fnc_canFastRope.sqf @@ -10,7 +10,7 @@ * Able to fast ropes * * Example: - * [_player, _vehicle] call ace_fastroping_fnc_canDeployRopes + * [_player, _vehicle] call ace_fastroping_fnc_canFastRope * * Public: No */ diff --git a/addons/fastroping/functions/fnc_canStowFRIES.sqf b/addons/fastroping/functions/fnc_canStowFRIES.sqf new file mode 100644 index 0000000000..655d5776b8 --- /dev/null +++ b/addons/fastroping/functions/fnc_canStowFRIES.sqf @@ -0,0 +1,23 @@ +/* + * Author: BaerMitUmlaut + * Checks if the unit can stow the helicopters FRIES. + * + * Arguments: + * 0: The helicopter itself + * + * Return Value: + * Able to stow FRIES + * + * Example: + * [_vehicle] call ace_fastroping_fnc_canStowFRIES + * + * Public: No + */ + +#include "script_component.hpp" +params ["_vehicle"]; + +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; + +(_vehicle getVariable [QGVAR(deploymentStage), 0]) == 2 && +{getText (_config >> QGVAR(onCut)) != ""} diff --git a/addons/fastroping/functions/fnc_cutRopes.sqf b/addons/fastroping/functions/fnc_cutRopes.sqf index d619a24297..2b3aaa8a8d 100644 --- a/addons/fastroping/functions/fnc_cutRopes.sqf +++ b/addons/fastroping/functions/fnc_cutRopes.sqf @@ -16,9 +16,8 @@ #include "script_component.hpp" params ["_vehicle"]; -private ["_deployedRopes", "_config", "_waitTime"]; -_deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; +private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; { _x params ["", "_ropeTop", "_ropeBottom", "_dummy", "_hook", "_occupied"]; @@ -40,14 +39,4 @@ _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; } count _deployedRopes; _vehicle setVariable [QGVAR(deployedRopes), [], true]; -_vehicle setVariable [QGVAR(deploymentStage), 1, true]; - -_config = configFile >> "CfgVehicles" >> typeOf _vehicle; -_waitTime = 0; -if (isText (_config >> QGVAR(onCut))) then { - _waitTime = [_vehicle] call (missionNamespace getVariable (getText (_config >> QGVAR(onCut)))); -}; - -[{ - _this setVariable [QGVAR(deploymentStage), 0, true]; -}, _vehicle, _waitTime] call CBA_fnc_waitAndExecute; +_vehicle setVariable [QGVAR(deploymentStage), 2, true]; diff --git a/addons/fastroping/functions/fnc_deployAI.sqf b/addons/fastroping/functions/fnc_deployAI.sqf index 646b171526..d88e07929e 100644 --- a/addons/fastroping/functions/fnc_deployAI.sqf +++ b/addons/fastroping/functions/fnc_deployAI.sqf @@ -18,7 +18,6 @@ #include "script_component.hpp" params [["_vehicle", objNull, [objNull]], ["_deploySpecial", false, [true]], ["_createDeploymentGroup", true, [true]]]; -private ["_config", "_configEnabled", "_deployTime", "_unitsToDeploy", "_deployGroup"]; if (isNull _vehicle || {!(_vehicle isKindOf "Helicopter")}) exitWith { if (hasInterface) then { @@ -28,8 +27,8 @@ if (isNull _vehicle || {!(_vehicle isKindOf "Helicopter")}) exitWith { ERROR('FUNC(deployAI): deployAI was called with an invalid or non-existant vehicle.'); }; -_config = configFile >> "CfgVehicles" >> typeOf _vehicle; -_configEnabled = getNumber (_config >> QGVAR(enabled)); +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _configEnabled = getNumber (_config >> QGVAR(enabled)); if (_configEnabled == 0) exitWith { if (hasInterface) then { [format ["You cannot fast rope from a ""%1"" helicopter.", getText (_config >> "DisplayName")], QFUNC(deployAI)] spawn BIS_fnc_guiMessage; @@ -44,7 +43,7 @@ if (_configEnabled == 2 && {isNull (_vehicle getVariable [QGVAR(FRIES), objNull] ERROR_1('FUNC(deployAI): "%1" requires a FRIES for fastroping but has not been equipped with one.',getText (_config >> "DisplayName")); }; -_unitsToDeploy = crew _vehicle; +private _unitsToDeploy = crew _vehicle; if (_deploySpecial) then { _unitsToDeploy deleteAt (_unitsToDeploy find driver _vehicle); } else { @@ -56,11 +55,11 @@ if (_unitsToDeploy isEqualTo []) exitWith { }; if (_createDeploymentGroup) then { - _deployGroup = createGroup side (_unitsToDeploy select 0); + private _deployGroup = createGroup side (_unitsToDeploy select 0); _unitsToDeploy joinSilent _deployGroup; }; -_deployTime = 0; +private _deployTime = 0; if (getText (_config >> QGVAR(onPrepare)) != "") then { _deployTime = [_vehicle] call (missionNamespace getVariable (getText (_config >> QGVAR(onPrepare)))); }; diff --git a/addons/fastroping/functions/fnc_deployAIWaypoint.sqf b/addons/fastroping/functions/fnc_deployAIWaypoint.sqf index df8cdef0c1..4df221c80e 100644 --- a/addons/fastroping/functions/fnc_deployAIWaypoint.sqf +++ b/addons/fastroping/functions/fnc_deployAIWaypoint.sqf @@ -7,7 +7,7 @@ * 1: Waypoint position * * Return Value: - * true + * true * * Example: * [_group, [6560, 12390, 0]] call ace_fastroping_fnc_deployAIWayoint @@ -17,11 +17,10 @@ #include "script_component.hpp" params [["_group", grpNull, [grpNull]], ["_position", [0, 0, 0], [[]], 3]]; -private ["_vehicle", "_commander", "_speedMode"]; -_vehicle = vehicle leader _group; -_commander = effectiveCommander _vehicle; -_speedMode = speedMode _group; +private _vehicle = vehicle leader _group; +private _commander = effectiveCommander _vehicle; +private _speedMode = speedMode _group; // - Approach ----------------------------------------------------------------- if (_vehicle distance2D _position > 50) then { diff --git a/addons/fastroping/functions/fnc_equipFRIES.sqf b/addons/fastroping/functions/fnc_equipFRIES.sqf index 6d714611be..1cc3202619 100644 --- a/addons/fastroping/functions/fnc_equipFRIES.sqf +++ b/addons/fastroping/functions/fnc_equipFRIES.sqf @@ -16,14 +16,13 @@ #include "script_component.hpp" params ["_vehicle"]; -private ["_config", "_fries"]; -_config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; if !(isNumber (_config >> QGVAR(enabled))) then { ["%1 has not been configured for ACE_Fastroping.", getText (_config >> "DisplayName")] call BIS_fnc_error; } else { if (getNumber (_config >> QGVAR(enabled)) == 2) then { - _fries = (getText (_config >> QGVAR(friesType))) createVehicle [0, 0, 0]; + private _fries = (getText (_config >> QGVAR(friesType))) createVehicle [0, 0, 0]; _fries attachTo [_vehicle, (getArray (_config >> QGVAR(friesAttachmentPoint)))]; _vehicle setVariable [QGVAR(FRIES), _fries, true]; _vehicle addEventHandler ["Killed", { diff --git a/addons/fastroping/functions/fnc_fastRope.sqf b/addons/fastroping/functions/fnc_fastRope.sqf index 0db73f4fce..ab78f122e5 100644 --- a/addons/fastroping/functions/fnc_fastRope.sqf +++ b/addons/fastroping/functions/fnc_fastRope.sqf @@ -17,12 +17,11 @@ #include "script_component.hpp" params ["_unit", "_vehicle"]; -private ["_deployedRopes", "_usableRope", "_usableRopeIndex"]; //Select unoccupied rope -_deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; -_usableRope = _deployedRopes select 0; -_usableRopeIndex = 0; +private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; +private _usableRope = _deployedRopes select 0; +private _usableRopeIndex = 0; { if !(_x select 5) exitWith { _usableRope = _x; diff --git a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf index 72177bce00..d7d49dd11f 100644 --- a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf @@ -17,13 +17,22 @@ #include "script_component.hpp" params ["_arguments", "_pfhHandle"]; -_arguments params ["_unit", "_vehicle", "_rope", "_ropeIndex", "_timeToPlayRopeSound"]; -_rope params ["_attachmentPoint", "_ropeTop", "_ropeBottom", "_dummy", "_hook", "_occupied"]; -private ["_vectorUp", "_vectorDir", "_origin"]; +_arguments params ["_unit", "", "_rope", "", "_timeToPlayRopeSound"]; +_rope params ["", "", "", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter if (vehicle _unit != _unit) exitWith {}; +// dummy lost hook +if (isNull _hook) exitWith { + TRACE_1("Hook lost, dropping and exiting pfeh",_unit); + + [_unit, "", 2] call EFUNC(common,doAnimation); + _unit setVectorUp [0, 0, 1]; + + [_pfhHandle] call CBA_fnc_removePerFrameHandler; +}; + //Start fast roping if (animationState _unit != "ACE_FastRoping") exitWith { _unit disableCollisionWith _dummy; diff --git a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf index 0011e0ecf9..8c4b347494 100644 --- a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf @@ -18,18 +18,23 @@ #include "script_component.hpp" params ["_arguments", "_pfhHandle"]; _arguments params ["_unit", "_vehicle", "_rope", "_ropeIndex", "_hasBeenAttached"]; -_rope params ["_attachmentPoint", "_ropeTop", "_ropeBottom", "_dummy", "_hook", "_occupied"]; -private ["_vectorUp", "_vectorDir", "_origin"]; +_rope params ["_attachmentPoint", "_ropeTop", "_ropeBottom", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter if (vehicle _unit != _unit) exitWith {}; +//Prevent teleport if hook has been deleted due to rope cut +if (isNull _hook) exitWith { + detach _unit; //Does not matter if unit was not attached yet + [_pfhHandle] call CBA_fnc_removePerFrameHandler; +}; + //Start fast roping if (getMass _dummy != 80) exitWith { //Fix for twitchyness _dummy setMass 80; _dummy setCenterOfMass [0, 0, -2]; - _origin = getPosASL _hook; + private _origin = getPosASL _hook; _dummy setPosASL (_origin vectorAdd [0, 0, -2]); _dummy setVectorUp [0, 0, 1]; @@ -65,7 +70,7 @@ if ( deleteVehicle _ropeTop; deleteVehicle _ropeBottom; - _origin = getPosASL _hook; + private _origin = getPosASL _hook; _dummy setPosASL (_origin vectorAdd [0, 0, -1]); //Restore original mass and center of mass @@ -79,7 +84,7 @@ if ( _ropeBottom addEventHandler ["RopeBreak", {[_this, "bottom"] call FUNC(onRopeBreak)}]; //Update deployedRopes array - _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; + private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; _deployedRopes set [_ropeIndex, [_attachmentPoint, _ropeTop, _ropeBottom, _dummy, _hook, false]]; _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; diff --git a/addons/fastroping/functions/fnc_onCutCommon.sqf b/addons/fastroping/functions/fnc_onCutCommon.sqf index 004c176b65..1c074a1e01 100644 --- a/addons/fastroping/functions/fnc_onCutCommon.sqf +++ b/addons/fastroping/functions/fnc_onCutCommon.sqf @@ -1,6 +1,6 @@ /* * Author: BaerMitUmlaut - * Function for opening doors and extending the hook for most vanilla helos. + * Function for closing doors and retracting the hook for most vanilla and older Arma helos. * * Arguments: * 0: Helicopter @@ -19,28 +19,17 @@ params ["_vehicle"]; private _fries = _vehicle getVariable [QGVAR(FRIES), objNull]; if !(isNull _fries) then { - _fries animate ["extendHookRight", 0]; - _fries animate ["extendHookLeft", 0]; + {_fries animate [_x, 0]} forEach ANIMS_HOOK; [{ - _this animateDoor ["door_R", 0]; - _this animateDoor ["door_L", 0]; - _this animateDoor ["CargoRamp_Open", 0]; - _this animateDoor ["Door_rear_source", 0]; - _this animateDoor ["Door_6_source", 0]; - _this animate ["dvere1_posunZ", 0]; - _this animate ["dvere2_posunZ", 0]; + {_this animateDoor [_x, 0]} forEach ANIMS_ANIMATEDOOR; + {_this animate [_x, 0]} forEach ANIMS_ANIMATE; _this setVariable [QGVAR(doorsLocked), false, true]; }, _vehicle, 2] call CBA_fnc_waitAndExecute; 4 } else { - _vehicle animateDoor ["door_R", 0]; - _vehicle animateDoor ["door_L", 0]; - _vehicle animateDoor ["CargoRamp_Open", 0]; - _vehicle animateDoor ["Door_rear_source", 0]; - _vehicle animateDoor ["Door_6_source", 0]; - _vehicle animate ["dvere1_posunZ", 0]; - _vehicle animate ["dvere2_posunZ", 0]; + {_vehicle animateDoor [_x, 0]} forEach ANIMS_ANIMATEDOOR; + {_vehicle animate [_x, 0]} forEach ANIMS_ANIMATE; _vehicle setVariable [QGVAR(doorsLocked), false, true]; 2 diff --git a/addons/fastroping/functions/fnc_onPrepareCommon.sqf b/addons/fastroping/functions/fnc_onPrepareCommon.sqf index 37eb6c7eb8..40603a6527 100644 --- a/addons/fastroping/functions/fnc_onPrepareCommon.sqf +++ b/addons/fastroping/functions/fnc_onPrepareCommon.sqf @@ -1,6 +1,6 @@ /* * Author: BaerMitUmlaut - * Function for closing doors and retracting the hook for most vanilla helos. + * Function for opening doors and extending the hook for most vanilla and older Arma helos. * * Arguments: * 0: Helicopter @@ -16,25 +16,18 @@ #include "script_component.hpp" params ["_vehicle"]; -private ["_fries", "_waitTime"]; -_waitTime = 2; +private _waitTime = 2; -_vehicle animateDoor ["door_R", 1]; -_vehicle animateDoor ["door_L", 1]; -_vehicle animateDoor ["CargoRamp_Open", 1]; -_vehicle animateDoor ["Door_rear_source", 1]; -_vehicle animateDoor ["Door_6_source", 1]; -_vehicle animate ["dvere1_posunZ", 1]; -_vehicle animate ["dvere2_posunZ", 1]; +{_vehicle animateDoor [_x, 1]} forEach ANIMS_ANIMATEDOOR; +{_vehicle animate [_x, 1]} forEach ANIMS_ANIMATE; _vehicle setVariable [QGVAR(doorsLocked), true, true]; -_fries = _vehicle getVariable [QGVAR(FRIES), objNull]; +private _fries = _vehicle getVariable [QGVAR(FRIES), objNull]; if !(isNull _fries) then { [{ - _this animate ["extendHookRight", 1]; - _this animate ["extendHookLeft", 1]; + {_this animate [_x, 1]} forEach ANIMS_HOOK; }, _fries, 2] call CBA_fnc_waitAndExecute; _waitTime = 4; }; diff --git a/addons/fastroping/functions/fnc_onRopeBreak.sqf b/addons/fastroping/functions/fnc_onRopeBreak.sqf index 29da355481..3c83daea30 100644 --- a/addons/fastroping/functions/fnc_onRopeBreak.sqf +++ b/addons/fastroping/functions/fnc_onRopeBreak.sqf @@ -18,20 +18,19 @@ #include "script_component.hpp" params ["_ehArgs", "_part"]; _ehArgs params ["_rope", "_helper1", "_helper2"]; -private ["_vehicle", "_deployedRopes", "_brokenRope", "_unit"]; if (_part == "bottom") then { _helper2 = (ropeAttachedObjects _helper1) select 0; }; -_vehicle = attachedTo _helper2; +private _vehicle = attachedTo _helper2; if (isNil "_vehicle") exitWith {}; //Exit when vehicle got destroyed if (_vehicle isKindOf "ACE_friesBase") then { _vehicle = attachedTo _vehicle; }; -_deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; -_brokenRope = []; +private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; +private _brokenRope = []; { if ((_x select 1 == _rope) || {(_x select 2 == _rope)}) exitWith { _brokenRope = _x; @@ -40,7 +39,7 @@ _brokenRope = []; _brokenRope set [5, true]; _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; -_unit = { +private _unit = { if (_x isKindOf "CAManBase") exitWith {_x}; } forEach (attachedObjects (_brokenRope select 3)); diff --git a/addons/fastroping/functions/fnc_prepareFRIES.sqf b/addons/fastroping/functions/fnc_prepareFRIES.sqf index e4bce8458c..7b98b5ff63 100644 --- a/addons/fastroping/functions/fnc_prepareFRIES.sqf +++ b/addons/fastroping/functions/fnc_prepareFRIES.sqf @@ -16,13 +16,12 @@ #include "script_component.hpp" params ["_vehicle"]; -private ["_config", "_waitTime"]; -//Stage indicator: 0 - travel mode; 1 - preparing FRIES; 2 - FRIES ready; 3 - ropes deployed +//Stage indicator: 0 - travel mode; 1 - preparing/stowing FRIES; 2 - FRIES ready; 3 - ropes deployed _vehicle setVariable [QGVAR(deploymentStage), 1, true]; -_config = configFile >> "CfgVehicles" >> typeOf _vehicle; -_waitTime = 0; +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _waitTime = 0; if (isText (_config >> QGVAR(onPrepare))) then { _waitTime = [_vehicle] call (missionNamespace getVariable (getText (_config >> QGVAR(onPrepare)))); }; diff --git a/addons/fastroping/functions/fnc_stowFRIES.sqf b/addons/fastroping/functions/fnc_stowFRIES.sqf new file mode 100644 index 0000000000..18813295d8 --- /dev/null +++ b/addons/fastroping/functions/fnc_stowFRIES.sqf @@ -0,0 +1,31 @@ +/* + * Author: BaerMitUmlaut + * Stows the helicopters FRIES. + * + * Arguments: + * 0: A helicopter with prepared FRIES + * + * Return Value: + * None + * + * Example: + * [_vehicle] call ace_fastroping_fnc_stowFRIES + * + * Public: No + */ + +#include "script_component.hpp" +params ["_vehicle"]; + +//Stage indicator: 0 - travel mode; 1 - preparing/stowing FRIES; 2 - FRIES ready; 3 - ropes deployed +_vehicle setVariable [QGVAR(deploymentStage), 1, true]; + +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _waitTime = 0; +if (isText (_config >> QGVAR(onCut))) then { + _waitTime = [_vehicle] call (missionNamespace getVariable (getText (_config >> QGVAR(onCut)))); +}; + +[{ + _this setVariable [QGVAR(deploymentStage), 0, true]; +}, _vehicle, _waitTime] call CBA_fnc_waitAndExecute; diff --git a/addons/fastroping/script_component.hpp b/addons/fastroping/script_component.hpp index 19bdd1a109..77c8168f8d 100644 --- a/addons/fastroping/script_component.hpp +++ b/addons/fastroping/script_component.hpp @@ -16,3 +16,8 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + + +#define ANIMS_HOOK ["extendHookRight", "extendHookLeft"] +#define ANIMS_ANIMATEDOOR ["door_R", "door_L", "CargoRamp_Open", "Door_rear_source", "Door_6_source", "CargoDoorR", "CargoDoorL"] +#define ANIMS_ANIMATE ["dvere1_posunZ", "dvere2_posunZ", "doors"] diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index f3988ee14f..8c8e4ee600 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -33,7 +33,7 @@ Prepare fast roping system - Bereite Fast Roping System vor + Bereite "Fast Roping"-System vor Przygotuj system zjazdu na linach Préparer le système de corde lisse Preparar el sistema fast roping @@ -46,6 +46,15 @@ 准备快速绳降系统 準備快速繩降系統 + + Stow fast roping system + Verstaue "Fast Roping"-System + Arrotola le corde + ファスト ロープのシステムを収容 + 收起快速繩降系統 + 收起快速绳降系统 + 패스트 로프 시스템 보관 + Deploy ropes Seile auswerfen @@ -132,6 +141,7 @@ ZJAZD NA LINACH 让单位快速绳降 讓單位快速繩降 + 패스트 로프를 놓음 diff --git a/addons/fcs/CfgVehicles.hpp b/addons/fcs/CfgVehicles.hpp index 47b731a66c..5b5935506e 100644 --- a/addons/fcs/CfgVehicles.hpp +++ b/addons/fcs/CfgVehicles.hpp @@ -47,25 +47,19 @@ class CfgVehicles { }; }; class Turrets { - class MainTurret: NewTurret { - GVAR(Enabled) = 1; // all tracked vehicles get one by default - }; + class MainTurret: NewTurret {}; }; }; class Tank_F: Tank { class Turrets { - class MainTurret: NewTurret { - GVAR(Enabled) = 1; // all tracked vehicles get one by default - }; + class MainTurret: NewTurret {}; }; }; class APC_Tracked_01_base_F: Tank_F { class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - }; + class MainTurret: MainTurret {}; }; }; @@ -86,14 +80,11 @@ class CfgVehicles { class APC_Tracked_02_base_F: Tank_F { class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - }; + class MainTurret: MainTurret {}; }; }; class O_APC_Tracked_02_base_F: APC_Tracked_02_base_F {}; - class O_APC_Tracked_02_AA_F: O_APC_Tracked_02_base_F { class Turrets: Turrets { class MainTurret: MainTurret { @@ -107,38 +98,6 @@ class CfgVehicles { }; }; - class APC_Tracked_03_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - }; - }; - }; - - class MBT_01_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - }; - }; - }; - - class MBT_02_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - }; - }; - }; - - class MBT_03_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - }; - }; - }; - // AIR VEHICLES class Air: AllVehicles {}; diff --git a/addons/fcs/config.cpp b/addons/fcs/config.cpp index 29aba659b5..df849ec346 100644 --- a/addons/fcs/config.cpp +++ b/addons/fcs/config.cpp @@ -30,3 +30,7 @@ class CfgPatches { class ACE_Extensions { extensions[] += {"ace_fcs"}; }; + +class ACE_Tests { + fcs = QPATHTOF(dev\test_debugConfigs.sqf); +}; diff --git a/addons/fcs/functions/dev_debugConfigs.sqf b/addons/fcs/dev/test_debugConfigs.sqf similarity index 89% rename from addons/fcs/functions/dev_debugConfigs.sqf rename to addons/fcs/dev/test_debugConfigs.sqf index 73abd89771..89fa6b0d31 100644 --- a/addons/fcs/functions/dev_debugConfigs.sqf +++ b/addons/fcs/dev/test_debugConfigs.sqf @@ -1,5 +1,8 @@ // PabstMirror -#include "script_component.hpp" +// ["fcs"] call ace_common_fnc_runTests; +// execVM "z\ace\addons\fcs\dev\test_debugConfigs.sqf; + +private _testPass = true; diag_log text format ["[ACE_FCS] ---------------"]; private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {2 == getNumber (_x >> 'scope')}", true]; @@ -20,7 +23,10 @@ private _problemUIs = []; _ballisticComputer = [_ballisticComputer, 5] call ace_common_fnc_toBin; if ((_ballisticComputer select [(count _ballisticComputer) - 5, 1]) == "1") then { _vanillaFCS = true; - if (_aceFCS) then {diag_log text format ["%1 -> %2: ACE FCS Enabled CONFLICTS with vanilla FCS [%3]", _vehicleType, _weapon, _ballisticComputer];}; + if (_aceFCS) then { + _testPass = false; + diag_log text format ["%1 -> %2: ACE FCS Enabled CONFLICTS with vanilla FCS [%3]", _vehicleType, _weapon, _ballisticComputer]; + }; }; } forEach _weapons; @@ -76,7 +82,8 @@ private _problemUIs = []; }; }; }; - } forEach [[0],[0,0]]; + // } forEach [[0],[0,0]]; + } forEach [[0],[0,0], [1], [2]]; } forEach _vehicles; _problemUIs sort true; @@ -86,3 +93,5 @@ diag_log text format ["[ACE_FCS] ------- Problem UIs --------"]; diag_log text format ["- %1", _x]; } forEach _problemUIs; diag_log text format ["[ACE_FCS] ---------------"]; + +_testPass diff --git a/addons/fcs/functions/fnc_vehicleInit.sqf b/addons/fcs/functions/fnc_vehicleInit.sqf index 47b8359b2b..8a60f31e2e 100644 --- a/addons/fcs/functions/fnc_vehicleInit.sqf +++ b/addons/fcs/functions/fnc_vehicleInit.sqf @@ -28,14 +28,13 @@ params ["_vehicle"]; // calculate offset between gunner camera and muzzle position if !(_vehicle isKindOf "Air") then { - private ["_gunBeg", "_gunnerView", "_gunBegPos", "_gunnerViewPos", "_viewDiff"]; - _gunBeg = getText (_turretConfig >> "gunBeg"); - _gunnerView = getText (_turretConfig >> "memoryPointGunnerOptics"); + private _gunBeg = getText (_turretConfig >> "gunBeg"); + private _gunnerView = getText (_turretConfig >> "memoryPointGunnerOptics"); - _gunBegPos = (_vehicle selectionPosition _gunBeg) select 0; - _gunnerViewPos = (_vehicle selectionPosition _gunnerView) select 0; - _viewDiff = _gunBegPos - _gunnerViewPos; + private _gunBegPos = (_vehicle selectionPosition _gunBeg) select 0; + private _gunnerViewPos = (_vehicle selectionPosition _gunnerView) select 0; + private _viewDiff = _gunBegPos - _gunnerViewPos; _vehicle setVariable [format ["%1_%2", QGVAR(ViewDiff), _x], _viewDiff, true]; } else { diff --git a/addons/fcs/stringtable.xml b/addons/fcs/stringtable.xml index 9e776f34cd..5c0b77d75b 100644 --- a/addons/fcs/stringtable.xml +++ b/addons/fcs/stringtable.xml @@ -19,7 +19,7 @@ Zeroed To - Haltepunkt + Genullt auf Ajustado a Wyzerowany na Nastaveno na diff --git a/addons/finger/ACE_Settings.hpp b/addons/finger/ACE_Settings.hpp index 73e1db1904..c28b33dd74 100644 --- a/addons/finger/ACE_Settings.hpp +++ b/addons/finger/ACE_Settings.hpp @@ -1,16 +1,20 @@ class ACE_Settings { class GVAR(enabled) { + category = CSTRING(DisplayName); value = 0; typeName = "BOOL"; displayName = CSTRING(enabled_displayName); }; class GVAR(maxRange) { + category = CSTRING(DisplayName); value = 4; typeName = "SCALAR"; displayName = CSTRING(maxRange_displayName); description = CSTRING(maxRange_description); + sliderSettings[] = {0, 50, 4, 1}; }; class GVAR(indicatorForSelf) { + category = CSTRING(DisplayName); value = 1; typeName = "BOOL"; isClientSettable = 1; @@ -18,6 +22,7 @@ class ACE_Settings { description = CSTRING(indicatorForSelf_description); }; class GVAR(indicatorColor) { + category = CSTRING(DisplayName); value[] = {0.83, 0.68, 0.21, 0.75}; typeName = "COLOR"; isClientSettable = 1; diff --git a/addons/finger/CfgVehicles.hpp b/addons/finger/CfgVehicles.hpp index 8125e7f2f5..8d6d1a4146 100644 --- a/addons/finger/CfgVehicles.hpp +++ b/addons/finger/CfgVehicles.hpp @@ -1,12 +1,12 @@ class CfgVehicles { class ACE_Module; class GVAR(moduleSettings): ACE_Module { - scope = 2; + scope = 1; category = "ACE"; displayName = CSTRING(moduleSettings_displayName); icon = QPATHTOF(UI\Icon_Module_finger_ca.paa); function = QFUNC(moduleSettings); - isGlobal = 0; + isGlobal = 1; isSingular = 1; author = ECSTRING(common,ACETeam); class Arguments { diff --git a/addons/finger/functions/fnc_keyPress.sqf b/addons/finger/functions/fnc_keyPress.sqf index b9231fb17b..a9949f6ce3 100644 --- a/addons/finger/functions/fnc_keyPress.sqf +++ b/addons/finger/functions/fnc_keyPress.sqf @@ -18,7 +18,7 @@ if (!alive ACE_player) exitWith {false}; // Conditions: canInteract -if !([ACE_player, ACE_player, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([ACE_player, ACE_player, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; //make sure player is dismounted or in a static weapon: if ((ACE_player != vehicle ACE_player) && {!((vehicle ACE_player) isKindOf "StaticWeapon")}) exitWith {false}; //Check camera view (not in GUNNER) @@ -60,6 +60,11 @@ TRACE_1("sending finger to",_sendFingerToPlayers); [QGVAR(fingered), [ACE_player, _fingerPosASL, _originASL vectorDistance _fingerPosASL], _sendFingerToPlayers] call CBA_fnc_targetEvent; -[ACE_player, "GestureGo"] call EFUNC(common,doGesture); +// BI gestures do not work underwater, play custom "point" gesture if loaded +if (["ace_gestures"] call EFUNC(common,isModLoaded)) then { + QEGVAR(gestures,point) call EFUNC(gestures,playSignal); // Works underwater +} else { + [ACE_player, "GestureGo"] call EFUNC(common,doGesture); // Does not work underwater +}; true diff --git a/addons/finger/functions/fnc_moduleSettings.sqf b/addons/finger/functions/fnc_moduleSettings.sqf index 4667e76c51..678b51ac5f 100644 --- a/addons/finger/functions/fnc_moduleSettings.sqf +++ b/addons/finger/functions/fnc_moduleSettings.sqf @@ -17,7 +17,6 @@ #include "script_component.hpp" params ["_logic"]; -if !(isServer) exitWith {}; [_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(maxRange), "maxRange"] call EFUNC(common,readSettingFromModule); diff --git a/addons/finger/functions/fnc_perFrameEH.sqf b/addons/finger/functions/fnc_perFrameEH.sqf index a28a30ef96..3c0d4a586f 100644 --- a/addons/finger/functions/fnc_perFrameEH.sqf +++ b/addons/finger/functions/fnc_perFrameEH.sqf @@ -17,7 +17,7 @@ if (!alive ACE_player) then {GVAR(fingersHash) = [] call CBA_fnc_hashCreate;}; // Conditions: canInteract -if !([ACE_player, ACE_player, ["isNotInside"]] call EFUNC(common,canInteractWith)) then {GVAR(fingersHash) = [] call CBA_fnc_hashCreate;}; +if !([ACE_player, ACE_player, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) then {GVAR(fingersHash) = [] call CBA_fnc_hashCreate;}; // Make sure player is dismounted or in a static weapon: if ((ACE_player != vehicle ACE_player) && {!((vehicle ACE_player) isKindOf "StaticWeapon")}) then {GVAR(fingersHash) = [] call CBA_fnc_hashCreate;}; diff --git a/addons/finger/stringtable.xml b/addons/finger/stringtable.xml index b6dc3c5f87..de566acb49 100644 --- a/addons/finger/stringtable.xml +++ b/addons/finger/stringtable.xml @@ -1,6 +1,15 @@ - + + + Pointing + Fingerzeig + Puntamento + 指向指示器 + 指向指示器 + 指差し + 가리키기 + Show pointing indicator to self Zeigersymbol einem selbst anzeigen @@ -12,7 +21,7 @@ Mostrar el indicador de señalado a uno mismo Zobrazit ukázání směru pro sebe Mostra puntatore per te stesso - 自分にポインティング表記を表示する + 自分に指差し表記を表示する 자신이 가리키는곳을 보여줍니다 显示指向指示器给自己 顯示指向指示器給自己 @@ -28,10 +37,10 @@ Muestra el indicador para el jugador que apunta. Esta opción no afecta si los otros jugadores verían el indicador Zobrazit infikátor, když ukážete prstem. Tato volba nemá vliv, zda ostatní hráči uvidí indikátor nebo ne. Mostra puntatore per il giocatore indicato. Questa opzione non influisce la possibilità che gli altri giocatori vedano il puntatore - プレイヤーへのポインティング表記を描画します。このオプションは他のプレイヤーの表記に影響しません。 + プレイヤーへの指差し表記を描画します。このオプションは他のプレイヤーの表記に影響しません。 대상이 가리키는곳을 보이게 합니다. - 显示指向指示器给玩家自己. 此选项设定并不影响其他玩家能否看到指示器. - 顯示指向指示器給玩家自己. 此選項設定並不影響其他玩家能否看到指示器. + 显示指向指示器给玩家自己。此选项设定并不影响其他玩家能否看到指示器 + 顯示指向指示器給玩家自己。此選項設定並不影響其他玩家能否看到指示器 Pointing indicator @@ -44,7 +53,7 @@ Indicador de señalado Ukazování směru Indicatore di puntamento - ポインティング表記 + 指差し表記 가리키기 표시기 指向指示器 指向指示器 @@ -60,7 +69,7 @@ Color del círculo indicador que señala Barva kruhu pro ukázání směru Colore del cerchio dell'indicatore di puntamento - ポインティング表記の円の色 + 指差し表記の円の色 가리키기의 원형 색상 指向指示器颜色 指向指示器顏色 @@ -76,7 +85,7 @@ Acción "apuntar con el dedo a" Akce "ukázat prstem na" Azione "punta il dito a" - "point a finger at"キー + "指差し"キー "손가락으로 가리키기"행동 使"手指指向在" 使"手指指向在" @@ -92,10 +101,10 @@ Señala y muestra un marcador virtual donde ustás apuntando para las unidades cercanas. Puede ser mantenido. Ukazuje virtuální značku kruhu ve směru, kterým se díváte pro všechny blízké jednotky. Punta e mostra un marker virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. - ポイント、そして架空のマーカー表記は自ユニットの近くにいると表記されます。これは押しっぱなしにできます。 + 指差しが出すマーカー表記は自ユニットの近くにいると表記されます。これは押しっぱなしにできます。 당신이 보는것을 가상의 마커로 표시함으로서 다른 인원이 볼 수 있게 합니다. 누른채로 유지할 수 있습니다. - 当按下此按键后, 你附近的单位即可看见一个虚拟图示, 标明你正在指向的位置. 此按键可以被按住来持续显示. - 當按下此按鍵後, 你附近的單位即可看見一個虛擬圖示, 標明你正在指向的位置. 此按鍵可以被按住來持續顯示. + 当按下此按键后,你附近的单位即可看见一个虚拟图示,标明你正在指向的位置。此按键可以被按住来持续显示。 + 當按下此按鍵後,你附近的單位即可看見一個虛擬圖示,標明你正在指向的位置。此按鍵可以被按住來持續顯示。 Pointing Settings @@ -108,7 +117,7 @@ Ajustes de señalado Nastavení ukázování směru Impostazioni puntamento - ポインティング設定 + 指差し設定 가리키기 설정 指向设定 指向設定 @@ -124,7 +133,7 @@ Señalado habilitado Ukazování povoleno Puntamento abilitato - ポインティングを有効 + 指差しを有効 가리키기 활성화 指向系统启动 指向系統啟動 @@ -140,14 +149,14 @@ Distancia máxima de señalado Maximální dosah pro ukazování směru Raggio massimo puntamento - ポインティングの最大範囲 + 指差しの最大範囲 가리키기 최대 범위 指向指示器最大显示距离 指向指示器最大顯示距離 Max range between players to show the pointing indicator [default: 4 meters] - Maximale Reichweite zwischen Spielern, welche das Zeigesymbol des jeweils anderen sehen können. (Standart: 4 Meter) + Maximale Reichweite zwischen Spielern, welche das Zeigesymbol des jeweils anderen sehen können. (Standard: 4 Meter). Distance maximale entre joueurs pour afficher l'indicateur (défaut: 4 mètres) Określ dystans na jakim można wskazywać coś palcem innym graczom. [domyślnie: 4m] A maximális távolság, amelyben a közeli játékosoknak megjelenik az indikátor. [alapértelmezett: 4 méter] @@ -156,10 +165,10 @@ Distancia máxima entre los jugadores para mostrar el indicador que señala [por defecto: 4 metros] Maximální vzdálenost mezi hráči pro ukázání směru [výchozí: 4 metry] Distanza massima tra giocatori per mostrare l'indicatore di puntamento [default: 4 metri] - ポインティング表記が他のプレイヤーに表示される範囲を決定できます。(標準 4 メートル) + 指差し表記が他のプレイヤーに表示される範囲を決定できます。(標準 4 メートル) 플레이어 사이에서 가리키기 표시를 보이게 하는 최대거리를 설정합니다[기본설정: 4 미터] - 设定指向指示器最大显示距离. [预设: 4公尺] - 設定指向指示器最大顯示距離. [預設: 4公尺] + 设定指向指示器最大显示距离。[预设: 4公尺] + 設定指向指示器最大顯示距離。[預設: 4公尺] diff --git a/addons/flashlights/CfgWeapons.hpp b/addons/flashlights/CfgWeapons.hpp index a708e1eb74..9623b4d069 100644 --- a/addons/flashlights/CfgWeapons.hpp +++ b/addons/flashlights/CfgWeapons.hpp @@ -1,15 +1,16 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_Flashlight_MX991: ACE_ItemCore { + author = ECSTRING(common,ACETeam); displayName = CSTRING(MX991_DisplayName); descriptionShort = CSTRING(MX991_Description); model = QPATHTOF(data\MX_991.p3d); picture = QPATHTOF(UI\mx991_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "red"; @@ -21,12 +22,13 @@ class CfgWeapons { }; class ACE_Flashlight_KSF1: ACE_ItemCore { + author = ECSTRING(common,ACETeam); displayName = CSTRING(KSF1_DisplayName); descriptionShort = CSTRING(KSF1_Description); model = QPATHTOF(data\KSF_1.p3d); picture = QPATHTOF(UI\ksf1_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "red"; @@ -38,12 +40,13 @@ class CfgWeapons { }; class ACE_Flashlight_XL50: ACE_ItemCore { + author = ECSTRING(common,ACETeam); displayName = CSTRING(XL50_DisplayName); descriptionShort = CSTRING(XL50_Description); model = QPATHTOF(data\Maglight.p3d); picture = QPATHTOF(UI\xl50_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; class FlashLight { ACE_Flashlight_Colour = "white"; @@ -53,4 +56,4 @@ class CfgWeapons { }; }; }; -}; \ No newline at end of file +}; diff --git a/addons/flashlights/stringtable.xml b/addons/flashlights/stringtable.xml index d896d3724a..08e291a2b6 100644 --- a/addons/flashlights/stringtable.xml +++ b/addons/flashlights/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,7 +11,7 @@ Fulton MX-991 Fulton MX-991 Fulton MX-991 - Fulton MX-991 + フルトン MX-991 Fulton MX-991 Fulton MX-991 Fulton MX-991 @@ -28,8 +28,8 @@ Lampe torche avec un filtre rouge. Pour utilisation sur carte. 赤色フィルタ付きのフラッシュライト。地図上でつかいます。 빨간색 필터가 달린 손전등입니다. 지도를 비출때 씁니다. - 拥有红色滤光片的手电筒. 用来照亮地图. - 擁有紅色濾光片的手電筒. 用來照亮地圖. + 拥有红色滤光片的手电筒。用来照亮地图。 + 擁有紅色濾光片的手電筒。用來照亮地圖。 Maglite XL50 @@ -41,7 +41,7 @@ Maglite XL50 Maglite XL50 Maglite XL50 - Maglite XL50 + マグライト XL50 Maglite XL50 Maglite XL50 Maglite XL50 @@ -58,8 +58,8 @@ Mini lampe torche blanche. Pour utilisation sur carte. 白色光の小さなフラッシュライト。地図上でつかいます。 하얀색 조그마한 손전등. 지도를 비출때 씁니다. - 白色的迷你手电筒. 用来照亮地图. - 白色的迷你手電筒. 用來照亮地圖. + 白色的迷你手电筒。用来照亮地图。 + 白色的迷你手電筒。用來照亮地圖。 KSF-1 @@ -78,7 +78,7 @@ Flashlight with red filter. For use on map. - Tachenlampe mit rotem Filter zum Kartenlesen. + Taschenlampe mit rotem Filter zum Kartenlesen. Latarka z czerwonym filtrem. Używana do podświetlania mapy. Lanterna com filtro vermelho. Para uso no mapa. Фонарь с красным светофильтром. Для использования на карте. @@ -88,8 +88,8 @@ Lampe torche avec un filtre rouge. Pour utilisation sur carte. 赤色フィルタ付きのフラッシュライト。地図上でつかいます。 빨간색 필터가 달린 손전등입니다. 지도를 비출때 씁니다. - 拥有红色滤光片的手电筒. 用来照亮地图. - 擁有紅色濾光片的手電筒. 用來照亮地圖. + 拥有红色滤光片的手电筒。用来照亮地图。 + 擁有紅色濾光片的手電筒。用來照亮地圖。 diff --git a/addons/fonts/CfgFontFamilies.hpp b/addons/fonts/CfgFontFamilies.hpp index 80c8114624..9ec341c83d 100644 --- a/addons/fonts/CfgFontFamilies.hpp +++ b/addons/fonts/CfgFontFamilies.hpp @@ -1,7 +1,5 @@ -class CfgFontFamilies -{ - class PixelSplitterBold - { +class CfgFontFamilies { + class PixelSplitterBold { fonts[] = { QPATHTOF(PixelSplitterBold\PixelSplitterBold6), QPATHTOF(PixelSplitterBold\PixelSplitterBold7), QPATHTOF(PixelSplitterBold\PixelSplitterBold8), diff --git a/addons/frag/ACE_Settings.hpp b/addons/frag/ACE_Settings.hpp index 63a3d564d2..6d511d3c3d 100644 --- a/addons/frag/ACE_Settings.hpp +++ b/addons/frag/ACE_Settings.hpp @@ -26,6 +26,7 @@ class ACE_Settings { description = CSTRING(MaxTrack_Desc); typeName = "SCALAR"; value = 10; + sliderSettings[] = {0, 50, 10, -1}; }; class GVAR(maxTrackPerFrame) { category = CSTRING(Module_DisplayName); @@ -33,5 +34,6 @@ class ACE_Settings { description = CSTRING(MaxTrackPerFrame_Desc); typeName = "SCALAR"; value = 10; + sliderSettings[] = {0, 50, 10, -1}; }; }; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index dcc1759648..65b9327d5a 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -13,10 +13,9 @@ * * Public: No */ - -//fnc_doSpall.sqf #include "script_component.hpp" -// ACE_player sideChat "WAAAAAAAAAAAAAAAAAAAAA"; + +#define WEIGHTED_SIZE [QGVAR(spall_small), 4, QGVAR(spall_medium), 3, QGVAR(spall_large), 2, QGVAR(spall_huge), 1] params ["_hitData", "_hitPartDataIndex"]; private _initialData = GVAR(spallHPData) select (_hitData select 0); @@ -51,6 +50,7 @@ if (alive _round) then { }; }; if (_exit) exitWith {}; + private _unitDir = vectorNormalized _velocity; private _pos = _hpData select 3; private _spallPos = []; @@ -88,14 +88,6 @@ if (_explosive > 0) then { _spallPolar set [0, _fragPower * 0.66]; }; -private _fragTypes = [ - QGVAR(spall_small), QGVAR(spall_small), QGVAR(spall_small), - QGVAR(spall_small),QGVAR(spall_medium),QGVAR(spall_medium),QGVAR(spall_medium), - QGVAR(spall_medium), QGVAR(spall_large), QGVAR(spall_large), QGVAR(spall_huge), - QGVAR(spall_huge) - -]; - // diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; private _spread = 15 + (random 25); private _spallCount = 5 + (random 10); @@ -110,8 +102,7 @@ for "_i" from 1 to _spallCount do { _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; - private _fragType = round (random ((count _fragTypes) - 1)); - private _fragment = (_fragTypes select _fragType) createVehicleLocal [0,0,10000]; + private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0,0,10000]; _fragment setPosASL _spallPos; _fragment setVelocity _spallFragVect; @@ -133,8 +124,7 @@ for "_i" from 1 to _spallCount do { _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; - private _fragType = round (random ((count _fragTypes) - 1)); - private _fragment = (_fragTypes select _fragType) createVehicleLocal [0, 0, 10000]; + private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0, 0, 10000]; _fragment setPosASL _spallPos; _fragment setVelocity _spallFragVect; diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index b1e29a79ca..a9d13cde08 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -54,6 +54,7 @@ if (_shouldAdd) then { private _localShooter = if (isNil "_gunner") then {local _unit} else {local _gunner}; TRACE_4("",_localShooter,_unit,_ammo,_projectile); if (!_localShooter) exitWith {}; + if (_weapon == "Put") exitWith {}; // Ignore explosives placed without ace_explosives // Skip if less than 0.5 second from last shot if ((CBA_missionTime - (_unit getVariable [QGVAR(lastTrack), -1])) < 0.5) exitWith {}; diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index d74033f6a4..071924ac65 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -138,8 +138,8 @@ Questo parametro controlla il numero massimo di proiettili che la frammentazione e il sistema di spalling tracciano in ogni momento. Se più proiettili sono sparati, non verranno tracciati. Abbassa questo parametro se non vuoi cali di FPS in scenari con molti proiettili (>200 proiettili in aria contemporaneamente) 時間が許すかぎり、破片と剥離システムの最大数を設定できます。設定数以上の弾丸が発射された場合、それは対象になりません。もし多い弾数による FPS の低下を望まない場合は、低い数へ設定にします。( &gt;一度に空中内で200発) 이 설정은 조각 및 파편 시스템으로 인해 생긴 발사체의 수를 결정합니다. 만약 더 많은 발사체가 나올경우 정해진 수 이외에는 추적하지 않습니다. 이 설정을 낮춤으로써 파편이 많은 시나리오를 실행할때 더욱 원활히 진행할 수 있습니다 (한 번에 200개 이하) - 设定在指定时间内, 系统最大可追踪的碎片/剥落粒子数量. 如有更多的碎片在这之后产生, 这些粒子将不会被追踪. 如果你想要维持好的帧数, 此设定勿调的过高. ( >一次200颗粒子) - 設定在指定時間內, 系統最大可追蹤的碎片/剝落粒子數量. 如有更多的碎片在這之後產生, 這些粒子將不會被追蹤. 如果你想要維持好的幀數, 此設定勿調的過高. ( >一次200顆粒子) + 设定在指定时间内,系统最大可追踪的碎片/剥落粒子数量。如有更多的碎片在这之后产生,这些粒子将不会被追踪。如果你想要维持好的帧数,此设定勿调的过高。( >一次200颗粒子) + 設定在指定時間內,系統最大可追蹤的碎片/剝落粒子數量。如有更多的碎片在這之後產生,這些粒子將不會被追蹤。如果你想要維持好的幀數,此設定勿調的過高。( >一次200顆粒子) Maximum Projectiles Per Frame @@ -170,8 +170,8 @@ Il numero di calcoli per tracciamento di spalling ad ogni frame. Questo aiuta a distribuire l'impatto del tracciamento dello spalling su più frame, limitando ancora di più l'impatto. 与えられたフレームごとに追跡する剥離の数を決定します。FPS に影響をあたえないよう、剥離を複数のフレームで追跡し、分散させています。 가능한 프레임마다 파편을 추적 및 계산합니다. 여러 프레임에 걸쳐 파편난 발사체를 추적하여 FPS에 도움을 줍니다. 이를 제한함으로써 더욱 큰 효과를 볼 수 있습니다. - 设定在每一帧数内, 系统最大可追踪的碎片/剥落粒子数量. 此设定可有效帮助系统减低计算压力. - 設定在每一幀數內, 系統最大可追蹤的碎片/剝落粒子數量. 此設定可有效幫助系統減低計算壓力. + 设定在每一帧数内,系统最大可追踪的碎片/剥落粒子数量。此设定可有效帮助系统减低计算压力。 + 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力。 (SP Only) Frag/Spall Debug Tracing @@ -201,8 +201,9 @@ (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の弾頭が見えるようになります。 - (仅在单人模式) 让你在单人模式下可观察到碎片/剥落粒子的移动轨迹. - (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡. + (仅在单人模式) 让你在单人模式下可观察到碎片/剥落粒子的移动轨迹。 + (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡。 + (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 조각화 및 스 폴링 라운드의 시각적 추적을 가능하게합니다. diff --git a/addons/gestures/CfgVehicles.hpp b/addons/gestures/CfgVehicles.hpp index 6eb3990446..1d94e5ecc4 100644 --- a/addons/gestures/CfgVehicles.hpp +++ b/addons/gestures/CfgVehicles.hpp @@ -1,5 +1,4 @@ class CfgVehicles { - class Man; class CAManBase: Man { class ACE_SelfActions { @@ -7,6 +6,7 @@ class CfgVehicles { displayName = CSTRING(Gestures); condition = QUOTE((canStand _target) && {GVAR(showOnInteractionMenu) == 2}); statement = ""; + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 3.5; icon = QPATHTOF(UI\gestures_ca.paa); @@ -14,42 +14,48 @@ class CfgVehicles { class GVAR(Advance) { displayName = CSTRING(Advance); condition = QUOTE(true); - statement = QUOTE([ARR_2(_target,'gestureAdvance')] call EFUNC(common,doGesture);); + statement = QUOTE([ARR_2(_target,'gestureAdvance')] call EFUNC(common,doGesture)); + //exceptions[] = {"isNotSwimming"}; // Does not work underwaterexceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.9; }; class GVAR(Go) { displayName = CSTRING(Go); condition = QUOTE(true); - statement = QUOTE([ARR_2(_target,selectRandom [ARR_2('gestureGo','gestureGoB')])] call EFUNC(common,doGesture);); + statement = QUOTE([ARR_2(_target,selectRandom [ARR_2('gestureGo','gestureGoB')])] call EFUNC(common,doGesture)); + //exceptions[] = {"isNotSwimming"}; // Does not work underwater showDisabled = 1; priority = 1.8; }; class GVAR(Follow) { displayName = CSTRING(Follow); condition = QUOTE(true); - statement = QUOTE([ARR_2(_target,'gestureFollow')] call EFUNC(common,doGesture);); + statement = QUOTE([ARR_2(_target,'gestureFollow')] call EFUNC(common,doGesture)); + //exceptions[] = {"isNotSwimming"}; // Does not work underwater showDisabled = 1; priority = 1.7; }; class GVAR(Up) { displayName = CSTRING(Up); condition = QUOTE(true); - statement = QUOTE([ARR_2(_target,'gestureUp')] call EFUNC(common,doGesture);); + statement = QUOTE([ARR_2(_target,'gestureUp')] call EFUNC(common,doGesture)); + //exceptions[] = {"isNotSwimming"}; // Does not work underwater showDisabled = 1; priority = 1.5; }; class GVAR(CeaseFire) { displayName = CSTRING(CeaseFire); condition = QUOTE(true); - statement = QUOTE([ARR_2(_target,'gestureCeaseFire')] call EFUNC(common,doGesture);); + statement = QUOTE([ARR_2(_target,'gestureCeaseFire')] call EFUNC(common,doGesture)); + //exceptions[] = {"isNotSwimming"}; // Does not work underwater showDisabled = 1; priority = 1.3; }; class GVAR(Stop) { displayName = CSTRING(Stop); condition = QUOTE(true); - statement = QUOTE([ARR_2(_target,'gestureFreeze')] call EFUNC(common,doGesture);); // BI animation - is actualls "stop" in all stances but prone + statement = QUOTE([ARR_2(_target,'gestureFreeze')] call EFUNC(common,doGesture)); // BI animation - is actually "stop" in all stances but prone + //exceptions[] = {"isNotSwimming"}; // Does not work underwater showDisabled = 1; priority = 1.2; }; @@ -57,6 +63,7 @@ class CfgVehicles { displayName = CSTRING(Forward); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(forward)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.9; }; @@ -64,6 +71,7 @@ class CfgVehicles { displayName = CSTRING(Regroup); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(regroup)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.8; }; @@ -71,6 +79,7 @@ class CfgVehicles { displayName = CSTRING(Freeze); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(freeze)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.7; }; @@ -78,6 +87,7 @@ class CfgVehicles { displayName = CSTRING(Cover); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(cover)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.6; }; @@ -85,6 +95,7 @@ class CfgVehicles { displayName = CSTRING(Point); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(point)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.5; }; @@ -92,6 +103,7 @@ class CfgVehicles { displayName = CSTRING(Engage); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(engage)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.4; }; @@ -99,6 +111,7 @@ class CfgVehicles { displayName = CSTRING(Hold); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(hold)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.3; }; @@ -106,6 +119,7 @@ class CfgVehicles { displayName = CSTRING(Warning); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(warning)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; priority = 1.2; }; diff --git a/addons/gestures/XEH_postInit.sqf b/addons/gestures/XEH_postInit.sqf index b2d5de86ef..935b81aa61 100644 --- a/addons/gestures/XEH_postInit.sqf +++ b/addons/gestures/XEH_postInit.sqf @@ -20,6 +20,8 @@ if (!hasInterface) exitWith {}; TRACE_4("Adding KeyBind",_currentName,_signalName,_code,_key); + ["ACE3 Gestures", localize LSTRING(ACEKeybindCategoryGestures)] call CBA_fnc_registerKeybindModPrettyName; + [ "ACE3 Gestures", _currentName, diff --git a/addons/gestures/anim/model.cfg b/addons/gestures/anim/model.cfg new file mode 100644 index 0000000000..be41a523a8 --- /dev/null +++ b/addons/gestures/anim/model.cfg @@ -0,0 +1,124 @@ +class cfgSkeletons +{ + class OFP2_ManSkeleton + { + isDiscrete = 0; + skeletonInherit = ""; + SkeletonBones[]= + { + "Pelvis","", + "Spine","Pelvis", + "Spine1","Spine", + "Spine2","Spine1", + "Spine3","Spine2", + "camera","Pelvis",// case has changed for arma3 + "weapon","Spine1", + "launcher","Spine1", + //Head skeleton in hierarchy + "Neck","Spine3", + "Neck1","Neck", + "Head","Neck1", + + //Left upper side + "LeftShoulder","Spine3", + "LeftArm","LeftShoulder", + "LeftArmRoll","LeftArm", + "LeftForeArm","LeftArmRoll", + "LeftForeArmRoll","LeftForeArm", + "LeftHand","LeftForeArmRoll", + "LeftHandRing","LeftHand", + "LeftHandRing1","LeftHandRing", + "LeftHandRing2","LeftHandRing1", + "LeftHandRing3","LeftHandRing2", + "LeftHandPinky1","LeftHandRing", + "LeftHandPinky2","LeftHandPinky1", + "LeftHandPinky3","LeftHandPinky2", + "LeftHandMiddle1","LeftHand", + "LeftHandMiddle2","LeftHandMiddle1", + "LeftHandMiddle3","LeftHandMiddle2", + "LeftHandIndex1","LeftHand", + "LeftHandIndex2","LeftHandIndex1", + "LeftHandIndex3","LeftHandIndex2", + "LeftHandThumb1","LeftHand", + "LeftHandThumb2","LeftHandThumb1", + "LeftHandThumb3","LeftHandThumb2", + //Right upper side + "RightShoulder","Spine3", + "RightArm","RightShoulder", + "RightArmRoll","RightArm", + "RightForeArm","RightArmRoll", + "RightForeArmRoll","RightForeArm", + "RightHand","RightForeArmRoll", + "RightHandRing","RightHand", + "RightHandRing1","RightHandRing", + "RightHandRing2","RightHandRing1", + "RightHandRing3","RightHandRing2", + "RightHandPinky1","RightHandRing", + "RightHandPinky2","RightHandPinky1", + "RightHandPinky3","RightHandPinky2", + "RightHandMiddle1","RightHand", + "RightHandMiddle2","RightHandMiddle1", + "RightHandMiddle3","RightHandMiddle2", + "RightHandIndex1","RightHand", + "RightHandIndex2","RightHandIndex1", + "RightHandIndex3","RightHandIndex2", + "RightHandThumb1","RightHand", + "RightHandThumb2","RightHandThumb1", + "RightHandThumb3","RightHandThumb2", + //Left lower side + "LeftUpLeg","Pelvis", + "LeftUpLegRoll","LeftUpLeg", + "LeftLeg","LeftUpLegRoll", + "LeftLegRoll","LeftLeg", + "LeftFoot","LeftLegRoll", + "LeftToeBase","LeftFoot", + //Right lower side + "RightUpLeg","Pelvis", + "RightUpLegRoll","RightUpLeg", + "RightLeg","RightUpLegRoll", + "RightLegRoll","RightLeg", + "RightFoot","RightLegRoll", + "RightToeBase","RightFoot", + + //New facial features arma3 only + "Face_Hub","Head", + "Face_Jawbone","Face_Hub", + "Face_Jowl","Face_Jawbone", + "Face_chopRight","Face_Jawbone", + "Face_chopLeft","Face_Jawbone", + "Face_LipLowerMiddle","Face_Jawbone", + "Face_LipLowerLeft","Face_Jawbone", + "Face_LipLowerRight","Face_Jawbone", + "Face_Chin","Face_Jawbone", + "Face_Tongue","Face_Jawbone", + "Face_CornerRight","Face_Hub", + "Face_CheekSideRight","Face_CornerRight", + "Face_CornerLeft","Face_Hub", + "Face_CheekSideLeft","Face_CornerLeft", + "Face_CheekFrontRight","Face_Hub", + "Face_CheekFrontLeft","Face_Hub", + "Face_CheekUpperRight","Face_Hub", + "Face_CheekUpperLeft","Face_Hub", + "Face_LipUpperMiddle","Face_Hub", + "Face_LipUpperRight","Face_Hub", + "Face_LipUpperLeft","Face_Hub", + "Face_NostrilRight","Face_Hub", + "Face_NostrilLeft","Face_Hub", + "Face_Forehead","Face_Hub", + "Face_BrowFrontRight","Face_Forehead", + "Face_BrowFrontLeft","Face_Forehead", + "Face_BrowMiddle","Face_Forehead", + "Face_BrowSideRight","Face_Forehead", + "Face_BrowSideLeft","Face_Forehead", + "Face_Eyelids","Face_Hub", + "Face_EyelidUpperRight","Face_Hub", + "Face_EyelidUpperLeft","Face_Hub", + "Face_EyelidLowerRight","Face_Hub", + "Face_EyelidLowerLeft","Face_Hub", + "EyeLeft","Face_Hub", + "EyeRight","Face_Hub" + };// end of skeleton array + // location of pivot points (local axes) for hierarchical animation + pivotsModel="Samples_F\TemplateRTM\ManSkeleton_Pivots.p3d"; + }; +}; diff --git a/addons/gestures/functions/fnc_playSignal.sqf b/addons/gestures/functions/fnc_playSignal.sqf index 9dc1ecce4b..68a3c1c044 100644 --- a/addons/gestures/functions/fnc_playSignal.sqf +++ b/addons/gestures/functions/fnc_playSignal.sqf @@ -18,7 +18,7 @@ TRACE_1("params",_this); if (GVAR(showOnInteractionMenu) == 0) exitWith {false}; -if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([ACE_player, objNull, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; private _gesture = if ((_this select [0,2]) == "BI") then { //If it starts with BI, just strip off the leading BI and use it directly diff --git a/addons/gestures/stringtable.xml b/addons/gestures/stringtable.xml index 18e8883227..fce2270cbb 100644 --- a/addons/gestures/stringtable.xml +++ b/addons/gestures/stringtable.xml @@ -1,6 +1,22 @@ - + + + ACE Gestures + ACE Gesten + ACE Gesty + ACE Posunky + ACE Gestes + ACE Kézjelek + ACE Gesti + ACE Gestos + ACE Жесты + ACE Gestos + ACE ジェスチャー + ACE 수신호 + ACE 手势 + ACE 手勢 + ACE Gestures ACE Gesten @@ -8,7 +24,7 @@ ACE Posunky ACE Gestes ACE Kézjelek - Gesti ACE + ACE Gesti ACE Gestos ACE Жесты ACE Gestos @@ -277,8 +293,8 @@ Показать жесты в меню взамиодейтсвия с собой или только использовать горячие клавиши, или полностью отключить キー操作や同時使用を無効化している場合はセルフ インタラクション メニュ上でジェスチャーを表示します 수신호를 상호작용 메뉴에서 보여주거나 혹은 단축키를 지정하거나 아니면 아예 사용하지 않습니다. - 显示手势选项在自己的互动选单上, 或只利用键盘来使用手势, 或完全禁用 - 顯示手勢選項在自己的互動選單上, 或只利用鍵盤來使用手勢, 或完全禁用 + 显示手势选项在自己的互动选单上,或只利用键盘来使用手势,或完全禁用 + 顯示手勢選項在自己的互動選單上,或只利用鍵盤來使用手勢,或完全禁用 Just Keybinds diff --git a/addons/gforces/stringtable.xml b/addons/gforces/stringtable.xml index 12d3d0ba53..adf7fb114d 100644 --- a/addons/gforces/stringtable.xml +++ b/addons/gforces/stringtable.xml @@ -1,9 +1,9 @@ - + Gforces Effects - Gforces Effekte + Effekte der G-Kräfte Efectos Gforces G Force efekty Efeitos de ForçaG diff --git a/addons/goggles/ACE_Settings.hpp b/addons/goggles/ACE_Settings.hpp index 659a10b4e3..2b20b46514 100644 --- a/addons/goggles/ACE_Settings.hpp +++ b/addons/goggles/ACE_Settings.hpp @@ -1,12 +1,14 @@ class ACE_Settings { class GVAR(effects) { + category = CSTRING(DisplayName); displayName = CSTRING(effects_displayName); typeName = "SCALAR"; value = 2; values[] = {ECSTRING(common,Disabled), CSTRING(effects_tintOnly), CSTRING(enabled_tintAndEffects)}; }; class GVAR(showInThirdPerson) { + category = CSTRING(DisplayName); value = 0; typeName = "BOOL"; isClientSettable = 1; diff --git a/addons/goggles/XEH_postInit.sqf b/addons/goggles/XEH_postInit.sqf index 5b93a7a459..9927a165f1 100644 --- a/addons/goggles/XEH_postInit.sqf +++ b/addons/goggles/XEH_postInit.sqf @@ -4,7 +4,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Common", QGVAR(wipeGlasses), localize LSTRING(WipeGlasses), { if (GVAR(effects) != 2) exitWith {false}; //Can only wipe if full effects setting is set - if (!(GETVAR(ace_player,ACE_isUnconscious,false))) exitWith { + if (!GETVAR(ace_player,ACE_isUnconscious,false)) exitWith { call FUNC(clearGlasses); true }; diff --git a/addons/goggles/define.hpp b/addons/goggles/define.hpp index 7f83930774..38271ccc67 100644 --- a/addons/goggles/define.hpp +++ b/addons/goggles/define.hpp @@ -7,7 +7,6 @@ //////////////// class RscPicture { - access = 0; idc = -1; type = CT_STATIC; style = ST_PICTURE; diff --git a/addons/goggles/functions/fnc_applyDirtEffect.sqf b/addons/goggles/functions/fnc_applyDirtEffect.sqf index 46f079dc38..2c50595e86 100644 --- a/addons/goggles/functions/fnc_applyDirtEffect.sqf +++ b/addons/goggles/functions/fnc_applyDirtEffect.sqf @@ -17,11 +17,9 @@ if (call FUNC(externalCamera)) exitWith {false}; -private ["_unit", "_effects"]; +private _unit = ACE_player; -_unit = ACE_player; - -_effects = GETGLASSES(_unit); +private _effects = GETGLASSES(_unit); _effects set [DIRT, true]; SETGLASSES(_unit,_effects); diff --git a/addons/goggles/functions/fnc_applyDustEffect.sqf b/addons/goggles/functions/fnc_applyDustEffect.sqf index 6277d34c21..3568137a1f 100644 --- a/addons/goggles/functions/fnc_applyDustEffect.sqf +++ b/addons/goggles/functions/fnc_applyDustEffect.sqf @@ -17,9 +17,7 @@ if (call FUNC(ExternalCamera)) exitWith {}; -private ["_unit", "_amount"]; - -_unit = ACE_player; +private _unit = ACE_player; if ([_unit] call FUNC(isGogglesVisible)) exitWith { GVAR(GogglesEffectsLayer) cutRsc ["RscACE_GogglesEffects", "PLAIN", 2, false]; @@ -42,7 +40,7 @@ if (GETVAR(_unit,ACE_EyesDamaged,false)) exitWith { SETDUST(DAMOUNT,CLAMP(GETDUSTT(DAMOUNT) + 1,0,2)); -_amount = 1 - (GETDUSTT(DAMOUNT) * 0.125); +private _amount = 1 - (GETDUSTT(DAMOUNT) * 0.125); GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [_amount, _amount, _amount, _amount], [1, 1, 1, 0]]; GVAR(PostProcessEyes) ppEffectCommit 1; diff --git a/addons/goggles/functions/fnc_applyGlassesEffect.sqf b/addons/goggles/functions/fnc_applyGlassesEffect.sqf index 71425ce6ca..ccefe45541 100644 --- a/addons/goggles/functions/fnc_applyGlassesEffect.sqf +++ b/addons/goggles/functions/fnc_applyGlassesEffect.sqf @@ -28,12 +28,10 @@ if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _player) >> "isPlayableLo TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) }; -private ["_config", "_postProcessColour", "_postProcessTintAmount", "_imagePath"]; +private _config = configFile >> "CfgGlasses" >> _glasses; -_config = configFile >> "CfgGlasses" >> _glasses; - -_postProcessColour = getArray (_config >> "ACE_Color"); -_postProcessTintAmount = getNumber (_config >> "ACE_TintAmount"); +private _postProcessColour = getArray (_config >> "ACE_Color"); +private _postProcessTintAmount = getNumber (_config >> "ACE_TintAmount"); if (_postProcessTintAmount != 0 && {GVAR(UsePP)}) then { _postProcessColour set [3, _postProcessTintAmount/100]; @@ -45,7 +43,7 @@ if (_postProcessTintAmount != 0 && {GVAR(UsePP)}) then { GVAR(PostProcess) ppEffectCommit 30; }; -_imagePath = getText (_config >> ["ACE_Overlay", "ACE_OverlayCracked"] select GETBROKEN); +private _imagePath = getText (_config >> ["ACE_Overlay", "ACE_OverlayCracked"] select GETBROKEN); if (_imagePath != "") then { GVAR(GogglesLayer) cutRsc ["RscACE_Goggles", "PLAIN", 1, false]; diff --git a/addons/goggles/functions/fnc_applyRainEffect.sqf b/addons/goggles/functions/fnc_applyRainEffect.sqf index 01b2894d87..183335740f 100644 --- a/addons/goggles/functions/fnc_applyRainEffect.sqf +++ b/addons/goggles/functions/fnc_applyRainEffect.sqf @@ -15,13 +15,11 @@ */ #include "script_component.hpp" -private ["_unit", "_fnc_underCover"]; - -_unit = ACE_player; +private _unit = ACE_player; if (!alive _unit) exitWith {}; -_fnc_underCover = { +private _fnc_underCover = { params ["_unit"]; if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith {true}; diff --git a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf index 7a883ab7e7..ffe75f808e 100644 --- a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf +++ b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf @@ -15,9 +15,7 @@ */ #include "script_component.hpp" -private ["_unit", "_fnc_underCover"]; - -_unit = ACE_player; +private _unit = ACE_player; if (!alive _unit) exitWith {}; @@ -33,10 +31,9 @@ if (GVAR(FrameEvent) select 0) exitWith { }; // check if the unit is affected by rotor wash -private ["_rotorWash", "_safe"]; -_rotorWash = GVAR(FrameEvent) select 1; -_safe = false; +private _rotorWash = GVAR(FrameEvent) select 1; +private _safe = false; // no rotor wash? remove effects. if !(_rotorWash select 0) exitWith { diff --git a/addons/goggles/functions/fnc_clearGlasses.sqf b/addons/goggles/functions/fnc_clearGlasses.sqf index b01960527a..c75d94ae1c 100644 --- a/addons/goggles/functions/fnc_clearGlasses.sqf +++ b/addons/goggles/functions/fnc_clearGlasses.sqf @@ -16,12 +16,10 @@ */ #include "script_component.hpp" -private ["_unit", "_broken", "_effects"]; +private _unit = ACE_player; -_unit = ACE_player; - -_broken = GETBROKEN; -_effects = GLASSESDEFAULT; +private _broken = GETBROKEN; +private _effects = GLASSESDEFAULT; _effects set [BROKEN, _broken]; SETGLASSES(_unit,_effects); diff --git a/addons/goggles/functions/fnc_handleExplosion.sqf b/addons/goggles/functions/fnc_handleExplosion.sqf index fcda2a3e49..129cd6fc36 100644 --- a/addons/goggles/functions/fnc_handleExplosion.sqf +++ b/addons/goggles/functions/fnc_handleExplosion.sqf @@ -23,9 +23,7 @@ call FUNC(applyDirtEffect); if (GETBROKEN) exitWith {true}; -private ["_config", "_effects"]; - -_config = configFile >> "CfgGlasses" >> goggles _unit; +private _config = configFile >> "CfgGlasses" >> goggles _unit; if ((_this select 1) call FUNC(GetExplosionIndex) < getNumber (_config >> "ACE_Resistance")) exitWith {true}; @@ -34,7 +32,7 @@ if !([_unit] call FUNC(isGogglesVisible)) exitWith { true }; -_effects = GETGLASSES(_unit); +private _effects = GETGLASSES(_unit); _effects set [BROKEN, true]; SETGLASSES(_unit,_effects); diff --git a/addons/goggles/functions/fnc_handleFired.sqf b/addons/goggles/functions/fnc_handleFired.sqf index e231a4562b..95a22d0a03 100644 --- a/addons/goggles/functions/fnc_handleFired.sqf +++ b/addons/goggles/functions/fnc_handleFired.sqf @@ -24,17 +24,15 @@ if (rain > 0.1) exitWith {true}; // effect only aplies when lying on the ground if (stance _unit != "PRONE") exitWith {true}; -private ["_position", "_particleConfig", "_cloudType", "_surface", "_bullets"]; - // check if the unit really is on the ground and not in a building -_position = getPosATL _unit; +private _position = getPosATL _unit; if (_position select 2 > 0.2) exitWith {true}; // get weapon dust effect -_particleConfig = configFile >> "CfgWeapons" >> _weapon >> "GunParticles"; +private _particleConfig = configFile >> "CfgWeapons" >> _weapon >> "GunParticles"; -_cloudType = ""; +private _cloudType = ""; if (isClass (_particleConfig >> "FirstEffect")) then { // @todo read this with custom / non-standard config classnames _cloudType = getText (_particleConfig >> "FirstEffect" >> "effectName"); @@ -50,7 +48,7 @@ if (_cloudType == "") exitWith {true}; // get if the surface is dusty if (surfaceIsWater _position) exitWith {true}; -_surface = surfaceType _position select [1]; // cuts of the leading # +private _surface = surfaceType _position select [1]; // cuts of the leading # if (_surface != GVAR(surfaceCache)) then { GVAR(surfaceCache) = _surface; @@ -61,7 +59,7 @@ if (_surface != GVAR(surfaceCache)) then { if (!GVAR(surfaceCacheIsDust)) exitWith {true}; // increment dust value with type bullet -_bullets = GETDUSTT(DBULLETS); +private _bullets = GETDUSTT(DBULLETS); if (diag_tickTime - GETDUSTT(DTIME) > 1) then { _bullets = 0; diff --git a/addons/goggles/functions/fnc_isGogglesVisible.sqf b/addons/goggles/functions/fnc_isGogglesVisible.sqf index dfa2b97087..f1205b5df6 100644 --- a/addons/goggles/functions/fnc_isGogglesVisible.sqf +++ b/addons/goggles/functions/fnc_isGogglesVisible.sqf @@ -17,9 +17,7 @@ params ["_unit"]; -private ["_currentGlasses", "_position"]; - -_currentGlasses = goggles _unit; +private _currentGlasses = goggles _unit; if (_currentGlasses == "") exitWith {false}; @@ -27,6 +25,6 @@ if (_currentGlasses == "") exitWith {false}; if (getNumber (configFile >> "CfgGlasses" >> _currentGlasses >> "ACE_Resistance") == 0) exitWith {false}; // check if in water and has diving goggles or on land and not diving goggles -_position = getPosASLW _unit; +private _position = getPosASLW _unit; (surfaceIsWater _position && {_position select 2 < 0.25}) isEqualTo (_currentGlasses call FUNC(isDivingGoggles)) // return diff --git a/addons/goggles/script_component.hpp b/addons/goggles/script_component.hpp index c0c8e43df4..854e27fab3 100644 --- a/addons/goggles/script_component.hpp +++ b/addons/goggles/script_component.hpp @@ -37,6 +37,6 @@ #define DBULLETS 2 #define DAMOUNT 3 -#define GLASSDISPLAY (GETUVAR(GVAR(Display),displayNull)) +#define GLASSDISPLAY GETUVAR(GVAR(Display),displayNull) #define CLAMP(x,low,high) (if(x > high)then{high}else{if(x < low)then{low}else{x}}) diff --git a/addons/goggles/stringtable.xml b/addons/goggles/stringtable.xml index 309a420a46..4c796c6ecc 100644 --- a/addons/goggles/stringtable.xml +++ b/addons/goggles/stringtable.xml @@ -1,6 +1,15 @@ - + + + Goggles + Schutzbrille + Occhiali + 護目鏡 + 护目镜 + ゴーグル + 고글 + Show Goggle Effects in Third Person Brilleneffekt in dritter Person anzeigen @@ -41,7 +50,7 @@ Brilleneffekt 고글 효과 Effets des lunettes - Effetto Occhiali + Effetti Occhiali 护目镜效果 護目鏡效果 diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index 6081daa8af..5b0384da3b 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -34,6 +34,8 @@ #define ORIENTATION 5.4 #define EXPANSION 1 +#define DESTRUCTION_RADIUS 1.8 + params ["_projectile", "_timeToLive", "_center"]; if (isNull _projectile) exitWith {TRACE_1("null",_projectile);}; @@ -169,7 +171,10 @@ if (isServer) then { _x setDamage 1; }; if (_x isKindOf "ReammoBox_F") then { - if ("ace_cookoff" call EFUNC(common,isModLoaded) && {EGVAR(cookoff,enable)}) then { + if ( + "ace_cookoff" call EFUNC(common,isModLoaded) && + {GETVAR(_x,EGVAR(cookoff,enableAmmoCookoff),EGVAR(cookoff,enableAmmobox))} + ) then { _x call EFUNC(cookoff,cookOffBox); } else { _x setDamage 1; @@ -184,7 +189,7 @@ if (isServer) then { // --- inflame fireplace, barrels etc. _x inflame true; }; -} forEach (_position nearObjects EFFECT_SIZE); +} forEach (_position nearObjects DESTRUCTION_RADIUS); // --- damage local vehicle private _vehicle = _position nearestObject "Car"; diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index fb54bed50b..3fc5ce6208 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,7 +12,7 @@ Gránátkezelési mód váltása Cambia tipo di granata Alternar Modo de Granada - グレネード モードを切り替え + 投てき方法を切り替え 투척 종류 전환 切换投掷模式 切換投擲模式 @@ -28,7 +28,7 @@ Normál dobás Lancio normale Arremesso Normal - 通常で投げる + 普通に投げる 일반 던지기 普通投掷 普通投擲 @@ -142,8 +142,8 @@ Também conhecida como flashbang. Causa uma clarão imediato, cegueira, surdez, zumbido e distúrbio no tímpano. フラッシュバンとも知られています。即時に失明と難聴、耳鳴り、内耳障害を引き起こします。 플래시뱅이라고도 알려져있습니다. 사용즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. - 也被称为闪光弹, 会造成暂时性失明, 耳聋, 耳鸣等效果 - 也被稱為閃光彈, 會造成暫時性失明, 耳聾, 耳鳴等效果 + 也被称为闪光弹,会造成暂时性失明,耳聋,耳鸣等效果。 + 也被稱為閃光彈,會造成暫時性失明,耳聾,耳鳴等效果。 M127A1 Hand Held Signal (White) @@ -370,8 +370,8 @@ 소이 수류탄은 무기나 탄약 그리고 장비를 파괴할때 쓰입니다. Grenade incendiaire utilisé pour détruire des armes, munitions et autres équipements. Granata incendiaria usata per distruggere armi, munizioni e altri equipaggiamenti. - 燃烧手榴弹是用来摧毁武器, 弹药以及其他装备的好帮手. - 燃燒手榴彈是用來摧毀武器, 彈藥以及其他裝備的好幫手. + 燃烧手榴弹是用来摧毁武器,弹药以及其他装备的好帮手。 + 燃燒手榴彈是用來摧毀武器,彈藥以及其他裝備的好幫手。 diff --git a/addons/hearing/ACE_Settings.hpp b/addons/hearing/ACE_Settings.hpp index 2fb2a46211..8814f2466d 100644 --- a/addons/hearing/ACE_Settings.hpp +++ b/addons/hearing/ACE_Settings.hpp @@ -10,11 +10,13 @@ class ACE_Settings { category = CSTRING(Module_DisplayName); value = 0.5; typeName = "SCALAR"; + sliderSettings[] = {0, 1, 0.5, 1}; }; class GVAR(unconsciousnessVolume) { category = CSTRING(Module_DisplayName); value = 0.4; typeName = "SCALAR"; + sliderSettings[] = {0, 1, 0.4, 1}; }; class GVAR(disableEarRinging) { category = CSTRING(Module_DisplayName); diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index f44e50e6d0..51e064d16b 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -6,7 +6,7 @@ class CfgVehicles { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}}); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE( [_player] call FUNC(putInEarPlugs) ); showDisabled = 0; priority = 2.5; @@ -15,7 +15,7 @@ class CfgVehicles { class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); condition = QUOTE( GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)}); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE( [_player] call FUNC(removeEarPlugs) ); showDisabled = 0; priority = 2.5; @@ -97,7 +97,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(moduleHearing); - scope = 2; + scope = 1; isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_Hearing_ca.paa); diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 8b138271b3..cba35e403e 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -1,14 +1,15 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_EarPlugs: ACE_ItemCore { + author = ECSTRING(common,ACETeam); displayName = CSTRING(EarPlugs_Name); descriptionShort = CSTRING(EarPlugs_Description); model = QPATHTOF(data\ace_earplugs.p3d); picture = QPATHTOF(UI\ACE_earplugs_x_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; @@ -39,6 +40,22 @@ class CfgWeapons { HEARING_PROTECTION_EARMUFF }; + class H_Construction_earprot_base_F: HelmetBase { + HEARING_PROTECTION_EARMUFF + }; + + class H_Construction_headset_base_F: HelmetBase { + HEARING_PROTECTION_EARMUFF + }; + + class H_EarProtectors_base_F: HelmetBase { + HEARING_PROTECTION_EARMUFF + }; + + class H_HeadSet_base_F: HelmetBase { + HEARING_PROTECTION_EARMUFF + }; + class H_HelmetB_light: H_HelmetB { HEARING_PROTECTION_PELTOR }; diff --git a/addons/hearing/functions/fnc_explosionNear.sqf b/addons/hearing/functions/fnc_explosionNear.sqf index 9087984b50..4917ac009b 100644 --- a/addons/hearing/functions/fnc_explosionNear.sqf +++ b/addons/hearing/functions/fnc_explosionNear.sqf @@ -20,8 +20,7 @@ params ["_unit", "_damage"]; TRACE_2("explosion near player",_unit,_damage); -private ["_strength"]; -_strength = (0 max _damage) * 30; +private _strength = (0 max _damage) * 30; if (_strength < 0.01) exitWith {}; // Call inmediately, as it will get pick up later anyway by the update thread diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index 01ab58ef76..7d0f875414 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -1,10 +1,10 @@ /* * Author: commy2 and esteldunedain and Ruthberg - * Updates and applys the current deafness. Called every 1 sec from a PFEH. + * Updates and applies the current deafness. Called every 1 sec from a PFEH. * * Arguments: * 0: Args - * -----0: Just update volume (skip ringing/recovery) + * 0: Just update volume (skip ringing/recovery) (default: false) * * Return Value: * None @@ -22,7 +22,7 @@ if (!alive ACE_player) exitWith { [QUOTE(ADDON), 1, true] call EFUNC(common,setHearingCapability); }; -(_this select 0) params ["_justUpdateVolume"]; +(_this select 0) params [["_justUpdateVolume", false]]; GVAR(deafnessDV) = (GVAR(deafnessDV) min 20) max 0; GVAR(volume) = (1 - (GVAR(deafnessDV) / 20)) max 0.05; diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index e8b44833ef..d745734ca1 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -30,8 +30,8 @@ Proteggono l'apparato uditivo, permettendo a chi li indossa di resistere ai suoni particolarmente forti senza alcun danno. 着けることにより、近くの大きな銃声から聴覚を保護します。 보호용 귀마개는 화기로부터의 큰소리로부터 사용자의 청력을 보호합니다. - 配戴防护耳塞, 遇到大声的武器发射时也不会损害听力. - 配戴防護耳塞, 遇到大聲的武器發射時也不會損害聽力. + 配戴防护耳塞,遇到大声的武器发射时也不会损害听力。 + 配戴防護耳塞,遇到大聲的武器發射時也不會損害聽力。 Earplugs in @@ -156,8 +156,8 @@ Убирает эффект звона в ушах, когда игрок получает повреждение слуха プレイヤーの聴覚が損傷をしたら耳鳴りの効果を削除します 플레이어가 청력손실을 입을때 생기는 이명현상을 제거합니다. - 关闭耳鸣效果时, 就算玩家受到相当程度的听力伤害, 也不会造成耳鸣效果. - 關閉耳鳴效果時, 就算玩家受到相當程度的聽力傷害, 也不會造成耳鳴效果. + 关闭耳鸣效果时,就算玩家受到相当程度的听力伤害, 也不会造成耳鸣效果 + 關閉耳鳴效果時,就算玩家受到相當程度的聽力傷害, 也不會造成耳鳴效果 Hearing @@ -219,8 +219,8 @@ Controlla la sordità da combattimento e fischio alle orecchie. Quando attivato, i giocatori possono essere assordati quando un'arma spara vicino o avviene un'esplosione senza protezione uditiva 戦闘による難聴や、耳鳴りを設定します。有効になった場合、聴覚を保護していないと近傍の銃声や爆発音により、難聴になります。 전투 난청과 이명현상을 조작합니다. 작동시 플레이어가 화기나 폭발의 주변에 있을경우 청력보호장치가 없을때 청력손실을 입습니다. - 设定战斗性耳聋和耳鸣. 当启用后, 玩家会在有武器在旁边射击或爆炸产生时造成耳鸣效果 - 設定戰鬥性耳聾和耳鳴. 當啟用後, 玩家會在有武器在旁邊射擊或爆炸產生時造成耳鳴效果 + 设定战斗性耳聋和耳鸣。当启用后,玩家会在有武器在旁边射击或爆炸产生时造成耳鸣效果 + 設定戰鬥性耳聾和耳鳴。當啟用後,玩家會在有武器在旁邊射擊或爆炸產生時造成耳鳴效果 Effect Zeus RC @@ -249,8 +249,8 @@ Permet aux unités controlées à distance de subir des traumatismes sonores. Zeus により遠隔操作されたユニットにも、聴覚へ損傷を受けるようにします。 Zeus가 원격으로 청력손실을 입힐 수 있게 합니다. - 设定宙斯远程遥控的单位也会受到耳鸣的效果. - 設定宙斯遠程遙控的單位也會受到耳鳴的效果. + 设定宙斯远程遥控的单位也会受到耳鸣的效果。 + 設定宙斯遠程遙控的單位也會受到耳鳴的效果。 Add earplugs to units @@ -269,7 +269,7 @@ Add the `ACE_EarPlugs` item to all units that have loud weapons. Can disable if using custom loadouts. - Fügt die "ACE_EarPlugs" zu allen Einheiten mit lauten Waffen hinzu. Wird deaktiviert wenn eine eigene Inventarkonfiguration vorgenommen wurde. + Fügt die "ACE_EarPlugs" zu allen Einheiten mit lauten Waffen hinzu. Wird deaktiviert wenn eigene Ausrüstungsprofile verwendet werden. Dodaje `ACE_EarPlugs` - stopery - do wszystkich jednostek, które posiadają głośną broń. Można wyłaczyć w przypadku korzystania z niestandardowych loadoutów. Добавляет предмет `ACE_EarPlugs` всем юнитам, которые имеют громкое оружие. Можно отключить при ручной настройке снаряжения. Adicionar o item `ACE_EarPlugs` a todas as unidades que tenham armas barulhentas. Pode ser desabilitado com carregamentos customizados. @@ -279,8 +279,8 @@ Ajoute l'objet "Ace_EarPlugs" à toutes les unités ayant des armes bruyantes. Peut être désactivé par des loadouts personalisés. 全ユニットへ`ACE_EarPlugs`アイテムをもたせます。これは変更された武装で無効化できます。 무기를 가지고 있는 모든 인원에게 'ACE_EarPlugs'를 지급합니다. 임의의 장비를 사용시 비활성화 할 수 있습니다. - 增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位. 当你想自定装备时, 此功能可被关闭. - 增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位. 當你想自定裝備時, 此功能可被關閉. + 增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位。当你想自定装备时,此功能可被关闭。 + 增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。 diff --git a/addons/hellfire/ACE_GuidanceConfig.hpp b/addons/hellfire/ACE_GuidanceConfig.hpp index 1c5d4705f3..ad3d8c667d 100644 --- a/addons/hellfire/ACE_GuidanceConfig.hpp +++ b/addons/hellfire/ACE_GuidanceConfig.hpp @@ -1,6 +1,5 @@ class EGVAR(missileguidance,AttackProfiles) { - class hellfire { - // LOBL and LOAL-DIR behaive the same + class hellfire { name = "LOAL-DIR"; nameLocked = "LOBL"; functionName = QFUNC(attackProfile); @@ -8,10 +7,12 @@ class EGVAR(missileguidance,AttackProfiles) { }; class hellfire_hi: hellfire { name = "LOAL-HI"; + nameLocked = "LOAL-HI"; GVAR(launchHeightClear) = 304.8; // clear 1000 ft by 1500m }; class hellfire_lo: hellfire_hi { name = "LOAL-LO"; + nameLocked = "LOAL-LO"; GVAR(launchHeightClear) = 91.5; // clear 300 ft by 600m }; }; diff --git a/addons/hellfire/CfgMagazines.hpp b/addons/hellfire/CfgMagazines.hpp index 79c5b5016c..de63540a2a 100644 --- a/addons/hellfire/CfgMagazines.hpp +++ b/addons/hellfire/CfgMagazines.hpp @@ -24,7 +24,7 @@ class CfgMagazines { count = 1; mass = 85; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"B_MISSILE_PYLON", "SCALPEL_1RND_EJECTOR", "B_ASRRAM_EJECTOR", "UNI_SCALPEL"}; + hardpoints[] = {"B_MISSILE_PYLON", "SCALPEL_1RND_EJECTOR", "B_ASRRAM_EJECTOR", "UNI_SCALPEL", "CUP_NATO_HELO_SMALL", "CUP_NATO_HELO_LARGE", "RHS_HP_MELB"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_1x_Missile_AA_04_F.p3d"; }; class PylonRack_3Rnd_ACE_Hellfire_AGM114K: 6Rnd_ACE_Hellfire_AGM114K { // 3x Launcher Support Rack @@ -32,7 +32,7 @@ class CfgMagazines { count = 3; mass = 250; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL"}; + hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_LONGBOW_RACK"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_3x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 3}; }; @@ -41,7 +41,7 @@ class CfgMagazines { count = 4; mass = 340; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"UNI_SCALPEL"}; + hardpoints[] = {"UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_HELLFIRE_RACK", "RHS_HP_LONGBOW_RACK"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_4x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 4, 3}; }; diff --git a/addons/hellfire/CfgWeapons.hpp b/addons/hellfire/CfgWeapons.hpp index 483f1dd0a7..e55492a59c 100644 --- a/addons/hellfire/CfgWeapons.hpp +++ b/addons/hellfire/CfgWeapons.hpp @@ -2,8 +2,9 @@ class CfgWeapons { class missiles_SCALPEL; class GVAR(launcher): missiles_SCALPEL { displayName = "AGM-114K Hellfire II"; - GVAR(enabled) = 1; // show attack profile / lock on hud + GVAR(enabled) = 1; // handle adding interactions and adding Laser Designator EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) + EGVAR(laser,showHud) = 1; // show attack profile / lock on hud canLock = 0; weaponLockSystem = 0; magazines[] = {"6Rnd_ACE_Hellfire_AGM114K", "PylonMissile_1Rnd_ACE_Hellfire_AGM114K", "PylonRack_1Rnd_ACE_Hellfire_AGM114K", "PylonRack_3Rnd_ACE_Hellfire_AGM114K", "PylonRack_4Rnd_ACE_Hellfire_AGM114K"}; diff --git a/addons/hellfire/XEH_PREP.hpp b/addons/hellfire/XEH_PREP.hpp index 8b07d00b2c..f30cf0bffd 100644 --- a/addons/hellfire/XEH_PREP.hpp +++ b/addons/hellfire/XEH_PREP.hpp @@ -2,4 +2,3 @@ LOG("prep"); PREP(attackProfile); PREP(getAttackProfileSettings); PREP(setupVehicle); -PREP(showHud); diff --git a/addons/hellfire/XEH_postInit.sqf b/addons/hellfire/XEH_postInit.sqf index 34fc5b92ba..e89bf7a3e3 100644 --- a/addons/hellfire/XEH_postInit.sqf +++ b/addons/hellfire/XEH_postInit.sqf @@ -2,9 +2,16 @@ if (!hasInterface) exitWith {}; -GVAR(pfID) = -1; - ["ace_settingsInitialized", { - ["turret", LINKFUNC(showHud), false] call CBA_fnc_addPlayerEventHandler; - ["vehicle", LINKFUNC(showHud), true] call CBA_fnc_addPlayerEventHandler; // only one of these needs the retro flag + ["turret", LINKFUNC(setupVehicle), false] call CBA_fnc_addPlayerEventHandler; + ["vehicle", LINKFUNC(setupVehicle), true] call CBA_fnc_addPlayerEventHandler; // only one of these needs the retro flag + + // Add UAV Control Compatibility + ["ACE_controlledUAV", { + params ["_UAV", "_seatAI", "_turret", "_position"]; + TRACE_4("ACE_controlledUAV EH",_UAV,_seatAI,_turret,_position); + if (!isNull _seatAI) then { + [_seatAI] call FUNC(setupVehicle); + }; + }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/hellfire/config.cpp b/addons/hellfire/config.cpp index 14c00904f1..8df1594612 100644 --- a/addons/hellfire/config.cpp +++ b/addons/hellfire/config.cpp @@ -20,4 +20,3 @@ class CfgPatches { #include "CfgMagazines.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" -#include "RscTitles.hpp" diff --git a/addons/hellfire/functions/fnc_setupVehicle.sqf b/addons/hellfire/functions/fnc_setupVehicle.sqf index 811e6c6f3f..36b724d8a6 100644 --- a/addons/hellfire/functions/fnc_setupVehicle.sqf +++ b/addons/hellfire/functions/fnc_setupVehicle.sqf @@ -4,22 +4,42 @@ * Also adds a Laser Designator if vehicle is configured for one. * * Arguments: - * 0: Vehicle - * 1: Player's Turret Path + * 0: Player * * Return Value: * Nothing * * Example: - * [(vehicle player), [0]] call ace_hellfire_fnc_setupVehicle + * [player] call ace_hellfire_fnc_setupVehicle * * Public: No */ // #define DEBUG_MODE_FULL #include "script_component.hpp" -params ["_vehicle", "_turretPath"]; -TRACE_2("setupVehicle",_vehicle,_turretPath); + +params ["_player"]; +// Note: player may be the currently controlled UAV's AI unit (so may be different from ace_player) +TRACE_1("showHud",_player); + +private _enabled = false; +private _vehicle = vehicle _player; +private _turretPath = [-1]; + +if ((alive _player) && {_player != _vehicle}) then { + if (_player != (driver _vehicle)) then { + _turretPath = _player call CBA_fnc_turretPath + }; + { + if ((getNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(enabled))) == 1) then { + TRACE_1("enabled",_x); + _enabled = true; + }; + } forEach (_vehicle weaponsTurret _turretPath); +}; + +if (!_enabled) exitWith {TRACE_3("Not enabled",_enabled,_vehicle,_turretPath);}; + // Add laser if vehicle is configured for one: if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QGVAR(addLaserDesignator))) == 1) then { @@ -40,7 +60,7 @@ if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> QGVAR(addLas _vehicle addWeaponTurret ["Laserdesignator_mounted", _turretPath]; _vehicle addMagazineTurret ["Laserbatteries", _turretPath]; }; - }, _this, 1] call CBA_fnc_waitAndExecute; // Need to delay slightly for turret to become local (probably only needs a single frame) + }, [_vehicle, _turretPath], 1] call CBA_fnc_waitAndExecute; // Need to delay slightly for turret to become local (probably only needs a single frame) }; diff --git a/addons/hellfire/script_component.hpp b/addons/hellfire/script_component.hpp index 2e8cf04eff..6d16736a9c 100644 --- a/addons/hellfire/script_component.hpp +++ b/addons/hellfire/script_component.hpp @@ -20,8 +20,3 @@ #define STAGE_SEEK_CRUISE 2 #define STAGE_ATTACK_CRUISE 3 #define STAGE_ATTACK_TERMINAL 4 - -#define IDC_MODECONTROLGROUP 1000 -#define IDC_ATTACKMODE 1001 -#define IDC_LASERCODE 1002 -#define IDC_LASERICON 1003 diff --git a/addons/hellfire/stringtable.xml b/addons/hellfire/stringtable.xml index 8afbad9bd8..34ed9555ed 100644 --- a/addons/hellfire/stringtable.xml +++ b/addons/hellfire/stringtable.xml @@ -1,12 +1,15 @@ - + Set Hellfire mode + Setze Hellfire-Modus Imposta modalità Hellfire ヘルファイア モードを設定 设定地狱火模式 設定地獄火模式 + Ustaw tryb pocisku Hellfire + 헬파이어 모드 세팅 diff --git a/addons/hitreactions/ACE_Settings.hpp b/addons/hitreactions/ACE_Settings.hpp index 4fa45e8ebc..0220e09629 100644 --- a/addons/hitreactions/ACE_Settings.hpp +++ b/addons/hitreactions/ACE_Settings.hpp @@ -4,5 +4,7 @@ class ACE_Settings { //Minimum mamage needed to trigger falling down while moving. Set to -1 to disable completely. typeName = "SCALAR"; value = 0.1; + displayName = CSTRING(minDamageToTrigger_displayName); + sliderSettings[] = {-1, 1, 0.1, 1}; }; }; diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml new file mode 100644 index 0000000000..3b26084538 --- /dev/null +++ b/addons/hitreactions/stringtable.xml @@ -0,0 +1,14 @@ + + + + + Min Damage to trigger falling + Danno Minimo da caduta se colpiti + 觸發倒下前最低需受到多少傷害 + 触发倒下前最低需受到多少伤害 + 崩れ落ちるまでの最低損傷値 + 방아쇠를 당기는 최소한의 피해 + Mindestschaden, um Sturz auszulösen + + + diff --git a/addons/huntir/CfgVehicles.hpp b/addons/huntir/CfgVehicles.hpp index cd5054a2da..99ca6f69a3 100644 --- a/addons/huntir/CfgVehicles.hpp +++ b/addons/huntir/CfgVehicles.hpp @@ -7,7 +7,7 @@ class CfgVehicles { class GVAR(open) { displayName = CSTRING(activateMonitor); condition = QUOTE([ARR_2(ACE_player,'ACE_HuntIR_monitor')] call EFUNC(common,hasItem)); - statement = QUOTE(call FUNC(huntir)); + statement = QUOTE([FUNC(huntir)] call CBA_fnc_execNextFrame;); showDisabled = 0; priority = 2; icon = QPATHTOF(UI\w_huntir_monitor_ca.paa); diff --git a/addons/huntir/CfgWeapons.hpp b/addons/huntir/CfgWeapons.hpp index 8a3b57c4b0..7cda0e7066 100644 --- a/addons/huntir/CfgWeapons.hpp +++ b/addons/huntir/CfgWeapons.hpp @@ -1,16 +1,17 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_HuntIR_monitor: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(monitor_displayName); picture = QPATHTOF(UI\w_huntir_monitor_ca.paa); descriptionShort = CSTRING(monitor_displayName); model = QPATHTOF(data\ace_huntir_monitor.p3d); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 20; }; }; diff --git a/addons/huntir/functions/fnc_cam.sqf b/addons/huntir/functions/fnc_cam.sqf index 4c9ba71745..753293f5ad 100644 --- a/addons/huntir/functions/fnc_cam.sqf +++ b/addons/huntir/functions/fnc_cam.sqf @@ -135,22 +135,20 @@ GVAR(no_cams) sort true; }; }; - private ["_cam_coord_y", "_cam_coord_x", "_cam_time", "_cam_pos"]; - GVAR(logic) setPosATL (GVAR(pos) vectorAdd [0, 0, -5]); GVAR(logic) setDir GVAR(ROTATE); GVAR(logic) setVectorUp [0.0001, 0.0001, 1]; GVAR(cam) CameraEffect ["internal", "BACK"]; - _cam_coord_y = GVAR(ELEVAT) * cos(GVAR(ROTATE)); - _cam_coord_x = GVAR(ELEVAT) * sin(GVAR(ROTATE)); + private _cam_coord_y = GVAR(ELEVAT) * cos(GVAR(ROTATE)); + private _cam_coord_x = GVAR(ELEVAT) * sin(GVAR(ROTATE)); GVAR(cam) camSetRelPos [_cam_coord_x, _cam_coord_y, 2]; GVAR(cam) camCommit 0; ctrlSetText [1, format["%1 m", round(GVAR(pos) select 2)]]; ctrlSetText [2, format["%1", GVAR(cur_cam) + 1]]; - _cam_time = CBA_missionTime - (GVAR(huntIR) getVariable [QGVAR(startTime), CBA_missionTime]); + private _cam_time = CBA_missionTime - (GVAR(huntIR) getVariable [QGVAR(startTime), CBA_missionTime]); ctrlSetText [3, format["%1 s", round(_cam_time)]]; - _cam_pos = getPosVisual GVAR(huntIR); + private _cam_pos = getPosVisual GVAR(huntIR); _cam_pos = format ["X = %1, Y = %2", round (_cam_pos select 0), round (_cam_pos select 1)]; ctrlSetText [5, _cam_pos]; ctrlSetText [6, ""]; diff --git a/addons/huntir/functions/fnc_handleFired.sqf b/addons/huntir/functions/fnc_handleFired.sqf index 50ed4713aa..85e228f958 100644 --- a/addons/huntir/functions/fnc_handleFired.sqf +++ b/addons/huntir/functions/fnc_handleFired.sqf @@ -33,9 +33,8 @@ if (!hasInterface) exitWith {}; "ACE_HuntIR_Propell" createVehicle (getPosATL _projectile); [{ - private ["_huntir"]; params ["_position"]; - _huntir = createVehicle ["ACE_HuntIR", _position, [], 0, "FLY"]; + private _huntir = createVehicle ["ACE_HuntIR", _position, [], 0, "FLY"]; _huntir setPosATL _position; _huntir setVariable [QGVAR(startTime), CBA_missionTime, true]; [{ @@ -44,10 +43,10 @@ if (!hasInterface) exitWith {}; if (isNull _huntir) exitWith { [_idPFH] call CBA_fnc_removePerFrameHandler; }; - private ["_parachuteDamage", "_velocity"]; - _parachuteDamage = _huntir getHitPointDamage "HitParachute"; + + private _parachuteDamage = _huntir getHitPointDamage "HitParachute"; if (_parachuteDamage > 0) then { - _velocity = velocity _huntir; + private _velocity = velocity _huntir; _velocity set [2, -1 min -20 * sqrt(_parachuteDamage)]; _huntir setVelocity _velocity; _huntir setVectorUp [0, 0, 1]; diff --git a/addons/huntir/functions/fnc_huntir.sqf b/addons/huntir/functions/fnc_huntir.sqf index f692da749b..075e2a9e6a 100644 --- a/addons/huntir/functions/fnc_huntir.sqf +++ b/addons/huntir/functions/fnc_huntir.sqf @@ -46,9 +46,16 @@ createDialog QGVAR(cam_dialog_off); closeDialog 0; }; - private ["_elapsedTime", "_nearestHuntIRs"]; - _elapsedTime = CBA_missionTime - GVAR(startTime); - _nearestHuntIRs = ACE_player nearEntities ["ACE_HuntIR", HUNTIR_MAX_TRANSMISSION_RANGE]; + private _elapsedTime = CBA_missionTime - GVAR(startTime); + private _nearestHuntIRs = ACE_player nearEntities ["ACE_HuntIR", HUNTIR_MAX_TRANSMISSION_RANGE]; + + if ((GVAR(state) in ["connecting", "connected"]) && {_nearestHuntIRs isEqualTo []}) then { + TRACE_1("reseting back to search because no valid ammo exists anymore",GVAR(state)); + GVAR(state) = "searching"; + GVAR(done) = false; + GVAR(message) = []; + GVAR(connectionDelay) = 5; + }; if ((!dialog) || GVAR(done)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/addons/huntir/functions/fnc_huntirCompass.sqf b/addons/huntir/functions/fnc_huntirCompass.sqf index 662dd621a3..d6fc417353 100644 --- a/addons/huntir/functions/fnc_huntirCompass.sqf +++ b/addons/huntir/functions/fnc_huntirCompass.sqf @@ -32,9 +32,7 @@ disableSerialization; #define __CENTER_X 0.70 #define __CENTER_Y 0.65 -private ["_fnc_correctIt"]; - -_fnc_correctIt = { +private _fnc_correctIt = { params ["_pos", "_dir"]; if (_dir >= 270 || {_dir <= 90}) then { _pos set [1, (_pos select 1) + __OFFSET_Y] @@ -62,12 +60,11 @@ HUNTIR_CAM_ROSE_LAYER_ID cutRsc [QGVAR(cam_rose), "PLAIN"]; [_idPFH] call CBA_fnc_removePerFrameHandler; }; - private ["_dir", "_x1", "_y1", "_pos"]; - _dir = getDir GVAR(cam); // direction player; + private _dir = getDir GVAR(cam); // direction player; - _x1 = __CENTER_X - (__RADIUS * sin(_dir)); - _y1 = __CENTER_Y - (__RADIUS * cos(_dir)); - _pos = [[_x1, _y1], _dir] call _fnc_correctIt; + private _x1 = __CENTER_X - (__RADIUS * sin(_dir)); + private _y1 = __CENTER_Y - (__RADIUS * cos(_dir)); + private _pos = [[_x1, _y1], _dir] call _fnc_correctIt; __CHAR_N ctrlSetPosition [_pos select 0, _pos select 1, __WIDTH, __HEIGHT]; __CHAR_N ctrlCommit 0; diff --git a/addons/huntir/functions/fnc_keyPressed.sqf b/addons/huntir/functions/fnc_keyPressed.sqf index 82764ffd05..90f74415a3 100644 --- a/addons/huntir/functions/fnc_keyPressed.sqf +++ b/addons/huntir/functions/fnc_keyPressed.sqf @@ -16,8 +16,7 @@ */ #include "script_component.hpp" -private ["_ret"]; -_ret = false; +private _ret = false; switch (_this select 1) do { // A = Lower zoom level diff --git a/addons/huntir/stringtable.xml b/addons/huntir/stringtable.xml index 3bba8c02ab..9360774031 100644 --- a/addons/huntir/stringtable.xml +++ b/addons/huntir/stringtable.xml @@ -188,7 +188,7 @@ Gauche/Droite - Rotation de la caméra Jobb/Bal - Kamera forgatás Esquerda/Direita - Rotaciona câmera - Left/Right - カメラを開店 + Left/Right - カメラ回転 좌/우 - 카메라 돌리기 左/右 - 旋转摄影机 左/右 - 旋轉攝影機 @@ -252,7 +252,7 @@ Esc - Sortir de l'aide Exit - Kilépés a súgóból Esc - Sai do Ajuda - Esc - ヘルプを出る + Esc - ヘルプ終了 Esc - 도움말 나가기 Esc - 离开帮助 Esc - 離開幫助 diff --git a/addons/interact_menu/CursorMenus.hpp b/addons/interact_menu/CursorMenus.hpp index 7705f3fcd2..385c3a0f75 100644 --- a/addons/interact_menu/CursorMenus.hpp +++ b/addons/interact_menu/CursorMenus.hpp @@ -1,6 +1,5 @@ class GVAR(cursorMenu) { idd = 91919; - access = 0; movingEnable = 0; enableSimulation = 1; onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(dlgCursorMenu)),_this select 0)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(cursorMenuOpened)),true)]); @@ -25,7 +24,6 @@ class RscTitles { text = ""; sizeEx = 0; lineSpacing = 0; - access = 0; type = 0; style = 0; size = 1; diff --git a/addons/interact_menu/XEH_PREP.hpp b/addons/interact_menu/XEH_PREP.hpp index 55c35d54df..840acbf10d 100644 --- a/addons/interact_menu/XEH_PREP.hpp +++ b/addons/interact_menu/XEH_PREP.hpp @@ -1,12 +1,14 @@ PREP(addActionToClass); PREP(addActionToObject); +PREP(addActionToZeus); PREP(addMainAction); PREP(compileMenu); PREP(compileMenuSelfAction); PREP(compileMenuZeus); PREP(collectActiveActionTree); PREP(createAction); +PREP(createVehiclesActions); PREP(ctrlSetParsedTextCached); PREP(findActionNode); PREP(handleEscapeMenu); diff --git a/addons/interact_menu/functions/fnc_addActionToZeus.sqf b/addons/interact_menu/functions/fnc_addActionToZeus.sqf new file mode 100644 index 0000000000..66c1f29d08 --- /dev/null +++ b/addons/interact_menu/functions/fnc_addActionToZeus.sqf @@ -0,0 +1,45 @@ +/* + * Author: PabstMirror + * Insert an ACE action to zeus. + * Note: This function is NOT global. + * + * Arguments: + * 0: Parent path of the new action (e.g. ["ACE_ZeusActions"]) + * 1: Action + * + * Return Value: + * The entry full path, which can be used to add children entries . + * + * Example: + * [["ACE_ZeusActions"], zeusAction] call ace_interact_menu_fnc_addActionToZeus; + * + * Public: Yes + */ +#include "script_component.hpp" + +if (!params [["_parentPath", [], [[]]], ["_action", [], [[]], 11]]) exitWith {ERROR("Bad Params"); []}; +if ((_parentPath param [0, ""]) != "ACE_ZeusActions") exitWith {ERROR_1("Bad path %1 - should have ACE_ZeusActions as base", _parentPath); []}; +TRACE_2("addActionToZeus",_parentPath,_action); + +private _currentPath = GVAR(ZeusActions); +private _pathValid = false; +{ + private _targetParent = _x; + _pathValid = false; + { + _x params ["_xAction", "_xSubActions"]; + TRACE_2("",_targetParent,_xAction); + if ((_xAction select 0) == _targetParent) exitWith { + _pathValid = true; + _currentPath = _xSubActions; + }; + } forEach _currentPath; +} forEach _parentPath; + +if (!_pathValid) exitWith {ERROR_1("Bad path %1", _parentPath); []}; + +TRACE_1("Adding Action",_currentPath); +_currentPath pushBack [_action, []]; + +// Return the full path +(_parentPath + [_action select 0]) diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index 9209447630..b4d969667b 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -117,7 +117,7 @@ private _actions = [ // Dummy statement so it's not collapsed when there's no available actions true }, - {[ACE_player, _target, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder"]] call EFUNC(common,canInteractWith)}, + {[ACE_player, _target, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)}, {}, {}, "Spine3", diff --git a/addons/interact_menu/functions/fnc_createVehiclesActions.sqf b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf new file mode 100644 index 0000000000..4f29b9e65b --- /dev/null +++ b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf @@ -0,0 +1,33 @@ +/* + * Author: Dystopian + * Creates child actions for vehicle list. + * Statement gets vehicle as action parameter. + * + * Arguments: + * 0: Vehicle list + * 1: Statement + * 2: Target + * + * Return Value: + * Array of actions + * + * Example: + * [nearestObjects [player, ["AllVehicles"], 10], {}, cursorObject] call ace_interact_menu_fnc_createVehiclesActions + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicles", "_statement", "_target"]; + +_vehicles apply { + private _type = typeOf _x; + private _name = getText (configFile >> "CfgVehicles" >> _type >> "displayName"); + private _ownerName = [_x, true] call EFUNC(common,getName); + if ("" != _ownerName) then { + _name = format ["%1 (%2)", _name, _ownerName]; + }; + private _icon = [_type] call EFUNC(common,getVehicleIcon); + private _action = [format ["%1", _x], _name, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); + [_action, [], _target] +} diff --git a/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf b/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf index 41e16e8951..d390d23d94 100644 --- a/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf +++ b/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf @@ -3,10 +3,13 @@ * Handle the escape key being pressed. * * Arguments: - * 0: Escape menu display that should be closed + * 0: Escape menu display that should be closed (default: displayNull) * * Return Value: - * Nothing + * None + * + * Example: + * [display] call ace_interact_menu_fnc_handleEscapeMenu * * Public: No */ diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 52388ffe89..5d19434c79 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -21,7 +21,7 @@ if (GVAR(openedMenuType) == _menuType) exitWith {true}; // Conditions: canInteract (these don't apply to zeus) if ((isNull curatorCamera) && { - !([ACE_player, objNull, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) + !([ACE_player, objNull, ["isNotInside","isNotDragging", "isNotCarrying", "isNotSwimming", "notOnMap", "isNotEscorting", "isNotSurrendering", "isNotSitting", "isNotOnLadder", "isNotRefueling"]] call EFUNC(common,canInteractWith)) }) exitWith {false}; while {dialog} do { @@ -41,6 +41,7 @@ GVAR(lastTimeSearchedActions) = -1000; GVAR(ParsedTextCached) = []; GVAR(useCursorMenu) = (vehicle ACE_player != ACE_player) || + (!(isNull (ACE_controlledUAV select 0))) || visibleMap || (!isNull curatorCamera) || {(_menuType == 1) && {(isWeaponDeployed ACE_player) || GVAR(AlwaysUseCursorSelfInteraction) || {cameraView == "GUNNER"}}} || @@ -93,12 +94,20 @@ GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff ( //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (vehicle ACE_player != ACE_player) then { - GVAR(menuDepthPath) = [["ACE_SelfActions", (vehicle ACE_player)]]; + if (!(isNull (ACE_controlledUAV select 0))) then { + GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; GVAR(expanded) = true; GVAR(expandedTime) = diag_tickTime; GVAR(lastPath) = +GVAR(menuDepthPath); GVAR(startHoverTime) = -1000; + } else { + if (vehicle ACE_player != ACE_player) then { + GVAR(menuDepthPath) = [["ACE_SelfActions", (vehicle ACE_player)]]; + GVAR(expanded) = true; + GVAR(expandedTime) = diag_tickTime; + GVAR(lastPath) = +GVAR(menuDepthPath); + GVAR(startHoverTime) = -1000; + }; }; } else { GVAR(menuDepthPath) = [["ACE_ZeusActions", (getAssignedCuratorLogic player)]]; diff --git a/addons/interact_menu/functions/fnc_removeActionFromObject.sqf b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf index 3b720d3c71..fd59e0eb4a 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromObject.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf @@ -19,12 +19,11 @@ params ["_object", "_typeNum", "_fullPath"]; -private ["_res","_varName","_actionList"]; -_res = _fullPath call FUNC(splitPath); +private _res = _fullPath call FUNC(splitPath); _res params ["_parentPath", "_actionName"]; -_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; -_actionList = _object getVariable [_varName, []]; +private _varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; +private _actionList = _object getVariable [_varName, []]; { if (((_x select 0) select 0) isEqualTo _actionName && {(_x select 1) isEqualTo _parentPath}) exitWith { diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 0572f15fa6..8d0e2de397 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -130,17 +130,22 @@ GVAR(collectedActionPoints) resize 0; // Render nearby actions, unit self actions or vehicle self actions as appropiate if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (vehicle ACE_player == ACE_player) then { - if (diag_tickTime > GVAR(lastTimeSearchedActions) + 0.20) then { - // Once every 0.2 secs, collect nearby objects active and visible action points and render them - call _fnc_renderNearbyActions; - } else { - // The rest of the frames just draw the same action points rendered the last frame - call _fnc_renderLastFrameActions; - }; + if (!(isNull (ACE_controlledUAV select 0))) then { + // Render UAV self actions when in control of UAV AI + (ACE_controlledUAV select 0) call _fnc_renderSelfActions; } else { - // Render vehicle self actions when in vehicle - (vehicle ACE_player) call _fnc_renderSelfActions; + if (vehicle ACE_player == ACE_player) then { + if (diag_tickTime > GVAR(lastTimeSearchedActions) + 0.20) then { + // Once every 0.2 secs, collect nearby objects active and visible action points and render them + call _fnc_renderNearbyActions; + } else { + // The rest of the frames just draw the same action points rendered the last frame + call _fnc_renderLastFrameActions; + }; + } else { + // Render vehicle self actions when in vehicle + (vehicle ACE_player) call _fnc_renderSelfActions; + }; }; } else { // Render zeus actions when zeus open diff --git a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf index 4b88212d59..fefab99721 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -37,7 +37,7 @@ private _pos = if((count _this) > 2) then { // For non-self actions, exit if the action is too far away or ocluded private _distanceToBasePoint = 0; //This will be 0 for self/zeus/in-vehicle (used later to check sub action distance) -if ((GVAR(openedMenuType) == 0) && {vehicle ACE_player == ACE_player} && {isNull curatorCamera} && +if ((GVAR(openedMenuType) == 0) && {isNull (ACE_controlledUAV select 0)} && {vehicle ACE_player == ACE_player} && {isNull curatorCamera} && { private _headPos = ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot"); _distanceToBasePoint = _headPos distance _pos; diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index 83d9b1c31f..a05dcee3e4 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -222,8 +222,8 @@ Mantieni il cursore centrato e sposta il menù intorno. Utile se lo schermo è piccolo. 常にカーソルを中央へ表示させ、オプション メニューが移動します。画面の大きさが制限されている時に使いやすくなります。 커서를 항상 가운데에 두고 메뉴를 움직입니다. 화면의 크기가 제한되있을때 유용합니다. - 保持游标在中心点并平移周遭的选项选单. 这对在荧幕尺寸有限的玩家很有用! - 保持游標在中心點並平移周遭的選項選單. 這對在螢幕尺寸有限的玩家很有用! + 保持游标在中心点并平移周遭的选项选单。这对在荧幕尺寸有限的玩家很有用! + 保持游標在中心點並平移周遭的選項選單。這對在螢幕尺寸有限的玩家很有用! Do action when releasing menu key @@ -286,8 +286,8 @@ Permette di controllare l'ombra del testo. L'impostazione "Contorno" ignora il colore dell'ombra. 文字への影を設定します。縁取りは設定された影の色を無視します。 문자의 그림자를 조절하는것을 가능케합니다. 외각선은 임의의 그림자색을 무시합니다. - 允许控制文字阴影. 轮廓部分则会忽略自定义的阴影颜色 - 允許控制文字陰影. 輪廓部分則會忽略自定義的陰影顏色 + 允许控制文字阴影。轮廓部分则会忽略自定义的阴影颜色。 + 允許控制文字陰影。輪廓部分則會忽略自定義的陰影顏色。 Outline @@ -334,8 +334,8 @@ Sfoca lo sfondo mentre il Menù Interazioni è aperto. インタラクション メニューを開いたとき、背景にボケを与えます。 상호작용 메뉴가 열릴시 배경을 흐릿하게 처리합니다. - 当互动选单开启时, 模糊背景画面 - 當互動選單開啟時, 模糊背景畫面 + 当互动选单开启时,模糊背景画面。 + 當互動選單開啟時,模糊背景畫面。 Blur screen @@ -398,8 +398,8 @@ Aggiunge azioni interattive per l'apertura delle porte e piazzamento scale su edifici. (Nota: C'è un costo in performance quando si apre il Menù Interazioni, soprattutto in città) 建物にあるドアの開閉やラダーの昇降といった動作をインタラクションへ追加します。(街などでインタラクション メニューを開くとパフォーマンスが低下します) 건물의 문을 열거나 사다리에 오르는 상호작용 행동을 추가합니다. (주의: 상호작용 메뉴를 열경우 성능하락이 있을 수 있음, 특히 마을 내부에서) - 增加互动选单的功能在可开启的门与建筑物的梯子上. (注意: 此功能有可能会降低系统效能, 特别是在城镇区更明显) - 增加互動選單的功能在可開啟的門與建築物的梯子上. (注意: 此功能有可能會降低系統效能, 特別是在城鎮區更明顯) + 增加互动选单的功能在可开启的门与建筑物的梯子上。(注意: 此功能有可能会降低系统效能,特别是在城镇区更明显) + 增加互動選單的功能在可開啟的門與建築物的梯子上。(注意: 此功能有可能會降低系統效能,特別是在城鎮區更明顯) Interaction Menu @@ -442,8 +442,9 @@ Hace la animación del menú más rápida, reduciendo el tiempo necesario para abrir sub-acciones. Rend les animations de menu plus rapide et réduit le temps nécessaire à l'affichage des sous menus d'action サブ動作が表示されるホバーをした時に、表示されるメニューのアニメーション速度を早くしたり遅くしたりできます - 使选单的动画速度更快, 并减少子选项显现出来的时间 - 使選單的動畫速度更快, 並減少子選項顯現出來的時間 + 使选单的动画速度更快,并减少子选项显现出来的时间 + 使選單的動畫速度更快,並減少子選項顯現出來的時間 + 상호 작용을 표시하기 위해 메뉴 애니메이션을 빠르게 만들고 마우스를 가져 오는 데 필요한 시간을 줄입니다. diff --git a/addons/interaction/ACE_Settings.hpp b/addons/interaction/ACE_Settings.hpp index e95947ec75..3efb745a6b 100644 --- a/addons/interaction/ACE_Settings.hpp +++ b/addons/interaction/ACE_Settings.hpp @@ -1,16 +1,24 @@ class ACE_Settings { class GVAR(enableTeamManagement) { + category = CSTRING(DisplayName); displayName = CSTRING(EnableTeamManagement_DisplayName); description = CSTRING(EnableTeamManagement_Description); value = 1; typeName = "BOOL"; }; class GVAR(enableMagazinePassing) { + category = CSTRING(DisplayName); value = 1; typeName = "BOOL"; isClientSettable = 1; displayName = CSTRING(PassMagazineSetting); - category = ECSTRING(interact_menu,Category_InteractionMenu); + }; + class GVAR(disableNegativeRating) { + category = CSTRING(DisplayName); + displayName = CSTRING(DisableNegativeRating_DisplayName); + description = CSTRING(DisableNegativeRating_Description); + value = 0; + typeName = "BOOL"; }; }; diff --git a/addons/interaction/ACE_ZeusActions.hpp b/addons/interaction/ACE_ZeusActions.hpp index 44b7078f4b..af6b4504e1 100644 --- a/addons/interaction/ACE_ZeusActions.hpp +++ b/addons/interaction/ACE_ZeusActions.hpp @@ -33,7 +33,7 @@ class ACE_ZeusActions { class remoteControl { displayName = "$STR_A3_CfgVehicles_ModuleRemoteControl_F"; icon = "\A3\Modules_F_Curator\Data\portraitRemoteControl_ca.paa"; - statement = "_unit = objNull; { if ((side _x in [east,west,resistance,civilian]) && !(isPlayer _x)) exitWith { _unit = _x; }; } forEach (curatorSelected select 0); bis_fnc_curatorObjectPlaced_mouseOver = ['OBJECT',_unit]; (group _target) createUnit ['ModuleRemoteControl_F',[0,0,0],[],0,''];"; + statement = "_unit = objNull; { if ((side _x in [east,west,resistance,civilian]) && !(isPlayer _x)) exitWith { _unit = _x; }; } forEach (curatorSelected select 0); bis_fnc_curatorObjectPlaced_mouseOver = ['OBJECT',_unit]; (group _target) createUnit ['ModuleRemoteControl_F',[0,0,0],[],0,'NONE'];"; }; }; @@ -52,7 +52,7 @@ class ACE_ZeusActions { class safe { displayName = "$STR_Combat_Safe"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\safe_ca.paa"; - statement = QUOTE([ARR_3(QQGVAR(zeusBehaviour),[ARR_2('CARELESS',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); + statement = QUOTE([ARR_3(QQGVAR(zeusBehaviour),[ARR_2('SAFE',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class aware { displayName = "$STR_Combat_Aware"; diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index cc281247db..9bd70a00da 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -7,8 +7,8 @@ class CfgVehicles { author = ECSTRING(common,ACETeam); category = "ACE"; displayName = CSTRING(Module_DisplayName); - function = "ACE_Interaction_fnc_moduleInteraction"; - scope = 2; + function = QFUNC(moduleInteraction); + scope = 1; isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_Interaction_ca.paa); @@ -19,6 +19,12 @@ class CfgVehicles { typeName = "BOOL"; defaultValue = 1; }; + class DisableNegativeRating { + displayName = CSTRING(DisableNegativeRating_DisplayName); + description = CSTRING(DisableNegativeRating_Description); + typeName = "BOOL"; + defaultValue = 0; + }; }; class ModuleDescription { description = CSTRING(Module_Description); @@ -40,6 +46,7 @@ class CfgVehicles { displayName = CSTRING(PassMagazine); condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 3.3; icon = "\a3\ui_f\data\gui\Rsc\RscDisplayArsenal\cargomag_ca.paa"; @@ -48,6 +55,7 @@ class CfgVehicles { displayName = CSTRING(PassMagazinePrimary); condition = QUOTE([ARR_3(_player,_target,primaryWeapon _target)] call FUNC(canPassMagazine)); statement = QUOTE([ARR_3(_player,_target,primaryWeapon _target)] call FUNC(passMagazine)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 3; icon = "\a3\ui_f\data\gui\Rsc\RscDisplayArsenal\primaryweapon_ca.paa"; @@ -56,6 +64,7 @@ class CfgVehicles { displayName = CSTRING(PassMagazineHandgun); condition = QUOTE([ARR_3(_player,_target,handgunWeapon _target)] call FUNC(canPassMagazine)); statement = QUOTE([ARR_3(_player,_target,handgunWeapon _target)] call FUNC(passMagazine)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 1; icon = "\a3\ui_f\data\gui\Rsc\RscDisplayArsenal\handgun_ca.paa"; @@ -66,6 +75,7 @@ class CfgVehicles { displayName = CSTRING(TeamManagement); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {GVAR(EnableTeamManagement)}); statement = ""; + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 3.2; icon = QPATHTOF(UI\team\team_management_ca.paa); @@ -74,6 +84,7 @@ class CfgVehicles { displayName = CSTRING(AssignTeamRed); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); statement = QUOTE([ARR_2(_target,'RED')] call DFUNC(joinTeam)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; icon = QPATHTOF(UI\team\team_red_ca.paa); priority = 2.4; @@ -82,6 +93,7 @@ class CfgVehicles { displayName = CSTRING(AssignTeamGreen); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); statement = QUOTE([ARR_2(_target,'GREEN')] call DFUNC(joinTeam)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; icon = QPATHTOF(UI\team\team_green_ca.paa); priority = 2.3; @@ -90,6 +102,7 @@ class CfgVehicles { displayName = CSTRING(AssignTeamBlue); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); statement = QUOTE([ARR_2(_target,'BLUE')] call DFUNC(joinTeam)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; icon = QPATHTOF(UI\team\team_blue_ca.paa); priority = 2.2; @@ -98,6 +111,7 @@ class CfgVehicles { displayName = CSTRING(AssignTeamYellow); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam)); statement = QUOTE([ARR_2(_target,'YELLOW')] call DFUNC(joinTeam)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; icon = QPATHTOF(UI\team\team_yellow_ca.paa); priority = 2.1; @@ -106,6 +120,7 @@ class CfgVehicles { displayName = CSTRING(LeaveTeam); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {assignedTeam _target != 'MAIN'}); statement = QUOTE([ARR_2(_target,'MAIN')] call DFUNC(joinTeam)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; icon = QPATHTOF(UI\team\team_white_ca.paa); priority = 2.5; @@ -117,6 +132,7 @@ class CfgVehicles { condition = QUOTE(GVAR(EnableTeamManagement) && {[ARR_2(_player,_target)] call DFUNC(canJoinGroup)}); statement = QUOTE([_player] joinSilent group _target); modifierFunction = QUOTE(call FUNC(modifyJoinGroupAction)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 2.6; icon = QPATHTOF(UI\team\team_management_ca.paa); @@ -132,6 +148,7 @@ class CfgVehicles { displayName = CSTRING(SendAway); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canInteractWithCivilian)); statement = QUOTE([ARR_2(_player,_target)] call DFUNC(sendAway)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 2.0; }; @@ -139,6 +156,7 @@ class CfgVehicles { displayName = CSTRING(Pardon); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canPardon)); statement = QUOTE([ARR_2(_player,_target)] call DFUNC(pardon)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 2.5; }; @@ -146,9 +164,18 @@ class CfgVehicles { displayName = CSTRING(GetOut); condition = QUOTE(!(isNull objectParent _target) && [ARR_2(_player,_target)] call DFUNC(canInteractWithCivilian)); statement = QUOTE([_target] call EFUNC(common,unloadPerson)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = 2.6; }; + + class GVAR(PullOutBody) { + displayName = CSTRING(PullOutBody); + condition = QUOTE(call DFUNC(canPullOutBody)); + statement = QUOTE(call DFUNC(pullOutBody)); + exceptions[] = {"isNotSwimming"}; + icon = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\getout_ca.paa"; + }; }; class ACE_Torso { @@ -157,6 +184,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_Head { displayName = CSTRING(Head); @@ -164,6 +192,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_ArmLeft { displayName = CSTRING(ArmLeft); @@ -171,6 +200,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_ArmRight { displayName = CSTRING(ArmRight); @@ -178,6 +208,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_LegLeft { displayName = CSTRING(LegLeft); @@ -185,6 +216,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_LegRight { displayName = CSTRING(LegRight); @@ -192,6 +224,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_Weapon { displayName = CSTRING(Weapon); @@ -199,6 +232,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_TapShoulderRight { displayName = CSTRING(TapShoulder); @@ -206,6 +240,7 @@ class CfgVehicles { distance = 2.0; condition = QUOTE([ARR_2(_player, _target)] call DFUNC(canTapShoulder)); statement = QUOTE([ARR_3(_player, _target, 0)] call DFUNC(tapShoulder)); + exceptions[] = {"isNotSwimming"}; }; class ACE_TapShoulderLeft { displayName = CSTRING(TapShoulder); @@ -213,6 +248,7 @@ class CfgVehicles { distance = 2.0; condition = QUOTE([ARR_2(_player, _target)] call DFUNC(canTapShoulder)); statement = QUOTE([ARR_3(_player, _target, 1)] call DFUNC(tapShoulder)); + exceptions[] = {"isNotSwimming"}; }; }; @@ -220,7 +256,7 @@ class CfgVehicles { class ACE_TeamManagement { displayName = CSTRING(TeamManagement); condition = QUOTE(GVAR(EnableTeamManagement)); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = ""; showDisabled = 1; priority = 3.2; @@ -229,7 +265,7 @@ class CfgVehicles { class ACE_JoinTeamRed { displayName = CSTRING(JoinTeamRed); condition = QUOTE(true); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_2(_player,'RED')] call DFUNC(joinTeam)); showDisabled = 1; priority = 2.4; @@ -238,7 +274,7 @@ class CfgVehicles { class ACE_JoinTeamGreen { displayName = CSTRING(JoinTeamGreen); condition = QUOTE(true); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_2(_player,'GREEN')] call DFUNC(joinTeam)); showDisabled = 1; priority = 2.3; @@ -247,7 +283,7 @@ class CfgVehicles { class ACE_JoinTeamBlue { displayName = CSTRING(JoinTeamBlue); condition = QUOTE(true); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_2(_player,'BLUE')] call DFUNC(joinTeam)); showDisabled = 1; priority = 2.2; @@ -256,7 +292,7 @@ class CfgVehicles { class ACE_JoinTeamYellow { displayName = CSTRING(JoinTeamYellow); condition = QUOTE(true); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_2(_player,'YELLOW')] call DFUNC(joinTeam)); showDisabled = 1; priority = 2.1; @@ -265,7 +301,7 @@ class CfgVehicles { class ACE_LeaveTeam { displayName = CSTRING(LeaveTeam); condition = QUOTE(assignedTeam _player != 'MAIN'); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE([ARR_2(_player,'MAIN')] call DFUNC(joinTeam)); showDisabled = 1; priority = 2.5; @@ -274,7 +310,7 @@ class CfgVehicles { class ACE_BecomeLeader { displayName = CSTRING(BecomeLeader); condition = QUOTE(_this call DFUNC(canBecomeLeader)); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE(_this call DFUNC(doBecomeLeader)); showDisabled = 1; priority = 1.0; @@ -283,7 +319,7 @@ class CfgVehicles { class ACE_LeaveGroup { displayName = CSTRING(LeaveGroup); condition = QUOTE(count (units group _player) > 1); - exceptions[] = {"isNotInside", "isNotSitting", "isNotOnLadder"}; + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; statement = QUOTE(_oldGroup = units group _player; _newGroup = createGroup side _player; [_player] joinSilent _newGroup; {_player reveal _x} forEach _oldGroup;); showDisabled = 1; priority = 1.2; @@ -294,7 +330,7 @@ class CfgVehicles { class ACE_Equipment { displayName = CSTRING(Equipment); condition = QUOTE(true); - exceptions[] = {"isNotInside", "notOnMap", "isNotSitting"}; + exceptions[] = {"isNotSwimming", "isNotInside", "notOnMap", "isNotSitting"}; statement = ""; showDisabled = 1; priority = 4.5; @@ -314,8 +350,9 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -324,7 +361,7 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; @@ -341,8 +378,9 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -351,7 +389,7 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; @@ -367,8 +405,9 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -377,8 +416,9 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -396,8 +436,9 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -406,7 +447,7 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; @@ -423,8 +464,9 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -433,7 +475,7 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; @@ -465,13 +507,15 @@ class CfgVehicles { distance = 6; condition = QUOTE(_target call FUNC(canPush)); statement = QUOTE(_this call FUNC(push)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = -1; }; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -480,7 +524,7 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; @@ -496,8 +540,9 @@ class CfgVehicles { condition = "true"; class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; + exceptions[] = {"isNotSwimming"}; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; @@ -506,7 +551,7 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; diff --git a/addons/interaction/RscTitles.hpp b/addons/interaction/RscTitles.hpp index 71070b1715..ee4783da30 100644 --- a/addons/interaction/RscTitles.hpp +++ b/addons/interaction/RscTitles.hpp @@ -8,7 +8,6 @@ class ACE_Interaction_Button_Base { action = ""; idc = -1; - access = 0; type = 1; text = ""; font = "RobotoCondensed"; @@ -156,6 +155,9 @@ class RscInteractionText: RscText{ w = 24 * GUI_GRID_W; h = 1.5 * GUI_GRID_H; }; +class RscInteractionText_right: RscText{ + style = 1; // right aligned text +}; class RscTitles { class GVAR(InteractionHelper) { diff --git a/addons/interaction/UI/CenterIcon_ca.paa b/addons/interaction/UI/CenterIcon_ca.paa deleted file mode 100644 index 86deb5df7c..0000000000 Binary files a/addons/interaction/UI/CenterIcon_ca.paa and /dev/null differ diff --git a/addons/interaction/UI/backArrow_ca.paa b/addons/interaction/UI/backArrow_ca.paa deleted file mode 100644 index 627cb64f17..0000000000 Binary files a/addons/interaction/UI/backArrow_ca.paa and /dev/null differ diff --git a/addons/interaction/UI/command_rose_ca.paa b/addons/interaction/UI/command_rose_ca.paa deleted file mode 100644 index 3dd8b58768..0000000000 Binary files a/addons/interaction/UI/command_rose_ca.paa and /dev/null differ diff --git a/addons/interaction/XEH_PREP.hpp b/addons/interaction/XEH_PREP.hpp index 4f0ef58357..1a70de8831 100644 --- a/addons/interaction/XEH_PREP.hpp +++ b/addons/interaction/XEH_PREP.hpp @@ -28,6 +28,8 @@ PREP(canTapShoulder); PREP(tapShoulder); PREP(canPardon); PREP(pardon); +PREP(canPullOutBody); +PREP(pullOutBody); // interaction with doors PREP(getDoor); diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index bbbda80bfa..5d2b49f9b1 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -83,7 +83,7 @@ GVAR(isOpeningDoor) = false; call EFUNC(interaction,openDoor); true }, { - //Probably don't want any condidtions here, so variable never gets locked down + //Probably don't want any conditions here, so variable never gets locked down // Statement GVAR(isOpeningDoor) = false; true @@ -106,5 +106,13 @@ GVAR(isOpeningDoor) = false; {false}, [20, [true, false, false]], false] call CBA_fnc_addKeybind; -["isNotSwimming", {!underwater (_this select 0)}] call EFUNC(common,addCanInteractWithCondition); +["isNotSwimming", {!(_this call EFUNC(common,isSwimming))}] call EFUNC(common,addCanInteractWithCondition); ["isNotOnLadder", {getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> animationState (_this select 0) >> "ACE_isLadder") != 1}] call EFUNC(common,addCanInteractWithCondition); + +["ace_settingsInitialized", { + if (GVAR(disableNegativeRating)) then { + player addEventHandler ["HandleRating", { + (_this select 1) max 0 + }]; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/interaction/functions/fnc_canPullOutBody.sqf b/addons/interaction/functions/fnc_canPullOutBody.sqf new file mode 100644 index 0000000000..f0f8f32db9 --- /dev/null +++ b/addons/interaction/functions/fnc_canPullOutBody.sqf @@ -0,0 +1,47 @@ +/* + * Author: Dystopian + * Checks if unit can pull target body out of vehicle. + * + * Arguments: + * 1: Body + * 2: Unit + * + * Return Value: + * Able to pull out target body + * + * Example: + * [crew cursorObject select 0, player] call ace_interaction_fnc_canPullOutBody + * + * Public: No + */ +#include "script_component.hpp" + +params ["_body", "_unit"]; + +private _vehicle = objectParent _body; + +if ( + !isNull objectParent _unit + || {alive _body} + || {isNull _vehicle} + || {1 < locked _vehicle} + || { + 0 < {alive _x} count crew _vehicle // alive is in vehicle + // group is used here for situations when side player == ENEMY + && {0.6 > side group _unit getFriend side group _vehicle} // player is enemy + } +) exitWith {false}; + +((fullCrew [_vehicle, ""] select {_body == _x select 0}) select 0) params ["", "", "_cargoIndex", "_turretPath"]; + +private _locked = if (!(_turretPath isEqualTo [])) then { + _vehicle lockedTurret _turretPath; +} else { + if (_cargoIndex > -1) then { + _vehicle lockedCargo _cargoIndex; + } else { + lockedDriver _vehicle; + }; +}; + +!_locked diff --git a/addons/interaction/functions/fnc_getDoor.sqf b/addons/interaction/functions/fnc_getDoor.sqf index 05793decc5..8570d2a7c8 100644 --- a/addons/interaction/functions/fnc_getDoor.sqf +++ b/addons/interaction/functions/fnc_getDoor.sqf @@ -19,23 +19,21 @@ params ["_distance"]; -private ["_position0", "_position1", "_intersections", "_house", "_door"]; +private _position0 = positionCameraToWorld [0, 0, 0]; +private _position1 = positionCameraToWorld [0, 0, _distance]; -_position0 = positionCameraToWorld [0, 0, 0]; -_position1 = positionCameraToWorld [0, 0, _distance]; - -_intersections = lineIntersectsSurfaces [AGLToASL _position0, AGLToASL _position1, cameraOn, objNull, true, 1, "GEOM"]; +private _intersections = lineIntersectsSurfaces [AGLToASL _position0, AGLToASL _position1, cameraOn, objNull, true, 1, "GEOM"]; if (_intersections isEqualTo []) exitWith {[objNull, ""]}; -_house = _intersections select 0 select 2; +private _house = _intersections select 0 select 2; // shithouse is bugged if (typeOf _house == "") exitWith {[objNull, ""]}; _intersections = [_house, "GEOM"] intersect [_position0, _position1]; -_door = toLower (_intersections select 0 select 0); +private _door = toLower (_intersections select 0 select 0); if (isNil "_door") exitWith {[_house, ""]}; diff --git a/addons/interaction/functions/fnc_getVehiclePos.sqf b/addons/interaction/functions/fnc_getVehiclePos.sqf index f66b071ecd..ebcb856267 100644 --- a/addons/interaction/functions/fnc_getVehiclePos.sqf +++ b/addons/interaction/functions/fnc_getVehiclePos.sqf @@ -19,7 +19,8 @@ private _bb = boundingBoxReal _target; (_bb select 0) params ["_bbX", "_bbY", "_bbZ"]; -private _relPos = _target worldToModelVisual ASLToAGL EGVAR(interact_menu,cameraPosASL); +private _cameraPosASL = EGVAR(interact_menu,cameraPosASL); +private _relPos = _target worldToModelVisual ASLToAGL _cameraPosASL; #ifdef DEBUG_MODE_FULL _relPos = _target worldToModelVisual ASLToAGL eyePos ACE_player; #endif @@ -29,7 +30,7 @@ private _ndx = (abs _dx) / ((abs (_bbx)) - 1); private _ndy = (abs _dy) / ((abs (_bbY)) - 1); private _ndz = (abs _dz) / ((abs (_bbZ)) - 1); -private "_pos"; +private _pos = []; if (_ndx > _ndy) then { if (_ndx > _ndz) then { // _ndx is greater, will colide with x plane first @@ -47,9 +48,14 @@ if (_ndx > _ndy) then { _pos = _relPos vectorMultiply ((1 / _ndz) min 0.8); }; }; -//Set max height at player's eye level (prevent very high interactin point on choppers) -_pos set [2, (_pos select 2) min _dz]; -TRACE_4("",_bb,_bbX,_relPos, _pos); + +// Set max height at player's eye level (prevent very high interaction point on choppers) +// Only when above water level to prevent underwater actions from following player eye level +if (_cameraPosASL select 2 >= 0) then { + _pos set [2, (_pos select 2) min _dz]; +}; + +TRACE_4("",_bb,_bbX,_relPos,_pos,_cameraPosASL); _pos /////////////////// diff --git a/addons/interaction/functions/fnc_getVehiclePosComplex.sqf b/addons/interaction/functions/fnc_getVehiclePosComplex.sqf index 6907721aba..bfb9fef803 100644 --- a/addons/interaction/functions/fnc_getVehiclePosComplex.sqf +++ b/addons/interaction/functions/fnc_getVehiclePosComplex.sqf @@ -34,7 +34,7 @@ private _ndy = (abs _dy) / ((abs (_bbY)) - 1); private _ndz = (abs _dz) / ((abs (_bbZ)) - 1); -private "_pos"; +private _pos = []; if (_ndx > _ndy) then { if (_ndx > _ndz) then { // _ndx is greater, will colide with x plane first @@ -53,7 +53,11 @@ if (_ndx > _ndy) then { }; }; -//Set max height at player's eye level (prevent very high interactin point on choppers) -_pos set [2, (_pos select 2) min _dz]; +// Set max height at player's eye level (prevent very high interaction point on vehicles) +// Only when above water level to prevent underwater actions from following player eye level +if (_cameraPosASL select 2 >= 0) then { + _pos set [2, (_pos select 2) min _dz]; +}; +TRACE_4("",_bb,_bbX,_relPos,_pos,_cameraPosASL); _pos diff --git a/addons/interaction/functions/fnc_getWeaponPos.sqf b/addons/interaction/functions/fnc_getWeaponPos.sqf index d0db3cee77..8f2d63713a 100644 --- a/addons/interaction/functions/fnc_getWeaponPos.sqf +++ b/addons/interaction/functions/fnc_getWeaponPos.sqf @@ -16,9 +16,7 @@ #include "script_component.hpp" // IGNORE_PRIVATE_WARNING(_target); -private ["_weaponDir", "_refSystem"]; - -_weaponDir = _target weaponDirection currentWeapon _target; -_refSystem = _weaponDir call EFUNC(common,createOrthonormalReference); +private _weaponDir = _target weaponDirection currentWeapon _target; +private _refSystem = _weaponDir call EFUNC(common,createOrthonormalReference); (_target selectionPosition "righthand") vectorAdd ((_refSystem select 2) vectorMultiply 0.1); diff --git a/addons/interaction/functions/fnc_hideMouseHint.sqf b/addons/interaction/functions/fnc_hideMouseHint.sqf index 757fe952e5..bb9fc9440a 100644 --- a/addons/interaction/functions/fnc_hideMouseHint.sqf +++ b/addons/interaction/functions/fnc_hideMouseHint.sqf @@ -19,7 +19,7 @@ if (isNull (uiNamespace getVariable ["ACE_Helper_Display", objNull])) exitWith { (QGVAR(InteractionHelper) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; -// Disable action menu, showHud also disables all scripted UI (such as drawIcon3D) +// Re-enable action menu inGameUISetEventHandler ["PrevAction", "false"]; inGameUISetEventHandler ["NextAction", "false"]; inGameUISetEventHandler ["Action", "false"]; diff --git a/addons/interaction/functions/fnc_joinTeam.sqf b/addons/interaction/functions/fnc_joinTeam.sqf index dfbb2b9070..311c45b1a5 100644 --- a/addons/interaction/functions/fnc_joinTeam.sqf +++ b/addons/interaction/functions/fnc_joinTeam.sqf @@ -22,7 +22,7 @@ params ["_unit", "_team"]; // display message if (_unit == ACE_player) then { - private "_message"; + private _message = ""; if (_team == "MAIN") then { _message = localize LSTRING(LeftTeam); diff --git a/addons/interaction/functions/fnc_moduleInteraction.sqf b/addons/interaction/functions/fnc_moduleInteraction.sqf index ec3ec0a086..e4f5418fda 100644 --- a/addons/interaction/functions/fnc_moduleInteraction.sqf +++ b/addons/interaction/functions/fnc_moduleInteraction.sqf @@ -22,5 +22,6 @@ params ["_logic", "", "_activated"]; if !(_activated) exitWith {}; [_logic, QGVAR(EnableTeamManagement), "EnableTeamManagement"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(disableNegativeRating), "DisableNegativeRating"] call EFUNC(common,readSettingFromModule); INFO("Interaction Module Initialized."); diff --git a/addons/interaction/functions/fnc_openDoor.sqf b/addons/interaction/functions/fnc_openDoor.sqf index 7d94a5c4a1..2457bc1f39 100644 --- a/addons/interaction/functions/fnc_openDoor.sqf +++ b/addons/interaction/functions/fnc_openDoor.sqf @@ -31,7 +31,7 @@ if (_animations isEqualTo []) exitWith {}; private _lockedVariable = format ["bis_disabled_%1", _door]; -//Check if the door can be locked aka have locked variable, otherwhise cant lock it +// Check if the door can be locked aka have locked variable, otherwhise cant lock it if ((_house animationPhase (_animations select 0) <= 0) && {_house getVariable [_lockedVariable, 0] == 1}) exitWith { private _lockedAnimation = format ["%1_locked_source", _door]; TRACE_3("locked",_house,_lockedAnimation,isClass (configfile >> "CfgVehicles" >> (typeOf _house) >> "AnimationSources" >> _lockedAnimation)); @@ -41,6 +41,13 @@ if ((_house animationPhase (_animations select 0) <= 0) && {_house getVariable [ }; }; +// Add handle on carrier +if (typeOf _house == "Land_Carrier_01_island_01_F") then { + private _handle = format ["door_handle_%1_rot_1", (_animations select 0) select [5, 1]]; + TRACE_1("carrier handle",_handle); + _animations pushBack _handle; +}; + playSound "ACE_Sound_Click"; // @todo replace with smth. more fitting GVAR(doorTargetPhase) = _house animationPhase (_animations select 0); diff --git a/addons/interaction/functions/fnc_passMagazine.sqf b/addons/interaction/functions/fnc_passMagazine.sqf index 15a193cd26..231d26b217 100644 --- a/addons/interaction/functions/fnc_passMagazine.sqf +++ b/addons/interaction/functions/fnc_passMagazine.sqf @@ -18,14 +18,13 @@ #include "script_component.hpp" params ["_player", "_target", "_weapon"]; -private ["_compatibleMags", "_filteredMags", "_magToPass", "_magToPassIndex", "_playerName", "_magToPassDisplayName"]; -_compatibleMags = getArray (configfile >> "CfgWeapons" >> _weapon >> "magazines"); -_filteredMags = magazinesAmmoFull _player select {(_x select 0) in _compatibleMags && {!(_x select 2)}}; +private _compatibleMags = getArray (configfile >> "CfgWeapons" >> _weapon >> "magazines"); +private _filteredMags = magazinesAmmoFull _player select {(_x select 0) in _compatibleMags && {!(_x select 2)}}; //select magazine with most ammo -_magToPass = _filteredMags select 0; -_magToPassIndex = 0; +private _magToPass = _filteredMags select 0; +private _magToPassIndex = 0; { _x params ["_className", "_ammoCount"]; if ((_ammoCount > (_magToPass select 1)) && (_target canAdd _className)) then { @@ -49,6 +48,6 @@ _player removeMagazines _magToPassClassName; _target addMagazine [_magToPassClassName, _magToPassAmmoCount]; -_playerName = [_player] call EFUNC(common,getName); -_magToPassDisplayName = getText (configFile >> "CfgMagazines" >> _magToPassClassName >> "displayName"); +private _playerName = [_player] call EFUNC(common,getName); +private _magToPassDisplayName = getText (configFile >> "CfgMagazines" >> _magToPassClassName >> "displayName"); [QEGVAR(common,displayTextStructured), [[LSTRING(PassMagazineHint), _playerName, _magToPassDisplayName], 1.5, _target], [_target]] call CBA_fnc_targetEvent; diff --git a/addons/interaction/functions/fnc_pullOutBody.sqf b/addons/interaction/functions/fnc_pullOutBody.sqf new file mode 100644 index 0000000000..bab54a0805 --- /dev/null +++ b/addons/interaction/functions/fnc_pullOutBody.sqf @@ -0,0 +1,63 @@ +/* + * Author: Dystopian + * Makes unit pull target body out of vehicle. + * + * Arguments: + * 0: Body + * 1: Unit + * + * Return Value: + * None + * + * Example: + * [crew cursorObject select 0, player] call ace_interaction_fnc_pullOutBody + * + * Public: No + */ +#include "script_component.hpp" + +params ["_body", "_unit"]; + +private _vehicle = objectParent _body; // vehicle command doesn't work for dead + +// get target crew properties +private ["_cargoIndex", "_turretPath"]; +private _cargoNumber = -1; +{ + if ("cargo" == _x select 1) then { + INC(_cargoNumber); + }; + if (_body == _x select 0) exitWith { + _cargoIndex = _x select 2; + _turretPath = _x select 3; + }; +} forEach fullCrew [_vehicle, "", true]; +TRACE_3("",_cargoIndex,_cargoNumber,_turretPath); + +private _preserveEngineOn = false; + +// first get in to target seat +if (!(_turretPath isEqualTo [])) then { + _unit action ["GetInTurret", _vehicle, _turretPath]; +} else { + if (_cargoIndex > -1) then { + _unit action ["GetInCargo", _vehicle, _cargoNumber]; + } else { + _unit action ["GetInDriver", _vehicle]; + _preserveEngineOn = isEngineOn _vehicle; + }; +}; + +// then get out +[ + {(_this select 0) in (_this select 1)}, + { + params ["_unit", "_vehicle", "_preserveEngineOn"]; + TRACE_3("",_unit,_vehicle,_preserveEngineOn); + _unit action ["GetOut", _vehicle]; + if (_preserveEngineOn) then { + [{isNull driver _this}, {_this engineOn true}, _vehicle] call CBA_fnc_waitUntilAndExecute; + }; + }, + [_unit, _vehicle, _preserveEngineOn] +] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/interaction/functions/fnc_showMouseHint.sqf b/addons/interaction/functions/fnc_showMouseHint.sqf index 9ea1f26cba..815aa09f41 100644 --- a/addons/interaction/functions/fnc_showMouseHint.sqf +++ b/addons/interaction/functions/fnc_showMouseHint.sqf @@ -1,11 +1,12 @@ /* * Author: Garth de Wet (LH) - * Shows the interaction helper text with the mouse buttons at the bottom middle of the screen + * Shows the interaction helper text with the mouse buttons at the bottom middle of the screen. * * Arguments: * 0: Left Click Text * 1: Right Click Text - * 2: Scroll Text (Optional) + * 2: Scroll Text (default: "") + * 2: Extra Icon/Text pairs (default: []) * * Return Value: * None @@ -20,7 +21,7 @@ #define GUI_GRID_W (0.025) #define GUI_GRID_H (0.04) -params ["_leftClick", "_rightClick", ["_scroll", ""]]; +params ["_leftClick", "_rightClick", ["_scroll", ""], ["_extraIconSets", []]]; (QGVAR(InteractionHelper) call BIS_fnc_rscLayer) cutRsc [QGVAR(InteractionHelper), "PLAIN", 0.5, false]; @@ -28,7 +29,7 @@ disableSerialization; private _display = uiNamespace getVariable ["ACE_Helper_Display", objNull]; -if (isNull _display) exitWith {}; +if (isNull _display) exitWith {WARNING("Display was null");}; (_display displayCtrl 1000) ctrlSetText _leftClick; (_display displayCtrl 1001) ctrlSetText _rightClick; @@ -38,18 +39,42 @@ if (isNull _display) exitWith {}; (_display displayCtrl 1001) ctrlShow (_rightClick != ""); (_display displayCtrl 1201) ctrlShow (_rightClick != ""); -if (_scroll == "") exitWith { +private _offset = 19; + +if (_scroll == "") then { (_display displayCtrl 1002) ctrlShow false; (_display displayCtrl 1202) ctrlShow false; (_display displayCtrl 1001) ctrlSetPosition [21 * GUI_GRID_W, 18 * GUI_GRID_H, 24 * GUI_GRID_W, 1.5 * GUI_GRID_H]; (_display displayCtrl 1201) ctrlSetPosition [20 * GUI_GRID_W, 18.5 * GUI_GRID_H, 1.5 * GUI_GRID_W, 1 * GUI_GRID_H]; (_display displayCtrl 1001) ctrlCommit 0; (_display displayCtrl 1201) ctrlCommit 0; +} else { + _offset = _offset + 1; + (_display displayCtrl 1002) ctrlSetText _scroll; + + // Disable action menu + inGameUISetEventHandler ["PrevAction", "true"]; + inGameUISetEventHandler ["NextAction", "true"]; + inGameUISetEventHandler ["Action", "true"]; }; -(_display displayCtrl 1002) ctrlSetText _scroll; +{ + _x params [["_xKeyName", "", [""]], ["_xText", "", [""]]]; + switch (toLower _xKeyName) do { + case ("alt"): {_xKeyName = format ["<%1>", toUpper localize "str_dik_alt"];}; + case ("control"); + case ("ctrl"): {_xKeyName = format ["<%1>", toUpper localize "str_dik_control"];}; + case ("shift"): {_xKeyName = format ["<%1>", toUpper localize "str_dik_shift"];}; + }; + + private _keyNameCtrl = _display ctrlCreate ["RscInteractionText_right", -1]; + private _textCtrl = _display ctrlCreate ["RscInteractionText", -1]; + _keyNameCtrl ctrlSetText _xKeyName; + _textCtrl ctrlSetText _xText; + _keyNameCtrl ctrlSetPosition [0 * GUI_GRID_W, _offset * GUI_GRID_H, 21.4 * GUI_GRID_W, 1.5 * GUI_GRID_H]; + _textCtrl ctrlSetPosition [21 * GUI_GRID_W, _offset * GUI_GRID_H, 24 * GUI_GRID_W, 1.5 * GUI_GRID_H]; + _keyNameCtrl ctrlCommit 0; + _textCtrl ctrlCommit 0; + _offset = _offset + 1; +} forEach _extraIconSets; -// Enable action menu -inGameUISetEventHandler ["PrevAction", "true"]; -inGameUISetEventHandler ["NextAction", "true"]; -inGameUISetEventHandler ["Action", "true"]; diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 1e9367347e..08081daaca 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -1,6 +1,15 @@ - + + + Interaction + Interaktion + Interazione + 互動 + 互动 + インタラクション + 상호작용 + Interactions Interaktionen @@ -188,7 +197,7 @@ Ajtó bezárása Zablokuj drzwi Zamknout dveře - ドアの鍵を閉める + ドアの鍵をしめる 문 잠그기 锁门 鎖門 @@ -204,7 +213,7 @@ Zár kinyitása Odblokuj drzwi Odemknout dveře - ドアの鍵を開ける + ドアの鍵をあける 잠긴문 열기 解锁门 解鎖門 @@ -220,7 +229,7 @@ Zárt ajtó Zablokowano drzwi Zamčené dveře - ドアの鍵を締めた + ドアの鍵をしめた 잠긴 문 门已上锁 門已上鎖 @@ -236,7 +245,7 @@ Nyitott ajtó Odblokowano drzwi Odemčené dveře - ドアの鍵を開けられた + ドアの鍵をあけた 열린 문 门未上锁 門未上鎖 @@ -252,7 +261,7 @@ Csatlakozás a csoporthoz Unir-se ao grupo Unisciti alla squadra - グループにはいる + グループに入る 그룹 참여 加入小队 加入小隊 @@ -268,7 +277,7 @@ Csoport elhagyása Deixar grupo Lascia la squadra - グループをぬける + グループを抜ける 그룹 나가기 离开小队 離開小隊 @@ -300,7 +309,7 @@ TÁNC! DANCE! DANZA! - おどれ! + おどれ! 춤추기! 跳舞 跳舞 @@ -332,7 +341,7 @@ << Vissza << Voltar << Indietro - &lt;&lt; もどる + <<もどる <<뒤로 <<返回 <<返回 @@ -364,8 +373,8 @@ Vállveregetés Tocar ombro Dai un colpetto - 肩をたたく - 어깨 두드리기 + 肩を叩く + 어깨 치기 轻拍肩膀 輕拍肩膀 @@ -444,7 +453,7 @@ Tűnés! Vá Embora! Via di qui! - うせろ! + 失せろ! 저리 가! 走开! 走開! @@ -460,7 +469,7 @@ Ложись! Abaixe-se! A terra! - ふせろ! + 伏せろ! 엎드려! 趴下! 趴下! @@ -474,7 +483,7 @@ Sortez ! Выходи Vystupte - 降りる + 降りろ 나가 出去 出去 @@ -906,7 +915,7 @@ Csapatkezelés engedélyezése Habilitar gestão de equipes Abilità Management Squadra - チーム管理をつかう + チーム管理を使う 팀 설정 활성화 启用小队管理 啟用小隊管理 @@ -922,11 +931,29 @@ A játékosoknak engedélyezve legyen a csapatkezelő menü? Alapértelmezett: Igen Devem os jogadores ter permissão de usar o menu de gestão de equipes? Padrão: Sim Possono i giocatori usare il Menù Managment Squadra? Default: Si - プレイヤーがチーム管理メニューを使えるようにしますか?標準:はい + プレイヤーがチーム管理メニューを使えるようにしますか? 標準: 有効化 플레이어들이 팀 설정하는 것을 허락합니까? 기본설정: 예 允许玩家使用小队管理选单? 预设: 是 允許玩家使用小隊管理選單? 預設: 是 + + Disable negative rating + Negative Bewertung deaktivieren + 否定評価を無効化 + Disabilita valutazione negativa + 關閉負面評價 + 关闭负面评价 + 부정행위 가중치 사용안함 + + + Should players receive negative rating? When enabled players are only receiving positive ratings which prevents friendly AI fire when destroying friendly equipment or killing team members. + Sollen Spieler negative Bewertungen erhalten dürfen? Wenn diese Option aktiviert ist, erhalten Spieler nur positive Bewertungen, was Freundbeschuss durch KI verhindert, wenn befreundete Ausrüstung zerstört oder befreundete Einheiten von Spielern des selben Teams getötet werden. + 否定評価を受けますか?有効化した場合プレイヤーは肯定評価のみを受け、友軍の装備を壊したり殺害をしてもAIからの攻撃を防ぎます。 + I giocatori dovrebbero ricevere delle valutazioni negative ? Quando è abilitato i giocatori ricevono esclusivamente valutazioni positive che prevengono il fuoco delle AI alleate quando distruggono equipaggiamenti o uccidono membri della squadra. + 玩家是否會收到負面評價? 當本功能開啟時玩家只會接收到正面評價,所以當玩家做出擊殺友軍AI、毀壞友軍裝備或殺害小隊夥伴都不會收到負面評價。 + 玩家是否会收到负面评价? 当本功能开启时玩家只会接收到正面评价,所以当玩家做出击杀友军AI、毁坏友军装备或杀害小队伙伴都不会收到负面评价。 + 플레이어의 부정행위 가중치를 계산합니까? 활성화된 플레이어는 높은 레이팅을 가질때, 아군의 장비나 병력을 사격해도 아군 AI의 사격을 받지 않습니다. + Team management allows color allocation for team members, taking team command and joining/leaving teams. Na zarządzanie drużyną składa się: przydział kolorów dla członków drużyny, przejmowanie dowodzenia, dołączanie/opuszczanie drużyn. @@ -940,8 +967,8 @@ Management Squadra permette l'assegnazione di colori per membri della squadra, prendere il comando ed entrare/uscire dalle squadre. チーム管理はチーム メンバーへ色の割り当てや指揮権を取ったり、チームの出入りを許可します。 팀 설정은 팀 멤버에게 색을 부여하거나 팀에 참여 혹은 나가게 할 수 있게 합니다. - 队伍管理系统允许将指定颜色分配到队伍成员上, 接管队长职位或加入/离开队伍. - 隊伍管理系統允許將指定顏色分配到隊伍成員上, 接管隊長職位或加入/離開隊伍. + 队伍管理系统允许将指定颜色分配到队伍成员上,接管队长职位或加入/离开队伍 + 隊伍管理系統允許將指定顏色分配到隊伍成員上,接管隊長職位或加入/離開隊伍 Turn on @@ -953,7 +980,7 @@ Zapnout Ligar Включить - 中に入る + 有効化 켜기 开启 開啟 @@ -968,7 +995,7 @@ Vypnout Desligar Выключить - 外に出す + 無効化 끄기 关闭 關閉 @@ -1048,5 +1075,12 @@ 显示"给予弹匣"互动动作 顯示"給予彈匣"互動動作 + + Pull out body + Вытащить тело + 身体を引き出す + Estrai il corpo + 시체 끌기 + diff --git a/addons/inventory/stringtable.xml b/addons/inventory/stringtable.xml index 6009a3e479..713c8b082b 100644 --- a/addons/inventory/stringtable.xml +++ b/addons/inventory/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -28,10 +28,10 @@ Alaphelyzetben a kezelőfelület mérete skálázza a felszerelési menüt. Ez az opció engedélyezi a menü felskálázását, de megtartja a betűméreteket, így növelve a láthatóságot. Normalmente il menù inventario è scalato in base alle dimensioni interfaccia. Questa opzione di permette di ingrandirlo ulteriormente ma senza aumentare la dimensione del testo. Normalmente o tamanho da tela do inventário é ditada pelo tamanho da UI. Isso permite aumentar o tamanho da tela de inventário, mas não aumenta o tamanho da fonte, permitindo que mais linhas sejam visualizadas. - 通常のインベントリは UI の大きさによって表示されます。これはインベントリ UI を大きくできますが、文字は大きくできません。 + 通常、インベントリは UI の大きさにより調整して表示されます。これはインベントリ UI を大きくできますが、文字は大きくできません。 보통 소지품 화면은 사용자 인터페이스 크기에 비례합니다. 이 항목은 소지품의 사용자 인터페이스를 확대를 가능케하면서 글씨는 그대로 냅두게 해줍니다. - 一般来说, 物品清单尺寸是由使用者介面来决定的. 此选项能让你的物品显示清单更大但不会增加字体大小, 此举可增加更多能被显示的描述行数! - 一般來說, 物品清單尺寸是由使用者介面來決定的. 此選項能讓你的物品顯示清單更大但不會增加字體大小, 此舉可增加更多能被顯示的描述行數! + 一般来说,物品清单尺寸是由使用者介面来决定的。此选项能让你的物品显示清单更大但不会增加字体大小,此举可增加更多能被显示的描述行数! + 一般來說,物品清單尺寸是由使用者介面來決定的。此選項能讓你的物品顯示清單更大但不會增加字體大小,此舉可增加更多能被顯示的描述行數! Backpacks diff --git a/addons/kestrel4500/CfgWeapons.hpp b/addons/kestrel4500/CfgWeapons.hpp index 8b318994a2..ea9cd2ab2f 100644 --- a/addons/kestrel4500/CfgWeapons.hpp +++ b/addons/kestrel4500/CfgWeapons.hpp @@ -1,7 +1,7 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_Kestrel4500: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -13,7 +13,7 @@ class CfgWeapons { icon = "iconObject_circle"; mapSize = 0.034; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; }; }; diff --git a/addons/kestrel4500/functions/fnc_collectData.sqf b/addons/kestrel4500/functions/fnc_collectData.sqf index 2e25fbcf60..703c07797e 100644 --- a/addons/kestrel4500/functions/fnc_collectData.sqf +++ b/addons/kestrel4500/functions/fnc_collectData.sqf @@ -15,19 +15,18 @@ */ #include "script_component.hpp" -private ["_playerDir", "_playerAltitude", "_temperature", "_humidity", "_barometricPressure", "_altitude", "_airDensity", "_densityAltitude", "_chill", "_heatIndex", "_dewPoint", "_wetBulb", "_windSpeed", "_crosswind", "_headwind"]; -_playerDir = getDir ACE_player; -_playerAltitude = (getPosASL ACE_player) select 2; -_temperature = _playerAltitude call EFUNC(weather,calculateTemperatureAtHeight); -_humidity = EGVAR(weather,currentHumidity); -_barometricPressure = _playerAltitude call EFUNC(weather,calculateBarometricPressure); -_altitude = EGVAR(common,mapAltitude) + _playerAltitude; -_airDensity = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateAirDensity); -_densityAltitude = _airDensity call EFUNC(weather,calculateDensityAltitude); -_chill = [_temperature, _humidity] call EFUNC(weather,calculateWindChill); -_heatIndex = [_temperature, _humidity] call EFUNC(weather,calculateHeatIndex); -_dewPoint = [_temperature, _humidity] call EFUNC(weather,calculateDewPoint); -_wetBulb = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateWetBulb); +private _playerDir = getDir ACE_player; +private _playerAltitude = (getPosASL ACE_player) select 2; +private _temperature = _playerAltitude call EFUNC(weather,calculateTemperatureAtHeight); +private _humidity = EGVAR(weather,currentHumidity); +private _barometricPressure = _playerAltitude call EFUNC(weather,calculateBarometricPressure); +private _altitude = EGVAR(common,mapAltitude) + _playerAltitude; +private _airDensity = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateAirDensity); +private _densityAltitude = _airDensity call EFUNC(weather,calculateDensityAltitude); +private _chill = [_temperature, _humidity] call EFUNC(weather,calculateWindChill); +private _heatIndex = [_temperature, _humidity] call EFUNC(weather,calculateHeatIndex); +private _dewPoint = [_temperature, _humidity] call EFUNC(weather,calculateDewPoint); +private _wetBulb = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateWetBulb); if (isNil QGVAR(MIN) || isNil QGVAR(MAX)) then { GVAR(MIN) = [0, _playerDir, 0, 0, 0, _temperature, _chill, _humidity, _heatIndex, _dewPoint, _wetBulb, _barometricPressure, _altitude, _densityAltitude]; @@ -47,11 +46,11 @@ if (GVAR(MinAvgMaxMode) == 1) then { } count [2, 3, 4]; // Wind SPD - _windSpeed = call FUNC(measureWindSpeed); + private _windSpeed = call FUNC(measureWindSpeed); [2, _windSpeed] call FUNC(updateMemory); // CROSSWIND - _crosswind = 0; + private _crosswind = 0; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { _crosswind = abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed); } else { @@ -60,7 +59,7 @@ if (GVAR(MinAvgMaxMode) == 1) then { [3, _crosswind] call FUNC(updateMemory); // HEADWIND - _headwind = 0; + private _headwind = 0; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { _headwind = cos(GVAR(RefHeading) - _playerDir) * _windSpeed; } else { diff --git a/addons/kestrel4500/functions/fnc_generateOutputData.sqf b/addons/kestrel4500/functions/fnc_generateOutputData.sqf index 039da0e213..240862b4f2 100644 --- a/addons/kestrel4500/functions/fnc_generateOutputData.sqf +++ b/addons/kestrel4500/functions/fnc_generateOutputData.sqf @@ -33,48 +33,46 @@ if (diag_tickTime - GVAR(headingSetDisplayTimer) < 0.8) exitWith {["", "", " Heading Set", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]}; -private ["_playerDir", "_playerAltitude", "_temperature", "_humidity", "_barometricPressure", "_airDensity", "_densityAltitude", "_chill", "_heatIndex", "_dewPoint", "_wetBulb", "_dayString", "_monthString", "_windSpeed", "_windDir", "_textTop", "_textCenterBig", "_textCenter", "_textCenterLine1Left", "_textCenterLine2Left", "_textCenterLine3Left", "_textCenterLine1Right", "_textCenterLine2Right", "_textCenterLine3Right", "_textInfoLine1", "_textInfoLine2", "_textBottomBig", "_textCenterLine1", "_textCenterLine2", "_textCenterLine3", "_textCenterLine4", "_textCenterLine5", "_textCenterLine6"]; - [] call FUNC(collectData); -_textTop = GVAR(Menus) select GVAR(Menu); -_textCenterBig = ""; -_textCenter = ""; +private _textTop = GVAR(Menus) select GVAR(Menu); +private _textCenterBig = ""; +private _textCenter = ""; -_textCenterLine1Left = ""; -_textCenterLine2Left = ""; -_textCenterLine3Left = ""; -_textCenterLine1Right = ""; -_textCenterLine2Right = ""; -_textCenterLine3Right = ""; +private _textCenterLine1Left = ""; +private _textCenterLine2Left = ""; +private _textCenterLine3Left = ""; +private _textCenterLine1Right = ""; +private _textCenterLine2Right = ""; +private _textCenterLine3Right = ""; -_textInfoLine1 = ""; -_textInfoLine2 = ""; +private _textInfoLine1 = ""; +private _textInfoLine2 = ""; -_textBottomBig = ""; +private _textBottomBig = ""; -_textCenterLine1 = ""; -_textCenterLine2 = ""; -_textCenterLine3 = ""; -_textCenterLine4 = ""; -_textCenterLine5 = ""; -_textCenterLine6 = ""; +private _textCenterLine1 = ""; +private _textCenterLine2 = ""; +private _textCenterLine3 = ""; +private _textCenterLine4 = ""; +private _textCenterLine5 = ""; +private _textCenterLine6 = ""; -_windSpeed = call FUNC(measureWindSpeed); -_windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); +private _windSpeed = call FUNC(measureWindSpeed); +private _windDir = (wind select 0) atan2 (wind select 1); -_playerDir = getDir ACE_player; -_playerAltitude = (getPosASL ACE_player) select 2; +private _playerDir = getDir ACE_player; +private _playerAltitude = (getPosASL ACE_player) select 2; -_temperature = _playerAltitude call EFUNC(weather,calculateTemperatureAtHeight); -_humidity = EGVAR(weather,currentHumidity); -_barometricPressure = _playerAltitude call EFUNC(weather,calculateBarometricPressure); -_airDensity = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateAirDensity); -_densityAltitude = _airDensity call EFUNC(weather,calculateDensityAltitude); -_chill = [_temperature, _humidity] call EFUNC(weather,calculateWindChill); -_heatIndex = [_temperature, _humidity] call EFUNC(weather,calculateHeatIndex); -_dewPoint = [_temperature, _humidity] call EFUNC(weather,calculateDewPoint); -_wetBulb = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateWetBulb); +private _temperature = _playerAltitude call EFUNC(weather,calculateTemperatureAtHeight); +private _humidity = EGVAR(weather,currentHumidity); +private _barometricPressure = _playerAltitude call EFUNC(weather,calculateBarometricPressure); +private _airDensity = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateAirDensity); +private _densityAltitude = _airDensity call EFUNC(weather,calculateDensityAltitude); +private _chill = [_temperature, _humidity] call EFUNC(weather,calculateWindChill); +private _heatIndex = [_temperature, _humidity] call EFUNC(weather,calculateHeatIndex); +private _dewPoint = [_temperature, _humidity] call EFUNC(weather,calculateDewPoint); +private _wetBulb = [_temperature, _barometricPressure, _humidity] call EFUNC(weather,calculateWetBulb); GVAR(Direction) = 4 * floor(_playerDir / 90); if (_playerDir % 90 > 10) then { GVAR(Direction) = GVAR(Direction) + 1}; @@ -87,8 +85,8 @@ if (GVAR(referenceHeadingMenu) == 0) then { switch (GVAR(Menu)) do { case 0: { // Date date params ["_year", "_month", "_day"]; - _dayString = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] select (date call FUNC(dayOfWeek)); - _monthString = localize (["str_january","str_february","str_march","str_april","str_may","str_june","str_july","str_august","str_september","str_october","str_november","str_december"] select (_month - 1)); + private _dayString = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] select (date call FUNC(dayOfWeek)); + private _monthString = localize (["str_january","str_february","str_march","str_april","str_may","str_june","str_july","str_august","str_september","str_october","str_november","str_december"] select (_month - 1)); _textTop = _dayString; _textCenter = format["%1 %2 %3", _day, _monthString, _year]; _textBottomBig = [daytime, "HH:MM:SS"] call bis_fnc_timeToString; @@ -136,8 +134,8 @@ if (GVAR(referenceHeadingMenu) == 0) then { _textCenterBig = Str(round(abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed) * 10) / 10); _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(_playerDir)]; } else { - _textCenterBig = Str(round(abs(sin(GVAR(RefHeading)) * _windSpeed) * 10) / 10); - _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(_windDir)]; + _textCenterBig = Str(round(abs(sin(GVAR(RefHeading) - _windDir) * _windSpeed) * 10) / 10); + _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(180 + _windDir)]; }; _textInfoLine2 = "- set heading"; } else { @@ -168,8 +166,8 @@ if (GVAR(referenceHeadingMenu) == 0) then { _textCenterBig = Str(round(cos(GVAR(RefHeading) - _playerDir) * _windSpeed * 10) / 10); _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(_playerDir)]; } else { - _textCenterBig = Str(round(cos(GVAR(RefHeading)) * _windSpeed * 10) / 10); - _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(_windDir)]; + _textCenterBig = Str(round(-cos(GVAR(RefHeading) - _windDir) * _windSpeed * 10) / 10); + _textInfoLine1 = format["%1 m/s @ %2", round(_windSpeed * 10) / 10, round(180 + _windDir)]; }; _textInfoLine2 = "- set heading"; } else { diff --git a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf index 2a8a4bbbb3..c023d8ec8d 100644 --- a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf +++ b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf @@ -15,11 +15,9 @@ */ #include "script_component.hpp" -private ["_playerDir", "_windSpeed", "_windDir"]; - -_playerDir = getDir ACE_player; -_windSpeed = vectorMagnitude ACE_wind; -_windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); +private _playerDir = getDir ACE_player; +private _windSpeed = vectorMagnitude wind; +private _windDir = (wind select 0) atan2 (wind select 1); if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { // With wind gradient _windSpeed = [eyePos ACE_player, true, true, true] call EFUNC(weather,calculateWindSpeed); diff --git a/addons/kestrel4500/initKeybinds.sqf b/addons/kestrel4500/initKeybinds.sqf index 8c99271970..8be7464615 100644 --- a/addons/kestrel4500/initKeybinds.sqf +++ b/addons/kestrel4500/initKeybinds.sqf @@ -27,11 +27,10 @@ //Add deviceKey entry: -private ["_conditonCode", "_toggleCode", "_closeCode"]; -_conditonCode = { +private _conditonCode = { [] call FUNC(canShow); }; -_toggleCode = { +private _toggleCode = { // Conditions: canInteract if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {}; @@ -44,7 +43,7 @@ _toggleCode = { [] call FUNC(createKestrelDialog); }; }; -_closeCode = { +private _closeCode = { // Statement if (GVAR(Overlay)) then { //If dispaly is open, close it: diff --git a/addons/kestrel4500/stringtable.xml b/addons/kestrel4500/stringtable.xml index bb65f22191..f83c875d57 100644 --- a/addons/kestrel4500/stringtable.xml +++ b/addons/kestrel4500/stringtable.xml @@ -12,7 +12,7 @@ Kestrel 4500NV Kestrel 4500NV Kestrel 4500NV - Kestrel 4500NV + ケストレル 4500NV Kestrel 4500NV 猎隼4500测风仪 獵隼4500測風儀 @@ -28,7 +28,7 @@ Kestrel 4500 Medidor Balístico Ativo Kestrel 4500 kézi szél-és időjárásmérő Příruční meteostanice Kestrel 4500 - Kestrel 4500 携帯型風速計 + ケストレル 4500 携帯型風速計 Kestrel 4500 휴대형 기상 관측기 猎隼4500掌上型天气追踪仪 獵隼4500掌上型天氣追蹤儀 @@ -60,7 +60,7 @@ Kestrel 4500 mutatása Zobrazit Kestrel 4500 Mostrar Kestrel 4500 - Kestrel 4500 を見る + ケストレル 4500 を見る Kestrel 4500 보이기 显示猎隼4500测风仪 顯示獵隼4500測風儀 @@ -92,7 +92,7 @@ Kestrel 4500 elővétele Otevřít Kestrel 4500 Abrir Kestrel 4500 - Kestrel 4500 を開く + ケストレル 4500 を開く Kestrel 4500 열기 开启猎隼4500测风仪 開啟獵隼4500測風儀 @@ -108,7 +108,7 @@ Kestrel 4500 mutatása Zobrazit Kestrel 4500 Mostrar Kestrel 4500 - Kestrel 4500 を見る + ケストレル 4500 を見る Kestrel 4500 숨기기 显示猎隼4500测风仪 顯示獵隼4500測風儀 diff --git a/addons/laser/ACE_Settings.hpp b/addons/laser/ACE_Settings.hpp index 72c513f928..3584a2086f 100644 --- a/addons/laser/ACE_Settings.hpp +++ b/addons/laser/ACE_Settings.hpp @@ -3,5 +3,6 @@ class ACE_Settings { value = 2; typeName = "SCALAR"; displayName = CSTRING(dispersionCount_displayName); + sliderSettings[] = {0, 5, 2, -1}; }; }; diff --git a/addons/laser/CfgVehicles.hpp b/addons/laser/CfgVehicles.hpp index 4f226a1468..4b36a8261d 100644 --- a/addons/laser/CfgVehicles.hpp +++ b/addons/laser/CfgVehicles.hpp @@ -10,23 +10,4 @@ class CfgVehicles { }; }; }; - - // laserTarget fails if the turret does not have "primaryGunner" config - // This only effects the indfor strider who's commander is not the primaryGunner - class LandVehicle; - class Car: LandVehicle { - class NewTurret; - }; - class Car_F: Car { - class Turrets { - class MainTurret: NewTurret {}; - }; - }; - class MRAP_03_base_F: Car_F { - class Turrets: Turrets { - class CommanderTurret: MainTurret { - primaryGunner = 1; - }; - }; - }; }; diff --git a/addons/laser/RscInGameUI.hpp b/addons/laser/RscInGameUI.hpp index ca57f56f6f..16d3dfcd91 100644 --- a/addons/laser/RscInGameUI.hpp +++ b/addons/laser/RscInGameUI.hpp @@ -1,9 +1,3 @@ -class RscControlsGroup; -class VScrollbar; -class HScrollbar; -class RscText; -class RscMapControl; - class RscInGameUI { class RscOptics_LaserDesignator { idd = 300; diff --git a/addons/hellfire/RscTitles.hpp b/addons/laser/RscTitles.hpp similarity index 97% rename from addons/hellfire/RscTitles.hpp rename to addons/laser/RscTitles.hpp index 2bbedae1b6..7421246181 100644 --- a/addons/hellfire/RscTitles.hpp +++ b/addons/laser/RscTitles.hpp @@ -1,7 +1,3 @@ -class RscControlsGroupNoScrollbars; -class RscPictureKeepAspect; -class RscText; - class RscTitles { class GVAR(modeDisplay) { idd = -1; diff --git a/addons/laser/XEH_PREP.hpp b/addons/laser/XEH_PREP.hpp index a95eae7842..6af5643e23 100644 --- a/addons/laser/XEH_PREP.hpp +++ b/addons/laser/XEH_PREP.hpp @@ -13,3 +13,4 @@ PREP(rotateVectLineGetMap); PREP(seekerFindLaserSpot); PREP(shootCone); PREP(shootRay); +PREP(showVehicleHud); diff --git a/addons/laser/XEH_postInit.sqf b/addons/laser/XEH_postInit.sqf index b439fd1f06..709682853b 100644 --- a/addons/laser/XEH_postInit.sqf +++ b/addons/laser/XEH_postInit.sqf @@ -1,7 +1,27 @@ #include "script_component.hpp" +if (hasInterface) then { #include "initKeybinds.sqf" + GVAR(pfID) = -1; + + ["ace_settingsInitialized", { + ["turret", LINKFUNC(showVehicleHud), false] call CBA_fnc_addPlayerEventHandler; + ["vehicle", LINKFUNC(showVehicleHud), true] call CBA_fnc_addPlayerEventHandler; // only one of these needs the retro flag + + // Add UAV Control Compatibility + ["ACE_controlledUAV", { + params ["_UAV", "_seatAI", "_turret", "_position"]; + TRACE_4("ACE_controlledUAV EH",_UAV,_seatAI,_turret,_position); + if (!isNull _seatAI) then { + [_seatAI] call FUNC(showVehicleHud); + } else { + [ace_player] call FUNC(showVehicleHud); + }; + }] call CBA_fnc_addEventHandler; + }] call CBA_fnc_addEventHandler; +}; + // Global Laser EHs ["ace_laserOn", { params ["_uuid", "_args"]; diff --git a/addons/laser/config.cpp b/addons/laser/config.cpp index 75f70449ea..fb6ae5e638 100644 --- a/addons/laser/config.cpp +++ b/addons/laser/config.cpp @@ -13,8 +13,19 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" +#include "ACE_Settings.hpp" #include "CfgEventhandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" + + +class RscControlsGroup; +class VScrollbar; +class HScrollbar; +class RscText; +class RscMapControl; +class RscControlsGroupNoScrollbars; +class RscPictureKeepAspect; + #include "RscInGameUI.hpp" +#include "RscTitles.hpp" diff --git a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf index 482a733b41..c4ac9d3967 100644 --- a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf +++ b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf @@ -13,6 +13,7 @@ * * Public: No */ +// #define DEBUG_MODE_FULL #include "script_component.hpp" TRACE_1("params",_this); @@ -34,5 +35,31 @@ TRACE_1("params",_this); [_targetObject, _owners select 0] call FUNC(addLaserTarget); }; - TRACE_1("Laser target doesn't have owner", _targetObject); + // Vehicle based laser designators won't be linked via laserTarget if the turret has "primaryGunner = 0" + // This backup method just checks the player's vic - which should be reasonably safe as we know the laserTarget is local + private _foundSource = false; + private _vehicle = vehicle ACE_player; + TRACE_2("",_vehicle,typeOf _vehicle); + if ((alive ACE_player) && {_vehicle != ACE_player}) then { + private _turretPath = if (ACE_player == (driver _vehicle)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + TRACE_1("",_turretPath); + if (!(_turretPath isEqualTo [])) then { + private _currentWeapon = _vehicle currentWeaponTurret _turretPath; + TRACE_1("",_currentWeapon); + if ((getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> "laser")) == 1) then { + #ifdef DEBUG_MODE_FULL + private _turretConfig = [_vehicle, _turretPath] call CBA_fnc_getTurret; + private _primaryGunner = getNumber (_turretConfig >> "primaryGunner"); + TRACE_1("",_primaryGunner); + #endif + TRACE_2("Laser target owner [backup method]",_targetObject,_vehicle); + [_targetObject, _vehicle] call FUNC(addLaserTarget); + _foundSource = true; + }; + }; + }; + if (!_foundSource) then { + WARNING_1("Laser target doesn't have owner", _targetObject); + }; + }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/laser/functions/fnc_keyLaserCodeChange.sqf b/addons/laser/functions/fnc_keyLaserCodeChange.sqf index c5140709e0..14c6ab70b6 100644 --- a/addons/laser/functions/fnc_keyLaserCodeChange.sqf +++ b/addons/laser/functions/fnc_keyLaserCodeChange.sqf @@ -24,12 +24,18 @@ if ((!alive ACE_player) || {!([ACE_player, vehicle ACE_player, []] call EFUNC(co private _currentShooter = objNull; private _currentWeapon = ""; -if (ACE_player call CBA_fnc_canUseWeapon) then { - _currentShooter = ACE_player; - _currentWeapon = currentWeapon ACE_player; +if (isNull (ACE_controlledUAV param [0, objNull])) then { + if (ACE_player call CBA_fnc_canUseWeapon) then { + _currentShooter = ACE_player; + _currentWeapon = currentWeapon ACE_player; + } else { + _currentShooter = vehicle ACE_player; + private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentWeapon = _currentShooter currentWeaponTurret _turretPath; + }; } else { - _currentShooter = vehicle ACE_player; - private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentShooter = ACE_controlledUAV select 0; + private _turretPath = ACE_controlledUAV select 2; _currentWeapon = _currentShooter currentWeaponTurret _turretPath; }; diff --git a/addons/laser/functions/fnc_laserOn.sqf b/addons/laser/functions/fnc_laserOn.sqf index cd300af083..baa7e9c1c3 100644 --- a/addons/laser/functions/fnc_laserOn.sqf +++ b/addons/laser/functions/fnc_laserOn.sqf @@ -8,15 +8,15 @@ * 2: Method, can be code, which emitter and owner are passed to, a string function name, an array with a position memory point and weapon name, or an array with a position memory point, a vector begining memory point, and vector ending memory point. * 3: Wavelength (1550nm is common eye safe) * 4: Laser code - * 5: Beam divergence (in mils off beam center). - * 6: Method Args + * 5: Beam divergence (in mils off beam center) + * 6: Method Args (default: nil) * * Return Value: - * UUID for sending to laserOff function. + * UUID for sending to laserOff function * * Example: - * [hmg, hmg, [[0,0,1], "HMG_static"], 1550, 1111, 1] call ace_laser_fnc_laserOn; - * [player, player, "ace_laser_fnc_findLaserSource", 1550, 1111, 1, ["pilot"]] call ace_laser_fnc_laserOn; + * [hmg, hmg, [[0,0,1], "HMG_static"], 1550, 1111, 1] call ace_laser_fnc_laserOn + * [player, player, "ace_laser_fnc_findLaserSource", 1550, 1111, 1, ["pilot"]] call ace_laser_fnc_laserOn * * Public: No */ diff --git a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf index 460add1c74..200e00acae 100644 --- a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf +++ b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf @@ -8,15 +8,15 @@ * 1: Direction vector (will be normalized) * 2: Seeker FOV in degrees * 3: Seeker max distance in meters - * 4: Seeker wavelength sensitivity range, [1550,1550] is common eye safe. + * 4: Seeker wavelength sensitivity range, [1550,1550] is common eye safe * 5: Seeker laser code. - * 6: Ignore 1 (e.g. Player's vehicle) + * 6: Ignore 1 (e.g. Player's vehicle) (default: objNull) * * Return Value: - * [Strongest compatible laser spot ASL pos, owner object] Nil array values if nothing found. + * [Strongest compatible laser spot ASL pos, owner object] Nil array values if nothing found * * Example: - * [getPosASL player, [0,1,0], 90, [1500, 1500], 1111, player] call ace_laser_fnc_seekerFindLaserSpot; + * [getPosASL player, [0,1,0], 90, [1500, 1500], 1111, player] call ace_laser_fnc_seekerFindLaserSpot * * Public: No */ @@ -25,15 +25,15 @@ BEGIN_COUNTER(seekerFindLaserSpot); -params ["_posASL", "_dir", "_seekerFov", "_seekerMaxDistnace", "_seekerWavelengths", "_seekerCode", ["_ignoreObj1", objNull]]; +params ["_posASL", "_dir", "_seekerFov", "_seekerMaxDistance", "_seekerWavelengths", "_seekerCode", ["_ignoreObj1", objNull]]; _dir = vectorNormalized _dir; _seekerWavelengths params ["_seekerWavelengthMin", "_seekerWavelengthMax"]; private _seekerCos = cos _seekerFov; -private _seekerMaxDistSq = _seekerMaxDistnace ^ 2; +private _seekerMaxDistSq = _seekerMaxDistance ^ 2; -TRACE_6("",_posASL,_dir,_seekerFov,_seekerMaxDistnace,_seekerWavelengths,_seekerCode); +TRACE_6("",_posASL,_dir,_seekerFov,_seekerMaxDistance,_seekerWavelengths,_seekerCode); private _spots = []; private _finalPos = nil; diff --git a/addons/laser/functions/fnc_shootCone.sqf b/addons/laser/functions/fnc_shootCone.sqf index ceb45ba24b..9cde6f2139 100644 --- a/addons/laser/functions/fnc_shootCone.sqf +++ b/addons/laser/functions/fnc_shootCone.sqf @@ -1,19 +1,19 @@ /* * Author: Nou - * Shoots multiple rays in a dispersion pattern + * Shoots multiple rays in a dispersion pattern. * * Arguments: * 0: Origin position ASL * 1: Direction (normalized) - * 2: Divergence (mils) - * 3: Count at each divergence level - * 4: Ignore vehicle 1 (e.g. Player's vehicle) + * 2: Divergence (mils) (default: 0.3) + * 3: Count at each divergence level (default: 3) + * 4: Ignore vehicle 1 (e.g. Player's vehicle) (default: objNull) * * Return Value: * [_longestReturn, _shortestReturn, _resultPositions] * * Example: - * [getPosASL player, [0,1,0]] call ace_laser_fnc_shootCone; + * [getPosASL player, [0,1,0]] call ace_laser_fnc_shootCone * * Public: No */ diff --git a/addons/laser/functions/fnc_shootRay.sqf b/addons/laser/functions/fnc_shootRay.sqf index ceae27fe77..12a3cf64bf 100644 --- a/addons/laser/functions/fnc_shootRay.sqf +++ b/addons/laser/functions/fnc_shootRay.sqf @@ -1,18 +1,18 @@ /* * Author: Nou, PabstMirror - * Shoots a ray from a source to a direction and finds first intersction and distance + * Shoots a ray from a source to a direction and finds first intersction and distance. * * Arguments: * 0: Origin position ASL * 1: Direction (normalized) - * 2: Ignore 1 (e.g. Player's vehicle) - * 2: Ignore 2 (e.g. Player's vehicle) + * 2: Ignore 1 (e.g. Player's vehicle) (default: objNull) + * 2: Ignore 2 (e.g. Player's vehicle) (default: objNull) * * Return Value: * [posASL, distance] - pos will be nil if no intersection * * Example: - * [getPosASL player, [0,1,0], player] call ace_laser_fnc_shootRay; + * [getPosASL player, [0,1,0], player] call ace_laser_fnc_shootRay * * Public: No */ @@ -28,6 +28,13 @@ private _resultPos = nil; private _farPoint = _posASL vectorAdd (_dir vectorMultiply 10000); private _intersects = lineIntersectsSurfaces [_posASL, _farPoint, _ignoreVehicle1, _ignoreVehicle2]; +// workaround for lineIntersectsSurfaces using a hardcoded max distance of 5000m. New max distance 15000m +if (_intersects isEqualTo []) then { + _intersects = lineIntersectsSurfaces [_posASL vectorAdd (_dir vectorMultiply 5000), _farPoint vectorAdd (_dir vectorMultiply 5000), _ignoreVehicle1, _ignoreVehicle2]; + if (_intersects isEqualTo []) then { + _intersects = lineIntersectsSurfaces [_posASL vectorAdd (_dir vectorMultiply 10000), _farPoint vectorAdd (_dir vectorMultiply 10000), _ignoreVehicle1, _ignoreVehicle2]; + }; +}; if (!(_intersects isEqualTo [])) then { (_intersects select 0) params ["_intersectPosASL", "", "_intersectObject"]; diff --git a/addons/hellfire/functions/fnc_showHud.sqf b/addons/laser/functions/fnc_showVehicleHud.sqf similarity index 73% rename from addons/hellfire/functions/fnc_showHud.sqf rename to addons/laser/functions/fnc_showVehicleHud.sqf index c79780c3fe..b4a5bcb519 100644 --- a/addons/hellfire/functions/fnc_showHud.sqf +++ b/addons/laser/functions/fnc_showVehicleHud.sqf @@ -1,6 +1,6 @@ /* * Author: PabstMirror - * Shows the hellfire hud when vehicle is equiped with the weapon. + * Shows the laser hud when vehicle is equiped with the weapon. * Shows laser code, fire mode and seeker status. * * Arguments: @@ -10,7 +10,7 @@ * Nothing * * Example: - * [player] call ace_hellfire_fnc_showHud + * [player] call ace_laser_fnc_showVehicleHud * * Public: No */ @@ -28,8 +28,8 @@ if ((alive _player) && {_player != _vehicle}) then { _turretPath = _player call CBA_fnc_turretPath }; { - if ((getNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(enabled))) == 1) then { - TRACE_1("enabled",_x); + if ((getNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(showHud))) == 1) then { + TRACE_1("showHud",_x); _enabled = true; }; } forEach (_vehicle weaponsTurret _turretPath); @@ -46,9 +46,7 @@ GVAR(pfID) = -1; if (!_enabled) exitWith {TRACE_2("Disabled - Now Off",_enabled,GVAR(pfID));}; -TRACE_2("Enabled - Adding actions and PFEH",_enabled,GVAR(pfID)); - -[_vehicle, _turretPath] call FUNC(setupVehicle); +TRACE_2("Enabled - Adding PFEH",_enabled,GVAR(pfID)); private _adjustDown = false; // Flares display will block ours, if present just move ours down a bit { @@ -77,7 +75,7 @@ GVAR(pfID) = [{ }; private _currentWeapon = _vehicle currentWeaponTurret _turretPath; - private _showLockMode = (getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> QGVAR(enabled))) == 1; + private _showLockMode = (getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> QGVAR(showHud))) == 1; private _ctrlGroup = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl 1000; @@ -91,30 +89,22 @@ GVAR(pfID) = [{ private _ctrlIcon = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_LASERICON; // Do Laser Scan: + private _ammo = getText (configFile >> "CfgMagazines" >> _vehicle currentMagazineTurret _turretPath >> "ammo"); private _laserSource = AGLtoASL (_vehicle modelToWorld (_vehicle selectionPosition _seekerSource)); private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; - private _laserResult = [_laserSource, vectorDir _vehicle, 70, 5000, [ACE_DEFAULT_LASER_WAVELENGTH,ACE_DEFAULT_LASER_WAVELENGTH], _laserCode, _vehicle] call EFUNC(laser,seekerFindLaserSpot); + private _seekerAngle = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerAngle"); + private _seekerMaxRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerMaxRange"); + private _laserResult = [_laserSource, vectorDir _vehicle, _seekerAngle, _seekerMaxRange, [ACE_DEFAULT_LASER_WAVELENGTH,ACE_DEFAULT_LASER_WAVELENGTH], _laserCode, _vehicle] call EFUNC(laser,seekerFindLaserSpot); private _foundTargetPos = _laserResult select 0; private _haveLock = !isNil "_foundTargetPos"; - private _modeShort = "ERR"; - private _vehicleLockMode = _vehicle getVariable [QEGVAR(missileguidance,attackProfile), ""]; + private _defaultAttackProfile = getText (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "defaultAttackProfile"); + private _vehicleLockMode = _vehicle getVariable [QEGVAR(missileguidance,attackProfile), _defaultAttackProfile]; - switch (_vehicleLockMode) do { // note: missileguidance is case sensitive - case ("hellfire_hi"): { - _modeShort = getText (configFile >> QEGVAR(missileguidance,AttackProfiles) >> _vehicleLockMode >> "name"); - }; - case ("hellfire_lo"): { - _modeShort = getText (configFile >> QEGVAR(missileguidance,AttackProfiles) >> _vehicleLockMode >> "name"); - }; - default { - _vehicleLockMode = "hellfire"; - _modeShort = if (_haveLock) then { - getText (configFile >> QEGVAR(missileguidance,AttackProfiles) >> _vehicleLockMode >> "nameLocked"); - } else { - getText (configFile >> QEGVAR(missileguidance,AttackProfiles) >> _vehicleLockMode >> "name"); - }; - }; + _modeShort = if (_haveLock) then { + getText (configFile >> QEGVAR(missileguidance,AttackProfiles) >> _vehicleLockMode >> "nameLocked"); + } else { + getText (configFile >> QEGVAR(missileguidance,AttackProfiles) >> _vehicleLockMode >> "name"); }; _ctrlIcon ctrlSetTextColor ([[0,0,0,0.25],[1,0,0,0.75]] select _haveLock); diff --git a/addons/laser/script_component.hpp b/addons/laser/script_component.hpp index af562536b6..b0d9951bf3 100644 --- a/addons/laser/script_component.hpp +++ b/addons/laser/script_component.hpp @@ -23,3 +23,8 @@ #define __LaserDesignatorIGUI_ACE_Distance (__LaserDesignatorIGUI displayCtrl 123002) #define __LaserDesignatorIGUI_CA_Distance (__LaserDesignatorIGUI displayCtrl 151) #define __LaserDesignatorIGUI_LaserOn (__LaserDesignatorIGUI displayCtrl 158) + +#define IDC_MODECONTROLGROUP 1000 +#define IDC_ATTACKMODE 1001 +#define IDC_LASERCODE 1002 +#define IDC_LASERICON 1003 diff --git a/addons/laserpointer/ACE_Settings.hpp b/addons/laserpointer/ACE_Settings.hpp index 0536db730d..833167ba28 100644 --- a/addons/laserpointer/ACE_Settings.hpp +++ b/addons/laserpointer/ACE_Settings.hpp @@ -1,5 +1,7 @@ class ACE_Settings { class GVAR(enabled) { + category = ECSTRING(common,ACEKeybindCategoryWeapons); + displayName = CSTRING(DisplayName); typeName = "BOOL"; value = 1; }; diff --git a/addons/laserpointer/functions/fnc_onDraw.sqf b/addons/laserpointer/functions/fnc_onDraw.sqf index 06c601869c..4c614064e7 100644 --- a/addons/laserpointer/functions/fnc_onDraw.sqf +++ b/addons/laserpointer/functions/fnc_onDraw.sqf @@ -15,8 +15,7 @@ */ #include "script_component.hpp" -// no lasers in thermal mode -if !(GVAR(isTI)) then { +if (count GVAR(redLaserUnits) + count GVAR(greenLaserUnits) > 0 && {!GVAR(isTI)}) then { private _brightness = 2 - call EFUNC(common,ambientBrightness); { diff --git a/addons/laserpointer/stringtable.xml b/addons/laserpointer/stringtable.xml index 88228dc289..17b7dbe933 100644 --- a/addons/laserpointer/stringtable.xml +++ b/addons/laserpointer/stringtable.xml @@ -1,6 +1,22 @@ + + Laser Pointer + Pointeur laser + Laserpointer + Лазерный прицел + Laserové ukazovátko + Wskaźnik laserowy + Lézer-pointer + Puntero láser + Puntatore laser + Laser + レーザ ポインタ + 레이저 지시기 + 雷射指示器 + 雷射指示器 + Laser Pointer (red) Pointeur laser (rouge) diff --git a/addons/logistics_uavbattery/CfgVehicles.hpp b/addons/logistics_uavbattery/CfgVehicles.hpp index 2daa8c8011..f36736fac9 100644 --- a/addons/logistics_uavbattery/CfgVehicles.hpp +++ b/addons/logistics_uavbattery/CfgVehicles.hpp @@ -15,11 +15,20 @@ class CfgVehicles { class ACE_MainActions: ACE_MainActions { class GVAR(RefuelUAV) { displayName = CSTRING(Recharge); - distance = 4; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRefuelUAV)); statement = QUOTE([ARR_2(_player, _target)] call FUNC(refuelUAV)); - showDisabled = 0; - priority = 1.245; + icon = QPATHTOF(ui\UAV_battery_ca.paa); + }; + }; + }; + }; + class UAV_06_base_F: Helicopter_Base_F { + class ACE_Actions: ACE_Actions{ + class ACE_MainActions: ACE_MainActions { + class GVAR(RefuelUAV) { + displayName = CSTRING(Recharge); + condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRefuelUAV)); + statement = QUOTE([ARR_2(_player, _target)] call FUNC(refuelUAV)); icon = QPATHTOF(ui\UAV_battery_ca.paa); }; }; diff --git a/addons/logistics_uavbattery/CfgWeapons.hpp b/addons/logistics_uavbattery/CfgWeapons.hpp index 8beedff39b..c4092dc017 100644 --- a/addons/logistics_uavbattery/CfgWeapons.hpp +++ b/addons/logistics_uavbattery/CfgWeapons.hpp @@ -1,14 +1,15 @@ class CfgWeapons { - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_ItemCore; class ACE_UAVBattery: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Battery_Name); descriptionShort = CSTRING(Battery_Description); model = QPATHTOF(data\ace_battery.p3d); picture = QPATHTOF(ui\UAV_battery_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 20; }; }; diff --git a/addons/logistics_uavbattery/stringtable.xml b/addons/logistics_uavbattery/stringtable.xml index 97c709d8dd..bd3ea82684 100644 --- a/addons/logistics_uavbattery/stringtable.xml +++ b/addons/logistics_uavbattery/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -13,7 +13,7 @@ Il drone è pieno БПЛА полностью заряжен ドローンは充電完了 - 드론 충전완료 + 무인기 충전완료 无人载具电池已充满 無人載具電池已充滿 @@ -29,7 +29,7 @@ Hai bisogno di una Batteria UAV Требуется аккумулятор для БПЛА UAV バッテリが必要です - UAV 배터리가 필요합니다 + 무인기 배터리가 필요합니다 你需要一个无人载具电池 你需要一個無人載具電池 @@ -61,7 +61,7 @@ Batteria UAV Аккумулятор БПЛА UAV バッテリ - UAV 배터리 + 무인기 배터리 无人载具电池 無人載具電池 @@ -77,7 +77,7 @@ Usata per ricaricare la Batteria dell'UAV Используется для зарядки переносных БПЛА 運んでいる UAV を充電に使う - UAV를 재충전 할때 씁니다. + 무인기를 재충전 할때 씁니다. 对可携式无人载具进行充电 對可攜式無人載具進行充電 @@ -92,9 +92,10 @@ Recarregando... In ricarica... Заряжается... - 充電中 + 充電しています・・・ 充电中... 充電中... + 충전중... diff --git a/addons/logistics_wirecutter/CfgWeapons.hpp b/addons/logistics_wirecutter/CfgWeapons.hpp index 2cb7e7b7b1..1eebf82877 100644 --- a/addons/logistics_wirecutter/CfgWeapons.hpp +++ b/addons/logistics_wirecutter/CfgWeapons.hpp @@ -1,5 +1,5 @@ class CfgWeapons { - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_ItemCore; class ACE_wirecutter: ACE_ItemCore { @@ -9,7 +9,7 @@ class CfgWeapons { model = QPATHTOF(data\ace_wirecutter.p3d); picture = QPATHTOF(ui\item_wirecutter_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 25; }; }; diff --git a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf index 61d8a254c5..911ddcf01d 100644 --- a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf @@ -19,37 +19,43 @@ params ["_unit", "_fenceObject"]; TRACE_2("params",_unit,_fenceObject); -private ["_timeToCut", "_progressCheck", "_onCompletion", "_onFail"]; - if (_unit != ACE_player) exitWith {}; -_timeToCut = if ([ACE_player] call EFUNC(common,isEngineer)) then {7.5} else {11}; +private _timeToCut = if ([_unit] call EFUNC(common,isEngineer)) then {7.5} else {11}; -[ACE_player, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation); +if !(_unit call EFUNC(common,isSwimming)) then { + [_unit, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation); +}; -_onCompletion = { +private _onCompletion = { TRACE_1("_onCompletion",_this); (_this select 0) params ["_fenceObject", "", "_unit"]; _fenceObject setdamage 1; - [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + if !(_unit call EFUNC(common,isSwimming)) then { + [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + }; }; -_onFail = { +private _onFail = { TRACE_1("_onFail", _this); (_this select 0) params ["", "", "_unit"]; - [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + if !(_unit call EFUNC(common,isSwimming)) then { + [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + }; }; -_progressCheck = { +private _progressCheck = { params ["_args", "_passedTime"]; - _args params ["_fenceObject", "_lastSoundEffectTime"]; + _args params ["_fenceObject", "_lastSoundEffectTime", "_unit"]; if (_passedTime > (_lastSoundEffectTime + SOUND_CLIP_TIME_SPACEING)) then { - playSound3D [QUOTE(PATHTO_R(sound\wirecut.ogg)), objNull, false, (getPosASL ACE_player), 3, 1, 10]; + playSound3D [QUOTE(PATHTO_R(sound\wirecut.ogg)), objNull, false, (getPosASL _unit), 3, 1, 10]; _args set [1, _passedTime]; }; - ((!isNull _fenceObject) && {(damage _fenceObject) < 1} && {("ACE_wirecutter" in (items ACE_player))}) + ((!isNull _fenceObject) && {(damage _fenceObject) < 1} && {("ACE_wirecutter" in (items _unit))}) }; -[_timeToCut, [_fenceObject,0,_unit], _onCompletion, _onFail, localize LSTRING(CuttingFence), _progressCheck] call EFUNC(common,progressBar); +[_timeToCut, [_fenceObject,0,_unit], _onCompletion, _onFail, localize LSTRING(CuttingFence), _progressCheck, ["isNotSwimming"]] call EFUNC(common,progressBar); + +["ace_wireCuttingStarted", [_unit, _fenceObject]] call CBA_fnc_globalEvent; diff --git a/addons/logistics_wirecutter/functions/fnc_interactEH.sqf b/addons/logistics_wirecutter/functions/fnc_interactEH.sqf index 302e4b0975..74f59a8104 100644 --- a/addons/logistics_wirecutter/functions/fnc_interactEH.sqf +++ b/addons/logistics_wirecutter/functions/fnc_interactEH.sqf @@ -27,7 +27,6 @@ if (!("ACE_wirecutter" in (items ace_player))) exitWith {}; TRACE_1("Starting wire-cut action PFEH",_interactionType); [{ - private ["_fncStatement", "_attachedFence", "_fncCondition", "_helper", "_action"]; params ["_args", "_pfID"]; _args params ["_setPosition", "_addedHelpers", "_fencesHelped"]; @@ -41,13 +40,13 @@ TRACE_1("Starting wire-cut action PFEH",_interactionType); //If player moved >5 meters from last pos, then rescan if (((getPosASL ace_player) distance _setPosition) > 5) then { - _fncStatement = { + private _fncStatement = { params ["", "_player", "_attachedFence"]; [_player, _attachedFence] call FUNC(cutDownFence); }; - _fncCondition = { + private _fncCondition = { params ["_helper", "_player", "_attachedFence"]; - if (!([_player, _attachedFence, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if (!([_player, _attachedFence, ["isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {false}; ((!isNull _attachedFence) && {(damage _attachedFence) < 1} && {("ACE_wirecutter" in (items _player))} && { //Custom LOS check for fence private _headPos = ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot"); @@ -60,8 +59,8 @@ TRACE_1("Starting wire-cut action PFEH",_interactionType); if (!(_x in _fencesHelped)) then { if ([_x] call FUNC(isFence)) then { _fencesHelped pushBack _x; - _helper = "ACE_LogicDummy" createVehicleLocal (getpos _x); - _action = [QGVAR(helperCutFence), (localize LSTRING(CutFence)), QPATHTOF(ui\wirecutter_ca.paa), _fncStatement, _fncCondition, {}, _x, {[0,0,0]}, 5.5, [false, false, false, false, true]] call EFUNC(interact_menu,createAction); + private _helper = "ACE_LogicDummy" createVehicleLocal (getpos _x); + private _action = [QGVAR(helperCutFence), (localize LSTRING(CutFence)), QPATHTOF(ui\wirecutter_ca.paa), _fncStatement, _fncCondition, {}, _x, {[0,0,0]}, 5.5, [false, false, false, false, true]] call EFUNC(interact_menu,createAction); [_helper, 0, [],_action] call EFUNC(interact_menu,addActionToObject); _helper setPosASL ((getPosASL _x) vectorAdd [0,0,1.25]); _addedHelpers pushBack _helper; diff --git a/addons/logistics_wirecutter/script_component.hpp b/addons/logistics_wirecutter/script_component.hpp index 7ec3a5dc0d..69711d289b 100644 --- a/addons/logistics_wirecutter/script_component.hpp +++ b/addons/logistics_wirecutter/script_component.hpp @@ -18,6 +18,6 @@ //find is case sensitive, so keep everything lowercase -#define FENCE_P3DS ["mil_wiredfence_f.p3d","wall_indfnc_3.p3d", "wall_indfnc_9.p3d", "wall_indfnc_corner.p3d", "pletivo_wired.p3d", "wall_fen1_5.p3d"] +#define FENCE_P3DS ["mil_wiredfence_f.p3d","wall_indfnc_3.p3d", "wall_indfnc_9.p3d", "wall_indfnc_corner.p3d", "pletivo_wired.p3d", "wall_fen1_5.p3d", "net_fence_8m_f.p3d"] #define SOUND_CLIP_TIME_SPACEING 1.5 diff --git a/addons/logistics_wirecutter/stringtable.xml b/addons/logistics_wirecutter/stringtable.xml index 53c5e21b14..62b7ef77d2 100644 --- a/addons/logistics_wirecutter/stringtable.xml +++ b/addons/logistics_wirecutter/stringtable.xml @@ -60,7 +60,7 @@ Sto tagliando... Drótok elvágása... Разрезаем забор / провода... - フェンス/ワイヤを切断中・・・ + フェンス/ワイヤを切断しています・・・ 철망/철조망 자르는중... 剪断护栏/刺网中... 剪斷護欄/刺網中... diff --git a/addons/magazinerepack/ACE_Settings.hpp b/addons/magazinerepack/ACE_Settings.hpp index 940af87d15..b66fe5f254 100644 --- a/addons/magazinerepack/ACE_Settings.hpp +++ b/addons/magazinerepack/ACE_Settings.hpp @@ -1,17 +1,26 @@ class ACE_Settings { //Time to move a round from one magazine to another class GVAR(timePerAmmo) { + category = CSTRING(DisplayName); + displayName = CSTRING(timePerAmmo); value = 1.5; typeName = "SCALAR"; + sliderSettings[] = {1, 10, 1.5, 1}; }; //Time to swap between magazines when repacking class GVAR(timePerMagazine) { + category = CSTRING(DisplayName); + displayName = CSTRING(timePerMagazine); value = 2.0; typeName = "SCALAR"; + sliderSettings[] = {1, 10, 2, 1}; }; //Time to relink 2 belts together class GVAR(timePerBeltLink) { + category = CSTRING(DisplayName); + displayName = CSTRING(timePerBeltLink); value = 8.0; typeName = "SCALAR"; + sliderSettings[] = {1, 10, 8, 1}; }; }; diff --git a/addons/magazinerepack/CfgVehicles.hpp b/addons/magazinerepack/CfgVehicles.hpp index 0bf4833bf0..2c8ef81608 100644 --- a/addons/magazinerepack/CfgVehicles.hpp +++ b/addons/magazinerepack/CfgVehicles.hpp @@ -5,10 +5,10 @@ class CfgVehicles { class ACE_RepackMagazines { displayName = CSTRING(RepackMagazines); condition = QUOTE(true); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; insertChildren = QUOTE(_this call FUNC(getMagazineChildren)); priority = -2; - icon = QPATHTOF(UI\repack_ca.paa); + icon = QPATHTOEF(common,UI\repack_ca.paa); }; }; }; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf index 36544b0084..286db1389b 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -25,11 +25,12 @@ _args params ["_magazineClassname", "_lastAmmoCount"]; private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count"); // Don't show anything if player can't interact -if (!([ACE_player, objNull, ["isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith))) exitWith {}; +if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; // Count mags private _fullMags = 0; private _partialMags = 0; +private _bulletsLeft = 0; { _x params ["_classname", "_count"]; @@ -38,15 +39,16 @@ private _partialMags = 0; _fullMags = _fullMags + 1; } else { _partialMags = _partialMags + 1; + _bulletsLeft = _count; }; }; } forEach (magazinesAmmoFull ACE_player); -private _repackedMagsText = format [localize LSTRING(RepackedMagazinesCount), _fullMags, _partialMags]; - private _structuredOutputText = if (_errorCode == 0) then { + private _repackedMagsText = format [localize LSTRING(RepackedMagazinesDetail), _fullMags, _bulletsLeft]; format ["%1
%2", localize LSTRING(RepackComplete), _repackedMagsText]; } else { + private _repackedMagsText = format [localize LSTRING(RepackedMagazinesCount), _fullMags, _partialMags]; format ["%1
%2", localize LSTRING(RepackInterrupted), _repackedMagsText]; }; diff --git a/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf index d3cd621305..e87fc5f221 100644 --- a/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf +++ b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf @@ -29,7 +29,7 @@ private _fullMagazineCount = getNumber (_magazineCfg >> "count"); private _isBelt = isNumber (_magazineCfg >> "ACE_isBelt") && {(getNumber (_magazineCfg >> "ACE_isBelt")) == 1}; //Check canInteractWith: -if !([_player, objNull, ["isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; +if !([_player, objNull, ["isNotInside", "isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; [_player] call EFUNC(common,goKneeling); @@ -67,5 +67,5 @@ private _totalTime = _simEvents select (count _simEvents - 1) select 0; {_this call FUNC(magazineRepackFinish)}, (localize LSTRING(RepackingMagazine)), {_this call FUNC(magazineRepackProgress)}, - ["isNotInside", "isNotSitting"] + ["isNotInside", "isNotSwimming", "isNotSitting"] ] call EFUNC(common,progressBar); diff --git a/addons/magazinerepack/stringtable.xml b/addons/magazinerepack/stringtable.xml index f82280961e..2ae06d02e1 100644 --- a/addons/magazinerepack/stringtable.xml +++ b/addons/magazinerepack/stringtable.xml @@ -1,6 +1,41 @@ - + + + Magazine Repack + Riempimento Caricatori + 重新整理彈匣 + 重新整理弹匣 + 弾倉詰め替え + 탄약 채우기 + + + Time per round + Zeit pro Patrone + Durata per proiettile + 每發所需時間 + 每发所需时间 + 弾頭毎の所有時間 + 구경 당 시간 + + + Time per magazine + Zeit pro Magazin + Durata per caricatore + 每匣所需時間 + 每匣所需时间 + 弾倉毎の所有時間 + 탄창 당 시간 + + + Time per belt link + Zeit pro Gurtglied + Durata per caricatore a nastro + 每彈鍊所需時間 + 每弹炼所需时间 + ベルトリンク毎の所有時間 + 탄약띠 당 시간 + Repack Magazines Magazine umpacken @@ -8,7 +43,7 @@ Réorganiser les chargeurs Przepakuj magazynki Přepáskovat zásobníky - Riempi i caricatori + Riempi Caricatori Reorganizar Carregadores Újratárazás Перепаковать магазины @@ -17,38 +52,6 @@ 重新整理弹匣 重新整理彈匣 - - Select Magazine Menu - Magazinauswahlmenü - Menú de selección de cargador - Sélectionner le menu des chargeurs - Menu wyboru magazynków - Zvolit menu zásobníků - Seleziona menù di ricarica - Menu de Seleção de Carregador - Fegyvertár menü kiválasztás - Меню выбора магазинов - 弾倉メニューから選ぶ - 탄창 메뉴 고르기 - 选择弹匣清单 - 選擇彈匣清單 - - - Select Mag - Magazin auswählen - Seleccionar cargador - Sélectionner le chargeur - Wybierz magazynek - Vyber zásobník - Seleziona caricatore - Selecionar Carregador - Tár kiválasztása - Выбрать магазин - 弾倉を選択 - 탄창 고르기 - 选择弹匣 - 選擇彈匣 - Repacking Magazines... Magazine umpacken... @@ -56,7 +59,7 @@ Réorganisation des chargeurs... Przepakowywanie magazynków... Přepáskovávám zásobník... - Sto riempendo i caricatori... + Riempendo i caricatori... Reorganizando Carregadores... Újratárazás... Перепаковка магазинов... @@ -65,22 +68,6 @@ 重新整理弹匣中 ... 重新整理彈匣中 ... - - Repacked Magazines - Magazine umgepackt - Cargadores reorganizados - Chargeurs réorganisés - Magazynki przepakowane - Přepáskované zásobníky - Caricatore riempito - Carregadores Reorganizados - Újratárazott tárak - Магазины перепакованы - 弾倉の詰め替えが終わった - 탄창 채워짐 - 弹匣已重新整理 - 彈匣已重新整理 - %1 full mag(s) and %2 extra round(s) %1 volle(s) Magazin(e) und %2 übrig gebliebene Patrone(n) @@ -92,7 +79,7 @@ %1 carregador(es) cheio(s) e %2 disparo(s) a mais %1 teljes tár és %2 extra lőszer %1 полных магазина(ов) и %2 патрона(ов) - %1 個の満杯な弾倉と入りきらなかった %2 個の弾倉 + %1 個の満杯な弾倉とあふれた %2 発の弾薬 %1개의 꽉찬 탄창과 %2발의 총알이 남았다 %1个满的弹匣与%2发额外子弹 %1個滿的彈匣與%2發額外子彈 @@ -106,7 +93,7 @@ Páskování dokončeno Przepakowywanie zakończone Újratárazás befejezve - Caricatori riempiti + Caricatori Riempiti Reorganização Terminada 詰め替えが完了 탄창 채우기 끝남 @@ -122,7 +109,7 @@ Páskování přerušeno Przepakowywanie przerwane Újratárazás megszakítva - Riempimento interrotto + Riempimento Interrotto Reorganização Interrompida 詰め替えを中断した 탄창 채우기 방해받음 @@ -132,15 +119,15 @@ %1 Full and %2 Partial %1 plein(s) et %2 partiel(s) - %1 volle Magazine und 1 Magazin mit %2 Partronen + %1 volle(s) Magazin(e) und %2 angefangene(s) Magazin(e) %1 Llenos y %2 Incompletos %1 полных и %2 неполных %1 plný a %2 částečně Pełnych: %1.<br/>Częściowo pełnych: %2. %1 teljes és %2 részleges - %1 pieno(i) e %2 parziale(i) + %1 Pieno(i) e %2 Parziale(i) %1 Total e %2 Parcial - %1 個の満杯で、 %2 の余分数 + %1 個の満杯と %2 個の弾薬入り弾倉 %1 꽉찼고 %2 부분참 %1个满的与%2个部分的 %1個滿的與%2個部分的 diff --git a/addons/main/CfgEditorSubcategories.hpp b/addons/main/CfgEditorSubcategories.hpp new file mode 100644 index 0000000000..baf892a3c5 --- /dev/null +++ b/addons/main/CfgEditorSubcategories.hpp @@ -0,0 +1,5 @@ +class CfgEditorSubcategories { + class GVAR(subcategory) { + displayName = CSTRING(Category_Logistics); + }; +}; diff --git a/addons/main/config.cpp b/addons/main/config.cpp index cf38747148..e04f573e62 100644 --- a/addons/main/config.cpp +++ b/addons/main/config.cpp @@ -19,6 +19,7 @@ class CfgPatches { "A3_Data_F_Jets_Loadorder", "A3_Data_F_Argo_Loadorder", "A3_Data_F_Patrol_Loadorder", + "A3_Data_F_Orange_Loadorder", // Vanilla "a3_3den", @@ -905,3 +906,4 @@ class CfgMods { #include "CfgSettings.hpp" #include "CfgModuleCategories.hpp" #include "CfgVehicleClasses.hpp" +#include "CfgEditorSubcategories.hpp" diff --git a/addons/main/script_debug.hpp b/addons/main/script_debug.hpp index d0574bcd32..bb08e34e09 100644 --- a/addons/main/script_debug.hpp +++ b/addons/main/script_debug.hpp @@ -23,12 +23,12 @@ STACK TRACING //#define DEBUG_EVENTS #ifdef ENABLE_CALLSTACK - #define CALLSTACK(function) {private ['_ret']; if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, 'ANON', _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = 'ANON'; _ret = _this call ##function; ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} - #define CALLSTACK_NAMED(function, functionName) {private ['_ret']; if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, functionName, _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = functionName; _ret = _this call ##function; ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} + #define CALLSTACK(function) {if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, 'ANON', _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = 'ANON'; private _ret = _this call ##function; ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} + #define CALLSTACK_NAMED(function, functionName) {if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, functionName, _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = functionName; private _ret = _this call ##function; ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} #define DUMPSTACK ([__FILE__, __LINE__] call ACE_DUMPSTACK_FNC) - #define FUNC(var1) {private ['_ret']; if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, 'TRIPLES(ADDON,fnc,var1)', _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = 'TRIPLES(ADDON,fnc,var1)'; _ret = _this call TRIPLES(ADDON,fnc,var1); ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} - #define EFUNC(var1,var2) {private ['_ret']; if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, 'TRIPLES(DOUBLES(PREFIX,var1),fnc,var2)', _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = 'TRIPLES(DOUBLES(PREFIX,var1),fnc,var2)'; _ret = _this call TRIPLES(DOUBLES(PREFIX,var1),fnc,var2); ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} + #define FUNC(var1) {if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, 'TRIPLES(ADDON,fnc,var1)', _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = 'TRIPLES(ADDON,fnc,var1)'; private _ret = _this call TRIPLES(ADDON,fnc,var1); ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} + #define EFUNC(var1,var2) {if(ACE_IS_ERRORED) then { ['AUTO','AUTO'] call ACE_DUMPSTACK_FNC; ACE_IS_ERRORED = false; }; ACE_IS_ERRORED = true; ACE_STACK_TRACE set [ACE_STACK_DEPTH, [diag_tickTime, __FILE__, __LINE__, ACE_CURRENT_FUNCTION, 'TRIPLES(DOUBLES(PREFIX,var1),fnc,var2)', _this]]; ACE_STACK_DEPTH = ACE_STACK_DEPTH + 1; ACE_CURRENT_FUNCTION = 'TRIPLES(DOUBLES(PREFIX,var1),fnc,var2)'; private _ret = _this call TRIPLES(DOUBLES(PREFIX,var1),fnc,var2); ACE_STACK_DEPTH = ACE_STACK_DEPTH - 1; ACE_IS_ERRORED = false; _ret;} #else #define CALLSTACK(function) function #define CALLSTACK_NAMED(function, functionName) function @@ -40,7 +40,7 @@ STACK TRACING PERFORMANCE COUNTERS SECTION **/ //#define ENABLE_PERFORMANCE_COUNTERS -// To Use: [] call ace_common_fnc_dumpPerformanceCounters; +// To Use: [] call ace_common_fnc_dumpPerformanceCounters; #ifdef ENABLE_PERFORMANCE_COUNTERS #define CBA_fnc_addPerFrameHandler { _ret = [(_this select 0), (_this select 1), (_this select 2), #function] call CBA_fnc_addPerFrameHandler; if(isNil "ACE_PFH_COUNTER" ) then { ACE_PFH_COUNTER=[]; }; ACE_PFH_COUNTER pushBack [[_ret, __FILE__, __LINE__], [(_this select 0), (_this select 1), (_this select 2)]]; _ret } diff --git a/addons/main/script_macros.hpp b/addons/main/script_macros.hpp index 167884616f..16a33583a0 100644 --- a/addons/main/script_macros.hpp +++ b/addons/main/script_macros.hpp @@ -20,11 +20,11 @@ #define SETPVAR_SYS(var1,var2) setVariable [ARR_3(QUOTE(var1),var2,true)] #undef GETVAR -#define GETVAR(var1,var2,var3) var1 GETVAR_SYS(var2,var3) -#define GETMVAR(var1,var2) missionNamespace GETVAR_SYS(var1,var2) -#define GETUVAR(var1,var2) uiNamespace GETVAR_SYS(var1,var2) -#define GETPRVAR(var1,var2) profileNamespace GETVAR_SYS(var1,var2) -#define GETPAVAR(var1,var2) parsingNamespace GETVAR_SYS(var1,var2) +#define GETVAR(var1,var2,var3) (var1 GETVAR_SYS(var2,var3)) +#define GETMVAR(var1,var2) (missionNamespace GETVAR_SYS(var1,var2)) +#define GETUVAR(var1,var2) (uiNamespace GETVAR_SYS(var1,var2)) +#define GETPRVAR(var1,var2) (profileNamespace GETVAR_SYS(var1,var2)) +#define GETPAVAR(var1,var2) (parsingNamespace GETVAR_SYS(var1,var2)) #undef SETVAR #define SETVAR(var1,var2,var3) var1 SETVAR_SYS(var2,var3) @@ -37,7 +37,7 @@ #define GETGVAR(var1,var2) GETMVAR(GVAR(var1),var2) #define GETEGVAR(var1,var2,var3) GETMVAR(EGVAR(var1,var2),var3) -#define ARR_SELECT(ARRAY,INDEX,DEFAULT) if (count ARRAY > INDEX) then {ARRAY select INDEX} else {DEFAULT} +#define ARR_SELECT(ARRAY,INDEX,DEFAULT) (if (count ARRAY > INDEX) then {ARRAY select INDEX} else {DEFAULT}) #define MACRO_ADDWEAPON(WEAPON,COUNT) class _xx_##WEAPON { \ @@ -109,4 +109,17 @@ #define TRACE_10(MESSAGE,A,B,C,D,E,F,G,H,I,J) /* disabled */ #endif +#define GRAVITY 9.8066 + +#define SD_TO_MIN_MAX(d) ((d) * 3.371) // Standard deviation -> min / max of random [min, mid, max] + +// Angular unit conversion +#define MRAD_TO_MOA(d) ((d) * 3.43774677) // Conversion factor: 54 / (5 * PI) +#define MOA_TO_MRAD(d) ((d) * 0.29088821) // Conversion factor: (5 * PI) / 54 +#define DEG_TO_MOA(d) ((d) * 60) // Conversion factor: 60 +#define MOA_TO_DEG(d) ((d) / 60) // Conversion factor: 1 / 60 +#define DEG_TO_MRAD(d) ((d) * 17.45329252) // Conversion factor: (50 * PI) / 9 +#define MRAD_TO_DEG(d) ((d) / 17.45329252) // Conversion factor: 9 / (50 * PI) +#define MOA_TO_RAD(d) ((d) * 0.00029088) // Conversion factor: PI / 10800 + #include "script_debug.hpp" diff --git a/addons/main/script_mod.hpp b/addons/main/script_mod.hpp index 7b2f6a92cd..04785a35a6 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -9,8 +9,8 @@ #define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD // MINIMAL required version for the Mod. Components can specify others.. -#define REQUIRED_VERSION 1.72 -#define REQUIRED_CBA_VERSION {3,3,1} +#define REQUIRED_VERSION 1.78 +#define REQUIRED_CBA_VERSION {3,5,0} #ifdef COMPONENT_BEAUTIFIED #define COMPONENT_NAME QUOTE(ACE3 - COMPONENT_BEAUTIFIED) diff --git a/addons/main/script_version.hpp b/addons/main/script_version.hpp index d10bb0eaf4..661e95a56d 100644 --- a/addons/main/script_version.hpp +++ b/addons/main/script_version.hpp @@ -1,4 +1,4 @@ #define MAJOR 3 -#define MINOR 10 -#define PATCHLVL 2 -#define BUILD 22 +#define MINOR 12 +#define PATCHLVL 1 +#define BUILD 31 diff --git a/addons/main/stringtable.xml b/addons/main/stringtable.xml index d312264cf6..7e6a6fb76a 100644 --- a/addons/main/stringtable.xml +++ b/addons/main/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -14,6 +14,7 @@ ACE ロジスティクス ACE 后勤 ACE 後勤 + ACE 논리 http://ace3mod.com/ diff --git a/addons/map/ACE_Settings.hpp b/addons/map/ACE_Settings.hpp index b04c7b39b3..a9702aebba 100644 --- a/addons/map/ACE_Settings.hpp +++ b/addons/map/ACE_Settings.hpp @@ -1,72 +1,32 @@ class ACE_Settings { class GVAR(BFT_Interval) { - category = CSTRING(Module_DisplayName); - value = 1.0; - typeName = "SCALAR"; - displayName = CSTRING(BFT_Interval_DisplayName); - description = CSTRING(BFT_Interval_Description); + movedToSQF = 1; }; class GVAR(BFT_Enabled) { - category = CSTRING(Module_DisplayName); - value = 0; - typeName = "BOOL"; - displayName = CSTRING(BFT_Enabled_DisplayName); - description = CSTRING(BFT_Enabled_Description); + movedToSQF = 1; }; class GVAR(BFT_HideAiGroups) { - category = CSTRING(Module_DisplayName); - value = 0; - typeName = "BOOL"; - displayName = CSTRING(BFT_HideAiGroups_DisplayName); - description = CSTRING(BFT_HideAiGroups_Description); + movedToSQF = 1; }; class GVAR(BFT_ShowPlayerNames) { - category = CSTRING(Module_DisplayName); - value = 0; - typeName = "BOOL"; - displayName = CSTRING(BFT_ShowPlayerNames_DisplayName); - description = CSTRING(BFT_ShowPlayerNames_Description); + movedToSQF = 1; }; class GVAR(mapIllumination) { - category = CSTRING(Module_DisplayName); - value = 1; - typeName = "BOOL"; - displayName = CSTRING(MapIllumination_DisplayName); - description = CSTRING(MapIllumination_Description); + movedToSQF = 1; }; class GVAR(mapGlow) { - category = CSTRING(Module_DisplayName); - value = 1; - typeName = "BOOL"; - displayName = CSTRING(MapGlow_DisplayName); - description = CSTRING(MapGlow_Description); + movedToSQF = 1; }; class GVAR(mapShake) { - category = CSTRING(Module_DisplayName); - value = 1; - typeName = "BOOL"; - displayName = CSTRING(MapShake_DisplayName); - description = CSTRING(MapShake_Description); + movedToSQF = 1; }; class GVAR(mapLimitZoom) { - category = CSTRING(Module_DisplayName); - value = 0; - typeName = "BOOL"; - displayName = CSTRING(MapLimitZoom_DisplayName); - description = CSTRING(MapLimitZoom_Description); + movedToSQF = 1; }; class GVAR(mapShowCursorCoordinates) { - category = CSTRING(Module_DisplayName); - value = 0; - typeName = "BOOL"; - displayName = CSTRING(MapShowCursorCoordinates_DisplayName); - description = CSTRING(MapShowCursorCoordinates_Description); + movedToSQF = 1; }; class GVAR(defaultChannel) { - category = CSTRING(Module_DisplayName); - value = -1; - typeName = "SCALAR"; - displayName = CSTRING(DefaultChannel_DisplayName); - description = CSTRING(DefaultChannel_Description); + movedToSQF = 1; }; }; diff --git a/addons/map/CfgMarkers.hpp b/addons/map/CfgMarkers.hpp index 0a04e4a691..3dd6463891 100644 --- a/addons/map/CfgMarkers.hpp +++ b/addons/map/CfgMarkers.hpp @@ -4,36 +4,7 @@ class CfgMarkers { // Reenable NATO symbols ... class b_unknown: Flag {scope = 2;}; - - // ... and disable all the useless ones - // If you think that some of these are needed, create an issue; But until - // there's a better way to place markers, there should be only the most - // important markers here. - // Keep in mind that all of these can still be placed in the editor. - class b_hq: b_unknown {scope = 1;}; - class b_installation: b_unknown {scope = 1;}; - class b_maint: b_unknown {scope = 1;}; - class b_med: b_unknown {scope = 1;}; - class b_service: b_unknown {scope = 1;}; - class b_support: b_unknown {scope = 1;}; - - class n_unknown: b_unknown {}; - class n_hq: n_unknown {scope = 1;}; - class n_installation: n_unknown {scope = 1;}; - class u_installation: n_unknown {scope = 1;}; // i have no idea... - class n_maint: n_unknown {scope = 1;}; - class n_med: n_unknown {scope = 1;}; - class n_service: n_unknown {scope = 1;}; - class n_support: n_unknown {scope = 1;}; - - class o_unknown: b_unknown {}; - class o_hq: o_unknown {scope = 1;}; - class o_installation: o_unknown {scope = 1;}; - class o_maint: o_unknown {scope = 1;}; - class o_med: o_unknown {scope = 1;}; - class o_service: o_unknown {scope = 1;}; - class o_support: o_unknown {scope = 1;}; - + // disable all civy markers (harbor etc.) class c_unknown: b_unknown {scope = 1;}; diff --git a/addons/map/CfgVehicles.hpp b/addons/map/CfgVehicles.hpp index 16eba79cb2..3a28fe4c3e 100644 --- a/addons/map/CfgVehicles.hpp +++ b/addons/map/CfgVehicles.hpp @@ -21,7 +21,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(moduleMap); - scope = 2; + scope = 1; isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_Map_ca.paa); @@ -81,8 +81,8 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(BFT_Module_DisplayName); function = QFUNC(blueForceTrackingModule); - scope = 2; - isGlobal = 0; + scope = 1; + isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_BFTracking_ca.paa); class Arguments { diff --git a/addons/map/CfgWeapons.hpp b/addons/map/CfgWeapons.hpp index c7f350a454..5831428c6c 100644 --- a/addons/map/CfgWeapons.hpp +++ b/addons/map/CfgWeapons.hpp @@ -13,4 +13,14 @@ class CfgWeapons { }; }; }; -}; \ No newline at end of file + class acc_flashlight_pistol: ItemCore { + class ItemInfo: InventoryFlashlightItem_Base_F { + class FlashLight { + ACE_Flashlight_Colour = "white"; + ACE_Flashlight_Beam = QPATHTOF(UI\Flashlight_beam_white_ca.paa); + ACE_Flashlight_Size = 2.75; + ACE_Flashlight_Sound = 1; + }; + }; + }; +}; diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index f022e2c81e..6f2f60fc0c 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -126,3 +126,43 @@ GVAR(hasWatch) = true; false } count (assignedItems _unit); }, true] call CBA_fnc_addPlayerEventHandler; + + +// Vehicle map lighting: +GVAR(vehicleLightCondition) = {true}; +GVAR(vehicleExteriorTurrets) = []; +GVAR(vehicleLightColor) = [1,1,1,0]; + +["vehicle", { + params ["_unit", "_vehicle"]; + if ((isNull _vehicle) || {_unit == _vehicle}) exitWith {}; + private _cfg = configfile >> "CfgVehicles" >> (typeOf _vehicle); + GVAR(vehicleExteriorTurrets) = getArray (_cfg >> QGVAR(vehicleExteriorTurrets)); + GVAR(vehicleLightColor) = [_cfg >> QGVAR(vehicleLightColor), "array", [1,1,1,0]] call CBA_fnc_getConfigEntry; + + // Handle vehicles with toggleable interior lights: + private _vehicleLightCondition = getText (_cfg >> QGVAR(vehicleLightCondition)); + if (_vehicleLightCondition == "") then { + private _userAction = toLower getText (_cfg >> "UserActions" >> "ToggleLight" >> "statement"); + switch (true) do { + case ((_userAction find "cabinlights_hide") > 0): {_vehicleLightCondition = "(_vehicle animationSourcePhase 'cabinlights_hide') == 1";}; + case ((_userAction find "cargolights_hide") > 0): {_vehicleLightCondition = "(_vehicle animationSourcePhase 'cargolights_hide') == 1";}; + }; + }; + + GVAR(vehicleLightCondition) = if (_vehicleLightCondition != "") then { + if (_vehicle isKindOf "Helicopter" || {_vehicle isKindOf "Plane"}) then { + compile format ["(driver _vehicle == _unit) || {gunner _vehicle == _unit} || {%1}", _vehicleLightCondition]; + } else { + compile _vehicleLightCondition + }; + } else { + switch (true) do { + case (_vehicle isKindOf "Tank"); + case (_vehicle isKindOf "Wheeled_APC"): { {true} }; + case (_vehicle isKindOf "Helicopter"); + case (_vehicle isKindOf "Plane"): { {(driver _vehicle == _unit) || {gunner _vehicle == _unit}} }; + default { {false} }; + }; + }; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/map/XEH_preInit.sqf b/addons/map/XEH_preInit.sqf index 7fe826a174..92a7e896f3 100644 --- a/addons/map/XEH_preInit.sqf +++ b/addons/map/XEH_preInit.sqf @@ -7,4 +7,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.sqf" + ADDON = true; diff --git a/addons/map/functions/fnc_blueForceTrackingModule.sqf b/addons/map/functions/fnc_blueForceTrackingModule.sqf index a892bf72cd..f19fc84e57 100644 --- a/addons/map/functions/fnc_blueForceTrackingModule.sqf +++ b/addons/map/functions/fnc_blueForceTrackingModule.sqf @@ -16,8 +16,6 @@ #include "script_component.hpp" -if (!isServer) exitWith {}; - params ["_logic"]; [_logic, QGVAR(BFT_Enabled), "Enabled"] call EFUNC(common,readSettingFromModule); diff --git a/addons/map/functions/fnc_determineMapLight.sqf b/addons/map/functions/fnc_determineMapLight.sqf index 89a2f6f606..3eaa39c6d8 100644 --- a/addons/map/functions/fnc_determineMapLight.sqf +++ b/addons/map/functions/fnc_determineMapLight.sqf @@ -47,9 +47,9 @@ if (_lightLevel > 0.95) exitWith { private _vehicle = vehicle _unit; // Do not obscure the map if the player is on a enclosed vehicle (assume internal illumination) -if ((_vehicle != _unit) && {!isTurnedOut _unit && {_vehicle isKindOf "Tank" || {(_vehicle isKindOf "Helicopter" || _vehicle isKindOf "Plane") && {driver _vehicle == _unit || {gunner _vehicle == _unit}}} || {_vehicle isKindOf "Wheeled_APC"}}}) exitWith { - TRACE_1("Player in a enclosed vehicle",""); - [false, [1,1,1,0]] +if ((_vehicle != _unit) && {(!isTurnedOut _unit)} && GVAR(vehicleLightCondition) && {!((_unit call CBA_fnc_turretPath) in GVAR(vehicleExteriorTurrets))}) exitWith { + TRACE_1("Player in a enclosed vehicle",GVAR(vehicleLightColor)); + [!(GVAR(vehicleLightColor) isEqualTo [1,1,1,0]), GVAR(vehicleLightColor)] }; // Player is not in a vehicle diff --git a/addons/map/functions/fnc_moduleMap.sqf b/addons/map/functions/fnc_moduleMap.sqf index 3dead784ca..077106eabe 100644 --- a/addons/map/functions/fnc_moduleMap.sqf +++ b/addons/map/functions/fnc_moduleMap.sqf @@ -16,8 +16,6 @@ #include "script_component.hpp" -if !(isServer) exitWith {}; - params ["_logic", "", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/map/functions/fnc_updateMapEffects.sqf b/addons/map/functions/fnc_updateMapEffects.sqf index e8ebcbd884..2c0f3c128c 100644 --- a/addons/map/functions/fnc_updateMapEffects.sqf +++ b/addons/map/functions/fnc_updateMapEffects.sqf @@ -35,7 +35,7 @@ if (GVAR(mapShake)) then { // Only shake map while moving on foot private _speed = 0; - if (vehicle ACE_player == ACE_player) then { + if ((alive ACE_player) && {vehicle ACE_player == ACE_player}) then { _speed = vectorMagnitude (velocity ACE_player); }; diff --git a/addons/map/initSettings.sqf b/addons/map/initSettings.sqf new file mode 100644 index 0000000000..1a72c6c90b --- /dev/null +++ b/addons/map/initSettings.sqf @@ -0,0 +1,90 @@ +[ + QGVAR(mapIllumination), + "CHECKBOX", + [localize LSTRING(MapIllumination_DisplayName), localize LSTRING(MapIllumination_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + true, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(mapGlow), + "CHECKBOX", + [localize LSTRING(MapGlow_DisplayName), localize LSTRING(MapGlow_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + true, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(mapShake), + "CHECKBOX", + [localize LSTRING(MapShake_DisplayName), localize LSTRING(MapShake_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + true, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(mapLimitZoom), + "CHECKBOX", + [localize LSTRING(MapLimitZoom_DisplayName), localize LSTRING(MapLimitZoom_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + false, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(mapShowCursorCoordinates), + "CHECKBOX", + [localize LSTRING(MapShowCursorCoordinates_DisplayName), localize LSTRING(MapShowCursorCoordinates_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + false, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(DefaultChannel), + "LIST", + [localize LSTRING(DefaultChannel_DisplayName), localize LSTRING(DefaultChannel_Description)], + format["ACE %1", localize LSTRING(Module_DisplayName)], + [[-1, 0, 1, 2, 3, 4, 5], [ELSTRING(common,Disabled), "STR_channel_global", "STR_channel_side", "STR_channel_command", "STR_channel_group", "STR_channel_vehicle", "STR_channel_direct"], 0], + true +] call CBA_settings_fnc_init; + +// Blue Force Tracking +[ + QGVAR(BFT_Enabled), + "CHECKBOX", + [localize LSTRING(BFT_Enabled_DisplayName), localize LSTRING(BFT_Enabled_Description)], + format ["ACE %1", localize LSTRING(BFT_Module_DisplayName)], + false, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(BFT_Interval), + "SLIDER", + [localize LSTRING(BFT_Interval_DisplayName), localize LSTRING(BFT_Interval_Description)], + format ["ACE %1", localize LSTRING(BFT_Module_DisplayName)], + [0, 30, 1, 1], + true +] call CBA_settings_fnc_init; + +[ + QGVAR(BFT_ShowPlayerNames), + "CHECKBOX", + [localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)], + format ["ACE %1", localize LSTRING(BFT_Module_DisplayName)], + false, + true +] call CBA_settings_fnc_init; + +[ + QGVAR(BFT_HideAiGroups), + "CHECKBOX", + [localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)], + format ["ACE %1", localize LSTRING(BFT_Module_DisplayName)], + false, + true +] call CBA_settings_fnc_init; diff --git a/addons/map/stringtable.xml b/addons/map/stringtable.xml index 9108f088bf..a19fd539e2 100644 --- a/addons/map/stringtable.xml +++ b/addons/map/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -18,20 +18,20 @@ 地圖 - Map illumination? + Map illumination Kartenbeleuchtung Oświetlenie mapy - ¿Iluminación de mapa? + ¿Iluminación de mapa Osvětlení mapy - Iluminação do mapa? - Illumination de la carte ? - Térkép megvilágítása? - Освещение карты? - Illuminazione Mappa? - 地図に照明? - 지도에 조명? - 地图照明? - 地圖照明? + Iluminação do mapa + Illumination de la carte + Térkép megvilágítása + Освещение карты + Illuminazione Mappa + 地図に照明 + 지도에 조명 + 地图照明 + 地圖照明 Simulate map lighting based on ambient lighting and player's items? @@ -43,25 +43,25 @@ Simular iluminación de mapa basada en la iluminación ambiente y los elementos de los jugadores? Simulovat nasvícení mapy v závisloti na okolí a předmětů hráče? Simula illuminazione della mappa in base alla luce ambientale e agli oggetti del giocatore? - 環境光やプレイヤーのアイテムにより、地図へ光のシミュレーションをおこないますか? + 地図へ環境光やプレイヤーのアイテムに基づいた光のシミュレーションをおこないますか? 주변 환경및 플레이어 조명에 의한 빛 변화를 지도에 반영할까요? 透过环境光与玩家的物品来决定地图亮度? 透過環境光與玩家的物品來決定地圖亮度? - Map flashlight glow? + Map flashlight glow Kartenbeleuchtung durch Dritte erkennbar Poświata latarki - Свет фонаря на карте? - Brilho de lanterna no mapa? - Resplandor de linterna en el mapa? - Nasvícení mapy pomocí baterky? - Luce della torcia in mappa? - Lumière de la lampe de carte ? - 地図をフラッシュライトで照らしますか? - 지도 조명이 빛이 납니까? - 增加地图亮度? - 增加地圖亮度? + Свет фонаря на карте + Brilho de lanterna no mapa + Resplandor de linterna en el mapa + Nasvícení mapy pomocí baterky + Luce della torcia in mappa + Lumière de la lampe de carte + 地図をライトで照らしますか + 지도 조명이 빛이 납니까 + 增加地图亮度 + 增加地圖亮度 Add external glow to players who use flashlight on map? @@ -73,26 +73,26 @@ Añadir resplandor externo a los jugadores que utilizan la linterna en el mapa? Přidat externí záři hráči který používá baterku v mapě? Aggiungi luce esterna a giocatori che usano la torcia in mappa? - プレイヤが地図上でフラッシュライトを使うと、照らすようにしますか? + プレイヤが地図上でフラッシュライトを使うと、照らすようにしますか? 지도에 불빛을 비치는 플레이어를 조금 더 밝게 합니까? - 当玩家拥有手电筒时, 增加地图亮度? - 當玩家擁有手電筒時, 增加地圖亮度? + 当玩家拥有手电筒时,增加地图亮度? + 當玩家擁有手電筒時,增加地圖亮度? - Map shake? + Map shake Drżenie mapy - ¿Temblor de mapa? + ¿Temblor de mapa Kamerawackeln - Třesení mapy? - Tremor de mapa? - Tremblement de la carte ? - Térkép-rázkódás? - Тряска карты? - Scuoti la mappa? - 地図を揺らしますか? - 지도 흔들림? - 地图震动? - 地圖震動? + Třesení mapy + Tremor de mapa + Tremblement de la carte + Térkép-rázkódás + Тряска карты + Scuoti la mappa + 地図を揺らしますか + 지도 흔들림 + 地图震动 + 地圖震動 Make map shake when walking? @@ -105,26 +105,26 @@ Rázkódjon-e a térkép mozgáskor? Заставлять карту трястись при ходьбе? Far scuotere la mappa mentre cammini? - 歩いているときは地図を揺らしますか? + 歩いているときは地図を揺らしますか? 걸을때 지도보면 흔들리게 합니까? 走路时让地图有震动的感觉? 走路時讓地圖有震動的感覺? - Limit map zoom? + Limit map zoom Ograniczony zoom - ¿Limitar el zoom de mapa? + ¿Limitar el zoom de mapa Kartenvergrößerung einschränken - Omezit přiblížení mapy? - Limitar zoom do mapa? - Limiter le zoom de la carte ? - Térkép-nagyítás korlátozása? - Ограничить приближение карты? - Limita lo zoom in mappa? - 地図の拡大を制限しますか? - 지도 확대 제한? - 限制地图缩放倍率? - 限制地圖縮放倍率? + Omezit přiblížení mapy + Limitar zoom do mapa + Limiter le zoom de la carte + Térkép-nagyítás korlátozása + Ограничить приближение карты + Limita lo zoom in mappa + 地図の拡大を制限しますか + 지도 확대 제한 + 限制地图缩放倍率 + 限制地圖縮放倍率 Limit the amount of zoom available for the map? @@ -137,26 +137,26 @@ Korlátozva legyen-e a nagyítás mennyisége a térképnél? Ограничить максимальное приближение, доступное на карте? Limita l'ammontare di zoom disponibile per la mappa? - 地図上で利用できる拡大倍率を制限しますか? + 地図上で利用できる拡大倍率を制限しますか? 지도 확대에 제한을 둡니까? 限制地图上可允许缩放的倍率? 限制地圖上可允許縮放的倍率? - Show cursor coordinates? + Show cursor coordinates Koordynaty pod kursorem - ¿Mostrar coordenadas de cursor? - Zeige Mauszeiger-Koordinaten? - Zobrazit souřadnice u kurzoru? - Mostrar coordenadas no cursor? - Afficher les coordonnées sur le curseur ? - Kurzor-koordináták mutatása? - Показывать координаты курсора? - Mostra coordinate sul cursore? - カーソル先で座標を表示しますか? - 커서에 좌표를 보이게 합니까? - 显示游标的座标? - 顯示游標的座標? + ¿Mostrar coordenadas de cursor + Zeige Mauszeiger-Koordinaten + Zobrazit souřadnice u kurzoru + Mostrar coordenadas no cursor + Afficher les coordonnées sur le curseur + Kurzor-koordináták mutatása + Показывать координаты курсора + Mostra coordinate sul cursore + カーソル先で座標を表示しますか + 커서에 좌표를 보이게 합니까 + 显示游标的座标 + 顯示游標的座標 Show the grid coordinates on the mouse pointer? @@ -169,7 +169,7 @@ Mutatva legyen-e a kurzornál található rész rácskoordinátája? Показывать координаты около курсора мыши? Mostra la griglia coordinate sul cursore mouse? - カーソルに合わせた先の地図座標を表示しますか? + カーソルに合わせた先を地図座標で表示しますか? 지도에서 커서 옆에 좌표가 뜨게 합니까? 显示滑鼠游标所在的网格座标? 顯示滑鼠游標所在的網格座標? @@ -185,7 +185,7 @@ Этот модуль позволяет настроить отображение карты. Este módulo permite personalizar la pantalla del mapa. Questo modulo ti permette di customizzare lo schermo della mappa. - モジュールは地図画面をカスタマイズできます。 + このモジュールは地図画面を変更できます。 이 모듈은 지도 화면을 임의로 설정할 수 있게 해줍니다. 此模块允许自定地图的相关效果. 此模塊允許自定地圖的相關效果. @@ -233,7 +233,7 @@ Blue Force követés engedélyezése. Alapértelmezett: Nem Включает систему служения BFT. По-умолчанию: Нет Abilita Blue Force Tracking. Default: No - ブルー フォース トラッキングを有効化します。標準:無効 + ブルー フォース トラッキングを有効化します。標準: 無効 GPS피아식별기 켭니다. 기본설정: 아니요 启用显示蓝方踪迹. 预设: 否 啟用顯示藍方蹤跡. 預設: 否 @@ -265,26 +265,26 @@ Milyen gyakran frissüljenek a jelölők (másodpercben) Как часто должны обновляться маркеры (в секундах) Quanto spesso vengono aggiornati i marker (in secondi) - マーカが再描画される間隔を設定できます(秒) + マーカが再描画される間隔を設定できます (秒) 몇 초마다 마커를 새로 갱신합니까? 设定每多少时间重新标示出单位位置 (秒) 設定每多少時間重新標示出單位位置 (秒) - Hide AI groups? + Hide AI groups Ukryj grupy AI - ¿Ocultar grupos de IA? - KI-Gruppen verstecken? - Skrýt AI skupiny? - Esconder grupos de IA? - Cacher les groupes d'IA ? - AI csoportok elrejtése? - Скрыть группы ботов? - Nascondere gruppi IA? - AI グループを非表示にしますか? - 인공지능 그룹을 숨깁니까? - 隐藏AI小队? - 隱藏AI小隊? + ¿Ocultar grupos de IA + KI-Gruppen verstecken + Skrýt AI skupiny + Esconder grupos de IA + Cacher les groupes d'IA + AI csoportok elrejtése + Скрыть группы ботов + Nascondere gruppi IA + AI グループを非表示にしますか + 인공지능 그룹을 숨깁니까 + 隐藏AI小队 + 隱藏AI小隊 Hide markers for 'AI only' groups? @@ -297,39 +297,39 @@ Jelölők elrejtése "csak AI" csoportoknál? Скрыть маркеры групп, которые состоят полностью из ботов? Nascondi markers per gruppi di sole IA? - 'AI のみ'グループのマーカを隠しますか? + 'AI のみ'グループのマーカを隠しますか? 인공지능만 있는 그룹의 마커를 숨깁니까? 隐藏'AI小队'的踪迹? 隱藏'AI小隊'的蹤跡? - Show player names? - Pokaż imiona graczy? - Mostrar nombres de los jugadores? - Zeigen Sie die Namen der Spieler? - Zobrazit jména hráčů? - Mostrar os nomes dos jogadores? - Afficher les noms des joueurs ? - Itt található az a játékos nevét? - Показать имена игроков? - Mostra i nomi dei giocatori? - プレイヤ名を表示しますか? - 플레이어 이름을 표시합니까? - 显示玩家名称? - 顯示玩家名稱? + Show player names + Pokaż imiona graczy + Mostrar nombres de los jugadores + Zeige einzelne Spielernamen + Zobrazit jména hráčů + Mostrar os nomes dos jogadores + Afficher les noms des joueurs + Itt található az a játékos nevét + Показать имена игроков + Mostra i nomi dei giocatori + プレイヤ名を表示しますか + 플레이어 이름을 표시합니까 + 显示玩家名称 + 顯示玩家名稱 Show individual player names? Pokaż poszczególne imiona graczy? Mostrar nombres de los jugadores individuales? - Zeigen einzelnen Spielernamen? + Zeigt die Namen der einzelnen Spieler an Zobrazit názvy jednotlivých hráčů? Mostrar nomes individuais dos jogadores? Affiche les noms des joueurs individuels ? Itt található az adott játékos neveket? Показать отдельные имена игроков? Mostra i nomi dei giocatori singoli? - プレイヤの名前を表示しますか? + プレイヤの名前を表示しますか? 각 플레이어의 이름을 표시합니까? 显示玩家的个别名称? 顯示玩家的個別名稱? @@ -347,8 +347,8 @@ Questo modulo permette il tracciamento di unità alleate con i marker BFT in mappa モジュールは BFT マップ マーカとともに、同勢力ユニットの追跡を許可します。 이 모듈은 아군을 지도상에서 추적할 수 있게 해줍니다. - 此模块将使你能在地图上看见友方单位的踪迹. - 此模塊將使你能在地圖上看見友方單位的蹤跡. + 此模块将使你能在地图上看见友方单位的踪迹 + 此模塊將使你能在地圖上看見友方單位的蹤跡 Flashlights @@ -420,7 +420,7 @@ Zvýšit jas Aumentar brillo Aumenta Luminosità - 感度を上げる + 明度を上げる 밝기 올리기 增加亮度 增加亮度 @@ -435,7 +435,7 @@ Snížit jas Reducir brillo Diminuisci Luminosità - 感度を下げる + 明度を下げる 밝기 내리기 降低亮度 降低亮度 @@ -521,8 +521,8 @@ Zawsze wyłączaj Blue Force Tracking dla tej grupy. Désactive en permanence le Blue Force Tracking pour ce groupe. Disabilita sempre il Blue Force Tracking per questo gruppo. - 对此小队永远关闭友军踪迹显示. - 對此小隊永遠關閉友軍蹤跡顯示. + 对此小队永远关闭友军踪迹显示 + 對此小隊永遠關閉友軍蹤跡顯示 diff --git a/addons/map_gestures/ACE_Settings.hpp b/addons/map_gestures/ACE_Settings.hpp index bb01592230..d74d58a1a5 100644 --- a/addons/map_gestures/ACE_Settings.hpp +++ b/addons/map_gestures/ACE_Settings.hpp @@ -12,6 +12,7 @@ class ACE_Settings { category = CSTRING(mapGestures_category); typeName = "SCALAR"; value = 7; + sliderSettings[] = {0, 50, 7, 1}; }; class GVAR(interval) { displayName = CSTRING(interval_displayName); @@ -19,6 +20,7 @@ class ACE_Settings { category = CSTRING(mapGestures_category); typeName = "SCALAR"; value = 0.03; + sliderSettings[] = {0, 1, 0.03, 2}; }; class GVAR(nameTextColor) { displayName = CSTRING(nameTextColor_displayName); diff --git a/addons/map_gestures/CfgVehicles.hpp b/addons/map_gestures/CfgVehicles.hpp index 0745c70a16..4823460971 100644 --- a/addons/map_gestures/CfgVehicles.hpp +++ b/addons/map_gestures/CfgVehicles.hpp @@ -1,11 +1,11 @@ class CfgVehicles { class ACE_Module; class GVAR(moduleSettings): ACE_Module { - scope = 2; + scope = 1; category = "ACE"; displayName = CSTRING(moduleSettings_displayName); function = QFUNC(moduleSettings); - isGlobal = 0; + isGlobal = 1; isSingular = 1; author = ECSTRING(common,ACETeam); icon = QPATHTOF(ui\icon_module_map_gestures_ca.paa); diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index 6e292ce75e..f49e1d4525 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -19,7 +19,7 @@ params ["_logic", "", "_activated"]; -if (!_activated || !isServer) exitWith {}; +if (!_activated) exitWith {}; [_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(maxRange), "maxRange"] call EFUNC(common,readSettingFromModule); @@ -30,14 +30,14 @@ private _defaultLeadColor = _logic getVariable ["defaultLeadColor", ""]; if (_defaultLeadColor != "") then { _defaultLeadColor = call compile ("[" + _defaultLeadColor + "]"); if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; - [QGVAR(defaultLeadColor), _defaultLeadColor, true, true] call EFUNC(common,setSetting); + ["CBA_settings_setSettingMission", [QGVAR(defaultLeadColor), _defaultLeadColor, true]] call CBA_fnc_localEvent; }; private _defaultColor = _logic getVariable ["defaultColor", ""]; if (_defaultColor != "") then { _defaultColor = call compile ("[" + _defaultColor + "]"); if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; - [QGVAR(defaultColor), _defaultColor, true, true] call EFUNC(common,setSetting); + ["CBA_settings_setSettingMission", [QGVAR(defaultColor), _defaultColor, true]] call CBA_fnc_localEvent; }; INFO("Map Gestures Module Initialized."); diff --git a/addons/map_gestures/functions/fnc_transmitterInit.sqf b/addons/map_gestures/functions/fnc_transmitterInit.sqf index 3c363d6f04..6a031e419b 100644 --- a/addons/map_gestures/functions/fnc_transmitterInit.sqf +++ b/addons/map_gestures/functions/fnc_transmitterInit.sqf @@ -45,9 +45,11 @@ if (!isNil QGVAR(MouseDownHandlerID)) then { GVAR(MouseDownHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseButtonDown", { if (!GVAR(enabled)) exitWith {}; - params ["", "_button"]; + params ["", "_button", "_x", "_y", "_shift", "_ctrl", "_alt"]; - if (_button == 0) then {call FUNC(initTransmit);}; + if (_button == 0 && {[_shift, _ctrl, _alt] isEqualTo [false, false, false]}) then { + call FUNC(initTransmit); + }; }]; // MouseUp EH @@ -60,5 +62,7 @@ GVAR(MouseUpHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseButtonUp", { params ["", "_button"]; - if (_button == 0) then {call FUNC(endTransmit);}; + if (_button == 0) then { + call FUNC(endTransmit); + }; }]; diff --git a/addons/map_gestures/stringtable.xml b/addons/map_gestures/stringtable.xml index feebdb7a08..2bcc1ca4bd 100644 --- a/addons/map_gestures/stringtable.xml +++ b/addons/map_gestures/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -87,8 +87,8 @@ Couleur par défaut pour les chefs de groupe quand il n'y a pas de réglage pour le groupe. (Module : laisser vide pour ne pas forcer chez les clients) グループ設定が存在しない場合に、グループ リーダーへ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] 그룹 설정이 없는 경우 리더의 예비 색상 값입니다. [모듈: 클라이언트에서 강체치 않기 위해 공백으로 비워둘것] - 当没有设定小队颜色时, 此功能会定义队长的指示器颜色. [模块: 此栏留空来保持预设颜色] - 當沒有設定小隊顏色時, 此功能會定義隊長的指示器顏色. [模塊: 此欄留空來保持預設顏色] + 当没有设定小队颜色时,此功能会定义队长的指示器颜色。[模块: 此栏留空来保持预设颜色] + 當沒有設定小隊顏色時,此功能會定義隊長的指示器顏色。[模塊: 此欄留空來保持預設顏色] Default Color @@ -116,8 +116,8 @@ Couleur par défaut quand il n'y a pas de réglage pour le groupe. (Module : laisser vide pour ne pas forcer chez les clients) グループ設定が存在しない場合に、グループ リーダーへ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] 그룹 설정이 없을 경우의 예비 색상입니다. [모듈: 클라이언트에서 강체치 않기 위해 공백으로 비워둘것] - 当没有设定小队颜色时, 此功能会定义玩家的指示器颜色. [模块: 此栏留空来保持预设颜色] - 當沒有設定小隊顏色時, 此功能會定義玩家的指示器顏色. [模塊: 此欄留空來保持預設顏色] + 当没有设定小队颜色时,此功能会定义玩家的指示器颜色。[模块: 此栏留空来保持预设颜色] + 當沒有設定小隊顏色時,此功能會定義玩家的指示器顏色。[模塊: 此欄留空來保持預設顏色] Lead Color @@ -145,8 +145,8 @@ Couleur pour les chefs de groupe des groupes synchronisés avec le module. モジュールで同期されたグループのリーダー用に色の値を決定します。 그룹이 이 모듈에 동기화 됐을때의 리더 색상입니다. - 改变与此同步小队队长的指示器颜色. - 改變與此同步小隊隊長的指示器顏色. + 改变与此同步小队队长的指示器颜色。 + 改變與此同步小隊隊長的指示器顏色。 Color @@ -263,8 +263,8 @@ Couleur des tags de nom à côté de marqueur de pointage sur carte. マップ ジェスチャに表示される、名前の色を決定します。 지도 색상에 표시되는 이름의 색상을 결정합니다. - 定义名称文字颜色. 使其与地图指示器颜色有所区别. - 定義名稱文字顏色. 使其與地圖指示器顏色有所區別. + 定义名称文字颜色。使其与地图指示器颜色有所区别。 + 定義名稱文字顏色。使其與地圖指示器顏色有所區別。 Map Gestures diff --git a/addons/maptools/ACE_Settings.hpp b/addons/maptools/ACE_Settings.hpp index cb2d98e1ce..c0642ed4e7 100644 --- a/addons/maptools/ACE_Settings.hpp +++ b/addons/maptools/ACE_Settings.hpp @@ -1,5 +1,6 @@ class ACE_Settings { class GVAR(rotateModifierKey) { + category = CSTRING(Name); value = 1; typeName = "SCALAR"; isClientSettable = 1; @@ -7,11 +8,12 @@ class ACE_Settings { description = CSTRING(rotateModifierKey_description); values[] = {"$STR_A3_OPTIONS_DISABLED", "ALT", "CTRL", "SHIFT"}; }; - class GVAR(drawStaightLines) { + class GVAR(drawStraightLines) { + category = CSTRING(Name); value = 1; typeName = "BOOL"; isClientSettable = 1; - displayName = CSTRING(drawStaightLines_displayName); - description = CSTRING(drawStaightLines_description); + displayName = CSTRING(drawStraightLines_displayName); + description = CSTRING(drawStraightLines_description); }; }; diff --git a/addons/maptools/CfgWeapons.hpp b/addons/maptools/CfgWeapons.hpp index dc7a7046dd..31d8bc491e 100644 --- a/addons/maptools/CfgWeapons.hpp +++ b/addons/maptools/CfgWeapons.hpp @@ -1,14 +1,15 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_MapTools: ACE_ItemCore { displayName = CSTRING(Name); + author = ECSTRING(common,ACETeam); descriptionShort = CSTRING(Description); model = QPATHTOF(data\ace_MapTools.p3d); picture = QPATHTOF(UI\maptool_item.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; diff --git a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf index ba9363c68f..ef354f0798 100644 --- a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf +++ b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -if (!GVAR(drawStaightLines)) exitWith {}; +if (!GVAR(drawStraightLines)) exitWith {}; params ["_theMap", "_roamerWidth"]; GVAR(mapTool_pos) params ["_roamerPosX", "_roamerPosY"]; diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index 20397d70eb..c467da5f2a 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -201,7 +201,7 @@ 修改旋转地图工具的按键 修改旋轉地圖工具的按鍵 - + Draw straight lines with maptools マップ ツールを使って直線を書く Zeichne gerade Linien mit dem Kartenwerkzeug @@ -212,7 +212,7 @@ 使用地图工具来绘制直线 使用地圖工具來繪製直線 - + Draw on the edge of maptools to draw straight lines. Note: Must hover at midpoint to delete. マップ ツールの端から直線を書きます。メモ:線の中央ホバーすると削除します。 Zeichne gerade Linien am Rand des Kartenwerkzeugs. Hinweis: zum Löschen über den Mittelpunkt der Linie fahren @@ -220,8 +220,8 @@ Przeciągnij po krawędzi narzędzi nawigacyjnych by narysować prostą linię. Uwaga: aby usunąć linię - nalezy ustawić kursor nad jej środkiem. Utiliser le bord des outils de navigation pour tracer des lignes droites. Note: l'on doit survoler le milieu du trait pour pouvoir le supprimer. Disegna sul bordo degli strumenti di mappatura per disegnare linee dritte. Nota: Deve spostarsi al centro per essere cancellato. - 使用地图工具的边缘来绘制直线. 备注: 要删除直线时, 请把滑鼠移动到该线条的中央即可删除该线. - 使用地圖工具的邊緣來繪製直線. 備註: 要刪除直線時, 請把滑鼠移動到該線條的中央即可刪除該線. + 使用地图工具的边缘来绘制直线。备注: 要删除直线时,请把滑鼠移动到该线条的中央即可删除该线。 + 使用地圖工具的邊緣來繪製直線。備註: 要刪除直線時,請把滑鼠移動到該線條的中央即可刪除該線。 diff --git a/addons/markers/ACE_Settings.hpp b/addons/markers/ACE_Settings.hpp new file mode 100644 index 0000000000..d8d72a5975 --- /dev/null +++ b/addons/markers/ACE_Settings.hpp @@ -0,0 +1,8 @@ +class ACE_Settings { + class GVAR(movableMarkersEnabled) { + movedToSQF = 1; + }; + class GVAR(moveRestriction) { + movedToSQF = 1; + }; +}; diff --git a/addons/markers/CfgVehicles.hpp b/addons/markers/CfgVehicles.hpp new file mode 100644 index 0000000000..61a6827491 --- /dev/null +++ b/addons/markers/CfgVehicles.hpp @@ -0,0 +1,9 @@ +class CfgVehicles { + class ACE_Module; + class ACE_ModuleMarkers: ACE_Module { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Module_DisplayName); + scope = 1; + icon = QPATHTOF(UI\Icon_Module_Markers_ca.paa); + }; +}; diff --git a/addons/markers/UI/Icon_Module_Markers_ca.paa b/addons/markers/UI/Icon_Module_Markers_ca.paa new file mode 100644 index 0000000000..8c9e41e0ca Binary files /dev/null and b/addons/markers/UI/Icon_Module_Markers_ca.paa differ diff --git a/addons/markers/XEH_PREP.hpp b/addons/markers/XEH_PREP.hpp index c6ad5c6ba2..bbac954b66 100644 --- a/addons/markers/XEH_PREP.hpp +++ b/addons/markers/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(getEnabledChannels); PREP(initInsertMarker); PREP(mapDisplayInitEH); @@ -11,3 +10,7 @@ PREP(placeMarker); PREP(sendMarkersJIP); PREP(setMarkerJIP); PREP(setMarkerNetwork); +PREP(canMove); +PREP(onMouseButtonDown); +PREP(onMouseButtonUp); +PREP(movePFH); diff --git a/addons/markers/XEH_postInit.sqf b/addons/markers/XEH_postInit.sqf index 6e1af95a50..ad0c2dfde3 100644 --- a/addons/markers/XEH_postInit.sqf +++ b/addons/markers/XEH_postInit.sqf @@ -9,8 +9,7 @@ // request marker data for JIP if (isMultiplayer && {!isServer} && {hasInterface}) then { - GVAR(localLogic) = (createGroup sideLogic) createUnit ["Logic", [0,0,0], [], 0, "NONE"]; - [QGVAR(sendMarkersJIP), [GVAR(localLogic)]] call CBA_fnc_serverEvent; + [QGVAR(sendMarkersJIP), CBA_clientID] call CBA_fnc_serverEvent; }; GVAR(mapDisplaysWithDrawEHs) = []; @@ -18,3 +17,21 @@ GVAR(currentMarkerPosition) = []; GVAR(currentMarkerAngle) = 0; GVAR(currentMarkerColorConfigName) = ""; GVAR(currentMarkerConfigName) = ""; + +// set marker pos local on every machine (prevent markers visible for everyone) +[QGVAR(setMarkerPosLocal), { + params ["_marker", "_pos"]; + _marker setMarkerPosLocal _pos; + + // handle JIP + if (isServer) then { + private _index = (GETGVAR(allMapMarkers,[])) find _marker; // case-sensitive, but should be fine + + if (_index < 0) exitWith { + ERROR_1("Could not find data for %1", _marker); + }; + + private _data = GVAR(allMapMarkersProperties) select _index; + _data set [2, _pos]; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/markers/XEH_preInit.sqf b/addons/markers/XEH_preInit.sqf index 7ee91d67e5..abf28d6e8b 100644 --- a/addons/markers/XEH_preInit.sqf +++ b/addons/markers/XEH_preInit.sqf @@ -6,6 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.sqf" + // init marker types if (isNil QGVAR(MarkersCache)) then { GVAR(MarkersCache) = []; diff --git a/addons/markers/config.cpp b/addons/markers/config.cpp index 1a8c310735..1881183ac1 100644 --- a/addons/markers/config.cpp +++ b/addons/markers/config.cpp @@ -15,4 +15,7 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "ACE_Settings.hpp" +#include "CfgVehicles.hpp" + #include "InsertMarker.hpp" diff --git a/addons/markers/functions/fnc_canMove.sqf b/addons/markers/functions/fnc_canMove.sqf new file mode 100644 index 0000000000..c97aafe07a --- /dev/null +++ b/addons/markers/functions/fnc_canMove.sqf @@ -0,0 +1,29 @@ +/* + * Author: chris579 + * Checks whether the player can move markers. + * + * Arguments: + * None + * + * Return Value: + * Whether the player can move markers + * + * Example: + * [] call ace_markers_fnc_canMove + * + * Public: No + */ +#include "script_component.hpp" + +switch (GVAR(moveRestriction)) do { + case MOVE_RESTRICTION_NOBODY: {false}; + case MOVE_RESTRICTION_ALL: {true}; + case MOVE_RESTRICTION_ADMINS: {IS_ADMIN}; + case MOVE_RESTRICTION_GROUP_LEADERS: { + leader ACE_player == ACE_player + }; + case MOVE_RESTRICTION_GROUP_LEADERS_ADMINS: { + (leader ACE_player == ACE_player) || IS_ADMIN + }; + default {true}; +}; // return diff --git a/addons/markers/functions/fnc_mapDisplayInitEH.sqf b/addons/markers/functions/fnc_mapDisplayInitEH.sqf index 662f6f80c0..4a740f0424 100644 --- a/addons/markers/functions/fnc_mapDisplayInitEH.sqf +++ b/addons/markers/functions/fnc_mapDisplayInitEH.sqf @@ -15,8 +15,6 @@ */ #include "script_component.hpp" -disableSerialization; - params ["_display"]; TRACE_1("params",_display); @@ -32,3 +30,8 @@ private _curSelColor = missionNamespace getVariable [QGVAR(curSelMarkerColor), 0 TRACE_2("color",_bisColorLB,_curSelColor); _bisColorLB ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(onLBSelChangedColor)}]; _bisColorLB lbSetCurSel _curSelColor; + +// movable markers +private _ctrlMap = _display displayCtrl 51; +_ctrlMap ctrlAddEventHandler ["MouseButtonDown", {_this call FUNC(onMouseButtonDown)}]; +_ctrlMap ctrlAddEventHandler ["MouseButtonUp", {_this call FUNC(onMouseButtonUp)}]; diff --git a/addons/markers/functions/fnc_movePFH.sqf b/addons/markers/functions/fnc_movePFH.sqf new file mode 100644 index 0000000000..6167b820af --- /dev/null +++ b/addons/markers/functions/fnc_movePFH.sqf @@ -0,0 +1,36 @@ +/* + * Author: chris579 + * When the marker is being moved. + * + * Arguments: + * 0: Marker data + * 1: PFH ID + * + * Return Value: + * None + * + * Example: + * [[MARKER], 5] call ace_markers_fnc_movePFH + * + * Public: No + */ +#include "script_component.hpp" + +(_this select 0) params ["_marker", "_ctrlMap", "_originalPos", "_originalAlpha"]; + +if (isNull _ctrlMap || !GVAR(moving)) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + private _finalPos = getMarkerPos _marker; + + if !([QGVAR(markerMoveEnded), [ACE_player, _marker, _originalPos, _finalPos]] call CBA_fnc_localEvent) then { + _marker setMarkerPosLocal _originalPos; + } else { + [QGVAR(setMarkerPosLocal), [_marker, _finalPos]] call CBA_fnc_globalEvent; + }; + + _marker setMarkerAlphaLocal _originalAlpha; + _ctrlMap ctrlMapCursor ["Track", "Track"]; +}; + +_marker setMarkerPosLocal (_ctrlMap posScreenToWorld getMousePosition); diff --git a/addons/markers/functions/fnc_onMouseButtonDown.sqf b/addons/markers/functions/fnc_onMouseButtonDown.sqf new file mode 100644 index 0000000000..dee5cab7ed --- /dev/null +++ b/addons/markers/functions/fnc_onMouseButtonDown.sqf @@ -0,0 +1,41 @@ +/* + * Author: chris579 + * Triggered when a mouse button is pressed on the map. + * + * Arguments: + * 0: Map Control the EVH was assigned to + * 1: Button code + * 2: Position of x + * 3: Position of y + * 4: State of Shift + * 5: State of Ctrl + * 6: State of Alt + * + * Return Value: + * None + * + * Example: + * [CONTROL, 2, 0, 0, true, false, false] call ace_markers_fnc_onMouseButtonDown + * + * Public: No + */ +#include "script_component.hpp" + +params ["_ctrlMap", "_button", "_x", "_y", "_shift", "_ctrl", "_alt"]; + +if (_button != 0 || {!([_shift, _ctrl, _alt] isEqualTo [false, false, true])}) exitWith {}; + +ctrlMapMouseOver _ctrlMap params [["_type", ""], "_marker"]; + +if (_type == "marker" && {_marker find "_USER_DEFINED" != -1 && {call FUNC(canMove)}}) then { + _ctrlMap ctrlMapCursor ["Track", "Move"]; + + private _originalPos = getMarkerPos _marker; + private _originalAlpha = markerAlpha _marker; + + if !([QGVAR(markerMoveStarted), [ACE_player, _marker, _originalPos]] call CBA_fnc_localEvent) exitWith {}; + + GVAR(moving) = true; + _marker setMarkerAlphaLocal 0.5; + [FUNC(movePFH), 0, [_marker, _ctrlMap, _originalPos, _originalAlpha]] call CBA_fnc_addPerFrameHandler; +}; diff --git a/addons/markers/functions/fnc_onMouseButtonUp.sqf b/addons/markers/functions/fnc_onMouseButtonUp.sqf new file mode 100644 index 0000000000..62b4cd5af7 --- /dev/null +++ b/addons/markers/functions/fnc_onMouseButtonUp.sqf @@ -0,0 +1,26 @@ +/* + * Author: chris579 + * Triggered when a mouse button is released on the map. + * + * Arguments: + * 0: Map Control the evh was assigned to + * 1: Button code + * 2: Position of x + * 3: Position of y + * 4: State of Shift + * 5: State of Ctrl + * 6: State of Alt + * + * Return Value: + * None + * + * Example: + * [CONTROL, 2] call ace_markers_fnc_onMouseButtonUp + * + * Public: No + */ +#include "script_component.hpp" + +params ["_ctrlMap", "_button", "_x", "_y", "_shift", "_ctrl", "_alt"]; + +GVAR(moving) = false; diff --git a/addons/markers/functions/fnc_sendMarkersJIP.sqf b/addons/markers/functions/fnc_sendMarkersJIP.sqf index e63a32b843..1eee39560c 100644 --- a/addons/markers/functions/fnc_sendMarkersJIP.sqf +++ b/addons/markers/functions/fnc_sendMarkersJIP.sqf @@ -15,11 +15,11 @@ */ #include "script_component.hpp" -params ["_logic"]; -TRACE_1("params",_logic); +params ["_owner"]; +TRACE_1("params",_owner); [ QGVAR(setMarkerJIP), [GETGVAR(allMapMarkers,[]), GETGVAR(allMapMarkersProperties,[])], - [_logic] -] call CBA_fnc_targetEvent; + _owner +] call CBA_fnc_ownerEvent; diff --git a/addons/markers/functions/fnc_setMarkerJIP.sqf b/addons/markers/functions/fnc_setMarkerJIP.sqf index ccac7d2b7b..1acd758556 100644 --- a/addons/markers/functions/fnc_setMarkerJIP.sqf +++ b/addons/markers/functions/fnc_setMarkerJIP.sqf @@ -50,8 +50,3 @@ TRACE_3("params",_allMapMarkers,_allMapMarkersProperties); }; false } count allMapMarkers; - -private _group = group GVAR(localLogic); -deleteVehicle GVAR(localLogic); -GVAR(localLogic) = nil; -deleteGroup _group; diff --git a/addons/markers/initSettings.sqf b/addons/markers/initSettings.sqf new file mode 100644 index 0000000000..d317d663ea --- /dev/null +++ b/addons/markers/initSettings.sqf @@ -0,0 +1,22 @@ +[ + QGVAR(moveRestriction), "LIST", + [LSTRING(MoveRestriction), LSTRING(MoveRestriction_Description)], + format ["ACE %1", localize ELSTRING(map,Module_DisplayName)], + [ + [ + MOVE_RESTRICTION_NOBODY, + MOVE_RESTRICTION_ALL, + MOVE_RESTRICTION_ADMINS, + MOVE_RESTRICTION_GROUP_LEADERS, + MOVE_RESTRICTION_GROUP_LEADERS_ADMINS + ], + [ + LSTRING(MoveRestriction_Nobody), + LSTRING(MoveRestriction_All), + LSTRING(MoveRestriction_Admins), + LSTRING(MoveRestriction_GroupLeaders), + LSTRING(MoveRestriction_GroupLeadersAndAdmins) + ], + 1 + ] +] call cba_settings_fnc_init; diff --git a/addons/markers/script_component.hpp b/addons/markers/script_component.hpp index 80256466e9..c081cbcc39 100644 --- a/addons/markers/script_component.hpp +++ b/addons/markers/script_component.hpp @@ -24,3 +24,9 @@ localize "str_channel_vehicle", \ localize "str_channel_direct" \ ] + +#define MOVE_RESTRICTION_NOBODY -1 +#define MOVE_RESTRICTION_ALL 0 +#define MOVE_RESTRICTION_ADMINS 1 +#define MOVE_RESTRICTION_GROUP_LEADERS 2 +#define MOVE_RESTRICTION_GROUP_LEADERS_ADMINS 3 diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index 1c87546a5e..b23462ba46 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,10 +12,73 @@ Irány: %1° Direzione: %1° Direção %1 - 方位:%1° + 方位: %1° 방위: %1° 方位: %1° 方位: %1° + + Markers + Markierungen + マーカー + Marcatori + 標誌 + 标志 + 맵마커 + + + Allow moving markers for + Erlaube Marker zu bewegen für + 次ユーザーにマーカー移動を許可 + 마커 이동 허가 + + + Restricts which players are able to move markers while holding the Alt key. + Beschränkt welche Spieler Marker mit gedrückter Alt-Taste bewegen können. + どのプレイヤーが Alt キーを押しながらマーカー移動をさせられるか制限できます。 + Alt 키를 누른 상태에서 마커를 움직일 수있는 플레이어를 제한합니다. + + + Nobody + Niemand + 不許可 + 비활성 + + + All players + Alle Spieler + 全プレイヤー + Tutti i giocatori + 所有玩家 + 所有玩家 + 모든 플레이어 + + + Admins + Admins + 管理者 + Amministratori + 管理員 + 管理员 + 관리자 + + + Group leaders + Gruppenführer + グループ リーダー + Capigruppo + 小隊長 + 小队长 + 분대장 + + + Group leaders and Admins + Gruppenführer und Admins + グループ リーダーと管理者 + Capigruppo e Amministratori + 小隊長與管理員 + 小队长与管理员 + 분대장과 관리자 + diff --git a/addons/maverick/$PBOPREFIX$ b/addons/maverick/$PBOPREFIX$ new file mode 100644 index 0000000000..78ffc29019 --- /dev/null +++ b/addons/maverick/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\maverick \ No newline at end of file diff --git a/addons/maverick/ACE_GuidanceConfig.hpp b/addons/maverick/ACE_GuidanceConfig.hpp new file mode 100644 index 0000000000..f6b9020157 --- /dev/null +++ b/addons/maverick/ACE_GuidanceConfig.hpp @@ -0,0 +1,7 @@ +class EGVAR(missileguidance,AttackProfiles) { + class maverick { + name = "LOAL-DIR"; + nameLocked = "LOBL-DIR"; + functionName = QEFUNC(missileguidance,attackProfile_DIR); + }; +}; diff --git a/addons/maverick/CfgAmmo.hpp b/addons/maverick/CfgAmmo.hpp new file mode 100644 index 0000000000..27d96d7573 --- /dev/null +++ b/addons/maverick/CfgAmmo.hpp @@ -0,0 +1,75 @@ +class CfgAmmo { + class MissileCore; + class MissileBase : MissileCore { + class Components; + }; + class Missile_AGM_02_F : MissileBase {}; + + class GVAR(L) : Missile_AGM_02_F { + author = "xrufix"; + autoSeekTarget = 0; + irLock = 0; + laserLock = 0; + manualControl = 0; + missileLockMaxDistance = 16000; + weaponLockSystem = 4; + class ace_missileguidance { + enabled = 1; + + minDeflection = 0.0005; + maxDeflection = 0.01; + incDeflection = 0.005; + + canVanillaLock = 0; + + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL","LOBL"}; + + seekLastTargetPos = 1; + seekerAngle = 60; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 16000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; + }; + }; + + class Missile_AGM_01_F: Missile_AGM_02_F {}; + class ace_kh25ml: Missile_AGM_01_F { + author = "xrufix"; + irLock = 0; + missileLockMaxDistance = 10000; + weaponLockSystem = 4; + class ace_missileguidance { + enabled = 1; + + minDeflection = 0.0005; + maxDeflection = 0.01; + incDeflection = 0.005; + + canVanillaLock = 0; + + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL"}; + + seekLastTargetPos = 1; + seekerAngle = 40; + seekerAccuracy = 1; + + seekerMinRange = 1; + seekerMaxRange = 10000; + + defaultAttackProfile = "maverick"; + attackProfiles[] = {"maverick"}; + }; + }; +}; diff --git a/addons/maverick/CfgMagazines.hpp b/addons/maverick/CfgMagazines.hpp new file mode 100644 index 0000000000..3254f605c0 --- /dev/null +++ b/addons/maverick/CfgMagazines.hpp @@ -0,0 +1,113 @@ +class CfgMagazines { + class CA_Magazine; + class VehicleMagazine : CA_Magazine {}; + + class magazine_Missile_AGM_02_x1 : VehicleMagazine {}; + class PylonMissile_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 {}; + class PylonMissile_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 {}; + + class 6Rnd_Missile_AGM_02_F : VehicleMagazine {}; + class PylonRack_1Rnd_Missile_AGM_02_F : 6Rnd_Missile_AGM_02_F {}; + class PylonRack_3Rnd_Missile_AGM_02_F : PylonRack_1Rnd_Missile_AGM_02_F{}; + + class PylonRack_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 {}; + class PylonRack_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 {}; + + class GVAR(L_magazine_x1) : magazine_Missile_AGM_02_x1 { + ammo = QGVAR(L); + author = "xrufix"; + descriptionShort = CSTRING(L_MAG_DESCR); + displayName = CSTRING(L_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + }; + + class GVAR(L_pylonmissile_x1) : PylonMissile_Missile_AGM_02_x1 { + ammo = QGVAR(L); + author = "xrufix"; + descriptionShort = CSTRING(L_MAG_DESCR); + displayName = CSTRING(L_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = QGVAR(L_Launcher); + }; + class GVAR(L_pylonmissile_x2) : PylonMissile_Missile_AGM_02_x2 { + ammo = QGVAR(L); + author = "xrufix"; + descriptionShort = CSTRING(L_MAG_DESCR); + displayName = CSTRING(L_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = QGVAR(L_Launcher); + }; + + class GVAR(L_pylonRack_1Rnd) : PylonRack_1Rnd_Missile_AGM_02_F { + ammo = QGVAR(L); + author = "xrufix"; + descriptionShort = CSTRING(L_MAG_DESCR); + displayName = CSTRING(L_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = QGVAR(L_Launcher_Plane); + }; + class GVAR(L_PylonRack_3Rnd) : PylonRack_3Rnd_Missile_AGM_02_F { + ammo = QGVAR(L); + author = "xrufix"; + descriptionShort = CSTRING(L_MAG_DESCR); + displayName = CSTRING(L_MAG_x3); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = QGVAR(L_Launcher_Plane); + }; + + class GVAR(L_PylonRack_x1) : PylonRack_Missile_AGM_02_x1 { + ammo = QGVAR(L); + author = "xrufix"; + descriptionShort = CSTRING(L_MAG_DESCR); + displayName = CSTRING(L_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = QGVAR(L_Launcher); + }; + class GVAR(L_PylonRack_x2) : PylonRack_Missile_AGM_02_x2 { + ammo = QGVAR(L); + author = "xrufix"; + descriptionShort = CSTRING(L_MAG_DESCR); + displayName = CSTRING(L_MAG_x2); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = QGVAR(L_Launcher); + }; + + // KH-25 + class 4Rnd_Missile_AGM_01_F; + class PylonRack_1Rnd_Missile_AGM_01_F : 4Rnd_Missile_AGM_01_F {}; + class magazine_Missile_AGM_KH25_x1 : VehicleMagazine {}; + class PylonMissile_Missile_AGM_KH25_x1 : magazine_Missile_AGM_KH25_x1 {}; + class PylonMissile_Missile_AGM_KH25_INT_x1 : PylonMissile_Missile_AGM_KH25_x1 {}; + + class ace_kh25ml_pylonrack_x1 : PylonRack_1Rnd_Missile_AGM_01_F { + ammo = "ace_kh25ml"; + author = "xrufix"; + descriptionShort = CSTRING(KH25ML_MAG_DESCR); + displayName = CSTRING(KH25ML_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = "ace_kh25ml_launcher"; + }; + class ace_kh25ml_magazine_x1 : magazine_Missile_AGM_KH25_x1 { + ammo = "ace_kh25ml"; + author = "xrufix"; + descriptionShort = CSTRING(KH25ML_MAG_DESCR); + displayName = CSTRING(KH25ML_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + }; + class ace_kh25ml_pylonmissile_x1 : PylonMissile_Missile_AGM_KH25_x1 { + ammo = "ace_kh25ml"; + author = "xrufix"; + descriptionShort = CSTRING(KH25ML_MAG_DESCR); + displayName = CSTRING(KH25ML_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = "ace_kh25ml_launcher"; + }; + class ace_kh25ml_pylonmissile_int_x1 : PylonMissile_Missile_AGM_KH25_INT_x1 { + ammo = "ace_kh25ml"; + author = "xrufix"; + descriptionShort = CSTRING(KH25ML_MAG_DESCR); + displayName = CSTRING(KH25ML_MAG_x1); + displayNameShort = CSTRING(L_MAG_short); + pylonWeapon = "ace_kh25ml_launcher"; + }; +}; diff --git a/addons/maverick/CfgWeapons.hpp b/addons/maverick/CfgWeapons.hpp new file mode 100644 index 0000000000..c3157f34dd --- /dev/null +++ b/addons/maverick/CfgWeapons.hpp @@ -0,0 +1,66 @@ +class CfgWeapons { + class LauncherCore; + class RocketPods : LauncherCore {}; + class weapon_AGM_65Launcher : RocketPods{}; + + class MissileLauncher : LauncherCore {}; + class Missile_AGM_02_Plane_CAS_01_F : MissileLauncher {}; + + class GVAR(L_Launcher) : weapon_AGM_65Launcher { + author = "xrufix"; + displayname = CSTRING(L); + magazines[] = { + QGVAR(L_magazine_x1), + QGVAR(L_pylonmissile_x1), + QGVAR(L_pylonmissile_x2), + QGVAR(L_pylonRack_1Rnd), + QGVAR(L_PylonRack_3Rnd), + QGVAR(L_PylonRack_x1), + QGVAR(L_PylonRack_x2) + }; + weaponLockDelay = 0.1; + weaponLockSystem = 0; + + EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) + EGVAR(laser,showHud) = 1; // show attack profile / lock on hud + GVAR(enabled) = 1; + }; + + class GVAR(L_Launcher_Plane) : Missile_AGM_02_Plane_CAS_01_F { + author = "xrufix"; + displayname = CSTRING(L); + magazines[] = { + QGVAR(L_magazine_x1), + QGVAR(L_pylonmissile_x1), + QGVAR(L_pylonmissile_x2), + QGVAR(L_pylonRack_1Rnd), + QGVAR(L_PylonRack_3Rnd), + QGVAR(L_PylonRack_x1), + QGVAR(L_PylonRack_x2) + }; + weaponLockDelay = 0.1; + weaponLockSystem = 0; + + EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) + EGVAR(laser,showHud) = 1; // show attack profile / lock on hud + GVAR(enabled) = 1; + }; + + class weapon_AGM_KH25Launcher : MissileLauncher {}; + class ace_kh25ml_launcher : weapon_AGM_KH25Launcher { + author = "xrufix"; + displayName = CSTRING(KH25ML); + magazines[] = { + "ace_kh25ml_pylonrack_x1", + "ace_kh25ml_magazine_x1", + "ace_kh25ml_pylonmissile_x1", + "ace_kh25ml_pylonmissile_int_x1" + }; + weaponLockDelay = 0.1; + weaponLockSystem = 0; + + EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code) + EGVAR(laser,showHud) = 1; // show attack profile / lock on hud + GVAR(enabled) = 1; + }; +}; diff --git a/addons/maverick/README.md b/addons/maverick/README.md new file mode 100644 index 0000000000..a931a2bc08 --- /dev/null +++ b/addons/maverick/README.md @@ -0,0 +1,17 @@ +ace_maverick +========== + +Adds pylon magazines with laser guided AGM-65 Maverick L and KH25ML. + +* The Mavericks can be added to every plane the vanilla Macer II can be added to. +* The KH25ML can be added to every plane the vanilla KH25 and Sharur missiles can be added to. +* The missile uses laser guidance based on ACE's Advanced Missile Guidance framework. +* The PylonWeapon is added to planes with pylons automatically. + +![Laser guided Maverick](https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/US_Navy_041128-N-5345W-016_Aviation_Ordnanceman_3rd_Class_William_Miller_arms_a_AGM-65_Maverick_laser-guided_missile.jpg/1280px-US_Navy_041128-N-5345W-016_Aviation_Ordnanceman_3rd_Class_William_Miller_arms_a_AGM-65_Maverick_laser-guided_missile.jpg) + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [xrufix](https://github.com/xrufix) diff --git a/addons/maverick/config.cpp b/addons/maverick/config.cpp new file mode 100644 index 0000000000..dbfabf7f9d --- /dev/null +++ b/addons/maverick/config.cpp @@ -0,0 +1,43 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"xrufix"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + ammo[] = { + GVAR(L), + "ace_kh25ml" + }; + magazines[] = { + QGVAR(L_magazine_x1), + QGVAR(L_pylonmissile_x1), + QGVAR(L_pylonmissile_x2), + QGVAR(L_pylonRack_1Rnd), + QGVAR(L_PylonRack_3Rnd), + QGVAR(L_PylonRack_x1), + QGVAR(L_PylonRack_x2), + "ace_kh25ml_magazine_x1", + "ace_kh25ml_pylonmissile_x1", + "ace_kh25ml_pylonmissile_int_x1" + }; + weapons[] = { + GVAR(L_Launcher_Plane), + GVAR(L_Launcher), + "ace_kh25ml_launcher" + }; + units[] = {}; + }; +}; + + +class SensorTemplateLaser; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "ACE_GuidanceConfig.hpp" diff --git a/addons/maverick/script_component.hpp b/addons/maverick/script_component.hpp new file mode 100644 index 0000000000..ff396b7cbf --- /dev/null +++ b/addons/maverick/script_component.hpp @@ -0,0 +1,17 @@ +#define COMPONENT maverick +#define COMPONENT_BEAUTIFIED Maverick +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_MAIN + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_MAIN + #define DEBUG_SETTINGS DEBUG_SETTINGS_MAIN +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/maverick/stringtable.xml b/addons/maverick/stringtable.xml new file mode 100644 index 0000000000..5233f7bf2f --- /dev/null +++ b/addons/maverick/stringtable.xml @@ -0,0 +1,80 @@ + + + + + + AGM-65 Maverick L, Laser Guided Anti-Ground-Missile + AGM-65 Maverick L, lasergelenkte Luft-Boden-Rakete + AGM-65 Maverick L, Guida Laser Missile-Anti-Terra + AGM-65 マーベリック L、レーザー誘導対地ミサイル + AGM-65"小牛"飛彈L型,雷射導引對地導彈 + AGM-65"小牛"飞弹L型,雷射导引对地导弹 + AGM-65 Maverick L, 레이저 유도 대지 미사일 + + + AGM-65 Maverick L [ACE] + AGM-65 Maverick L [ACE] + AGM-65 Maverick L [ACE] + AGM-65 マーベリック L [ACE] + AGM-65"小牛"飛彈L型 [ACE] + AGM-65"小牛"飞弹L型 [ACE] + AGM-65 Maverick L [ACE] + + + 2x AGM-65 Maverick L [ACE] + 2x AGM-65 Maverick L [ACE] + 2x AGM-65 Maverick L [ACE] + 2x AGM-65 マーベリック L [ACE] + 2x AGM-65"小牛"飛彈L型 [ACE] + 2x AGM-65"小牛"飞弹L型 [ACE] + 2x AGM-65 Maverick L [ACE] + + + 3x AGM-65 Maverick L [ACE] + 3x AGM-65 Maverick L [ACE] + 3x AGM-65 Maverick L [ACE] + 3x AGM-65 マーベリック L [ACE] + 3x AGM-65"小牛"飛彈L型 [ACE] + 3x AGM-65"小牛"飞弹L型 [ACE] + 3x AGM-65 Maverick L [ACE] + + + Laser Guided + Lasergelenkt + Guida Laser + レーザー誘導 + 雷射導引 + 雷射导引 + 레이저 유도 + + + Kh-25ML, Laser Guided Air-to-Ground-Missile + Ch-25ML, Lasergelenkte Luft-Boden-Rakete + Kh-25ML, 레이저 유도 대공 미사일 + + + 1x Kh-25ML [ACE] + 1x Ch-25ML [ACE] + 1x Х-25МЛ [ACE] + 1x Kh-25ML [ACE] + + + + + AGM-65 Maverick L + AGM-65 Maverick L + AGM-65 Maverick L + AGM-65 マーベリック L + AGM-65"小牛"飛彈L型 + AGM-65"小牛"飞弹L型 + AGM-65 Maverick L + + + Kh-25ML + Ch-25ML + Х-25МЛ + Kh-25ML + + + + diff --git a/addons/medical/ACE_Medical_SelfActions.hpp b/addons/medical/ACE_Medical_SelfActions.hpp index fca025adcb..bf3fbe775f 100644 --- a/addons/medical/ACE_Medical_SelfActions.hpp +++ b/addons/medical/ACE_Medical_SelfActions.hpp @@ -1,7 +1,7 @@ class Medical { displayName = CSTRING(Actions_Medical); runOnHover = 1; - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE([ARR_3(_target, true, 0)] call DFUNC(displayPatientInformation)); condition = "true"; icon = QPATHTOF(UI\icons\medical_cross.paa); @@ -9,7 +9,7 @@ class Medical { class ACE_Head { displayName = CSTRING(Head); icon = QPATHTOF(UI\icons\medical_cross.paa); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE([ARR_3(_target, true, 0)] call DFUNC(displayPatientInformation)); modifierFunction = QUOTE([ARR_4(_target,_player,0,_this select 3)] call FUNC(modifyMedicalAction)); condition = "true"; @@ -19,7 +19,7 @@ class Medical { displayName = CSTRING(Bandage); distance = 2.0; condition = QUOTE([ARR_4(_player, _target, 'head', 'Bandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'head', 'Bandage')] call DFUNC(treatment)); showDisabled = 1; priority = 2; @@ -30,7 +30,7 @@ class Medical { displayName = CSTRING(Actions_FieldDressing); distance = 5.0; condition = QUOTE([ARR_4(_player, _target, 'head', 'FieldDressing')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'head', 'FieldDressing')] call DFUNC(treatment)); showDisabled = 0; priority = 2; @@ -39,35 +39,35 @@ class Medical { class PackingBandage: fieldDressing { displayName = CSTRING(Actions_PackingBandage); condition = QUOTE([ARR_4(_player, _target, 'head', 'PackingBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'head', 'PackingBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\packingBandage.paa); }; class ElasticBandage: fieldDressing { displayName = CSTRING(Actions_ElasticBandage); condition = QUOTE([ARR_4(_player, _target, 'head', 'ElasticBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'head', 'ElasticBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\bandage.paa); }; class QuikClot: fieldDressing { displayName = CSTRING(Actions_QuikClot); condition = QUOTE([ARR_4(_player, _target, 'head', 'QuikClot')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'head', 'QuikClot')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\bandage.paa); }; class CheckPulse: fieldDressing { displayName = CSTRING(Actions_CheckPulse); condition = QUOTE([ARR_4(_player, _target, 'head', 'CheckPulse')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'head', 'CheckPulse')] call DFUNC(treatment)); icon = ""; }; class CheckBloodPressure: CheckPulse { displayName = CSTRING(Actions_CheckBloodPressure); condition = QUOTE([ARR_4(_player, _target, 'head', 'CheckBloodPressure')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'head', 'CheckBloodPressure')] call DFUNC(treatment)); }; }; @@ -76,7 +76,7 @@ class Medical { distance = 5.0; condition = "true"; runOnHover = 1; - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE([ARR_3(_target, true, 1)] call DFUNC(displayPatientInformation)); modifierFunction = QUOTE([ARR_4(_target,_player,1,_this select 3)] call FUNC(modifyMedicalAction)); showDisabled = 1; @@ -87,7 +87,7 @@ class Medical { displayName = CSTRING(Bandage); distance = 2.0; condition = QUOTE([ARR_4(_player, _target, 'body', 'Bandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'body', 'Bandage')] call DFUNC(treatment)); showDisabled = 1; priority = 2; @@ -98,7 +98,7 @@ class Medical { displayName = CSTRING(Actions_TriageCard); distance = 2.0; condition = "true"; - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_2(_target, true)] call DFUNC(displayTriageCard)); showDisabled = 1; priority = 2; @@ -110,7 +110,7 @@ class Medical { displayName = CSTRING(Actions_FieldDressing); distance = 5.0; condition = QUOTE([ARR_4(_player, _target, 'body', 'FieldDressing')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'body', 'FieldDressing')] call DFUNC(treatment)); showDisabled = 0; priority = 2; @@ -119,21 +119,21 @@ class Medical { class PackingBandage: fieldDressing { displayName = CSTRING(Actions_PackingBandage); condition = QUOTE([ARR_4(_player, _target, 'body', 'PackingBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'body', 'PackingBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\packingBandage.paa); }; class ElasticBandage: fieldDressing { displayName = CSTRING(Actions_ElasticBandage); condition = QUOTE([ARR_4(_player, _target, 'body', 'ElasticBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'body', 'ElasticBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\bandage.paa); }; class QuikClot: fieldDressing { displayName = CSTRING(Actions_QuikClot); condition = QUOTE([ARR_4(_player, _target, 'body', 'QuikClot')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'body', 'QuikClot')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -141,7 +141,7 @@ class Medical { class ACE_ArmLeft { displayName = ECSTRING(interaction,ArmLeft); runOnHover = 1; - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE([ARR_3(_target, true, 2)] call DFUNC(displayPatientInformation)); modifierFunction = QUOTE([ARR_4(_target,_player,2,_this select 3)] call FUNC(modifyMedicalAction)); condition = "true"; @@ -151,7 +151,7 @@ class Medical { displayName = CSTRING(Bandage); distance = 2.0; condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'Bandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'Bandage')] call DFUNC(treatment)); showDisabled = 1; priority = 2; @@ -163,7 +163,7 @@ class Medical { displayName = CSTRING(Actions_FieldDressing); distance = 5.0; condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'FieldDressing')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'FieldDressing')] call DFUNC(treatment)); showDisabled = 0; priority = 2; @@ -172,83 +172,83 @@ class Medical { class PackingBandage: fieldDressing { displayName = CSTRING(Actions_PackingBandage); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'PackingBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'PackingBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\packingBandage.paa); }; class ElasticBandage: fieldDressing { displayName = CSTRING(Actions_ElasticBandage); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'ElasticBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'ElasticBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\bandage.paa); }; class QuikClot: fieldDressing { displayName = CSTRING(Actions_QuikClot); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'QuikClot')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'QuikClot')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\bandage.paa); }; class Tourniquet: fieldDressing { displayName = CSTRING(Actions_Tourniquet); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'Tourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'Tourniquet')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\tourniquet.paa); }; class Morphine: fieldDressing { displayName = CSTRING(Inject_Morphine); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'Morphine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'Morphine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Adenosine: Morphine { displayName = CSTRING(Inject_Atropine); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'Adenosine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'Adenosine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Atropine: Morphine { displayName = CSTRING(Inject_Atropine); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'Atropine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'Atropine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Epinephrine: Morphine { displayName = CSTRING(Inject_Epinephrine); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'Epinephrine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'Epinephrine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class CheckPulse: fieldDressing { displayName = CSTRING(Actions_CheckPulse); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'CheckPulse')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'CheckPulse')] call DFUNC(treatment)); icon = ""; }; class CheckBloodPressure: CheckPulse { displayName = CSTRING(Actions_CheckBloodPressure); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'CheckBloodPressure')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'CheckBloodPressure')] call DFUNC(treatment)); }; class RemoveTourniquet: Tourniquet { displayName = CSTRING(Actions_RemoveTourniquet); condition = QUOTE([ARR_4(_player, _target, 'hand_l', 'RemoveTourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'RemoveTourniquet')] call DFUNC(treatment)); }; }; class ACE_ArmRight { displayName = ECSTRING(interaction,ArmRight); runOnHover = 1; - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE([ARR_3(_target, true, 3)] call DFUNC(displayPatientInformation)); modifierFunction = QUOTE([ARR_4(_target,_player,3,_this select 3)] call FUNC(modifyMedicalAction)); condition = "true"; @@ -258,7 +258,7 @@ class Medical { displayName = CSTRING(Bandage); distance = 2.0; condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'Bandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'Bandage')] call DFUNC(treatment)); showDisabled = 1; priority = 2; @@ -270,7 +270,7 @@ class Medical { displayName = CSTRING(Actions_FieldDressing); distance = 5.0; condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'FieldDressing')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'FieldDressing')] call DFUNC(treatment)); showDisabled = 0; priority = 2; @@ -279,79 +279,79 @@ class Medical { class PackingBandage: fieldDressing { displayName = CSTRING(Actions_PackingBandage); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'PackingBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'PackingBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\packingBandage.paa); }; class ElasticBandage: fieldDressing { displayName = CSTRING(Actions_ElasticBandage); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'ElasticBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'ElasticBandage')] call DFUNC(treatment)); }; class QuikClot: fieldDressing { displayName = CSTRING(Actions_QuikClot); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'QuikClot')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'QuikClot')] call DFUNC(treatment)); }; class Tourniquet: fieldDressing { displayName = CSTRING(Actions_Tourniquet); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'Tourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'Tourniquet')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\tourniquet.paa); }; class Morphine: fieldDressing { displayName = CSTRING(Inject_Morphine); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'Morphine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'Morphine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Adenosine: Morphine { - displayName = CSTRING(Inject_Atropine); + displayName = CSTRING(Inject_Adenosine); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'Adenosine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'Adenosine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Atropine: Morphine { displayName = CSTRING(Inject_Atropine); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'Atropine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'Atropine')] call DFUNC(treatment)); }; class Epinephrine: Morphine { displayName = CSTRING(Inject_Epinephrine); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'Epinephrine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'Epinephrine')] call DFUNC(treatment)); }; class CheckPulse: fieldDressing { displayName = CSTRING(Actions_CheckPulse); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'CheckPulse')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'CheckPulse')] call DFUNC(treatment)); icon = ""; }; class CheckBloodPressure: CheckPulse { displayName = CSTRING(Actions_CheckBloodPressure); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'CheckBloodPressure')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'CheckBloodPressure')] call DFUNC(treatment)); }; class RemoveTourniquet: Tourniquet { displayName = CSTRING(Actions_RemoveTourniquet); condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'RemoveTourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'RemoveTourniquet')] call DFUNC(treatment)); }; }; class ACE_LegLeft { displayName = ECSTRING(interaction,LegLeft); runOnHover = 1; - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE([ARR_3(_target, true, 4)] call DFUNC(displayPatientInformation)); modifierFunction = QUOTE([ARR_4(_target,_player,4,_this select 3)] call FUNC(modifyMedicalAction)); condition = "true"; @@ -361,7 +361,7 @@ class Medical { displayName = CSTRING(Bandage); distance = 2.0; condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'Bandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Bandage')] call DFUNC(treatment)); showDisabled = 1; priority = 2; @@ -374,7 +374,7 @@ class Medical { displayName = CSTRING(Actions_FieldDressing); distance = 5.0; condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'FieldDressing')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'FieldDressing')] call DFUNC(treatment)); showDisabled = 0; priority = 2; @@ -383,67 +383,67 @@ class Medical { class PackingBandage: fieldDressing { displayName = CSTRING(Actions_PackingBandage); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'PackingBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'PackingBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\packingBandage.paa); }; class ElasticBandage: fieldDressing { displayName = CSTRING(Actions_ElasticBandage); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'ElasticBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'ElasticBandage')] call DFUNC(treatment)); }; class QuikClot: fieldDressing { displayName = CSTRING(Actions_QuikClot); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'QuikClot')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'QuikClot')] call DFUNC(treatment)); }; class Tourniquet: fieldDressing { displayName = CSTRING(Actions_Tourniquet); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'Tourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Tourniquet')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\tourniquet.paa); }; class Morphine: fieldDressing { displayName = CSTRING(Inject_Morphine); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'Morphine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Morphine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Adenosine: Morphine { displayName = CSTRING(Inject_Atropine); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'Adenosine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Adenosine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Atropine: Morphine { displayName = CSTRING(Inject_Atropine); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'Atropine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Atropine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Epinephrine: Morphine { displayName = CSTRING(Inject_Epinephrine); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'Epinephrine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Epinephrine')] call DFUNC(treatment)); }; class RemoveTourniquet: Tourniquet { displayName = CSTRING(Actions_RemoveTourniquet); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'RemoveTourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'RemoveTourniquet')] call DFUNC(treatment)); }; }; class ACE_LegRight { displayName = ECSTRING(interaction,LegRight); runOnHover = 1; - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE([ARR_3(_target, true, 5)] call DFUNC(displayPatientInformation)); modifierFunction = QUOTE([ARR_4(_target,_player,5,_this select 3)] call FUNC(modifyMedicalAction)); condition = "true"; @@ -453,7 +453,7 @@ class Medical { displayName = CSTRING(Bandage); distance = 2.0; condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'Bandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Bandage')] call DFUNC(treatment)); showDisabled = 1; priority = 2; @@ -466,7 +466,7 @@ class Medical { displayName = CSTRING(Actions_FieldDressing); distance = 5.0; condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'FieldDressing')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'FieldDressing')] call DFUNC(treatment)); showDisabled = 0; priority = 2; @@ -475,59 +475,59 @@ class Medical { class PackingBandage: fieldDressing { displayName = CSTRING(Actions_PackingBandage); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'PackingBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'PackingBandage')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\packingBandage.paa); }; class ElasticBandage: fieldDressing { displayName = CSTRING(Actions_ElasticBandage); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'ElasticBandage')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'ElasticBandage')] call DFUNC(treatment)); }; class QuikClot: fieldDressing { displayName = CSTRING(Actions_QuikClot); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'QuikClot')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'QuikClot')] call DFUNC(treatment)); }; class Tourniquet: fieldDressing { displayName = CSTRING(Actions_Tourniquet); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'Tourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Tourniquet')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\tourniquet.paa); }; class Morphine: fieldDressing { displayName = CSTRING(Inject_Morphine); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'Morphine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Morphine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Adenosine: Morphine { displayName = CSTRING(Inject_Atropine); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'Adenosine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Adenosine')] call DFUNC(treatment)); icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Atropine: Morphine { displayName = CSTRING(Inject_Atropine); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'Atropine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Atropine')] call DFUNC(treatment)); }; class Epinephrine: Morphine { displayName = CSTRING(Inject_Epinephrine); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'Epinephrine')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Epinephrine')] call DFUNC(treatment)); }; class RemoveTourniquet: Tourniquet { displayName = CSTRING(Actions_RemoveTourniquet); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'RemoveTourniquet')] call DFUNC(canTreatCached)); - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'RemoveTourniquet')] call DFUNC(treatment)); }; }; diff --git a/addons/medical/ACE_Settings.hpp b/addons/medical/ACE_Settings.hpp index 9434686f4b..3ba1052ea1 100644 --- a/addons/medical/ACE_Settings.hpp +++ b/addons/medical/ACE_Settings.hpp @@ -41,6 +41,7 @@ class ACE_Settings { description = CSTRING(MedicalSettings_bleedingCoefficient_Description); typeName = "SCALAR"; value = 1; + sliderSettings[] = {0, 25, 1, 1}; }; class GVAR(painCoefficient) { category = CSTRING(Category_Medical); @@ -48,23 +49,14 @@ class ACE_Settings { description = CSTRING(MedicalSettings_painCoefficient_Description); typeName = "SCALAR"; value = 1; - }; - class GVAR(enableAirway) { - category = CSTRING(Category_Medical); - typeName = "BOOL"; - value = false; - }; - class GVAR(enableFractures) { - category = CSTRING(Category_Medical); - typeName = "BOOL"; - value = false; + sliderSettings[] = {0, 25, 1, 1}; }; class GVAR(enableAdvancedWounds) { category = CSTRING(Category_Medical); displayName = CSTRING(AdvancedMedicalSettings_enableAdvancedWounds_DisplayName); description = CSTRING(AdvancedMedicalSettings_enableAdvancedWounds_Description); typeName = "BOOL"; - value = false; + value = 0; }; class GVAR(enableVehicleCrashes) { category = CSTRING(Category_Medical); @@ -86,6 +78,7 @@ class ACE_Settings { description = CSTRING(MedicalSettings_playerDamageThreshold_Description); typeName = "SCALAR"; value = 1; + sliderSettings[] = {0, 25, 1, 1}; }; class GVAR(AIDamageThreshold) { category = CSTRING(Category_Medical); @@ -93,6 +86,7 @@ class ACE_Settings { description = CSTRING(MedicalSettings_AIDamageThreshold_Description); typeName = "SCALAR"; value = 1; + sliderSettings[] = {0, 25, 1, 1}; }; class GVAR(enableUnconsciousnessAI) { category = CSTRING(Category_Medical); @@ -130,6 +124,7 @@ class ACE_Settings { description = CSTRING(ReviveSettings_maxReviveTime_Description); typeName = "SCALAR"; value = 120; + sliderSettings[] = {0, 3600, 120, 0}; }; class GVAR(amountOfReviveLives) { category = CSTRING(Category_Medical); @@ -137,6 +132,7 @@ class ACE_Settings { description = CSTRING(ReviveSettings_amountOfReviveLives_Description); typeName = "SCALAR"; value = -1; + sliderSettings[] = {-1, 25, -1, -1}; }; class GVAR(allowDeadBodyMovement) { category = CSTRING(Category_Medical); @@ -166,6 +162,7 @@ class ACE_Settings { description = CSTRING(MedicalSettings_litterCleanUpDelay_Description); typeName = "SCALAR"; value = 0; + sliderSettings[] = {-1, 3600, 0, 0}; }; class GVAR(medicSetting_basicEpi) { category = CSTRING(Category_Medical); @@ -301,5 +298,6 @@ class ACE_Settings { description = CSTRING(MedicalSettings_delayUnconCaptive_Description); typeName = "SCALAR"; value = 3; + sliderSettings[] = {0, 30, 3, 0}; }; }; diff --git a/addons/medical/CfgEventHandlers.hpp b/addons/medical/CfgEventHandlers.hpp index ab7c1868ab..becf395052 100644 --- a/addons/medical/CfgEventHandlers.hpp +++ b/addons/medical/CfgEventHandlers.hpp @@ -16,40 +16,3 @@ class Extended_PostInit_EventHandlers { init = QUOTE(call COMPILE_FILE(XEH_postInit)); }; }; - -class Extended_Init_EventHandlers { - class CAManBase { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_init)); - }; - }; - class ACE_bodyBagObject { - class ADDON { - init = QUOTE(_this call DEFUNC(dragging,initObject)); - }; - }; -}; - -class Extended_Respawn_EventHandlers { - class CAManBase { - class ADDON { - respawn = QUOTE(call COMPILE_FILE(XEH_respawn)); - }; - }; -}; - -class Extended_Killed_EventHandlers { - class CAManBase { - class ADDON { - killed = QUOTE(call FUNC(handleKilled)); - }; - }; -}; - -class Extended_Local_EventHandlers { - class CAManBase { - class ADDON { - local = QUOTE(call FUNC(handleLocal)); - }; - }; -}; diff --git a/addons/medical/CfgVehicles.hpp b/addons/medical/CfgVehicles.hpp index 84bda805fd..34bba3c95e 100644 --- a/addons/medical/CfgVehicles.hpp +++ b/addons/medical/CfgVehicles.hpp @@ -12,7 +12,7 @@ class CfgVehicles { class ACE_Module; class ACE_moduleMedicalSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(MedicalSettings_Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; @@ -154,7 +154,7 @@ class CfgVehicles { }; }; class ACE_moduleBasicMedicalSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(BasicMedicalSettings_Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; @@ -196,7 +196,7 @@ class CfgVehicles { }; }; class ACE_moduleAdvancedMedicalSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(AdvancedMedicalSettings_Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; @@ -318,7 +318,7 @@ class CfgVehicles { }; class ACE_moduleReviveSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(ReviveSettings_Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; @@ -362,7 +362,7 @@ class CfgVehicles { }; class ACE_moduleAssignMedicRoles: Module_F { - scope = 2; + scope = 1; displayName = CSTRING(AssignMedicRoles_Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; @@ -409,7 +409,7 @@ class CfgVehicles { }; class ACE_moduleAssignMedicVehicle: Module_F { - scope = 2; + scope = 1; displayName = CSTRING(AssignMedicVehicle_Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; @@ -453,7 +453,7 @@ class CfgVehicles { }; class ACE_moduleAssignMedicalFacility: Module_F { - scope = 2; + scope = 1; displayName = CSTRING(AssignMedicalFacility_Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; @@ -522,7 +522,7 @@ class CfgVehicles { class ACE_Actions { // Include actions in body parts for treatment while in the open - #define EXCEPTIONS exceptions[] = {}; + #define EXCEPTIONS exceptions[] = {"isNotSwimming"}; #define ACTION_CONDITION condition = QUOTE(GVAR(menuTypeStyle) == 0); #include "ACE_Medical_Actions.hpp" @@ -538,29 +538,30 @@ class CfgVehicles { #undef EXCEPTIONS #undef ACTION_CONDITION - #define EXCEPTIONS exceptions[] = {"isNotInside"}; + #define EXCEPTIONS exceptions[] = {"isNotInside", "isNotSwimming"}; #define ACTION_CONDITION condition = "true"; #include "ACE_Medical_Actions.hpp" }; class GVAR(loadPatient) { displayName = CSTRING(LoadPatient); distance = 5; - condition = QUOTE(_target getVariable[ARR_2(QUOTE(QUOTE(ACE_isUnconscious)),false)] && vehicle _target == _target); + condition = QUOTE(_target getVariable [ARR_2(QUOTE(QUOTE(ACE_isUnconscious)), false)] && {alive _target} && {vehicle _target == _target}); statement = QUOTE([ARR_2(_player, _target)] call DFUNC(actionLoadUnit)); showDisabled = 0; priority = 2; icon = QPATHTOF(UI\icons\medical_cross.paa); - exceptions[] = {"isNotDragging", "isNotCarrying"}; + exceptions[] = {"isNotDragging", "isNotCarrying", "isNotSwimming"}; + insertChildren = QUOTE(call DFUNC(addLoadPatientActions)); }; class GVAR(UnLoadPatient) { displayName = CSTRING(UnloadPatient); distance = 5; - condition = QUOTE(_target getVariable[ARR_2(QUOTE(QUOTE(ACE_isUnconscious)),false)] && vehicle _target != _target); + condition = QUOTE(_target getVariable [ARR_2(QUOTE(QUOTE(ACE_isUnconscious)), false)] && {alive _target} && {vehicle _target != _target} && {vehicle _player == _player}); statement = QUOTE([ARR_2(_player, _target)] call DFUNC(actionUnloadUnit)); showDisabled = 0; priority = 2; icon = QPATHTOF(UI\icons\medical_cross.paa); - exceptions[] = {"isNotDragging", "isNotCarrying", "isNotInside"}; + exceptions[] = {"isNotDragging", "isNotCarrying", "isNotInside", "isNotSwimming"}; }; }; }; @@ -876,14 +877,22 @@ class CfgVehicles { }; }; - class NATO_Box_Base; + class ThingX; + class ReammoBox_F: ThingX { + class ACE_Actions; + }; + class NATO_Box_Base: ReammoBox_F { + class ACE_Actions: ACE_Actions { + class ACE_MainActions; + }; + }; class ACE_medicalSupplyCrate: NATO_Box_Base { scope = 2; scopeCurator = 2; accuracy = 1000; displayName = CSTRING(medicalSupplyCrate); model = QPATHTOF(data\ace_medcrate.p3d); - author = ECSTRING(common,ACETeam); + author = "ElTyranos"; class TransportItems { MACRO_ADDITEM(ACE_fieldDressing,50); MACRO_ADDITEM(ACE_morphine,25); @@ -893,6 +902,35 @@ class CfgVehicles { MACRO_ADDITEM(ACE_bloodIV_250,15); MACRO_ADDITEM(ACE_bodyBag,10); }; + class AnimationSources { + class Cover { + source = "user"; + animPeriod = 1.5; + initPhase = 0; + minValue = 0; + maxValue = 1; + }; + }; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + selection = "cover_action"; + + class ACE_OpenLid { + displayName = CSTRING(openLid); + condition = QUOTE(alive _target && {_target animationPhase 'Cover' < 0.5}); + statement = QUOTE(_target animate ARR_2(['Cover',1])); + showDisabled = 0; + priority = -1; + }; + class ACE_CloseLid { + displayName = CSTRING(closeLid); + condition = QUOTE(alive _target && {_target animationPhase 'Cover' >= 0.5}); + statement = QUOTE(_target animate ARR_2(['Cover',0])); + showDisabled = 0; + priority = -1; + }; + }; + }; }; class ACE_medicalSupplyCrate_advanced: ACE_medicalSupplyCrate { displayName = CSTRING(medicalSupplyCrate_advanced); diff --git a/addons/medical/CfgWeapons.hpp b/addons/medical/CfgWeapons.hpp index df9a756a34..7260452bc4 100644 --- a/addons/medical/CfgWeapons.hpp +++ b/addons/medical/CfgWeapons.hpp @@ -1,19 +1,21 @@ class CfgWeapons { class ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class InventoryFirstAidKitItem_Base_F; class MedikitItem; // ITEMS class FirstAidKit: ItemCore { type = 0; + ace_arsenal_hide = 1; class ItemInfo: InventoryFirstAidKitItem_Base_F { mass = 4; }; }; class Medikit: ItemCore { type = 0; + ace_arsenal_hide = 1; class ItemInfo: MedikitItem { mass = 60; }; @@ -22,95 +24,104 @@ class CfgWeapons { class ACE_ItemCore; class ACE_fieldDressing: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); model = QPATHTOF(data\bandage.p3d); picture = QPATHTOF(ui\items\fieldDressing_x_ca.paa); displayName = CSTRING(Bandage_Basic_Display); descriptionShort = CSTRING(Bandage_Basic_Desc_Short); descriptionUse = CSTRING(Bandage_Basic_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_packingBandage: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Packing_Bandage_Display); picture = QPATHTOF(ui\items\packingBandage_x_ca.paa); model = QPATHTOF(data\packingbandage.p3d); descriptionShort = CSTRING(Packing_Bandage_Desc_Short); descriptionUse = CSTRING(Packing_Bandage_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_elasticBandage: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Bandage_Elastic_Display); picture = QPATHTOF(ui\items\elasticBandage_x_ca.paa); model = "\A3\Structures_F_EPA\Items\Medical\Bandage_F.p3d"; descriptionShort = CSTRING(Bandage_Elastic_Desc_Short); descriptionUse = CSTRING(Bandage_Elastic_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_tourniquet: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Tourniquet_Display); picture = QPATHTOF(ui\items\tourniquet_x_ca.paa); model = QPATHTOF(data\tourniquet.p3d); descriptionShort = CSTRING(Tourniquet_Desc_Short); descriptionUse = CSTRING(Tourniquet_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_morphine: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Morphine_Display); picture = QPATHTOF(ui\items\morphine_x_ca.paa); model = QPATHTOF(data\morphine.p3d); descriptionShort = CSTRING(Morphine_Desc_Short); descriptionUse = CSTRING(Morphine_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_adenosine: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Adenosine_Display); picture = QPATHTOF(ui\items\adenosine_x_ca.paa); model = QPATHTOF(data\adenosine.p3d); descriptionShort = CSTRING(adenosine_Desc_Short); descriptionUse = CSTRING(adenosine_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_atropine: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Atropine_Display); picture = QPATHTOF(ui\items\atropine_x_ca.paa); model = QPATHTOF(data\atropine.p3d); descriptionShort = CSTRING(Atropine_Desc_Short); descriptionUse = CSTRING(Atropine_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_epinephrine: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Epinephrine_Display); picture = QPATHTOF(ui\items\epinephrine_x_ca.paa); model = QPATHTOF(data\epinephrine.p3d); descriptionShort = CSTRING(Epinephrine_Desc_Short); descriptionUse = CSTRING(Epinephrine_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_plasmaIV: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Plasma_IV); model = QPATHTOF(data\IVBag_1000ml.p3d); hiddenSelections[] = {"camo"}; @@ -118,7 +129,7 @@ class CfgWeapons { picture = QPATHTOF(ui\items\plasmaIV_x_ca.paa); descriptionShort = CSTRING(Plasma_IV_Desc_Short); descriptionUse = CSTRING(Plasma_IV_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; }; @@ -126,7 +137,7 @@ class CfgWeapons { displayName = CSTRING(Plasma_IV_500); model = QPATHTOF(data\IVBag_500ml.p3d); hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_500ml_ca.paa) }; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 5; }; }; @@ -134,12 +145,13 @@ class CfgWeapons { displayName = CSTRING(Plasma_IV_250); model = QPATHTOF(data\IVBag_250ml.p3d); hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_250ml_ca.paa) }; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2.5; }; }; class ACE_bloodIV: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); model = QPATHTOF(data\IVBag_1000ml.p3d); displayName = CSTRING(Blood_IV); picture = QPATHTOF(ui\items\bloodIV_x_ca.paa); @@ -147,7 +159,7 @@ class CfgWeapons { hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_1000ml_ca.paa) }; descriptionShort = CSTRING(Blood_IV_Desc_Short); descriptionUse = CSTRING(Blood_IV_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; }; @@ -155,7 +167,7 @@ class CfgWeapons { displayName = CSTRING(Blood_IV_500); model = QPATHTOF(data\IVBag_500ml.p3d); hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_500ml_ca.paa) }; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 5; }; }; @@ -163,12 +175,13 @@ class CfgWeapons { displayName = CSTRING(Blood_IV_250); model = QPATHTOF(data\IVBag_250ml.p3d); hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_250ml_ca.paa) }; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2.5; }; }; class ACE_salineIV: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Saline_IV); model = QPATHTOF(data\IVBag_1000ml.p3d); hiddenSelections[] = {"camo"}; @@ -176,7 +189,7 @@ class CfgWeapons { picture = QPATHTOF(ui\items\salineIV_x_ca.paa); descriptionShort = CSTRING(Saline_IV_Desc_Short); descriptionUse = CSTRING(Saline_IV_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; }; @@ -184,7 +197,7 @@ class CfgWeapons { displayName = CSTRING(Saline_IV_500); model = QPATHTOF(data\IVBag_500ml.p3d); hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_500ml_ca.paa) }; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 5; }; }; @@ -192,50 +205,54 @@ class CfgWeapons { displayName = CSTRING(Saline_IV_250); model = QPATHTOF(data\IVBag_250ml.p3d); hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_250ml_ca.paa) }; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2.5; }; }; class ACE_quikclot: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(QuikClot_Display); model = QPATHTOF(data\QuikClot.p3d); picture = QPATHTOF(ui\items\quickclot_x_ca.paa); descriptionShort = CSTRING(QuikClot_Desc_Short); descriptionUse = CSTRING(QuikClot_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; class ACE_personalAidKit: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(Aid_Kit_Display); picture = QPATHTOF(ui\items\personal_aid_kit_x_ca.paa); descriptionShort = CSTRING(Aid_Kit_Desc_Short); descriptionUse = CSTRING(Aid_Kit_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; }; class ACE_surgicalKit: ACE_ItemCore { scope=2; + author = ECSTRING(common,ACETeam); displayName= CSTRING(SurgicalKit_Display); model = QPATHTOF(data\surgical_kit.p3d); picture = QPATHTOF(ui\items\surgicalKit_x_ca.paa); descriptionShort = CSTRING(SurgicalKit_Desc_Short); descriptionUse = CSTRING(SurgicalKit_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 15; }; }; class ACE_bodyBag: ACE_ItemCore { scope=2; + author = ECSTRING(common,ACETeam); displayName= CSTRING(Bodybag_Display); model = QPATHTOF(data\bodybagItem.p3d); picture = QPATHTOF(ui\items\bodybag_x_ca.paa); descriptionShort = CSTRING(Bodybag_Desc_Short); descriptionUse = CSTRING(Bodybag_Desc_Use); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 7; }; }; diff --git a/addons/medical/XEH_PREP.hpp b/addons/medical/XEH_PREP.hpp index b754f00f5d..e6fa31112d 100644 --- a/addons/medical/XEH_PREP.hpp +++ b/addons/medical/XEH_PREP.hpp @@ -11,7 +11,7 @@ PREP(actionLoadUnit); PREP(actionUnloadUnit); PREP(addDamageToUnit); PREP(addHeartRateAdjustment); -PREP(addToInjuredCollection); +PREP(addLoadPatientActions); PREP(addToLog); PREP(addToTriageCard); PREP(addUnconsciousCondition); @@ -40,9 +40,11 @@ PREP(handleDamage_fractures); PREP(handleDamage_internalInjuries); PREP(handleDamage_wounds); PREP(handleDamage_woundsOld); -PREP(handleUnitVitals); +PREP(handleInit); PREP(handleKilled); PREP(handleLocal); +PREP(handleRespawn); +PREP(handleUnitVitals); PREP(handleBandageOpening); PREP(hasItem); PREP(hasItems); diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index 979f3c47bc..991124fcb1 100644 --- a/addons/medical/XEH_postInit.sqf +++ b/addons/medical/XEH_postInit.sqf @@ -31,6 +31,20 @@ GVAR(heartBeatSounds_Slow) = ["ACE_heartbeat_slow_1", "ACE_heartbeat_slow_2"]; if (isServer) then { ["ace_placedInBodyBag", FUNC(serverRemoveBody)] call CBA_fnc_addEventHandler; [QGVAR(createLitterServer), FUNC(handleCreateLitter)] call CBA_fnc_addEventHandler; + addMissionEventHandler ["BuildingChanged", { + if (isNil QGVAR(allCreatedLitter)) exitWith {}; + params ["_buildingOld", "_buildingNew", "_isRuin"]; + TRACE_3("BuildingChanged",_buildingOld,_buildingNew,_isRuin); + private _radius = sizeOf typeOf _buildingOld / 2; + TRACE_1("",_radius); + { + _x params ["", "_objects"]; + if (({(_x distance2d _buildingOld) < _radius && {getPos _x select 2 > 0.1}} count _objects) > 0) then { + GVAR(allCreatedLitter) deleteAt (GVAR(allCreatedLitter) find _x); + { TRACE_1("deleting",_x); deleteVehicle _x } forEach _objects; + }; + } forEach (+GVAR(allCreatedLitter)); + }]; }; ["ace_unconscious", { @@ -107,7 +121,6 @@ GVAR(effectTimeBlood) = CBA_missionTime; // MAIN EFFECTS LOOP [{ - private ["_bleeding", "_blood"]; // Zeus interface is open or player is dead; disable everything if (!(isNull curatorCamera) or !(alive ACE_player)) exitWith { GVAR(effectUnconsciousCC) ppEffectEnable false; @@ -148,7 +161,7 @@ GVAR(effectTimeBlood) = CBA_missionTime; }; }; - _bleeding = [ACE_player] call FUNC(getBloodLoss); + private _bleeding = [ACE_player] call FUNC(getBloodLoss); // Bleeding Indicator if (_bleeding > 0 and GVAR(effectTimeBlood) + 3.5 < CBA_missionTime) then { GVAR(effectTimeBlood) = CBA_missionTime; @@ -156,7 +169,7 @@ GVAR(effectTimeBlood) = CBA_missionTime; }; // Blood Volume Effect - _blood = if (GVAR(level) < 2) then { + private _blood = if (GVAR(level) < 2) then { (ACE_player getVariable [QGVAR(bloodVolume), 100]) / 100; } else { (((ACE_player getVariable [QGVAR(bloodVolume), 100]) - 60) max 0) / 40; @@ -177,14 +190,13 @@ GVAR(lastHeartBeatSound) = CBA_missionTime; // HEARTRATE BASED EFFECTS [{ - private ["_heartRate", "_interval", "_minTime", "_sound", "_strength", "_pain"]; - _heartRate = ACE_player getVariable [QGVAR(heartRate), 70]; - _pain = ACE_player getVariable [QGVAR(pain), 0]; + private _heartRate = ACE_player getVariable [QGVAR(heartRate), 70]; + private _pain = ACE_player getVariable [QGVAR(pain), 0]; if (GVAR(level) == 1) then { _heartRate = 60 + 40 * _pain; }; if (_heartRate <= 0) exitWith {}; - _interval = 60 / (_heartRate min 40); + private _interval = 60 / (_heartRate min 40); if ((ACE_player getVariable ["ACE_isUnconscious", false])) then { if (GVAR(painEffectType) == 1) then { @@ -198,7 +210,7 @@ GVAR(lastHeartBeatSound) = CBA_missionTime; // Pain effect, no pain effect in zeus camera if (isNull curatorCamera) then { - _strength = ((_pain - (ACE_player getVariable [QGVAR(painSuppress), 0])) max 0) min 1; + private _strength = ((_pain - (ACE_player getVariable [QGVAR(painSuppress), 0])) max 0) min 1; _strength = _strength * (ACE_player getVariable [QGVAR(painCoefficient), GVAR(painCoefficient)]); if (GVAR(painEffectType) == 1) then { GVAR(effectPainCC) ppEffectEnable false; @@ -250,12 +262,12 @@ GVAR(lastHeartBeatSound) = CBA_missionTime; }; if (GVAR(level) >= 2 && {_heartRate > 0}) then { - _minTime = 60 / _heartRate; + private _minTime = 60 / _heartRate; if (CBA_missionTime - GVAR(lastHeartBeatSound) > _minTime) then { GVAR(lastHeartBeatSound) = CBA_missionTime; // Heart rate sound effect if (_heartRate < 60) then { - _sound = GVAR(heartBeatSounds_Normal) select (random((count GVAR(heartBeatSounds_Normal)) -1)); + private _sound = GVAR(heartBeatSounds_Normal) select (random((count GVAR(heartBeatSounds_Normal)) -1)); playSound _sound; } else { if (_heartRate > 150) then { @@ -293,3 +305,9 @@ if (hasInterface) then { [player] call FUNC(init); }] call CBA_fnc_addEventHandler; }; + +if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(arsenal,displayOpened), { + EGVAR(arsenal,virtualItems) set [17, (EGVAR(arsenal,virtualItems) select 17) - ["FirstAidKit", "Medikit"]]; + }] call CBA_fnc_addEventHandler; +}; diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index 6d09e9427c..51c2c16688 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -10,10 +10,8 @@ GVAR(injuredUnitCollection) = []; private _versionEx = "ace_medical" callExtension "version"; DFUNC(handleDamage_assignWounds) = if (_versionEx == "") then { - INFO_1("Extension %1.dll not installed.","ace_medical"); DFUNC(handleDamage_woundsOld) } else { - INFO_2("Extension version: %1: %2","ace_medical",_versionEx); DFUNC(handleDamage_wounds) }; @@ -41,6 +39,11 @@ private _fixStatic = { }; ["StaticWeapon", "init", _fixStatic] call CBA_fnc_addClassEventHandler; ["Car", "init", _fixStatic] call CBA_fnc_addClassEventHandler; +["CAManBase", "Init", FUNC(handleInit)] call CBA_fnc_addClassEventHandler; +["CAManBase", "Respawn", FUNC(handleRespawn)] call CBA_fnc_addClassEventHandler; +["CAManBase", "Killed", FUNC(handleKilled)] call CBA_fnc_addClassEventHandler; +["CAManBase", "Local", FUNC(handleLocal)] call CBA_fnc_addClassEventHandler; + addMissionEventHandler ["Loaded",{ { TRACE_1("starting preload (save load)",_x); diff --git a/addons/medical/config.cpp b/addons/medical/config.cpp index 9dc5f3dc17..002c9e2cf4 100644 --- a/addons/medical/config.cpp +++ b/addons/medical/config.cpp @@ -54,3 +54,7 @@ class ACE_newEvents { actionCheckBloodPressureLocal = QGVAR(actionCheckBloodPressureLocal); addVitalLoop = QGVAR(addVitalLoop); }; + +class ACE_Extensions { + extensions[] += {"ace_medical"}; +}; diff --git a/addons/medical/data/ace_medcrate.p3d b/addons/medical/data/ace_medcrate.p3d index 4398599b99..6158b3c972 100644 Binary files a/addons/medical/data/ace_medcrate.p3d and b/addons/medical/data/ace_medcrate.p3d differ diff --git a/addons/medical/data/ace_medcrate.rvmat b/addons/medical/data/ace_medcrate.rvmat new file mode 100644 index 0000000000..17488ebfdf --- /dev/null +++ b/addons/medical/data/ace_medcrate.rvmat @@ -0,0 +1,79 @@ +surfaceInfo = "a3\data_f\penetration\metal.bisurf"; +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={1,1,1,0}; +specularPower=50; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 { + texture="z\ace\addons\medical\data\ace_medcrate_nohq.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage2 { + texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage3 { + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage4 { + texture="z\ace\addons\medical\data\ace_medcrate_as.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage5 { + texture="z\ace\addons\medical\data\ace_medcrate_smdi.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage6 { + texture="#(ai,64,64,1)fresnel(2,0.1)"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage7 { + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/medical/data/ace_medcrate_as.paa b/addons/medical/data/ace_medcrate_as.paa new file mode 100644 index 0000000000..de1952e756 Binary files /dev/null and b/addons/medical/data/ace_medcrate_as.paa differ diff --git a/addons/medical/data/ace_medcrate_co.paa b/addons/medical/data/ace_medcrate_co.paa index a817bf0ae4..725902d0ef 100644 Binary files a/addons/medical/data/ace_medcrate_co.paa and b/addons/medical/data/ace_medcrate_co.paa differ diff --git a/addons/medical/data/ace_medcrate_nohq.paa b/addons/medical/data/ace_medcrate_nohq.paa new file mode 100644 index 0000000000..ea67585d62 Binary files /dev/null and b/addons/medical/data/ace_medcrate_nohq.paa differ diff --git a/addons/medical/data/ace_medcrate_r.p3d b/addons/medical/data/ace_medcrate_r.p3d deleted file mode 100644 index f711996bec..0000000000 Binary files a/addons/medical/data/ace_medcrate_r.p3d and /dev/null differ diff --git a/addons/medical/data/ace_medcrate_smdi.paa b/addons/medical/data/ace_medcrate_smdi.paa new file mode 100644 index 0000000000..7335753fbd Binary files /dev/null and b/addons/medical/data/ace_medcrate_smdi.paa differ diff --git a/addons/medical/data/model.cfg b/addons/medical/data/model.cfg index 114fae7ada..e6b373cb38 100644 --- a/addons/medical/data/model.cfg +++ b/addons/medical/data/model.cfg @@ -4,6 +4,14 @@ class CfgSkeletons { skeletonInherit = ""; skeletonBones[] = {}; }; + + class ACE_Medcrate_Skeleton { + isDiscrete = 1; + skeletonInherit = "Default"; + skeletonBones[] = { + "cover","" + }; + }; }; class CfgModels { @@ -12,13 +20,33 @@ class CfgModels { sections[] = {""}; skeletonName = ""; }; + class IVBagBase: Default { sectionsInherit = ""; sections[] = {"camo"}; skeletonName = ""; }; - class IVBag_250ml: IVBagBase {}; class IVBag_500ml: IVBagBase {}; class IVBag_1000ml: IVBagBase {}; -}; \ No newline at end of file + + class ace_medcrate: Default { + skeletonName = "ACE_Medcrate_Skeleton"; + sectionsInherit = "Default"; + + class Animations { + class Cover { + type = "rotationX"; + source = "user"; + selection = "cover"; + axis = "cover_axis"; + memory = 1; + sourceAddress = "clamp"; + minValue = 0; + maxValue = 1; + angle0 = "0"; + angle1 = "rad + 240"; + }; + }; + }; +}; diff --git a/addons/medical/functions/fnc_actionLoadUnit.sqf b/addons/medical/functions/fnc_actionLoadUnit.sqf index 11a875bf2f..264fb72a4b 100644 --- a/addons/medical/functions/fnc_actionLoadUnit.sqf +++ b/addons/medical/functions/fnc_actionLoadUnit.sqf @@ -1,10 +1,11 @@ /* * Author: Glowbal - * Action for loading an unconscious or dead unit in the nearest vechile + * Action for loading an unconscious or dead unit in the nearest vehicle, or _vehicle if given. * * Arguments: * 0: The medic * 1: The patient + * 2: The vehicle (default: objNull) * * Return Value: * None @@ -17,7 +18,7 @@ #include "script_component.hpp" -params ["_caller", "_target"]; +params ["_caller", "_target", ["_vehicle", objNull]]; if ([_target] call EFUNC(common,isAwake)) exitWith { [QEGVAR(common,displayTextStructured), [[LSTRING(CanNotLoaded), [_target] call EFUNC(common,getName)], 1.5, _caller], [_caller]] call CBA_fnc_targetEvent; @@ -29,4 +30,4 @@ if ([_target] call FUNC(isBeingDragged)) then { [_caller, _target] call EFUNC(dragging,dropObject); }; -private _vehicle = [_caller, _target] call EFUNC(common,loadPerson); +[_caller, _target, _vehicle] call EFUNC(common,loadPerson); diff --git a/addons/medical/functions/fnc_actionPlaceInBodyBag.sqf b/addons/medical/functions/fnc_actionPlaceInBodyBag.sqf index 1ae1dfdc6d..3f329d3dbb 100644 --- a/addons/medical/functions/fnc_actionPlaceInBodyBag.sqf +++ b/addons/medical/functions/fnc_actionPlaceInBodyBag.sqf @@ -41,7 +41,7 @@ private _direction = _dirVect call CBA_fnc_vectDir; //move the body away now, so it won't physX the bodyBag object (this setPos seems to need to be called where object is local) _target setPosASL [-5000, -5000, 0]; -private _bodyBag = createVehicle ["ACE_bodyBagObject", _position, [], 0, ""]; +private _bodyBag = createVehicle ["ACE_bodyBagObject", _position, [], 0, "NONE"]; // prevent body bag from flipping _bodyBag setPosASL _position; diff --git a/addons/medical/functions/fnc_addLoadPatientActions.sqf b/addons/medical/functions/fnc_addLoadPatientActions.sqf new file mode 100644 index 0000000000..b00ff72472 --- /dev/null +++ b/addons/medical/functions/fnc_addLoadPatientActions.sqf @@ -0,0 +1,25 @@ +/* + * Author: 654wak654 + * Adds child actions to the "load patient" action for near vehicles. + * + * Arguments: + * 0: Patient + * + * Return Value: + * Child actions + * + * Example: + * [kevin] call ace_medical_fnc_addLoadPatientActions + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target"]; + +private _statement = { + params ["_target", "_player", "_vehicle"]; + [_player, _target, _vehicle] call FUNC(actionLoadUnit); +}; + +[_target call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/medical/functions/fnc_addToInjuredCollection.sqf b/addons/medical/functions/fnc_addToInjuredCollection.sqf deleted file mode 100644 index 2da3ca34a1..0000000000 --- a/addons/medical/functions/fnc_addToInjuredCollection.sqf +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Author: Glowbal - * Enabled the vitals loop for a unit. Deprecated! - * - * Arguments: - * 0: The Unit - * - * Return Value: - * None - * - * Example: - * [bob] call ACE_medical_fnc_addToInjuredCollection - * - * Public: No - */ - -#include "script_component.hpp" - -ACE_DEPRECATED("ace_medical_fnc_addToInjuredCollection","3.7.0","ace_medical_fnc_addVitalLoop"); - -_this call FUNC(addVitalLoop); diff --git a/addons/medical/functions/fnc_adjustPainLevel.sqf b/addons/medical/functions/fnc_adjustPainLevel.sqf index e37972d0ef..b935041faf 100644 --- a/addons/medical/functions/fnc_adjustPainLevel.sqf +++ b/addons/medical/functions/fnc_adjustPainLevel.sqf @@ -16,8 +16,6 @@ */ #include "script_component.hpp" -private ["_pain"]; - params ["_unit", "_addedPain"]; //Only run on local units: if (!local _unit) exitWith {ERROR("unit is not local");}; diff --git a/addons/medical/functions/fnc_copyDeadBody.sqf b/addons/medical/functions/fnc_copyDeadBody.sqf index da7fb16cff..7bed7f39ec 100644 --- a/addons/medical/functions/fnc_copyDeadBody.sqf +++ b/addons/medical/functions/fnc_copyDeadBody.sqf @@ -17,18 +17,17 @@ #include "script_component.hpp" -private ["_newUnit", "_class", "_group", "_position", "_side", "_name"]; params ["_oldBody", "_caller"]; if (alive _oldBody) exitWith {_oldBody}; // we only want to do this for dead bodies -_name = _oldBody getVariable ["ACE_name", "unknown"]; -_class = typeOf _oldBody; -_side = side _caller; -_group = createGroup _side; -_position = getPos _oldBody; +private _name = _oldBody getVariable ["ACE_name", "unknown"]; +private _class = typeOf _oldBody; +private _side = side _caller; +private _group = createGroup _side; +private _position = getPos _oldBody; -_newUnit = _group createUnit [typeOf _oldBody, _position, [], 0, "NONE"]; +private _newUnit = _group createUnit [typeOf _oldBody, _position, [], 0, "NONE"]; _newUnit setVariable ["ACE_name", _name, true]; _newUnit disableAI "TARGET"; diff --git a/addons/medical/functions/fnc_displayPatientInformation.sqf b/addons/medical/functions/fnc_displayPatientInformation.sqf index 334db62613..fdc87da8b5 100644 --- a/addons/medical/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical/functions/fnc_displayPatientInformation.sqf @@ -31,7 +31,6 @@ if (_show) then { ("ACE_MedicalRscDisplayInformation" call BIS_fnc_rscLayer) cutRsc [QGVAR(DisplayInformation),"PLAIN"]; [{ - private ["_target", "_display", "_alphaLevel", "_damaged", "_availableSelections", "_openWounds", "_selectionBloodLoss", "_red", "_green", "_blue", "_alphaLevel", "_allInjuryTexts", "_lbCtrl", "_genericMessages"]; params ["_args", "_idPFH"]; _args params ["_target", "_selectionN"]; diff --git a/addons/medical/functions/fnc_getTriageStatus.sqf b/addons/medical/functions/fnc_getTriageStatus.sqf index 5174b92139..ac1ad4aa9a 100644 --- a/addons/medical/functions/fnc_getTriageStatus.sqf +++ b/addons/medical/functions/fnc_getTriageStatus.sqf @@ -18,10 +18,10 @@ #include "script_component.hpp" -private ["_unit","_return","_status"]; params ["_unit"]; -_status = _unit getVariable [QGVAR(triageLevel), -1]; -_return = switch (_status) do { + +private _status = _unit getVariable [QGVAR(triageLevel), -1]; +private _return = switch (_status) do { case 1: {[localize LSTRING(Triage_Status_Minor), 1, [0, 0.5, 0, 0.9]]}; case 2: {[localize LSTRING(Triage_Status_Delayed), 2, [0.7, 0.5, 0, 0.9]]}; case 3: {[localize LSTRING(Triage_Status_Immediate), 3, [0.4, 0.07, 0.07, 0.9]]}; diff --git a/addons/medical/functions/fnc_handleBandageOpening.sqf b/addons/medical/functions/fnc_handleBandageOpening.sqf index 6f8f0c05fe..4884b43757 100644 --- a/addons/medical/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical/functions/fnc_handleBandageOpening.sqf @@ -21,7 +21,6 @@ #include "script_component.hpp" -private ["_className", "_reopeningChance", "_reopeningMinDelay", "_reopeningMaxDelay", "_config", "_woundTreatmentConfig", "_bandagedWounds", "_exist", "_injuryId", "_existingInjury", "_delay", "_openWounds", "_selectedInjury", "_bandagedInjury"]; params ["_target", "_impact", "_part", "_injuryIndex", "_injury", "_bandage"]; private _classID = _injury select 1; @@ -66,7 +65,7 @@ private _bandagedInjury = []; { if ((_x select 1) == _injuryType && (_x select 2) == (_injury select 2)) exitwith { _exist = true; - _existingInjury = _x; + private _existingInjury = _x; _existingInjury set [3, (_existingInjury select 3) + _impact]; _bandagedWounds set [_foreachIndex, _existingInjury]; @@ -85,7 +84,7 @@ _target setVariable [QGVAR(bandagedWounds), _bandagedWounds, true]; TRACE_1("",_reopeningChance); // Check if we are ever going to reopen this if (random(1) <= _reopeningChance) then { - _delay = _reopeningMinDelay + random(_reopeningMaxDelay - _reopeningMinDelay); + private _delay = _reopeningMinDelay + random(_reopeningMaxDelay - _reopeningMinDelay); TRACE_1("Will open",_delay); [{ params ["_target", "_impact", "_part", "_injuryIndex", "_injury"]; @@ -103,7 +102,7 @@ if (random(1) <= _reopeningChance) then { { if ((_x select 1) == _injuryId && (_x select 2) == (_injury select 2)) exitwith { _exist = true; - _existingInjury = _x; + private _existingInjury = _x; _existingInjury set [3, ((_existingInjury select 3) - _impact) max 0]; _bandagedWounds set [_foreachIndex, _existingInjury]; }; diff --git a/addons/medical/functions/fnc_handleCollisionDamage.sqf b/addons/medical/functions/fnc_handleCollisionDamage.sqf index a101f9b1f9..e5b553bc15 100644 --- a/addons/medical/functions/fnc_handleCollisionDamage.sqf +++ b/addons/medical/functions/fnc_handleCollisionDamage.sqf @@ -19,11 +19,9 @@ params ["_unit", "_newDamage"]; -private ["_selection", "_totalDamage"]; +private _selection = "body"; -_selection = "body"; - -_totalDamage = (_unit getHit _selection) + _newDamage; +private _totalDamage = (_unit getHit _selection) + _newDamage; _unit setHit [_selection, _totalDamage]; diff --git a/addons/medical/functions/fnc_handleDamage_fractures.sqf b/addons/medical/functions/fnc_handleDamage_fractures.sqf index 1681acbe6d..546d6623ac 100644 --- a/addons/medical/functions/fnc_handleDamage_fractures.sqf +++ b/addons/medical/functions/fnc_handleDamage_fractures.sqf @@ -20,11 +20,10 @@ #include "script_component.hpp" -private ["_bodyPartn", "_fractures", "_fractureType"]; params ["_unit", "_selectionName", "_amountOfDamage", "_sourceOfDamage", "_typeOfDamage"]; -_bodyPartn = [_selectionName] call FUNC(selectionNameToNumber); +private _bodyPartn = [_selectionName] call FUNC(selectionNameToNumber); -_fractureType = 1; +private _fractureType = 1; if (_amountOfDamage > 0.05) then { // TODO specify fractures based off typeOfInjury details better. @@ -61,10 +60,9 @@ if (_amountOfDamage > 0.05) then { }; }; - private ["_fractures", "_fractureID", "_amountOf"]; - _fractures = _unit getVariable[QGVAR(fractures), []]; - _fractureID = 1; - _amountOf = count _fractures; + private _fractures = _unit getVariable[QGVAR(fractures), []]; + private _fractureID = 1; + private _amountOf = count _fractures; if (_amountOf > 0) then { _fractureID = (_fractures select (_amountOf - 1) select 0) + 1; }; diff --git a/addons/medical/functions/fnc_handleDamage_woundsOld.sqf b/addons/medical/functions/fnc_handleDamage_woundsOld.sqf index 18c4d76d19..376d50ff8c 100644 --- a/addons/medical/functions/fnc_handleDamage_woundsOld.sqf +++ b/addons/medical/functions/fnc_handleDamage_woundsOld.sqf @@ -20,19 +20,18 @@ #include "script_component.hpp" -private ["_bodyPartn", "_injuryTypeInfo", "_allInjuriesForDamageType", "_allPossibleInjuries", "_highestPossibleDamage", "_highestPossibleSpot", "_minDamage", "_openWounds", "_woundID", "_toAddInjury", "_painToAdd", "_bloodLoss", "_bodyPartNToAdd", "_classType", "_damageLevels", "_foundIndex", "_i", "_injury", "_maxDamage", "_pain", "_painLevel", "_selections", "_toAddClassID", "_woundsCreated"]; params ["_unit", "_selectionName", "_damage", "_typeOfProjectile", "_typeOfDamage"]; TRACE_6("ACE_DEBUG: HandleDamage_WoundsOLD Called",_unit, _selectionName, _damage, _shooter, _typeOfProjectile,_typeOfDamage); // Convert the selectionName to a number and ensure it is a valid selection. -_bodyPartn = [_selectionName] call FUNC(selectionNameToNumber); +private _bodyPartn = [_selectionName] call FUNC(selectionNameToNumber); if (_bodyPartn < 0) exitWith {}; // Get the injury type information. Format: [typeDamage thresholds, selectionSpecific, woundTypes] -_injuryTypeInfo = missionNamespace getVariable [format[QGVAR(woundInjuryType_%1), _typeOfDamage],[[], false, []]]; +private _injuryTypeInfo = missionNamespace getVariable [format[QGVAR(woundInjuryType_%1), _typeOfDamage],[[], false, []]]; // This are the available injuries for this damage type. Format [[classtype, selections, bloodloss, minimalDamage, pain], ..] -_allInjuriesForDamageType = _injuryTypeInfo select 2; +private _allInjuriesForDamageType = _injuryTypeInfo select 2; // It appears we are dealing with an unknown type of damage. if (count _allInjuriesForDamageType == 0) then { @@ -42,20 +41,19 @@ if (count _allInjuriesForDamageType == 0) then { }; // find the available injuries for this damage type and damage amount -_highestPossibleSpot = -1; -_highestPossibleDamage = -1; -_allPossibleInjuries = []; +private _highestPossibleSpot = -1; +private _highestPossibleDamage = -1; +private _allPossibleInjuries = []; { - _damageLevels = _x select 4; - _minDamage = _damageLevels select 0; - _maxDamage = _damageLevels select 1; + private _damageLevels = _x select 4; + _damageLevels params ["_minDamage","_maxDamage"]; // Check if the damage is higher as the min damage for the specific injury if (_damage >= _minDamage && {_damage <= _maxDamage || _maxDamage < 0}) then { - //_classType = _x select 0; - _selections = _x select 1; - //_bloodLoss = _x select 2; - //_pain = _x select 3; + //private _classType = _x select 0; + private _selections = _x select 1; + //private _bloodLoss = _x select 2; + //private _pain = _x select 3; // Check if the injury can be applied to the given selection name if ("All" in _selections || _selectionName in _selections) then { @@ -76,21 +74,21 @@ _allPossibleInjuries = []; if (_highestPossibleSpot < 0) exitWith {}; // Administration for open wounds and ids -_openWounds = _unit getVariable[QGVAR(openWounds), []]; -_woundID = _unit getVariable[QGVAR(lastUniqueWoundID), 1]; +private _openWounds = _unit getVariable[QGVAR(openWounds), []]; +private _woundID = _unit getVariable[QGVAR(lastUniqueWoundID), 1]; -_painToAdd = 0; -_woundsCreated = []; +private _painToAdd = 0; +private _woundsCreated = []; { if (_x select 0 <= _damage) exitWith { for "_i" from 0 to ((_x select 1)-1) do { // Find the injury we are going to add. Format [ classID, allowdSelections, bloodloss, painOfInjury, minimalDamage] - _toAddInjury = if (random(1) >= 0.85) then {_allInjuriesForDamageType select _highestPossibleSpot} else {selectRandom _allPossibleInjuries}; - _toAddClassID = _toAddInjury select 0; - _foundIndex = -1; + private _toAddInjury = if (random(1) >= 0.85) then {_allInjuriesForDamageType select _highestPossibleSpot} else {selectRandom _allPossibleInjuries}; + private _toAddClassID = _toAddInjury select 0; + private _foundIndex = -1; - _bodyPartNToAdd = if (_injuryTypeInfo select 1) then {_bodyPartn} else {floor(random(6))}; + private _bodyPartNToAdd = if (_injuryTypeInfo select 1) then {_bodyPartn} else {floor(random(6))}; // If the injury type is selection part specific, we will check if one of those injury types already exists and find the spot for it.. if ((_injuryTypeInfo select 1)) then { { @@ -101,7 +99,7 @@ _woundsCreated = []; } forEach _openWounds; }; - _injury = []; + private _injury = []; if (_foundIndex < 0) then { // Create a new injury. Format [ID, classID, bodypart, percentage treated, bloodloss rate] _injury = [_woundID, _toAddInjury select 0, _bodyPartNToAdd, 1, _toAddInjury select 2]; @@ -132,6 +130,6 @@ if (count _woundsCreated > 0) then { _unit setVariable [QGVAR(lastUniqueWoundID), _woundID, true]; }; -_painLevel = _unit getVariable [QGVAR(pain), 0]; +private _painLevel = _unit getVariable [QGVAR(pain), 0]; _unit setVariable [QGVAR(pain), _painLevel + _painToAdd]; TRACE_6("ACE_DEBUG: HandleDamage_WoundsOLD",_unit, _painLevel, _painToAdd, _unit getVariable QGVAR(pain), _unit getVariable QGVAR(openWounds),_woundsCreated); diff --git a/addons/medical/XEH_init.sqf b/addons/medical/functions/fnc_handleInit.sqf similarity index 59% rename from addons/medical/XEH_init.sqf rename to addons/medical/functions/fnc_handleInit.sqf index acdd50ce82..7094219aae 100644 --- a/addons/medical/XEH_init.sqf +++ b/addons/medical/functions/fnc_handleInit.sqf @@ -1,3 +1,18 @@ +/* + * Author: KoffeinFlummi + * Called when a unit is initialized via XEH_init + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [bob] call ACE_medical_fnc_handleInit + * + * Public: No + */ #include "script_component.hpp" params ["_unit"]; diff --git a/addons/medical/XEH_respawn.sqf b/addons/medical/functions/fnc_handleRespawn.sqf similarity index 59% rename from addons/medical/XEH_respawn.sqf rename to addons/medical/functions/fnc_handleRespawn.sqf index 1d1c34d6c7..99efcaaac1 100644 --- a/addons/medical/XEH_respawn.sqf +++ b/addons/medical/functions/fnc_handleRespawn.sqf @@ -1,3 +1,18 @@ +/* + * Author: KoffeinFlummi + * Called when a unit is Respawned + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [bob] call ACE_medical_fnc_handleRespawn + * + * Public: No + */ #include "script_component.hpp" params ["_unit"]; @@ -7,7 +22,7 @@ params ["_unit"]; // Reset captive status for respawning unit if (!(_unit getVariable ["ACE_isUnconscious", false])) then { - [_unit, "setCaptive", "ace_unconscious", false] call EFUNC(common,statusEffect_set); + [_unit, "setHidden", "ace_unconscious", false] call EFUNC(common,statusEffect_set); }; // Remove maximum unconsciousness time handler diff --git a/addons/medical/functions/fnc_init.sqf b/addons/medical/functions/fnc_init.sqf index 82b6b435e6..f5f484106e 100644 --- a/addons/medical/functions/fnc_init.sqf +++ b/addons/medical/functions/fnc_init.sqf @@ -69,16 +69,14 @@ _unit setVariable [QGVAR(hasPain), false, true]; _unit setVariable [QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives), true]; _unit setVariable [QGVAR(painSuppress), 0, true]; -private ["_allUsedMedication", "_logs"]; - // medication -_allUsedMedication = _unit getVariable [QGVAR(allUsedMedication), []]; +private _allUsedMedication = _unit getVariable [QGVAR(allUsedMedication), []]; { _unit setVariable [_x select 0, nil]; } forEach _allUsedMedication; _unit setVariable [QGVAR(allUsedMedication), [], true]; -_logs = _unit getVariable [QGVAR(allLogs), []]; +private _logs = _unit getVariable [QGVAR(allLogs), []]; { _unit setVariable [_x, nil]; } forEach _logs; diff --git a/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf b/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf index 97dcc35a6b..61e140d0fd 100644 --- a/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf +++ b/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf @@ -18,11 +18,10 @@ #include "script_component.hpp" -private ["_setting", "_objects"]; params [["_logic", objNull, [objNull]]]; if (!isNull _logic) then { - _setting = _logic getVariable ["class",0]; - _objects = synchronizedObjects _logic; + private _setting = _logic getVariable ["class",0]; + private _objects = synchronizedObjects _logic; { if (local _x) then { _x setVariable[QGVAR(isMedicalFacility), true, true]; diff --git a/addons/medical/functions/fnc_parseConfigForInjuries.sqf b/addons/medical/functions/fnc_parseConfigForInjuries.sqf index c3ef815e74..07bd69fa52 100644 --- a/addons/medical/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical/functions/fnc_parseConfigForInjuries.sqf @@ -15,14 +15,12 @@ */ #include "script_component.hpp" -private ["_injuriesRootConfig", "_woundsConfig", "_allWoundClasses", "_amountOf", "_entry","_classType", "_selections", "_bloodLoss", "_pain","_minDamage","_causes", "_damageTypesConfig", "_thresholds", "_typeThresholds", "_selectionSpecific", "_selectionSpecificType", "_classDisplayName", "_subClassDisplayName", "_maxDamage", "_subClassmaxDamage", "_defaultMinLethalDamage", "_minLethalDamage", "_allFoundDamageTypes", "_classID", "_configDamageTypes", "_i", "_parseForSubClassWounds", "_subClass", "_subClassConfig", "_subClassbloodLoss", "_subClasscauses", "_subClassminDamage", "_subClasspain", "_subClassselections", "_subClasstype", "_type", "_varName", "_woundTypes"]; - -_injuriesRootConfig = (configFile >> "ACE_Medical_Advanced" >> "Injuries"); -_allFoundDamageTypes = []; -_configDamageTypes = (_injuriesRootConfig >> "damageTypes"); +private _injuriesRootConfig = (configFile >> "ACE_Medical_Advanced" >> "Injuries"); +private _allFoundDamageTypes = []; +private _configDamageTypes = (_injuriesRootConfig >> "damageTypes"); // minimum lethal damage collection, mapped to damageTypes -_defaultMinLethalDamage = getNumber (_configDamageTypes >> "lethalDamage"); +private _defaultMinLethalDamage = getNumber (_configDamageTypes >> "lethalDamage"); GVAR(minLethalDamages) = []; // Collect all available damage types from the config @@ -30,7 +28,7 @@ for "_i" from 0 to (count _configDamageTypes -1) /* step +1 */ do { // Only get the subclasses in damageType class if (isClass(_configDamageTypes select _i)) then { _allFoundDamageTypes pushBack (configName (_configDamageTypes select _i)); - _minLethalDamage = if (isNumber((_configDamageTypes select _i) >> "lethalDamage")) then { + private _minLethalDamage = if (isNumber((_configDamageTypes select _i) >> "lethalDamage")) then { getNumber((_configDamageTypes select _i) >> "lethalDamage"); } else { _defaultMinLethalDamage @@ -45,18 +43,18 @@ GVAR(fractureClassNames) = []; // Parsing the wounds // function for parsing a sublcass of an injury -_parseForSubClassWounds = { - _subClass = _this select 0; +private _parseForSubClassWounds = { + private _subClass = _this select 0; if (isClass (_entry >> _subClass)) exitWith { - _subClassConfig = (_entry >> _subClass); - _subClasstype = _classType + (configName _subClassConfig); - _subClassselections = if (isArray(_subClassConfig >> "selections")) then { getArray(_subClassConfig >> "selections");} else { _selections }; - _subClassbloodLoss = if (isNumber(_subClassConfig >> "bleedingRate")) then { getNumber(_subClassConfig >> "bleedingRate");} else { _bloodLoss }; - _subClasspain = if (isNumber(_subClassConfig >> "pain")) then { getNumber(_subClassConfig >> "pain");} else { _pain }; - _subClassminDamage = if (isNumber(_subClassConfig >> "minDamage")) then { getNumber(_subClassConfig >> "minDamage");} else { _minDamage }; - _subClassmaxDamage = if (isNumber(_subClassConfig >> "maxDamage")) then { getNumber(_subClassConfig >> "maxDamage");} else { _maxDamage }; - _subClasscauses = if (isArray(_subClassConfig >> "causes")) then { getArray(_subClassConfig >> "causes");} else { _causes }; - _subClassDisplayName = if (isText(_subClassConfig >> "name")) then { getText(_subClassConfig >> "name");} else {_classDisplayName + " " + _subClass}; + private _subClassConfig = (_entry >> _subClass); + private _subClasstype = _classType + (configName _subClassConfig); + private _subClassselections = if (isArray(_subClassConfig >> "selections")) then { getArray(_subClassConfig >> "selections");} else { _selections }; + private _subClassbloodLoss = if (isNumber(_subClassConfig >> "bleedingRate")) then { getNumber(_subClassConfig >> "bleedingRate");} else { _bloodLoss }; + private _subClasspain = if (isNumber(_subClassConfig >> "pain")) then { getNumber(_subClassConfig >> "pain");} else { _pain }; + private _subClassminDamage = if (isNumber(_subClassConfig >> "minDamage")) then { getNumber(_subClassConfig >> "minDamage");} else { _minDamage }; + private _subClassmaxDamage = if (isNumber(_subClassConfig >> "maxDamage")) then { getNumber(_subClassConfig >> "maxDamage");} else { _maxDamage }; + private _subClasscauses = if (isArray(_subClassConfig >> "causes")) then { getArray(_subClassConfig >> "causes");} else { _causes }; + private _subClassDisplayName = if (isText(_subClassConfig >> "name")) then { getText(_subClassConfig >> "name");} else {_classDisplayName + " " + _subClass}; if (count _selections > 0 && {count _causes > 0}) then { GVAR(woundClassNames) pushBack _subClasstype; _allWoundClasses pushBack [_classID, _subClassselections, _subClassbloodLoss, _subClasspain, [_subClassminDamage, _subClassmaxDamage], _subClasscauses, _subClassDisplayName]; @@ -68,22 +66,22 @@ _parseForSubClassWounds = { }; // TODO classTypes are strings currently. Convert them to unqiue IDs instead. -_woundsConfig = (_injuriesRootConfig >> "wounds"); -_allWoundClasses = []; -_classID = 0; +private _woundsConfig = (_injuriesRootConfig >> "wounds"); +private _allWoundClasses = []; +private _classID = 0; if (isClass _woundsConfig) then { - _amountOf = count _woundsConfig; + private _amountOf = count _woundsConfig; for "_i" from 0 to (_amountOf -1) /* step +1 */ do { - _entry = _woundsConfig select _i; + private _entry = _woundsConfig select _i; if (isClass _entry) then { - _classType = (ConfigName _entry); - _selections = if (isArray(_entry >> "selections")) then { getArray(_entry >> "selections");} else {[]}; - _bloodLoss = if (isNumber(_entry >> "bleedingRate")) then { getNumber(_entry >> "bleedingRate");} else {0}; - _pain = if (isNumber(_entry >> "pain")) then { getNumber(_entry >> "pain");} else {0}; - _minDamage = if (isNumber(_entry >> "minDamage")) then { getNumber(_entry >> "minDamage");} else {0}; - _maxDamage = if (isNumber(_entry >> "maxDamage")) then { getNumber(_entry >> "maxDamage");} else {-1}; - _causes = if (isArray(_entry >> "causes")) then { getArray(_entry >> "causes");} else {[]}; - _classDisplayName = if (isText(_entry >> "name")) then { getText(_entry >> "name");} else {_classType}; + private _classType = (ConfigName _entry); + private _selections = if (isArray(_entry >> "selections")) then { getArray(_entry >> "selections");} else {[]}; + private _bloodLoss = if (isNumber(_entry >> "bleedingRate")) then { getNumber(_entry >> "bleedingRate");} else {0}; + private _pain = if (isNumber(_entry >> "pain")) then { getNumber(_entry >> "pain");} else {0}; + private _minDamage = if (isNumber(_entry >> "minDamage")) then { getNumber(_entry >> "minDamage");} else {0}; + private _maxDamage = if (isNumber(_entry >> "maxDamage")) then { getNumber(_entry >> "maxDamage");} else {-1}; + private _causes = if (isArray(_entry >> "causes")) then { getArray(_entry >> "causes");} else {[]}; + private _classDisplayName = if (isText(_entry >> "name")) then { getText(_entry >> "name");} else {_classType}; // TODO instead of hardcoding minor, medium and large just go through all sub classes recursively until none are found if (["Minor"] call _parseForSubClassWounds || ["Medium"] call _parseForSubClassWounds || ["Large"] call _parseForSubClassWounds) exitWith {}; // continue to the next one @@ -101,31 +99,30 @@ if (isClass _woundsConfig) then { GVAR(AllWoundInjuryTypes) = _allWoundClasses; // Linking injuries to the woundInjuryType variables. -_damageTypesConfig = (configFile >> "ACE_Medical_Advanced" >> "Injuries" >> "damageTypes"); -_thresholds = getArray(_damageTypesConfig >> "thresholds"); -_selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific"); +private _damageTypesConfig = (configFile >> "ACE_Medical_Advanced" >> "Injuries" >> "damageTypes"); +private _thresholds = getArray(_damageTypesConfig >> "thresholds"); +private _selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific"); { - _varName = format[QGVAR(woundInjuryType_%1),_x]; - _woundTypes = []; - _type = _x; + private _varName = format[QGVAR(woundInjuryType_%1),_x]; + private _woundTypes = []; + private _type = _x; { // Check if this type is in the causes of a wound class, if so, we will store the wound types for this damage type if (_type in (_x select 5)) then { _woundTypes pushBack _x; }; } forEach _allWoundClasses; - _typeThresholds = _thresholds; - _selectionSpecificType = _selectionSpecific; + private _typeThresholds = _thresholds; + private _selectionSpecificType = _selectionSpecific; if (isClass(_damageTypesConfig >> _x)) then { if (isArray(_damageTypesConfig >> _x >> "thresholds")) then { _typeThresholds = getArray(_damageTypesConfig >> _x >> "thresholds");}; if (isNumber(_damageTypesConfig >> _x >> "selectionSpecific")) then { _selectionSpecificType = getNumber(_damageTypesConfig >> _x >> "selectionSpecific");}; }; missionNamespace setVariable [_varName, [_typeThresholds, _selectionSpecificType > 0, _woundTypes]]; - private ["_minDamageThresholds", "_amountThresholds"]; // extension loading - _minDamageThresholds = ""; - _amountThresholds = ""; + private _minDamageThresholds = ""; + private _amountThresholds = ""; { _minDamageThresholds = _minDamageThresholds + str(_x select 0); _amountThresholds = _amountThresholds + str(_x select 1); @@ -143,12 +140,11 @@ _selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific"); // Extension loading { - private ["_classID", "_className", "_allowedSelections", "_bloodLoss", "_pain", "_minDamage", "_maxDamage", "_causes", "_classDisplayName", "_extensionInput", "_selections", "_causesArray"]; // add shit to addInjuryType _x params ["_classID", "_selections", "_bloodLoss", "_pain", "_damage", "_causesArray", "_classDisplayName"]; _damage params ["_minDamage", "_maxDamage"]; - _className = GVAR(woundClassNames) select _forEachIndex; - _allowedSelections = ""; + private _className = GVAR(woundClassNames) select _forEachIndex; + private _allowedSelections = ""; { _allowedSelections = _allowedSelections + _x; @@ -157,7 +153,7 @@ _selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific"); }; } forEach _selections; - _causes = ""; + private _causes = ""; { _causes = _causes + _x; diff --git a/addons/medical/functions/fnc_setDead.sqf b/addons/medical/functions/fnc_setDead.sqf index fcc8b42235..3949f2cfd9 100644 --- a/addons/medical/functions/fnc_setDead.sqf +++ b/addons/medical/functions/fnc_setDead.sqf @@ -18,7 +18,6 @@ #include "script_component.hpp" -private ["_reviveVal", "_lifesLeft"]; params ["_unit", ["_force", false], ["_delaySetDamage", false]]; if ((!alive _unit) || {_unit getVariable ["ACE_isDead", false]}) exitWith {true}; @@ -27,12 +26,12 @@ if (!local _unit) exitwith { false; }; -_reviveVal = _unit getVariable [QGVAR(enableRevive), GVAR(enableRevive)]; +private _reviveVal = _unit getVariable [QGVAR(enableRevive), GVAR(enableRevive)]; if (((_reviveVal == 1 && {[_unit] call EFUNC(common,isPlayer)} || _reviveVal == 2)) && !_force) exitwith { if (_unit getVariable [QGVAR(inReviveState), false]) exitwith { if (GVAR(amountOfReviveLives) > 0) then { - _lifesLeft = _unit getVariable[QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives)]; - if (_lifesLeft == 0) then { + private _lifesLeft = _unit getVariable[QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives)]; + if (_lifesLeft <= 0) then { [_unit, true] call FUNC(setDead); }; }; diff --git a/addons/medical/functions/fnc_setHitPointDamage.sqf b/addons/medical/functions/fnc_setHitPointDamage.sqf index 16daee5e5d..eb93b6740e 100644 --- a/addons/medical/functions/fnc_setHitPointDamage.sqf +++ b/addons/medical/functions/fnc_setHitPointDamage.sqf @@ -24,7 +24,6 @@ #define ARMDAMAGETRESHOLD1 1 #define ARMDAMAGETRESHOLD2 1.7 -private ["_unit", "_selection", "_damage", "_selections", "_damages", "_damageOld", "_damageSumOld", "_damageNew", "_damageSumNew", "_damageFinal", "_armdamage", "_legdamage"]; params ["_unit", "_selection", "_damage", ["_disabled", false]]; // Unit isn't local, give function to machine where it is. @@ -37,7 +36,7 @@ if (_disabled) exitWith { _unit setHitPointDamage [_selection, _damage]; }; -_selections = [ +private _selections = [ "HitHead", "HitBody", "HitLeftArm", @@ -50,10 +49,10 @@ if !(_selection in _selections) exitWith { _unit setHitPointDamage [_selection, _damage]; }; -_damages = _selections apply {_unit getHitPointDamage _x}; +private _damages = _selections apply {_unit getHitPointDamage _x}; -_damageOld = damage _unit; -_damageSumOld = 0; +private _damageOld = damage _unit; +private _damageSumOld = 0; { _damageSumOld = _damageSumOld + _x; } forEach _damages; @@ -61,12 +60,12 @@ _damageSumOld = _damageSumOld max 0.001; _damages set [_selections find _selection, _damage]; -_damageSumNew = 0; +private _damageSumNew = 0; { _damageSumNew = _damageSumNew + _x; } forEach _damages; -_damageNew = _damageSumNew / 6; +private _damageNew = _damageSumNew / 6; if (_damageOld > 0) then { _damageNew = _damageOld * (_damageSumNew / _damageSumOld); }; @@ -80,12 +79,12 @@ if (_damageNew >= 0.9) then { }; { - _damageFinal = (_damages select _forEachIndex); + private _damageFinal = (_damages select _forEachIndex); _unit setHitPointDamage [_x, _damageFinal]; } forEach _selections; // Leg Damage -_legdamage = (_unit getHitPointDamage "HitLeftLeg") + (_unit getHitPointDamage "HitRightLeg"); +private _legdamage = (_unit getHitPointDamage "HitLeftLeg") + (_unit getHitPointDamage "HitRightLeg"); if (_legdamage >= LEGDAMAGETRESHOLD1) then { if (_unit getHitPointDamage "HitLegs" != 1) then {_unit setHitPointDamage ["HitLegs", 1]}; } else { @@ -95,7 +94,7 @@ if (_legdamage >= LEGDAMAGETRESHOLD1) then { // Arm Damage -_armdamage = (_unit getHitPointDamage "HitLeftArm") + (_unit getHitPointDamage "HitRightArm"); +private _armdamage = (_unit getHitPointDamage "HitLeftArm") + (_unit getHitPointDamage "HitRightArm"); if (_armdamage >= ARMDAMAGETRESHOLD1) then { if (_unit getHitPointDamage "HitHands" != 1) then {_unit setHitPointDamage ["HitHands", 1]}; } else { diff --git a/addons/medical/functions/fnc_setUnconscious.sqf b/addons/medical/functions/fnc_setUnconscious.sqf index c2d503ceee..61d831f533 100644 --- a/addons/medical/functions/fnc_setUnconscious.sqf +++ b/addons/medical/functions/fnc_setUnconscious.sqf @@ -26,7 +26,6 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setUnconscious), _this]; }; -private ["_animState", "_originalPos", "_startingTime", "_isDead"]; params ["_unit", ["_set", true], ["_minWaitingTime", DEFAULT_DELAY], ["_force", false]]; // No change, fuck off. (why is there no xor?) @@ -55,9 +54,9 @@ if (_unit == ACE_player) then { }; // if we have unconsciousness for AI disabled, we will kill the unit instead -_isDead = false; +private _isDead = false; if (!([_unit, GVAR(remoteControlledAI)] call EFUNC(common,isPlayer)) && !_force) then { - _enableUncon = _unit getVariable [QGVAR(enableUnconsciousnessAI), GVAR(enableUnconsciousnessAI)]; + private _enableUncon = _unit getVariable [QGVAR(enableUnconsciousnessAI), GVAR(enableUnconsciousnessAI)]; if (_enableUncon == 0 or {_enableUncon == 1 and (random 1) < 0.5}) then { [_unit, true] call FUNC(setDead); _isDead = true; @@ -86,7 +85,7 @@ if (vehicle _unit != _unit) then { }; //Save current stance: -_originalPos = unitPos _unit; +private _originalPos = unitPos _unit; _unit setUnitPos "DOWN"; [_unit, true] call EFUNC(common,disableAI); @@ -98,17 +97,21 @@ if (GVAR(moveUnitsFromGroupOnUnconscious)) then { }; // Delay Unconscious so the AI dont instant stop shooting on the unit #3121 if (GVAR(delayUnconCaptive) == 0) then { - [_unit, "setCaptive", "ace_unconscious", true] call EFUNC(common,statusEffect_set); + [_unit, "setHidden", "ace_unconscious", true] call EFUNC(common,statusEffect_set); } else { + // when the Delay is so high that the unit can wake up and get uncon again we need to check if it is the correct wait that got executed + private _counter = _unit getVariable [QGVAR(unconsciousCounter), 0]; + _counter = _counter + 1; + _unit setVariable [QGVAR(unconsciousCounter), _counter]; [{ - params ["_unit"]; - if (_unit getVariable ["ACE_isUnconscious", false]) then { - [_unit, "setCaptive", "ace_unconscious", true] call EFUNC(common,statusEffect_set); + params ["_unit", "_counter"]; + if (_unit getVariable ["ACE_isUnconscious", false] && (_unit getVariable [QGVAR(unconsciousCounter), 0]) == _counter) then { + [_unit, "setHidden", "ace_unconscious", true] call EFUNC(common,statusEffect_set); }; - },[_unit], GVAR(delayUnconCaptive)] call CBA_fnc_waitAndExecute; + },[_unit, _counter], GVAR(delayUnconCaptive)] call CBA_fnc_waitAndExecute; }; -_anim = [_unit] call EFUNC(common,getDeathAnim); +private _anim = [_unit] call EFUNC(common,getDeathAnim); [_unit, _anim, 1, true] call EFUNC(common,doAnimation); [{ params ["_unit", "_anim"]; @@ -117,7 +120,7 @@ _anim = [_unit] call EFUNC(common,getDeathAnim); }; }, [_unit, _anim], 0.5, 0] call CBA_fnc_waitAndExecute; -_startingTime = CBA_missionTime; +private _startingTime = CBA_missionTime; [DFUNC(unconsciousPFH), 0.1, [_unit, _originalPos, _startingTime, _minWaitingTime, false, vehicle _unit isKindOf "ParachuteBase"] ] call CBA_fnc_addPerFrameHandler; diff --git a/addons/medical/functions/fnc_showBloodEffect.sqf b/addons/medical/functions/fnc_showBloodEffect.sqf index 2e2a282884..61cd6fe464 100644 --- a/addons/medical/functions/fnc_showBloodEffect.sqf +++ b/addons/medical/functions/fnc_showBloodEffect.sqf @@ -20,10 +20,12 @@ params ["_bloodRemaining"]; disableSerialization; // get already existing controls, or create them -private ["_fxBloodControls", "_bloodCtrl1", "_bloodCtrl2", "_bloodCtrl3"]; -_fxBloodControls = GETUVAR(GVAR(FXBloodControls),[]); +private _fxBloodControls = GETUVAR(GVAR(FXBloodControls),[]); +private _bloodCtrl1 = controlNull; +private _bloodCtrl2 = controlNull; +private _bloodCtrl3 = controlNull; if (count _fxBloodControls != 3) then { _bloodCtrl1 = findDisplay 46 ctrlCreate ["RscPicture", -1]; _bloodCtrl2 = findDisplay 46 ctrlCreate ["RscPicture", -1]; diff --git a/addons/medical/functions/fnc_treatment.sqf b/addons/medical/functions/fnc_treatment.sqf index f5c0d6a1bb..80f097fee4 100644 --- a/addons/medical/functions/fnc_treatment.sqf +++ b/addons/medical/functions/fnc_treatment.sqf @@ -176,21 +176,24 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { _caller selectWeapon (primaryWeapon _caller); // unit always has a primary weapon here }; - if (isWeaponDeployed _caller) then { - TRACE_1("Weapon Deployed, breaking out first",(stance _caller)); - [_caller, "", 0] call EFUNC(common,doAnimation); - }; - - if ((stance _caller) == "STAND") then { - switch (_wpn) do {//If standing, end in a crouched animation based on their current weapon - case ("rfl"): {_caller setVariable [QGVAR(treatmentPrevAnimCaller), "AmovPknlMstpSrasWrflDnon"];}; - case ("pst"): {_caller setVariable [QGVAR(treatmentPrevAnimCaller), "AmovPknlMstpSrasWpstDnon"];}; - case ("non"): {_caller setVariable [QGVAR(treatmentPrevAnimCaller), "AmovPknlMstpSnonWnonDnon"];}; + if !(_caller call EFUNC(common,isSwimming)) then { + // Weapon on back also does not work underwater + if (isWeaponDeployed _caller) then { + TRACE_1("Weapon Deployed, breaking out first",(stance _caller)); + [_caller, "", 0] call EFUNC(common,doAnimation); }; - } else { - _caller setVariable [QGVAR(treatmentPrevAnimCaller), animationState _caller]; + + if ((stance _caller) == "STAND") then { + switch (_wpn) do {//If standing, end in a crouched animation based on their current weapon + case ("rfl"): {_caller setVariable [QGVAR(treatmentPrevAnimCaller), "AmovPknlMstpSrasWrflDnon"];}; + case ("pst"): {_caller setVariable [QGVAR(treatmentPrevAnimCaller), "AmovPknlMstpSrasWpstDnon"];}; + case ("non"): {_caller setVariable [QGVAR(treatmentPrevAnimCaller), "AmovPknlMstpSnonWnonDnon"];}; + }; + } else { + _caller setVariable [QGVAR(treatmentPrevAnimCaller), animationState _caller]; + }; + [_caller, _callerAnim] call EFUNC(common,doAnimation); }; - [_caller, _callerAnim] call EFUNC(common,doAnimation); }; //Get treatment time @@ -220,7 +223,7 @@ private _treatmentTime = if (isNumber (_config >> "treatmentTime")) then { DFUNC(treatment_failure), getText (_config >> "displayNameProgress"), _callbackProgress, - ["isnotinside"] + ["isNotInside", "isNotSwimming"] ] call EFUNC(common,progressBar); // Display Icon diff --git a/addons/medical/functions/fnc_treatment_failure.sqf b/addons/medical/functions/fnc_treatment_failure.sqf index 8ddd8c5cf2..fbd69dde5b 100644 --- a/addons/medical/functions/fnc_treatment_failure.sqf +++ b/addons/medical/functions/fnc_treatment_failure.sqf @@ -26,7 +26,7 @@ _args params ["_caller", "_target", "_selectionName", "_className", "_items", "_ if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; -if (vehicle _caller == _caller) then { +if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { private _lastAnim = _caller getVariable [QGVAR(treatmentPrevAnimCaller), ""]; //Don't play another medic animation (when player is rapidily treating) TRACE_2("Reseting to old animation", animationState player, _lastAnim); @@ -37,7 +37,6 @@ if (vehicle _caller == _caller) then { case "ainvppnemstpslaywpstdnon_medic": {_lastAnim = "AinvPpneMstpSlayWpstDnon"}; case "ainvpknlmstpslaywpstdnon_medic": {_lastAnim = "AmovPknlMstpSrasWpstDnon"}; }; - [_caller, _lastAnim, 2] call EFUNC(common,doAnimation); }; _caller setVariable [QGVAR(treatmentPrevAnimCaller), nil]; diff --git a/addons/medical/functions/fnc_treatment_success.sqf b/addons/medical/functions/fnc_treatment_success.sqf index 3984606e5f..37b5f8a51d 100644 --- a/addons/medical/functions/fnc_treatment_success.sqf +++ b/addons/medical/functions/fnc_treatment_success.sqf @@ -26,7 +26,7 @@ _args params ["_caller", "_target", "_selectionName", "_className", "_items", "_ if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; -if (vehicle _caller == _caller) then { +if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { private _lastAnim = _caller getVariable [QGVAR(treatmentPrevAnimCaller), ""]; //Don't play another medic animation (when player is rapidily treating) TRACE_2("Reseting to old animation", animationState player, _lastAnim); @@ -37,7 +37,6 @@ if (vehicle _caller == _caller) then { case "ainvppnemstpslaywpstdnon_medic": {_lastAnim = "AinvPpneMstpSlayWpstDnon"}; case "ainvpknlmstpslaywpstdnon_medic": {_lastAnim = "AmovPknlMstpSrasWpstDnon"}; }; - [_caller, _lastAnim, 2] call EFUNC(common,doAnimation); }; _caller setVariable [QGVAR(treatmentPrevAnimCaller), nil]; diff --git a/addons/medical/functions/fnc_unconsciousPFH.sqf b/addons/medical/functions/fnc_unconsciousPFH.sqf index 3c5609d85a..2f9d1a5522 100644 --- a/addons/medical/functions/fnc_unconsciousPFH.sqf +++ b/addons/medical/functions/fnc_unconsciousPFH.sqf @@ -23,7 +23,6 @@ #include "script_component.hpp" -private ["_unit", "_minWaitingTime", "_slotInfo", "_hasMovedOut", "_parachuteCheck", "_args", "_originalPos", "_startingTime", "_awakeInVehicleAnimation", "_oldVehicleAnimation", "_vehicle"]; params ["_args", "_idPFH"]; _args params ["_unit", "_originalPos", "_startingTime", "_minWaitingTime", "_hasMovedOut", "_parachuteCheck"]; @@ -37,7 +36,7 @@ if (!alive _unit) exitWith { if (GVAR(moveUnitsFromGroupOnUnconscious)) then { [_unit, false, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide); }; - [_unit, "setCaptive", "ace_unconscious", false] call EFUNC(common,statusEffect_set); + [_unit, "setHidden", "ace_unconscious", false] call EFUNC(common,statusEffect_set); [_unit, false] call EFUNC(common,disableAI); //_unit setUnitPos _originalPos; @@ -68,9 +67,9 @@ if !(_unit getVariable ["ACE_isUnconscious",false]) exitWith { [_unit,"amovppnemstpsnonwnondnon", 2] call EFUNC(common,doAnimation); }; } else { - _vehicle = vehicle _unit; - _oldVehicleAnimation = _unit getVariable [QGVAR(vehicleAwakeAnim), []]; - _awakeInVehicleAnimation = ""; + private _vehicle = vehicle _unit; + private _oldVehicleAnimation = _unit getVariable [QGVAR(vehicleAwakeAnim), []]; + private _awakeInVehicleAnimation = ""; if (((count _oldVehicleAnimation) > 0) && {(_oldVehicleAnimation select 0) == _vehicle}) then { _awakeInVehicleAnimation = _oldVehicleAnimation select 1; }; @@ -80,7 +79,7 @@ if !(_unit getVariable ["ACE_isUnconscious",false]) exitWith { } else { //Don't have a valid animation saved, reset the unit animation with a moveInXXX TRACE_1("No Valid Animation, doing seat reset", _awakeInVehicleAnimation); - _slotInfo = []; + private _slotInfo = []; {if ((_x select 0) == _unit) exitWith {_slotInfo = _x;};} forEach (fullCrew _vehicle); if (_slotInfo isEqualTo []) exitWith {ERROR("No _slotInfo?");}; //Move the unit out: @@ -105,7 +104,7 @@ if !(_unit getVariable ["ACE_isUnconscious",false]) exitWith { }; if (!_hasMovedOut) then { // Reset the unit back to the previous captive state. - [_unit, "setCaptive", "ace_unconscious", false] call EFUNC(common,statusEffect_set); + [_unit, "setHidden", "ace_unconscious", false] call EFUNC(common,statusEffect_set); // Swhich the unit back to its original group //Unconscious units shouldn't be put in another group #527: diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index d94fe3ae5a..55174bb84f 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -1,10 +1,10 @@ - + INJURIES VERLETZUNGEN - LESIONI + FERITE ТРАВМЫ BLESSURES OBRAŻENIA @@ -20,7 +20,7 @@ No injuries on this bodypart... Körperteil nicht verletzt... - Non ci sono lesioni in questa parte del corpo... + Non ci sono ferite in questa parte del corpo... Данная часть тела не повреждена... Aucune blessure ici... Brak obrażeń na tej części ciała... @@ -28,7 +28,7 @@ Ezen a testrészen nincs sérülés... Žádné zranění na této části těla... Nenhum ferimento nesta parte do corpo... - 怪我をしていない + この身体は怪我をしていません・・・ 이 부위에는 부상이 없습니다... 此身体部位没有受伤 此身體部位沒有受傷 @@ -44,7 +44,7 @@ Hulladékszimuláció részletessége Detalhe da simulação de sujeira Počet zobrazených předmětů po použití zdravotnického materiálu - 医療廃棄物を再現する詳細度 + 医療廃棄物シミュレーション詳細度 의료폐기물 재현 상세도 医疗废弃物模拟细节 醫療廢棄物模擬細節 @@ -60,10 +60,10 @@ A hulladékszimuláció részletessége megszabja a kliens által megjelenített hulladékobjektumok mennyiségét. Súlyos mennyiségek izolált területeken alacsony FPS-t okozhatnak, így ez egy kliensoldali beállítás. O nível de detalhe de sujeira determina o número de itens que irão aparecer no cliente. Quantidades excessivas em áreas locais podem aumentar o lag do FPS, então esta é uma opção somente para o cliente. Počet zobrazených předmětů po použití zdravotnického materiálu ovlivňuje počet objektů, které budou zobrazeny klientovi v místě použití zdravotnického materiálu. Vyšší množství objektů může způsobovat poklesy FPS a proto je toto nastavení čistě na klientovi. - 医療廃棄物再現度は各クライアントでローカルに作成される、医療廃棄物への詳細度を決定できます。ローカルで多くのアイテムがあると FPS の低下を引き起こすため、クライアント側のみの設定です。 + 医療廃棄物シミュレーションは各クライアントでローカルに作成される、医療廃棄物の詳細度を決定できます。ローカルで多くのアイテムがあると FPS の低下を引き起こすため、クライアント側のみの設定です。 의료폐기물 재현 상세도의 경우 얼마나 많은 수의 폐기물이 클라이언트 주변에 생성되는지를 정합니다. 매우 많은 수의 지역은 프레임드랍을 유발할 수 있습니다, 고로 이는 클라이언트 전용 설정입니다. - 设定医疗废弃物的最大产生数量, 过多的数量会导致画面更新率延迟, 因此这由用户端来设定 - 設定醫療廢棄物的最大產生數量, 過多的數量會導致畫面更新率延遲, 因此這由用戶端來設定 + 设定医疗废弃物的最大产生数量,过多的数量会导致画面更新率延迟,因此这由用户端来设定。 + 設定醫療廢棄物的最大產生數量,過多的數量會導致畫面更新率延遲,因此這由用戶端來設定。 Inject Adenosine @@ -315,7 +315,7 @@ Morfium beadása... Injetando Morfina... Inietto la morfina... - モルヒネを投与中・・・ + モルヒネを投与しています・・・ 모르핀 주사중... 吗啡注射中... 嗎啡注射中... @@ -331,7 +331,7 @@ Epinefrin beadása... Injetando Epinefrina... Inietto l'adrenalina... - アドレナリンを投与中・・・ + アドレナリンを投与しています・・・ 에피네프린 주사중... 肾上腺素注射中... 腎上腺素注射中... @@ -346,7 +346,7 @@ Aplikuji adenosine... Injetando Adenosina... Введение аденозина... - アドネシンを投与中・・・ + アドネシンを投与しています・・・ 아데노신 주사중... 腺苷注射中... 腺苷注射中... @@ -362,7 +362,7 @@ Atropin beadása... Inietto l'atropina... Injetando Atropina - アトロピンを投与中・・・ + アトロピンを投与しています・・・ 아트리핀 주사중... 阿托品注射中 ... 阿托品注射中 ... @@ -378,7 +378,7 @@ Infúzió vérrel... Transfundindo Sangue... Effettuo la trasfusione di sangue... - 輸血中・・・ + 輸血しています・・・ 혈액 수혈중... 输血液中 ... 輸血液中 ... @@ -394,7 +394,7 @@ Infúzió sós vizzel... Effettuo la rasfusione di soluzione salina Transfundindo Soro... - 生理食塩水を投与中・・・ + 生理食塩水を投与しています・・・ 생리식염수 수혈중... 施打生理食盐水中 ... 施打生理食鹽水中 ... @@ -410,7 +410,7 @@ Infúzió vérplazmával... Effettu la trasfusione di plasma... Transfundindo Plasma... - 血しょうを投与中・・・ + 血しょうを投与しています・・・ 혈장 수혈중... 输血浆中 ... 輸血漿中 ... @@ -586,7 +586,7 @@ Ez az orvosi lap nem tartalmaz bejegyzést. Žádné záznamy na tomto štítku Nenhuma entrada neste cartão de triagem - トリアージ カードには何も無い + トリアージ カードには何も無い。 부상자 분류 카드에 쓰여있는것이 없습니다. 此检伤分类卡上没有任何资料 此檢傷分類卡上沒有任何資料 @@ -650,7 +650,7 @@ Diagnózis folyamatban... Diagnostika... Diagnosticando... - 診断中・・・ + 診断しています・・・ 진단중... 诊断中... 診斷中... @@ -682,7 +682,7 @@ Újraélesztés folyamatban... Provádím CPR... Realizando o SBV... - 心肺蘇生を実行中・・・ + 心肺蘇生をしています・・・ 심폐소생중... 进行心肺复苏术中... 進行心肺復甦術中... @@ -1018,10 +1018,10 @@ Sok vért vesztett Ha perso parecchio sangue Perdeu muito sangue - 大量出血している - 많은 양의 혈액을 잃음 + 大量失血している 大量失血中 大量失血中 + 혈액 부족 Tourniquet [CAT] @@ -1050,10 +1050,10 @@ Infúzióra kötve [%1ml] Ricevendo EV [%1ml] Recebendo IV [%1ml] - IV [%1ml] を投与されている - IV로 [%1ml] 수혈중 + IV で [%1ml] 投与されている 接收静脉注射液中 [%1ml] 接收靜脈注射液中 [%1ml] + IV처리 [%1ml] 수혈중 Bandage (Basic) @@ -1098,10 +1098,10 @@ Una benda apposita, utilizzata per coprire una ferita, la quale viene applicata su di essa una volta fermata l'emorragia. Uma curativo, material específico para cobrir um ferimento que é aplicado assim que o sangramento é estancando. Obvaz je vhodným způsobem upravený sterilní materiál, určený k překrytí rány, případně k fixaci poranění. - 緊急圧迫包帯は、傷口を血液凝固剤でおおうようにできていて、つかうと出血の原因を取りさります。 + 緊急圧迫包帯は傷口を血液凝固剤でおおうようにできていて、つかうと出血の原因を取りさります。 드레싱, 출혈을 막고서 상처를 덮기위해 쓰는 물건입니다. - 用于覆盖伤口以防止出血, 透过敷料的止血剂来让出血慢慢停止. - 用於覆蓋傷口以防止出血, 透過敷料的止血劑來讓出血慢慢停止. + 用于覆盖伤口以防止出血,透过敷料的止血剂来让出血慢慢停止。 + 用於覆蓋傷口以防止出血,透過敷料的止血劑來讓出血慢慢停止。 Packing Bandage @@ -1132,8 +1132,8 @@ Používá se k zastavení středních až silnějších krvácení 弾性包帯は粘着フィルム状で、普通から大きめなケガにつかい止血します。 중형 또는 대형 상처를 채우고 출혈을 막기위해 쓰입니다 - 用于包扎中到大型伤口, 并防止出血 - 用於包紮中到大型傷口, 並防止出血 + 用于包扎中到大型伤口,并防止出血 + 用於包紮中到大型傷口,並防止出血 A bandage used to pack the wound to stem bleeding and facilitate wound healing. Packing a wound is an option in large polytrauma injuries. @@ -1146,10 +1146,10 @@ Ein Verband, um die Wunde abzudecken und die Wundheilung zu fördern. Wunden abdecken ist eine Option bei größeren Polytraumen Uma bandagem usada para preencher o ferimento para estancar o sangramento e facilitar a cicatrização. Preenchimento de feridas é uma opção em ferimentos de politrauma grandes. Tlakový obvaz se skládá se ze sterilní krycí vrstvy, na kterou je přiložena silná vrstva savého materiálu stlačující cévu v ráně a která je přitlačována k ráně a připevněna obinadlem. Slouží k zastavení silnějších krvácení. - 包帯をつかうと出血の原因を取りのぞき、それを促進させます。また大きめな多発性外傷にたいしても使えます。 + 包帯をつかうと出血を防ぎ治療を促進させます。また大きめな多発性外傷にたいしても使えます。 출혈을 막고 상처를 치유하기 위한 붕대. 다발성외상의 경우 상처를 채우는것도 한 가지 방법입니다. - 用于包扎中到大型伤口, 并防止出血, 为在大型多处性伤口的选项之一! - 用於包紮中到大型傷口, 並防止出血, 為在大型多處性傷口的選項之一! + 用于包扎中到大型伤口,并防止出血,为在大型多处性伤口的选项之一! + 用於包紮中到大型傷口,並防止出血,為在大型多處性傷口的選項之一! Bandage (Elastic) @@ -1196,8 +1196,8 @@ Hodí se k fixačním účelům a to i v oblastech kloubů. 負傷部分へ最大の対応と止血を続けられます。 부상 부위를 골고루 압박해주면서 동시에 고정시켜 줍니다. - 可对伤口持续压迫并固定以防止伤口情况变严重. - 可對傷口持續壓迫並固定以防止傷口情況變嚴重. + 可对伤口持续压迫并固定以防止伤口情况变严重 + 可對傷口持續壓迫並固定以防止傷口情況變嚴重 Tourniquet (CAT) @@ -1226,7 +1226,7 @@ Rallenta la perdita di sangue in caso di sanguinamento Reduz a velocidade da perda de sangue Zpomaluje ztráty krve při krvácení - 出血しているときに、流れ出る量をへらします。 + 出血しているときに、失血量をおさえます。 출혈 시 혈액손실을 늦춰줍니다 减缓失血的速度 減緩失血的速度 @@ -1244,8 +1244,8 @@ Zařízení používané ke stlačení venózního a arteriálního oběhu. V důsledku dochází ke zpomalení toku krve a tedy i snížení ztrát krve. 止血帯は静脈や動脈へ圧力をかけ、循環を遅らせることで血液の流れをおそくし、失血を防ぎます。 정맥과 동맥을 압축시키켜 혈액순환을 억제 혹은 늦추게하여 혈액손실을 줄이는 도구입니다. - 用于压迫静脉与动脉的血液流动, 达到减缓失血速度的目的. - 用於壓迫靜脈與動脈的血液流動, 達到減緩失血速度的目的. + 用于压迫静脉与动脉的血液流动,达到减缓失血速度的目的。 + 用於壓迫靜脈與動脈的血液流動,達到減緩失血速度的目的。 Morphine autoinjector @@ -1258,7 +1258,7 @@ Morfium autoinjektor Autoiniettore di morfina Auto-injetor de morfina - モルヒネ + モルヒネ注射器 모르핀 자동주사기 吗啡自动注射器 嗎啡自動注射器 @@ -1292,8 +1292,8 @@ Analgetikum slouží k tlumení středně těžkých a těžkých bolestí 戦闘が収まったとき、モルヒネを痛みにたいしてつかいます。 심한 통증을 완화하기 위해 쓰이는 진통제입니다. - 止痛药的一种, 用于减低中度至重度的疼痛感. - 止痛藥的一種, 用於減低中度至重度的疼痛感. + 止痛药的一种,用于减低中度至重度的疼痛感。 + 止痛藥的一種,用於減低中度至重度的疼痛感。 Adenosine autoinjector @@ -1305,7 +1305,7 @@ Auto-adenosine Auto-injetor de Adenosina Аденозин в пневмошприце - アデノシン + アデノシン注射器 아데노신 자동주사기 腺苷自动注射器 腺苷自動注射器 @@ -1351,7 +1351,7 @@ Atropin autoinjektor Autoiniettore di atropina Auto-injetor de Atropina - アトロピン + アトロピン注射器 아트로핀 자동주사기 阿托品自动注射器 阿托品自動注射器 @@ -1367,7 +1367,7 @@ Usato in situazioni con gas nervino. Usado em casos de ataque QBRN Používá se v přítomnosti nervových plynů - 核・生物・化学兵器がつかわれている条件下にてつかいます。 + 核・生物・化学兵器によ汚染環境下にてつかいます。 핵,생물,화학 상황에 쓰입니다 使用于核生化污染的情况 使用於核生化汙染的情況 @@ -1385,8 +1385,8 @@ Atropin slouží jako protijed na otravu organofosfátovými insekticidy (diazinon) a nervovými plyny. 核・生物・化学兵器がつかわれている条件下にてつかいます。 핵,생물,화학 상황에 쓰이는 군용 약품 - 军用神经解毒针, 用来应付核生化污染的情况. - 軍用神經解毒針, 用來應付核生化汙染的情況. + 军用神经解毒针,用来应付核生化污染的情况。 + 軍用神經解毒針,用來應付核生化汙染的情況。 Epinephrine autoinjector @@ -1399,7 +1399,7 @@ Epinefrin autoinjektor Autoiniettore di adrenalina Auto-injetor de epinefrina - アドレナリン + アドレナリン注射器 에피네프린 자동주사기 肾上腺素自动注射器 腎上腺素自動注射器 @@ -1433,8 +1433,8 @@ Zúžení periferních cév díky působení na alfa receptory a následné kontrakci hladkých svalů, tím dochází k tzv. centralizaci oběhu, krev se soustřeďuje v životně důležitých centrálních orgánech (srdce, mozek, plíce), působí také pozitivně na srdeční činnost a dochází ke zvýšení krevního tlaku a tepu. Dále se používá při náhlé srdeční zástavě. 薬は気管支を拡張するよう交感神経を拡張させ、心拍数を増加させます。それにアレルギー反応を収める効果もあります(アナフィラキシー ショック)。得られる効果は少ないですが、心停止している場合などにつかわれます。 기관지를 확장시키는 교감 신경 반응을 이끌어내는 약물로써, 심박을 높이고 알러지 효과에 대응합니다(아나필락시스). 심폐가 정지하는 경우 호전이 되지않을때 사용합니다. - 俗称强心针, 为一种支气管扩张药物, 会增加心跳速率并减缓过敏反应(过敏性休克), 在心跳骤停时有恢复心跳的效果! - 俗稱強心針, 為一種支氣管擴張藥物, 會增加心跳速率並減緩過敏反應(過敏性休克), 在心跳驟停時有恢復心跳的效果! + 俗称强心针,为一种支气管扩张药物,会增加心跳速率并减缓过敏反应(过敏性休克),在心跳骤停时有恢复心跳的效果! + 俗稱強心針,為一種支氣管擴張藥物,會增加心跳速率並減緩過敏反應(過敏性休克),在心跳驟停時有恢復心跳的效果! Plasma IV (1000ml) @@ -1543,10 +1543,10 @@ Blut IV, Bluthaushalt des Patienten wiederherstellen. (Kühl halten) Sangue intravenoso, para restaurar o volume sanguinio do paciente.(Manter frio) Krevní transfuze pro doplnění pacientovi krve (skladujte v chladu) - 血液 IV は、患者へ血液を補給します。(要低温保存) + 血液 IV は、患者へ血液を補給します。(要低温保存) 혈액 IV, 환자에게 혈액을 공급합니다. (차갑게 할것) - 血液, 用于补充伤者流失的血液 (需冷藏) - 血液, 用於補充傷者流失的血液 (需冷藏) + 血液,用于补充伤者流失的血液 (需冷藏) + 血液,用於補充傷者流失的血液 (需冷藏) O Negative infusion blood used in strict and rare events to replenish blood supply usually conducted in the transport phase of medical care. @@ -1561,8 +1561,8 @@ 0 Rh negativní krev se používá v vzácných případech k doplnění pacientovy hladiny krve, obvykle při převozu zraněné osoby do nemocnice. O 型への輸血はまれで厳格であり、通常は治療のための輸送段階で輸血をおこないます。 O- 형 혈액 투여는 매우 엄격하고 드문 혈액보급의 경우에 쓰이는데 주로 치료의 운송단계에서 사용됩니다. - O型负值注射用血液, 在紧急情况时使用, 用于补充伤者流失的血液 - O型負值注射用血液, 在緊急情況時使用, 用於補充傷者流失的血液 + O型负值注射用血液,在紧急情况时使用,用于补充伤者流失的血液。 + O型負值注射用血液,在緊急情況時使用,用於補充傷者流失的血液。 Blood IV (500ml) @@ -1625,8 +1625,8 @@ Fyziologický roztok se aplikuje intravenózně a slouží k obnově pacientovi krve 生理食塩水 IV は、患者の血液量を補助します 생리식염수, 환자의 혈액량을 보충할때 쓰입니다 - 生理食盐水, 用于恢复伤者血液 - 生理食鹽水, 用於恢復傷者血液 + 生理食盐水,用于恢复伤者血液 + 生理食鹽水,用於恢復傷者血液 A medical volume-replenishing agent introduced into the blood system through an IV infusion. @@ -1641,8 +1641,8 @@ Fyziologický roztok se využívá nejčastěji jako infuze při dehydrataci organismu. 生理食塩水 IV を静脈へ投与し、血液量を増加させることができます。 혈류에 IV로 투여되는 의료 용적 대체 요법 - 利用静脉注射进入人体血液系统, 帮助伤者血液恢复 - 利用靜脈注射進入人體血液系統, 幫助傷者血液恢復 + 利用静脉注射进入人体血液系统,帮助伤者血液恢复。 + 利用靜脈注射進入人體血液系統,幫助傷者血液恢復。 Saline IV (500ml) @@ -1703,7 +1703,7 @@ Bendaggio emostatico (QuikClot) Bandagem com agente coagulante Hemostatický obvaz (QuikClot) - クイッククロット + クイッククロット包帯 퀵 클롯 붕대 止血粉绷带 止血粉繃帶 @@ -1721,8 +1721,8 @@ Hemostatický obvaz určený k zástavě krvácení 血液凝固剤をふくむ包帯により、止血できます。 지혈시 사용하는 붕대로 혈액 응고제를 포함하고있습니다. - 包含止血粉成分的止血绷带, 可用于止血 - 包含止血粉成分的止血繃帶, 可用於止血 + 包含止血粉成分的止血绷带,可用于止血。 + 包含止血粉成分的止血繃帶,可用於止血。 Personal Aid Kit @@ -1753,8 +1753,8 @@ Osobní lékárnička obsahuje zdravotnický materiál umožňující šití a pokročilejší ošetřování raněných 縫合や高度な処置に必要とされる、さまざまな治療器具が含まれています。 봉합및 고급 조치에 필요한 다양한 치료 도구가 있습니다. - 包含各种医疗套件, 以及进阶伤口系统需要的缝合用品. - 包含各種醫療套件, 以及進階傷口系統需要的縫合用品. + 包含各种医疗套件,以及进阶伤口系统需要的缝合用品 + 包含各種醫療套件,以及進階傷口系統需要的縫合用品 Personal Aid Kit for in field stitching or advanced treatment @@ -1769,8 +1769,8 @@ Pronto soccorso personale da campo per mettersi i punti o per trattamenti avanzati. 戦場で縫合や高度な処置に必要とされる、さまざまな治療器具が含まれています。 야전에서 봉합및 고급 조치를 위한 개인응급키트 - 个人急救包可用于战地缝合手术或进阶伤口系统使用. - 個人急救包可用於戰地縫合手術或進階傷口系統使用. + 个人急救包可用于战地缝合手术或进阶伤口系统使用 + 個人急救包可用於戰地縫合手術或進階傷口系統使用 Use Personal Aid Kit @@ -1817,8 +1817,8 @@ Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli 縫合キットは戦場で高度な処置をするためにつかわれます。 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 - 用于在战场上为伤口进行缝合(需要开启进阶伤口系统). - 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統). + 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) + 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) Surgical Kit for in field advanced medical treatment @@ -1833,8 +1833,8 @@ Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli 縫合キットは戦場で高度な処置をするためにつかわれます。 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 - 用于在战场上为伤口进行缝合(需要开启进阶伤口系统). - 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統). + 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) + 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) Use Surgical Kit @@ -1864,9 +1864,9 @@ Saco para cadáver Pytel na mrtvoly 死体袋 - 시체 가방 尸袋 屍袋 + 시체 운반 가방 A bodybag for dead bodies @@ -1927,7 +1927,7 @@ Controllando la pressione sanguigna.. Aferindo Pressão Arterial... Měřím krevní tlak... - 血圧を測定中・・・ + 血圧を測定しています・・・ 혈압 측정증... 检查血压中... 檢查血壓中... @@ -1992,9 +1992,9 @@ Pressão Arterial baixa Naměřil si nízký krevní tlak 血圧はかなり低い - 혈압이 매우 낮다 发现到低血压 發現到低血壓 + 혈압이 낮음 You find a normal blood pressure @@ -2008,9 +2008,9 @@ Pressão Arterial normal Naměřil si normální krevní tlak 血圧は通常 - 혈압이 정상이다 发现到正常血压 發現到正常血壓 + 혈압이 정상 You find a high blood pressure @@ -2024,9 +2024,9 @@ Pressão Arterial Alta Naměřil si vysoký krevní tlak 血圧はかなり高い - 혈압이 매우 높다 发现到高血压 發現到高血壓 + 혈압이 높음 You find no blood pressure @@ -2151,7 +2151,7 @@ Controllando il battito cardiaco... Aferindo Pulso... Kontroluji srdeční tep... - 心拍数を測定中・・・ + 心拍数を測定しています・・・ 맥박 확인중... 检查心跳中... 檢查心跳中... @@ -2264,9 +2264,9 @@ A Freqüência Cardíaca é de %2 Nahmatal jsi srdeční tep u %2 心拍数は %2 - 맥박이 %2 이다 心跳为%2 心跳為%2 + 맥박 %2 You find a weak Heart Rate @@ -2280,9 +2280,9 @@ Freqüência Cardíaca baixa Nahmatal si slabý srdeční puls 自分の心拍数は低い - 약한 맥박이다 心跳微弱 心跳微弱 + 약한 맥박 You find a strong Heart Rate @@ -2296,9 +2296,9 @@ Freqüência Cardíaca normal Nahmatal si silný srdeční puls 自分の心拍数は強い - 강한 맥박이다 心跳过快 心跳過快 + 강한 맥박 You find a normal Heart Rate @@ -2312,9 +2312,9 @@ Freqüência Cardíaca alta Nahmatal si normální srdeční puls 自分の心拍数は通常 - 보통 맥박이다 心跳正常 心跳正常 + 보통 맥박 You find no Heart Rate @@ -2328,9 +2328,9 @@ Sem Freqüência Cardíaca Žádný puls 心拍数を測れなかった - 맥박을 찾을 수가 없다 量不到心跳 量不到心跳 + 맥박 없음 Response @@ -2376,9 +2376,9 @@ %1 está respondendo %1 odpovídá %1 は反応あり - %1 은 반응이있다 %1 有反应 %1 有反應 + %1 은 반응이 있다 %1 is not responsive @@ -2392,9 +2392,9 @@ %1 não está respondendo %1 neodpovídá %1 の反応なし - %1 은 반응이없다 %1 没有反应 %1 沒有反應 + %1 은 반응이 없다 You checked %1 @@ -2423,7 +2423,7 @@ A páciens, %1,<br/>%2.<br/>%3.<br/>%4 Pacient %1<br/>je %2.<br/>%3.<br/>%4 Paciente %1<br/>é %2.<br/>%3.<br/>%4 - 痛み %1<br/>は %2.<br/>%3.<br/>%4 + 患者 %1<br/>は %2.<br/>%3.<br/>%4 환자 %1<br/>는 %2.<br/>%3.<br/>%4 伤者 %1<br/>is %2.<br/>%3.<br/>%4 傷者 %1<br/>is %2.<br/>%3.<br/>%4 @@ -2487,7 +2487,7 @@ Ztratil hodně krve Ele perdeu muito sangue Ha perso molto sangue - 彼は大量出血している + 彼は大量失血している 많은 양의 피를 잃었다 他流失大量血液 他流失大量血液 @@ -2503,7 +2503,7 @@ Nem vesztett vért Neztratil žádnou krev Ele não perdeu sangue - 彼は出血していない + 彼は失血していない 피를 잃지 않았다 他并没有失血 他並沒有失血 @@ -2583,7 +2583,7 @@ %1 verbindet dich %1 está aplicando uma bandagem em você %1 tě obvazuje - %1 は自分に包帯を巻いている + %1 はあなたに包帯を巻いている %1 (이)가 나에게 붕대를 감고있다 %1 正在对你包扎绷带中 %1 正在對你包紮繃帶中 @@ -2615,7 +2615,7 @@ Suturando Suturando Šití - 縫合 + 縫合中 붕합중 缝合中 縫合中 @@ -2807,7 +2807,7 @@ Stai mettendo il corpo nella sacca... Colocando corpo dentro do saco para cadáver... Umístňuji tělo do pytle na mrtvoly... - 死体袋へ梱包中・・・ + 死体袋へ入れています・・・ 시체 가방에 담는중... 将尸体放入尸袋中... 將屍體放入屍袋中... @@ -2824,9 +2824,9 @@ %1 aplicou bandagem no paciente %1 již obvázal pacienta %1 は包帯を巻いた - %1 (이)가 붕대를 감아줬다 %1 已包扎伤者 %1 已包紮傷者 + %1 (이)가 붕대를 감음 %1 performed CPR @@ -2839,9 +2839,9 @@ %1 realicó RCP %1 à fait une RCP %1 は心肺蘇生をした - %1 (이)가 심폐소생술을 실시했다 %1 已执行心肺复苏术 %1 已執行心肺復甦術 + %1 (이)가 심폐소생술을 실시함 %1 used %2 @@ -2855,9 +2855,9 @@ %1 usou %2 %1 použil %2 %1 は %2 をつかった - %1 (이)가 %2 을 썼다 %1 已使用 %2 %1 已使用 %2 + %1 (이)가 %2 을 사용함 %1 has given an IV @@ -2870,10 +2870,10 @@ %1 ha somministrato una EV %1 aplicou um intravenoso %1 již aplikoval IV - %1 は IV を与えた - %1 (이)가 IV를 실시했다 + %1 は IV をした %1 已经给予静脉注射液 %1 已經給予靜脈注射液 + %1 (이)가 IV를 실시함 %1 applied a tourniquet @@ -2887,9 +2887,9 @@ %1 aplicou um torniquete %1 použil škrtidlo %1 は止血帯を巻いた - %1 (이)가 지혈대를 적용했다 %1 已经绑上止血带 %1 已經綁上止血帶 + %1 (이)가 지혈대를 적용함 %1 used Personal Aid Kit @@ -2902,9 +2902,9 @@ %1 usó Kit de Primeros Auxilios %1 a utilisé une trousse %1 は応急処置キットをつかった - %1 (이)가 개인응급키트를 사용했다 %1 已使用了个人急救包 %1 已使用了個人急救包 + %1 (이)가 개인응급키트를 사용함 Heavily wounded @@ -3077,9 +3077,9 @@ Боль приглушается только временно Dolore è soppresso solo temporaneamente 痛みは一時的な影響 - 고통은 일시적으로만 회복가능 疼痛只会暂时性压制 疼痛只會暫時性壓制 + 고통은 일시적으로만 회복 Pain Effect Type @@ -3172,7 +3172,7 @@ Választékok (3D) 3D výběr Selezione (3D) - 選択 (3d) + 選択 (3D) 선택 (3d) 选择 (3D) 選擇 (3D) @@ -3732,7 +3732,7 @@ Tratando... Ošetřuji... Curando... - 治療中・・・ + 治療しています・・・ 치료중... 治疗中... 治療中... @@ -3748,7 +3748,7 @@ Sundavám škrtidlo... Снятие жгута... Togliendo il laccio emostatico... - 止血帯を外している・・・ + 止血帯を外しています・・・ 지혈대 제거중... 移除军用止血带中... 移除軍用止血帶中... @@ -3812,7 +3812,7 @@ Quel niveau de simulation médicale choisissez-vous? Milyen komplex legyen az orvosi szimuláció? Qual'è il livello di simulazione medica? - 治療の再現度は? + 治療の再現度は? 의료 시뮬레이션의 수준 选择需要的医疗模拟等级 選擇需要的醫療模擬等級 @@ -3876,10 +3876,10 @@ Quel niveau de détail voulez-vous pour les infirmiers? Mi a javasolt részletesség orvosok számára? Qual'è il livello di dettagli preferito per i medici? - >衛生兵への再現度をどのくらいに設定しますか? + 衛生兵への再現度をどのくらいに設定しますか? 의무병의 시뮬레이션 정도? - 设定医护兵的预设医疗水平(医疗兵, 军医) - 設定醫護兵的預設醫療水平(醫療兵, 軍醫) + 设定医护兵的预设医疗水平(医疗兵,军医) + 設定醫護兵的預設醫療水平(醫療兵,軍醫) Locations boost training @@ -3892,9 +3892,9 @@ Le lieu améliore l'efficacité Места ускоренного обучения 衛生兵としての能力を与える場所 - 교육 증가 지역 受所在位置影响提升医疗能力 受所在位置影響提升醫療能力 + 의료 효과 증가 지역 Boost medic rating in medical vehicles or near medical facilities [untrained becomes medic, medic becomes doctor] @@ -3906,10 +3906,10 @@ Aumenta a classificação do médico dentro de veículos médicos ou perto de instalações médicas [sem treinamento vira médico, médico vira doutor] Améliore l'efficacité des soins dans les véhicules ou structures de soins [non formés deviennent médecins, médecins deviennent docteurs] Улучшает медицинскую подготовку в мед. транспорте и около мед. строений [нетренированные становятся медиками, медики становятся врачами] - 医療車両や医療施設の近くは衛生兵としての能力を与える場所となり、衛生兵の訓練を受けていないのに衛生兵としてなる(未訓練は衛生兵に、衛生兵は医師に) + 医療車両や医療施設の近くは衛生兵としての能力を与える場所となり、衛生兵の訓練を受けていないのに衛生兵としてなる (未訓練は衛生兵に、衛生兵は医師に) 의무병의 수준이 주변의 차량이나 의료시설에 따라 증가합니다. [비교육자가 의무병이되고, 의무병이 의사가 됩니다] - 当人员在医疗载具或是医护设施旁进行医疗时, 该员医疗能力将会有所提升 (未受训人员提升为医疗兵, 医疗兵提升为军医) - 當人員在醫療載具或是醫護設施旁進行醫療時, 該員醫療能力將會有所提升 (未受訓人員提升為醫療兵, 醫療兵提升為軍醫) + 当人员在医疗载具或是医护设施旁进行医疗时,该员医疗能力将会有所提升 (未受训人员提升为医疗兵,医疗兵提升为军医) + 當人員在醫療載具或是醫護設施旁進行醫療時,該員醫療能力將會有所提升 (未受訓人員提升為醫療兵,醫療兵提升為軍醫) Disable medics @@ -3956,8 +3956,8 @@ Abilita la creazione della barella dopo trattamento 治療を始めると、医療廃棄物の作成を有効化する 의료폐기물이 치료중 주변에 생성되는것을 활성화 합니다 - 本功能启用后, 当每次医疗动作结束时, 地上会产生相应的医疗废弃物 - 本功能啟用後, 當每次醫療動作結束時, 地上會產生相應的醫療廢棄物 + 本功能启用后,当每次医疗动作结束时,地上会产生相应的医疗废弃物 + 本功能啟用後,當每次醫療動作結束時,地上會產生相應的醫療廢棄物 Life time of litter objects @@ -3986,10 +3986,10 @@ Combien de temps doivent rester affiché les détritus? En secondes. -1 pour tout le temps Milyen sokáig legyenek jelen a szemétobjektumok (másodpercben)? A -1 végtelen időt jelent. Per quanto devono restare le barelle? In secondi. -1 è permanente - 医療廃棄物オブジェクトが表示されつづける時間を設定しますか?-1 は永遠です。 + 医療廃棄物オブジェクトが表示されつづける時間を設定しますか? -1 は永遠です。 얼마동안 폐기물이 존재합니까? 초 단위. -1 은 영구적. - 定义医疗废弃物存在时间, 以秒为单位, -1为永远存在. - 定義醫療廢棄物存在時間, 以秒為單位, -1為永遠存在. + 定义医疗废弃物存在时间,以秒为单位,-1为永远存在。 + 定義醫療廢棄物存在時間,以秒為單位,-1為永遠存在。 Enable Screams @@ -4050,7 +4050,7 @@ Quels dégâts peut subir un joueur avant d'être tué Mennyi sérülést szenvedhet el egy játékos, mielőtt meghal? Quanto è il danno che un giocatore può sostenere prima di essere ucciso? - プレイヤーが死に始める前に損傷を受けるようにしますか? + プレイヤーが死に始める前に損傷を受けるようにしますか? 얼마정도의 부상을 플레이어가 죽기 전까지 버틸 수 있습니까? 玩家死亡前所能承受的伤害程度 玩家死亡前所能承受的傷害程度 @@ -4082,7 +4082,7 @@ Quels dégâts peut subir une IA avant d'être tuée Mennyi sérülést szenvedhet el egy AI, mielőtt meghal? Quanto è il danno che un'IA può sostenere prima di essere uccisa? - AI が死に始める前に損傷を受けるようにしますか? + AI が死に始める前に損傷を受けるようにしますか? 얼마정도의 부상을 인공지능이 죽기 전까지 버틸 수 있습니까? AI 死亡前所能承受的伤害程度 AI 死亡前所能承受的傷害程度 @@ -4146,7 +4146,7 @@ Távvezérelt egységek AI-ként, nem játékosként való kezelése? Обрабатывать дистанционно управляемых юнитов как ботов, а не как игроков? Considera le unità controllate in remoto come IA e non come giocatori? - 遠隔操作された AI は、非プレイヤーとして扱いますか? + 遠隔操作された AI は、非プレイヤーとして扱いますか? 원격 조작하는 AI는 비 플레이어로 취급합니까? 以医疗AI的方式医疗被遥控的单位 以醫療AI的方式醫療被遙控的單位 @@ -4180,8 +4180,8 @@ Imposta un'unità come incosciente invece di morta ユニットの即死を防止するために、気絶へ移行させます 인원의 즉사를 방지코자 즉사 대신 기절시킵니다 - 伤者最严重只会立即进入昏迷, 而非立即死亡 - 傷者最嚴重只會立即進入昏迷, 而非立即死亡 + 伤者最严重只会立即进入昏迷,而非立即死亡 + 傷者最嚴重只會立即進入昏迷,而非立即死亡 Bleeding coefficient @@ -4276,8 +4276,8 @@ Mantieni lo stato delle unità sincronizzato. Consigliato attivo. ユニット状態の同期を続けます。有効化を推奨。 인원의 상태를 동기화합니다. 켜기를 권장합니다. - 保持单位状态同步, 建议启用! - 保持單位狀態同步, 建議啟用! + 保持单位状态同步,建议启用! + 保持單位狀態同步,建議啟用! Provides a medical system for both players and AI. @@ -4292,8 +4292,8 @@ Fornisce un sistema medico sia per giocatori che IA. プレイヤーと AI の両方へ医療システムを提供します。 의료 시스템을 플레이어 및 인공지능에게 제공합니다. - 医疗系统将同时对玩家与AI发生作用 - 醫療系統將同時對玩家與AI發生作用 + 医疗系统将同时对玩家与AI发生作用。 + 醫療系統將同時對玩家與AI發生作用。 Basic Medical Settings [ACE] @@ -4417,7 +4417,7 @@ Les plaies peuvent se rouvrir Visszanyílhatnak a bekötözött sebek? Permetti la riapertura di ferite bendate? - 包帯で巻かれた傷を再び開くようにしますか? + 包帯で巻かれた傷を再び開くようにしますか? 붕대가 풀리는것을 활성화합니까? 启用进阶伤口系统会使已被包扎的伤口有机率裂开 啟用進階傷口系統會使已被包紮的傷口有機率裂開 @@ -4449,7 +4449,7 @@ Les unités subissent des dégats lors d'accident Sérülnek-e az egységek autós ütközés során? Le unità sostengono danni da incidenti con veicoli? - ユニットは車両の衝突による損傷を受けるようにしますか? + ユニットは車両の衝突による損傷を受けるようにしますか? 차량 사고시 인원들이 부상을 입습니까? 设定人员是否会因为载具冲撞别的物件而产生伤害? 設定人員是否會因為載具衝撞別的物件而產生傷害? @@ -4479,7 +4479,7 @@ Kdo může použít adrenalin k úplnému vyléčení? (Pouze základní zdravotní systém) Quem pode usar Epinefrina para cura completa? (Somente sistema médico básico) Кому разрешено использовать адреналин для полного излечения? (Только для базовой медицины) - 完全に回復できるよう誰しもがアドレナリンを使えるようにしますか?(ベーシック医療のみ) + 完全に回復できるよう誰しもがアドレナリンを使えるようにしますか? (ベーシック医療のみ) 완전한 체력회복을 위해 어느 인원이 에피네프린을 쓸 수 있습니까? (기본 의료 전용) 谁可以使用肾上腺素完整医治? (仅适用于基本医疗) 誰可以使用腎上腺素完整醫治? (僅適用於基本醫療) @@ -4511,7 +4511,7 @@ Qui peut utilier la trousse sanitaire pour des soins complets? Ki használhatja az elsősegélycsomagot teljes gyógyításra? Chi può usare il KPS per cura completa? - 完全に回復できるよう誰しもが応急処置キットを使えるようにしますか? + 完全に回復できるよう誰しもが応急処置キットを使えるようにしますか? 완전한 체력회복을 위해 어느 인원이 개인응급키트을 쓸 수 있습니까? (기본 의료 전용) 谁能够使用个人急救包来达到完整医疗? 誰能夠使用個人急救包來達到完整醫療? @@ -4591,7 +4591,7 @@ La trousse sanitaire doit être consommée à l'utilisation? Eltávolítódjon az elsősegélycsomag használatkor? Il Kit Pronto Soccorso dev'essere rimosso dopo l'utilizzo? - 応急処置キットを使うと削除しますか? + 応急処置キットを使うと削除しますか? 개인응급키트를 사용하고 나서 제거합니까? 要在使用后删除个人急救包吗? 要在使用後刪除個人急救包嗎? @@ -4621,7 +4621,7 @@ Kde může být použit adrenalin? (Pouze základní zdravotní systém) Onde pode-se usar a Epinefrina? (Somente sistema médico básico) Где может использоваться адреналин? (Базовая медицина) - どこでもアドレナリンをつかえるようにしますか?(ベーシック医療のみ) + どこでもアドレナリンをつかえるようにしますか? (ベーシック医療のみ) 어디에서 에피네프린을 사용할 수 있습니까? (기본 의료) 在哪里可以使用肾上腺素? (基本医疗) 在哪裡可以使用腎上腺素? (基本醫療) @@ -4653,7 +4653,7 @@ Où la trousse sanitaire peut être utilisée ? Hol lehet az elsősegélycsomagot használni? Dove può essere usato il Kit Pronto Soccorso? - どこでも応急処置キットをつかえるようにしますか? + どこでも応急処置キットをつかえるようにしますか? 어디에서 개인응급키트를 사용할 수 있습니까? 在哪里可以使用个人急救包? 在哪裡可以使用個人急救包? @@ -4685,7 +4685,7 @@ Onde o kit de primeiros socorros pode ser utilizado? Когда может использоваться аптечка? Quando può essere usato il Kit Pronto Soccorso? - どこでも応急処置キットをつかえるようにしますか? + どこでも応急処置キットをつかえるようにしますか? 언제 개인응급키트를 사용할 수 있습니까? 何时可以使用个人急救包? 何時可以使用個人急救包? @@ -4781,7 +4781,7 @@ Qui peut utiliser les trousses chirurgicales? Ki használhatja a sebészkészletet? Chi può usare il Kit Chirurgico? - だれでも縫合キットをつかえるようにしますか? + だれでも縫合キットをつかえるようにしますか? 어느 인원이 봉합키트를 사용할 수 있습니까? 谁能够使用手术包? 誰能夠使用手術包? @@ -4813,7 +4813,7 @@ La trousse chirurgicale doit être consommée à l'utilisation? Eltávolítódjon a sebészkészlet használatkor? Il Kit Chirurgico dev'essere rimosso dopo l'uso? - 縫合キットをつかった後に削除しますか? + 縫合キットをつかった後に削除しますか? 봉합키트를 사용하고 나서 제거합니까? 手术包会在使用后被删除吗? 手術包會在使用後被刪除嗎? @@ -4845,7 +4845,7 @@ Où peut être utilisé les trousses chirurgicales? Hol lehet a sebészkészletet használni? Dove può essere usato il Kit Chirurgico? - どこでも縫合キットをつかえるようにしますか? + どこでも縫合キットをつかえるようにしますか? 어디에서 봉합키트를 사용할 수 있게 합니까? 定义手术包可被使用的地方? 定義手術包可被使用的地方? @@ -4877,7 +4877,7 @@ Onde o kit cirúrgico pode ser utilizado? Когда может использоваться хирургический набор? Quando può essere usato il Kit Chirurgico? - いつでも縫合キットをつかえるようにしますか? + いつでも縫合キットをつかえるようにしますか? 언제 봉합키트를 사용할 수 있습니까? 何时可以使用手术工具包? 何時可以使用手術工具包? @@ -4941,8 +4941,8 @@ Dolore è solo temporaneamente soppresso, non rimosso 痛みを一時的に継続させ、取り除かない 고통은 제거가 아닌 일시적으로 억제만 가능합니다. - 疼痛只会被暂时抑制, 而不能完全消除 - 疼痛只會被暫時抑制, 而不能完全消除 + 疼痛只会被暂时抑制,而不能完全消除 + 疼痛只會被暫時抑制,而不能完全消除 Configure the treatment settings from ACE Basic Medical @@ -5083,8 +5083,8 @@ Numero massimo di vite di un'unità. 0 o -1 per disabilitare. ユニットの最大リバイブ数を設定できます。0 または -1 は無効化になります 소생 가능한 횟수입니다. 0 혹은 -1 로 비활성화 합니다 - 一个人员最大可被救活次数, 0或-1为关闭 (无限救活). - 一個人員最大可被救活次數, 0或-1為關閉 (無限救活). + 一个人员最大可被救活次数,0或-1为关闭 (无限救活) + 一個人員最大可被救活次數,0或-1為關閉 (無限救活) Provides a medical system for both players and AI. @@ -5147,8 +5147,8 @@ Lista di nomi unità che verranno classificati come medici, separati da virgole. 衛生兵として設定されるユニット名を一覧で指定でき、コンマで区切りを付けられます。 보직 이름 목록으로 의무병이 구분됩니다, 쉼표로 구분. - 列出的单位名字将被指派为医疗兵, 记得用逗号隔开! - 列出的單位名字將被指派為醫療兵, 記得用逗號隔開! + 列出的单位名字将被指派为医疗兵,记得用逗号隔开! + 列出的單位名字將被指派為醫療兵,記得用逗號隔開! Is Medic @@ -5179,8 +5179,8 @@ Questo modulo ti permette di assegnare la classe Medico alle unità selezionate. 選択されたユニットを衛生兵として指定します。 이 모듈은 선택한 보직이 의무병을 할 수 있게 해줍니다. - 本模块可让被同步的单位成为医疗兵. - 本模塊可讓被同步的單位成為醫療兵. + 本模块可让被同步的单位成为医疗兵 + 本模塊可讓被同步的單位成為醫療兵 None @@ -5307,8 +5307,8 @@ Lista di veicoli che verranno classificati come veicoli medici, separati da virgole. 医療車両として設定されるクラス名を一覧で指定でき、コンマで区切りを付けられます 차량 명칭 목록으로 의료차량이 구분됩니다, 쉼표로 구분. - 列出的载具将被指定为医疗载具, 记得用逗号隔开! - 列出的載具將被指定為醫療載具, 記得用逗號隔開! + 列出的载具将被指定为医疗载具,记得用逗号隔开! + 列出的載具將被指定為醫療載具,記得用逗號隔開! Is Medical Vehicle @@ -5354,9 +5354,9 @@ Hozzárendeli az ACE orvosi jelzőt egy egységhez Assegna la classe medico ACE ad un'unità ユニットを ACE の衛生兵として割り当てる - 차량에 ACE 의무병 보직 선정 指派ACE医疗职位给该单位 指派ACE醫療職位給該單位 + 병력에 ACE 의무병 보직 선정 Set Medical Facility [ACE] @@ -5419,8 +5419,8 @@ Definisce un oggetto come struttura medica. Questo permette cure più avanzate. Può essere usato su edifici e veicoli. オブジェクトを医療施設として割り当てます。建物と車両へ割り当てられた場合、より高度な治療が可能になります。 물체를 의료시설로 정의합니다. 건물 혹은 차량이 될 수 있습니다. 이는 고급 의료 조치를 할 수 있게해줍니다. - 定义一个物件作为医疗设施, 此医疗设施将被允许使用更进阶的医疗方法. 此功能可用于建筑物或是载具上! - 定義一個物件作為醫療設施, 此醫療設施將被允許使用更進階的醫療方法. 此功能可用於建築物或是載具上! + 定义一个物件作为医疗设施,此医疗设施将被允许使用更进阶的医疗方法。此功能可用于建筑物或是载具上! + 定義一個物件作為醫療設施,此醫療設施將被允許使用更進階的醫療方法。此功能可用於建築物或是載具上! [ACE] Medical Supply Crate (Basic) @@ -5481,7 +5481,7 @@ Estável После стабилизации Stabile - 安定 + 安静下 안정된 稳定状态下 穩定狀態下 @@ -5542,7 +5542,7 @@ Žádné škrtidlo na této části těla! Non c'è nessun laccio emostatico su questa parte del corpo! Il n'y a pas de garrot sur ce membre ! - 身体には止血帯が無い! + 身体には止血帯が無い! 이 부위에는 지혈대가 없습니다! 这部位没有止血带! 這部位沒有止血帶! @@ -5605,5 +5605,23 @@ 延长AI对已无意识玩家的停火时间 延長AI對已無意識玩家的停火時間 + + Open lid + Deckel aufklappen + フタをあける + Apri lid + 打開蓋子 + 打开盖子 + 뚜껑 열기 + + + Close lid + Deckel zuklappen + フタをしめる + Chiudi lid + 關閉蓋子 + 关闭盖子 + 뚜껑 닫기 + diff --git a/addons/medical_ai/XEH_postInit.sqf b/addons/medical_ai/XEH_postInit.sqf index b84238dc64..075a972c25 100644 --- a/addons/medical_ai/XEH_postInit.sqf +++ b/addons/medical_ai/XEH_postInit.sqf @@ -4,9 +4,9 @@ TRACE_1("settingsInitialized", GVAR(enabledFor)); if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled if ((GVAR(enabledFor) == 1) && {!isServer} && {hasInterface}) exitWith {}; // 1: Don't Run on non-hc Clients - + // Only run for AI that does not have to deal with advanced medical - if (EGVAR(medical,enableFor) == 1 || {hasInterface && {EGVAR(medical,level) == 2}}) exitWith {}; + if (EGVAR(medical,level) == 2 && {EGVAR(medical,enableFor) == 1 || hasInterface}) exitWith {}; ["ace_firedNonPlayer", { _unit setVariable [QGVAR(lastFired), CBA_missionTime]; diff --git a/addons/medical_ai/functions/fnc_healUnit.sqf b/addons/medical_ai/functions/fnc_healUnit.sqf index 569d62f890..78471469da 100644 --- a/addons/medical_ai/functions/fnc_healUnit.sqf +++ b/addons/medical_ai/functions/fnc_healUnit.sqf @@ -54,6 +54,7 @@ _target forceSpeed 0; private _needsBandaging = ([_target] call EFUNC(medical,getBloodLoss)) > 0; private _needsMorphine = (_target getVariable [QEGVAR(medical,pain), 0]) > 0.2; +private _needsEpinephrine = _target getVariable ["ACE_isUnconscious", false]; switch (true) do { case _needsBandaging: { @@ -66,7 +67,7 @@ switch (true) do { }; } forEach _openWounds; private _selection = ["head","body","hand_l","hand_r","leg_l","leg_r"] select _partIndex; - [_target, "Bandage", _selection] call EFUNC(medical,treatmentAdvanced_bandageLocal); + [_this, _target, _selection, "Bandage"] call EFUNC(medical,treatmentAdvanced_bandage); #ifdef DEBUG_MODE_FULL systemChat format ["%1 is bandaging selection %2 on %3", _this, _selection, _target]; @@ -77,7 +78,7 @@ switch (true) do { _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 5]; }; case _needsMorphine: { - [_target] call EFUNC(medical,treatmentBasic_morphineLocal); + [_this, _target] call EFUNC(medical,treatmentBasic_morphine); [_this, false, false] call FUNC(playTreatmentAnim); _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; @@ -85,4 +86,13 @@ switch (true) do { systemChat format ["%1 is giving %2 morphine", _this, _target]; #endif }; + case _needsEpinephrine: { + [_this, _target] call EFUNC(medical,treatmentBasic_epipen); + [_this, false, false] call FUNC(playTreatmentAnim); + _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; + + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 is using an epipen on %2", _this, _target]; + #endif + }; }; diff --git a/addons/medical_ai/functions/fnc_isInjured.sqf b/addons/medical_ai/functions/fnc_isInjured.sqf index 4c25ba72a1..e91802f912 100644 --- a/addons/medical_ai/functions/fnc_isInjured.sqf +++ b/addons/medical_ai/functions/fnc_isInjured.sqf @@ -17,9 +17,4 @@ if !(alive _this) exitWith {false}; -private _bloodLoss = [_this] call EFUNC(medical,getBloodLoss); -private _pain = _this getVariable [QEGVAR(medical,pain), 0]; -// Advanced only? -// private _heartRate = _this getVariable [QEGVAR(medical,heartRate), 70]; - -(_bloodLoss > 0) || {_pain > 0.2} // || {_heartRate > 100} || {_heartRate < 40} +((_this getVariable [QEGVAR(medical,pain), 0] > 0.2) || {[_this] call EFUNC(medical,getBloodLoss) > 0 || {_this getVariable ["ACE_isUnconscious", false]}}) diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 8a8068e7d6..b2bda42146 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,7 @@ Solo Server e HC 只在伺服器或无头客户端 只在伺服器或無頭客戶端 + 서버와 헤드리스만 diff --git a/addons/medical_blood/stringtable.xml b/addons/medical_blood/stringtable.xml index 1e61151d0d..0464d661b7 100644 --- a/addons/medical_blood/stringtable.xml +++ b/addons/medical_blood/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -30,8 +30,9 @@ Włącz lub wyłącz pozostawianie śladów krwi na ziemi kiedy postać odnosi obrażenia bądź krwawi (Dés)active les gouttes de sang lors d'un saignement ou de blessure Abilita o disabilita la Perdite di Sangue create sanguinando e prendendo danno - 开启后, 会让受伤时伤口有血液滴落的效果. - 開啟後, 會讓受傷時傷口有血液滴落的效果. + 开启后, 会让受伤时伤口有血液滴落的效果 + 開啟後, 會讓受傷時傷口有血液滴落的效果 + 출혈이나 부상을 입었을 때, 떨어지는 혈액을 활성화 하거나 비활성화 합니다. diff --git a/addons/medical_menu/ACE_Settings.hpp b/addons/medical_menu/ACE_Settings.hpp index d74a6bdfe0..e3ece532fd 100644 --- a/addons/medical_menu/ACE_Settings.hpp +++ b/addons/medical_menu/ACE_Settings.hpp @@ -29,5 +29,6 @@ class ACE_Settings { value = 3; typeName = "SCALAR"; category = ECSTRING(medical,Category_Medical); + sliderSettings[] = {0, 10, 3, 1}; }; }; diff --git a/addons/medical_menu/CfgVehicles.hpp b/addons/medical_menu/CfgVehicles.hpp index 1918511566..d152077f47 100644 --- a/addons/medical_menu/CfgVehicles.hpp +++ b/addons/medical_menu/CfgVehicles.hpp @@ -3,13 +3,13 @@ class CfgVehicles { class ACE_Module; class ACE_moduleMedicalMenuSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(module_DisplayName); icon = QPATHTOEF(medical,UI\Icon_Module_Medical_ca.paa); category = "ACE_medical"; function = QUOTE(DFUNC(module)); functionPriority = 1; - isGlobal = 0; + isGlobal = 1; isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); @@ -47,7 +47,7 @@ class CfgVehicles { class Medical_Menu { displayName = CSTRING(OpenMenu); runOnHover = 0; - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; condition = QUOTE([ARR_2(ACE_player,_target)] call FUNC(canOpenMenu)); statement = QUOTE([_target] call DFUNC(openMenu)); icon = QPATHTOEF(medical,UI\icons\medical_cross.paa); @@ -60,7 +60,7 @@ class CfgVehicles { class Medical_Menu { displayName = CSTRING(OpenMenu); runOnHover = 0; - exceptions[] = {"isNotInside"}; + exceptions[] = {"isNotInside", "isNotSwimming"}; condition = QUOTE([ARR_2(ACE_player,_target)] call FUNC(canOpenMenu)); statement = QUOTE([_target] call DFUNC(openMenu)); icon = QPATHTOEF(medical,UI\icons\medical_cross.paa); diff --git a/addons/medical_menu/XEH_postInit.sqf b/addons/medical_menu/XEH_postInit.sqf index b028a16e75..89488c0d69 100644 --- a/addons/medical_menu/XEH_postInit.sqf +++ b/addons/medical_menu/XEH_postInit.sqf @@ -21,7 +21,7 @@ GVAR(pendingReopen) = false; if (!((_target isKindOf "CAManBase") && {[ACE_player, _target] call FUNC(canOpenMenu)})) then {_target = ACE_player}; // Conditions: canInteract - if !([ACE_player, _target, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, _target, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; if !([ACE_player, _target] call FUNC(canOpenMenu)) exitWith {false}; // Statement diff --git a/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf b/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf index 80b43bae3c..293eb07836 100644 --- a/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf +++ b/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf @@ -19,7 +19,7 @@ params ["_player", "_target", "_name"]; -if (!([ACE_player, _target, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {[]}; +if (!([ACE_player, _target, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {[]}; private _actions = if (EGVAR(medical,level) == 2) then { GVAR(actionsAdvanced); diff --git a/addons/medical_menu/functions/fnc_handleUI_DisplayOptions.sqf b/addons/medical_menu/functions/fnc_handleUI_DisplayOptions.sqf index 97e5c19519..4cb8f4ceab 100644 --- a/addons/medical_menu/functions/fnc_handleUI_DisplayOptions.sqf +++ b/addons/medical_menu/functions/fnc_handleUI_DisplayOptions.sqf @@ -21,20 +21,18 @@ if (!hasInterface) exitWith{}; -private ["_entries", "_display", "_newTarget", "_ctrl", "_code"]; - params ["_name"]; disableSerialization; -_display = uiNamespace getVariable QGVAR(medicalMenu); +private _display = uiNamespace getVariable QGVAR(medicalMenu); if (isNil "_display") exitWith {}; // no valid dialog present if (_name isEqualTo "toggle") exitWith { - _newTarget = ACE_player; + private _newTarget = ACE_player; //If we are on the player, and only if our old target is still valid, switch to it: if ((GVAR(INTERACTION_TARGET) == ACE_player) && - {[ACE_player, GVAR(INTERACTION_TARGET_PREVIOUS), ["isNotInside"]] call EFUNC(common,canInteractWith)} && + {[ACE_player, GVAR(INTERACTION_TARGET_PREVIOUS), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)} && {[ACE_player, GVAR(INTERACTION_TARGET_PREVIOUS)] call FUNC(canOpenMenu)}) then { _newTarget = GVAR(INTERACTION_TARGET_PREVIOUS); }; @@ -49,7 +47,7 @@ if (_name isEqualTo "toggle") exitWith { // Clean the dropdown options list from all actions for [{_x = START_IDC}, {_x <= END_IDC}, {_x = _x + 1}] do { - _ctrl = (_display displayCtrl (_x)); + private _ctrl = (_display displayCtrl (_x)); _ctrl ctrlSetText ""; _ctrl ctrlShow false; _ctrl ctrlSetEventHandler ["ButtonClick",""]; @@ -64,12 +62,11 @@ lbClear 212; if (_name isEqualTo "triage") exitWith { ctrlEnable [212, true]; - private ["_log", "_triageCardTexts", "_message"]; - _log = GVAR(INTERACTION_TARGET) getVariable [QEGVAR(medical,triageCard), []]; - _triageCardTexts = []; + private _log = GVAR(INTERACTION_TARGET) getVariable [QEGVAR(medical,triageCard), []]; + private _triageCardTexts = []; { _x params ["_item", "_amount", "_time"]; - _message = _item; + private _message = _item; if (isClass(configFile >> "CfgWeapons" >> _item)) then { _message = getText(configFile >> "CfgWeapons" >> _item >> "DisplayName"); } else { @@ -100,7 +97,7 @@ _entries = [ACE_player, GVAR(INTERACTION_TARGET), _name] call FUNC(getTreatmentO _ctrl = (_display displayCtrl (START_IDC + _forEachIndex)); if (!(_forEachIndex > AMOUNT_OF_ENTRIES)) then { _ctrl ctrlSetText (_x select 0); - _code = format ["ace_medical_menu_pendingReopen = true; call %1;", (_x select 3)]; + private _code = format ["ace_medical_menu_pendingReopen = true; call %1;", (_x select 3)]; _ctrl ctrlSetEventHandler ["ButtonClick", _code]; _ctrl ctrlSetTooltip (_x select 0); // TODO implement _ctrl ctrlShow true; diff --git a/addons/medical_menu/functions/fnc_onMenuOpen.sqf b/addons/medical_menu/functions/fnc_onMenuOpen.sqf index 58cb9ff74e..3b933d1862 100644 --- a/addons/medical_menu/functions/fnc_onMenuOpen.sqf +++ b/addons/medical_menu/functions/fnc_onMenuOpen.sqf @@ -75,7 +75,7 @@ GVAR(MenuPFHID) = [{ [GVAR(LatestDisplayOptionMenu)] call FUNC(handleUI_DisplayOptions); //Check that it's valid to stay open: - if !(([ACE_player, GVAR(INTERACTION_TARGET), ["isNotInside"]] call EFUNC(common,canInteractWith)) && {[ACE_player, GVAR(INTERACTION_TARGET)] call FUNC(canOpenMenu)}) then { + if !(([ACE_player, GVAR(INTERACTION_TARGET), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) && {[ACE_player, GVAR(INTERACTION_TARGET)] call FUNC(canOpenMenu)}) then { closeDialog 314412; //If we failed because of distance check, show UI message: if ((ACE_player distance GVAR(INTERACTION_TARGET)) > GVAR(maxRange)) then { diff --git a/addons/medical_menu/functions/fnc_updateUIInfo.sqf b/addons/medical_menu/functions/fnc_updateUIInfo.sqf index 4994ad2acf..5fef1ff2a4 100644 --- a/addons/medical_menu/functions/fnc_updateUIInfo.sqf +++ b/addons/medical_menu/functions/fnc_updateUIInfo.sqf @@ -18,15 +18,13 @@ params ["_target", "_display"]; -private ["_allInjuryTexts", "_bandagedwounds", "_damaged", "_genericMessages", "_logs", "_openWounds", "_part", "_partText", "_pointDamage", "_selectionBloodLoss", "_selectionN", "_severity", "_totalIvVolume", "_triageStatus"]; - if (isNil "_display" || {isNull _display}) exitWith {ERROR("No display");}; -_selectionN = GVAR(selectedBodyPart); +private _selectionN = GVAR(selectedBodyPart); if (_selectionN < 0 || {_selectionN > 5}) exitWith {}; -_genericMessages = []; -_partText = [ELSTRING(medical,Head), ELSTRING(medical,Torso), ELSTRING(medical,LeftArm) ,ELSTRING(medical,RightArm) ,ELSTRING(medical,LeftLeg), ELSTRING(medical,RightLeg)] select _selectionN; +private _genericMessages = []; +private _partText = [ELSTRING(medical,Head), ELSTRING(medical,Torso), ELSTRING(medical,LeftArm) ,ELSTRING(medical,RightArm) ,ELSTRING(medical,LeftLeg), ELSTRING(medical,RightLeg)] select _selectionN; _genericMessages pushBack [localize _partText, [1, 1, 1, 1]]; if (_target getVariable [QEGVAR(medical,isBleeding), false]) then { @@ -45,7 +43,7 @@ if (_target getVariable [QEGVAR(medical,hasPain), false]) then { _genericMessages pushBack [localize ELSTRING(medical,Status_Pain), [1, 1, 1, 1]]; }; -_totalIvVolume = 0; +private _totalIvVolume = 0; private _bloodBags = _target getVariable [QEGVAR(medical,ivBags), []]; { _x params ["_bagVolumeRemaining"]; @@ -56,15 +54,14 @@ if (_totalIvVolume >= 1) then { _genericMessages pushBack [format [localize ELSTRING(medical,receivingIvVolume), floor _totalIvVolume], [1, 1, 1, 1]]; }; -_damaged = [false, false, false, false, false, false]; -_selectionBloodLoss = [0, 0, 0, 0, 0, 0]; +private _damaged = [false, false, false, false, false, false]; +private _selectionBloodLoss = [0, 0, 0, 0, 0, 0]; -_allInjuryTexts = []; +private _allInjuryTexts = []; if ((EGVAR(medical,level) >= 2) && {([_target] call EFUNC(medical,hasMedicalEnabled))}) then { - _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; - private "_amountOf"; + private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; { - _amountOf = _x select 3; + private _amountOf = _x select 3; // Find how much this bodypart is bleeding if (_amountOf > 0) then { _damaged set [_x select 2, true]; @@ -83,9 +80,9 @@ if ((EGVAR(medical,level) >= 2) && {([_target] call EFUNC(medical,hasMedicalEnab }; } forEach _openWounds; - _bandagedwounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; + private _bandagedwounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; { - _amountOf = _x select 3; + private _amountOf = _x select 3; // Find how much this bodypart is bleeding if !(_damaged select (_x select 2)) then { _selectionBloodLoss set [_x select 2, (_selectionBloodLoss select (_x select 2)) + (20 * ((_x select 4) * _amountOf))]; @@ -106,10 +103,9 @@ if ((EGVAR(medical,level) >= 2) && {([_target] call EFUNC(medical,hasMedicalEnab } else { // Add all bleeding from wounds on selection - _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; - private "_amountOf"; + private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; { - _amountOf = _x select 3; + private _amountOf = _x select 3; // Find how much this bodypart is bleeding if (_amountOf > 0) then { _damaged set [_x select 2, true]; @@ -117,9 +113,9 @@ if ((EGVAR(medical,level) >= 2) && {([_target] call EFUNC(medical,hasMedicalEnab }; } forEach _openWounds; - _bandagedwounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; + private _bandagedwounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; { - _amountOf = _x select 3; + private _amountOf = _x select 3; // Find how much this bodypart is bleeding if !(_damaged select (_x select 2)) then { _selectionBloodLoss set [_x select 2, (_selectionBloodLoss select (_x select 2)) + (20 * ((_x select 4) * _amountOf))]; diff --git a/addons/medical_menu/stringtable.xml b/addons/medical_menu/stringtable.xml index 20180d3b91..96b765d174 100644 --- a/addons/medical_menu/stringtable.xml +++ b/addons/medical_menu/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -73,8 +73,8 @@ Si autorisé par le serveur, active l'option d'utiliser le menu médical à travers les raccourcis clavier et le menu d'interaction. サーバーが有効化を許可している場合は、オプションから有効化でき治療メニューはキー割り当てとインタラクション メニューを無視できます 서버 허가하에 단축키와 상호작용 메뉴로 의료 메뉴사용을 허가합니다 - 如果伺服器允许, 只需透过按键即可叫出医疗选单 - 如果伺服器允許, 只需透過按鍵即可叫出醫療選單 + 如果伺服器允许,只需透过按键即可叫出医疗选单 + 如果伺服器允許,只需透過按鍵即可叫出醫療選單 Re-open Medical menu @@ -341,7 +341,7 @@ Alternar (Si mesmo) Přepnout (na sebe) Attiva (Te Stesso) - トグル (自分) + 切り替え (自分) 토글 (자신) 切换 (自己) 切換 (自己) @@ -761,7 +761,7 @@ Sangrando Krvácí Sanguinamento - 出血 + 出血中 출혈 出血中 出血中 @@ -791,7 +791,7 @@ Perdeu muito sangue Ztratil hodně krve Perso molto Sangue - 大量出血している + 大量失血している 많은 피를 흘림 大量失血 大量失血 diff --git a/addons/microdagr/CfgVehicles.hpp b/addons/microdagr/CfgVehicles.hpp index cf596c9762..cc06db69f9 100644 --- a/addons/microdagr/CfgVehicles.hpp +++ b/addons/microdagr/CfgVehicles.hpp @@ -36,8 +36,8 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(moduleMapFill); - scope = 2; - isGlobal = 0; + scope = 1; + isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_microDAGR_ca.paa); functionPriority = 0; diff --git a/addons/microdagr/CfgWeapons.hpp b/addons/microdagr/CfgWeapons.hpp index 92ace96c53..6c7c920427 100644 --- a/addons/microdagr/CfgWeapons.hpp +++ b/addons/microdagr/CfgWeapons.hpp @@ -1,6 +1,6 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_microDAGR: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -9,7 +9,7 @@ class CfgWeapons { descriptionShort = CSTRING(itemDescription); model = QPATHTOF(data\MicroDAGR.p3d); picture = QPATHTOF(images\microDAGR_item.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; }; }; diff --git a/addons/microdagr/XEH_clientInit.sqf b/addons/microdagr/XEH_clientInit.sqf index 46003b9cb1..d82721e697 100644 --- a/addons/microdagr/XEH_clientInit.sqf +++ b/addons/microdagr/XEH_clientInit.sqf @@ -4,15 +4,14 @@ if (!hasInterface) exitWith {}; //Add deviceKey entry: -private ["_conditonCode", "_toggleCode", "_closeCode"]; -_conditonCode = { +private _conditonCode = { ("ACE_microDAGR" in (items ACE_player)) }; -_toggleCode = { +private _toggleCode = { if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; [] call FUNC(openDisplay); //toggle display mode }; -_closeCode = { +private _closeCode = { if (GVAR(currentShowMode) == DISPLAY_MODE_CLOSED) exitWith {}; [DISPLAY_MODE_CLOSED] call FUNC(openDisplay); }; diff --git a/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf b/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf index 86ace87b3e..7e0049d007 100644 --- a/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf +++ b/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf @@ -15,23 +15,21 @@ */ #include "script_component.hpp" -private ["_display", "_editText", "_actualPos"]; - params ["_keypadButton"]; disableSerialization; -_display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; +private _display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; if (isNull _display) exitWith {ERROR("No Display");}; if (GVAR(currentApplicationPage) != APP_MODE_MARK) exitWith {}; -_editText = ctrlText (_display displayCtrl IDC_MODEMARK_CORDSEDIT); +private _editText = ctrlText (_display displayCtrl IDC_MODEMARK_CORDSEDIT); switch (_keypadButton) do { case ("ok"): { if ((count GVAR(newWaypointPosition)) == 0) then { - _actualPos = [_editText, true] call EFUNC(common,getMapPosFromGrid); + private _actualPos = [_editText, true] call EFUNC(common,getMapPosFromGrid); _actualPos set [2, (getTerrainHeightASL _actualPos)]; GVAR(newWaypointPosition) = _actualPos; [APP_MODE_MARK] call FUNC(saveCurrentAndSetNewMode); diff --git a/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf b/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf index d1fe1e8bdd..c03ff06265 100644 --- a/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf +++ b/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf @@ -15,14 +15,12 @@ */ #include "script_component.hpp" -private ["_display", "_wpIndex"]; - disableSerialization; -_display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; +private _display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; if (isNull _display) exitWith {ERROR("No Display");}; -_wpIndex = lbCurSel (_display displayCtrl IDC_MODEWAYPOINTS_LISTOFWAYPOINTS); +private _wpIndex = lbCurSel (_display displayCtrl IDC_MODEWAYPOINTS_LISTOFWAYPOINTS); //If it's our currentWP then deactivate if (GVAR(currentWaypoint) == _wpIndex) then {GVAR(currentWaypoint) = -1}; diff --git a/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf b/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf index d2b3b0e20c..b0d10667a0 100644 --- a/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf +++ b/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf @@ -15,14 +15,12 @@ */ #include "script_component.hpp" -private ["_wpListBox", "_newWpIndex", "_waypoints"]; - disableSerialization; params ["_wpButton"]; -_wpListBox = (ctrlParent _wpButton) displayCtrl 144501; -_newWpIndex = lbCurSel _wpListBox; -_waypoints = [] call FUNC(deviceGetWaypoints); +private _wpListBox = (ctrlParent _wpButton) displayCtrl 144501; +private _newWpIndex = lbCurSel _wpListBox; +private _waypoints = [] call FUNC(deviceGetWaypoints); if ((_newWpIndex < 0) || (_newWpIndex > ((count _waypoints) - 1))) exitWith { GVAR(currentWaypoint) = -1; diff --git a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf index b3b28775d9..0c1925f1f8 100644 --- a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf +++ b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf @@ -15,23 +15,21 @@ */ #include "script_component.hpp" -private ["_mapSize", "_waypoints", "_size", "_targetPos", "_relBearing", "_wpName", "_wpPos", "_alpha"]; - params ["_theMap"]; -_mapSize = (ctrlPosition _theMap) select 3; +private _mapSize = (ctrlPosition _theMap) select 3; -_waypoints = [] call FUNC(deviceGetWaypoints); +private _waypoints = [] call FUNC(deviceGetWaypoints); if (GVAR(currentApplicationPage) == 1) then { _theMap ctrlMapAnimAdd [0, DUMMY_ZOOM, DUMMY_POS]; ctrlMapAnimCommit _theMap; - _size = 412 * _mapSize; + private _size = 412 * _mapSize; _theMap drawIcon [QUOTE(PATHTO_R(images\compass_starInverted.paa)), [1,1,1,1], DUMMY_POS, _size, _size, (-1 * (([ACE_player] call CBA_fnc_headDir) select 0)), '', 0 ]; _theMap drawIcon [QUOTE(PATHTO_R(images\compass_needle.paa)), [0.533,0.769,0.76,1], DUMMY_POS, _size, _size, 0, '', 0 ]; if (GVAR(currentWaypoint) != -1) then { - _targetPos = []; + private _targetPos = []; if (GVAR(currentWaypoint) == -2) then { if ((count GVAR(rangeFinderPositionASL)) == 3) then { _targetPos = GVAR(rangeFinderPositionASL); @@ -42,7 +40,7 @@ if (GVAR(currentApplicationPage) == 1) then { }; }; if ((count _targetPos) == 3) then { - _relBearing = (ACE_player getDir _targetPos) - (([ACE_player] call CBA_fnc_headDir) select 0); + private _relBearing = (ACE_player getDir _targetPos) - (([ACE_player] call CBA_fnc_headDir) select 0); _theMap drawIcon [QUOTE(PATHTO_R(images\compass_needle.paa)), [1,0.564,0.564,1], DUMMY_POS, _size, _size, _relBearing, '', 0 ]; }; }; @@ -55,14 +53,14 @@ if (GVAR(currentApplicationPage) == 1) then { _theMap ctrlMapAnimAdd [0, (GVAR(mapZoom)/_mapSize), (getPosASL ACE_player)]; ctrlMapAnimCommit _theMap; }; - _size = 48 * _mapSize; + private _size = 48 * _mapSize; _theMap drawIcon [QUOTE(PATHTO_R(images\icon_self.paa)), [0.533,0.769,0.76,0.75], (getPosASL ACE_player), _size, _size, (([ACE_player] call CBA_fnc_headDir) select 0), '', 0 ]; if (GVAR(settingShowAllWaypointsOnMap)) then { _size = 32 * _mapSize; { _x params ["_wpName", "_wpPos"]; - _alpha = if (_forEachIndex == GVAR(currentWaypoint)) then {1} else {0.5}; + private _alpha = if (_forEachIndex == GVAR(currentWaypoint)) then {1} else {0.5}; _theMap drawIcon [QUOTE(PATHTO_R(images\icon_mapWaypoints.paa)), [1,1,1,_alpha], _wpPos, _size, _size, 0, '', 0 ]; } forEach _waypoints; }; diff --git a/addons/microdagr/functions/fnc_moduleMapFill.sqf b/addons/microdagr/functions/fnc_moduleMapFill.sqf index 03089a4ff4..46b071122a 100644 --- a/addons/microdagr/functions/fnc_moduleMapFill.sqf +++ b/addons/microdagr/functions/fnc_moduleMapFill.sqf @@ -15,7 +15,6 @@ */ #include "script_component.hpp" -if !(isServer) exitWith {}; params ["_logic"]; [_logic, QGVAR(MapDataAvailable), "MapDataAvailable"] call EFUNC(common,readSettingFromModule); diff --git a/addons/microdagr/functions/fnc_openDisplay.sqf b/addons/microdagr/functions/fnc_openDisplay.sqf index aa2db94827..0f407138f5 100644 --- a/addons/microdagr/functions/fnc_openDisplay.sqf +++ b/addons/microdagr/functions/fnc_openDisplay.sqf @@ -1,9 +1,9 @@ /* * Author: PabstMirror - * Changes the display mode of the microDAGR + * Changes the display mode of the MicroDAGR. * * Arguments: - * 0: Display Mode to show the microDAGR in + * 0: Display Mode to show the microDAGR in (default: -1) * * Return Value: * None @@ -15,10 +15,8 @@ */ #include "script_component.hpp" -private ["_oldShowMode", "_args", "_player"]; - params [["_newDisplayShowMode", -1, [-1]]]; -_oldShowMode = GVAR(currentShowMode); +private _oldShowMode = GVAR(currentShowMode); if (_newDisplayShowMode == -1) then { //Toggle mode button: diff --git a/addons/microdagr/functions/fnc_recieveRangefinderData.sqf b/addons/microdagr/functions/fnc_recieveRangefinderData.sqf index 8b2c6672a8..9d9bec33ef 100644 --- a/addons/microdagr/functions/fnc_recieveRangefinderData.sqf +++ b/addons/microdagr/functions/fnc_recieveRangefinderData.sqf @@ -16,19 +16,16 @@ * Public: No */ #include "script_component.hpp" - -private ["_horizontalDistance", "_verticleDistance", "_targetOffset", "_targetPosASL"]; - params ["_slopeDistance", "_azimuth", "_inclination"]; if (GVAR(currentWaypoint) != -2) exitWith {}; //Only take waypoint when "connected" if (_slopeDistance < 0) exitWith {}; //Bad Data -_horizontalDistance = (cos _inclination) * _slopeDistance; -_verticleDistance = (sin _inclination) * _slopeDistance; +private _horizontalDistance = (cos _inclination) * _slopeDistance; +private _verticleDistance = (sin _inclination) * _slopeDistance; -_targetOffset = [((sin _azimuth) * _horizontalDistance), ((cos _azimuth) * _horizontalDistance), _verticleDistance]; +private _targetOffset = [((sin _azimuth) * _horizontalDistance), ((cos _azimuth) * _horizontalDistance), _verticleDistance]; //This assumes the "rangefinder view" pos is very close to player, at worst the turret should only be a few meters different -_targetPosASL = (getPosASL ACE_player) vectorAdd _targetOffset; +private _targetPosASL = (getPosASL ACE_player) vectorAdd _targetOffset; GVAR(rangeFinderPositionASL) = _targetPosASL; diff --git a/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf b/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf index 7cbec9f242..9c98f2f7dc 100644 --- a/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf +++ b/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf @@ -15,22 +15,19 @@ * Public: No */ #include "script_component.hpp" - -private ["_display", "_theMap", "_centerPos", "_mapCtrlPos"]; - params ["_newMode"]; disableSerialization; -_display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; +private _display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; if (isNull _display) exitWith {ERROR("No Display");}; if (GVAR(currentApplicationPage) == 2) then { - _theMap = [_display displayCtrl IDC_MAPDETAILS, _display displayCtrl IDC_MAPPLAIN] select (!GVAR(mapShowTexture)); - _mapCtrlPos = ctrlPosition _theMap; + private _theMap = [_display displayCtrl IDC_MAPDETAILS, _display displayCtrl IDC_MAPPLAIN] select (!GVAR(mapShowTexture)); + private _mapCtrlPos = ctrlPosition _theMap; _mapCtrlPos params ["_mapCtrlPosX", "_mapCtrlPosY", "_mapCtrlPosZ", "_mapSize"]; - _centerPos = [(_mapCtrlPosX + _mapCtrlPosZ / 2), (_mapCtrlPosY + _mapSize / 2)]; + private _centerPos = [(_mapCtrlPosX + _mapCtrlPosZ / 2), (_mapCtrlPosY + _mapSize / 2)]; GVAR(mapPosition) = _theMap ctrlMapScreenToWorld _centerPos; GVAR(mapZoom) = (ctrlMapScale _theMap) * _mapSize; diff --git a/addons/microdagr/functions/fnc_showApplicationPage.sqf b/addons/microdagr/functions/fnc_showApplicationPage.sqf index 903680e896..c944aa6546 100644 --- a/addons/microdagr/functions/fnc_showApplicationPage.sqf +++ b/addons/microdagr/functions/fnc_showApplicationPage.sqf @@ -15,11 +15,9 @@ */ #include "script_component.hpp" -private ["_display", "_theMap", "_mapSize"]; - disableSerialization; -_display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; +private _display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; if (isNull _display) exitWith {ERROR("No Display");}; diff --git a/addons/microdagr/functions/fnc_updateDisplay.sqf b/addons/microdagr/functions/fnc_updateDisplay.sqf index b13abbec06..f60db3bb0f 100644 --- a/addons/microdagr/functions/fnc_updateDisplay.sqf +++ b/addons/microdagr/functions/fnc_updateDisplay.sqf @@ -15,33 +15,31 @@ */ #include "script_component.hpp" -private ["_display", "_waypoints", "_posString", "_eastingText", "_northingText", "_numASL", "_aboveSeaLevelText", "_compassAngleText", "_targetPos", "_targetPosName", "_targetPosLocationASL", "_bearingText", "_rangeText", "_targetName", "_bearing", "_2dDistanceKm", "_SpeedText", "_wpListBox", "_currentIndex", "_wpName", "_wpPos", "_settingListBox", "_yearString", "_monthSring", "_dayString", "_daylight"]; - disableSerialization; -_display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; +private _display = uiNamespace getVariable [[QGVAR(RscTitleDisplay), QGVAR(DialogDisplay)] select (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG), displayNull]; if (isNull _display) exitWith {ERROR("No Display");}; //Fade "shell" at night -_daylight = [] call EFUNC(common,ambientBrightness); +private _daylight = [] call EFUNC(common,ambientBrightness); (_display displayCtrl IDC_MICRODAGRSHELL) ctrlSetTextColor [_daylight, _daylight, _daylight, 1]; (_display displayCtrl IDC_CLOCKTEXT) ctrlSetText ([daytime, "HH:MM"] call bis_fnc_timeToString); -_waypoints = [] call FUNC(deviceGetWaypoints); +private _waypoints = [] call FUNC(deviceGetWaypoints); switch (GVAR(currentApplicationPage)) do { case (APP_MODE_INFODISPLAY): { //Easting/Northing: - _posString = [getPos ACE_player] call EFUNC(common,getMapGridFromPos); - _eastingText = (_posString select 0) + "e"; - _northingText = (_posString select 1) + "n"; + private _posString = [getPos ACE_player] call EFUNC(common,getMapGridFromPos); + private _eastingText = (_posString select 0) + "e"; + private _northingText = (_posString select 1) + "n"; (_display displayCtrl IDC_MODEDISPLAY_EASTING) ctrlSetText _eastingText; (_display displayCtrl IDC_MODEDISPLAY_NORTHING) ctrlSetText _northingText; //Elevation: - _numASL = ((getPosASL ACE_player) select 2) + EGVAR(common,mapAltitude); - _aboveSeaLevelText = [_numASL, 5, 0] call CBA_fnc_formatNumber; + private _numASL = ((getPosASL ACE_player) select 2) + EGVAR(common,mapAltitude); + private _aboveSeaLevelText = [_numASL, 5, 0] call CBA_fnc_formatNumber; _aboveSeaLevelText = if (_numASL > 0) then {"+" + _aboveSeaLevelText + " MSL"} else {_aboveSeaLevelText + " MSL"}; (_display displayCtrl IDC_MODEDISPLAY_ELEVATIONNUM) ctrlSetText _aboveSeaLevelText; @@ -58,23 +56,22 @@ case (APP_MODE_INFODISPLAY): { if (GVAR(currentWaypoint) == -1) then { - _yearString = (date select 0); - _monthSring = localize (["error","str_january","str_february","str_march","str_april","str_may","str_june","str_july","str_august","str_september","str_october","str_november","str_december"] select (date select 1)); - _dayString = if ((date select 2) < 10) then {"0" + str (date select 2)} else {str (date select 2)}; + private _yearString = (date select 0); + private _monthSring = localize (["error","str_january","str_february","str_march","str_april","str_may","str_june","str_july","str_august","str_september","str_october","str_november","str_december"] select (date select 1)); + private _dayString = if ((date select 2) < 10) then {"0" + str (date select 2)} else {str (date select 2)}; (_display displayCtrl IDC_MODEDISPLAY_TIMEDISPLAYGREEN1) ctrlSetText format ["%1-%2-%3", _yearString, _monthSring, _dayString]; //"18-Feb-2010"; (_display displayCtrl IDC_MODEDISPLAY_TIMEDISPLAYGREEN2) ctrlSetText ([daytime, "HH:MM:SS"] call bis_fnc_timeToString); } else { - _targetPosName = ""; - _targetPosLocationASL = []; + private _targetPosName = ""; + private _targetPosLocationASL = []; _bearingText = "----"; _rangeText = "----"; _aboveSeaLevelText = "----"; - _targetName = "----"; if (GVAR(currentWaypoint) == -2) then { if (!(GVAR(rangeFinderPositionASL) isEqualTo [])) then { - _targetPos = [GVAR(rangeFinderPositionASL)] call EFUNC(common,getMapGridFromPos); + private _targetPos = [GVAR(rangeFinderPositionASL)] call EFUNC(common,getMapGridFromPos); _targetPosName = format ["[%1 %2 %3]", EGVAR(common,MGRS_data) select 1, _targetPos select 0, _targetPos select 1]; _targetPosLocationASL = GVAR(rangeFinderPositionASL); }; @@ -85,15 +82,15 @@ case (APP_MODE_INFODISPLAY): { }; if (!(_targetPosLocationASL isEqualTo [])) then { - _bearing = [(getPosASL ACE_player), _targetPosLocationASL] call BIS_fnc_dirTo; + private _bearing = [(getPosASL ACE_player), _targetPosLocationASL] call BIS_fnc_dirTo; _bearingText = if (GVAR(settingUseMils)) then { [(floor ((6400 / 360) * (_bearing))), 4, 0] call CBA_fnc_formatNumber; } else { ([_bearing, 3, 1] call CBA_fnc_formatNumber) + "°" //degree symbol is in UTF-8 }; - _2dDistanceKm = ((getPosASL ACE_player) distance2D _targetPosLocationASL) / 1000; - _rangeText = format ["%1km", ([_2dDistanceKm, 1, 1] call CBA_fnc_formatNumber)]; - _numASL = (_targetPosLocationASL select 2) + EGVAR(common,mapAltitude); + private _2dDistanceKm = ((getPosASL ACE_player) distance2D _targetPosLocationASL) / 1000; + _rangeText = format ["%1km", _2dDistanceKm toFixed 3]; + private _numASL = (_targetPosLocationASL select 2) + EGVAR(common,mapAltitude); _aboveSeaLevelText = [_numASL, 5, 0] call CBA_fnc_formatNumber; _aboveSeaLevelText = if (_numASL > 0) then {"+" + _aboveSeaLevelText + " MSL"} else {_aboveSeaLevelText + " MSL"}; }; @@ -106,7 +103,7 @@ case (APP_MODE_INFODISPLAY): { }; case (APP_MODE_COMPASS): { //Heading: - _compassAngleText = if (GVAR(settingUseMils)) then { + private _compassAngleText = if (GVAR(settingUseMils)) then { [(floor ((6400 / 360) * (([ACE_player] call CBA_fnc_headDir) select 0))), 4, 0] call CBA_fnc_formatNumber; } else { ([([ACE_player] call CBA_fnc_headDir) select 0, 3, 1] call CBA_fnc_formatNumber) + "°" //degree symbol is in UTF-8 @@ -114,7 +111,7 @@ case (APP_MODE_COMPASS): { (_display displayCtrl IDC_MODECOMPASS_HEADING) ctrlSetText _compassAngleText; //Speed: - _SpeedText = format ["%1kph", (round (speed (vehicle ACE_player)))];; + private _SpeedText = format ["%1kph", (round (speed (vehicle ACE_player)))];; (_display displayCtrl IDC_MODECOMPASS_SPEED) ctrlSetText _SpeedText; if (GVAR(currentWaypoint) == -1) then { @@ -122,12 +119,12 @@ case (APP_MODE_COMPASS): { (_display displayCtrl IDC_MODECOMPASS_RANGE) ctrlSetText ""; (_display displayCtrl IDC_MODECOMPASS_TARGET) ctrlSetText ""; } else { - _targetPosName = ""; - _targetPosLocationASL = []; + private _targetPosName = ""; + private _targetPosLocationASL = []; if (GVAR(currentWaypoint) == -2) then { if (!(GVAR(rangeFinderPositionASL) isEqualTo [])) then { - _targetPos = [GVAR(rangeFinderPositionASL)] call EFUNC(common,getMapGridFromPos); + private _targetPos = [GVAR(rangeFinderPositionASL)] call EFUNC(common,getMapGridFromPos); _targetPosName = format ["[%1 %2 %3]", EGVAR(common,MGRS_data) select 1, _targetPos select 0, _targetPos select 1]; _targetPosLocationASL = GVAR(rangeFinderPositionASL); }; @@ -137,18 +134,18 @@ case (APP_MODE_COMPASS): { _targetPosLocationASL = (_waypoints select GVAR(currentWaypoint)) select 1; }; - _bearing = "---"; + _bearingText = "---"; _rangeText = "---"; if (!(_targetPosLocationASL isEqualTo [])) then { - _bearing = [(getPosASL ACE_player), _targetPosLocationASL] call BIS_fnc_dirTo; + private _bearing = [(getPosASL ACE_player), _targetPosLocationASL] call BIS_fnc_dirTo; _bearingText = if (GVAR(settingUseMils)) then { [(floor ((6400 / 360) * (_bearing))), 4, 0] call CBA_fnc_formatNumber; } else { ([_bearing, 3, 1] call CBA_fnc_formatNumber) + "°" //degree symbol is in UTF-8 }; - _2dDistanceKm = ((getPosASL ACE_player) distance2D _targetPosLocationASL) / 1000; - _rangeText = format ["%1km", ([_2dDistanceKm, 1, 1] call CBA_fnc_formatNumber)]; + private _2dDistanceKm = ((getPosASL ACE_player) distance2D _targetPosLocationASL) / 1000; + _rangeText = format ["%1km", _2dDistanceKm toFixed 3]; }; (_display displayCtrl IDC_MODECOMPASS_BEARING) ctrlSetText _bearingText; @@ -158,15 +155,15 @@ case (APP_MODE_COMPASS): { }; case (APP_MODE_WAYPOINTS): { - _wpListBox = _display displayCtrl IDC_MODEWAYPOINTS_LISTOFWAYPOINTS; - _currentIndex = lbCurSel _wpListBox; + private _wpListBox = _display displayCtrl IDC_MODEWAYPOINTS_LISTOFWAYPOINTS; + private _currentIndex = lbCurSel _wpListBox; lbClear _wpListBox; { _x params ["_wpName", "_wpPos"]; _wpListBox lbAdd _wpName; - _2dDistanceKm = ((getPosASL ACE_player) distance2D _wpPos) / 1000; - _wpListBox lbSetTextRight [_forEachIndex, (format ["%1km", ([_2dDistanceKm, 1, 1] call CBA_fnc_formatNumber)])]; + private _2dDistanceKm = ((getPosASL ACE_player) distance2D _wpPos) / 1000; + _wpListBox lbSetTextRight [_forEachIndex, (format ["%1km", _2dDistanceKm toFixed 3])]; } forEach _waypoints; _currentIndex = (_currentIndex max 0) min (count _waypoints); @@ -177,7 +174,7 @@ case (APP_MODE_WAYPOINTS): { }; case (APP_MODE_SETUP): { - _settingListBox = _display displayCtrl IDC_MODESETTINGS; + private _settingListBox = _display displayCtrl IDC_MODESETTINGS; lbClear _settingListBox; _settingListBox lbAdd (localize LSTRING(settingUseMils)); diff --git a/addons/microdagr/stringtable.xml b/addons/microdagr/stringtable.xml index af18c39c03..f9015c5512 100644 --- a/addons/microdagr/stringtable.xml +++ b/addons/microdagr/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -44,7 +44,7 @@ Szögmértékegység: Unità angolare: Unidade Angular: - 角度の種類: + 角度の種類: 각도의 단위: 角密位: 角密位: @@ -60,7 +60,7 @@ Mil Mils Mils: - ミリ ラジアン + ミル 密位 密位 @@ -76,7 +76,7 @@ Útvonalpontok mutatása a térképen: Mostra waypoint sulla mappa: Mostrar Waypoints no mapa: - 地図へウェイポイントを表示: + 地図へウェイポイントを表示: 웨이포인트를 지도에 보이기: 显示路径点在地图上: 顯示路徑點在地圖上: @@ -140,10 +140,10 @@ Add meg a rácskoordinátákat: Introduci griglia coordinate: Digite as Ccords. do Grid - 座標を入力: - 망 좌표 입력: + 座標を入力: 输入网格座标: 輸入網格座標: + 좌표 입력: Name of [%1] @@ -173,9 +173,9 @@ Nuovo MGRS MGRS-Novo MGRS-New - MGRS-새 것 军事网格座标系统-新型 軍事網格座標系統-新型 + MGRS-New WGD @@ -204,7 +204,7 @@ Távolság: Distanza: Distância: - 距離: + 距離: 거리: 范围: 範圍: @@ -300,7 +300,7 @@ UP Beállítása Definisci WayPoints Definir WP - ウェイポイント設定 + ウェイポイント設定 웨이포인트 설정 设置路径点 設置路徑點 @@ -510,8 +510,8 @@ Controlla quanti dati sono presenti negli oggetti MicroDAGR. Meno dati costringono la vista mappa a mostrare meno informazioni nella minimappa. アイテム上で表示されるデータ量を決定します。設定を減らすと地図上での情報が少なくなります。 MicroDAGR에 얼마나 많은 데이터가 들어있는지 정합니다. 적을 수록 지도상에도 비춰지는게 적어집니다. - 设定有多少数据会显示在微型军用GPS接收器上. 这些资料的多寡会反映在迷你地图的显示上. - 設定有多少數據會顯示在微型軍用GPS接收器上. 這些資料的多寡會反映在迷你地圖的顯示上. + 设定有多少数据会显示在微型军用GPS接收器上。这些资料的多寡会反映在迷你地图的显示上。 + 設定有多少數據會顯示在微型軍用GPS接收器上。這些資料的多寡會反映在迷你地圖的顯示上。 diff --git a/addons/minedetector/functions/fnc_getDetectedObject.sqf b/addons/minedetector/functions/fnc_getDetectedObject.sqf index 0b6faa6168..ea7698dce7 100644 --- a/addons/minedetector/functions/fnc_getDetectedObject.sqf +++ b/addons/minedetector/functions/fnc_getDetectedObject.sqf @@ -42,7 +42,7 @@ private _distance = -1; private _objectType = typeOf _x; _isDetectable = GVAR(detectableClasses) getVariable _objectType; - if (isNil "_isDetectable") then { + if (isNil "_isDetectable" || {(getModelInfo _x) select 0 == "empty.p3d"}) then { _isDetectable = false; }; diff --git a/addons/missileguidance/ACE_Settings.hpp b/addons/missileguidance/ACE_Settings.hpp deleted file mode 100644 index 6394e75390..0000000000 --- a/addons/missileguidance/ACE_Settings.hpp +++ /dev/null @@ -1,9 +0,0 @@ -class ACE_Settings { - class GVAR(enabled) { - value = 2; - typeName = "SCALAR"; - displayName = CSTRING(Title); - description = CSTRING(Desc); - values[] = {CSTRING(Off), CSTRING(PlayerOnly), CSTRING(PlayerAndAi)}; - }; -}; diff --git a/addons/missileguidance/XEH_pre_init.sqf b/addons/missileguidance/XEH_pre_init.sqf index b47cf6628d..f377efddb6 100644 --- a/addons/missileguidance/XEH_pre_init.sqf +++ b/addons/missileguidance/XEH_pre_init.sqf @@ -6,4 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +// Formally a ace_setting, users can still disable by `setting ace_missileguidance_enabled = x;` +// [0 - Off , 1 - PlayerOnly, 2 - PlayerAndAi] +// As weapons take config changes, there is little point in being able to disable guidance +if (isNil QGVAR(enabled)) then { GVAR(enabled) = 2; }; + ADDON = true; diff --git a/addons/missileguidance/config.cpp b/addons/missileguidance/config.cpp index ce75e277b4..e98d99ebcb 100644 --- a/addons/missileguidance/config.cpp +++ b/addons/missileguidance/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_Comanche_Test"}; + units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_laser"}; @@ -14,7 +14,6 @@ class CfgPatches { }; #include "ACE_GuidanceConfig.hpp" -#include "ACE_Settings.hpp" #include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index a878924ed5..97531eb1e5 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -23,15 +23,23 @@ if (!alive ACE_player) exitWith {}; if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; -private ["_currentShooter", "_currentMagazine"]; -if (((vehicle ACE_player) == ACE_player) || {ACE_player call CBA_fnc_canUseWeapon}) then { - _currentShooter = ACE_player; - _currentMagazine = currentMagazine ACE_player; +private _currentShooter = objNull; +private _currentMagazine = ""; +if (isNull (ACE_controlledUAV param [0, objNull])) then { + if (((vehicle ACE_player) == ACE_player) || {ACE_player call CBA_fnc_canUseWeapon}) then { + _currentShooter = ACE_player; + _currentMagazine = currentMagazine ACE_player; + } else { + _currentShooter = vehicle ACE_player; + private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentMagazine = _currentShooter currentMagazineTurret _turretPath; + }; } else { - _currentShooter = vehicle ACE_player; - private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentShooter = ACE_controlledUAV select 0; + private _turretPath = ACE_controlledUAV select 2; _currentMagazine = _currentShooter currentMagazineTurret _turretPath; }; + if (_currentMagazine == "") exitWith {TRACE_1("no magazine",_currentMagazine)}; private _ammo = getText (configFile >> "CfgMagazines" >> _currentMagazine >> "ammo"); diff --git a/addons/missileguidance/functions/fnc_doHandoff.sqf b/addons/missileguidance/functions/fnc_doHandoff.sqf index 2145b4e585..56abc8fbf0 100644 --- a/addons/missileguidance/functions/fnc_doHandoff.sqf +++ b/addons/missileguidance/functions/fnc_doHandoff.sqf @@ -16,6 +16,6 @@ */ #include "script_component.hpp" -PARAMS_2(_target,_args); +params ["_target", "_args"]; [QGVAR(handoff), [_target, _args]] call CBA_fnc_globalEvent; diff --git a/addons/missileguidance/functions/fnc_handleHandoff.sqf b/addons/missileguidance/functions/fnc_handleHandoff.sqf index 63af6d6901..e2122a56a4 100644 --- a/addons/missileguidance/functions/fnc_handleHandoff.sqf +++ b/addons/missileguidance/functions/fnc_handleHandoff.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -PARAMS_2(_target,_args); +params ["_target", "_args"]; if (isNil "_target" || {isNull _target} || {!local _target} ) exitWith { false }; diff --git a/addons/missileguidance/stringtable.xml b/addons/missileguidance/stringtable.xml index 72de552422..7f03b695bc 100644 --- a/addons/missileguidance/stringtable.xml +++ b/addons/missileguidance/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -30,8 +30,8 @@ Pokočilé navádění raket (AMG) poskytuje několik vylepšení pro lepší zaměření a následnou střelbu. Je to prvek vyžadovaný u typu zbraní jako jsou rakety. 高度なミサイルの誘導、または AMG はミサイルの捕捉と発射に複数の強化をあたえます。これはミサイルの種類によって、枠組みを必要とします。 고급 미사일 유도 혹은 AMG 는 표적 획득 및 발사를 위한 여러 기능을 제공합니다. 미사일 종류에따라 체계가 필요합니다. - 进阶飞弹制导增强了多种导弹锁定和射击的能力. 此系统适用于所有飞弹类型的武器. - 進階飛彈制導增強了多種導彈鎖定和射擊的能力. 此系統適用於所有飛彈類型的武器. + 进阶飞弹制导增强了多种导弹锁定和射击的能力。此系统适用于所有飞弹类型的武器。 + 進階飛彈制導增強了多種導彈鎖定和射擊的能力。此系統適用於所有飛彈類型的武器。 Hydra-70 DAGR Missile @@ -44,7 +44,7 @@ Míssil Hydra-70 DAGR Hydra-70 DAGR rakéta Hydra-70 DAGR - Hydra-70 DAGR ミサイル + ハイドラ-70 DAGR ミサイル Hydra-70 DAGR 미사일 九头蛇-70 直接攻击导引飞弹 九頭蛇-70 直接攻擊導引飛彈 @@ -76,10 +76,10 @@ Míssil guiado a laser Hydra-70 DAGR Hydra-70 DAGR lézer-irányított rakéta Управляемая ракета лазерного наведения Hydra-70 DAGR - Hydra-70 DAGR レーザ誘導ミサイル + ハイドラ-70 DAGR レーザ誘導ミサイル Hydra-70 DAGR 레이저 유도 미사일 - 九头蛇-70 直接攻击雷射导引飞弹e - 九頭蛇-70 直接攻擊雷射導引飛彈e + 九头蛇-70 直接攻击雷射导引飞弹 + 九頭蛇-70 直接攻擊雷射導引飛彈 Hellfire II AGM-114K Missile @@ -92,7 +92,7 @@ Míssil Hellfire II AGM-114K Hellfire II AGM-114K rakéta Hellfire II AGM-114K - Hellfire II AGM-114K ミサイル + ヘルファイア II AGM-114K ミサイル Hellfire II AGM-114K 미사일 地狱火II型 AGM-114K 导弹 地獄火II型 AGM-114K 導彈 @@ -124,7 +124,7 @@ Míssil guiado a laser Hellfire II AGM-114K Hellfire II AGM-114K lézer-irányított rakéta Управляемая ракета лазерного наведения Hellfire II AGM-114K - Hellfire II AGM-114K レーザ誘導ミサイル + ヘルファイア II AGM-114K レーザ誘導ミサイル Hellfire II AGM-114K 레이저 유도 미사일 地狱火II型 AGM-114K 雷射导引飞弹 地獄火II型 AGM-114K 雷射導引飛彈 @@ -175,6 +175,7 @@ プレイヤーと AI 玩家和AI 玩家和AI + 플레이어와 AI Cycle Fire Mode diff --git a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf index dc6ca4c7b1..f01aa8017a 100644 --- a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf +++ b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf @@ -18,94 +18,93 @@ #include "script_component.hpp" -private ["_ambianceSounds", "_minimalDistance","_maximalDistance", "_minimalDistance", "_maxDelayBetweenSounds", "_missionRoot", "_unparsedSounds", "_splittedList", "_soundPath"]; params ["_logic", "_units", "_activated"]; // We only play this on the locality of the logic, since the sounds are broadcasted across the network -if (_activated && local _logic) then { - _ambianceSounds = []; - _unparsedSounds = _logic getVariable ["soundFiles", ""]; - _minimalDistance = (_logic getVariable ["minimalDistance", 400]) max 1; - _maximalDistance = (_logic getVariable ["maximalDistance", 10]) max _minimalDistance; - _minDelayBetweensounds = (_logic getVariable ["minimalDelay", 10]) max 1; - _maxDelayBetweenSounds = (_logic getVariable ["maximalDelay", 170]) max _minDelayBetweensounds; - _volume = (_logic getVariable ["soundVolume", 30]) max 1; - _followPlayers = _logic getVariable ["followPlayers", false]; +if (!_activated || !local _logic) exitWith {0}; - _splittedList = _unparsedSounds splitString ","; - _missionRoot = str missionConfigFile select [0, count str missionConfigFile - 15]; +private _ambianceSounds = []; +private _unparsedSounds = _logic getVariable ["soundFiles", ""]; +private _minimalDistance = (_logic getVariable ["minimalDistance", 400]) max 1; +private _maximalDistance = (_logic getVariable ["maximalDistance", 10]) max _minimalDistance; +private _minDelayBetweensounds = (_logic getVariable ["minimalDelay", 10]) max 1; +private _maxDelayBetweenSounds = (_logic getVariable ["maximalDelay", 170]) max _minDelayBetweensounds; +private _volume = (_logic getVariable ["soundVolume", 30]) max 1; +private _followPlayers = _logic getVariable ["followPlayers", false]; - { - _x = [_x] call CBA_fnc_removeWhitespace; +private _splittedList = _unparsedSounds splitString ","; +private _missionRoot = str missionConfigFile select [0, count str missionConfigFile - 15]; - if (isClass (missionConfigFile >> "CfgSounds" >> _x)) then { - // CfgSounds accepts a leading backslash, but a double backslash - // is not accepted in the path, so we have to filter that. - _soundPath = getArray (missionConfigFile >> "CfgSounds" >> _x >> "sound") select 0; - if (_soundPath select [0,1] == "\") then { - _ambianceSounds pushBack (_missionRoot + (_soundPath select [1])); - } else { - _ambianceSounds pushBack (_missionRoot + _soundPath); - }; +{ + _x = [_x] call CBA_fnc_removeWhitespace; + + if (isClass (missionConfigFile >> "CfgSounds" >> _x)) then { + // CfgSounds accepts a leading backslash, but a double backslash + // is not accepted in the path, so we have to filter that. + private _soundPath = getArray (missionConfigFile >> "CfgSounds" >> _x >> "sound") select 0; + if (_soundPath select [0,1] == "\") then { + _ambianceSounds pushBack (_missionRoot + (_soundPath select [1])); } else { - if (isClass (configFile >> "CfgSounds" >> _x)) then { - _soundPath = (getArray(configFile >> "CfgSounds" >> _x >> "sound")) param [0, ""]; - if ((_soundPath select [0, 1]) == "\") then {_soundPath = _soundPath select [1];}; - _ambianceSounds pushBack _soundPath; + _ambianceSounds pushBack (_missionRoot + _soundPath); + }; + } else { + if (isClass (configFile >> "CfgSounds" >> _x)) then { + _soundPath = (getArray(configFile >> "CfgSounds" >> _x >> "sound")) param [0, ""]; + if ((_soundPath select [0, 1]) == "\") then {_soundPath = _soundPath select [1];}; + _ambianceSounds pushBack _soundPath; + } else { + ERROR_1("Ambient Sounds: Sound ""%1"" not found.",_x); + }; + }; + + false +} count _splittedList; + +if (count _ambianceSounds == 0) exitWith {}; +{ + if ((_x find ".") == -1) then { + _ambianceSounds set [_forEachIndex, _x + ".wss"]; + }; +} forEach _ambianceSounds; + +TRACE_1("",_ambianceSounds); + +[{ + params ["_args", "_pfhHandle"]; + _args params ["_logic", "_ambianceSounds", "_minimalDistance", "_maximalDistance", "_minDelayBetweensounds", "_maxDelayBetweenSounds", "_volume", "_followPlayers", "_lastTimePlayed"]; + + if (!alive _logic) exitWith { + [_pfhHandle] call CBA_fnc_removePerFrameHandler; + }; + + if (CBA_missionTime - _lastTimePlayed >= ((_minDelayBetweensounds + random(_maxDelayBetweenSounds)) min _maxDelayBetweenSounds)) then { + + // Find all players in session. + private _allUnits = if (isMultiplayer) then {playableUnits} else {[ACE_player]}; + + // Check if there are enough players to even start playing this sound. + if (count _allUnits > 0) then { + // find the position from which we are going to play this sound from. + private _newPosASL = if (_followPlayers) then { + // Select a target unit at random. + private _targetUnit = selectRandom _allUnits; + AGLtoASL (_targetUnit getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); } else { - ERROR_1("Ambient Sounds: Sound ""%1"" not found.",_x); + AGLtoASL (_logic getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); + }; + + TRACE_1("",_newPosASL); + // If no unit is to close to this position, we will play the sound. + if ({(_newPosASL distance _x < (_minimalDistance / 2))}count _allUnits == 0) then { + private _soundFile = selectRandom _ambianceSounds; + TRACE_2("playing file",_soundFile,_newPosASL); + playSound3D [_soundFile, objNull, false, _newPosASL, _volume, 1, 1000]; + _args set [8, CBA_missionTime]; + } else { + TRACE_1("pos is too close to a player",_newPosASL); }; }; - - false - } count _splittedList; - - if (count _ambianceSounds == 0) exitWith {}; - { - if ((_x find ".") == -1) then { - _ambianceSounds set [_forEachIndex, _x + ".wss"]; - }; - } forEach _ambianceSounds; - - TRACE_1("",_ambianceSounds); - - [{ - params ["_args", "_pfhHandle"]; - _args params ["_logic", "_ambianceSounds", "_minimalDistance", "_maximalDistance", "_minDelayBetweensounds", "_maxDelayBetweenSounds", "_volume", "_followPlayers", "_lastTimePlayed"]; - - if (!alive _logic) exitWith { - [_pfhHandle] call CBA_fnc_removePerFrameHandler; - }; - - if (CBA_missionTime - _lastTimePlayed >= ((_minDelayBetweensounds + random(_maxDelayBetweenSounds)) min _maxDelayBetweenSounds)) then { - - // Find all players in session. - private _allUnits = if (isMultiplayer) then {playableUnits} else {[ACE_player]}; - - // Check if there are enough players to even start playing this sound. - if (count _allUnits > 0) then { - // find the position from which we are going to play this sound from. - private _newPosASL = if (_followPlayers) then { - // Select a target unit at random. - private _targetUnit = selectRandom _allUnits; - AGLtoASL (_targetUnit getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); - } else { - AGLtoASL (_logic getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); - }; - - TRACE_1("",_newPosASL); - // If no unit is to close to this position, we will play the sound. - if ({(_newPosASL distance _x < (_minimalDistance / 2))}count _allUnits == 0) then { - private _soundFile = selectRandom _ambianceSounds; - TRACE_2("playing file",_soundFile,_newPosASL); - playSound3D [_soundFile, objNull, false, _newPosASL, _volume, 1, 1000]; - _args set [8, CBA_missionTime]; - } else { - TRACE_1("pos is too close to a player",_newPosASL); - }; - }; - }; - }, 0.1, [_logic, _ambianceSounds, _minimalDistance, _maximalDistance, _minDelayBetweensounds, _maxDelayBetweenSounds, _volume, _followPlayers, CBA_missionTime] ] call CBA_fnc_addPerFrameHandler; -}; + }; +}, 0.1, [_logic, _ambianceSounds, _minimalDistance, _maximalDistance, _minDelayBetweensounds, _maxDelayBetweenSounds, _volume, _followPlayers, CBA_missionTime] ] call CBA_fnc_addPerFrameHandler; true; diff --git a/addons/missionmodules/stringtable.xml b/addons/missionmodules/stringtable.xml index f69fbad1ec..55a754bf85 100644 --- a/addons/missionmodules/stringtable.xml +++ b/addons/missionmodules/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -61,8 +61,8 @@ Nomi classi dei suoni ambientali da eseguire. Separati da ',' 再生する環境音のクラスネームを記載。','で複数指定できます。 재생되는 환경 효과음의 단위와 이름입니다. ','로 구분됩니다. - 输入想使用的环境声音classname. 每个classname用','做区隔 - 輸入想使用的環境聲音classname. 每個classname用','做區隔 + 输入想使用的环境声音classname。每个classname用','做区隔 + 輸入想使用的環境聲音classname。每個classname用','做區隔 Minimal Distance @@ -93,8 +93,8 @@ Usati per calcolare una posizione casuale ed impostare la distanza minima tra i giocatori ed il file suono eseguito 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最低距離を設定します 무작위 위치 계산에 사용되며 플레이어와 재생 된 사운드 파일 간의 최소 거리를 설정합니다. - 声音将随机产生在玩家附近, 此选项定义该声音最近会距离玩家多少公尺. - 聲音將隨機產生在玩家附近, 此選項定義該聲音最近會距離玩家多少公尺. + 声音将随机产生在玩家附近,此选项定义该声音最近会距离玩家多少公尺 + 聲音將隨機產生在玩家附近,此選項定義該聲音最近會距離玩家多少公尺 Maximum Distance @@ -125,8 +125,8 @@ Usato per calcolare una posizione casuale ed impostare la distanza massima tra giocatori e il file suono eseguito 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最大距離を設定します 무작위 위치 계산에 사용되며 플레이어와 재생 된 사운드 파일 간의 최대 거리를 설정합니다. - 声音将随机产生在玩家附近, 此选项定义该声音最远会距离玩家多少公尺. - 聲音將隨機產生在玩家附近, 此選項定義該聲音最遠會距離玩家多少公尺. + 声音将随机产生在玩家附近,此选项定义该声音最远会距离玩家多少公尺 + 聲音將隨機產生在玩家附近,此選項定義該聲音最遠會距離玩家多少公尺 Minimal Delay @@ -221,8 +221,8 @@ Segui Giocatori. Se impostato su falso, il ciclo eseguirà i suoni solo vicino ad una posizione logica. プレイヤーを追随します。False に設定するとロジックの近くで延々と再生します。 플레이어를 따라갑니다. 거짓으로 설정될경우 오직 한 자리에서만 반복해서 소리를 재생합니다. - 设定声音是否会在玩家的附近产生. 假如关闭此功能, 声音只会在模块的位置产生. - 設定聲音是否會在玩家的附近產生. 假如關閉此功能, 聲音只會在模塊的位置產生. + 设定声音是否会在玩家的附近产生。假如关闭此功能,声音只会在模块的位置产生。 + 設定聲音是否會在玩家的附近產生。假如關閉此功能,聲音只會在模塊的位置產生。 Volume diff --git a/addons/mk6mortar/ACE_Settings.hpp b/addons/mk6mortar/ACE_Settings.hpp index cd7d4e64cb..5fb88aa23b 100644 --- a/addons/mk6mortar/ACE_Settings.hpp +++ b/addons/mk6mortar/ACE_Settings.hpp @@ -1,6 +1,7 @@ class ACE_Settings { //These settings effect gameplay difficutly: defaults will leave the mortar the same as vanilla class GVAR(airResistanceEnabled) { + category = CSTRING(DisplayName); displayName = CSTRING(airResistanceEnabled_DisplayName); description = CSTRING(airResistanceEnabled_Description); value = 0; @@ -8,6 +9,7 @@ class ACE_Settings { isClientSetable = 0; }; class GVAR(allowComputerRangefinder) { + category = CSTRING(DisplayName); displayName = CSTRING(allowComputerRangefinder_DisplayName); description = CSTRING(allowComputerRangefinder_Description); value = 1; @@ -15,6 +17,7 @@ class ACE_Settings { isClientSetable = 0; }; class GVAR(allowCompass) { + category = CSTRING(DisplayName); displayName = CSTRING(allowCompass_DisplayName); description = CSTRING(allowCompass_Description); value = 1; @@ -22,6 +25,7 @@ class ACE_Settings { isClientSetable = 0; }; class GVAR(useAmmoHandling) { + category = CSTRING(DisplayName); displayName = CSTRING(useAmmoHandling_DisplayName); description = CSTRING(useAmmoHandling_Description); value = 0; diff --git a/addons/mk6mortar/CfgVehicles.hpp b/addons/mk6mortar/CfgVehicles.hpp index 75b0277192..36315772d4 100644 --- a/addons/mk6mortar/CfgVehicles.hpp +++ b/addons/mk6mortar/CfgVehicles.hpp @@ -99,8 +99,8 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(moduleInit); - scope = 2; - isGlobal = 0; + scope = 1; + isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_mk6_ca.paa); functionPriority = 0; diff --git a/addons/mk6mortar/CfgWeapons.hpp b/addons/mk6mortar/CfgWeapons.hpp index cb5454321d..3e247910fb 100644 --- a/addons/mk6mortar/CfgWeapons.hpp +++ b/addons/mk6mortar/CfgWeapons.hpp @@ -1,6 +1,6 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_RangeTable_82mm: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -8,7 +8,7 @@ class CfgWeapons { displayName = CSTRING(rangetable_name); descriptionShort = CSTRING(rangetable_description); picture = QPATHTOF(UI\icon_rangeTable.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0.5; }; }; diff --git a/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf b/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf index c0858a328a..2114c7d3a8 100644 --- a/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf @@ -18,19 +18,17 @@ #include "script_component.hpp" params ["_static","_unit",["_magazineClassOptional","",[""]]]; -private ["_canLoadMagazine","_currentMagazine","_weapon","_listOfMagNames", - "_hasCompatibleMagazine","_count"]; if !(alive _static && GVAR(useAmmoHandling)) exitWith {false}; -_canLoadMagazine = false; -_hasCompatibleMagazine = false; +private _canLoadMagazine = false; +private _hasCompatibleMagazine = false; -_currentMagazine = (magazinesAllTurrets _static) select 1; -_weapon = (_static weaponsTurret [0]) select 0; +private _currentMagazine = (magazinesAllTurrets _static) select 1; +private _weapon = (_static weaponsTurret [0]) select 0; -_listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines"); -_count = 0; +private _listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines"); +private _count = 0; //If function is called with an optional string then check if player has that magzine otherwise check all magazines of the player to see if they are compatible with the static weapon if (_magazineClassOptional != "") then { diff --git a/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf b/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf index b1d6593574..ddb0c8d10b 100644 --- a/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf @@ -17,12 +17,11 @@ #include "script_component.hpp" params ["_static","_unit"]; -private ["_canUnloadMagazine","_ammoCount"]; if !(alive _static && GVAR(useAmmoHandling) && _static getVariable [QGVAR(initialized),false]) exitWith {false}; -_canUnloadMagazine = false; +private _canUnloadMagazine = false; -_ammoCount = ((magazinesAllTurrets _static) select 1) select 2; +private _ammoCount = ((magazinesAllTurrets _static) select 1) select 2; if (_ammoCount > 0) then { _canUnloadMagazine = true; }; diff --git a/addons/mk6mortar/functions/fnc_dev_buildTable.sqf b/addons/mk6mortar/functions/fnc_dev_buildTable.sqf index 1f648ead4a..6af83c27f2 100644 --- a/addons/mk6mortar/functions/fnc_dev_buildTable.sqf +++ b/addons/mk6mortar/functions/fnc_dev_buildTable.sqf @@ -17,21 +17,18 @@ */ #include "script_component.hpp" - -private ["_muzzleVelocity", "_airFriction", "_stillInRange", "_currentRange", "_increasePerRow", "_outputArray", "_rangeToHit", "_lineElevation", "_lineHeightElevation", "_lineTimeOfFlight", "_lineCrosswindDeg", "_lineHeadwindMeters", "_lineTailWindMeters", "_lineTempDec", "_lineTempInc", "_lineAirDensDec", "_lineAirDensInc", "_result", "_outputString"]; - -_muzzleVelocity = _this select 0; -_airFriction = _this select 1; -_stillInRange = true; -_currentRange = 100; -_increasePerRow = 50; -_outputArray = []; +private _muzzleVelocity = _this select 0; +private _airFriction = _this select 1; +private _stillInRange = true; +private _currentRange = 100; +private _increasePerRow = 50; +private _outputArray = []; //[_rangeToHit, _lineElevation, _lineHeightElevation, _lineHeightTimeDelta, _lineTimeOfFlight, _lineCrosswindDeg, _lineHeadwindMeters, _lineTailWindMeters, _lineTempDec, _lineTempInc, _lineAirDensDec, _lineAirDensInc] while {_stillInRange} do { - _result = [_muzzleVelocity, _currentRange, _airFriction] call FUNC(dev_simulateCalcRangeTableLine); + private _result = [_muzzleVelocity, _currentRange, _airFriction] call FUNC(dev_simulateCalcRangeTableLine); if (_result isEqualTo []) then { _stillInRange = false; } else { @@ -66,7 +63,7 @@ while {_stillInRange} do { }; //handle floating point rounding errors -_outputString = format ["case ((abs(_muzzleVelocity - %1) < 0.00001) && {(abs(_airFriction - %2) < 0.00001)}): { +private _outputString = format ["case ((abs(_muzzleVelocity - %1) < 0.00001) && {(abs(_airFriction - %2) < 0.00001)}): { [ ", _muzzleVelocity, _airFriction]; diff --git a/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf b/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf index 3e70e0f917..713daefbed 100644 --- a/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf +++ b/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf @@ -17,14 +17,10 @@ */ #include "script_component.hpp" -private ["_theNumber", "_inputType", "_convertToMils", "_decimalPlaces", "_integerPlaces", "_prefix", "_return"]; +params ["_theNumber", "_inputType", "_convertToMils"]; -_theNumber = _this select 0; -_inputType = _this select 1; -_convertToMils = _this select 2; - -_decimalPlaces = -1; -_integerPlaces = -1; +private _decimalPlaces = -1; +private _integerPlaces = -1; switch (toLower _inputType) do { case ("meters"): { @@ -73,8 +69,8 @@ case ("sec"): { //CBA_fnc_formatNumber is silly: [-9.58545, 1, 1, false] call CBA_fnc_formatNumber == "-9.-6" -_prefix = if (_theNumber < 0) then {"-"} else {""}; +private _prefix = if (_theNumber < 0) then {"-"} else {""}; -_return = [abs (_theNumber), _integerPlaces, _decimalPlaces, false] call CBA_fnc_formatNumber; +private _return = [abs (_theNumber), _integerPlaces, _decimalPlaces, false] call CBA_fnc_formatNumber; (_prefix + _return) diff --git a/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf b/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf index 8a9c6d1a98..5d83913c3c 100644 --- a/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf +++ b/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf @@ -19,44 +19,42 @@ #define TIME_STEP (1/50) -private ["_startTime", "_muzzleVelocity", "_rangeToHit", "_airFriction", "_vacElevation", "_radicand", "_maxElev", "_minElev", "_error", "_solutionElevation", "_lastTestResult", "_numberOfAttempts", "_lineElevation", "_lineTimeOfFlight", "_lineHeightElevation", "_lineHeightTimeDelta", "_lineCrosswindDeg", "_lineHeadwindMeters", "_lineTailWindMeters", "_result"]; +params ["_muzzleVelocity", "_rangeToHit", "_airFriction"]; + +private _startTime = diag_tickTime; -_startTime = diag_tickTime; -_muzzleVelocity = _this select 0; -_rangeToHit = _this select 1; -_airFriction = _this select 2; //Run Binary search for correct elevation -_solution = [_rangeToHit, 0, _muzzleVelocity, _airFriction, TIME_STEP] call FUNC(dev_simulateFindSolution); +private _solution = [_rangeToHit, 0, _muzzleVelocity, _airFriction, TIME_STEP] call FUNC(dev_simulateFindSolution); if (_solution isEqualTo []) exitWith {[]}; //Real Elevation -_lineElevation = _solution select 0; +private _lineElevation = _solution select 0; //Time Of Flight: -_lineTimeOfFlight = _solution select 1; +private _lineTimeOfFlight = _solution select 1; //Height Adjustment for -100m (another binary search) -_solution = [_rangeToHit, -100, _muzzleVelocity, _airFriction, TIME_STEP] call FUNC(dev_simulateFindSolution); +private _solution = [_rangeToHit, -100, _muzzleVelocity, _airFriction, TIME_STEP] call FUNC(dev_simulateFindSolution); if (_solution isEqualTo []) exitWith {[]};//should never be triggered (lower elevation easier to hit) -_lineHeightElevation = ((_solution select 0) - _lineElevation); -_lineHeightTimeDelta = (_solution select 1) - _lineTimeOfFlight; +private _lineHeightElevation = ((_solution select 0) - _lineElevation); +private _lineHeightTimeDelta = (_solution select 1) - _lineTimeOfFlight; //Compute for 10x and divide to minimize rounding errors //Crosswind -_lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, 0, 10, 0, TIME_STEP] call FUNC(dev_simulateShot); -_lineCrosswindDeg = (_lastTestResult select 2) / 10; +private _lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, 0, 10, 0, TIME_STEP] call FUNC(dev_simulateShot); +private _lineCrosswindDeg = (_lastTestResult select 2) / 10; //Headwind: _lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, -10, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -_lineHeadwindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; +private _lineHeadwindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; //TailWind: _lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1, 10, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -_lineTailWindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; +private _lineTailWindMeters = (_rangeToHit - (_lastTestResult select 0)) / 10; //Air Temp Dec _lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, (15 - 10), 1, 0, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); @@ -68,11 +66,11 @@ _lineTempInc = (_rangeToHit - (_lastTestResult select 0)) / 10; //Air Density Dec _lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 0.9, 0, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -_lineAirDensDec = (_rangeToHit - (_lastTestResult select 0)) / 10; +private _lineAirDensDec = (_rangeToHit - (_lastTestResult select 0)) / 10; //Air Density Inc _lastTestResult = [_lineElevation, _muzzleVelocity, _airFriction, 15, 1.1, 0, 0, 0, TIME_STEP] call FUNC(dev_simulateShot); -_lineAirDensInc = (_rangeToHit - (_lastTestResult select 0)) / 10; +private _lineAirDensInc = (_rangeToHit - (_lastTestResult select 0)) / 10; // systemChat format ["debug: Range %1 - in %2 sec", _rangeToHit, (diag_tickTime - _startTime)]; diff --git a/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf b/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf index 29ac0c010a..3a91b3cf4a 100644 --- a/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf +++ b/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf @@ -19,23 +19,16 @@ */ #include "script_component.hpp" -private ["_rangeToHit", "_heightToHit", "_muzzleVelocity", "_airFriction", "_maxElev", "_minElev", "_error", "_solutionElevation", "_lastTestResult", "_numberOfAttempts"]; - #define MAX_ATTEMPTS 22 +params ["_rangeToHit", "_heightToHit", "_muzzleVelocity", "_airFriction","_timeStep"]; -_rangeToHit = _this select 0; -_heightToHit = _this select 1; -_muzzleVelocity = _this select 2; -_airFriction = _this select 3; -_timeStep = _this select 4; +private _maxElev = 90; +private _minElev = 45; //todo - Low Angle Howitzers??? -_maxElev = 90; -_minElev = 45; //todo - Low Angle Howitzers??? - -_error = 10000; -_solutionElevation = -1; -_lastTestResult = []; -_numberOfAttempts = 0; +private _error = 10000; +private _solutionElevation = -1; +private _lastTestResult = []; +private _numberOfAttempts = 0; //(binary search) while {(_numberOfAttempts < MAX_ATTEMPTS) && {(abs _error) > 0.2}} do { diff --git a/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf b/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf index 0e53807a6b..fa74c842e1 100644 --- a/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf +++ b/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf @@ -23,35 +23,25 @@ */ #include "script_component.hpp" -private ["_angleDeg", "_muzzleVelocity", "_airFriction", "_temp", "_relDensity", "_tailWind", "_crosswind", "_heightOfTarget", "_timeStep", "_wind", "_gravity", "_currentPos", "_currentVelocity", "_currentTime", "_lastPos", "_kCoefficent", "_aparentWind", "_changeInVelocity", "_linConversion", "_middlePos", "_middlePosOld", "_middleTotalTravelTime", "_offsetDeg"]; +params ["_angleDeg", "_muzzleVelocity", "_airFriction", "_temp", "_relDensity", "_tailWind", "_crosswind", "_heightOfTarget", "_timeStep"]; -_angleDeg = _this select 0; -_muzzleVelocity = _this select 1; -_airFriction = _this select 2; -_temp = _this select 3; -_relDensity = _this select 4; -_tailWind = _this select 5; -_crosswind = _this select 6; -_heightOfTarget = _this select 7; -_timeStep = _this select 8; +private _wind = [_crosswind, _tailWind, 0]; +private _gravity = [0,0,-9.8]; -_wind = [_crosswind, _tailWind, 0]; -_gravity = [0,0,-9.8]; +private _currentPos = [0,0,0]; +private _muzzleVelocity = _muzzleVelocity * (((_temp + 273.13) / 288.13 - 1) / 40 + 1); +private _currentVelocity = [0, (_muzzleVelocity * cos _angleDeg), (_muzzleVelocity * sin _angleDeg)]; -_currentPos = [0,0,0]; -_muzzleVelocity = _muzzleVelocity * (((_temp + 273.13) / 288.13 - 1) / 40 + 1); -_currentVelocity = [0, (_muzzleVelocity * cos _angleDeg), (_muzzleVelocity * sin _angleDeg)]; +private _currentTime = 0; +private _lastPos = _currentPos; -_currentTime = 0; -_lastPos = _currentPos; - -_kCoefficent = -1 * _relDensity * _airFriction; //save time in the loop and compute once +private _kCoefficent = -1 * _relDensity * _airFriction; //save time in the loop and compute once while {((_currentVelocity select 2) > 0) || ((_currentPos select 2) >= _heightOfTarget)} do { _lastPos = _currentPos; - _aparentWind = _wind vectorDiff _currentVelocity; - _changeInVelocity = _gravity vectorAdd (_aparentWind vectorMultiply ((vectorMagnitude _aparentWind) * _kCoefficent)); + private _aparentWind = _wind vectorDiff _currentVelocity; + private _changeInVelocity = _gravity vectorAdd (_aparentWind vectorMultiply ((vectorMagnitude _aparentWind) * _kCoefficent)); _currentVelocity = _currentVelocity vectorAdd (_changeInVelocity vectorMultiply _timeStep); @@ -60,14 +50,14 @@ while {((_currentVelocity select 2) > 0) || ((_currentPos select 2) >= _heightOf }; //Uses linearConversion to get a weighted average betwen points before and after dropping below target height -_linConversion = linearConversion [(_lastPos select 2), (_currentPos select 2), _heightOfTarget, 0, 1, true]; -_middlePos = (_lastPos vectorMultiply (1 - _linConversion)) vectorAdd (_currentPos vectorMultiply (_linConversion)); -// _middlePosOld = (_lastPos vectorAdd _currentPos) vectorMultiply 0.5; +private _linConversion = linearConversion [(_lastPos select 2), (_currentPos select 2), _heightOfTarget, 0, 1, true]; +private _middlePos = (_lastPos vectorMultiply (1 - _linConversion)) vectorAdd (_currentPos vectorMultiply (_linConversion)); +// private _middlePosOld = (_lastPos vectorAdd _currentPos) vectorMultiply 0.5; //Same to find travel time -_middleTotalTravelTime = _currentTime - (_timeStep * (1-_linConversion)); +private _middleTotalTravelTime = _currentTime - (_timeStep * (1-_linConversion)); //Find shot offset (from crosswind), in degrees -_offsetDeg = (_middlePos select 0) aTan2 (_middlePos select 1); +private _offsetDeg = (_middlePos select 0) aTan2 (_middlePos select 1); [(_middlePos select 1), _middleTotalTravelTime, _offsetDeg] diff --git a/addons/mk6mortar/functions/fnc_handleFired.sqf b/addons/mk6mortar/functions/fnc_handleFired.sqf index 98fa8eebdf..b6cdac2b03 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -21,7 +21,7 @@ */ #include "script_component.hpp" -PARAMS_7(_vehicle,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); +params ["_vehicle", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; if (GVAR(useAmmoHandling) && {_vehicle getVariable [QGVAR(initialized),false] && !(_vehicle getVariable [QGVAR(exclude),false])}) then { // if !(_vehicle getVariable [QGVAR(exclude),false]) then { @@ -32,8 +32,6 @@ if (GVAR(useAmmoHandling) && {_vehicle getVariable [QGVAR(initialized),false] && if (!GVAR(airResistanceEnabled)) exitWith {}; -private ["_shooterMan", "_temperature", "_newMuzzleVelocityCoefficent", "_bulletVelocity", "_bulletSpeed"]; - // Large enough distance to not simulate any wind deflection if (_vehicle distance ACE_player > 8000) exitWith {false}; @@ -42,17 +40,17 @@ _shooterMan = gunner _vehicle; if (!([_shooterMan] call EFUNC(common,isPlayer))) exitWith {false}; //Calculate air density: -_altitude = (getPosASL _vehicle) select 2; -_temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight); -_pressure = _altitude call EFUNC(weather,calculateBarometricPressure); -_relativeHumidity = EGVAR(weather,currentHumidity); -_airDensity = [_temperature, _pressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); -_relativeDensity = _airDensity / 1.225; +private _altitude = (getPosASL _vehicle) select 2; +private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight); +private _pressure = _altitude call EFUNC(weather,calculateBarometricPressure); +private _relativeHumidity = EGVAR(weather,currentHumidity); +private _airDensity = [_temperature, _pressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); +private _relativeDensity = _airDensity / 1.225; TRACE_5("FiredWeather",_temperature,_pressure,_relativeHumidity,_airDensity,_relativeDensity); //powder effects: -_newMuzzleVelocityCoefficent = (((_temperature + 273.13) / 288.13 - 1) / 40 + 1); +private _newMuzzleVelocityCoefficent = (((_temperature + 273.13) / 288.13 - 1) / 40 + 1); if (_newMuzzleVelocityCoefficent != 1) then { _bulletVelocity = velocity _projectile; _bulletSpeed = vectorMagnitude _bulletVelocity; @@ -62,26 +60,25 @@ if (_newMuzzleVelocityCoefficent != 1) then { [{ - private ["_deltaT", "_bulletVelocity", "_bulletSpeed", "_trueVelocity", "_trueSpeed", "_dragRef", "_accelRef", "_drag", "_accel"]; - PARAMS_2(_args,_pfID); - EXPLODE_4_PVT(_args,_shell,_airFriction,_time,_relativeDensity); + params ["_args", "_pfID"]; + _args params ["_shell", "_airFriction", "_time", "_relativeDensity"]; if (isNull _shell || {!alive _shell}) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; }; - _deltaT = CBA_missionTime - _time; + private _deltaT = CBA_missionTime - _time; _args set[2, CBA_missionTime]; - _bulletVelocity = velocity _shell; - _bulletSpeed = vectorMagnitude _bulletVelocity; + private _bulletVelocity = velocity _shell; + private _bulletSpeed = vectorMagnitude _bulletVelocity; - _trueVelocity = _bulletVelocity vectorDiff ACE_wind; - _trueSpeed = vectorMagnitude _trueVelocity; + private _trueVelocity = _bulletVelocity vectorDiff wind; + private _trueSpeed = vectorMagnitude _trueVelocity; - _drag = _deltaT * _airFriction * _trueSpeed * _relativeDensity; - _accel = _trueVelocity vectorMultiply (_drag); - _bulletVelocity = _bulletVelocity vectorAdd _accel; + private _drag = _deltaT * _airFriction * _trueSpeed * _relativeDensity; + private _accel = _trueVelocity vectorMultiply (_drag); + private _bulletVelocity = _bulletVelocity vectorAdd _accel; _shell setVelocity _bulletVelocity; diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index db56f71691..568a1a326e 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -45,7 +45,6 @@ if (_lastFireMode != -1) then { }; [{ - private ["_chargeText", "_currentChargeMode", "_currentFireMode", "_display", "_elevDeg", "_elevationDiff", "_lookVector", "_notGunnerView", "_realAzimuth", "_realElevation", "_upVectorDir", "_useMils", "_weaponDir"]; params ["_args", "_pfID"]; _args params ["_mortarVeh", "_fireModes"]; @@ -53,11 +52,11 @@ if (_lastFireMode != -1) then { [_pfID] call CBA_fnc_removePerFrameHandler; } else { - _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; + private _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; //Compute: 'charge' from weaponstate - _currentFireMode = (weaponState [_mortarVeh, [0]]) select 2; - _currentChargeMode = _fireModes find _currentFireMode; + private _currentFireMode = (weaponState [_mortarVeh, [0]]) select 2; + private _currentChargeMode = _fireModes find _currentFireMode; //Save firemode on vehicle: _mortarVeh setVariable [QGVAR(lastFireMode), _currentChargeMode]; @@ -68,18 +67,18 @@ if (_lastFireMode != -1) then { [parseText "Computer Disabled"] call EFUNC(common,displayTextStructured); }; - _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; + private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; if (isNull _display) exitWith {}; //It may be null for the first frame - _chargeText = format ["%1: %2 ", (localize LSTRING(rangetable_charge)), _currentChargeMode, QPATHTOF(UI\ui_charges.paa)]; + private _chargeText = format ["%1: %2 ", (localize LSTRING(rangetable_charge)), _currentChargeMode, QPATHTOF(UI\ui_charges.paa)]; //Hud should hidden in 3rd person - _notGunnerView = cameraView != "GUNNER"; + private _notGunnerView = cameraView != "GUNNER"; //Calc real azimuth/elevation //(looking at the sky VS looking at ground will radicaly change fire direction because BIS) - _realAzimuth = -1; - _realElevation = -1; + private _realAzimuth = -1; + private _realElevation = -1; private _useRealWeaponDir = (ctrlText (_display displayCtrl 173)) == "--"; if (_useRealWeaponDir && {(_mortarVeh ammo (currentWeapon _mortarVeh)) == 0}) then { @@ -94,15 +93,15 @@ if (_lastFireMode != -1) then { if (_useRealWeaponDir) then { //No range (looking at sky), it will follow weaponDir: - _weaponDir = _mortarVeh weaponDirection (currentWeapon _mortarVeh); + private _weaponDir = _mortarVeh weaponDirection (currentWeapon _mortarVeh); _realAzimuth = (_weaponDir select 0) atan2 (_weaponDir select 1); _realElevation = asin (_weaponDir select 2); } else { //Valid range, will fire at camera dir - _lookVector = ((positionCameraToWorld [0,0,0]) call EFUNC(common,positionToASL)) vectorFromTo ((positionCameraToWorld [0,0,10]) call EFUNC(common,positionToASL)); + private _lookVector = ((positionCameraToWorld [0,0,0]) call EFUNC(common,positionToASL)) vectorFromTo ((positionCameraToWorld [0,0,10]) call EFUNC(common,positionToASL)); _realAzimuth = ((_lookVector select 0) atan2 (_lookVector select 1)); - _upVectorDir = (((vectorUp _mortarVeh) select 0) atan2 ((vectorUp _mortarVeh) select 1)); - _elevationDiff = (cos (_realAzimuth - _upVectorDir)) * acos ((vectorUp _mortarVeh) select 2); + private _upVectorDir = (((vectorUp _mortarVeh) select 0) atan2 ((vectorUp _mortarVeh) select 1)); + private _elevationDiff = (cos (_realAzimuth - _upVectorDir)) * acos ((vectorUp _mortarVeh) select 2); _realElevation = ((180 / PI) * (_mortarVeh animationPhase "mainGun")) + 75 - _elevationDiff; }; @@ -135,7 +134,7 @@ if (_lastFireMode != -1) then { if (_notGunnerView || (!GVAR(allowComputerRangefinder))) then { (_display displayCtrl 80176) ctrlSetText ""; } else { - _elevDeg = parseNumber ctrlText (_display displayCtrl 176); + private _elevDeg = parseNumber ctrlText (_display displayCtrl 176); if (_elevDeg <= 0) then { //Bad data means "----" out of range (_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176)); } else { diff --git a/addons/mk6mortar/functions/fnc_loadMagazine.sqf b/addons/mk6mortar/functions/fnc_loadMagazine.sqf index 37fa2f4db4..df92c820cd 100644 --- a/addons/mk6mortar/functions/fnc_loadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_loadMagazine.sqf @@ -18,8 +18,6 @@ #include "script_component.hpp" params ["_static","_unit",["_magazineClassOptional","",[""]]]; -private ["_weapon","_currentMagazine","_count","_magazines","_magazineDetails","_listOfMagNames", - "_magazineClass","_magazineClassDetails","_parsed","_roundsLeft"]; //If function has been called with an optional classname hten add that magazine to the static weapon. Otherwise add the compatible magazine if(_magazineClassOptional != "") then { @@ -27,20 +25,19 @@ if(_magazineClassOptional != "") then { [QGVAR(addMagazine), [_static, _magazineClassOptional]] call CBA_fnc_globalEvent; } else { //Get weapon & magazine information of static weapon - _weapon = (_static weaponsTurret [0]) select 0; - _currentMagazine = (magazinesAllTurrets _static) select 1; - _currentMagazineClass = _currentMagazine select 0; - _count = _currentMagazine select 2; + private _weapon = (_static weaponsTurret [0]) select 0; + private _currentMagazine = (magazinesAllTurrets _static) select 1; + private _currentMagazineClass = _currentMagazine select 0; + private _count = _currentMagazine select 2; //Check all of the players magazines to see if they are compatible with the static weapon. First magazine that is compatible is chosen //VKing: This section ought to be double checked. - _magazines = magazines _unit; - _magazineDetails = magazinesDetail _unit; - _listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines"); - _magazineClass = ""; - _magazineClassDetails = ""; - _parsed =""; - _roundsLeft = 0; + private _magazines = magazines _unit; + private _magazineDetails = magazinesDetail _unit; + private _listOfMagNames = getArray(configFile >> "cfgWeapons" >> _weapon >> "magazines"); + private _magazineClass = ""; + private _magazineClassDetails = ""; + private _roundsLeft = 0; { if (_x in _listOfMagNames) exitWith { _magazineClass = _x; @@ -53,7 +50,7 @@ if(_magazineClassOptional != "") then { }; //Find out the ammo count of the compatible magazine found if (_magazineClassDetails != "") then{ - _parsed = _magazineClassDetails splitString "([]/: )"; + private _parsed = _magazineClassDetails splitString "([]/: )"; _parsed params ["_type", "", "", "_roundsLeftText", "_maxRoundsText"]; _roundsLeft = parseNumber _roundsLeftText; _magType = _type; diff --git a/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf b/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf index 16016f06e6..fa0adb28d0 100644 --- a/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf +++ b/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf @@ -1,12 +1,12 @@ /* * Author: Grey - * Loads Magazine into static weapon using a timer + * Loads Magazine into static weapon using a timer. * * Arguments: - * 0: static - * 1: unit - * 2: time to load - * 3: magazineClassOptional + * 0: Static + * 1: Unit + * 2: Time to load + * 3: Magazine Class (default: "") * * Return Value: * None @@ -20,7 +20,7 @@ params ["_static","_unit","_timeToLoad",["_magazineClassOptional","",[""]]]; -//Move player into animation if player is standing +// Move player into animation if player is standing if ((_unit call CBA_fnc_getUnitAnim) select 0 == "stand") then { [_unit, "AmovPercMstpSrasWrflDnon_diary", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/mk6mortar/functions/fnc_moduleInit.sqf b/addons/mk6mortar/functions/fnc_moduleInit.sqf index 3dedbb2c9e..4fef320117 100644 --- a/addons/mk6mortar/functions/fnc_moduleInit.sqf +++ b/addons/mk6mortar/functions/fnc_moduleInit.sqf @@ -17,10 +17,9 @@ */ #include "script_component.hpp" -PARAMS_3(_logic,_syncedUnits,_activated); +params ["_logic", "_syncedUnits", "_activated"]; if (!_activated) exitWith {WARNING("Module - placed but not active");}; -if (!isServer) exitWith {}; [_logic, QGVAR(airResistanceEnabled), "airResistanceEnabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(allowComputerRangefinder), "allowComputerRangefinder"] call EFUNC(common,readSettingFromModule); diff --git a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf index 1a3301d779..b98ee543f5 100644 --- a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf @@ -16,6 +16,6 @@ */ #include "script_component.hpp" -PARAMS_2(_vehicle,_player); +params ["_vehicle", "_player"]; "ACE_RangeTable_82mm" in (items _player); diff --git a/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf b/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf index 0f237e1a37..688253038c 100644 --- a/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf @@ -17,28 +17,26 @@ #define LIST_CHARGE ((uiNamespace getVariable "ACE_82mm_RangeTable_Dialog") displayCtrl 1501) -private ["_weaponName", "_magazines", "_initSpeed", "_fireModes", "_muzzleVelocities", "_showToPlayer", "_artilleryCharge"]; - -_weaponName = "mortar_82mm"; //todo: work on other weapons +private _weaponName = "mortar_82mm"; //todo: work on other weapons createDialog "ACE_82mm_RangeTable_Dialog"; if (isNull (uiNamespace getVariable ["ACE_82mm_RangeTable_Dialog", displayNull])) exitWith {ERROR("Dialog failed to open");}; //Get Magazine Types -_magazines = getArray (configFile >> "CfgWeapons" >> _weaponName >> "magazines"); +private _magazines = getArray (configFile >> "CfgWeapons" >> _weaponName >> "magazines"); //For now just get settings from first mag, all rounds have same flight characteristics: if ((count _magazines) < 1) exitWith {ERROR("No Magazines for weapon");}; -_initSpeed = getNumber (configFile >> "CfgMagazines" >> (_magazines select 0) >> "initSpeed"); +private _initSpeed = getNumber (configFile >> "CfgMagazines" >> (_magazines select 0) >> "initSpeed"); //Get Charge Modes -_fireModes = getArray (configFile >> "CfgWeapons" >> _weaponName >> "modes"); +private _fireModes = getArray (configFile >> "CfgWeapons" >> _weaponName >> "modes"); -_muzzleVelocities = []; +private _muzzleVelocities = []; { - _showToPlayer = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "showToPlayer"); + private _showToPlayer = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "showToPlayer"); if (_showToPlayer == 1) then { - _artilleryCharge = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "artilleryCharge"); + private _artilleryCharge = getNumber (configFile >> "CfgWeapons" >> _weaponName >> _x >> "artilleryCharge"); LIST_CHARGE lbAdd format ["%1: %2", (localize LSTRING(rangetable_charge)), (count _muzzleVelocities)]; LIST_CHARGE lbSetData [(count _muzzleVelocities), str (_artilleryCharge * _initSpeed)]; _muzzleVelocities pushBack _artilleryCharge; diff --git a/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf b/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf index 1090967e5a..e78fc40574 100644 --- a/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf @@ -18,15 +18,13 @@ #define RANGE_TABLE ((uiNamespace getVariable "ACE_82mm_RangeTable_Dialog") displayCtrl 20001) #define LIST_CHARGE ((uiNamespace getVariable "ACE_82mm_RangeTable_Dialog") displayCtrl 1501) -private ["_listBoxData", "_muzzleVelocity", "_airFriction", "_precalcArray"]; - -_listBoxData = LIST_CHARGE lbData (lbCurSel LIST_CHARGE); +private _listBoxData = LIST_CHARGE lbData (lbCurSel LIST_CHARGE); if (isNil "_listBoxData" || {_listBoxData == ""}) exitWith {ERROR("lbCurSel out of bounds or no data");}; -_muzzleVelocity = parseNumber _listBoxData; +private _muzzleVelocity = parseNumber _listBoxData; -_airFriction = if (GVAR(airResistanceEnabled)) then {MK6_82mm_AIR_FRICTION} else {0}; +private _airFriction = if (GVAR(airResistanceEnabled)) then {MK6_82mm_AIR_FRICTION} else {0}; -_precalcArray = [_muzzleVelocity, _airFriction] call FUNC(rangeTablePreCalculatedValues); +private _precalcArray = [_muzzleVelocity, _airFriction] call FUNC(rangeTablePreCalculatedValues); lnbClear RANGE_TABLE; { diff --git a/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf b/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf index d035959da4..a288ee03f9 100644 --- a/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf @@ -17,7 +17,7 @@ */ #include "script_component.hpp" -PARAMS_2(_muzzleVelocity,_airFriction); +params ["_muzzleVelocity", "_airFriction"]; switch (true) do { diff --git a/addons/mk6mortar/functions/fnc_toggleMils.sqf b/addons/mk6mortar/functions/fnc_toggleMils.sqf index 075c7c3143..cd2c7cf76f 100644 --- a/addons/mk6mortar/functions/fnc_toggleMils.sqf +++ b/addons/mk6mortar/functions/fnc_toggleMils.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -PARAMS_2(_mortarVeh,_unit); +params ["_mortarVeh", "_unit"]; private _currentSetting = _mortarVeh getVariable [QGVAR(useMils), true]; _mortarVeh setVariable [QGVAR(useMils), (!_currentSetting)]; diff --git a/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf b/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf index da7a529d86..924b00a90e 100644 --- a/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf +++ b/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf @@ -24,8 +24,6 @@ TRACE_2("params",_display,_rscType); if (_rscType != "Mk6Mortar") exitWith {}; if (isNull _display) exitWith {}; -private ["_fnc_hideControl", "_xPos", "_yPos", "_wPos", "_hPos"]; - #define CTRL_CA_OPTICSPITCH (configFile >> "RscInGameUI" >> "ACE_Mk6_RscWeaponRangeArtillery" >> "CA_IGUI_elements_group" >> "controls" >> "CA_OPTICSPITCH") #define CTRL_CA_OPTICSZOOM (configFile >> "RscInGameUI" >> "ACE_Mk6_RscWeaponRangeArtillery" >> "CA_IGUI_elements_group" >> "controls" >> "CA_OPTICSZOOM") #define CTRL_CA_SOLUTION_TEXT (configFile >> "RscInGameUI" >> "ACE_Mk6_RscWeaponRangeArtillery" >> "CA_IGUI_elements_group" >> "controls" >> "CA_SOLUTION_TEXT") @@ -40,11 +38,10 @@ private ["_fnc_hideControl", "_xPos", "_yPos", "_wPos", "_hPos"]; #define CTRL_CA_ELEV (configFile >> "RscInGameUI" >> "ACE_Mk6_RscWeaponRangeArtillery" >> "CA_IGUI_elements_group" >> "controls" >> "CA_ELEV") #define CTRL_CA_ELEV_NEED (configFile >> "RscInGameUI" >> "ACE_Mk6_RscWeaponRangeArtillery" >> "CA_IGUI_elements_group" >> "controls" >> "CA_ELEV_NEED") -_fnc_hideControl = { - private ["_idc", "_pos"]; - PARAMS_2(_path,_hideCtrl); - _idc = getNumber (_path >> "IDC"); - _pos = []; +private _fnc_hideControl = { + params ["_path", "_hideCtrl"]; + private _idc = getNumber (_path >> "IDC"); + private _pos = []; if (_hideCtrl) then { _pos = [-9,-9,0,0]; } else { diff --git a/addons/mk6mortar/functions/fnc_unloadMagazine.sqf b/addons/mk6mortar/functions/fnc_unloadMagazine.sqf index c485a39a3a..9aa0fa0437 100644 --- a/addons/mk6mortar/functions/fnc_unloadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_unloadMagazine.sqf @@ -18,12 +18,11 @@ #include "script_component.hpp" params ["_static","_unit"]; -private ["_currentMagazine","_currentMagazineClass","_ammoCount"]; //Get weapon & magazine information about static weapon -_currentMagazine = (magazinesAllTurrets _static) select 1; -_currentMagazineClass = _currentMagazine select 0; -_ammoCount = _currentMagazine select 2; +private _currentMagazine = (magazinesAllTurrets _static) select 1; +private _currentMagazineClass = _currentMagazine select 0; +private _ammoCount = _currentMagazine select 2; // Try to add the round to player inventory, otherwise place it on the ground near the player if (_ammoCount > 0) then { diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index 58c0af47d6..b6dbbc2db5 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -65,6 +65,14 @@ 装药 裝藥 + + Mk6 Mortar + Mk6 Mörser + Mortaio Mk6 + MK6迫擊炮 + MK6迫击炮 + Mk6 迫撃砲 + Mk6 Settings Moździerz Mk6 - Ustawienia @@ -110,8 +118,8 @@ Per Proiettili dei Giocatori, simula la Resistenza dell'Aria e gli Effetti del Vento プレイヤが射撃すると、空気抵抗モデルと風による影響をあたえます。 플레이어 사격시 공기저항과 바람에 영향을 받습니다 - 设定由玩家射击的迫击炮, 将会受到空气阻力与风力的影响 - 設定由玩家射擊的迫擊砲, 將會受到空氣阻力與風力的影響 + 设定由玩家射击的迫击炮,将会受到空气阻力与风力的影响 + 設定由玩家射擊的迫擊砲,將會受到空氣阻力與風力的影響 Allow Mk6 Computer @@ -142,8 +150,8 @@ Mostra il Computer e Distaziometro (questi DEVONO essere rimossi se vuoi abilitare la resistenza dell'aria) コンピュータと距離を表示します (空気抵抗を有効化している場合は必ず削除してください) 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을경우 이 항목은 비활성화 되어야만 합니다) - 显示射控电脑和测距仪 (如果有启用空气阻力功能时, 须停用此项功能) - 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時, 須停用此項功能) + 显示射控电脑和测距仪 (如果有启用空气阻力功能时,须停用此项功能) + 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時,須停用此項功能) Allow Mk6 Compass @@ -189,8 +197,8 @@ Este módulo permite configurar los parámetros del mortero Mk6. Mk6 迫撃砲への設定をできます。 이 모듈은 Mk6 설치 설정을 가능케 합니다. - 这个模块允许你设定MK6迫击炮的相关功能. - 這個模塊允許你設定MK6迫擊砲的相關功能. + 这个模块允许你设定MK6迫击炮的相关功能 + 這個模塊允許你設定MK6迫擊砲的相關功能 Use Ammunition handling @@ -217,8 +225,8 @@ Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжащим. Не влияет на артиллерию ИИ. 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI 迫撃砲へ影響を与えません。 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야만 합니다. 인공지능은 영향을 받지 않습니다. - 开启此功能时. 迫击炮的弹药需由炮手与装填手共同合作来进行装填. 此功能并不影响由AI射击的迫击炮. - 開啟此功能時. 迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填. 此功能並不影響由AI射擊的迫擊砲. + 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由AI射击的迫击炮 + 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 Remove Round diff --git a/addons/modules/XEH_postInit.sqf b/addons/modules/XEH_postInit.sqf index dcd6277aed..c6892046fe 100644 --- a/addons/modules/XEH_postInit.sqf +++ b/addons/modules/XEH_postInit.sqf @@ -39,6 +39,7 @@ }; if (_isDisposable) then { + if (_isGlobal) then {WARNING_1("Deleting Global Module??? [%1]",_logicType);}; deleteVehicle _logic; }; }; diff --git a/addons/movement/ACE_Settings.hpp b/addons/movement/ACE_Settings.hpp deleted file mode 100644 index fdc0bd36b0..0000000000 --- a/addons/movement/ACE_Settings.hpp +++ /dev/null @@ -1,8 +0,0 @@ -class ACE_Settings { - class GVAR(useImperial) { - value = 0; - typeName = "BOOL"; - isClientSettable = 1; - displayName = CSTRING(UseImperial); - }; -}; diff --git a/addons/movement/CfgEventHandlers.hpp b/addons/movement/CfgEventHandlers.hpp index 083c5bb089..6aee79933c 100644 --- a/addons/movement/CfgEventHandlers.hpp +++ b/addons/movement/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); @@ -19,6 +18,6 @@ class Extended_PostInit_EventHandlers { class Extended_DisplayLoad_EventHandlers { class RscDisplayInventory { - ADDON = QUOTE(_this call COMPILE_FILE(XEH_inventoryDisplayLoad)); + ADDON = QUOTE(_this call FUNC(inventoryDisplayLoad)); }; }; diff --git a/addons/movement/XEH_PREP.hpp b/addons/movement/XEH_PREP.hpp index 04913f7670..ceafa7f5dc 100644 --- a/addons/movement/XEH_PREP.hpp +++ b/addons/movement/XEH_PREP.hpp @@ -1,7 +1,6 @@ - PREP(addLoadToUnitContainer); -PREP(getWeight); PREP(canClimb); PREP(climb); PREP(handleClimb); PREP(handleVirtualMass); +PREP(inventoryDisplayLoad); diff --git a/addons/movement/XEH_inventoryDisplayLoad.sqf b/addons/movement/XEH_inventoryDisplayLoad.sqf deleted file mode 100644 index ae717e7b39..0000000000 --- a/addons/movement/XEH_inventoryDisplayLoad.sqf +++ /dev/null @@ -1,14 +0,0 @@ -#include "script_component.hpp" - -disableSerialization; - -[{ - disableSerialization; - params ["_dialog"]; - - if (isNull _dialog) exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; - - (_dialog displayCtrl 111) ctrlSetText format ["%1 - %2 %3", [ACE_player, false, true] call EFUNC(common,getName), localize LSTRING(Weight), [ACE_player] call FUNC(getWeight)]; -}, 0, _this select 0] call CBA_fnc_addPerFrameHandler; diff --git a/addons/movement/config.cpp b/addons/movement/config.cpp index 14a3b8f68d..4979faf819 100644 --- a/addons/movement/config.cpp +++ b/addons/movement/config.cpp @@ -18,4 +18,3 @@ class CfgPatches { #include "CfgFatigue.hpp" #include "CfgMoves.hpp" #include "CfgVehicles.hpp" -#include "ACE_Settings.hpp" diff --git a/addons/movement/functions/fnc_handleClimb.sqf b/addons/movement/functions/fnc_handleClimb.sqf index ed3ff93d7e..84f78cfcc0 100644 --- a/addons/movement/functions/fnc_handleClimb.sqf +++ b/addons/movement/functions/fnc_handleClimb.sqf @@ -24,4 +24,5 @@ private _pos = _unit modelToWorldVisual (_unit selectionPosition "camera"); _pos = _pos vectorDiff (_unit selectionPosition "camera"); -_unit setPos _pos; +_unit setPosASL (AGLtoASL _pos); +TRACE_2("",AGLtoASL _pos,getPosASL _unit); diff --git a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf b/addons/movement/functions/fnc_inventoryDisplayLoad.sqf new file mode 100644 index 0000000000..f7c240f332 --- /dev/null +++ b/addons/movement/functions/fnc_inventoryDisplayLoad.sqf @@ -0,0 +1,35 @@ +/* + * Author: commy2 + * Executed every time an inventory display is opened. + * + * Arguments: + * 0: Inventory display + * + * Return Value: + * None + * + * Example: + * [DISPLAY] call ACE_movement_fnc_inventoryDisplayLoad + * + * Public: No + */ +#include "script_component.hpp" + +params ["_display"]; + +private _fnc_update = { + params ["_display"]; + private _control = _display displayCtrl 111; + + _control ctrlSetText format ["%1 - %2 %3 (%4)", + [ACE_player, false, true] call EFUNC(common,getName), + localize ELSTRING(common,Weight), + [ACE_player] call EFUNC(common,getWeight), + [ACE_player, true] call EFUNC(common,getWeight) + ]; +}; + +_display displayAddEventHandler ["MouseMoving", _fnc_update]; +_display displayAddEventHandler ["MouseHolding", _fnc_update]; + +_display call _fnc_update; diff --git a/addons/movement/stringtable.xml b/addons/movement/stringtable.xml index 5bba66974a..2d587ce3d2 100644 --- a/addons/movement/stringtable.xml +++ b/addons/movement/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -17,22 +17,6 @@ 使用磅来显示重量 使用磅來顯示重量 - - Weight: - Gewicht: - Peso: - Poids : - Waga: - Váha: - Peso: - Peso: - Súly: - Вес: - 重量: - 무게: - 重量: - 重量: - Climb Grimper @@ -63,6 +47,7 @@ ここは登れない 这里无法攀爬 這裡無法攀爬 + 여기는 올라갈 수 없다 diff --git a/addons/nametags/ACE_Settings.hpp b/addons/nametags/ACE_Settings.hpp index ab6220f131..5f2956d03c 100644 --- a/addons/nametags/ACE_Settings.hpp +++ b/addons/nametags/ACE_Settings.hpp @@ -56,12 +56,14 @@ class ACE_Settings { typeName = "SCALAR"; isClientSettable = 0; category = CSTRING(Module_DisplayName); + sliderSettings[] = {0, 50, 5, 1}; }; class GVAR(playerNamesMaxAlpha) { value = 0.8; typeName = "SCALAR"; isClientSettable = 0; category = CSTRING(Module_DisplayName); + sliderSettings[] = {0, 1, 0.8, 2}; }; class GVAR(tagSize) { value = 2; diff --git a/addons/nametags/CfgVehicles.hpp b/addons/nametags/CfgVehicles.hpp index 47f530df68..e712459f68 100644 --- a/addons/nametags/CfgVehicles.hpp +++ b/addons/nametags/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(moduleNameTags); - scope = 2; + scope = 1; isGlobal = 1; isSingular = 1; icon = QPATHTOF(UI\Icon_Module_NameTags_ca.paa); diff --git a/addons/nametags/functions/fnc_doShow.sqf b/addons/nametags/functions/fnc_doShow.sqf index c21d587c0b..08ab633f28 100644 --- a/addons/nametags/functions/fnc_doShow.sqf +++ b/addons/nametags/functions/fnc_doShow.sqf @@ -16,24 +16,22 @@ #include "script_component.hpp" #include "common.hpp" -private ["_roleImages", "_player", "_vehicle", "_type", "_config", "_text", "_data", "_isAir", "_turretUnits", "_turretRoles", "_index", "_roleType", "_unit", "_toShow"]; +private _player = ACE_player; +private _vehicle = vehicle _player; +private _type = typeOf _vehicle; +private _config = configFile >> "CfgVehicles" >> _type; +private _text = format[" %2
", getText(_config>>"picture"), getText (_config >> "DisplayName")]; -_player = ACE_player; -_vehicle = vehicle _player; -_type = typeOf _vehicle; -_config = configFile >> "CfgVehicles" >> _type; -_text = format[" %2
", getText(_config>>"picture"), getText (_config >> "DisplayName")]; +private _data = [_type] call FUNC(getVehicleData); -_data = [_type] call FUNC(getVehicleData); +private _isAir = _data select 0; +private _data = _data select 1; -_isAir = _data select 0; -_data = _data select 1; +private _turretUnits = _data apply {_vehicle turretUnit (_x select 0)}; +private _turretRoles = _data apply {_x select 1}; -_turretUnits = _data apply {_vehicle turretUnit (_x select 0)}; -_turretRoles = _data apply {_x select 1}; - -_roleType = CARGO; -_toShow = []; +private _roleType = CARGO; +private _toShow = []; { switch (_x) do { case commander _vehicle: { @@ -70,10 +68,10 @@ _toShow = [ } ] call BIS_fnc_sortBy; -_roleImages = ROLE_IMAGES; +private _roleImages = ROLE_IMAGES; { - _unit = _x select 0; - _roleType = _x select 1; + private _unit = _x select 0; + private _roleType = _x select 1; _text = _text + format["%1
", [_unit] call EFUNC(common,getName), _roleImages select _roleType]; } forEach _toShow; diff --git a/addons/nametags/functions/fnc_initIsSpeaking.sqf b/addons/nametags/functions/fnc_initIsSpeaking.sqf index 9428768ec8..6624f59485 100644 --- a/addons/nametags/functions/fnc_initIsSpeaking.sqf +++ b/addons/nametags/functions/fnc_initIsSpeaking.sqf @@ -54,9 +54,8 @@ if (isClass (configFile >> "CfgPatches" >> "acre_api")) then { //Note: class RscDisplayVoiceChat {idd = 55} - only present when talking [{ - private ["_oldSetting", "_newSetting"]; - _oldSetting = ACE_player getVariable [QGVAR(isSpeakingInGame), false]; - _newSetting = (!(isNull findDisplay 55)); + private _oldSetting = ACE_player getVariable [QGVAR(isSpeakingInGame), false]; + private _newSetting = (!(isNull findDisplay 55)); if (!(_oldSetting isEqualTo _newSetting)) then { ACE_player setVariable [QGVAR(isSpeakingInGame), _newSetting, true]; }; diff --git a/addons/nametags/functions/fnc_moduleNameTags.sqf b/addons/nametags/functions/fnc_moduleNameTags.sqf index e1fa1a5dc7..c2d0cf8c79 100644 --- a/addons/nametags/functions/fnc_moduleNameTags.sqf +++ b/addons/nametags/functions/fnc_moduleNameTags.sqf @@ -16,8 +16,6 @@ #include "script_component.hpp" -if !(isServer) exitWith {}; - params ["_logic", "", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/nametags/functions/fnc_setText.sqf b/addons/nametags/functions/fnc_setText.sqf index 9bc084cfd4..688ecabc4a 100644 --- a/addons/nametags/functions/fnc_setText.sqf +++ b/addons/nametags/functions/fnc_setText.sqf @@ -19,10 +19,8 @@ params ["_text"]; -private ["_ctrl"]; - disableSerialization; -_ctrl = (uiNamespace getVariable QGVAR(dialog)) displayCtrl TextIDC; +private _ctrl = (uiNamespace getVariable QGVAR(dialog)) displayCtrl TextIDC; _ctrl ctrlSetStructuredText parseText _text; _ctrl ctrlCommit 0; diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index fde54a8607..ef6f27fb16 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -44,7 +44,7 @@ Mostrar nome de jogador somente no cursor (requer nome de jogadores) Játékosok nevének mutatása csak a kurzoron (a nevek mutatása szükséges) Показать имена игроков только под курсором (при включенных именах) - カーソルを合わせた時だけプレイヤ名を表示 (プレイヤ名が必要 + カーソルを合わせた時だけプレイヤ名を表示 (プレイヤ名が必要) 커서로 지시할때만 플레이어 이름 표시(플레이어 이름 필요) 仅在准心指到后显示玩家名称 (玩家必须有设定名称) 僅在準心指到後顯示玩家名稱 (玩家必須有設定名稱) @@ -126,8 +126,8 @@ Mostrar onda sonora (requer nome de jogadores) 音波形を表示 (プレイヤ名が必要) 음파 표시 (플레이어 이름 필요) - 当玩家讲话时, 显示声波图案 (玩家必须有设定名称) - 當玩家講話時, 顯示聲波圖案 (玩家必須有設定名稱) + 当玩家讲话时,显示声波图案 (玩家必须有设定名称) + 當玩家講話時,顯示聲波圖案 (玩家必須有設定名稱) Default Nametag Color (Non Group Members) @@ -188,10 +188,10 @@ Méterben megadott érték a játékosok nevének mutatására. Alapértelmezett: 5 Дистанция в метрах, на которой отображаются имена игроков. По-умолчанию: 5 Distanza in metri a cui sono visibili i nomi giocatori. Default: 5 - プレイヤの周り何メートルまで名札を表示できます。標準:5 + プレイヤの周り何メートルまで名札を表示できます。標準: 5 플레이어 이름이 표시되는 미터. 기본설정: 5 - 设定名称在多少距离以内显示. 预设:5公尺 - 設定名稱在多少距離以內顯示. 預設:5公尺 + 设定名称在多少距离以内显示。预设:5公尺 + 設定名稱在多少距離以內顯示。預設:5公尺 Show name tags for AI? @@ -204,7 +204,7 @@ Névcímkék megjelenítése AI-nál? Показывать имена ботов? Mostra etichette nomi per IA? - AI の名札も表示しますか? + AI の名札も表示しますか? 인공지능의 이름도 표시합니까? 显示AI名称? 顯示AI名稱? @@ -220,7 +220,7 @@ Mutassa-e a szövetséges AI egységek nevét és rangját? Alapértelmezett: Nincs felülbírálás Показывать имена и звания дружественных ботов? По-умолчанию: Не обязывать Mostra etichette nomi ed etichette gradi per unità IA alleate? Default: Non forzare - 友軍の AI にも名前と階級を表示しますか?標準:強制しない + 友軍の AI にも名前と階級を表示しますか? 標準: 強制しない 아군 인공지능의 계급을 표시합니까? 기본설정: 강제하지 않음 显示友军AI的名称和军阶? 预设: 不显示 顯示友軍AI的名稱和軍階? 預設: 不顯示 @@ -284,10 +284,10 @@ A legénységi adatok mutatása, alapértelmezett esetben a játékos által kiválasztható. Alapértelmezett: Nincs felülbírálás Показывать информацию об экипаже техники, или по-умолчанию, позволяет игрокам выбрать свою настройку. По-умолчанию: Не обязывать Mostra informazioni sull'equipaggio del veicolo, oppure consenti di default di lasciare che siano i giocatori a scegliere. Default: Non Forzare - 車両の乗員を表示します。標準ではプレイヤ各々が選べられます。標準:強制しない + 車両の乗員を表示します。標準ではプレイヤ各々が選べられます。標準: 強制しない 승무원 정보를 표시하거나 플레이어가 직접 고르게 냅둡니다. 기본설정: 강제하지 않음 - 显示载具成员讯息. 在预设的情况下, 系统允许玩家自己决定开关此讯息. 预设: 不显示 - 顯示載具成員訊息. 在預設的情況下, 系統允許玩家自己決定開關此訊息. 預設: 不顯示 + 显示载具成员讯息。在预设的情况下,系统允许玩家自己决定开关此讯息。预设: 不显示 + 顯示載具成員訊息。在預設的情況下,系統允許玩家自己決定開關此訊息。預設: 不顯示 Show for Vehicles @@ -315,10 +315,10 @@ Показывать имя командира техники (только, если клиент включил отображение имен). По-умолчанию: Нет Afficher les étiquettes de nom pour les commandants de véhicule (uniquement si l'affichage est activé pour le client). Défaut: non Mostra il nome sul cursore per il comandante del veicolo (solo se il client ha le Etichette Nomi attive) Default: No - 車長の名札をカーソルを当てて表示します (クライアント側で名札を有効化する必要があります) 標準:無効 + 車長の名札をカーソルを当てて表示します (クライアント側で名札を有効化する必要があります) 標準: 無効 차량의 사령관의 이름표를 표시합니다 (오직 클라이언트가 이름표를 활성화 할시에만 보입니다) 기본설정: 아니요 - 使载具指挥官能透过准心指到别的单位来显示其名称 (仅当客户端的名称功能已启用). 预设: 关闭 - 使載具指揮官能透過準心指到別的單位來顯示其名稱 (僅當客戶端的名稱功能已啟用). 預設: 關閉 + 使载具指挥官能透过准心指到别的单位来显示其名称 (仅当客户端的名称功能已启用)。预设: 关闭 + 使載具指揮官能透過準心指到別的單位來顯示其名稱 (僅當客戶端的名稱功能已啟用)。預設: 關閉 This module allows you to customize settings and range of Name Tags. @@ -333,8 +333,8 @@ Questo modulo ti consente di personalizzare le impostazioni ed il raggio delle Etichette Nomi このモジュールは名札の表示範囲と設定を変更できます。 이 모듈은 당신이 이름표의 범위를 임의로 수정할 수 있게 해줍니다. - 这个模块允许您设定名称和显示范围等设定. - 這個模塊允許您設定名稱和顯示範圍等設定. + 这个模块允许您设定名称和显示范围等设定 + 這個模塊允許您設定名稱和顯示範圍等設定 Only on Cursor @@ -475,10 +475,10 @@ Mutassa a játékosok nevét és kezelje az aktivációjukat. Alapértelmezett: Engedélyezve Показывать имена игроков и установить их активацию. По-умолчанию: Включено Mostra nomi giocatori ed imposta la loro attivazione. Default: Abilitato - プレイヤ名の表示と設定を有効化します。標準:有効 + プレイヤ名の表示と設定を有効化します。標準: 有効 플레이어 이름의 표시와 설정을 활성화합니다. 기본설정: 활성화 - 显示玩家的名称并设置其启动方式. 预设: 启用 - 顯示玩家的名稱並設置其啟動方式. 預設: 啟用 + 显示玩家的名称并设置其启动方式。预设: 启用 + 顯示玩家的名稱並設置其啟動方式。預設: 啟用 Effect of sound waves above the heads of speaking players after holding the PTT key. This option works with TFAR and ACRE2. @@ -493,8 +493,8 @@ Effetto delle onde sonore sopra la testa dei giocatori parlanti quando premono il tasto PTT. Questa opzione funziona con TFAR ed ACRE2 プレイヤーが PTT キーを押している間は、音波形を表示します。このオプションは TFAR と ACRE2 で動作します。 플레이어가 PTT로 말할시 머리위에 음파효과를 적용합니다. 이 옵션은 TFAR과 ACRE2가 있을때만 적용됩니다. - 当玩家使用按键发话时, 其头上的角色名称旁会显示声波的图案. 此功能可搭配TFAR、ACRE2等模组使用. - 當玩家使用按鍵發話時, 其頭上的角色名稱旁會顯示聲波的圖案. 此功能可搭配TFAR、ACRE2等模組使用. + 当玩家使用按键发话时,其头上的角色名称旁会显示声波的图案。此功能可搭配TFAR、ACRE2等模组使用。 + 當玩家使用按鍵發話時,其頭上的角色名稱旁會顯示聲波的圖案。此功能可搭配TFAR、ACRE2等模組使用。 Nametags Size diff --git a/addons/nightvision/ACE_Settings.hpp b/addons/nightvision/ACE_Settings.hpp index 32dbab7fff..2cf90a2c05 100644 --- a/addons/nightvision/ACE_Settings.hpp +++ b/addons/nightvision/ACE_Settings.hpp @@ -1,8 +1,32 @@ class ACE_Settings { class GVAR(disableNVGsWithSights) { + category = CSTRING(Category); displayName = CSTRING(DisableNVGsWithSights_DisplayName); description = CSTRING(DisableNVGsWithSights_description); typeName = "BOOL"; value = 0; }; + class GVAR(fogScaling) { + category = CSTRING(Category); + displayName = CSTRING(fogScaling_DisplayName); + description = CSTRING(fogScaling_Description); + typeName = "SCALAR"; + value = 1; + sliderSettings[] = {0, 2, 1, 1}; + }; + class GVAR(effectScaling) { + category = CSTRING(Category); + displayName = CSTRING(effectScaling_DisplayName); + description = CSTRING(effectScaling_Description); + typeName = "SCALAR"; + value = 1; + sliderSettings[] = {0, 2, 1, 1}; + }; + class GVAR(aimDownSightsBlur) { + category = CSTRING(Category); + displayName = CSTRING(aimDownSightsBlur_DisplayName); + typeName = "SCALAR"; + value = 1; + sliderSettings[] = {0, 2, 1, 1}; + }; }; diff --git a/addons/nightvision/CfgEventHandlers.hpp b/addons/nightvision/CfgEventHandlers.hpp index 152887a24a..5f8c191f66 100644 --- a/addons/nightvision/CfgEventHandlers.hpp +++ b/addons/nightvision/CfgEventHandlers.hpp @@ -1,30 +1,22 @@ - 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) ); + init = QUOTE(call COMPILE_FILE(XEH_preInit)); }; }; - class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient)); + init = QUOTE(call COMPILE_FILE(XEH_postInit)); }; }; +// In SP-Editor, opening escape menu will break nvg grain effect class Extended_DisplayLoad_EventHandlers { - class RscDisplayCurator { - ADDON = QUOTE(_this call FUNC(updatePPEffects)); - }; -}; - -class Extended_DisplayUnload_EventHandlers { - class RscDisplayCurator { - ADDON = QUOTE(displayNull call FUNC(updatePPEffects)); // emulate zeus display being deleted + class RscDisplayInterrupt { + GVAR(resetGrain) = QUOTE(if (GVAR(ppeffectGrain) > -1) then {ppEffectDestroy GVAR(ppeffectGrain);};); }; }; diff --git a/addons/nightvision/CfgVehicles.hpp b/addons/nightvision/CfgVehicles.hpp index c540251dbb..6b7b04f25d 100644 --- a/addons/nightvision/CfgVehicles.hpp +++ b/addons/nightvision/CfgVehicles.hpp @@ -1,9 +1,4 @@ class CfgVehicles { - class All { - ACE_NightVision_grain = 0.75; - ACE_NightVision_blur = 0.055; - }; - class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { class TransportItems { @@ -17,7 +12,7 @@ class CfgVehicles { class ACE_Module; class GVAR(ModuleSettings): ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_ca.paa); category = "ACE"; diff --git a/addons/nightvision/CfgWeapons.hpp b/addons/nightvision/CfgWeapons.hpp index 72be31d8cf..5d87b0170c 100644 --- a/addons/nightvision/CfgWeapons.hpp +++ b/addons/nightvision/CfgWeapons.hpp @@ -2,55 +2,85 @@ class CfgWeapons { class Binocular; class NVGoggles: Binocular { displayName = CSTRING(NVG_Gen3_brown); - ACE_NightVision_grain = 0.75; - ACE_NightVision_blur = 0.055; - ACE_NightVision_radBlur = 0.001; + modelOptics = ""; + GVAR(border) = QPATHTOF(data\nvg_mask_binos_4096.paa); + GVAR(bluRadius) = 0.15; + }; + class O_NVGoggles_hex_F: NVGoggles { // APEX NVG with multiple lenses (spider eyes) + modelOptics = ""; + GVAR(border) = QPATHTOF(data\nvg_mask_quad_4096.paa); // Use quad tube mask + GVAR(bluRadius) = 0.26; + }; + class NVGogglesB_grn_F: NVGoggles { // APEX NVG/Thermal + modelOptics = "\A3\weapons_f\reticle\optics_night"; // use vanilla modelOptics so it will show in IR mode }; class NVGoggles_OPFOR: NVGoggles { + modelOptics = ""; displayName = CSTRING(NVG_Gen3_black); }; class NVGoggles_INDEP: NVGoggles { + modelOptics = ""; displayName = CSTRING(NVG_Gen3_green); }; - class ACE_NVG_Gen1: NVGoggles_OPFOR { author = ECSTRING(common,ACETeam); - modelOptics = "\A3\weapons_f\reticle\optics_night"; displayName = CSTRING(NVG_Gen1); - ACE_NightVision_grain = 2.25; - ACE_NightVision_blur = 0.22; - ACE_NightVision_radBlur = 0.004; + GVAR(generation) = 1; }; class ACE_NVG_Gen2: NVGoggles_INDEP { author = ECSTRING(common,ACETeam); - modelOptics = "\A3\weapons_f\reticle\optics_night"; displayName = CSTRING(NVG_Gen2); - ACE_NightVision_grain = 1.5; - ACE_NightVision_blur = 0.11; - ACE_NightVision_radBlur = 0.002; + GVAR(generation) = 2; }; - /*class ACE_NVG_Gen3: NVGoggles { - author = ECSTRING(common,ACETeam); - modelOptics = "\A3\weapons_f\reticle\optics_night"; - displayName = CSTRING(NVG_Gen3); - ACE_NightVision_grain = 0.75; - ACE_NightVision_blur = 0.055; - ACE_NightVision_radBlur = 0.001; -};*/ class ACE_NVG_Gen4: NVGoggles { author = ECSTRING(common,ACETeam); - modelOptics = "\A3\weapons_f\reticle\optics_night"; displayName = CSTRING(NVG_Gen4); - ACE_NightVision_grain = 0.0; - ACE_NightVision_blur = 0.0; - ACE_NightVision_radBlur = 0.0; + GVAR(generation) = 4; }; class ACE_NVG_Wide: NVGoggles { author = ECSTRING(common,ACETeam); modelOptics = QPATHTOF(models\ACE_nvg_wide_optics); displayName = CSTRING(NVG_FullScreen); - ACE_NightVision_grain = 0.75; - ACE_NightVision_blur = 0.055; - ACE_NightVision_radBlur = 0.001; + }; + + + // Examples of different goggle effect types (scope=1) + // These all function differently, but we have no models to go with them + class ACE_NVG_Biocular: NVGoggles { + scope = 1; + modelOptics = ""; + author = ECSTRING(common,ACETeam); + descriptionShort = "Biocular nightvision goggles"; + displayName = "NV Goggles (Bio)"; + GVAR(border) = QPATHTOF(data\nvg_mask_4096.paa); + GVAR(bluRadius) = 0.13; + GVAR(eyeCups) = 1; + }; + class ACE_NVG_Monocular: NVGoggles { + scope = 1; + modelOptics = ""; + author = ECSTRING(common,ACETeam); + descriptionShort = "Monocular nightvision goggles"; + displayName = "NV Goggles (Mono)"; + GVAR(border) = QPATHTOF(data\nvg_mask_4096.paa); + GVAR(bluRadius) = 0.13; + }; + class ACE_NVG_Binocular: NVGoggles { + scope = 1; + modelOptics = ""; + author = ECSTRING(common,ACETeam); + descriptionShort = "Binocular nightvision goggles"; + displayName = "NV Goggles (Bino)"; + GVAR(border) = QPATHTOF(data\nvg_mask_binos_4096.paa); + GVAR(bluRadius) = 0.15; + }; + class ACE_NVG_Quadocular: NVGoggles { + scope = 1; + modelOptics = ""; + author = ECSTRING(common,ACETeam); + descriptionShort = "Quadocular nightvision goggles"; + displayName = "NV Goggles (Quad)"; + GVAR(border) = QPATHTOF(data\nvg_mask_quad_4096.paa); + GVAR(bluRadius) = 0.26; }; }; diff --git a/addons/nightvision/RscTitles.hpp b/addons/nightvision/RscTitles.hpp new file mode 100644 index 0000000000..98c2b11cb3 --- /dev/null +++ b/addons/nightvision/RscTitles.hpp @@ -0,0 +1,41 @@ +class RscPicture; +class RscText; + +class RscTitles { + class GVAR(title) { + idd = 10777; + movingEnable = 1; + enableSimulation = 1; + enableDisplay = 1; + + onLoad = QUOTE(with uiNamespace do {GVAR(titleDisplay) = _this select 0};); + onunLoad = ""; + + duration = 999999; + fadein = 0; + fadeout = 0; + + class controls { + class Hexes: RscPicture { + idc = 1000; + }; + class Mask: RscPicture { + idc = 1001; + }; + + // Add blinders for side monitors for tripple monitors (mask won't cover them) + class trippleHeadLeft: RscPicture { + idc = 1002; + text = "#(argb,8,8,3)color(0,0,0,1)"; + x = "safeZoneXAbs"; + Y = "safezoneY"; + W = "(safezoneX - safeZoneXAbs) * ((getResolution select 4)/(16/3))"; + H = "safeZoneH"; + }; + class trippleHeadRight: trippleHeadLeft { + idc = 1003; + x = "safeZoneXAbs + safeZoneWAbs - (safezoneX - safeZoneXABS) * ((getResolution select 4)/(16/3))"; + }; + }; + }; +}; diff --git a/addons/nightvision/XEH_PREP.hpp b/addons/nightvision/XEH_PREP.hpp index 251c8cc5dd..c212d22b18 100644 --- a/addons/nightvision/XEH_PREP.hpp +++ b/addons/nightvision/XEH_PREP.hpp @@ -1,7 +1,12 @@ -PREP(blending); PREP(changeNVGBrightness); PREP(initModule); +PREP(nonDedicatedFix); PREP(onCameraViewChanged); +PREP(onFiredPlayer); +PREP(onLoadoutChanged); PREP(onVisionModeChanged); -PREP(updatePPEffects); +PREP(pfeh); +PREP(refreshGoggleType); +PREP(scaleCtrl); +PREP(setupDisplayEffects); diff --git a/addons/nightvision/XEH_postInit.sqf b/addons/nightvision/XEH_postInit.sqf new file mode 100644 index 0000000000..986013d106 --- /dev/null +++ b/addons/nightvision/XEH_postInit.sqf @@ -0,0 +1,101 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +GVAR(PFID) = -1; +GVAR(running) = false; +GVAR(nextEffectsUpdate) = -1; + +GVAR(playerHMD) = "#"; + +GVAR(priorFog) = nil; +GVAR(nvgFog) = [0,0,0]; + +GVAR(nvgBlurRadius) = -1; +GVAR(nvgGeneration) = -1; +GVAR(defaultPositionBorder) = []; +GVAR(defaultPositionHex) = []; + +GVAR(ppeffectGrain) = -1; +GVAR(ppeffectRadialBlur) = -1; +GVAR(ppeffectColorCorrect) = -1; +GVAR(ppeffectBlur) = -1; + + +["ace_settingsInitialized", { + TRACE_3("settingsInitialized",GVAR(disableNVGsWithSights),GVAR(fogScaling),GVAR(effectScaling)); + + ["visionMode", LINKFUNC(onVisionModeChanged), false] call CBA_fnc_addPlayerEventHandler; + + // handle only brightness if effects are disabled + if (GVAR(effectScaling) == 0) exitWith { + GVAR(ppEffectNVGBrightness) = ppEffectCreate ["ColorCorrections", 1236]; + GVAR(ppEffectNVGBrightness) ppEffectForceInNVG true; + GVAR(ppEffectNVGBrightness) ppEffectAdjust [1, (-3+3)/5 + 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; + GVAR(ppEffectNVGBrightness) ppEffectCommit 0; + }; + + ["loadout", LINKFUNC(onLoadoutChanged), true] call CBA_fnc_addPlayerEventHandler; + ["cameraView", LINKFUNC(onCameraViewChanged), true] call CBA_fnc_addPlayerEventHandler; + ["vehicle", LINKFUNC(refreshGoggleType), false] call CBA_fnc_addPlayerEventHandler; + ["turret", LINKFUNC(refreshGoggleType), true] call CBA_fnc_addPlayerEventHandler; + + ["ace_firedPlayer", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(onFiredPlayer)] call CBA_fnc_addEventHandler; + + + addMissionEventHandler ["Loaded", { // Restart UI vars on mission load + if (GVAR(running)) then { + TRACE_1("restarting effects",CBA_missionTime); + [false] call FUNC(setupDisplayEffects); + [true] call FUNC(setupDisplayEffects); + }; + }]; +}] call CBA_fnc_addEventHandler; + + +// Handle an edge case for non-dedicated servers were the server running the fog effect would sync fog to other clients +[QGVAR(nonDedicatedFix), LINKFUNC(nonDedicatedFix)] call CBA_fnc_addEventHandler; +if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If var is defined, run it now (we must be a jip) + + +// Add keybinds +["ACE3 Equipment", QGVAR(IncreaseNVGBrightness), localize LSTRING(IncreaseNVGBrightness), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if ((currentVisionMode ACE_player != 1)) exitWith {false}; + if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + + // Statement + [ACE_player, 1] call FUNC(changeNVGBrightness); + true +}, {false}, [201, [false, false, true]], false] call CBA_fnc_addKeybind; //PageUp + ALT + +["ACE3 Equipment", QGVAR(DecreaseNVGBrightness), localize LSTRING(DecreaseNVGBrightness), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if ((currentVisionMode ACE_player != 1)) exitWith {false}; + if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + + // Statement + [ACE_player, -1] call FUNC(changeNVGBrightness); + true +}, {false}, [209, [false, false, true]], false] call CBA_fnc_addKeybind; //PageDown + ALT + +#ifdef DEBUG_MODE_FULL +WARNING("Debug mouse wheel action enabled, this should NOT be in a final release"); +["MouseZChanged", { + GVAR(nextEffectsUpdate) = 0; + if (cba_events_shift) then { + GVAR(effectScaling) = ((GVAR(effectScaling) + ((_this select 1) / 20)) max 0) min 1; + systemChat format ["%1: %2", QGVAR(effectScaling), GVAR(effectScaling)]; + }; + if (cba_events_control) then { + GVAR(fogScaling) = ((GVAR(fogScaling) + ((_this select 1) / 20)) max 0) min 1; + systemChat format ["%1: %2", QGVAR(fogScaling), GVAR(fogScaling)]; + }; +}] call CBA_fnc_addDisplayHandler; +#endif + diff --git a/addons/nightvision/XEH_postInitClient.sqf b/addons/nightvision/XEH_postInitClient.sqf deleted file mode 100644 index de0b629d76..0000000000 --- a/addons/nightvision/XEH_postInitClient.sqf +++ /dev/null @@ -1,65 +0,0 @@ -// by commy2 -#include "script_component.hpp" - -if (!hasInterface) exitWith {}; - -GVAR(ppEffectBlur) = ppEffectCreate ["dynamicBlur", 1234]; -GVAR(ppEffectBlur) ppEffectForceInNVG true; -GVAR(ppEffectBlur) ppEffectAdjust [0]; -GVAR(ppEffectBlur) ppEffectCommit 0; - -GVAR(ppEffectRadialBlur) = ppEffectCreate ["radialBlur", 1238]; -GVAR(ppEffectRadialBlur) ppEffectForceInNVG true; -GVAR(ppEffectRadialBlur) ppEffectAdjust [0, 0, 0, 0]; -GVAR(ppEffectRadialBlur) ppEffectCommit 0; - -GVAR(ppEffectFilmGrain) = ppEffectCreate ["FilmGrain", 1235]; -GVAR(ppEffectFilmGrain) ppEffectAdjust [0.25, 2.5, 2.5, 2.5*0.3, 2.5*0.3, false]; -GVAR(ppEffectFilmGrain) ppEffectCommit 0; - -GVAR(ppEffectNVGBrightness) = ppEffectCreate ["ColorCorrections", 1236]; -GVAR(ppEffectNVGBrightness) ppEffectForceInNVG true; -GVAR(ppEffectNVGBrightness) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; -GVAR(ppEffectNVGBrightness) ppEffectCommit 0; - -GVAR(ppEffectMuzzleFlash) = ppEffectCreate ["ColorCorrections", 1237]; -GVAR(ppEffectMuzzleFlash) ppEffectEnable true; -GVAR(ppEffectMuzzleFlash) ppEffectForceInNVG true; -GVAR(ppEffectMuzzleFlash) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; -GVAR(ppEffectMuzzleFlash) ppEffectCommit 0; - -// Setup the event handlers -["loadout", FUNC(updatePPEffects)] call CBA_fnc_addPlayerEventHandler; -["visionMode", FUNC(updatePPEffects)] call CBA_fnc_addPlayerEventHandler; -["visionMode", FUNC(onVisionModeChanged)] call CBA_fnc_addPlayerEventHandler; -["cameraView", FUNC(updatePPEffects)] call CBA_fnc_addPlayerEventHandler; -["cameraView", FUNC(onCameraViewChanged)] call CBA_fnc_addPlayerEventHandler; -["vehicle", FUNC(updatePPEffects)] call CBA_fnc_addPlayerEventHandler; -["turret", FUNC(updatePPEffects)] call CBA_fnc_addPlayerEventHandler; - -// Add keybinds -["ACE3 Equipment", QGVAR(IncreaseNVGBrightness), localize LSTRING(IncreaseNVGBrightness), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if ((currentVisionMode ACE_player != 1)) exitWith {false}; - - // Statement - [ACE_player, 1] call FUNC(changeNVGBrightness); - true -}, {false}, [201, [false, false, true]], false] call CBA_fnc_addKeybind; //PageUp + ALT - -["ACE3 Equipment", QGVAR(DecreaseNVGBrightness), localize LSTRING(DecreaseNVGBrightness), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if ((currentVisionMode ACE_player != 1)) exitWith {false}; - - // Statement - [ACE_player, -1] call FUNC(changeNVGBrightness); - true -}, {false}, [209, [false, false, true]], false] call CBA_fnc_addKeybind; //PageDown + ALT - -// Register fire event handler -["ace_firedPlayer", DFUNC(blending)] call CBA_fnc_addEventHandler; -["ace_firedPlayerVehicle", DFUNC(blending)] call CBA_fnc_addEventHandler; diff --git a/addons/nightvision/config.cpp b/addons/nightvision/config.cpp index 673a7d31c0..8e33002c31 100644 --- a/addons/nightvision/config.cpp +++ b/addons/nightvision/config.cpp @@ -18,3 +18,4 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "ACE_Settings.hpp" +#include "RscTitles.hpp" diff --git a/addons/nightvision/data/nvg_mask_2048.paa b/addons/nightvision/data/nvg_mask_2048.paa new file mode 100644 index 0000000000..93913fc08c Binary files /dev/null and b/addons/nightvision/data/nvg_mask_2048.paa differ diff --git a/addons/nightvision/data/nvg_mask_4096.paa b/addons/nightvision/data/nvg_mask_4096.paa new file mode 100644 index 0000000000..24d83ef648 Binary files /dev/null and b/addons/nightvision/data/nvg_mask_4096.paa differ diff --git a/addons/nightvision/data/nvg_mask_binos_2048.paa b/addons/nightvision/data/nvg_mask_binos_2048.paa new file mode 100644 index 0000000000..b3f6e2525f Binary files /dev/null and b/addons/nightvision/data/nvg_mask_binos_2048.paa differ diff --git a/addons/nightvision/data/nvg_mask_binos_4096.paa b/addons/nightvision/data/nvg_mask_binos_4096.paa new file mode 100644 index 0000000000..4a208090f4 Binary files /dev/null and b/addons/nightvision/data/nvg_mask_binos_4096.paa differ diff --git a/addons/nightvision/data/nvg_mask_hexes.paa b/addons/nightvision/data/nvg_mask_hexes.paa new file mode 100644 index 0000000000..f81514b074 Binary files /dev/null and b/addons/nightvision/data/nvg_mask_hexes.paa differ diff --git a/addons/nightvision/data/nvg_mask_hexes_thin.paa b/addons/nightvision/data/nvg_mask_hexes_thin.paa new file mode 100644 index 0000000000..57fed1ccb0 Binary files /dev/null and b/addons/nightvision/data/nvg_mask_hexes_thin.paa differ diff --git a/addons/nightvision/data/nvg_mask_quad_2048.paa b/addons/nightvision/data/nvg_mask_quad_2048.paa new file mode 100644 index 0000000000..43df98c333 Binary files /dev/null and b/addons/nightvision/data/nvg_mask_quad_2048.paa differ diff --git a/addons/nightvision/data/nvg_mask_quad_4096.paa b/addons/nightvision/data/nvg_mask_quad_4096.paa new file mode 100644 index 0000000000..3449bc8e7a Binary files /dev/null and b/addons/nightvision/data/nvg_mask_quad_4096.paa differ diff --git a/addons/nightvision/functions/fnc_blending.sqf b/addons/nightvision/functions/fnc_blending.sqf deleted file mode 100644 index 4a858838d3..0000000000 --- a/addons/nightvision/functions/fnc_blending.sqf +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Author: commy2 - * Change the blending when the player fires??. Called from the unified fired EH only for the local player and his vehicle. - * - * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) - * - * Return Value: - * Noneg - * - * Example: - * [clientFiredBIS-XEH] call ace_nightvision_fnc_blending - * - * Public: No - */ -#include "script_component.hpp" - -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); - -private _player = ACE_player; - -//If we're not in NVG mode, or it's a grenade, exit -if (currentVisionMode _player != 1 || {toLower _weapon in ["throw", "put"]}) exitWith {}; - -private _silencer = _player weaponAccessories _weapon select 0; - -private _visibleFireCoef = 1; -private _visibleFireTimeCoef = 1; - -if (_silencer != "") then { - _visibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "visibleFire"); - _visibleFireTimeCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "visibleFireTime"); -}; - -private _visibleFire = getNumber (configFile >> "CfgAmmo" >> _ammo >> "visibleFire"); -private _visibleFireTime = getNumber (configFile >> "CfgAmmo" >> _ammo >> "visibleFireTime"); - -private _fnc_isTracer = { - if (getNumber (configFile >> "CfgAmmo" >> _ammo >> "nvgOnly") > 0) exitWith {false}; - - private _indexShot = (_player ammo _weapon) + 1; - - private _lastRoundsTracer = getNumber (configFile >> "CfgMagazines" >> _magazine >> "lastRoundsTracer"); - if (_indexShot <= _lastRoundsTracer) exitWith {true}; - - private _tracersEvery = getNumber (configFile >> "CfgMagazines" >> _magazine >> "tracersEvery"); - if (_tracersEvery == 0) exitWith {false}; - - (_indexShot - _lastRoundsTracer) % _tracersEvery == 0 -}; - -if (call _fnc_isTracer) then { - _visibleFire = _visibleFire + 2; - _visibleFireTime = _visibleFireTime + 2; -}; - -private _darkness = 1 - (call EFUNC(common,ambientBrightness)); -private _nvgBrightnessCoef = 1 + (_player getVariable [QGVAR(NVGBrightness), 0]) / 4; - -_visibleFire = _darkness * _visibleFireCoef * _visibleFire * _nvgBrightnessCoef / 10 min 1; -_visibleFireTime = _darkness * _visibleFireTimeCoef * _visibleFireTime * _nvgBrightnessCoef / 10 min 0.5; - -TRACE_2("Player Shot, Adjusting NVG Effect", _visibleFire, _visibleFireTime); - -GVAR(ppEffectMuzzleFlash) ppEffectAdjust [1, 1, _visibleFire, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; -GVAR(ppEffectMuzzleFlash) ppEffectCommit 0; - -GVAR(ppEffectMuzzleFlash) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; -GVAR(ppEffectMuzzleFlash) ppEffectCommit _visibleFireTime; diff --git a/addons/nightvision/functions/fnc_changeNVGBrightness.sqf b/addons/nightvision/functions/fnc_changeNVGBrightness.sqf index 5bb5d52721..b6ea640564 100644 --- a/addons/nightvision/functions/fnc_changeNVGBrightness.sqf +++ b/addons/nightvision/functions/fnc_changeNVGBrightness.sqf @@ -1,6 +1,6 @@ /* * Author: commy2 - * Change the brightness of the unit's NVG + * Change the brightness of the unit's NVG. * * Arguments: * 0: The Unit @@ -17,18 +17,24 @@ #include "script_component.hpp" params ["_player", "_changeInBrightness"]; -TRACE_2("params",_player,_changeInBrightness); +TRACE_2("changeNVGBrightness",_player,_changeInBrightness); -if (!hasInterface) exitWith {}; +private _areEffectsDisabled = GVAR(effectScaling) == 0; +private _brightness = _player getVariable [QGVAR(NVGBrightness), [0, -3] select _areEffectsDisabled]; -private _brightness = _player getVariable [QGVAR(NVGBrightness), 0]; - -_brightness = ((round (10 * _brightness + _changeInBrightness) / 10) min 0.5) max -0.5; +_brightness = ((_brightness + _changeInBrightness) min 0) max -6; _player setVariable [QGVAR(NVGBrightness), _brightness, false]; -GVAR(ppEffectNVGBrightness) ppEffectAdjust [1, (_brightness + 1), 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; -GVAR(ppEffectNVGBrightness) ppEffectCommit 0; - -[format [(localize LSTRING(NVGBrightness)), (_brightness * 10)]] call EFUNC(common,displayTextStructured); +[format [(localize LSTRING(NVGBrightness)), _brightness]] call EFUNC(common,displayTextStructured); playSound "ACE_Sound_Click"; + +// handle only brightness if effects are disabled +if (_areEffectsDisabled) exitWith { + // here we take (-6; 0) _brightness range and alter it to (0.4; 1.6) + GVAR(ppEffectNVGBrightness) ppEffectAdjust [1, (_brightness+3)/5 + 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 1]]; + GVAR(ppEffectNVGBrightness) ppEffectCommit 0; +}; + +// Trigger full ppEffects update next time run in the PFEH: +GVAR(nextEffectsUpdate) = -1; diff --git a/addons/nightvision/functions/fnc_initModule.sqf b/addons/nightvision/functions/fnc_initModule.sqf index 6831a29edf..50f8785e91 100644 --- a/addons/nightvision/functions/fnc_initModule.sqf +++ b/addons/nightvision/functions/fnc_initModule.sqf @@ -17,5 +17,6 @@ #include "script_component.hpp" params ["_module"]; +TRACE_1("initModule",_module); [_module, QGVAR(disableNVGsWithSights), "disableNVGsWithSights"] call EFUNC(common,readSettingFromModule); diff --git a/addons/nightvision/functions/fnc_nonDedicatedFix.sqf b/addons/nightvision/functions/fnc_nonDedicatedFix.sqf new file mode 100644 index 0000000000..2a5178a595 --- /dev/null +++ b/addons/nightvision/functions/fnc_nonDedicatedFix.sqf @@ -0,0 +1,30 @@ +/* + * Author: PabstMirror + * Handles the client who is the non-dedicated server turning on the fog effects. + * + * Arguments: + * 0: Module + * + * Return Value: + * None + * + * Example: + * [] call ace_nightvision_fnc_nonDedicatedFix + * + * Public: No + */ +#include "script_component.hpp" + +TRACE_1("Starting PFEH to handling non-dedicated server running effect",GVAR(serverPriorFog)); + +if (isServer) exitWith {}; + +[{ + if (isNil QGVAR(serverPriorFog)) exitWith { + TRACE_1("Ending PFEH to handling non-dedicated server running effect",_this); + [_this select 1] call CBA_fnc_removePerFrameHandler; + }; + if (!GVAR(running)) then { // If we aren't running the effect ourselves, then use the server's old fog value + 0 setFog GVAR(serverPriorFog); + }; +}, 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf index 5384d6924c..08ec3afcec 100644 --- a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf +++ b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf @@ -14,10 +14,13 @@ * * Public: No */ - #include "script_component.hpp" params ["_unit", "_cameraView"]; +TRACE_2("onCameraViewChanged",_unit,_cameraView); + +// Refresh goggle effect (e.g. switching to vehicle's NVG) +[] call FUNC(refreshGoggleType); if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { if ((vehicle _unit == _unit) diff --git a/addons/nightvision/functions/fnc_onFiredPlayer.sqf b/addons/nightvision/functions/fnc_onFiredPlayer.sqf new file mode 100644 index 0000000000..3621c975f8 --- /dev/null +++ b/addons/nightvision/functions/fnc_onFiredPlayer.sqf @@ -0,0 +1,61 @@ +/* + * Author: commy2, Dslyecxi, PabstMirror + * Change the blending when the player fires. Called from the unified fired EH only for the local player and his vehicle. + * + * Arguments: + * None. Parameters inherited from EFUNC(common,firedEH) + * + * Return Value: + * None + * + * Example: + * [clientFiredBIS-XEH] call ace_nightvision_fnc_onFiredPlayer + * + * Public: No + */ +#include "script_component.hpp" + +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; +TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); + +if ((!GVAR(running)) || {_weapon == "throw"} || {_weapon == "put"}) exitWith {}; + +private _visibleFireCoef = 1; +if (_unit == ace_player) then { + private _silencer = (_unit weaponAccessories _weapon) select 0; + if (_silencer != "") then { + _visibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "visibleFire"); + TRACE_1("muzzle attachement",_visibleFireCoef); + }; +}; + +private _visibleFire = getNumber (configFile >> "CfgAmmo" >> _ammo >> "visibleFire"); + +private _isTracer = call { + if (getNumber (configFile >> "CfgAmmo" >> _ammo >> "nvgOnly") > 0) exitWith {false}; + private _indexShot = (_unit ammo _weapon) + 1; + private _lastRoundsTracer = getNumber (configFile >> "CfgMagazines" >> _magazine >> "lastRoundsTracer"); + if (_indexShot <= _lastRoundsTracer) exitWith {true}; + private _tracersEvery = getNumber (configFile >> "CfgMagazines" >> _magazine >> "tracersEvery"); + if (_tracersEvery == 0) exitWith {false}; + (_indexShot - _lastRoundsTracer) % _tracersEvery == 0 +}; + +TRACE_3("",_ammo,_visibleFire,_isTracer); +if ( _isTracer) then { + _visibleFire = _visibleFire + 2; +}; + +_visibleFire = _visibleFireCoef * _visibleFire; +if (_ammo isKindOf "BulletBase") then { + _visibleFire = _visibleFire min 5; // Prevent every shot from triggering with HMG +}; +TRACE_1("final", _visibleFire); + +if (_visibleFire <= 1.5) exitWith {}; +if ((random (linearConversion [1, 4, GVAR(nvgGeneration), 10, 20])) > _visibleFire) exitWith {}; + +QGVAR(cutoff) cutText ["", "BLACK", .1]; +[{ + QGVAR(cutoff) cutText ["", "PLAIN", 0]; +}, [], 0.07] call CBA_fnc_waitAndExecute; diff --git a/addons/nightvision/functions/fnc_onLoadoutChanged.sqf b/addons/nightvision/functions/fnc_onLoadoutChanged.sqf new file mode 100644 index 0000000000..32f1914bfa --- /dev/null +++ b/addons/nightvision/functions/fnc_onLoadoutChanged.sqf @@ -0,0 +1,25 @@ +/* + * Author: Dslyecxi, PabstMirror + * Refreshes nvg effect if switching NVG goggles. + * + * Arguments: + * 0: Player + * + * Return Value: + * None + * + * Example: + * [player] call ace_nightvision_fnc_onLoadoutChange + * + * Public: No + */ +#include "script_component.hpp" + +params ["_player"]; +TRACE_1("onLoadoutChange",_player); + +private _newHMD = hmd _player; +if (_newHMD != GVAR(playerHMD)) then { + GVAR(playerHMD) = _newHMD; + [] call FUNC(refreshGoggleType); +}; diff --git a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf index 64f77a69bc..f28e39b964 100644 --- a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf +++ b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf @@ -1,5 +1,5 @@ /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, Dslyecxi, PabstMirror * Disables turning on NVGs while the player aims down his sight. * * Arguments: @@ -14,17 +14,36 @@ * * Public: No */ - #include "script_component.hpp" params ["_unit", "_visionMode"]; +TRACE_2("onVisionModeChanged",_unit,_visionMode); +// handle only brightness if effects are disabled +if (GVAR(effectScaling) == 0) exitWith { + GVAR(ppEffectNVGBrightness) ppEffectEnable (_visionMode == 1); +}; + +// Start PFEH when entering night vision mode: +if (_visionMode == 1) then { + if (GVAR(PFID) == -1) then { + GVAR(running) = true; + [true] call FUNC(setupDisplayEffects); + [] call FUNC(refreshGoggleType); + GVAR(PFID) = [LINKFUNC(pfeh), 0, []] call CBA_fnc_addPerFrameHandler; + + // Fade in from black when turning nvg on + QGVAR(turnOnEffect) cutText ["", "BLACK IN", 2.5]; + }; +}; + +// Handle disableNVGsWithSights setting: if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { if ((vehicle _unit == _unit) - || {isTurnedOut _unit} - || {!([_unit] call EFUNC(common,hasHatch)) - && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} - }) then { + || {isTurnedOut _unit} + || {!([_unit] call EFUNC(common,hasHatch)) + && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} + }) then { if ((cameraView == "GUNNER") && {_visionMode > 0}) then { _unit action ["NVGogglesOff", _unit]; }; diff --git a/addons/nightvision/functions/fnc_pfeh.sqf b/addons/nightvision/functions/fnc_pfeh.sqf new file mode 100644 index 0000000000..5da34d2aac --- /dev/null +++ b/addons/nightvision/functions/fnc_pfeh.sqf @@ -0,0 +1,159 @@ +/* + * Author: Dslyecxi, PabstMirror + * PFEH to handle refreshing effects. + * Updates UI scale on every frame, effects are updated less often. + * + * Arguments: + * 1: PFEH ID + * + * Return Value: + * None + * + * Example: + * [[], 1] call ace_nightvision_fnc_pfeh + * + * Public: No + */ +#include "script_component.hpp" + +if ((currentVisionMode ACE_player) != 1) exitWith { + GVAR(running) = false; + [false] call FUNC(setupDisplayEffects); + [GVAR(PFID)] call CBA_fnc_removePerFrameHandler; + GVAR(PFID) = -1; +}; +if (EGVAR(common,OldIsCamera)) exitWith { + if (GVAR(running)) then { + TRACE_2("pausing NVG for scripted camera",alive ACE_player,EGVAR(common,OldIsCamera)); + GVAR(running) = false; + [false] call FUNC(setupDisplayEffects); + }; +}; +if (!GVAR(running)) then { + TRACE_1("Un-Pausing", GVAR(paused)); + GVAR(running) = true; + [true] call FUNC(setupDisplayEffects); + [] call FUNC(refreshGoggleType); +}; + +// Scale Border / Hex +BEGIN_COUNTER(borderScaling); +private _scale = (call EFUNC(common,getZoom)) * 1.12513; +if (!(GVAR(defaultPositionBorder) isEqualTo [])) then { + // Prevents issues when "zooming out" on ultra wide monitors - The square mask would be narrower than the screen + if (((GVAR(defaultPositionBorder) select 2) * _scale) < safeZoneW) then { + _scale = safeZoneW / (GVAR(defaultPositionBorder) select 2); + }; + [(uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1000, GVAR(defaultPositionHex), _scale] call FUNC(scaleCtrl); + [(uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1001, GVAR(defaultPositionBorder), _scale] call FUNC(scaleCtrl); + // Fade out hexes with high zoom (optics are doing the magnifying, not the player "focusing in") + ((uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1000) ctrlSetFade (linearConversion [4, 6, _scale, 0.2, 1, true]); +}; +END_COUNTER(borderScaling); + +if (CBA_missionTime < GVAR(nextEffectsUpdate)) then { + // Update radial blur as it depends on zoom level, so should be changed each frame like the border/hex + if (GVAR(ppeffectRadialBlur) != -1) then { + GVAR(ppeffectRadialBlur) ppEffectAdjust [.005, .005, _scale * GVAR(nvgBlurRadius), _scale * .16]; + GVAR(ppeffectRadialBlur) ppEffectCommit 0; + }; + // Need to rapidly update fog or it will try to resync from the server + if (GVAR(fogScaling) > 0) then { + 0 setFog GVAR(nvgFog); + }; +} else { + // Redo full effects less often + BEGIN_COUNTER(updateAllEffects); + GVAR(nextEffectsUpdate) = CBA_missionTime + 5; + + // Detecting the efficiency of the nightvision. + private _lightFinal = 0 max (moonIntensity - ((overcast * .8) min .275) - (rain * .5)); + private _effectiveLight = _lightFinal * linearConversion [1, 3, GVAR(nvgGeneration), 0.25, 1]; + private _effectMod = linearConversion [1, 3, GVAR(nvgGeneration), 1.5, 1]; + // This has become a little weird. Basically means that lightfinal is unlikely to reach zero with any moon in the sky + // buuut it just so happens that setting it like this means that the lighting progression from clear -> cloudy -> rainy works particularly well. + + private _grainFinal = linearConversion [1, 0, _effectiveLight, ST_NVG_GRAIN_MIN, ST_NVG_GRAIN_MAX, true]; + private _blurFinal = _effectMod *_effectMod * linearConversion [1, 0, _effectiveLight, ST_NVG_BLUR_MIN, ST_NVG_BLUR_MAX, true]; + private _brightFinal = linearConversion [0, 1, _effectiveLight, ST_NVG_BRIGHT_MIN, ST_NVG_BRIGHT_MAX, true]; + private _contrastFinal = linearConversion [0, 1, _effectiveLight, ST_NVG_CONTRAST_MIN, ST_NVG_CONTRAST_MAX, true]; + private _grainIntensityFinal = _effectMod * linearConversion [1, 0, _effectiveLight, ST_NVG_NOISEINTENSITY_MIN, ST_NVG_NOISEINTENSITY_MAX, true]; + private _noiseSharpnessFinal = linearConversion [1, 0, _effectiveLight, ST_NVG_NOISESHARPNESS_MIN, ST_NVG_NOISESHARPNESS_MAX, true]; + + private _playerBrightSetting = ACE_player getVariable [QGVAR(NVGBrightness), 0]; + _brightFinal = _brightFinal + (_playerBrightSetting / 20); + + private _fogApply = linearConversion [0, 1, _effectiveLight, ST_NVG_MAXFOG, ST_NVG_MINFOG, true]; + + // Modify blur if looking down scope + if ((cameraView == "GUNNER") && {[ACE_player] call CBA_fnc_canUseWeapon}) then { + if (currentWeapon ACE_player == "") exitWith {}; + if (currentWeapon ACE_player == primaryWeapon ACE_player) exitWith {_blurFinal = _blurFinal * linearConversion [0, 1, GVAR(aimDownSightsBlur), 1, ST_NVG_CAMERA_BLUR_SIGHTS_RIFLE]}; // Rifles are bad + if (currentWeapon ACE_player == handgunWeapon ACE_player) exitWith {_blurFinal = _blurFinal * linearConversion [0, 1, GVAR(aimDownSightsBlur), 1, ST_NVG_CAMERA_BLUR_SIGHTS_PISTOL]}; // Pistols aren't so bad + }; + + // Scale effects based on ace_nightvision_effectScaling setting + _grainIntensityFinal = _grainIntensityFinal * GVAR(effectScaling); + _noiseSharpnessFinal = linearConversion [0, 1, GVAR(effectScaling), 2.5, _noiseSharpnessFinal]; + private _radialBlurPower = 0.0025 * GVAR(effectScaling); + _brightFinal = linearConversion [0, 1, GVAR(effectScaling), 1, _brightFinal]; + _contrastFinal = linearConversion [0, 1, GVAR(effectScaling), 1, _contrastFinal]; + + + // Setup all effects + // This is hacky but... works. This prevents the effects from being cancelled by various things - alt-tabbing, resizing, going into AT sights, etc. A nicer method would be welcome but I don't have time to spend on it. TODO. + + // FilmGrain - Electronic Noise + // Params: [intensity(0..1), sharpness(0..20), grainsize(1..8), intensityX0, intensityX1, monochromatic(bool)] + GVAR(ppeffectGrain) = ppEffectCreate ["FilmGrain", 200]; + GVAR(ppeffectGrain) ppEffectAdjust [_grainIntensityFinal, _noiseSharpnessFinal, _grainFinal, 0.3, 0.3]; + // OldNVG: [0.25, 2.5, 2.5, _grainSetting, _grainSetting, false] + GVAR(ppeffectGrain) ppEffectCommit 0; + GVAR(ppeffectGrain) ppEffectForceInNVG true; + GVAR(ppeffectGrain) ppEffectEnable true; + + // RadialBlur - Blurs closer to the edge nvg border (radius based on GVAR(bluRadius) config; e.g. larger for quadtube) + // Note: "Will not do anything if RADIAL BLUR is disabled in Video Options." - So should try to keep this effect to a minimum to prevent balance issues + // Params: [powerX, powerY, offsetX, offsetY] + if (GVAR(nvgBlurRadius) != -1) then { + GVAR(ppeffectRadialBlur) = ppEffectCreate ["RadialBlur", 451]; + GVAR(ppeffectRadialBlur) ppEffectAdjust [_radialBlurPower, _radialBlurPower, _scale * GVAR(nvgBlurRadius), _scale * .16]; + GVAR(ppeffectRadialBlur) ppEffectCommit 0; + GVAR(ppeffectRadialBlur) ppEffectForceInNVG true; + GVAR(ppeffectRadialBlur) ppEffectEnable true; + }; + + // ColorCorrections - Changes brightness, contrast and "green" color of nvg + // Params: [brightness(0..2), contrast(0..inf), offset(-x..+x), blendArray, colorizeArray, weightArray] + GVAR(ppeffectColorCorrect) = ppEffectCreate ["ColorCorrections", 2003]; + GVAR(ppeffectColorCorrect) ppEffectAdjust [_brightFinal, _contrastFinal, 0, [0.0, 0.0, 0.0, 0.0], [1.3, 1.2, 0.0, 0.9], [6, 1, 1, 0.0]]; + GVAR(ppeffectColorCorrect) ppEffectCommit 0; + GVAR(ppeffectColorCorrect) ppEffectForceInNVG true; + GVAR(ppeffectColorCorrect) ppEffectEnable true; + + // DynamicBlur - Increases overall screen blur when aiming down sights (which would be hard/impossible with NVG) + // Params: [value(0..inf)] + GVAR(ppeffectBlur) = ppEffectCreate ["DynamicBlur", 190]; + GVAR(ppeffectBlur) ppEffectAdjust [_blurFinal]; + GVAR(ppeffectBlur) ppEffectCommit 0; + GVAR(ppeffectBlur) ppEffectForceInNVG true; + GVAR(ppeffectBlur) ppEffectEnable true; + + + // Modify local fog: + if (GVAR(fogScaling) > 0) then { + if (((vehicle ACE_player) != ACE_player) && {(vehicle ACE_player) isKindOf "Air"}) then { // For flying in particular, can refine nicer later. + _fogApply = _fogApply * ST_NVG_AIR_FOG_MULTIPLIER; + }; + _fogApply = linearConversion [0, 1, GVAR(priorFog) select 0, (GVAR(fogScaling) * _fogApply), 1]; // mix in old fog if present + GVAR(nvgFog) = [_fogApply, 0, 0]; + 0 setFog GVAR(nvgFog) + }; + + #ifdef DEBUG_MODE_FULL + private _aceAmbient = [] call EFUNC(common,ambientBrightness); + hintSilent format ["EffectiveLight %1\nLight: %2\nACE Ambient: %3\nBrightness: %4\nContrast: %5\nGrain: %6\nBlur: %7\nFog: %8\nScaling %9", _effectiveLight, _lightFinal, _aceAmbient, _brightFinal, _contrastFinal, [_grainIntensityFinal, _noiseSharpnessFinal, _grainFinal], _blurFinal, _fogApply, [GVAR(effectScaling),GVAR(fogScaling)]]; + #endif + + END_COUNTER(updateAllEffects); +}; diff --git a/addons/nightvision/functions/fnc_refreshGoggleType.sqf b/addons/nightvision/functions/fnc_refreshGoggleType.sqf new file mode 100644 index 0000000000..1ebadf56ae --- /dev/null +++ b/addons/nightvision/functions/fnc_refreshGoggleType.sqf @@ -0,0 +1,129 @@ +/* + * Author: Dslyecxi, PabstMirror + * Determines night vision source (player/vehicle) - Updates UI based on type. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_nightvision_fnc_refreshGoggleType + * + * Public: No + */ +#include "script_component.hpp" + +TRACE_1("refreshGoggleType",_this); + +if (!GVAR(running)) exitWith {}; + +// Defaults (good for most vehicles/binoculars) +private _borderImage = ""; +private _eyeCups = false; +private _hideHex = true; +private _nvgGen = 3; +private _blurRadius = -1; + +if (alive ACE_player) then { + if (((vehicle ACE_player) == ACE_player) || { + // Test if we are using player's nvg or if sourced from vehicle: + + private _currentVehicle = vehicle ACE_player; + private _vehConfig = configFile >> "CfgVehicles" >> (typeOf _currentVehicle); + + if (cameraView != "GUNNER") exitWith {true}; // asume hmd usage outside of gunner view + + if (ACE_player == (driver _currentVehicle)) exitWith { + !("NVG" in getArray (_vehConfig >> "ViewOptics" >> "visionMode")); + }; + private _result = true; + private _turret = ACE_player call CBA_fnc_turretPath; + private _turretConfig = [_currentVehicle, _turret] call CBA_fnc_getTurret; + + // Seems to cover things like the offroad technical + if ((isNumber (_turretConfig >> "optics")) && {(getNumber (_turretConfig >> "optics")) == 0}) exitWith {true}; + + private _turretConfigOpticsIn = _turretConfig >> "OpticsIn"; + if (isClass _turretConfigOpticsIn) then { + for "_index" from 0 to (count _turretConfigOpticsIn - 1) do { + if ("NVG" in getArray (_turretConfigOpticsIn select _index >> "visionMode")) exitWith {_result = false}; + }; + } else { + // No OpticsIn usualy means RCWS, still need to test on more vehicles + _result = false; + }; + _result + }) then { + if ((cameraView == "GUNNER") && {currentWeapon ACE_player != ""} && {binocular ACE_player == currentWeapon ACE_player}) exitWith { + TRACE_1("souce: binocular",binocular ACE_player); // Source is from player's binocular (Rangefinder/Vector21bNite) + private _config = configFile >> "CfgWeapons" >> (binocular ACE_player); + if (isNumber (_config >> QGVAR(generation))) then {_nvgGen = getNumber (_config >> QGVAR(generation));}; + }; + + TRACE_1("source: hmd",GVAR(playerHMD)); // Source is player's HMD (or possibly a NVG scope, but no good way to detect that) + private _config = configFile >> "CfgWeapons" >> GVAR(playerHMD); + if (!isClass _config) exitWith {}; + + // Only use border if there is no modelOptics + if ((getText (_config >> "modelOptics")) == "") then { + _borderImage = getText (_config >> QGVAR(border)); + _eyeCups = ((getNumber (_config >> QGVAR(eyeCups))) == 1); + _hideHex = (getNumber (_config >> QGVAR(hideHex))) == 1; + if (isNumber (_config >> QGVAR(bluRadius))) then {_blurRadius = getNumber (_config >> QGVAR(bluRadius));}; + }; + if (isNumber (_config >> QGVAR(generation))) then {_nvgGen = getNumber (_config >> QGVAR(generation));}; + + } else { + TRACE_1("source: vehicle - defaults",typeOf vehicle ACE_player); + }; +}; + +#ifdef DEBUG_MODE_FULL +systemChat format ["NVG Refresh - Border: %1", _borderImage]; +systemChat format ["EyeCups: %1, HideHex %2, NVGen: %3, BluRadius: %4", _eyeCups, _hideHex, _nvgGen, _blurRadius]; +#endif + +GVAR(nvgBlurRadius) = _blurRadius; +GVAR(nvgGeneration) = _nvgGen; + +// Setup border and hex image based on NVG config: +private _scale = (call EFUNC(common,getZoom)) * 1.12513; + +private _borderImageCtrl = (uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1001; +private _trippleHeadLeft = (uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1002; +private _trippleHeadRight = (uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1003; +if (_borderImage == "") then { + _borderImageCtrl ctrlShow false; + _trippleHeadLeft ctrlShow false; + _trippleHeadRight ctrlShow false; + GVAR(defaultPositionBorder) = []; +} else { + _borderImageCtrl ctrlShow true; + _trippleHeadLeft ctrlShow true; + _trippleHeadRight ctrlShow true; + + _borderImageCtrl ctrlSetText _borderImage; + _borderImageCtrl ctrlSetFade ([.15, 0] select _eyeCups); + + #define BORDER_SIZE 3 + GVAR(defaultPositionBorder) = [safezoneX - (((BORDER_SIZE * 0.75) * safezoneH) - safezoneW) / 2, safezoneY - ((BORDER_SIZE - 1) / 2) * safezoneH, (BORDER_SIZE * 0.75) * safezoneH, BORDER_SIZE * safezoneH]; + [_borderImageCtrl, GVAR(defaultPositionBorder), _scale] call FUNC(scaleCtrl); +}; + +private _hexCtrl = (uiNamespace getVariable QGVAR(titleDisplay)) displayCtrl 1000; +if (_hideHex) then { + _hexCtrl ctrlShow false; +} else { + _hexCtrl ctrlShow true; + // _hexCtrl ctrlSetText QPATHTOF(data\nvg_mask_hexes.paa); + _hexCtrl ctrlSetText QPATHTOF(data\nvg_mask_hexes_thin.paa); + + #define HEX_SIZE 1.5 + GVAR(defaultPositionHex) = [safezoneX - (((HEX_SIZE * 0.75) * safezoneH) - safezoneW) / 2, safezoneY - ((HEX_SIZE - 1) / 2) * safezoneH, (HEX_SIZE * 0.75) * safezoneH, HEX_SIZE * safezoneH]; + [_hexCtrl, GVAR(defaultPositionHex), _scale] call FUNC(scaleCtrl); +}; + +// Trigger full ppEffects update next time run in the PFEH: +GVAR(nextEffectsUpdate) = -1; diff --git a/addons/nightvision/functions/fnc_scaleCtrl.sqf b/addons/nightvision/functions/fnc_scaleCtrl.sqf new file mode 100644 index 0000000000..b5bb80715d --- /dev/null +++ b/addons/nightvision/functions/fnc_scaleCtrl.sqf @@ -0,0 +1,31 @@ +/* + * Author: Dslyecxi, PabstMirror + * Determines night vision source (player/vehicle) - Updates UI based on type. + * + * Arguments: + * 0: Control + * 1: Default position [x,y,w,h] + * 2: Zoom Level + * + * Return Value: + * None + * + * Example: + * [] call ace_nightvision_fnc_scaleCtrl + * + * Public: No + */ +#include "script_component.hpp" + +params ["_ctrl", "_default_pos", "_scale"]; + +if (!ctrlShown _ctrl) exitWith {}; + +_ctrl ctrlSetPosition +[(((_default_pos select 0) - 0.5) * _scale) + 0.5, +(((_default_pos select 1) - 0.5) * _scale) + 0.5, +(_default_pos select 2) * _scale, +(_default_pos select 3) * _scale]; + + +_ctrl ctrlCommit 0; diff --git a/addons/nightvision/functions/fnc_setupDisplayEffects.sqf b/addons/nightvision/functions/fnc_setupDisplayEffects.sqf new file mode 100644 index 0000000000..8201b9a0f5 --- /dev/null +++ b/addons/nightvision/functions/fnc_setupDisplayEffects.sqf @@ -0,0 +1,73 @@ +/* + * Author: Dslyecxi, PabstMirror + * Handles setting up the effects: fog, ppEffects and the RscTittle. + * + * Arguments: + * 0: Activated + * + * Return Value: + * None + * + * Example: + * [true] call ace_nightvision_fnc_setupDisplayEffects + * + * Public: No + */ +#include "script_component.hpp" + +params ["_activated"]; +TRACE_1("setupDisplayEffects",_activated); + +// Backup and restore changes to fog: +if (GVAR(fogScaling) > 0) then { + if (_activated) then { + if (isNil QGVAR(priorFog)) then { + TRACE_1("Backing up fog",fogParams); + GVAR(priorFog) = fogParams; + } else { + ERROR("fog already backed up"); + }; + + // Handle non-dedicated: + if (isServer && hasInterface) then { + missionNamespace setVariable [QGVAR(serverPriorFog), fogParams, true]; + [QGVAR(nonDedicatedFix), []] call CBA_fnc_remoteEvent; + }; + } else { + if (!isNil QGVAR(priorFog)) then { + 0 setFog GVAR(priorFog); + GVAR(priorFog) = nil; + } else { + ERROR("no fog backed up"); + }; + + // Handle non-dedicated: + if (isServer && hasInterface) then { + missionNamespace setVariable [QGVAR(serverPriorFog), nil, true]; + }; + }; +}; + +// Note: Using BIS_fnc_rscLayer because of bug with string syntax - https://feedback.bistudio.com/T120768 +(QGVAR(display) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; // Cleanup Old Display +if (_activated) then { // Create New Display + (QGVAR(display) call BIS_fnc_rscLayer) cutRsc [QGVAR(title), "PLAIN", 0, false]; +}; + +// Cleanup Old PP Effects +if (GVAR(ppeffectGrain) != -1) then { + ppEffectDestroy GVAR(ppeffectGrain); + GVAR(ppeffectGrain) = -1; +}; +if (GVAR(ppeffectBlur) != -1) then { + ppEffectDestroy GVAR(ppeffectBlur); + GVAR(ppeffectBlur) = -1; +}; +if (GVAR(ppeffectRadialBlur) != -1) then { + ppEffectDestroy GVAR(ppeffectRadialBlur); + GVAR(ppeffectRadialBlur) = -1; +}; +if (GVAR(ppeffectColorCorrect) != -1) then { + ppEffectDestroy GVAR(ppeffectColorCorrect); + GVAR(ppeffectColorCorrect) = -1; +}; diff --git a/addons/nightvision/functions/fnc_updatePPEffects.sqf b/addons/nightvision/functions/fnc_updatePPEffects.sqf deleted file mode 100644 index 7f4f660bd7..0000000000 --- a/addons/nightvision/functions/fnc_updatePPEffects.sqf +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Author: commy2, PabstMirror and esteldunedain - * Update the ppEffects everytime something changes - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [someEvent] call ace_nightvision_fnc_updatePPEffects - * - * Public: No - */ -#include "script_component.hpp" - -if (!hasInterface) exitWith {}; - -disableSerialization; - -params [["_display", displayNull]]; - -if !(_display isEqualType displayNull) then { - _display = displayNull; -}; - -private ["_currentVehicle", "_grainSetting", "_blurSetting", "_radBlurSetting", "_config", "_hmd", "_cameraView", "_turret"]; - -_currentVehicle = vehicle ACE_player; - -// If the Zeus display is on or the player has no nightvision -if (ctrlIDD _display == 312 || currentVisionMode ACE_player != 1) exitWith { - GVAR(ppEffectFilmGrain) ppEffectEnable false; - GVAR(ppEffectBlur) ppEffectEnable false; - GVAR(ppEffectRadialBlur) ppEffectEnable false; - GVAR(ppEffectNVGBrightness) ppEffectEnable false; -}; - -// The unit has nightvision -_config = configFile >> "CfgVehicles" >> typeOf _currentVehicle; -_hmd = hmd ACE_player; -_cameraView = cameraView; -_turret = [ACE_player] call EFUNC(common,getTurretIndex); - - -_fnc_isUsingHMD = { - if (_cameraView != "GUNNER") exitWith {true}; // asume hmd usage outside of gunner view - - if (ACE_player == (driver _currentVehicle)) exitWith { - !("NVG" in getArray (_config >> "ViewOptics" >> "visionMode")); - }; - - private ["_result", "_turretConfig", "_turretConfigOpticsIn", "_index"]; - _result = true; - _turretConfig = [_config, _turret] call EFUNC(common,getTurretConfigPath); - _turretConfigOpticsIn = _turretConfig >> "OpticsIn"; - - if (isClass _turretConfigOpticsIn) then { - for "_index" from 0 to (count _turretConfigOpticsIn - 1) do { - if ("NVG" in getArray (_turretConfigOpticsIn select _index >> "visionMode")) exitWith {_result = false}; - }; - } else { - //No OpticsIn usualy means RCWS, still need to test on more vehicles - _result = false; - }; - _result -}; - -if ((_currentVehicle == ACE_player) || _fnc_isUsingHMD) then { - _grainSetting = getNumber (configFile >> "CfgWeapons" >> _hmd >> "ACE_NightVision_grain"); - _blurSetting = getNumber (configFile >> "CfgWeapons" >> _hmd >> "ACE_NightVision_blur"); - _radBlurSetting = getNumber (configFile >> "CfgWeapons" >> _hmd >> "ACE_NightVision_radBlur"); - TRACE_3("New NVG Settings From Player NVG",_grainSetting,_blurSetting,_radBlurSetting) -} else { - _grainSetting = _currentVehicle getVariable ["ACE_NightVision_grain", getNumber (_config >> "ACE_NightVision_grain")]; - _blurSetting = _currentVehicle getVariable ["ACE_NightVision_blur", getNumber (_config >> "ACE_NightVision_blur")]; - _radBlurSetting = _currentVehicle getVariable ["ACE_NightVision_radBlur", getNumber (_config >> "ACE_NightVision_radBlur")]; - TRACE_3("New NVG Settings From Vehicle",_grainSetting,_blurSetting,_radBlurSetting) -}; - - -// Enable the effects -GVAR(ppEffectFilmGrain) ppEffectEnable true; -GVAR(ppEffectBlur) ppEffectEnable true; -GVAR(ppEffectRadialBlur) ppEffectEnable true; -GVAR(ppEffectNVGBrightness) ppEffectEnable true; - -// Configure effects parameters -GVAR(ppEffectFilmGrain) ppEffectAdjust [0.25, 2.5, 2.5, _grainSetting, _grainSetting, false]; -GVAR(ppEffectFilmGrain) ppEffectCommit 0; -GVAR(ppEffectBlur) ppEffectAdjust [_blurSetting]; -GVAR(ppEffectBlur) ppEffectCommit 0; -GVAR(ppEffectRadialBlur) ppEffectAdjust [_radBlurSetting, _radBlurSetting, 0.2, 0.2]; -GVAR(ppEffectRadialBlur) ppEffectCommit 0; diff --git a/addons/nightvision/script_component.hpp b/addons/nightvision/script_component.hpp index 142983ebdc..0fd46d1fa3 100644 --- a/addons/nightvision/script_component.hpp +++ b/addons/nightvision/script_component.hpp @@ -15,3 +15,34 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + + +// Effect Settings / Magic values to tweak: + +// Decreases fog when in air vehicles +#define ST_NVG_AIR_FOG_MULTIPLIER 0.5 + +// Increase blur when looking down sights +#define ST_NVG_CAMERA_BLUR_SIGHTS_RIFLE 6 +#define ST_NVG_CAMERA_BLUR_SIGHTS_PISTOL 2 + +#define ST_NVG_MINFOG 0.2 +#define ST_NVG_MAXFOG 0.3 + +#define ST_NVG_GRAIN_MIN 2.25 +#define ST_NVG_GRAIN_MAX 2.7 + +#define ST_NVG_BLUR_MIN 0.05 +#define ST_NVG_BLUR_MAX 0.11 + +#define ST_NVG_BRIGHT_MIN 0.65 +#define ST_NVG_BRIGHT_MAX 0.75 + +#define ST_NVG_CONTRAST_MIN 0.4 +#define ST_NVG_CONTRAST_MAX 0.8 + +#define ST_NVG_NOISEINTENSITY_MIN 0.4 +#define ST_NVG_NOISEINTENSITY_MAX 0.55 + +#define ST_NVG_NOISESHARPNESS_MIN 1.2 +#define ST_NVG_NOISESHARPNESS_MAX 1 diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index 8e4e1fafde..9bb333a82d 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -1,6 +1,12 @@ - + + + ACE Nightvision + ACE 暗視装置 + Visione notturna ACE + ACE-Nachtsicht + NV Goggles (Gen1) Noktovizor (Gen1) @@ -12,7 +18,7 @@ ПНВ (Gen1) Gafas de visión nocturna (Gen1) Éjjellátó szemüveg (1. Gen.) - 夜間暗視装置つきゴーグル (第1世代) + 暗視装置 (第1世代) 야투경 (1세대) 夜视镜 (初代) 夜視鏡 (初代) @@ -28,7 +34,7 @@ ПНВ (Gen2) Gafas de visión nocturna (Gen2) Éjjellátó szemüveg (2. Gen.) - 夜間暗視装置つきゴーグル (第2世代) + 暗視装置 (第2世代) 야투경 (2세대) 夜视镜 (二代) 夜視鏡 (二代) @@ -44,7 +50,7 @@ ПНВ (Gen3) Gafas de visión nocturna (Gen3) Éjjellátó szemüveg (3. Gen.) - 夜間暗視装置つきゴーグル (第3世代) + 暗視装置 (第3世代) 야투경 (3세대) 夜视镜 (三代) 夜視鏡 (三代) @@ -54,13 +60,13 @@ Noktovizor (Gen3, hnědý) JVN (Gen3, marron) NS-Brille (3. Gen., braun) - Occhiali notturni (Gen3, marroni) + Occhiali notturni (Gen3, Marroni) Gogle noktowizyjne (Gen3, brązowe) Óculos de visão noturna (Gen3, marrons) ПНВ (Gen3, Коричневый) Gafas de visión nocturna (Gen3, marrón) Éjjellátó szemüveg (3. Gen., barna) - 夜間暗視装置つきゴーグル (第3世代、ブラウン) + 暗視装置 (第3世代、ブラウン) 야투경 (3세대, 갈색) 夜视镜 (三代, 棕色) 夜視鏡 (三代, 棕色) @@ -70,13 +76,13 @@ Noktovizor (Gen3, zelený) JVN (Gen3, vertes) NS-Brille (3. Gen., grün) - Occhiali notturni (Gen3, verdi) + Occhiali notturni (Gen3, Verdi) Gogle noktowizyjne (Gen3, zielone) Óculos de visão noturna (Gen3, verdes) ПНВ (Gen3, Зелёный) Gafas de visión nocturna (Gen3, verde) Éjjellátó szemüveg (3. Gen., zöld) - 夜間暗視装置つきゴーグル (第3世代、グリーン) + 暗視装置 (第3世代、グリーン) 야투경 (3세대, 녹색) 夜视镜 (三代, 绿色) 夜視鏡 (三代, 綠色) @@ -86,13 +92,13 @@ Noktovizor (Gen3, černý) JVN (Gen3, noires) NS-Brille (3. Gen., schwarz) - Occhiali notturni (Gen3, neri) + Occhiali notturni (Gen3, Neri) Gogle noktowizyjne (Gen3, czarne) Óculos de visão noturna (Gen3, pretos) ПНВ (Gen3, Чёрный) Gafas de visión nocturna (Gen3, negro) Éjjellátó szemüveg (3. Gen., fekete) - 夜間暗視装置つきゴーグル (第3世代、ブラック) + 暗視装置 (第3世代、ブラック) 야투경 (3세대, 검정색) 夜视镜 (三代, 黑色) 夜視鏡 (三代, 黑色) @@ -108,7 +114,7 @@ ПНВ (Gen4) Gafas de visión nocturna (Gen4) Éjjellátó szemüveg (4. Gen.) - 夜間暗視装置つきゴーグル (第4世代) + 暗視装置 (第4世代) 야투경 (4세대) 夜视镜 (四代) 夜視鏡 (四代) @@ -124,7 +130,7 @@ Éjjellátó szemüveg (széles látószögű) Óculos de visão noturna (Panorâmico) Occhiali notturni (Larghi) - 夜間暗視装置つきゴーグル (ワイド) + 暗視装置 (ワイド) 야투경 (넓음) 夜视镜 (宽版) 夜視鏡 (寬版) @@ -140,7 +146,7 @@ Fényerő: %1 Luminosidade: %1 Luminosità: %1 - 光度:%1 + 明度: %1 밝기: %1 亮度: %1 亮度: %1 @@ -156,7 +162,7 @@ Éjjellátó fényerejének növelése Aumentar Luminosidade do EVN Aumenta la luminosità dell'NVG - 夜間暗視装置の光度を上げる + 暗視装置の明度を上げる 야투경 밝기 높이기 增加夜视镜亮度 增加夜視鏡亮度 @@ -172,7 +178,7 @@ Éjjellátó fényerejének csökkentése Diminuir Luminosidade do EVN Riduci la luminosità dell'NVG - 夜間暗視装置の光度を下げる + 暗視装置の明度を下げる 야투경 밝기 줄이기 减少夜视镜亮度 減少夜視鏡亮度 @@ -187,7 +193,7 @@ Visione Notturna Visión Nocturna Vision nocturne - 夜間暗視装置 + 暗視装置 야간투시경 夜视 夜視 @@ -202,7 +208,7 @@ Impostazioni per visione notturna. Parámetros para visión nocturna Réglage pour la vision nocturne - 夜間暗視装置の設定。 + 暗視装置の設定。 야간투시경 설정 设定夜视选项. 設定夜視選項. @@ -217,7 +223,7 @@ Disabilita NVG nei mirini Desactivar NVG en miras Desactiver les JVN dans les viseurs. - スコープを覗くと夜間暗視装置を無効化 + スコープでは暗視装置を無効化 조준경 사용시 야투경 비활성화 使用瞄准镜时关闭夜视镜 使用瞄準鏡時關閉夜視鏡 @@ -232,10 +238,39 @@ Blocca l'uso di visori notturni mentre miri con ottiche. Desactiva el uso de gafas visión nocturna cuando se utilizan miras normales. Bloque l'usage des JVN pendant la visée. - スコープを使い狙いを付けると、夜間暗視装置を無効化します。 + スコープを使い狙いを付けると、暗視装置を無効化します。 조준시 야투경의 사용을 제한합니다. - 此功能开启后, 当要使用瞄准镜时, 为避免夜视镜镜头碰撞到瞄准镜, 会先拿开夜视镜后再进行瞄准镜瞄准. - 此功能開啟後, 當要使用瞄準鏡時, 為避免夜視鏡鏡頭碰撞到瞄準鏡, 會先拿開夜視鏡後再進行瞄準鏡瞄準. + 此功能开启后,当要使用瞄准镜时,为避免夜视镜镜头碰撞到瞄准镜,会先拿开夜视镜后再进行瞄准镜瞄准。 + 此功能開啟後,當要使用瞄準鏡時,為避免夜視鏡鏡頭碰撞到瞄準鏡,會先拿開夜視鏡後再進行瞄準鏡瞄準。 + + + NVG Fog Scale + 暗視装置の霧の規模 + Livello Nebbia NVG + Nebel in Nachtsicht + + + Fog is used to limit visibility. + 霧は視界制限のために使われます。 + La nebbia viene utilizzata per limitare la visibilità. + Nebel wird genutzt, um die Sichtbarkeit einzuschränken. + + + NVG Effect Scale + 暗視装置の効果規模 + Effetto livello NVG + Nachtsichteffekte + + + Blur, grain and brightness effects [Setting to 0 will disable ALL nightvision effects] + ぼかしと粒子、明度効果 [0 に設定で全効果を無効化します] + Effetti di sfocatura, sgranatura e luminosità [Importare a 0 disabiliterà TUTTI gli effetti della visione notturna] + Unschärfe-, Körnungs- und Helligkeitseffekte [Dies auf 0 zu setzen deaktiviert SÄMTLICHE Nachtsichteffekte] + + + Aim Down Sights Blur + 照準器を使用時にぼかし + Visierunschärfe diff --git a/addons/nlaw/stringtable.xml b/addons/nlaw/stringtable.xml index 74de6d21d8..8292cba0b9 100644 --- a/addons/nlaw/stringtable.xml +++ b/addons/nlaw/stringtable.xml @@ -1,26 +1,35 @@ - + NLAW Track Target (Hold) + NLAW Zielverfolgung NLAW Traccia Bersaglio (Mantieni) NALW 目標の追跡 (押しっぱ) 次世代轻型反坦克导弹发射器追踪目标 (按住) 次世代輕型反坦克導彈發射器追蹤目標 (按住) + Śledzenie Celu NLAW (Przytrzymaj) + NLAW 목표 추적 (누름유지) Direct Attack + Direkter Angriff Attacco Diretto ダイレクト アタック 直射模式 直射模式 + Bezpośredni atak + 직접 사격 Overfly Top Attack + Überflugangriff Attacco dall'alto オーバーフライ トップ アタック 攻顶模式 攻頂模式 + Atak z góry + 탑어택 diff --git a/addons/noidle/CfgMoves.hpp b/addons/noidle/CfgMoves.hpp index 1b8848ff00..2b5b06529a 100644 --- a/addons/noidle/CfgMoves.hpp +++ b/addons/noidle/CfgMoves.hpp @@ -1,4 +1,3 @@ - class CfgMovesBasic { class StandBase; }; @@ -7,29 +6,29 @@ class CfgMovesMaleSdr: CfgMovesBasic { class States { // rifle class AmovPercMstpSlowWrflDnon: StandBase { - variantsPlayer[] = {/*"AidlPercMstpSlowWrflDnon_G01",0.5,"AidlPercMstpSlowWrflDnon_G02",0.125,"AidlPercMstpSlowWrflDnon_G03",0.125,"AidlPercMstpSlowWrflDnon_G04",0.125,"AidlPercMstpSlowWrflDnon_G05",0.125*/}; + variantsPlayer[] = {/*"AidlPercMstpSlowWrflDnon_G01", 0.5, "AidlPercMstpSlowWrflDnon_G02", 0.125, "AidlPercMstpSlowWrflDnon_G03", 0.125, "AidlPercMstpSlowWrflDnon_G04", 0.125, "AidlPercMstpSlowWrflDnon_G05", 0.125*/}; }; class AmovPknlMstpSlowWrflDnon: AmovPercMstpSlowWrflDnon { - variantsPlayer[] = {/*"AidlPknlMstpSlowWrflDnon_G01",0.25,"AidlPknlMstpSlowWrflDnon_G02",0.25,"AidlPknlMstpSlowWrflDnon_G03",0.25*/}; + variantsPlayer[] = {/*"AidlPknlMstpSlowWrflDnon_G01", 0.25, "AidlPknlMstpSlowWrflDnon_G02", 0.25, "AidlPknlMstpSlowWrflDnon_G03", 0.25*/}; }; // pistol class AmovPercMstpSrasWpstDnon; class AmovPercMstpSlowWpstDnon: AmovPercMstpSrasWpstDnon { - variantsPlayer[] = {/*"AidlPercMstpSlowWpstDnon_G01",0.333,"AidlPercMstpSlowWpstDnon_G02",0.333,"AidlPercMstpSlowWpstDnon_G03",0.334*/}; + variantsPlayer[] = {/*"AidlPercMstpSlowWpstDnon_G01", 0.333, "AidlPercMstpSlowWpstDnon_G02", 0.333, "AidlPercMstpSlowWpstDnon_G03", 0.334*/}; }; class AmovPknlMstpSrasWpstDnon; class AmovPknlMstpSlowWpstDnon: AmovPknlMstpSrasWpstDnon { - variantsPlayer[] = {/*"AidlPknlMstpSlowWpstDnon_G03",0.333,"AidlPknlMstpSlowWpstDnon_G02",0.333,"AidlPknlMstpSlowWpstDnon_G01",0.334*/}; + variantsPlayer[] = {/*"AidlPknlMstpSlowWpstDnon_G03", 0.333, "AidlPknlMstpSlowWpstDnon_G02", 0.333, "AidlPknlMstpSlowWpstDnon_G01", 0.334*/}; }; // none class AmovPercMstpSnonWnonDnon: StandBase { - variantsPlayer[] = {/*"AidlPercMstpSnonWnonDnon_G01",0.16,"AidlPercMstpSnonWnonDnon_G02",0.16,"AidlPercMstpSnonWnonDnon_G03",0.16,"AidlPercMstpSnonWnonDnon_G04",0.16,"AidlPercMstpSnonWnonDnon_G05",0.16,"AidlPercMstpSnonWnonDnon_G06",0.16*/}; + variantsPlayer[] = {/*"AidlPercMstpSnonWnonDnon_G01", 0.16, "AidlPercMstpSnonWnonDnon_G02", 0.16, "AidlPercMstpSnonWnonDnon_G03", 0.16, "AidlPercMstpSnonWnonDnon_G04", 0.16, "AidlPercMstpSnonWnonDnon_G05", 0.16, "AidlPercMstpSnonWnonDnon_G06", 0.16*/}; }; class AmovPknlMstpSnonWnonDnon: AmovPercMstpSnonWnonDnon { - variantsPlayer[] = {/*"AidlPknlMstpSnonWnonDnon_G01",0.33,"AidlPknlMstpSnonWnonDnon_G02",0.33,"AidlPknlMstpSnonWnonDnon_G03",0.33*/}; + variantsPlayer[] = {/*"AidlPknlMstpSnonWnonDnon_G01", 0.33, "AidlPknlMstpSnonWnonDnon_G02", 0.33, "AidlPknlMstpSnonWnonDnon_G03", 0.33*/}; }; }; }; diff --git a/addons/noradio/CfgEventhandlers.hpp b/addons/noradio/CfgEventhandlers.hpp index 386d98d241..b928bc2de6 100644 --- a/addons/noradio/CfgEventhandlers.hpp +++ b/addons/noradio/CfgEventhandlers.hpp @@ -1,6 +1,5 @@ - -class Extended_PostInit_EventHandlers { +class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_FILE(XEH_preInit)); }; }; diff --git a/addons/noradio/XEH_postInit.sqf b/addons/noradio/XEH_postInit.sqf deleted file mode 100644 index 722a1d358c..0000000000 --- a/addons/noradio/XEH_postInit.sqf +++ /dev/null @@ -1,29 +0,0 @@ -// by commy2 -#include "script_component.hpp" - -// unmute unit if that player disconnects -if (isServer) then { - addMissionEventHandler ["HandleDisconnect", { - [_this select 0, "isPlayer"] call EFUNC(common,unmuteUnit); - }]; -}; - -if (!hasInterface) exitWith {}; - -// Handle early CBA_fnc_addPlayerEventHandler -if (!isNull ace_player) then { - [ace_player, "isPlayer"] call EFUNC(common,muteUnit); -}; - -// mutes/unmutes units when the player changes -["unit", { - params ["_newPlayer", "_oldPlayer"]; - - // mute the new player - [_newPlayer, "isPlayer"] call EFUNC(common,muteUnit); - - // unmute the old player - if (alive _oldPlayer) then { - [_oldPlayer, "isPlayer"] call EFUNC(common,unmuteUnit); - }; -}] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/noradio/XEH_preInit.sqf b/addons/noradio/XEH_preInit.sqf new file mode 100644 index 0000000000..5be74ddf1b --- /dev/null +++ b/addons/noradio/XEH_preInit.sqf @@ -0,0 +1,38 @@ +// By commy2 +#include "script_component.hpp" + +if (isServer) then { + // Unmute unit if that player disconnects + addMissionEventHandler ["HandleDisconnect", { + TRACE_1("re-enabling voice",_this); + [_this select 0, "isPlayer"] call EFUNC(common,unmuteUnit); + }]; +}; + +if (hasInterface) then { + // Mutes/unmutes units when the player changes + ["unit", { + if (!GVAR(enabled)) exitWith {}; + + params ["_newPlayer", "_oldPlayer"]; + TRACE_2("player change",_newPlayer,_oldPlayer); + + // Mute the new player + [_newPlayer, "isPlayer"] call EFUNC(common,muteUnit); + + // Unmute the old player + if (alive _oldPlayer) then { + [_oldPlayer, "isPlayer"] call EFUNC(common,unmuteUnit); + }; + }, true] call CBA_fnc_addPlayerEventHandler; +}; + +[QGVAR(enabled), "CHECKBOX", [LSTRING(setting), LSTRING(setting_tooltip)], format ["ACE %1", localize ELSTRING(common,DisplayName)], true, true, { + params ["_enabled"]; + + if (_enabled) then { + [ACE_player, "isPlayer"] call EFUNC(common,muteUnit); + } else { + [ACE_player, "isPlayer"] call EFUNC(common,unmuteUnit); + }; +}] call CBA_settings_fnc_init; diff --git a/addons/noradio/stringtable.xml b/addons/noradio/stringtable.xml new file mode 100644 index 0000000000..3ac0d075bf --- /dev/null +++ b/addons/noradio/stringtable.xml @@ -0,0 +1,21 @@ + + + + + Mute Player + Spieler stummschalten + Muta Giocatore + 玩家靜音 + 玩家静音 + プレイヤーをミュート + + + Mutes the controlled player avatar. + Schaltet eigenen Spieleravatar stumm. + Muta l'avatar del giocatore controllato. + 靜音玩家所控制的角色。 + 静音玩家所控制的角色。 + プレイヤーに操作されているこのキャラをミュートします。 + + + diff --git a/addons/norearm/CfgActions.hpp b/addons/norearm/CfgActions.hpp index 336c31273a..003ad3ae67 100644 --- a/addons/norearm/CfgActions.hpp +++ b/addons/norearm/CfgActions.hpp @@ -1,4 +1,3 @@ - class CfgActions { class None; class Rearm: None { diff --git a/addons/optics/CfgEventHandlers.hpp b/addons/optics/CfgEventHandlers.hpp index becf395052..0d3301d6e0 100644 --- a/addons/optics/CfgEventHandlers.hpp +++ b/addons/optics/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); diff --git a/addons/optics/CfgOpticsEffect.hpp b/addons/optics/CfgOpticsEffect.hpp index 8638277732..30c372fdac 100644 --- a/addons/optics/CfgOpticsEffect.hpp +++ b/addons/optics/CfgOpticsEffect.hpp @@ -1,7 +1,7 @@ class CfgOpticsEffect { class ACE_OpticsRadBlur1 { type = "radialblur"; - params[] = {0.015,0,0.14,0.2}; + params[] = {0.015, 0, 0.14, 0.2}; priority = 950; }; }; diff --git a/addons/optics/CfgRscTitles.hpp b/addons/optics/CfgRscTitles.hpp index 42a2326a0e..3df4632e16 100644 --- a/addons/optics/CfgRscTitles.hpp +++ b/addons/optics/CfgRscTitles.hpp @@ -9,12 +9,12 @@ class RscInGameUI { }; class ACE_RscWeaponZeroing: RscWeaponZeroing { - controls[] = {"CA_Zeroing","CA_FOVMode","ACE_DrawReticleHelper","ACE_ScriptedReticle"}; + controls[] = {"CA_Zeroing", "CA_FOVMode", "ACE_DrawReticleHelper", "ACE_ScriptedReticle"}; - class CA_FOVMode: RscOpticsValue { // idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used + class CA_FOVMode: RscOpticsValue { // Idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used idc = 154; style = 2; - colorText[] = {0,0,0,0}; + colorText[] = {0, 0, 0, 0}; x = 0; y = 0; w = 0; @@ -40,12 +40,12 @@ class RscInGameUI { }; class ACE_RscWeapon_base: RscWeaponZeroing { - controls[] = {"CA_Zeroing","CA_FOVMode","ACE_DrawReticleHelper","ReticleDay","ReticleNight","BodyNight","BodyDay", "trippleHeadLeft", "trippleHeadRight"}; // don't change this order + controls[] = {"CA_Zeroing", "CA_FOVMode", "ACE_DrawReticleHelper", "ReticleDay", "ReticleNight", "BodyNight", "BodyDay", "trippleHeadLeft", "trippleHeadRight"}; // Don't change this order - class CA_FOVMode: RscOpticsValue { // idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used + class CA_FOVMode: RscOpticsValue { // Idea by Taosenai. Apparently this can be used via isNil check to determine wheter the scope or the kolimator is used idc = 154; style = 2; - colorText[] = {0,0,0,0}; + colorText[] = {0, 0, 0, 0}; x = 0; y = 0; w = 0; @@ -66,12 +66,12 @@ class RscInGameUI { size = 0; sizeEx = 1; text = ""; - colorText[] = {1,1,1,0}; - colorBackground[] = {0,0,0,0}; - x = safezoneX+0.5*safezoneW-0.5*SIZEX; - y = safezoneY+0.5*safezoneH-0.5*SIZEX*(4/3); + colorText[] = {1, 1, 1, 0}; + colorBackground[] = {0, 0, 0, 0}; + x = safezoneX + 0.5 * safezoneW - 0.5 * SIZEX; + y = safezoneY + 0.5 * safezoneH - 0.5 * SIZEX * (4 / 3); w = SIZEX; - h = SIZEX*(4/3); + h = SIZEX * (4 / 3); }; class ReticleNight: ReticleDay { @@ -84,10 +84,10 @@ class RscInGameUI { class BodyDay: ReticleDay { idc = 1713005; text = ""; - x = safezoneX+0.5*safezoneW-0.5*SIZEX; - y = safezoneY+0.5*safezoneH-0.5*SIZEX*(4/3); + x = safezoneX + 0.5 * safezoneW - 0.5 * SIZEX; + y = safezoneY + 0.5 * safezoneH - 0.5 * SIZEX * (4 / 3); w = SIZEX; - h = SIZEX*(4/3); + h = SIZEX * (4 / 3); }; class BodyNight: BodyDay { @@ -95,21 +95,21 @@ class RscInGameUI { text = ""; }; - //These are just black side panels to cover the areas that the optics p3d doesn't cover - //It will ONLY effect tripple head users as (safezoneX == safeZoneXAbs) for everyone else - //Reference PR #1156: + // These are just black side panels to cover the areas that the optics p3d doesn't cover + // It will ONLY effect tripple head users as (safezoneX == safeZoneXAbs) for everyone else + // Reference PR #1156: class trippleHeadLeft: RscText { idc = 1713010; x = "safeZoneXAbs"; Y = "safezoneY"; - W = "(safezoneX - safeZoneXAbs) * ((getResolution select 4)/(16/3))"; + W = "(safezoneX - safeZoneXAbs) * ((getResolution select 4) / (16 / 3))"; H = "safeZoneH"; - colorBackground[] = {0,0,0,1}; + colorBackground[] = {0, 0, 0, 1}; }; class trippleHeadRight: trippleHeadLeft { idc = 1713011; - x = "safeZoneXAbs + safeZoneWAbs - (safezoneX - safeZoneXABS) * ((getResolution select 4)/(16/3))"; - colorBackground[] = {0,0,0,1}; + x = "safeZoneXAbs + safeZoneWAbs - (safezoneX - safeZoneXABS) * ((getResolution select 4) / (16 / 3))"; + colorBackground[] = {0, 0, 0, 1}; }; }; @@ -190,12 +190,12 @@ class RscInGameUI { _ctrl = (D displayCtrl 1713006); -_sizeX = 1.54/(getResolution select 5); -_sizeY = _sizeX*safezoneW/safezoneH; +_sizeX = 1.54 / (getResolution select 5); +_sizeY = _sizeX * safezoneW / safezoneH; _ctrl ctrlSetPosition [ - safezoneX+0.5*safezoneW-0.5*_sizeX, - safezoneY+0.5*safezoneH-0.5*_sizeY, + safezoneX + 0.5 * safezoneW - 0.5 * _sizeX, + safezoneY + 0.5 * safezoneH - 0.5 * _sizeY, _sizeX, _sizeY ]; diff --git a/addons/optics/CfgWeapons.hpp b/addons/optics/CfgWeapons.hpp index 75b0319b62..c9dfbb8d7b 100644 --- a/addons/optics/CfgWeapons.hpp +++ b/addons/optics/CfgWeapons.hpp @@ -86,9 +86,9 @@ class CfgWeapons { opticsZoomInit = 0.0872664626; opticsZoomMax = 0.0872664626; opticsZoomMin = 0.0872664626; - opticsPPEffects[] = {"OpticsCHAbera5","OpticsBlur5","ACE_OpticsRadBlur1"}; + opticsPPEffects[] = {"OpticsCHAbera5", "OpticsBlur5", "ACE_OpticsRadBlur1"}; opticsDisablePeripherialVision = 0; - visionMode[] = {"Normal","NVG"}; + visionMode[] = {"Normal", "NVG"}; }; }; }; @@ -135,7 +135,7 @@ class CfgWeapons { opticsZoomInit = 0.0872664626; opticsZoomMax = 0.0872664626; opticsZoomMin = 0.0872664626; - opticsPPEffects[] = {"OpticsCHAbera5","OpticsBlur5","ACE_OpticsRadBlur1"}; + opticsPPEffects[] = {"OpticsCHAbera5", "OpticsBlur5", "ACE_OpticsRadBlur1"}; opticsDisablePeripherialVision = 0; visionMode[] = {"Normal"}; }; @@ -184,7 +184,7 @@ class CfgWeapons { opticsZoomInit = 0.0872664626; opticsZoomMax = 0.0872664626; opticsZoomMin = 0.0872664626; - opticsPPEffects[] = {"OpticsCHAbera5","OpticsBlur5","ACE_OpticsRadBlur1"}; + opticsPPEffects[] = {"OpticsCHAbera5", "OpticsBlur5", "ACE_OpticsRadBlur1"}; opticsDisablePeripherialVision = 0; visionMode[] = {"Normal"}; }; @@ -227,13 +227,13 @@ class CfgWeapons { class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_reticle90.p3d),QPATHTOF(models\ace_optics_reticle90.p3d)}; + modelOptics[] = {QPATHTOF(models\ace_optics_reticle90.p3d), QPATHTOF(models\ace_optics_reticle90.p3d)}; useModelOptics = 1; opticsZoomInit = 0.0116; opticsZoomMax = 0.0464; opticsZoomMin = 0.0116; discreteFOV[] = {0.0464, 0.0116}; - opticsPPEffects[] = {"OpticsCHAbera1","OpticsBlur1","ACE_OpticsRadBlur1"}; + opticsPPEffects[] = {"OpticsCHAbera1", "OpticsBlur1", "ACE_OpticsRadBlur1"}; opticsDisablePeripherialVision = 0; }; class Iron: Iron {}; @@ -250,7 +250,7 @@ class CfgWeapons { class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_pip.p3d),QPATHTOF(models\ace_optics_pip.p3d)}; + modelOptics[] = {QPATHTOF(models\ace_optics_pip.p3d), QPATHTOF(models\ace_optics_pip.p3d)}; }; class Iron: Iron {}; }; @@ -279,13 +279,13 @@ class CfgWeapons { class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_reticle90.p3d),QPATHTOF(models\ace_optics_reticle90.p3d)}; + modelOptics[] = {QPATHTOF(models\ace_optics_reticle90.p3d), QPATHTOF(models\ace_optics_reticle90.p3d)}; useModelOptics = 1; opticsZoomInit = 0.0116; opticsZoomMax = 0.0464; opticsZoomMin = 0.0116; discreteFOV[] = {}; - opticsPPEffects[] = {"OpticsCHAbera1","OpticsBlur1","ACE_OpticsRadBlur1"}; + opticsPPEffects[] = {"OpticsCHAbera1", "OpticsBlur1", "ACE_OpticsRadBlur1"}; opticsDisablePeripherialVision = 0; }; }; @@ -301,7 +301,7 @@ class CfgWeapons { class ItemInfo: ItemInfo { class OpticsModes: OpticsModes { class Snip: Snip { - modelOptics[] = {QPATHTOF(models\ace_optics_pip.p3d),QPATHTOF(models\ace_optics_pip.p3d)}; + modelOptics[] = {QPATHTOF(models\ace_optics_pip.p3d), QPATHTOF(models\ace_optics_pip.p3d)}; }; }; }; diff --git a/addons/optics/XEH_PREP.hpp b/addons/optics/XEH_PREP.hpp index 2b846a552a..8eb8eb1eb5 100644 --- a/addons/optics/XEH_PREP.hpp +++ b/addons/optics/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(handleFired); PREP(onDrawScope); PREP(onDrawScope2D); diff --git a/addons/optics/XEH_postInit.sqf b/addons/optics/XEH_postInit.sqf index a4f118619b..2c02e72638 100644 --- a/addons/optics/XEH_postInit.sqf +++ b/addons/optics/XEH_postInit.sqf @@ -18,7 +18,7 @@ GVAR(camera) = objNull; params ["", "_isfeatureCameraActive"]; TRACE_1("ace_activeCameraChanged",_isfeatureCameraActive); if (!_isfeatureCameraActive) then { - //Destroy the camera, and it will be re-created in the onDrawScope2d helper + // Destroy the camera, and it will be re-created in the onDrawScope2d helper if (!isNull GVAR(camera)) then { GVAR(camera) cameraEffect ["TERMINATE", "BACK"]; camDestroy GVAR(camera); diff --git a/addons/optics/functions/fnc_handleFired.sqf b/addons/optics/functions/fnc_handleFired.sqf index 10b21b5042..435e7e8e7c 100644 --- a/addons/optics/functions/fnc_handleFired.sqf +++ b/addons/optics/functions/fnc_handleFired.sqf @@ -18,12 +18,12 @@ #include "script_component.hpp" -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; +// IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); disableSerialization; -// check if compatible scope is used +// Check if compatible scope is used private _display = uiNamespace getVariable [QGVAR(RscWeaponInfo2D), displayNull]; if (isNull _display) exitWith {}; @@ -36,25 +36,23 @@ private _recoilCoef = switch (true) do { }; // Constants which determine how the scope recoils -private ["_recoilScope", "_reticleShiftX", "_reticleShiftY", "_scopeShiftX", "_scopeShiftY"]; -_recoilScope = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_RECOIL_MIN, SCOPE_RECOIL_MAX, false]; +private _recoilScope = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_RECOIL_MIN, SCOPE_RECOIL_MAX, false]; -_reticleShiftX = _recoilCoef * linearConversion [0, 1, random 1, RETICLE_SHIFT_X_MIN, RETICLE_SHIFT_X_MAX, false]; -_reticleShiftY = _recoilCoef * linearConversion [0, 1, random 1, RETICLE_SHIFT_Y_MIN, RETICLE_SHIFT_Y_MAX, false]; +private _reticleShiftX = _recoilCoef * linearConversion [0, 1, random 1, RETICLE_SHIFT_X_MIN, RETICLE_SHIFT_X_MAX, false]; +private _reticleShiftY = _recoilCoef * linearConversion [0, 1, random 1, RETICLE_SHIFT_Y_MIN, RETICLE_SHIFT_Y_MAX, false]; -_scopeShiftX = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_SHIFT_X_MIN, SCOPE_SHIFT_X_MAX, false]; -_scopeShiftY = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_SHIFT_Y_MIN, SCOPE_SHIFT_Y_MAX, false]; +private _scopeShiftX = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_SHIFT_X_MIN, SCOPE_SHIFT_X_MAX, false]; +private _scopeShiftY = _recoilCoef * linearConversion [0, 1, random 1, SCOPE_SHIFT_Y_MIN, SCOPE_SHIFT_Y_MAX, false]; // Create and commit recoil effect -private ["_sizeX", "_sizeY"]; -_sizeX = (0.75 + _recoilScope)/(getResolution select 5); -_sizeY = _sizeX*(4/3); +private _sizeX = (0.75 + _recoilScope) / (getResolution select 5); +private _sizeY = _sizeX * (4 / 3); private _positionReticle = [ - safezoneX + 0.5 * safezoneW - 0.5*(_sizeX + _reticleShiftX), - safezoneY + 0.5 * safezoneH - 0.5*(_sizeY + _reticleShiftY), + safezoneX + 0.5 * safezoneW - 0.5 * (_sizeX + _reticleShiftX), + safezoneY + 0.5 * safezoneH - 0.5 * (_sizeY + _reticleShiftY), _sizeX, _sizeY ]; @@ -63,8 +61,8 @@ private _positionReticle = [ (_display displayCtrl 1713002) ctrlSetPosition _positionReticle; private _positionBody = [ - safezoneX + 0.5 * safezoneW - 0.5*(2 * _sizeX + _scopeShiftX), - safezoneY + 0.5 * safezoneH - 0.5*(2 * _sizeY + _scopeShiftY), + safezoneX + 0.5 * safezoneW - 0.5 * (2 * _sizeX + _scopeShiftX), + safezoneY + 0.5 * safezoneH - 0.5 * (2 * _sizeY + _scopeShiftY), 2 * _sizeX, 2 * _sizeY ]; @@ -78,8 +76,8 @@ private _positionBody = [ (_display displayCtrl 1713006) ctrlCommit 0; // Bring them all back -_sizeX = 0.75/(getResolution select 5); -_sizeY = _sizeX*(4/3); +_sizeX = 0.75 / (getResolution select 5); +_sizeY = _sizeX * (4 / 3); _positionReticle = [ safezoneX + 0.5 * safezoneW - 0.5 * _sizeX, diff --git a/addons/optics/functions/fnc_onDrawScope.sqf b/addons/optics/functions/fnc_onDrawScope.sqf index e3114c8c84..1f2f86e21a 100644 --- a/addons/optics/functions/fnc_onDrawScope.sqf +++ b/addons/optics/functions/fnc_onDrawScope.sqf @@ -26,12 +26,12 @@ if (!ctrlShown (_display displayCtrl 154)) exitWith { _control ctrlShow false; }; -private _sizeX = (call EFUNC(common,getZoom))/4; -private _sizeY = _sizeX*safezoneW/safezoneH; +private _sizeX = (call EFUNC(common,getZoom)) / 4; +private _sizeY = _sizeX * safezoneW / safezoneH; _control ctrlSetPosition [ - safezoneX+0.5*safezoneW-0.5*_sizeX, - safezoneY+0.5*safezoneH-0.5*_sizeY, + safezoneX + 0.5 * safezoneW - 0.5 * _sizeX, + safezoneY + 0.5 * safezoneH - 0.5 * _sizeY, _sizeX, _sizeY ]; diff --git a/addons/optics/functions/fnc_onDrawScope2D.sqf b/addons/optics/functions/fnc_onDrawScope2D.sqf index c429740de0..cdfcca6b00 100644 --- a/addons/optics/functions/fnc_onDrawScope2D.sqf +++ b/addons/optics/functions/fnc_onDrawScope2D.sqf @@ -32,7 +32,7 @@ if (_isPIP) then { }; // PiP technique by BadBenson - GVAR(camera) = "camera" camCreate positionCameraToWorld [0,0,0]; + GVAR(camera) = "camera" camCreate positionCameraToWorld [0, 0, 0]; GVAR(camera) camSetFov 0.7; GVAR(camera) camSetTarget ACE_player; GVAR(camera) camCommit 1; @@ -42,7 +42,7 @@ if (_isPIP) then { TRACE_2("created new pip camera",GVAR(camera),isNull GVAR(camera)); - //Start a waitUntil to handle destruction after GVAR(pipLastFrame) is no longer updated + // Start a waitUntil to handle destruction after GVAR(pipLastFrame) is no longer updated [{ (abs (diag_frameno - GVAR(pipLastFrame))) > 1 }, { @@ -64,8 +64,8 @@ if (!ctrlShown (_display displayCtrl 154)) exitWith { }; if (_isPIP) then { - GVAR(camera) setPosATL positionCameraToWorld [0,0,0.4]; - GVAR(camera) camPrepareTarget positionCameraToWorld [0,0,50]; + GVAR(camera) setPosATL positionCameraToWorld [0, 0, 0.4]; + GVAR(camera) camPrepareTarget positionCameraToWorld [0, 0, 50]; GVAR(camera) camCommitPrepared 0; // @todo, check if that needs to be done at all @@ -78,15 +78,15 @@ if (_isPIP) then { }; }; -// calculate lighting +// Calculate lighting private _dayOpacity = call EFUNC(common,ambientBrightness); -private _nightOpacity = [1,0] select (_dayOpacity == 1); +private _nightOpacity = [1, 0] select (_dayOpacity == 1); // Apply lighting and make layers visible -(_display displayCtrl 1713001) ctrlSetTextColor [1,1,1,1]; -(_display displayCtrl 1713002) ctrlSetTextColor [1,1,1,[0,1] select (_dayOpacity < 0.5)]; -(_display displayCtrl 1713005) ctrlSetTextColor [1,1,1,_dayOpacity]; -(_display displayCtrl 1713006) ctrlSetTextColor [1,1,1,_nightOpacity]; +(_display displayCtrl 1713001) ctrlSetTextColor [1, 1, 1, 1]; +(_display displayCtrl 1713002) ctrlSetTextColor [1, 1, 1, [0, 1] select (_dayOpacity < 0.5)]; +(_display displayCtrl 1713005) ctrlSetTextColor [1, 1, 1, _dayOpacity]; +(_display displayCtrl 1713006) ctrlSetTextColor [1, 1, 1, _nightOpacity]; /* (_display displayCtrl 1713001) ctrlCommit 0; diff --git a/addons/optionsmenu/ACE_Settings.hpp b/addons/optionsmenu/ACE_Settings.hpp index 0badbad660..bab67cd37f 100644 --- a/addons/optionsmenu/ACE_Settings.hpp +++ b/addons/optionsmenu/ACE_Settings.hpp @@ -1,11 +1,4 @@ class ACE_Settings { - class GVAR(optionMenuDisplaySize) { - value = 0; - typeName = "SCALAR"; - isClientSettable = 1; - displayName = CSTRING(uiScaing); - values[] = {"$str_medium", "$str_large", "$str_very_large"}; - }; class GVAR(showNewsOnMainMenu) { value = 1; typeName = "BOOL"; diff --git a/addons/optionsmenu/CfgEventHandlers.hpp b/addons/optionsmenu/CfgEventHandlers.hpp index dc5816df05..4f50c9613f 100644 --- a/addons/optionsmenu/CfgEventHandlers.hpp +++ b/addons/optionsmenu/CfgEventHandlers.hpp @@ -11,12 +11,6 @@ class Extended_PreInit_EventHandlers { }; }; -class Extended_PostInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); - }; -}; - class Extended_DisplayLoad_EventHandlers { class RscDisplayMain { GVAR(loadMainMenuBox) = QUOTE(_this call COMPILE_FILE(init_loadMainMenuBox)); diff --git a/addons/optionsmenu/CfgVehicles.hpp b/addons/optionsmenu/CfgVehicles.hpp index cbe03a4cfb..a00d8abc3e 100644 --- a/addons/optionsmenu/CfgVehicles.hpp +++ b/addons/optionsmenu/CfgVehicles.hpp @@ -1,27 +1,7 @@ class CfgVehicles { class ACE_Module; class ACE_moduleAllowConfigExport: ACE_Module { - scope = 2; - displayName = CSTRING(AllowConfigExport_Module_DisplayName); - //icon = ""; - category = "ACE"; - function = QUOTE(DFUNC(moduleAllowConfigExport)); - functionPriority = 1; - isGlobal = 1; - isSingular = 1; - isTriggerActivated = 0; - author = ECSTRING(common,ACETeam); - class Arguments { - class allowconfigurationExport { - displayName = CSTRING(AllowConfigExport_allowconfigurationExport_DisplayName); - description = CSTRING(AllowConfigExport_allowconfigurationExport_Description); - typeName = "BOOL"; - defaultValue = 1; - }; - }; - class ModuleDescription { - description = CSTRING(AllowConfigExport_Module_Description); - sync[] = {}; - }; + scope = 1; + displayName = "Deprecated ACE Module"; }; }; diff --git a/addons/optionsmenu/README.md b/addons/optionsmenu/README.md index f8d8c54d09..e274229053 100644 --- a/addons/optionsmenu/README.md +++ b/addons/optionsmenu/README.md @@ -1,7 +1,8 @@ ace_optionsmenu =============== -Adds the options menu used by other components. +Previously held the options menu. +Now just handles version display on main menu and debug/headbug on options menu. ## Maintainers diff --git a/addons/optionsmenu/XEH_PREP.hpp b/addons/optionsmenu/XEH_PREP.hpp index f1ffe1ed98..becbe9904f 100644 --- a/addons/optionsmenu/XEH_PREP.hpp +++ b/addons/optionsmenu/XEH_PREP.hpp @@ -1,22 +1,2 @@ PREP(debugDumpToClipboard); -PREP(onListBoxSettingsChanged); -PREP(onListBoxShowSelectionChanged); -PREP(onSettingsMenuOpen); -PREP(onSliderPosChanged); -PREP(onServerSaveInputField); -PREP(onServerSettingsMenuOpen); -PREP(onServerListBoxShowSelectionChanged); -PREP(onCategorySelectChanged); -PREP(resetSettings); -PREP(serverResetSettings); -PREP(settingsMenuUpdateKeyView); -PREP(settingsMenuUpdateList); -PREP(serverSettingsMenuUpdateKeyView); -PREP(serverSettingsMenuUpdateList); -PREP(onServerCategorySelectChanged); -PREP(updateSetting); -PREP(exportSettings); -PREP(toggleIncludeClientSettings); -PREP(moduleAllowConfigExport); -PREP(stringEscape); diff --git a/addons/optionsmenu/XEH_postInit.sqf b/addons/optionsmenu/XEH_postInit.sqf deleted file mode 100644 index 2ef332446a..0000000000 --- a/addons/optionsmenu/XEH_postInit.sqf +++ /dev/null @@ -1,11 +0,0 @@ - -#include "script_component.hpp" - -["ace_settingsInitialized", { - GVAR(categories) pushBack ""; //Ensure All Catagories is at top - { - if !(_x select 8 in GVAR(categories)) then { - GVAR(categories) pushBack (_x select 8); - }; - }forEach EGVAR(common,settings); -}] call CBA_fnc_addEventHandler; diff --git a/addons/optionsmenu/XEH_preInit.sqf b/addons/optionsmenu/XEH_preInit.sqf index 57e017e054..46d58b5a8a 100644 --- a/addons/optionsmenu/XEH_preInit.sqf +++ b/addons/optionsmenu/XEH_preInit.sqf @@ -6,15 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(clientSideOptions) = []; -GVAR(clientSideColors) = []; - -GVAR(serverConfigGeneration) = 0; -GVAR(ClientSettingsExportIncluded) = false; -GVAR(serverSideOptions) = []; -GVAR(serverSideColors) = []; -GVAR(serverSideValues) = []; -GVAR(categories) = []; -GVAR(currentCategorySelection) = 0; +if (hasInterface) then { + [[format ["ACE %1", localize LSTRING(DumpDebug)], localize LSTRING(DumpDebugTooltip)], QGVAR(MainMenuHelperDumpDebug)] call CBA_fnc_addPauseMenuOption; + [[format ["ACE %1", localize LSTRING(headBugFix)], localize LSTRING(headBugFixTooltip)], QGVAR(MainMenuHelperHeadBugFix)] call CBA_fnc_addPauseMenuOption; +}; ADDON = true; diff --git a/addons/optionsmenu/config.cpp b/addons/optionsmenu/config.cpp index 650f9eb74a..b17fe12cc3 100644 --- a/addons/optionsmenu/config.cpp +++ b/addons/optionsmenu/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_moduleAllowConfigExport"}; + units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; @@ -23,13 +23,12 @@ class CfgAddons { }; #include "CfgEventHandlers.hpp" -#include "gui\define.hpp" -#include "gui\settingsMenu.hpp" -#include "gui\pauseMenu.hpp" - #include "CfgVehicles.hpp" #include "ACE_Settings.hpp" +#include "gui\mainMenu.hpp" +#include "gui\pauseMenu.hpp" + class ACE_Extensions { extensions[] += {"ace_clipboard"}; }; diff --git a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf index dd2c187bf7..a502934f50 100644 --- a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf +++ b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf @@ -15,17 +15,15 @@ */ #include "script_component.hpp" -private ["_var", "_unit", "_outputText", "_text"]; - #define MIN_ARRAY_SIZE 50 -_outputText = { +private _outputText = { diag_log text (_this select 0); "ace_clipboard" callExtension ((_this select 0) + " "); }; -_text = format ["~~~~~~~~~ACE Debug~~~~~~~~~ +private _text = format ["~~~~~~~~~ACE Debug~~~~~~~~~ time = %1 ------Performance------ @@ -57,15 +55,16 @@ if (isNull ace_player) then {"null"} else {animationState ace_player}]; _text = format [" -------ACE Settings------"]; +------ACE's CBA Settings------"]; [_text] call _outputText; - +private _aceSettings = cba_settings_allSettings select {((_x select [0,4]) == "ace_") || {(_x select [0,5]) == "acex_"}}; +_aceSettings sort true; { - _var = missionNamespace getVariable [(_x select 0), "ERROR: Not Defined"]; - _text = format ["%1 - %2", (_x select 0), _var]; + _var = missionNamespace getVariable [_x, "ERROR: Not Defined"]; + _text = format ["%1 - %2", _x, _var]; [_text] call _outputText; -} forEach EGVAR(common,settings); +} forEach _aceSettings; _text = format [" @@ -82,9 +81,9 @@ _text = format [" } forEach (allVariables missionNamespace); { - _unit = _x; + private _unit = _x; { - _var = _unit getVariable [_x, nil]; + private _var = _unit getVariable [_x, nil]; if(!isnil "_var" && {_var isEqualType []} && {(count _var) > MIN_ARRAY_SIZE}) then { _text = format ["%1 on [%2] - ARRAY SIZE: %3", _x, _unit, (count _var)]; [_text] call _outputText; diff --git a/addons/optionsmenu/functions/fnc_exportSettings.sqf b/addons/optionsmenu/functions/fnc_exportSettings.sqf deleted file mode 100644 index e798784871..0000000000 --- a/addons/optionsmenu/functions/fnc_exportSettings.sqf +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Author: Glowbal - * Export all config settings with their current values. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_exportSettings - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_compiledConfig", "_name", "_typeName", "_isClientSetable", "_localizedName", "_localizedDescription", "_possibleValues", "_defaultValue", "_value", "_compiledConfigEntry", "_formatedValue"]; - -{ - /*_settingData = [ - _name, - _typeName, - _isClientSetable, - _localizedName, - _localizedDescription, - _possibleValues, - _isForced, - _defaultValue - ];*/ - - _name = _x select 0; - _typeName = _x select 1; - _isClientSetable = _x select 2; - _localizedName = _x select 3; - _localizedDescription = _x select 4; - _possibleValues = _x select 5; - _defaultValue = _x select 6; - - if (GVAR(ClientSettingsExportIncluded) || !_isClientSetable) then { - _value = missionNamespace getVariable [_name, _defaultValue]; - _formatedValue = switch (toLower _typeName) do { - case ("scalar"): { - format['value = %1;', _value]; - }; - case ("string"): { - format['value = "%1";', _value]; - }; - case ("bool"): { - if (!(_value isEqualType false)) then {ERROR("weird bool typename??");}; - _value = if ((_value isEqualType false) && {_value}) then {1} else {0}; - format ['value = %1;', _value]; - }; - case ("color"): { - _value params [["_r",1], ["_b",0], ["_g",1], ["_a",1]]; - format ["value[] = {%1, %2, %3, %4};", _r, _b, _g, _a]; - }; - default { - ERROR("unknown typeName"); - "" - }; - - }; - _compiledConfigEntry = format [" -class %1 { - %2 - typeName = %3; - force = 1; -};", _name, _formatedValue, format['"%1"', _typeName]]; - - "ace_clipboard" callExtension _compiledConfigEntry; - }; -} forEach EGVAR(common,settings); - -"ace_clipboard" callExtension "--COMPLETE--"; - -[LSTRING(settingsExported)] call EFUNC(common,displayTextStructured); diff --git a/addons/optionsmenu/functions/fnc_moduleAllowConfigExport.sqf b/addons/optionsmenu/functions/fnc_moduleAllowConfigExport.sqf deleted file mode 100644 index 2426bb2f26..0000000000 --- a/addons/optionsmenu/functions/fnc_moduleAllowConfigExport.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Author: Glowbal - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_optionsmenu_fnc_moduleAllowConfigExport - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_logic"]; - -if (isMultiplayer) exitWith {}; - -if (_logic getVariable ["allowconfigurationExport", false]) then { - GVAR(serverConfigGeneration) = 1; -} else { - GVAR(serverConfigGeneration) = 0; -}; diff --git a/addons/optionsmenu/functions/fnc_onCategorySelectChanged.sqf b/addons/optionsmenu/functions/fnc_onCategorySelectChanged.sqf deleted file mode 100644 index 2824c2e2fa..0000000000 --- a/addons/optionsmenu/functions/fnc_onCategorySelectChanged.sqf +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Author: Glowbal - * Changes which category is selected - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_onCategorySelectChanged - * - * Public: No - */ - -#include "script_component.hpp" - -disableSerialization; -private _settingsMenu = uiNamespace getVariable 'ACE_settingsMenu'; - -private _ctrlComboBox = (_settingsMenu displayCtrl 14); -GVAR(currentCategorySelection) = _ctrlComboBox lbValue (lbCurSel _ctrlComboBox); - -[true] call FUNC(settingsMenuUpdateList); diff --git a/addons/optionsmenu/functions/fnc_onListBoxSettingsChanged.sqf b/addons/optionsmenu/functions/fnc_onListBoxSettingsChanged.sqf deleted file mode 100644 index 6486a5e39b..0000000000 --- a/addons/optionsmenu/functions/fnc_onListBoxSettingsChanged.sqf +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Author: Glowbal - * Called when the listbox selection is changed for an options (eg: chaning a setting from false to true) - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_onListBoxSettingsChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private _rightDropDownIndex = lbCurSel 400; //Index of right drop down -if (_rightDropDownIndex < 0) then {_rightDropDownIndex = 0;}; - -private _settingIndex = -1; -if (((lnbCurSelRow 200) >= 0) && {(lnbCurSelRow 200) < ((lnbSize 200) select 0)}) then { - _settingIndex = lnbValue [200, [(lnbCurSelRow 200), 0]]; -}; -if (_settingIndex == -1) exitWith {}; - -switch (GVAR(optionMenu_openTab)) do { - case (MENU_TAB_OPTIONS): { - if ((_settingIndex >= 0) && (_settingIndex < (count GVAR(clientSideOptions)))) then { - _settingIndex = (GVAR(clientSideOptions) select _settingIndex) select 0; - [MENU_TAB_OPTIONS, _settingIndex, _rightDropDownIndex] call FUNC(updateSetting); - }; - [false] call FUNC(settingsMenuUpdateList); - }; - case (MENU_TAB_SERVER_OPTIONS): { - if ((_settingIndex >= 0) && (_settingIndex < (count GVAR(serverSideOptions)))) then { - _settingIndex = (GVAR(serverSideOptions) select _settingIndex) select 0; - [MENU_TAB_SERVER_OPTIONS, _settingIndex, _rightDropDownIndex] call FUNC(updateSetting); - }; - [false] call FUNC(serverSettingsMenuUpdateList); - }; -}; diff --git a/addons/optionsmenu/functions/fnc_onListBoxShowSelectionChanged.sqf b/addons/optionsmenu/functions/fnc_onListBoxShowSelectionChanged.sqf deleted file mode 100644 index 0ddcc8d2a9..0000000000 --- a/addons/optionsmenu/functions/fnc_onListBoxShowSelectionChanged.sqf +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Author: Glowbal - * Changes which tab is open (options or colors) - * - * Arguments: - * The tab to open (defined in script_component) - * - * Return Value: - * None - * - * Example: - * [MENU_TAB_COLORS] call ACE_optionsmenu_fnc_onListBoxShowSelectionChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingsMenu", "_localizedHeader"]; - -PARAMS_1(_openTab); -GVAR(optionMenu_openTab) = _openTab; - -disableSerialization; -_settingsMenu = uiNamespace getVariable 'ACE_settingsMenu'; - -switch (GVAR(optionMenu_openTab)) do { -case (MENU_TAB_OPTIONS): { - _localizedHeader = format ["%1: %2", (localize LSTRING(OpenConfigMenu)), (localize LSTRING(TabOptions))]; - ctrlSetText [13, _localizedHeader]; - lbClear 400; - - (_settingsMenu displayCtrl 301) ctrlShow true; - - (_settingsMenu displayCtrl 400) ctrlShow true; - (_settingsMenu displayCtrl 410) ctrlShow false; - (_settingsMenu displayCtrl 411) ctrlShow false; - (_settingsMenu displayCtrl 412) ctrlShow false; - (_settingsMenu displayCtrl 413) ctrlShow false; - }; -case (MENU_TAB_COLORS): { - _localizedHeader = format ["%1: %2", (localize LSTRING(OpenConfigMenu)), (localize LSTRING(TabColors))]; - ctrlSetText [13, _localizedHeader]; - - lbClear 400; - - (_settingsMenu displayCtrl 301) ctrlShow false; - - (_settingsMenu displayCtrl 400) ctrlShow false; - (_settingsMenu displayCtrl 410) ctrlShow true; - (_settingsMenu displayCtrl 411) ctrlShow true; - (_settingsMenu displayCtrl 412) ctrlShow true; - (_settingsMenu displayCtrl 413) ctrlShow true; - - (_settingsMenu displayCtrl 410) sliderSetRange [0, 255]; - (_settingsMenu displayCtrl 411) sliderSetRange [0, 255]; - (_settingsMenu displayCtrl 412) sliderSetRange [0, 255]; - (_settingsMenu displayCtrl 413) sliderSetRange [0, 255]; - }; -}; - -[true] call FUNC(settingsMenuUpdateList); diff --git a/addons/optionsmenu/functions/fnc_onServerCategorySelectChanged.sqf b/addons/optionsmenu/functions/fnc_onServerCategorySelectChanged.sqf deleted file mode 100644 index d134cda993..0000000000 --- a/addons/optionsmenu/functions/fnc_onServerCategorySelectChanged.sqf +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Author: Glowbal - * Changes which category is selected - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_onCategorySelectChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingsMenu", "_ctrlComboBox"]; -disableSerialization; -_settingsMenu = uiNamespace getVariable 'ACE_serverSettingsMenu'; - -_ctrlComboBox = (_settingsMenu displayCtrl 14); -GVAR(currentCategorySelection) = lbCurSel _ctrlComboBox; - -[true] call FUNC(serverSettingsMenuUpdateList); diff --git a/addons/optionsmenu/functions/fnc_onServerListBoxShowSelectionChanged.sqf b/addons/optionsmenu/functions/fnc_onServerListBoxShowSelectionChanged.sqf deleted file mode 100644 index 669faf74ed..0000000000 --- a/addons/optionsmenu/functions/fnc_onServerListBoxShowSelectionChanged.sqf +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Author: Glowbal - * Changes which tab is open (options or colors) - * - * Arguments: - * The tab to open (defined in script_component) - * - * Return Value: - * None - * - * Example: - * [MENU_TAB_COLORS] call ACE_optionsmenu_fnc_onListBoxShowSelectionChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingsMenu", "_localizedHeader"]; - -PARAMS_1(_openTab); -GVAR(optionMenu_openTab) = _openTab; - -disableSerialization; -_settingsMenu = uiNamespace getVariable 'ACE_serverSettingsMenu'; - -switch (GVAR(optionMenu_openTab)) do { -case (MENU_TAB_SERVER_OPTIONS): { - _localizedHeader = format ["%1: %2", (localize LSTRING(OpenConfigMenu)), (localize LSTRING(TabOptions))]; - ctrlSetText [13, _localizedHeader]; - lbClear 400; - - (_settingsMenu displayCtrl 301) ctrlShow true; - - (_settingsMenu displayCtrl 400) ctrlShow true; - (_settingsMenu displayCtrl 410) ctrlShow false; - (_settingsMenu displayCtrl 411) ctrlShow false; - (_settingsMenu displayCtrl 412) ctrlShow false; - (_settingsMenu displayCtrl 413) ctrlShow false; - (_settingsMenu displayCtrl 414) ctrlShow false; - (_settingsMenu displayCtrl 415) ctrlShow false; - (_settingsMenu displayCtrl 416) ctrlShow false; - (_settingsMenu displayCtrl 416) ctrlEnable false; - }; -case (MENU_TAB_SERVER_COLORS): { - _localizedHeader = format ["%1: %2", (localize LSTRING(OpenConfigMenu)), (localize LSTRING(TabColors))]; - ctrlSetText [13, _localizedHeader]; - - lbClear 400; - - (_settingsMenu displayCtrl 301) ctrlShow false; - - (_settingsMenu displayCtrl 400) ctrlShow false; - (_settingsMenu displayCtrl 410) ctrlShow true; - (_settingsMenu displayCtrl 411) ctrlShow true; - (_settingsMenu displayCtrl 412) ctrlShow true; - (_settingsMenu displayCtrl 413) ctrlShow true; - - (_settingsMenu displayCtrl 410) sliderSetRange [0, 255]; - (_settingsMenu displayCtrl 411) sliderSetRange [0, 255]; - (_settingsMenu displayCtrl 412) sliderSetRange [0, 255]; - (_settingsMenu displayCtrl 413) sliderSetRange [0, 255]; - - (_settingsMenu displayCtrl 414) ctrlShow false; - (_settingsMenu displayCtrl 415) ctrlShow false; - (_settingsMenu displayCtrl 416) ctrlShow false; - (_settingsMenu displayCtrl 416) ctrlEnable false; - }; -case (MENU_TAB_SERVER_VALUES): { - _localizedHeader = format ["%1: %2", (localize LSTRING(OpenConfigMenu)), (localize LSTRING(TabValues))]; - ctrlSetText [13, _localizedHeader]; - - lbClear 400; - (_settingsMenu displayCtrl 301) ctrlShow false; - (_settingsMenu displayCtrl 400) ctrlShow false; - (_settingsMenu displayCtrl 410) ctrlShow false; - (_settingsMenu displayCtrl 411) ctrlShow false; - (_settingsMenu displayCtrl 412) ctrlShow false; - (_settingsMenu displayCtrl 413) ctrlShow false; - - (_settingsMenu displayCtrl 414) ctrlShow true; - (_settingsMenu displayCtrl 415) ctrlShow true; - (_settingsMenu displayCtrl 416) ctrlShow true; - (_settingsMenu displayCtrl 416) ctrlEnable true; - }; -}; - -[true] call FUNC(serverSettingsMenuUpdateList); diff --git a/addons/optionsmenu/functions/fnc_onServerSaveInputField.sqf b/addons/optionsmenu/functions/fnc_onServerSaveInputField.sqf deleted file mode 100644 index fde370426f..0000000000 --- a/addons/optionsmenu/functions/fnc_onServerSaveInputField.sqf +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Author: Glowbal - * Called when the listbox selection is changed for an options (eg: chaning a setting from false to true) - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_onListBoxSettingsChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingIndex", "_inputText", "_setting", "_settingName", "_convertedValue"]; - -_inputText = ctrlText 414; //Index of right drop down - -_settingIndex = -1; -if (((lnbCurSelRow 200) >= 0) && {(lnbCurSelRow 200) < ((lnbSize 200) select 0)}) then { - _settingIndex = lnbValue [200, [(lnbCurSelRow 200), 0]]; -}; - -switch (GVAR(optionMenu_openTab)) do { - case (MENU_TAB_SERVER_VALUES): { - if ((_settingIndex >= 0) && (_settingIndex < (count GVAR(serverSideValues)))) then { - try { - _setting = (GVAR(serverSideValues) select _settingIndex); - _settingName = _setting select 0; - - _convertedValue = switch (toUpper (_setting select 1)) do { - case "STRING": { - ctrlSetText [414, _inputText call FUNC(stringEscape)]; - format ['%1', _inputText call FUNC(stringEscape)]; - }; - case "ARRAY": {format [call compile "[%1]", _inputText]}; - case "SCALAR": {parseNumber _inputText;}; - default {throw "Error"}; - }; - [MENU_TAB_SERVER_VALUES, _settingName, _convertedValue] call FUNC(updateSetting); - } catch { - }; - }; - [false] call FUNC(serverSettingsMenuUpdateList); - }; -}; diff --git a/addons/optionsmenu/functions/fnc_onServerSettingsMenuOpen.sqf b/addons/optionsmenu/functions/fnc_onServerSettingsMenuOpen.sqf deleted file mode 100644 index 6a9e5c9fb8..0000000000 --- a/addons/optionsmenu/functions/fnc_onServerSettingsMenuOpen.sqf +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Author: Glowbal - * Called from the onLoad of ACE_settingsMenu dialog. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [onLoadEvent] call ACE_optionsmenu_fnc_onSettingsMenuOpen - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_setting", "_settingsMenu"]; - -if (GVAR(serverConfigGeneration) == 0 || isMultiplayer) exitWith {closeDialog 145246;}; - -// Filter only user setable setting -GVAR(serverSideOptions) = []; -GVAR(serverSideColors) = []; -GVAR(serverSideValues) = []; -{ - _x params ["_name", "_typeName", "_isClientSetable", "_localizedName", "_localizedDescription", "_possibleValues", "_defaultValue"]; - - // Exclude client side options if they are not included for the export - if (!(_isClientSetable) || GVAR(ClientSettingsExportIncluded)) then { - // Append the current value to the setting metadata - _setting = + _x; - _setting pushBack (missionNamespace getVariable (_x select 0)); - - // Categorize the setting according to types - // @todo: allow the user to modify other types of parameters? - if ((_typeName == "SCALAR" && count _possibleValues > 0) || (_x select 1) == "BOOL") then { - GVAR(serverSideOptions) pushBack _setting; - }; - if (_typeName == "COLOR") then { - GVAR(serverSideColors) pushBack _setting; - }; - if ((_typeName == "SCALAR" && count _possibleValues == 0) || _typeName == "ARRAY" || _typeName == "STRING") then { - GVAR(serverSideValues) pushBack _setting; - }; - }; -} forEach EGVAR(common,settings); - -//Delay a frame -[{ [MENU_TAB_SERVER_OPTIONS] call FUNC(onServerListBoxShowSelectionChanged) }, []] call CBA_fnc_execNextFrame; - -disableSerialization; -private _menu = uiNamespace getVariable "ACE_serverSettingsMenu"; -(_menu displayCtrl 1003) ctrlEnable false; - -if (GVAR(ClientSettingsExportIncluded)) then { - (_settingsMenu displayCtrl 1102) ctrlSetText localize (LSTRING(exClientSettings)); -} else { - (_settingsMenu displayCtrl 1102) ctrlSetText localize (LSTRING(inClientSettings)); -}; - - -lbClear (_menu displayCtrl 14); -{ - if (_x == "") then { - _x = localize (LSTRING(category_all)); - }; - (_menu displayCtrl 14) lbAdd _x; -} forEach GVAR(categories); - -(_menu displayCtrl 14) lbSetCurSel GVAR(currentCategorySelection); //All Catagoies diff --git a/addons/optionsmenu/functions/fnc_onSettingsMenuOpen.sqf b/addons/optionsmenu/functions/fnc_onSettingsMenuOpen.sqf deleted file mode 100644 index 42157f230f..0000000000 --- a/addons/optionsmenu/functions/fnc_onSettingsMenuOpen.sqf +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Author: Glowbal - * Called from the onLoad of ACE_settingsMenu dialog. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [onLoadEvent] call ACE_optionsmenu_fnc_onSettingsMenuOpen - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_setting", "_menu"]; - -// Filter only user setable setting -GVAR(clientSideOptions) = []; -GVAR(clientSideColors) = []; -private _clientSettableCategories = [""]; - -{ - // If the setting is user setable and not forced - if ((_x select 2) && !(_x select 6)) then { - // Append the current value to the setting metadata - _setting = + _x; - _setting pushBack (missionNamespace getVariable (_x select 0)); - - // Categorize the setting according to types - // @todo: allow the user to modify other types of parameters? - if ((_x select 1) == "SCALAR" || (_x select 1) == "BOOL") then { - GVAR(clientSideOptions) pushBack _setting; - }; - if ((_x select 1) == "COLOR") then { - GVAR(clientSideColors) pushBack _setting; - }; - _clientSettableCategories pushBackUnique (_x select 8); //Add to list of user-settable categories - }; -} forEach EGVAR(common,settings); - -//Delay a frame -[{ [MENU_TAB_OPTIONS] call FUNC(onListBoxShowSelectionChanged) }, []] call CBA_fnc_execNextFrame; - -disableSerialization; -_menu = uiNamespace getVariable "ACE_settingsMenu"; -(_menu displayCtrl 1002) ctrlEnable false; -(_menu displayCtrl 1003) ctrlEnable false; - -if (GVAR(serverConfigGeneration) == 0) then { - (_menu displayCtrl 1102) ctrlEnable false; - (_menu displayCtrl 1102) ctrlShow false; -}; - -lbClear (_menu displayCtrl 14); -{ - if (_x in _clientSettableCategories) then { //only show category if it has user-settable options - if (_x == "") then { - _x = localize LSTRING(category_all); - }; - private _Index = (_menu displayCtrl 14) lbAdd _x; - (_menu displayCtrl 14) lbSetValue [_Index, _forEachIndex]; - }; -} forEach GVAR(categories); - -(_menu displayCtrl 14) lbSetCurSel GVAR(currentCategorySelection); //All Catagoies - - diff --git a/addons/optionsmenu/functions/fnc_onSliderPosChanged.sqf b/addons/optionsmenu/functions/fnc_onSliderPosChanged.sqf deleted file mode 100644 index 7df198cc5f..0000000000 --- a/addons/optionsmenu/functions/fnc_onSliderPosChanged.sqf +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Author: PabstMirror - * Called when one of the color sliders is moved. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_onSliderPosChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_newColor", "_settingIndex"]; - -_settingIndex = -1; -if (((lnbCurSelRow 200) >= 0) && {(lnbCurSelRow 200) < ((lnbSize 200) select 0)}) then { - _settingIndex = lnbValue [200, [(lnbCurSelRow 200), 0]]; -}; -if (_settingIndex == -1) exitWith {}; - -switch (GVAR(optionMenu_openTab)) do { - case (MENU_TAB_COLORS): { - - _newColor = []; - { - _newColor pushBack ((sliderPosition _x) / 255); - } forEach [410, 411, 412, 413]; - - if ((_settingIndex >= 0) && (_settingIndex < (count GVAR(clientSideColors)))) then { - _settingIndex = (GVAR(clientSideColors) select _settingIndex) select 0; - [MENU_TAB_COLORS, _settingIndex, _newColor] call FUNC(updateSetting); - }; - [false] call FUNC(settingsMenuUpdateList); - }; - case (MENU_TAB_SERVER_COLORS): { - - _newColor = []; - { - _newColor pushBack ((sliderPosition _x) / 255); - } forEach [410, 411, 412, 413]; - - if ((_settingIndex >= 0) && (_settingIndex < (count GVAR(clientSideColors)))) then { - _settingIndex = (GVAR(clientSideColors) select _settingIndex) select 0; - [MENU_TAB_SERVER_COLORS, _settingIndex, _newColor] call FUNC(updateSetting); - }; - [false] call FUNC(serverSettingsMenuUpdateList); - }; - default {}; -}; diff --git a/addons/optionsmenu/functions/fnc_resetSettings.sqf b/addons/optionsmenu/functions/fnc_resetSettings.sqf deleted file mode 100644 index 8d6c3958c6..0000000000 --- a/addons/optionsmenu/functions/fnc_resetSettings.sqf +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Author: Glowbal - * Resets all settings to default. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_onListBoxSettingsChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_name", "_default", "_lastSelected"]; - -{ - _name = _x select 0; - _default = _x select 7; - [MENU_TAB_OPTIONS, _name, _default] call FUNC(updateSetting); -} forEach GVAR(clientSideOptions); - -{ - _name = _x select 0; - _default = _x select 7; - [MENU_TAB_COLORS, _name, _default] call FUNC(updateSetting); -} forEach GVAR(clientSideColors); - -_lastSelected = lnbCurSelRow 200; -[GVAR(optionMenu_openTab)] call FUNC(onListBoxShowSelectionChanged); -if (_lastSelected != -1) then { - lnbSetCurSelRow [200, _lastSelected]; -}; diff --git a/addons/optionsmenu/functions/fnc_serverResetSettings.sqf b/addons/optionsmenu/functions/fnc_serverResetSettings.sqf deleted file mode 100644 index d9f6a4ad96..0000000000 --- a/addons/optionsmenu/functions/fnc_serverResetSettings.sqf +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Author: Glowbal - * Resets all server settings to default. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_onListBoxSettingsChanged - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_name", "_default", "_lastSelected"]; - -{ - _name = _x select 0; - _default = _x select 7; - [MENU_TAB_SERVER_OPTIONS, _name, _default] call FUNC(updateSetting); -} forEach GVAR(serverSideOptions); - -{ - _name = _x select 0; - _default = _x select 7; - [MENU_TAB_SERVER_COLORS, _name, _default] call FUNC(updateSetting); -} forEach GVAR(serverSideColors); - -{ - _name = _x select 0; - _default = _x select 7; - [MENU_TAB_SERVER_VALUES, _name, _default] call FUNC(updateSetting); -} forEach GVAR(serverSideVakyes); - -_lastSelected = lnbCurSelRow 200; -[GVAR(optionMenu_openTab)] call FUNC(onserverListBoxShowSelectionChanged); -if (_lastSelected != -1) then { - lbSetCurSel [200, _lastSelected]; -}; diff --git a/addons/optionsmenu/functions/fnc_serverSettingsMenuUpdateKeyView.sqf b/addons/optionsmenu/functions/fnc_serverSettingsMenuUpdateKeyView.sqf deleted file mode 100644 index dfffbca6a6..0000000000 --- a/addons/optionsmenu/functions/fnc_serverSettingsMenuUpdateKeyView.sqf +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Author: Glowbal - * Updates the right half of the option menu for the currently selected option. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_settingsMenuUpdateKeyView - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingsMenu", "_collection", "_settingIndex", "_setting", "_entryName", "_localizedName", "_localizedDescription", "_possibleValues", "_settingsValue", "_currentColor", "_expectedType"]; -disableSerialization; - -_settingsMenu = uiNamespace getVariable 'ACE_serverSettingsMenu'; - -_collection = switch (GVAR(optionMenu_openTab)) do { - case MENU_TAB_SERVER_OPTIONS: {GVAR(serverSideOptions)}; - case MENU_TAB_SERVER_COLORS: {GVAR(serverSideColors)}; - case MENU_TAB_SERVER_VALUES: {GVAR(serverSideValues)}; - default {[]}; -}; - -_settingIndex = -1; -if (((lnbCurSelRow 200) >= 0) && {(lnbCurSelRow 200) < ((lnbSize 200) select 0)}) then { - _settingIndex = lnbValue [200, [(lnbCurSelRow 200), 0]]; -}; - -if ((_settingIndex >= 0) && {_settingIndex <= (count _collection)}) then { - _setting = _collection select _settingIndex; - - _entryName = _setting select 0; - _localizedName = _setting select 3; - _localizedDescription = _setting select 4; - - if (_localizedName == "") then {_localizedName = _entryName;}; - (_settingsMenu displayCtrl 250) ctrlSetText _localizedName; - (_settingsMenu displayCtrl 251) ctrlSetText _localizedDescription; - (_settingsMenu displayCtrl 300) ctrlSetText _entryName; - - switch (GVAR(optionMenu_openTab)) do { - case (MENU_TAB_SERVER_OPTIONS): { - _possibleValues = _setting select 5; - _settingsValue = _setting select 9; - // Created disable/enable options for bools - if ((_setting select 1) == "BOOL") then { - lbClear 400; - lbAdd [400, (localize ELSTRING(common,No))]; - lbAdd [400, (localize ELSTRING(common,Yes))]; - _settingsValue = [0, 1] select _settingsValue; - } else { - lbClear 400; - { lbAdd [400, _x]; } forEach _possibleValues; - }; - (_settingsMenu displayCtrl 400) lbSetCurSel _settingsValue; - }; - case (MENU_TAB_SERVER_COLORS): { - _currentColor = _setting select 9; - { - sliderSetPosition [_x, (255 * (_currentColor select _forEachIndex))]; - } forEach [410, 411, 412, 413]; - }; - case (MENU_TAB_SERVER_VALUES): { - // TODO implement - _settingsValue = _setting select 9; - - // Created disable/enable options for bools - _expectedType = switch (_setting select 1) do { - case "STRING": {LSTRING(stringType)}; - case "ARRAY": {LSTRING(arrayType)}; - case "SCALAR": {LSTRING(scalarType)}; - default {LSTRING(unknownType)}; - }; - (_settingsMenu displayCtrl 414) ctrlSetText format["%1", _settingsValue]; - (_settingsMenu displayCtrl 415) ctrlSetText format[localize _expectedType]; - }; - }; -} else { //no settings in list: - lbClear 400; - (_settingsMenu displayCtrl 250) ctrlSetText "No settings available"; - (_settingsMenu displayCtrl 251) ctrlSetText "No settings available"; - (_settingsMenu displayCtrl 300) ctrlSetText "No settings available"; -}; diff --git a/addons/optionsmenu/functions/fnc_serverSettingsMenuUpdateList.sqf b/addons/optionsmenu/functions/fnc_serverSettingsMenuUpdateList.sqf deleted file mode 100644 index 9718da3988..0000000000 --- a/addons/optionsmenu/functions/fnc_serverSettingsMenuUpdateList.sqf +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Author: Glowbal - * Updates the setting when the client has selected a new value. Saves to profilenamespace. - * - * Arguments: - * 0: Update the keylist as well - * - * Return Value: - * None - * - * Example: - * [false] call ACE_optionsmenu_fnc_settingsMenuUpdateList - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingName", "_added", "_settingsMenu", "_ctrlList", "_settingsText", "_color", "_settingsColor", "_updateKeyView", "_settingsValue", "_selectedCategory"]; -DEFAULT_PARAM(0,_updateKeyView,true); - -disableSerialization; -_settingsMenu = uiNamespace getVariable 'ACE_serverSettingsMenu'; -_ctrlList = _settingsMenu displayCtrl 200; - -lnbClear _ctrlList; - -_selectedCategory = GVAR(categories) select GVAR(currentCategorySelection); - -_added = 0; -switch (GVAR(optionMenu_openTab)) do { - case (MENU_TAB_SERVER_OPTIONS): { - { - if (_selectedCategory == "" || {_selectedCategory == (_x select 8)}) then { - _settingName = if ((_x select 3) != "") then { - (_x select 3); - } else { - (_x select 0); - }; - - _settingsValue = _x select 9; - - // Created disable/enable options for bools - _settingsText = if ((_x select 1) == "BOOL") then { - [(localize ELSTRING(common,No)), (localize ELSTRING(common,Yes))] select _settingsValue; - } else { - (_x select 5) select _settingsValue; - }; - - _added = _ctrlList lnbAddRow [_settingName, _settingsText]; - _ctrlList lnbSetValue [[_added, 0], _forEachIndex]; - }; - }forEach GVAR(serverSideOptions); - }; - case (MENU_TAB_SERVER_COLORS): { - { - if (_selectedCategory == "" || {_selectedCategory == (_x select 8)}) then { - _color = +(_x select 9); - { - _color set [_forEachIndex, ((round (_x * 100))/100)]; - } forEach _color; - _settingsColor = str _color; - _settingName = if ((_x select 3) != "") then { - (_x select 3); - } else { - (_x select 0); - }; - - _added = _ctrlList lnbAddRow [_settingName, _settingsColor]; - _ctrlList lnbSetColor [[_added, 1], (_x select 9)]; - _ctrlList lnbSetValue [[_added, 0], _forEachIndex]; - }; - }forEach GVAR(serverSideColors); - }; - case (MENU_TAB_SERVER_VALUES): { - { - if (_selectedCategory == "" || {_selectedCategory == (_x select 8)}) then { - _settingName = if ((_x select 3) != "") then { - (_x select 3); - } else { - (_x select 0); - }; - _settingsValue = _x select 9; - if (!(_settingsValue isEqualType "")) then { - _settingsValue = format["%1", _settingsValue]; - }; - _added = _ctrlList lnbAddRow [_settingName, _settingsValue]; - _ctrlList lnbSetValue [[_added, 0], _forEachIndex]; - }; - }forEach GVAR(serverSideValues); - }; -}; -if (_updateKeyView) then { - [] call FUNC(serverSettingsMenuUpdateKeyView); -}; diff --git a/addons/optionsmenu/functions/fnc_settingsMenuUpdateKeyView.sqf b/addons/optionsmenu/functions/fnc_settingsMenuUpdateKeyView.sqf deleted file mode 100644 index defef99395..0000000000 --- a/addons/optionsmenu/functions/fnc_settingsMenuUpdateKeyView.sqf +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Author: Glowbal - * Updates the right half of the option menu for the currently selected option. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ACE_optionsmenu_fnc_settingsMenuUpdateKeyView - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingsMenu", "_ctrlList", "_collection", "_settingIndex", "_setting", "_entryName", "_localizedName", "_localizedDescription", "_possibleValues", "_settingsValue", "_currentColor"]; -disableSerialization; - -_settingsMenu = uiNamespace getVariable 'ACE_settingsMenu'; -_ctrlList = _settingsMenu displayCtrl 200; - -_collection = switch (GVAR(optionMenu_openTab)) do { - case MENU_TAB_OPTIONS: {GVAR(clientSideOptions)}; - case MENU_TAB_COLORS: {GVAR(clientSideColors)}; - default {[]}; -}; - -_settingIndex = -1; -if (((lnbCurSelRow 200) >= 0) && {(lnbCurSelRow 200) < ((lnbSize 200) select 0)}) then { - _settingIndex = lnbValue [200, [(lnbCurSelRow 200), 0]]; -}; - -if ((_settingIndex >= 0) && {_settingIndex <= (count _collection)}) then { - _setting = _collection select _settingIndex; - - _entryName = _setting select 0; - _localizedName = _setting select 3; - _localizedDescription = _setting select 4; - - if (_localizedName == "") then {_localizedName = _entryName;}; - (_settingsMenu displayCtrl 250) ctrlSetText _localizedName; - (_settingsMenu displayCtrl 251) ctrlSetText _localizedDescription; - (_settingsMenu displayCtrl 300) ctrlSetText _entryName; - - switch (GVAR(optionMenu_openTab)) do { - case (MENU_TAB_OPTIONS): { - _possibleValues = _setting select 5; - _settingsValue = _setting select 9; - - // Created disable/enable options for bools - if ((_setting select 1) == "BOOL") then { - lbClear 400; - lbAdd [400, (localize ELSTRING(common,No))]; - lbAdd [400, (localize ELSTRING(common,Yes))]; - _settingsValue = [0, 1] select _settingsValue; - } else { - lbClear 400; - { lbAdd [400, _x]; } forEach _possibleValues; - }; - (_settingsMenu displayCtrl 400) lbSetCurSel _settingsValue; - }; - case (MENU_TAB_COLORS): { - _currentColor = _setting select 9; - { - sliderSetPosition [_x, (255 * (_currentColor select _forEachIndex))]; - } forEach [410, 411, 412, 413]; - }; - }; -} else { //no settings in list: - lbClear 400; - (_settingsMenu displayCtrl 250) ctrlSetText "No settings available"; - (_settingsMenu displayCtrl 251) ctrlSetText "No settings available"; - (_settingsMenu displayCtrl 300) ctrlSetText "No settings available"; -}; diff --git a/addons/optionsmenu/functions/fnc_settingsMenuUpdateList.sqf b/addons/optionsmenu/functions/fnc_settingsMenuUpdateList.sqf deleted file mode 100644 index ed64ebde69..0000000000 --- a/addons/optionsmenu/functions/fnc_settingsMenuUpdateList.sqf +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Author: Glowbal - * Updates the setting when the client has selected a new value. Saves to profilenamespace. - * - * Arguments: - * 0: Update the keylist as well - * - * Return Value: - * None - * - * Example: - * [false] call ACE_optionsmenu_fnc_settingsMenuUpdateList - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_settingName", "_added", "_settingsMenu", "_ctrlList", "_settingsText", "_color", "_settingsColor", "_updateKeyView", "_settingsValue", "_selectedCategory"]; -DEFAULT_PARAM(0,_updateKeyView,true); - -disableSerialization; -_settingsMenu = uiNamespace getVariable 'ACE_settingsMenu'; -_ctrlList = _settingsMenu displayCtrl 200; - -lnbClear _ctrlList; - -_selectedCategory = GVAR(categories) select GVAR(currentCategorySelection); - -switch (GVAR(optionMenu_openTab)) do { - case (MENU_TAB_OPTIONS): { - { - if (_selectedCategory == "" || {_selectedCategory == (_x select 8)}) then { - _settingName = (_x select 3); - _settingsValue = _x select 9; - - // Created disable/enable options for bools - _settingsText = if ((_x select 1) == "BOOL") then { - [(localize ELSTRING(common,No)), (localize ELSTRING(common,Yes))] select _settingsValue; - } else { - private _values = _x select 5; - if !((!isNil "_values") && {_values isEqualType []} && {_settingsValue >= 0} && {_settingsValue < (count _values)}) exitWith { - ERROR_3("Setting (%1) has bad values (%2) for index (%3)", _settingName, _values, _settingsValue); - "ERROR" - }; - _values select _settingsValue; - }; - _added = _ctrlList lnbAddRow [_settingName, _settingsText]; - _ctrlList lnbSetValue [[_added, 0], _forEachIndex]; - }; - } forEach GVAR(clientSideOptions); - }; - case (MENU_TAB_COLORS): { - { - if (_selectedCategory == "" || {_selectedCategory == (_x select 8)}) then { - _color = +(_x select 9); - { - _color set [_forEachIndex, ((round (_x * 100))/100)]; - } forEach _color; - _settingsColor = str _color; - _settingName = (_x select 3); - - _added = _ctrlList lnbAddRow [_settingName, _settingsColor]; - _ctrlList lnbSetColor [[_added, 1], (_x select 9)]; - _ctrlList lnbSetValue [[_added, 0], _forEachIndex]; - }; - }forEach GVAR(clientSideColors); - }; -}; -if (_updateKeyView) then { - [] call FUNC(settingsMenuUpdateKeyView); -}; diff --git a/addons/optionsmenu/functions/fnc_stringEscape.sqf b/addons/optionsmenu/functions/fnc_stringEscape.sqf deleted file mode 100644 index 09e1357a31..0000000000 --- a/addons/optionsmenu/functions/fnc_stringEscape.sqf +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Author: Glowbal - * Parse the string for quotation marks, so it can be used for config export. - * - * Arguments: - * 0: string - * - * Return Value: - * parsed string - * - * Example: - * [] call ACE_optionsmenu_fnc_stringEscape - * - * Public: No - */ - -private ["_str", "_array", "_maxIndex", "_isEven"]; -_str = _this; - -_isEven = { - params ["_array", "_index"]; - private [ "_count"]; - _count = 0; - { - if (_forEachIndex <= _index && {_x == 39}) then { - _count = _count + 1; - }; - }forEach _array; - - _count %2 == 0; -}; - -// reg: 34 -// single: 39 -_array = toArray _str; -{ - if (_x == 34) then { - _array set [_forEachIndex, 39]; - }; -}forEach _array; - -_maxIndex = count _array; -for "_i" from 0 to _maxIndex /* step +1 */ do { - if (((_i + 1) < _maxIndex - 1) && {_array select _i == 39 && (_array select (_i + 1)) == 39}) then { - if ([_array, _i] call _isEven) then { - _array deleteAt _i; - _i = _i - 1; - _maxIndex = _maxIndex - 1; - }; - }; -}; - -{ - if (_x == 34) then { - _array set [_forEachIndex, 39]; - }; -}forEach _array; - -toString _array; diff --git a/addons/optionsmenu/functions/fnc_toggleIncludeClientSettings.sqf b/addons/optionsmenu/functions/fnc_toggleIncludeClientSettings.sqf deleted file mode 100644 index 2256620cf6..0000000000 --- a/addons/optionsmenu/functions/fnc_toggleIncludeClientSettings.sqf +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Author: Glowbal - * - * - * Arguments: - * none - * - * Return Value: - * None - * - * Example: - * call ace_optionsmenu_fnc_toggleIncludeClientSettings - * - * Public: No - */ - -#include "script_component.hpp" - -GVAR(ClientSettingsExportIncluded) = !(GVAR(ClientSettingsExportIncluded)); - -[] call FUNC(onServerSettingsMenuOpen); diff --git a/addons/optionsmenu/functions/fnc_updateSetting.sqf b/addons/optionsmenu/functions/fnc_updateSetting.sqf deleted file mode 100644 index 7374d1f2c1..0000000000 --- a/addons/optionsmenu/functions/fnc_updateSetting.sqf +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Author: Glowbal - * Updates the setting when the client has selected a new value. Saves to profilenamespace and calls setSetting. - * - * Arguments: - * 0: The Tab Open - * 1: The setting's name - * 2: The new value either an index or a color OR - * - * Return Value: - * None - * - * Example: - * [MENU_TAB_COLORS, "ace_fireTruckColor", [1,0,0,1]] call ACE_optionsmenu_fnc_updateSetting - * - * Public: No - */ - -#include "script_component.hpp" - -private ["_changed"]; -PARAMS_3(_type,_name,_newValue); - -_changed = false; - -switch (_type) do { - case (MENU_TAB_OPTIONS): { - { - if ((_x select 0) == _name) then { - - if ((_x select 1) == "BOOL") then { - _newValue = [false, true] select _newValue; - }; - - if !((_x select 9) isEqualTo _newValue) then { - _changed = true; - _x set [9, _newValue]; - } ; - - }; - } forEach GVAR(clientSideOptions); - }; - case (MENU_TAB_COLORS): { - { - if (((_x select 0) == _name) && {!((_x select 9) isEqualTo _newValue)}) then { - _changed = true; - _x set [9, _newValue]; - }; - } forEach GVAR(clientSideColors); - }; - case (MENU_TAB_SERVER_OPTIONS): { - { - if ((_x select 0) == _name) then { - - if ((_x select 1) == "BOOL") then { - _newValue = [false, true] select _newValue; - }; - - if !((_x select 9) isEqualTo _newValue) then { - _changed = true; - _x set [9, _newValue]; - } ; - - }; - } forEach GVAR(serverSideOptions); - }; - case (MENU_TAB_SERVER_COLORS): { - { - if (((_x select 0) == _name) && {!((_x select 9) isEqualTo _newValue)}) then { - _changed = true; - _x set [9, _newValue]; - }; - } forEach GVAR(serverSideColors); - }; - case (MENU_TAB_SERVER_VALUES): { - { - if (((_x select 0) == _name) && {!((_x select 9) isEqualTo _newValue)}) then { - _changed = true; - _x set [9, _newValue]; - }; - } forEach GVAR(serverSideValues); - }; -}; - -if (_changed) then { - if (GVAR(serverConfigGeneration) > 0) then { - if !(isMultiplayer) then { - missionNamespace setVariable [_name, _newValue]; - }; - } else { - profileNamespace setVariable [_name, _newValue]; - [_name, _newValue] call EFUNC(common,setSetting); - }; -}; diff --git a/addons/optionsmenu/gui/define.hpp b/addons/optionsmenu/gui/define.hpp deleted file mode 100644 index 9620bdd7e6..0000000000 --- a/addons/optionsmenu/gui/define.hpp +++ /dev/null @@ -1,101 +0,0 @@ -// define.hpp - -class ACE_gui_backgroundBase; -class ACE_gui_editBase; -class ACE_gui_buttonBase; -class ACE_gui_staticBase; -class ACE_gui_listNBox; -class ACE_gui_comboBoxBase; -class RscXSliderH; -class RscControlsGroupNoScrollbars; -class RscHTML; -class RscText; - - -class RscControlsGroupNoHScrollbars; -class RscPicture; -class RscButtonMenu; - - -#ifndef ACE_DEFINE_H -#define ACE_DEFINE_H - -#define true 1 -#define false 0 - -#define CT_STATIC 0 -#define CT_BUTTON 1 -#define CT_EDIT 2 -#define CT_SLIDER 3 -#define CT_COMBO 4 -#define CT_LISTBOX 5 -#define CT_TOOLBOX 6 -#define CT_CHECKBOXES 7 -#define CT_PROGRESS 8 -#define CT_HTML 9 -#define CT_STATIC_SKEW 10 -#define CT_ACTIVETEXT 11 -#define CT_TREE 12 -#define CT_STRUCTURED_TEXT 13 -#define CT_CONTEXT_MENU 14 -#define CT_CONTROLS_GROUP 15 -#define CT_SHORTCUTBUTTON 16 -#define CT_XKEYDESC 40 -#define CT_XBUTTON 41 -#define CT_XLISTBOX 42 -#define CT_XSLIDER 43 -#define CT_XCOMBO 44 -#define CT_ANIMATED_TEXTURE 45 -#define CT_OBJECT 80 -#define CT_OBJECT_ZOOM 81 -#define CT_OBJECT_CONTAINER 82 -#define CT_OBJECT_CONT_ANIM 83 -#define CT_LINEBREAK 98 -#define CT_ANIMATED_USER 99 -#define CT_MAP 100 -#define CT_MAP_MAIN 101 -#define CT_LISTNBOX 102 - -// Static styles -#define ST_POS 0x0F -#define ST_HPOS 0x03 -#define ST_VPOS 0x0C -#define ST_LEFT 0x00 -#define ST_RIGHT 0x01 -#define ST_CENTER 0x02 -#define ST_DOWN 0x04 -#define ST_UP 0x08 -#define ST_VCENTER 0x0c - -#define ST_TYPE 0xF0 -#define ST_SINGLE 0 -#define ST_MULTI 16 -#define ST_TITLE_BAR 32 -#define ST_PICTURE 48 -#define ST_FRAME 64 -#define ST_BACKGROUND 80 -#define ST_GROUP_BOX 96 -#define ST_GROUP_BOX2 112 -#define ST_HUD_BACKGROUND 128 -#define ST_TILE_PICTURE 144 -#define ST_WITH_RECT 160 -#define ST_LINE 176 - -#define ST_SHADOW 0x100 -#define ST_NO_RECT 0x200 // this style works for CT_STATIC in conjunction with ST_MULTI -#define ST_KEEP_ASPECT_RATIO 0x800 - -#define ST_TITLE ST_TITLE_BAR + ST_CENTER - -// Slider styles -#define SL_DIR 0x400 -#define SL_VERT 0 -#define SL_HORZ 0x400 - -#define SL_TEXTURES 0x10 - -// Listbox styles -#define LB_TEXTURES 0x10 -#define LB_MULTI 0x20 - -#endif diff --git a/addons/optionsmenu/gui/mainMenu.hpp b/addons/optionsmenu/gui/mainMenu.hpp new file mode 100644 index 0000000000..0b26df7017 --- /dev/null +++ b/addons/optionsmenu/gui/mainMenu.hpp @@ -0,0 +1,77 @@ +class RscControlsGroupNoHScrollbars; +class RscHTML; +class RscText; + +class RscStandardDisplay; +class RscDisplayMain: RscStandardDisplay { + class controls { + class InfoMods: RscControlsGroupNoHScrollbars { + class Controls; + }; + + class InfoNews: InfoMods { + class Controls: Controls { + class Background; + class BackgroundIcon; + class Icon; + class News; + class Notification; + class Button; + }; + }; + + class ACE_news_apex: InfoNews { + idc = IDC_MAIN_INFO; + y = "safezoneY + safezoneH - (3 * 2 + 1) * (pixelH * pixelGrid * 2) - 4 * (4 * pixelH)"; + + class Controls: Controls { + class Background: Background {}; + class BackgroundIcon: BackgroundIcon {}; + class Icon: Icon { + text = QPATHTOF(gui\aceMenuIcon_ca.paa); + }; + class CurrentVersionInfo: RscText { + idc = IDC_MAIN_INFO_CURRENT_VERSION_INFO; + style = 1; + text = ""; + sizeEx = "(pixelH * pixelGrid * 1.5)"; + font = "RobotoCondensedLight"; + shadow = 1; + colorBackground[] = {0,0,0,0}; + x = 0; + y = 0; + w = "(10 - 1.25 * 2) * (pixelW * pixelGrid * 2)"; + h = "1 * (pixelH * pixelGrid * 2)"; + onLoad = "(_this select 0) ctrlenable false;"; + }; + class HTTPVersionInfo: RscHTML { + idc = IDC_MAIN_INFO_NEWEST_VERSION_INFO; + shadow = 0; + + class H1 { + sizeEx = "(pixelH * pixelGrid * 1.5)"; + font = "RobotoCondensedLight"; + fontBold = "RobotoCondensedLight"; + align = "right"; + }; + class H2: H1 { + sizeEx = "(pixelH * pixelGrid * 1.5)"; + }; + class P: H1 { + sizeEx = "(pixelH * pixelGrid * 1.5)"; + }; + + x = 0; + y = "1 * (pixelH * pixelGrid * 2)"; + w = "(10 - 1.25 * 2) * (pixelW * pixelGrid * 2)"; + h = "1 * (pixelH * pixelGrid * 2)"; + onLoad = "(_this select 0) ctrlenable false;"; + }; + class Button: Button { + tooltip = "Download latest and report issues:"; + url = "https://github.com/acemod/ACE3/releases"; + }; + }; + }; + }; +}; diff --git a/addons/optionsmenu/gui/pauseMenu.hpp b/addons/optionsmenu/gui/pauseMenu.hpp index 304cd7e8d1..f48cecfd0f 100644 --- a/addons/optionsmenu/gui/pauseMenu.hpp +++ b/addons/optionsmenu/gui/pauseMenu.hpp @@ -1,179 +1,13 @@ - -class ACE_Open_SettingsMenu_BtnBase : ACE_gui_buttonBase { - class Attributes { - font = "RobotoCondensed"; - color = "#E5E5E5"; - align = "left"; - shadow = "true"; - }; - class AttributesImage { - font = "RobotoCondensed"; - color = "#E5E5E5"; - align = "left"; - }; - class HitZone { - left = 0.0; - top = 0.0; - right = 0.0; - bottom = 0.0; - }; - class ShortcutPos { - left = 0; - top = 0; - w = 0; - h = 0; - }; - class TextPos { - left = 0.01; - top = 0; - right = 0; - bottom = 0; - }; - animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureDisabled = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureNormal = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; - animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; - color2[] = {0,0,0,1}; - color[] = {1,1,1,1}; - //colorBackground2[] = {0.75,0.75,0.75,1}; - //colorBackground[] = {0,0,0,0.8}; - colorBackground[] = {1, 0.647, 0, 0.5}; - colorBackground2[] = {1, 0.647, 0, 0.5}; - colorBackgroundFocused[] = {1, 1, 1, 0}; - colorDisabled[] = {1,1,1,0.25}; - colorFocused[] = {0,0,0,1}; - colorText[] = {1,1,1,1}; - //default = 0; - font = "RobotoCondensed"; - idc = -1; - period = 1.2; - periodFocus = 1.2; - periodOver = 1.2; - shadow = 0; - shortcuts[] = {}; - size = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; - sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; - soundClick[] = {"\A3\ui_f\data\sound\RscButtonMenu\soundClick",0.09,1}; - soundEnter[] = {"\A3\ui_f\data\sound\RscButtonMenu\soundEnter",0.09,1}; - soundEscape[] = {"\A3\ui_f\data\sound\RscButtonMenu\soundEscape",0.09,1}; - soundPush[] = {"\A3\ui_f\data\sound\RscButtonMenu\soundPush",0.09,1}; - style = "0x02 + 0xC0"; - text = CSTRING(OpenConfigMenu); - textureNoShortcut = "#(argb,8,8,3)color(0,0,0,0)"; - tooltip = ""; - tooltipColorBox[] = {1,1,1,1}; - tooltipColorShade[] = {0,0,0,0.65}; - tooltipColorText[] = {1,1,1,1}; - type = 16; - x = "1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX)"; - y = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + safezoneY"; - w = "15 * (((safezoneW / safezoneH) min 1.2) / 40)"; - h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - action = "(findDisplay 49) closeDisplay 0; createDialog 'ACE_settingsMenu';"; +class RscDisplayEmpty; +class GVAR(MainMenuHelperDumpDebug): RscDisplayEmpty { + onLoad = QUOTE(\ + [] call FUNC(debugDumpToClipboard);\ + (_this select 0) closeDisplay 0;\ + ); }; - -class RscStandardDisplay; -class RscDisplayMPInterrupt: RscStandardDisplay { - class controls { - class ACE_Open_settingsMenu_Btn: ACE_Open_SettingsMenu_BtnBase {}; - }; -}; - -class RscDisplayInterruptEditorPreview: RscStandardDisplay { - class controls { - class ACE_Open_settingsMenu_Btn: ACE_Open_SettingsMenu_BtnBase {}; - }; -}; - -class RscDisplayInterrupt: RscStandardDisplay { - class controls { - class ACE_Open_settingsMenu_Btn: ACE_Open_SettingsMenu_BtnBase {}; - }; -}; - -class RscDisplayInterruptEditor3D: RscStandardDisplay { - class controls { - class ACE_Open_settingsMenu_Btn: ACE_Open_SettingsMenu_BtnBase {}; - }; -}; - -class RscDisplayMovieInterrupt: RscStandardDisplay { - class controls { - class ACE_Open_settingsMenu_Btn: ACE_Open_SettingsMenu_BtnBase {}; - }; -}; - -class RscDisplayMain: RscStandardDisplay { - class controls { - class InfoMods: RscControlsGroupNoHScrollbars { - class Controls; - }; - - class InfoNews: InfoMods { - class Controls: Controls { - class Background; - class BackgroundIcon; - class Icon; - class News; - class Notification; - class Button; - }; - }; - - class ACE_news_apex: InfoNews { - idc = IDC_MAIN_INFO; - y = "safezoneY + safezoneH - (3 * 2 + 1) * (pixelH * pixelGrid * 2) - 4 * (4 * pixelH)"; - - class Controls: Controls { - class Background: Background {}; - class BackgroundIcon: BackgroundIcon {}; - class Icon: Icon { - text = QPATHTOF(gui\aceMenuIcon_ca.paa); - }; - class CurrentVersionInfo: RscText { - idc = IDC_MAIN_INFO_CURRENT_VERSION_INFO; - style = 1; - text = ""; - sizeEx = "(pixelH * pixelGrid * 1.5)"; - font = "RobotoCondensedLight"; - shadow = 1; - colorBackground[] = {0,0,0,0}; - x = 0; - y = 0; - w = "(10 - 1.25 * 2) * (pixelW * pixelGrid * 2)"; - h = "1 * (pixelH * pixelGrid * 2)"; - onLoad = "(_this select 0) ctrlenable false;"; - }; - class HTTPVersionInfo: RscHTML { - idc = IDC_MAIN_INFO_NEWEST_VERSION_INFO; - shadow = 0; - - class H1 { - sizeEx = "(pixelH * pixelGrid * 1.5)"; - font = "RobotoCondensedLight"; - fontBold = "RobotoCondensedLight"; - align = "right"; - }; - class H2: H1 { - sizeEx = "(pixelH * pixelGrid * 1.5)"; - }; - class P: H1 { - sizeEx = "(pixelH * pixelGrid * 1.5)"; - }; - - x = 0; - y = "1 * (pixelH * pixelGrid * 2)"; - w = "(10 - 1.25 * 2) * (pixelW * pixelGrid * 2)"; - h = "1 * (pixelH * pixelGrid * 2)"; - onLoad = "(_this select 0) ctrlenable false;"; - }; - class Button: Button { - tooltip = "Download latest and report issues:"; - url = "https://github.com/acemod/ACE3/releases"; - }; - }; - }; - }; +class GVAR(MainMenuHelperHeadBugFix): RscDisplayEmpty { + onLoad = QUOTE(\ + 0 spawn EFUNC(common,headBugFix);\ + (_this select 0) closeDisplay 0;\ + ); }; diff --git a/addons/optionsmenu/gui/settingsMenu.hpp b/addons/optionsmenu/gui/settingsMenu.hpp deleted file mode 100644 index e9265e59fd..0000000000 --- a/addons/optionsmenu/gui/settingsMenu.hpp +++ /dev/null @@ -1,487 +0,0 @@ -#define SIZEX (((safezoneW / safezoneH) min 1.2)) -#define SIZEY (SIZEX / 1.2) -#define X_ORIGINAL(num) (num * (SIZEX / 40) + (safezoneX + (safezoneW - SIZEX)/2)) -#define Y_ORIGINAL(num) (num * (SIZEY / 25) + (safezoneY + (safezoneH - (SIZEX / 1.2))/2)) -#define W_ORIGINAL(num) (num * (SIZEX / 40)) -#define H_ORIGINAL(num) (num * (SIZEY / 25)) - -#define X_MAKEITBIGGA(num) (num * (safeZoneH / 40) + (safezoneX + (safezoneW - safeZoneH)/2)) -#define Y_MAKEITBIGGA(num) (num * (safeZoneH / 30) + (safezoneY + (safezoneH - (safeZoneH / 1.2))/2)) -#define W_MAKEITBIGGA(num) (num * (safeZoneH / 40)) -#define H_MAKEITBIGGA(num) (num * (safeZoneH / 30)) - -#define X_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(optionMenuDisplaySize)), 0)]), X_ORIGINAL(num), X_MAKEITBIGGA(num))]) -#define Y_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(optionMenuDisplaySize)), 0)]), Y_ORIGINAL(num), Y_MAKEITBIGGA(num))]) -#define W_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(optionMenuDisplaySize)), 0)]), W_ORIGINAL(num), W_MAKEITBIGGA(num))]) -#define H_PART(num) QUOTE(linearConversion [ARR_5(0, 2, (missionNamespace getVariable [ARR_2(QUOTE(QGVAR(optionMenuDisplaySize)), 0)]), H_ORIGINAL(num), H_MAKEITBIGGA(num))]) - -class ACE_settingsMenu { - idd = 145246; - movingEnable = false; - onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_settingsMenu', _this select 0)]; [] call FUNC(onSettingsMenuOpen);); - onUnload = QUOTE(uiNamespace setVariable [ARR_2('ACE_settingsMenu', nil)]; saveProfileNamespace;); - - class controlsBackground { - class HeaderBackground: ACE_gui_backgroundBase { - idc = -1; - type = CT_STATIC; - x = X_PART(1); - y = Y_PART(1); - w = W_PART(38); - h = H_PART(1); - style = ST_LEFT + ST_SHADOW; - font = "RobotoCondensed"; - SizeEx = H_PART(1); - colorText[] = {0.95, 0.95, 0.95, 0.75}; - colorBackground[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])","(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])","(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; - text = ""; - }; - class CenterBackground: HeaderBackground { - y = Y_PART(2.1); - h = H_PART(2.5); - text = ""; - colorText[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; - colorBackground[] = {0,0,0,"(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; - }; - class LeftBackground: CenterBackground { - y = Y_PART(4.8); - h = H_PART(17.4); - w = W_PART(25); - }; - class RightBackground: LeftBackground { - x = X_PART(26.1); - w = W_PART(12.9); - }; - class RightBackgroundHeader: RightBackground { - h = H_PART(1.4); - colorBackground[] = {0,0,0,1}; - }; - }; - - class controls { - class HeaderName { - idc = 1; - type = CT_STATIC; - x = X_PART(1); - y = Y_PART(1); - w = W_PART(38); - h = H_PART(1); - style = ST_LEFT + ST_SHADOW; - font = "RobotoCondensed"; - SizeEx = H_PART(1); - colorText[] = {0.95, 0.95, 0.95, 0.75}; - colorBackground[] = {0,0,0,0}; - text = CSTRING(OpenConfigMenu); - }; - class labelSubHeader: ACE_gui_staticBase { - idc = 13; - x = X_PART(2); - y = Y_PART(3.4); - w = W_PART(15); - h = H_PART(1); - text = ""; - }; - class categorySelection: ACE_gui_comboBoxBase { - idc = 14; - x = X_PART(14); - y = Y_PART(3.4); - w = W_PART(9); - h = H_PART(1); - text = ""; - onLBSelChanged = QUOTE( call FUNC(onCategorySelectChanged)); - SizeEx = H_PART(0.9); - }; - class selectionAction_1: ACE_gui_buttonBase { - idc = 1000; - text = CSTRING(TabOptions); - x = X_PART(1); - y = Y_PART(2.1); - w = W_PART(9.5); - h = H_PART(1); - animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.9)"; - animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.8)"; - animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; - animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; - color[] = {1, 1, 1, 1}; - color2[] = {0,0,0, 1}; - colorBackgroundFocused[] = {1,1,1,1}; - colorBackground[] = {1,1,1,1}; - colorbackground2[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,1}; - colorFocused[] = {0,0,0,1}; - periodFocus = 1; - periodOver = 1; - action = QUOTE([MENU_TAB_OPTIONS] call FUNC(onListBoxShowSelectionChanged);); - SizeEx = H_PART(1); - Size = H_PART(1); - }; - class selectionAction_2: selectionAction_1 { - idc = 1001; - text = CSTRING(TabColors); - x = X_PART(10.5); - action = QUOTE([MENU_TAB_COLORS] call FUNC(onListBoxShowSelectionChanged);); - }; - class selectionAction_3: selectionAction_1 { - idc = 1002; - text = ""; - x = X_PART(20); - action = ""; - }; - class selectionAction_4: selectionAction_1 { - idc = 1003; - text = ""; - x = X_PART(29.5); - action = ""; - }; - class listBoxSettingsList: ACE_gui_listNBox { - idc = 200; - x = X_PART(2); - y = Y_PART(5.5); - w = W_PART(23); - h = H_PART(15); - SizeEx = H_ORIGINAL(0.8); - colorBackground[] = {0, 0, 0, 0.9}; - colorSelectBackground[] = {0, 0, 0, 0.9}; - columns[] = {0.0, 0.6}; - onLBSelChanged = QUOTE(_this call FUNC(settingsMenuUpdateKeyView)); - }; - class labelTitle: ACE_gui_staticBase { - idc = 250; - x = X_PART(27.1); - y = Y_PART(5.1); - w = W_PART(11); - h = H_PART(1); - text = ""; - SizeEx = H_PART(1); - }; - class labelKey: ACE_gui_staticBase { //Variable Name - idc = 300; - x = X_PART(27.1); - y = Y_PART(6.2); - w = W_PART(11); - h = H_PART(1); - text = ""; - SizeEx = H_PART(0.65); - }; - class Label2: labelKey { - idc = 301; - y = Y_PART(7.3); - text = CSTRING(Setting); - SizeEx = H_PART(1); - }; - class comboBox1: ACE_gui_comboBoxBase { - idc = 400; - x = X_PART(31.1); - y = Y_PART(7.3); - w = W_PART(7); - h = H_PART(1); - onLBSelChanged = QUOTE( call FUNC(onListBoxSettingsChanged)); - SizeEx = H_PART(0.9); - }; - class sliderBar1: RscXSliderH { - idc = 410; - x = X_PART(27.1); - y = Y_PART(7.3); - w = W_PART(11); - h = H_PART(0.75); - onSliderPosChanged = QUOTE(_this call FUNC(onSliderPosChanged)); - color[] = {1,0,0,0.4}; - colorActive[] = {1,0,0,1}; - }; - class sliderBar2: sliderBar1 { - idc = 411; - y = Y_PART(8.2); - color[] = {0,1,0,0.4}; - colorActive[] = {0,1,0,1}; - }; - class sliderBar3: sliderBar1 { - idc = 412; - y = Y_PART(9.1); - color[] = {0,0,1,0.4}; - colorActive[] = {0,0,1,1}; - }; - class sliderBar4: sliderBar1 { - idc = 413; - y = Y_PART(10); - color[] = {1,1,1,0.4}; - colorActive[] = {1,1,1,1}; - }; - class labelDesc: ACE_gui_staticBase { - idc = 251; - x = X_PART(27.1); - y = Y_PART(11); - w = W_PART(11); - h = H_PART(11); - text = ""; - style = ST_LEFT + ST_MULTI; - lineSpacing = 1; - SizeEx = H_PART(0.8); - }; - class actionClose: ACE_gui_buttonBase { - idc = 10; - text = "$STR_DISP_CLOSE"; - x = X_PART(1); - y = Y_PART(22.3); - w = W_PART(7.5); - h = H_PART(1); - style = ST_LEFT; - animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.8)"; - animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.5)"; - animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; - animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; - color[] = {1, 1, 1, 1}; - color2[] = {0,0,0, 1}; - colorBackgroundFocused[] = {1,1,1,1}; - colorBackground[] = {1,1,1,1}; - colorbackground2[] = {1,1,1,1}; - colorDisabled[] = {0.5,0.5,0.5,0.8}; - colorFocused[] = {0,0,0,1}; - periodFocus = 1; - periodOver = 1; - action = "closedialog 0;"; - SizeEx = H_PART(1); - Size = H_PART(1); - }; - class action_reset: actionClose { - idc = 1100; - text = CSTRING(ResetAll); - x = X_PART(9.5); - action = QUOTE([] call FUNC(resetSettings)); - }; - class action_exportServerConfig: actionClose { - idc = 1102; - text = CSTRING(OpenExport); - x = X_PART(18); - action = QUOTE(if (GVAR(serverConfigGeneration) > 0) then {closeDialog 0; createDialog 'ACE_serverSettingsMenu';}); - }; - class action_debug: actionClose { - idc = 1102; - text = CSTRING(DumpDebug); - x = X_PART(26.1); - action = QUOTE([] call FUNC(debugDumpToClipboard)); - tooltip = CSTRING(DumpDebugTooltip); - }; - class action_headBugFix: actionClose { - idc = 1102; - text = CSTRING(headBugFix); - x = X_PART(34); - w = W_PART(5); - action = QUOTE(0 spawn EFUNC(common,headBugFix); closedialog 0;); - tooltip = CSTRING(headBugFixTooltip); - }; - }; -}; -class ACE_serverSettingsMenu: ACE_settingsMenu { - onLoad = QUOTE(uiNamespace setVariable [ARR_2('ACE_serverSettingsMenu', _this select 0)]; [] call FUNC(onServerSettingsMenuOpen);); - onUnload = QUOTE(uiNamespace setVariable [ARR_2('ACE_serverSettingsMenu', nil)];); - class controls: controls { - class HeaderName { - idc = 1; - type = CT_STATIC; - x = X_PART(1); - y = Y_PART(1); - w = W_PART(38); - h = H_PART(1); - style = ST_LEFT + ST_SHADOW; - font = "RobotoCondensed"; - SizeEx = H_PART(1); - colorText[] = {0.95, 0.95, 0.95, 0.75}; - colorBackground[] = {0,0,0,0}; - text = CSTRING(OpenConfigMenu); - }; - class labelSubHeader: ACE_gui_staticBase { - idc = 13; - x = X_PART(2); - y = Y_PART(3.4); - w = W_PART(30); - h = H_PART(1); - text = ""; - }; - class categorySelection: ACE_gui_comboBoxBase { - idc = 14; - x = X_PART(14); - y = Y_PART(3.4); - w = W_PART(9); - h = H_PART(1); - text = ""; - onLBSelChanged = QUOTE( call FUNC(onServerCategorySelectChanged)); - SizeEx = H_PART(0.9); - }; - class selectionAction_1: ACE_gui_buttonBase { - idc = 1000; - text = CSTRING(TabOptions); - x = X_PART(1); - y = Y_PART(2.1); - w = W_PART(9.5); - h = H_PART(1); - animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.9)"; - animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.8)"; - animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; - animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; - color[] = {1, 1, 1, 1}; - color2[] = {0,0,0, 1}; - colorBackgroundFocused[] = {1,1,1,1}; - colorBackground[] = {1,1,1,1}; - colorbackground2[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,1}; - colorFocused[] = {0,0,0,1}; - periodFocus = 1; - periodOver = 1; - action = QUOTE([MENU_TAB_SERVER_OPTIONS] call FUNC(onServerListBoxShowSelectionChanged);); - }; - class selectionAction_2: selectionAction_1 { - idc = 1001; - text = CSTRING(TabColors); - x = X_PART(10.5); - action = QUOTE([MENU_TAB_SERVER_COLORS] call FUNC(onServerListBoxShowSelectionChanged);); - }; - class selectionAction_3: selectionAction_1 { - idc = 1002; - text = CSTRING(TabValues); - x = X_PART(20); - action = QUOTE([MENU_TAB_SERVER_VALUES] call FUNC(onServerListBoxShowSelectionChanged);); - }; - class selectionAction_4: selectionAction_1 { - idc = 1003; - text = ""; - x = X_PART(29.5); - action = ""; - }; - class listBoxSettingsList: ACE_gui_listNBox { - idc = 200; - x = X_PART(2); - y = Y_PART(5.5); - w = W_PART(23); - h = H_PART(15); - SizeEx = H_ORIGINAL(0.8); - colorBackground[] = {0, 0, 0, 0.9}; - colorSelectBackground[] = {0, 0, 0, 0.9}; - columns[] = {0.0, 0.6}; - onLBSelChanged = QUOTE(_this call FUNC(serverSettingsMenuUpdateKeyView)); - }; - class labelTitle: ACE_gui_staticBase { - idc = 250; - x = X_PART(27.1); - y = Y_PART(5.1); - w = W_PART(11); - h = H_PART(1); - text = ""; - SizeEx = H_PART(1); - }; - class labelKey: ACE_gui_staticBase { //Variable Name - idc = 300; - x = X_PART(27.1); - y = Y_PART(6.2); - w = W_PART(11); - h = H_PART(1); - text = ""; - SizeEx = H_PART(0.65); - }; - class Label2: labelKey { - idc = 301; - y = Y_PART(7.3); - text = CSTRING(Setting); - SizeEx = H_PART(1); - }; - class comboBox1: ACE_gui_comboBoxBase { - idc = 400; - x = X_PART(31.1); - y = Y_PART(7.3); - w = W_PART(7); - h = H_PART(1); - onLBSelChanged = QUOTE( call FUNC(onListBoxSettingsChanged)); - SizeEx = H_PART(0.9); - }; - class sliderBar1: RscXSliderH { - idc = 410; - x = X_PART(27.1); - y = Y_PART(7.3); - w = W_PART(11); - h = H_PART(0.75); - onSliderPosChanged = QUOTE(_this call FUNC(onSliderPosChanged)); - color[] = {1,0,0,0.4}; - colorActive[] = {1,0,0,1}; - }; - class sliderBar2: sliderBar1 { - idc = 411; - y = Y_PART(8.2); - color[] = {0,1,0,0.4}; - colorActive[] = {0,1,0,1}; - }; - class sliderBar3: sliderBar1 { - idc = 412; - y = Y_PART(9.1); - color[] = {0,0,1,0.4}; - colorActive[] = {0,0,1,1}; - }; - class sliderBar4: sliderBar1 { - idc = 413; - y = Y_PART(10); - color[] = {1,1,1,0.4}; - colorActive[] = {1,1,1,1}; - }; - class inputField1: ACE_gui_editBase { - idc = 414; - x = X_PART(27.1); - y = Y_PART(7.3); - w = W_PART(11); - h = H_PART(0.75); - }; - class inputFieldTypeLabel: ACE_gui_staticBase { - idc = 415; - x = X_PART(27.1); - y = Y_PART(8.2); - w = W_PART(11); - h = H_PART(0.75); - text = ""; - style = ST_LEFT + ST_MULTI; - lineSpacing = 1; - SizeEx = H_PART(0.8); - }; - class saveInputButton: selectionAction_1 { - idc = 416; - text = CSTRING(SaveInput); - x = X_PART(27.1); - y = Y_PART(9.1); - w = W_PART(11); - h = H_PART(1); - action = QUOTE([] call FUNC(onServerSaveInputField);); - }; - class labelDesc: ACE_gui_staticBase { - idc = 251; - x = X_PART(27.1); - y = Y_PART(11); - w = W_PART(11); - h = H_PART(11); - text = ""; - style = ST_LEFT + ST_MULTI; - lineSpacing = 1; - SizeEx = H_PART(0.8); - }; - class actionClose; - class action_reset: actionClose { - idc = 1100; - text = CSTRING(ResetAll); - x = X_PART(26.1); - action = QUOTE([] call FUNC(serverResetSettings)); - }; - class action_exportServerConfig: actionClose { - idc = 1101; - text = CSTRING(Export); - x = X_PART(1); - action = QUOTE([] call FUNC(exportSettings)); - }; - class action_toggleIncludeClientSettings: actionClose { - idc = 1102; - text = CSTRING(inClientSettings); - x = X_PART(9); - action = QUOTE([] call FUNC(toggleIncludeClientSettings)); - }; - }; -}; diff --git a/addons/optionsmenu/script_component.hpp b/addons/optionsmenu/script_component.hpp index c13e915702..7ae6409e6c 100644 --- a/addons/optionsmenu/script_component.hpp +++ b/addons/optionsmenu/script_component.hpp @@ -20,10 +20,3 @@ #define IDC_MAIN_INFO 80090 #define IDC_MAIN_INFO_CURRENT_VERSION_INFO 80091 #define IDC_MAIN_INFO_NEWEST_VERSION_INFO 80092 - -#define MENU_TAB_OPTIONS 0 -#define MENU_TAB_COLORS 1 - -#define MENU_TAB_SERVER_OPTIONS 10 -#define MENU_TAB_SERVER_COLORS 11 -#define MENU_TAB_SERVER_VALUES 12 diff --git a/addons/optionsmenu/stringtable.xml b/addons/optionsmenu/stringtable.xml index 5b43574561..6ebc553748 100644 --- a/addons/optionsmenu/stringtable.xml +++ b/addons/optionsmenu/stringtable.xml @@ -1,357 +1,116 @@ - + - - ACE Options - ACE-Optionen - Opciones ACE - Ustawienia ACE - ACE Nastavení - Options ACE - ACE Настройки - Opções do ACE - ACE Beállítások - Opzioni ACE - ACE オプション - ACE 옵션 - ACE 设定 - ACE 設定 + + Debug To Clipboard + Debug do schowka + Depurar al portapapeles + Debug do schránky + Debug in die Zwischenablage + Depuração para área de transferência + Debug vers le presse-papier + Debug a vágólapra + Отладка в буфер обмена + Debug su Blocco Note + クリップボードにデバッグ + 디버그를 클립보드로 + 复制除错讯息至剪贴簿 + 複製除錯訊息至剪貼簿 - - Fix Animation - Behebe Animation - Arreglar animación - Фикс анимации - Opravit animace - Napraw animację - Corriger animation - Animációk kijavítása - Sistema l'animazione - Arrumar Animação - アニメーションを修正 - 동작 고정 + + Sends debug information to RPT and clipboard. + Wysyła informacje o debugowaniu do RPT oraz schowka. + Envía información de depuración al RPT y el portapapeles. + Pošle debug informace do RPT a schránky. + Protokolliert Debug-Informationen im RPT und speichert sie in der Zwischenablage. + Envia informação de depuração para RPT e área de transferência. + Copie le Debug dans le RPT et le presse-papier + Debug információt küld az RPT-be és a vágólapra. + Отправляет отладочную информацию в RPT и буфер обмена. + Invia informazioni di debug all'RPT e al Blocco Note + デバッグ情報を RPT とクリップボードに送った。 + 디버그 정보를 보고하기 및 클립보드에 복사하기 위해 보냅니다. + 复制除错讯息至剪贴簿与RPT报告档中。 + 複製除錯訊息至剪貼簿與RPT報告檔中。 + + + Headbug Fix + Behebe Headbug + Fix Headbug + HeadBug + "Fejhiba" fix + Corrigir Headbug + Fix Headbug + Fix Headbug + Corregir error de cabeza (headbug) + Sistema Bug della Testa + ヘッドバグ修正 + 헤드버그 수정 修复动作BUG 修復動作BUG - - Reset All - Alles zurücksetzen - Reiniciar todo - Полный сброс - Vyresetovat vše - Resetuj wszystko - Défaut - Minden visszaállítása - Resetta tutto - Resetar Tudo - すべて初期化 - 모두 초기화 - 重置为预设值 - 重置為預設值 + + Resets your animation state. + Setzt die derzeitige Animation zurück. + Resetuje aktualną animację. + Réinitialise l'état de l'animation + Visszaállítja az animációs állapotodat. + Redefine seu estado de animação. + Исправляет баг с зациклившейся анимацией. + Resetovat aktuální animaci. + Restablece tu estado de animación. + Resetta il tuo stato animazione + 現在のアニメーションの状況を初期化します。 + 자신의 동작 상태 초기화 + 当ACE发生动作BUG时,点此修复。 + 當ACE發生動作BUG時,點此修復。 - - Colors - Couleurs - Farben - Colores - Цвета - Barvy - Kolory - Színek - Colori - Cores - - 색상 - 颜色 - 顏色 + + ACE News + Noticias ACE + ACE-Neuigkeiten + Notícias do ACE + Wiadomości ACE + ACE Zprávy + Nouveautés ACE + ACE hírek + Новости ACE + Novità ACE + ACE ニュース + ACE 새소식 + ACE新闻 + ACE新聞 - - Options - Optionen - Opciones - Opcje - Nastavení - Options - Настройки - Opções - Beállítások - Opzioni - オプション - 옵션 - 中文化由[MR]Diss制作 - 設定 + + Show News on Main Menu + Mostrar noticias en el menú principal + Zeige Neuigkeiten im Hauptmenü + Mostrar notícias no menu principal + Pokazuj wiadomości ACE w menu głównym + Affiche les nouveautés sur l'écran principal + Hírek mutatása a főmenüben + Показывать новости в Главном Меню + Zobrazit zprávy v hlavním menu + Mostra News nel Menù Princinpale + メイン画面にニュースを表示します + 메인메뉴에 새소식을 표시합니다 + 显示新闻消息于主选单 + 顯示新聞消息於主選單 - - Values - Valores - Значения - Hodnoty - Wartości - Valeurs - Werte - Értékek - Valori - Valores - - - 数值 - 數值 - - - Setting: - Nastavení: - Einstellung: - Установки: - Ajuste: - Ustaw: - Paramètres - Opció: - Parametri: - Opção: - 設定: - 설정: - 设定: - 設定: - - - Export - Exportieren - Exportar - Экспорт - Exportovat - Eksport - Exporter - Exportálás - Esporta - Exportar - 出力 - 내보내기 - 输出 - 輸出 - - - Open Export Menu - Öffne Exportmenü - Abrir menú de exportación - Открыть меню экспорта - Otevřít exportovací menu - Eksport ustawień - Ouvrir le menu d'exportation - Exportálási menü megnyitása - Apri menù esportazione - Abrir menu de exportação - 出力メニューを開く - 내보내기 메뉴 열기 - 开启输出选单 - 開啟輸出選單 - - - String input. - Zeichenketteneingabe - Introducir cadena de texto. - Строчный ввод. - Wpisywanie tekstu. - Vkládání textu. - Entrée - String bevitel. - Stringa di unput. - Input de String - 文字列の入力 - 문자열 입력 - 输入数值 - 輸入數值 - - - Array. Seperate elements by using ,. - Array. Teile unterschiedliche Elemente mit ,. - Matriz. Separa elementos usando ,. - Массив. Разделяйте элемены, используя запятую. - Tablica. Oddziel elementy używając ,. - Tableau. Séparation par ,. - Tabulka. Odděl elementy použitím ,. - Array. Válasszad el az elemeket vesszővel. - Vettor. Separa gli elementi usando ,. - Vetor. Separe elementos usando *,*. - アライ。,を使うことで区別できます。 - 배열. 요소를 ,. 로 나눔 - 阵列. 使用','来做每个值的区隔. - 陣列. 使用','來做每個值的區隔. - - - Number - Zahl - Número - Число - Číslo - Cyfra - Nombre - Szám - Numero - Número - - 숫자 - 数字 - 數字 - - - Uknown input type - Unbekannter Eingabetyp - Tipo de entrada desconocida - Неизвестный тип ввода - Neznámý vstup - Nieznany rodzaj danych - Type d'entrée inconnue - Ismeretlen beviteli típus - Input inserito sconosciuto - Tipo desonhecido de input - 不明な入力です - 불분명한 입력입니다 - 未知输入类型 - 未知輸入類型 - - - Save input - Speichere Eingabe - Guardar entrada - Сохранить ввод - Uložit vstup - Zapisz dane - Sauvegarder - Bevitel elmentése - Salva input - Salvar input - 入力を保存 - 입력 저장 - 储存输入 - 儲存輸入 - - - Include Client Settings - Schließe Client-Einstellungen ein - Incluir configuración de cliente - Включить настройки клиента - Zahrnout nastavení klienta - Zaw. ustaw. klienta - Inclure paramètres client - Kliens-beállítások melléklése - Includi i parametri del client - Incluir opções do cliente - クライアント設定を含む - 클라이언트 설정 포함 - 包含客户端设定 - 包含客戶端設定 - - - Exclude Client Settings - Schließe Client-Einstellungen aus - Excluir configuración de cliente - Исключить настройки клиента - Nezahrnout nastavení klienta - Wyklucz ustawienia klienta - Exclure paramètres client - Kliens-beállítások elhagyása - Escludi i parametri del client - Excluir opções do cliente - クライアント設定を実行する - 클라이언트 설정 제외 - 不包含客户端设定 - 不包含客戶端設定 - - - Settings exported to clipboard - Einstellungen in die Zwischenablage exportiert - Configuración exportada al portapapeles - Настройки экспортированы в буфер обмена - Nastevení exportována do schránky - Ustawienia wyeksportowano do schowka - Paramètres exportés dans le presse papier - Beállítások exportálva a vágólapba - Parametri esportati alla clipboard - Opções exportadas para o clipboard. - クリップボードに設定を出力する - 클립보드로 설정 내보내기 - 设定输出至剪贴簿 - 設定輸出至剪貼簿 - - - Option Menu UI Scaling - Menu option: taille de l'UI - Skalowanie UI menu ustawień - Měřítko UI v menu nastavení - Размер интерфейса меню настройки - Opción de escalado del menú IU - Nutzeroberflächen-Skalierung - Beállításmenü kezelőfelületének skálázása - Escalar o menu de opções - Proporzioni della interfaccia utente - オプション メニューにあるユーザ インタフェイスの大きさ - 옵션메뉴 UI 비례도 - 调整设定选单视窗大小 - 調整設定選單視窗大小 - - - Allow Config Export [ACE] - Pozwól na eksport ustawień - [ACE] Permitir exportar configuración - Erlaube Config-Export [ACE] - Povolit export natavení [ACE] - [ACE] Permitir exportação de configurações - Autoriser l'exportation de la configuration [ACE] - Konfiguráció-exportálás engedélyezése [ACE] - Разрешить экспорт настроек [ACE] - Consenti Esportazione del Config [ACE] - 設定の出力を許可 [ACE] - 설정 내보내기 허가 [ACE] - 允许配置导出 [ACE] - 允許配置導出 [ACE] - - - Allow - Zezwól - Permitir - Erlaube - Povolit - Permitir - Autoriser - Engedélyezés - Разрешить - Consenti - 許可 - 허가 - 允许 - 允許 - - - Allow export of all settings to a server config formatted. - Zezwól na eksport wszystkich ustawień do formatu konfiguracji serwera. - Permitir la exportación de todos los ajustes de configuración a un servidor con formato. - Erlaube alle Einstellungen in einer Server-Config zu exportieren. - Povolit exportovat všechna nastavení do formátu server configu. - Permitir exportação de todas as configurações para uma configuração formatada de servidor. - Autorise l'exportation des toutes les options vers un fichier de configuration - Az összes beállítás szerver-konfigurációba való exportálásának engedélyezése. - Разрешить экспорт всех настроек в формате серверного конфига. - Consenti esportazione di tutti i parametri ad config formato per server. - 全ての設定をサーバ用設定の形式へと出力できるようにします。 - 모든 설정을 서버 설정 형식으로 내보내는것을 허락합니다. - 允许导出所有设定成伺服器配置格式的档案. - 允許導出所有設定成伺服器配置格式的檔案. - - - When allowed, you have access to the settings modification and export in SP. Clicking export will place the formated config on your clipboard. - Jeżeli ustawione na zezwól, wtedy będziesz mieć dostęp do ekranu modyfikacji wszystich ustawień i zmiennych ACE, a także będziesz mieć możliwość eksportu tychże ustawień do formatu rozpoznawalnego przez userconfig serwera. Kliknięcie opcji Eksportuj skopiuje wszystkie ustawienia do schowka. Działa tylko w trybie SP. - Cuando esta permitido, se tiene acceso a los ajustes de modificación y exportación en SP. Pulsar en exportar copiara la configuración al portapapeles. - Wenn erlaubt, können die Einstellungsmodifikationen angezeigt und im SP exportiert werden. Wenn auf "Exportieren" geklickt wird, wird eine formatierte Config-Datei in der Zwischenablage abgespeichert. - Pokud je povoleno, budete mít přístup k modifikaci nastavení a exportování v SP. Kliknutím na export umístníte formátovaný config do vaší schránky. - Quando permitido, você tem acesso à modificação de definições e exportação em SP. Clicando em exportação colocará a configuração formatada em sua área de transferência. - Quand autorisé, vous pouvez accéder aux modifications et à l'exporation en solo. Cliquer sur exporter placera la configuration dans le presse-papier - Engedélyezéskor hozzáférést kapsz a beállítások módosításához és exportálásához egyjátékos módban. Exportáláskor a formázott konfiguráció a vágólapra kerül. - Когда разршен, у вас появляется доступ к модификации настроек и экспорту их в одинночном режиме. Нажатие на кнопку Экспорт поместит форматированные настройки в буфер обмена. - Quando consentito, hai accesso alle modifiche delle impostazioni ed esportazione in SP. Cliccando Esporta piazzera il config formattato sul tuo Blocco Note. - 許可の場合、あなたは設定の変更と出力をシングルプレイで可能です。出力をクリックすると、サーバ用設定の形式となっている設定がクリップボードに保存されます。 - 허락하는 경우 싱글플레이에서 설정의 변경과 내보내기가 가능해집니다. 내보내기를 눌러서 서버 형성의 설정을 클립보드로 보냅니다. - 当本功能开启时, 你将能在单人模式中调整并输出设定. 点击输出按钮后将会让相关设定参数复制到剪贴簿上. - 當本功能開啟時, 你將能在單人模式中調整並輸出設定. 點擊輸出按鈕後將會讓相關設定參數複製到剪貼簿上. + + Logistics + Logistik + Logistyka + Logística + Логистика + Logistika + Logística + Logistica + Logistique + ロジスティクス + 보급 + 后勤设定 + 後勤設定 Hide @@ -382,8 +141,8 @@ In Alto a Destra, verso il Basso 右上、下側 오른쪽 위에서 아래로 - 右上角, 向下 - 右上角, 向下 + 右上角,向下 + 右上角,向下 Top right, to the left @@ -398,8 +157,8 @@ In Alto a Destra, verso Sinistra 右上、左詰 오른쪽 위에서 왼쪽으로 - 右上角, 向左 - 右上角, 向左 + 右上角,向左 + 右上角,向左 Top left, downwards @@ -414,8 +173,8 @@ In Alto a Sinistra, verso il Basso 左上、下側 왼쪽 위에서 아래로 - 左上角, 向下 - 左上角, 向下 + 左上角,向下 + 左上角,向下 Top left, to the right @@ -430,8 +189,8 @@ In Alto a Sinistra, verso Destra 右上、右詰 왼쪽 위에서 오른쪽으로 - 左上角, 向右 - 左上角, 向右 + 左上角,向右 + 左上角,向右 Top @@ -465,131 +224,5 @@ 下方 下方 - - Debug To Clipboard - Debug do schowka - Depurar al portapapeles - Debug do schránky - Debug in die Zwischenablage - Depuração para área de transferência - Debug vers le presse-papier - Debug a vágólapra - Отладка в буфер обмена - Debug su Blocco Note - クリップボードへデバッグ - 디버그를 클립보드로 - 复制除错讯息至剪贴簿 - 複製除錯訊息至剪貼簿 - - - Sends debug information to RPT and clipboard. - Wysyła informacje o debugowaniu do RPT oraz schowka. - Envía información de depuración al RPT y el portapapeles. - Pošle debug informace do RPT a schránky. - Protokolliert Debug-Informationen im RPT und speichert sie in der Zwischenablage. - Envia informação de depuração para RPT e área de transferência. - Copie le Debug dans le RPT et le presse-papier - Debug információt küld az RPT-be és a vágólapra. - Отправляет отладочную информацию в RPT и буфер обмена. - Invia informazioni di debug all'RPT e al Blocco Note - デバッグ情報の RPT とクリップボードに送ります。 - 디버그 정보를 보고하기 및 클립보드에 복사하기 위해 보냅니다. - 复制除错讯息至剪贴簿与RPT报告档中. - 複製除錯訊息至剪貼簿與RPT報告檔中. - - - Headbug Fix - Behebe Headbug - Fix Headbug - HeadBug - "Fejhiba" fix - Corrigir Headbug - Fix Headbug - Fix Headbug - Corregir error de cabeza (headbug) - Sistema Bug della Testa - ヘッドバグ修正 - 헤드버그 수정 - 修复动作BUG - 修復動作BUG - - - Resets your animation state. - Setzt die derzeitige Animation zurück. - Resetuje aktualną animację. - Réinitialise l'état de l'animation - Visszaállítja az animációs állapotodat. - Redefine seu estado de animação. - Исправляет баг с зациклившейся анимацией. - Resetovat aktuální animaci. - Restablece tu estado de animación. - Resetta il tuo stato animazione - 現在のアニメーションの状況を初期化します。 - 자신의 동작 상태 초기화 - 当ACE发生动作BUG时, 点此修复. - 當ACE發生動作BUG時, 點此修復. - - - ACE News - Noticias ACE - ACE-Neuigkeiten - Notícias do ACE - Wiadomości ACE - ACE Zprávy - Nouveautés ACE - ACE hírek - Новости ACE - Novità ACE - ACE からのお知らせ - ACE 새소식 - ACE新闻 - ACE新聞 - - - Show News on Main Menu - Mostrar noticias en el menú principal - Zeige Neuigkeiten im Hauptmenü - Mostrar notícias no menu principal - Pokazuj wiadomości ACE w menu głównym - Affiche les nouveautés sur l'écran principal - Hírek mutatása a főmenüben - Показывать новости в Главном Меню - Zobrazit zprávy v hlavním menu - Mostra News nel Menù Princinpale - メイン メニュにお知らせを表示します - 메인메뉴에 새소식을 표시합니다 - 显示新闻消息于主选单 - 顯示新聞消息於主選單 - - - All Categories - Alle Kategorien - Wszystkie kategorie - Todas categorias - Все категории - Všechny Kategorie - Todas las categorías - Tutte le Categorie - Toutes les catégories - 全カテゴリ - 모든 카테고리 - 全局设定 - 全局設定 - - - Logistics - Logistik - Logistyka - Logística - Логистика - Logistika - Logística - Logistica - Logistique - ロジスティクス - 보급 - 后勤设定 - 後勤設定 - diff --git a/addons/overheating/ACE_Settings.hpp b/addons/overheating/ACE_Settings.hpp index fc3237da0f..5a4b8941e9 100644 --- a/addons/overheating/ACE_Settings.hpp +++ b/addons/overheating/ACE_Settings.hpp @@ -1,5 +1,6 @@ class ACE_Settings { class GVAR(displayTextOnJam) { + category = CSTRING(DisplayName); typeName = "BOOL"; isClientSettable = 1; value = 1; @@ -7,6 +8,7 @@ class ACE_Settings { description = CSTRING(DisplayTextOnJam_description); }; class GVAR(showParticleEffects) { + category = CSTRING(DisplayName); typeName = "BOOL"; isClientSettable = 1; value = 1; @@ -14,6 +16,7 @@ class ACE_Settings { description = CSTRING(showParticleEffects_description); }; class GVAR(showParticleEffectsForEveryone) { + category = CSTRING(DisplayName); typeName = "BOOL"; isClientSettable = 1; value = 0; @@ -21,24 +24,29 @@ class ACE_Settings { description = CSTRING(showParticleEffectsForEveryone_description); }; class GVAR(overheatingDispersion) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 1; displayName = CSTRING(overheatingDispersion_displayName); description = CSTRING(overheatingDispersion_description); }; class GVAR(unJamOnreload) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 0; displayName = CSTRING(unJamOnreload_displayName); description = CSTRING(unJamOnreload_description); }; class GVAR(unJamFailChance) { + category = CSTRING(DisplayName); typeName = "SCALAR"; value = 0.1; displayName = CSTRING(unJamFailChance_displayName); description = CSTRING(unJamFailChance_description); + sliderSettings[] = {0, 1, 0.1, 2}; }; class GVAR(enabled) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 1; displayName = CSTRING(enabled_displayName); diff --git a/addons/overheating/CfgVehicles.hpp b/addons/overheating/CfgVehicles.hpp index 2d6a48b7b3..aa9d4e8535 100644 --- a/addons/overheating/CfgVehicles.hpp +++ b/addons/overheating/CfgVehicles.hpp @@ -7,15 +7,16 @@ class CfgVehicles { class GVAR(UnJam) { displayName = CSTRING(UnjamWeapon); condition = QUOTE( GVAR(enabled) && {[_player] call FUNC(canUnjam)} ); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE( [ARR_2(_player, currentMuzzle _player)] call FUNC(clearJam); ); showDisabled = 0; priority = 4; - icon = QPATHTOF(UI\unjam_ca.paa); + icon = QPATHTOEF(common,UI\repack_ca.paa); }; class GVAR(SwapBarrel) { displayName = CSTRING(SwapBarrel); condition = QUOTE( [ARR_2(_player, currentWeapon _player)] call FUNC(canSwapBarrel) ); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE( [ARR_3(_player, _player, currentWeapon _player)] call FUNC(swapBarrel); ); showDisabled = 0; priority = 3; @@ -24,7 +25,7 @@ class CfgVehicles { class GVAR(CheckTemperature) { displayName = CSTRING(CheckTemperatureShort); condition = QUOTE( GVAR(enabled) && {switch (currentWeapon _player) do {case (''): {false}; case (primaryWeapon _player); case (handgunWeapon _player): {true}; default {false}}} ); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE( [ARR_3(_player, _player, currentWeapon _player)] call FUNC(checkTemperature); ); showDisabled = 0; priority = 2.9; @@ -33,7 +34,7 @@ class CfgVehicles { class GVAR(CheckTemperatureSpareBarrels) { displayName = CSTRING(CheckTemperatureSpareBarrelsShort); condition = QUOTE((_player) call FUNC(canCheckSpareBarrelsTemperatures) ); - exceptions[] = {"isNotInside", "isNotSitting"}; + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE( [_player] call FUNC(checkSpareBarrelsTemperatures); ); showDisabled = 0; priority = 2.8; @@ -48,12 +49,13 @@ class CfgVehicles { displayName = CSTRING(SwapBarrel); condition = QUOTE( [ARR_2(_player, currentWeapon _target)] call FUNC(canSwapBarrel) ); statement = QUOTE([ARR_3(_player, _target, currentWeapon _target)] call FUNC(swapBarrelAssistant);); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; icon = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); }; class GVAR(CheckTemperature) { displayName = CSTRING(CheckTemperatureShort); - condition = QUOTE( GVAR(enabled) && {switch (currentWeapon _target) do {case (''): {false}; case (primaryWeapon _target); case (handgunWeapon _target): {true}; default {false}}} ); - exceptions[] = {"isNotInside", "isNotSitting"}; + condition = QUOTE( GVAR(enabled) && {switch (currentWeapon _target) do {case ('ACE_FakePrimaryWeapon'); case (''): {false}; case (primaryWeapon _target); case (handgunWeapon _target): {true}; default {false}}} ); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; statement = QUOTE( [ARR_3(_player, _target, currentWeapon _target)] call FUNC(checkTemperature); ); icon = QUOTE(PATHTOF(UI\temp_ca.paa)); }; diff --git a/addons/overheating/CfgWeapons.hpp b/addons/overheating/CfgWeapons.hpp index c7a83eec6e..f094ec7b27 100644 --- a/addons/overheating/CfgWeapons.hpp +++ b/addons/overheating/CfgWeapons.hpp @@ -1,7 +1,4 @@ class CfgWeapons { - class ACE_ItemCore; - class InventoryItem_Base_F; - class RifleCore; class Rifle: RifleCore { //Mean Rounds Between Stoppages (this will be scaled based on the barrel temp) diff --git a/addons/overheating/UI/unjam_ca.paa b/addons/overheating/UI/unjam_ca.paa deleted file mode 100644 index 45f7dadcea..0000000000 Binary files a/addons/overheating/UI/unjam_ca.paa and /dev/null differ diff --git a/addons/overheating/functions/fnc_calculateCooling.sqf b/addons/overheating/functions/fnc_calculateCooling.sqf index ced682d6d7..2986bcb9c7 100644 --- a/addons/overheating/functions/fnc_calculateCooling.sqf +++ b/addons/overheating/functions/fnc_calculateCooling.sqf @@ -19,6 +19,7 @@ params ["_temperature", "_barrelMass", "_totalTime"]; +if (_temperature < 1) exitWith {0}; // If a long time passed since the last shot, there's no need to calculate anything; the weapon should be cool if (_totalTime > 1800) exitWith {0}; diff --git a/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf b/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf index a0c0ba12de..8f4280b261 100644 --- a/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf +++ b/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf @@ -18,9 +18,6 @@ params ["_player"]; -// Check canInteractWith: -if (!([_player, objNull, ["isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith))) exitWith {}; - // Make the unit go kneeling [_player] call EFUNC(common,goKneeling); @@ -37,5 +34,5 @@ if (!([_player, objNull, ["isNotInside", "isNotSitting"]] call EFUNC(common,canI {}, (localize LSTRING(CheckingSpareBarrelsTemperatures)), {true}, - ["isNotInside", "isNotSitting"] + ["isNotInside", "isNotSitting", "isNotSwimming"] ] call EFUNC(common,progressBar); diff --git a/addons/overheating/functions/fnc_firedEH.sqf b/addons/overheating/functions/fnc_firedEH.sqf index d690b85aa7..e9bf89eef7 100644 --- a/addons/overheating/functions/fnc_firedEH.sqf +++ b/addons/overheating/functions/fnc_firedEH.sqf @@ -20,76 +20,68 @@ TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectil BEGIN_COUNTER(firedEH); -if ((_unit distance ACE_player) > 3000 //Ignore far away shots +if ((_unit distance ACE_player) > 3000 || {(_muzzle != (primaryWeapon _unit)) && {_muzzle != (handgunWeapon _unit)}}) exitWith { // Only rifle or pistol muzzles (ignore grenades / GLs) END_COUNTER(firedEH); }; -// Compute new temperature if the unit is the local player -if (_unit == ACE_player) then { - _this call FUNC(overheat); -}; - // Get current temperature from the unit variable private _temperature = _unit getVariable [format [QGVAR(%1_temp), _weapon], 0]; private _scaledTemperature = linearConversion [0, 1000, _temperature, 0, 1, true]; TRACE_2("Unit fired with temp:",_unit,_temperature); -//Get weapon data from cache: +// Get weapon data from cache: ([_weapon] call FUNC(getWeaponData)) params ["_dispersion", "_slowdownFactor", "_jamChance"]; TRACE_4("weapon data from cache",_weapon,_dispersion,_slowdownFactor,_jamChance); -// Dispersion and bullet slow down -if (GVAR(overheatingDispersion)) then { - // Exit if GVAR(pseudoRandomList) isn't synced yet - if (isNil QGVAR(pseudoRandomList)) exitWith {ERROR("No pseudoRandomList sync");}; +if (_scaledTemperature > 0.1) then { + // Dispersion and bullet slow down + if (GVAR(overheatingDispersion)) then { + if (isNil QGVAR(pseudoRandomList)) exitWith {ERROR("No pseudoRandomList sync");}; - //Dispersion: 0 mils @ 0°C, 0.5 mils @ 333°C, 2.2 mils @ 666°C, 5 mils at 1000°C - _dispersion = _dispersion * 0.28125 * (_scaledTemperature^2); + //Dispersion: 0 mils @ 0°C, 0.5 mils @ 333°C, 2.2 mils @ 666°C, 5 mils at 1000°C + _dispersion = _dispersion * 0.28125 * (_scaledTemperature^2); - _slowdownFactor = _slowdownFactor * linearConversion [0.666, 1, _scaledTemperature, 0, -0.1, true]; + _slowdownFactor = _slowdownFactor * linearConversion [0.666, 1, _scaledTemperature, 0, -0.1, true]; - // Get the pseudo random values for dispersion from the remaining ammo count - (GVAR(pseudoRandomList) select ((_unit ammo _weapon) mod (count GVAR(pseudoRandomList)))) params ["_dispersionX", "_dispersionY"]; + // Get the pseudo random values for dispersion from the remaining ammo count + (GVAR(pseudoRandomList) select ((_unit ammo _weapon) mod (count GVAR(pseudoRandomList)))) params ["_dispersionX", "_dispersionY"]; - TRACE_4("change",_dispersion,_slowdownFactor,_dispersionX,_dispersionY); + TRACE_4("change",_dispersion,_slowdownFactor,_dispersionX,_dispersionY); - TRACE_PROJECTILE_INFO(_projectile); - [_projectile, _dispersionX * _dispersion, _dispersionY * _dispersion, _slowdownFactor * vectorMagnitude (velocity _projectile)] call EFUNC(common,changeProjectileDirection); - TRACE_PROJECTILE_INFO(_projectile); -}; - - -// ------ LOCAL AND NEARBY PLAYERS DEPENDING ON SETTINGS ------------ -// Particle effects only apply to the local player and, depending on settings, to other nearby players -if (_unit != ACE_player && (!GVAR(showParticleEffectsForEveryone) || {_unit distance ACE_player > 20})) exitWith { - END_COUNTER(firedEH); -}; - -//Particle Effects: -if (GVAR(showParticleEffects) && {(CBA_missionTime > ((_unit getVariable [QGVAR(lastDrop), -1000]) + 0.40)) && {_scaledTemperature > 0.1}}) then { - _unit setVariable [QGVAR(lastDrop), CBA_missionTime]; - - private _direction = (_unit weaponDirection _weapon) vectorMultiply 0.25; - private _position = (position _projectile) vectorAdd (_direction vectorMultiply (4*(random 0.30))); - - // Refract SFX, beginning at temp 100°C and maxs out at 500°C - private _intensity = linearConversion [0.1, 0.5, _scaledTemperature, 0, 1, true]; - TRACE_3("refract",_direction,_position,_intensity); - if (_intensity > 0) then { - drop [ - "\A3\data_f\ParticleEffects\Universal\Refract", "", "Billboard", 10, 2, _position, _direction, 0, 1.2, 1.0, - 0.1, [0.10,0.25], [[0.6,0.6,0.6,0.3 * _intensity],[0.2,0.2,0.2,0.05 * _intensity]], [0,1], 0.1, 0.05, "", "", ""]; + TRACE_PROJECTILE_INFO(_projectile); + [_projectile, _dispersionX * _dispersion, _dispersionY * _dispersion, _slowdownFactor * vectorMagnitude (velocity _projectile)] call EFUNC(common,changeProjectileDirection); + TRACE_PROJECTILE_INFO(_projectile); }; - // Smoke SFX, beginning at temp 150°C - private _intensity = linearConversion [0.15, 1, _scaledTemperature, 0, 1, true]; - TRACE_3("smoke",_direction,_position,_intensity); - if (_intensity > 0) then { - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 12, 1, 16], "", "Billboard", 10, 1.2, _position, - [0,0,0.15], 100 + random 80, 1.275, 1, 0.025, [0.15,0.43], [[0.6,0.6,0.6,0.5 * _intensity],[0.2,0.2,0.2,0.15 * _intensity]], - [0,1], 1, 0.04, "", "", ""]; + + // Particle Effects + if (GVAR(showParticleEffects) + && {GVAR(showParticleEffectsForEveryone) || {_unit == ACE_player} || {_unit distance ACE_player <= 20}} + && {CBA_missionTime > (_unit getVariable [QGVAR(lastDrop), -1000]) + 0.40}) then { + + _unit setVariable [QGVAR(lastDrop), CBA_missionTime]; + + private _direction = (_unit weaponDirection _weapon) vectorMultiply 0.25; + private _position = (position _projectile) vectorAdd (_direction vectorMultiply (4*(random 0.30))); + + // Refract SFX, beginning at temp 100°C and maxs out at 500°C + private _intensity = linearConversion [0.1, 0.5, _scaledTemperature, 0, 1, true]; + TRACE_3("refract",_direction,_position,_intensity); + if (_intensity > 0) then { + drop [ + "\A3\data_f\ParticleEffects\Universal\Refract", "", "Billboard", 10, 2, _position, _direction, 0, 1.2, 1.0, + 0.1, [0.10,0.25], [[0.6,0.6,0.6,0.3 * _intensity],[0.2,0.2,0.2,0.05 * _intensity]], [0,1], 0.1, 0.05, "", "", ""]; + }; + // Smoke SFX, beginning at temp 150°C + private _intensity = linearConversion [0.15, 1, _scaledTemperature, 0, 1, true]; + TRACE_3("smoke",_direction,_position,_intensity); + if (_intensity > 0) then { + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 12, 1, 16], "", "Billboard", 10, 1.2, _position, + [0,0,0.15], 100 + random 80, 1.275, 1, 0.025, [0.15,0.43], [[0.6,0.6,0.6,0.5 * _intensity],[0.2,0.2,0.2,0.15 * _intensity]], + [0,1], 1, 0.04, "", "", ""]; + }; }; }; @@ -97,20 +89,34 @@ if (GVAR(showParticleEffects) && {(CBA_missionTime > ((_unit getVariable [QGVAR( // Only compute jamming for the local player if (_unit != ACE_player) exitWith {END_COUNTER(firedEH);}; -_jamChance = _jamChance * ([[0.5, 1, 2, 8, 20, 150], 5 * _scaledTemperature] call EFUNC(common,interpolateFromArray)); +// Compute new temperature once every 3 bullets +if ((_unit ammo _weapon) % 3 == 0) then { + _this call FUNC(overheat); +}; -// increase jam chance on dusty grounds if prone (and at ground level) -if ((stance _unit == "PRONE") && {((getPosATL _unit) select 2) < 1}) then { - private _surface = configFile >> "CfgSurfaces" >> ((surfaceType getPosASL _unit) select [1]); - if (isClass _surface) then { - TRACE_1("dust",getNumber (_surface >> "dust")); - _jamChance = _jamChance + (getNumber (_surface >> "dust")) * _jamChance; +private _value = 5 * _scaledTemperature; +private _array = [0.5, 1, 2, 8, 20, 150]; +_jamChance = _jamChance * linearConversion [0, 1, _value % 1, _array select floor _value, _array select ceil _value]; + +TRACE_3("check for random jam",_unit,_weapon,_jamChance); + +private _randomNumber = random 1; + +// Fail early if we know that we won't have a malfunction regardless of the ground type. +if (_randomNumber < _jamChance * 2) then { + if (_randomNumber > _jamChance) then { + // Increase jam chance on dusty grounds if prone (and at ground level) + if ((stance _unit == "PRONE") && {((getPosATL _unit) select 2) < 1}) then { + private _surface = configFile >> "CfgSurfaces" >> ((surfaceType getPosASL _unit) select [1]); + if (isClass _surface) then { + TRACE_1("dust",getNumber (_surface >> "dust")); + _jamChance = _jamChance + (getNumber (_surface >> "dust")) * _jamChance; + }; + }; + }; + if (_randomNumber < _jamChance) then { + [_unit, _weapon] call FUNC(jamWeapon); }; }; -TRACE_3("check for random jam",_unit,_weapon,_jamChance); -if ((random 1) < _jamChance) then { - [_unit, _weapon] call FUNC(jamWeapon); -}; - END_COUNTER(firedEH); diff --git a/addons/overheating/functions/fnc_overheat.sqf b/addons/overheating/functions/fnc_overheat.sqf index c29f2d5dd1..cc30e2ad22 100644 --- a/addons/overheating/functions/fnc_overheat.sqf +++ b/addons/overheating/functions/fnc_overheat.sqf @@ -23,27 +23,25 @@ params ["_unit", "_weapon", "", "", "_ammo", "", "_projectile"]; TRACE_4("params",_unit,_weapon,_ammo,_projectile); -// Only do heat calculations every 3 bullets -if (((_unit ammo _weapon) % 3) != 0) exitWith {}; - BEGIN_COUNTER(overheat); // Get bullet parameters -private _bulletMass = GVAR(cacheAmmoData) getVariable _ammo; -if (isNil "_bulletMass") then { +private _energyIncrement = GVAR(cacheAmmoData) getVariable _ammo; +if (isNil "_energyIncrement") then { _bulletMass = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_BulletMass"); if (_bulletMass == 0) then { // If the bullet mass is not configured, estimate it _bulletMass = 3.4334 + 0.5171 * (getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber")); }; - GVAR(cacheAmmoData) setVariable [_ammo, _bulletMass]; -}; + + // Projectile motion is roughly equal to Barrel heat + // Ref: https://en.wikipedia.org/wiki/Physics_of_firearms + // Muzzle Engergy = 1/2 * m * v^2 = (1/2 * 0.001 g/kg * bulletMass (grams) * v^2) + // Multiple by 3 becase we only calc every 3rd bullet: (3 * 1/2 * 0.001) = 0.0015 + private _energyIncrement = 0.0015 * _bulletMass * (vectorMagnitudeSqr velocity _projectile); -// Projectile motion is roughly equal to Barrel heat -// Ref: https://en.wikipedia.org/wiki/Physics_of_firearms -// Muzzle Engergy = 1/2 * m * v^2 = (1/2 * 0.001 g/kg * bulletMass (grams) * v^2) -// Multiple by 3 becase we only calc every 3rd bullet: (3 * 1/2 * 0.001) = 0.0015 -private _energyIncrement = 0.0015 * _bulletMass * (vectorMagnitudeSqr velocity _projectile); + GVAR(cacheAmmoData) setVariable [_ammo, _energyIncrement]; +}; // Increase overheating depending on how obstrusive is the current supressor, // if any. Typical arma supressors have visibleFire=0.5 and audibleFire=0.3, @@ -64,7 +62,7 @@ if (_silencer != "") then { _energyIncrement = _energyIncrement * _silencerCoef; }; -TRACE_2("heat",_bulletMass,_energyIncrement); +TRACE_1("heat",_energyIncrement); [_unit, _weapon, _energyIncrement] call FUNC(updateTemperature); diff --git a/addons/overheating/functions/fnc_swapBarrel.sqf b/addons/overheating/functions/fnc_swapBarrel.sqf index 3ad49df7d7..40e4f193b8 100644 --- a/addons/overheating/functions/fnc_swapBarrel.sqf +++ b/addons/overheating/functions/fnc_swapBarrel.sqf @@ -34,4 +34,4 @@ if (_assistant isEqualTo _gunner) then { _duration = 5.0; }; -[_duration, [_assistant,_gunner,_weapon], {(_this select 0) call FUNC(swapBarrelCallback)}, {}, (localize LSTRING(SwappingBarrel))] call EFUNC(common,progressBar); +[_duration, [_assistant,_gunner,_weapon], {(_this select 0) call FUNC(swapBarrelCallback)}, {}, localize LSTRING(SwappingBarrel), nil, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,progressBar); diff --git a/addons/overheating/functions/fnc_swapBarrelAssistant.sqf b/addons/overheating/functions/fnc_swapBarrelAssistant.sqf index 2a98e0fa8b..fd75130be3 100644 --- a/addons/overheating/functions/fnc_swapBarrelAssistant.sqf +++ b/addons/overheating/functions/fnc_swapBarrelAssistant.sqf @@ -28,6 +28,6 @@ if (stance _assistant != "PRONE") then { // Barrel dismount gesture playSound "ACE_BarrelSwap"; -[3, [_assistant, _gunner, _weapon], {}, {}, (localize LSTRING(SwappingBarrel))] call EFUNC(common,progressBar); +[3, [_assistant, _gunner, _weapon], {}, {}, localize LSTRING(SwappingBarrel), nil, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,progressBar); [QGVAR(initiateSwapBarrelAssisted), [_assistant, _gunner, _weapon], _gunner] call CBA_fnc_targetEvent; diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index 37e40c2dc1..57e14a50e2 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -1,6 +1,14 @@ - + + + Overheating + Heißlaufen + Surriscaldamento + 過熱 + 过热 + 過熱 + Display text on jam Zeige Text bei Ladehemmung @@ -120,8 +128,8 @@ Přehřátá zbraň bude méně přesná a bude mít menší úsťovou rychlost. Platí pro všechny hráče. 過熱は精度を減少させたり、初速を低下させます、これは全プレイヤに適用します。 무기 과열시 무기의 명중률이 저하되고 총구속도가 감소합니다. 이는 모든 플레이어에게 적용됩니다. - 过热的武器将会有打不准和减少射击初速的情况. 适用于所有玩家 - 過熱的武器將會有打不準和減少射擊初速的情況. 適用於所有玩家 + 过热的武器将会有打不准和减少射击初速的情况。适用于所有玩家 + 過熱的武器將會有打不準和減少射擊初速的情況。適用於所有玩家 Unjam weapon on reload @@ -180,8 +188,8 @@ Pravděpodobnost, že uvolnění zbraně selže, je proto nutné tuto akci opakovat. 弾詰りの除去を失敗する可能性が生まれ、もう一度動作を行う必要があります。 탄걸림 해결 시도시 실패할 확률이 있습니다. 이는 다시 탄걸림 해결을 시도해야함을 의미합니다. - 清除卡弹时有可能会失败, 需要反覆进行清枪 - 清除卡彈時有可能會失敗, 需要反覆進行清槍 + 清除卡弹时有可能会失败,需要反覆进行清枪。 + 清除卡彈時有可能會失敗,需要反覆進行清槍。 Spare barrel @@ -226,7 +234,7 @@ Megakadt a fegyver! Arma travada! Arma inceppata! - 武器が詰まった! + 武器が詰まった! 탄걸림! 武器卡弹! 武器卡彈! @@ -305,7 +313,7 @@ Cső kicserélése folyamatban... Substituindo cano... Sostituendo la canna... - 銃身を交換中・・・ + 銃身を交換しています・・・ 총열 교체중... 换枪管中... 換槍管中... @@ -369,7 +377,7 @@ Conferindo temperatura... Controllando la temperatura... Проверка температуры... - 温度を測っている・・・ + 温度を測っています・・・ 무기 온도 확인중... 检查枪管温度中... 檢查槍管溫度中... @@ -394,7 +402,7 @@ Vérification de la température des canons de rechange... Проверка температуры запасных стволов... Kontroluji teplotu náhradní hlavně... - 予備銃身の温度を測っている・・・ + 予備銃身の温度を測っています・・・ Sprawdzanie temperatury zapasowych luf... Prüfe Temperatur der Wechselläufe ... 총열 온도 확인중... diff --git a/addons/overpressure/ACE_Settings.hpp b/addons/overpressure/ACE_Settings.hpp index f2ddb5e302..58e0d3d8ac 100644 --- a/addons/overpressure/ACE_Settings.hpp +++ b/addons/overpressure/ACE_Settings.hpp @@ -4,5 +4,6 @@ class ACE_Settings { description = CSTRING(distanceCoefficient_toolTip); typeName = "SCALAR"; value = 1; + sliderSettings[] = {-1, 10, 5, 1}; }; }; diff --git a/addons/overpressure/functions/fnc_firedEHBB.sqf b/addons/overpressure/functions/fnc_firedEHBB.sqf index a9a37a0560..e1370f0e9e 100644 --- a/addons/overpressure/functions/fnc_firedEHBB.sqf +++ b/addons/overpressure/functions/fnc_firedEHBB.sqf @@ -54,6 +54,8 @@ if (_distance < _backblastRange) then { if (isClass (configFile >> "CfgPatches" >> "ACE_Medical") && {([_unit] call EFUNC(medical,hasMedicalEnabled))}) then { [_unit, _damage, "body", "backblast"] call EFUNC(medical,addDamageToUnit); } else { + TRACE_1("",isDamageAllowed _unit); + if (!isDamageAllowed _unit) exitWith {}; // Skip damage if not allowed _unit setDamage (damage _unit + _damage); }; }; diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index f75568e29b..b8e4054e95 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -59,6 +59,8 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); if (isClass (configFile >> "CfgPatches" >> "ACE_Medical") && {([_x] call EFUNC(medical,hasMedicalEnabled))}) then { [_x, _damage, "body", "backblast"] call EFUNC(medical,addDamageToUnit); } else { + TRACE_1("",isDamageAllowed _x); + if (!isDamageAllowed _x) exitWith {}; // Skip damage if not allowed _x setDamage (damage _x + _damage); }; diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml index 7a9edc06e5..9d909f918e 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -3,6 +3,7 @@ Overpressure Distance Coefficient + Überdruckentfernungskoeffizient 過圧の距離係数 초과압력 거리 계수 Mnożnik dystansu nadciśnienia @@ -13,6 +14,7 @@ Scales the overpressure effect [Default: 1] + Stellt den Koeffizient für die Überdruckentfernung ein [Standard: 1] 過圧効果の範囲 [標準: 1] 초과압력의 효과 크기 [기본설정: 1] Skaluje efekt nadciśnienia [Domyślne: 1] diff --git a/addons/parachute/CfgEventHandlers.hpp b/addons/parachute/CfgEventHandlers.hpp index f972afc2ca..8fa46b49f3 100644 --- a/addons/parachute/CfgEventHandlers.hpp +++ b/addons/parachute/CfgEventHandlers.hpp @@ -16,11 +16,3 @@ class Extended_PostInit_EventHandlers { init = QUOTE(call COMPILE_FILE(XEH_postInit)); }; }; - -class Extended_Respawn_EventHandlers { - class CAManBase { - class ADDON { - respawn = QUOTE(call COMPILE_FILE(XEH_respawn)); - }; - }; -}; diff --git a/addons/parachute/CfgVehicles.hpp b/addons/parachute/CfgVehicles.hpp index e734962a0e..402ff9497e 100644 --- a/addons/parachute/CfgVehicles.hpp +++ b/addons/parachute/CfgVehicles.hpp @@ -9,23 +9,18 @@ class CfgVehicles { }; }; - class Man; - class CAManBase: Man { - class ACE_SelfActions { - class ACE_CutParachute { - displayName = CSTRING(CutParachute); - exceptions[] = {"isNotInside"}; - condition = QUOTE([_player] call FUNC(checkCutParachute)); - statement = QUOTE([_player] call FUNC(cutParachute)); - showDisabled = 0; - priority = 2.9; - icon = QPATHTOF(UI\cut_ca.paa); - }; - }; - }; - class Helicopter; class ParachuteBase: Helicopter { + class ACE_SelfActions { + class ACE_CutParachute { + displayName = CSTRING(CutParachute); + condition = QUOTE(_target getVariable [ARR_2(QQGVAR(canCut),false)]); + statement = QUOTE([ARR_2(_player,_target)] call FUNC(cutParachute)); + showDisabled = 0; + priority = 2.9; + icon = QPATHTOF(UI\cut_ca.paa); + }; + }; MACRO_HASRESERVE }; class ParachuteWest: ParachuteBase { @@ -43,13 +38,13 @@ class CfgVehicles { class NonSteerable_Parachute_F: Parachute { MACRO_HASRESERVE }; - class Paraglide: ParachuteWest{ + class Paraglide: ParachuteWest { MACRO_HASRESERVE }; - class Steerable_Parachute_F: Paraglide{ + class Steerable_Parachute_F: Paraglide { MACRO_HASRESERVE }; - class Parachute_02_base_F: parachuteBase { + class Parachute_02_base_F: ParachuteBase { MACRO_HASRESERVE }; class B_Parachute_02_F: Parachute_02_base_F { @@ -98,7 +93,7 @@ class CfgVehicles { ace_reserveParachute = ""; ace_hasReserveParachute = 0; }; - + class ACE_NonSteerableReserveParachute: ACE_ReserveParachute { ParachuteClass = "NonSteerable_Parachute_F"; }; diff --git a/addons/parachute/XEH_PREP.hpp b/addons/parachute/XEH_PREP.hpp index c2567b8468..6edd22c260 100644 --- a/addons/parachute/XEH_PREP.hpp +++ b/addons/parachute/XEH_PREP.hpp @@ -1,9 +1,5 @@ - -PREP(doLanding); -PREP(handleInfoDisplayChanged); -PREP(hideAltimeter); -PREP(onEachFrame); -PREP(showAltimeter); PREP(cutParachute); -PREP(checkCutParachute); -PREP(storeParachute); +PREP(handleInfoDisplayChanged); +PREP(handleReserve); +PREP(hideAltimeter); +PREP(showAltimeter); diff --git a/addons/parachute/XEH_postInit.sqf b/addons/parachute/XEH_postInit.sqf index 1570d3cd98..73ea9276a1 100644 --- a/addons/parachute/XEH_postInit.sqf +++ b/addons/parachute/XEH_postInit.sqf @@ -19,25 +19,22 @@ if (!hasInterface) exitWith {}; ["ACE3 Equipment", QGVAR(showAltimeter), localize LSTRING(showAltimeter), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if (!('ACE_Altimeter' in assignedItems ace_player)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(AltimeterActive), false])) then { + if ( + !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) || + {!('ACE_Altimeter' in assignedItems ACE_player)} + ) exitWith { false }; + + if !(GETMVAR(GVAR(AltimeterActive),false)) then { [ACE_player] call FUNC(showAltimeter); } else { call FUNC(hideAltimeter); }; + true }, {false}, [24, [false, false, false]], false] call CBA_fnc_addKeybind; -GVAR(PFH) = false; -["vehicle",{ - if (!GVAR(PFH) && {(vehicle ACE_player) isKindOf "ParachuteBase"}) then { - GVAR(PFH) = true; - [FUNC(onEachFrame), 0.1, []] call CALLSTACK(CBA_fnc_addPerFrameHandler); - }; -}] call CBA_fnc_addPlayerEventHandler; +// Handle reserve chute based on current backpack (fires when parachute opens too) +["loadout", FUNC(handleReserve), true] call CBA_fnc_addPlayerEventHandler; -// don't show speed and height when in expert mode +// Don't show vanilla speed and height when in expert mode ["ace_infoDisplayChanged", {_this call FUNC(handleInfoDisplayChanged)}] call CBA_fnc_addEventHandler; - -["loadout", FUNC(storeParachute)] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/parachute/XEH_preInit.sqf b/addons/parachute/XEH_preInit.sqf index 227fa9e38c..e5fa52644b 100644 --- a/addons/parachute/XEH_preInit.sqf +++ b/addons/parachute/XEH_preInit.sqf @@ -21,4 +21,14 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +[ + QGVAR(hideAltimeter), + "CHECKBOX", + [LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)], + format ["ACE %1", localize ELSTRING(common,DisplayName)], + true, + false, + {[QGVAR(hideAltimeter), _this, false] call EFUNC(common,cbaSettings_settingChanged)} +] call cba_settings_fnc_init; + ADDON = true; diff --git a/addons/parachute/XEH_respawn.sqf b/addons/parachute/XEH_respawn.sqf deleted file mode 100644 index 31e3ff2ae2..0000000000 --- a/addons/parachute/XEH_respawn.sqf +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Author: joko // Jonas - * Reset the parachute system. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * None - * - * Public: No - */ -#include "script_component.hpp" -ACE_player setVariable [QGVAR(chuteIsCut), false]; \ No newline at end of file diff --git a/addons/parachute/functions/fnc_checkCutParachute.sqf b/addons/parachute/functions/fnc_checkCutParachute.sqf deleted file mode 100644 index 67fd842f92..0000000000 --- a/addons/parachute/functions/fnc_checkCutParachute.sqf +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Author: joko // Jonas - * Reset the parachute system. - * - * Arguments: - * 0: Object - * - * Return Value: - * Boolean - * - * Example: - * [player] call FUNC(checkCutParachute); - * - * Public: No - */ -#include "script_component.hpp" -params ["_unit"]; -(vehicle _unit isKindOf 'ParachuteBase' && !(_unit getVariable [QGVAR(chuteIsCut),false]) && (_unit getVariable [QGVAR(hasReserve),false])) diff --git a/addons/parachute/functions/fnc_cutParachute.sqf b/addons/parachute/functions/fnc_cutParachute.sqf index 34b808d9d8..af56235ba0 100644 --- a/addons/parachute/functions/fnc_cutParachute.sqf +++ b/addons/parachute/functions/fnc_cutParachute.sqf @@ -1,6 +1,6 @@ /* - * Author: joko // Jonas - * Cut Parachute and delete Old + * Author: joko, Jonas, SilentSpike + * Perform the cut parachute action (move unit out and delete) * * Arguments: * 0: Object @@ -9,13 +9,11 @@ * None * * Example: - * [player] call FUNC(cutParachute); + * [player, vehicle player] call FUNC(cutParachute); * * Public: No */ #include "script_component.hpp" -params ["_unit"]; -private _vehicle = vehicle _unit; -_unit action ["GetOut", _vehicle]; -deleteVehicle _vehicle; -_unit setVariable [QGVAR(chuteIsCut), true, true]; +params ["_unit", "_parachute"]; +_unit action ["GetOut", _parachute]; +deleteVehicle _parachute; diff --git a/addons/parachute/functions/fnc_doLanding.sqf b/addons/parachute/functions/fnc_doLanding.sqf deleted file mode 100644 index b80bc44d00..0000000000 --- a/addons/parachute/functions/fnc_doLanding.sqf +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Author: Garth 'L-H' de Wet - * Performs the landing animation fix - * - * Arguments: - * 0: unit - * - * Return Value: - * None - * - * Example: - * [player] call ACE_Parachute_fnc_doLanding; - * - * Public: No - */ -#include "script_component.hpp" - -params ["_unit"]; - -GVAR(PFH) = false; - -[_unit, "AmovPercMevaSrasWrflDf_AmovPknlMstpSrasWrflDnon", 2] call EFUNC(common,doAnimation); - -_unit setVariable [QGVAR(chuteIsCut), false, true]; - -[{ - (_this select 0) params ["_time", "_unit"]; - - if (CBA_missionTime > _time + 1) then { - [_unit, "Crouch"] call EFUNC(common,doGesture); - [_this select 1] call CALLSTACK(CBA_fnc_removePerFrameHandler); - }; -}, 1, [CBA_missionTime, _unit]] call CALLSTACK(CBA_fnc_addPerFrameHandler); diff --git a/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf b/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf index 7bb500912e..644bd29c94 100644 --- a/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf +++ b/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf @@ -18,7 +18,7 @@ params ["_dialog", "_type"]; // don't do anything in noob mode -if (cadetMode) exitWith {}; +if (!GVAR(hideAltimeter)) exitWith {}; switch (_type) do { case ("Parachute"): { diff --git a/addons/parachute/functions/fnc_handleReserve.sqf b/addons/parachute/functions/fnc_handleReserve.sqf new file mode 100644 index 0000000000..7b92d8e9f4 --- /dev/null +++ b/addons/parachute/functions/fnc_handleReserve.sqf @@ -0,0 +1,42 @@ +/* + * Author: joko, Jonas, SilentSpike + * Cache reserve parachute on player unit when their inventory changes and add it when they open their parachute + * + * Arguments: + * None + * + * Return Value: + * 0: Unit + * + * Example: + * [player] call ace_parachute_fnc_handleReserve + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_unit"]; +private _backpack = backpack _unit; + +if ( + _backpack == "" && + {(vehicle _unit) isKindOf "ParachuteBase"} && + {GETVAR(_unit,GVAR(hasReserve),false)} +) then { + // Case where unit has just opened parachute and reserve should be added + _unit addBackpackGlobal GETVAR(_unit,GVAR(backpackClass),"ACE_NonSteerableReserveParachute"); + SETVAR(vehicle _unit,GVAR(canCut),true); // Mark the parachute cuttable since reserve is present +} else { + // Case where inventory has changed otherwise (including when reserve is added) + private _backpackCfg = configFile >> "CfgVehicles" >> _backpack; + private _hasReserve = getNumber (_backpackCfg >> "ace_hasReserveParachute") == 1; + + // Cache reserve parachute state and class when backpack changes + SETVAR(_unit,GVAR(hasReserve),_hasReserve); + if (_hasReserve) then { + SETVAR(_unit,GVAR(backpackClass),getText (_backpackCfg >> "ace_reserveParachute")); + } else { + SETVAR(_unit,GVAR(backpackClass),""); + }; +}; diff --git a/addons/parachute/functions/fnc_hideAltimeter.sqf b/addons/parachute/functions/fnc_hideAltimeter.sqf index dd7d29fce4..50f1eac503 100644 --- a/addons/parachute/functions/fnc_hideAltimeter.sqf +++ b/addons/parachute/functions/fnc_hideAltimeter.sqf @@ -15,4 +15,4 @@ */ #include "script_component.hpp" GVAR(AltimeterActive) = false; -(["ACE_Altimeter"] call BIS_fnc_rscLayer) cutText ["","PLAIN",0,true]; +"ACE_Altimeter" cutText ["","PLAIN",0,true]; diff --git a/addons/parachute/functions/fnc_onEachFrame.sqf b/addons/parachute/functions/fnc_onEachFrame.sqf deleted file mode 100644 index 0c6809b648..0000000000 --- a/addons/parachute/functions/fnc_onEachFrame.sqf +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Author: Garth 'L-H' de Wet - * Checks whether the unit should preform landing. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ACE_Parachute_fnc_onEachFrame; - * - * Public: No - */ -#include "script_component.hpp" -private _player = ACE_player; -if (!GVAR(PFH)) exitWith {[(_this select 1)] call CALLSTACK(CBA_fnc_removePerFrameHandler);}; -if (isNull _player) exitWith {[(_this select 1)] call CALLSTACK(CBA_fnc_removePerFrameHandler);GVAR(PFH) = false;}; -if !((vehicle _player) isKindOf "ParachuteBase") exitWith {[(_this select 1)] call CALLSTACK(CBA_fnc_removePerFrameHandler);GVAR(PFH) = false;}; -if (isTouchingGround _player) exitWith {[(_this select 1)] call CALLSTACK(CBA_fnc_removePerFrameHandler);GVAR(PFH) = false;}; - -private ["_pos"]; -_pos = getPosASL (vehicle _player); - -if ((lineIntersects [_pos, _pos vectorAdd [0,0,-0.5], vehicle _player, _player]) || {((ASLtoATL _pos) select 2) < 0.75}) then { - [(_this select 1)] call CALLSTACK(CBA_fnc_removePerFrameHandler); - GVAR(PFH) = false; -// I believe this will not work for Zeus units. - deleteVehicle (vehicle _player); - [_player] call FUNC(doLanding); -}; diff --git a/addons/parachute/functions/fnc_showAltimeter.sqf b/addons/parachute/functions/fnc_showAltimeter.sqf index b8ee8add6d..c93775e135 100644 --- a/addons/parachute/functions/fnc_showAltimeter.sqf +++ b/addons/parachute/functions/fnc_showAltimeter.sqf @@ -17,34 +17,33 @@ params ["_unit"]; -(["ACE_Altimeter"] call BIS_fnc_rscLayer) cutRsc ["ACE_Altimeter", "PLAIN", 0, true]; +"ACE_Altimeter" cutRsc ["ACE_Altimeter", "PLAIN", 0, true]; if (isNull (uiNamespace getVariable ["ACE_Altimeter", displayNull])) exitWith {}; GVAR(AltimeterActive) = true; [{ - if (!GVAR(AltimeterActive)) exitWith {[_this select 1] call CALLSTACK(CBA_fnc_removePerFrameEventHandler)}; + if (!GVAR(AltimeterActive)) exitWith {[_this select 1] call CBA_fnc_removePerFrameEventHandler}; disableSerialization; (_this select 0) params ["_display", "_unit", "_oldHeight", "_prevTime"]; - if !("ACE_Altimeter" in assignedItems _unit) exitWith {[_this select 1] call CALLSTACK(CBA_fnc_removePerFrameEventHandler); call FUNC(hideAltimeter)}; + if !("ACE_Altimeter" in assignedItems _unit) exitWith {[_this select 1] call CBA_fnc_removePerFrameEventHandler; call FUNC(hideAltimeter)}; - private ["_height", "_hour", "_minute", "_descentRate","_HeightText", "_DecendRate", "_TimeText", "_curTime", "_timeDiff"]; + private _HeightText = _display displayCtrl 1100; + private _DecendRate = _display displayCtrl 1000; + private _TimeText = _display displayCtrl 1001; - _HeightText = _display displayCtrl 1100; - _DecendRate = _display displayCtrl 1000; - _TimeText = _display displayCtrl 1001; - _hour = floor daytime; - _minute = floor ((daytime - _hour) * 60); + private _hour = floor daytime; + private _minute = floor ((daytime - _hour) * 60); - _height = ((getPosASL _unit) select 2) + EGVAR(common,mapAltitude); - _curTime = CBA_missionTime; - _timeDiff = _curTime - _prevTime; - _descentRate = if(_timeDiff > 0) then {floor((_oldHeight - _height) / _timeDiff)} else {0}; + private _height = ((getPosASL _unit) select 2) + EGVAR(common,mapAltitude); + private _curTime = CBA_missionTime; + private _timeDiff = _curTime - _prevTime; + private _descentRate = if (_timeDiff > 0) then {floor((_oldHeight - _height) / _timeDiff)} else {0}; - _TimeText ctrlSetText (format ["%1:%2",[_hour, 2] call EFUNC(common,numberToDigitsString),[_minute, 2] call EFUNC(common,numberToDigitsString)]); - _HeightText ctrlSetText (format ["%1", floor(_height)]); + _TimeText ctrlSetText (format ["%1:%2", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber]); + _HeightText ctrlSetText (format ["%1", floor _height]); _DecendRate ctrlSetText (format ["%1", _descentRate max 0]); (_this select 0) set [2, _height]; (_this select 0) set [3, _curTime]; -}, 0.2, [uiNamespace getVariable ["ACE_Altimeter", displayNull], _unit,floor ((getPosASL _unit) select 2), CBA_missionTime]] call CALLSTACK(CBA_fnc_addPerFrameHandler); +}, 0.2, [uiNamespace getVariable ["ACE_Altimeter", displayNull], _unit, floor ((getPosASL _unit) select 2), CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/parachute/functions/fnc_storeParachute.sqf b/addons/parachute/functions/fnc_storeParachute.sqf deleted file mode 100644 index adc513fbf9..0000000000 --- a/addons/parachute/functions/fnc_storeParachute.sqf +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Author: joko // Jonas - * Add the Reserve Parachute to Units or Save Backpack if is a Parachute in Unit - * - * Arguments: - * None - * - * Return Value: - * 0: Unit - * - * Example: - * call ace_parachute_fnc_storeParachute - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_unit"]; -private _backpack = backpack _unit; - -if ((vehicle _unit) isKindOf "ParachuteBase" && {backpack _unit == ""} && {!(_unit getVariable [QGVAR(chuteIsCut),false])} && {_unit getVariable [QGVAR(hasReserve),false]}) then { - _unit addBackpackGlobal (_unit getVariable[QGVAR(backpackClass),"ACE_NonSteerableParachute"]); -} else { - if ((getNumber(configFile >> "CfgVehicles" >> _backpack >> "ace_hasReserveParachute")) == 1) then { - _unit setVariable[QGVAR(backpackClass),getText(configFile >> "CfgVehicles" >> _backpack >> "ace_reserveParachute"),true]; - }; - if (!(_unit getVariable [QGVAR(chuteIsCut),false]) && {!(animationState _unit == 'para_pilot')}) then { - _unit setVariable [QGVAR(hasReserve),[false,true] select (getNumber(configFile >> "CfgVehicles" >> _backpack >> "ace_hasReserveParachute")),true]; - }; -}; diff --git a/addons/parachute/stringtable.xml b/addons/parachute/stringtable.xml index c57f50b54f..820aa822d1 100644 --- a/addons/parachute/stringtable.xml +++ b/addons/parachute/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -46,8 +46,8 @@ Usado para mostrar altura, taxa de descida e o tempo. 高度や降下率、時間を見るのに使います。 높이와, 하강속도 그리고 시간을 보여줍니다. - 用于显示高度, 下降率和时间. - 用於顯示高度, 下降率和時間. + 用于显示高度,下降率和时间。 + 用於顯示高度,下降率和時間。 Non-Steerable Parachute @@ -97,5 +97,17 @@ 备用降落伞 備用降落傘 + + Hide Freefall Altimeter + Freifall-Höhenmesser verstecken + 降下時に高度計を非表示 + Nascondi Altimetro in Caduta Libera + + + Hides the altitude and speed shown while free falling or parachuting. + Blendet den Höhen- und Geschwindigkeitsmesser während des Fallschirmspringens aus. + 自由降下時かパラシュート中に高度と速度を非表示にします。 + Nasconde l'altitudine e la velocità mostrate durante la caduta libera o paracadutandosi. + diff --git a/addons/pylons/$PBOPREFIX$ b/addons/pylons/$PBOPREFIX$ new file mode 100644 index 0000000000..4da952ebb7 --- /dev/null +++ b/addons/pylons/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\pylons diff --git a/addons/pylons/ACE_Settings.hpp b/addons/pylons/ACE_Settings.hpp new file mode 100644 index 0000000000..242b5c472d --- /dev/null +++ b/addons/pylons/ACE_Settings.hpp @@ -0,0 +1,46 @@ +class ACE_Settings { + class GVAR(enabled) { + category = CSTRING(Category_Pylons); + displayName = CSTRING(Enabled); + description = CSTRING(Enabled_description); + value = 1; + typeName = "BOOL"; + }; + class GVAR(rearmNewPylons) { + category = CSTRING(Category_Pylons); + displayName = CSTRING(RearmNewPylons); + description = CSTRING(RearmNewPylons_description); + value = 0; + typeName = "BOOL"; + }; + class GVAR(searchDistance) { + category = CSTRING(Category_Pylons); + displayName = CSTRING(SearchDistance); + description = CSTRING(SearchDistance_description); + value = 15; + typeName = "SCALAR"; + sliderSettings[] = {0, 50, 15, 1}; + }; + class GVAR(timePerPylon) { + category = CSTRING(Category_Pylons); + displayName = CSTRING(TimePerPylon); + description = CSTRING(TimePerPylon_description); + value = 5; + typeName = "SCALAR"; + sliderSettings[] = {0, 10, 5, 1}; + }; + class GVAR(requireEngineer) { + category = CSTRING(Category_Pylons); + displayName = CSTRING(RequireEngineer); + description = CSTRING(RequireEngineer_description); + value = 0; + typeName = "BOOL"; + }; + class GVAR(requireToolkit) { + category = CSTRING(Category_Pylons); + displayName = CSTRING(RequireToolkit); + description = CSTRING(RequireToolkit_description); + value = 1; + typeName = "BOOL"; + }; +}; diff --git a/addons/pylons/CfgEventHandlers.hpp b/addons/pylons/CfgEventHandlers.hpp new file mode 100644 index 0000000000..0d3301d6e0 --- /dev/null +++ b/addons/pylons/CfgEventHandlers.hpp @@ -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 { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/pylons/README.md b/addons/pylons/README.md new file mode 100644 index 0000000000..b2b6d9d064 --- /dev/null +++ b/addons/pylons/README.md @@ -0,0 +1,11 @@ +ace_pylons +============ + +Adds an interface that allows players to configure aircraft pylons. + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [654wak654](https://github.com/654wak654) diff --git a/addons/pylons/XEH_PREP.hpp b/addons/pylons/XEH_PREP.hpp new file mode 100644 index 0000000000..56388b09b4 --- /dev/null +++ b/addons/pylons/XEH_PREP.hpp @@ -0,0 +1,13 @@ +PREP(canConfigurePylons); +PREP(configurePylons); +PREP(handleDisconnect); +PREP(onButtonApply); +PREP(onButtonClose); +PREP(onButtonDelete); +PREP(onButtonLoad); +PREP(onButtonSave); +PREP(onButtonTurret); +PREP(onComboSelChange); +PREP(onNameChange); +PREP(onPylonMirror); +PREP(showDialog); diff --git a/addons/pylons/XEH_postInit.sqf b/addons/pylons/XEH_postInit.sqf new file mode 100644 index 0000000000..8dae8d4552 --- /dev/null +++ b/addons/pylons/XEH_postInit.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" + +["ace_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; + + private _filter = "isClass (_x >> 'Components' >> 'TransportPylonsComponent') && {(getNumber (_x >> 'scope')) > 0}"; + GVAR(aircraftWithPylons) = (_filter configClasses (configFile >> "CfgVehicles")) apply {configName _x}; + { + [_x, "init", { + params ["_aircraft"]; + + private _loadoutAction = [ + QGVAR(loadoutAction), + localize LSTRING(ConfigurePylons), + "", + {[_target] call FUNC(showDialog)}, + { + private _vehicles = nearestObjects [_target, ["Air", "LandVehicle", "Slingload_base_F", "ReammoBox_F"], GVAR(searchDistance) + 10]; + private _filter = ["transportAmmo", QEGVAR(rearm,defaultSupply)] select (["ace_rearm"] call EFUNC(common,isModLoaded)); + private _rearmVehicles = {(getNumber (configFile >> "CfgVehicles" >> typeOf _x >> _filter)) > 0} count _vehicles; + + (_rearmVehicles > 0 && {[ace_player, _target] call FUNC(canConfigurePylons)}) + } + ] call EFUNC(interact_menu,createAction); + + [_aircraft, 0, ["ACE_MainActions"], _loadoutAction] call EFUNC(interact_menu,addActionToObject); + }, false, [], true] call CBA_fnc_addClassEventHandler; + } forEach GVAR(aircraftWithPylons); + + [QGVAR(setPylonLoadOutEvent), { + params ["_aircraft", "_pylonIndex", "_pylon", "_turret"]; + _aircraft setPylonLoadOut [_pylonIndex, _pylon, false, _turret]; + }] call CBA_fnc_addEventHandler; + + [QGVAR(setAmmoOnPylonEvent), { + params ["_aircraft", "_pylonIndex", "_count"]; + _aircraft setAmmoOnPylon [_pylonIndex, _count]; + }] call CBA_fnc_addEventHandler; + + if (isServer) then { + GVAR(currentAircraftNamespace) = true call CBA_fnc_createNamespace; + publicVariable QGVAR(currentAircraftNamespace); + + addMissionEventHandler ["HandleDisconnect", LINKFUNC(handleDisconnect)]; + }; + + GVAR(searchDistanceSqr) = GVAR(searchDistance) ^ 2; +}] call CBA_fnc_addEventHandler; diff --git a/addons/pylons/XEH_preInit.sqf b/addons/pylons/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/pylons/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/pylons/XEH_preStart.sqf b/addons/pylons/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/pylons/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/optionals/server/config.cpp b/addons/pylons/config.cpp similarity index 64% rename from optionals/server/config.cpp rename to addons/pylons/config.cpp index c27ed4a341..fc7159e08b 100644 --- a/optionals/server/config.cpp +++ b/addons/pylons/config.cpp @@ -6,14 +6,14 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_interact_menu"}; author = ECSTRING(common,ACETeam); - authors[] = {"Glowbal"}; + authors[] = {"654wak654"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; -class ACE_ServerSettings { - #include "\userconfig\ace\serverconfig.hpp" -}; +#include "ACE_Settings.hpp" +#include "CfgEventHandlers.hpp" +#include "menu.hpp" diff --git a/addons/pylons/functions/fnc_canConfigurePylons.sqf b/addons/pylons/functions/fnc_canConfigurePylons.sqf new file mode 100644 index 0000000000..c679b9592d --- /dev/null +++ b/addons/pylons/functions/fnc_canConfigurePylons.sqf @@ -0,0 +1,27 @@ +/* + * Author: 654wak654 + * Checks if given unit can access the pylon configuration dialog for the given aircraft. + * + * Arguments: + * 0: Unit + * 1: Aircraft + * + * Return Value: + * Unit can configure the aircraft's pylons + * + * Example: + * [ace_player, cursorObject] call ace_pylons_fnc_canConfigurePylons + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_aircraft"]; + +if (GVAR(requireEngineer) && {!([_unit] call EFUNC(common,isEngineer))}) exitWith {false}; + +if (GVAR(requireToolkit) && {!([_unit, "ToolKit"] call EFUNC(common,hasItem))}) exitWith {false}; + +if ((_unit distanceSqr _aircraft) > GVAR(searchDistanceSqr)) exitWith {false}; + +[_unit, _aircraft] call EFUNC(common,canInteractWith) diff --git a/addons/pylons/functions/fnc_configurePylons.sqf b/addons/pylons/functions/fnc_configurePylons.sqf new file mode 100644 index 0000000000..2fbc91e949 --- /dev/null +++ b/addons/pylons/functions/fnc_configurePylons.sqf @@ -0,0 +1,74 @@ +/* + * Author: 654wak654 + * Recursively shows the progress bar for each configured pylon. + * + * Arguments: + * 0: Indexes of pylons to configure + * 1: Current index + * + * Return Value: + * None + * + * Example: + * [_pylonsToConfigure, 0] call ace_pylons_fnc_configurePylons + * + * Public: No + */ +#include "script_component.hpp" + +params ["_pylonsToConfigure", "_currentPylon"]; + +if (_currentPylon == count _pylonsToConfigure) exitWith {}; + +// TODO: Animation and sound +[ + [GVAR(timePerPylon), 0] select GVAR(isCurator), + _this, + { + (_this select 0) params ["_pylonsToConfigure", "_currentPylon"]; + private _pylonIndex = _pylonsToConfigure select _currentPylon; + + // Remove the weapon of current pylon from aircraft IF weapon is only on this pylon + private _currentPylonMagazine = (getPylonMagazines GVAR(currentAircraft)) select _pylonIndex; + if (_currentPylonMagazine != "") then { + private _allPylonWeapons = (getPylonMagazines GVAR(currentAircraft)) apply { + getText (configFile >> "CfgMagazines" >> _x >> "pylonWeapon") + }; + private _pylonWeapon = _allPylonWeapons select _pylonIndex; + if (({_x == _pylonWeapon} count _allPylonWeapons) == 1) then { + GVAR(currentAircraft) removeWeaponGlobal _pylonWeapon; + }; + }; + + private _combo = GVAR(comboBoxes) select _pylonIndex select 0; + private _pylonMagazine = _combo lbData (lbCurSel _combo); + private _turret = (GVAR(comboBoxes) select _pylonIndex select 2) getVariable [QGVAR(turret), []]; + if (_turret isEqualTo [-1]) then {_turret = [];}; + + [ + QGVAR(setPylonLoadOutEvent), + [GVAR(currentAircraft), _pylonIndex + 1, _pylonMagazine, _turret] + ] call CBA_fnc_globalEvent; + + private _count = if (GVAR(rearmNewPylons) || {GVAR(isCurator)}) then { + getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count") + } else { + 0 + }; + + [ + QGVAR(setAmmoOnPylonEvent), + [GVAR(currentAircraft), _pylonIndex + 1, _count], + GVAR(currentAircraft) + ] call CBA_fnc_targetEvent; + + [_pylonsToConfigure, _currentPylon + 1] call FUNC(configurePylons); + }, + { + (_this select 0) params ["", "_currentPylon"]; + [format [localize LSTRING(Stopped), _currentPylon + 1], false, 5] call EFUNC(common,displayText); + }, + format [localize LSTRING(ReplacingPylon), _currentPylon + 1, count _pylonsToConfigure], + {GVAR(isCurator) || {(ace_player distanceSqr GVAR(currentAircraft)) <= GVAR(searchDistanceSqr)}}, + ["isNotInZeus"] +] call EFUNC(common,progressBar); diff --git a/addons/pylons/functions/fnc_handleDisconnect.sqf b/addons/pylons/functions/fnc_handleDisconnect.sqf new file mode 100644 index 0000000000..f255b36535 --- /dev/null +++ b/addons/pylons/functions/fnc_handleDisconnect.sqf @@ -0,0 +1,25 @@ +/* + * Author: 654wak654 + * Cleans up pylons on client disconnect. + * + * Arguments: + * 0: Player + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_handleDisconnect + * + * Public: No + */ +#include "script_component.hpp" + +params ["", "", "_uid"]; + +private _aircraft = GVAR(currentAircraftNamespace) getVariable ["_uid", objNull]; +if (!isNull _aircraft) then { + _aircraft setVariable [QGVAR(currentUser), objNull, true]; + + GVAR(currentAircraftNamespace) setVariable [_uid, nil, true]; // Remove var from namespace, no need to keep objNull +}; diff --git a/addons/pylons/functions/fnc_onButtonApply.sqf b/addons/pylons/functions/fnc_onButtonApply.sqf new file mode 100644 index 0000000000..ae27e98d4c --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonApply.sqf @@ -0,0 +1,46 @@ +/* + * Author: 654wak654 + * Starts the pylon configuration. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonApply + * + * Public: No + */ +#include "script_component.hpp" + +// Check for FRIES change +private _checkbox = CONTROL(ID_DIALOG) ID_CHECKBOX_FRIES; +if (ctrlShown _checkbox && {!((cbChecked _checkbox) isEqualTo (_checkbox getVariable QGVAR(originalState)))}) then { + if (cbChecked _checkbox) then { + [GVAR(currentAircraft)] call EFUNC(fastroping,equipFRIES); + } else { + [GVAR(currentAircraft)] call EFUNC(fastroping,cutRopes); + private _fries = GVAR(currentAircraft) getVariable [QEGVAR(fastroping,FRIES), objNull]; + deleteVehicle _fries; + }; + _checkbox setVariable [QGVAR(originalState), cbChecked _checkbox]; +}; + +private _pylonsToConfigure = []; +{ + // Pick combo boxes where current selection doesn't match original selection + if ((lbCurSel (_x select 0)) != (_x select 3)) then { + _pylonsToConfigure pushBack _forEachIndex; + }; +} forEach GVAR(comboBoxes); + +if (_pylonsToConfigure isEqualTo []) exitWith {}; + +[_pylonsToConfigure, 0] call FUNC(configurePylons); + +// As a zeus you expect module dialogs to close once you click apply +if (GVAR(isCurator)) then { + call FUNC(onButtonClose); +}; diff --git a/addons/pylons/functions/fnc_onButtonClose.sqf b/addons/pylons/functions/fnc_onButtonClose.sqf new file mode 100644 index 0000000000..fa06f3d506 --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonClose.sqf @@ -0,0 +1,20 @@ +/* + * Author: 654wak654 + * Handles the closing of the dialog. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonClose + * + * Public: No + */ +#include "script_component.hpp" + +GVAR(currentAircraft) setVariable [QGVAR(currentUser), objNull, true]; +GVAR(currentAircraftNamespace) setVariable [getPlayerUID ace_player, nil, true]; // Remove var from namespace, no need to keep objNull +closeDialog 2; diff --git a/addons/pylons/functions/fnc_onButtonDelete.sqf b/addons/pylons/functions/fnc_onButtonDelete.sqf new file mode 100644 index 0000000000..8d1fdee6de --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonDelete.sqf @@ -0,0 +1,29 @@ +/* + * Author: 654wak654 + * Deletes the selected pylon configuration from profileNamespace. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonDelete + * + * Public: No + */ +#include "script_component.hpp" + +private _loadoutName = lbText [ID_LIST_LOADOUTS, lbCurSel ID_LIST_LOADOUTS]; + +lbDelete [ID_LIST_LOADOUTS, lbCurSel ID_LIST_LOADOUTS]; + +private _aircraftLoadouts = profileNamespace getVariable [QGVAR(aircraftLoadouts), []]; +private _index = { + if ((_x select 0) isEqualTo _loadoutName && {(_x select 3) isEqualTo typeOf GVAR(currentAircraft)}) exitWith { + _forEachIndex + }; +} forEach _aircraftLoadouts; +_aircraftLoadouts deleteAt _index; +profileNamespace setVariable [QGVAR(aircraftLoadouts), _aircraftLoadouts]; diff --git a/addons/pylons/functions/fnc_onButtonLoad.sqf b/addons/pylons/functions/fnc_onButtonLoad.sqf new file mode 100644 index 0000000000..9092d0a910 --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonLoad.sqf @@ -0,0 +1,58 @@ +/* + * Author: 654wak654 + * Loads selected pylon configuration from either config or profileNamespace. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonLoad + * + * Public: No + */ +#include "script_component.hpp" + +[false] call FUNC(onPylonMirror); +(CONTROL(ID_DIALOG) ID_CHECKBOX_MIRROR) cbSetChecked false; + +private _loadoutName = ctrlText ID_EDIT_LOADOUTNAME; +private _fnc_setSelections = { + params ["_mags", "_turrets"]; + + { + _x params ["_combo", "_mirroredIndex", "_button"]; + + private _index = 0; + for "_i" from 1 to ((lbSize _combo) - 1) do { + if ((_combo lbData _i) == (_mags param [_forEachIndex, ""])) exitWith { + _index = _i; + }; + }; + _combo lbSetCurSel _index; + + [_button, false, _turrets select _forEachIndex] call FUNC(onButtonTurret); + } forEach GVAR(comboBoxes); +}; + +private _pylonComponent = configFile >> "CfgVehicles" >> typeOf GVAR(currentAircraft) >> "Components" >> "TransportPylonsComponent"; +private _loadoutFound = { + if (getText (_x >> "displayName") isEqualTo _loadoutName) exitWith { + // Get default turrets from config + private _turrets = ("true" configClasses (_pylonComponent >> "Pylons")) apply {getArray (_x >> "turret")}; + [getArray (_x >> "attachment"), _turrets] call _fnc_setSelections; + true + }; + false +} forEach ("true" configClasses (_pylonComponent >> "Presets")); + +if (_loadoutFound) exitWith {}; + +private _aircraftLoadouts = profileNamespace getVariable [QGVAR(aircraftLoadouts), []]; +{ + if ((_x select 0) isEqualTo _loadoutName && {(_x select 3) isEqualTo typeOf GVAR(currentAircraft)}) exitWith { + [_x select 1, _x select 2] call _fnc_setSelections; + }; +} forEach _aircraftLoadouts; diff --git a/addons/pylons/functions/fnc_onButtonSave.sqf b/addons/pylons/functions/fnc_onButtonSave.sqf new file mode 100644 index 0000000000..c20c8928ec --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonSave.sqf @@ -0,0 +1,37 @@ +/* + * Author: 654wak654 + * Saves the selected pylon configuration to profileNamespace. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonSave + * + * Public: No + */ +#include "script_component.hpp" + +private _loadoutName = ctrlText ID_EDIT_LOADOUTNAME; +private _aircraftLoadouts = profileNamespace getVariable [QGVAR(aircraftLoadouts), []]; +private _loadoutPylons = GVAR(comboBoxes) apply {(_x select 0) lbData (lbCurSel (_x select 0))}; +private _turretOwners = GVAR(comboBoxes) apply {(_x select 2) getVariable [QGVAR(turret), [-1]]}; + +private _found = false; +{ + if ((_x select 0) isEqualTo _loadoutName && {(_x select 2) isEqualTo typeOf GVAR(currentAircraft)}) exitWith { + _aircraftLoadouts set [_forEachIndex, [_loadoutName, _loadoutPylons, _turretOwners, typeOf GVAR(currentAircraft)]]; + _found = true; + }; +} forEach _aircraftLoadouts; + +if (!_found) then { + private _index = lbAdd [ID_LIST_LOADOUTS, _loadoutName]; + lbSetCurSel [ID_LIST_LOADOUTS, _index]; + _aircraftLoadouts pushBack [_loadoutName, _loadoutPylons, _turretOwners, typeOf GVAR(currentAircraft)]; +}; + +profileNamespace setVariable [QGVAR(aircraftLoadouts), _aircraftLoadouts]; diff --git a/addons/pylons/functions/fnc_onButtonTurret.sqf b/addons/pylons/functions/fnc_onButtonTurret.sqf new file mode 100644 index 0000000000..4554075c37 --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonTurret.sqf @@ -0,0 +1,48 @@ +/* + * Author: 654wak654 + * Handles init and click events of turret switch buttons. + * + * Arguments: + * 0: Button + * 1: Should switch icons + * 2: Turret path + * + * Return Value: + * None + * + * Example: + * [_button, true, []] call ace_pylons_fnc_onButtonTurret + * + * Public: No + */ +#include "script_component.hpp" + +params ["_ctrl", "_switch", "_turret"]; + +if (_switch) then { + _turret = [[0], [-1]] select ((_ctrl getVariable QGVAR(turret)) isEqualTo [0]); + + { + _x params ["", "_mirroredIndex", "_button"]; + if (_ctrl == _button) exitWith { + if (_mirroredIndex == -1) then { + private _indexOf = _forEachIndex; + { + _x params ["", "_mirroredIndex", "_button"]; + if (_mirroredIndex == _indexOf && {!ctrlEnabled _button}) exitWith { + [_button, false, _turret] call FUNC(onButtonTurret); + }; + } forEach GVAR(comboBoxes); + }; + }; + } forEach GVAR(comboBoxes); +}; +_ctrl setVariable [QGVAR(turret), _turret]; + +if (_turret isEqualTo [-1]) then { + _ctrl ctrlSetText "a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_driver_ca.paa"; + _ctrl ctrlSetTooltip localize "str_driver"; +} else { + _ctrl ctrlSetText "a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_gunner_ca.paa"; + _ctrl ctrlSetTooltip localize "str_gunner"; +}; diff --git a/addons/pylons/functions/fnc_onComboSelChange.sqf b/addons/pylons/functions/fnc_onComboSelChange.sqf new file mode 100644 index 0000000000..97130ea54d --- /dev/null +++ b/addons/pylons/functions/fnc_onComboSelChange.sqf @@ -0,0 +1,38 @@ +/* + * Author: 654wak654 + * Handles various UI changes when a combobox' selection changes. + * + * Arguments: + * 0: Combobox + * 1: Selected index + * + * Return Value: + * None + * + * Example: + * [_combo, 5] call ace_pylons_fnc_onComboSelChange + * + * Public: No + */ +#include "script_component.hpp" + +params ["_ctrl", "_index"]; + +{ + _x params ["_combo", "_mirroredIndex", "", "_originalIndex"]; + if (_ctrl == _combo) exitWith { + if (_mirroredIndex == -1) then { + private _indexOf = _forEachIndex; + { + _x params ["_combo", "_mirroredIndex"]; + if (_mirroredIndex == _indexOf && {!ctrlEnabled _combo}) exitWith { + _combo lbSetCurSel _index; + }; + } forEach GVAR(comboBoxes); + }; + if !(GVAR(rearmNewPylons) || {GVAR(isCurator)}) then { + private _color = [[0.5, 0.05, 0.05, 1], [0.05, 0.05, 0.05, 1]] select (_index == _originalIndex); + _combo ctrlSetBackgroundColor _color; + }; + }; +} forEach GVAR(comboBoxes); diff --git a/addons/pylons/functions/fnc_onNameChange.sqf b/addons/pylons/functions/fnc_onNameChange.sqf new file mode 100644 index 0000000000..9915aeee70 --- /dev/null +++ b/addons/pylons/functions/fnc_onNameChange.sqf @@ -0,0 +1,25 @@ +/* + * Author: 654wak654 + * Called when current loadout name is changed. + * Prevents default presets from gettings deleted / overwritten. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onNameChange + * + * Public: No + */ +#include "script_component.hpp" + +if ((ctrlText ID_EDIT_LOADOUTNAME) in GVAR(defaultLoadoutNames)) then { + ctrlEnable [ID_BUTTON_SAVE, false]; + ctrlEnable [ID_BUTTON_DELETE, false]; +} else { + ctrlEnable [ID_BUTTON_SAVE, true]; + ctrlEnable [ID_BUTTON_DELETE, true]; +}; diff --git a/addons/pylons/functions/fnc_onPylonMirror.sqf b/addons/pylons/functions/fnc_onPylonMirror.sqf new file mode 100644 index 0000000000..55987b2b94 --- /dev/null +++ b/addons/pylons/functions/fnc_onPylonMirror.sqf @@ -0,0 +1,41 @@ +/* + * Author: 654wak654 + * Called when the "mirror" checkbox on the loadout dialog is checked. + * Changes the comboboxes and buttons to be mirrored / normal. + * + * Arguments: + * 0: Checked status + * + * Return Value: + * None + * + * Example: + * [false] call ace_pylons_fnc_onPylonMirror + * + * Public: No + */ +#include "script_component.hpp" + +params ["_checked"]; + +if (_checked) then { + { + _x params ["_combo", "_mirroredIndex", "_button"]; + + if (_mirroredIndex != -1) then { + private _selection = lbCurSel ((GVAR(comboBoxes) select _mirroredIndex) select 0); + _combo lbSetCurSel _selection; + _combo ctrlEnable false; + + private _mirroredButton = (GVAR(comboBoxes) select _mirroredIndex) select 2; + private _turret = _mirroredButton getVariable [QGVAR(turret), [-1]]; + [_button, false, _turret] call FUNC(onButtonTurret); + _button ctrlEnable false; + }; + } forEach GVAR(comboBoxes); +} else { + { + (_x select 0) ctrlEnable true; + (_x select 2) ctrlEnable true; + } forEach GVAR(comboBoxes); +}; diff --git a/addons/pylons/functions/fnc_showDialog.sqf b/addons/pylons/functions/fnc_showDialog.sqf new file mode 100644 index 0000000000..47b6585c89 --- /dev/null +++ b/addons/pylons/functions/fnc_showDialog.sqf @@ -0,0 +1,155 @@ +/* +* Author: 654wak654 +* Shows the aircraft loadout dialog for given aircraft. +* +* Arguments: +* 0: Aircraft +* 1: Is curator. Disables time and resource requirements. (default: false) +* +* Return Value: +* None +* +* Example: +* [vehicle ace_player] call ace_pylons_fnc_showDialog +* +* Public: Yes +*/ +#include "script_component.hpp" + +params ["_aircraft", ["_isCurator", false]]; + +if (!GVAR(enabled) || {!(typeOf _aircraft in GVAR(aircraftWithPylons))}) exitWith {}; + +private _currentUser = _aircraft getVariable [QGVAR(currentUser), objNull]; +if (!isNull _currentUser) exitWith { + [format [localize LSTRING(InUse), name _currentUser], false, 5] call EFUNC(common,displayText); +}; +_aircraft setVariable [QGVAR(currentUser), ace_player, true]; +GVAR(currentAircraftNamespace) setVariable [getPlayerUID ace_player, _aircraft, true]; + +GVAR(isCurator) = _isCurator; +GVAR(currentAircraft) = _aircraft; + +createDialog QGVAR(DialogLoadout); +private _display = DISPLAY(ID_DIALOG); +_display displayAddEventHandler ["Unload", LINKFUNC(onButtonClose)]; + +if (GVAR(rearmNewPylons) || {_isCurator}) then { + ctrlShow [ID_TEXT_BANNER, false]; +}; + +private _config = configFile >> "CfgVehicles" >> typeOf _aircraft; +private _pylonComponent = _config >> "Components" >> "TransportPylonsComponent"; + +ctrlSetText [ID_PICTURE_AIRCRAFT, getText (_pylonComponent >> "uiPicture")]; + +private _hasFRIES = getNumber (_config >> QEGVAR(fastroping,enabled)); +if (["ace_fastroping"] call EFUNC(common,isModLoaded) && {_hasFRIES > 1}) then { + private _checkbox = _display displayCtrl ID_CHECKBOX_FRIES; + private _fries = _aircraft getVariable [QEGVAR(fastroping,FRIES), objNull]; + _checkbox cbSetChecked (!isNull _fries); + _checkbox setVariable [QGVAR(originalState), !isNull _fries]; +} else { + ctrlShow [ID_CHECKBOX_FRIES, false]; + ctrlShow [ID_TEXT_FRIES, false]; +}; + +GVAR(comboBoxes) = []; +{ + private _combo = _display ctrlCreate [QGVAR(CtrlCombo), -1]; + private _picturePos = ctrlPosition (_display displayCtrl ID_PICTURE_AIRCRAFT); + private _uiPos = getArray (_x >> "UIposition"); + MAP(_uiPos,if (_x isEqualType 0) then {_x} else {call compile _x}); // Handle string positions + _combo ctrlSetPosition [ + (_picturePos select 0) + (_uiPos select 0), + (_picturePos select 1) + (_uiPos select 1), + 0.1 * safezoneW, + 0.028 * safezoneH + ]; + _combo ctrlCommit 0; + + _combo lbAdd localize LSTRING(Empty); + _combo lbSetData [0, ""]; + + private _mag = (getPylonMagazines _aircraft) select _forEachIndex; + private _mags = _aircraft getCompatiblePylonMagazines (_forEachIndex + 1); + private _userWhitelist = _aircraft getVariable [QGVAR(magazineWhitelist), _mags]; + private _userBlacklist = _aircraft getVariable [QGVAR(magazineBlacklist), []]; + + _mags = _mags arrayIntersect _userWhitelist; + _mags = _mags - _userBlacklist; + + private _index = 0; + { + _combo lbAdd getText (configFile >> "CfgMagazines" >> _x >> "displayName"); + _combo lbSetData [_forEachIndex + 1, _x]; + + if (_x == _mag) then { + _index = _forEachIndex + 1; + }; + } forEach _mags; + _combo lbSetCurSel _index; + _combo ctrlAddEventHandler ["LBSelChanged", LINKFUNC(onComboSelChange)]; + // TODO: Allow pylon priority selection? + + private _mirroredIndex = getNumber (_x >> "mirroredMissilePos"); + + private _button = controlNull; + if (count allTurrets [_aircraft, false] > 0) then { + _button = _display ctrlCreate ["ctrlButtonPictureKeepAspect", -1]; + private _turret = [_aircraft, _forEachIndex] call EFUNC(common,getPylonTurret); + [_button, false, _turret] call FUNC(onButtonTurret); + _button ctrlAddEventHandler ["ButtonClick", {[_this select 0, true, []] call FUNC(onButtonTurret)}]; + _button ctrlSetPosition [ + (_picturePos select 0) + (_uiPos select 0) - (0.0165 * safezoneW), + (_picturePos select 1) + (_uiPos select 1), + 0.0165 * safezoneW, + 0.028 * safezoneH + ]; + _button ctrlCommit 0; + }; + + GVAR(comboBoxes) pushBack [_combo, _mirroredIndex - 1, _button, _index]; +} forEach ("true" configClasses (_pylonComponent >> "Pylons")); + +GVAR(defaultLoadoutNames) = []; +{ + lbAdd [ID_LIST_LOADOUTS, getText (_x >> "displayName")]; + lbSetPicture [ID_LIST_LOADOUTS, _forEachIndex, "a3\data_f_jets\logos\jets_logo_small_ca.paa"]; + + GVAR(defaultLoadoutNames) pushBack getText (_x >> "displayName"); +} forEach ("true" configClasses (_pylonComponent >> "Presets")); + +{ + if ((_x select 3) == typeOf _aircraft) then { + lbAdd [ID_LIST_LOADOUTS, _x select 0]; + }; +} forEach (profileNamespace getVariable [QGVAR(aircraftLoadouts), []]); + +private _displayName = getText (_config >> "displayName"); +ctrlSetText [ID_TEXT_LISTTITLE, format [localize LSTRING(LoadoutsFor), _displayName]]; + +private _list = _display displayCtrl ID_LIST_LOADOUTS; +_list ctrlAddEventHandler ["LBSelChanged", { + params ["_ctrl"]; + + ctrlSetText [ID_EDIT_LOADOUTNAME, _ctrl lbText (lbCurSel _ctrl)]; + call FUNC(onNameChange); +}]; + +private _edit = _display displayCtrl ID_EDIT_LOADOUTNAME; +_edit ctrlAddEventHandler ["KeyUp", LINKFUNC(onNameChange)]; +_edit ctrlAddEventHandler ["KeyDown", LINKFUNC(onNameChange)]; + +private _checkbox = _display displayCtrl ID_CHECKBOX_MIRROR; +_checkbox ctrlAddEventHandler ["CheckedChanged", {[(_this select 1) == 1] call FUNC(onPylonMirror)}]; + +if (!GVAR(isCurator)) then { + [{ + isNull (GVAR(currentAircraft) getVariable [QGVAR(currentUser), objNull]) || + {(ace_player distanceSqr GVAR(currentAircraft)) > GVAR(searchDistanceSqr)} + }, { + [localize LSTRING(TooFar), false, 5] call EFUNC(common,displayText); + call FUNC(onButtonClose); + }] call CBA_fnc_waitUntilAndExecute; +}; diff --git a/addons/pylons/functions/script_component.hpp b/addons/pylons/functions/script_component.hpp new file mode 100644 index 0000000000..62e8ea51a0 --- /dev/null +++ b/addons/pylons/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\pylons\script_component.hpp" diff --git a/addons/pylons/menu.hpp b/addons/pylons/menu.hpp new file mode 100644 index 0000000000..85ca6b1c95 --- /dev/null +++ b/addons/pylons/menu.hpp @@ -0,0 +1,166 @@ +// combo box that looks good + doesn't get cut off +class RscCombo; +class GVAR(CtrlCombo): RscCombo { + arrowEmpty = "\a3\3DEN\Data\Controls\ctrlCombo\arrowEmpty_ca.paa"; + arrowFull = "\a3\3DEN\Data\Controls\ctrlCombo\arrowFull_ca.paa"; + colorSelectBackground[] = {"(profileNamespace getVariable ['GUI_BCG_RGB_R', 0.13])","(profileNamespace getVariable ['GUI_BCG_RGB_G', 0.54])","(profileNamespace getVariable ['GUI_BCG_RGB_B', 0.21])",1}; +}; + +class IGUIBack; +class RscCheckBox; +class RscListBox; +class RscEdit; +class RscButtonMenu; +class RscText; +class RscPictureKeepAspect; + +class GVAR(DialogLoadout) { + idd = ID_DIALOG; + name = QGVAR(DialogLoadout); + enableSimulation = 1; + + class Controls { + class TextTitlebar: RscText { + idc = ID_TEXT_TITLEBAR; + text = CSTRING(AircraftLoadoutTitle); + x = 0.15835 * safezoneW + safezoneX; + y = 0.262 * safezoneH + safezoneY; + w = 0.68304 * safezoneW; + h = 0.028 * safezoneH; + colorBackground[] = {"(profileNamespace getVariable ['GUI_BCG_RGB_R', 0.13])","(profileNamespace getVariable ['GUI_BCG_RGB_G', 0.54])","(profileNamespace getVariable ['GUI_BCG_RGB_B', 0.21])",1}; + }; + class BackgroundDialog: IGUIBack { + idc = ID_BACKGROUND_DIALOG; + x = 0.15835 * safezoneW + safezoneX; + y = 0.29 * safezoneH + safezoneY; + w = 0.68304 * safezoneW; + h = 0.448 * safezoneH; + colorBackground[] = {0,0,0,0.3}; + }; + class BackgroundPicture: IGUIBack { + idc = ID_BACKGROUND_PICTURE; + x = 0.171616 * safezoneW + safezoneX; + y = 0.318 * safezoneH + safezoneY; + w = 0.440035 * safezoneW; + h = 0.392 * safezoneH; + colorBackground[] = {0.3,0.3,0.3,1}; + }; + class PictureAircraft: RscPictureKeepAspect { + idc = ID_PICTURE_AIRCRAFT; + x = 0.171616 * safezoneW + safezoneX; + y = 0.318 * safezoneH + safezoneY; + w = 0.440035 * safezoneW; + h = 0.392 * safezoneH; + }; + class CheckboxMirror: RscCheckBox { + idc = ID_CHECKBOX_MIRROR; + x = 0.171616 * safezoneW + safezoneX; + y = 0.318 * safezoneH + safezoneY; + w = 0.0165 * safezoneW; + h = 0.028 * safezoneH; + }; + class TextMirror: RscText { + idc = ID_TEXT_MIRROR; + text = "$STR_3DEN_Object_Attribute_PylonsMirror_displayName"; + tooltip="$STR_3DEN_Object_Attribute_PylonsMirror_tooltip"; + x = 0.188116 * safezoneW + safezoneX; + y = 0.318 * safezoneH + safezoneY; + w = 0.0656768 * safezoneW; + h = 0.028 * safezoneH; + colorBackground[] = {0,0,0,0.5}; + }; + class CheckboxFRIES: RscCheckBox { + idc = ID_CHECKBOX_FRIES; + x = 0.171616 * safezoneW + safezoneX; + y = 0.346 * safezoneH + safezoneY; + w = 0.0165 * safezoneW; + h = 0.028 * safezoneH; + }; + class TextFRIES: RscText { + idc = ID_TEXT_FRIES; + text = "FRIES"; + x = 0.188116 * safezoneW + safezoneX; + y = 0.346 * safezoneH + safezoneY; + w = 0.0656768 * safezoneW; + h = 0.028 * safezoneH; + colorBackground[] = {0,0,0,0.5}; + }; + class TextListTitle: RscText { + idc = ID_TEXT_LISTTITLE; + x = 0.624786 * safezoneW + safezoneX; + y = 0.318 * safezoneH + safezoneY; + w = 0.203437 * safezoneW; + h = 0.028 * safezoneH; + colorBackground[] = {0,0,0,0.5}; + }; + class ListLoadouts: RscListBox { + idc = ID_LIST_LOADOUTS; + x = 0.624786 * safezoneW + safezoneX; + y = 0.346 * safezoneH + safezoneY; + w = 0.203437 * safezoneW; + h = 0.294 * safezoneH; + }; + class EditLoadoutName: RscEdit { + idc = ID_EDIT_LOADOUTNAME; + x = 0.624786 * safezoneW + safezoneX; + y = 0.64 * safezoneH + safezoneY; + w = 0.203437 * safezoneW; + h = 0.028 * safezoneH; + colorBackground[] = {0,0,0,0.7}; + }; + class ButtonSave: RscButtonMenu { + idc = ID_BUTTON_SAVE; + action = QUOTE(call FUNC(onButtonSave)); + text = "$STR_disp_int_save"; + x = 0.624786 * safezoneW + safezoneX; + y = 0.682 * safezoneH + safezoneY; + w = 0.0590625 * safezoneW; + h = 0.028 * safezoneH; + }; + class ButtonLoad: RscButtonMenu { + idc = ID_BUTTON_LOAD; + action = QUOTE(call FUNC(onButtonLoad)); + text = "$STR_disp_int_load"; + x = 0.69703 * safezoneW + safezoneX; + y = 0.682 * safezoneH + safezoneY; + w = 0.0590625 * safezoneW; + h = 0.028 * safezoneH; + }; + class ButtonDelete: RscButtonMenu { + idc = ID_BUTTON_DELETE; + action = QUOTE(call FUNC(onButtonDelete)); + text = "$STR_disp_delete"; + x = 0.769275 * safezoneW + safezoneX; + y = 0.682 * safezoneH + safezoneY; + w = 0.0590625 * safezoneW; + h = 0.028 * safezoneH; + }; + class ButtonApply: RscButtonMenu { + idc = ID_BUTTON_APPLY; + action = QUOTE(call FUNC(onButtonApply)); + text = "$STR_ui_debug_but_apply"; + x = 0.683895 * safezoneW + safezoneX; + y = 0.738 * safezoneH + safezoneY; + w = 0.0721875 * safezoneW; + h = 0.028 * safezoneH; + }; + class ButtonClose: RscButtonMenu { + idc = ID_BUTTON_CLOSE; + text = "$STR_disp_cancel"; + action = QUOTE(call FUNC(onButtonClose)); + x = 0.769275 * safezoneW + safezoneX; + y = 0.738 * safezoneH + safezoneY; + w = 0.0721875 * safezoneW; + h = 0.028 * safezoneH; + }; + class TextBanner: RscText { + idc = ID_TEXT_BANNER; + text = CSTRING(BannerText); + x = 0.171616 * safezoneW + safezoneX; + y = 0.738 * safezoneH + safezoneY; + w = 0.440035 * safezoneW; + h = 0.028 * safezoneH; + colorBackground[] = {0.5,0,0,0.5}; + }; + }; +}; diff --git a/addons/pylons/script_component.hpp b/addons/pylons/script_component.hpp new file mode 100644 index 0000000000..fd511edc06 --- /dev/null +++ b/addons/pylons/script_component.hpp @@ -0,0 +1,37 @@ +#define COMPONENT pylons +#define COMPONENT_BEAUTIFIED Pylons +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_PYLONS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_PYLONS + #define DEBUG_SETTINGS DEBUG_SETTINGS_PYLONS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + + +#define ID_DIALOG 654654 +#define ID_TEXT_TITLEBAR 100 +#define ID_BACKGROUND_DIALOG 110 +#define ID_BACKGROUND_PICTURE 111 +#define ID_PICTURE_AIRCRAFT 120 +#define ID_CHECKBOX_MIRROR 130 +#define ID_TEXT_MIRROR 140 +#define ID_CHECKBOX_FRIES 141 +#define ID_TEXT_FRIES 142 +#define ID_TEXT_LISTTITLE 150 +#define ID_LIST_LOADOUTS 160 +#define ID_EDIT_LOADOUTNAME 170 +#define ID_BUTTON_SAVE 180 +#define ID_BUTTON_LOAD 190 +#define ID_BUTTON_DELETE 200 +#define ID_BUTTON_APPLY 210 +#define ID_BUTTON_CLOSE 211 +#define ID_TEXT_BANNER 220 diff --git a/addons/pylons/stringtable.xml b/addons/pylons/stringtable.xml new file mode 100644 index 0000000000..e127392293 --- /dev/null +++ b/addons/pylons/stringtable.xml @@ -0,0 +1,203 @@ + + + + + AIRCRAFT LOADOUT + 航空機の兵装 + LOADOUT AEREO + 飛機武裝配置 + 飞机武装配置 + 항공기 무장 + AUSRÜSTUNG DES FLUGGERÄTS + + + Loadouts for %1 + %1の兵装 + Loadouts per %1 + %1用的武裝配置 + %1用的武装配置 + %1 무장 + Ausrüstung für %1 + + + Configure Pylons + パイロン設定 + Configura Piloni + 定義派龍架 + 定义派龙架 + 파일런 설정 + Konfiguriere Außenlaststationen + + + Pylons + パイロン + Piloni + 派龍架 + 派龙架 + 파일런 + Außenlaststationen + + + <empty> + <空> + <vuoto> + <空> + <空> + <비어있음> + <leer> + + + Pylons that are colored red will have to be manually rearmed. + 赤色に設定されたパイロンは手動で再武装する必要があります。 + I Piloni di colore rosso devono essere riarmati manualmente. + 以紅色標記出的派龍架必須以手動方式進行彈藥整補。 + 以红色标记出的派龙架必须以手动方式进行弹药整补。 + 붉은색의 파일런은 수동으로 재무장해야 합니다. + Außenlaststationen, die rot markiert sind, müssen manuell aufmunitioniert werden. + + + %1 is already configuring this aircraft! + %1はすでにこの機体へ設定されています! + % sta già configurando questo aereo! + %1已經正在定義此飛機的武裝配置! + %1已经正在定义此飞机的武装配置! + 이미 이 항공기에 장착되어 있음 (%1) + %1 konfiguriert dieses Fluggerät bereits! + + + Replacing pylon %1 out of %2... + パイロン%1を作業し残り%2・・・ + Sostituendo pilone %1 al posto di %2... + 共有%2個派龍架,正在整補%1號派龍架中... + 共有%2个派龙架,正在整补%1号派龙架中... + 교체중 (%2 -> %1) + Ersetze Außenlaststation %1 von insgesamt %2 + + + Stopped at pylon %1! + パイロン%1で停止しました! + Fermato al pilone %1! + 已停止在%1號派龍架! + 已停止在%1号派龙架! + %1 파일런이 멈춤 + Gestoppt bei Außenlaststation %1 + + + Vehicle too far + Veicolo troppo lontano + 차량이 너무 멈 + 載具過遠 + 载具过远 + 車両が遠すぎます + Fahrzeug zu weit entfernt + + + Enable Pylons Menu + パイロン メニューを有効化 + Abilita Menu Piloni + 啟用派龍架選單 + 启用派龙架选单 + 파일런 메뉴 활성 + Aktiviere das Menü für Außenlaststationen. + + + Enable pylon configuration menu for aircraft. + 航空機へのパイロン設定メニューを有効化します。 + Abilita il menù di configurazione piloni per aereo. + 啟用後可透過派龍架選單來定義飛機的武裝配置。 + 启用后可透过派龙架选单来定义飞机的武装配置。 + 항공기의 파일런 설정 메뉴를 활성합니다. + Aktiviert die Konfiguration der Außenlaststationen. für Fluggeräte. + + + Rearm New Pylons + 新規パイロンの再武装 + Riarma Nuovi Piloni + 重新武裝新的派龍架 + 重新武装新的派龙架 + 새파일런 재무장 + Neue Außenlaststationen. aufmunitionieren + + + Automatically rearm new pylons from the nearest rearm vehicle. + 近くの補給車両から自動的に新規パイロンを再武装します。 + Riarma automaticamente i nuovi piloni dal veicoli di riarmo più vicino. + 自動從附近的整補載具中為派龍架進行彈藥整補。 + 自动从附近的整补载具中为派龙架进行弹药整补。 + 근처의 재무장 차량에서 빈 파일런을 자동으로 재무장 합니다. + Neue Außenlaststationen. automatisch vom nächsten Munitionsfahrzeug aufmunitionieren + + + Time Per Pylon + パイロンへの時間 + Tempo Per Pilone + 派龍架整補所需時間(個別) + 派龙架整补所需时间(个别) + 파일런당 시간 + Zeit pro Außenlaststation + + + The time it takes to replace each pylon (in seconds). + 各パイロンの置き換えにかかる時間を設定します。(秒) + Il tempo che impiega ogni pilone ad essere sostituito (in secondi). + 每個派龍架需花多久時間進行整補(單位為秒)。 + 每个派龙架需花多久时间进行整补(单位为秒)。 + 파일런을 재설정 하는데 걸리는 시간 (초) + Die benötigte Zeit, um einzelne Außenlaststationen zu ersetzen (in Sekunden). + + + Search Distance + 検索距離 + Distanza di Ricerca + 搜索距離 + 搜索距离 + 검색 반경 + Suchdistanz + + + The distance an aircraft needs to be from a rearm vehicle. + 補給車両から航空機までの必要な距離。 + La distanza necessaria per un aereo da un veicolo di riarmo. + 設定飛機必須距離整補載具多少公尺才能進行彈藥整補。 + 设定飞机必须距离整补载具多少公尺才能进行弹药整补。 + 항공기에서 재보급 가능한 재무장 차량을 찾습니다. + Die Distanz, die ein Fahrzeug von einem Munitionsfahrzeug entfernt sein darf. + + + Require Engineer + 工兵の必須化 + Necessita Ingegnere + 需要工兵 + 需要工兵 + 정비병 요구 + Benötigt Pionier + + + Require an engineer. + 工兵を必須とします。 + Necessita un ingegnere. + 需要工兵才能進行彈藥整補。 + 需要工兵才能进行弹药整补。 + 정비병이 필요합니다. + Benötigt einen Pionier. + + + Require Toolkit + ツールキットの必須化 + Necessita Kit Riparazione + 需要工具包 + 需要工具包 + 툴킷 요구 + Benötigt Werkzeugkasten + + + Require a toolkit in inventory. + インベントリ内にツールキットの存在を必須とします。 + Necessita un kit di riparazione nell'inventario + 需要工具包才能進行彈藥整補。 + 需要工具包才能进行弹药整补。 + 툴킷이 필요합니다. + Benötigt einen Werkzeugkasten im Inventar. + + + diff --git a/addons/quickmount/ACE_Settings.hpp b/addons/quickmount/ACE_Settings.hpp index bcb45f8c43..b4e07be4b4 100644 --- a/addons/quickmount/ACE_Settings.hpp +++ b/addons/quickmount/ACE_Settings.hpp @@ -36,6 +36,6 @@ class ACE_Settings { description = CSTRING(PriorityDescription); isClientSettable = 1; force = 0; - values[] = {"Driver", "Gunner", "Commander", "Passenger"}; + values[] = {"$str_getin_pos_driver", "$str_getin_pos_gunn", "$str_getin_pos_comm", "$STR_GETIN_POS_PASSENGER"}; }; }; diff --git a/addons/quickmount/CfgVehicles.hpp b/addons/quickmount/CfgVehicles.hpp index 758e462900..702f7cab4e 100644 --- a/addons/quickmount/CfgVehicles.hpp +++ b/addons/quickmount/CfgVehicles.hpp @@ -5,11 +5,11 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Category); function = QFUNC(moduleInit); - scope = 2; + scope = 1; isGlobal = 1; isTriggerActivated = 0; isDisposable = 0; - icon = QPATHTOF(UI\Icon_Module_QuickMount_ca.paa); + icon = "a3\ui_f\data\IGUI\Cfg\Actions\Obsolete\ui_action_getin_ca.paa"; class Arguments { class enabled { displayName = ECSTRING(common,Enabled); diff --git a/addons/quickmount/UI/Icon_Module_QuickMount_ca.paa b/addons/quickmount/UI/Icon_Module_QuickMount_ca.paa deleted file mode 100644 index 425f744a47..0000000000 Binary files a/addons/quickmount/UI/Icon_Module_QuickMount_ca.paa and /dev/null differ diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf index 43e66e648c..4b5debc2aa 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -63,6 +63,12 @@ if (!isNull _target && if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner if ((_effectiveRole == "driver") && {(getNumber (([_target] call CBA_fnc_getObjectConfig) >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) + + // Seats can be locked independently of the main vehicle + if ((_role == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; + if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; + if ((!(_turretPath isEqualTo [])) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; + if (_effectiveRole == "turret") then { if ((getNumber (([_target, _turretPath] call CBA_fnc_getTurret) >> "isCopilot")) == 1) exitWith { _effectiveRole = "driver"; @@ -75,12 +81,25 @@ if (!isNull _target && TRACE_2("",_effectiveRole,_x); if (_effectiveRole != _desiredRole) exitWith {}; - if (_role == "Turret") then { - ACE_player action ["GetIn" + _role, _target, _turretPath]; - TRACE_3("Geting In",_x,_role,_turretPath); + if (!(_turretPath isEqualTo [])) then { + // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander + ACE_player action ["GetInTurret", _target, _turretPath]; + TRACE_3("Geting In Turret",_x,_role,_turretPath); } else { - ACE_player action ["GetIn" + _role, _target]; - TRACE_3("Geting In",_x,_role); + if (_cargoIndex > -1) then { + // GetInCargo expects the index of the seat in the "cargo" array from fullCrew + // See description: https://community.bistudio.com/wiki/fullCrew + private _cargoActionIndex = -1; + { + if ((_x select 2) == _cargoIndex) exitWith {_cargoActionIndex = _forEachIndex}; + } forEach (fullCrew [_target, "cargo", true]); + + ACE_player action ["GetInCargo", _target, _cargoActionIndex]; + TRACE_4("Geting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); + } else { + ACE_player action ["GetIn" + _role, _target]; + TRACE_2("Geting In",_x,_role); + }; }; _hasAction = true; diff --git a/addons/quickmount/stringtable.xml b/addons/quickmount/stringtable.xml index 057e6482a7..2032af7a44 100644 --- a/addons/quickmount/stringtable.xml +++ b/addons/quickmount/stringtable.xml @@ -1,84 +1,115 @@ - + Quick Mount + Schnellzugang Entrata Rapida クイック マウント 快速搭乘 快速搭乘 + Szybkie wsiadanie + 빠른 탑승 Vehicle quick mount - Fahrzeug schnell montieren - Pojazd szybkie mocowanie + Fahrzeug-Schnellzugang + Szybkie wsiadanie do pojazdu Entrata rapida veicolo 車両クイック マウント 快速搭乘载具 快速搭乘載具 + 빠른 차량 탑승 Quickly enter the vehicle you are directly looking at. + Schnellzugang in das Fahrzeug, welches man direkt anschaut. Entra velocemente nel veicolo che stai guardando. 直接見ている車両へ迅速に搭乗します。 - 快速进入你正在看的载具之中. - 快速進入你正在看的載具之中. + 快速进入你正在看的载具之中 + 快速進入你正在看的載具之中 + Szybko wsiądź do pojazdu, na który patrzysz. + 빠르게 당신이 보고 있는 가까운 차량에 탑승합니다. Vehicle Full + Fahrzeug voll Veicolo Pieno 車両は満員 载具已满 載具已滿 + Pojazd pełny + 만차 Distance + Entfernung Distanza 距離 距离 距離 + Odległość + 거리 Maximum distance to check for vehicles. + Maximale Entfernung zu Fahrzeugen Distanza massima per controllare i veicoli. 車両を確認できる最大距離 最大可检查载具的距离. 最大可檢查載具的距離. + Maksymalna odległość do pojazdu. + 탑승 가능한 차량과의 거리 Vehicle Locked + Fahrzeug abgeschlossen Veicolo Bloccato. 車両は施錠されている 载具已上锁 載具已上鎖 + Pojazd zablokowany + 차량 잠김 Maximum Speed (km/h) + Maximale Geschwindigkeit (km/h) Velocità Massima (km/h) 最高速度 (km/h) 最高速度 (公里/小时) 最高速度 (公里/小時) + Maksymalna prędkość (km/h) + 최대 속도 (km/h) Maximum vehicle speed (km/h) allowed for player entry + Maximale Geschwindigkeit (km/h) für Schnellzugang Velocità massima del veicolo (km/h) consentita per far salire un giocatore プレイヤーが搭乗できる限界速度 (km/h) - 设置玩家能在最高多少的速度之下进入载具. - 設置玩家能在最高多少的速度之下進入載具. + 设置玩家能在最高多少的速度之下进入载具。 + 設置玩家能在最高多少的速度之下進入載具。 + Maksymalna prędkość pojazdu (km/h) pozwalająca graczowi wsiąść. + 플레이어가 탑승 가능한 목표 차량의 최대 속도 Prioritize Seat + Priorisierter Sitzplatz Priorità Sedile 優先席 优先座位 優先座位 + Priorytet zajmowanych pozycji + 좌석 우선순위 지정 Seat priority on entry + Priorisierter Sitzplatz zum Schnellzugang Priorità del sedile in entrata 搭乗の際の優先順位 - 优先想进入哪个座位. - 優先想進入哪個座位. + 优先想进入哪个座位。 + 優先想進入哪個座位。 + Priorytet pozycji w pojeździe + 탑승할 좌석의 우선순위를 지정합니다. diff --git a/addons/rangecard/CfgWeapons.hpp b/addons/rangecard/CfgWeapons.hpp index dfc643fa47..659b0ecfcb 100644 --- a/addons/rangecard/CfgWeapons.hpp +++ b/addons/rangecard/CfgWeapons.hpp @@ -1,10 +1,10 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_RangeCard: ACE_ItemCore { - author[] = {"Ruthberg"}; + author = "Ruthberg"; scope = 2; displayName = CSTRING(Name); descriptionShort = CSTRING(Description); @@ -12,7 +12,7 @@ class CfgWeapons { icon = "iconObject_circle"; mapSize = 0.034; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; }; diff --git a/addons/rangecard/functions/fnc_calculateRangeCard.sqf b/addons/rangecard/functions/fnc_calculateRangeCard.sqf index 67952f27f4..5bb12e220a 100644 --- a/addons/rangecard/functions/fnc_calculateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_calculateRangeCard.sqf @@ -39,48 +39,43 @@ params [ GVAR(rangeCardDataMVs) set [_rangeCardSlot, format[" %1", round(_muzzleVelocity)]]; -private ["_tx", "_tz", "_lastBulletPos", "_bulletPos", "_bulletVelocity", "_bulletAccel", "_bulletSpeed", "_gravity", "_deltaT", "_speedOfSound"]; -_tx = 0; -_tz = 0; -_lastBulletPos = [0, 0, 0]; -_bulletPos = [0, 0, 0]; -_bulletVelocity = [0, 0, 0]; -_bulletAccel = [0, 0, 0]; -_bulletSpeed = 0; -_gravity = [0, sin(_scopeBaseAngle) * -9.80665, cos(_scopeBaseAngle) * -9.80665]; -_deltaT = 1 / _simSteps; -_speedOfSound = 0; +private _tx = 0; +private _tz = 0; +private _lastBulletPos = [0, 0, 0]; +private _bulletPos = [0, 0, 0]; +private _bulletVelocity = [0, 0, 0]; +private _bulletAccel = [0, 0, 0]; +private _bulletSpeed = 0; +private _gravity = [0, sin(_scopeBaseAngle) * -GRAVITY, cos(_scopeBaseAngle) * -GRAVITY]; +private _deltaT = 1 / _simSteps; +private _speedOfSound = 0; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { _speedOfSound = _temperature call EFUNC(weather,calculateSpeedOfSound); }; -private ["_elevation", "_windage", "_lead", "_TOF", "_trueVelocity", "_trueSpeed"]; -_elevation = 0; -_windage = 0; -_lead = 0; -_TOF = 0; -_trueVelocity = [0, 0, 0]; -_trueSpeed = 0; +private _elevation = 0; +private _windage = 0; +private _lead = 0; +private _TOF = 0; +private _trueVelocity = [0, 0, 0]; +private _trueSpeed = 0; -private ["_n", "_range"]; -_n = 0; -_range = 0; +private _n = 0; +private _range = 0; if (_useABConfig) then { _bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel])); }; -private ["_airFrictionCoef", "_airDensity"]; -_airFrictionCoef = 1; +private _airFrictionCoef = 1; if (!_useABConfig && (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { - _airDensity = [_temperature, _barometricPressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); + private _airDensity = [_temperature, _barometricPressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); _airFrictionCoef = _airDensity / 1.22498; }; -private ["_speedTotal", "_stepsTotal", "_speedAverage"]; -_speedTotal = 0; -_stepsTotal = 0; -_speedAverage = 0; +private _speedTotal = 0; +private _stepsTotal = 0; +private _speedAverage = 0; _bulletPos set [0, 0]; _bulletPos set [1, 0]; @@ -103,7 +98,7 @@ while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do { _trueSpeed = vectorMagnitude _trueVelocity; if (_useABConfig) then { - private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed])); + private _drag = parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3:%4", _dragModel, _bc, _trueSpeed, _temperature])); _bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag); } else { _bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction * _airFrictionCoef); @@ -127,21 +122,21 @@ while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do { _tz = (_lastBulletPos select 2) + (_range - (_lastBulletPos select 1)) * ((_bulletPos select 2) - (_lastBulletPos select 2)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); _elevation = - atan(_tz / _range); _windage = - atan(_tx / _range); - _lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _range); + _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _range); }; - private ["_elevationString", "_windageString", "_leadString"]; - _elevationString = Str(round(-_elevation * 60 / 3.38 * 10) / 10); + + private _elevationString = Str(round(-DEG_TO_MRAD(_elevation) * 10) / 10); if (_elevationString == "0") then { _elevationString = "-0.0"; }; if (_elevationString find "." == -1) then { _elevationString = _elevationString + ".0"; }; - _windageString = Str(round(_windage * 60 / 3.38 * 10) / 10); + private _windageString = Str(round(DEG_TO_MRAD(_windage) * 10) / 10); if (_windageString find "." == -1) then { _windageString = _windageString + ".0"; }; - _leadString = Str(round(_lead * 10) / 10); + private _leadString = Str(round(_lead * 10) / 10); if (_leadString find "." == -1) then { _leadString = _leadString + ".0"; }; diff --git a/addons/rangecard/functions/fnc_updateClassNames.sqf b/addons/rangecard/functions/fnc_updateClassNames.sqf index 12f9c5c2e8..8af70eb02b 100644 --- a/addons/rangecard/functions/fnc_updateClassNames.sqf +++ b/addons/rangecard/functions/fnc_updateClassNames.sqf @@ -15,19 +15,18 @@ */ #include "script_component.hpp" -private ["_unit", "_ammoClass", "_magazineClass", "_weaponClass", "_ammo", "_ammoConfig", "_parentClasses"]; -_unit = _this; +private _unit = _this; -_ammoClass = ""; -_magazineClass = ""; -_weaponClass = primaryWeapon _unit; +private _ammoClass = ""; +private _magazineClass = ""; +private _weaponClass = primaryWeapon _unit; -if (_weaponClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "") }; +if (_weaponClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "") }; { - _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - _ammoConfig = (configFile >> "CfgAmmo" >> _ammo); - _parentClasses = [_ammoConfig, true] call BIS_fnc_returnParents; + private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); + private _ammoConfig = (configFile >> "CfgAmmo" >> _ammo); + private _parentClasses = [_ammoConfig, true] call BIS_fnc_returnParents; if ("BulletBase" in _parentClasses) exitWith { _ammoClass = _ammo; _magazineClass = _x; diff --git a/addons/rangecard/functions/fnc_updateRangeCard.sqf b/addons/rangecard/functions/fnc_updateRangeCard.sqf index 3328600dc3..9ab6fc6341 100644 --- a/addons/rangecard/functions/fnc_updateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_updateRangeCard.sqf @@ -22,7 +22,6 @@ disableSerialization; #define __dsp (uiNamespace getVariable "RangleCard_Display") -private ["_airFriction", "_ammoConfig", "_atmosphereModel", "_transonicStabilityCoef", "_barrelLength", "_barrelTwist", "_bc", "_cacheEntry", "_column", "_control", "_dragModel", "_i", "_muzzleVelocity", "_offset", "_row", "_weaponConfig", "_initSpeed", "_initSpeedCoef"]; params ["_zeroRange", "_boreHeight", "_ammoClass", "_magazineClass", "_weaponClass"]; @@ -34,8 +33,8 @@ if (_ammoClass == "" || _magazineClass == "" || _weaponClass == "") exitWith {}; GVAR(controls) = []; for "_row" from 0 to 49 do { - _offset = if (_row < 5) then {0} else {0.003}; - _control = (__dsp ctrlCreate ["RangeCard_RscText", 790000 + _row]); + private _offset = if (_row < 5) then {0} else {0.003}; + private _control = (__dsp ctrlCreate ["RangeCard_RscText", 790000 + _row]); _control ctrlSetPosition [safeZoneX + 0.183, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.062, 0.025]; if (_row in [0, 8, 18, 28, 38, 48]) then { _control ctrlSetTextColor [1, 1, 1, 1]; @@ -48,8 +47,8 @@ for "_row" from 0 to 49 do { }; for "_column" from 0 to 8 do { for "_row" from 0 to 49 do { - _offset = if (_row < 5) then {0} else {0.003}; - _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + _column * 100 + _row]); + private _offset = if (_row < 5) then {0} else {0.003}; + private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + _column * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.249 + _column * 0.055, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.052, 0.025]; _control ctrlCommit 0; _control ctrlSetText "-0.0"; @@ -58,8 +57,8 @@ for "_column" from 0 to 8 do { }; for "_column" from 0 to 2 do { for "_row" from 0 to 49 do { - _offset = if (_row < 5) then {0} else {0.003}; - _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (9 +_column) * 100 + _row]); + private _offset = if (_row < 5) then {0} else {0.003}; + private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (9 +_column) * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.743 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025]; _control ctrlCommit 0; _control ctrlSetText "-0.0"; @@ -68,8 +67,8 @@ for "_column" from 0 to 2 do { }; for "_column" from 0 to 2 do { for "_row" from 0 to 49 do { - _offset = if (_row < 5) then {0} else {0.003}; - _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (12 +_column) * 100 + _row]); + private _offset = if (_row < 5) then {0} else {0.003}; + private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (12 +_column) * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.892 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025]; _control ctrlCommit 0; _control ctrlSetText "-0.0"; @@ -93,20 +92,20 @@ GVAR(rangeCardStartRange) = 100; GVAR(rangeCardIncrement) = 50; GVAR(rangeCardEndRange) = GVAR(rangeCardStartRange) + 49 * GVAR(rangeCardIncrement); -_ammoConfig = _ammoClass call EFUNC(advanced_ballistics,readAmmoDataFromConfig); -_weaponConfig = _weaponClass call EFUNC(advanced_ballistics,readWeaponDataFromConfig); -_airFriction = _ammoConfig select 0; -_barrelTwist = _weaponConfig select 0; -_barrelLength = _weaponConfig select 2; -_muzzleVelocity = 0; +private _ammoConfig = _ammoClass call EFUNC(advanced_ballistics,readAmmoDataFromConfig); +private _weaponConfig = _weaponClass call EFUNC(advanced_ballistics,readWeaponDataFromConfig); +private _airFriction = _ammoConfig select 0; +private _barrelTwist = _weaponConfig select 0; +private _barrelLength = _weaponConfig select 2; +private _muzzleVelocity = 0; -_bc = 0; +private _bc = 0; if (count (_ammoConfig select 6) > 0) then { _bc = (_ammoConfig select 6) select 0; }; -_transonicStabilityCoef = _ammoConfig select 4; -_dragModel = _ammoConfig select 5; -_atmosphereModel = _ammoConfig select 8; +private _transonicStabilityCoef = _ammoConfig select 4; +private _dragModel = _ammoConfig select 5; +private _atmosphereModel = _ammoConfig select 8; private _useABConfig = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]); if (_bc == 0) then { @@ -116,8 +115,8 @@ if (_bc == 0) then { if (_barrelLength > 0 && _useABConfig) then { _muzzleVelocity = [_barrelLength, _ammoConfig select 10, _ammoConfig select 11, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); } else { - _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed"); - _initSpeedCoef = getNumber (configFile >> "CfgWeapons" >> _weaponClass >> "initSpeed"); + private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed"); + private _initSpeedCoef = getNumber (configFile >> "CfgWeapons" >> _weaponClass >> "initSpeed"); if (_initSpeedCoef < 0) then { _initSpeed = _initSpeed * -_initSpeedCoef; }; @@ -127,16 +126,13 @@ if (_barrelLength > 0 && _useABConfig) then { _muzzleVelocity = _initSpeed; }; -if (_useABConfig) then { - ctrlSetText [770000, format["%1'' - %2 gr (%3)", round((_ammoConfig select 1) * 39.3700787) / 1000, round((_ammoConfig select 3) * 15.4323584), _ammoClass]]; - if (_barrelLength > 0 && _barrelTwist > 0) then { +ctrlSetText [770000, format["%1'' - %2 gr (%3)", round((_ammoConfig select 1) * 39.3700787) / 1000, round((_ammoConfig select 3) * 15.4323584), _ammoClass]]; +if (_barrelLength > 0) then { + if (_useABConfig && _barrelTwist > 0) then { ctrlSetText [770002, format["Barrel: %1'' 1:%2'' twist", round(2 * _barrelLength * 0.0393700787) / 2, round(_barrelTwist * 0.0393700787)]]; } else { - ctrlSetText [770002, ""]; + ctrlSetText [770002, format["Barrel: %1''", round(2 * _barrelLength * 0.0393700787) / 2]]; }; -} else { - ctrlSetText [770000, getText (configFile >> "CfgMagazines" >> _magazineClass >> "displayNameShort")]; - ctrlSetText [770002, getText (configFile >> "CfgWeapons" >> _weaponClass >> "displayName")]; }; lnbAddRow [770100, ["4mps Wind(MRADs)", "1mps LEAD(MRADs)"]]; @@ -157,13 +153,13 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t ctrlSetText [77004 , ""]; }; -_cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]]; +private _cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]]; if (isNil {_cacheEntry}) then { private _scopeBaseAngle = if (!_useABConfig) then { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then { @@ -171,10 +167,10 @@ if (isNil {_cacheEntry}) then { private _mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift); private _mv = _muzzleVelocity + _mvShift; - [_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),100,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_useABConfig] call FUNC(calculateRangeCard); + [_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_useABConfig] call FUNC(calculateRangeCard); } forEach [-15, -5, 5, 10, 15, 20, 25, 30, 35]; } else { - [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),100,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_useABConfig] call FUNC(calculateRangeCard); + [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_useABConfig] call FUNC(calculateRangeCard); }; for "_i" from 0 to 9 do { @@ -205,7 +201,7 @@ lnbAddRow [770200, GVAR(rangeCardDataMVs)]; for "_column" from 0 to 8 do { for "_row" from 0 to 49 do { - _control = (__dsp displayCtrl (90000 + _column * 100 + _row)); + private _control = (__dsp displayCtrl (90000 + _column * 100 + _row)); _control ctrlSetText ((GVAR(rangeCardDataElevation) select _column) select _row); if (_row >= (GVAR(lastValidRow) select _column)) then { _control ctrlSetTextColor [0, 0, 0, 0.6]; @@ -217,7 +213,7 @@ for "_column" from 0 to 8 do { }; { for "_row" from 0 to 49 do { - _control = (__dsp displayCtrl (90000 + (9 + _forEachIndex) * 100 + _row)); + private _control = (__dsp displayCtrl (90000 + (9 + _forEachIndex) * 100 + _row)); _control ctrlSetText ((GVAR(rangeCardDataWindage) select _x) select _row); if (_row >= (GVAR(lastValidRow) select _x)) then { _control ctrlSetTextColor [0, 0, 0, 0.6]; @@ -230,7 +226,7 @@ for "_column" from 0 to 8 do { { for "_row" from 0 to 49 do { - _control = (__dsp displayCtrl (90000 + (12 + _forEachIndex) * 100 + _row)); + private _control = (__dsp displayCtrl (90000 + (12 + _forEachIndex) * 100 + _row)); _control ctrlSetText ((GVAR(rangeCardDataLead) select _x) select _row); if (_row >= (GVAR(lastValidRow) select _x)) then { _control ctrlSetTextColor [0, 0, 0, 0.6]; @@ -241,10 +237,5 @@ for "_column" from 0 to 8 do { }; } forEach [0, 3, 8]; -if (_useABConfig) then { - ctrlSetText [770020, "For best results keep ammunition at ambient air temperature. Tables calculated for the above listed barrel"]; - ctrlSetText [770021, format["and load with optic mounted %1'' above line of bore.", round((_boreHeight / 2.54) * 10) / 10]]; -} else { - ctrlSetText [770020, ""]; - ctrlSetText [770021, ""]; -}; +ctrlSetText [770020, "For best results keep ammunition at ambient air temperature. Tables calculated for the above listed barrel"]; +ctrlSetText [770021, format["and load with optic mounted %1'' above line of bore.", round((_boreHeight / 2.54) * 10) / 10]]; diff --git a/addons/rangecard/functions/script_component.hpp b/addons/rangecard/functions/script_component.hpp index fdc4a3d486..d4a493206b 100644 --- a/addons/rangecard/functions/script_component.hpp +++ b/addons/rangecard/functions/script_component.hpp @@ -1 +1 @@ -#include "\z\ace\addons\rangecard\script_component.hpp" \ No newline at end of file +#include "\z\ace\addons\rangecard\script_component.hpp" diff --git a/addons/realisticnames/CfgMagazines.hpp b/addons/realisticnames/CfgMagazines.hpp index d32ee3ec2c..ad6746df06 100644 --- a/addons/realisticnames/CfgMagazines.hpp +++ b/addons/realisticnames/CfgMagazines.hpp @@ -434,10 +434,25 @@ class CfgMagazines { }; class 6Rnd_Missile_AGM_02_F; class PylonRack_1Rnd_Missile_AGM_02_F: 6Rnd_Missile_AGM_02_F { - displayName = "AGM-65 Maverick"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] + displayName = "AGM-65 Maverick G"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] }; class PylonRack_3Rnd_Missile_AGM_02_F: PylonRack_1Rnd_Missile_AGM_02_F { - displayName = "AGM-65 Maverick 3x"; // [vanilla: Macer 3x - Missile_AGM_02_Plane_CAS_01_F] + displayName = "AGM-65 Maverick G 3x"; // [vanilla: Macer 3x - Missile_AGM_02_Plane_CAS_01_F] + }; + class magazine_Missile_AGM_02_x1 : VehicleMagazine { + displayName = "AGM-65 Maverick G"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] + }; + class PylonMissile_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 { + displayName = "AGM-65 Maverick G"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] + }; + class PylonMissile_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 { + displayName = "AGM-65 Maverick G 2x"; // [vanilla: Macer 2x - Missile_AGM_02_Plane_CAS_01_F] + }; + class PylonRack_Missile_AGM_02_x1 : magazine_Missile_AGM_02_x1 { + displayName = "AGM-65 Maverick G"; // [vanilla: Macer - Missile_AGM_02_Plane_CAS_01_F] + }; + class PylonRack_Missile_AGM_02_x2 : magazine_Missile_AGM_02_x1 { + displayName = "AGM-65 Maverick G 2x"; // [vanilla: Macer 2x - Missile_AGM_02_Plane_CAS_01_F] }; class 2Rnd_LG_scalpel; class PylonRack_1Rnd_LG_scalpel: 2Rnd_LG_scalpel { @@ -457,7 +472,7 @@ class CfgMagazines { }; class 12Rnd_missiles; class PylonRack_12Rnd_missiles: 12Rnd_missiles { - displayName = "Hydra 70"; // [vanilla: DAR - missiles_DAR] + displayName = "Hydra 70 12x HE"; // [vanilla: DAR - missiles_DAR] }; class PylonRack_20Rnd_Rocket_03_HE_F: 20Rnd_Rocket_03_HE_F { displayName = "S-8 20x HE"; // [vanilla: Tratnyr 20x HE - Rocket_03_HE_Plane_CAS_02_F] diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index 3d217164e5..708bf1c53f 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -66,16 +66,25 @@ class CfgVehicles { class O_MRAP_02_F: MRAP_02_base_F { displayName = CSTRING(MRAP_02_Name); }; + class O_T_MRAP_02_ghex_F: MRAP_02_base_F { + displayName = CSTRING(MRAP_02_Name); + }; class MRAP_02_hmg_base_F: MRAP_02_base_F {}; class O_MRAP_02_hmg_F: MRAP_02_hmg_base_F { displayName = CSTRING(MRAP_02_hmg_Name); }; + class O_T_MRAP_02_hmg_ghex_F: MRAP_02_hmg_base_F { + displayName = CSTRING(MRAP_02_hmg_Name); + }; class MRAP_02_gmg_base_F: MRAP_02_hmg_base_F {}; class O_MRAP_02_gmg_F: MRAP_02_gmg_base_F { displayName = CSTRING(MRAP_02_gmg_Name); }; + class O_T_MRAP_02_gmg_ghex_F: MRAP_02_gmg_base_F { + displayName = CSTRING(MRAP_02_gmg_Name); + }; // strider class MRAP_03_base_F; @@ -173,8 +182,8 @@ class CfgVehicles { displayName = CSTRING(APC_Wheeled_01_cannon_Name); }; - class O_APC_Wheeled_02_base_F; - class O_APC_Wheeled_02_rcws_F: O_APC_Wheeled_02_base_F { + class APC_Wheeled_02_base_F; + class O_APC_Wheeled_02_base_F : APC_Wheeled_02_base_F { displayName = CSTRING(APC_Wheeled_02_rcws_Name); }; @@ -305,6 +314,9 @@ class CfgVehicles { class Heli_Light_01_civil_base_F: Heli_Light_01_unarmed_base_F { displayName = CSTRING(Heli_Light_01_civil_Name); }; + class I_C_Heli_Light_01_civil_F: Heli_Light_01_civil_base_F { + displayName = CSTRING(Heli_Light_01_civil_Name); + }; class Heli_Light_01_armed_base_F; class B_Heli_Light_01_armed_F: Heli_Light_01_armed_base_F { @@ -397,6 +409,11 @@ class CfgVehicles { displayName = CSTRING(Plane_Fighter_03_Name); }; + class Plane_Fighter_04_Base_F; + class I_Plane_Fighter_04_F : Plane_Fighter_04_Base_F { + displayName = CSTRING(Plane_Fighter_04_Name); + }; + // uavs class UAV_02_base_F; class B_UAV_02_F: UAV_02_base_F { @@ -713,6 +730,9 @@ class CfgVehicles { class C_Offroad_02_unarmed_F: Offroad_02_unarmed_base_F { displayName = CSTRING(C_Offroad_02_unarmed); }; + class I_C_Offroad_02_unarmed_F: Offroad_02_unarmed_base_F { + displayName = CSTRING(C_Offroad_02_unarmed); + }; class C_Offroad_02_unarmed_F_black: C_Offroad_02_unarmed_F { displayName = CSTRING(C_Offroad_02_unarmed_black); }; @@ -734,10 +754,35 @@ class CfgVehicles { class C_Plane_Civil_01_racing_F: Plane_Civil_01_base_F { displayName = CSTRING(C_Plane_Civil_01_racing); }; + class I_C_Plane_Civil_01_F: Plane_Civil_01_base_F { + displayName = CSTRING(C_Plane_Civil_01); + }; // Burraq class UAV_04_base_F; class O_T_UAV_04_CAS_F: UAV_04_base_F { displayName = CSTRING(O_T_UAV_04_CAS); }; + + // Polaris DAGOR (Prowler) + class LSV_01_base_F; + class LSV_01_armed_base_F : LSV_01_base_F { + displayName = CSTRING(lsv_01_armed); + }; + class LSV_01_unarmed_base_F : LSV_01_base_F { + displayName = CSTRING(lsv_01_unarmed); + }; + class LSV_01_light_base_F : LSV_01_base_F { + displayName = CSTRING(lsv_01_light); + }; + + // Light Strike Vehicle Mk. II (Qilin) + class LSV_02_base_F; + class LSV_02_armed_base_F : LSV_02_base_F { + displayName = CSTRING(lsv_02_armed); + }; + class LSV_02_unarmed_base_F : LSV_02_base_F { + displayName = CSTRING(lsv_02_unarmed); + }; + }; diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index 6aa3c7c3c8..fc873ccf10 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -232,9 +232,6 @@ class CfgWeapons { displayName = CSTRING(srifle_DMR_03_woodland); //Mk-I EMR 7.62 mm (Woodland); }; - class srifle_DMR_03_spotter_F: srifle_DMR_03_F { - displayName = CSTRING(srifle_DMR_03_spotter); //NATO DMR (provisional) spotter; - }; class DMR_04_base_F: Rifle_Long_Base_F { displayName = CSTRING(DMR_04); //ASP-1 Kir 12.7 mm; }; @@ -351,7 +348,7 @@ class CfgWeapons { class MissileLauncher; class Missile_AGM_02_Plane_CAS_01_F: MissileLauncher { - displayName = "AGM-65 Maverick"; + displayName = "AGM-65 Maverick G"; }; class Missile_AGM_01_Plane_CAS_02_F: Missile_AGM_02_Plane_CAS_01_F { displayName = "Kh-25MTP"; @@ -549,6 +546,16 @@ class CfgWeapons { }; }; + class autocannon_40mm_VTOL_01: autocannon_40mm_CTWS { + displayName = "L/60 Bofors Autocannon"; + class AP: AP { + displayName = "L/60 Bofors Autocannon"; + }; + class HE: HE { + displayName = "L/60 Bofors Autocannon"; + }; + }; + class autocannon_30mm_CTWS: autocannon_Base_F { displayName = "Mk44 Bushmaster II"; class AP: autocannon_Base_F { diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 6ea746a671..61a54b393b 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -179,7 +179,7 @@ M-ATV (HMG) - M-ATV (SMG) + M-ATV (sMG) M-ATV (HMG) M-ATV (CKM) M-ATV (HMG) @@ -483,7 +483,7 @@ Fennek (HMG) - Fennek (SMG) + Fennek (sMG) Fennek (HMG) Fennek (CKM) Fennek (HMG) @@ -563,7 +563,7 @@ KamAZ Transport - KamAZ Transport + KamAS Transport KamAZ de transporte KamAZ transportowy KamAZ (valník) @@ -579,7 +579,7 @@ KamAZ Transport (covered) - KamAZ Transport (bedeckt) + KamAS Transport (bedeckt) KamAZ de transporte (cubierto) KamAZ Transportowy (zakryty) KamAZ (valník-krytý) @@ -595,7 +595,7 @@ KamAZ Ammo - KamAZ Munition + KamAS Munition KamAZ de munición KamAZ Amunicyjny KamAZ (muniční) @@ -611,7 +611,7 @@ KamAZ Fuel - KamAZ Treibstoff + KamAS Treibstoff KamAZ de combustible KamAZ cysterna KamAZ (cisterna) @@ -627,7 +627,7 @@ KamAZ Repair - KamAZ Instandsetzung + KamAS Instandsetzung KamAZ de reparación KamAZ Naprawczy KamAZ (opravárenský) @@ -643,7 +643,7 @@ KamAZ Medical - KamAZ Sanitäter + KamAS Sanitäter KamAZ médico KamAZ Medyczny KamAZ (zdravotnický) @@ -658,50 +658,50 @@ "卡玛斯"卡车 (医疗) - Punisher - Punisher - Punisher - Punisher - Punisher - Punisher + Karatel + Karatel + Karatel + Karatel + Karatel + Karatel Kаратель - Punisher - Punisher - Punisher - パニッシャー - Punisher + Karatel + Karatel + Karatel + カラテル + Karatel "懲罰者"防地雷反伏擊車 "惩罚者"防地雷反伏击车 - Punisher (HMG) - Punisher (SMG) - Punisher (HMG) - Punisher (CKM) - Punisher (HMG) - Punisher (HMG) + Karatel (HMG) + Karatel (sMG) + Karatel (HMG) + Karatel (CKM) + Karatel (HMG) + Karatel (HMG) Kаратель (Пулемёт) - Punisher (HMG) - Punisher (nehézgéppuska) - Punisher (HMG) - パニッシャー (HMG) - Punisher (HMG) + Karatel (HMG) + Karatel (nehézgéppuska) + Karatel (HMG) + カラテル (HMG) + Karatel (HMG) "懲罰者"防地雷反伏擊車 (重機槍) "惩罚者"防地雷反伏击车 (重机枪) - Punisher (GMG) - Punisher (GMW) - Punisher (GMG) - Punisher (GMG) - Punisher (GMG) - Punisher (GMG) + Karatel (GMG) + Karatel (GMW) + Karatel (GMG) + Karatel (GMG) + Karatel (GMG) + Karatel (GMG) Kаратель (Гранатомёт) - Punisher (GMG) - Punisher (gránátgéppuska) - Punisher (GMG) - パニッシャー (GMG) - Punisher (GMG) + Karatel (GMG) + Karatel (gránátgéppuska) + Karatel (GMG) + カラテル (GMG) + Karatel (GMG) "懲罰者"防地雷反伏擊車 (榴彈機槍) "惩罚者"防地雷反伏击车 (榴弹机枪) @@ -764,7 +764,7 @@ ZSU-35 Tigris ZSU-35 Tigris ZSU-35 Tigris - ZSU-35 + ZSU-35 ティグリス ZSU-35 Tigris ZSU-35"虎式"防空車 ZSU-35"虎式"防空车 @@ -780,7 +780,7 @@ Otokar ARMA Otokar ARMA Otokar ARMA - ティグリスOtokar アルマ + オトカ アルマ Otokar ARMA "奧托卡-阿爾默"裝甲運兵車 "奥托卡-阿尔默"装甲运兵车 @@ -796,7 +796,7 @@ Typhoon Transporte Typhoon szállítójármű Typhoon da trasporto - Typhoon 輸送型 + タイフーン 輸送型 Typhoon 수송 "颱風"卡車 (運輸) "台风"卡车 (运输) @@ -812,7 +812,7 @@ Typhoon Transporte (coberto) Typhoon szállítójármű (ponyvás) Typhoon da trasporto (coperto) - Typhoon 輸送型 (幌) + タイフーン 輸送型 (幌) Typhoon 수송 (덮개) "颱風"卡車 (運輸, 棚布) "台风"卡车 (运输, 棚布) @@ -828,7 +828,7 @@ Typhoon Dispositivo Typhoon (eszköz) Typhoon per dispositivo - Typhoon デバイス型 + タイフーン デバイス型 Typhoon 장치 "颱風"卡車 (精密設備) "台风"卡车 (精密设备) @@ -844,7 +844,7 @@ Typhoon Munições Typhoon (lőszerszállító) Typhoon di rifornimento munizioni - Typhoon 弾薬給弾型 + タイフーン 弾薬給弾型 Typhoon 탄약 "颱風"卡車 (彈藥) "台风"卡车 (弹药) @@ -860,7 +860,7 @@ Typhoon Combustível Typhoon (üzemanyag-szállító) Typhoon di rifornimento carburante - Typhoon 燃料給油車 + タイフーン 燃料給油車 Typhoon 연료 "颱風"卡車 (燃油) "台风"卡车 (燃油) @@ -876,7 +876,7 @@ Typhoon Reparador Typhoon (szerelő-jármű) Typhoon riparatore - Typhoon 修理型 + タイフーン 修理型 Typhoon 수리 "颱風"卡車 (維修) "台风"卡车 (维修) @@ -892,7 +892,7 @@ Typhoon Médico Typhoon (egészségügyi) Typhoon medico - Typhoon 救急車 + タイフーン 救急車 Typhoon 의료 "颱風"卡車 (醫療) "台风"卡车 (医疗) @@ -1089,6 +1089,20 @@ L-159先進輕型戰鬥機 (空對空) L-159先进轻型战斗机 (空对空) + + JAS 39 Gripen + JAS 39 Gripen + JAS 39 Gripen + JAS 39 Gripen + JAS 39 Gripen + JAS 39 Gripen + JAS 39 Грипен + JAS 39 Gripen + JAS 39 Gripen + JAS 39 グリペン + JAS 39 그리펜 + JAS 39 獅鷲戰鬥機 + Ka-60 Kasatka Ka-60 Kasatka @@ -1115,7 +1129,7 @@ Ka-60 Kasatka (preto e branco) Ka-60 Касатка (белый и черный) Ka-60 Kasatka (blanco y negro) - Ka-60 カサートカ (黒&白) + Ka-60 カサートカ (黒 & 白) Ka-60 Kasatka (검정 및 하양) Ka-60"逆戟鯨"直升機 (黑&白) Ka-60"逆戟鲸"直升机 (黑&白) @@ -1147,7 +1161,7 @@ Yak-130 Jak-130 Yak-130 - Yak-130 ミトン + Yak-130 Yak-130 Yak-130"手套"攻擊機 Yak-130"手套"攻击机 @@ -1227,7 +1241,7 @@ M112 Carga de Demolição M112 romboló tömb M112 Demolition Block - M113 爆薬ブロック + M112 爆薬ブロック M112 폭파 블럭 M112塑性炸藥 M112塑性炸药 @@ -1250,7 +1264,7 @@ M83 Smoke Grenade (White) - M83 Rauchgranate (Weiss) + M83 Rauchgranate (Weiß) Granada de humo M83 (Blanco) Granat dymny M83 (Biały) M83 Kouřový Granát (Bílý) @@ -1921,20 +1935,20 @@ CTAR-21卡宾步枪 - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21 EGLM - TAR-21突擊步槍 (榴彈) - TAR-21突击步枪 (榴弹) + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21 EGLM + GTAR-21突擊步槍 (榴彈) + GTAR-21突击步枪 (榴弹) Vector SMG @@ -2166,7 +2180,7 @@ Noreen "Bad News" ULR (Camo) Noreen "Bad News" ULR (Camuflaje) Noreen "Bad News" ULR (Камо) - Noreen "Bad News" ULR (Camo) + Noreen "Bad News" ULR (Tarnmuster) Noreen "Bad News" ULR (kamuflaż) Noreen "Bad News" ULR (Camo) Noreen "Bad News"ULR (Terepmintás) @@ -2182,7 +2196,7 @@ Noreen "Bad News" ULR (Beige) Noreen "Bad News" ULR (Arena) Noreen "Bad News" ULR (Песочный) - Noreen "Bad News" ULR (Sand) + Noreen "Bad News" ULR (sandfarben) Noreen "Bad News" ULR (piaskowy) Noreen "Bad News" ULR (Sabbia) Noreen "Bad News"ULR (Homok) @@ -2247,7 +2261,7 @@ SIG 556 (Arena) SIG 556 (Песочный) SIG 556 (piaskowy) - SIG 556 (Sand) + SIG 556 (sandfarben) SIG 556 (Sabbia) SIG 556 (Homok) SIG 556 (Deserto) @@ -2263,7 +2277,7 @@ SIG 556 (Camuflaje) SIG 556 (Камо) SIG 556 (kamuflaż) - SIG 556 (Camo) + SIG 556 (Tarnmuster) SIG 556 (Camo) SIG 556 (Terepmintás) SIG 556 (Camuflagem) @@ -2279,7 +2293,7 @@ SIG 556 (Bosque) SIG 556 (Лесной) SIG 556 (leśny) - SIG 556 (Woodland) + SIG 556 (Grünes Tarnmuster) SIG 556 (Woodland) SIG 556 (Erdőmintás) SIG 556 (Floresta) @@ -2288,22 +2302,6 @@ SIG 556精準步槍 (森林迷彩) SIG 556精准步枪 (森林迷彩) - - SIG 556 (provisional) spotter - SIG 556 (provizorní) spotter - SIG 556 (provisoire) Observateur - SIG 556 (provisional) observador - SIG 556 (provisional) корректировщик - SIG 556 (prowizoryczny) obserwator - SIG 556 (provisorisch) Beobachter - SIG 556 (provisional) spotter - SIG 556 (Ellátmányi) Megfigyelő - SIG 556 (provisional) observador - SIG 556 (仮) スポッター - SIG 556 (임시) spotter - SIG 556精準步槍 (暫定) 觀測手 - SIG 556精准步枪 (暂定) 观测手 - ASP-1 Kir ASP-1 Kir @@ -2316,7 +2314,7 @@ ASP-1 Kir ASP-1 Kir ASP-1 Kir - ASP-1 Kir + ASP-1 キール ASP-1"基爾"消音狙擊步槍 ASP-1"基尔"消音狙击步枪 @@ -2331,7 +2329,7 @@ ASP-1 Kir (Nero) ASP-1 Kir (Fekete) ASP-1 Kir (Preto) - ASP-1 Kir (黒) + ASP-1 キール (黒) ASP-1 Kir (검정) ASP-1"基爾"消音狙擊步槍 (黑色) ASP-1"基尔"消音狙击步枪 (黑色) @@ -2347,7 +2345,7 @@ ASP-1 Kir (Tan) ASP-1 Kir (Cserszín) ASP-1 Kir (Deserto) - ASP-1 Kir (黄褐) + ASP-1 キール (黄褐) ASP-1 Kir (황갈) ASP-1"基爾"消音狙擊步槍 (黃褐色) ASP-1"基尔"消音狙击步枪 (黄褐色) @@ -2439,7 +2437,7 @@ M14 (Camuflaje) M14 (Камо) M14 (kamuflaż) - M14 (Camo) + M14 (Tarnmuster) M14 (Camo) M14 (Terepmintás) M14 (Camuflagem) @@ -2455,7 +2453,7 @@ M14 (Oliva) M14 (Олива) M14 (oliwkowy) - M14 (Olive) + M14 (Olivgrün) M14 (Olive) M14 (Olíva) M14 (Oliva) @@ -2567,7 +2565,7 @@ LWMMG (Arena) LWMMG (Песочный) LWMMG (piaskowy) - LWMMG (Sand) + LWMMG (sandfarben) LWMMG (Sabbia) LWMMG (Homok) LWMMG (Deserto) @@ -2945,20 +2943,20 @@ GM6"天猫"反器材狙击步枪 (绿色数位蜂巢迷彩) - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249班用自動機槍 - M249班用自动机枪 + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN Minimi SPW + FN ミニミ SPW + FN Minimi SPW + FN Minimi班用自動機槍 + FN Minimi班用自动机枪 M200 Intervention (Tropic) @@ -3030,7 +3028,7 @@ HK416A5 11" (Beige) HK416A5 11" (Arena) HK416A5 11" (Песочный) - HK416A5 11" (Sand) + HK416A5 11" (sandfarben) HK416A5 11" (piaskowy) HK416A5 11" (Sabbia) HK416A5 11" (Homok) @@ -3078,7 +3076,7 @@ HK416A5 11" GL (Beige) HK416A5 11" GL (Arena) HK416A5 11" GL (Песочный) - HK416A5 11" GL (Sand) + HK416A5 11" GL (sandfarben) HK416A5 11" GL (piaskowy) HK416A5 11" GL (Sabbia) HK416A5 11" GL (Homok) @@ -3126,7 +3124,7 @@ HK416A5 14.5" (Beige) HK416A5 14.5" (Arena) HK416A5 14.5" (Песочный) - HK416A5 14.5" (Sand) + HK416A5 14.5" (sandfarben) HK416A5 14.5" (piaskowy) HK416A5 14.5" (Sabbia) HK416A5 14.5" (Homok) @@ -3174,7 +3172,7 @@ HK417A2 20" (Beige) HK417A2 20" (Arena) HK417A2 20" (Песочный) - HK417A2 20" (Sand) + HK417A2 20" (sandfarben) HK417A2 20" (piaskowy) HK417A2 20" (Sabbia) HK417A2 20" (Homok) @@ -3211,7 +3209,7 @@ P99 (Khaki) P99 (Khaki) P99 (Caqui) - P99 (カーキ) + P99 (土埃) P99 (카키) P99半自動手槍 (卡其色) P99半自动手枪 (卡其色) @@ -3232,5 +3230,30 @@ "馬卡洛夫"手槍 "马卡洛夫"手枪 + + Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + ポラリス DAGOR (XM312) + + + Polaris DAGOR + Polaris DAGOR + ポラリス DAGOR + + + Polaris DAGOR (light) + Polaris DAGOR (leicht) + ポラリス DAGOR (軽) + + + LSV Mk. II (M134) + LSV Mk. II (M134) + LSV Mk. II (M134) + + + LSV Mk. II + LSV Mk. II + LSV Mk. II + diff --git a/addons/rearm/ACE_Settings.hpp b/addons/rearm/ACE_Settings.hpp index 2e0fae277f..2bd4eec450 100644 --- a/addons/rearm/ACE_Settings.hpp +++ b/addons/rearm/ACE_Settings.hpp @@ -1,6 +1,6 @@ class ACE_Settings { class GVAR(level) { - category = ECSTRING(OptionsMenu,CategoryLogistics); + category = CSTRING(DisplayName); displayName = CSTRING(RearmSettings_level_DisplayName); description = CSTRING(RearmSettings_level_Description); value = 0; @@ -8,6 +8,7 @@ class ACE_Settings { values[] = {CSTRING(RearmSettings_vehicle), CSTRING(RearmSettings_magazine), CSTRING(RearmSettings_caliber)}; }; class GVAR(supply) { + category = CSTRING(DisplayName); displayName = CSTRING(RearmSettings_supply_DisplayName); description = CSTRING(RearmSettings_supply_Description); value = 0; diff --git a/addons/rearm/CfgEventHandlers.hpp b/addons/rearm/CfgEventHandlers.hpp index 17edc1dc30..077779a642 100644 --- a/addons/rearm/CfgEventHandlers.hpp +++ b/addons/rearm/CfgEventHandlers.hpp @@ -28,7 +28,7 @@ class Extended_PostInit_EventHandlers { class Extended_Respawn_EventHandlers { class CAManBase { class ADDON { - respawn = QUOTE(call COMPILE_FILE(XEH_respawn)); + respawn = QUOTE(call FUNC(handleRespawn)); }; }; }; diff --git a/addons/rearm/CfgVehicles.hpp b/addons/rearm/CfgVehicles.hpp index de141c2837..7c442e4df9 100644 --- a/addons/rearm/CfgVehicles.hpp +++ b/addons/rearm/CfgVehicles.hpp @@ -17,13 +17,13 @@ class CBA_Extended_EventHandlers; class CfgVehicles { class ACE_Module; class ACE_moduleRearmSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(RearmSettings_Module_DisplayName); icon = QPATHTOF(ui\icon_module_rearm.paa); category = "ACE_Logistics"; function = QFUNC(moduleRearmSettings); functionPriority = 1; - isGlobal = 0; + isGlobal = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); class Arguments { @@ -106,12 +106,8 @@ class CfgVehicles { GVAR(defaultSupply) = 1200; }; - class Truck_02_Ammo_base_F; - class I_Truck_02_ammo_F: Truck_02_Ammo_base_F { - transportAmmo = 0; - GVAR(defaultSupply) = 1200; - }; - class O_Truck_02_Ammo_F: Truck_02_Ammo_base_F { + class Truck_02_base_F; + class Truck_02_Ammo_base_F: Truck_02_base_F { transportAmmo = 0; GVAR(defaultSupply) = 1200; }; diff --git a/addons/rearm/XEH_PREP.hpp b/addons/rearm/XEH_PREP.hpp index 59a43b4b29..dc34fbd9e9 100644 --- a/addons/rearm/XEH_PREP.hpp +++ b/addons/rearm/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(addMagazineToSupply); PREP(addRearmActions); PREP(addVehicleMagazinesToSupply); @@ -9,14 +8,16 @@ PREP(canTakeAmmo); PREP(createDummy); PREP(disable); PREP(dropAmmo); +PREP(getAllRearmTurrets); PREP(getCaliber); -PREP(getHardpointMagazines); PREP(getMaxMagazines); PREP(getNeedRearmMagazines); PREP(getSupplyCount); -PREP(getVehicleMagazines); +PREP(getTurretConfigMagazines); +PREP(getTurretMagazineAmmo); PREP(grabAmmo); PREP(handleKilled); +PREP(handleRespawn); PREP(handleUnconscious); PREP(hasEnoughSupply); PREP(initSupplyVehicle); @@ -32,6 +33,7 @@ PREP(rearmSuccess); PREP(rearmSuccessLocal); PREP(removeMagazineFromSupply); PREP(setSupplyCount); +PREP(setTurretMagazineAmmo); PREP(storeAmmo); PREP(takeAmmo); PREP(takeSuccess); diff --git a/addons/rearm/XEH_postInit.sqf b/addons/rearm/XEH_postInit.sqf index 59920be498..1fd9462df8 100644 --- a/addons/rearm/XEH_postInit.sqf +++ b/addons/rearm/XEH_postInit.sqf @@ -24,10 +24,3 @@ if (isServer) then { [QGVAR(rearmSuccessEH), LINKFUNC(rearmSuccess)] call CBA_fnc_addEventHandler; [QGVAR(rearmSuccessLocalEH), LINKFUNC(rearmSuccessLocal)] call CBA_fnc_addEventHandler; - -#ifdef DEBUG_MODE_FULL -INFO("Showing CfgVehicles with vanilla transportAmmo"); -{ - WARNING_2("Type [%1] needs config [transportAmmo: %2]", configName _x, getNumber (_x >> 'transportAmmo')); -} forEach (configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportAmmo')) > 0}", true]); -#endif diff --git a/addons/rearm/config.cpp b/addons/rearm/config.cpp index a4c130c974..348ca8751b 100644 --- a/addons/rearm/config.cpp +++ b/addons/rearm/config.cpp @@ -20,3 +20,7 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgVehicles.hpp" + +class ACE_Tests { + vehicleTransportAmmo = QPATHTOF(dev\test_debugConfigs.sqf); +}; diff --git a/addons/rearm/dev/test_debugConfigs.sqf b/addons/rearm/dev/test_debugConfigs.sqf new file mode 100644 index 0000000000..8b61bf195f --- /dev/null +++ b/addons/rearm/dev/test_debugConfigs.sqf @@ -0,0 +1,14 @@ +// ["vehicleTransportAmmo"] call ace_common_fnc_runTests; +// execVM "z\ace\addons\rearm\dev\test_debugConfigs.sqf"; + +#include "\z\ace\addons\rearm\script_component.hpp" + +private _testPass = true; + +INFO("Showing CfgVehicles with vanilla transportAmmo"); +{ + WARNING_2("Type [%1] needs config [transportAmmo: %2]", configName _x, getNumber (_x >> 'transportAmmo')); + _testPass = false; +} forEach (configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportAmmo')) > 0}", true]); + +_testPass diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf index c017c93509..b164449575 100644 --- a/addons/rearm/functions/fnc_addRearmActions.sqf +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -3,7 +3,7 @@ * Show the resupplyable ammunition of all surrounding vehicles. * * Arguments: - * 0: Target + * 0: Ammo Truck * * Return Value: * ChildActions @@ -15,7 +15,7 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]]]; +params ["_truck"]; private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20]; _vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}}; @@ -23,49 +23,12 @@ _vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && private _vehicleActions = []; { private _vehicle = _x; - private _magazineHelper = []; - { - private _turretPath = _x; - private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); - { - private _magazine = _x; - if (!(_magazine in _magazineHelper)) then { - private _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); - private _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines); - - if ((_currentMagazines < _maxMagazines) || {(_vehicle magazineTurretAmmo [_magazine, _turretPath]) < getNumber (configFile >> "CfgMagazines" >> _magazine >> "count")}) then { - _magazineHelper pushBack _magazine; - }; - }; - false - } count _magazines; - false - } count REARM_TURRET_PATHS; - - // 1.70 pylons - private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; - { - private _pylonName = configName _x; - private _pylonAmmo = _vehicle ammoOnPylon _pylonName; - private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex; - TRACE_3("",_pylonName,_pylonAmmo,_pylonMagazine); - - if (_pylonAmmo > 0) then { - // Try to refill current pylon: - private _magAmmo = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); - if ((!(_pylonMagazine in _magazineHelper)) && {_pylonAmmo < _magAmmo}) then { - _magazineHelper pushBack _pylonMagazine; - }; - } else { - // See what we magazines can add to the empty pylon: - private _hardpointMags = [_x] call FUNC(getHardpointMagazines); - { - if (!(_x in _magazineHelper)) then { - _magazineHelper pushBack _x; - }; - } forEach _hardpointMags; - }; - } forEach _pylonConfigs; + + // Array of magazines that can be rearmed in the vehicle + private _needRearmMags = ([_vehicle] call FUNC(getNeedRearmMagazines)) apply {_x select 0}; + + // _needRearmMags without duplicates + private _magazineHelper = _needRearmMags arrayIntersect _needRearmMags; _magazineHelper = _magazineHelper select {[_truck, _x] call FUNC(hasEnoughSupply)}; TRACE_2("can add",_x,_magazineHelper); @@ -77,40 +40,46 @@ private _vehicleActions = []; }; if (GVAR(level) == 0) then { // [Level 0] adds a single action to rearm the entire vic - private _action = [_vehicle, - getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), - _icon, - {_this call FUNC(rearmEntireVehicle)}, - {true}, - {}, - _vehicle] call EFUNC(interact_menu,createAction); + private _action = [ + _vehicle, + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), + _icon, + {_this call FUNC(rearmEntireVehicle)}, + {true}, + {}, + _vehicle + ] call EFUNC(interact_menu,createAction); _vehicleActions pushBack [_action, [], _truck]; } else { // [Level 1,2] - Add actions for each magazine private _actions = []; { - private _action = [_x, - getText(configFile >> "CfgMagazines" >> _x >> "displayName"), - getText(configFile >> "CfgMagazines" >> _x >> "picture"), - {_this call FUNC(takeAmmo)}, - {true}, - {}, - [_x, _vehicle]] call EFUNC(interact_menu,createAction); + private _action = [ + _x, + getText(configFile >> "CfgMagazines" >> _x >> "displayName"), + getText(configFile >> "CfgMagazines" >> _x >> "picture"), + {_this call FUNC(takeAmmo)}, + {true}, + {}, + [_x, _vehicle] + ] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _truck]; } forEach _magazineHelper; - private _action = [_vehicle, + private _action = [ + _vehicle, getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), _icon, {}, {true}, {}, - []] call EFUNC(interact_menu,createAction); + [] + ] call EFUNC(interact_menu,createAction); + _vehicleActions pushBack [_action, _actions, _truck]; }; }; - false -} count _vehicles; +} forEach _vehicles; _vehicleActions diff --git a/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf index 087ea7fddd..2a8f9fed14 100644 --- a/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf +++ b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf @@ -29,16 +29,17 @@ if (_vehicle isEqualType objNull) then {_vehicle = typeOf _vehicle}; if (_vehicle == "") exitWith { ERROR_1("VehicleType [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_string); }; +private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); { private _turretPath = _x; - private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); + private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines); TRACE_2("",_turretPath,_magazines); { [_truck, _x] call FUNC(addMagazineToSupply); false } count _magazines; false -} count REARM_TURRET_PATHS; +} count _turrets; // 1.70 pylons private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; diff --git a/addons/rearm/functions/fnc_canReadSupplyCounter.sqf b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf index 80b5d35cd7..60ca21b3f5 100644 --- a/addons/rearm/functions/fnc_canReadSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; (alive _unit) && {_unit isKindOf "CAManBase"} diff --git a/addons/rearm/functions/fnc_canRearm.sqf b/addons/rearm/functions/fnc_canRearm.sqf index ea41cae5a9..236f23e233 100644 --- a/addons/rearm/functions/fnc_canRearm.sqf +++ b/addons/rearm/functions/fnc_canRearm.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_vehicle", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_vehicle", "_unit"]; if (!alive _vehicle) exitWith {false}; if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {_vehicle distance _unit > REARM_ACTION_DISTANCE} || {_vehicle getVariable [QGVAR(disabled), false]}) exitWith {false}; @@ -29,4 +26,9 @@ if (isNull _dummy) exitwith {false}; private _magazineClass = _dummy getVariable QGVAR(magazineClass); if (isNil "_magazineClass") exitWith {false}; -([_vehicle, _magazineClass] call FUNC(getNeedRearmMagazines)) select 0 +private _needRearmMags = [_vehicle] call FUNC(getNeedRearmMagazines); + +// Testing if vehicle needs rearm on any magazines of class _magazineClass +private _needsRearm = ({(_x select 0) isEqualTo _magazineClass} count _needRearmMags) > 0; + +_needsRearm diff --git a/addons/rearm/functions/fnc_canStoreAmmo.sqf b/addons/rearm/functions/fnc_canStoreAmmo.sqf index b303af372c..4c4989b1d7 100644 --- a/addons/rearm/functions/fnc_canStoreAmmo.sqf +++ b/addons/rearm/functions/fnc_canStoreAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; (alive _unit) && {_unit isKindOf "CAManBase"} diff --git a/addons/rearm/functions/fnc_canTakeAmmo.sqf b/addons/rearm/functions/fnc_canTakeAmmo.sqf index 6f15f46eb0..c508df378d 100644 --- a/addons/rearm/functions/fnc_canTakeAmmo.sqf +++ b/addons/rearm/functions/fnc_canTakeAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; (alive _unit) && {_unit isKindOf "CAManBase"} diff --git a/addons/rearm/functions/fnc_createDummy.sqf b/addons/rearm/functions/fnc_createDummy.sqf index ecdaf9ff55..afca11935f 100644 --- a/addons/rearm/functions/fnc_createDummy.sqf +++ b/addons/rearm/functions/fnc_createDummy.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_unit", objNull, [objNull]], - ["_magazineClass", "", [""]] -]; +params ["_unit", "_magazineClass"]; private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); private _dummyName = getText (configFile >> "CfgAmmo" >> _ammo >> QGVAR(dummy)); diff --git a/addons/rearm/functions/fnc_dropAmmo.sqf b/addons/rearm/functions/fnc_dropAmmo.sqf index 8c1336476d..30b8b9d67d 100644 --- a/addons/rearm/functions/fnc_dropAmmo.sqf +++ b/addons/rearm/functions/fnc_dropAmmo.sqf @@ -18,9 +18,9 @@ #include "script_component.hpp" params [ - ["_unit", objNull, [objNull]], - ["_delete", false, [false]], - ["_unholster", true, [true]] + "_unit", + ["_delete", false], + ["_unholster", true] ]; private _dummy = _unit getVariable [QGVAR(dummy), objNull]; @@ -38,7 +38,8 @@ if (_actionID != -1) then { _unit removeAction _actionID; _unit setVariable [QGVAR(ReleaseActionID), nil]; }; -[_unit, "forceWalk", QGVAR(vehRearm), false] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", "ACE_rearm", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_rearm", false] call EFUNC(common,statusEffect_set); if (_unholster) then { REARM_UNHOLSTER_WEAPON diff --git a/addons/rearm/functions/fnc_getAllRearmTurrets.sqf b/addons/rearm/functions/fnc_getAllRearmTurrets.sqf new file mode 100644 index 0000000000..890fe5cc6f --- /dev/null +++ b/addons/rearm/functions/fnc_getAllRearmTurrets.sqf @@ -0,0 +1,28 @@ +/* + * Author: Tuupertunut + * Returns all turrets in a vehicle. + * + * BIS command "allTurrets" does not return the driver turret at the time of writing (2017-07-16). + * This function just adds driver turret to the array returned by "allTurrets". + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Turret paths + * + * Example: + * [vehicle] call ace_rearm_fnc_getAllRearmTurrets + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicle"]; + +private _turrets = allTurrets _vehicle; + +// Adding the driver turret "[-1]". +_turrets pushBack [-1]; + +_turrets diff --git a/addons/rearm/functions/fnc_getCaliber.sqf b/addons/rearm/functions/fnc_getCaliber.sqf index 7a07b9a1db..87f7b6cd88 100644 --- a/addons/rearm/functions/fnc_getCaliber.sqf +++ b/addons/rearm/functions/fnc_getCaliber.sqf @@ -18,7 +18,7 @@ #include "script_component.hpp" params [ - ["_magazineClass", "", [""]] + ["_magazineClass", ""] ]; if (_magazineClass isEqualTo "") exitWith {[8, 2]}; diff --git a/addons/rearm/functions/fnc_getHardpointMagazines.sqf b/addons/rearm/functions/fnc_getHardpointMagazines.sqf deleted file mode 100644 index 2a00fa8eb6..0000000000 --- a/addons/rearm/functions/fnc_getHardpointMagazines.sqf +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Author: PabstMirror - * Gets possible magazines that can be added to a pylon. - * - * Arguments: - * 0: Pylon config - * - * Return Value: - * Magazines - * - * Example: - * [config] call ace_rearm_fnc_getHardpointMagazines - * - * Public: No - */ -#include "script_component.hpp" - -params ["_pylonConfig"]; - -private _return = GVAR(hardpointGroupsCache) getVariable (str _pylonConfig); -if (isNil "_return") then { - _return = []; - private _hardpoints = (getArray (_pylonConfig >> "hardpoints")) apply {toLower _x}; - private _maxWeight = if (isNumber (_pylonConfig >> "maxWeight")) then {getNumber (_pylonConfig >> "maxWeight")} else {1e5}; - private _mags = configProperties [configFile >> "CfgMagazines", "(isClass _x) && {isArray (_x >> 'hardpoints')}"]; - { - if ((getNumber (_x >> "mass")) < _maxWeight) then { - private _magHardpoints = (getArray (_x >> "hardpoints")) apply {toLower _x}; - if (!((_hardpoints arrayIntersect _magHardpoints) isEqualTo [])) then { - _return pushBack configName _x; - }; - }; - } forEach _mags; - if ((str _pylonConfig) != "") then { - GVAR(hardpointGroupsCache) setVariable [(str _pylonConfig), _return]; - }; -}; - -_return; diff --git a/addons/rearm/functions/fnc_getMaxMagazines.sqf b/addons/rearm/functions/fnc_getMaxMagazines.sqf index c747714d86..6eba4e0ecc 100644 --- a/addons/rearm/functions/fnc_getMaxMagazines.sqf +++ b/addons/rearm/functions/fnc_getMaxMagazines.sqf @@ -17,13 +17,7 @@ */ #include "script_component.hpp" -params [ - ["_vehicle", objNull, [objNull]], - ["_turretPath", [], [[]]], - ["_magazineClass", "", [""]] -]; +params ["_vehicle", "_turretPath", "_magazineClass"]; -if (isNull _vehicle) exitWith {0}; - -private _count = {_x == _magazineClass} count ([_vehicle, _turretPath] call FUNC(getVehicleMagazines)); +private _count = {_x == _magazineClass} count ([_vehicle, _turretPath] call FUNC(getTurretConfigMagazines)); _count diff --git a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf index 6b2620a99a..b4195bb966 100644 --- a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf +++ b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf @@ -1,78 +1,87 @@ /* - * Author: GitHawk, Jonpas - * Get rearm return value. + * Author: Tuupertunut + * Returns information about every magazine that can be rearmed in the vehicle. Multiple mags of + * same class in the same turret are grouped together for practical reasons. * * Arguments: * 0: Vehicle - * 1: Magazine Classname * * Return Value: - * Return Value - * 0: Can Rearm - * 1: TurretPath - * 2: Number of current magazines in turret path - * 3: Pylon Index (-1 if not a pylon) + * Magazine info + * Child arrays: + * 0: Magazine class + * 1: Turret path + * 2: Is pylon magazine + * 3: Pylon index (-1 if not pylon) + * 4: Max magazines + * 5: Current magazines + * 6: Max rounds per magazine + * 7: Current rounds in magazines * * Example: - * [tank, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getNeedRearmMagazines + * [tank] call ace_rearm_fnc_getNeedRearmMagazines * * Public: No */ #include "script_component.hpp" -params [["_vehicle", objNull, [objNull]], ["_magazineClass", "", [""]]]; +params ["_vehicle"]; -private _return = [false, [], 0, -1]; +private _magazineInfo = []; + +// 1.70 pylons +private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; { - private _magazines = [_vehicle, _x] call FUNC(getVehicleMagazines); + private _pylonConfig = _x; + + // Strangely, a 1-based index. + private _pylonIndex = _forEachIndex + 1; + + // Retrieving pylon magazine by index. If the pylon is empty, it is marked with "". + private _pylonMagazine = (getPylonMagazines _vehicle) select (_pylonIndex - 1); + + // Only care about pylons that have a magazine. + if (!(_pylonMagazine isEqualTo "")) then { + + private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); + private _currentRounds = _vehicle ammoOnPylon _pylonIndex; + + if (_currentRounds < _maxRounds) then { + // getPylonTurret expects 0 based index, and returns driver turret as [-1] + private _pylonTurret = [_vehicle, (_pylonIndex - 1)] call EFUNC(common,getPylonTurret); - if (_magazineClass in _magazines) then { - private _currentMagazines = {_x == _magazineClass} count (_vehicle magazinesTurret _x); - - if ((_vehicle magazineTurretAmmo [_magazineClass, _x]) < getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count")) exitWith { - _return = [true, _x, _currentMagazines, -1]; - }; - - if (_currentMagazines < ([_vehicle, _x, _magazineClass] call FUNC(getMaxMagazines))) exitWith { - _return = [true, _x, _currentMagazines, -1]; + _magazineInfo pushBack [_pylonMagazine, _pylonTurret, true, _pylonIndex, 1, 1, _maxRounds, [_currentRounds]]; }; }; +} forEach _pylonConfigs; - if (_return select 0) exitWith {}; - false -} count REARM_TURRET_PATHS; +private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); +{ + private _turretPath = _x; + private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines); -if (!(_return select 0)) then { - // 1.70 pylons - private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; + // _magazines without duplicates + private _magazineClasses = _magazines arrayIntersect _magazines; + { - private _pylonName = configName _x; - private _pylonIndex = _forEachIndex + 1; // WTF BIS - private _pylonAmmo = _vehicle ammoOnPylon _pylonName; - private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex; - private _pylonTurret = getArray (_x >> "turret"); - if (_pylonTurret isEqualTo []) then {_pylonTurret = [-1];}; // convert to expected array for driver - TRACE_4("",_pylonName,_pylonAmmo,_pylonMagazine,_pylonTurret); + private _magazineClass = _x; + + private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMaxMagazines); + private _maxRoundsPerMag = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); + + /* Array of ammo counts in every magazine. Example: [200, 200, 152] means 2 mags with 200 + * rounds and 1 mag with 152 rounds. */ + private _currentRounds = [_vehicle, _turretPath, _magazineClass] call FUNC(getTurretMagazineAmmo); + private _currentMagazines = count _currentRounds; - if (_pylonAmmo > 0) then { - if (_magazineClass == _pylonMagazine) then { // Try to refill current pylon: - private _magAmmo = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); - if (_pylonAmmo < _magAmmo) then { - _return = [true, _pylonTurret, 0, _pylonIndex]; - }; - }; - } else { - // See what we magazines can add to the empty pylon: - private _hardpointMags = [_x] call FUNC(getHardpointMagazines); - { - if (_x == _magazineClass) then { - _return = [true, _pylonTurret, 0, _pylonIndex]; - }; - } forEach _hardpointMags; + /* If there is space for new magazines or if some magazines are not full, add the magazine + * type to _magazineInfo. */ + if ((_currentMagazines < _maxMagazines) || {({_x < _maxRoundsPerMag} count _currentRounds) > 0}) then { + _magazineInfo pushBack [_magazineClass, _turretPath, false, -1, _maxMagazines, _currentMagazines, _maxRoundsPerMag, _currentRounds]; }; - if (_return select 0) exitWith {}; - } forEach _pylonConfigs; -}; + + } forEach _magazineClasses; +} forEach _turrets; -TRACE_3("getNeedRearmMagazines",_vehicle,_magazineClass,_return); -_return +TRACE_2("getNeedRearmMagazines",_vehicle,_magazineInfo); +_magazineInfo diff --git a/addons/rearm/functions/fnc_getVehicleMagazines.sqf b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf similarity index 86% rename from addons/rearm/functions/fnc_getVehicleMagazines.sqf rename to addons/rearm/functions/fnc_getTurretConfigMagazines.sqf index 6a0932d908..0421e1ed1a 100644 --- a/addons/rearm/functions/fnc_getVehicleMagazines.sqf +++ b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf @@ -10,7 +10,7 @@ * Magazine classes in TurretPath * * Example: - * [vehicle, [0]] call ace_rearm_fnc_getVehicleMagazines + * [vehicle, [0]] call ace_rearm_fnc_getTurretConfigMagazines * * Public: No */ diff --git a/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf new file mode 100644 index 0000000000..53107dd7b0 --- /dev/null +++ b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf @@ -0,0 +1,27 @@ +/* + * Author: Tuupertunut + * Returns the current ammo counts in all magazines of given class in turret. + * + * BIS command "magazineTurretAmmo" is broken at the time of writing (2017-06-24) + * (https://feedback.bistudio.com/T79689). This function is intended as a workaround for it, + * extracting the data from the array returned by "magazinesAllTurrets". + * + * Arguments: + * 0: Vehicle + * 1: Turret Path + * 2: Magazine Classname + * + * Return Value: + * Current ammo counts in magazines. + * + * Example: + * [vehicle, [0], "200Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getTurretMagazineAmmo + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicle", "_turretPath", "_magazineClass"]; + +private _ammo = magazinesAllTurrets _vehicle select {(_x select 0) isEqualTo _magazineClass && {(_x select 1) isEqualTo _turretPath}} apply {_x select 2}; +_ammo diff --git a/addons/rearm/functions/fnc_grabAmmo.sqf b/addons/rearm/functions/fnc_grabAmmo.sqf index a77a17284b..13159987f2 100644 --- a/addons/rearm/functions/fnc_grabAmmo.sqf +++ b/addons/rearm/functions/fnc_grabAmmo.sqf @@ -16,19 +16,16 @@ */ #include "script_component.hpp" -params [ - ["_dummy", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_dummy", "_unit"]; REARM_HOLSTER_WEAPON; -[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", "ACE_rearm", true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_rearm", true] call EFUNC(common,statusEffect_set); [ TIME_PROGRESSBAR(5), [_dummy, _unit], { - private ["_actionID"]; params ["_args"]; _args params ["_dummy", "_unit"]; [_dummy, _unit] call FUNC(pickUpAmmo); diff --git a/addons/rearm/functions/fnc_handleKilled.sqf b/addons/rearm/functions/fnc_handleKilled.sqf index 3e39dc727e..b0cdabaed5 100644 --- a/addons/rearm/functions/fnc_handleKilled.sqf +++ b/addons/rearm/functions/fnc_handleKilled.sqf @@ -15,9 +15,7 @@ */ #include "script_component.hpp" -params [ - ["_unit", objNull, [objNull]] -]; +params ["_unit"]; if (!local _unit) exitWith {}; diff --git a/addons/rearm/XEH_respawn.sqf b/addons/rearm/functions/fnc_handleRespawn.sqf similarity index 63% rename from addons/rearm/XEH_respawn.sqf rename to addons/rearm/functions/fnc_handleRespawn.sqf index 5148894f98..26cb918c0e 100644 --- a/addons/rearm/XEH_respawn.sqf +++ b/addons/rearm/functions/fnc_handleRespawn.sqf @@ -1,3 +1,18 @@ +/* + * Author: unknown + * Called when a unit is Respawned + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [bob] call ACE_rearm_fnc_handleRespawn + * + * Public: No + */ #include "script_component.hpp" params ["_unit"]; diff --git a/addons/rearm/functions/fnc_handleUnconscious.sqf b/addons/rearm/functions/fnc_handleUnconscious.sqf index 0fbf1b8f06..f9d703f4ec 100644 --- a/addons/rearm/functions/fnc_handleUnconscious.sqf +++ b/addons/rearm/functions/fnc_handleUnconscious.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_unit", objNull, [objNull]], - ["_isUnconscious", false, [false]] -]; +params ["_unit", "_isUnconscious"]; if (!local _unit || {!_isUnconscious}) exitWith {}; diff --git a/addons/rearm/functions/fnc_hasEnoughSupply.sqf b/addons/rearm/functions/fnc_hasEnoughSupply.sqf index a2944db014..93f1f9ea3a 100644 --- a/addons/rearm/functions/fnc_hasEnoughSupply.sqf +++ b/addons/rearm/functions/fnc_hasEnoughSupply.sqf @@ -16,9 +16,7 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]]]; - -if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {false}; +params ["_truck", "_magazineClass"]; // With infinite supply, there is always enough if (GVAR(supply) == 0) exitWith {true}; diff --git a/addons/rearm/functions/fnc_makeDummy.sqf b/addons/rearm/functions/fnc_makeDummy.sqf index fbdd336a0d..574944a974 100644 --- a/addons/rearm/functions/fnc_makeDummy.sqf +++ b/addons/rearm/functions/fnc_makeDummy.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_obj", objNull, [objNull]], - ["_dirAndUp", [[1,0,0],[0,0,1]], [[]]] -]; +params ["_obj", "_dirAndUp"]; _obj setVectorDirAndUp _dirAndUp; _obj allowDamage false; diff --git a/addons/rearm/functions/fnc_moduleRearmSettings.sqf b/addons/rearm/functions/fnc_moduleRearmSettings.sqf index 2d498c8b57..61b6016c9d 100644 --- a/addons/rearm/functions/fnc_moduleRearmSettings.sqf +++ b/addons/rearm/functions/fnc_moduleRearmSettings.sqf @@ -1,6 +1,6 @@ /* * Author: GitHawk - * Module for adjusting the refuel settings. + * Module for adjusting the rearm settings. * * Arguments: * 0: The module logic @@ -28,4 +28,4 @@ if (!_activated) exitWith {}; [_logic, QGVAR(level), "level"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(supply), "supply"] call EFUNC(common,readSettingFromModule); -INFO_2("Module Initialized [level: %1][supply: %2]", GVAR(level), GVAR(supply)); +INFO_2("Module Initialized [level: %1][supply: %2]",GVAR(level),GVAR(supply)); diff --git a/addons/rearm/functions/fnc_pickUpAmmo.sqf b/addons/rearm/functions/fnc_pickUpAmmo.sqf index ee2845336b..0f47325a13 100644 --- a/addons/rearm/functions/fnc_pickUpAmmo.sqf +++ b/addons/rearm/functions/fnc_pickUpAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_dummy", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_dummy", "_unit"]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; if !(isNull _attachedDummy) exitWith {}; diff --git a/addons/rearm/functions/fnc_readSupplyCounter.sqf b/addons/rearm/functions/fnc_readSupplyCounter.sqf index cfcdb1b865..a1b46862b9 100644 --- a/addons/rearm/functions/fnc_readSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_readSupplyCounter.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]],["_unit", objNull, [objNull]]]; +params ["_truck", "_unit"]; TRACE_2("readSupplyCounter",_truck,_unit); if (GVAR(supply) == 0) exitWith {WARNING("Supply is unlimited");}; @@ -31,7 +31,7 @@ if (GVAR(supply) == 1) then { if (_supplyCount > 0 ) then { [[LSTRING(Hint_RemainingSupplyPoints), _supplyCount], 2, _unit] call EFUNC(common,displayTextStructured); } else { - [LSTRING(Hint_EmptySupplyPoints), 2, _unit] call EFUNC(common,displayTextStructured); + [LSTRING(Hint_Empty), 2, _unit] call EFUNC(common,displayTextStructured); }; true }, diff --git a/addons/rearm/functions/fnc_rearm.sqf b/addons/rearm/functions/fnc_rearm.sqf index 363a4905c7..e9d65c43b4 100644 --- a/addons/rearm/functions/fnc_rearm.sqf +++ b/addons/rearm/functions/fnc_rearm.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -params [["_target", objNull, [objNull]],["_unit", objNull, [objNull]]]; +params ["_target", "_unit"]; TRACE_2("rearm",_target,_unit); private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; @@ -27,24 +27,30 @@ if (isNil "_magazineClass") exitWith {ERROR_1("magazineClass nil",_attachedDummy ([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; // Get magazines that can be rearmed -private _needRearmMags = [_target, _magazineClass] call FUNC(getNeedRearmMagazines); -_needRearmMags params ["_needRearm", "_turretPath", "_cnt", "_pylon"]; +private _needRearmMags = [_target] call FUNC(getNeedRearmMagazines); +private _needRearmMagsOfClass = _needRearmMags select {(_x select 0) isEqualTo _magazineClass}; // Exit if no magazines need rearming -if (!_needRearm) exitWith {ERROR_2("Could not find turret for %1 in %2", _magazineClass, typeOf _target);}; +if ((count _needRearmMagsOfClass) == 0) exitWith {ERROR_2("Could not find turret for %1 in %2",_magazineClass,typeOf _target);}; + +private _currentRearmableMag = _needRearmMagsOfClass select 0; +_currentRearmableMag params ["", "_turretPath", "", "_pylon", "", "_magazineCount"]; private _magazineDisplayName = getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"); if (_magazineDisplayName == "") then { _magazineDisplayName = _magazineClass; - ERROR_1("Magazine is missing display name [%1]", _magazineClass); + ERROR_1("Magazine is missing display name [%1]",_magazineClass); }; [ TIME_PROGRESSBAR(REARM_DURATION_REARM select _idx), - [_target, _unit, _turretPath, _cnt, _magazineClass, (REARM_COUNT select _idx), _pylon], + [_target, _unit, _turretPath, _magazineCount, _magazineClass, (REARM_COUNT select _idx), _pylon], {(_this select 0) call FUNC(rearmSuccess)}, "", format [localize LSTRING(RearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName"), _magazineDisplayName], - {true}, + { + param [0] params ["_target", "_unit"]; + (_unit distanceSqr _target) <= REARM_ACTION_DISTANCE_SQR + }, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf index 8fddb4ab85..a388b80c32 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf @@ -17,18 +17,18 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - "", - ["_vehicle", objNull, [objNull]] -]; +params ["_truck", "_player", "_vehicle"]; +TRACE_3("rearmEntireVehicle",_truck,_player,_vehicle); [ TIME_PROGRESSBAR(10), - [_truck, _vehicle], + [_truck, _vehicle, _player], FUNC(rearmEntireVehicleSuccess), "", format [localize LSTRING(BasicRearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], - {true}, + { + param [0] params ["", "_vehicle", "_player"]; + (_player distanceSqr _vehicle) <= REARM_ACTION_DISTANCE_SQR + }, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf index dda3ff9ca7..2ad70f9626 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf @@ -5,7 +5,7 @@ * Arguments: * 0: Rearm information * 0: Ammo Truck - * 1: Vehicle * * Return Value: * None @@ -18,10 +18,11 @@ #include "script_component.hpp" params ["_args"]; -_args params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull]]]; +_args params ["_truck", "_vehicle"]; TRACE_2("rearmEntireVehicleSuccess",_truck,_vehicle); if (isServer) then { + private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); { private _turretOwnerID = _vehicle turretOwner _x; if (_turretOwnerID == 0) then { @@ -30,7 +31,7 @@ if (isServer) then { [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent; }; false - } count REARM_TURRET_PATHS; + } count _turrets; } else { [QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent; }; diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf index 01901fdf87..031c1d1f4d 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf @@ -1,5 +1,5 @@ /* - * Author: GitHawk + * Author: Tuupertunut * Rearm an entire turret locally. * * Arguments: @@ -17,60 +17,42 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull]], ["_turretPath", [], [[]]]]; +params ["_truck", "_vehicle", "_turretPath"]; TRACE_3("rearmEntireVehicleSuccessLocal",_truck,_vehicle,_turretPath); -// 1.70 pylons -private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; +// Fetching all rearmable magazines in this turret +private _magazines = ([_vehicle] call FUNC(getNeedRearmMagazines)) select {(_x select 1) isEqualTo _turretPath}; { - private _pylonTurret = getArray (_x >> "turret"); - if (_pylonTurret isEqualTo []) then {_pylonTurret = [-1];}; // convert to expected array for driver - if (_pylonTurret isEqualTo _turretPath) then { - private _pylonIndex = _forEachIndex + 1; // GJ BIS - private _pylonAmmo = _vehicle ammoOnPylon _pylonIndex; - private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex; - private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); - TRACE_4("",_pylonIndex,_pylonAmmo,_maxRounds,_pylonMagazine); - if (_pylonAmmo < _maxRounds) then { - if ((GVAR(supply) == 0) || {[_truck, _pylonMagazine, (_maxRounds - _pylonAmmo)] call FUNC(removeMagazineFromSupply)}) then { - TRACE_3("Adding Rounds",_vehicle,_pylonIndex,_maxRounds); - _vehicle setAmmoOnPylon [_pylonIndex, _maxRounds]; + _x params ["_magazineClass", "_magTurretPath", "_isPylonMag", "_pylonIndex", "_maxMagazines", "_currentMagazines", "_maxRoundsPerMag", "_currentRounds"]; + + // Array of planned ammo counts in every magazine after the rearm is complete + private _plannedRounds = +_currentRounds; + + // Trying to fill all existing magazines. + { + if (_x < _maxRoundsPerMag) then { + if ((GVAR(supply) == 0) || {[_truck, _magazineClass, (_maxRoundsPerMag - _x)] call FUNC(removeMagazineFromSupply)}) then { + _plannedRounds set [_forEachIndex, _maxRoundsPerMag]; }; }; - }; -} forEach _pylonConfigs; - -private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); -if (isNil "_magazines") exitWith {}; -{ - private _magazine = _x; - private _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); - private _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines); - private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); - private _currentRounds = _vehicle magazineTurretAmmo [_magazine, _turretPath]; - - TRACE_7("Rearmed Turret",_vehicle,_turretPath,_currentMagazines,_maxMagazines,_currentRounds,_maxRounds,_magazine); - - if (_turretPath isEqualTo [-1] && _currentMagazines == 0) then { - // On driver, the empty magazine is still there, but is not returned by magazinesTurret - _currentMagazines = _currentMagazines + 1; - }; + } forEach _currentRounds; + + // Trying to add new full magazines, if there is space left. if (_currentMagazines < _maxMagazines) then { - private _success = true; - if ((GVAR(supply) == 0) || {[_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply)}) then { - _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; - }; - for "_idx" from 1 to (_maxMagazines - _currentMagazines) do { - if ((GVAR(supply) == 0) || {[_truck, _magazine, _maxRounds] call FUNC(removeMagazineFromSupply)}) then { - _vehicle addMagazineTurret [_magazine, _turretPath]; + if ((GVAR(supply) == 0) || {[_truck, _magazineClass, _maxRoundsPerMag] call FUNC(removeMagazineFromSupply)}) then { + _plannedRounds pushBack _maxRoundsPerMag; }; }; - } else { - if ((GVAR(supply) == 0) || {[_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply)}) then { - _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; - }; }; - false -} count _magazines; + + TRACE_2("rearming",_x,_plannedRounds); + + // Updating new ammo counts to vehicle. + if (_isPylonMag) then { + _vehicle setAmmoOnPylon [_pylonIndex, (_plannedRounds select 0)]; + } else { + [_vehicle, _magTurretPath, _magazineClass, _plannedRounds] call FUNC(setTurretMagazineAmmo); + }; +} forEach _magazines; diff --git a/addons/rearm/functions/fnc_rearmSuccess.sqf b/addons/rearm/functions/fnc_rearmSuccess.sqf index c609117002..0fc8219180 100644 --- a/addons/rearm/functions/fnc_rearmSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmSuccess.sqf @@ -21,7 +21,7 @@ */ #include "script_component.hpp" -params [["_vehicle", objNull, [objNull]], ["_unit", objNull, [objNull]], "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"]; +params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"]; TRACE_7("rearmSuccess",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon); if (local _unit) then { diff --git a/addons/rearm/functions/fnc_setSupplyCount.sqf b/addons/rearm/functions/fnc_setSupplyCount.sqf index d9d5194550..ef99a78416 100644 --- a/addons/rearm/functions/fnc_setSupplyCount.sqf +++ b/addons/rearm/functions/fnc_setSupplyCount.sqf @@ -23,6 +23,6 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the s params [["_truck", objNull, [objNull]], ["_supply", 0, [0]]]; if (GVAR(supply) != 1) exitWith {WARNING("supply setting is not set to limited");}; -if (isNull _truck) exitWith {WARNING_1("Truck is null [%1]", _truck);}; +if (isNull _truck) exitWith {WARNING_1("Truck is null [%1]",_truck);}; _truck setVariable [QGVAR(currentSupply), (_supply max 0), true]; diff --git a/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf new file mode 100644 index 0000000000..2cc5e156d5 --- /dev/null +++ b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf @@ -0,0 +1,89 @@ +/* + * Author: Tuupertunut + * Sets the ammo counts of all magazines of given class in turret. + * + * BIS command "setMagazineTurretAmmo" is broken at the time of writing (2017-06-24) + * (https://feedback.bistudio.com/T79689). This function is intended as a workaround for it. All + * magazines are removed and then added again with updated ammo counts. + * Note: As an unintended side effect, the turret reloads after running this function. + * + * Arguments: + * 0: Vehicle + * 1: Turret Path + * 2: Magazine Classname + * 3: Ammo Counts in Magazines + * + * Return Value: + * None + * + * Example: + * [vehicle, [0], "200Rnd_127x99_mag_Tracer_Red", [200, 152]] call ace_rearm_fnc_setTurretMagazineAmmo + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicle", "_turretPath", "_magazineClass", "_ammoCounts"]; + +// Checking if a magazine of given class is currently loaded in any weapon. +private _magLoadedInWeapon = false; +private _loadedWeapon = ""; +{ + private _currentlyLoadedMag = (weaponState [_vehicle, _turretPath, _x]) select 3; + + if (_currentlyLoadedMag isEqualTo _magazineClass) exitWith { + _magLoadedInWeapon = true; + _loadedWeapon = _x; + }; +} forEach (_vehicle weaponsTurret _turretPath); + + +if (!_magLoadedInWeapon) then { + /* The easy case: + * The magazine class was not loaded, so we can just remove those magazines and + * add them back with updated ammo counts. */ + + _vehicle removeMagazinesTurret [_magazineClass, _turretPath]; + { + _vehicle addMagazineTurret [_magazineClass, _turretPath, _x]; + } forEach _ammoCounts; + +} else { + /* Special hack case: + * The magazine class was loaded into a weapon. If the weapon has more than one type of + * magazine (e.g. AP and HEAT in a cannon), then removing all magazines would trigger the + * weapon to load a different magazine type. For example, removing the HEAT shells while HEAT + * is loaded makes the cannon switch to AP. + * + * To prevent that, we must remove all magazines that would fit into the weapon and then add + * them back with the magazine-to-be-loaded being the first. */ + + private _allowedMagClassesInWeapon = getArray (configFile >> "CfgWeapons" >> _loadedWeapon >> "magazines"); + + /* Current ammo counts of all allowed magazine classes in weapon. + * Example: [["8Rnd_82mm_Mo_shells", [8, 8, 2]], ["8Rnd_82mm_Mo_Flare_white", [7]]] */ + private _ammoCountsByMagClass = _allowedMagClassesInWeapon apply {[_x, ([_vehicle, _turretPath, _x] call FUNC(getTurretMagazineAmmo))]}; + + // Removing all magazines that fit into the weapon. + { + _vehicle removeMagazinesTurret [_x, _turretPath]; + } forEach _allowedMagClassesInWeapon; + + // Adding the mags of the given class first with updated ammo counts. + { + _vehicle addMagazineTurret [_magazineClass, _turretPath, _x]; + } forEach _ammoCounts; + + // Adding back all other magazines with their original ammo counts. + { + _x params ["_loopMagClass", "_loopAmmoCounts"]; + + if (!(_loopMagClass isEqualTo _magazineClass)) then { + { + _vehicle addMagazineTurret [_loopMagClass, _turretPath, _x]; + } forEach _loopAmmoCounts; + }; + } forEach _ammoCountsByMagClass; +}; + +TRACE_5("setTurretMagazineAmmo",_vehicle,_turretPath,_magazineClass,_ammoCounts,_loadedWeapon); diff --git a/addons/rearm/functions/fnc_storeAmmo.sqf b/addons/rearm/functions/fnc_storeAmmo.sqf index c056421bba..0da99c081a 100644 --- a/addons/rearm/functions/fnc_storeAmmo.sqf +++ b/addons/rearm/functions/fnc_storeAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; if (isNull _attachedDummy) exitwith {}; diff --git a/addons/rearm/functions/fnc_takeAmmo.sqf b/addons/rearm/functions/fnc_takeAmmo.sqf index 23f19fedf4..69db94729d 100644 --- a/addons/rearm/functions/fnc_takeAmmo.sqf +++ b/addons/rearm/functions/fnc_takeAmmo.sqf @@ -19,11 +19,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]], - ["_args", ["", objNull], [[]]] -]; +params ["_truck", "_unit", "_args"]; _args params ["_magazineClass", "_vehicle"]; TRACE_5("takeAmmo",_truck,_unit,_args,_magazineClass,_vehicle); diff --git a/addons/rearm/functions/fnc_takeSuccess.sqf b/addons/rearm/functions/fnc_takeSuccess.sqf index e458036176..9e6be0fe1c 100644 --- a/addons/rearm/functions/fnc_takeSuccess.sqf +++ b/addons/rearm/functions/fnc_takeSuccess.sqf @@ -18,7 +18,7 @@ */ #include "script_component.hpp" -params [["_args", [objNull, "", objNull], [[]], 3]]; +params ["_args"]; _args params ["_unit", "_magazineClass", "_truck"]; TRACE_3("takeSuccess",_unit,_magazineClass,_truck); @@ -28,7 +28,8 @@ if (GVAR(supply) > 0) then { }; if !(_success) exitWith {WARNING_2("takeSuccess failed to take [%1] from [%2]",_magazineClass,_truck);}; -[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set); +[_unit, "forceWalk", "ACE_rearm", true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_rearm", true] call EFUNC(common,statusEffect_set); private _dummy = [_unit, _magazineClass] call FUNC(createDummy); [_dummy, _unit] call FUNC(pickUpAmmo); diff --git a/addons/rearm/script_component.hpp b/addons/rearm/script_component.hpp index 3edfeda3f1..a80dab55b2 100644 --- a/addons/rearm/script_component.hpp +++ b/addons/rearm/script_component.hpp @@ -19,7 +19,7 @@ #define REARM_ACTION_DISTANCE 7 -#define REARM_TURRET_PATHS [[-1], [0], [0,0], [0,1], [1], [2], [0,2]] +#define REARM_ACTION_DISTANCE_SQR 49 #define REARM_CALIBERS [ 6, 7, 8, 13, 19, 20, 25, 30, 35, 39, 40, 60, 70, 80, 82, 100, 105, 120, 122, 125, 155, 230, 250] #define REARM_DURATION_TAKE [ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 13, 10] diff --git a/addons/rearm/stringtable.xml b/addons/rearm/stringtable.xml index 05aecd1102..3823d031ef 100644 --- a/addons/rearm/stringtable.xml +++ b/addons/rearm/stringtable.xml @@ -1,6 +1,14 @@ - + + + Rearm + Aufmunitionierung + Riarmo + 整裝 + 整装 + 再武装 + Rearm Settings Aufmunitioniereinstellungen @@ -11,10 +19,10 @@ Impostazioni Riarmo Parámetros de rearme Options de réarmement - 再武装設定 재보급 설정 整装设定 整裝設定 + 再武装設定 This module allows you to tweak rearm system settings. @@ -108,11 +116,13 @@ Ammunition supply - Munitionsvorat + Munitionsvorrat Scorta munizioni 弾薬の供給 弹药补给 彈藥補給 + Zapas amunicji + 탄약 보급 How much ammunition does an ammo truck carry? @@ -121,22 +131,28 @@ 弾薬トラックがどの位の弾薬を供給できるようにしますか? 弹药卡车会携带多少的弹药? 彈藥卡車會攜帶多少的彈藥? + Ile amunicji przewozi ciężarówka? + 탄약 차량은 얼마나 많은 양의 탄약을 가질 수 있음? Unlimited ammo supply - Unbegrenzter Munitionsvorat + Unbegrenzter Munitionsvorrat Scorta munizioni infinita 無制限供給 无限弹药 無限彈藥 + Nielimitowany zapas amunicji + 무한의 탄약 Limited ammo supply based on caliber - Begrenzter, kaliberabhängiger Munitionsvorat + Begrenzter, kaliberabhängiger Munitionsvorrat Scorta munizioni limitata in base al calibro 口径に基づいた限定的供給 基于口径限制弹药数量 基於口徑限制彈藥數量 + Zapas amunicji zależny od kalibru + 구경에 따라 제한된 탄약 Only specific Magazines @@ -145,6 +161,8 @@ 特定の弾薬のみ 只有指定的弹药 只有指定的彈藥 + Tylko konkretne magazynki + 특정 탄약만 Check remaining ammunition @@ -153,6 +171,8 @@ 残弾薬を確認 检查剩余的弹药 檢查剩餘的彈藥 + Sprawdź ilość amunicji + 남은 탄약 확인 Checking remaining ammunition... @@ -161,6 +181,8 @@ 残弾薬を確認しています・・・ 正在检查剩余的弹药中... 正在檢查剩餘的彈藥中... + Sprawdzanie ilości amunicji... + 남은 탄약 확인중... There is ammunition worth %1 points left. @@ -169,6 +191,8 @@ この弾薬は%1残っている 还剩下%1多的弹药. 還剩下%1多的彈藥. + Pozostało %1 punktów amunicji. + 여기에는 최소 %1 포인트의 탄약이 남았습니다. The following ammunition is left:%1 @@ -177,6 +201,8 @@ この弾薬の残りは:%1 以下剩余的弹药:%1 以下剩餘的彈藥:%1 + Pozostała amunicja: %1 + 다음의 탄약이 남음 : %1 There is no ammunition left. @@ -185,6 +211,8 @@ 弾薬は残っていません。 已经没有剩余的弹药了. 已經沒有剩餘的彈藥了. + Brak amunicji w zapasie. + 여기에는 탄약이 남지 않았습니다. Rearm @@ -465,7 +493,7 @@ Hydra 70 HE Hydra 70 HE Hydra 70 HE - ハイドラ 70 りゅう弾 + ハイドラ 70 HE Hydra 70 고폭탄 九头蛇 70 高爆弹 九頭蛇 70 高爆彈 @@ -480,7 +508,7 @@ S-8 HE S-8 HE S-8 HE - S-8 りゅう弾 + S-8 HE S-8 고폭탄 S-8 高爆弹 S-8 高爆彈 @@ -495,7 +523,7 @@ Hydra 70 AP Hydra 70 AP Hydra 70 AP - ハイドラ 70 徹甲弾 + ハイドラ 70 AP Hydra 70 철갑탄 九头蛇 70 反人员弹 九頭蛇 70 反人員彈 @@ -510,7 +538,7 @@ S-8 AP S-8 AP S-8 AP - S-8 徹甲弾 + S-8 AP S-8 철갑탄 S-8 反人员弹 S-8 反人員彈 diff --git a/addons/refuel/ACE_Settings.hpp b/addons/refuel/ACE_Settings.hpp index a25c36a2ba..6904d33431 100644 --- a/addons/refuel/ACE_Settings.hpp +++ b/addons/refuel/ACE_Settings.hpp @@ -5,11 +5,13 @@ class ACE_Settings { description = CSTRING(RefuelSettings_speed_Description); value = 1; typeName = "SCALAR"; + sliderSettings[] = {0, 25, 1, 1}; }; class GVAR(hoseLength) { category = ECSTRING(OptionsMenu,CategoryLogistics); displayName = CSTRING(RefuelSettings_hoseLength_DisplayName); value = 12; typeName = "SCALAR"; + sliderSettings[] = {0, 50, 12, 1}; }; }; diff --git a/addons/refuel/Cfg3DEN.hpp b/addons/refuel/Cfg3DEN.hpp new file mode 100644 index 0000000000..3dbc91c2cf --- /dev/null +++ b/addons/refuel/Cfg3DEN.hpp @@ -0,0 +1,36 @@ +#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) +#define GET_1ST_ARRAY(config) (if (isArray (config)) then {getArray (config) select 0} else {[ARR_3(0,0,0)]}) + +#define DEFAULT_FUELCARGO GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(fuelCargo),REFUEL_DISABLED_FUEL) +#define DEFAULT_HOOKS GET_1ST_ARRAY(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(hooks)) + +class Cfg3DEN { + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class GVAR(fuelCargo) { + displayName = CSTRING(fuelCargo_edenName); + tooltip = CSTRING(fuelCargo_edenDesc); + property = QGVAR(fuelCargo); + control = "EditShort"; + expression = QUOTE(if (_value != DEFAULT_FUELCARGO) then {[ARR_2(_this,_value)] call DFUNC(makeSource)}); + defaultValue = QUOTE(DEFAULT_FUELCARGO); + validate = "number"; + condition = "(1-objectBrain)*(1-objectAgent)"; + typeName = "NUMBER"; + }; + class GVAR(hooks) { + displayName = CSTRING(hooks_edenName); + tooltip = CSTRING(hooks_edenDesc); + property = QGVAR(hooks); + control = "EditXYZ"; + expression = QUOTE(if !(_value isEqualTo DEFAULT_HOOKS) then {_this setVariable [ARR_3('%s',[_value],true)]}); + defaultValue = QUOTE(DEFAULT_HOOKS); + condition = "(1-objectBrain)*(1-objectAgent)"; + }; + }; + }; + }; + }; +}; diff --git a/addons/refuel/CfgEventHandlers.hpp b/addons/refuel/CfgEventHandlers.hpp index 20f482c8ca..c8d6e21596 100644 --- a/addons/refuel/CfgEventHandlers.hpp +++ b/addons/refuel/CfgEventHandlers.hpp @@ -19,15 +19,7 @@ class Extended_PostInit_EventHandlers { class Extended_Respawn_EventHandlers { class CAManBase { class ADDON { - respawn = QUOTE(call COMPILE_FILE(XEH_respawn)); - }; - }; -}; - -class Extended_Killed_EventHandlers { - class CAManBase { - class ADDON { - killed = QUOTE(_this call FUNC(handleKilled)); + respawn = QUOTE(call DFUNC(handleRespawn)); }; }; }; @@ -35,7 +27,7 @@ class Extended_Killed_EventHandlers { class Extended_InitPost_EventHandlers { class Land_CanisterFuel_F { class ADDON { - init = QUOTE(_this call DFUNC(makeJerryCan)); + init = QUOTE(call DFUNC(makeJerryCan)); }; }; }; diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index de361a6816..cf4d590df8 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -1,61 +1,3 @@ - -#define MACRO_REFUEL_ACTIONS \ - class ACE_Actions: ACE_Actions { \ - class ACE_MainActions: ACE_MainActions { \ - class GVAR(Refuel) { \ - displayName = CSTRING(Refuel); \ - distance = REFUEL_ACTION_DISTANCE; \ - condition = "alive _target"; \ - statement = ""; \ - showDisabled = 0; \ - priority = 2; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - class GVAR(TakeNozzle) { \ - displayName = CSTRING(TakeNozzle); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); \ - statement = QUOTE([ARR_3(_player,_target,objNull)] call FUNC(TakeNozzle)); \ - exceptions[] = {"isNotInside"}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - class GVAR(CheckFuelCounter) { \ - displayName = CSTRING(CheckFuelCounter); \ - condition = "true"; \ - statement = QUOTE([ARR_2(_player,_target)] call FUNC(readFuelCounter)); \ - exceptions[] = {"isNotInside"}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - class GVAR(CheckFuel) { \ - displayName = CSTRING(CheckFuel); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckFuel)); \ - statement = QUOTE([ARR_2(_player,_target)] call FUNC(checkFuel)); \ - exceptions[] = {"isNotInside"}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - class GVAR(Return) { \ - displayName = CSTRING(Return); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canReturnNozzle)); \ - statement = QUOTE([ARR_2(_player,_target)] call DFUNC(returnNozzle)); \ - exceptions[] = {"isNotInside"}; \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - }; \ - }; \ - }; \ - }; - -#define MACRO_CONNECT_ACTIONS \ - class ACE_Actions { \ - class ACE_MainActions { \ - class GVAR(Connect) { \ - displayName = CSTRING(Connect); \ - distance = REFUEL_ACTION_DISTANCE; \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canConnectNozzle)); \ - statement = QUOTE([ARR_2(_player,_target)] call DFUNC(connectNozzle)); \ - icon = QPATHTOF(ui\icon_refuel_interact.paa); \ - exceptions[] = {"isNotInside"}; \ - }; \ - }; \ - }; - #define MACRO_NOZZLE_ACTIONS \ class ACE_Actions { \ class ACE_MainActions { \ @@ -64,35 +6,36 @@ position = "[0,-0.025,0.125]"; \ condition = "true"; \ statement = ""; \ + exceptions[] = {INTERACT_EXCEPTIONS}; \ showDisabled = 0; \ priority = 2; \ icon = QPATHTOF(ui\icon_refuel_interact.paa); \ class GVAR(PickUpNozzle) { \ displayName = CSTRING(TakeNozzle); \ condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); \ - statement = QUOTE([ARR_3(_player,objNull,_target)] call FUNC(takeNozzle)); \ - exceptions[] = {"isNotInside"}; \ + statement = QUOTE([ARR_2(_player,_target)] call FUNC(takeNozzle)); \ + exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \ icon = QPATHTOF(ui\icon_refuel_interact.paa); \ }; \ class GVAR(TurnOn) { \ displayName = CSTRING(TurnOn); \ condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOn)); \ statement = QUOTE([ARR_2(_player,_target)] call DFUNC(turnOn)); \ - exceptions[] = {"isNotInside"}; \ + exceptions[] = {INTERACT_EXCEPTIONS}; \ icon = QPATHTOF(ui\icon_refuel_interact.paa); \ }; \ class GVAR(TurnOff) { \ displayName = CSTRING(TurnOff); \ condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOff)); \ statement = QUOTE([ARR_2(_player,_target)] call DFUNC(turnOff)); \ - exceptions[] = {"isNotInside"}; \ + exceptions[] = {INTERACT_EXCEPTIONS}; \ icon = QPATHTOF(ui\icon_refuel_interact.paa); \ }; \ class GVAR(Disconnect) { \ displayName = CSTRING(Disconnect); \ condition = QUOTE([ARR_2(_player,_target)] call FUNC(canDisconnect)); \ statement = QUOTE([ARR_2(_player,_target)] call DFUNC(disconnect)); \ - exceptions[] = {"isNotInside"}; \ + exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \ icon = QPATHTOF(ui\icon_refuel_interact.paa); \ }; \ }; \ @@ -103,13 +46,13 @@ class CBA_Extended_EventHandlers; class CfgVehicles { class ACE_Module; class ACE_moduleRefuelSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(RefuelSettings_Module_DisplayName); icon = QPATHTOF(ui\icon_module_refuel.paa); category = "ACE_Logistics"; function = QFUNC(moduleRefuelSettings); functionPriority = 1; - isGlobal = 0; + isGlobal = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); class Arguments { @@ -164,31 +107,27 @@ class CfgVehicles { class Land: AllVehicles {}; class LandVehicle: Land {}; class Car: LandVehicle { - MACRO_CONNECT_ACTIONS + GVAR(canReceive) = 1; }; class Tank: LandVehicle { - MACRO_CONNECT_ACTIONS + GVAR(canReceive) = 1; GVAR(flowRate) = 4; }; - class StaticWeapon: LandVehicle { - MACRO_CONNECT_ACTIONS - }; - class Air: AllVehicles { GVAR(flowRate) = 8; }; class Helicopter: Air { - MACRO_CONNECT_ACTIONS + GVAR(canReceive) = 1; }; class Helicopter_Base_F: Helicopter {}; class Helicopter_Base_H: Helicopter_Base_F {}; class Plane: Air { - MACRO_CONNECT_ACTIONS + GVAR(canReceive) = 1; GVAR(flowRate) = 16; }; @@ -197,7 +136,7 @@ class CfgVehicles { class Ship: AllVehicles {}; class Ship_F: Ship { - MACRO_CONNECT_ACTIONS + GVAR(canReceive) = 1; GVAR(flowRate) = 4; }; @@ -215,11 +154,14 @@ class CfgVehicles { class Rubber_duck_base_F: Boat_F { GVAR(fuelCapacity) = 30; }; - class SDV_01_base_F: Boat_F { +/* class SDV_01_base_F: Boat_F { // SDV is using electrical propulsion - GVAR(fuelCapacity) = 0; + // but we can't recharge it ATM another way + // TODO make recharging, maybe with this objects: + // Land_PowerGenerator_F Land_Portable_generator_F + GVAR(canReceive) = 0; }; - +*/ class Car_F: Car { // Assuming large vehicle tank GVAR(fuelCapacity) = 60; @@ -301,7 +243,6 @@ class CfgVehicles { }; class Van_01_fuel_base_F: Van_01_base_F { - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{0.38,-3.17,-.7},{-0.41,-3.17,-.7}}; GVAR(fuelCargo) = 2000; }; @@ -326,7 +267,6 @@ class CfgVehicles { class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { transportFuel = 0; //3k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{-1.08,-4.81,-.8}}; GVAR(fuelCargo) = 1000; }; @@ -412,7 +352,11 @@ class CfgVehicles { class UAV_01_base_F: Helicopter_Base_F { // Darter is electrical - GVAR(fuelCapacity) = 0; + GVAR(canReceive) = 0; + }; + class UAV_06_base_F: Helicopter_Base_F { + // Orange UAV is electrical + GVAR(canReceive) = 0; }; class UAV: Plane {}; @@ -430,21 +374,21 @@ class CfgVehicles { // Vanilla fuel vehicles class Truck_02_fuel_base_F: Truck_02_base_F { transportFuel = 0; //3k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{0.99,-3.47,-0.67},{-1.04,-3.47,-0.67}}; GVAR(fuelCargo) = 10000; }; + class Truck_02_water_base_F: Truck_02_fuel_base_F { + GVAR(fuelCargo) = REFUEL_DISABLED_FUEL; + }; class B_Truck_01_fuel_F: B_Truck_01_mover_F { transportFuel = 0; //3k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{.28,-4.99,-.3},{-.25,-4.99,-.3}}; GVAR(fuelCargo) = 10000; }; class O_Truck_03_fuel_F: Truck_03_base_F { transportFuel = 0; //3k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{1.3,-1.59,-.62},{-1.16,-1.59,-.62}}; GVAR(fuelCargo) = 10000; }; @@ -459,7 +403,6 @@ class CfgVehicles { class Pod_Heli_Transport_04_base_F: Slingload_base_F {}; class Land_Pod_Heli_Transport_04_fuel_F: Pod_Heli_Transport_04_base_F { transportFuel = 0; //3k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{-1.49,1.41,-.3}}; GVAR(fuelCargo) = 10000; }; @@ -467,14 +410,12 @@ class CfgVehicles { class Slingload_01_Base_F: Slingload_base_F {}; class B_Slingload_01_Fuel_F: Slingload_01_Base_F { transportFuel = 0; //3k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{0.55,3.02,-0.5},{-0.52,3.02,-0.5}}; GVAR(fuelCargo) = 10000; }; class O_Heli_Transport_04_fuel_F: Heli_Transport_04_base_F { transportFuel = 0; //3k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{-1.52,1.14,-1.18}}; GVAR(fuelCargo) = 10000; }; @@ -496,7 +437,6 @@ class CfgVehicles { }; transportFuel = 0; //60k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{-3.35,2.45,0.17}}; GVAR(fuelCargo) = 60000; }; @@ -513,7 +453,6 @@ class CfgVehicles { }; class Land_FlexibleTank_01_F: FlexibleTank_base_F { transportFuel = 0; //300 - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{0, 0, 0.5}}; GVAR(fuelCargo) = 300; }; @@ -521,27 +460,23 @@ class CfgVehicles { // Vanilla buildings class Land_Fuelstation_Feed_F: House_Small_F { transportFuel = 0; //50k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{0,0,-0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_fs_feed_F: House_Small_F { transportFuel = 0; //50k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{-0.4,0.022,-.23}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_F: House_F { transportFuel = 0; //50k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_malevil_F: House_F { transportFuel = 0; //50k - MACRO_REFUEL_ACTIONS GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; diff --git a/addons/refuel/XEH_PREP.hpp b/addons/refuel/XEH_PREP.hpp index 282b008fca..e4c5298036 100644 --- a/addons/refuel/XEH_PREP.hpp +++ b/addons/refuel/XEH_PREP.hpp @@ -1,30 +1,26 @@ - PREP(canCheckFuel); -PREP(canConnectNozzle); PREP(canDisconnect); PREP(canReturnNozzle); PREP(canTakeNozzle); PREP(canTurnOff); PREP(canTurnOn); PREP(checkFuel); -PREP(connectNozzle); PREP(connectNozzleAction); PREP(disconnect); PREP(dropNozzle); PREP(getFuel); PREP(handleDisconnect); -PREP(handleKilled); -PREP(handlePlayerWeaponChanged); -PREP(handleUnconscious); +PREP(handleRespawn); +PREP(initSource); PREP(makeJerryCan); -PREP(maxDistanceDropNozzle); +PREP(makeSource); PREP(moduleRefuelSettings); +PREP(onMouseButtonDown); PREP(readFuelCounter); PREP(refuel); -PREP(reset); -PREP(resetLocal); PREP(returnNozzle); PREP(setFuel); +PREP(startNozzleInHandsPFH); PREP(takeNozzle); PREP(turnOff); PREP(turnOn); diff --git a/addons/refuel/XEH_postInit.sqf b/addons/refuel/XEH_postInit.sqf index 5d56e388e9..b2d55e1f7f 100644 --- a/addons/refuel/XEH_postInit.sqf +++ b/addons/refuel/XEH_postInit.sqf @@ -1,50 +1,110 @@ #include "script_component.hpp" -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; -["weapon", FUNC(handlePlayerWeaponChanged)] call CBA_fnc_addPlayerEventHandler; - if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {_this call FUNC(handleDisconnect)}]; + addMissionEventHandler ["HandleDisconnect", LINKFUNC(handleDisconnect)]; }; -[QGVAR(resetLocal), { - _this call FUNC(resetLocal); -}] call CBA_fnc_addEventHandler; +[QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; -// workaround for static fuel stations -if (hasInterface) then { +if (!hasInterface) exitWith {}; + +["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + +["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + +GVAR(mainAction) = [ + QGVAR(Refuel), + localize LSTRING(Refuel), + QPATHTOF(ui\icon_refuel_interact.paa), + {}, { - if ( - configName _x isKindOf "Building" && - {isClass (_x >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(Refuel))} && - {getNumber (_x >> "scope") == 2} - ) then { - TRACE_1("Compiling menu",configName _x); - [configName _x] call EFUNC(interact_menu,compileMenu); - }; - } count ('true' configClasses (configFile >> "CfgVehicles")); -}; + alive _target + && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} + && {REFUEL_DISABLED_FUEL != [_target] call FUNC(getFuel)} + }, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); +GVAR(actions) = [ + [QGVAR(TakeNozzle), + localize LSTRING(TakeNozzle), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(canTakeNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuelCounter), + localize LSTRING(CheckFuelCounter), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(readFuelCounter)}, + {true}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuel), + localize LSTRING(CheckFuel), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(checkFuel)}, + {[_player, _target] call FUNC(canCheckFuel)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(Return), + localize LSTRING(Return), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(returnNozzle)}, + {[_player, _target] call FUNC(canReturnNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction) +]; -#ifdef DEBUG_MODE_FULL -diag_log text format ["[ACE-refuel] Showing CfgVehicles with vanilla transportFuel"]; -private _fuelTrucks = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportFuel')) > 0}", true]; +// init menu for config refuel vehicles +private _sourceClasses = []; { - if ((configName _x) isKindOf "Car") then { - diag_log text format ["Car [%1] needs config [fuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - } else { - diag_log text format ["Non-car? [%1] needs config [fuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; + private _fuelCargo = getNumber (_x >> QGVAR(fuelCargo)); + if (_fuelCargo > 0 || {_fuelCargo == REFUEL_INFINITE_FUEL}) then { + private _sourceClass = configName _x; + if (isClass (_x >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(Refuel))) exitWith { + if (!isClass (inheritsFrom _x >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(Refuel))) then { + ACE_DEPRECATED(FORMAT_1(QUOTE(GVAR(Refuel) interaction menu in %1),_sourceClass),"3.13.0",QUOTE(GVAR(fuelCargo) config value)); + }; + }; + // check if we can use actions with inheritance + if ( + !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init") // addActionToClass relies on XEH init + || {configName _x isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class + ) then { + if (2 == getNumber (_x >> "scope")) then { + [_sourceClass, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); + { + [_sourceClass, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to static",_sourceClass); + }; + } else { + if (0 == {_sourceClass isKindOf _x} count _sourceClasses) then { + _sourceClasses pushBack _sourceClass; + [_sourceClass, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + { + [_sourceClass, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to dynamic",_sourceClass); + }; + }; }; -} forEach _fuelTrucks; -#endif +} forEach ('true' configClasses (configFile >> "CfgVehicles")); + #ifdef DRAW_HOOKS_POS addMissionEventHandler ["Draw3D", { - private _target = cursorObject; - private _cfgPos = getArray (configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(hooks)); - private _dynPos = _target getVariable [QGVAR(dev_hooks), []]; + private _source = cursorObject; + private _cfgPos = getArray (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(hooks)); + private _dynPos = _source getVariable [QGVAR(hooks), []]; { - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _target modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; } forEach ([_dynPos, _cfgPos] select (_dynPos isEqualTo [])); }]; #endif diff --git a/addons/refuel/XEH_respawn.sqf b/addons/refuel/XEH_respawn.sqf deleted file mode 100644 index 085361e7dc..0000000000 --- a/addons/refuel/XEH_respawn.sqf +++ /dev/null @@ -1,9 +0,0 @@ -#include "script_component.hpp" - -params ["_unit"]; - -if !(local _unit) exitWith {}; - -[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); -_unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; -_unit setVariable [QGVAR(isRefueling), false]; diff --git a/addons/refuel/config.cpp b/addons/refuel/config.cpp index 40e28d9222..39765e323c 100644 --- a/addons/refuel/config.cpp +++ b/addons/refuel/config.cpp @@ -15,5 +15,10 @@ class CfgPatches { }; #include "ACE_Settings.hpp" +#include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" + +class ACE_Tests { + vehicleTransportFuel = QPATHTOF(dev\test_debugConfigs.sqf); +}; diff --git a/addons/refuel/dev/test_debugConfigs.sqf b/addons/refuel/dev/test_debugConfigs.sqf new file mode 100644 index 0000000000..834d3626bf --- /dev/null +++ b/addons/refuel/dev/test_debugConfigs.sqf @@ -0,0 +1,18 @@ +// ["vehicleTransportFuel"] call ace_common_fnc_runTests; +// execVM "z\ace\addons\refuel\dev\test_debugConfigs.sqf"; + +#include "\z\ace\addons\refuel\script_component.hpp" + +private _testPass = true; + +diag_log text format ["[ACE-refuel] Showing CfgVehicles with vanilla transportFuel"]; +private _fuelTrucks = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportFuel')) > 0}", true]; +{ + if ((configName _x) isKindOf "Car") then { + diag_log text format ["Car [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; + } else { + diag_log text format ["Non-car? [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; + }; +} forEach _fuelTrucks; + +_testPass diff --git a/addons/refuel/functions/fnc_canCheckFuel.sqf b/addons/refuel/functions/fnc_canCheckFuel.sqf index 57514e4b8f..6e86092652 100644 --- a/addons/refuel/functions/fnc_canCheckFuel.sqf +++ b/addons/refuel/functions/fnc_canCheckFuel.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Unit - * 1: Fuel Truck/Station + * 1: Fuel Source * * Return Value: * Can Check Fuel @@ -16,11 +16,11 @@ */ #include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; !(isNull _unit || {!(_unit isKindOf "CAManBase")} || {!local _unit} || - {!alive _target} || - {([_unit, _target] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE} || - {(_target call FUNC(getFuel) == REFUEL_INFINITE_FUEL)}) + {!alive _source} || + {([_unit, _source] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE} || + {(_source call FUNC(getFuel) == REFUEL_INFINITE_FUEL)}) diff --git a/addons/refuel/functions/fnc_canConnectNozzle.sqf b/addons/refuel/functions/fnc_canConnectNozzle.sqf deleted file mode 100644 index 03cd79d3c6..0000000000 --- a/addons/refuel/functions/fnc_canConnectNozzle.sqf +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Author: GitHawk - * Check if a unit can connect a fuel nozzle - * - * Arguments: - * 0: Unit - * 1: Target - * - * Return Value: - * Can Connect Nozzle - * - * Example: - * [player, tank] call ace_refuel_fnc_canConnectNozzle - * - * Public: No - */ -#include "script_component.hpp" - -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; - -private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; -private _engine = false; - -if (_target isKindOf "AllVehicles") then { - _engine = isEngineOn _target; -}; - -!(isNull _nozzle || - {!alive _target} || - {_engine} || - {([_unit, _target] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE} || - {!isNull (_target getVariable [QGVAR(nozzle), objNull])}) diff --git a/addons/refuel/functions/fnc_canReturnNozzle.sqf b/addons/refuel/functions/fnc_canReturnNozzle.sqf index 04849c5ca0..226576be0d 100644 --- a/addons/refuel/functions/fnc_canReturnNozzle.sqf +++ b/addons/refuel/functions/fnc_canReturnNozzle.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Unit - * 1: Fuel truck + * 1: Fuel Source * * Return Value: * Can Return Nozzle @@ -16,10 +16,10 @@ */ #include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; (!isNull _nozzle) && -{([_unit, _target] call EFUNC(interaction,getInteractionDistance)) < REFUEL_ACTION_DISTANCE} && -{_target == (_nozzle getVariable [QGVAR(source), objNull])} +{([_unit, _source] call EFUNC(interaction,getInteractionDistance)) < REFUEL_ACTION_DISTANCE} && +{_source == (_nozzle getVariable [QGVAR(source), objNull])} diff --git a/addons/refuel/functions/fnc_canTakeNozzle.sqf b/addons/refuel/functions/fnc_canTakeNozzle.sqf index d3852a668c..8847675058 100644 --- a/addons/refuel/functions/fnc_canTakeNozzle.sqf +++ b/addons/refuel/functions/fnc_canTakeNozzle.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Unit - * 1: Fuel Station or Nozzle + * 1: Fuel Source or Nozzle * * Return Value: * Can connect @@ -16,14 +16,14 @@ */ #include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_object", objNull, [objNull]]]; if (isNull _unit || {!(_unit isKindOf "CAManBase")} || {!local _unit} || - {!alive _target} || + {!alive _object} || {!isNull (_unit getVariable [QGVAR(nozzle), objNull])} || - {typeOf _target == QGVAR(fuelNozzle) && {!isNull (attachedTo _target)}} || // Not carried by someone else - {([_unit, _target] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE}) exitWith {false}; + {typeOf _object == QGVAR(fuelNozzle) && {!isNull (attachedTo _object)}} || // Not carried by someone else + {([_unit, _object] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE}) exitWith {false}; -!(_target getVariable [QGVAR(isConnected), false]) && {!(_unit getVariable [QGVAR(isRefueling), false])} +!(_object getVariable [QGVAR(isConnected), false]) && {!(_unit getVariable [QGVAR(isRefueling), false])} diff --git a/addons/refuel/functions/fnc_canTurnOn.sqf b/addons/refuel/functions/fnc_canTurnOn.sqf index e9de5c205c..98173e0fa4 100644 --- a/addons/refuel/functions/fnc_canTurnOn.sqf +++ b/addons/refuel/functions/fnc_canTurnOn.sqf @@ -27,5 +27,4 @@ if (isNull _unit || !(_nozzle getVariable [QGVAR(isRefueling), false]) && {[_nozzle getVariable QGVAR(source)] call FUNC(getFuel) != 0} && {!isNull (_nozzle getVariable [QGVAR(sink), objNull])} && - {(fuel (_nozzle getVariable QGVAR(sink))) < 1} && - {!(isEngineOn (_nozzle getVariable QGVAR(sink)))} + {(fuel (_nozzle getVariable QGVAR(sink))) < 1} diff --git a/addons/refuel/functions/fnc_checkFuel.sqf b/addons/refuel/functions/fnc_checkFuel.sqf index 081f344732..fdb4a525d2 100644 --- a/addons/refuel/functions/fnc_checkFuel.sqf +++ b/addons/refuel/functions/fnc_checkFuel.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Unit - * 1: Fuel Truck + * 1: Fuel Source * * Return Value: * None @@ -16,16 +16,16 @@ */ #include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; -private _fuel = [_target] call FUNC(getFuel); +private _fuel = [_source] call FUNC(getFuel); [ TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION * 2), - [_unit, _target, _fuel], + [_unit, _source, _fuel], { params ["_args"]; - _args params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]], ["_fuel", 0, [0]]]; + _args params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]], ["_fuel", 0, [0]]]; if (_fuel > 0 ) then { [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RemainingFuel), _fuel], 2, _unit], _unit] call CBA_fnc_targetEvent; } else { @@ -36,5 +36,5 @@ private _fuel = [_target] call FUNC(getFuel); {true}, localize LSTRING(CheckFuelAction), {true}, - ["isnotinside"] + [INTERACT_EXCEPTIONS] ] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_connectNozzle.sqf b/addons/refuel/functions/fnc_connectNozzle.sqf deleted file mode 100644 index 807960977e..0000000000 --- a/addons/refuel/functions/fnc_connectNozzle.sqf +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Author: GitHawk et.al. - * Connect a fuel nozzle. - * With code from ace_attach - * - * Arguments: - * 0: Unit - * 1: Target - * - * Return Value: - * None - * - * Example: - * [player, tank] call ace_refuel_fnc_connectNozzle - * - * Public: No - */ -#include "script_component.hpp" - -#define PLACE_WAITING -1 -#define PLACE_CANCEL 0 -#define PLACE_APPROVE 1 - -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; - -private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; -if (isNull _nozzle) exitWith {}; - -GVAR(placeAction) = PLACE_WAITING; - -[{[localize LSTRING(Connect_Action), ""] call EFUNC(interaction,showMouseHint)}, []] call CBA_fnc_execNextFrame; -_unit setVariable [QGVAR(placeActionEH), [_unit, "DefaultAction", {true}, {GVAR(placeAction) = PLACE_APPROVE;}] call EFUNC(common,AddActionEventHandler)]; - -private _actionID = _unit addAction [format ["%1", localize LSTRING(Cancel)], {GVAR(placeAction) = PLACE_CANCEL;}]; - -[{ - params ["_args","_pfID"]; - _args params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_actionID", -1, [0]]]; - - private _virtualPosASL = (eyePos _unit) vectorAdd (positionCameraToWorld [0,0,0.6]) vectorDiff (positionCameraToWorld [0,0,0]); - if (cameraView == "EXTERNAL") then { - _virtualPosASL = _virtualPosASL vectorAdd ((positionCameraToWorld [0.3,0,0]) vectorDiff (positionCameraToWorld [0,0,0])); - }; - private _lineInterection = lineIntersects [eyePos ace_player, _virtualPosASL, ace_player]; - - //Don't allow placing in a bad position: - if (_lineInterection && {GVAR(placeAction) == PLACE_APPROVE}) then {GVAR(placeAction) = PLACE_WAITING;}; - - if ((GVAR(placeAction) != PLACE_WAITING) || - {_unit != ace_player} || - {!([_unit, _target, []] call EFUNC(common,canInteractWith))}) then { - - [_pfID] call CBA_fnc_removePerFrameHandler; - [] call EFUNC(interaction,hideMouseHint); - [_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler); - _unit removeAction _actionID; - - if (GVAR(placeAction) == PLACE_APPROVE) then { - [_unit, _target, _virtualPosASL, _nozzle] call FUNC(ConnectNozzleAction); - }; - }; // TODO add model like in attach/functions/fnc_attach -}, 0, [_unit, _target, _nozzle, _actionID] ] call cba_fnc_addPerFrameHandler; diff --git a/addons/refuel/functions/fnc_connectNozzleAction.sqf b/addons/refuel/functions/fnc_connectNozzleAction.sqf index 31ebe1bfdc..eece4b0caa 100644 --- a/addons/refuel/functions/fnc_connectNozzleAction.sqf +++ b/addons/refuel/functions/fnc_connectNozzleAction.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Unit - * 1: Target + * 1: Vehicle * 2: Visual Position ASL * 3: Nozzle * @@ -18,16 +18,15 @@ * Public: No */ #include "script_component.hpp" -private ["_closeInDistance", "_endPosTestOffset"]; -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]], ["_startingPosASL", [0,0,0], [[]], 3], ["_nozzle", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_startingPosASL", [0,0,0], [[]], 3], ["_nozzle", objNull, [objNull]]]; private _bestPosASL = []; private _bestPosDistance = 1e99; private _viewPos = _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0,0,1])) vectorMultiply 3); -private _modelVector = _startingPosASL vectorFromTo (AGLtoASL (_target modelToWorld [0,0,0])); -private _modelVectorLow = _startingPosASL vectorFromTo (AGLtoASL (_target modelToWorld [0,0,-1])); +private _modelVector = _startingPosASL vectorFromTo (AGLtoASL (_sink modelToWorld [0,0,0])); +private _modelVectorLow = _startingPosASL vectorFromTo (AGLtoASL (_sink modelToWorld [0,0,-1])); { private _endPosASL = _x; @@ -35,7 +34,7 @@ private _modelVectorLow = _startingPosASL vectorFromTo (AGLtoASL (_target modelT private _intersections = lineIntersectsSurfaces [_startingPosASL, _endPosASL, _unit]; { _x params ["_intersectPosASL", "", "_intersectObject"]; - if (_intersectObject == _target) then { + if (_intersectObject == _sink) then { private _distance = _startingPosASL distance _intersectPosASL; if (_distance < _bestPosDistance) then { _bestPosDistance = _distance; @@ -51,41 +50,33 @@ private _modelVectorLow = _startingPosASL vectorFromTo (AGLtoASL (_target modelT _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0,-0.25,1])) vectorMultiply 3), _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [-0.25,-0.25,1])) vectorMultiply 3), _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0.25,-0.25,1])) vectorMultiply 3), - AGLtoASL (_target modelToWorld [0,0,0]), // Try old method of just using model center - AGLtoASL (_target modelToWorld [0,0,-0.5]) + AGLtoASL (_sink modelToWorld [0,0,0]), // Try old method of just using model center + AGLtoASL (_sink modelToWorld [0,0,-0.5]) ]; //Checks (too close to center or can't attach) if (_bestPosASL isEqualTo []) exitWith { - TRACE_2("no valid spot found",_closeInDistance,_startDistanceFromCenter); [localize LSTRING(Failed)] call EFUNC(common,displayTextStructured); }; //Move it out slightly, for visibility sake (better to look a little funny than be embedded//sunk in the hull and be useless) _bestPosASL = _bestPosASL vectorAdd ((_bestPosASL vectorFromTo _startingPosASL) vectorMultiply 0.05); -private _attachPosModel = _target worldToModel (ASLtoAGL _bestPosASL); +private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); [ TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), - [_unit, _nozzle, _target, _attachPosModel], + [_unit, _nozzle, _sink, _attachPosModel], { params ["_args"]; - _args params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_target", objNull, [objNull]], ["_endPosTestOffset", [0,0,0], [[]], 3]]; + _args params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_endPosTestOffset", [0,0,0], [[]], 3]]; _unit setVariable [QGVAR(nozzle), nil, true]; _unit setVariable [QGVAR(isRefueling), false]; - [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); - REFUEL_UNHOLSTER_WEAPON - private _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; - if (_actionID != -1) then { - _unit removeAction _actionID; - _unit setVariable [QGVAR(ReleaseActionID), nil]; - }; detach _nozzle; - _nozzle attachTo [_target, _endPosTestOffset]; + _nozzle attachTo [_sink, _endPosTestOffset]; _endPosTestOffset params ["_x", "_y"]; - private _bb = boundingBoxReal _target; + private _bb = boundingBoxReal _sink; _bb params ["_ll", "_rr"]; _ll set [2, 0]; _rr set [2, 0]; @@ -115,9 +106,10 @@ private _attachPosModel = _target worldToModel (ASLtoAGL _bestPosASL); }; }; [QEGVAR(common,setVectorDirAndUp), [_nozzle, _dirAndUp], _nozzle] call CBA_fnc_targetEvent; - _nozzle setVariable [QGVAR(sink), _target, true]; + if (_nozzle isKindOf "Land_CanisterFuel_F") then { _nozzle setVariable [QEGVAR(cargo,canLoad), false, true]; }; + _nozzle setVariable [QGVAR(sink), _sink, true]; _nozzle setVariable [QGVAR(isConnected), true, true]; - _target setVariable [QGVAR(nozzle), _nozzle, true]; + _sink setVariable [QGVAR(nozzle), _nozzle, true]; _source = _nozzle getVariable QGVAR(source); private _fuel = [_source] call FUNC(getFuel); @@ -127,10 +119,17 @@ private _attachPosModel = _target worldToModel (ASLtoAGL _bestPosASL); _source setVariable [QGVAR(fuelCounter), _fuel, true]; }; - [_unit, _target, _nozzle, _endPosTestOffset] call FUNC(refuel); + [_unit, _sink, _nozzle, _endPosTestOffset] call FUNC(refuel); + + if ([_unit, _nozzle] call FUNC(canTurnOn)) then { + _unit setVariable [QGVAR(tempFuel), nil]; + [_unit, _nozzle] call FUNC(turnOn); + } else { + [LSTRING(CouldNotTurnOn)] call EFUNC(common,displayText); + }; }, "", localize LSTRING(ConnectAction), {true}, - ["isnotinside"] + [INTERACT_EXCEPTIONS] ] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_disconnect.sqf b/addons/refuel/functions/fnc_disconnect.sqf index 41fde6d365..793eefbb93 100644 --- a/addons/refuel/functions/fnc_disconnect.sqf +++ b/addons/refuel/functions/fnc_disconnect.sqf @@ -21,9 +21,10 @@ params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; private _sink = _nozzle getVariable [QGVAR(sink), objNull]; if (isNull _sink) exitWith {}; -_sink setVariable [QGVAR(nozzle), objNull, true]; -_nozzle setVariable [QGVAR(sink), objNull, true]; +_sink setVariable [QGVAR(nozzle), nil, true]; +if (_nozzle isKindOf "Land_CanisterFuel_F") then { _nozzle setVariable [QEGVAR(cargo,canLoad), true, true]; }; +_nozzle setVariable [QGVAR(sink), nil, true]; _nozzle setVariable [QGVAR(isConnected), false, true]; [objNull, _nozzle, true] call FUNC(dropNozzle); -[_unit, objNull, _nozzle] call FUNC(takeNozzle); +[_unit, _nozzle] call FUNC(takeNozzle); diff --git a/addons/refuel/functions/fnc_dropNozzle.sqf b/addons/refuel/functions/fnc_dropNozzle.sqf index 21b700a757..fac88d6591 100644 --- a/addons/refuel/functions/fnc_dropNozzle.sqf +++ b/addons/refuel/functions/fnc_dropNozzle.sqf @@ -41,5 +41,5 @@ _nozzle setPosASL _groundPosition; TRACE_1("finalPos",getPosATL _nozzle); if (isNull _unit) exitWith {}; -_unit setVariable [QGVAR(isRefueling), false, true]; +_unit setVariable [QGVAR(isRefueling), false]; _unit setVariable [QGVAR(nozzle), objNull, true]; diff --git a/addons/refuel/functions/fnc_getFuel.sqf b/addons/refuel/functions/fnc_getFuel.sqf index 863c017102..1ec128cb68 100644 --- a/addons/refuel/functions/fnc_getFuel.sqf +++ b/addons/refuel/functions/fnc_getFuel.sqf @@ -3,7 +3,7 @@ * Get the remaining fuel amount. * * Arguments: - * 0: Target + * 0: Fuel Source * * Return Value: * Fuel left (in liters) @@ -15,15 +15,15 @@ */ #include "script_component.hpp" -params [["_target", objNull, [objNull]]]; +params [["_source", objNull, [objNull]]]; -if (isNull _target) exitWith {0}; +if (isNull _source) exitWith {0}; -private _fuel = _target getVariable QGVAR(currentFuelCargo); +private _fuel = _source getVariable QGVAR(currentFuelCargo); if (isNil "_fuel") then { - _fuel = getNumber (configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(fuelCargo)); - _target setVariable [QGVAR(currentFuelCargo), _fuel, true]; + _fuel = getNumber (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(fuelCargo)); + _source setVariable [QGVAR(currentFuelCargo), _fuel, true]; }; _fuel diff --git a/addons/refuel/functions/fnc_handleDisconnect.sqf b/addons/refuel/functions/fnc_handleDisconnect.sqf index edc3393cb4..a7e46e23fe 100644 --- a/addons/refuel/functions/fnc_handleDisconnect.sqf +++ b/addons/refuel/functions/fnc_handleDisconnect.sqf @@ -1,6 +1,6 @@ /* * Author: GitHawk - * Cleans up refuel + * Cleans up refuel on client disconnect. * * Arguments: * 0: Player @@ -15,12 +15,13 @@ */ #include "script_component.hpp" -params [["_disconnectedPlayer", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]]]; +TRACE_1("disconnect",_unit); -if (isNull _disconnectedPlayer) exitWith {}; - -private _nozzle = _disconnectedPlayer getVariable [QGVAR(nozzle), objNull]; +if (isNull _unit) exitWith {}; +private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; if (isNull _nozzle) exitWith {}; -[_disconnectedPlayer, _nozzle] call FUNC(dropNozzle); +[_unit, _nozzle] call FUNC(dropNozzle); +[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); diff --git a/addons/refuel/functions/fnc_handleKilled.sqf b/addons/refuel/functions/fnc_handleKilled.sqf deleted file mode 100644 index 045bf47028..0000000000 --- a/addons/refuel/functions/fnc_handleKilled.sqf +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Author: GitHawk, Jonpas - * Handles medical on set dead event. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Example: - * [player] call ace_refuel_fnc_handleKilled - * - * Public: No - */ -#include "script_component.hpp" - -params [["_unit", objNull, [objNull]]]; - -if (!local _unit) exitWith {}; - -_unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; -private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; -if !(isNull _nozzle) then { - [_unit, _nozzle] call FUNC(dropNozzle); -}; diff --git a/addons/refuel/functions/fnc_handlePlayerWeaponChanged.sqf b/addons/refuel/functions/fnc_handlePlayerWeaponChanged.sqf deleted file mode 100644 index 57897aef89..0000000000 --- a/addons/refuel/functions/fnc_handlePlayerWeaponChanged.sqf +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Author: Jonpas - * Drops nozzle or jerry can when selecting a weapon. - * - * Arguments: - * 0: Unit - * 1: Weapon (unused) - * - * Return Value: - * None - * - * Example: - * [_unit, "gun"] call ace_refuel_fnc_handlePlayerWeaponChanged; - * - * Public: No -*/ -#include "script_component.hpp" - -params ["_unit"]; - -// Drop nozzle/jerry can when selecting a non-primary weapon -if (_unit getVariable [QGVAR(isRefueling), false]) then { - private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; - if !(isNull _nozzle) then { - [_unit, _nozzle] call FUNC(dropNozzle); - _unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; - [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); - }; -}; diff --git a/addons/refuel/functions/fnc_handleRespawn.sqf b/addons/refuel/functions/fnc_handleRespawn.sqf new file mode 100644 index 0000000000..145cd16e60 --- /dev/null +++ b/addons/refuel/functions/fnc_handleRespawn.sqf @@ -0,0 +1,26 @@ +/* + * Author: Dystopian + * Clean variables on unit respawn. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_refuel_fnc_handleRespawn + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; +TRACE_1("respawn",_unit); + +if (isNull (_unit getVariable [QGVAR(nozzle), objNull])) exitWith {}; + +_unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; +_unit setVariable [QGVAR(isRefueling), false]; +_unit setVariable [QGVAR(nozzle), nil, true]; +_unit setVariable [QGVAR(hint), nil]; diff --git a/addons/refuel/functions/fnc_handleUnconscious.sqf b/addons/refuel/functions/fnc_handleUnconscious.sqf deleted file mode 100644 index bfcdcb3776..0000000000 --- a/addons/refuel/functions/fnc_handleUnconscious.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Author: GitHawk, Jonpas - * Handles medical on unconscious event. - * - * Arguments: - * 0: Unit - * 1: Is Unconscious - * - * Return Value: - * None - * - * Example: - * [player, true] call ace_refuel_fnc_handleUnconscious - * - * Public: No - */ -#include "script_component.hpp" - -params [["_unit", objNull, [objNull]], ["_isUnconscious", false, [false]]]; - -if (!local _unit || {!_isUnconscious}) exitWith {}; - -[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); -private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; -if !(isNull _nozzle) then { - [_unit, _nozzle] call FUNC(dropNozzle); -}; diff --git a/addons/refuel/functions/fnc_initSource.sqf b/addons/refuel/functions/fnc_initSource.sqf new file mode 100644 index 0000000000..51daa5f03e --- /dev/null +++ b/addons/refuel/functions/fnc_initSource.sqf @@ -0,0 +1,26 @@ +/* + * Author: Dystopian + * Adds refuel menu to object. + * + * Arguments: + * 0: Source + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_refuel_fnc_initSource + * + * Public: No + */ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +params ["_source"]; +TRACE_2("init",_source,typeOf _source); + +[_source, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToObject); +{ + [_source, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToObject); +} forEach GVAR(actions); diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf index f42808d40a..96fc30adce 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -44,7 +44,7 @@ private _action = [QGVAR(Refuel), _action = [QGVAR(PickUpNozzle), localize LSTRING(TakeNozzle), QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, objNull, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(takeNozzle)}, {[_player, _target] call FUNC(canTakeNozzle)}, {}, [], diff --git a/addons/refuel/functions/fnc_makeSource.sqf b/addons/refuel/functions/fnc_makeSource.sqf new file mode 100644 index 0000000000..05707e5301 --- /dev/null +++ b/addons/refuel/functions/fnc_makeSource.sqf @@ -0,0 +1,60 @@ +/* + * Author: Dystopian + * Makes an object into a refuel source. + * Run on server only. + * + * Arguments: + * 0: Fuel Source + * 1: Fuel amount (in liters) (default: 0) + * 2: Hooks positions (default: [[0,0,0]]) + * + * Return Value: + * None + * + * Example: + * [cursorObject, 100] call ace_refuel_fnc_makeSource + * + * Public: Yes + */ +#include "script_component.hpp" + +if (!isServer) exitWith {}; + +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeSource), _this]; +}; + +params [ + ["_source", objNull, [objNull]], + ["_fuelCargo", 0, [0]], + ["_hooks", nil, [[]]] +]; +TRACE_3("makeSource",_source,_fuelCargo,_hooks); + +private _fuelCargoConfig = getNumber (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(fuelCargo)); + +if ( + isNull _source + || {_fuelCargo < 0 && {!(_fuelCargo in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL])}} + || {_fuelCargo != 0 && {_fuelCargo == _fuelCargoConfig}} +) exitWith {}; + +[_source, _fuelCargo] call FUNC(setFuel); + +if (_fuelCargo == REFUEL_DISABLED_FUEL) exitWith {}; + +if ( + !isNil "_hooks" + && {_hooks isEqualTypeAll []} + && {0 == {!(_x isEqualTypeParams [0,0,0]) || {3 < count _x}} count _hooks} +) then { + _source setVariable [QGVAR(hooks), _hooks, true]; +}; + +// check if menu already exists +if (_fuelCargoConfig != 0 || {!isNil {_source getVariable QGVAR(initSource_jipID)}}) exitWith {}; + +private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; +[_jipID, _source] call CBA_fnc_removeGlobalEventJIP; +_source setVariable [QGVAR(initSource_jipID), _jipID]; diff --git a/addons/refuel/functions/fnc_maxDistanceDropNozzle.sqf b/addons/refuel/functions/fnc_maxDistanceDropNozzle.sqf deleted file mode 100644 index 0f83f48fbb..0000000000 --- a/addons/refuel/functions/fnc_maxDistanceDropNozzle.sqf +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Author: GitHawk, Jonpas - * Drops the nozzle at maximum hose distance. - * - * Arguments: - * 0: Unit - * 1: Fuel Truck - * 2: End Pos Offset - * 3: Nozzle (optional) - * - * Return Value: - * None - * - * Example: - * [player, fuelTruck, [0, 0, 0], nozzle] call ace_refuel_fnc_maxDistanceDropNozzle - * - * Public: No - */ -#include "script_component.hpp" - -params ["_unit", "_source", "_endPosOffset", "_nozzle"]; - -// Exit if jerry can (no maximum distance there as it's not connected to anything) -if (_nozzle getVariable [QGVAR(jerryCan), false]) exitWith {}; - -// Check distance periodically to drop it at maximum hose length -[{ - params ["_args", "_pfID"]; - _args params [ - ["_unit", player, [objNull]], - ["_source", objNull, [objNull]], - ["_endPosOffset", [0, 0, 0], [[]], 3], - ["_nozzle", (_args select 0) getVariable [QGVAR(nozzle), objNull], [objNull]] - ]; - - if (!(_unit getVariable [QGVAR(isRefueling), false])) exitWith { - TRACE_1("player not isRefueling",_unit); - [_pfID] call CBA_fnc_removePerFrameHandler; - }; - - private _hoseLength = _source getVariable [QGVAR(hoseLength), GVAR(hoseLength)]; - if (isNull _source || {_unit distance (_source modelToWorld _endPosOffset) > (_hoseLength - 2)} || {!alive _source}) exitWith { - if !(isNull _nozzle) then { - [_unit, _nozzle] call FUNC(dropNozzle); - REFUEL_UNHOLSTER_WEAPON - - [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); - if (isNull _source || {!alive _source}) then { - private _rope = _nozzle getVariable [QGVAR(rope), objNull]; - if !(isNull _rope) then { - ropeDestroy _rope; - }; - private _helper = _nozzle getVariable [QGVAR(helper), objNull]; - if !(isNull _helper) then { - deleteVehicle _helper; - }; - deleteVehicle _nozzle; - } else { - [LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured); - }; - }; - [_pfID] call CBA_fnc_removePerFrameHandler; - }; -}, 0, [_unit, _target, _endPosOffset, _nozzle]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/refuel/functions/fnc_onMouseButtonDown.sqf b/addons/refuel/functions/fnc_onMouseButtonDown.sqf new file mode 100644 index 0000000000..5c1951b280 --- /dev/null +++ b/addons/refuel/functions/fnc_onMouseButtonDown.sqf @@ -0,0 +1,53 @@ +/* + * Author: Dystopian + * Mouse button down event. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_refuel_fnc_onMouseButtonDown + * + * Public: No + */ +#include "script_component.hpp" + +private _button = _this select 1; +private _unit = ACE_player; +private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; + +if (_button > 1 || {isNull _nozzle}) exitWith {}; + +getCursorObjectParams params ["_cursorObject", "", "_distance"]; + +// RMB +if (_button == 1) exitWith { + if ( + !isNull _cursorObject + && {_distance < REFUEL_NOZZLE_ACTION_DISTANCE} + && {[_unit, _cursorObject] call FUNC(canReturnNozzle)} + ) then { + [_unit, _cursorObject] call FUNC(returnNozzle); + } else { + [_unit, _nozzle] call FUNC(dropNozzle); + }; +}; + +// LMB +// code from attach, don't know what it is +private _virtualPosASL = (eyePos _unit) vectorAdd (positionCameraToWorld [0,0,0.6]) vectorDiff (positionCameraToWorld [0,0,0]); +if (cameraView == "EXTERNAL") then { + _virtualPosASL = _virtualPosASL vectorAdd ((positionCameraToWorld [0.3,0,0]) vectorDiff (positionCameraToWorld [0,0,0])); +}; +if ( + !isNull _cursorObject + && {_distance < REFUEL_NOZZLE_ACTION_DISTANCE} + && {1 == getNumber (configFile >> "CfgVehicles" >> (typeOf _cursorObject) >> QGVAR(canReceive))} + && {isNull (_cursorObject getVariable [QGVAR(nozzle), objNull])} + && {!lineIntersects [eyePos _unit, _virtualPosASL, _unit]} +) then { + [_unit, _cursorObject, _virtualPosASL, _nozzle] call FUNC(connectNozzleAction); +}; diff --git a/addons/refuel/functions/fnc_readFuelCounter.sqf b/addons/refuel/functions/fnc_readFuelCounter.sqf index 98393e69ea..70c6a2799b 100644 --- a/addons/refuel/functions/fnc_readFuelCounter.sqf +++ b/addons/refuel/functions/fnc_readFuelCounter.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Unit - * 1: Fuel Truck + * 1: Fuel Source * * Return Value: * None @@ -16,26 +16,14 @@ */ #include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; -[ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), - [_unit, _target], - { - params ["_args"]; - _args params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +private _currentFuel = [_source] call FUNC(getFuel); +private _fuelCounter = if (_currentFuel == REFUEL_INFINITE_FUEL) then { + _source getVariable [QGVAR(fuelCounter), 0] +} else { + (_source getVariable [QGVAR(fuelCounter), _currentFuel]) - _currentFuel +}; - private _currentFuel = [_target] call FUNC(getFuel); - if (_currentFuel == REFUEL_INFINITE_FUEL) then { - private _fuelCounter = 0.01 * round (100 * (_target getVariable [QGVAR(fuelCounter), 0])); - [[LSTRING(Hint_FuelCounter), _fuelCounter], 1.5, _unit] call EFUNC(common,displayTextStructured); - } else { - private _fuelCounter = 0.01 * round (100 * ((_target getVariable [QGVAR(fuelCounter), _currentFuel]) - _currentFuel)); - [[LSTRING(Hint_FuelCounter), _fuelCounter], 1.5, _unit] call EFUNC(common,displayTextStructured); - }; - }, - "", - localize LSTRING(CheckFuelCounterAction), - {true}, - ["isnotinside"] -] call EFUNC(common,progressBar); +private _fuelCounter = 0.01 * round (100 * _fuelCounter); +[[LSTRING(Hint_FuelCounter), _fuelCounter], 1.5, _unit] call EFUNC(common,displayTextStructured); diff --git a/addons/refuel/functions/fnc_refuel.sqf b/addons/refuel/functions/fnc_refuel.sqf index 15fef426d2..f23e0aae5b 100644 --- a/addons/refuel/functions/fnc_refuel.sqf +++ b/addons/refuel/functions/fnc_refuel.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Unit - * 1: Target + * 1: Vehicle * 2: Nozzle * 3: Connection Point * @@ -19,9 +19,9 @@ #include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_connectToPoint", [0,0,0], [[]], 3]]; +params [["_unit", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_connectToPoint", [0,0,0], [[]], 3]]; -private _config = configFile >> "CfgVehicles" >> typeOf _target; +private _config = configFile >> "CfgVehicles" >> typeOf _sink; private _rate = getNumber (_config >> QGVAR(flowRate)) * GVAR(rate); private _maxFuel = getNumber (_config >> QGVAR(fuelCapacity)); @@ -43,8 +43,9 @@ if (_maxFuel == 0) then { if (!alive _source || {!alive _sink}) exitWith { [objNull, _nozzle] call FUNC(dropNozzle); _nozzle setVariable [QGVAR(isConnected), false, true]; - _nozzle setVariable [QGVAR(sink), objNull, true]; - _sink setVariable [QGVAR(nozzle), objNull, true]; + if (_nozzle isKindOf "Land_CanisterFuel_F") then { _nozzle setVariable [QEGVAR(cargo,canLoad), true, true]; }; + _nozzle setVariable [QGVAR(sink), nil, true]; + _sink setVariable [QGVAR(nozzle), nil, true]; [_pfID] call CBA_fnc_removePerFrameHandler; }; private _hoseLength = _source getVariable [QGVAR(hoseLength), GVAR(hoseLength)]; @@ -54,18 +55,15 @@ if (_maxFuel == 0) then { [objNull, _nozzle] call FUNC(dropNozzle); _nozzle setVariable [QGVAR(isConnected), false, true]; - _nozzle setVariable [QGVAR(sink), objNull, true]; - _sink setVariable [QGVAR(nozzle), objNull, true]; + if (_nozzle isKindOf "Land_CanisterFuel_F") then { _nozzle setVariable [QEGVAR(cargo,canLoad), true, true]; }; + _nozzle setVariable [QGVAR(sink), nil, true]; + _sink setVariable [QGVAR(nozzle), nil, true]; [_pfID] call CBA_fnc_removePerFrameHandler; }; private _finished = false; private _fueling = _nozzle getVariable [QGVAR(isRefueling), false]; if (_fueling) then { - if (isEngineOn _sink) exitWith { - _nozzle setVariable [QGVAR(lastTickMissionTime), nil]; - _nozzle setVariable [QGVAR(isRefueling), false, true]; - }; private _fuelInSource = [_source] call FUNC(getFuel); if (_fuelInSource == 0) exitWith { [LSTRING(Hint_SourceEmpty), 2, _unit] call EFUNC(common,displayTextStructured); @@ -108,11 +106,11 @@ if (_maxFuel == 0) then { }; }, 1, [ _nozzle getVariable QGVAR(source), - _target, + _sink, _unit, _nozzle, _rate, - fuel _target, + fuel _sink, _maxFuel, _nozzle getVariable [QGVAR(attachPos), [0,0,0]], _connectToPoint diff --git a/addons/refuel/functions/fnc_reset.sqf b/addons/refuel/functions/fnc_reset.sqf deleted file mode 100644 index 480beb6ca0..0000000000 --- a/addons/refuel/functions/fnc_reset.sqf +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Author: GitHawk - * Resets a fuel vehicle in case is got bugged - * - * Arguments: - * 0: Fuel truck - * - * Return Value: - * None - * - * Example: - * [truck] call ace_refuel_fnc_reset - * - * Public: Yes - */ -#include "script_component.hpp" - -params [["_target", objNull, [objNull]]]; - -[_target, "blockEngine", "ACE_Refuel", false] call EFUNC(common,statusEffect_set); -_target setVariable [QGVAR(isConnected), false, true]; - -private _nozzle = _target getVariable [QGVAR(ownedNozzle), nil]; -if !(isNil "_nozzle") then { - private _nozzleTarget = _nozzle getVariable [QGVAR(sink), nil]; - if !(isNil "_nozzleTarget") then { - _nozzleTarget setVariable [QGVAR(nozzle), nil, true]; - }; - - private _rope = _nozzle getVariable [QGVAR(rope), objNull]; - if !(isNull _rope) then { - ropeDestroy _rope; - }; - private _helper = _nozzle getVariable [QGVAR(helper), objNull]; - if !(isNull _helper) then { - deleteVehicle _helper; - }; - - { - [QGVAR(resetLocal), [_x, _nozzle], _x] call CBA_fnc_targetEvent; - } count allPlayers; - deleteVehicle _nozzle; -}; -_target setVariable [QGVAR(ownedNozzle), nil, true]; diff --git a/addons/refuel/functions/fnc_resetLocal.sqf b/addons/refuel/functions/fnc_resetLocal.sqf deleted file mode 100644 index 2e80ab98d7..0000000000 --- a/addons/refuel/functions/fnc_resetLocal.sqf +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Author: GitHawk - * Resets a player - * - * Arguments: - * 0: Fuel nozzle - * - * Return Value: - * None - * - * Example: - * [nozzle] call ace_refuel_fnc_resetLocal - * - * Public: No - */ -#include "script_component.hpp" - -params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; - -if (isNull _unit || - {isNull _nozzle} || - {!(_unit isKindOf "CAManBase")} || - {!local _unit}) exitWith {}; - -private _attachedNozzle = _unit getVariable [QGVAR(nozzle), nil]; -if (isNil "_attachedNozzle") exitWith {}; - -if (_nozzle != _attachedNozzle) exitWith {}; - -private _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; -if (_actionID != -1) then { - _unit removeAction _actionID; - _unit setVariable [QGVAR(isRefueling), false, true]; - _unit setVariable [QGVAR(ReleaseActionID), nil]; - _unit setVariable [QGVAR(nozzle), nil, true]; -}; diff --git a/addons/refuel/functions/fnc_returnNozzle.sqf b/addons/refuel/functions/fnc_returnNozzle.sqf index 2b1ac64f8b..5da5935fd2 100644 --- a/addons/refuel/functions/fnc_returnNozzle.sqf +++ b/addons/refuel/functions/fnc_returnNozzle.sqf @@ -4,10 +4,10 @@ * * Arguments: * 0: Unit - * 1: Fuel Truck + * 1: Fuel Source * * Return Value: - * Returned Nozzle + * None * * Example: * [player, fuelTruck] call ace_refuel_fnc_returnNozzle @@ -16,32 +16,24 @@ */ #include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; -private _source = _nozzle getVariable QGVAR(source); -if (isNull _nozzle || {_source != _target}) exitWith {false}; +if (isNull _nozzle || {_source != _nozzle getVariable QGVAR(source)}) exitWith {}; [ TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), - [_unit, _nozzle, _target], + [_unit, _nozzle, _source], { params ["_args"]; - _args params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_target", objNull, [objNull]]]; + _args params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_source", objNull, [objNull]]]; _unit setVariable [QGVAR(nozzle), nil, true]; detach _nozzle; - [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); - REFUEL_UNHOLSTER_WEAPON _unit setVariable [QGVAR(isRefueling), false]; - private _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; - if (_actionID != -1) then { - _unit removeAction _actionID; - _unit setVariable [QGVAR(ReleaseActionID), nil]; - }; - _target setVariable [QGVAR(isConnected), false, true]; - _target setVariable [QGVAR(ownedNozzle), nil, true]; + _source setVariable [QGVAR(isConnected), false, true]; + _source setVariable [QGVAR(ownedNozzle), nil, true]; private _rope = _nozzle getVariable [QGVAR(rope), objNull]; if !(isNull _rope) then { ropeDestroy _rope; @@ -52,12 +44,10 @@ if (isNull _nozzle || {_source != _target}) exitWith {false}; }; deleteVehicle _nozzle; - [_target, "blockEngine", "ACE_Refuel", false] call EFUNC(common,statusEffect_set); + [_source, "blockEngine", "ACE_Refuel", false] call EFUNC(common,statusEffect_set); }, "", localize LSTRING(ReturnAction), {true}, - ["isnotinside"] + [INTERACT_EXCEPTIONS] ] call EFUNC(common,progressBar); - -true diff --git a/addons/refuel/functions/fnc_setFuel.sqf b/addons/refuel/functions/fnc_setFuel.sqf index 6033660a48..0732160f4c 100644 --- a/addons/refuel/functions/fnc_setFuel.sqf +++ b/addons/refuel/functions/fnc_setFuel.sqf @@ -3,7 +3,7 @@ * Set the remaining fuel amount. * * Arguments: - * 0: Fuel Truck + * 0: Fuel Source * 1: Amount (in liters) * * Return Value: @@ -16,9 +16,9 @@ */ #include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_fuel", nil, [0]]]; +params [["_source", objNull, [objNull]], ["_fuel", nil, [0]]]; -if (isNull _target || +if (isNull _source || {isNil "_fuel"}) exitWith {}; -_target setVariable [QGVAR(currentFuelCargo), _fuel, true]; +_source setVariable [QGVAR(currentFuelCargo), _fuel, true]; diff --git a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf new file mode 100644 index 0000000000..95c853a217 --- /dev/null +++ b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf @@ -0,0 +1,114 @@ +/* + * Author: Dystopian + * PFH while nozzle is in hands. + * + * Arguments: + * 0: Unit + * 1: Nozzle + * + * Return Value: + * None + * + * Example: + * [player, nozzle] call ace_refuel_fnc_startNozzleInHandsPFH + * + * Public: No + */ +#include "script_component.hpp" + +#define DROP_NOZZLE [_unit, _nozzle] call FUNC(dropNozzle); +#define UNHOLSTER_WEAPON \ + _unit selectWeapon (_unit getVariable QGVAR(selectedWeaponOnRefuel)); \ + _unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; +#define END_PFH \ + _unit setVariable [QGVAR(hint), nil]; \ + call EFUNC(interaction,hideMouseHint); \ + [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); \ + [_unit, "blockThrow", "ACE_refuel", false] call EFUNC(common,statusEffect_set); \ + [_idPFH] call CBA_fnc_removePerFrameHandler; + +params ["_unit", "_nozzle"]; +TRACE_2("start",_unit,_nozzle); + +[{ + params ["_args", "_idPFH"]; + _args params ["_unit", "_nozzle"]; + + if !( + alive _unit + && {"" isEqualTo currentWeapon _unit || {_unit call EFUNC(common,isSwimming)}} + && {[_unit, objNull, [INTERACT_EXCEPTIONS, "notOnMap"]] call EFUNC(common,canInteractWith)} + && {!("unconscious" isEqualTo toLower animationState _unit)} + && {!(_unit getVariable ["ACE_isUnconscious", false])} + ) exitWith { + TRACE_3("stop dead/weapon/interact/uncon",_unit,alive _unit,currentWeapon _unit); + DROP_NOZZLE + _unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; + END_PFH + }; + + // check drop from external events + if (isNull (_unit getVariable [QGVAR(nozzle), objNull])) exitWith { + TRACE_2("stop drop",_unit,_nozzle); + UNHOLSTER_WEAPON + END_PFH + }; + + private _source = _nozzle getVariable [QGVAR(source), objNull]; + if !(alive _source) exitWith { + TRACE_3("stop source",_unit,_nozzle,_source); + DROP_NOZZLE + private _rope = _nozzle getVariable [QGVAR(rope), objNull]; + if !(isNull _rope) then { + ropeDestroy _rope; + }; + private _helper = _nozzle getVariable [QGVAR(helper), objNull]; + if !(isNull _helper) then { + deleteVehicle _helper; + }; + deleteVehicle _nozzle; + UNHOLSTER_WEAPON + END_PFH + }; + + if !(_unit == vehicle _unit && {_unit isEqualTo ACE_player}) exitWith { + TRACE_1("stop vehicle/player",_unit,vehicle _unit); + DROP_NOZZLE + UNHOLSTER_WEAPON + END_PFH + }; + + // check hoseLength < distance + if ( + !(_nozzle getVariable [QGVAR(jerryCan), false]) + && {((_source getVariable [QGVAR(hoseLength), GVAR(hoseLength)]) - 2) < _unit distance (_source modelToWorld (_nozzle getVariable QGVAR(attachPos)))} + ) exitWith { + TRACE_1("stop length",_unit); + DROP_NOZZLE + UNHOLSTER_WEAPON + END_PFH + [LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured); + }; + + private _hintLMB = ""; + private _hintRMB = localize ELSTRING(dragging,Drop); + + getCursorObjectParams params ["_cursorObject", "", "_distance"]; + if (!isNull _cursorObject && {_distance < REFUEL_NOZZLE_ACTION_DISTANCE}) then { + if ( + 1 == getNumber (configFile >> "CfgVehicles" >> (typeOf _cursorObject) >> QGVAR(canReceive)) + && {isNull (_cursorObject getVariable [QGVAR(nozzle), objNull])} + ) then { + _hintLMB = localize LSTRING(Connect); + }; + if ([_unit, _cursorObject] call FUNC(canReturnNozzle)) then { + _hintRMB = localize LSTRING(Return); + }; + }; + + private _hint = [_hintLMB, _hintRMB]; + if !(_hint isEqualTo (_unit getVariable [QGVAR(hint), []])) then { + _unit setVariable [QGVAR(hint), _hint]; + _hint call EFUNC(interaction,showMouseHint); + }; +}, 0, [_unit, _nozzle]] call cba_fnc_addPerFrameHandler; diff --git a/addons/refuel/functions/fnc_takeNozzle.sqf b/addons/refuel/functions/fnc_takeNozzle.sqf index 1b0baac80c..5049adfee6 100644 --- a/addons/refuel/functions/fnc_takeNozzle.sqf +++ b/addons/refuel/functions/fnc_takeNozzle.sqf @@ -4,15 +4,13 @@ * * Arguments: * 0: Unit - * 1: Fuel Truck - * 2: Nozzle (optional) + * 1: Fuel Source or Nozzle * * Return Value: * None * * Example: - * [player, fuelTruck] call ace_refuel_fnc_takeNozzle - * [player, objNull, nozzle] call ace_refuel_fnc_takeNozzle + * [player, cursorObject] call ace_refuel_fnc_takeNozzle * * Public: No */ @@ -20,133 +18,82 @@ params [ ["_unit", objNull, [objNull]], - ["_target", objNull, [objNull]], - ["_nozzle", objNull, [objNull]] + ["_object", objNull, [objNull]] ]; -REFUEL_HOLSTER_WEAPON +[ + TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), + [_unit, _object], + { + params ["_args"]; + _args params ["_unit", "_object"]; -private _endPosOffset = [0, 0, 0]; -if (isNull _nozzle) then { // func is called on fuel truck - _endPosOffset = getArray (configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(hooks)); - if (count _endPosOffset == 2) then { - if (_unit distance (_target modelToWorld (_endPosOffset select 0)) < _unit distance (_target modelToWorld (_endPosOffset select 1))) then { - _endPosOffset = _endPosOffset select 0; - } else { - _endPosOffset = _endPosOffset select 1; - }; - } else { - _endPosOffset = _endPosOffset select 0; - }; - [ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), - [_unit, _target, _endPosOffset], - { - params ["_args"]; - _args params [ - ["_unit", objNull, [objNull]], - ["_target", objNull, [objNull]], - ["_endPosOffset", [0, 0, 0], [[]], 3] - ]; - - private _newNozzle = QGVAR(fuelNozzle) createVehicle position _unit; - _newNozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; - _unit setVariable [QGVAR(nozzle), _newNozzle, true]; - - private _ropeTarget = _target; - if (!(_target isKindOf "AllVehicles")) then { - private _helper = QGVAR(helper) createVehicle [0,0,0]; - [QEGVAR(common,hideObjectGlobal), [_helper, true]] call CBA_fnc_serverEvent; - if ((getText (configFile >> "CfgVehicles" >> typeOf _target >> "simulation")) isEqualTo "thingX") then { - _helper attachTo [_target, [0,0,0]]; - } else { - _helper setPosWorld (getPosWorld _target); - _helper setDir (getDir _target); - _helper setVectorUp (vectorUp _target); - }; - _newNozzle setVariable [QGVAR(helper), _helper, true]; - _ropeTarget = _helper; - }; - private _hoseLength = _target getVariable [QGVAR(hoseLength), GVAR(hoseLength)]; - private _rope = ropeCreate [_ropeTarget, _endPosOffset, _newNozzle, [0, -0.20, 0.12], _hoseLength]; - _newNozzle setVariable [QGVAR(rope), _rope, true]; - _newNozzle setVariable [QGVAR(attachPos), _endPosOffset, true]; - _newNozzle setVariable [QGVAR(source), _target, true]; - - [_target, "blockEngine", "ACE_Refuel", true] call EFUNC(common,statusEffect_set); - _target setVariable [QGVAR(isConnected), true, true]; - _target setVariable [QGVAR(ownedNozzle), _newNozzle, true]; - - [_unit, "forceWalk", "ACE_refuel", true] call EFUNC(common,statusEffect_set); - _unit setVariable [QGVAR(isRefueling), true]; - private _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; - if (_actionID != -1) then { - _unit removeAction _actionID; - }; - _actionID = _unit addAction [ - format ["%1", localize ELSTRING(dragging,Drop)], - '_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); REFUEL_UNHOLSTER_WEAPON', - nil, - 20, - false, - true, - "", - '!isNull (_target getVariable [QGVAR(nozzle), objNull])' - ]; - _unit setVariable [QGVAR(ReleaseActionID), _actionID]; - - // Drop nozzle at maximum hose distance - [_unit, _target, _endPosOffset, _nozzle] call FUNC(maxDistanceDropNozzle); - }, - "", - localize LSTRING(TakeNozzleAction), - {true}, - ["isnotinside"] - ] call EFUNC(common,progressBar); -} else { // func is called on muzzle either connected or on ground - [ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), - [_unit, _nozzle], - { - params ["_args"]; - _args params [ - ["_unit", objNull, [objNull]], - ["_nozzle", objNull, [objNull]] - ]; + if !([_unit, _object] call FUNC(canTakeNozzle)) exitWith {}; + private _source = _object; + private _nozzle = _object; + if (typeOf _object isEqualTo QGVAR(fuelNozzle) || {_object getVariable [QGVAR(jerryCan), false]}) then { // func is called on muzzle either connected or on ground + _source = _nozzle getVariable QGVAR(source); if (_nozzle getVariable [QGVAR(jerryCan), false]) then { _nozzle attachTo [_unit, [0,1,0], "pelvis"]; } else { _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; }; - _unit setVariable [QGVAR(nozzle), _nozzle, true]; + } else { // func is called on fuel truck + _nozzle = QGVAR(fuelNozzle) createVehicle [0,0,0]; + _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; - [_unit, "forceWalk", "ACE_refuel", true] call EFUNC(common,statusEffect_set); - _unit setVariable [QGVAR(isRefueling), true]; - private _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; - if (_actionID != -1) then { - _unit removeAction _actionID; + private _ropeTarget = _source; + if !(_source isKindOf "AllVehicles") then { + private _helper = QGVAR(helper) createVehicle [0,0,0]; + [QEGVAR(common,hideObjectGlobal), [_helper, true]] call CBA_fnc_serverEvent; + if ((getText (configFile >> "CfgVehicles" >> typeOf _source >> "simulation")) isEqualTo "thingX") then { + _helper attachTo [_source, [0,0,0]]; + } else { + _helper setPosWorld (getPosWorld _source); + _helper setDir (getDir _source); + _helper setVectorUp (vectorUp _source); + }; + _nozzle setVariable [QGVAR(helper), _helper, true]; + _ropeTarget = _helper; }; - _actionID = _unit addAction [ - format ["%1", localize ELSTRING(dragging,Drop)], - '_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); REFUEL_UNHOLSTER_WEAPON', - nil, - 20, - false, - true, - "", - '!isNull (_target getVariable [QGVAR(nozzle), objNull])' - ]; - _unit setVariable [QGVAR(ReleaseActionID), _actionID]; + private _attachPos = _source getVariable [QGVAR(hooks), getArray (configFile >> "CfgVehicles" >> typeOf _source >> QGVAR(hooks))]; + if (_attachPos isEqualTo []) then { + _attachPos = [[0,0,0]]; + }; + if (count _attachPos == 1) then { + _attachPos = _attachPos select 0; + } else { + // select closest hook + private _hookDistances = _attachPos apply {_unit distance (_source modelToWorld _x)}; + _attachPos = _attachPos select (_hookDistances find selectMin _hookDistances); + }; + private _hoseLength = _source getVariable [QGVAR(hoseLength), GVAR(hoseLength)]; + private _rope = ropeCreate [_ropeTarget, _attachPos, _nozzle, [0, -0.20, 0.12], _hoseLength]; + _nozzle setVariable [QGVAR(rope), _rope, true]; + _nozzle setVariable [QGVAR(attachPos), _attachPos, true]; + _nozzle setVariable [QGVAR(source), _source, true]; - // Drop nozzle at maximum hose distance - private _target = _nozzle getVariable QGVAR(source); - private _endPosOffset = _nozzle getVariable QGVAR(attachPos); - [_unit, _target, _endPosOffset, _nozzle] call FUNC(maxDistanceDropNozzle); - }, - "", - localize LSTRING(TakeNozzleAction), - {true}, - ["isnotinside"] - ] call EFUNC(common,progressBar); -}; + [_source, "blockEngine", "ACE_Refuel", true] call EFUNC(common,statusEffect_set); + _source setVariable [QGVAR(isConnected), true, true]; + _source setVariable [QGVAR(ownedNozzle), _nozzle, true]; + }; + + _unit setVariable [QGVAR(nozzle), _nozzle, true]; + _unit setVariable [QGVAR(isRefueling), true]; + + // holster weapon + _unit setVariable [QGVAR(selectedWeaponOnRefuel), currentWeapon _unit]; + _unit call EFUNC(common,fixLoweredRifleAnimation); + _unit action ["SwitchWeapon", _unit, _unit, 299]; + + [_unit, "forceWalk", "ACE_refuel", true] call EFUNC(common,statusEffect_set); + [_unit, "blockThrow", "ACE_refuel", true] call EFUNC(common,statusEffect_set); + + [_unit, _nozzle] call FUNC(startNozzleInHandsPFH); + }, + {}, + localize LSTRING(TakeNozzleAction), + {true}, + [INTERACT_EXCEPTIONS_REFUELING] +] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_turnOff.sqf b/addons/refuel/functions/fnc_turnOff.sqf index 2c2b8de158..067d59c51e 100644 --- a/addons/refuel/functions/fnc_turnOff.sqf +++ b/addons/refuel/functions/fnc_turnOff.sqf @@ -18,18 +18,6 @@ params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; -[ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), - [_unit, _nozzle], - { - params ["_args"]; - _args params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; - _nozzle setVariable [QGVAR(lastTickMissionTime), nil]; - _nozzle setVariable [QGVAR(isRefueling), false, true]; - [LSTRING(Hint_Stopped), 1.5, _unit] call EFUNC(common,displayTextStructured); - }, - "", - localize LSTRING(TurnOffAction), - {true}, - ["isnotinside"] -] call EFUNC(common,progressBar); +_nozzle setVariable [QGVAR(lastTickMissionTime), nil]; +_nozzle setVariable [QGVAR(isRefueling), false, true]; +[LSTRING(Hint_Stopped), 1.5, _unit] call EFUNC(common,displayTextStructured); diff --git a/addons/refuel/functions/fnc_turnOn.sqf b/addons/refuel/functions/fnc_turnOn.sqf index cf8656f558..e57cd3725a 100644 --- a/addons/refuel/functions/fnc_turnOn.sqf +++ b/addons/refuel/functions/fnc_turnOn.sqf @@ -18,18 +18,6 @@ params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; -[ - TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), - [_unit, _nozzle], - { - params ["_args"]; - _args params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; - _nozzle setVariable [QGVAR(lastTickMissionTime), CBA_missionTime]; - _nozzle setVariable [QGVAR(isRefueling), true, true]; - [LSTRING(Hint_Started), 1.5, _unit] call EFUNC(common,displayTextStructured); - }, - "", - localize LSTRING(TurnOnAction), - {true}, - ["isnotinside"] -] call EFUNC(common,progressBar); +_nozzle setVariable [QGVAR(lastTickMissionTime), CBA_missionTime]; +_nozzle setVariable [QGVAR(isRefueling), true, true]; +[LSTRING(Hint_Started), 1.5, _unit] call EFUNC(common,displayTextStructured); diff --git a/addons/refuel/script_component.hpp b/addons/refuel/script_component.hpp index a4d6f6df31..be346e0cca 100644 --- a/addons/refuel/script_component.hpp +++ b/addons/refuel/script_component.hpp @@ -19,21 +19,16 @@ #include "\z\ace\addons\main\script_macros.hpp" #define REFUEL_INFINITE_FUEL -10 +#define REFUEL_DISABLED_FUEL -1 #define REFUEL_ACTION_DISTANCE 7 +#define REFUEL_NOZZLE_ACTION_DISTANCE 2 #define REFUEL_PROGRESS_DURATION 2 -#define REFUEL_HOLSTER_WEAPON \ - _unit setVariable [QGVAR(selectedWeaponOnRefuel), currentWeapon _unit]; \ - _unit call EFUNC(common,fixLoweredRifleAnimation); \ - _unit action ["SwitchWeapon", _unit, _unit, 299]; - -#define REFUEL_UNHOLSTER_WEAPON \ - _weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRefuel); \ - _unit selectWeapon _weaponSelect; \ - _unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; - #ifdef FAST_PROGRESSBARS #define TIME_PROGRESSBAR(X) ((X) * 0.075) #else #define TIME_PROGRESSBAR(X) (X) #endif + +#define INTERACT_EXCEPTIONS_REFUELING "isNotInside", "isNotOnLadder", "isNotSwimming" +#define INTERACT_EXCEPTIONS INTERACT_EXCEPTIONS_REFUELING, "isNotRefueling" diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index e2a4c45cd3..00cdb7e308 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -41,7 +41,7 @@ Quanto velocemente dovrebbe essere rifornito un veicolo? Cuán rápido se reabastecen los vehículos? A quelle vitesse devrait être ravitaillé un véhicule ? - どのくらいの速さで車両へ給油しますか? + どのくらいの速さで車両へ給油しますか? 차량이 얼마나 빨리 재급유될 수 있습니까? 载具多快会加油完毕? 載具多快會加油完畢? @@ -86,7 +86,7 @@ Prendendo manicotto benzina... Tomando surtidor... Prise de la pompe... - 給油ノズルを取っている・・・ + 給油ノズルを取っています・・・ 주유기 획득중... 拿取燃料喷嘴中... 拿取燃料噴嘴中... @@ -116,7 +116,7 @@ Collegando manicotto benzina... Conectando surtidor... Connection de la pompe... - 給油ノズルを接続している・・・ + 給油ノズルを接続しています・・・ 주유기 꼽는중... 连结燃料喷嘴中... 連結燃料噴嘴中... @@ -176,7 +176,7 @@ Controllando la benzina rimanente... Verificando combustible remanente,,, Vérifie le carburant restant... - 残燃料を見ている・・・ + 残燃料を見ています・・・ 남은 연료 확인중... 检查剩余燃料中... 檢查剩餘燃料中... @@ -193,8 +193,8 @@ Il reste %1 litres. 後 %1 リットル残っている。 %1 리터 남음 - 剩下%1公升的燃料. - 剩下%1公升的燃料. + 剩下%1公升的燃料。 + 剩下%1公升的燃料。 There is no fuel left. @@ -256,21 +256,6 @@ 停止加油 停止加油 - - Stopping fueling... - Stoppe Betankung... - Zatrzymywanie tankowania... - Останавливаем заправку... - Parando reabastecimento... - Zastavuji tankování... - Fermando il rifornimento... - Deteniendo reabastecimiento... - Arrête le ravitaillement... - 給油をやめている・・・ - 재급유 그만하는중... - 停止加油中... - 停止加油中... - Start fueling Betankung beginnen @@ -286,20 +271,14 @@ 开始加油 開始加油 - - Starting fueling... - Beginne Betankung... - Rozpoczynanie tankowania... - Начинаем заправку... - Começando reabastecimento... - Spouštím tankování... - Iniziando il rifornimento... - Comenzando reabastecimiento... - Début du ravitaillement... - 給油を始めている・・・ - 재급유 시작중... - 开始加油中... - 開始加油中... + + Couldn't turn on fuel nozzle + Kann Zapfpistole nicht anschalten + Impossibile iniziare il rifornimento + 給油を始められなかった + 無法開啟燃料噴嘴 + 无法开启燃料喷嘴 + 주유기를 켤 수 없습니다. %1 Liters fueled @@ -327,9 +306,9 @@ La fuente de combustible está vacía. La source de carburant est vide. 給油元は空です。 - 재급유처가 비었음. 燃料来源已空. 燃料來源已空. + 연료공급처가 비었음. Maximum fuel hose length reached. @@ -343,8 +322,8 @@ Tuyau tendu au maximum 給油ホースはもうこれ以上届かない。 주유기 호스 최대 거리에 도달함. - 已加满至最大油量. - 已加滿至最大油量. + 已加满至最大油量。 + 已加滿至最大油量。 Fueling completed @@ -416,7 +395,7 @@ Riponendo la manica della benzina... Devolviendo el surtidor... Retourne la pompe - 給油ノズルを戻している・・・ + 給油ノズルを戻しています・・・ 주유기 반환중 放回燃料喷嘴中... 放回燃料噴嘴中... @@ -436,21 +415,6 @@ 检查燃料表 檢查燃料表 - - Checking fuel counter... - Betrachte Tankuhr... - Sprawdzanie wskaźnika paliwa... - Проверяем счетчик топлива... - Verificando contador de combustível... - Konroluji palivoměr... - Controllando l'indicatore del livello benzina... - Verificando el contador de combustible - Vérification du compteur... - 燃料計を見ている・・・ - 연료카운터 확인중... - 检查燃料表中... - 檢查燃料表中... - %1 liters have been fueled. %1 Liter wurden getankt. @@ -461,10 +425,10 @@ %1 litri sono stati riforniti. Se reabastecieron %1 lt %1 litres ont été écoulés. - %1 リッターがある + %1 リッターが給油された %1 리터가 재급유되었습니다. - 已加入%1公升. - 已加入%1公升. + 已加入%1公升 + 已加入%1公升 Refuel hose length @@ -474,6 +438,49 @@ 給油ホースの長さ 加油软管长度 加油軟管長度 + Długość węża paliwowego + 주유기 호스 길이 + + + Fuel Cargo Volume + Tankvolumen + Объем топлива для заправки + 貯油量 + Capacità Carburante Cargo + 儲油量 + 储油量 + 연료통 크기 + + + + The fuel volume available for refueling (-1 disable, -10 if infinite) + Das Tankvolumen, welches zum Nachtanken verfügbar ist (-1 deaktiviert, -10 unendlich) + Объем топлива, доступный для заправки других машин (-1 отключить, -10 если неограничен) + 給油用の貯油量を設定 (-1で無効、-10で無限) + La capacità del carburante disponibile per il rifornimento (-1 disabilita, -10 se infinito) + 設定有多少油料可供載具進行加油(-1時關閉,-10為無限油量) + 设定有多少油料可供载具进行加油(-1时关闭,-10为无限油量) + 재급유에 사용 할 수 있는 연료량 (-1=비활성, -10=무한) + + + Refuel Hose attach coordinates + Befestigungskoordinaten der Zapfpistole + Координаты крепления шланга + 給油ノズルの取り付け座標 + Coordinate del tubo di rifornimento + 加油軟管安裝位置 + 加油软管安装位置 + 재급유기 부착 좌표 + + + Model coordinates used to attach refuel hose + Modelkoordinaten zum Anheften der Zapfpistole + Координаты модели, куда крепится заправочный шланг + 給油ノズルの取り付けにモデル座標を使用 + Coordinate del modello utilizzate per il fissaggio del tubo + 設定加油軟管會安裝到模型的哪個位置上 + 设定加油软管会安装到模型的哪个位置上 + 재급유기 부착에 쓰이는 모델 좌표 diff --git a/addons/reload/ACE_Settings.hpp b/addons/reload/ACE_Settings.hpp index 72d26b46cf..82e9f32637 100644 --- a/addons/reload/ACE_Settings.hpp +++ b/addons/reload/ACE_Settings.hpp @@ -1,5 +1,6 @@ class ACE_Settings { class GVAR(displayText) { + category = ECSTRING(common,ACEKeybindCategoryWeapons); typeName = "BOOL"; isClientSettable = 1; value = 1; diff --git a/addons/reload/CfgVehicles.hpp b/addons/reload/CfgVehicles.hpp index 05ac18ea70..7a1d483bd9 100644 --- a/addons/reload/CfgVehicles.hpp +++ b/addons/reload/CfgVehicles.hpp @@ -8,12 +8,14 @@ class CfgVehicles { distance = 2.0; condition = QUOTE(([ARR_2(_player, _target)] call FUNC(getAmmoToLinkBelt)) > 0); statement = QUOTE([ARR_2(_player, _target)] call FUNC(startLinkingBelt)); + exceptions[] = {"isNotInside"}; }; class GVAR(CheckAmmo) { displayName = CSTRING(checkAmmo); distance = 2.0; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canCheckAmmo)); statement = QUOTE([ARR_2(_player, _target)] call FUNC(checkAmmo)); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; }; }; }; @@ -28,6 +30,7 @@ class CfgVehicles { distance = 2.0; condition = QUOTE([ARR_2(_player, _target)] call FUNC(canCheckAmmo)); statement = QUOTE([ARR_2(_player, _target)] call FUNC(checkAmmo)); + exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"}; }; }; }; diff --git a/addons/reload/XEH_postInit.sqf b/addons/reload/XEH_postInit.sqf index 7a5e17464c..070edfa225 100644 --- a/addons/reload/XEH_postInit.sqf +++ b/addons/reload/XEH_postInit.sqf @@ -6,7 +6,7 @@ if (!hasInterface) exitWith {}; // Add keybinds ["ACE3 Weapons", QGVAR(checkAmmo), localize LSTRING(checkAmmo), { // Conditions: canInteract - if !([ACE_player, vehicle ACE_player, ["isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, vehicle ACE_player, ["isNotInside", "isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if !(ACE_player call CBA_fnc_canUseWeapon || {(vehicle ACE_player) isKindOf "StaticWeapon"}) exitWith {false}; diff --git a/addons/reload/functions/fnc_startLinkingBelt.sqf b/addons/reload/functions/fnc_startLinkingBelt.sqf index 4e64bfc154..aac6ed4561 100644 --- a/addons/reload/functions/fnc_startLinkingBelt.sqf +++ b/addons/reload/functions/fnc_startLinkingBelt.sqf @@ -43,7 +43,7 @@ private _onFinish = { }; private _onFailure = { - EXPLODE_3_PVT((_this select 0),_player,_target,_magazine); + (_this select 0) params ["_player", "_target", "_magazine"]; [_player, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); // Add back the magazine with the former ammo count @@ -56,4 +56,4 @@ private _onFailure = { [_player, _magazineType, _maxAmmo] call EFUNC(common,removeSpecificMagazine); // Call progress bar -[4, [_player, _target, [_magazineType, _maxAmmo]], _onFinish, _onFailure, (localize LSTRING(LinkingBelt)), _condition] call EFUNC(common,progressBar); +[4, [_player, _target, [_magazineType, _maxAmmo]], _onFinish, _onFailure, (localize LSTRING(LinkingBelt)), _condition, ["isNotInside"]] call EFUNC(common,progressBar); diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index 5cdbe3e9ba..2a7764dc04 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -28,7 +28,7 @@ A lőszer ellenőrzése az új tárad behelyezésekor újratöltés közben. Controlla le munizioni rimanenti nel caricatore in fase di cambio caricatore. Confere a munição no seu novo carregador ao recarregar a arma - あたらしく装填された弾倉の弾薬を確認します。 + 新しく装填された弾倉の弾薬を確認します。 재장전시 새탄창에 있는 탄약을 확인합니다. 在重新装填时检查新弹匣上的弹药. 在重新裝填時檢查新彈匣上的彈藥. @@ -76,7 +76,7 @@ Töltényheveder összekötése Attacca la tracolla Ligar cintos de munição - ベルト リンク + ベルトをつなげる 벨트 연결 连接弹链 連接彈鏈 @@ -92,7 +92,7 @@ Töltényheveder összekötése folyamatban... Attaccando la tracolla... Ligando cintos... - ベルトをつなげている・・・ + ベルトをつなげています・・・ 벨트 연결중... 连接弹链中... 連接彈鏈中... diff --git a/addons/reloadlaunchers/CfgVehicles.hpp b/addons/reloadlaunchers/CfgVehicles.hpp index 3d7a5c9353..eccd30d1f7 100644 --- a/addons/reloadlaunchers/CfgVehicles.hpp +++ b/addons/reloadlaunchers/CfgVehicles.hpp @@ -8,6 +8,7 @@ class CfgVehicles { selection = "launcher"; distance = 4; condition = ""; + exceptions[] = {"isNotInside", "isNotSwimming"}; insertChildren = QUOTE(_this call FUNC(addMissileReloadActions)); }; }; diff --git a/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf index 1597654847..a3caa76152 100644 --- a/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf +++ b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf @@ -33,20 +33,18 @@ private _loadableMissiles = [_unit, _weapon] call FUNC(getLoadableMissiles); TRACE_2("",_weapon,_loadableMissiles); { - private ["_name", "_displayName", "_statement", "_condition", "_action"]; + private _name = format [QGVAR(Missile_%1), _x]; + private _displayName = format [localize LSTRING(LoadMagazine), getText (configFile >> "CfgMagazines" >> _x >> "displayName")]; - _name = format [QGVAR(Missile_%1), _x]; - _displayName = format [localize LSTRING(LoadMagazine), getText (configFile >> "CfgMagazines" >> _x >> "displayName")]; - - _statement = { + private _statement = { (_this select 2) call DFUNC(load); }; - _condition = { + private _condition = { (_this select 2) call DFUNC(canLoad) }; - _action = [_name, _displayName, "", _statement, _condition, {}, [_unit, _target, _weapon, _x], "", 4] call EFUNC(interact_menu,createAction); + private _action = [_name, _displayName, "", _statement, _condition, {}, [_unit, _target, _weapon, _x], "", 4] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _unit]; } forEach _loadableMissiles; diff --git a/addons/reloadlaunchers/functions/fnc_canLoad.sqf b/addons/reloadlaunchers/functions/fnc_canLoad.sqf index 9f76cab49a..2e578b1be7 100644 --- a/addons/reloadlaunchers/functions/fnc_canLoad.sqf +++ b/addons/reloadlaunchers/functions/fnc_canLoad.sqf @@ -23,7 +23,7 @@ TRACE_4("params",_unit,_target,_weapon,_magazine); if (!alive _target) exitWith {false}; if (vehicle _target != _target) exitWith {false}; -if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([_unit, _target, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // target is awake if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false}; diff --git a/addons/reloadlaunchers/functions/fnc_load.sqf b/addons/reloadlaunchers/functions/fnc_load.sqf index 8330b111b7..2017ecf94e 100644 --- a/addons/reloadlaunchers/functions/fnc_load.sqf +++ b/addons/reloadlaunchers/functions/fnc_load.sqf @@ -31,21 +31,20 @@ private _reloadTime = if (isNumber (configFile >> "CfgWeapons" >> _weapon >> QGV [_unit] call EFUNC(common,goKneeling); // show progress bar -private ["_onSuccess", "_onFailure", "_condition"]; -_onSuccess = { +private _onSuccess = { (_this select 0 select 0) removeMagazine (_this select 0 select 3); [QGVAR(reloadLauncher), _this select 0, _this select 0 select 1] call CBA_fnc_targetEvent; [localize LSTRING(LauncherLoaded)] call DEFUNC(common,displayTextStructured); }; -_onFailure = { +private _onFailure = { [localize ELSTRING(common,ActionAborted)] call DEFUNC(common,displayTextStructured); }; -_condition = { +private _condition = { (_this select 0) call DFUNC(canLoad) && {(_this select 0 select 0) distance (_this select 0 select 1) < 4} }; -[_reloadTime, [_unit, _target, _weapon, _magazine], _onSuccess, _onFailure, localize LSTRING(LoadingLauncher), _condition] call EFUNC(common,progressBar); +[_reloadTime, [_unit, _target, _weapon, _magazine], _onSuccess, _onFailure, localize LSTRING(LoadingLauncher), _condition, ["isNotInside", "isNotSwimming"]] call EFUNC(common,progressBar); diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index ccbca809f0..eef4c9e50a 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -12,7 +12,7 @@ Kilövö betöltése Carica lanciamissili Recarregar lançador - ランチャーを装填 + ランチャーに装填 무기 재장전 装载发射器 裝載發射器 @@ -28,7 +28,7 @@ Kilövő betöltés alatt... Caricando il lanciamissili... Recarregando lançador... - ランチャーを装填している・・・ + ランチャーに装填中・・・ 무기 재장전중... 装载发射器中... 裝載發射器中... @@ -44,7 +44,7 @@ Kilövő betöltve Lanciamissili caricato Lançador Carregado - ランチャーの装填完了 + ランチャーに装填完了 무기 재장전됨 发射器装载完毕 發射器裝載完畢 @@ -60,7 +60,7 @@ %1 betöltése Caricato %1 Recarregar %1 - %1 へ装填 + %1 を装填 %1 장전 装载%1 裝載%1 diff --git a/addons/repair/ACE_Settings.hpp b/addons/repair/ACE_Settings.hpp index 0c05bc8459..ea3994caec 100644 --- a/addons/repair/ACE_Settings.hpp +++ b/addons/repair/ACE_Settings.hpp @@ -8,16 +8,16 @@ class ACE_Settings { category = ECSTRING(OptionsMenu,CategoryLogistics); }; class GVAR(engineerSetting_repair) { - displayName = CSTRING(enginerSetting_Repair_name); - description = CSTRING(enginerSetting_Repair_description); + displayName = CSTRING(engineerSetting_Repair_name); + description = CSTRING(engineerSetting_Repair_description); typeName = "SCALAR"; value = 1; values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_AdvancedOnly)}; category = ECSTRING(OptionsMenu,CategoryLogistics); }; class GVAR(engineerSetting_wheel) { - displayName = CSTRING(enginerSetting_Wheel_name); - description = CSTRING(enginerSetting_Wheel_description); + displayName = CSTRING(engineerSetting_Wheel_name); + description = CSTRING(engineerSetting_Wheel_description); typeName = "SCALAR"; value = 0; values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_AdvancedOnly)}; @@ -29,6 +29,7 @@ class ACE_Settings { typeName = "SCALAR"; value = 0.6; category = ECSTRING(OptionsMenu,CategoryLogistics); + sliderSettings[] = {0, 1, 0.6, 2}; }; class GVAR(repairDamageThreshold_engineer) { displayName = CSTRING(repairDamageThreshold_Engineer_name); @@ -36,6 +37,7 @@ class ACE_Settings { typeName = "SCALAR"; value = 0.4; category = ECSTRING(OptionsMenu,CategoryLogistics); + sliderSettings[] = {0, 1, 0.4, 2}; }; class GVAR(consumeItem_toolKit) { displayName = CSTRING(consumeItem_ToolKit_name); diff --git a/addons/repair/CfgEden.hpp b/addons/repair/CfgEden.hpp index 1c1263755b..be92ec6689 100644 --- a/addons/repair/CfgEden.hpp +++ b/addons/repair/CfgEden.hpp @@ -63,6 +63,28 @@ class Cfg3DEN { condition = "(1 - objectBrain) * (1 - objectVehicle)"; defaultValue = 0; }; + class GVAR(editorLoadedTracks) { + displayName = CSTRING(editorLoadedTracks); + tooltip = CSTRING(editorLoadedTracks_tooltip); + property = QGVAR(editorLoadedTracks); + control = "Edit"; + expression = "_this setVariable ['%s',_value];"; + defaultValue = "[0,1] select (_this isKindOf 'Tank')"; // must match pre init script + validate = "number"; + condition = "objectHasInventoryCargo"; + typeName = "NUMBER"; + }; + class GVAR(editorLoadedWheels) { + displayName = CSTRING(editorLoadedWheels); + tooltip = CSTRING(editorLoadedWheels_tooltip); + property = QGVAR(editorLoadedWheels); + control = "Edit"; + expression = "_this setVariable ['%s',_value];"; + defaultValue = "[0,1] select (_this isKindOf 'Car')"; // must match pre init script + validate = "number"; + condition = "objectHasInventoryCargo"; + typeName = "NUMBER"; + }; }; }; }; diff --git a/addons/repair/CfgMoves.hpp b/addons/repair/CfgMoves.hpp new file mode 100644 index 0000000000..4e42310851 --- /dev/null +++ b/addons/repair/CfgMoves.hpp @@ -0,0 +1,9 @@ +class CfgMovesBasic; +class CfgMovesMaleSdr: CfgMovesBasic { + class States { + class Campaign_Base; + class Acts_carFixingWheel: Campaign_Base { + soundOverride = ""; + }; + }; +}; diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp index e06c18115b..79f46ef753 100644 --- a/addons/repair/CfgVehicles.hpp +++ b/addons/repair/CfgVehicles.hpp @@ -10,7 +10,7 @@ priority = 2; \ icon = "\A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; \ distance = 4; \ - exceptions[] = {"isNotOnLadder"}; \ + exceptions[] = {"isNotSwimming", "isNotOnLadder"}; \ }; \ }; \ }; @@ -20,7 +20,7 @@ class CBA_Extended_EventHandlers_base; class CfgVehicles { class ACE_Module; class ACE_moduleRepairSettings: ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(moduleName); icon = QPATHTOF(ui\Icon_Module_Repair_ca.paa); category = "ACE_Logistics"; @@ -32,8 +32,8 @@ class CfgVehicles { author = ECSTRING(Common,ACETeam); class Arguments { class engineerSetting_Repair { - displayName = CSTRING(enginerSetting_Repair_name); - description = CSTRING(enginerSetting_Repair_description); + displayName = CSTRING(engineerSetting_Repair_name); + description = CSTRING(engineerSetting_Repair_description); typeName = "NUMBER"; class values { class anyone { name = CSTRING(engineerSetting_anyone); value = 0; }; @@ -42,8 +42,8 @@ class CfgVehicles { }; }; class engineerSetting_Wheel { - displayName = CSTRING(enginerSetting_Wheel_name); - description = CSTRING(enginerSetting_Wheel_description); + displayName = CSTRING(engineerSetting_Wheel_name); + description = CSTRING(engineerSetting_Wheel_description); typeName = "NUMBER"; class values { class anyone { name = CSTRING(engineerSetting_anyone); value = 0; default = 1; }; @@ -118,7 +118,7 @@ class CfgVehicles { class Module_F; class ACE_moduleAssignEngineerRoles: Module_F { - scope = 2; + scope = 1; displayName = CSTRING(AssignEngineerRole_Module_DisplayName); icon = QPATHTOF(ui\Icon_Module_Repair_ca.paa); category = "ACE_Logistics"; @@ -162,7 +162,7 @@ class CfgVehicles { }; }; class ACE_moduleAssignRepairVehicle: Module_F { - scope = 2; + scope = 1; displayName = CSTRING(AssignRepairVehicle_Module_DisplayName); icon = QPATHTOF(ui\Icon_Module_Repair_ca.paa); category = "ACE_Logistics"; @@ -234,7 +234,7 @@ class CfgVehicles { }; }; class ACE_moduleAddSpareParts: Module_F { - scope = 2; + scope = 1; displayName = CSTRING(AddSpareParts_Module_DisplayName); icon = QPATHTOF(ui\Icon_Module_Repair_ca.paa); category = "ACE_Logistics"; @@ -321,7 +321,8 @@ class CfgVehicles { accuracy = 0.2; vehicleClass = "ACE_Logistics_Items"; - destrType = "DesturctNo"; // scripted delayed destruction + editorCategory = "EdCat_Supplies"; + editorSubcategory = QEGVAR(main,subcategory); }; class ACE_Track: ACE_RepairItem_Base { @@ -335,7 +336,7 @@ class CfgVehicles { mapSize = 0.5; // damage handling - armor = 0.6; + armor = 1000; armorStructural = 1; minTotalDamageThreshold = 0.01; explosionShielding = 1; @@ -350,6 +351,8 @@ class CfgVehicles { QPATHTO_R(data\trailObjects_steel_destruct.rvmat) }; }; + + editorPreview = QPATHTOF(data\preview_track.jpg); }; class ACE_Wheel: ACE_RepairItem_Base { @@ -364,7 +367,7 @@ class CfgVehicles { mapSize = 0.7; // damage handling - armor = 0.05; + armor = 120; armorStructural = 1; minTotalDamageThreshold = 0.01; explosionShielding = 1; @@ -396,6 +399,8 @@ class CfgVehicles { QPATHTO_R(data\trailObjects_steel_destruct.rvmat) }; }; + + editorPreview = QPATHTOF(data\preview_wheel.jpg); }; // disable vanilla repair @@ -481,8 +486,7 @@ class CfgVehicles { transportRepair = 0; }; - class Quadbike_01_base_F; - class B_Quadbike_01_F: Quadbike_01_base_F { + class Quadbike_01_base_F: Car_F { GVAR(hitpointPositions)[] = { {"HitEngine", {0, 0.5, -0.7}}, {"HitFuel", {0, 0, -0.5}} }; }; class Hatchback_01_base_F: Car_F { diff --git a/addons/repair/XEH_PREP.hpp b/addons/repair/XEH_PREP.hpp index 692bee6112..7c2e5a1f15 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -24,6 +24,7 @@ PREP(isInRepairFacility); PREP(isNearRepairVehicle); PREP(isRepairVehicle); PREP(modifyInteraction); +PREP(modifySelectionInteraction); PREP(moduleAddSpareParts); PREP(moduleAssignEngineer); PREP(moduleAssignRepairVehicle); diff --git a/addons/repair/XEH_postInit.sqf b/addons/repair/XEH_postInit.sqf index 5c94924a5c..2f0bbe7869 100644 --- a/addons/repair/XEH_postInit.sqf +++ b/addons/repair/XEH_postInit.sqf @@ -5,14 +5,3 @@ // wheels [QGVAR(setWheelHitPointDamage), {(_this select 0) setHitPointDamage [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; - -if (isServer) then { - ["ace_settingsInitialized", { - TRACE_1("ace_settingsInitialized eh", GVAR(addSpareParts)); - if (!GVAR(addSpareParts)) exitWith {}; - if (!(["ace_cargo"] call EFUNC(common,isModLoaded))) exitWith {}; - - ["Car", "Init", {[_this select 0, 1, "ACE_Wheel"] call FUNC(addSpareParts)}, true, [], true] call CBA_fnc_addClassEventHandler; - ["Tank", "Init", {[_this select 0, 1, "ACE_Track"] call FUNC(addSpareParts)}, true, [], true] call CBA_fnc_addClassEventHandler; - }] call CBA_fnc_addEventHandler; -}; diff --git a/addons/repair/XEH_preInit.sqf b/addons/repair/XEH_preInit.sqf index 8e6a606f0f..ca76ce5758 100644 --- a/addons/repair/XEH_preInit.sqf +++ b/addons/repair/XEH_preInit.sqf @@ -12,4 +12,27 @@ PREP_RECOMPILE_END; [{deleteVehicle _this}, _object, 5] call CBA_fnc_waitAndExecute; }] call CBA_fnc_addClassEventHandler; +// load tracks and wheels +if (isServer) then { + private _fnc_addSpareItems = { + if (!GVAR(addSpareParts)) exitWith {}; + params ["_vehicle"]; + + private _spareTracks = _vehicle getVariable QGVAR(editorLoadedTracks); + if (isNil "_spareTracks") then { + _spareTracks = [0, 1] select (_vehicle isKindOf "Tank"); // must match eden attribute default + }; + [_vehicle, _spareTracks, "ACE_Track"] call FUNC(addSpareParts); + + private _spareWheels = _vehicle getVariable QGVAR(editorLoadedWheels); + if (isNil "_spareWheels") then { + _spareWheels = [0, 1] select (_vehicle isKindOf "Car"); // must match eden attribute default + }; + [_vehicle, _spareWheels, "ACE_Wheel"] call FUNC(addSpareParts); + }; + + ["Tank", "initPost", _fnc_addSpareItems] call CBA_fnc_addClassEventHandler; + ["Car", "initPost", _fnc_addSpareItems] call CBA_fnc_addClassEventHandler; +}; + ADDON = true; diff --git a/addons/repair/config.cpp b/addons/repair/config.cpp index a8904a0a0a..1dbe9b46b1 100644 --- a/addons/repair/config.cpp +++ b/addons/repair/config.cpp @@ -16,7 +16,8 @@ class CfgPatches { #include "ACE_Repair.hpp" #include "ACE_Settings.hpp" -#include "CfgEventHandlers.hpp" #include "CfgActions.hpp" -#include "CfgVehicles.hpp" #include "CfgEden.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMoves.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/repair/data/ace_track.p3d b/addons/repair/data/ace_track.p3d index 53ac8971a7..83ffb9e675 100644 Binary files a/addons/repair/data/ace_track.p3d and b/addons/repair/data/ace_track.p3d differ diff --git a/addons/repair/data/preview_track.jpg b/addons/repair/data/preview_track.jpg new file mode 100644 index 0000000000..9ccae6e5f3 Binary files /dev/null and b/addons/repair/data/preview_track.jpg differ diff --git a/addons/repair/data/preview_wheel.jpg b/addons/repair/data/preview_wheel.jpg new file mode 100644 index 0000000000..fc290ed92e Binary files /dev/null and b/addons/repair/data/preview_wheel.jpg differ diff --git a/addons/repair/data/trailObjects_steel_damage.rvmat b/addons/repair/data/trailObjects_steel_damage.rvmat index 1850a7396c..f797f4ac61 100644 --- a/addons/repair/data/trailObjects_steel_damage.rvmat +++ b/addons/repair/data/trailObjects_steel_damage.rvmat @@ -38,10 +38,10 @@ class Stage3 { texture = "a3\data_f\destruct\damage_metal_mc.paa"; uvSource = "tex"; class uvTransform { - aside[] = {3,0,0}; - up[] = {0,3,0}; - dir[] = {0,0,0}; - pos[] = {0.1,0.23,0}; + aside[] = {3,0,0}; + up[] = {0,3,0}; + dir[] = {0,0,0}; + pos[] = {0.1,0.23,0}; }; }; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 398083a080..8a1e068379 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -20,11 +20,9 @@ if (!hasInterface) exitWith {}; params ["_vehicle"]; TRACE_2("params", _vehicle,typeOf _vehicle); -private ["_action", "_childHitPoint", "_condition", "_groupsConfig", "_hitPoint", "_hitPointsAddedAmount", "_hitPointsAddedNames", "_hitPointsAddedStrings", "_icon", "_initializedClasses", "_name", "_position", "_positionsConfig", "_processedHitPoints", "_selection", "_statement", "_target", "_type"]; +private _type = typeOf _vehicle; -_type = typeOf _vehicle; - -_initializedClasses = GETMVAR(GVAR(initializedClasses),[]); +private _initializedClasses = GETMVAR(GVAR(initializedClasses),[]); // do nothing if the class is already initialized if (_type in _initializedClasses) exitWith {}; @@ -35,31 +33,30 @@ if (_type in _initializedClasses) exitWith {}; // get hitpoints of wheels with their selections ([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; -_hitPointsAddedNames = []; -_hitPointsAddedStrings = []; -_hitPointsAddedAmount = []; -_processedHitpoints = []; +private _hitPointsAddedNames = []; +private _hitPointsAddedStrings = []; +private _hitPointsAddedAmount = []; +private _processedHitpoints = []; +private _icon = QPATHTOF(ui\repair_0_ca.paa); { - _selection = _x; - _hitpoint = _hitPoints select _forEachIndex; + private _selection = _x; + private _hitpoint = _hitPoints select _forEachIndex; if (_selection in _wheelHitSelections) then { // Wheels should always be unique if (_hitpoint in _processedHitpoints) exitWith {TRACE_3("Duplicate Wheel",_hitpoint,_forEachIndex,_selection);}; - _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; - - _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; + private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; TRACE_3("Adding Wheel Actions",_hitpoint,_forEachIndex,_selection); // An action to remove the wheel is required - _name = format ["Remove_%1_%2", _forEachIndex, _hitpoint]; + private _name = format ["Remove_%1_%2", _forEachIndex, _hitpoint]; private _text = localize LSTRING(RemoveWheel); - _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(canRepair)}; - _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(repair)}; - _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); + private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(canRepair)}; + private _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(repair)}; + private _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2, nil, FUNC(modifySelectionInteraction)] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); // An action to replace the wheel is required @@ -85,8 +82,8 @@ _processedHitpoints = []; }; // Associated hitpoints can be grouped via config to produce a single repair action - _groupsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointGroups); - _childHitPoint = false; + private _groupsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointGroups); + private _childHitPoint = false; if (isArray _groupsConfig) then { { { @@ -100,10 +97,10 @@ _processedHitpoints = []; if (_childHitPoint) exitWith { TRACE_3("childHitpoint",_hitpoint,_forEachIndex,_selection); }; // Find the action position - _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; + private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; // Custom position can be defined via config for associated hitpoint - _positionsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointPositions); + private _positionsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointPositions); if (isArray _positionsConfig) then { { _x params ["_hit", "_pos"]; @@ -120,8 +117,7 @@ _processedHitpoints = []; }; // Prepair the repair action - _name = format ["Repair_%1_%2", _forEachIndex, _selection]; - _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; + private _name = format ["Repair_%1_%2", _forEachIndex, _selection]; // Find localized string and track those added for numerization ([_hitpoint, "%1", _hitpoint, [_hitPointsAddedNames, _hitPointsAddedStrings, _hitPointsAddedAmount]] call FUNC(getHitPointString)) params ["_text", "_trackArray"]; @@ -138,15 +134,15 @@ _processedHitpoints = []; _position = compile format ["private _return = _target selectionPosition ['%1', 'HitPoints']; _return set [1, 0]; _return", _selection]; }; TRACE_4("Adding RepairTrack",_hitpoint,_forEachIndex,_selection,_text); - _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(canRepair)}; - _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(repair)}; - _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 4] call EFUNC(interact_menu,createAction); + private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(canRepair)}; + private _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(repair)}; + private _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 4] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); } else { TRACE_4("Adding MiscRepair",_hitpoint,_forEachIndex,_selection,_text); - _condition = {[_this select 1, _this select 0, _this select 2 select 0, "MiscRepair"] call DFUNC(canRepair)}; - _statement = {[_this select 1, _this select 0, _this select 2 select 0, "MiscRepair"] call DFUNC(repair)}; - _action = [_name, _text, _icon, _statement, _condition, {}, [_forEachIndex], _position, 5] call EFUNC(interact_menu,createAction); + private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "MiscRepair"] call DFUNC(canRepair)}; + private _statement = {[_this select 1, _this select 0, _this select 2 select 0, "MiscRepair"] call DFUNC(repair)}; + private _action = [_name, _text, _icon, _statement, _condition, {}, [_forEachIndex], _position, 5] call EFUNC(interact_menu,createAction); // Put inside main actions if no other position was found above if (_position isEqualTo [0,0,0]) then { [_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass); @@ -159,9 +155,9 @@ _processedHitpoints = []; }; } forEach _hitSelections; -_condition = {[_this select 1, _this select 0, "", "fullRepair"] call DFUNC(canRepair)}; -_statement = {[_this select 1, _this select 0, "", "fullRepair"] call DFUNC(repair)}; -_action = [QGVAR(fullRepair), localize LSTRING(fullRepair), "A3\ui_f\data\igui\cfg\actions\repair_ca.paa", _statement, _condition, {}, [], "", 4] call EFUNC(interact_menu,createAction); +private _condition = {[_this select 1, _this select 0, "", "fullRepair"] call DFUNC(canRepair)}; +private _statement = {[_this select 1, _this select 0, "", "fullRepair"] call DFUNC(repair)}; +private _action = [QGVAR(fullRepair), localize LSTRING(fullRepair), _icon, _statement, _condition, {}, [], "", 4] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass); // set class as initialized diff --git a/addons/repair/functions/fnc_canMiscRepair.sqf b/addons/repair/functions/fnc_canMiscRepair.sqf index 7ebfb5c5a8..9d9fc29478 100644 --- a/addons/repair/functions/fnc_canMiscRepair.sqf +++ b/addons/repair/functions/fnc_canMiscRepair.sqf @@ -18,18 +18,17 @@ #include "script_component.hpp" -private ["_hitpointGroupConfig", "_hitpointGroup", "_postRepairDamage", "_return", "_hitPointClassname", "_subHitIndex"]; params ["_caller", "_target", "_hitPointIndex"]; (getAllHitPointsDamage _target) params ["_allHitPoints", "", "_allHitPointDamages"]; -if !([_caller, _target, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([_caller, _target, ["isNotDragging", "isNotCarrying", "isNotSwimming", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Get hitpoint groups if available -_hitpointGroupConfig = configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(hitpointGroups); -_hitpointGroup = []; +private _hitpointGroupConfig = configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(hitpointGroups); +private _hitpointGroup = []; if (isArray _hitpointGroupConfig) then { - _hitPointClassname = _allHitPoints select _hitPointIndex; + private _hitPointClassname = _allHitPoints select _hitPointIndex; // Retrieve hitpoint subgroup if current hitpoint is main hitpoint of a group { @@ -37,7 +36,7 @@ if (isArray _hitpointGroupConfig) then { // Exit using found hitpoint group if this hitpoint is leader of any if (_masterHitpoint == _hitPointClassname) exitWith { { - _subHitIndex = _allHitPoints find _x; + private _subHitIndex = _allHitPoints find _x; if (_subHitIndex == -1) then { ERROR("Hitpoint Not Found"); } else { @@ -52,10 +51,10 @@ if (isArray _hitpointGroupConfig) then { _hitpointGroup pushBack _hitPointIndex; // Get post repair damage -_postRepairDamage = [_caller] call FUNC(getPostRepairDamage); +private _postRepairDamage = [_caller] call FUNC(getPostRepairDamage); // Return true if damage can be repaired on any hitpoint in the group, else false -_return = false; +private _return = false; { if ((_allHitPointDamages select _x) > _postRepairDamage) exitWith { _return = true; diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index 6027a34fd5..a54e2d3ce4 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -21,14 +21,12 @@ params ["_caller", "_target", "_hitPoint", "_className"]; TRACE_4("params",_caller,_target,_hitPoint,_className); -private ["_config", "_engineerRequired", "_items", "_return", "_condition", "_vehicleStateCondition", "_settingName", "_settingItemsArray"]; - -_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); if !(isClass _config) exitWith {false}; // or go for a default? // if(isEngineOn _target) exitWith {false}; // Ignore here so action shows, then exit and show warning when selected #3348 -_engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { +private _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { getNumber (_config >> "requiredEngineer"); } else { // Check for required class @@ -40,11 +38,11 @@ _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitWith {false}; //Items can be an array of required items or a string to a ACE_Setting array -_items = if (isArray (_config >> "items")) then { +private _items = if (isArray (_config >> "items")) then { getArray (_config >> "items"); } else { - _settingName = getText (_config >> "items"); - _settingItemsArray = getArray (configFile >> "ACE_Settings" >> _settingName >> "_values"); + private _settingName = getText (_config >> "items"); + private _settingItemsArray = getArray (configFile >> "ACE_Settings" >> _settingName >> "_values"); if ((isNil _settingName) || {(missionNamespace getVariable _settingName) >= (count _settingItemsArray)}) exitWith { ERROR("bad setting"); ["BAD"] }; @@ -52,9 +50,9 @@ _items = if (isArray (_config >> "items")) then { }; if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; -_return = true; +private _return = true; if (getText (_config >> "condition") != "") then { - _condition = getText (_config >> "condition"); + private _condition = getText (_config >> "condition"); if (isNil _condition) then { _condition = compile _condition; } else { @@ -69,7 +67,7 @@ if (getText (_config >> "condition") != "") then { if (!_return) exitWith {false}; -// _vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { +// private _vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { // missionNamespace getVariable [getText(_config >> "vehicleStateCondition"), 0] // } else { // getNumber(_config >> "vehicleStateCondition") diff --git a/addons/repair/functions/fnc_doFullRepair.sqf b/addons/repair/functions/fnc_doFullRepair.sqf index ed67a69e99..492ceb01a0 100644 --- a/addons/repair/functions/fnc_doFullRepair.sqf +++ b/addons/repair/functions/fnc_doFullRepair.sqf @@ -1,6 +1,6 @@ /* * Author: Glowbal - * Fully repairs vehicle + * Fully repairs vehicle. * * Arguments: * 0: Unit that does the repairing (not used) diff --git a/addons/repair/functions/fnc_getClaimObjects.sqf b/addons/repair/functions/fnc_getClaimObjects.sqf index c2311a467f..18b2e9f7ef 100644 --- a/addons/repair/functions/fnc_getClaimObjects.sqf +++ b/addons/repair/functions/fnc_getClaimObjects.sqf @@ -1,6 +1,6 @@ /* * Author: PabstMirror - * Returns array of required nearby repair objects (wheels/tracks) + * Returns array of required nearby repair objects (wheels/tracks). * * Arguments: * 0: Unit that does the repairing diff --git a/addons/repair/functions/fnc_getHitPointString.sqf b/addons/repair/functions/fnc_getHitPointString.sqf index 31e4ed400f..da039c34ff 100644 --- a/addons/repair/functions/fnc_getHitPointString.sqf +++ b/addons/repair/functions/fnc_getHitPointString.sqf @@ -21,12 +21,10 @@ params ["_hitPoint", "_textLocalized", "_textDefault", ["_trackArray", []]]; -private ["_track", "_trackNames", "_trackStrings", "_trackAmount", "_text", "_toFind", "_trackIndex", "_combinedString"]; - -_track = if (count _trackArray > 0) then {true} else {false}; -_trackNames = []; -_trackStrings = []; -_trackAmount = []; +private _track = (count _trackArray > 0); +private _trackNames = []; +private _trackStrings = []; +private _trackAmount = []; if (_track) then { _trackNames = _trackArray select 0; @@ -35,10 +33,10 @@ if (_track) then { }; // Prepare first part of the string from stringtable -_text = LSTRING(Hit); +private _text = LSTRING(Hit); // Remove "Hit" from hitpoint name if one exists -_toFind = if ((toLower _hitPoint) find "hit" == 0) then { +private _toFind = if ((toLower _hitPoint) find "hit" == 0) then { [_hitPoint, 3] call CBA_fnc_substr } else { _hitPoint @@ -48,7 +46,7 @@ _toFind = if ((toLower _hitPoint) find "hit" == 0) then { for "_i" from 0 to (count _hitPoint) do { if (_track) then { // Loop through already added hitpoints and save index - _trackIndex = -1; + private _trackIndex = -1; { if (_x == _toFind) exitWith { _trackIndex = _forEachIndex; @@ -65,7 +63,7 @@ for "_i" from 0 to (count _hitPoint) do { // Localize if localization found - _combinedString = _text + _toFind; + private _combinedString = _text + _toFind; if (isLocalized _combinedString) exitWith { _text = format [_textLocalized, localize _combinedString]; TRACE_1("Hitpoint localized",_toFind); diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf index 93f4883063..5b40710c19 100644 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -19,8 +19,6 @@ params ["_vehicle"]; TRACE_1("params",_vehicle); -private ["_bestDist", "_bestIndex", "_wheelBone", "_wheelBoneNameResized", "_wheelCenter", "_wheelCenterPos", "_wheelHitPoint", "_wheelHitPointSelection", "_wheelHitPointSelections", "_wheelHitPoints", "_wheelName", "_xDist", "_xPos"]; - // get the vehicles wheel config private _wheels = configFile >> "CfgVehicles" >> typeOf _vehicle >> "Wheels"; @@ -33,19 +31,19 @@ if !(isClass _wheels) exitWith {TRACE_1("No Wheels",_wheels); [[],[]]}; // get all wheels and read selections from config _wheels = "true" configClasses _wheels; -_wheelHitPoints = []; -_wheelHitPointSelections = []; +private _wheelHitPoints = []; +private _wheelHitPointSelections = []; { - _wheelName = configName _x; - _wheelCenter = getText (_x >> "center"); - _wheelBone = getText (_x >> "boneName"); - _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. + private _wheelName = configName _x; + private _wheelCenter = getText (_x >> "center"); + private _wheelBone = getText (_x >> "boneName"); + private _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); - _wheelHitPoint = ""; - _wheelHitPointSelection = ""; + private _wheelHitPoint = ""; + private _wheelHitPointSelection = ""; //Commy's orginal method { @@ -61,19 +59,19 @@ _wheelHitPointSelections = []; //Backup method, search for the closest hitpoint to the wheel's center selection pos. //Ref #2742 - RHS's HMMWV if (_wheelHitPoint == "") then { - _wheelCenterPos = _vehicle selectionPosition _wheelCenter; + private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; if (_wheelCenterPos isEqualTo [0,0,0]) exitWith {TRACE_1("no center?",_wheelCenter);}; - _bestDist = 99; - _bestIndex = -1; + private _bestDist = 99; + private _bestIndex = -1; { if (_x != "") then { //Filter out things that definitly aren't wheeels (#3759) if ((toLower (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; - _xPos = _vehicle selectionPosition _x; + private _xPos = _vehicle selectionPosition _x; if (_xPos isEqualTo [0,0,0]) exitWith {}; - _xDist = _wheelCenterPos distance _xPos; + private _xDist = _wheelCenterPos distance _xPos; if (_xDist < _bestDist) then { _bestIndex = _forEachIndex; _bestDist = _xDist; diff --git a/addons/repair/functions/fnc_hasItems.sqf b/addons/repair/functions/fnc_hasItems.sqf index 3af9316256..0b06be8d49 100644 --- a/addons/repair/functions/fnc_hasItems.sqf +++ b/addons/repair/functions/fnc_hasItems.sqf @@ -19,9 +19,7 @@ params ["_unit", "_items"]; TRACE_2("params",_unit,_items); -private ["_return"]; - -_return = true; +private _return = true; { if ((_x isEqualType []) && {({[_unit, _x] call EFUNC(common,hasItem)} count _x == 0)}) exitWith { _return = false; diff --git a/addons/repair/functions/fnc_isEngineer.sqf b/addons/repair/functions/fnc_isEngineer.sqf index d2ee71b913..92ce1091b0 100644 --- a/addons/repair/functions/fnc_isEngineer.sqf +++ b/addons/repair/functions/fnc_isEngineer.sqf @@ -19,8 +19,7 @@ params ["_unit", ["_engineerN", 1]]; TRACE_2("params",_unit,_engineerN); -private ["_class"]; -_class = _unit getVariable ["ACE_IsEngineer", _unit getUnitTrait "engineer"]; +private _class = _unit getVariable ["ACE_IsEngineer", _unit getUnitTrait "engineer"]; // This if statement is here for copmatability with the common variant of isEngineer, which requires a bool. // We cannot move this function to common because we require the GVAR(engineerSetting_Repair), which only makes sense to include in the repair module. diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf index b72d8a5985..c9aed130ba 100644 --- a/addons/repair/functions/fnc_isInRepairFacility.sqf +++ b/addons/repair/functions/fnc_isInRepairFacility.sqf @@ -18,13 +18,11 @@ params ["_object"]; TRACE_1("params",_object); -private ["_position","_objects","_isInBuilding","_repairFacility"]; +private _position = getPosASL _object; +private _isInBuilding = false; +private _repairFacility = []; -_position = getPosASL _object; -_isInBuilding = false; -_repairFacility = []; - -_objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position select 2)], _object modelToWorldVisual [0, 0, (_position select 2) +10], _object]); +private _objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position select 2)], _object modelToWorldVisual [0, 0, (_position select 2) +10], _object]); { if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitWith { _isInBuilding = true; diff --git a/addons/repair/functions/fnc_modifyInteraction.sqf b/addons/repair/functions/fnc_modifyInteraction.sqf index f1956ee384..5288d10211 100644 --- a/addons/repair/functions/fnc_modifyInteraction.sqf +++ b/addons/repair/functions/fnc_modifyInteraction.sqf @@ -1,6 +1,6 @@ /* * Author: PabstMirror - * Modifies the base interaction point for repair items to show it's current damage + * Modifies the base interaction point for repair items to show it's current damage. * * Arguments: * 0: Target @@ -12,7 +12,7 @@ * None * * Example: - * [cursorObject, player, [], []] call ace_repair_fnc_modifyInteraction; + * [cursorObject, ace_player, [], []] call ace_repair_fnc_modifyInteraction; * * Public: No */ diff --git a/addons/repair/functions/fnc_modifySelectionInteraction.sqf b/addons/repair/functions/fnc_modifySelectionInteraction.sqf new file mode 100644 index 0000000000..cf776a1831 --- /dev/null +++ b/addons/repair/functions/fnc_modifySelectionInteraction.sqf @@ -0,0 +1,32 @@ +/* + * Author: 654wak654 + * Modifies interaction color of vehicle selection to show it's current damage. + * + * Arguments: + * 0: Target + * 1: Player + * 2: Args + * 3: Action Data + * + * Return Value: + * None + * + * Example: + * [cursorObject, ace_player, [], []] call ace_repair_fnc_modifySelectionInteraction; + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target", "_player", "_args", "_actionData"]; +TRACE_4("params",_target,_player,_args,_actionData); + +// Interaction wrenches numbered 0..8, white to red. +// Convert damage to number (rounding up), so that even slight damage can bee seen + +private _fileName = format [ + QPATHTOF(ui\repair_%1_ca.paa), + ceil (linearConversion [0, 1, _target getHitPointDamage (_args select 0), 0, 8, true]) +]; + +_actionData set [2, _fileName]; diff --git a/addons/repair/functions/fnc_moduleAddSpareParts.sqf b/addons/repair/functions/fnc_moduleAddSpareParts.sqf index bc2502c0f4..5d24de86f0 100644 --- a/addons/repair/functions/fnc_moduleAddSpareParts.sqf +++ b/addons/repair/functions/fnc_moduleAddSpareParts.sqf @@ -20,10 +20,9 @@ params ["_logic"]; if (!isNull _logic) then { - private ["_list", "_part", "_amount"]; - _list = _logic getVariable ["List", ""]; - _part = _logic getVariable ["Part", 0]; - _amount = _logic getVariable ["Amount", 1]; + private _list = _logic getVariable ["List", ""]; + private _part = _logic getVariable ["Part", 0]; + private _amount = _logic getVariable ["Amount", 1]; // Parse list _list = [_list, true, true] call EFUNC(common,parseList); diff --git a/addons/repair/functions/fnc_moduleAssignEngineer.sqf b/addons/repair/functions/fnc_moduleAssignEngineer.sqf index d64573130c..fcdb08d4f1 100644 --- a/addons/repair/functions/fnc_moduleAssignEngineer.sqf +++ b/addons/repair/functions/fnc_moduleAssignEngineer.sqf @@ -20,9 +20,8 @@ params ["_logic"]; if (!isNull _logic) then { - private ["_list", "_setting"]; - _list = _logic getVariable ["EnableList", ""]; - _setting = _logic getVariable ["role", 0]; + private _list = _logic getVariable ["EnableList", ""]; + private _setting = _logic getVariable ["role", 0]; [_list, "ACE_IsEngineer", _setting, true] call EFUNC(common,assignObjectsInList); [synchronizedObjects _logic, "ACE_IsEngineer", _setting, true] call EFUNC(common,assignObjectsInList); diff --git a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf index 9f01a06afc..9f0b514f1d 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf @@ -20,9 +20,8 @@ params ["_logic"]; if (!isNull _logic) then { - private ["_list", "_setting"]; - _list = _logic getVariable ["EnableList", ""]; - _setting = _logic getVariable ["role", 0]; + private _list = _logic getVariable ["EnableList", ""]; + private _setting = _logic getVariable ["role", 0]; [_list, "ACE_isRepairFacility", _setting, true] call EFUNC(common,assignObjectsInList); [synchronizedObjects _logic, "ACE_isRepairFacility", _setting, true] call EFUNC(common,assignObjectsInList); diff --git a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf index f5df8d58e2..63b5e3756f 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf @@ -20,9 +20,8 @@ params ["_logic"]; if (!isNull _logic) then { - private ["_list", "_setting"]; - _list = _logic getVariable ["EnableList", ""]; - _setting = _logic getVariable ["role", 0]; + private _list = _logic getVariable ["EnableList", ""]; + private _setting = _logic getVariable ["role", 0]; [_list, "ACE_isRepairVehicle", _setting, true] call EFUNC(common,assignObjectsInList); [synchronizedObjects _logic, "ACE_isRepairVehicle", _setting, true] call EFUNC(common,assignObjectsInList); diff --git a/addons/repair/functions/fnc_moduleRepairSettings.sqf b/addons/repair/functions/fnc_moduleRepairSettings.sqf index cfd363e99f..4bbd505006 100644 --- a/addons/repair/functions/fnc_moduleRepairSettings.sqf +++ b/addons/repair/functions/fnc_moduleRepairSettings.sqf @@ -17,8 +17,6 @@ params ["_logic"]; -if (!isServer) exitWith {}; - [_logic, QGVAR(engineerSetting_Repair), "engineerSetting_Repair"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(engineerSetting_Wheel), "engineerSetting_Wheel"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(consumeItem_ToolKit), "consumeItem_ToolKit"] call EFUNC(common,readSettingFromModule); diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index 3ee6d4097f..aeaafb4f97 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -19,14 +19,12 @@ #include "script_component.hpp" params ["_caller", "_target", "_hitPoint", "_className"]; -TRACE_4("params",_calller,_target,_hitPoint,_className); +TRACE_4("params",_caller,_target,_hitPoint,_className); -private ["_callbackProgress", "_callerAnim", "_calller", "_condition", "_config", "_consumeItems", "_displayText", "_engineerRequired", "_iconDisplayed", "_items", "_repairTime", "_repairTimeConfig", "_return", "_usersOfItems", "_vehicleStateCondition", "_wpn", "_settingName", "_settingItemsArray", "_hitPointClassname"]; - -_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); if !(isClass _config) exitWith {false}; // or go for a default? -_engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { +private _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { getNumber (_config >> "requiredEngineer"); } else { // Check for required class @@ -46,11 +44,11 @@ if ((isEngineOn _target) && {!GVAR(autoShutOffEngineWhenStartingRepair)}) exitWi }; //Items can be an array of required items or a string to a ACE_Setting array -_items = if (isArray (_config >> "items")) then { +private _items = if (isArray (_config >> "items")) then { getArray (_config >> "items"); } else { - _settingName = getText (_config >> "items"); - _settingItemsArray = getArray (configFile >> "ACE_Settings" >> _settingName >> "_values"); + private _settingName = getText (_config >> "items"); + private _settingItemsArray = getArray (configFile >> "ACE_Settings" >> _settingName >> "_values"); if ((isNil _settingName) || {(missionNamespace getVariable _settingName) >= (count _settingItemsArray)}) exitWith { ERROR("bad setting"); ["BAD"] }; @@ -58,9 +56,9 @@ _items = if (isArray (_config >> "items")) then { }; if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; -_return = true; +private _return = true; if (getText (_config >> "condition") != "") then { - _condition = getText (_config >> "condition"); + private _condition = getText (_config >> "condition"); if (isNil _condition) then { _condition = compile _condition; } else { @@ -74,7 +72,7 @@ if (getText (_config >> "condition") != "") then { }; if (!_return) exitWith {false}; -// _vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { +// private _vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { // missionNamespace getVariable [getText(_config >> "vehicleStateCondition"), 0] // } else { // getNumber(_config >> "vehicleStateCondition") @@ -123,7 +121,7 @@ if !(_return && alive _target) exitWith {false}; [_caller, _x, false] call EFUNC(common,claim); } forEach _claimObjectsAvailable; -_consumeItems = if (isNumber (_config >> "itemConsumed")) then { +private _consumeItems = if (isNumber (_config >> "itemConsumed")) then { getNumber (_config >> "itemConsumed"); } else { // Check for required class @@ -133,13 +131,13 @@ _consumeItems = if (isNumber (_config >> "itemConsumed")) then { 0; }; -_usersOfItems = []; +private _usersOfItems = []; if (_consumeItems > 0) then { _usersOfItems = ([_caller, _items] call FUNC(useItems)) select 1; }; // Parse the config for the progress callback -_callbackProgress = getText (_config >> "callbackProgress"); +private _callbackProgress = getText (_config >> "callbackProgress"); if (_callbackProgress == "") then { _callbackProgress = "true"; }; @@ -151,7 +149,7 @@ if (isNil _callbackProgress) then { // Player Animation -_callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE"); +private _callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE"); _caller setVariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller]; // Cannot use secondairy weapon for animation @@ -159,7 +157,7 @@ if (currentWeapon _caller == secondaryWeapon _caller) then { _caller selectWeapon (primaryWeapon _caller); }; -_wpn = ["non", "rfl", "pst"] select (1 + ([primaryWeapon _caller, handgunWeapon _caller] find (currentWeapon _caller))); +private _wpn = ["non", "rfl", "pst"] select (1 + ([primaryWeapon _caller, handgunWeapon _caller] find (currentWeapon _caller))); _callerAnim = [_callerAnim, "[wpn]", _wpn] call CBA_fnc_replace; if (vehicle _caller == _caller && {_callerAnim != ""}) then { if (primaryWeapon _caller == "") then { @@ -169,16 +167,21 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { _caller selectWeapon (primaryWeapon _caller); // unit always has a primary weapon here }; - if (stance _caller == "STAND") then { - _caller setVariable [QGVAR(repairPrevAnimCaller), "amovpknlmstpsraswrfldnon"]; - } else { - _caller setVariable [QGVAR(repairPrevAnimCaller), animationState _caller]; + if !(_caller call EFUNC(common,isSwimming)) then { + if (stance _caller == "STAND") then { + _caller setVariable [QGVAR(repairPrevAnimCaller), "amovpknlmstpsraswrfldnon"]; + } else { + _caller setVariable [QGVAR(repairPrevAnimCaller), animationState _caller]; + }; + [_caller, _callerAnim] call EFUNC(common,doAnimation); }; - [_caller, _callerAnim] call EFUNC(common,doAnimation); }; +private _soundPosition = AGLToASL (_caller modelToWorldVisual (_caller selectionPosition "RightHand")); +["Acts_carFixingWheel", _soundPosition, nil, 50] call EFUNC(common,playConfigSound3D); + // Get repair time -_repairTime = [ +private _repairTime = [ configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(repairTimes) >> configName _config, "number", -1 @@ -189,7 +192,7 @@ if (_repairTime < 0) then { getNumber (_config >> "repairingTime"); } else { if (isText (_config >> "repairingTime")) exitWith { - _repairTimeConfig = getText (_config >> "repairingTime"); + private _repairTimeConfig = getText (_config >> "repairingTime"); if (isNil _repairTimeConfig) then { _repairTimeConfig = compile _repairTimeConfig; } else { @@ -205,7 +208,7 @@ if (_repairTime < 0) then { }; // Find localized string -_hitPointClassname = if (_hitPoint isEqualType "") then { +private _hitPointClassname = if (_hitPoint isEqualType "") then { _hitPoint } else { ((getAllHitPointsDamage _target) select 0) select _hitPoint @@ -224,17 +227,17 @@ TRACE_4("display",_hitPoint,_hitPointClassname,_processText,_text); DFUNC(repair_failure), _text, _callbackProgress, - ["isNotOnLadder"] + ["isNotSwimming", "isNotOnLadder"] ] call EFUNC(common,progressBar); // Display Icon -_iconDisplayed = getText (_config >> "actionIconPath"); +private _iconDisplayed = getText (_config >> "actionIconPath"); if (_iconDisplayed != "") then { [QGVAR(repairActionIcon), true, _iconDisplayed, [1,1,1,1], getNumber(_config >> "actionIconDisplayTime")] call EFUNC(common,displayIcon); }; // handle display of text/hints -_displayText = ""; +private _displayText = ""; if (_target != _caller) then { _displayText = getText(_config >> "displayTextOther"); } else { diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index db58c94448..c433b29f92 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -26,17 +26,15 @@ params ["_args"]; _args params ["_caller", "_target","_selectionName","_className","","_usersOfItems", "_claimedObjects"]; TRACE_5("params",_caller,_target,_selectionName,_className,_usersOfItems); -private ["_config","_callback", "_usersOfItems", "_weaponSelect"]; - if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; -if (vehicle _caller == _caller) then { +if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -_weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); +private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); if (_weaponSelect != "") then { _caller selectWeapon _weaponSelect; } else { @@ -55,9 +53,9 @@ if (_weaponSelect != "") then { // Record specific callback -_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); -_callback = getText (_config >> "callbackFailure"); +private _callback = getText (_config >> "callbackFailure"); if (isNil _callback) then { _callback = compile _callback; } else { diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index 5196075735..c2fa40bfbb 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -26,17 +26,15 @@ params ["_args"]; _args params ["_caller", "_target","_selectionName","_className","","","_claimedObjects"]; TRACE_4("params",_caller,_target,_selectionName,_className); -private ["_config","_callback", "_weaponSelect"]; - if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; -if (vehicle _caller == _caller) then { +if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -_weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); +private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); if (_weaponSelect != "") then { _caller selectWeapon _weaponSelect; } else { @@ -50,9 +48,9 @@ if (_weaponSelect != "") then { } forEach _claimedObjects; // Record specific callback -_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); +private _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); -_callback = getText (_config >> "callbackSuccess"); +private _callback = getText (_config >> "callbackSuccess"); if (isNil _callback) then { _callback = compile _callback; } else { diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index 57c65d1407..771a1c9dce 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -1,12 +1,13 @@ /* * Author: commy2 * Set the hitpoint damage and change the structural damage acordingly, requires local vehicle. - * Handles the ace_repair_setVehicleHitPointDamage event + * Handles the ace_repair_setVehicleHitPointDamage event. * * Arguments: * 0: Local Vehicle to Damage * 1: Selected hitpoint INDEX * 2: Total Damage + * 3: Skip destruction effects * * Return Value: * None @@ -18,11 +19,9 @@ */ #include "script_component.hpp" -params ["_vehicle", "_hitPointIndex", "_hitPointDamage"]; +params ["_vehicle", "_hitPointIndex", "_hitPointDamage", ["_useEffects", true]]; TRACE_4("params",_vehicle,typeOf _vehicle,_hitPointIndex,_hitPointDamage); -private ["_damageNew", "_damageOld", "_hitPointDamageRepaired", "_hitPointDamageSumOld", "_realHitpointCount", "_selectionName"]; - // can't execute all commands if the vehicle isn't local. exit here. if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1", _vehicle);}; @@ -34,13 +33,13 @@ if ((_hitPointIndex < 0) || {_hitPointIndex >= (count _allHitPoints)}) exitWith // save structural damage and sum of hitpoint damages -_damageOld = damage _vehicle; +private _damageOld = damage _vehicle; -_realHitpointCount = 0; -_hitPointDamageSumOld = 0; -_hitPointDamageRepaired = 0; //positive for repairs : newSum = (oldSum - repaired) +private _realHitpointCount = 0; +private _hitPointDamageSumOld = 0; +private _hitPointDamageRepaired = 0; //positive for repairs : newSum = (oldSum - repaired) { - _selectionName = _allHitPointsSelections select _forEachIndex; + private _selectionName = _allHitPointsSelections select _forEachIndex; //Filter out all the bad hitpoints (HitPoint="" or no selection) if ((!isNil {_vehicle getHit _selectionName}) && {_x != ""}) then { _realHitpointCount = _realHitpointCount + 1; @@ -55,7 +54,7 @@ _hitPointDamageRepaired = 0; //positive for repairs : newSum = (oldSum - repaire } forEach _allHitPoints; // calculate new structural damage -_damageNew = (_hitPointDamageSumOld - _hitPointDamageRepaired) / _realHitpointCount; +private _damageNew = (_hitPointDamageSumOld - _hitPointDamageRepaired) / _realHitpointCount; if (_hitPointDamageSumOld > 0) then { _damageNew = _damageOld * ((_hitPointDamageSumOld - _hitPointDamageRepaired) / _hitPointDamageSumOld); @@ -63,14 +62,14 @@ if (_hitPointDamageSumOld > 0) then { TRACE_5("structuralDamage",_damageOld,_damageNew,_hitPointDamageRepaired,_hitPointDamageSumOld,_realHitpointCount); // set new structural damage value -_vehicle setDamage _damageNew; +_vehicle setDamage [_damageNew, _useEffects]; //Repair the hitpoint in the damages array: _allHitPointDamages set [_hitPointIndex, _hitPointDamage]; //Set the new damage for all hitpoints { - _vehicle setHitIndex [_forEachIndex, _x]; + _vehicle setHitIndex [_forEachIndex, _x, _useEffects]; } forEach _allHitPointDamages; // normalize hitpoints diff --git a/addons/repair/functions/fnc_useItems.sqf b/addons/repair/functions/fnc_useItems.sqf index 859115b68c..86b4400272 100644 --- a/addons/repair/functions/fnc_useItems.sqf +++ b/addons/repair/functions/fnc_useItems.sqf @@ -19,21 +19,19 @@ params ["_unit", "_items"]; TRACE_2("params",_unit,_items); -private ["_itemUsedInfo", "_itemsUsedBy"]; - -_itemsUsedBy = []; +private _itemsUsedBy = []; { // handle a one of type use item if (_x isEqualType []) then { { - _itemUsedInfo = [_unit, _x] call FUNC(useItem); + private _itemUsedInfo = [_unit, _x] call FUNC(useItem); if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; } forEach _x; }; // handle required item if (_x isEqualType "") then { - _itemUsedInfo = [_unit, _x] call FUNC(useItem); + private _itemUsedInfo = [_unit, _x] call FUNC(useItem); if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; }; } forEach _items; diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 7ab7788778..fb4a44ca7b 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -59,7 +59,7 @@ Cambiando rueda... Sostituendo la ruota... Remplacement de la roue... - タイヤを交換中・・・ + タイヤを交換しています・・・ 바퀴 교체중... 更换轮胎中... 更換輪胎中... @@ -74,7 +74,7 @@ Rueda cambiada Ruota sostituita Roue remplacée - タイヤを履き替え + タイヤを交換した 바퀴 교체됨 轮胎更换完毕 輪胎更換完畢 @@ -105,7 +105,7 @@ Quitando rueda... Rimuovendo la ruota... Démontage de la roue... - タイヤを外している・・ + タイヤを外しています・・・ 바퀴 제거중... 卸下轮胎中... 卸下輪胎中... @@ -150,7 +150,7 @@ Cambiando oruga... Sostituendo il cingolo... Remplacement de la chenille... - 履帯を交換中・・・ + 履帯を交換しています・・・ 궤도 교체중... 更换履带中... 更換履帶中... @@ -195,7 +195,7 @@ Quitando oruga... Rimuovendo il cingolo... Enlèvement de la chenille... - 履帯を外している・・・ + 履帯を外しています・・・ 궤도 제거중... 卸下履带中... 卸下履帶中... @@ -240,7 +240,7 @@ Reparando vehículo... Riparando il veicolo... Réparation du véhicule... - 車両を修理中・・・ + 車両を修理しています・・・ 차량 수리중... 维修载具中... 維修載具中... @@ -255,7 +255,7 @@ Lugares de reparación completa Luoghi Riparazione Completa Lieu de réparation complète - 完全修理をできる場所 + 完全修理できる場所 완전수리 구역 完整维修地点 完整維修地點 @@ -270,7 +270,7 @@ V které oblasti může být vozidlo plně opraveno? In quali luoghi è possibile riparare completamente un veicolo? Où peuvent être réparés complètement les véhicules ? - どのような場所で車両の完全な修理を出来るようにしますか? + どのような場所で車両の完全な修理を出来るようにしますか? 어느 구역에서 차량을 완전히 수리할 수 있게 합니까? 什么位置可以完整维修载具? 什麼位置可以完整維修載具? @@ -285,7 +285,7 @@ Permitir reparación completa Consenti Riparazione Completa Autoriser les réparations complètes. - 完全な修理をさせる + 完全修理を許可 완전 수리 활성화 允许完整维修 允許完整維修 @@ -300,7 +300,7 @@ Kdo může provést úplné opravy na vozidle? Chi può eseguire una riparazione completa su un veicolo? Qui peut faire une réparation complète ? - 誰が車両の完全な修理を出来るようにしますか? + 誰が車両の完全な修理を出来るようにしますか? 누가 완전 수리를 할 수 있습니까? 谁可以完整维修载具? 誰可以完整維修載具? @@ -330,7 +330,7 @@ Přidat náhradní díly do vozidla (vyžaduje úložný prostor)? Aggiungi parti di ricambio ai veicoli (richiede componente Cargo)? Ajouter des pièces de rechage aux véhicules ? (à besoin du système de cargaison) - 車両へ予備部品を追加しますか(カーゴ コンポーネントが必要)? + 車両へ予備部品を追加しますか(カーゴ コンポーネントが必要)? 차량에 예비 부품을 더합니까?(짐칸 요소 필요) 添加载具备件 (需相关货物组件)? 添加載具備件 (需相關貨物組件)? @@ -392,7 +392,7 @@ Riparando... javítása... Ремонтируем... - 修理中・・・ + 修理しています・・・ 수리중... 维修中... 維修中... @@ -408,7 +408,7 @@ Riparando %1... %1 javítása... Ремонтируем %1... - %1 を修理中・・・ + %1 を修理しています・・・ %1 수리중... 维修%1中... 維修%1中... @@ -439,7 +439,7 @@ Parte totalmente reparado Parte riparata completamente Pièce entièrement réparée - 部分的な完全な修理 + 完全に修理された部品 부분 완벽히 수리됨 完整维修部分 完整維修部分 @@ -577,7 +577,7 @@ Stabilizzatore Verticale Stabilisateur vertical Seitenleitwerk - 車両安定器 + 車両スタビライザ 수직 안정판 垂直稳定 垂直穩定 @@ -905,7 +905,7 @@ Ruota posteriore destra Jobb hátsó kerék Правое заднее колесо - 右の後 + 右の後輪 오른쪽 뒤쪽 바퀴 右后轮 右後輪 @@ -1031,7 +1031,7 @@ ERA ERA ДЗ - 爆発反応装甲 + ERA 폭발반응장갑 爆炸式反应装甲 爆炸式反應裝甲 @@ -1061,10 +1061,10 @@ Poskytuje rozsáhlý systém oprav pro všechny typy vozidel. Fornisce un sistema di riparazione per tutti i tipi di veicoli. Fournit un système de réparation pour tous les types de véhicules. - 車両の全種類に修理システムを適用しますか? + 車両の全種類に修理システムを適用しますか? 모든 차량에 대해 수리 시스템을 제공합니다. - 提供修复系统给所有载具. - 提供修復系統給所有載具. + 提供修复系统给所有载具 + 提供修復系統給所有載具 Anyone @@ -1098,12 +1098,15 @@ Advanced Engineer only + Instandsetzer Solo Geniere avanzato 上級工兵のみ 只有维修专精兵 只有維修專精兵 + Tylko zaawansowani mechanicy + 고급 정비공만 - + Allow Wheel Erlaube Radwechsel Wymiana kół @@ -1118,7 +1121,7 @@ 允许轮胎 允許輪胎 - + Who can remove and replace wheels? Wer kann Radwechsel durchführern? Kto może zdejmować i zmieniać koła? @@ -1128,12 +1131,12 @@ ¿Quién puede quitar y cambiar las ruedas? Chi può rimuovere e sostituire le ruote? Qui peut enlever et remplacer les roues ? - 誰がタイヤの除去と交換を出来るようにしますか? + 誰がタイヤの除去と交換を出来るようにしますか? 누가 바퀴를 제거 및 교체할 수 있습니까? 谁可维修轮胎? 誰可維修輪胎? - + Allow Repair Erlaube Reperatur Możliwość naprawy @@ -1148,7 +1151,7 @@ 允许维修 允許維修 - + Who can perform repair actions? Wer kann eine Reperatur durchführen? Kto może wykonywać czynności związane z naprawą pojazdów? @@ -1158,14 +1161,14 @@ ¿Quién puede realizar reparaciones? Chi può eseguire riparazioni? Qui peut réparer ? - 誰が修理を出来るようににしますか? + 誰が修理を出来るようににしますか? 누가 수리를 할 수 있습니까? 谁可以进行维修操作? 誰可以進行維修操作? Repair Threshold - Repariere Schweller + Reparaturlimit Próg naprawy Limite de reparo Лимит ремкомплекта @@ -1180,7 +1183,7 @@ What is the maximum damage that can be repaired with a toolkit? - Wie hoch ist der Schaden, der von einem Reperatursatz behoben werden kann? + Der maximale Schaden, der von einem Reperatursatz behoben werden kann? Jaki jest maksymalny poziom uszkodzeń jaki może zostać naprawiony przy pomocy narzędzi? Qual é o dano máximo que pode ser reparado com um kit de ferramentas? Какой максимальный урон можно починить с помощью ремкомплекта? @@ -1188,14 +1191,14 @@ Jaké maximální poškození může být opraveno pomocí opravárenské sady? Qual'è il danno massimo che può essere riparato con il Toolkit? Quel est le maximum de dommages réparable par une trousse à outils ? - ツールキットで修理できる、最大の損傷許容範囲を設定しますか? + ツールキットで修理できる、最大の損傷許容範囲を設定しますか? 어느정도의 피해까지 툴킷으로 수리가 가능합니까? 工具包可以修复的最大损坏值? 工具包可以修復的最大損壞值? Repair Threshold (Engineer) - Repariere Schweller (Pionier) + Reparaturlimit (Pionier) Próg naprawy (mechanik) Limite de reparo (Engenheiro) Лимит инженера @@ -1210,7 +1213,7 @@ What is the maximum damage that can be repaired by an engineer? - Wie hoch ist der Schaden, der von einem Pionier behoben werden kann? + Der maximale Schaden, der von einem Pionier behoben werden kann? Jaki jest maksymalny poziom uszkodzeń jaki może zostać naprawiony przez mechanika? Qual é o dano máximo que pode ser reparado com um engenheiro? Какой максимальный урон может починить инженер? @@ -1218,7 +1221,7 @@ Jaké maximální poškození může být opraveno pomoci inženýra? Qual'è il danno massimo che può essere riparato da un Geniere? Quel est le maximum de dommages qui peuvent être réparés par un ingénieur ? - 工兵が修理できる、最大の損傷許容範囲を設定しますか? + 工兵が修理できる、最大の損傷許容範囲を設定しますか? 정비공은 어느정도의 피해까지 수리할 수 있습니까? 工兵可以修复的最大损坏值? 工兵可以修復的最大損壞值? @@ -1248,7 +1251,7 @@ Má být odstraněna sada nástroju po použití? Il Toolkit dev'essere rimosso dopo l'uso? La trousse à outils devrait-elle être enlevée après usage ? - ツールキットを使うと削除しますか? + ツールキットを使うと削除しますか? 툴킷을 사용하면 제거를 합니까? 要在使用后删除工具包吗? 要在使用後刪除工具包嗎? @@ -1263,7 +1266,7 @@ En cualquier sitio Ovunque N'importe où - だれでも + どこでも 어디서나 任何地点 任何地點 @@ -1355,8 +1358,8 @@ Liste des noms d'unités qui seront considérées ingénieurs. Séparé par des virgules 一覧に記載されたユニット名を、工兵として指定します。コンマで複数を指定できます。 목록내 보직이름은 정비공으로 분류됩니다. 쉼표로 구분합니다. - 工兵名单, 把单位名称输入在这边即可定义其为工兵. 每个单位使用逗号以做区隔. - 工兵名單, 把單位名稱輸入在這邊即可定義其為工兵. 每個單位使用逗號以做區隔. + 工兵名单,把单位名称输入在这边即可定义其为工兵。每个单位使用逗号以做区隔。 + 工兵名單,把單位名稱輸入在這邊即可定義其為工兵。每個單位使用逗號以做區隔。 Is Engineer @@ -1398,7 +1401,7 @@ Ningún Nessuna Aucun - 工兵 + なし 없음 @@ -1413,7 +1416,7 @@ Ingeniero Geniere Ingénieur - 専門兵 + 工兵 정비공 工兵 工兵 @@ -1421,10 +1424,13 @@ Adv. Engineer + Instandsetzer Adv. Geniere 上級工兵 专精 專精 + Zaaw. mechanik + 고급 정비공 Assign one or multiple units as an engineer @@ -1483,8 +1489,8 @@ Liste de véhicules qui seront considérés comme véhicules de réparation. Séparé par des virgules. 一覧に記載されたユニット名を、修理車両として指定します。コンマで複数を指定できます。 목록내 차량은 정비 차량으로 분류됩니다. 쉼표로 구분합니다. - 载具名单, 把载具名称输入在这边即可定义其为维修载具. 每个载具使用逗号以做区隔. - 載具名單, 把載具名稱輸入在這邊即可定義其為維修載具. 每個載具使用逗號以做區隔. + 载具名单,把载具名称输入在这边即可定义其为维修载具。每个载具使用逗号以做区隔。 + 載具名單,把載具名稱輸入在這邊即可定義其為維修載具。每個載具使用逗號以做區隔。 Is Repair Vehicle @@ -1511,7 +1517,7 @@ Je vozidlo klasifikováno jako opravárenské? Il veicolo è classificato dome veicolo riparazioni? Le véhicule est-il considéré comme un véhicule de réparation ? - 車両を修理車両と指定しますか? + 車両を修理車両と指定しますか? 이 차량을 정비 차량으로 분류합니까? 此载具是维修载具吗? 此載具是維修載具嗎? @@ -1573,8 +1579,8 @@ Liste des objets considérés comme installations de réparation. Séparé par des virgules 一覧に記載されたユニット名を、修理施設として指定します。コンマで複数を指定できます。 목록내 시설은 정비 시설으로 분류됩니다. 쉼표로 구분합니다. - 设施名单, 把设施名称输入在这边即可定义其为维修设施. 每个设施使用逗号以做区隔. - 設施名單, 把設施名稱輸入在這邊即可定義其為維修設施. 每個設施使用逗號以做區隔. + 设施名单,把设施名称输入在这边即可定义其为维修设施。每个设施使用逗号以做区隔。 + 設施名單,把設施名稱輸入在這邊即可定義其為維修設施。每個設施使用逗號以做區隔。 Is Repair Facility @@ -1601,7 +1607,7 @@ Je objekt klasifikován jako opravárenské zařízení? L'oggetto è classificato come struttura riparazioni? L'objet est-il considéré comme une installation de réparation ? - オブジェクトを修理施設として指定しますか? + オブジェクトを修理施設として指定しますか? 이 시설을 정비 시설로 분류합니까? 此设施是维修设施吗? 此設施是維修設施嗎? @@ -1678,8 +1684,8 @@ Liste des objets qui recevront des pièces de réparation en plus. Séparé par des virgules 一覧に追加されたオブジェクトへ予備部品を与えます。コンマで複数を指定できます。 목록내 물체는 예비 부품을 받습니다, 쉼표로 구분합니다. - 添加备件到名单的载具上. 每个载具使用逗号以做区隔. - 添加備件到名單的載具上. 每個載具使用逗號以做區隔. + 添加备件到名单的载具上。每个载具使用逗号以做区隔。 + 添加備件到名單的載具上。每個載具使用逗號以做區隔。 Part @@ -1766,7 +1772,7 @@ Položka vyžaduje odstraněná/vyměněná kola Oggetti richiesti per riparare/rimuovere ruote Items exigés pour enlever/remplacer les roues - タイヤの除去と交換にアイテムを必要としますか? + タイヤの除去と交換にアイテムを必要としますか? 바퀴를 제거/교체하는데 필요한 물건 需要特定物品来移除/更换车轮 需要特定物品來移除/更換車輪 @@ -1786,5 +1792,29 @@ 引擎必须先关闭才能开始进行维修 引擎必須先關閉才能開始進行維修 + + Spare Tracks + Ersatzketten + 予備履帯 + Cingoli di Scorta + + + Number of spare tracks in cargo. + Anzahl der Ersatzketten im Laderaum. + カーゴ内にある予備履帯の数を指定します。 + Numero dei cingoli di scorta nel cargo. + + + Spare Wheels + Ersatzreifen + 予備タイヤ + Ruote di Scorta + + + Number of spare wheels in cargo. + Anzahl der Ersatzreifen im Laderaum. + カーゴ内にある予備タイヤの数を指定します。 + Numero delle ruote di scorta nel cargo. + diff --git a/addons/repair/ui/repair_0_ca.paa b/addons/repair/ui/repair_0_ca.paa new file mode 100644 index 0000000000..edb6c3681d Binary files /dev/null and b/addons/repair/ui/repair_0_ca.paa differ diff --git a/addons/repair/ui/repair_1_ca.paa b/addons/repair/ui/repair_1_ca.paa new file mode 100644 index 0000000000..bb6d85eca9 Binary files /dev/null and b/addons/repair/ui/repair_1_ca.paa differ diff --git a/addons/repair/ui/repair_2_ca.paa b/addons/repair/ui/repair_2_ca.paa new file mode 100644 index 0000000000..e5ed37905a Binary files /dev/null and b/addons/repair/ui/repair_2_ca.paa differ diff --git a/addons/repair/ui/repair_3_ca.paa b/addons/repair/ui/repair_3_ca.paa new file mode 100644 index 0000000000..24940192f4 Binary files /dev/null and b/addons/repair/ui/repair_3_ca.paa differ diff --git a/addons/repair/ui/repair_4_ca.paa b/addons/repair/ui/repair_4_ca.paa new file mode 100644 index 0000000000..bdf36fd572 Binary files /dev/null and b/addons/repair/ui/repair_4_ca.paa differ diff --git a/addons/repair/ui/repair_5_ca.paa b/addons/repair/ui/repair_5_ca.paa new file mode 100644 index 0000000000..cdabf0f8bf Binary files /dev/null and b/addons/repair/ui/repair_5_ca.paa differ diff --git a/addons/repair/ui/repair_6_ca.paa b/addons/repair/ui/repair_6_ca.paa new file mode 100644 index 0000000000..c1716ba16d Binary files /dev/null and b/addons/repair/ui/repair_6_ca.paa differ diff --git a/addons/repair/ui/repair_7_ca.paa b/addons/repair/ui/repair_7_ca.paa new file mode 100644 index 0000000000..4cf28c97e4 Binary files /dev/null and b/addons/repair/ui/repair_7_ca.paa differ diff --git a/addons/repair/ui/repair_8_ca.paa b/addons/repair/ui/repair_8_ca.paa new file mode 100644 index 0000000000..1db3809543 Binary files /dev/null and b/addons/repair/ui/repair_8_ca.paa differ diff --git a/addons/respawn/ACE_Settings.hpp b/addons/respawn/ACE_Settings.hpp index 7f0c4f9d96..d9dd41134e 100644 --- a/addons/respawn/ACE_Settings.hpp +++ b/addons/respawn/ACE_Settings.hpp @@ -1,19 +1,24 @@ class ACE_Settings { class GVAR(savePreDeathGear) { + category = CSTRING(DisplayName); displayName = CSTRING(SavePreDeathGear_DisplayName); description = CSTRING(SavePreDeathGear_Description); value = 0; typeName = "BOOL"; }; class GVAR(removeDeadBodiesDisconnected) { + category = CSTRING(DisplayName); displayName = CSTRING(RemoveDeadBodiesDisconnected_DisplayName); description = CSTRING(RemoveDeadBodiesDisconnected_Description); value = 1; typeName = "BOOL"; }; - class GVAR(bodyRemoveTimer) { - value = 0; - typeName = "SCALAR"; - }; + // Not used anywhere??? + // class GVAR(bodyRemoveTimer) { + // category = CSTRING(DisplayName); + // displayName = CSTRING(DeadBodyRemoveTimer); + // value = 0; + // typeName = "SCALAR"; + // }; }; diff --git a/addons/respawn/CfgVehicles.hpp b/addons/respawn/CfgVehicles.hpp index 103fab0537..847b32fe84 100644 --- a/addons/respawn/CfgVehicles.hpp +++ b/addons/respawn/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CBA_Extended_EventHandlers; class CfgVehicles { @@ -8,8 +7,8 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(module); - scope = 2; - isGlobal = 0; + scope = 1; + isGlobal = 1; icon = QPATHTOF(UI\Icon_Module_Respawn_ca.paa); class Arguments { @@ -71,6 +70,7 @@ class CfgVehicles { displayName = CSTRING(Rallypoint_MoveRallypoint); condition = QUOTE([ARR_2(_player, side group _player)] call FUNC(canMoveRallypoint)); statement = QUOTE([ARR_2(_player, side group _player)] call FUNC(moveRallypoint)); + exceptions[] = {"isNotSwimming"}; showDisabled = 0; priority = -0.5; }; @@ -110,6 +110,7 @@ class CfgVehicles { distance = 4; condition = QUOTE(side group _player == west); statement = QUOTE([ARR_3(_player,side group _player,'ACE_Rallypoint_West')] call FUNC(teleportToRallypoint)); + exceptions[] = {"isNotSwimming"}; position = "[-0.05,-0.35,-2.6]"; showDisabled = 1; priority = 1; @@ -132,6 +133,7 @@ class CfgVehicles { distance = 4; condition = QUOTE(side group _player == east); statement = QUOTE([ARR_3(_player,side group _player,'ACE_Rallypoint_East')] call FUNC(teleportToRallypoint)); + exceptions[] = {"isNotSwimming"}; position = "[-0.05,-0.35,-2.6]"; showDisabled = 1; priority = 1; @@ -154,6 +156,7 @@ class CfgVehicles { distance = 4; condition = QUOTE(side group _player == independent); statement = QUOTE([ARR_3(_player,side group _player,'ACE_Rallypoint_Independent')] call FUNC(teleportToRallypoint)); + exceptions[] = {"isNotSwimming"}; position = "[-0.05,-0.35,-2.6]"; showDisabled = 1; priority = 1; @@ -177,6 +180,7 @@ class CfgVehicles { distance = 4; condition = QUOTE(side group _player == west); statement = QUOTE([ARR_3(_player,side group _player,'ACE_Rallypoint_West_Base')] call FUNC(teleportToRallypoint)); + exceptions[] = {"isNotSwimming"}; position = "[-0.05,-0.35,-2.6]"; showDisabled = 1; priority = 1; @@ -199,6 +203,7 @@ class CfgVehicles { distance = 4; condition = QUOTE(side group _player == east); statement = QUOTE([ARR_3(_player,side group _player,'ACE_Rallypoint_East_Base')] call FUNC(teleportToRallypoint)); + exceptions[] = {"isNotSwimming"}; position = "[-0.05,-0.35,-2.6]"; showDisabled = 1; priority = 1; @@ -221,6 +226,7 @@ class CfgVehicles { distance = 4; condition = QUOTE(side group _player == independent); statement = QUOTE([ARR_3(_player,side group _player,'ACE_Rallypoint_Independent_Base')] call FUNC(teleportToRallypoint)); + exceptions[] = {"isNotSwimming"}; position = "[-0.05,-0.35,-2.6]"; showDisabled = 1; priority = 1; diff --git a/addons/respawn/functions/fnc_handleInitPostServer.sqf b/addons/respawn/functions/fnc_handleInitPostServer.sqf index 107fbe444b..9f43ed0445 100644 --- a/addons/respawn/functions/fnc_handleInitPostServer.sqf +++ b/addons/respawn/functions/fnc_handleInitPostServer.sqf @@ -18,11 +18,9 @@ params ["_unit"]; -private ["_groupUnit", "_rallypoint", "_leaderVarName"]; +private _groupUnit = group _unit; // _group is a reserved veriable and shouldn't be used -_groupUnit = group _unit; // _group is a reserved veriable and shouldn't be used - -_rallypoint = [ +private _rallypoint = [ objNull, missionNamespace getVariable ["ACE_Rallypoint_West", objNull], missionNamespace getVariable ["ACE_Rallypoint_East", objNull], @@ -33,7 +31,7 @@ _rallypoint = [ if (isNull _rallypoint) exitWith {}; // find leader -_leaderVarName = _groupUnit getVariable [QGVAR(leaderVarName), ""]; +private _leaderVarName = _groupUnit getVariable [QGVAR(leaderVarName), ""]; // exit if group already has a playable slot assigned as rallypoint leader if (_leaderVarName != "") exitWith { diff --git a/addons/respawn/functions/fnc_moveRallypoint.sqf b/addons/respawn/functions/fnc_moveRallypoint.sqf index 353d90e56a..3ee1f7fbdb 100644 --- a/addons/respawn/functions/fnc_moveRallypoint.sqf +++ b/addons/respawn/functions/fnc_moveRallypoint.sqf @@ -18,9 +18,7 @@ params ["_unit", "_side"]; -private ["_rallypoint", "_position"]; - -_rallypoint = [ +private _rallypoint = [ objNull, missionNamespace getVariable ["ACE_Rallypoint_West", objNull], missionNamespace getVariable ["ACE_Rallypoint_East", objNull], @@ -31,7 +29,7 @@ TRACE_3("moving rally",_unit,_rallypoint,typeOf _rallypoint); if (isNull _rallypoint) exitWith {}; -_position = getPosATL _unit; +private _position = getPosATL _unit; _position = _position findEmptyPosition [0, 2, typeOf _rallypoint]; if (_position isEqualTo []) then {_position = getPosATL _unit}; diff --git a/addons/respawn/functions/fnc_restoreGear.sqf b/addons/respawn/functions/fnc_restoreGear.sqf index 1d234f16be..64b7437d15 100644 --- a/addons/respawn/functions/fnc_restoreGear.sqf +++ b/addons/respawn/functions/fnc_restoreGear.sqf @@ -17,9 +17,16 @@ #include "script_component.hpp" params ["_unit", "_allGear", "_activeWeaponAndMuzzle"]; +TRACE_3("restoreGear",_unit, count _allGear, _activeWeaponAndMuzzle); // restore all gear if (!isNil "_allGear") then { + _allGear params ["_primaryWeaponArray"]; + if ((_primaryWeaponArray param [0, ""]) == "ACE_FakePrimaryWeapon") then { + TRACE_1("Ignoring fake gun",_primaryWeaponArray); + _allGear set [0, []]; + _activeWeaponAndMuzzle = nil; + }; _unit setUnitLoadout _allGear; }; diff --git a/addons/respawn/functions/fnc_updateRallypoint.sqf b/addons/respawn/functions/fnc_updateRallypoint.sqf index 8b34f87019..4a71f4284e 100644 --- a/addons/respawn/functions/fnc_updateRallypoint.sqf +++ b/addons/respawn/functions/fnc_updateRallypoint.sqf @@ -21,10 +21,8 @@ params ["_rallypoint", "_side", "_position"]; if (!hasInterface) exitWith {}; -private ["_marker", "_markerDate"]; - -_marker = _rallypoint getVariable [QGVAR(marker), ""]; -_markerDate = _rallypoint getVariable [QGVAR(markerDate), ""]; +private _marker = _rallypoint getVariable [QGVAR(marker), ""]; +private _markerDate = _rallypoint getVariable [QGVAR(markerDate), ""]; _marker setMarkerPosLocal _position; _marker setMarkerTextLocal _markerDate; diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index d298ef804a..47a9f7b756 100644 --- a/addons/respawn/stringtable.xml +++ b/addons/respawn/stringtable.xml @@ -1,6 +1,13 @@ - + + + Respawn + Riapparizione + 重生 + 重生 + リスポン + Deploy in 5 seconds... Déploiement dans 5 secondes... @@ -108,10 +115,10 @@ Gyülekezőpont, Nyugat (Bázis) Rallypoint Západ (Základna) Ponto de encontro Oeste (Base) - ラリーポイント ウエスト (ベース) - 서쪽 집결지 (기지) + ラリーポイント 同盟軍 (ベース) 蓝方集合点 (基地) 藍方集合點 (基地) + 청군 집결지 (기지) Rallypoint East (Base) @@ -124,10 +131,10 @@ Gyülekezőpont, Kelet (Bázis) Ralllypoint Východ (Základna) Ponto de encontro Lest (Base) - ラリーポイント イースト (ベース) - 동쪽 집결지 (기지) + ラリーポイント OPFOR軍 (ベース) 红方集合点 (基地) 紅方集合點 (基地) + 대항군 집결지 (기지) Rallypoint Independent (Base) @@ -140,10 +147,10 @@ Gyülekezőpont, Független (Bázis) Rallypoint Nezávislý (Základna) Ponto de encontro Independente (Base) - ラリーポイント インデペンデント (ベース) - 독립 집결지 (기지) + ラリーポイント 独立軍 (ベース) 独立方集合点 (基地) 獨立方集合點 (基地) + 독립군 집결지 (기지) Rallypoint West @@ -156,10 +163,10 @@ Gyülekezőpont, Nyugat Rallypoint Západ Ponto de encontro Oeste - ラリーポイント ウエスト - 서쪽 집결지 + ラリーポイント 同盟軍 蓝方集合点 藍方集合點 + 청군 집결지 Rallypoint East @@ -172,10 +179,10 @@ Gyülekezőpont, Kelet Rallypoint Východ Ponto de encontro Leste - ラリーポイント イースト - 동쪽 집결지 + ラリーポイント OPFOR軍 红方集合点 紅方集合點 + 대항군 집결지 Rallypoint Independent @@ -188,10 +195,10 @@ Gyülekezőpont, Független Rallypoint Nezávislý Ponto de encontro Independente - ラリーポイント インデペンデント - 독립 집결지 + ラリーポイント 独立軍 独立方集合点 獨立方集合點 + 독립군 집결지 Respawn System @@ -220,7 +227,7 @@ Felszerelés elmentése? Сохранять снаряжение? Salva Equipaggiamento? - 装備を保存? + 装備を保存? 장비를 저장합니까? 储存装备? 儲存裝備? @@ -236,7 +243,7 @@ Az egység halála előtti felszerelésével való respawnolása? Возрождать солдата с тем же снаряжением, которое было на нем при смерти? Respawna con l'equipaggiamento che il soldato aveva appena prima di morire? - ユニットが死ぬ前に持っていた装備でリスポンしますか? + ユニットが死ぬ前に持っていた装備でリスポンしますか? 죽기 전에 가지고 있던 장비로 재배치합니까? 是否在重生时载入死亡前的装备? 是否在重生時載入死亡前的裝備? @@ -252,7 +259,7 @@ Holttestek eltávolítása? Удалять трупы? Rimuovi corpi? - 死体を削除? + 死体を削除? 시체를 제거합니까? 删除尸体? 刪除屍體? @@ -268,11 +275,18 @@ Játékosi testek eltávolítása távozás után? Удалять трупы игроков после дисконнекта? Rimuovi i corpi dei giocatori quando si disconnettono? - 切断後はプレイヤーの死体を削除しますか? + 切断後はプレイヤーの死体を削除しますか? 접속이 끊긴 플레이어의 시체를 제거합니까? 要删除已离线的玩家尸体吗? 要刪除已離線的玩家屍體嗎? + + Body remove timer + Timer rimozione corpo + 屍體移除計時器 + 尸体移除计时器 + 死体削除タイマー + This module enables you to configure ACE functionality specific to respawns. Moduł ten pozwala dostosować ustawienia odrodzenia (respawnu). @@ -283,10 +297,10 @@ Ce module permet de régler les options de Respawn Questo modulo ti permette di configurare le funzionalità ACE specifiche dei respawn. Este módulo permite configurar parámetros relacionados con la reaparición - あなたが設定した ACE 機能をリスポンへ設定できます。 + このモジュールを有効化するとリスポンへ ACE 機能を設定できます。 이 모듈은 ACE 재배치의 자세한 설정을 변결할 수 있게 해줍니다. - 该模块使您可以设定ACE的重生功能. - 該模塊使您可以設定ACE的重生功能. + 该模块使您可以设定ACE的重生功能 + 該模塊使您可以設定ACE的重生功能 Friendly Fire Messages @@ -316,8 +330,8 @@ El usar este módulo, todas las muertes por fuego amigo serán indicadas en el chat. もし友軍誤射による死者が出た場合は、チャットにてその旨を表示します。 이 모듈은 미션 중 아군사격으로 인한 사망자 발생시 채팅창에 메세지를 표시해줍니다. - 摆放此模块后, 当有发生友军误击致死的事件, 会显示提示讯息在聊天视窗中. - 擺放此模塊後, 當有發生友軍誤擊致死的事件, 會顯示提示訊息在聊天視窗中. + 摆放此模块后,当有发生友军误击致死的事件,会显示提示讯息在聊天视窗中。 + 擺放此模塊後,當有發生友軍誤擊致死的事件,會顯示提示訊息在聊天視窗中。 Rallypoint System @@ -347,8 +361,8 @@ Ce module vous permet d'utiliser les "rally points" auxquels vous pouvez vous téléporter rapidement depuis un drapeau à la base. Il nécessite le placement d'objets spéciaux sur la carte - base et drapeau, disponibles dans la catégorie Vide -> ACE Respawn. ミッションでベースから素早く移動できるラリーポイントを使えるようにします。ゲーム内に専用オブジェクトとなるベースとフラッグを設置している必要があります。両オブジェクトは Empty 下の ACE リスポンから設置できます。 이 모듈은 미션 중에 기지 깃발에서 집결지로 빠르게 텔레포트 시켜주는 역활을 합니다. 지도 상에 기지 및 깃발이 필요합니다. 두 가지 모두 Empty->ACE Respawn 카테고리에서 찾을 수 있습니다. - 摆放此模块后, 你将能在任务中布署集合点, 使你可以快速往返基地与前线. 要使用本功能, 请记得放上空物件->ACE 重生里面的基地与旗帜. - 擺放此模塊後, 你將能在任務中佈署集合點, 使你可以快速往返基地與前線. 要使用本功能, 請記得放上空物件->ACE 重生裡面的基地與旗幟. + 摆放此模块后,你将能在任务中布署集合点,使你可以快速往返基地与前线。要使用本功能,请记得放上空物件->ACE 重生里面的基地与旗帜。 + 擺放此模塊後,你將能在任務中佈署集合點,使你可以快速往返基地與前線。要使用本功能,請記得放上空物件->ACE 重生裡面的基地與旗幟。 Move Rallypoint diff --git a/addons/safemode/XEH_postInit.sqf b/addons/safemode/XEH_postInit.sqf index 42f9dc3dd5..81c1521c92 100644 --- a/addons/safemode/XEH_postInit.sqf +++ b/addons/safemode/XEH_postInit.sqf @@ -11,7 +11,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Weapons", QGVAR(safeMode), localize LSTRING(SafeMode), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if !([ACE_player] call CBA_fnc_canUseWeapon && {currentWeapon ACE_player != binocular ACE_player} && {currentWeapon ACE_player != ""}) exitWith {false}; diff --git a/addons/safemode/functions/fnc_lockSafety.sqf b/addons/safemode/functions/fnc_lockSafety.sqf index 2675068e94..927b5c5d96 100644 --- a/addons/safemode/functions/fnc_lockSafety.sqf +++ b/addons/safemode/functions/fnc_lockSafety.sqf @@ -22,9 +22,7 @@ if (inputAction "nextWeapon" > 0) exitWith {}; params ["_unit", "_weapon", "_muzzle"]; -private ["_safedWeapons", "_picture"]; - -_safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; +private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; if (_weapon in _safedWeapons) exitWith { _this call FUNC(unlockSafety); @@ -69,5 +67,5 @@ if (_muzzle isEqualType "") then { [_unit, _weapon, _muzzle] call FUNC(playChangeFiremodeSound); // show info box -_picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); +private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); [localize LSTRING(PutOnSafety), _picture] call EFUNC(common,displayTextPicture); diff --git a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf index 5da4aeb672..50998d93fb 100644 --- a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf @@ -18,16 +18,14 @@ params ["_unit", "_weapon"]; -private ["_sound", "_position"]; - -_sound = getArray (configFile >> "CfgWeapons" >> _weapon >> "changeFiremodeSound"); +private _sound = getArray (configFile >> "CfgWeapons" >> _weapon >> "changeFiremodeSound"); if (_sound isEqualTo []) exitWith { playSound "ACE_Sound_Click"; }; // get position where to play the sound (position of the weapon) -_position = AGLToASL (_unit modelToWorldVisual (_unit selectionPosition "RightHand")); +private _position = AGLToASL (_unit modelToWorldVisual (_unit selectionPosition "RightHand")); _sound params ["_filename", ["_volume", 1], ["_soundPitch", 1], ["_distance", 0]]; diff --git a/addons/safemode/functions/fnc_unlockSafety.sqf b/addons/safemode/functions/fnc_unlockSafety.sqf index da93bfa671..58ecba5189 100644 --- a/addons/safemode/functions/fnc_unlockSafety.sqf +++ b/addons/safemode/functions/fnc_unlockSafety.sqf @@ -19,9 +19,7 @@ params ["_unit", "_weapon", "_muzzle"]; -private ["_safedWeapons", "_picture"]; - -_safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; +private _safedWeapons = _unit getVariable [QGVAR(safedWeapons), []]; _safedWeapons deleteAt (_safedWeapons find _weapon); _unit setVariable [QGVAR(safedWeapons), _safedWeapons]; @@ -36,10 +34,8 @@ _unit selectWeapon _muzzle; if (inputAction "nextWeapon" > 0) then { // switch to the last mode to roll over to first after the default nextWeapon action - private ["_modes", "_mode", "_index"]; - // get weapon modes - _modes = []; + private _modes = []; { if (getNumber (configFile >> "CfgWeapons" >> _weapon >> _x >> "showToPlayer") == 1) then { _modes pushBack _x; @@ -51,10 +47,10 @@ if (inputAction "nextWeapon" > 0) then { } count getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); // select last mode - _mode = _modes select (count _modes - 1); + private _mode = _modes select (count _modes - 1); // switch to last mode - _index = 0; + private _index = 0; while { _index < 299 && {currentMuzzle _unit != _weapon || {currentWeaponMode _unit != _mode}} } do { @@ -70,5 +66,5 @@ if (inputAction "nextWeapon" > 0) then { [true] call FUNC(setSafeModeVisual); // show info box -_picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); +private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); [localize LSTRING(TookOffSafety), _picture] call EFUNC(common,displayTextPicture); diff --git a/addons/safemode/stringtable.xml b/addons/safemode/stringtable.xml index fa9b951908..2e259bc9d3 100644 --- a/addons/safemode/stringtable.xml +++ b/addons/safemode/stringtable.xml @@ -40,7 +40,7 @@ Zabezpieczono broń Zbraň zajistěna Biztonsági kapcsoló helyretolása - Поставить на предохранитель + Поставлено на предохранитель Sécurité mise Sicura inserita Colocar Segurança @@ -56,7 +56,7 @@ Odbezpieczono broń Zbraň odjištěna Biztonságos mód megszüntetve - Снят с предохранителя + Снято с предохранителя Sécurité enlevée Sicura tolta Tirou Segurança diff --git a/addons/sandbag/CfgVehicles.hpp b/addons/sandbag/CfgVehicles.hpp index df18b42c06..aebbef5be7 100644 --- a/addons/sandbag/CfgVehicles.hpp +++ b/addons/sandbag/CfgVehicles.hpp @@ -1,5 +1,5 @@ -class CBA_Extended_EventHandlers; +class CBA_Extended_EventHandlers_base; class CfgVehicles { class Man; @@ -25,6 +25,9 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(sandbagEmpty_displayName); vehicleClass = "Items"; + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; + editorPreview = QPATHTOF(data\preview_sandbag.jpg); class TransportItems { MACRO_ADDITEM(ACE_Sandbag_empty,1); }; @@ -47,7 +50,7 @@ class CfgVehicles { class ThingX; class ACE_SandbagObject: ThingX { class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; + class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers_base {}; }; author = ECSTRING(common,ACETeam); @@ -79,7 +82,7 @@ class CfgVehicles { class ACE_MainActions { selection = ""; distance = 5; - condition = "true"; + condition = "(true)"; class ACE_PickUp { selection = ""; @@ -94,6 +97,10 @@ class CfgVehicles { }; }; }; + + editorCategory = "EdCat_Supplies"; + editorSubcategory = QEGVAR(main,subcategory); + editorPreview = QPATHTOF(data\preview_sandbag.jpg); }; class ACE_SandbagObject_NoGeo: ACE_SandbagObject { diff --git a/addons/sandbag/CfgWeapons.hpp b/addons/sandbag/CfgWeapons.hpp index 6a5fe29b79..72336e8bbf 100644 --- a/addons/sandbag/CfgWeapons.hpp +++ b/addons/sandbag/CfgWeapons.hpp @@ -1,7 +1,7 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_Sandbag_empty: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -10,7 +10,7 @@ class CfgWeapons { model = QPATHTOF(data\ace_sandbag_m.p3d); picture = QPATHTOF(data\m_sandbag_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 8; }; }; @@ -22,7 +22,7 @@ class CfgWeapons { model = QPATHTOF(data\ace_sandbag_build.p3d); picture = QPATHTOF(data\m_sandbag_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 160; }; }; diff --git a/addons/sandbag/data/preview_sandbag.jpg b/addons/sandbag/data/preview_sandbag.jpg new file mode 100644 index 0000000000..8f584388f2 Binary files /dev/null and b/addons/sandbag/data/preview_sandbag.jpg differ diff --git a/addons/sandbag/functions/fnc_deploy.sqf b/addons/sandbag/functions/fnc_deploy.sqf index af7d5c0a2f..da22483835 100644 --- a/addons/sandbag/functions/fnc_deploy.sqf +++ b/addons/sandbag/functions/fnc_deploy.sqf @@ -19,6 +19,7 @@ params ["_unit"]; // prevent the placing unit from running [_unit, "forceWalk", "ACE_Sandbag", true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Sandbag", true] call EFUNC(common,statusEffect_set); // create the sandbag private _sandBag = createVehicle ["ACE_SandbagObject_NoGeo", [0, 0, 0], [], 0, "NONE"]; diff --git a/addons/sandbag/functions/fnc_deployCancel.sqf b/addons/sandbag/functions/fnc_deployCancel.sqf index 6cb38e4f73..bd5e1a0d86 100644 --- a/addons/sandbag/functions/fnc_deployCancel.sqf +++ b/addons/sandbag/functions/fnc_deployCancel.sqf @@ -22,6 +22,7 @@ if (_key != 1 || {GVAR(deployPFH) == -1}) exitWith {}; // enable running again [_unit, "forceWalk", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); // delete placement dummy deleteVehicle GVAR(sandBag); diff --git a/addons/sandbag/functions/fnc_deployConfirm.sqf b/addons/sandbag/functions/fnc_deployConfirm.sqf index 68328cca67..29fca46f54 100644 --- a/addons/sandbag/functions/fnc_deployConfirm.sqf +++ b/addons/sandbag/functions/fnc_deployConfirm.sqf @@ -19,6 +19,7 @@ params ["_unit"]; // enable running again [_unit, "forceWalk", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set); // remove sandbag from inventory _unit removeItem "ACE_Sandbag_empty"; diff --git a/addons/sandbag/functions/fnc_handleUnconscious.sqf b/addons/sandbag/functions/fnc_handleUnconscious.sqf index 709e633377..e225dac7c3 100644 --- a/addons/sandbag/functions/fnc_handleUnconscious.sqf +++ b/addons/sandbag/functions/fnc_handleUnconscious.sqf @@ -17,6 +17,8 @@ params ["_unit"]; +if (!local _unit) exitWith {}; + if (_unit getVariable [QGVAR(isDeploying), false]) then { [_unit] call FUNC(deployCancel); }; diff --git a/addons/sandbag/stringtable.xml b/addons/sandbag/stringtable.xml index 555dcab416..4559e43b00 100644 --- a/addons/sandbag/stringtable.xml +++ b/addons/sandbag/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -25,7 +25,7 @@ Saco de arena (vacio) Sac de sable (vide) Pytel na písek (prázdný) - Sacco di Sabbia (Vuoto) + Sacco di Sabbia (vuoto) Homokzsák (üres) Saco de Areia (vazio) 土のう (空) diff --git a/addons/scopes/ACE_Settings.hpp b/addons/scopes/ACE_Settings.hpp index 6ff483cb50..04e0e92ffb 100644 --- a/addons/scopes/ACE_Settings.hpp +++ b/addons/scopes/ACE_Settings.hpp @@ -1,5 +1,6 @@ class ACE_Settings { class GVAR(enabled) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 1; displayName = CSTRING(enabled_displayName); @@ -7,6 +8,7 @@ class ACE_Settings { }; // ACE_ScopeAdjust_Vertical and ACE_ScopeAdjust_Horizontal will be populated with default values instead of [0,0] class GVAR(forceUseOfAdjustmentTurrets) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 0; displayName = CSTRING(forceUseOfAdjustmentTurrets_displayName); @@ -15,6 +17,7 @@ class ACE_Settings { // Auto corrects the zeroing in both vanilla- and advanced ballistics class GVAR(correctZeroing) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 1; displayName = CSTRING(correctZeroing_displayName); @@ -22,6 +25,7 @@ class ACE_Settings { }; // Enables the use of the 'defaultZeroRange' setting to overwrite the discreteDistance[] config class GVAR(overwriteZeroRange) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 0; displayName = CSTRING(overwriteZeroRange_displayName); @@ -29,35 +33,61 @@ class ACE_Settings { }; // Only affects scopes with elevation adjustment turrets (ACE_ScopeAdjust_Vertical != [0,0]) class GVAR(defaultZeroRange) { + category = CSTRING(DisplayName); typeName = "SCALAR"; value = 100; displayName = CSTRING(defaultZeroRange_displayName); description = CSTRING(defaultZeroRange_description); + sliderSettings[] = {0, 1000, 100, 0}; }; // Only relevant when advanced ballistics is enabled class GVAR(zeroReferenceTemperature) { + category = CSTRING(DisplayName); typeName = "SCALAR"; value = 15; displayName = CSTRING(zeroReferenceTemperature_displayName); description = CSTRING(zeroReferenceTemperature_description); + sliderSettings[] = {-55, 55, 15, 0}; }; class GVAR(zeroReferenceBarometricPressure) { + category = CSTRING(DisplayName); typeName = "SCALAR"; value = 1013.25; displayName = CSTRING(zeroReferenceBarometricPressure_displayName); description = CSTRING(zeroReferenceBarometricPressure_description); + sliderSettings[] = {0, 1013.25, 1013.25, 2}; }; class GVAR(zeroReferenceHumidity) { + category = CSTRING(DisplayName); typeName = "SCALAR"; - value = 0.5; + value = 0.0; displayName = CSTRING(zeroReferenceHumidity_displayName); description = CSTRING(zeroReferenceHumidity_description); + sliderSettings[] = {0, 1, 0, 2}; }; class GVAR(deduceBarometricPressureFromTerrainAltitude) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 0; displayName = CSTRING(deduceBarometricPressureFromTerrainAltitude_displayName); description = CSTRING(deduceBarometricPressureFromTerrainAltitude_description); }; + + class GVAR(useLegacyUI) { + category = CSTRING(DisplayName); + typeName = "BOOL"; + value = 0; + isClientSettable = 1; + displayName = CSTRING(useLegacyUI_displayName); + description = CSTRING(useLegacyUI_description); + }; + + class GVAR(simplifiedZeroing) { + category = CSTRING(DisplayName); + typeName = "BOOL"; + value = 0; + displayName = CSTRING(simplifiedZeroing_displayName); + description = CSTRING(simplifiedZeroing_description); + }; }; diff --git a/addons/scopes/CfgVehicles.hpp b/addons/scopes/CfgVehicles.hpp index fd2a7d01c6..b1e76d4401 100644 --- a/addons/scopes/CfgVehicles.hpp +++ b/addons/scopes/CfgVehicles.hpp @@ -11,14 +11,24 @@ class CfgVehicles { showDisabled = 0; priority = 0.2; //icon = QPATHTOF(UI\...); // TODO - exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; + exceptions[] = {"notOnMap", "isNotInside", "isNotSwimming", "isNotSitting"}; + }; + class GVAR(resetZero) { + // Updates the zero reference + displayName = CSTRING(ResetZero); + condition = QUOTE([ACE_player] call FUNC(canResetZero)); + statement = QUOTE([ACE_player] call FUNC(resetZero)); + showDisabled = 0; + priority = 0.2; + //icon = QPATHTOF(UI\...); // TODO + exceptions[] = {"notOnMap", "isNotInside", "isNotSwimming", "isNotSitting"}; }; }; }; }; class ACE_Module; class GVAR(ModuleSettings): ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(DisplayName); //icon = ""; // needs an icon category = "ACE"; @@ -74,7 +84,7 @@ class CfgVehicles { displayName = CSTRING(zeroReferenceHumidity_DisplayName); description = CSTRING(zeroReferenceHumidity_Description); typeName = "NUMBER"; - defaultValue = 0.5; + defaultValue = 0.0; }; class deduceBarometricPressureFromTerrainAltitude { displayName = CSTRING(deduceBarometricPressureFromTerrainAltitude_DisplayName); @@ -82,6 +92,12 @@ class CfgVehicles { typeName = "BOOL"; defaultValue = 0; }; + class simplifiedZeroing { + displayName = CSTRING(simplifiedZeroing_displayName); + description = CSTRING(simplifiedZeroing_description); + typeName = "BOOL"; + defaultValue = 0; + }; }; class ModuleDescription { description = CSTRING(Description); diff --git a/addons/scopes/CfgWeapons.hpp b/addons/scopes/CfgWeapons.hpp index 43a4b24639..2a5be51ee0 100644 --- a/addons/scopes/CfgWeapons.hpp +++ b/addons/scopes/CfgWeapons.hpp @@ -1,57 +1,61 @@ +class Mode_SemiAuto; +class Mode_Burst; +class Mode_FullAuto; + class CfgWeapons { class ItemCore; class InventoryOpticsItem_Base_F; class optic_Yorris : ItemCore { - ACE_ScopeHeightAboveRail = 0.4; + ACE_ScopeHeightAboveRail = 2.77224; }; class optic_MRD : ItemCore { - ACE_ScopeHeightAboveRail = 0.6; + ACE_ScopeHeightAboveRail = 2.8; }; class optic_Aco : ItemCore { - ACE_ScopeHeightAboveRail = 1.8; + ACE_ScopeHeightAboveRail = 3.69248; }; class optic_ACO_grn : ItemCore { - ACE_ScopeHeightAboveRail = 1.8; + ACE_ScopeHeightAboveRail = 3.69248; }; class optic_ACO_grn_smg : ItemCore { - ACE_ScopeHeightAboveRail = 1.8; + ACE_ScopeHeightAboveRail = 3.69248; }; class optic_ACO_smg : ItemCore { - ACE_ScopeHeightAboveRail = 1.8; + ACE_ScopeHeightAboveRail = 3.69248; }; class optic_Holosight : ItemCore { - ACE_ScopeHeightAboveRail = 2.4; + ACE_ScopeHeightAboveRail = 4.66933; }; class optic_Holosight_smg : ItemCore { - ACE_ScopeHeightAboveRail = 2.4; + ACE_ScopeHeightAboveRail = 4.66933; }; class optic_Arco : ItemCore { - ACE_ScopeHeightAboveRail = 3.0; + ACE_ScopeHeightAboveRail = 4.89287; }; class optic_ERCO_blk_F : optic_Arco { - ACE_ScopeHeightAboveRail = 2.6; + ACE_ScopeHeightAboveRail = 3.48836; }; class optic_Hamr : ItemCore { - ACE_ScopeHeightAboveRail = 3.2; + ACE_ScopeHeightAboveRail = 4.48584; }; class optic_MRCO : ItemCore { - ACE_ScopeHeightAboveRail = 2.5; + ACE_ScopeHeightAboveRail = 3.88405; }; class optic_Nightstalker : ItemCore { - ACE_ScopeHeightAboveRail = 4.2; + ACE_ScopeHeightAboveRail = 5.54325; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -67,7 +71,7 @@ class CfgWeapons { }; class optic_NVS : ItemCore { - ACE_ScopeHeightAboveRail = 4.2; + ACE_ScopeHeightAboveRail = 5.54325; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -83,7 +87,7 @@ class CfgWeapons { }; class optic_TWS : ItemCore { - ACE_ScopeHeightAboveRail = 4.2; + ACE_ScopeHeightAboveRail = 5.52874; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -99,7 +103,7 @@ class CfgWeapons { }; class optic_LRPS : ItemCore { - ACE_ScopeHeightAboveRail = 4.0; + ACE_ScopeHeightAboveRail = 4.2098; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -119,7 +123,7 @@ class CfgWeapons { }; class optic_SOS : ItemCore { - ACE_ScopeHeightAboveRail = 3.8; + ACE_ScopeHeightAboveRail = 4.41328; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -135,7 +139,7 @@ class CfgWeapons { }; class optic_DMS : ItemCore { - ACE_ScopeHeightAboveRail = 3.6; + ACE_ScopeHeightAboveRail = 3.86253; ACE_ScopeAdjust_Vertical[] = {-4, 20}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -151,7 +155,7 @@ class CfgWeapons { }; class optic_AMS_base : ItemCore { - ACE_ScopeHeightAboveRail = 3.6; + ACE_ScopeHeightAboveRail = 3.8933; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -171,7 +175,7 @@ class CfgWeapons { }; class optic_KHS_base : ItemCore { - ACE_ScopeHeightAboveRail = 4.0; + ACE_ScopeHeightAboveRail = 4.30723; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -191,7 +195,7 @@ class CfgWeapons { }; class optic_KHS_old : ItemCore { - ACE_ScopeHeightAboveRail = 4.0; + ACE_ScopeHeightAboveRail = 4.30723; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -209,4 +213,224 @@ class CfgWeapons { }; }; }; + + class Rifle_Base_F; + class Rifle_Short_Base_F: Rifle_Base_F {}; + class Rifle_Long_Base_F: Rifle_Base_F {}; + + class DMR_07_base_F: Rifle_Long_Base_F { + ACE_RailHeightAboveBore = 5.07109; + ACE_IronSightBaseAngle = -0.00160721; + }; + + class arifle_MX_Base_F: Rifle_Base_F { + class Single: Mode_SemiAuto {}; + class FullAuto: Mode_FullAuto {}; + }; + class arifle_MX_SW_F: arifle_MX_Base_F { + ACE_RailHeightAboveBore = 2.40874; + ACE_IronSightBaseAngle = 0.216372; + }; + class arifle_MXM_F: arifle_MX_Base_F { + ACE_RailHeightAboveBore = 2.40323; + ACE_IronSightBaseAngle = 0.157545; + }; + + class arifle_SPAR_01_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 3.20768; + ACE_IronSightBaseAngle = -0.166678; + }; + class arifle_SPAR_02_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 3.22175; + ACE_IronSightBaseAngle = -0.184641; + }; + class arifle_SPAR_03_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 3.71491; + ACE_IronSightBaseAngle = -0.134908; + }; + + class LMG_Mk200_F: Rifle_Long_Base_F { + ACE_RailHeightAboveBore = 2.68925; + ACE_IronSightBaseAngle = 0.0182228; + }; + class LMG_Zafir_F: Rifle_Long_Base_F { + ACE_RailHeightAboveBore = 0.996651; + ACE_IronSightBaseAngle = 0.19812212; + }; + class LMG_03_base_F: Rifle_Long_Base_F { + ACE_RailHeightAboveBore = 4.24282; + ACE_IronSightBaseAngle = 0.00181939; + }; + + class pdw2000_base_F: Rifle_Short_Base_F { + ACE_RailHeightAboveBore = 3.08883; + ACE_RailBaseAngle = 0.019366; + ACE_IronSightBaseAngle = 0.0399664; + }; + + class arifle_AKS_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 0; + ACE_IronSightBaseAngle = 0.00574991; + }; + class arifle_AKM_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 0; + ACE_IronSightBaseAngle = 0.006273; + }; + class arifle_AK12_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 3.82508; + ACE_IronSightBaseAngle = 0.0276926; + }; + class arifle_CTAR_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 6.07588; + ACE_IronSightBaseAngle = 0.0151815; + }; + class arifle_CTARS_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 6.0787; + ACE_IronSightBaseAngle = 0.0125245; + }; + class arifle_ARX_base_F: Rifle_Base_F { + ACE_RailHeightAboveBore = 2.81635; + ACE_IronSightBaseAngle = 0.113024; + }; + + class arifle_katiba_Base_F: Rifle_Base_F {}; + + class arifle_Katiba_F: arifle_katiba_Base_F { + ACE_RailHeightAboveBore = 5.75468; + ACE_IronSightBaseAngle = 0.0863227; + }; + class arifle_Katiba_C_F: arifle_katiba_Base_F { + ACE_RailHeightAboveBore = 5.75468; + ACE_IronSightBaseAngle = 0.083419; + }; + class arifle_Katiba_GL_F: arifle_katiba_Base_F { + ACE_RailHeightAboveBore = 5.75468; + ACE_IronSightBaseAngle = 0.0863227; + }; + + class arifle_MX_F: arifle_MX_Base_F { + ACE_RailHeightAboveBore = 2.80201; + ACE_IronSightBaseAngle = 0.19502; + }; + class arifle_MX_GL_F: arifle_MX_Base_F { + ACE_RailHeightAboveBore = 2.80201; + ACE_IronSightBaseAngle = 0.17142857; + }; + + class arifle_MXC_F: arifle_MX_Base_F { + ACE_RailHeightAboveBore = 2.40874; + ACE_IronSightBaseAngle = 0.0154129; + }; + + class SDAR_base_F: Rifle_Base_F {}; + + class arifle_SDAR_F: SDAR_base_F { + ACE_RailHeightAboveBore = 0; + ACE_IronSightBaseAngle = -0.0237516; + }; + + class SMG_01_Base: Rifle_Short_Base_F { + ACE_RailHeightAboveBore = 4.85355; + ACE_RailBaseAngle = 0.0250956; + ACE_IronSightBaseAngle = -0.159239; + }; + class SMG_02_base_F: Rifle_Short_Base_F { + ACE_RailHeightAboveBore = 4.41831; + ACE_RailBaseAngle = 0.0217724; + ACE_IronSightBaseAngle = 0.434847; + }; + class SMG_05_base_F: Rifle_Short_Base_F { + ACE_RailHeightAboveBore = 4.05169; + ACE_RailBaseAngle = 0.019366; + ACE_IronSightBaseAngle = -0.122823; + }; + + class Tavor_base_F: Rifle_Base_F {}; + + class arifle_TRG20_F: Tavor_base_F { + ACE_RailHeightAboveBore = 4.30954; + ACE_IronSightBaseAngle = 0.0338428; + }; + class arifle_TRG21_F: Tavor_base_F { + ACE_RailHeightAboveBore = 4.30954; + ACE_IronSightBaseAngle = 0.0317759; + }; + class arifle_TRG21_GL_F: arifle_TRG21_F { + ACE_RailHeightAboveBore = 4.30954; + ACE_IronSightBaseAngle = -0.03428571; + }; + + class mk20_base_F: Rifle_Base_F {}; + + class arifle_Mk20_F: mk20_base_F { + ACE_RailHeightAboveBore = 4.57255; + ACE_IronSightBaseAngle = -0.153292; + }; + class arifle_Mk20C_F: mk20_base_F { + ACE_RailHeightAboveBore = 4.41539; + ACE_IronSightBaseAngle = -0.137835; + }; + class arifle_Mk20_GL_F: mk20_base_F { + ACE_RailHeightAboveBore = 4.41539; + ACE_IronSightBaseAngle = -0.1532926; + }; + + class EBR_base_F: Rifle_Long_Base_F {}; + class LRR_base_F: Rifle_Long_Base_F {}; + class GM6_base_F: Rifle_Long_Base_F {}; + class DMR_01_base_F: Rifle_Long_Base_F {}; + class DMR_02_base_F: Rifle_Long_Base_F {}; + class DMR_03_base_F: Rifle_Long_Base_F {}; + class DMR_04_base_F: Rifle_Long_Base_F {}; + class DMR_05_base_F: Rifle_Long_Base_F {}; + class DMR_06_base_F: Rifle_Long_Base_F {}; + + class srifle_EBR_F: EBR_base_F { + ACE_RailHeightAboveBore = 1.98812; + ACE_IronSightBaseAngle = -0.00601782; + }; + class srifle_LRR_F: LRR_base_F { + ACE_RailHeightAboveBore = 3.20864; + ACE_IronSightBaseAngle = -0.0302847; + }; + class srifle_GM6_F: GM6_base_F { + ACE_RailHeightAboveBore = 4.75572; + ACE_IronSightBaseAngle = -0.165062; + }; + class srifle_DMR_01_F: DMR_01_base_F { + ACE_RailHeightAboveBore = 2.83284; + ACE_IronSightBaseAngle = 0.234393; + }; + class srifle_DMR_02_F: DMR_02_base_F { + ACE_RailHeightAboveBore = 3.43913; + ACE_IronSightBaseAngle = 0.013878; + }; + class srifle_DMR_03_F: DMR_03_base_F { + ACE_RailHeightAboveBore = 4.0795; + ACE_IronSightBaseAngle = 0.0138099; + }; + class srifle_DMR_04_F: DMR_04_base_F { + ACE_RailHeightAboveBore = 2.38022; + ACE_RailBaseAngle = 0.0171842; + }; + class srifle_DMR_05_blk_F: DMR_05_base_F { + ACE_RailHeightAboveBore = 3.91334; + ACE_IronSightBaseAngle = 0.0123425; + }; + class srifle_DMR_06_camo_F: DMR_06_base_F { + ACE_RailHeightAboveBore = 3.27488; + ACE_IronSightBaseAngle = 0.018227; + }; + + class MMG_01_base_F; + class MMG_02_base_F; + + class MMG_01_hex_F: MMG_01_base_F { + ACE_RailHeightAboveBore = 4.73961; + ACE_IronSightBaseAngle = -0.0101613; + }; + class MMG_02_camo_F: MMG_02_base_F { + ACE_RailHeightAboveBore = 5.01913; + ACE_IronSightBaseAngle = 0.0136377; + }; }; diff --git a/addons/scopes/RscTitles.hpp b/addons/scopes/RscTitles.hpp index 1a4bcc99c3..a15cbbed67 100644 --- a/addons/scopes/RscTitles.hpp +++ b/addons/scopes/RscTitles.hpp @@ -51,7 +51,7 @@ class RscTitles { class ACE_Scopes_Zeroing_Horizontal : RscText { idc = 13; type = 0; - style = 0; + style = 2; sizeEx = 0.04; lineSpacing = 1; font = "RobotoCondensed"; @@ -62,7 +62,7 @@ class RscTitles { x = (0.5 - 0.4 / 2 + 0.6*0.4) * safezoneW + safezoneX; y = (0 + 0.47*0.3) * safezoneH + safezoneY; - w = 0.04 * safezoneW; + w = 0.019 * safezoneW; h = 0.025 * safezoneH; }; }; diff --git a/addons/scopes/XEH_PREP.hpp b/addons/scopes/XEH_PREP.hpp index a8489fe585..58b4e494f2 100644 --- a/addons/scopes/XEH_PREP.hpp +++ b/addons/scopes/XEH_PREP.hpp @@ -4,10 +4,13 @@ PREP(adjustZero); PREP(applyScopeAdjustment); PREP(calculateZeroAngleCorrection); PREP(canAdjustZero); +PREP(canResetZero); PREP(firedEH); +PREP(getBaseAngle); PREP(getBoreHeight); PREP(getCurrentZeroRange); PREP(getOptics); PREP(initModuleSettings); PREP(inventoryCheck); +PREP(resetZero); PREP(showZeroing); diff --git a/addons/scopes/XEH_postInit.sqf b/addons/scopes/XEH_postInit.sqf index 0145bfcb66..075ea48a76 100644 --- a/addons/scopes/XEH_postInit.sqf +++ b/addons/scopes/XEH_postInit.sqf @@ -13,13 +13,12 @@ GVAR(Optics) = ["", "", ""]; GVAR(Guns) = ["", "", ""]; GVAR(canAdjustElevation) = [false, false, false]; GVAR(canAdjustWindage) = [false, false, false]; -GVAR(boreHeight) = [0, 0, 0]; GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ace_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; - + if (GVAR(deduceBarometricPressureFromTerrainAltitude)) then { GVAR(zeroReferenceBarometricPressure) = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; }; @@ -45,7 +44,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; // Add keybinds ["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), localize LSTRING(AdjustUpMinor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -57,7 +56,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), localize LSTRING(AdjustDownMinor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -69,7 +68,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), localize LSTRING(AdjustLeftMinor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -81,7 +80,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), localize LSTRING(AdjustRightMinor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -93,7 +92,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), localize LSTRING(AdjustUpMajor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -105,7 +104,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), localize LSTRING(AdjustDownMajor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -117,7 +116,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), localize LSTRING(AdjustLeftMajor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -129,7 +128,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), localize LSTRING(AdjustRightMajor), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; @@ -143,5 +142,5 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; // Register fire event handler ["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; ["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; - + }] call CBA_fnc_addEventHandler; diff --git a/addons/scopes/functions/fnc_adjustScope.sqf b/addons/scopes/functions/fnc_adjustScope.sqf index a16568b0d9..8c48ee654b 100644 --- a/addons/scopes/functions/fnc_adjustScope.sqf +++ b/addons/scopes/functions/fnc_adjustScope.sqf @@ -17,26 +17,26 @@ */ #include "script_component.hpp" -private ["_weaponIndex", "_zeroing", "_optic", "_opticConfig", "_verticalIncrement", "_horizontalIncrement", "_maxVertical", "_maxHorizontal", "_adjustment"]; - params ["_unit", "_turretAndDirection", "_majorStep"]; +TRACE_3("adjustScope",_unit,_turretAndDirection,_majorStep); if (!(_unit isKindOf "Man")) exitWith {false}; if (currentMuzzle _unit != currentWeapon _unit) exitWith {false}; if (!GVAR(enabled)) exitWith {false}; -_weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); +private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; -_adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; - +TRACE_2("",GVAR(canAdjustElevation),GVAR(canAdjustWindage)); if (!(GVAR(canAdjustElevation) select _weaponIndex) && (_turretAndDirection in [ELEVATION_UP, ELEVATION_DOWN])) exitWith {false}; -if (!(GVAR(canAdjustWindage) select _weaponIndex) && (_turretAndDirection in [WINDAGE_UP, WINDAGE_DOWN])) exitWith {false}; +if (!(GVAR(canAdjustWindage) select _weaponIndex) && (_turretAndDirection in [WINDAGE_LEFT, WINDAGE_RIGHT])) exitWith {false}; -_zeroing = _adjustment select _weaponIndex; +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _zeroing = _adjustment select _weaponIndex; _zeroing params ["_elevation", "_windage", "_zero"]; (GVAR(scopeAdjust) select _weaponIndex) params ["_maxVertical", "_verticalIncrement", "_maxHorizontal", "_horizontalIncrement"]; +TRACE_4("",_maxVertical,_verticalIncrement,_maxHorizontal,_horizontalIncrement); switch (_turretAndDirection) do { case ELEVATION_UP: { _elevation = _elevation + _verticalIncrement }; @@ -54,8 +54,8 @@ if (_majorStep) then { }; }; -_elevation = round(_elevation * 10) / 10; -_windage = round(_windage * 10) / 10; +_elevation = round(_elevation / MIN_INCREMENT) * MIN_INCREMENT; +_windage = round(_windage / MIN_INCREMENT) * MIN_INCREMENT; if ((_elevation + _zero) < _maxVertical select 0 or (_elevation + _zero) > _maxVertical select 1) exitWith {false}; if (_windage < _maxHorizontal select 0 or _windage > _maxHorizontal select 1) exitWith {false}; diff --git a/addons/scopes/functions/fnc_adjustZero.sqf b/addons/scopes/functions/fnc_adjustZero.sqf index bc702a8c5f..b551d6b2c7 100644 --- a/addons/scopes/functions/fnc_adjustZero.sqf +++ b/addons/scopes/functions/fnc_adjustZero.sqf @@ -1,6 +1,6 @@ /* * Author: KoffeinFlummi, Ruthberg - * Updates the zero reference for the current scope + * Updates the zero adjustment of the current scope * * Arguments: * 0: Unit @@ -15,22 +15,28 @@ */ #include "script_component.hpp" -private ["_weaponIndex", "_adjustment", "_zeroing"]; - params ["_unit"]; if (vehicle _unit != _unit) exitWith {false}; -_weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); +private _weaponClass = currentWeapon _unit; +private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; -_adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; -_zeroing = _adjustment select _weaponIndex; +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _zeroing = _adjustment select _weaponIndex; _zeroing params ["_elevation", "_windage", "_zero"]; -_zero = round((_zero + _elevation) * 10) / 10; +_zero = round((_zero + _elevation) / MIN_INCREMENT) * MIN_INCREMENT; _elevation = 0; +private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; +if (_zero != 0) then { + profileNamespace setVariable [format[QGVAR(PersistentZero_%1_%2), _weaponClass, _opticsClass], _zero]; +} else { + profileNamespace setVariable [format[QGVAR(PersistentZero_%1_%2), _weaponClass, _opticsClass], nil]; +}; + [_unit, _elevation, _windage, _zero] call FUNC(applyScopeAdjustment); true diff --git a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf index 2777df65b5..f4d6959754 100644 --- a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf +++ b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf @@ -18,14 +18,12 @@ */ #include "script_component.hpp" -private ["_adjustmentDifference", "_pitchBankYaw", "_adjustment", "_weaponIndex"]; - params ["_unit", "_elevation", "_windage", "_zero"]; -_weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); +private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); -_adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; -_adjustmentDifference = (_adjustment select _weaponIndex) vectorDiff [_elevation, _windage, _zero]; +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _adjustmentDifference = (_adjustment select _weaponIndex) vectorDiff [_elevation, _windage, _zero]; if (_adjustmentDifference isEqualTo [0,0,0]) exitWith {false}; // Don't coninue if no adjustment is made _adjustment set [_weaponIndex, [_elevation, _windage, _zero]]; @@ -35,14 +33,16 @@ playSound selectRandom ["ACE_Scopes_Click_1", "ACE_Scopes_Click_2", "ACE_Scopes_ // slightly rotate the player if looking through optic if (cameraView == "GUNNER") then { - // Convert adjustmentDifference from mils to degrees - _adjustmentDifference = _adjustmentDifference apply {_x * 0.05625}; - _adjustmentDifference params ["_elevationDifference", "_windageDifference"]; - _pitchBankYaw = [_unit] call EFUNC(common,getPitchBankYaw); - _pitchBankYaw params ["_pitch", "_bank", "_yaw"]; - _pitch = _pitch + _elevationDifference; - _yaw = _yaw + _windageDifference; - [_unit, _pitch, _bank, _yaw] call EFUNC(common,setPitchBankYaw); + if (!GVAR(simplifiedZeroing)) then { + // Convert adjustmentDifference from mils to degrees + _adjustmentDifference = _adjustmentDifference apply {MRAD_TO_DEG(_x)}; + _adjustmentDifference params ["_elevationDifference", "_windageDifference"]; + private _pitchBankYaw = [_unit] call EFUNC(common,getPitchBankYaw); + _pitchBankYaw params ["_pitch", "_bank", "_yaw"]; + _pitch = _pitch + _elevationDifference; + _yaw = _yaw + _windageDifference; + [_unit, _pitch, _bank, _yaw] call EFUNC(common,setPitchBankYaw); + }; } else { [] call FUNC(showZeroing); }; diff --git a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf index 5197a94e70..4573a1c97a 100644 --- a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf +++ b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf @@ -32,11 +32,15 @@ if (_initSpeedCoef < 0) then { _initSpeed = _initSpeed * (-1 * _initSpeedCoef); }; -private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _oldZeroRange, _initSpeed, _airFriction, 0]; +private _zeroAngle = "ace_advanced_ballistics" callExtension format ["replicateVanillaZero:%1:%2:%3", _oldZeroRange, _initSpeed, _airFriction]; private _vanillaZero = parseNumber _zeroAngle; +#ifdef DISABLE_DISPERSION + _vanillaZero = 0; +#endif + private _trueZero = if (!_advancedBallistics) then { - _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight]; + _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { // Get Weapon and Ammo Configurations @@ -49,7 +53,7 @@ private _trueZero = if (!_advancedBallistics) then { _WeaponCacheEntry = _weapon call EFUNC(advanced_ballistics,readWeaponDataFromConfig); }; - _AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable"]; + _AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"]; _WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"]; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]) then { @@ -57,7 +61,12 @@ private _trueZero = if (!_advancedBallistics) then { _initSpeed = _initSpeed + _barrelVelocityShift; }; - _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _newZeroRange, _initSpeed, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel]; + if (missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then { + private _ammoTemperatureVelocityShift = ([_ammoTempMuzzleVelocityShifts, GVAR(zeroReferenceTemperature)] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift)); + _initSpeed = _initSpeed + _ammoTemperatureVelocityShift; + }; + + _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _newZeroRange, _initSpeed, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; diff --git a/addons/scopes/functions/fnc_canAdjustZero.sqf b/addons/scopes/functions/fnc_canAdjustZero.sqf index 30e2918805..996e6ae7fc 100644 --- a/addons/scopes/functions/fnc_canAdjustZero.sqf +++ b/addons/scopes/functions/fnc_canAdjustZero.sqf @@ -1,6 +1,6 @@ /* * Author: KoffeinFlummi, Ruthberg - * Changes the adjustment for the current scope + * Checks if the unit can change the zero adjustment of the current scope * * Arguments: * 0: Unit @@ -15,19 +15,18 @@ */ #include "script_component.hpp" -private ["_weaponIndex", "_adjustment", "_elevation"]; - params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; if (vehicle _unit != _unit) exitWith {false}; +if (GVAR(simplifiedZeroing)) exitWith {false}; if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; -_weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); +private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; -_adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; -_elevation = (_adjustment select _weaponIndex) select 0; +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _elevation = (_adjustment select _weaponIndex) select 0; // You can only adjust your zero reference, if your relative elevation setting is not 0 _elevation != 0 diff --git a/addons/scopes/functions/fnc_canResetZero.sqf b/addons/scopes/functions/fnc_canResetZero.sqf new file mode 100644 index 0000000000..fe9def4a19 --- /dev/null +++ b/addons/scopes/functions/fnc_canResetZero.sqf @@ -0,0 +1,31 @@ +/* + * Author: KoffeinFlummi, Ruthberg + * Checks if the unit can reset the zero adjustment of the current scope + * + * Arguments: + * 0: Unit + * + * Return Value: + * Can we reset the zero reference? + * + * Example: + * [player] call ace_scopes_fnc_canResetZero + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; + +if (cameraView == "GUNNER") exitWith {false}; +if (vehicle _unit != _unit) exitWith {false}; +if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; + +private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); +if (_weaponIndex < 0) exitWith {false}; + +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _zero = (_adjustment select _weaponIndex) select 2; + +// You can only reset your zero reference, if it is not 0 already +_zero != 0 diff --git a/addons/scopes/functions/fnc_firedEH.sqf b/addons/scopes/functions/fnc_firedEH.sqf index f83371ec13..6d63f9107a 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -23,23 +23,31 @@ if (!(_ammo isKindOf "BulletBase")) exitWith {}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; -private _adjustment = ACE_player getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; private _zeroing = +(_adjustment select _weaponIndex); TRACE_1("Adjusting With",_zeroing); // Convert zeroing from mils to degrees -_zeroing = _zeroing vectorMultiply 0.05625; +_zeroing = _zeroing vectorMultiply MRAD_TO_DEG(1); -if (GVAR(correctZeroing)) then { +if (GVAR(correctZeroing) || GVAR(simplifiedZeroing)) then { private _advancedBallistics = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; - private _boreHeight = GVAR(boreHeight) select _weaponIndex; + private _baseAngle = (_unit getVariable [QGVAR(baseAngle), [0,0,0]]) select _weaponIndex; + private _boreHeight = (_unit getVariable [QGVAR(boreHeight), [0,0,0]]) select _weaponIndex; private _oldZeroRange = currentZeroing _unit; private _newZeroRange = [_unit] call FUNC(getCurrentZeroRange); private _zeroCorrection = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5_%6_%7), _oldZeroRange, _newZeroRange, _boreHeight, _weapon, _ammo, _magazine, _advancedBallistics]; if (isNil "_zeroCorrection") then { _zeroCorrection = [_oldZeroRange, _newZeroRange, _boreHeight, _weapon, _ammo, _magazine, _advancedBallistics] call FUNC(calculateZeroAngleCorrection); }; - _zeroing = _zeroing vectorAdd [0, 0, _zeroCorrection]; + if (GVAR(simplifiedZeroing)) then { + _zeroing = [0, 0, _zeroCorrection - _baseAngle]; + } else { + _zeroing = _zeroing vectorAdd [0, 0, _zeroCorrection - _baseAngle]; + }; +#ifdef DISABLE_DISPERSION + _projectile setVelocity (_unit weaponDirection currentWeapon _unit) vectorMultiply (vectorMagnitude (velocity _projectile)); +#endif }; if (_zeroing isEqualTo [0, 0, 0]) exitWith {}; diff --git a/addons/scopes/functions/fnc_getBaseAngle.sqf b/addons/scopes/functions/fnc_getBaseAngle.sqf new file mode 100644 index 0000000000..d529fef2f4 --- /dev/null +++ b/addons/scopes/functions/fnc_getBaseAngle.sqf @@ -0,0 +1,37 @@ +/* + * Author: Ruthberg + * Gets the base angle of the weapon & optic combination with the given weapon index + * + * Arguments: + * 0: Unit + * 1: Weapon index + * + * Return Value: + * base angle + * + * Example: + * [player, 0] call ace_scopes_fnc_getBaseAngle + * + * Public: Yes + */ +#include "script_component.hpp" + +params ["_unit", "_weaponIndex"]; + +if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; + +private _weaponClass = [primaryWeapon _unit, secondaryWeapon _unit, handgunWeapon _unit] select _weaponIndex; +private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; + +private _weaponConfig = configFile >> "CfgWeapons" >> _weaponClass; +private _baseAngle = getNumber(_weaponConfig >> "ACE_IronSightBaseAngle"); + +if (_opticsClass != "") then { + if (isNumber (_weaponConfig >> "ACE_RailBaseAngle")) then { + _baseAngle = getNumber(_weaponConfig >> "ACE_RailBaseAngle"); + } else { + _baseAngle = DEFAULT_RAIL_BASE_ANGLE; + }; +}; + +_baseAngle diff --git a/addons/scopes/functions/fnc_getBoreHeight.sqf b/addons/scopes/functions/fnc_getBoreHeight.sqf index fb061e5d46..b76a9c7f9e 100644 --- a/addons/scopes/functions/fnc_getBoreHeight.sqf +++ b/addons/scopes/functions/fnc_getBoreHeight.sqf @@ -10,18 +10,18 @@ * bore height * * Example: - * [player] call ace_scopes_fnc_getBoreHeight + * [player, 0] call ace_scopes_fnc_getBoreHeight * * Public: Yes */ #include "script_component.hpp" -params ["_player", "_weaponIndex"]; +params ["_unit", "_weaponIndex"]; -if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; +if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; -private _weaponClass = [primaryWeapon _player, secondaryWeapon _player, handgunWeapon _player] select _weaponIndex; -private _opticsClass = ([_player] call FUNC(getOptics)) select _weaponIndex; +private _weaponClass = [primaryWeapon _unit, secondaryWeapon _unit, handgunWeapon _unit] select _weaponIndex; +private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; if (_opticsClass == "") then { _opticsClass = _weaponClass; }; @@ -32,7 +32,7 @@ if (isNumber (_weaponConfig >> "ACE_RailHeightAboveBore")) then { _railHeightAboveBore = getNumber(_weaponConfig >> "ACE_RailHeightAboveBore"); } else { switch (_weaponIndex) do { - case 0: { _railHeightAboveBore = 2.0; }; // Rifle + case 0: { _railHeightAboveBore = 3.0; }; // Rifle case 2: { _railHeightAboveBore = 0.7; }; // Pistol }; }; @@ -43,12 +43,12 @@ if (isNumber (_opticConfig >> "ACE_ScopeHeightAboveRail")) then { _scopeHeightAboveRail = getNumber(_opticConfig >> "ACE_ScopeHeightAboveRail"); } else { switch (getNumber(_opticConfig >> "ItemInfo" >> "opticType")) do { - case 1: { _scopeHeightAboveRail = 3.0; }; // RCO or similar + case 1: { _scopeHeightAboveRail = 4.5; }; // RCO or similar case 2: { _scopeHeightAboveRail = 4.0; }; // High power scope default { switch (_weaponIndex) do { - case 0: { _scopeHeightAboveRail = 0.5; }; // Rifle iron sights - case 2: { _scopeHeightAboveRail = 0.3; }; // Pistol iron sights + case 0: { _scopeHeightAboveRail = 2.0; }; // Rifle iron sights + case 2: { _scopeHeightAboveRail = 1.0; }; // Pistol iron sights }; }; }; diff --git a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf index 7af8d2e3e9..2da5f32eb0 100644 --- a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf +++ b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf @@ -21,6 +21,10 @@ if (!GVAR(enabled)) exitWith { currentZeroing _unit }; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith { currentZeroing _unit }; +if (GVAR(simplifiedZeroing)) exitWith { + private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; + ((_adjustment select _weaponIndex) select 0) +}; private _optic = GVAR(Optics) select _weaponIndex; private _opticConfig = if (_optic != "") then { diff --git a/addons/scopes/functions/fnc_initModuleSettings.sqf b/addons/scopes/functions/fnc_initModuleSettings.sqf index 92742afd14..db5d5cd8a5 100644 --- a/addons/scopes/functions/fnc_initModuleSettings.sqf +++ b/addons/scopes/functions/fnc_initModuleSettings.sqf @@ -30,8 +30,7 @@ if !(_activated) exitWith {}; [_logic, QGVAR(zeroReferenceBarometricPressure), "zeroReferenceBarometricPressure"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(zeroReferenceHumidity), "zeroReferenceHumidity"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(deduceBarometricPressureFromTerrainAltitude), "deduceBarometricPressureFromTerrainAltitude"] call EFUNC(common,readSettingFromModule); - GVAR(defaultZeroRange) = 0 max GVAR(defaultZeroRange) min 1000; -GVAR(zeroReferenceTemperature) = -55 max GVAR(zeroReferenceTemperature) max 55; +GVAR(zeroReferenceTemperature) = -55 max GVAR(zeroReferenceTemperature) min 55; GVAR(zeroReferenceBarometricPressure) = 0 max GVAR(zeroReferenceBarometricPressure) min 1013.25; GVAR(zeroReferenceHumidity) = 0 max GVAR(zeroReferenceHumidity) min 1.0; diff --git a/addons/scopes/functions/fnc_inventoryCheck.sqf b/addons/scopes/functions/fnc_inventoryCheck.sqf index 817d301221..fa0fa426c6 100644 --- a/addons/scopes/functions/fnc_inventoryCheck.sqf +++ b/addons/scopes/functions/fnc_inventoryCheck.sqf @@ -25,32 +25,50 @@ private _newOptics = [_player] call FUNC(getOptics); if (_newOptics select _forEachIndex != _x) then { private _opticConfig = configFile >> "CfgWeapons" >> (_newOptics select _forEachIndex); private _opticType = getNumber(_opticConfig >> "ItemInfo" >> "opticType"); - private _verticalIncrement = -1; - if (isNumber (_opticConfig >> "ACE_ScopeAdjust_VerticalIncrement")) then { - _verticalIncrement = getNumber (_opticConfig >> "ACE_ScopeAdjust_VerticalIncrement"); - }; - private _horizontalIncrement = -1; - if (isNumber (_opticConfig >> "ACE_ScopeAdjust_HorizontalIncrement")) then { - _horizontalIncrement = getNumber (_opticConfig >> "ACE_ScopeAdjust_HorizontalIncrement"); - }; private _maxVertical = []; - if (isArray (_opticConfig >> "ACE_ScopeAdjust_Vertical")) then { - _maxVertical = getArray (_opticConfig >> "ACE_ScopeAdjust_Vertical"); - }; + private _verticalIncrement = -1; private _maxHorizontal = []; - if (isArray (_opticConfig >> "ACE_ScopeAdjust_Horizontal")) then { - _maxHorizontal = getArray (_opticConfig >> "ACE_ScopeAdjust_Horizontal"); - }; - if (GVAR(forceUseOfAdjustmentTurrets) && _opticType == 2) then { - if (_maxVertical isEqualTo []) then { _maxVertical = [-4, 30]; }; - if (_maxHorizontal isEqualTo []) then { _maxHorizontal = [-6, 6]; }; - if (_verticalIncrement == -1) then { _verticalIncrement = 0.1; }; - if (_horizontalIncrement == -1) then { _horizontalIncrement = 0.1; }; + private _horizontalIncrement = -1; + if (GVAR(simplifiedZeroing)) then { + private _maxDistanceZoomMax = 300; + private _maxDiscreteDistanceSize = 0; + { + _maxDistanceZoomMax = _maxDistanceZoomMax max (getNumber ( _x >> "distanceZoomMax")); + _maxDiscreteDistanceSize = _maxDiscreteDistanceSize max (count getArray (_x >> "discreteDistance")); + } forEach ("isArray (_x >> 'discreteDistance')" configClasses (_opticConfig >> "ItemInfo" >> "OpticsModes")); + if (_maxDiscreteDistanceSize < 2 && {getNumber (_opticConfig >> "ACE_ScopeAdjust_VerticalIncrement") != 0}) then { + _maxVertical = [50, _maxDistanceZoomMax]; + _verticalIncrement = 50; + } else { + _maxVertical = [0, 0]; + _verticalIncrement = 0; + }; + _maxHorizontal = [0, 0]; + _horizontalIncrement = 0; } else { - if (_maxVertical isEqualTo []) then { _maxVertical = [0, 0]; }; - if (_maxHorizontal isEqualTo []) then { _maxHorizontal = [0, 0]; }; - if (_verticalIncrement == -1) then { _verticalIncrement = 0; }; - if (_horizontalIncrement == -1) then { _horizontalIncrement = 0; }; + if (isNumber (_opticConfig >> "ACE_ScopeAdjust_VerticalIncrement")) then { + _verticalIncrement = getNumber (_opticConfig >> "ACE_ScopeAdjust_VerticalIncrement"); + }; + if (isNumber (_opticConfig >> "ACE_ScopeAdjust_HorizontalIncrement")) then { + _horizontalIncrement = getNumber (_opticConfig >> "ACE_ScopeAdjust_HorizontalIncrement"); + }; + if (isArray (_opticConfig >> "ACE_ScopeAdjust_Vertical")) then { + _maxVertical = getArray (_opticConfig >> "ACE_ScopeAdjust_Vertical"); + }; + if (isArray (_opticConfig >> "ACE_ScopeAdjust_Horizontal")) then { + _maxHorizontal = getArray (_opticConfig >> "ACE_ScopeAdjust_Horizontal"); + }; + if (GVAR(forceUseOfAdjustmentTurrets) && _opticType == 2) then { + if (_maxVertical isEqualTo []) then { _maxVertical = [-4, 30]; }; + if (_maxHorizontal isEqualTo []) then { _maxHorizontal = [-6, 6]; }; + if (_verticalIncrement == -1) then { _verticalIncrement = 0.1; }; + if (_horizontalIncrement == -1) then { _horizontalIncrement = 0.1; }; + } else { + if (_maxVertical isEqualTo []) then { _maxVertical = [0, 0]; }; + if (_maxHorizontal isEqualTo []) then { _maxHorizontal = [0, 0]; }; + if (_verticalIncrement == -1) then { _verticalIncrement = 0; }; + if (_horizontalIncrement == -1) then { _horizontalIncrement = 0; }; + }; }; (GVAR(scopeAdjust) select _forEachIndex) set [0, _maxVertical]; (GVAR(scopeAdjust) select _forEachIndex) set [1, _verticalIncrement]; @@ -61,34 +79,32 @@ private _newOptics = [_player] call FUNC(getOptics); }; } forEach GVAR(Optics); +private _unitBaseAngle = +(_player getVariable [QGVAR(baseAngle), [0,0,0]]); +private _unitBoreHeight = +(_player getVariable [QGVAR(boreHeight), [0,0,0]]); + private _newGuns = [primaryWeapon _player, secondaryWeapon _player, handgunWeapon _player]; { if ((_newOptics select _x) != (GVAR(Optics) select _x) || (_newGuns select _x != GVAR(Guns) select _x)) then { - // The optic or the weapon changed, set adjustment to zero - if (!((_adjustment select _forEachIndex) isEqualTo [0, 0, 0])) then { - _adjustment set [_forEachIndex, [0, 0, 0]]; - _updateAdjustment = true; - }; - - GVAR(boreHeight) set [_x, [_player, _x] call FUNC(getBoreHeight)]; - + _unitBaseAngle set [_x, [_player, _x] call FUNC(getBaseAngle)]; + _unitBoreHeight set [_x, [_player, _x] call FUNC(getBoreHeight)]; if ((_newOptics select _x) == "") then { - // Check if the weapon comes with an integrated optic - private _weaponConfig = configFile >> "CfgWeapons" >> (_newGuns select _x); - private _verticalIncrement = 0; - if (isNumber (_weaponConfig >> "ACE_ScopeAdjust_VerticalIncrement")) then { - _verticalIncrement = getNumber (_weaponConfig >> "ACE_ScopeAdjust_VerticalIncrement"); - }; - private _horizontalIncrement = 0; - if (isNumber (_weaponConfig >> "ACE_ScopeAdjust_HorizontalIncrement")) then { - _horizontalIncrement = getNumber (_weaponConfig >> "ACE_ScopeAdjust_HorizontalIncrement"); - }; + // Check if the weapon comes with an integrated optic + private _weaponConfig = configFile >> "CfgWeapons" >> (_newGuns select _x); private _maxVertical = [0, 0]; - if (isArray (_weaponConfig >> "ACE_ScopeAdjust_Vertical")) then { - _maxVertical = getArray (_weaponConfig >> "ACE_ScopeAdjust_Vertical"); - }; + private _verticalIncrement = 0; private _maxHorizontal = [0, 0]; - if (isArray (_weaponConfig >> "ACE_ScopeAdjust_Horizontal")) then { + private _horizontalIncrement = 0; + if (GVAR(simplifiedZeroing)) then { + private _maxZeroing = 300 max (getNumber (_weaponConfig >> "maxZeroing")); + private _maxDiscreteDistanceSize = count getArray (configFile >> "CfgWeapons" >> (_newGuns select _x) >> "discreteDistance"); + if (_maxDiscreteDistanceSize < 2 && {getNumber (_weaponConfig >> "ACE_ScopeAdjust_VerticalIncrement") != 0}) then { + _maxVertical = [50, _maxZeroing]; + _verticalIncrement = 50; + }; + } else { + _verticalIncrement = getNumber (_weaponConfig >> "ACE_ScopeAdjust_VerticalIncrement"); + _horizontalIncrement = getNumber (_weaponConfig >> "ACE_ScopeAdjust_HorizontalIncrement"); + _maxVertical = getArray (_weaponConfig >> "ACE_ScopeAdjust_Vertical"); _maxHorizontal = getArray (_weaponConfig >> "ACE_ScopeAdjust_Horizontal"); }; TRACE_5("",_newGuns select _x,_verticalIncrement,_horizontalIncrement,_maxVertical,_maxHorizontal); @@ -99,9 +115,32 @@ private _newGuns = [primaryWeapon _player, secondaryWeapon _player, handgunWeapo GVAR(canAdjustElevation) set [_x, (_verticalIncrement > 0) && !(_maxVertical isEqualTo [0, 0])]; GVAR(canAdjustWindage) set [_x, (_horizontalIncrement > 0) && !(_maxHorizontal isEqualTo [0, 0])]; }; + + // The optic or the weapon changed, reset the adjustment + private _persistentZero = profileNamespace getVariable [format[QGVAR(PersistentZero_%1_%2), _newGuns select _x, _newOptics select _x], 0]; + ((GVAR(scopeAdjust) select _x) select 0) params ["_minElevation", "_maxElevation"]; + if (!(_persistentZero isEqualType 0) || {_persistentZero < _minElevation || _persistentZero > _maxElevation}) then { + _persistentZero = 0; + }; + private _defaultElevation = [0, 300] select GVAR(simplifiedZeroing); + if (!((_adjustment select _forEachIndex) isEqualTo [_defaultElevation, 0, _persistentZero])) then { + _adjustment set [_forEachIndex, [_defaultElevation, 0, _persistentZero]]; + _updateAdjustment = true; + }; } } forEach [0, 1, 2]; +if (GVAR(correctZeroing) || GVAR(simplifiedZeroing)) then { + if (!(_unitBaseAngle isEqualTo (_player getVariable [QGVAR(baseAngle), [0,0,0]]))) then { + TRACE_2("syncing",_unitBaseAngle,_player getVariable QGVAR(baseAngle)); + _player setVariable [QGVAR(baseAngle), _unitBaseAngle, true]; + }; + if (!(_unitBoreHeight isEqualTo (_player getVariable [QGVAR(boreHeight), [0,0,0]]))) then { + TRACE_2("syncing",_unitBoreHeight,_player getVariable QGVAR(boreHeight)); + _player setVariable [QGVAR(boreHeight), _unitBoreHeight, true]; + }; +}; + if (_updateAdjustment) then { [ACE_player, QGVAR(Adjustment), _adjustment, 0.5] call EFUNC(common,setVariablePublic); }; diff --git a/addons/scopes/functions/fnc_resetZero.sqf b/addons/scopes/functions/fnc_resetZero.sqf new file mode 100644 index 0000000000..8d083cf2ee --- /dev/null +++ b/addons/scopes/functions/fnc_resetZero.sqf @@ -0,0 +1,38 @@ +/* + * Author: KoffeinFlummi, Ruthberg + * Resets the zero adjustment of the current scope + * + * Arguments: + * 0: Unit + * + * Return Value: + * true + * + * Example: + * [player] call ace_scopes_fnc_resetZero + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; + +if (vehicle _unit != _unit) exitWith {false}; + +private _weaponClass = currentWeapon _unit; +private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); +if (_weaponIndex < 0) exitWith {false}; + +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _zeroing = _adjustment select _weaponIndex; +_zeroing params ["_elevation", "_windage", "_zero"]; + +_elevation = round((_zero + _elevation) / MIN_INCREMENT) * MIN_INCREMENT; +_zero = 0; + +private _opticsClass = ([_unit] call FUNC(getOptics)) select _weaponIndex; +profileNamespace setVariable [format[QGVAR(PersistentZero_%1_%2), _weaponClass, _opticsClass], nil]; + +[_unit, _elevation, _windage, _zero] call FUNC(applyScopeAdjustment); + +true diff --git a/addons/scopes/functions/fnc_showZeroing.sqf b/addons/scopes/functions/fnc_showZeroing.sqf index cf74e38842..533d68f7e1 100644 --- a/addons/scopes/functions/fnc_showZeroing.sqf +++ b/addons/scopes/functions/fnc_showZeroing.sqf @@ -35,8 +35,34 @@ private _zeroing = _adjustment select _weaponIndex; _zeroing params ["_elevation", "_windage"]; private _vertical = _display displayCtrl 12; private _horizontal = _display displayCtrl 13; -_vertical ctrlSetText (str _elevation); -_horizontal ctrlSetText (str _windage); +if (GVAR(simplifiedZeroing)) then { + _vertical ctrlSetText format["%1 m", round(_elevation)]; + _horizontal ctrlSetText ""; +} else { + if (GVAR(useLegacyUI)) then { + _vertical ctrlSetText (str _elevation); + _horizontal ctrlSetText (str _windage); + } else { + if (_elevation == 0) then { + _vertical ctrlSetText "0"; + } else { + if (_elevation > 0) then { + _vertical ctrlSetText (str _elevation); + } else { + _vertical ctrlSetText format[localize LSTRING(DisplayAdjustmentDown), abs(_elevation)]; + }; + }; + if (_windage == 0) then { + _horizontal ctrlSetText "0"; + } else { + if (_windage > 0) then { + _horizontal ctrlSetText format[localize LSTRING(DisplayAdjustmentRight), abs(_windage)]; + } else { + _horizontal ctrlSetText format[localize LSTRING(DisplayAdjustmentLeft), abs(_windage)]; + }; + }; + }; +}; // Set the time when to hide the knobs GVAR(timeToHide) = diag_tickTime + 3.0; diff --git a/addons/scopes/script_component.hpp b/addons/scopes/script_component.hpp index a797b36191..9e867a9bd2 100644 --- a/addons/scopes/script_component.hpp +++ b/addons/scopes/script_component.hpp @@ -14,6 +14,12 @@ #define MINOR_INCREMENT false #define MAJOR_INCREMENT true +#define MIN_INCREMENT 0.05 // mrad + +#define DEFAULT_RAIL_BASE_ANGLE 0.0086 // deg + +// #define DISABLE_DISPERSION + #ifdef DEBUG_ENABLED_SCOPES #define DEBUG_MODE_FULL #endif diff --git a/addons/scopes/stringtable.xml b/addons/scopes/stringtable.xml index 16898757fd..aac4152678 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -1,8 +1,9 @@ - + Scopes + Zielfernrohre スコープ 조준경 Celowniki optyczne @@ -13,6 +14,7 @@ Enable ACE Scope adjustment + Aktiviere das Nullen von Zielfernrohren ACE スコープ調節を有効化 ACE 조준경 영점조작 활성화 Włącz ustawienia celowników optycznych ACE @@ -22,7 +24,8 @@ 開啟ACE瞄準鏡歸零調節 - Enable adjustmet turrets on high powered scopes + Enable adjustment turrets on high powered scopes + Aktiviere Absehenverstellungen für Waffen mit Zielfernrohren 高倍率スコープでACE スコープ調節を有効化 고성능 조준경 조절 나사 활성화 Włącz pokrętła regulacyjne @@ -33,6 +36,7 @@ Force adjustment turrets + Erzwinge Absehenverstellungen ACE スコープ調節を有効化 조절 나사 강제 Wymuś użycie pokręteł regulacyjnych @@ -43,6 +47,7 @@ Force usage of adjustmet turrets on high powered scopes + Erzwinge Absehenverstellungen für Waffen mit Zielfernrohren 高倍率スコープで調整の使用を強制させます 고성능 조준경의 조절 나사 사용을 강제합니다 Wymuś użycie pokręteł regulacyjnych dla celowników o dużym powiększeniu @@ -53,6 +58,7 @@ Correct zeroing + Nullungsanpassung ゼロイン調節 영점 고치기 Poprawka zerowania @@ -63,6 +69,7 @@ Corrects the zeroing of all small arms sights + Korrigiert alle Nullungen von Handfeuerwaffen 全ての小口径用照準器のゼロインを調節します 모든 소화기의 영점을 고칩니다 Poprawia zerowanie wszystkich celowników broni ręcznej @@ -73,6 +80,7 @@ Overwrite zero distance + Überschreibe Nullung ゼロイン距離を上書き 영점거리 덮어쓰기 Nadpisuje ustawienie dla zerowego dystansu @@ -83,6 +91,7 @@ Uses the 'defaultZeroRange' setting to overwrite the zero range of high power scopes + Nutzt die Einstellung 'defaultZeroRange' um Zielfernrohre anzupassen 'defaultZeroRange'設定を使う高倍率スコープのゼロイン距離を上書きします 기존 고성능 조준경의 영점거리에 '기본설정 영점거리' 를 덮어씌웁니다 Używa 'defaultZeroRange' zamiast ustawionej odległości zerowania dla celowników o duzym przybliżeniu @@ -93,6 +102,7 @@ Default zero distance + Standard Nullung 標準のゼロイン距離 기본설정 영점거리 Domyślne zerowanie @@ -102,7 +112,8 @@ 預設歸零距離 - High power scopes will be zeroed at this distance + High powered scopes will be zeroed at this distance + Zielfernrohre werden auf diese Entfernung genullt 高倍率スコープのゼロイン距離はこの設定になります 고성능 조준경이 정해진 수만큼 영점거리를 맞추게 됩니다. Celowniki o dużym powiększeniu będą zerowane dla tej odległości @@ -113,6 +124,7 @@ Reference temperature + Bezugstemperatur 温度の参照 온도 기준 Referencyjna temperatura @@ -123,6 +135,7 @@ Temperature at which the scope was zeroed + Temperatur bei der das Zielfernrohr genullt wurde スコープがゼロインされる温度 조준경 영점조준시 온도 Temperatura, przy której celownik został wyzerowany @@ -133,6 +146,7 @@ Reference barometric pressure + Bezugsluftdruck 気圧の参照 기압 기준 Referencyjne ciśnienie barometryczne @@ -143,16 +157,18 @@ Barometric pressure at which the scope was zeroed - 気圧の参照 + Luftdruck bei dem das Zielfernrohr genullt wurde + スコープがゼロインされる気圧 조준경 영점조준시 기압 Ciśnienie barometryczne, przy którym celownik został wyzerowany Pression barométrique de référence pour le zérotage des optiques Pressione barometrica a cui è stato azzerato il mirino - 武器参考多少大气压力来进行归零. - 武器參考多少大氣壓力來進行歸零. + 武器参考多少大气压力来进行归零。 + 武器參考多少大氣壓力來進行歸零。 Reference humidity + Bezugsluftfeuchtigkeit 湿度の参照 습도 기준 Referencyjna wilgotność @@ -163,16 +179,18 @@ Humidity at which the scope was zeroed + Luftfeuchtigkeit bei der das Zielfernrohr genullt wurde スコープがゼロインされる湿度 조준경 영점조준시 습도 Wilgotność powietrza, przy której celownik został wyzerowany Taux d'humidité de référence pour le zérotage des optiques Umidità a cui è stato azzerato il mirino - 武器参考多少湿度来进行归零. - 武器參考多少濕度來進行歸零. + 武器参考多少湿度来进行归零。 + 武器參考多少濕度來進行歸零。 Deduce pressure from altitude + Abgeleiteter Luftdruck von der Höhe 高度により圧が減少 고도에 맞춰 기압 설정 Ciśnienie określone na podstawie wysokości @@ -183,6 +201,7 @@ Deduce the barometric pressure from the terrain altitude + Abgeleiteter Luftdruck der Geländeumgebung 標高により気圧が減少されます 주변 고도에 맞춰 기압을 설정합니다 Określ ciśnienie barometryczne na podstawie wysokości terenu @@ -191,14 +210,46 @@ 在不同高度上会有不同的大气压力 在不同高度上會有不同的大氣壓力 + + Use legacy UI + Vorheriges UI verwenden + Usa UI precedente + 使用舊版介面 + 使用旧版介面 + 昔の UI を使用 + 기존 UI 사용 + + + Displays elevation and windage with signed numbers + Anzeige der Absehenverstellungen mit vorzeichenbehafteten Zahlen + Visualizza l'elevazione e la derivazione con i numeri firmati + 使用帶著標籤的數字顯示歸零遠近與風偏程度 + 使用带着标签的数字显示归零远近与风偏程度 + 印付きの数字で仰角と横風を表示 + 기존의 부호가 있는 숫자로 표고와 폭을 표시합니다. + + + Simplified zeroing + Vereinfachte Nullung + 簡略なゼロイン + Azzeramento semplificato + 단순화 된 영점 조정 + + + Replicates the vanilla zeroing system for riflescopes. + Repliziert das Vanilla-Zeroing-System für Zielfernrohre. + 標準で使われるライフルスコープ用のゼロイン システムを複製します。 + Replica il sistema di azzeramento vanilla per le ottiche. + 라이플스코프 용 바닐라 영점조정 시스템을 복제합니다. + Minor adjustment up + Kleine Korrektur hoch Zerowanie powoli w górę Малая корректировка ВВЕРХ Ajuste menor arriba Regola leggermente alzata in alto Hausse + - Kleine Korrektur nach oben Enyhe állítás fel Pequeno ajuste para cima Korekce nahoru (mírně) @@ -209,12 +260,12 @@ Minor adjustment down + Kleine Korrektur runter Zerowanie powoli w dół Малая корректировка ВНИЗ Ajuste menor abajo Regola leggermente alzata in basso Hausse - - Kleine Korrektur nach unten Enyhe állítás le Pequeno ajuste para baixo Korekce dolů (mírně) @@ -225,12 +276,12 @@ Minor adjustment right + Kleine Korrektur rechts Zerowanie powoli w prawo Малая корректировка ВПРАВО Ajuste menor derecha Regola leggermente il tiro a destra Dérive + - Kleine Korrektur nach rechts Enyhe állítás jobbra Pequeno ajuste para direita Korekce doprava (mírně) @@ -241,12 +292,12 @@ Minor adjustment left + Kleine Korrektur links Zerowanie powoli w lewo Малая корректировка ВЛЕВО Ajuste menor izquierda Regola leggermete il tiro a sinistra Dérive - - Kleine Korrektur nach links Enyhe állítás balra Pequeno ajuste para esquerda Korekce doleva (mírně) @@ -257,12 +308,12 @@ Major adjustment up + Große Korrektur hoch Zerowanie w górę Большая корректировка ВВЕРХ Ajuste mayor arriba Regola l'alzata in alto Hausse +++ - Große Korrektur nach oben Nagy állítás fel Ajuste grande para cima Korekce nahoru @@ -273,12 +324,12 @@ Major adjustment down + Große Korrektur runter Zerowanie w dół Большая корректировка ВНИЗ Ajuste mayor abajo Regola l'alzata in basso Hausse - - - - Große Korrektur nach unten Nagy állítás le Ajuste grande para baixo Korekce dolů @@ -289,12 +340,12 @@ Major adjustment right + Große Korrektur rechts Zerowanie w prawo Большая корректировка ВПРАВО Ajuste mayor derecha Regola il tiro a destra Dérive +++ - Große Korrektur nach rechts Nagy állítás jobbra Ajuste grande para direita Korekce doprava @@ -305,12 +356,12 @@ Major adjustment left + Große Korrektur links Zerowanie w lewo Большая корректировка ВЛЕВО Ajuste mayor izquierda Regola il tiro a sinistra Dérive - - - - Große Korrektur nach links Nagy állítás balra Ajuste grande para esquerda Korekce doleva @@ -321,12 +372,12 @@ Set zero adjustment + Nullung durchführen Zresetuj wyzerowanie Сбросить корректировку Establecer ajuste a cero - Resetta i valori del tiro + Imposta i valori dell'azzeramento RAZ corrections - Auf 0 justieren Állítások nullázása Zerar ajuste Vynulovat korekci @@ -335,15 +386,53 @@ 设定归零 設定歸零 + + Reset zero adjustment + Nullung zurücksetzen + ゼロイン調節を初期化 + Resetta i valori dell'azzeramento + 영점 조정 재설정 + This module adds windage and elevation adjustment turrets on high power rifle scopes. - モジュールは高倍率ライフル スコープにおいて横風と仰角の調節ができます。 + Dieses Modul fügt Absehenverstellung (horizontal und vertikal) zu Zielfernrohren hinzu. + このモジュールは高倍率ライフル スコープにおいて横風と仰角の調節ができます。 이 모듈은 고성능 조준경에 조준 나사를 이용한 편차 및 고도 조절 기능을 더해줍니다. Ten moduł włącza pokrętła kalibracyjne poprawki na wiatr oraz poprawki wysokości dla celowników o dużym powiększeniu. Ce module ajoute les tambours de correction de la hausse et de dérive sur les optiques de visée à fort grossissement. Questo modulo aggiunge lo spostamento dell'aria e la regolazione dell'elevazione delle torrette in mirini a lunga gittata - 此模块可为高倍率瞄准镜新增归零风偏, 距离用的调整纽. - 此模塊可為高倍率瞄準鏡新增歸零風偏, 距離用的調整紐. + 此模块可为高倍率瞄准镜新增归零风偏,距离用的调整纽。 + 此模塊可為高倍率瞄準鏡新增歸零風偏,距離用的調整紐。 + + + %1D + %1T + %1B + %1D + %1D + %1D + %1D + %1D + + + %1L + %1L + %1G + %1L + %1L + %1L + %1L + %1L + + + %1R + %1R + %1D + %1R + %1R + %1R + %1R + %1R diff --git a/addons/slideshow/stringtable.xml b/addons/slideshow/stringtable.xml index f563e62e53..3abaa07592 100644 --- a/addons/slideshow/stringtable.xml +++ b/addons/slideshow/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -30,8 +30,8 @@ Questo modulo ti permette di creare una presentazione con diapositive su vari oggetti. Un modulo per lista immagini. Solo oggetti con hiddenSelection 0 sono supportati. さまざまなオブジェクトへスライドショーを設定することができます。1つのモジュールは各画像リストになっています。オブジェクトが hiddenSelection 0へ対応している必要があります。 이 모듈은 다른 물체에 대해 슬라이드 쇼를 놓을 수 있게 해줍니다. 한 모듈당 한 이미지목록만 가능합니다. 또한 물체가 hiddenSelection 0 를 지원해야만합니다. - 此模塊可讓圖片以幻燈片的形式顯示在物件上. 每個模塊都能設定一串幻燈片清單. 被設定的物件不能有隱藏部位(hiddenSelection). - 此模块可让图片以幻灯片的形式显示在物件上. 每个模块都能设定一串幻灯片清单. 被设定的物件不能有隐藏部位(hiddenSelection). + 此模塊可讓圖片以幻燈片的形式顯示在物件上,每個模塊都能設定一串幻燈片清單,被設定的物件不能有隱藏部位(hiddenSelection) + 此模块可让图片以幻灯片的形式显示在物件上,每个模块都能设定一串幻灯片清单,被设定的物件不能有隐藏部位(hiddenSelection) Objects @@ -62,8 +62,8 @@ Nomi di oggetti (possono anche essere oggetti sincronizzati) che verranno usati per la presentazione di diapositive, separato da virgole se più di uno. スライドショーを表示するオブジェクト名 (オブジェクトとの同期も可)。複数ある場合はコンマで区切れます 슬라이드 쇼가 보여질 물체(동기화 되는 물체도 가능합니다) 명칭, 다수의 경우 쉼표로 구분합니다. - 物件名稱 (也可使用同步線來設定), 幻燈片將會顯示在該物件上, 如有多個物件, 請以逗號作區隔. - 物件名称 (也可使用同步线来设定), 幻灯片将会显示在该物件上, 如有多个物件, 请以逗号作区隔. + 物件名稱 (也可使用同步線來設定),幻燈片將會顯示在該物件上,如有多個物件,請以逗號作區隔 + 物件名称 (也可使用同步线来设定),幻灯片将会显示在该物件上,如有多个物件,请以逗号作区隔 Controllers @@ -93,8 +93,8 @@ Nomi di oggetti controllori, separati da virgole se multipli. コントローラに指定するオブジェクト名を記入し、複数ある場合はコンマで区切れます。 조종 장치 물체 명칭, 다수의 경우 쉼표로 구분됩니다. - 指定是控制器的物件名稱, 如有多個物件, 請以逗號作區隔. - 指定是控制器的物件名称, 如有多个物件, 请以逗号作区隔. + 指定是控制器的物件名稱,如有多個物件,請以逗號作區隔 + 指定是控制器的物件名称,如有多个物件,请以逗号作区隔 Images @@ -125,8 +125,8 @@ Lista di immagini che verranno usate durante la presentazione, separati da virgole, con il formato completo del percorso (es. images\image.paa) 完全なパスでスライドショーに使う画像一覧を入力してください。コンマで区別できます。(例: images\image.paa) 슬라이드 쇼에 쓰일 사진목록입니다, 쉼표로 구분됩니다, 경로설정을 정확히 하십시요. (예: 사진\사진.ppa) - 要做為幻燈片的圖片清單, 每個圖片請已逗號區隔, 並輸入完整路徑位址 (例如:images\image.paa). - 要做为幻灯片的图片清单, 每个图片请已逗号区隔, 并输入完整路径位址 (例如:images\image.paa). + 要做為幻燈片的圖片清單,每個圖片請已逗號區隔,並輸入完整路徑位址 (例如:images\image.paa) + 要做为幻灯片的图片清单,每个图片请已逗号区隔,并输入完整路径位址 (例如:images\image.paa) Interaction Names @@ -156,26 +156,30 @@ Liste aller Namen, die für Interaktionseinträge genutzt werden. Mit Kommata getrennt, in Reihenfolge der Bilder. 画像を操作できるインタラクション エントリ名の一覧を入力してください。コンマで区切り複数を指定できます。 상호작용 메세지에 쓰일 명칭입니다, 쉼표로 구분합니다, 이미지의 순서입니다. - 設定互動鍵切換圖片時的按鈕名稱, 多個按鈕請以逗號做區隔, 有多少圖片就輸入多少個按鈕, 以利切換圖片. - 设定互动键切换图片时的按钮名称, 多个按钮请以逗号做区隔, 有多少图片就输入多少个按钮, 以利切换图片. + 設定互動鍵切換圖片時的按鈕名稱,多個按鈕請以逗號做區隔,有多少圖片就輸入多少個按鈕,以利切換圖片 + 设定互动键切换图片时的按钮名称,多个按钮请以逗号做区隔,有多少图片就输入多少个按钮,以利切换图片 Set Name + Setze Namen Ustaw nazwę 名前設定 Définir le nom Imposta Nome 設定名稱 设定名称 + 이름 설정 Name that will be used for main interaction entry (to distinguish multiple slideshows). Default: "Slides" + Name der für den Hauptinteraktionseintrag benutzt wird (um mehrere Diavorführungen voneinander zu trennen). Nazwa, która będzie użyta w głównym menu interakcji (w celu rozróżnienia różnych slajdów). Domyślnie: "Slides" メイン インタラクション エントリで使われる名前を設定します。(複数のスライドショーを区別するため)。標準: "Slides" Un nom qui sera utilisé pour interagir avec plusieurs diaporamas. Par défaut : "Slides" Nome che sarà utilizzato per le principali interazioni (per distinguere le multiple diapositive). Predefinito: "Slides" - 設定該幻燈片的標題名稱 (用來區分多個不同標題的幻燈片.) 預設名稱: "幻燈片" - 设定该幻灯片的标题名称 (用来区分多个不同标题的幻灯片.) 预设名称: "幻灯片" + 設定該幻燈片的標題名稱 (用來區分多個不同標題的幻燈片) 預設名稱: "幻燈片" + 设定该幻灯片的标题名称 (用来区分多个不同标题的幻灯片) 预设名称: "幻灯片" + 상위 상호작용 이름 (여러개의 슬라이드 쇼를 구분하기 위해 사용됨) 기본: "Slides" Slide Duration @@ -206,8 +210,8 @@ Länge der Diavorführung pro Bild. Standard: 0 (Automatischer Wechsel deaktiviert) 各スライドの持続時間。標準:0 (自動的な切り替えは無効) 매 슬라이드의 지속시간. 기본설정: 0 (자동 전환 비활성화) - 每張幻燈片顯示的時間. 預設:0 (自動換圖已禁用) - 每张幻灯片显示的时间. 预设:0 (自动换图已禁用) + 每張幻燈片顯示的時間。 預設:0 (自動換圖已禁用) + 每张幻灯片显示的时间。 预设:0 (自动换图已禁用) Slides diff --git a/addons/smallarms/CfgMagazines.hpp b/addons/smallarms/CfgMagazines.hpp index a9cc718258..ac55a86f6b 100644 --- a/addons/smallarms/CfgMagazines.hpp +++ b/addons/smallarms/CfgMagazines.hpp @@ -6,36 +6,6 @@ class CfgMagazines { // 2. Remove tracers at bottom of magazine. // 3. Do string updates. - // 5.56mm //////////////////////////////////// - - class 30Rnd_556x45_Stanag : CA_Magazine { - displayname = "5.56mm 30Rnd Mag"; - displaynameshort = "5.56mm"; - - tracersEvery = 0; - lastRoundsTracer = 0; - }; - - class 30Rnd_556x45_Stanag_Tracer_Red: 30Rnd_556x45_Stanag { - displayname = "5.56mm 30Rnd Tracer Mag"; - displaynameshort = "5.56mm"; - }; - - class 30Rnd_556x45_Stanag_Tracer_Green: 30Rnd_556x45_Stanag { - displayname = "5.56mm 30Rnd Tracer Mag"; - displaynameshort = "5.56mm"; - }; - - class 30Rnd_556x45_Stanag_Tracer_Yellow: 30Rnd_556x45_Stanag { - displayname = "5.56mm 30Rnd Tracer Mag"; - displaynameshort = "5.56mm"; - }; - - class 20Rnd_556x45_UW_mag: 30Rnd_556x45_Stanag { - displayname = "5.56mm 20Rnd MEA Mag"; - displaynameshort = "5.56mm MEA"; - }; - // 6.5mm ////////////////////////////////////////// class 30Rnd_65x39_caseless_mag : CA_Magazine { // MX!! diff --git a/addons/spectator/ACE_Settings.hpp b/addons/spectator/ACE_Settings.hpp index 31e4ea3fd0..ef74580428 100644 --- a/addons/spectator/ACE_Settings.hpp +++ b/addons/spectator/ACE_Settings.hpp @@ -1,26 +1,21 @@ class ACE_Settings { - class GVAR(filterUnits) { - displayName = CSTRING(units_DisplayName); - description = CSTRING(units_Description); - typeName = "SCALAR"; - value = 2; - values[] = {CSTRING(units_none), CSTRING(units_players), CSTRING(units_playable), CSTRING(units_all)}; - }; - class GVAR(filterSides) { - displayName = CSTRING(sides_DisplayName); - description = CSTRING(sides_Description); - typeName = "SCALAR"; + class GVAR(enableAI) { + category = CSTRING(Module_DisplayName); + displayName = CSTRING(ai_DisplayName); + description = CSTRING(ai_Description); + typeName = "BOOL"; value = 0; - values[] = {CSTRING(sides_player), CSTRING(sides_friendly), CSTRING(sides_hostile), CSTRING(sides_all)}; }; class GVAR(restrictModes) { + category = CSTRING(Module_DisplayName); displayName = CSTRING(modes_DisplayName); description = CSTRING(modes_Description); typeName = "SCALAR"; value = 0; - values[] = {CSTRING(modes_all), CSTRING(modes_unit), CSTRING(modes_free), CSTRING(modes_internal), CSTRING(modes_external)}; + values[] = {CSTRING(modes_all), CSTRING(modes_unit), "$STR_A3_Spectator_free_camera_tooltip", "$STR_A3_Spectator_1pp_camera_tooltip", "$STR_A3_Spectator_3pp_camera_tooltip"}; }; class GVAR(restrictVisions) { + category = CSTRING(Module_DisplayName); displayName = CSTRING(visions_DisplayName); description = CSTRING(visions_Description); typeName = "SCALAR"; diff --git a/addons/spectator/CfgEventHandlers.hpp b/addons/spectator/CfgEventHandlers.hpp index becf395052..7abe7ca4e3 100644 --- a/addons/spectator/CfgEventHandlers.hpp +++ b/addons/spectator/CfgEventHandlers.hpp @@ -16,3 +16,15 @@ class Extended_PostInit_EventHandlers { init = QUOTE(call COMPILE_FILE(XEH_postInit)); }; }; + +class Extended_DisplayLoad_EventHandlers { + class RscRespawnCounter { + ADDON = QUOTE(_this call FUNC(compat_counter)); + }; + class RscDisplayEGSpectator { + ADDON = QUOTE(_this call FUNC(compat_spectatorBI)); + }; + class RscDisplayCurator { + ADDON = QUOTE(_this call FUNC(compat_zeus)); + }; +}; diff --git a/addons/spectator/CfgVehicles.hpp b/addons/spectator/CfgVehicles.hpp index 268aabbef5..772c0fec5f 100644 --- a/addons/spectator/CfgVehicles.hpp +++ b/addons/spectator/CfgVehicles.hpp @@ -1,61 +1,19 @@ class CfgVehicles { class ACE_Module; class GVAR(moduleSettings): ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(Settings_DisplayName); - icon = QPATHTOF(UI\Icon_Module_Spectator_ca.paa); + icon = QPATHTOF(data\Icon_Module_Spectator_ca.paa); category = "ACE"; function = QFUNC(moduleSpectatorSettings); isGlobal = 1; author = ECSTRING(common,ACETeam); class Arguments { - class unitsFilter { - displayName = CSTRING(units_DisplayName); - description = CSTRING(units_Description); - typeName = "NUMBER"; - class values { - class none { - name = CSTRING(units_none); - value = 0; - }; - class players { - name = CSTRING(units_players); - value = 1; - }; - class playable { - name = CSTRING(units_playable); - value = 2; - default = 1; - }; - class all { - name = CSTRING(units_all); - value = 3; - }; - }; - }; - class sidesFilter { - displayName = CSTRING(sides_DisplayName); - description = CSTRING(sides_Description); - typeName = "NUMBER"; - class values { - class player { - name = CSTRING(sides_player); - value = 0; - default = 1; - }; - class friendly { - name = CSTRING(sides_friendly); - value = 1; - }; - class hostile { - name = CSTRING(sides_hostile); - value = 2; - }; - class all { - name = CSTRING(sides_all); - value = 3; - }; - }; + class enableAI { + displayName = CSTRING(ai_DisplayName); + description = CSTRING(ai_Description); + typeName = "BOOL"; + defaultValue = 0; }; class cameraModes { displayName = CSTRING(modes_DisplayName); @@ -72,15 +30,15 @@ class CfgVehicles { value = 1; }; class free { - name = CSTRING(modes_free); + name = "$STR_A3_Spectator_free_camera_tooltip"; value = 2; }; class internal { - name = CSTRING(modes_internal); + name = "$STR_A3_Spectator_1pp_camera_tooltip"; value = 3; }; class external { - name = CSTRING(modes_external); + name = "$STR_A3_Spectator_3pp_camera_tooltip"; value = 4; }; }; @@ -114,4 +72,17 @@ class CfgVehicles { description = CSTRING(Settings_Description); }; }; + class VirtualMan_F; + class GVAR(virtual): VirtualMan_F { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(Settings_DisplayName); + scope = 2; + scopeArsenal = 0; + scopeCurator = 0; + + weapons[] = {}; + + delete ACE_Actions; + delete ACE_SelfActions; + }; }; diff --git a/addons/spectator/UI/interface.hpp b/addons/spectator/UI/interface.hpp deleted file mode 100644 index 8c566844ee..0000000000 --- a/addons/spectator/UI/interface.hpp +++ /dev/null @@ -1,255 +0,0 @@ -// Temporary fix until BI take care of it -class RscFrame { - x = 0; - y = 0; - w = 0; - h = 0; -}; - - -class RscButtonMenu; -class RscControlsGroupNoScrollbars; -//class RscFrame; -class RscListBox; -class RscMapControl; -class RscPicture; -class RscText; -class RscTree; - -class GVAR(interface) { - idd = 12249; - enableSimulation = 1; - movingEnable = 0; - onLoad = QUOTE([ARR_2('onLoad',_this)] call FUNC(handleInterface)); - onUnload = QUOTE([ARR_2('onUnload',_this)] call FUNC(handleInterface)); - onKeyDown = QUOTE([ARR_2('onKeyDown',_this)] call FUNC(handleInterface)); - onKeyUp = QUOTE([ARR_2('onKeyUp',_this)] call FUNC(handleInterface)); - class controlsBackground { - class mouseHandler: RscControlsGroupNoScrollbars { - x = safeZoneXAbs; - y = safeZoneY; - w = safeZoneWAbs; - h = safeZoneH; - onMouseButtonDown = QUOTE([ARR_2('onMouseButtonDown',_this)] call FUNC(handleInterface)); - onMouseButtonUp = QUOTE([ARR_2('onMouseButtonUp',_this)] call FUNC(handleInterface)); - onMouseZChanged = QUOTE([ARR_2('onMouseZChanged',_this)] call FUNC(handleInterface)); - onMouseMoving = QUOTE([ARR_2('onMouseMoving',_this)] call FUNC(handleInterface)); - onMouseHolding = QUOTE([ARR_2('onMouseMoving',_this)] call FUNC(handleInterface)); - }; - }; - class controls { - class compass: RscControlsGroupNoScrollbars { - idc = IDC_COMP; - x = COMPASS_X; - y = safeZoneY; - w = COMPASS_W; - h = TOOL_H; - class controls { - class compassBack: RscText { - x = 0; - y = 0; - w = COMPASS_W; - h = TOOL_H; - colorBackground[] = {COL_BACK}; - }; - class compass0_90: RscPicture { - idc = IDC_COMP_0; - x = COMPASS_W * 0.5; - y = 0; - w = COMPASS_W * 0.5; - h = TOOL_H; - text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture180_ca.paa"; - }; - class compass90_180: compass0_90 { - idc = IDC_COMP_90; - x = COMPASS_W; - text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture270_ca.paa"; - }; - class compass180_270: compass0_90 { - idc = IDC_COMP_180; - x = 0; - text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture0_ca.paa"; - }; - class compass270_0: compass0_90 { - idc = IDC_COMP_270; - x = COMPASS_W * -0.5; - text = "A3\UI_F_Curator\Data\CfgIngameUI\compass\texture90_ca.paa"; - }; - class compassCaret: RscFrame { - x = COMPASS_W * 0.5; - y = 0; - w = 0; - h = TOOL_H; - colorText[] = {COL_FORE}; - }; - class compassFrame: compassBack { - style = 64; - shadow=2; - colorText[] = {COL_FORE}; - }; - }; - }; - class toolbar: RscControlsGroupNoScrollbars { - idc = IDC_TOOL; - x = safeZoneX; - y = safeZoneY + safeZoneH - TOOL_H; - w = safeZoneW; - h = TOOL_H; - class controls { - class nameTool: RscText { - idc = IDC_TOOL_NAME; - style = 2; - x = 0; - y = 0; - w = TOOL_W * 2; - h = TOOL_H; - shadow = 2; - colorText[]={COL_FORE}; - colorBackground[] = {COL_BACK}; - sizeEx = H_PART(1); - }; - class nameFrame: nameTool { - idc = -1; - style = 64; - }; - class viewTool: nameTool { - idc = IDC_TOOL_VIEW; - x = TOOL_W * 2 + MARGIN; - w = TOOL_W; - }; - class viewFrame: viewTool { - idc = -1; - style = 64; - }; - class visionTool: viewTool { - idc = IDC_TOOL_VISION; - x = TOOL_W * 3 + MARGIN * 2; - }; - class visionFrame: visionTool { - idc = -1; - style = 64; - }; - class clockTool: viewTool { - idc = IDC_TOOL_CLOCK; - x = safeZoneW - TOOL_W * 3 - MARGIN * 2; - }; - class clockFrame: clockTool { - idc = -1; - style = 64; - }; - class zoomTool: viewTool { - idc = IDC_TOOL_FOV; - x = safeZoneW - TOOL_W * 2 - MARGIN; - }; - class zoomFrame: zoomTool { - idc = -1; - style = 64; - }; - class speedTool: viewTool { - idc = IDC_TOOL_SPEED; - x = safeZoneW - TOOL_W; - }; - class speedFrame: speedTool { - idc = -1; - style = 64; - }; - }; - }; - class unitWindow: RscControlsGroupNoScrollbars { - idc = IDC_UNIT; - x = safeZoneX; - y = safeZoneY + TOOL_H * 6; - w = TOOL_W * 2; - h = safeZoneH - TOOL_H * 13; - class controls { - class unitTitle: RscText { - x = 0; - y = 0; - w = TOOL_W * 2; - h = H_PART(1); - style = 2; - colorText[] = {COL_FORE}; - colorBackground[] = {COL_FORE_D}; - sizeEx = H_PART(1); - text = CSTRING(UnitTitle); - }; - class unitTree: RscTree { - idc = IDC_UNIT_TREE; - x = 0; - y = H_PART(1); - w = TOOL_W * 2; - h = safeZoneH - TOOL_H * 14; - sizeEx = H_PART(0.8); - colorText[] = {COL_FORE}; - colorBorder[] = {0,0,0,0}; - colorBackground[] = {COL_BACK}; - colorSelect[] = { - "profilenamespace getVariable ['GUI_BCG_RGB_R',0.77]", - "profilenamespace getVariable ['GUI_BCG_RGB_G',0.51]", - "profilenamespace getVariable ['GUI_BCG_RGB_B',0.08]", - 1 - }; - multiselectEnabled = 0; - disableKeyboardSearch = 1; - onTreeDblClick = QUOTE([ARR_2('onTreeDblClick',_this)] call FUNC(handleInterface)); - }; - class unitFrame: RscFrame { - x = 0; - y = 0; - w = TOOL_W * 2; - h = safeZoneH - TOOL_H * 13; - shadow = 2; - colorText[] = {COL_FORE}; - }; - }; - }; - class helpWindow: RscControlsGroupNoScrollbars { - idc = IDC_HELP; - x = safeZoneX + safeZoneW - TOOL_W * 2; - y = safeZoneY + TOOL_H * 6; - w = TOOL_W * 2; - h = safeZoneH - TOOL_H * 13; - class controls { - class helpTitle: RscText { - x = 0; - y = 0; - w = TOOL_W * 2; - h = H_PART(1); - style = 2; - colorText[] = {COL_FORE}; - colorBackground[] = {COL_FORE_D}; - sizeEx = H_PART(1); - text = CSTRING(HelpTitle); - }; - class helpContent: RscListBox { - idc = IDC_HELP_LIST; - x = 0; - y = H_PART(1); - w = TOOL_W * 2; - h = safeZoneH - TOOL_H * 14; - colorBackground[] = {COL_BACK}; - sizeEx = H_PART(0.8); - default = 1; - }; - class helpFrame: RscFrame { - x = 0; - y = 0; - w = TOOL_W * 2; - h = safeZoneH - TOOL_H * 13; - shadow = 2; - colorText[] = {COL_FORE}; - }; - }; - }; - class mapOverlay: RscMapControl { - idc = IDC_MAP; - type = 100; - x = safeZoneX; - y = safeZoneY; - w = safeZoneW; - h = safeZoneH; - onMouseButtonDown = QUOTE([ARR_2('onMapClick',_this)] call FUNC(handleInterface)); - onDraw = QUOTE(_this call FUNC(handleMap)); - }; - }; -}; diff --git a/addons/spectator/XEH_PREP.hpp b/addons/spectator/XEH_PREP.hpp index cc29fde611..ddca0c226c 100644 --- a/addons/spectator/XEH_PREP.hpp +++ b/addons/spectator/XEH_PREP.hpp @@ -1,23 +1,56 @@ +// Camera functions +PREP(cam); +PREP(cam_prepareTarget); +PREP(cam_resetTarget); +PREP(cam_setCameraMode); +PREP(cam_setTarget); +PREP(cam_setVisionMode); +PREP(cam_tick); +PREP(cam_toggleSlow); -PREP(cacheUnitInfo); -PREP(cycleCamera); -PREP(handleCamera); -PREP(handleCompass); -PREP(handleIcons); -PREP(handleInterface); -PREP(handleMap); -PREP(handleMouse); -PREP(handleToolbar); -PREP(handleUnits); -PREP(interrupt); +// UI functions +PREP(ui); +PREP(ui_draw3D); +PREP(ui_fadeList); +PREP(ui_getTreeDataIndex); +PREP(ui_handleChildDestroyed); +PREP(ui_handleKeyDown); +PREP(ui_handleKeyUp); +PREP(ui_handleListClick); +PREP(ui_handleLoad); +PREP(ui_handleMapClick); +PREP(ui_handleMapDraw); +PREP(ui_handleMouseButtonDblClick); +PREP(ui_handleMouseButtonDown); +PREP(ui_handleMouseMoving); +PREP(ui_handleMouseZChanged); +PREP(ui_toggleMap); +PREP(ui_toggleUI); +PREP(ui_updateCamButtons); +PREP(ui_updateHelp); +PREP(ui_updateIconsToDraw); +PREP(ui_updateListEntities); +PREP(ui_updateListFocus); +PREP(ui_updateWidget); + +// Utility functions +PREP(compat_counter); +PREP(compat_spectatorBI); +PREP(compat_zeus); +PREP(getGroupIcon); +PREP(getTargetEntities); +PREP(handleFired); PREP(moduleSpectatorSettings); PREP(respawnTemplate); +PREP(setFocus); +PREP(switchFocus); + +// Public functions +PREP(getCameraAttributes); +PREP(players); PREP(setCameraAttributes); PREP(setSpectator); -PREP(stageSpectator); -PREP(transitionCamera); -PREP(toggleInterface); PREP(updateCameraModes); -PREP(updateSpectatableSides); +PREP(updateSides); PREP(updateUnits); PREP(updateVisionModes); diff --git a/addons/spectator/XEH_postInit.sqf b/addons/spectator/XEH_postInit.sqf index 72c53a2af0..715dbe1c3d 100644 --- a/addons/spectator/XEH_postInit.sqf +++ b/addons/spectator/XEH_postInit.sqf @@ -1,31 +1,36 @@ #include "script_component.hpp" -//#include "initKeybinds.sqf"; - -// Add interaction menu exception -["isNotSpectating", {!(GETVAR((_this select 0),GVAR(isStaged),false))}] call EFUNC(common,addCanInteractWithCondition); ["ace_settingsInitialized", { GVAR(availableModes) = [[0,1,2], [1,2], [0], [1], [2]] select GVAR(restrictModes); GVAR(availableVisions) = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select GVAR(restrictVisions); }] call CBA_fnc_addEventHandler; -// Create a radio channel for any spectators to text chat in if (isServer) then { + // Create a radio channel for any spectators to text chat in GVAR(channel) = radioChannelCreate [[0.729,0.149,0.098,1],"Spectator","Spectator (%UNIT_NAME)",[]]; publicVariable QGVAR(channel); + + // Used by the template to transfer zeus to virtual unit + // Commands must be ran on server + [QGVAR(transferZeus),{ + unassignCurator (_this select 1); + + // Can only re-assign when ready + [ + {isNull getAssignedCuratorUnit (_this select 0)}, + {(_this select 0) assignCurator (_this select 1)}, + _this + ] call CBA_fnc_waitUntilAndExecute; + }] call CBA_fnc_addEventHandler; }; -// Should prevent unending spectator on mission end -if (isServer) then { - addMissionEventHandler ["Ended", { - [QGVAR(endMission), []] call CBA_fnc_globalEvent; - }]; +// A virtual spectator cannot exist without an interface +if (hasInterface) then { + // Local player (not ACE_Player) must be initalized to check + [ + { !isNull player }, + { + if (player isKindOf QGVAR(virtual)) then { [true] call FUNC(setSpectator); }; + } + ] call CBA_fnc_waitUntilAndExecute; }; - -[QGVAR(endMission), { - if (GVAR(isSet)) then { - [false] call FUNC(setSpectator); - }; -}] call CBA_fnc_addEventHandler; - -[QGVAR(stageSpectator), FUNC(stageSpectator)] call CBA_fnc_addEventHandler; diff --git a/addons/spectator/XEH_preInit.sqf b/addons/spectator/XEH_preInit.sqf index 4bdf07b3a1..8220b21520 100644 --- a/addons/spectator/XEH_preInit.sqf +++ b/addons/spectator/XEH_preInit.sqf @@ -6,39 +6,15 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -// Reset the stored display -SETUVAR(GVAR(interface),displayNull); - -// Permanent variables -GVAR(availableModes) = [0,1,2]; +// Used by public functions +GVAR(availableModes) = [MODE_FREE, MODE_FPS, MODE_FOLLOW]; GVAR(availableSides) = [west,east,resistance,civilian]; -GVAR(availableVisions) = [-2,-1,0,1]; - -GVAR(camAgent) = objNull; -GVAR(camDistance) = 10; -GVAR(camMode) = 0; -GVAR(camPan) = 0; -GVAR(camPos) = ATLtoASL [worldSize * 0.5, worldSize * 0.5, 20]; -GVAR(camSpeed) = 1.5; -GVAR(camTilt) = -10; -GVAR(camUnit) = objNull; -GVAR(camVision) = -2; -GVAR(camZoom) = 1.25; - +GVAR(availableVisions) = [VISION_NORM,VISION_NVG,0,1]; GVAR(interrupts) = []; -GVAR(isSet) = false; - -GVAR(showComp) = true; -GVAR(showHelp) = true; -GVAR(showIcons) = true; -GVAR(showInterface) = true; -GVAR(showMap) = false; -GVAR(showTool) = true; -GVAR(showUnit) = true; - -GVAR(unitList) = []; GVAR(unitBlacklist) = []; GVAR(unitWhitelist) = []; -GVAR(groupList) = []; + +// Tracks whether spectator is active +GVAR(isSet) = false; ADDON = true; diff --git a/addons/spectator/config.cpp b/addons/spectator/config.cpp index 934bfd5f63..359b96135b 100644 --- a/addons/spectator/config.cpp +++ b/addons/spectator/config.cpp @@ -17,13 +17,13 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" -#include "UI\interface.hpp" +#include "ui.hpp" class CfgRespawnTemplates { class ADDON { - displayName = CSTRING(DisplayName); + displayName = CSTRING(Settings_DisplayName); onPlayerKilled = QFUNC(respawnTemplate); onPlayerRespawn = QFUNC(respawnTemplate); - respawnTypes[] = {2,3}; + respawnTypes[] = {1,2,3,4,5}; }; }; diff --git a/addons/spectator/UI/Icon_Module_Spectator_ca.paa b/addons/spectator/data/Icon_Module_Spectator_ca.paa similarity index 100% rename from addons/spectator/UI/Icon_Module_Spectator_ca.paa rename to addons/spectator/data/Icon_Module_Spectator_ca.paa diff --git a/addons/spectator/data/b_air.paa b/addons/spectator/data/b_air.paa new file mode 100644 index 0000000000..eeb69e354a Binary files /dev/null and b/addons/spectator/data/b_air.paa differ diff --git a/addons/spectator/data/b_armor.paa b/addons/spectator/data/b_armor.paa new file mode 100644 index 0000000000..8e3922f0b1 Binary files /dev/null and b/addons/spectator/data/b_armor.paa differ diff --git a/addons/spectator/data/b_art.paa b/addons/spectator/data/b_art.paa new file mode 100644 index 0000000000..0aac8b828e Binary files /dev/null and b/addons/spectator/data/b_art.paa differ diff --git a/addons/spectator/data/b_inf.paa b/addons/spectator/data/b_inf.paa new file mode 100644 index 0000000000..235c2080c3 Binary files /dev/null and b/addons/spectator/data/b_inf.paa differ diff --git a/addons/spectator/data/b_installation.paa b/addons/spectator/data/b_installation.paa new file mode 100644 index 0000000000..3ce55f2d36 Binary files /dev/null and b/addons/spectator/data/b_installation.paa differ diff --git a/addons/spectator/data/b_maint.paa b/addons/spectator/data/b_maint.paa new file mode 100644 index 0000000000..53b969a731 Binary files /dev/null and b/addons/spectator/data/b_maint.paa differ diff --git a/addons/spectator/data/b_mech_inf.paa b/addons/spectator/data/b_mech_inf.paa new file mode 100644 index 0000000000..967cbe7ee1 Binary files /dev/null and b/addons/spectator/data/b_mech_inf.paa differ diff --git a/addons/spectator/data/b_med.paa b/addons/spectator/data/b_med.paa new file mode 100644 index 0000000000..82bccdef5e Binary files /dev/null and b/addons/spectator/data/b_med.paa differ diff --git a/addons/spectator/data/b_mortar.paa b/addons/spectator/data/b_mortar.paa new file mode 100644 index 0000000000..331bdcbcb0 Binary files /dev/null and b/addons/spectator/data/b_mortar.paa differ diff --git a/addons/spectator/data/b_motor_inf.paa b/addons/spectator/data/b_motor_inf.paa new file mode 100644 index 0000000000..d78ddfc9d6 Binary files /dev/null and b/addons/spectator/data/b_motor_inf.paa differ diff --git a/addons/spectator/data/b_naval.paa b/addons/spectator/data/b_naval.paa new file mode 100644 index 0000000000..812355fbc2 Binary files /dev/null and b/addons/spectator/data/b_naval.paa differ diff --git a/addons/spectator/data/b_plane.paa b/addons/spectator/data/b_plane.paa new file mode 100644 index 0000000000..d7be073299 Binary files /dev/null and b/addons/spectator/data/b_plane.paa differ diff --git a/addons/spectator/data/b_recon.paa b/addons/spectator/data/b_recon.paa new file mode 100644 index 0000000000..5c5dc8bb3d Binary files /dev/null and b/addons/spectator/data/b_recon.paa differ diff --git a/addons/spectator/data/b_service.paa b/addons/spectator/data/b_service.paa new file mode 100644 index 0000000000..3c74ca018c Binary files /dev/null and b/addons/spectator/data/b_service.paa differ diff --git a/addons/spectator/data/b_support.paa b/addons/spectator/data/b_support.paa new file mode 100644 index 0000000000..56d3773b93 Binary files /dev/null and b/addons/spectator/data/b_support.paa differ diff --git a/addons/spectator/data/b_uav.paa b/addons/spectator/data/b_uav.paa new file mode 100644 index 0000000000..e900cc2509 Binary files /dev/null and b/addons/spectator/data/b_uav.paa differ diff --git a/addons/spectator/data/b_unknown.paa b/addons/spectator/data/b_unknown.paa new file mode 100644 index 0000000000..f92ffbe9cb Binary files /dev/null and b/addons/spectator/data/b_unknown.paa differ diff --git a/addons/spectator/data/c_air.paa b/addons/spectator/data/c_air.paa new file mode 100644 index 0000000000..4170013fe2 Binary files /dev/null and b/addons/spectator/data/c_air.paa differ diff --git a/addons/spectator/data/c_car.paa b/addons/spectator/data/c_car.paa new file mode 100644 index 0000000000..832e17cbd6 Binary files /dev/null and b/addons/spectator/data/c_car.paa differ diff --git a/addons/spectator/data/c_plane.paa b/addons/spectator/data/c_plane.paa new file mode 100644 index 0000000000..d12fa68fbe Binary files /dev/null and b/addons/spectator/data/c_plane.paa differ diff --git a/addons/spectator/data/c_ship.paa b/addons/spectator/data/c_ship.paa new file mode 100644 index 0000000000..f53701175a Binary files /dev/null and b/addons/spectator/data/c_ship.paa differ diff --git a/addons/spectator/data/c_unknown.paa b/addons/spectator/data/c_unknown.paa new file mode 100644 index 0000000000..f67a3b5444 Binary files /dev/null and b/addons/spectator/data/c_unknown.paa differ diff --git a/addons/spectator/functions/fnc_cacheUnitInfo.sqf b/addons/spectator/functions/fnc_cacheUnitInfo.sqf deleted file mode 100644 index 9f40651748..0000000000 --- a/addons/spectator/functions/fnc_cacheUnitInfo.sqf +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Author: SilentSpike - * Caches the units information for quick retrevial in spectator interface PFHs - * - * Arguments: - * 0: Unit to have info cached for - * - * Return Value: - * None - * - * Example: - * [vehicle player] call ace_spectator_fnc_cacheUnitInfo - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_unit"]; -private ["_color","_icon","_name"]; - -// Group info only needs to be cached once (groups can't change) -if (isNil { GETVAR((group _unit),GVAR(gColor),nil) }) then { - _color = [side group _unit] call BIS_fnc_sideColor; - SETVAR((group _unit),GVAR(gColor),_color); -}; - -// Unit info should be updated each time -_icon = getText (configFile >> "CfgVehicles" >> typeOf _unit >> "Icon"); -_name = [_unit,false] call EFUNC(common,getName); - -// Handle CfgVehicleIcons -if (isText (configFile >> "CfgVehicleIcons" >> _icon)) then { - _icon = getText (configFile >> "CfgVehicleIcons" >> _icon); -}; - -SETVAR(_unit,GVAR(uIcon),_icon); -SETVAR(_unit,GVAR(uName),_name); diff --git a/addons/spectator/functions/fnc_cam.sqf b/addons/spectator/functions/fnc_cam.sqf new file mode 100644 index 0000000000..992476d53f --- /dev/null +++ b/addons/spectator/functions/fnc_cam.sqf @@ -0,0 +1,150 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Handles camera initialisation and destruction + * + * Arguments: + * 0: Init/Terminate + * + * Return Value: + * None + * + * Example: + * [true] call ace_spectator_fnc_cam + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_init"]; +TRACE_1("cam",_init); + +// No change +if (_init isEqualTo !isNil QGVAR(camera)) exitWith {}; + +// Note that init and destroy intentionally happen in reverse order +// Init: Vars > Camera > Camera Stuff +// Destroy: Camera Stuff > Camera > Vars +if (_init) then { + // Start tracking camera attributes if not pre-set by public function + ISNILS(GVAR(camMode),MODE_FREE); + ISNILS(GVAR(camVision),VISION_NORM); + ISNILS(GVAR(camFocus),objNull); + + // Ticking related + GVAR(camDeltaTime) = 0; + GVAR(camLastTickTime) = 0; + GVAR(camHasTarget) = false; + GVAR(camTargetInVehicle) = false; + + // Follow camera related + GVAR(camDistance) = 0; + GVAR(camDistanceTrue) = 0; + GVAR(camYaw) = 0; + GVAR(camPitch) = 0; + + // Toggles + GVAR(camSlow) = false; + GVAR(camLights) = []; + GVAR(camLight) = false; + + // Handle pre-set pos and dir (delete GVARs when done) + private _pos = if (isNil QGVAR(camPos)) then {eyePos player} else {GVAR(camPos)}; + private _dir = if (isNil QGVAR(camDir)) then {getDirVisual player} else {GVAR(camDir)}; + GVAR(camPos) = nil; + GVAR(camDir) = nil; + + // Create the camera (CamCurator required for engine driven controls) + private _camera = "CamCurator" camCreate _pos; + + if (isNull _camera) exitWith { ERROR("Camera wasn't created successfully"); }; + + // Switch to the camera and set its attributes + _camera cameraEffect ["internal", "back"]; + _camera setPosASL _pos; + _camera setDir _dir; + _camera camCommand "maxPitch 89"; + _camera camCommand "minPitch -89"; + _camera camCommand format ["speedDefault %1", SPEED_DEFAULT]; + _camera camCommand format ["speedMax %1", SPEED_FAST]; + _camera camCommand "ceilingHeight 5000"; + cameraEffectEnableHUD true; + + // If camera followed terrain it would be annoying to track units, etc. + _camera camCommand "atl off"; + + // Camera speed should be consistent irrespective of height (painfully slow otherwise) + _camera camCommand "surfaceSpeed off"; + + // Store camera + GVAR(camera) = _camera; + + // Create agent used to fix draw3D in free camera for case where player is perma-dead + GVAR(camAgentFree) = createAgent [QGVAR(virtual), [0,0,0], [], 0, "NONE"]; + GVAR(camAgentFree) enableSimulation false; // Prevent falling into water + + // Create dummy target used for follow camera + GVAR(camDummy) = "Logic" createVehicleLocal getPosASLVisual GVAR(camFocus); + + // Handle initial camera mode limitation + if !(GVAR(camMode) in GVAR(availableModes)) then { + GVAR(camMode) = GVAR(availableModes) select 0; + }; + + // If inital camera mode is not free cam and no focus, find initial focus + if (GVAR(camMode) != MODE_FREE && isNull GVAR(camFocus)) then { + [true] call FUNC(setFocus); + }; + + // Set the initial camera mode (could be pre-set or limited) + [GVAR(camMode)] call FUNC(cam_setCameraMode); + + // Handle initial vision mode limitation + if !(GVAR(camVision) in GVAR(availableVisions)) then { + GVAR(camVision) = GVAR(availableVisions) select 0; + }; + + // Set the initial vision mode (could be pre-set or limited) + [GVAR(camVision)] call FUNC(cam_setVisionMode); + + // Start ticking (follow camera requires EachFrame to avoid jitter) + GVAR(camTick) = addMissionEventHandler ["EachFrame", {call FUNC(cam_tick)}]; +} else { + // Stop ticking + removeMissionEventHandler ["EachFrame", GVAR(camTick)]; + GVAR(camTick) = nil; + + // Return to player view + if !(isNull GVAR(camera)) then { + GVAR(camera) cameraEffect ["terminate", "back"]; + deleteVehicle GVAR(camera); + }; + player switchCamera "internal"; + + // Remove camera variable + GVAR(camera) = nil; + + // Destroy free camera agent + deleteVehicle GVAR(camAgentFree); + GVAR(camAgentFree) = nil; + + // Destroy dummy target + deleteVehicle GVAR(camDummy); + GVAR(camDummy) = nil; + + // Stop tracking everything + GVAR(camMode) = nil; + GVAR(camVision) = nil; + GVAR(camFocus) = nil; + GVAR(camDeltaTime) = nil; + GVAR(camLastTickTime) = nil; + GVAR(camHasTarget) = nil; + GVAR(camTargetInVehicle) = nil; + GVAR(camDistance) = nil; + GVAR(camDistanceTrue) = nil; + GVAR(camYaw) = nil; + GVAR(camPitch) = nil; + GVAR(camSlow) = nil; + GVAR(camLights) = nil; + GVAR(camLight) = nil; +}; diff --git a/addons/spectator/functions/fnc_cam_prepareTarget.sqf b/addons/spectator/functions/fnc_cam_prepareTarget.sqf new file mode 100644 index 0000000000..81bec1504e --- /dev/null +++ b/addons/spectator/functions/fnc_cam_prepareTarget.sqf @@ -0,0 +1,55 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Moves the spectator camera to a position relative to the camera focus. + * Used for 3PP camera and teleporting, etc. + * + * Arguments: + * 0: New Target + * + * Return Value: + * None + * + * Example: + * [player] call ace_spectator_fnc_cam_prepareTarget + * + * Public: No + */ + +#include "script_component.hpp" + +private _focus = vehicle (param [0, objNull, [objNull]]); +TRACE_1("cam_prepareTarget",_focus); + +if !(isNull _focus) then { + // Zooming takes place smoothly over multiple frames + // _zoom is target set by user, _zoomTrue is actual value each frame + private _zoom = [0, GVAR(camDistance)] select (GVAR(camMode) == MODE_FOLLOW); + private _zoomTrue = GVAR(camDistanceTrue); + + // Interpolate zoom each frame until desired zoom is reached + if (_zoomTrue != _zoom) then { + _zoomTrue = (_zoomTrue * (1 - GVAR(camDeltaTime) * 10)) + (_zoom * GVAR(camDeltaTime) * 10); + GVAR(camDistanceTrue) = _zoomTrue; + TRACE_2("new zoom",GVAR(camDeltaTime),_zoomTrue); + }; + + // The distance at which to place camera from the focus pivot + private _bbd = [_focus] call BIS_fnc_getObjectBBD; + private _distance = (_bbd select 1) + _zoomTrue; + + // The pivot on the target vehicle + private _isMan = _focus isKindOf "Man"; + private _height = if !(_isMan) then { (_bbd select 2) / 3 } else { switch (stance _focus) do { case "STAND": {1.4}; case "CROUCH": {0.8}; default {0.4}; }; }; + + private _center = if (_isMan) then { AGLToASL (_focus modelToWorldVisual (_focus selectionPosition "Spine3")) } else { AGLToASL (_focus modelToWorldVisual [0,0,_height]) }; + + // Set dummy location and rotation + private _dummy = GVAR(camDummy); + + _dummy setPosASL _center; + [_dummy, [GVAR(camYaw), GVAR(camPitch), 0]] call BIS_fnc_setObjectRotation; + + // Apply location and rotation to camera + GVAR(camera) setPosASL (AGLToASL (_dummy modelToWorldVisual [0, -_distance, 0])); + GVAR(camera) setVectorDirAndUp [vectorDirVisual _dummy, vectorUpVisual _dummy]; +}; diff --git a/addons/spectator/functions/fnc_cam_resetTarget.sqf b/addons/spectator/functions/fnc_cam_resetTarget.sqf new file mode 100644 index 0000000000..94f934d6d6 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_resetTarget.sqf @@ -0,0 +1,29 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Removes the current camera interest and detaches dummy target. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_cam_resetTarget + * + * Public: No + */ + +#include "script_component.hpp" + +private _camera = GVAR(camera); +private _dummy = GVAR(camDummy); + +if !(isNull _camera || isNull _dummy) then { + _camera camPrepareTarget objNull; + _camera camCommitPrepared 0; + + detach _dummy; + + GVAR(camHasTarget) = false; +}; diff --git a/addons/spectator/functions/fnc_cam_setCameraMode.sqf b/addons/spectator/functions/fnc_cam_setCameraMode.sqf new file mode 100644 index 0000000000..02238ed91e --- /dev/null +++ b/addons/spectator/functions/fnc_cam_setCameraMode.sqf @@ -0,0 +1,89 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to select the camera mode + * + * Intended to run even if new mode == old mode, as it handles focus + * + * Arguments: + * 0: New camera mode + * + * Return Value: + * None + * + * Example: + * [1] call ace_spectator_fnc_cam_setCameraMode + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_newMode"]; + +private _oldMode = GVAR(camMode); +private _modes = GVAR(availableModes); +private _focus = GVAR(camFocus); + +// If new mode isn't available then keep current (unless current also isn't) +if !(_newMode in _modes) then { + _newMode = _modes select ((_modes find _oldMode) max 0); +}; + +// Can't switch camera from free mode with no focus selected +if (!isNull _focus || _newMode == MODE_FREE) then { + private _camera = GVAR(camera); + private _showHUD = [true,true,true,true,true,true,true,true]; + + if (_newMode == MODE_FPS) then { + _camera cameraEffect ["Terminate", "BACK"]; + _focus switchCamera "INTERNAL"; + + // Reset vision mode + [VISION_NORM] call FUNC(cam_setVisionMode); + + [] call FUNC(cam_resetTarget); + + // Disable camera input + _camera camCommand "manual off"; + + // Hide all unit/group information in first person view + _showHUD = [true,false,false,false,false,false,false,true]; + }; + + if (_newMode == MODE_FOLLOW) then { + _camera cameraEffect ["Internal", "BACK"]; + _focus switchCamera "EXTERNAL"; + + [] call FUNC(cam_resetTarget); + + // Disable camera input + _camera camCommand "manual off"; + }; + + if (_newMode == MODE_FREE) then { + _camera cameraEffect ["Internal", "BACK"]; + switchCamera GVAR(camAgentFree); // Fix draw3D while in free camera for case where player is perma-dead + _camera setDir getDirVisual _camera; + + if (!isNull _focus) then { + if (_oldMode == MODE_FPS) then { + [_focus] call FUNC(cam_prepareTarget); + }; + [_focus] call FUNC(cam_setTarget); + }; + + // Enable camera input + _camera camCommand "manual on"; + }; + + // Update the HUD + cameraEffectEnableHUD true; + showHUD _showHUD; + GVAR(camMode) = _newMode; + + // Only update display if it exists, this function is independent of it + if !(isNull SPEC_DISPLAY) then { + [] call FUNC(ui_updateCamButtons); + [] call FUNC(ui_updateHelp); + }; +}; diff --git a/addons/spectator/functions/fnc_cam_setTarget.sqf b/addons/spectator/functions/fnc_cam_setTarget.sqf new file mode 100644 index 0000000000..51cd80215a --- /dev/null +++ b/addons/spectator/functions/fnc_cam_setTarget.sqf @@ -0,0 +1,32 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Sets the current camera interest using dummy target. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [player] call ace_spectator_fnc_cam_setTarget + * + * Public: No + */ + +#include "script_component.hpp" +#define CAMERA_TARGET_CHANGE_TIME 0.5 + +params ["_object"]; + +private _camera = GVAR(camera); +private _dummy = GVAR(camDummy); +private _location = _object worldToModel (_object modelToWorldVisual (_object selectionPosition "Head")); + +if (!isNull _camera && !isNull _dummy) then { + _dummy attachTo [vehicle _object, _location]; + _camera camPrepareTarget _dummy; + _camera camCommitPrepared CAMERA_TARGET_CHANGE_TIME; + + GVAR(camhasTarget) = true; +}; diff --git a/addons/spectator/functions/fnc_cam_setVisionMode.sqf b/addons/spectator/functions/fnc_cam_setVisionMode.sqf new file mode 100644 index 0000000000..c9eed499fe --- /dev/null +++ b/addons/spectator/functions/fnc_cam_setVisionMode.sqf @@ -0,0 +1,45 @@ +/* + * Author: SilentSpike + * Function used to select the camera vision mode + * + * Arguments: + * 0: New vision mode + * + * Return Value: + * None + * + * Example: + * [-1] call ace_spectator_fnc_cam_setVisionMode + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_newVision"]; + +private _oldVision = GVAR(camVision); +private _visions = GVAR(availableVisions); + +// If new vision isn't available then keep current (unless current also isn't) +if !(_newVision in _visions) then { + _newVision = _visions select ((_visions find _oldVision) max 0); +}; + +// Vision mode does not apply to fps view +if (GVAR(camMode) != MODE_FPS) then { + // 0+ are all thermal vision types + if (_newVision < 0) then { + false setCamUseTi 0; + camUseNVG (_newVision >= VISION_NVG); + } else { + true setCamUseTi _newVision; + }; + + // Give user feedback that vision mode changed + if (_newVision != _oldVision) then { + playSound "RscDisplayCurator_visionMode"; + + GVAR(camVision) = _newVision; + }; +}; diff --git a/addons/spectator/functions/fnc_cam_tick.sqf b/addons/spectator/functions/fnc_cam_tick.sqf new file mode 100644 index 0000000000..1ba9ee2797 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_tick.sqf @@ -0,0 +1,84 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to perform camera ticks + * + * Updates camera position in follow mode + * Updates camera focus if current focus becomes null (in unit modes) + * Updates camera when focus enters/exits a vehicle + * Updates camera lights position + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * addMissionEventHandler ["EachFrame", {call ace_spectator_fnc_cam_tick}] + * + * Public: No + */ + +#include "script_component.hpp" + +BEGIN_COUNTER(camTick); +private _cameraMode = GVAR(camMode); +private _camTarget = GVAR(camFocus); + +// UI mouse handler makes use of delta time between camera ticks +private _currentTime = diag_tickTime; +GVAR(camDeltaTime) = _currentTime - GVAR(camLastTickTime); +GVAR(camLastTickTime) = _currentTime; + + +// If no focus in unit camera modes try to find a new one +if (_cameraMode != MODE_FREE) then { + private _focus = if (isNull _camTarget) then { + private _testFocus = ([] call FUNC(getTargetEntities)) select 0; + if (isNil "_testFocus") then { + objNull + } else { + _testFocus + } + } else { + _camTarget + }; + + // If new focus was found then switch to it + if (!isNull _focus && {_focus != _camTarget}) then { + [_focus] call FUNC(setFocus); + }; + + // Update the follow camera position + if (!isNull _focus && {_cameraMode == MODE_FOLLOW}) then { + [_focus] call FUNC(cam_prepareTarget); + }; +}; + +// Refresh the local variable +_camTarget = GVAR(camFocus); + +// Focus get in / out of vehicle state +if !(isNull _camTarget) then { + private _targetInVeh = GVAR(camTargetInVehicle); + + if (GVAR(camHasTarget)) then { + if (!_targetInVeh && { vehicle _camTarget != _camTarget }) then { + [_camTarget] call FUNC(cam_setTarget); + GVAR(camTargetInVehicle) = true; + }; + + if (_targetInVeh && { vehicle _camTarget == _camTarget }) then { + [_camTarget] call FUNC(cam_setTarget); + GVAR(camTargetInVehicle) = false; + }; + }; +} else { + GVAR(camTargetInVehicle) = false; +}; + +// Camera lights +if (count GVAR(camLights) > 1) then { + (GVAR(camLights) select 1) setPosASL (AGLToASL (screenToWorld getMousePosition)); +}; +END_COUNTER(camTick); diff --git a/addons/spectator/functions/fnc_cam_toggleSlow.sqf b/addons/spectator/functions/fnc_cam_toggleSlow.sqf new file mode 100644 index 0000000000..e689351ce8 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_toggleSlow.sqf @@ -0,0 +1,36 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Function used to set camera slow speed mode + * + * Arguments: + * 0: Enable slow speed + * + * Return Value: + * None + * + * Example: + * [true] call ace_spectator_fnc_cam_toggleSlow + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_slowSpeed"]; + +if !(GVAR(camSlow) isEqualTo _slowSpeed) then { + private _camera = GVAR(camera); + + if (GVAR(camMode) == MODE_FREE) then { + GVAR(camSlow) = _slowSpeed; + + if (_slowSpeed) then { + _camera camCommand format ["speedDefault %1", SPEED_SLOW]; + } else { + _camera camCommand format ["speedDefault %1", SPEED_DEFAULT]; + }; + } else { + _camera camCommand format ["speedDefault %1", SPEED_DEFAULT]; + GVAR(camSlow) = false; + }; +}; diff --git a/addons/spectator/functions/fnc_compat_counter.sqf b/addons/spectator/functions/fnc_compat_counter.sqf new file mode 100644 index 0000000000..8a54d6dbdf --- /dev/null +++ b/addons/spectator/functions/fnc_compat_counter.sqf @@ -0,0 +1,36 @@ +/* + * Author: SilentSpike + * Handles integrating the counter respawn template into the spectator UI + * + * Should be called from both RscRespawnCounter XEH and spectator init to account for arbitrary order + * + * Arguments: + * 0: RscRespawnCounter + * + * Return Value: + * None + * + * Example: + * [GETUVAR(RscRespawnCounter,displayNull)] call ace_spectator_fnc_compat_counter + * + * Public: No + */ + +#include "script_component.hpp" +#define IDC_COUNTER_TITLE 1001 +#define IDC_COUNTER_BACK 1002 +#define IDC_COUNTER_TEXT 1003 + +params ["_display"]; + +if (isNull _display) exitWith {}; + +{ + private _ctrl = _display displayCtrl _x; + + (ctrlPosition _ctrl) params ["_xOld","","_w","_h"]; + + // Center controls at top middle of screen + _ctrl ctrlSetPosition [_xOld, safeZoneY, _w, _h]; + _ctrl ctrlCommit 0; +} forEach [IDC_COUNTER_TITLE, IDC_COUNTER_BACK, IDC_COUNTER_TEXT]; diff --git a/addons/spectator/functions/fnc_compat_spectatorBI.sqf b/addons/spectator/functions/fnc_compat_spectatorBI.sqf new file mode 100644 index 0000000000..0024664c88 --- /dev/null +++ b/addons/spectator/functions/fnc_compat_spectatorBI.sqf @@ -0,0 +1,56 @@ +/* + * Author: SilentSpike + * Handles "compatibility" (i.e. override) for BI spectator respawn types 1, 4 & 5 + * + * Called from the RscDisplayEGSpectator XEH + * + * Arguments: + * 0: RscDisplayEGSpectator + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_compat_spectatorBI + * + * Public: No + */ + +#include "script_component.hpp" + +private _respawn = getMissionConfigValue ["respawn",0]; +if (_respawn isEqualType "") then { _respawn = ["","bird","","","group","side"] find (toLower _respawn); }; +if !(_respawn in [1,4,5]) exitWith {}; + +// Remember to check for side specific templates +private _templates = getMissionConfigValue [["respawnTemplates",side group player] joinString "",getMissionConfigValue ["respawnTemplates",[]]]; +if !(QUOTE(ADDON) in _templates) exitWith {}; + +// Kill BI spectator +["Terminate"] call BIS_fnc_EGSpectator; + +// Start our spectator +[true] call FUNC(setSpectator); + +// Delete the seagull that spawns (not actually the player, a CfgNonAIVehicles object) +// Respawn type 1 is handled in the template where seagull is passed as paremeter +if (_respawn in [4,5]) then { + // This could delete seagulls created by a wildlife module (a necessary evil) + // TODO: Try to find seagull position and delete more accurately with reduced radius + { if (_x isKindOf "seagull") then {deleteVehicle _x;}; } forEach (nearestObjects [player, [], 250]); +}; + +// Switch to a virtual unit so draw3D continues to work +private _grp = createGroup [sideLogic, true]; +private _virtual = _grp createUnit [QGVAR(virtual),[0,0,0],[],0,"NONE"]; + +// Prevent unit falling into water (compatibility for some addons) +_virtual enableSimulation false; + +// Transfer assigned zeus if applicable +private _zeus = getAssignedCuratorLogic player; +if !(isNull _zeus) then { + [QGVAR(transferZeus), [_virtual,_zeus]] call CBA_fnc_serverEvent; +}; + +selectPlayer _virtual; diff --git a/addons/spectator/functions/fnc_compat_zeus.sqf b/addons/spectator/functions/fnc_compat_zeus.sqf new file mode 100644 index 0000000000..f379e549ce --- /dev/null +++ b/addons/spectator/functions/fnc_compat_zeus.sqf @@ -0,0 +1,34 @@ +/* + * Author: SilentSpike + * Handles compatibility with curator interface (i.e. re-opens spectator if applicable) + * + * Called from the RscDisplayCurator XEH + * + * Arguments: + * 0: RscDisplayCurator + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_compat_zeus + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_display"]; + +_display displayAddEventHandler ["Unload",{ + // Only re-open if still a spectator (and not remote-controlling) + if (GVAR(isSet) && {isNull (GETMVAR(bis_fnc_moduleRemoteControl_unit,objNull))}) then { + // Display must be opened next frame to prevent game crash + [{ + // Reset the camera and vision modes + [GVAR(camMode)] call FUNC(cam_setCameraMode); + [GVAR(camVision)] call FUNC(cam_setVisionMode); + [true] call FUNC(ui); + }] call CBA_fnc_execNextFrame; + }; +}]; diff --git a/addons/spectator/functions/fnc_cycleCamera.sqf b/addons/spectator/functions/fnc_cycleCamera.sqf deleted file mode 100644 index 474d25cd0c..0000000000 --- a/addons/spectator/functions/fnc_cycleCamera.sqf +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Author: SilentSpike - * Cycle through the spectator camera vision/view/units in steps - * - * Arguments: - * 0: Camera mode steps - * 1: Camera unit steps - * 2: Vision mode steps - * - * Return Value: - * None - * - * Example: - * [0, -1] call ace_spectator_fnc_cycleCamera - * - * Public: No - */ - -#include "script_component.hpp" - -params [["_stepMode",0], ["_stepUnit",0], ["_stepVision",0]]; -private ["_modes","_visions","_iMode","_iVision","_countModes","_countVisions","_newMode","_newVision","_newUnit"]; - -_modes = GVAR(availableModes); -_units = GVAR(unitList); -_visions = GVAR(availableVisions); - -// Get current index -_iMode = (_modes find GVAR(camMode)) max 0; -_iUnit = (_units find GVAR(camUnit)) max 0; -_iVision = (_visions find GVAR(camVision)) max 0; - -_countModes = count _modes; -_countUnits = count _units; -_countVisions = count _visions; - -// Step index by step number (loop at ends) -if (_countModes != 0) then { - _iMode = (_iMode + _stepMode) % _countModes; - if (_iMode < 0) then { _iMode = _countModes + _iMode; }; -}; - -if (_countUnits != 0) then { - _iUnit = (_iUnit + _stepUnit) % _countUnits; - if (_iUnit < 0) then { _iUnit = _countUnits + _iUnit; }; -}; - -if (_countVisions != 0) then { - _iVision = (_iVision + _stepVision) % _countVisions; - if (_iVision < 0) then { _iVision = _countVisions + _iVision; }; -}; - -// Get value at new index -_newMode = _modes select _iMode; -_newUnit = _units select _iUnit; -_newVision = _visions select _iVision; - -[_newMode, _newUnit, _newVision] call FUNC(transitionCamera); diff --git a/addons/spectator/functions/fnc_getCameraAttributes.sqf b/addons/spectator/functions/fnc_getCameraAttributes.sqf new file mode 100644 index 0000000000..3f43a9003a --- /dev/null +++ b/addons/spectator/functions/fnc_getCameraAttributes.sqf @@ -0,0 +1,30 @@ +/* + * Author: SilentSpike + * Returns the current spectator camera attributes (see setCameraAttributes for details). + * + * Arguments: + * None + * + * Return Value: + * [Mode, Focus, Vision, Position, Direction] + * + * Example: + * [] call ace_spectator_fnc_getCameraAttributes + * + * Public: Yes + */ + +#include "script_component.hpp" + +if !(isNil QGVAR(camera)) then { + [GVAR(camMode), GVAR(camFocus), GVAR(camVision), getPosATL GVAR(camera), getDirVisual GVAR(camera)] +} else { + // These values could be pre-set by function + [ + GETMVAR(GVAR(camMode),0), + GETMVAR(GVAR(camFocus),objNull), + GETMVAR(GVAR(camVision),-2), + GETMVAR(GVAR(camPos),[ARR_3(0,0,0)]), + GETMVAR(GVAR(camDir),0) + ] +}; diff --git a/addons/spectator/functions/fnc_getGroupIcon.sqf b/addons/spectator/functions/fnc_getGroupIcon.sqf new file mode 100644 index 0000000000..fdc2772edc --- /dev/null +++ b/addons/spectator/functions/fnc_getGroupIcon.sqf @@ -0,0 +1,162 @@ +/* + * Author: SilentSpike + * Function used to get an appropriate icon for provided group. Approximate. + * + * Arguments: + * 0: Group to get the icon of + * 1: Return icons for draw3D use (Default: false) + * + * Return Value: + * Icon of group + * + * Examples: + * [group player] call ace_spectator_fnc_getGroupIcon + * + * Public: No + */ + +#include "script_component.hpp" +#define ICON_PATH(var1) QUOTE(a3\ui_f\data\Map\Markers\NATO\var1) + +// Military icons +#define ICON_UNKNOWN [ICON_PATH(b_unknown.paa), QPATHTOF(data\b_unknown.paa)] select _forDraw +#define ICON_UAV [ICON_PATH(b_uav.paa), QPATHTOF(data\b_uav.paa)] select _forDraw +#define ICON_SUPPORT [ICON_PATH(b_support.paa), QPATHTOF(data\b_support.paa)] select _forDraw +#define ICON_SERVICE [ICON_PATH(b_service.paa), QPATHTOF(data\b_service.paa)] select _forDraw +#define ICON_RECON [ICON_PATH(b_recon.paa), QPATHTOF(data\b_recon.paa)] select _forDraw +#define ICON_PLANE [ICON_PATH(b_plane.paa), QPATHTOF(data\b_plane.paa)] select _forDraw +#define ICON_NAVAL [ICON_PATH(b_naval.paa), QPATHTOF(data\b_naval.paa)] select _forDraw +#define ICON_MOTOR_INF [ICON_PATH(b_motor_inf.paa), QPATHTOF(data\b_motor_inf.paa)] select _forDraw +#define ICON_MORTAR [ICON_PATH(b_mortar.paa), QPATHTOF(data\b_mortar.paa)] select _forDraw +#define ICON_MED [ICON_PATH(b_med.paa), QPATHTOF(data\b_med.paa)] select _forDraw +#define ICON_MECH_INF [ICON_PATH(b_mech_inf.paa), QPATHTOF(data\b_mech_inf.paa)] select _forDraw +#define ICON_MAINT [ICON_PATH(b_maint.paa), QPATHTOF(data\b_maint.paa)] select _forDraw +#define ICON_INSTALLATION [ICON_PATH(b_installation.paa), QPATHTOF(data\b_installation.paa)] select _forDraw +#define ICON_INF [ICON_PATH(b_inf.paa), QPATHTOF(data\b_inf.paa)] select _forDraw +#define ICON_ART [ICON_PATH(b_art.paa), QPATHTOF(data\b_art.paa)] select _forDraw +#define ICON_ARMOR [ICON_PATH(b_armor.paa), QPATHTOF(data\b_armor.paa)] select _forDraw +#define ICON_AIR [ICON_PATH(b_air.paa), QPATHTOF(data\b_air.paa)] select _forDraw + +// Civilian icons +#define CIV_ICON_UNKNOWN [ICON_PATH(c_unknown.paa), QPATHTOF(data\c_unknown.paa)] select _forDraw +#define CIV_ICON_AIR [ICON_PATH(c_air.paa), QPATHTOF(data\c_air.paa)] select _forDraw +#define CIV_ICON_CAR [ICON_PATH(c_car.paa), QPATHTOF(data\c_car.paa)] select _forDraw +#define CIV_ICON_PLANE [ICON_PATH(c_plane.paa), QPATHTOF(data\c_plane.paa)] select _forDraw +#define CIV_ICON_SHIP [ICON_PATH(c_ship.paa), QPATHTOF(data\c_ship.paa)] select _forDraw + +params [["_group", grpNull, [grpNull]], ["_forDraw", false, [true]]]; + +// Handle empty or null group +private _leader = leader _group; +if (isNull _leader) exitWith { [ICON_UNKNOWN, CIV_ICON_UNKNOWN] select (side _group == civilian) }; + +// Civilians are easy, just check leader's vehicle (unlikely group is large) +if (side _group == civilian) exitWith { + if (_leader != vehicle _leader) then { + // More common cases should be checked first + (vehicle _leader) call { + if (_this isKindOf "Car") exitWith { + CIV_ICON_CAR + }; + + // Plane inherits Air, check first + if (_this isKindOf "Plane") exitWith { + CIV_ICON_PLANE + }; + + if (_this isKindOf "Air") exitWith { + CIV_ICON_AIR + }; + + if (_this isKindOf "Ship") exitWith { + CIV_ICON_SHIP + }; + + CIV_ICON_UNKNOWN + }; + } else { + CIV_ICON_UNKNOWN + }; +}; + +// Handle military groups +private _units = units _group; +private _vehicles = (_units apply { vehicle _x }) - _units; + +// If more than 33% of the group is mounted, use most common vehicle +if (count _vehicles >= 0.33 * count _units) exitWith { + // Check the most likely cases first + _vehicles call { + private _threshold = 0.5 * count _this; + + if ("Car" countType _this >= _threshold) exitWith { + ICON_MOTOR_INF + }; + + // APC inherits Tank, check first + if ("APC" countType _this >= _threshold) exitWith { + ICON_MECH_INF + }; + + // MBT_01_arty_base_F inherits Tank, check first + // Unfortunately no common arty class to check + if ("MBT_01_arty_base_F" countType _this >= _threshold) exitWith { + ICON_ART + }; + if ("MBT_02_arty_base_F" countType _this >= _threshold) exitWith { + ICON_ART + }; + + if ("Tank" countType _this >= _threshold) exitWith { + ICON_ARMOR + }; + + // UAV inherits Plane, check first + if ("UAV" countType _this >= _threshold) exitWith { + ICON_UAV + }; + + // Plane inherits Air, check first + if ("Plane" countType _this >= _threshold) exitWith { + ICON_PLANE + }; + + if ("Air" countType _this >= _threshold) exitWith { + ICON_AIR + }; + + if ("Ship" countType _this >= _threshold) exitWith { + ICON_NAVAL + }; + + // StaticMortar inherits StaticWeapon, check first + if ("StaticMortar" countType _this >= _threshold) exitWith { + ICON_MORTAR + }; + + if ("StaticWeapon" countType _this >= _threshold) exitWith { + ICON_INSTALLATION + }; + + // If it reaches here then it's a mixed group of vehicles + ICON_UNKNOWN + }; +}; + +// Check leader for medic/engineer/etc, otherwise just default to infantry +private _medic = [_leader] call EFUNC(common,isMedic); +private _engineer = [_leader] call EFUNC(common,isEngineer); + +if (_medic && _engineer) exitWith { + ICON_SUPPORT +}; + +if (_medic) exitWith { + ICON_MED +}; + +if (_engineer) exitWith { + ICON_MAINT +}; + +ICON_INF diff --git a/addons/spectator/functions/fnc_getTargetEntities.sqf b/addons/spectator/functions/fnc_getTargetEntities.sqf new file mode 100644 index 0000000000..80ee72fe03 --- /dev/null +++ b/addons/spectator/functions/fnc_getTargetEntities.sqf @@ -0,0 +1,45 @@ +/* + * Author: SilentSpike + * Gets the possible entities to spectate based on settings. + * Optionally includes dead units for the list and switching. + * + * Arguments: + * 0: Include dead + * + * Return Value: + * Valid entities + * + * Example: + * [true] call ace_spectator_fnc_getTargetEntities + * + * Public: No + */ + +#include "script_component.hpp" + +// Include dead units if specified (used by entity list) +private _entities = allUnits; +if (param [0,false]) then { _entities append allDeadMen; }; + +// Quicker to use local vars that are accessed often in iteration +private _sides = GVAR(availableSides); + +// Apply entity filtering +_entities = _entities select { + (GVAR(enableAI) || {isPlayer _x}) && // AI setting + {(side group _x) in _sides} && // Available sides + {simulationEnabled _x && {simulationEnabled vehicle _x}} && // Hide disabled things + { !isObjectHidden _x && {!isObjectHidden vehicle _x} } // Hide hidden things +}; + +// Respect the blacklist +_entities = _entities - GVAR(unitBlacklist); + +// Whitelist overrides filtering +_entities append GVAR(unitWhitelist); + +// Never include the local player +_entities deleteAt (_entities find player); + +// Return no duplicates +_entities arrayIntersect _entities diff --git a/addons/spectator/functions/fnc_handleCamera.sqf b/addons/spectator/functions/fnc_handleCamera.sqf deleted file mode 100644 index f21581ea58..0000000000 --- a/addons/spectator/functions/fnc_handleCamera.sqf +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Author: F3 Project, Head, SilentSpike - * Handles free camera manipulation according to input - * - * Arguments: - * 0: Parameters - * 1: PFH handle - * - * Return Value: - * None - * - * Example: - * [ace_spectator_fnc_handleCamera, 0] call CBA_fnc_addPerFrameHandler; - * - * Public: No - */ - -#include "script_component.hpp" - -// Kill PFH when not in free cam (or display is closed) -if (isNil QGVAR(camHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; }; - -private ["_camera","_pan","_tilt"]; - -_pan = (GVAR(camPan) + 360) % 360; -_tilt = GVAR(camTilt); - -if (GVAR(camMode) == 0) then { - private ["_oldPos","_altMod","_zoomMod","_mX","_mY","_mZ","_x","_y","_z"]; - _camera = GVAR(freeCamera); - _oldPos = GVAR(camPos); - - // Dolly/Boom amount should be influnced by zoom level (it should really be exponential) - // Dollying should also slow as the camera gets close to the ground - _zoomMod = (GVAR(camZoom) * 0.8) max 1; - _altMod = ((((getPos _camera) select 2) * 0.05) max 0.1) min 1; - - _mX = (GVAR(camDolly) select 0) * _altMod / _zoomMod; - _mY = (GVAR(camDolly) select 1) * _altMod / _zoomMod; - _mZ = GVAR(camBoom) / _zoomMod; - - _x = (_oldPos select 0) + (_mX * cos(_pan)) + (_mY * sin(_pan)); - _y = (_oldPos select 1) - (_mX * sin(_pan)) + (_mY * cos(_pan)); - _z = (_oldPos select 2) + _mZ; - - // Prevent camera going under terrain - GVAR(camPos) = [_x,_y,_z max (getTerrainHeightASL [_x,_y])]; - - // Update camera position and rotation - _camera setPosASL GVAR(camPos); - _camera setDir _pan; - [_camera, _tilt, 0] call BIS_fnc_setPitchBank; -} else { - private ["_unit","_target","_distance","_vector"]; - _camera = GVAR(unitCamera); - - _unit = GVAR(camUnit); - _target = GVAR(targetCamera); - _distance = GVAR(camDistance); - - // Generate a position vector relative to the unit - _vector = [0,-_distance*cos(_tilt),0]; - _vector = [_vector,[-_pan] call CBA_fnc_simplifyAngle180] call BIS_fnc_rotateVector2D; - _vector = _vector vectorAdd [0,0,_distance*sin(-_tilt)]; - - // Update the position of the target camera (used for smooth unit tracking) - _target camSetPos ((ASLToAGL getPosASLVisual _unit) vectorAdd [0,0,1.5]); - _target camCommit 0; - - // Update the relative position of the unit camera - _camera camSetRelPos _vector; - _camera camCommit 0; - - GVAR(camPos) = getPosASL _camera; -}; diff --git a/addons/spectator/functions/fnc_handleCompass.sqf b/addons/spectator/functions/fnc_handleCompass.sqf deleted file mode 100644 index 6f0f94b0ee..0000000000 --- a/addons/spectator/functions/fnc_handleCompass.sqf +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Author: SilentSpike, voiper - * Handles the spectator UI compass - * - * Arguments: - * 0: Parameters - * 1: PFH handle - * - * Return Value: - * None - * - * Example: - * [ace_spectator_fnc_handleCompass, 0, _display] call CBA_fnc_addPerFrameHandler; - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_display"]; - -// Kill PFH when compass hidden (or display is closed) -if (isNil QGVAR(compHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; }; - -private ["_compass","_NE","_ES","_SW","_WN","_compassW","_degree","_heading","_offset","_positions","_sequence"]; - -_compass = _display displayCtrl IDC_COMP; - -_NE = _compass controlsGroupCtrl IDC_COMP_0; -_ES = _compass controlsGroupCtrl IDC_COMP_90; -_SW = _compass controlsGroupCtrl IDC_COMP_180; -_WN = _compass controlsGroupCtrl IDC_COMP_270; - -_compassW = (ctrlPosition _compass) select 2; -_degree = _compassW / 180; - -// Get direction of screen rather than object (accounts for unit freelook) -_heading = (positionCameraToWorld [0,0,1]) vectorDiff (positionCameraToWorld [0,0,0]); -_heading = (((_heading select 0) atan2 (_heading select 1)) + 360) % 360; -_offset = -(_heading % 90) * _degree; - -_positions = [ - [_compassW * -0.5 + _offset, 0], - [_offset, 0], - [_compassW * 0.5 + _offset, 0], - [_compassW + _offset, 0] -]; - -_sequence = [ - [_SW, _WN, _NE, _ES], - [_WN, _NE, _ES, _SW], - [_NE, _ES, _SW, _WN], - [_ES, _SW, _WN, _NE] -] select floor(_heading/90); - - -{ - _x ctrlSetPosition (_positions select _forEachIndex); - _x ctrlCommit 0; -} forEach _sequence; diff --git a/addons/spectator/functions/fnc_handleFired.sqf b/addons/spectator/functions/fnc_handleFired.sqf new file mode 100644 index 0000000000..4b0d640585 --- /dev/null +++ b/addons/spectator/functions/fnc_handleFired.sqf @@ -0,0 +1,49 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to add projectiles to be drawn when a unit fires + * + * Arguments: + * Fired EH arguments + * + * Return Value: + * None + * + * Example: + * _unit addEventHandler ["Fired",{_this call ace_spectator_fnc_handleFired}] + * + * Public: No + */ + +#include "script_component.hpp" + +params [ + "_unit", + ["_weapon", "", [""]], + "", // Muzzle + "", // Mode + ["_ammo", "", [""]], // Ammo + "", // Magazine + ["_projectile", objNull, [objNull]] +]; + +// Remove the EH when spectator is no longer active or unit is removed +if (isNil QGVAR(entitiesToDraw) || {!(_unit in GVAR(entitiesToDraw))}) exitWith { + //USES_VARIABLES ["_thisEventHandler"] + _unit removeEventHandler ["Fired", _thisEventHandler]; + SETVAR(_unit,GVAR(firedEH),nil); +}; + +// Fire time used for unit icon highlighting +_unit setVariable [QGVAR(highlightTime), time + FIRE_HIGHLIGHT_TIME]; + +// expensive, but any non local units might have this as null for 'global' projectiles (like grenades) +if (isNull _projectile) then { + _projectile = nearestObject [_unit, _ammo]; +}; + +// Store projectiles / grenades for drawing +if (_weapon == "Throw") then { + [QGVAR(addToGrenadeTracking), [_projectile]] call CBA_fnc_localEvent; +} else { + [QGVAR(addToProjectileTracking), [_projectile]] call CBA_fnc_localEvent; +}; diff --git a/addons/spectator/functions/fnc_handleIcons.sqf b/addons/spectator/functions/fnc_handleIcons.sqf deleted file mode 100644 index 8f735c2a32..0000000000 --- a/addons/spectator/functions/fnc_handleIcons.sqf +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Author: Head, SilentSpike - * Handles rendering the spectator 3D unit icons - * - * Arguments: - * 0: Parameters - * 1: PFH handle - * - * Return Value: - * None - * - * Example: - * [ace_spectator_fnc_handleIcons, 0] call CBA_fnc_addPerFrameHandler; - * - * Public: No - */ - -#include "script_component.hpp" - -if !(GVAR(showIcons)) exitWith {}; -private ["_refPoint","_drawVehicles","_leader","_color","_txt","_unit"]; - -// Draw groups unless leader is within distance -_refPoint = [GVAR(freeCamera),GVAR(camUnit)] select (GVAR(camMode) > 0); -_drawVehicles = []; -{ - _leader = leader _x; - if ((_leader distanceSqr _refPoint) > 40000) then { - _color = GETVAR(_x,GVAR(gColor),[ARR_4(0,0,0,0)]); - _txt = groupID _x; - - drawIcon3D ["\A3\ui_f\data\map\markers\nato\b_inf.paa", _color, (_leader modelToWorldVisual (_leader selectionPosition "Head")) vectorAdd [0,0,28.5], 1, 1, 0, _txt, 2, 0.02]; - } else { - _drawVehicles append (units _x); - }; - false -} count GVAR(groupList); - -// Draw units for groups within distance -{ - _color = GETVAR((group _x),GVAR(gColor),[ARR_4(0,0,0,0)]); - _txt = ["", GETVAR(_x,GVAR(uName),"")] select (isPlayer _x); - - drawIcon3D ["a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\UnitIcon_ca.paa", _color, (_x modelToWorldVisual (_x selectionPosition "Head")) vectorAdd [0,0,1.5], 0.7, 0.7, 0, _txt, 1, 0.02]; - false -} count (_drawVehicles arrayIntersect GVAR(unitList)); diff --git a/addons/spectator/functions/fnc_handleInterface.sqf b/addons/spectator/functions/fnc_handleInterface.sqf deleted file mode 100644 index 9ba64ec0f0..0000000000 --- a/addons/spectator/functions/fnc_handleInterface.sqf +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Author: SilentSpike - * Handles spectator interface events - * - * Arguments: - * 0: Event name - * 1: Event arguments - * - * Return Value: - * None - * - * Example: - * ["onLoad",_this] call ace_spectator_fnc_handleInterface - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_mode",["_args",[]]]; - -switch (toLower _mode) do { - case "onload": { - _args params ["_display"]; - SETUVAR(GVAR(interface),_display); - - // Always show interface and hide map upon opening - [_display,nil,nil,!GVAR(showInterface),GVAR(showMap)] call FUNC(toggleInterface); - - // Initalize the unit tree - ["onUnitsUpdate",[(_display displayCtrl IDC_UNIT) controlsGroupCtrl IDC_UNIT_TREE]] call FUNC(handleInterface); - - // Keep unit list and tree up to date - [FUNC(handleUnits), 9, _display] call CBA_fnc_addPerFrameHandler; - - // Handle 3D unit icons - GVAR(iconHandler) = addMissionEventHandler ["Draw3D", {call FUNC(handleIcons)}]; - - // Populate the help window - private _help = (_display displayCtrl IDC_HELP) controlsGroupCtrl IDC_HELP_LIST; - { - _i = _help lbAdd (_x select 0); - if ((_x select 1) == "") then { - _help lbSetPicture [_i,"\A3\ui_f\data\map\markers\military\dot_CA.paa"]; - _help lbSetPictureColor [_i,[COL_FORE]]; - } else { - _help lbSetTooltip [_i,_x select 1]; - }; - } forEach [ - [localize LSTRING(uiControls),""], - [localize LSTRING(uiToggleUnits),keyName 2], - [localize LSTRING(uiToggleHelp),keyName 3], - [localize LSTRING(uiToggleTools),keyName 4], - [localize LSTRING(uiToggleCompass),keyName 5], - [localize LSTRING(uiToggleIcons),keyName 6], - [localize LSTRING(uiToggleMap),keyName 50], - [localize LSTRING(uiToggleInterface),keyName 14], - [localize LSTRING(freeCamControls),""], - [localize LSTRING(freeCamForward),keyName 17], - [localize LSTRING(freeCamBackward),keyName 31], - [localize LSTRING(freeCamLeft),keyName 30], - [localize LSTRING(freeCamRight),keyName 32], - [localize LSTRING(freeCamUp),keyName 16], - [localize LSTRING(freeCamDown),keyName 44], - [localize LSTRING(freeCamPan),"RMB (Hold)"], - [localize LSTRING(freeCamDolly),"LMB (Hold)"], - [localize LSTRING(freeCamBoost),"Shift (Hold)"], - [localize LSTRING(attributeControls),""], - [localize LSTRING(nextCam),keyName 200], - [localize LSTRING(prevCam),keyName 208], - [localize LSTRING(nextUnit),keyName 205], - [localize LSTRING(prevUnit),keyName 203], - [localize LSTRING(nextVis),keyName 49], - [localize LSTRING(prevVis),format["%1 + %2",keyName 29,keyname 49]], - [localize LSTRING(adjZoom),"Scrollwheel"], - [localize LSTRING(adjSpeed),format["%1 + Scrollwheel",keyName 29]], - [localize LSTRING(incZoom),format["%1/%2",keyName 74,keyName 78]], - [localize LSTRING(incSpeed),format["%1 + %2/%3",keyName 29,keyName 74,keyName 78]], - [localize LSTRING(reZoom),format["%1 + %2",keyName 56,keyName 74]], - [localize LSTRING(reSpeed),format["%1 + %2",keyName 56,keyName 78]] - ]; - - // Handle support for BI's respawn counter - [{ - if !(isNull (GETUVAR(RscRespawnCounter,displayNull))) then { - disableSerialization; - private ["_counter","_title","_back","_timer","_frame","_x","_y"]; - _counter = GETUVAR(RscRespawnCounter,displayNull); - _title = _counter displayCtrl 1001; - _back = _counter displayCtrl 1002; - _timer = _counter displayCtrl 1003; - _frame = _counter ctrlCreate ["RscFrame",1008]; - - _x = safeZoneX + safeZoneW - TOOL_W * 4 - MARGIN * 3; - _y = safeZoneY + safeZoneH - TOOL_H; - - // Timer - _title ctrlSetPosition [_x,_y,TOOL_W,TOOL_H]; - _back ctrlSetPosition [_x,_y,TOOL_W,TOOL_H]; - _timer ctrlSetPosition [_x,_y,TOOL_W,TOOL_H]; - _frame ctrlSetPosition [_x,_y,TOOL_W,TOOL_H]; - - _title ctrlSetBackgroundColor [0,0,0,0]; - _back ctrlSetBackgroundColor [COL_BACK]; - _timer ctrlSetFontHeight TOOL_H; - _frame ctrlSetTextColor [COL_FORE]; - - _title ctrlCommit 0; - _back ctrlCommit 0; - _timer ctrlCommit 0; - _frame ctrlCommit 0; - }; - },[],0.5] call CBA_fnc_waitAndExecute; - }; - case "onunload": { - // Kill GUI PFHs - removeMissionEventHandler ["Draw3D",GVAR(iconHandler)]; - GVAR(camHandler) = nil; - GVAR(compHandler) = nil; - GVAR(iconHandler) = nil; - GVAR(toolHandler) = nil; - - // Reset variables - GVAR(camBoom) = 0; - GVAR(camDolly) = [0,0]; - GVAR(ctrlKey) = false; - GVAR(heldKeys) = []; - GVAR(heldKeys) resize 255; - GVAR(mouse) = [false,false]; - GVAR(mousePos) = [0.5,0.5]; - }; - // Mouse events - case "onmousebuttondown": { - _args params ["_ctrl","_button"]; - GVAR(mouse) set [_button,true]; - - // Detect right click - if ((_button == 1) && (GVAR(camMode) == 1)) then { - // In first person toggle sights mode - GVAR(camGun) = !GVAR(camGun); - [] call FUNC(transitionCamera); - }; - }; - case "onmousebuttonup": { - _args params ["_ctrl","_button"]; - - GVAR(mouse) set [_button,false]; - if (_button == 0) then { GVAR(camDolly) = [0,0]; }; - }; - case "onmousezchanged": { - _args params ["_ctrl","_zChange"]; - - // Scroll to modify distance value in third person - if (GVAR(camMode) == 0) then { - // Scroll to change speed, modifier for zoom - if (GVAR(ctrlKey)) then { - [nil,nil,nil,nil,nil,nil,nil, GVAR(camSpeed) + _zChange * 0.2] call FUNC(setCameraAttributes); - } else { - [nil,nil,nil,nil,nil,nil, GVAR(camZoom) + _zChange * 0.1] call FUNC(setCameraAttributes); - }; - } else { - GVAR(camDistance) = ((GVAR(camDistance) - _zChange * 2) max 5) min 50; - }; - }; - case "onmousemoving": { - _args params ["_ctrl","_x","_y"]; - - [_x,_y] call FUNC(handleMouse); - }; - // Keyboard events - case "onkeydown": { - _args params ["_display","_dik","_shift","_ctrl","_alt"]; - - if ((alive player) && {_dik in (actionKeys "curatorInterface")} && {!isNull (getAssignedCuratorLogic player)}) exitWith { - [QGVAR(zeus)] call FUNC(interrupt); - ["zeus"] call FUNC(handleInterface); - }; - if (_dik in (actionKeys "Chat")) exitWith { - false - }; - if (_dik in (actionKeys "PrevChannel" + actionKeys "NextChannel")) exitWith { - !(isServer || serverCommandAvailable "#kick") - }; - - // Handle held keys (prevent repeat calling) - if (GVAR(heldKeys) param [_dik,false]) exitWith {}; - // Exclude movement/adjustment keys so that speed can be adjusted on fly - if !(_dik in [16,17,30,31,32,44,74,78]) then { - GVAR(heldKeys) set [_dik,true]; - }; - - switch (_dik) do { - case 1: { // Esc - [QGVAR(escape)] call FUNC(interrupt); - ["escape"] call FUNC(handleInterface); - }; - case 2: { // 1 - [_display,nil,nil,nil,nil,nil,true] call FUNC(toggleInterface); - }; - case 3: { // 2 - [_display,nil,true] call FUNC(toggleInterface); - }; - case 4: { // 3 - [_display,nil,nil,nil,nil,true] call FUNC(toggleInterface); - }; - case 5: { // 4 - [_display,true] call FUNC(toggleInterface); - }; - case 6: { // 5 - GVAR(showIcons) = !GVAR(showIcons); - }; - case 14: { // Backspace - [_display,nil,nil,true] call FUNC(toggleInterface); - }; - case 16: { // Q - GVAR(camBoom) = 0.5 * GVAR(camSpeed) * ([1, 2] select _shift); - }; - case 17: { // W - GVAR(camDolly) set [1, GVAR(camSpeed) * ([1, 2] select _shift)]; - }; - case 29: { // Ctrl - GVAR(ctrlKey) = true; - }; - case 30: { // A - GVAR(camDolly) set [0, -GVAR(camSpeed) * ([1, 2] select _shift)]; - }; - case 31: { // S - GVAR(camDolly) set [1, -GVAR(camSpeed) * ([1, 2] select _shift)]; - }; - case 32: { // D - GVAR(camDolly) set [0, GVAR(camSpeed) * ([1, 2] select _shift)]; - }; - case 44: { // Z - GVAR(camBoom) = -0.5 * GVAR(camSpeed) * ([1, 2] select _shift); - }; - case 49: { // N - if (GVAR(camMode) != 1) then { - if (_ctrl) then { - [nil,nil,-1] call FUNC(cycleCamera); - } else { - [nil,nil,1] call FUNC(cycleCamera); - }; - }; - }; - case 50: { // M - [_display,nil,nil,nil,true] call FUNC(toggleInterface); - }; - case 57: { // Spacebar - // Switch between unit and freecam here - }; - case 74: { // Num - - if (_alt) exitWith { [nil,nil,nil,nil,nil,nil, 1.25] call FUNC(setCameraAttributes); }; - if (_ctrl) then { - [nil,nil,nil,nil,nil,nil,nil, GVAR(camSpeed) - 0.05] call FUNC(setCameraAttributes); - } else { - [nil,nil,nil,nil,nil,nil, GVAR(camZoom) - 0.01] call FUNC(setCameraAttributes); - }; - }; - case 78: { // Num + - if (_alt) exitWith { [nil,nil,nil,nil,nil,nil,nil, 1.5] call FUNC(setCameraAttributes); }; - if (_ctrl) then { - [nil,nil,nil,nil,nil,nil,nil, GVAR(camSpeed) + 0.05] call FUNC(setCameraAttributes); - } else { - [nil,nil,nil,nil,nil,nil, GVAR(camZoom) + 0.01] call FUNC(setCameraAttributes); - }; - }; - case 200: { // Up arrow - [-1] call FUNC(cycleCamera); - }; - case 203: { // Left arrow - [nil,1] call FUNC(cycleCamera); - }; - case 205: { // Right arrow - [nil,-1] call FUNC(cycleCamera); - }; - case 208: { // Down arrow - [1] call FUNC(cycleCamera); - }; - }; - - true - }; - case "onkeyup": { - _args params ["_display","_dik","_shift","_ctrl","_alt"]; - - // No longer being held - GVAR(heldKeys) set [_dik,nil]; - - switch (_dik) do { - case 16: { // Q - GVAR(camBoom) = 0; - }; - case 17: { // W - GVAR(camDolly) set [1, 0]; - }; - case 29: { // Ctrl - GVAR(ctrlKey) = false; - }; - case 30: { // A - GVAR(camDolly) set [0, 0]; - }; - case 31: { // S - GVAR(camDolly) set [1, 0]; - }; - case 32: { // D - GVAR(camDolly) set [0, 0]; - }; - case 44: { // Z - GVAR(camBoom) = 0; - }; - }; - - true - }; - // Tree events - case "ontreedblclick": { - // Update camera view when listbox unit is double clicked on - _args params ["_tree","_sel"]; - - // Ensure a unit was selected - if (count _sel == 3) then { - private ["_netID","_newUnit","_newMode"]; - _netID = (_args select 0) tvData _sel; - _newUnit = objectFromNetId _netID; - - // When unit is reselected, toggle camera mode - if (_newUnit == GVAR(camUnit) || GVAR(camMode) == 0) then { - _newMode = [2,2,1] select GVAR(camMode); - }; - - [_newMode,_newUnit] call FUNC(transitionCamera); - }; - }; - case "onunitsupdate": { - _args params ["_tree"]; - private ["_cachedUnits","_cachedGrps","_cachedSides","_sT","_gT","_uT","_s","_g","_u","_grp","_unit","_side"]; - - // Cache existing group and side nodes and cull removed data - _cachedUnits = []; - _cachedGrps = []; - _cachedSides = []; - // Track deleted nodes to account for decrease in index - _sT = _tree tvCount []; - for [{_s = 0;}, {_s < _sT}, {_s = _s + 1}] do { - _gT = _tree tvCount [_s]; - - for [{_g = 0;}, {_g < _gT}, {_g = _g + 1}] do { - _grp = groupFromNetID (_tree tvData [_s,_g]); - - if (_grp in GVAR(groupList)) then { - _cachedGrps pushBack _grp; - _cachedGrps pushBack _g; - - _uT = _tree tvCount [_s,_g]; - for [{_u = 0;}, {_u < _uT}, {_u = _u + 1}] do { - _unit = objectFromNetId (_tree tvData [_s,_g,_u]); - - if (_unit in GVAR(unitList)) then { - _cachedUnits pushBack _unit; - } else { - _tree tvDelete [_s,_g,_u]; - _u = _u - 1; - _uT = _uT - 1; - }; - }; - } else { - _tree tvDelete [_s,_g]; - _g = _g - 1; - _gT = _gT - 1; - }; - }; - - if ((_tree tvCount [_s]) > 0) then { - _cachedSides pushBack (_tree tvText [_s]); - _cachedSides pushBack _s; - } else { - _tree tvDelete [_s]; - _s = _s - 1; - _sT = _sT - 1; - }; - }; - - // Update the tree from the unit list - { - _grp = group _x; - _side = [side _grp] call BIS_fnc_sideName; - - // Use correct side node - if !(_side in _cachedSides) then { - // Add side node - _s = _tree tvAdd [[], _side]; - _tree tvExpand [_s]; - - _cachedSides pushBack _side; - _cachedSides pushBack _s; - } else { - // If side already processed, use existing node - _s = _cachedSides select ((_cachedSides find _side) + 1); - }; - - // Use correct group node - if !(_grp in _cachedGrps) then { - // Add group node - _g = _tree tvAdd [[_s], groupID _grp]; - _tree tvSetData [[_s,_g], netID _grp]; - - _cachedGrps pushBack _grp; - _cachedGrps pushBack _g; - } else { - // If group already processed, use existing node - _g = _cachedGrps select ((_cachedGrps find _grp) + 1); - }; - - _u = _tree tvAdd [[_s,_g], GETVAR(_x,GVAR(uName),"")]; - _tree tvSetData [[_s,_g,_u], netID _x]; - _tree tvSetPicture [[_s,_g,_u], GETVAR(_x,GVAR(uIcon),"")]; - _tree tvSetPictureColor [[_s,_g,_u], GETVAR(_grp,GVAR(gColor),[ARR_4(1,1,1,1)])]; - - _tree tvSort [[_s,_g],false]; - } forEach (GVAR(unitList) - _cachedUnits); - - _tree tvSort [[],false]; - - if ((_tree tvCount []) <= 0) then { - _tree tvAdd [[], localize LSTRING(units_none)]; - }; - }; - // Map events - case "onmapclick": { - _args params ["_map","_button","_x","_y","_shift","_ctrl","_alt"]; - private ["_newPos","_oldZ"]; - - if ((GVAR(camMode) == 0) && (_button == 0)) then { - _newPos = _map ctrlMapScreenToWorld [_x,_y]; - _oldZ = (ASLtoATL GVAR(camPos)) select 2; - _newPos set [2, _oldZ]; - [nil,nil,nil, _newPos] call FUNC(setCameraAttributes); - }; - }; - // Interrupt events - case "escape": { - createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select isMultiplayer); - - disableSerialization; - private _dlg = finddisplay 49; - _dlg displayAddEventHandler ["KeyDown", { - _key = _this select 1; - !(_key == 1) - }]; - - // Disable save, respawn, options & manual buttons - (_dlg displayCtrl 103) ctrlEnable false; - if !(alive player) then { - (_dlg displayCtrl 1010) ctrlEnable false; - }; - (_dlg displayCtrl 101) ctrlEnable false; - (_dlg displayCtrl 122) ctrlEnable false; - - // Initalize abort button (the "spawn" is a necessary evil) - (_dlg displayCtrl 104) ctrlAddEventHandler ["ButtonClick",{_this spawn { - disableSerialization; - _display = ctrlparent (_this select 0); - _abort = [localize "str_msg_confirm_return_lobby",nil,localize "str_disp_xbox_hint_yes",localize "str_disp_xbox_hint_no",_display,nil,true] call BIS_fnc_guiMessage; - if (_abort) then {_display closeDisplay 2; failMission "loser"}; - }}]; - - // PFH to re-open display when menu closes - [{ - if !(isNull (_this select 0)) exitWith {}; - - // If still a spectator then re-enter the interface - [QGVAR(escape),false] call FUNC(interrupt); - - [_this select 1] call CBA_fnc_removePerFrameHandler; - },0,_dlg] call CBA_fnc_addPerFrameHandler; - }; - case "zeus": { - openCuratorInterface; - - [{ - // PFH to re-open display when menu closes - [{ - if !((isNull curatorCamera) && {isNull (GETMVAR(bis_fnc_moduleRemoteControl_unit,objNull))}) exitWith {}; - - // If still a spectator then re-enter the interface - [QGVAR(zeus),false] call FUNC(interrupt); - - [_this select 1] call CBA_fnc_removePerFrameHandler; - },0] call CBA_fnc_addPerFrameHandler; - },[],5] call CBA_fnc_waitAndExecute; - - true - }; -}; diff --git a/addons/spectator/functions/fnc_handleMap.sqf b/addons/spectator/functions/fnc_handleMap.sqf deleted file mode 100644 index b83ccdcd7d..0000000000 --- a/addons/spectator/functions/fnc_handleMap.sqf +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Author: Head, SilentSpike - * Handles rendering the spectator map icons - * - * Arguments: - * 0: Parameters - * 1: PFH handle - * - * Return Value: - * None - * - * Example: - * [ace_spectator_fnc_handleIcons, 0] call CBA_fnc_addPerFrameHandler; - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_map"]; -private ["_center","_radius","_scaled","_drawVehicles","_leader","_color","_cachedVehicles","_unit","_icon","_txt"]; - -if (GVAR(camMode) == 0) then { - _map drawIcon ["\A3\UI_F\Data\GUI\Rsc\RscDisplayMissionEditor\iconcamera_ca.paa",[0,0,0,1],GVAR(freeCamera),20,20,GVAR(camPan)]; -}; - -_center = _map ctrlMapScreenToWorld [0.5,0.5]; -_radius = (_map ctrlMapScreenToWorld [safeZoneX,safeZoneY]) distance2D _center; -_scaled = (ctrlMapScale _map) > 0.2; - -// Draw only group icons when scaled out -_drawVehicles = []; -{ - _leader = leader _x; - if (_scaled) then { - _color = GETVAR(_x,GVAR(gColor),[ARR_4(0,0,0,0)]); - _map drawIcon ["\A3\ui_f\data\map\markers\nato\b_inf.paa", _color, _leader, 20, 20, 0, "", 0, 0]; - } else { - if ((_leader distance2D _center) < _radius) then { - _drawVehicles append (units _x); - }; - }; - nil -} count GVAR(groupList); - -// Draw units when group leader is within screen bounds -_cachedVehicles = []; -{ - _unit = vehicle _x; - - if !(_unit in _cachedVehicles) then { - _cachedVehicles pushBack _unit; - - // Use previously cached info where possible - if (GETVAR(_unit,GVAR(uIcon),"") == "") then { - [_unit] call FUNC(cacheUnitInfo); - }; - - // Function has caching built in - _color = [side effectiveCommander _unit] call BIS_fnc_sideColor; - _icon = GETVAR(_unit,GVAR(uIcon),""); - _txt = ["", GETVAR(_x,GVAR(uName),"")] select (isPlayer _x); - - _map drawIcon [_icon, _color, _unit, 19, 19, getDir _unit, _txt, 1, 0.04]; - }; - nil -} count (_drawVehicles arrayIntersect GVAR(unitList)); diff --git a/addons/spectator/functions/fnc_handleMouse.sqf b/addons/spectator/functions/fnc_handleMouse.sqf deleted file mode 100644 index 1c2b62798c..0000000000 --- a/addons/spectator/functions/fnc_handleMouse.sqf +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Author: F3 Project, Head, SilentSpike - * Processes the change in mouse position for the spectator camera - * - * Arguments: - * 0: Mouse x coord - * 1: Mouse y coord - * - * Return Value: - * None - * - * Example: - * [0.5, 0.5] call ace_spectator_fnc_handleMouse; - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_x","_y"]; -private ["_leftButton","_rightButton","_oldX","_oldY","_deltaX","_deltaY","_zoomMod"]; - -_leftButton = GVAR(mouse) select 0; -_rightButton = GVAR(mouse) select 1; - -_oldX = GVAR(mousePos) select 0; -_oldY = GVAR(mousePos) select 1; - -// Get change in pos -_deltaX = _oldX - _x; -_deltaY = _oldY - _y; - -if (_leftButton) then { - GVAR(camDolly) set [0, _deltaX * -100 * GVAR(camSpeed)]; - GVAR(camDolly) set [1, _deltaY * 100 * GVAR(camSpeed)]; -} else { - if (_rightButton) then { - // Pan/Tilt amount should be influnced by zoom level (it should really be exponential) - _zoomMod = (GVAR(camZoom) * 0.8) max 1; - - GVAR(camPan) = GVAR(camPan) - ((_deltaX * 360) / _zoomMod); - GVAR(camTilt) = ((GVAR(camTilt) + ((_deltaY * 180) / _zoomMod)) min 89) max -89; - }; -}; - -GVAR(mousePos) = [_x,_y]; diff --git a/addons/spectator/functions/fnc_handleToolbar.sqf b/addons/spectator/functions/fnc_handleToolbar.sqf deleted file mode 100644 index 4e79c172bd..0000000000 --- a/addons/spectator/functions/fnc_handleToolbar.sqf +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Author: Karel Moricky, SilentSpike - * Handles the spectator UI toolbar values - * - * Arguments: - * 0: Parameters - * 1: PFH handle - * - * Return Value: - * None - * - * Example: - * [ace_spectator_fnc_handleToolbar, 0, _display] call CBA_fnc_addPerFrameHandler; - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_display"]; - -// Kill PFH when toolbar hidden (or display is closed) -if (isNil QGVAR(toolHandler)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; }; - -private ["_name","_vision","_fov","_speed","_mode","_time","_toolbar"]; -_toolbar = _display displayCtrl IDC_TOOL; - -// Find all tool values -if (GVAR(camVision) >= 0) then { - _vision = localize LSTRING(VisionThermal); -} else { - _vision = [localize LSTRING(VisionNight), localize LSTRING(VisionNormal)] select (GVAR(camVision) < -1); -}; - -if (GVAR(camMode) == 0) then { - _fov = format ["%1x", floor(GVAR(camZoom) * 100) * 0.01]; - _speed = format ["%1 m/s", floor(GVAR(camSpeed) * 100) * 0.01]; -} else { - _vision = [side group GVAR(camUnit)] call BIS_fnc_sideName; - _fov = format ["%1 m", floor(getPosASL GVAR(camUnit) select 2)]; - _speed = format ["%1 km/h", floor(speed GVAR(camUnit)) max 0]; -}; - -if (alive GVAR(camUnit)) then { - _name = GETVAR(GVAR(camUnit),GVAR(uName),""); -} else { - _name = localize "STR_Special_None"; -}; - -_mode = [localize LSTRING(ViewFree),localize LSTRING(ViewInternal),localize LSTRING(ViewExternal)] select GVAR(camMode); -_time = [daytime,"HH:MM"] call BIS_fnc_timeToString; - -// Update the UI tools -(_toolbar controlsGroupCtrl IDC_TOOL_CLOCK) ctrlSetText _time; -(_toolbar controlsGroupCtrl IDC_TOOL_VISION) ctrlSetText _vision; -(_toolbar controlsGroupCtrl IDC_TOOL_FOV) ctrlSetText _fov; -(_toolbar controlsGroupCtrl IDC_TOOL_NAME) ctrlSetText _name; -(_toolbar controlsGroupCtrl IDC_TOOL_SPEED) ctrlSetText _speed; -(_toolbar controlsGroupCtrl IDC_TOOL_VIEW) ctrlSetText _mode; diff --git a/addons/spectator/functions/fnc_handleUnits.sqf b/addons/spectator/functions/fnc_handleUnits.sqf deleted file mode 100644 index f51c922b8e..0000000000 --- a/addons/spectator/functions/fnc_handleUnits.sqf +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Author: SilentSpike - * Maintains the spectatable unit list and updates the unit tree accordingly - * Also updates current camera unit when status changes - * - * Arguments: - * 0: Parameters - * 1: PFH handle - * - * Return Value: - * None - * - * Example: - * [ace_spectator_fnc_handleUnits, 10, _display] call CBA_fnc_addPerFrameHandler; - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_display"]; - -// Kill PFH when display is closed -if (isNull _display) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; }; - -// Remove all dead and null units from the list -[] call FUNC(updateUnits); - -// Camera shouldn't stay on unit that isn't in the list (unless dead) -if !(GVAR(camUnit) in GVAR(unitList)) then { - if (alive GVAR(camUnit) || isNull GVAR(camUnit)) then { - [nil,1] call FUNC(cycleCamera); - }; -}; - -// Reduce overhead when unit tree is hidden -if (ctrlShown (_display displayCtrl IDC_UNIT)) then { - // Reduce overhead by spreading across frames - [FUNC(handleInterface),["onUnitsUpdate",[(_display displayCtrl IDC_UNIT) controlsGroupCtrl IDC_UNIT_TREE]],1] call CBA_fnc_waitAndExecute; -}; diff --git a/addons/spectator/functions/fnc_interrupt.sqf b/addons/spectator/functions/fnc_interrupt.sqf deleted file mode 100644 index 0826949b30..0000000000 --- a/addons/spectator/functions/fnc_interrupt.sqf +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Author: SilentSpike - * Interrupts the spectator interface for external systems - * - * Arguments: - * 0: Reason - * 1: Interrupting (default: true) - * - * Return Value: - * None - * - * Example: - * ["mySystem"] call ace_spectator_fnc_interrupt - * - * Public: Yes - */ -#include "script_component.hpp" - -params [["_reason", "", [""]], ["_interrupt", true, [true]]]; - -// Nothing to do when spectator is closed -if !(GVAR(isSet)) exitWith {}; - -if (_reason == "") exitWith { ERROR("Invalid Reason"); }; -if (_interrupt) then { - GVAR(interrupts) pushBack _reason; -} else { - GVAR(interrupts) = GVAR(interrupts) - [_reason]; -}; - -if (GVAR(interrupts) isEqualTo []) then { - if (isNull (GETUVAR(GVAR(interface),displayNull))) then { - (findDisplay 46) createDisplay QGVAR(interface); - [] call FUNC(transitionCamera); - }; -} else { - if !(isNull (GETUVAR(GVAR(interface),displayNull))) then { - while {dialog} do { - closeDialog 0; - }; - - (GETUVAR(GVAR(interface),displayNull)) closeDisplay 0; - }; -}; diff --git a/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf b/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf index 8224c77e57..4a7c891497 100644 --- a/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf +++ b/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf @@ -8,7 +8,7 @@ * 2: activated * * Return Value: - * None + * None * * Example: * [LOGIC, [bob, kevin], true] call ace_spectator_fnc_moduleSpectatorSettings @@ -22,7 +22,6 @@ params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; -[_logic, QGVAR(filterUnits), "unitsFilter"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(filterSides), "sidesFilter"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(enableAI), "enableAI"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(restrictModes), "cameraModes"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(restrictVisions), "visionModes"] call EFUNC(common,readSettingFromModule); diff --git a/addons/spectator/functions/fnc_players.sqf b/addons/spectator/functions/fnc_players.sqf new file mode 100644 index 0000000000..3525b835d5 --- /dev/null +++ b/addons/spectator/functions/fnc_players.sqf @@ -0,0 +1,19 @@ +/* + * Author: SilentSpike + * Return all of the player entities who are currently in ace spectator + * + * Arguments: + * None + * + * Return Value: + * Spectator Players + * + * Example: + * [] call ace_spectator_fnc_players + * + * Public: Yes + */ + +#include "script_component.hpp" + +allPlayers select { GETVAR(_x,GVAR(isSet),false) } diff --git a/addons/spectator/functions/fnc_respawnTemplate.sqf b/addons/spectator/functions/fnc_respawnTemplate.sqf index 59759d1371..d5b91bbd2e 100644 --- a/addons/spectator/functions/fnc_respawnTemplate.sqf +++ b/addons/spectator/functions/fnc_respawnTemplate.sqf @@ -1,7 +1,8 @@ /* * Author: SilentSpike - * The ace_spectator respawn template, handles killed + respawn - * Can be used via BI's respawn framework, see: + * The ace_spectator respawn template, compatible with types 1,2,3,4 & 5 + * + * Handles killed and respawned events as per BI's respawn framework: * https://community.bistudio.com/wiki/Arma_3_Respawn * * Arguments: @@ -11,7 +12,7 @@ * 3: Respawn Delay * * Return Value: - * None + * None * * Example: * [bob, kevin, 3, 6] call ace_spectator_fnc_respawnTemplate @@ -21,26 +22,22 @@ #include "script_component.hpp" -params [["_unit",objNull,[objNull]], ["_killer",objNull,[objNull]], ["_respawn",0,[0]], ["_respawnDelay",0,[0]]]; +params [["_newCorpse",objNull,[objNull]], ["_oldKiller",objNull,[objNull]], ["_respawn",0,[0]], ["_respawnDelay",0,[0]]]; +TRACE_4("respawnTemplate",_newCorpse,_oldKiller,_respawn,_respawnDelay); -// Some environment information can be used for the initial camera attributes -if (isNull _killer) then {_killer = _unit}; -private _vision = [-2,-1] select (sunOrMoon < 1); -private _pos = (getPosATL _unit) vectorAdd [0,0,5]; - -// Enter/exit spectator based on the respawn type and whether killed/respawned -if (alive _unit) then { - if (_respawn == 1) then { - [_unit] call FUNC(stageSpectator); - [2,_killer,_vision,_pos,getDir _unit] call FUNC(setCameraAttributes); - [true] call FUNC(setSpectator); - } else { - [false] call FUNC(setSpectator); - }; -} else { - // Negligible respawn delay can result in entering spectator after respawn - if (playerRespawnTime <= 1) exitWith {}; - - [2,_killer,_vision,_pos,getDir _unit] call FUNC(setCameraAttributes); - [true] call FUNC(setSpectator); +// Compatibility handled via spectator display XEH +if (_respawn in [0,1,4,5]) exitWith { + // This only applies to respawn type 1 (BIRD/SPECTATOR) + // Remove the seagull (not actually the player, a CfgNonAIVehicles object) + if (typeOf _newCorpse == "seagull") then { deleteVehicle _newCorpse; }; +}; + +// Virtual spectators should be ignored by the template (otherwise they break) +if (_newCorpse isKindOf QGVAR(virtual)) exitWith {}; + +// If player died while already in spectator, ignore +if (!GVAR(isSet) || {alive _newCorpse}) then { + // Negligible respawn delay can result in entering spectator after respawn + // So we just use this value rather than living state of the unit + [playerRespawnTime > 1] call FUNC(setSpectator); }; diff --git a/addons/spectator/functions/fnc_setCameraAttributes.sqf b/addons/spectator/functions/fnc_setCameraAttributes.sqf index fac9c94059..c9a272407b 100644 --- a/addons/spectator/functions/fnc_setCameraAttributes.sqf +++ b/addons/spectator/functions/fnc_setCameraAttributes.sqf @@ -1,27 +1,30 @@ /* * Author: SilentSpike - * Sets the spectator camera attributes as desired - * All values are optional and default to whatever the current value is + * Sets the spectator camera attributes as desired. Local effect. + * All values are optional and default to no change. * * Arguments: * 0: Camera mode * - 0: Free - * - 1: Internal - * - 2: External - * 1: Camera unit (objNull for random) + * - 1: First Person + * - 2: Follow + * 1: Camera focus * 2: Camera vision * - -2: Normal * - -1: Night vision * - 0: Thermal white hot * - 1: Thermal black hot + * - ... * 3: Camera position (ATL) - * 4: Camera pan (0 - 360) - * 5: Camera tilt (-90 - 90) - * 6: Camera zoom (0.01 - 2) - * 7: Camera speed in m/s (0.05 - 10) + * 4: Camera direction (0 - 360) + * + * Notes: + * - If camera mode is not free and camera has no focus, random will be used + * - To remove any current camera focus in free cam, use objNull + * - To select a random camera focus, use a boolean * * Return Value: - * None + * None * * Example: * [1, objNull] call ace_spectator_fnc_setCameraAttributes @@ -32,37 +35,64 @@ #include "script_component.hpp" params [ - ["_mode",GVAR(camMode),[0]], - ["_unit",GVAR(camUnit),[objNull]], - ["_vision",GVAR(camVision),[0]], - ["_position",ASLtoATL GVAR(camPos),[[]],3], - ["_heading",GVAR(camPan),[0]], - ["_tilt",GVAR(camTilt),[0]], - ["_zoom",GVAR(camZoom),[0]], - ["_speed",GVAR(camSpeed),[0]] + ["_mode",nil,[0]], + ["_focus",nil,[objNull,true]], + ["_vision",nil,[0]], + ["_position",nil,[[]],3], + ["_direction",nil,[0]] ]; -// Normalize input -if !(_mode in GVAR(availableModes)) then { - _mode = GVAR(availableModes) select ((GVAR(availableModes) find GVAR(camMode)) max 0); -}; - -if !(_vision in GVAR(availableVisions)) then { - _vision = GVAR(availableVisions) select ((GVAR(availableVisions) find GVAR(camVision)) max 0); -}; - -GVAR(camPan) = _heading % 360; -GVAR(camSpeed) = (_speed max 0.05) min 10; -GVAR(camTilt) = (_tilt max -89) min 89; -GVAR(camUnit) = _unit; -GVAR(camVision) = _vision; -GVAR(camZoom) = (_zoom min 2) max 0.01; - // Apply if camera exists -if (GVAR(isSet)) then { - GVAR(camPos) = (ATLtoASL _position); // Camera position will be updated in FUNC(handleCamera) - [_mode,_unit,_vision] call FUNC(transitionCamera); +if !(isNil QGVAR(camera)) then { + // These functions are smart and handle unavailable inputs + if !(isNil "_focus") then { + [_focus] call FUNC(setFocus); + }; + + if !(isNil "_mode") then { + // If mode not free and no focus, find focus + if ((_mode != MODE_FREE) && {isNull GVAR(camFocus)}) then { + [true] call FUNC(setFocus); + }; + + [_mode] call FUNC(cam_setCameraMode); + }; + + if !(isNil "_vision") then { + [_vision] call FUNC(cam_setVisionMode); + }; + + if !(isNil "_position") then { + GVAR(camera) setPosATL _position; + }; + + if !(isNil "_direction") then { + GVAR(camera) setDir _direction; + }; } else { - GVAR(camMode) = _mode; - GVAR(camPos) = (ATLtoASL _position); + if !(isNil "_focus") then { + // If there are no entities this becomes nil, handled on camera startup + if (_focus isEqualType true) then { + _focus = ([] call FUNC(getTargetEntities)) select 0; + }; + + GVAR(camFocus) = _focus; + }; + + if !(isNil "_mode") then { + GVAR(camMode) = _mode; + }; + + if !(isNil "_vision") then { + GVAR(camVision) = _vision; + }; + + // GVARs exits purely for pre-setting of these attributes + if !(isNil "_position") then { + GVAR(camPos) = ATLtoASL _position; + }; + + if !(isNil "_direction") then { + GVAR(camDir) = _direction; + }; }; diff --git a/addons/spectator/functions/fnc_setFocus.sqf b/addons/spectator/functions/fnc_setFocus.sqf new file mode 100644 index 0000000000..e2054ecfe6 --- /dev/null +++ b/addons/spectator/functions/fnc_setFocus.sqf @@ -0,0 +1,59 @@ +/* + * Author: AACO, SilentSpike + * Function used to set the camera focus + * + * Arguments: + * 0: New focus + * + * Return Value: + * None + * + * Example: + * [player] call ace_spectator_fnc_setFocus + * + * Public: No + */ + +#include "script_component.hpp" + +params [["_newFocus", objNull, [objNull,true]]]; + +// If boolean provided then first find a focus +if (_newFocus isEqualType true) then { + private _testFocus = ([] call FUNC(getTargetEntities)) select 0; + + if (isNil "_testFocus") then { + if (MODE_FREE in GVAR(availableModes)) then { + WARNING("No available entities to focus on. Switching to free cam."); + [MODE_FREE] call FUNC(cam_setCameraMode); + _newFocus = objNull; + } else { + // Default to player if necessary + WARNING("No available entities to focus on. Using player."); + _newFocus = player; + }; + } else { + _newFocus = _testFocus; + }; +}; + +if (_newFocus != GVAR(camFocus) && { !(isNull _newFocus && { isNull GVAR(camFocus) }) }) then { + GVAR(camFocus) = _newFocus; + + if (isNull _newFocus) then { + if (GVAR(camMode) == MODE_FREE) then { + [] call FUNC(cam_resetTarget); + } else { + [MODE_FREE] call FUNC(cam_setCameraMode); + }; + } else { + [GVAR(camMode)] call FUNC(cam_setCameraMode); + }; + + // Only update display if it exists, this function is independent of it + if !(isNull SPEC_DISPLAY) then { + [] call FUNC(ui_updateListFocus); + [] call FUNC(ui_updateWidget); + [] call FUNC(ui_updateHelp); + }; +}; diff --git a/addons/spectator/functions/fnc_setSpectator.sqf b/addons/spectator/functions/fnc_setSpectator.sqf index 45bb15df42..ca829559e7 100644 --- a/addons/spectator/functions/fnc_setSpectator.sqf +++ b/addons/spectator/functions/fnc_setSpectator.sqf @@ -1,17 +1,17 @@ /* * Author: SilentSpike - * Sets local client to the given spectator state (virtually) - * To physically handle a spectator see ace_spectator_fnc_stageSpectator + * Enter/exit spectator mode for the local player * * Client will be able to communicate in ACRE/TFAR as appropriate - * The spectator interface will be opened/closed + * If "hide player" is true player will be hidden from group, invisible and invulnerable, but unmoved * * Arguments: * 0: Spectator state of local client (default: true) * 1: Force interface (default: true) + * 2: Hide player (if alive) (default: true) * * Return Value: - * None + * None * * Example: * [true] call ace_spectator_fnc_setSpectator @@ -21,47 +21,44 @@ #include "script_component.hpp" -params [["_set",true,[true]], ["_force",true,[true]]]; +params [["_set",true,[true]], ["_force",true,[true]], ["_hide",true,[true]]]; +TRACE_3("Params",_set,_force,_hide); // Only clients can be spectators if !(hasInterface) exitWith {}; -// Exit if no change +// Let the display know if it is or isn't forced +// Could be switched after spectator has already started +GVAR(uiForced) = _force; + +// Exit if no change (everything above this may need to be ran again) if (_set isEqualTo GVAR(isSet)) exitWith {}; -// Handle common addon audio +// Delay if local player (must not be ACE_Player) does not exist +if (isNull player) exitWith { + [ + { !isNull player }, + FUNC(setSpectator), + _this + ] call CBA_fnc_waitUntilAndExecute; +}; + +// Remove any current deafness and disable volume updates while spectating if (["ace_hearing"] call EFUNC(common,isModLoaded)) then { EGVAR(hearing,disableVolumeUpdate) = _set; EGVAR(hearing,deafnessDV) = 0; }; + +// Toggle spectator mode in 3rd party radio addons if (["acre_sys_radio"] call EFUNC(common,isModLoaded)) then {[_set] call acre_api_fnc_setSpectator}; if (["task_force_radio"] call EFUNC(common,isModLoaded)) then {[player, _set] call TFAR_fnc_forceSpectator}; if (_set) then { - // Initalize camera variables - GVAR(camBoom) = 0; - GVAR(camDolly) = [0,0]; - GVAR(camGun) = false; + // Initalize the camera + [true] call FUNC(cam); - // Initalize display variables - GVAR(ctrlKey) = false; - GVAR(heldKeys) = []; - GVAR(heldKeys) resize 255; - GVAR(mouse) = [false,false]; - GVAR(mousePos) = [0.5,0.5]; - - // Update units before opening to support pre-set camera unit - [] call FUNC(updateUnits); - - // Initalize the camera objects - GVAR(freeCamera) = "Camera" camCreate (ASLtoATL GVAR(camPos)); - GVAR(unitCamera) = "Camera" camCreate [0,0,0]; - GVAR(targetCamera) = "Camera" camCreate [0,0,0]; - - // Initalize view - GVAR(unitCamera) camSetTarget GVAR(targetCamera); - GVAR(unitCamera) camCommit 0; - [] call FUNC(transitionCamera); + // Create the display when main display is ready + [{ !isNull MAIN_DISPLAY },{ [true] call FUNC(ui) }] call CBA_fnc_waitUntilAndExecute; // Cache current channel to switch back to on exit GVAR(channelCache) = currentChannel; @@ -70,35 +67,6 @@ if (_set) then { GVAR(channel) radioChannelAdd [player]; setCurrentChannel (5 + GVAR(channel)); - // Close map and clear the chat - openMap [false,false]; - clearRadio; - enableRadio false; - - // Disable BI damage effects - BIS_fnc_feedback_allowPP = false; - - // Close any open dialogs - while {dialog} do { - closeDialog 0; - }; - - [{ - disableSerialization; - // Create the display - _display = (findDisplay 46) createDisplay QGVAR(interface); - - // If not forced, make esc end spectator - if (_this) then { - _display displayAddEventHandler ["KeyDown", { - if (_this select 1 == 1) then { - [false] call FUNC(setSpectator); - true - }; - }]; - }; - }, !_force] call CBA_fnc_execNextFrame; - // Cache and disable nametag settings if (["ace_nametags"] call EFUNC(common,isModLoaded)) then { GVAR(nametagSettingCache) = [EGVAR(nametags,showPlayerNames), EGVAR(nametags,showNamesForAI)]; @@ -106,19 +74,14 @@ if (_set) then { EGVAR(nametags,showNamesForAI) = false; }; } else { - // Close any open dialogs (could be interrupts) - while {dialog} do { - closeDialog 0; - }; + // Kill the display (ensure main display exists, handles edge case where spectator turned off beforehand) + [{ !isNull MAIN_DISPLAY },{ [false] call FUNC(ui) }] call CBA_fnc_waitUntilAndExecute; - // Kill the display - (GETUVAR(GVAR(interface),displayNull)) closeDisplay 0; + // This variable doesn't matter anymore + GVAR(uiForced) = nil; // Terminate camera - GVAR(freeCamera) cameraEffect ["terminate", "back"]; - camDestroy GVAR(freeCamera); - camDestroy GVAR(unitCamera); - camDestroy GVAR(targetCamera); + [false] call FUNC(cam); // Remove from spectator chat GVAR(channel) radioChannelRemove [player]; @@ -127,35 +90,6 @@ if (_set) then { setCurrentChannel GVAR(channelCache); GVAR(channelCache) = nil; - // Clear any residual spectator chat - clearRadio; - enableRadio true; - - // Return to player view - player switchCamera "internal"; - - // Enable BI damage effects - BIS_fnc_feedback_allowPP = true; - - // Cleanup camera variables - GVAR(camBoom) = nil; - GVAR(camDolly) = nil; - GVAR(camGun) = nil; - GVAR(freeCamera) = nil; - GVAR(unitCamera) = nil; - GVAR(targetCamera) = nil; - - //Kill these PFEH handlers now because the PFEH can run before the `onunload` event is handled - GVAR(camHandler) = nil; - GVAR(compHandler) = nil; - GVAR(toolHandler) = nil; - - // Cleanup display variables - GVAR(ctrlKey) = nil; - GVAR(heldKeys) = nil; - GVAR(mouse) = nil; - GVAR(mousePos) = nil; - // Reset nametag settings if (["ace_nametags"] call EFUNC(common,isModLoaded)) then { EGVAR(nametags,showPlayerNames) = GVAR(nametagSettingCache) select 0; @@ -164,10 +98,33 @@ if (_set) then { }; }; +// Hide/Unhide the player if enabled and alive +if (alive player) then { + private _hidden = (_hide && _set); + TRACE_1("",_hidden); + + // Ignore damage (vanilla and ace_medical) + player allowDamage !_hidden; + player setVariable [QEGVAR(medical,allowDamage), !_hidden]; + + // Move to/from group as appropriate + [player, _hidden, QGVAR(isSet), side group player] call EFUNC(common,switchToGroupSide); + + // Ghosts can't talk + if (_hidden) then { + [player, QGVAR(isSet)] call EFUNC(common,hideUnit); + [player, QGVAR(isSet)] call EFUNC(common,muteUnit); + } else { + [player, QGVAR(isSet)] call EFUNC(common,unhideUnit); + [player, QGVAR(isSet)] call EFUNC(common,unmuteUnit); + }; +}; + // Reset interruptions GVAR(interrupts) = []; // Mark spectator state for reference GVAR(isSet) = _set; +player setVariable [QGVAR(isSet), _set, true]; -["ace_spectatorSet", [_set]] call CBA_fnc_localEvent; +["ace_spectatorSet", [_set, player]] call CBA_fnc_globalEvent; diff --git a/addons/spectator/functions/fnc_stageSpectator.sqf b/addons/spectator/functions/fnc_stageSpectator.sqf deleted file mode 100644 index a7cc926d33..0000000000 --- a/addons/spectator/functions/fnc_stageSpectator.sqf +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Author: SilentSpike - * Sets target unit to the given spectator state (physically) - * To virtually handle a spectator see ace_spectator_fnc_setSpectator - * - * Units will be gathered at marker ace_spectator_respawn (or [0,0,0] by default) - * Upon unstage, units will be moved to the position they were in upon staging - * - * Arguments: - * 0: Unit to put into spectator stage (default: player) - * 1: Unit should be staged (default: true) - * - * Return Value: - * None - * - * Example: - * [player, false] call ace_spectator_fnc_stageSpectator - * - * Public: Yes - */ - -#include "script_component.hpp" - -params [["_unit",player,[objNull]], ["_set",true,[true]]]; - -// No change, no service (but allow spectators to be reset) -if !(_set || (GETVAR(_unit,GVAR(isStaged),false))) exitWith {}; - -if !(local _unit) exitWith { - [QGVAR(stageSpectator), [_unit, _set], _unit] call CBA_fnc_targetEvent; -}; - -// Prevent unit falling into water -_unit enableSimulation !_set; - -// Move to/from group as appropriate -[_unit, _set, QGVAR(isStaged), side group _unit] call EFUNC(common,switchToGroupSide); - -if (_set) then { - // Position should only be saved on first entry - if !(GETVAR(_unit,GVAR(isStaged),false)) then { - GVAR(oldPos) = getPosATL _unit; - }; - - // Ghosts can't talk - [_unit, QGVAR(isStaged)] call EFUNC(common,hideUnit); - [_unit, QGVAR(isStaged)] call EFUNC(common,muteUnit); - - _unit setPos (markerPos QGVAR(respawn)); -} else { - // Physical beings can talk - [_unit, QGVAR(isStaged)] call EFUNC(common,unhideUnit); - [_unit, QGVAR(isStaged)] call EFUNC(common,unmuteUnit); - - _unit setPosATL GVAR(oldPos); -}; - -// Spectators ignore damage (vanilla and ace_medical) -_unit allowDamage !_set; -_unit setVariable [QEGVAR(medical,allowDamage), !_set]; - -// No theoretical change if an existing spectator was reset -if !(_set isEqualTo (GETVAR(_unit,GVAR(isStaged),false))) then { - // Mark spectator state for reference - _unit setVariable [QGVAR(isStaged), _set, true]; - - ["ace_spectatorStaged", [_set]] call CBA_fnc_localEvent; -}; - -//BandAid for #2677 - if player in unitList weird before being staged, weird things can happen -if ((player in GVAR(unitList)) || {ACE_player in GVAR(unitList)}) then { - [] call FUNC(updateUnits); //update list now - if (!(isNull (findDisplay 12249))) then {//If display is open now, close it and restart - WARNING("Player in unitList, call ace_spectator_fnc_stageSpectator before ace_spectator_fnc_setSpectator"); - ["fixWeirdList", true] call FUNC(interrupt); - [{["fixWeirdList", false] call FUNC(interrupt);}, []] call CBA_fnc_execNextFrame; - }; -}; diff --git a/addons/spectator/functions/fnc_switchFocus.sqf b/addons/spectator/functions/fnc_switchFocus.sqf new file mode 100644 index 0000000000..444bd72b6d --- /dev/null +++ b/addons/spectator/functions/fnc_switchFocus.sqf @@ -0,0 +1,31 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Function used to switch to next or previous camera focus + * + * Arguments: + * 0: Next/Prev unit + * + * Return Value: + * None + * + * Example: + * [false] call ace_spectator_fnc_switchFocus + * + * Public: No + */ + +#include "script_component.hpp" + +private _next = param [0, true]; +private _entities = [true] call FUNC(getTargetEntities); +private _focus = GVAR(camFocus); + +// No entities to switch to +if ((_entities isEqualTo []) || (_entities isEqualTo [_focus])) exitWith {}; + +private _index = (_entities find _focus) max 0; + +_index = (_index + ([-1, 1] select _next)) % (count _entities); +if (_index < 0) then { _index = count _entities + _index; }; + +[_entities select _index] call FUNC(setFocus); diff --git a/addons/spectator/functions/fnc_toggleInterface.sqf b/addons/spectator/functions/fnc_toggleInterface.sqf deleted file mode 100644 index 4bf10fdbfe..0000000000 --- a/addons/spectator/functions/fnc_toggleInterface.sqf +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Author: SilentSpike - * Correctly handles toggling of spectator interface elements for clean UX - * - * Arguments: - * 0: Display - * 1: Toogle compass - * 2: Toogle help - * 3: Toogle interface - * 4: Toogle map - * 5: Toogle toolbar - * 6: Toogle unit list - * - * Return Value: - * None - * - * Example: - * [_display, nil, true] call ace_spectator_fnc_toggleInterface - * - * Public: No - */ - -#include "script_component.hpp" - -params ["_display", ["_toggleComp",false], ["_toggleHelp",false], ["_toggleInterface",false], ["_toggleMap",false], ["_toggleTool",false], ["_toggleUnit",false]]; - -private ["_comp","_help","_map","_tool","_unit"]; -_comp = _display displayCtrl IDC_COMP; -_help = _display displayCtrl IDC_HELP; -_map = _display displayCtrl IDC_MAP; -_tool = _display displayCtrl IDC_TOOL; -_unit = _display displayCtrl IDC_UNIT; - -// Map operates outside of interface -GVAR(showMap) = [GVAR(showMap), !GVAR(showMap)] select _toggleMap; -_map ctrlShow GVAR(showMap); - -if (GVAR(showMap)) then { - // When map is shown, temporarily hide interface to stop overlapping - { - _x ctrlShow false; - } forEach [_comp,_help,_tool,_unit]; - - // Centre map on camera/unit upon opening - if (_toggleMap) then { - _map ctrlMapAnimAdd [0, 0.5, [GVAR(camUnit),GVAR(freeCamera)] select (GVAR(camMode) == 0)]; - ctrlMapAnimCommit _map; - }; -} else { - // Can only toggle interface with map minimised - GVAR(showInterface) = [GVAR(showInterface), !GVAR(showInterface)] select _toggleInterface; - - if (GVAR(showInterface)) then { - // Can only toggle interface elements with interface shown - GVAR(showComp) = [GVAR(showComp), !GVAR(showComp)] select _toggleComp; - GVAR(showHelp) = [GVAR(showHelp), !GVAR(showHelp)] select _toggleHelp; - GVAR(showTool) = [GVAR(showTool), !GVAR(showTool)] select _toggleTool; - GVAR(showUnit) = [GVAR(showUnit), !GVAR(showUnit)] select _toggleUnit; - - _comp ctrlShow GVAR(showComp); - _help ctrlShow GVAR(showHelp); - _tool ctrlShow GVAR(showTool); - _unit ctrlShow GVAR(showUnit); - } else { - { - _x ctrlShow false; - } forEach [_comp,_help,_tool,_unit]; - }; -}; - -// Only run PFHs when respective control is shown, otherwise kill -if (ctrlShown _comp) then { - if (isNil QGVAR(compHandler)) then { GVAR(compHandler) = [FUNC(handleCompass), 0, _display] call CBA_fnc_addPerFrameHandler; }; -} else { - GVAR(compHandler) = nil; -}; - -if (ctrlShown _tool) then { - if (isNil QGVAR(toolHandler)) then { GVAR(toolHandler) = [FUNC(handleToolbar), 0, _display] call CBA_fnc_addPerFrameHandler; }; -} else { - GVAR(toolHandler) = nil; -}; diff --git a/addons/spectator/functions/fnc_transitionCamera.sqf b/addons/spectator/functions/fnc_transitionCamera.sqf deleted file mode 100644 index 254dfef131..0000000000 --- a/addons/spectator/functions/fnc_transitionCamera.sqf +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Author: SilentSpike - * Transitions the spectator camera vision/view/unit - * - * Arguments: - * 0: Camera mode - * - 0: Free - * - 1: Internal - * - 2: External - * 1: Camera unit - * 2: Vision mode - * - -2: Normal - * - -1: NV - * - 0: White hot - * - 1: Black hot - * - * Return Value: - * None - * - * Example: - * [0,objNull] call ace_spectator_fnc_transitionCamera - * - * Public: No - */ - -#include "script_component.hpp" - -params [["_newMode",GVAR(camMode)], ["_newUnit",GVAR(camUnit)], ["_newVision",GVAR(camVision)]]; - -// If new mode isn't available then keep current (unless current also isn't) -if !(_newMode in GVAR(availableModes)) then { - _newMode = GVAR(availableModes) select ((GVAR(availableModes) find GVAR(camMode)) max 0); -}; - -// When no units available to spectate, exit to freecam -if ((GVAR(unitList) isEqualTo []) && (alive _newUnit || isNull _newUnit)) then { - _newMode = 0; - _newUnit = objNull; -}; - -// Reset gun cam if not internal -if (_newMode != 1) then { - GVAR(camGun) = false; -}; - -private ["_camera"]; -if (_newMode == 0) then { // Free - _camera = GVAR(freeCamera); - - // Preserve camUnit value for consistency when manually changing view - _camera cameraEffect ["internal", "back"]; - - // Apply the camera zoom - _camera camSetFov -(linearConversion [0.01,2,GVAR(camZoom),-2,-0.01,true]); - _camera camCommit 0; - - // Agent is switched to in free cam to hide death table and prevent AI chat while allowing icons to draw (also prevents systemChat and unit HUD) - // (Why is so much stuff tied into the current camera unit BI?!) - if (isNull GVAR(camAgent)) then { - GVAR(camAgent) = createAgent ["VirtualMan_F",markerPos QGVAR(respawn),[],0,""]; - }; - - GVAR(camAgent) switchCamera "internal"; -} else { - _camera = GVAR(unitCamera); - - // When null unit is given choose random - if (isNull _newUnit) then { - _newUnit = selectRandom GVAR(unitList); - }; - - // Switch camera view to internal unit view (external uses the camera) - if (GVAR(camGun)) then { - _newUnit switchCamera "gunner"; - } else { - _newUnit switchCamera "internal"; - }; - - // Handle camera differently for internal/external view - if (_newMode == 1) then { - // Terminate camera view - _camera cameraEffect ["terminate", "back"]; - GVAR(camHandler) = nil; - } else { - // Switch to the camera - _camera cameraEffect ["internal", "back"]; - }; - - GVAR(camUnit) = _newUnit; -}; - -if (_newMode in [0,2]) then { - // Set up camera UI - showCinemaBorder false; - cameraEffectEnableHUD true; - - // Handle camera movement - if (isNil QGVAR(camHandler)) then { GVAR(camHandler) = [FUNC(handleCamera), 0] call CBA_fnc_addPerFrameHandler; }; - - // If new vision isn't available then keep current (unless current also isn't) - if !(_newVision in GVAR(availableVisions)) then { - _newVision = GVAR(availableVisions) select ((GVAR(availableVisions) find GVAR(camVision)) max 0); - }; - - // Vision mode applies to free and external cam - if (_newVision < 0) then { - false setCamUseTi 0; - camUseNVG (_newVision >= -1); - } else { - true setCamUseTi _newVision; - }; - GVAR(camVision) = _newVision; -}; - -GVAR(camMode) = _newMode; diff --git a/addons/spectator/functions/fnc_ui.sqf b/addons/spectator/functions/fnc_ui.sqf new file mode 100644 index 0000000000..475f794deb --- /dev/null +++ b/addons/spectator/functions/fnc_ui.sqf @@ -0,0 +1,191 @@ +/* + * Author: SilentSpike + * Handles UI initialisation and destruction + * + * Arguments: + * 0: Init/Terminate + * + * Return Value: + * None + * + * Example: + * [false] call ace_spectator_fnc_ui + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_init"]; +TRACE_1("ui",_init); + +// No change +if (_init isEqualTo !isNull SPEC_DISPLAY) exitWith {}; + +// Close map +openMap [false,false]; + +// Close any open dialogs +while {dialog} do { + closeDialog 0; +}; + +// Controls some PP effects, but a little unclear which +BIS_fnc_feedback_allowPP = !_init; + +// Removes death blur if present +if !(isNil "BIS_DeathBlur") then { + BIS_DeathBlur ppEffectAdjust [0]; + BIS_DeathBlur ppEffectCommit 0; +}; + +// Note that init and destroy intentionally happen in reverse order +// Init: Vars > Display > UI Stuff +// Destroy: UI Stuff > Display > Vars +if (_init) then { + // UI visibility tracking + GVAR(uiVisible) = true; + GVAR(uiHelpVisible) = true; + GVAR(uiMapVisible) = true; + GVAR(uiWidgetVisible) = true; + + // Drawing related + GVAR(drawProjectiles) = false; + GVAR(drawUnits) = true; + GVAR(entitiesToDraw) = []; + GVAR(grenadesToDraw) = []; + GVAR(iconsToDraw) = []; + GVAR(projectilesToDraw) = []; + + // RMB tracking is used for follow camera mode + GVAR(holdingRMB) = false; + + // Highlighted map object is used for click and drawing events + GVAR(uiMapHighlighted) = objNull; + + // Holds the current list data + GVAR(curList) = []; + + // Cache view distance and set spectator default + GVAR(oldViewDistance) = viewDistance; + setViewDistance DEFAULT_VIEW_DISTANCE; + + // If counter already exists handle it, otherwise display XEH will handle it + [GETUVAR(RscRespawnCounter,displayNull)] call FUNC(compat_counter); + + // Create the display + MAIN_DISPLAY createDisplay QGVAR(display); + + // Store default H value for scaling purposes + GVAR(uiHelpH) = (ctrlPosition CTRL_HELP) select 3; + + // Initially hide map + [] call FUNC(ui_toggleMap); + + // Initially fade the list + [true] call FUNC(ui_fadeList); + + // Initalise the help, widget and list information + [] call FUNC(ui_updateCamButtons); + [] call FUNC(ui_updateListEntities); + [] call FUNC(ui_updateListFocus); + [] call FUNC(ui_updateWidget); + [] call FUNC(ui_updateHelp); + + // Start updating things to draw + GVAR(collectPFH) = [LINKFUNC(ui_updateIconsToDraw), 0.2] call CBA_fnc_addPerFrameHandler; + + // Draw icons and update the cursor object + GVAR(uiDraw3D) = addMissionEventHandler ["Draw3D", {call FUNC(ui_draw3D)}]; + + // Periodically update list and focus widget + GVAR(uiPFH) = [{ + [] call FUNC(ui_updateListEntities); + [] call FUNC(ui_updateWidget); + }, 5] call CBA_fnc_addPerFrameHandler; + + // register grenade track EH + GVAR(grenadeTrackingEH) = [ + QGVAR(addToGrenadeTracking), { + params [["_projectile", objNull, [objNull]]]; + if (GVAR(drawProjectiles) && {!isNull _projectile}) then { + if (count GVAR(grenadesToDraw) > MAX_GRENADES) then { GVAR(grenadesToDraw) deleteAt 0; }; + GVAR(grenadesToDraw) pushBack _projectile; + }; + } + ] call CBA_fnc_addEventHandler; + + // register projectile track EH + GVAR(projectileTrackingEH) = [ + QGVAR(addToProjectileTracking), { + params [["_projectile", objNull, [objNull]]]; + if (GVAR(drawProjectiles) && {!isNull _projectile}) then { + if (count GVAR(projectilesToDraw) > MAX_PROJECTILES) then { GVAR(projectilesToDraw) deleteAt 0; }; + GVAR(projectilesToDraw) pushBack [_projectile, [[getPosVisual _projectile, [1,0,0,0]]]]; + }; + } + ] call CBA_fnc_addEventHandler; + + // register advanced throwing EH + GVAR(advancedThrowingEH) = [ + QEGVAR(advanced_throwing,throwFiredXEH), { + // Fire time used for unit icon highlighting + (_this select 0) setVariable [QGVAR(highlightTime), time + FIRE_HIGHLIGHT_TIME]; + + // add grenade to tracking + [QGVAR(addToGrenadeTracking), [_this select 6]] call CBA_fnc_localEvent; + } + ] call CBA_fnc_addEventHandler; +} else { + // Stop updating the list and focus widget + [GVAR(uiPFH)] call CBA_fnc_removePerFrameHandler; + GVAR(uiPFH) = nil; + + // Stop drawing icons and tracking cursor object + removeMissionEventHandler ["Draw3D", GVAR(uiDraw3D)]; + GVAR(uiDraw3D) = nil; + + // Stop updating things to draw + [GVAR(collectPFH)] call CBA_fnc_removePerFrameHandler; + GVAR(collectPFH) = nil; + + // remove advanced throwing EH + [QEGVAR(advanced_throwing,throwFiredXEH), GVAR(advancedThrowingEH)] call CBA_fnc_removeEventHandler; + GVAR(advancedThrowingEH) = nil; + + // remove projectile track EH + [QGVAR(addToProjectileTracking), GVAR(projectileTrackingEH)] call CBA_fnc_removeEventHandler; + GVAR(projectileTrackingEH) = nil; + + // remove grenade track EH + [QGVAR(addToGrenadeTracking), GVAR(grenadeTrackingEH)] call CBA_fnc_removeEventHandler; + GVAR(grenadeTrackingEH) = nil; + + // Destroy the display + SPEC_DISPLAY closeDisplay 1; + + // Stop tracking everything + GVAR(uiVisible) = nil; + GVAR(uiHelpVisible) = nil; + GVAR(uiMapVisible) = nil; + GVAR(uiWidgetVisible) = nil; + GVAR(holdingRMB) = nil; + GVAR(uiMapHighlighted) = nil; + GVAR(curList) = nil; + GVAR(uiHelpH) = nil; + + // Stop drawing + GVAR(drawProjectiles) = nil; + GVAR(drawUnits) = nil; + GVAR(entitiesToDraw) = nil; + GVAR(grenadesToDraw) = nil; + GVAR(iconsToDraw) = nil; + GVAR(projectilesToDraw) = nil; + + // Reset view distance + setViewDistance GVAR(oldViewDistance); + GVAR(oldViewDistance) = nil; + + // Ensure chat is shown again + showChat true; +}; diff --git a/addons/spectator/functions/fnc_ui_draw3D.sqf b/addons/spectator/functions/fnc_ui_draw3D.sqf new file mode 100644 index 0000000000..3a60c28d64 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_draw3D.sqf @@ -0,0 +1,140 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to draw the 3D icons and track the cursor object + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * addMissionEventHandler ["Draw3D", {call ace_spectator_fnc_ui_draw3D}] + * + * Public: No + */ + +#include "script_component.hpp" +#define HEIGHT_OFFSET 1.5 + +BEGIN_COUNTER(updateCursor); +private _camTarget = missionNamespace getVariable [QGVAR(camFocus), objNull]; +private _camTargetVeh = vehicle _camTarget; +private _cursorObject = objNull; + +// This doesn't work for units underwater due to use of screenToWorld +// Would be hard to work around due to parallax +private _start = AGLToASL positionCameraToWorld [0,0,0]; +private _end = AGLToASL screenToWorld getMousePosition; + +// Can only select units within name drawing distance +if ((_start distanceSqr _end) <= DISTANCE_NAMES_SQR) then { + private _intersections = lineIntersectsSurfaces [_start, _end, _camTarget, _camTargetVeh]; + + if !(_intersections isEqualTo []) then { + _cursorObject = effectiveCommander ((_intersections select 0) select 3); + }; +}; + +GVAR(cursorObject) = _cursorObject; +END_COUNTER(updateCursor); + +if !(GVAR(uiMapVisible)) then { + if (GVAR(drawUnits)) then { + BEGIN_COUNTER(drawTags); + // Groups and Units + { + _x params ["_unit", "_type", "_icon"]; + private _position = (_unit modelToWorldVisual (_unit selectionPosition "Head")) vectorAdd [0,0,HEIGHT_OFFSET]; + + // Cursor object is always effectiveCommander so no need to check `in` + if (_type == 2 && {_unit in _camTargetVeh || _unit == _cursorObject}) then { + drawIcon3D [ + ICON_BACKGROUND_UNIT, + [0, 0, 0, [0.4, 0.8] select (_unit in _camTargetVeh)], + _position, + 5, + 4, + 0, + "", + 0, + 0.035, + "PuristaMedium", + "center" + ]; + }; + + // Apply modifiers + if (_type == 1 && { time <= GETVAR(_unit,GVAR(highlightTime),0) }) then { + _icon set [1, [1,1,1, ((_icon select 1) select 3)]]; + }; + _icon set [2, _position]; + + // Draw icon + drawIcon3D _icon; + } forEach GVAR(iconsToDraw); + END_COUNTER(drawTags); + }; + + // Draw projectiles and grenades paths + if (GVAR(drawProjectiles)) then { + BEGIN_COUNTER(drawTracers); + private _projectilesNew = []; + private _grenadesNew = []; + + // Draw projectiles if there are any + { + _x params [ + ["_projectile", objNull, [objNull]], + ["_segments", [], [[]]] + ]; + + if !(isNull _projectile) then { + // Store new segment + private _newestIndex = _segments pushBack [ + getPosVisual _projectile, + (vectorMagnitude velocity _projectile) call { + if (_this < 250) exitWith { [0,0,1,1] }; + if (_this < 500) exitWith { [0,1,0,1] }; + [1,0,0,1] + } + ]; + + // Clamp number of segments to be drawn + if (_newestIndex > MAX_PROJECTILE_SEGMENTS) then { + _segments deleteAt 0; + DEC(_newestIndex); + }; + + // Store projectiles for next frame + _projectilesNew pushBack [_projectile, _segments]; + + // Draw all projectile segments + private _oldLoc = []; + { + _x params ["_locNew", "_colorNew"]; + if !(_oldLoc isEqualTo []) then { + drawLine3D [_oldLoc, _locNew, _colorNew]; + }; + _oldLoc = _locNew; + } forEach _segments; + }; + } forEach GVAR(projectilesToDraw); + GVAR(projectilesToDraw) = _projectilesNew; + + { + if !(isNull _x) then { + private _grenadeVelocityMagnitude = vectorMagnitude velocity _x; + + // Draw grenade (rotate icon to represent spinning) + drawIcon3D [ICON_GRENADE, [1,0,0,1], getPosVisual _x, 0.6, 0.6, if (_grenadeVelocityMagnitude > 0) then { time * 100 * _grenadeVelocityMagnitude } else { 0 }, "", 0, 0.05, "TahomaB"]; + + // Store grenade for next frame + _grenadesNew pushBack _x; + }; + } forEach GVAR(grenadesToDraw); + + GVAR(grenadesToDraw) = _grenadesNew; + END_COUNTER(drawTracers); + }; +}; diff --git a/addons/spectator/functions/fnc_ui_fadeList.sqf b/addons/spectator/functions/fnc_ui_fadeList.sqf new file mode 100644 index 0000000000..dbc5344228 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_fadeList.sqf @@ -0,0 +1,50 @@ +/* + * Author: Nelson Duarte, AACO + * Function used to fade/unfade the entitiy list + * + * Arguments: + * 0: Fade the list + * + * Return Value: + * None + * + * Example: + * [false] call ace_spectator_fnc_ui_fadeList + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_fadeList"]; + +if (GVAR(uiVisible)) then { + private _list = CTRL_LIST; + private _tabs = CTRL_TABS; + + if (_fadeList) then { + _list ctrlSetBackgroundColor [0,0,0,0]; + _list ctrlSetFade 0.8; + + _tabs ctrlSetBackgroundColor [0,0,0,0]; + _tabs ctrlSetFade 0.5; + + ctrlSetFocus CTRL_MOUSE; + + showChat true; + } else { + _list ctrlSetBackgroundColor [0,0,0,0.75]; + _list ctrlSetFade 0; + + _tabs ctrlSetBackgroundColor [0,0,0,0.25]; + _tabs ctrlSetFade 0; + + ctrlSetFocus _list; + + // List overlaps with chat + showChat false; + }; + + _list ctrlCommit 0.2; + _tabs ctrlCommit 0.2; +}; diff --git a/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf b/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf new file mode 100644 index 0000000000..529751a09f --- /dev/null +++ b/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf @@ -0,0 +1,44 @@ +/* + * Author: Nelson Duarte, AACO + * Function used to find the tree path of an entity + * + * Arguments: + * 0: Data to search tree for + * + * Return Value: + * Tree path to data + * + * Example: + * [groupID _group] call ace_spectator_fnc_ui_getTreeDataIndex + * + * Public: No + */ + +#include "script_component.hpp" + +params [["_data", "", [""]]]; + +scopeName QGVAR(getTreeDataIndex); + +// Make sure data is not empty +if (_data != "") then { + private _ctrl = CTRL_LIST; + + for "_sideIndex" from 0 to ((_ctrl tvCount []) - 1) do { + if (_ctrl tvData [_sideIndex] == _data) then { + [_sideIndex] breakOut QGVAR(getTreeDataIndex); + }; + for "_groupIndex" from 0 to ((_ctrl tvCount [_sideIndex]) - 1) do { + if (_ctrl tvData [_sideIndex, _groupIndex] == _data) then { + [_sideIndex, _groupIndex] breakOut QGVAR(getTreeDataIndex); + }; + for "_unitIndex" from 0 to ((_ctrl tvCount [_sideIndex, _groupIndex]) - 1) do { + if (_ctrl tvData [_sideIndex, _groupIndex, _unitIndex] == _data) then { + [_sideIndex, _groupIndex, _unitIndex] breakOut QGVAR(getTreeDataIndex); + }; + }; + }; + }; +}; + +[-1] // return empty path if not found (worst case) diff --git a/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf b/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf new file mode 100644 index 0000000000..f2dcab47ef --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf @@ -0,0 +1,28 @@ +/* + * Author: Nelson Duarte + * Function used to handle child destroyed event + * This only matters when abort button is pressed in child escape menu + * Will close main display to exit client from mission + * + * Arguments: + * 0: Spectator display + * 1: Child display + * 2: Exit code of child + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleChildDestroyed + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_display","_child","_exitCode"]; + +if (_exitCode == 104) then { + _display closeDisplay 2; + MAIN_DISPLAY closeDisplay 2; +}; diff --git a/addons/spectator/functions/fnc_ui_handleKeyDown.sqf b/addons/spectator/functions/fnc_ui_handleKeyDown.sqf new file mode 100644 index 0000000000..2ac7a049b7 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleKeyDown.sqf @@ -0,0 +1,200 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to handle key down event + * + * Arguments: + * 0: Spectator display + * 1: Key DIK code + * 2: State of shift + * 3: State of ctrl + * 4: State of alt + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleKeyDown + * + * Public: No + */ + +#include "script_component.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" + +params ["","_key","_shift","_ctrl","_alt"]; + +// Handle map toggle +if (_key == DIK_M) exitWith { + [] call FUNC(ui_toggleMap); + true +}; + +// Handle very fast speed +if (_key == DIK_LALT) exitWith { + [true] call FUNC(cam_toggleSlow); + true +}; + +// Handle escape menu +if (_key == DIK_ESCAPE) exitWith { + if (GVAR(uiMapVisible)) then { + [] call FUNC(ui_toggleMap); + } else { + if (GVAR(uiForced)) then { + private _displayType = ["RscDisplayInterrupt","RscDisplayMPInterrupt"] select isMultiplayer; + SPEC_DISPLAY createDisplay _displayType; + } else { + [false] call FUNC(setSpectator); + }; + }; + true +}; + +// Handle perspective cycling +if (_key in [DIK_SPACE, DIK_NUMPADENTER]) exitWith { + private _oldMode = GVAR(camMode); + private _modes = GVAR(availableModes); + + // Get current index and index count + private _iMode = (_modes find _oldMode) max 0; + private _countModes = count _modes; + + if (_countModes != 0) then { + _iMode = (_iMode + 1) % _countModes; + if (_iMode < 0) then { _iMode = _countModes + _iMode; }; + }; + + private _newMode = _modes select _iMode; + + [_newMode] call FUNC(cam_setCameraMode); + + true +}; + +// Handle vision mode cycling +if (_key == DIK_N) exitWith { + private _oldVision = GVAR(camVision); + private _visions = GVAR(availableVisions); + + // Get current index and index count + private _iVision = (_visions find _oldVision) max 0; + private _countVisions = count _visions; + + if (_countVisions != 0) then { + _iVision = (_iVision + 1) % _countVisions; + if (_iVision < 0) then { _iVision = _countVisions + _iVision; }; + }; + + private _newVision = _visions select _iVision; + + [_newVision] call FUNC(cam_setVisionMode); + true +}; + +// Handle postive change in draw +if (_key == DIK_PGUP) exitWith { + setViewDistance ((viewDistance + 250) min MAX_VIEW_DISTANCE); + true +}; + +// Handle negative change in draw +if (_key == DIK_PGDN) exitWith { + setViewDistance ((viewDistance - 250) max MIN_VIEW_DISTANCE); + true +}; + +// Handle spectate lights +if (_key == DIK_L) exitWith { + if (GVAR(camLight)) then { + { deleteVehicle _x; } forEach GVAR(camLights); + GVAR(camLights) = []; + } else { + private _cameraLight = "#lightpoint" createvehicleLocal getPosASL GVAR(camera); + _cameraLight setLightBrightness 2; + _cameraLight setLightAmbient [1,1,1]; + _cameraLight setLightColor [0,0,0]; + _cameraLight lightAttachObject [GVAR(camera), [0,0,0]]; + + private _pointerLight = "#lightpoint" createvehicleLocal getPosASL GVAR(camera); + _pointerLight setLightBrightness 1; + _pointerLight setLightAmbient [1,1,1]; + _pointerLight setLightColor [0,0,0]; + + GVAR(camLights) = [_cameraLight, _pointerLight]; + }; + + GVAR(camLight) = !GVAR(camLight); + + true +}; + +// Handle toggling the UI +if (_key == DIK_BACKSPACE) exitWith { + [] call FUNC(ui_toggleUI); + true +}; + +// Handle toggling help +if (_key == DIK_F1) exitWith { + GVAR(uiHelpVisible) = !GVAR(uiHelpVisible); + + [] call FUNC(ui_updateHelp); + + CTRL_HELP ctrlShow GVAR(uiHelpVisible); + CTRL_HELP_BACK ctrlShow GVAR(uiHelpVisible); + + true +}; + +// Handle toggle focus info widget +if (_key == DIK_I) exitWith { + GVAR(uiWidgetVisible) = !GVAR(uiWidgetVisible); + [] call FUNC(ui_updateWidget); + true +}; + +// Handle toggling projectile drawing +if (_key == DIK_P) exitWith { + GVAR(drawProjectiles) = !GVAR(drawProjectiles); + true +}; + +// Handle toggling unit drawing +if (_key == DIK_O) exitWith { + GVAR(drawUnits) = !GVAR(drawUnits); + true +}; + +// Handle getting next focus target +if (_key == DIK_RIGHT) exitWith { + [true] call FUNC(switchFocus); + true +}; + +// Handle getting previous focus target +if (_key == DIK_LEFT) exitWith { + [false] call FUNC(switchFocus); + true +}; + +// If the zeus key is pressed and unit is curator, open zeus interface +if ((_key in (actionKeys "CuratorInterface")) && {!isNull (getAssignedCuratorLogic player)}) exitWith { + // Close the UI and disable camera input + [false] call FUNC(ui); + GVAR(camera) camCommand "manual off"; + + // Display XEH handles re-opening + openCuratorInterface; + + // Set the curator camera to the spectator camera location + [{!isNull curatorCamera},{ + curatorCamera setPosASL (getPosASL GVAR(camera)); + curatorCamera setDir (getDirVisual GVAR(camera)); + + // Curator tracks its own vision mode + [getAssignedCuratorLogic player, 0] call bis_fnc_toggleCuratorVisionMode; + }] call CBA_fnc_waitUntilAndExecute; + true +}; + +false // default to unhandled diff --git a/addons/spectator/functions/fnc_ui_handleKeyUp.sqf b/addons/spectator/functions/fnc_ui_handleKeyUp.sqf new file mode 100644 index 0000000000..672f2f7bb8 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleKeyUp.sqf @@ -0,0 +1,31 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Function used to handle key up event + * + * Arguments: + * 0: Spectator display + * 1: Key DIK code + * 2: State of shift + * 3: State of ctrl + * 4: State of alt + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleKeyUp + * + * Public: No + */ + +#include "script_component.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" + +params ["","_key","_shift","_ctrl","_alt"]; + +if (_key == DIK_LALT) exitWith { + [false] call FUNC(cam_toggleSlow); + true +}; + +false diff --git a/addons/spectator/functions/fnc_ui_handleListClick.sqf b/addons/spectator/functions/fnc_ui_handleListClick.sqf new file mode 100644 index 0000000000..9616e77cac --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleListClick.sqf @@ -0,0 +1,56 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to handle list single/double clicks + * + * Expected behaviour: + * Clicking an entry focuses the camera on it (any camera mode) + * Double clicking an entry teleports the free camera nearby and focuses on it + * + * Arguments: + * 0: Double clicked + * 1: List Click EH's _this + * + * Return Value: + * None + * + * Example: + * [false, _this] call ace_spectator_fnc_ui_handleListClick + * + * Public: No + */ +#include "script_component.hpp" + +params ["_dblClick","_params"]; +_params params ["_list","_index"]; + +private _handled = false; +private _data = _list tvData _index; + +// List contains unique object variables +private _object = missionNamespace getVariable [_data, objNull]; + +if !(isNull _object) then { + if (_dblClick) then { + // Place camera within ~10m of the object and above ground level + private _pos = getPosASLVisual _object; + GVAR(camera) setPosASL (AGLtoASL (_pos getPos [1 + random 10, random 360]) vectorAdd [0,0,2 + random 10]); + + // Reset the focus + [objNull] call FUNC(setFocus); + [_object] call FUNC(setFocus); + + _handled = true; + } else { + if (_object != GVAR(camFocus)) then { + [_object] call FUNC(setFocus); + + _handled = true; + }; + }; +}; + +if (_handled) then { + playSound "ReadoutClick"; +}; + +_handled diff --git a/addons/spectator/functions/fnc_ui_handleLoad.sqf b/addons/spectator/functions/fnc_ui_handleLoad.sqf new file mode 100644 index 0000000000..1afa5ce123 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleLoad.sqf @@ -0,0 +1,25 @@ +/* + * Author: SilentSpike, Jonpas + * Function used to handle load event. + * + * Arguments: + * 0: Spectator display + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleLoad + * + * Public: No + */ +#include "script_component.hpp" + +params ["_display"]; + +uiNamespace setVariable [QGVAR(display), _display]; + +// Handle ACRE2 Toggle Spectator (if present) +if (!isNil "acre_api_fnc_addDisplayPassthroughKeys") then { + [_display] call acre_api_fnc_addDisplayPassthroughKeys; +}; diff --git a/addons/spectator/functions/fnc_ui_handleMapClick.sqf b/addons/spectator/functions/fnc_ui_handleMapClick.sqf new file mode 100644 index 0000000000..6e74ed0e97 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMapClick.sqf @@ -0,0 +1,40 @@ +/* + * Author: Nelson Duarte, AACO + * Function used to handle map mouse click events + * + * Arguments: + * 0: Map control + * 1: Mouse button pressed + * 2: x screen coordinate clicked + * 3: y screen coordinate clicked + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleMapClick + * + * Public: No + */ + +#include "script_component.hpp" + +params ["", "", "_x", "_y"]; + +if (isNull GVAR(uiMapHighlighted)) then { + // Give user feedback that camera is no longer focused + if !(isNull GVAR(camFocus)) then { + playSound "ReadoutHideClick1"; + }; + + // Preserve camera height on teleport + private _pos = CTRL_MAP ctrlMapScreenToWorld [_x, _y]; + _pos set [2, (getPosASLVisual GVAR(camera)) select 2]; + + GVAR(camera) setPosASL _pos; +} else { + // Give user feedback that camera is focused on highlighted unit + playSound "ReadoutClick"; +}; + +[GVAR(uiMapHighlighted)] call FUNC(setFocus); diff --git a/addons/spectator/functions/fnc_ui_handleMapDraw.sqf b/addons/spectator/functions/fnc_ui_handleMapDraw.sqf new file mode 100644 index 0000000000..40ad5c3f9a --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMapDraw.sqf @@ -0,0 +1,87 @@ +/* + * Author: Nelson Duarte, AACO + * Function used to handle map draw + * + * Arguments: + * 0: Map control + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleMapDraw + * + * Public: No + */ + +#include "script_component.hpp" +#define MAP_MIN_ENTITY_DISTANCE 30 + +// Moved timer into map controls group, update here +CTRL_TIME ctrlSetText (["+", [time / 3600] call BIS_fnc_timeToString] joinString ""); + +BEGIN_COUNTER(drawMap); + +params ["_map"]; + +// Track nearest unit +private _loc = _map ctrlMapScreenToWorld getMousePosition; +private _nearestEntity = objNull; +private _minDist = 999999; + +// Draw unit icons +private _handledVehicles = []; +{ + private _dist = _x distance2D _loc; + + if (_dist < _minDist && { _dist < MAP_MIN_ENTITY_DISTANCE }) then { + _minDist = _dist; + _nearestEntity = _x; + }; + + private _vehicle = vehicle _x; + if !(_vehicle in _handledVehicles) then { + _handledVehicles pushBack _vehicle; + + private _vehicleTexture = [_vehicle] call EFUNC(common,getVehicleIcon); + private _sideColor = [side group _vehicle] call BIS_fnc_sideColor; + private _text = ""; + + if (GVAR(uiMapHighlighted) == _vehicle || {GVAR(uiMapHighlighted) in _vehicle}) then { + _text = ([GVAR(uiMapHighlighted)] call EFUNC(common,getName)) select [0, NAME_MAX_CHARACTERS]; + if !(isPlayer GVAR(uiMapHighlighted)) then { _text = format ["%1: %2", localize "str_player_ai", _text]; }; + _sideColor = [0.8, 0.8, 0.5, 1]; + }; + + if (NEEDS_REVIVE(_vehicle)) then { + _vehicleTexture = ICON_REVIVE; + _sideColor = [0.5, 0, 0, 1]; + }; + + if (time <= _vehicle getVariable [QGVAR(highlightTime), 0]) then { + _sideColor = [1, 1, 1, 1]; + }; + + _map drawIcon [_vehicleTexture, _sideColor, getPosASLVisual _vehicle, 24, 24, getDirVisual _vehicle, _text, 1, 0.04, "TahomaB", "right"]; + }; +} forEach ([] call FUNC(getTargetEntities)); + +// Set highlighted unit +private _text = if (isNull _nearestEntity) then { + "" +} else { + format ["%1 [%2 m]", [_nearestEntity] call EFUNC(common,getName), round (_nearestEntity distance2D GVAR(camera))] +}; + +GVAR(uiMapHighlighted) = _nearestEntity; +CTRL_MAP_FOOTER ctrlSetText _text; + +// Draw camera icon +if !(isNil QGVAR(camera)) then { + private _cameraPos = getPosASLVisual GVAR(camera); + private _cameraDir = getDirVisual GVAR(camera); + _map drawIcon [ICON_CAMERA, [0.5, 1, 0.5, 1], _cameraPos, 32, 48, _cameraDir, "", 1, 0.05, "TahomaB", "right"]; + _map drawArrow [_cameraPos, (_cameraPos getPos [300, _cameraDir]), [0.5, 1, 0.5, 1]]; +}; + +END_COUNTER(drawMap); diff --git a/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf b/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf new file mode 100644 index 0000000000..f880daf81b --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf @@ -0,0 +1,27 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to handle mouse button double clicks + * + * Expected behaviour: + * Double left click teleports free camera toward the unit, but does not focus + * + * Arguments: + * 0: Control + * 1: Mouse button pressed + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleMouseButtonDblClick + * + * Public: No + */ + +#include "script_component.hpp" + +params ["", "_button"]; + +if (_button == 0 && {!isNull GVAR(cursorObject)}) then { + [GVAR(cursorObject)] call FUNC(cam_prepareTarget); +}; diff --git a/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf b/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf new file mode 100644 index 0000000000..a6bb64d744 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf @@ -0,0 +1,52 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to handle mouse down event + * + * Expected behaviour: + * Left clicking a unit focuses the camera on that unit (in any camera mode) + * Left clicking empty space removes the current camera focus in free camera + * Right clicking removes the camera lock, but retains the focus in free camera + * Right clicking and dragging orbits around the unit in follow camera + * + * Arguments: + * 0: Control + * 1: Mouse button pressed + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleMouseButtonDown + * + * Public: No + */ + +#include "script_component.hpp" + +params ["", "_button"]; + +// Left click +if (_button == 0) exitWith { + if (isNull GVAR(cursorObject)) then { + if (GVAR(camMode) == MODE_FREE && { !isNull GVAR(camFocus) }) then { + playSound "ReadoutHideClick1"; + [objNull] call FUNC(setFocus); + }; + } else { + if (GVAR(cursorObject) in ([] call FUNC(getTargetEntities))) then { + playSound "ReadoutClick"; + + // Focus will be at screen center + [GVAR(cursorObject)] call FUNC(setFocus); + setMousePosition [0.5, 0.5]; + }; + }; +}; + +// Right click +if (_button == 1) then { + if (GVAR(camMode) == MODE_FREE && { !isNull GVAR(camFocus) } && { !isNull (attachedTo GVAR(camDummy)) }) then { + [] call FUNC(cam_resetTarget); + }; + GVAR(holdingRMB) = true; +}; diff --git a/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf b/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf new file mode 100644 index 0000000000..af3f1ede62 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf @@ -0,0 +1,31 @@ +/* + * Author: Nelson Duarte, AACO + * Function used to handle mouse moving event + * + * Arguments: + * 0: Control + * 1: Change in x + * 2: Change in y + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleMouseMoving + * + * Public: No + */ + +#include "script_component.hpp" + +if (GVAR(holdingRMB) && { GVAR(camMode) == MODE_FOLLOW }) then { + params ["", "_deltaX", "_deltaY"]; + + if (_deltaX != 0) then { + GVAR(camYaw) = ((GVAR(camYaw) + (_deltaX * 100 * GVAR(camDeltaTime)) + 180) % 360) - 180; + }; + + if (_deltaY != 0) then { + GVAR(camPitch) = (((GVAR(camPitch) - (_deltaY * 100 * GVAR(camDeltaTime))) max -90) min 90); + }; +}; diff --git a/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf b/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf new file mode 100644 index 0000000000..5e54cb8b72 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf @@ -0,0 +1,27 @@ +/* + * Author: Nelson Duarte, AACO + * Function used to handle mouse scroll event + * + * Arguments: + * 0: Control + * 1: Change in Z + * + * Return Value: + * None + * + * Example: + * _this call ace_spectator_fnc_ui_handleMouseZChanged + * + * Public: No + */ + +#include "script_component.hpp" +#define FOLLOW_CAMERA_MAX_DISTANCE 5 + +if (GVAR(camMode) == MODE_FOLLOW) then { + if ((_this select 1) > 0) then { + GVAR(camDistance) = (GVAR(camDistance) - 1) max 0; + } else { + GVAR(camDistance) = (GVAR(camDistance) + 1) min FOLLOW_CAMERA_MAX_DISTANCE; + }; +}; diff --git a/addons/spectator/functions/fnc_ui_toggleMap.sqf b/addons/spectator/functions/fnc_ui_toggleMap.sqf new file mode 100644 index 0000000000..23114fe4cb --- /dev/null +++ b/addons/spectator/functions/fnc_ui_toggleMap.sqf @@ -0,0 +1,47 @@ +/* + * Author: Nelson Duarte, AACO + * Function used to toggle the map + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_toggleMap + * + * Public: No + */ + +#include "script_component.hpp" + +if (GVAR(uiMapVisible)) then { + CTRL_MAP ctrlShow false; + CTRL_MAP_GROUP ctrlShow false; + + ctrlSetFocus CTRL_MOUSE; + + if (GVAR(camMode) == MODE_FREE) then { + GVAR(camera) camCommand "manual on"; + }; +} else { + CTRL_MAP ctrlShow true; + CTRL_MAP_GROUP ctrlShow true; + + CTRL_MAP_TITLE ctrlSetText (getMissionConfigValue ["onLoadName", getMissionConfigValue ["briefingName", localize ELSTRING(common,unknown)]]); + CTRL_MAP_SPEC_NUM ctrlSetText str ({GETVAR(_x,GVAR(isSet),false)} count allPlayers); + + // Center on camera position (accounts for first person) + CTRL_MAP ctrlMapAnimAdd [0, 0.05, positionCameraToWorld [0,0,0]]; + ctrlMapAnimCommit CTRL_MAP; + + // Disable camera input while map is open + GVAR(camera) camCommand "manual off"; +}; + +// Toggle the tracking variable +GVAR(uiMapVisible) = !GVAR(uiMapVisible); + +// Reset highlighted object +GVAR(uiMapHighlighted) = objNull; diff --git a/addons/spectator/functions/fnc_ui_toggleUI.sqf b/addons/spectator/functions/fnc_ui_toggleUI.sqf new file mode 100644 index 0000000000..b15e8b1962 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_toggleUI.sqf @@ -0,0 +1,34 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to toggle the whole user interface + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_toggleUI + * + * Public: No + */ + +#include "script_component.hpp" + +private _visible = !GVAR(uiVisible); + +{ + private _fade = 1; + if (_visible) then { + _fade = getNumber (configFile >> QGVAR(display) >> "Controls" >> ctrlClassName _x >> "fade"); + }; + + _x ctrlSetFade _fade; + _x ctrlCommit 0.25; +} forEach [CTRL_LIST, CTRL_TABS, CTRL_CAM_TYPES, CTRL_WIDGET]; + +showChat !_visible; +playSound (["HintExpand","HintCollapse"] select _visible); + +GVAR(uiVisible) = _visible; diff --git a/addons/spectator/functions/fnc_ui_updateCamButtons.sqf b/addons/spectator/functions/fnc_ui_updateCamButtons.sqf new file mode 100644 index 0000000000..d110aac4ea --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateCamButtons.sqf @@ -0,0 +1,38 @@ +/* + * Author: SilentSpike + * Used to update the docked camera buttons + * Disables unavailable, highlights current + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_updateCamButtons + * + * Public: No + */ + +#include "script_component.hpp" + +// These correspond to the camera mode indices +#define ENUM_IDCs [IDC_FREE, IDC_FPS, IDC_FOLLOW] +#define ENUM_ACTIVE [CAM_ICON_FREE_SELECTED, CAM_ICON_FPS_SELECTED, CAM_ICON_FOLLOW_SELECTED] +#define ENUM_INACTIVE [CAM_ICON_FREE, CAM_ICON_FPS, CAM_ICON_FOLLOW] + +private _current = ENUM_IDCs select GVAR(camMode); + +{ + if (_forEachIndex in GVAR(availableModes)) then { + // Highlight the current camera mode button + private _icon = ([ENUM_INACTIVE, ENUM_ACTIVE] select (_x == _current)) select _forEachIndex; + + (CTRL_CAM_TYPES controlsGroupCtrl _x) ctrlSetText _icon; + (CTRL_CAM_TYPES controlsGroupCtrl _x) ctrlShow true; + } else { + // Disable any inactive camera modes + (CTRL_CAM_TYPES controlsGroupCtrl _x) ctrlShow false; + }; +} forEach ENUM_IDCs; diff --git a/addons/spectator/functions/fnc_ui_updateHelp.sqf b/addons/spectator/functions/fnc_ui_updateHelp.sqf new file mode 100644 index 0000000000..65c9408ace --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateHelp.sqf @@ -0,0 +1,139 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Updates spectator UI help element + * + * Note that there are some redundant conditions in this file + * This is intentional, since controls appear via priority que + * The overhead is minimal + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_updateHelp + * + * Public: No + */ + +#include "script_component.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" +#define MAX_CONTROLS_HELP_ENTRIES 12 + +if !(GVAR(uiHelpVisible)) exitWith {}; + +private _cameraMode = GVAR(camMode); +private _availableModes = GVAR(availableModes); +private _hasTarget = !isNull GVAR(camFocus); + +private _controls = []; + +// When not in first person, camera rotation applies +if (_cameraMode != MODE_FPS) then { + _controls pushback ["[RMB]", localize "STR_A3_Spectator_Helper_CameraRotation"]; +}; + +// When in free camera, focus/un-focus with LMB +if (_cameraMode == MODE_FREE) then { + if (_hasTarget) then { + _controls pushBack ["[LMB]", localize "STR_A3_Spectator_Helper_Unfocus"]; + } else { + _controls pushBack ["[LMB]", localize "STR_A3_Spectator_Helper_Focus"]; + }; +}; + +// When the camera has a focus, switch mode applies (if other modes are available) +if (_hasTarget && {count _availableModes > 1}) then { + _controls pushBack [ + format ["[%1]", toUpper ([DIK_SPACE] call CBA_fnc_localizeKey)], + localize "STR_A3_Spectator_Helper_CameraMode" + ]; +}; + +if (_cameraMode == MODE_FREE) then { + _controls pushback [ + format ["[%1/%2]", [DIK_W] call CBA_fnc_localizeKey, [DIK_S] call CBA_fnc_localizeKey], + localize "STR_A3_Spectator_Helper_Movement" + ]; + _controls pushback [ + format ["[%1/%2]", [DIK_A] call CBA_fnc_localizeKey, [DIK_D] call CBA_fnc_localizeKey], + localize "STR_A3_Spectator_Helper_Strafing" + ]; + _controls pushback [ + format ["[%1/%2]", [DIK_Q] call CBA_fnc_localizeKey, [DIK_Z] call CBA_fnc_localizeKey], + localize "STR_A3_Spectator_Helper_Height" + ]; +} else { + _controls pushback [ + format ["[%1]", toUpper ([DIK_RIGHT] call CBA_fnc_localizeKey)], + localize LSTRING(nextUnit) + ]; + _controls pushback [ + format ["[%1]", toUpper ([DIK_LEFT] call CBA_fnc_localizeKey)], + localize LSTRING(prevUnit) + ]; +}; + +if (_cameraMode != MODE_FPS) then { + _controls pushback [ + format ["[%1]", ([DIK_N] call CBA_fnc_localizeKey)], + localize LSTRING(nextVis) + ]; +}; + +_controls pushBack [ + format ["[%1]", toUpper ([DIK_BACK] call CBA_fnc_localizeKey)], + localize "STR_A3_Spectator_Helper_Interface" +]; +_controls pushBack [ + format ["[%1]", [DIK_F1] call CBA_fnc_localizeKey], + localize "STR_A3_Spectator_Helper_Controls" +]; + +// Too many controls in the UI, leave these out? +// _controls pushBack [ +// format ["[%1]", [DIK_M] call CBA_fnc_localizeKey], +// localize "str_usract_map" +// ]; +// _controls pushBack [ +// format ["[%1]", [DIK_I] call CBA_fnc_localizeKey], +// localize LSTRING(uiIcons) +// ]; +// _controls pushBack [ +// format ["[%1]", [DIK_O] call CBA_fnc_localizeKey], +// localize LSTRING(uiProjectiles) +// ]; + +if (_cameraMode == MODE_FREE) then { + _controls pushBack ["[LSHIFT]", localize "STR_A3_Spectator_Helper_Shift"]; + _controls pushBack ["[LALT]", localize LSTRING(camSlow)]; +}; + +if (count _controls > MAX_CONTROLS_HELP_ENTRIES) then { + _controls resize MAX_CONTROLS_HELP_ENTRIES; +}; + +disableSerialization; // This function could run scheduled as a result of public API +private _help = CTRL_HELP; + +_help ctrlEnable false; +_help lnbSetColumnsPos [0, 0.45]; +lnbClear _help; + +{ + _help lnbAddRow _x; + _help lnbSetColor [[_forEachIndex, 0], [0.75,0.6,0,1]]; +} forEach _controls; + +// Set height based on number of rows +private _newH = (GVAR(uiHelpH) / MAX_CONTROLS_HELP_ENTRIES) * count _controls; +private _newY = safezoneY + safezoneH - _newH; + +(ctrlPosition _help) params ["_newX","","_newW"]; + +{ + _x ctrlSetPosition [_newX, _newY, _newW, _newH]; + _x ctrlCommit 0.15; +} forEach [CTRL_HELP_BACK, _help]; diff --git a/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf b/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf new file mode 100644 index 0000000000..4c79d5ecf4 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf @@ -0,0 +1,145 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used update the things to 3D draw + * + * Arguments: + * None + * + * Return Value: + * None + * + * Examples: + * [] call ace_spectator_fnc_ui_updateIconsToDraw + * + * Public: No + */ + +#include "script_component.hpp" + +private _iconsToDraw = []; +private _entitiesToDraw = []; + +// camToWorld is used instead of camera object to account for FPP +private _camPos = AGLToASL positionCameraToWorld [0,0,0]; +{ + private _vehicle = vehicle _x; + private _inVehicle = (_vehicle != _x); + private _distanceToCameraSqr = _camPos distanceSqr _x; + + if (_distanceToCameraSqr <= DISTANCE_ICONS_SQR && { !_inVehicle || { _x == effectiveCommander _vehicle } }) then { + private _group = group _x; + private _isLeader = _x == leader _group; + private _groupColor = [side _group] call BIS_fnc_sideColor; + + // Calculate distance fade + (_distanceToCameraSqr call { + if (_this <= 250000) exitWith { // 500^2 + [1, 4, -2.5, 0.04] + }; + if (_this <= 1000000) exitWith { // 1000^2 + [0.75, 3.5, -2.2, 0.035] + }; + if (_this <= 2250000) exitWith { // 1500^2 + [0.5, 3, -1.9, 0.03] + }; + if (_this <= 4000000) exitWith { // 2000^2 + [0.3, 2.5, -1.6, 0.025] + }; + if (_this <= 6250000) exitWith { // 2500^2 + [0.2, 2, -1.3, 0.02] + }; + [0.15, 1.5, -1, 0.015] + }) params ["_fadeByDistance", "_sizeByDistance", "_heightByDistance", "_fontSizeByDistance"]; + + // Apply color fade + _groupColor set [3, _fadeByDistance]; + + // Show unit name only if camera is near enough + if (_distanceToCameraSqr < DISTANCE_NAMES_SQR) then { + private _name = ([_x] call EFUNC(common,getName)) select [0, NAME_MAX_CHARACTERS]; + if !(isPlayer _x) then { _name = format ["%1: %2", localize "str_player_ai", _name]; }; + + if (_inVehicle) then { + private _crewCount = (({alive _x} count (crew _vehicle)) - 1); + if (_crewCount > 0) then { + _name = format ["%1 (+%2)", _name, _crewCount]; + }; + }; + + // Draw unit name for effective commander or all units on foot + _iconsToDraw pushBack [_x, 2, [ + "", + [1,1,1,1], + [0,0,0], + 0, + _heightByDistance, + 0, + _name, + 2, + _fontSizeByDistance, + "PuristaMedium", + "center" + ]]; + } else { + // Draw group name for effective commander or leader on foot + if (_inVehicle || _isLeader) then { + _iconsToDraw pushBack [_x, 0, [ + "", + [1,1,1,_fadeByDistance], + [0,0,0], + 0, + _heightByDistance, + 0, + groupID _group, + 2, + _fontSizeByDistance, + "PuristaMedium", + "center" + ]]; + }; + }; + + // Draw group icon for effective commander or leader on foot + if (_inVehicle || _isLeader) then { + _iconsToDraw pushBack [_x, 0, [ + [_group, true] call FUNC(getGroupIcon), + _groupColor, + [0,0,0], + _sizeByDistance, + _sizeByDistance, + 0, + "", + 0, + 0.035, + "PuristaMedium", + "center" + ]]; + }; + + // Draw unit icon for effective commander or all units on foot + _iconsToDraw pushBack [_x, 1, [ + [ICON_UNIT, ICON_REVIVE] select (NEEDS_REVIVE(_x)), + _groupColor, + [0,0,0], + _sizeByDistance, + _sizeByDistance, + 0, + "", + 0, + 0.035, + "PuristaMedium", + "center" + ]]; + + // Track entities themselves for use with fired EH + _entitiesToDraw pushBack _vehicle; + + // Add fired EH for drawing and icon highlighting + if (GETVAR(_vehicle,GVAR(firedEH),-1) == -1) then { + SETVAR(_vehicle,GVAR(firedEH),_vehicle addEventHandler [ARR_2("Fired",{_this call FUNC(handleFired)})]); + }; + }; +} forEach ([] call FUNC(getTargetEntities)); + +GVAR(iconsToDraw) = _iconsToDraw; +GVAR(entitiesToDraw) = _entitiesToDraw; diff --git a/addons/spectator/functions/fnc_ui_updateListEntities.sqf b/addons/spectator/functions/fnc_ui_updateListEntities.sqf new file mode 100644 index 0000000000..e5ee48005a --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateListEntities.sqf @@ -0,0 +1,217 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Updates spectator UI list of units/groups + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_updateListEntities + * + * Public: No + */ + +#include "script_component.hpp" + +private _newUnits = []; +private _newGroups = []; +// Always show the 4 main sides in this intuative order +private _newSides = [str west, str east, str resistance, str civilian]; +private _newList = [ + [west, str west, [west] call BIS_fnc_sideName, [west] call BIS_fnc_sideColor, []], + [east, str east, [east] call BIS_fnc_sideName, [east] call BIS_fnc_sideColor, []], + [resistance, str resistance, [resistance] call BIS_fnc_sideName, [resistance] call BIS_fnc_sideColor, []], + [civilian, str civilian, [civilian] call BIS_fnc_sideName, [civilian] call BIS_fnc_sideColor, []] +]; + +// Go through entity groups and cache information (include dead entities) +private _entities = [true] call FUNC(getTargetEntities); +{ + // Add the group if new + private _group = _x; + if !(str _group in _newGroups) then { + // Include the group if it contains valid entities + private _entitiesGroup = units _group arrayIntersect _entities; + + if !(_entitiesGroup isEqualTo []) then { + // Cache the info of valid units in the group + private _unitsInfo = []; + { + _newUnits pushBack ([_x] call BIS_fnc_objectVar); + + private _name = ([_x] call EFUNC(common,getName)) select [0, NAME_MAX_CHARACTERS]; + if !(isPlayer _x) then { _name = format ["%1: %2", localize "str_player_ai", _name]; }; + + _unitsInfo pushBack [ + _x, + alive _x, + alive _x && { NEEDS_REVIVE(_x) }, + _name + ]; + } forEach _entitiesGroup; + + // Cache the info of the group itself + private _groupTexture = [_group] call FUNC(getGroupIcon); + private _groupInfo = [_group, str _group, _groupTexture, groupID _group]; + + // Add the group to the correct side + private _side = side _group; + private _sideIndex = _newSides find (str _side); + + // Add the side if new + if (_sideIndex < 0) then { + _newList pushBack [ + _side, + str _side, + [_side] call BIS_fnc_sideName, + [_side] call BIS_fnc_sideColor, + [] + ]; + + _sideIndex = _newSides pushBack (str _side); + }; + + // Add it to the right index + _newGroups pushBack (str _group); + ((_newList select _sideIndex) select 4) pushBack [_groupInfo, _unitsInfo]; + }; + }; +} forEach allGroups; + +// Whether an update to the list is required (really only if something changed) +if !(GVAR(curList) isEqualTo _newList) then { + private _ctrl = CTRL_LIST; + + // Remove groups/units that are no longer there + for "_sideIndex" from ((_ctrl tvCount []) - 1) to 0 step -1 do { + for "_groupIndex" from ((_ctrl tvCount [_sideIndex]) - 1) to 0 step -1 do { + for "_unitIndex" from ((_ctrl tvCount [_sideIndex, _groupIndex]) - 1) to 0 step -1 do { + private _lookup = _newUnits find (_ctrl tvData [_sideIndex, _groupIndex, _unitIndex]); + if (_lookup < 0) then { + _ctrl tvDelete [_sideIndex, _groupIndex, _unitIndex]; + } else { + _newUnits deleteAt _lookup; + }; + }; + private _lookup = _newGroups find (_ctrl tvData [_sideIndex, _groupIndex]); + if (_lookup < 0) then { + _ctrl tvDelete [_sideIndex, _groupIndex]; + } else { + _newGroups deleteAt _lookup; + }; + }; + private _lookup = _newSides find (_ctrl tvData [_sideIndex]); + if (_lookup < 0) then { + _ctrl tvDelete [_sideIndex]; + } else { + _newSides deleteAt _lookup; + }; + }; + + // Hash location lookups, note hashing assumes unique side/group/unit data + private _sideDataToPathHash = [[], []]; + private _groupDataToPathHash = [[], []]; + private _unitDataToPathHash = [[], []]; + + for "_sideIndex" from 0 to ((_ctrl tvCount []) - 1) do { + (_sideDataToPathHash select 0) pushBack (_ctrl tvData [_sideIndex]); + (_sideDataToPathHash select 1) pushBack [_sideIndex]; + for "_groupIndex" from 0 to ((_ctrl tvCount [_sideIndex]) - 1) do { + (_groupDataToPathHash select 0) pushBack (_ctrl tvData [_sideIndex, _groupIndex]); + (_groupDataToPathHash select 1) pushBack [_sideIndex, _groupIndex]; + for "_unitIndex" from 0 to ((_ctrl tvCount [_sideIndex, _groupIndex]) - 1) do { + (_unitDataToPathHash select 0) pushBack (_ctrl tvData [_sideIndex, _groupIndex, _unitIndex]); + (_unitDataToPathHash select 1) pushBack [_sideIndex, _groupIndex, _unitIndex]; + }; + }; + }; + + // Update/add the values + { + _x params ["_side", "_sideStr", "_sideTitle", "_sideColor", "_nestedGroupData"]; + + private _sideIndex = -1; + private _lookup = (_sideDataToPathHash select 0) find _sideStr; + if (_lookup < 0) then { + _sideIndex = _ctrl tvAdd [[], _sideTitle]; + _ctrl tvSetData [[_sideIndex], _sideStr]; + _ctrl tvExpand [_sideIndex]; + } else { + // pop data out of hash to improve later lookups + (_sideDataToPathHash select 0) deleteAt _lookup; + private _path = (_sideDataToPathHash select 1) deleteAt _lookup; + _sideIndex = _path select 0; + + _ctrl tvSetText [_path, _sideTitle]; + }; + + { + _x params ["_groupInfo", "_nestedUnitData"]; + _groupInfo params ["_group", "_groupStr", "_groupTexture", "_groupId"]; + + private _groupIndex = -1; + private _lookup = (_groupDataToPathHash select 0) find _groupStr; + if (_lookup < 0) then { + _groupIndex = _ctrl tvAdd [[_sideIndex], _groupId]; + _ctrl tvSetData [[_sideIndex, _groupIndex], _groupStr]; + _ctrl tvSetPicture [[_sideIndex, _groupIndex], _groupTexture]; + _ctrl tvSetPictureColor [[_sideIndex, _groupIndex], _sideColor]; + _ctrl tvSetTooltip [[_sideIndex, _groupIndex], _groupId]; + _ctrl tvExpand [_sideIndex, _groupIndex]; + } else { + // pop data out of hash to improve later lookups + (_groupDataToPathHash select 0) deleteAt _lookup; + private _path = (_groupDataToPathHash select 1) deleteAt _lookup; + _groupIndex = _path select 1; + + _ctrl tvSetText [_path, _groupId]; + _ctrl tvSetPicture [_path, _groupTexture]; + _ctrl tvSetPictureColor [_path, _sideColor]; + _ctrl tvSetTooltip [_path, _groupId]; + }; + + { + _x params ["_unit", "_isAlive", "_isIncapacitated", "_name"]; + + // Show full name in tooltip + whether medic + whether engineer + private _tooltip = [[_unit] call EFUNC(common,getName)]; + if ([_unit] call EFUNC(common,isMedic)) then { _tooltip pushBack (localize "str_support_medic"); }; + if ([_unit] call EFUNC(common,isEngineer)) then { _tooltip pushBack (localize LSTRING(TooltipEngineer)); }; + _tooltip = _tooltip joinString " - "; + + private _texture = [_isAlive, _isIncapacitated, _unit] call { + params ["","","_unit"]; + if !(_this select 0) exitWith { ICON_DEAD }; + if (_this select 1) exitWith { ICON_REVIVE }; + [vehicle _unit] call EFUNC(common,getVehicleIcon) + }; + + private _lookup = (_unitDataToPathHash select 0) find ([_unit] call BIS_fnc_objectVar); + if (_lookup < 0) then { + private _unitIndex = _ctrl tvAdd [[_sideIndex, _groupIndex], _name]; + _ctrl tvSetData [[_sideIndex, _groupIndex, _unitIndex], [_unit] call BIS_fnc_objectVar]; + _ctrl tvSetPicture [[_sideIndex, _groupIndex, _unitIndex], _texture]; + _ctrl tvSetPictureColor [[_sideIndex, _groupIndex, _unitIndex], _sideColor]; + _ctrl tvSetTooltip [[_sideIndex, _groupIndex, _unitIndex], _tooltip]; + } else { + // pop data out of hash to improve later lookups + (_unitDataToPathHash select 0) deleteAt _lookup; + private _path = (_unitDataToPathHash select 1) deleteAt _lookup; + _ctrl tvSetText [_path, _name]; + _ctrl tvSetPicture [_path, _texture]; + _ctrl tvSetPictureColor [_path, _sideColor]; + _ctrl tvSetTooltip [_path, _tooltip]; + }; + } forEach _nestedUnitData; + } forEach _nestedGroupData; + } forEach _newList; + + // Store the new list as the current list + GVAR(curList) = _newList; +}; + +// Update focus if required +[] call FUNC(ui_updateListFocus); diff --git a/addons/spectator/functions/fnc_ui_updateListFocus.sqf b/addons/spectator/functions/fnc_ui_updateListFocus.sqf new file mode 100644 index 0000000000..1e9dcafaec --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateListFocus.sqf @@ -0,0 +1,19 @@ +/* + * Author: Nelson Duarte, AACO, SilentSpike + * Function used to update the list current selection + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_updateListFocus + * + * Public: No + */ + +#include "script_component.hpp" + +CTRL_LIST tvSetCurSel ([[GVAR(camFocus)] call BIS_fnc_objectVar] call FUNC(ui_getTreeDataIndex)); diff --git a/addons/spectator/functions/fnc_ui_updateWidget.sqf b/addons/spectator/functions/fnc_ui_updateWidget.sqf new file mode 100644 index 0000000000..068bff7cb0 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateWidget.sqf @@ -0,0 +1,90 @@ +/* + * Author: Nelson Duarte, SilentSpike + * Updates spectator UI unit info widget + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_updateWidget + * + * Public: No + */ + +#include "script_component.hpp" +#define IMG_COMMANDER "a3\Ui_f\data\IGUI\Cfg\CommandBar\imageCommander_ca.paa" +#define IMG_DRIVER "a3\Ui_f\data\IGUI\Cfg\CommandBar\imageDriver_ca.paa" +#define IMG_GUNNER "a3\Ui_f\data\IGUI\Cfg\CommandBar\imageGunner_ca.paa" +#define IMG_CARGO "a3\Ui_f\data\IGUI\Cfg\CommandBar\imageCargo_ca.paa" +#define IMG_UNARMED "" // TODO: Find suitable unarmed icon + +// Hide if no target or widget is toggled off +if (!GVAR(uiWidgetVisible) || {isNull GVAR(camFocus)}) exitWith {CTRL_WIDGET ctrlShow false}; + +private _focus = GVAR(camFocus); + +private _name = ([_focus] call EFUNC(common,getName)) select [0, NAME_MAX_CHARACTERS]; +if !(isPlayer _focus) then { _name = format ["%1: %2", localize "str_player_ai", _name]; }; + +private _unitTypePicture = ""; +private _vehicleTypePicture = ""; +private _vehiclePositionPicture = ""; +if (_focus != vehicle _focus) then { + _vehicleTypePicture = getText (configFile >> "CfgVehicles" >> typeOf vehicle _focus >> "Picture"); + + _vehiclePositionPicture = switch (_focus) do { + case (commander vehicle _focus): {IMG_COMMANDER}; + case (driver vehicle _focus): {IMG_DRIVER}; + case (gunner vehicle _focus): {IMG_GUNNER}; + default {IMG_CARGO}; + }; +} else { + _unitTypePicture = [_focus] call EFUNC(common,getVehicleIcon); +}; + + +private _weapon = currentWeapon _focus; +private _weaponPicture = if (_weapon != "") then { + getText (configFile >> "CfgWeapons" >> _weapon >> "Picture") +} else { + IMG_UNARMED +}; + +private _throwable = (currentThrowable _focus) param [0,""]; +private _throwablePicture = if (_throwable != "") then { + getText (configFile >> "CfgMagazines" >> _throwable >> "Picture") +} else { + IMG_UNARMED +}; + +(getPlayerScores _focus) params [ + ["_kills",0,[0]], + ["_softKills",0,[0]], + ["_armoredKills",0,[0]], + ["_airKills",0,[0]], + ["_deaths",0,[0]], + ["_total",0,[0]] +]; + +CTRL_WIDGET_NAME ctrlSetText _name; +CTRL_WIDGET_KILLS ctrlSetText str _kills; +CTRL_WIDGET_LAND ctrlSetText str _softKills; +CTRL_WIDGET_ARMORED ctrlSetText str _armoredKills; +CTRL_WIDGET_AIR ctrlSetText str _airKills; +CTRL_WIDGET_DEATHS ctrlSetText str _deaths; +CTRL_WIDGET_TOTAL ctrlSetText str _total; + +CTRL_WIDGET_WEAPON ctrlSetText _weaponPicture; +CTRL_WIDGET_THROWABLE ctrlSetText _throwablePicture; + +CTRL_WIDGET_UNIT ctrlSetText _unitTypePicture; +CTRL_WIDGET_VEHICLE ctrlSetText _vehicleTypePicture; +CTRL_WIDGET_VEHICLE_POS ctrlSetText _vehiclePositionPicture; + +// Handle widget toggling +if !(ctrlShown CTRL_WIDGET) then { + CTRL_WIDGET ctrlShow true; +}; diff --git a/addons/spectator/functions/fnc_updateCameraModes.sqf b/addons/spectator/functions/fnc_updateCameraModes.sqf index 819636ee22..2931fe5295 100644 --- a/addons/spectator/functions/fnc_updateCameraModes.sqf +++ b/addons/spectator/functions/fnc_updateCameraModes.sqf @@ -3,8 +3,10 @@ * Adds or removes spectator camera modes from the selection available to the local player. * Possible camera modes are: * - 0: Free - * - 1: Internal - * - 2: External + * - 1: First person + * - 2: Follow + * + * Default selection is [0,1,2] * * Arguments: * 0: Camera modes to add @@ -26,12 +28,11 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { }; params [["_addModes",[],[[]]], ["_removeModes",[],[[]]]]; -private ["_newModes","_currentModes"]; -_currentModes = GVAR(availableModes); +private _currentModes = GVAR(availableModes); // Restrict additions to only possible values -_newModes = _addModes arrayIntersect [0,1,2]; +private _newModes = _addModes arrayIntersect ALL_MODES; _newModes append (_currentModes - _removeModes); _newModes = _newModes arrayIntersect _newModes; @@ -39,14 +40,19 @@ _newModes sort true; // Can't become an empty array if (_newModes isEqualTo []) then { - ["Cannot remove all camera modes (%1)", QFUNC(updateCameraModes)] call BIS_fnc_error; + WARNING("Cannot remove all spectator camera modes"); } else { GVAR(availableModes) = _newModes; }; // Update camera in case of change -if (GVAR(isSet)) then { - [] call FUNC(transitionCamera); +if !(isNil QGVAR(camera)) then { + // If mode was free and no longer available, find a focus + if (!(MODE_FREE in _newModes) && {GVAR(camMode) == MODE_FREE} && {isNull GVAR(camFocus)}) then { + [true] call FUNC(setFocus); + }; + + [GVAR(camMode)] call FUNC(cam_setCameraMode); }; _newModes diff --git a/addons/spectator/functions/fnc_updateSpectatableSides.sqf b/addons/spectator/functions/fnc_updateSides.sqf similarity index 73% rename from addons/spectator/functions/fnc_updateSpectatableSides.sqf rename to addons/spectator/functions/fnc_updateSides.sqf index 57f7756d54..ec4606b951 100644 --- a/addons/spectator/functions/fnc_updateSpectatableSides.sqf +++ b/addons/spectator/functions/fnc_updateSides.sqf @@ -1,7 +1,6 @@ /* * Author: SilentSpike - * Adds or removes sides from the selection available to spectate by the local player. - * Note that the side filter setting is applied to the available sides dynamically. + * Adds or removes sides from the selection available to spectate. Local effect. * * Default selection is [west,east,resistance,civilian] * @@ -10,10 +9,10 @@ * 1: Sides to remove * * Return Value: - * Spectatable sides + * Sides available * * Example: - * [[west], [east,civilian]] call ace_spectator_fnc_updateSpectatableSides + * [[west], [east,civilian]] call ace_spectator_fnc_updateSides * * Public: Yes */ diff --git a/addons/spectator/functions/fnc_updateUnits.sqf b/addons/spectator/functions/fnc_updateUnits.sqf index 418643be38..6df7cad8ad 100644 --- a/addons/spectator/functions/fnc_updateUnits.sqf +++ b/addons/spectator/functions/fnc_updateUnits.sqf @@ -1,69 +1,40 @@ /* * Author: SilentSpike - * Adds units to spectator whitelist/blacklist and refreshes the filter units + * Adds and removed units from the spectator list. Local effect. * * Arguments: - * 0: Units to add to the whitelist - * 1: Use blacklist (default: false) + * 0: Units to show in the list + * 1: Units to hide in the list * * Return Value: - * None + * None * * Example: - * [allUnits,true] call ace_spectator_fnc_updateUnits + * [allPlayers, [player]] call ace_spectator_fnc_updateUnits * * Public: Yes */ #include "script_component.hpp" -params [["_newUnits",[],[[]]],["_blacklist",false,[false]]]; - // Function only matters on player clients if (!hasInterface) exitWith {}; -// If adding to a list we can exit here, since it won't show up until the UI refreshes anyway -if !(_newUnits isEqualTo []) exitWith { - if (_blacklist) then { - GVAR(unitWhitelist) = GVAR(unitWhitelist) - _newUnits; - GVAR(unitBlacklist) append _newUnits; - } else { - GVAR(unitBlacklist) = GVAR(unitBlacklist) - _newUnits; - GVAR(unitWhitelist) append _newUnits; +params [["_addUnits",[],[[]]], ["_removeUnits",[],[[], true]]]; + +// Deprecated parameter (remember to remove bool from params when removed) +if (_removeUnits isEqualType true) then { + ACE_DEPRECATED("Boolean parameter","3.12.0","array (see function header or doc)"); + if (_removeUnits) then { + _removeUnits = _addUnits; + _addUnits = []; }; }; -// Unit setting filter -private _newUnits = [[],allPlayers,playableUnits,allUnits] select GVAR(filterUnits); +// Add to the whitelist and prevent list overlap +GVAR(unitBlacklist) = GVAR(unitBlacklist) - _addUnits; +GVAR(unitWhitelist) append _addUnits; -// Side setting filter -private _sideFilter = [ - {_x == (side group player)}, - {(_x getFriend (side group player)) >= 0.6}, - {(_x getFriend (side group player)) < 0.6}, - {true} -] select GVAR(filterSides); - -private _filteredSides = GVAR(availableSides) select _sideFilter; - -// Filter units and append to list -private _filteredUnits = (_newUnits - GVAR(unitBlacklist)) select { - (alive _x) && - {(_x isKindOf "CAManBase")} && - {(side group _x) in _filteredSides} && // Side filter - {simulationEnabled _x} && - {!(_x getVariable [QGVAR(isStaged), false])} // Who watches the watchmen? -}; -_filteredUnits append GVAR(unitWhitelist); - -// Cache icons and colour for drawing -private _filteredGroups = []; -{ - // Intentionally re-applied to units in case their status changes - [_x] call FUNC(cacheUnitInfo); - _filteredGroups pushBackUnique (group _x); -} forEach _filteredUnits; - -// Replace previous lists entirely (removes any no longer valid) -GVAR(groupList) = _filteredGroups; -GVAR(unitList) = _filteredUnits arrayIntersect _filteredUnits; +// Blacklist overrides the whitelist +GVAR(unitWhitelist) = GVAR(unitWhitelist) - _removeUnits; +GVAR(unitBlacklist) append _removeUnits; diff --git a/addons/spectator/functions/fnc_updateVisionModes.sqf b/addons/spectator/functions/fnc_updateVisionModes.sqf index 6db965af3e..56b6696752 100644 --- a/addons/spectator/functions/fnc_updateVisionModes.sqf +++ b/addons/spectator/functions/fnc_updateVisionModes.sqf @@ -1,7 +1,7 @@ /* * Author: SilentSpike * Adds or removes spectator vision modes from the selection available to the local player. - * The default selection is [-2,-1,0,1]. + * * Possible vision modes are: * - -2: Normal * - -1: Night vision @@ -14,6 +14,8 @@ * - 6: White Hot / Darker Red Cold * - 7: Thermal (Shade of Red and Green, Bodies are white) * + * Default selection is [-2,-1,0,1] + * * Arguments: * 0: Vision modes to add * 1: Vision modes to remove @@ -34,12 +36,11 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { }; params [["_addModes",[],[[]]], ["_removeModes",[],[[]]]]; -private ["_newModes","_currentModes"]; -_currentModes = GVAR(availableVisions); +private _currentModes = GVAR(availableVisions); // Restrict additions to only possible values -_newModes = _addModes arrayIntersect [-2,-1,0,1,2,3,4,5,6,7]; +private _newModes = _addModes arrayIntersect [-2,-1,0,1,2,3,4,5,6,7]; _newModes append (_currentModes - _removeModes); _newModes = _newModes arrayIntersect _newModes; @@ -47,14 +48,14 @@ _newModes sort true; // Can't become an empty array if (_newModes isEqualTo []) then { - ["Cannot remove all vision modes (%1)", QFUNC(updateVisionModes)] call BIS_fnc_error; + WARNING("Cannot remove all spectator vision modes"); } else { GVAR(availableVisions) = _newModes; }; // Update camera in case of change -if (GVAR(isSet)) then { - [] call FUNC(transitionCamera); +if !(isNil QGVAR(camera)) then { + [GVAR(camVision)] call FUNC(cam_setVisionMode); }; _newModes diff --git a/addons/spectator/script_component.hpp b/addons/spectator/script_component.hpp index 38561f3cdd..b4e7c82ac8 100644 --- a/addons/spectator/script_component.hpp +++ b/addons/spectator/script_component.hpp @@ -24,39 +24,117 @@ #define X_PART(num) (W_PART(num) + (safezoneX + (safezoneW - SIZEX)/2)) #define Y_PART(num) (H_PART(num) + (safezoneY + (safezoneH - SIZEY)/2)) -// UI tools -#define TOOL_H H_PART(1) -#define TOOL_W W_PART(5) -#define MARGIN TOOL_W * 0.05 +// UI/Camera related values +#define SPEED_SLOW 0.1 +#define SPEED_DEFAULT 1 +#define SPEED_FAST 2 // Seems to be some form of multiplier (but using 1 stil makes it faster...?) -// UI compass -#define COMPASS_W (TOOL_W * 4) -#define COMPASS_X (safeZoneX + safeZoneW * 0.5 - COMPASS_W * 0.5) +#define MODE_FREE 0 +#define MODE_FPS 1 +#define MODE_FOLLOW 2 +#define ALL_MODES [MODE_FREE,MODE_FPS,MODE_FOLLOW] -// UI IDCs -#define IDC_COMP 4490 -#define IDC_COMP_0 5000 -#define IDC_COMP_90 5090 -#define IDC_COMP_180 5180 -#define IDC_COMP_270 5270 +#define VISION_NORM -2 +#define VISION_NVG -1 -#define IDC_HELP 7631 -#define IDC_HELP_LIST 7622 +#define MAX_VIEW_DISTANCE 2500 +#define MIN_VIEW_DISTANCE 500 +#define DEFAULT_VIEW_DISTANCE 1200 -#define IDC_MAP 6791 +#define FIRE_HIGHLIGHT_TIME 0.05 +#define MAX_GRENADES 15 +#define MAX_PROJECTILES 50 +#define MAX_PROJECTILE_SEGMENTS 50 -#define IDC_TOOL 3000 -#define IDC_TOOL_CLOCK 3003 -#define IDC_TOOL_FOV 3005 -#define IDC_TOOL_NAME 3001 -#define IDC_TOOL_SPEED 3006 -#define IDC_TOOL_VIEW 3002 -#define IDC_TOOL_VISION 3004 +#define DISTANCE_ICONS_SQR 9000000 // Icons are rendered within 3000m, squared for `distanceSqr` speed +#define DISTANCE_NAMES_SQR 30625 // Names are rendered within 175m, squared for `distanceSqr` speed +#define NAME_MAX_CHARACTERS 17 -#define IDC_UNIT 6002 -#define IDC_UNIT_TREE 6005 +#define LIST_ENTITIES 0 +#define LIST_UPDATE_RATE 1 -// UI colours -#define COL_BACK 0.1,0.1,0.1,0.7 -#define COL_FORE 1,1,1,1 -#define COL_FORE_D 0.1,0.1,0.1,0.8 +// Revive variables +#define BIS_REVIVE "BIS_revive_incapacitated" +#define ACE_REVIVE "ACE_isUnconscious" +#define NEEDS_REVIVE(unit) (unit getVariable [ACE_REVIVE,false]) || {unit getVariable [BIS_REVIVE,false]} + +// Icons used in the UI/drawing +#define ICON_DEAD "a3\Ui_F_Curator\Data\CfgMarkers\kia_ca.paa" +#define ICON_GRENADE "A3\Ui_f\data\IGUI\Cfg\HoldActions\holdAction_connect_ca.paa" +#define ICON_UNIT "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\UnitIcon_ca.paa" +#define ICON_REVIVE "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\ReviveIcon_ca.paa" +#define ICON_BACKGROUND_UNIT "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\UnitName_ca.paa" +#define ICON_CAMERA "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\cameraTexture_ca.paa" +#define CAM_ICON_FREE "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\FreeSelected.paa" +#define CAM_ICON_FREE_SELECTED "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Free.paa" +#define CAM_ICON_FOLLOW "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\FollowSelected.paa" +#define CAM_ICON_FOLLOW_SELECTED "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Follow.paa" +#define CAM_ICON_FPS "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\FpsSelected.paa" +#define CAM_ICON_FPS_SELECTED "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Fps.paa" + +// IDCs +#define MAIN_DISPLAY ([] call BIS_fnc_displayMission) + +#define IDD_SPEC_DISPLAY 60000 +#define SPEC_DISPLAY (findDisplay IDD_SPEC_DISPLAY) + +#define IDC_MOUSE 60001 +#define CTRL_MOUSE (SPEC_DISPLAY displayCtrl IDC_MOUSE) + +#define IDC_TIME 60002 +#define CTRL_TIME (SPEC_DISPLAY displayCtrl IDC_TIME) + +#define IDC_LIST 60003 +#define CTRL_LIST (SPEC_DISPLAY displayCtrl IDC_LIST) + +#define IDC_TABS 60004 +#define CTRL_TABS (SPEC_DISPLAY displayCtrl IDC_TABS) + +#define IDC_CAM_TYPES 60005 +#define CTRL_CAM_TYPES (SPEC_DISPLAY displayCtrl IDC_CAM_TYPES) +#define IDC_FREE 60006 +#define IDC_FOLLOW 60007 +#define IDC_FPS 60008 + +#define IDC_MAP_GROUP 60010 +#define CTRL_MAP_GROUP (SPEC_DISPLAY displayCtrl IDC_MAP_GROUP) +#define IDC_MAP_TITLE 60011 +#define CTRL_MAP_TITLE (SPEC_DISPLAY displayCtrl IDC_MAP_TITLE) +#define IDC_MAP_FOOTER 60012 +#define CTRL_MAP_FOOTER (SPEC_DISPLAY displayCtrl IDC_MAP_FOOTER) +#define IDC_MAP_SPEC_NUM 60013 +#define CTRL_MAP_SPEC_NUM (SPEC_DISPLAY displayCtrl IDC_MAP_SPEC_NUM) +#define IDC_MAP 60014 +#define CTRL_MAP (SPEC_DISPLAY displayCtrl IDC_MAP) + +#define IDC_HELP_BACK 60020 +#define CTRL_HELP_BACK (SPEC_DISPLAY displayCtrl IDC_HELP_BACK) +#define IDC_HELP 60021 +#define CTRL_HELP (SPEC_DISPLAY displayCtrl IDC_HELP) + +#define IDC_WIDGET 60030 +#define CTRL_WIDGET (SPEC_DISPLAY displayCtrl IDC_WIDGET) +#define IDC_WIDGET_VEHICLE 60031 +#define CTRL_WIDGET_VEHICLE (SPEC_DISPLAY displayCtrl IDC_WIDGET_VEHICLE) +#define IDC_WIDGET_UNIT 60032 +#define CTRL_WIDGET_UNIT (SPEC_DISPLAY displayCtrl IDC_WIDGET_UNIT) +#define IDC_WIDGET_NAME 60033 +#define CTRL_WIDGET_NAME (SPEC_DISPLAY displayCtrl IDC_WIDGET_NAME) +#define IDC_WIDGET_VEHICLE_POS 60034 +#define CTRL_WIDGET_VEHICLE_POS (SPEC_DISPLAY displayCtrl IDC_WIDGET_VEHICLE_POS) +#define IDC_WIDGET_KILLS 60035 +#define CTRL_WIDGET_KILLS (SPEC_DISPLAY displayCtrl IDC_WIDGET_KILLS) +#define IDC_WIDGET_LAND 60036 +#define CTRL_WIDGET_LAND (SPEC_DISPLAY displayCtrl IDC_WIDGET_LAND) +#define IDC_WIDGET_ARMORED 60037 +#define CTRL_WIDGET_ARMORED (SPEC_DISPLAY displayCtrl IDC_WIDGET_ARMORED) +#define IDC_WIDGET_AIR 60038 +#define CTRL_WIDGET_AIR (SPEC_DISPLAY displayCtrl IDC_WIDGET_AIR) +#define IDC_WIDGET_DEATHS 60039 +#define CTRL_WIDGET_DEATHS (SPEC_DISPLAY displayCtrl IDC_WIDGET_DEATHS) +#define IDC_WIDGET_TOTAL 60040 +#define CTRL_WIDGET_TOTAL (SPEC_DISPLAY displayCtrl IDC_WIDGET_TOTAL) +#define IDC_WIDGET_WEAPON 60041 +#define CTRL_WIDGET_WEAPON (SPEC_DISPLAY displayCtrl IDC_WIDGET_WEAPON) +#define IDC_WIDGET_THROWABLE 60042 +#define CTRL_WIDGET_THROWABLE (SPEC_DISPLAY displayCtrl IDC_WIDGET_THROWABLE) diff --git a/addons/spectator/stringtable.xml b/addons/spectator/stringtable.xml index ae65487d23..a9aec6cbb0 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -1,28 +1,25 @@ - + - + + Spectator + Zuschauer + Spettatore + 旁觀者 + 旁观者 + スペクテイター + 관전자 + + ACE Spectator + ACE Zuschauer ACE スペクテイター Spettatore ACE Spectateur ACE ACE 旁观者 ACE 旁觀者 - - - Spectator Settings - Zuschauer Einstellungen - Ustawienia obserwatora - Preferências de Espectador - Настройки спектатора - Nastavení pozorovatele - Ajustes de espectador - Impostazioni Spettatore - Réglages de spectateur - スペクテイター設定 - 관전자 설정 - 旁观者设定 - 旁觀者設定 + Obserwator ACE + ACE 관전자 Configure how the spectator system will operate by default. @@ -36,188 +33,26 @@ Configure comment le système de spectateurs opère par défaut. スペクテイター システムが標準でどのように動作するか設定できます。 어떻게 관전자 시스템이 기본적으로 작동되는지 설정합니다 - 设定旁观者系统相关配置. - 設定旁觀者系統相關配置. + 设定旁观者系统相关配置 + 設定旁觀者系統相關配置 - - Unit filter - Einheitenfilter - Filtr jednostek - Filtro de unidades - Фильтр юнитов - Filtr jednotek - Filtro de unidad - Filtro Unità - Filtre d'unités - ユニット フィルタ - 인원 필터 - 单位过滤器 - 單位過濾器 + + AI Enabled + KI Sichtbarkeit + AI にも有効化 + AI Abilitate + 可觀察AI + 可观察AI + AI 활성 - - Method of filtering spectatable units. - Einheiten denen zugeschaut werden kann. - Wybierz jednostki, jakie będzie można obserwować po uruchomeniu obserwatora. - Método para filtrar unidades espectáveis - Метод фильтрации наблюдаемых юнитов. - Método de filtrado de unidades de espectador - Metoda filtrování pozorovaných jednotek. - Metodo di filtraggio delle unità osservabili. - Méthode de filtration des unités regardables. - 観察できるユニットへのフィルタ設定ができます。 - 관전할 수 있는 인원을 고릅니다 - 过滤哪些单位可以使用旁观者系统. - 過濾哪些單位可以使用旁觀者系統. - - - No units - Keine Einheiten - Brak jednostek - Sem unidades - Никто - Žádné jednotky - Ninguna - Nessuna unità - Pas d'unités - ユニットなし - 인원 없음 - 无单位 - 無單位 - - - Only players - Nur Spieler - Tylko gracze - Somente jogadores - Только игроки - Pouze hráči - Solo jugadores - Solo giocatori - Joueurs seulements - プレイヤのみ - 플레이어만 - 只有玩家 - 只有玩家 - - - Playable Units - Nur spielbare Einheiten - Grywalne jednostki - Unidades jogáveis - Играбельные юниты - Hratelné jednotky - Unidades jugables - Unità giocabili - Unités jouables - プレイ可能なユニットのみ - 플레이 가능한 인원 - 可扮演单位 - 可扮演單位 - - - All units - Alle Einheiten - Wszystkie jednostki - Todas unidades - Все юниты - Všechny jednotky - Todas las unidades - Tutte le unità - Toutes les unités - 全てのユニット - 모든 인원 - 所有单位 - 所有單位 - - - Side filter - Fraktionenfilter - Filtr stron - Filtro de lados - Фильтр стороны - Filtr stran - Filtro de bando - Filtro Lato - Filtre de faction - 勢力フィルタ - 진영 필터 - 阵营过滤器 - 陣營過濾器 - - - Method of filtering spectatable sides. - Fraktionen denen zugeschaut werden kann. - Wybierz strony, jakie będzie można obserwować po uruchomeniu obserwatora. - Método para filtrar lados espectáveis. - Метод фильтрации наблюдаемых сторон. - Método de filtrado de bandos de espectador - Metoda filtrování pozorovaných stran. - Metodo per filtrare i lati osservabili. - Méthode de filtration des factions regardables - 観察できる勢力へのフィルタ設定ができます。 - 관전할 수 있는 진영을 고릅니다 - 过滤可旁观的阵营. - 過濾可旁觀的陣營. - - - Player side - Spielerseite - Strona gracza - Lado do jogador - Сторона игрока - Strana hráče - Bando del jugador - Lato giocatore - Faction du joueur - プレイヤーと同じ勢力 - 플레이어 진영 - 玩家 - 玩家 - - - Friendly sides - Verbündete - Strony sojusznicze - Lados aliados - Дружественные стороны - Strana spojenců - Bandos amigos - Lati alleati - Factions amies - 友軍勢力 - 아군 진영 - 友军 - 友軍 - - - Hostile sides - Feinde - Strony wrogie - Lados hostis - Враждебные стороны - Strana nepřítele - Bandos enemigos - Lati nemici - Factions hostiles - 敵対勢力 - 적군 진영 - 敌方 - 敵方 - - - All sides - Alle Fraktionen - Wszystkie strony - Todos os lados - Все стороны - Všechny strany - Todos los bandos - Tutti i lati - Toutes les factions - 全ての勢力 - 모든 진영 - 所有阵营 - 所有陣營 + + Make AI viewable in spectator + Macht KI-Einheiten den Zuschauern sichtbar + スペクテイターで AI 視点を可能に + Permette la visibilità delle AI in spettatore + 開啟此功能後可在觀察者模式下觀察AI單位。 + 开启此功能后可在观察者模式下观察AI单位。 + 관전자가 AI를 관전 할 수 있습니다. Camera modes @@ -235,7 +70,7 @@ 攝影機模式 - Camera modes that can be used. + Camera modes that can be used Verwendbare Kameramodi Tryby kamery, jakie mogą być używane. Modos de camera que podem ser utilizados @@ -244,10 +79,10 @@ Módy kamery které mohou být použity. Modalità che la camera può utilizzare. Modes de caméra qui peuvent être utilisés - カメラ モードを使えます。 + カメラ モードを設定できます。 사용할 수 있는 카메라 모드들 입니다 - 设定可使用的摄影机模式. - 設定可使用的攝影機模式. + 设定可使用的摄影机模式 + 設定可使用的攝影機模式 All @@ -264,47 +99,24 @@ 所有 所有 - - Free only - Nur freie Kamera - Tylko wolna - Somente livre - Только свободная - Pouze volná - Solo libre - Solo libera - Libre seulement - 自由視点のみ - 오직 자유만 - 只有自由模式 - 只有自由模式 - - - Internal only - Erste Person //Bitte überprüfen! - Tylko wewnętrznaSomente internaТолько внутренняяPouze pohled z první osobySolo internaSolo internaInterne seulement一人称視点のみ오직 내부만只有第一人称只有第一人稱 - - External only - Dritte Person //Bitte überpfüfen! - Tylko zewnętrznaSomente externaТолько внешняяPouze pohled z třetí osobySolo externaSolo esternaExterne seulement三人称視点のみ오직 외부만只有第三人称只有第三人稱 - Internal and external - Erste und dritte Person - Wewnętrzna i zewnętrzna - Interna e externa - Внутренняя и внешняя - Pohled z první a třetí osoby - Interna y externa - Interna ed Esterna - Interne et externe - 一人称と三人称視点 - 외부 및 내부 - 第一和第三人称 - 第一和第三人稱 + 1PP and 3PP + 1ère et 3e personne + 1.ª y 3.ª persona + 1° e 3° pers + 1 i 3 os. + первого а также третьего + 1PP und 3PP + 1. a 3. osoby + 1ª e 3ª pessoa + 1PP 과 3PP 카메라 + 1PP と 3PP カメラ + 第一人稱與第三人稱 + 第一人称与第三人称 Vision modes - Sichtmodi + Sichtmodus Tryby wizji Modos de visão Режимы видения @@ -318,7 +130,7 @@ 視覺模式 - Vision modes that can be used. + Vision modes that can be used Sichtmodi die verwendet werden können. Tryby wizji, jakie mogą być używane. Modos de visão que podem ser utilizados @@ -327,10 +139,10 @@ Módy zobrazení které mohou být použity. Modalità visuali che possono essere usate. Modes de visions qui peuvent être utilisés - ビジョン モードを使えます。 + ビジョン モードを設定できます。 사용할 수 있는 시야 모드들 입니다 - 设定可使用的视觉模式. - 設定可使用的視覺模式. + 设定可使用的视觉模式 + 設定可使用的視覺模式 Night vision @@ -363,35 +175,20 @@ 熱成像 - - Spectator Units - Zuschauereinheiten - Jednostki obserwatora - Unidades espectadoras - Юниты - Unidades espectador - Jednotky pozorovatele - Unità Osservabili - Unités spectatrices - スペクテイター ユニット - 관전 인원 - 旁观者单位 - 旁觀者單位 - - - Spectator Controls - Zuschauersteuerung - Sterowanie obserwatorem - Controle do espectador - Управление спектатором - Controles de espectador - Ovládání pozorovatele - Controlli Osservatore - Contrôles de spectateur - スペクテイター操作 - 관전 조작 - 旁观者控制 - 旁觀者控制 + + Engineer + Pionier + Mechanik + Engenheiro + Инженер + Inženýr + Ingeniero + Geniere + Ingénieur + 工兵 + 정비공 + 工兵 + 工兵 Free @@ -408,14 +205,6 @@ 自由模式 自由模式 - - Internal - Erste Person //Bitte überprüfen! - WewnętrznaInternaВнутренняяPohled z první osobyInternaInternaInterne一人称視点내부第一人称第一人稱 - - External - Dritte Person //Bitte überprüfen! - ZewnętrznaExternaВнешняяPohled z třetí osobyExternaEsternaExterne三人称視点외부第三人称第三人稱 Normal Normal @@ -462,335 +251,23 @@ 熱成像 - - Free Camera - Freie Kamera - Kamera swobodna - Câmera livre - Свободная камера - Volná Kamera - Cámara libre - Camera Libera - Caméra libre - 自由視点 - 자유 카메라 - 自由摄影机 - 自由攝影機 + + Icons + Icons + アイコン + Icone + 單位圖示 + 单位图示 + 아이콘 - - Camera Forward - Kamera vor - Kamera naprzód - Câmera para frente - Камера вперед - Vpřed (Kamera) - Cámara delantera - Camera Avanti - Caméra en avant - カメラを前に - 카메라 앞으로 - 摄影机往前 - 攝影機往前 - - - Camera Backward - Kamera zurück - Kamera w tył - Câmera para trás - Камера назад - Zpět (Kamera) - Cámara trasera - Camera Indietro - Caméra en arrière - カメラを後ろに - 카메라 뒤로 - 摄影机往后 - 攝影機往後 - - - Camera Left - Kamera links - Kamera w lewo - Câmera para esquerda - Камера влево - Doleva (Kamera) - Cámara izquierda - Camera Sinistra - Caméra à gauche - カメラを左に - 카메라 왼쪽으로 - 摄影机往左 - 攝影機往左 - - - Camera Right - Kamera rechts - Kamera w prawo - Câmera para direita - Камера вправо - Doprava (Kamera) - Cámara derecha - Camera Destra - Caméra à droite - カメラを右に - 카메라 오른쪽으로 - 摄影机往右 - 攝影機往右 - - - Camera Up - Kamera hoch - Kamera w górę - Câmera para cima - Камера вверх - Nahoru (Kamera) - Cámara arriba - Camera Su - Caméra en haut - カメラを上に - 카메라 위로 - 摄影机往上 - 攝影機往上 - - - Camera Down - Kamera runter - Kamera w dół - Câmera para baixo - Камера вниз - Dolů (Kamera) - Cámara abajo - Camera Giù - Caméra en bas - カメラを下に - 카메라 아래로 - 摄影机往下 - 攝影機往下 - - - Pan Camera - Kamera mitschwenken - Panoramowanie - Câmera panorâmica - Панорамирование - Cámara panorámica - Otáčet kameru - Camera Panoramica - Tourner la caméra - カメラを振る - 카메라 돌리기 - 平移摄影机 - 平移攝影機 - - - Dolly Camera - Kamerafahrt - Płynna kamera - Câmera dolly - Рельсовая камера - Cámara dolly - Posouvat kameru - Camera dolly - Bouger la caméra - カメラを動かす - 카메라 추적 - 移动摄影机 - 移動攝影機 - - - Lock Camera to Target - Kamera Ziel verfolgen - Zablokuj kamerę na celu - Travar câmera em alvo - Зафиксировать камеру на цели - Zamknout kameru na Cíl - Fijar cámara al objetivo - Blocca la camera su obbiettivo - Verrouiller la caméra sur la cible - カメラを目標に固定 - 목표에 카메라 고정 - 锁定摄影机观察单一目标 - 鎖定攝影機觀察單一目標 - - - Speed Boost - Geschwindigkeitserhöhung - Przyśpieszenie kamery - Aumento de velocidade - Ускорение камеры - Aumento de velocidad - Zrychlení kamery - Aumento Velocità - Boost de vitesse - 速度の増加 - 속도 증가 - 速度提升 - 速度提升 - - - Interface - Nuteroberfläche - Interfejs - Interface - Интерфейс - Rozhraní - Interfaz - Interfaccia - Interface - インターフェイス - 인터페이스 - 介面 - 介面 - - - Toggle Interface - Nutzeroberfläche umschalten - Przełącz interfejs - Alternar interface - Переключить интерфейс - Zobrazit/skrýt rozhraní - Conmutar - Apri Interfaccia - Bascule de l'interface - インターフェイスをトグル - 인터페이스 토글 - 切换介面 - 切換介面 - - - Toggle Unit Icons - Einheitensymbole umschalten - Przełącz ikony jednostek - Alternar ícone de unidades - Вкл./выкл. иконки юнитов - Zobrazit/skrýt ikony jednotek - Conmutar iconos de unidad - Apri Icone Unità - Bascule des icônes des unités - ユニット アイコンをトグル - 인원 아이콘 토글 - 切换单位图示 - 切換單位圖示 - - - Toggle Unit List - Einheitenliste umschalten - Przełącz listę jednostek - Alternar lista de unidades - Вкл./выкл. список юнитов - Zobrazit/skrýt seznam jednotek - Conmutar lista de unidades - Apri Lista Unità - Bascule de la liste des unités - ユニット一覧をトグル - 인원 목록 토글 - 切换单位名单 - 切換單位名單 - - - Toggle Toolbar - Werkzeuge umschalten - Przełącz pasek narzędzi - Alternar barra de ferramentas - Вкл./выкл. тулбар - Conmutar barra de herramientas - Zobrazit/skrýt spodní panel - Apri Barra degli Strumenti - Bascule de la barre d'outils - ツールバーをトグル - 툴바 토글 - 切换工具栏 - 切換工具欄 - - - Toggle Compass - Kompass umschalten - Przełącz kompas - Alternar bússola - Вкл./выкл. компас - Zobrazit/skrýt kompas - Conmutar brújula - Apri Bussola - Basculer le compas - 方位磁石をトグル - 나침반 토글 - 切换指北针 - 切換指北針 - - - Toggle Map - Karte umschalten - Przełącz mapę - Alternar mapa - Вкл./выкл. карту - Zobrazit/skrýt mapu - Conmutar map - Apri Mappa - Basculer la carte - 地図をトグル - 지도 토글 - 切换地图 - 切換地圖 - - - Toggle Help - Hilfe umschalten - Przełącz pomoc - Alternar ajuda - Вкл./выкл. помощь - Zobrazit/skrýt ovládání - Conmutar ayuda - Apri Aiuti - Basculer l'aide - ヘルプをトグル - 도움 토글 - 切换帮助 - 切換幫助 - - - Camera Attributes - Kameraeigenschaften - Atrybuty kamery - Atributos de câmera - Атрибуты камеры - Atributos de cámara - Atributy kamery - Attributi Camera - Propriétés de la caméra - カメラ高度 - 카메라 속성 - 摄影机属性 - 攝影機屬性 - - - Next Camera - Nächste Kamera - Następna kamera - Próxima câmera - Следующая камера - Následující kamera - Siguiente cámara - Prossima Camera - Caméra suivante - 次のカメラ - 다음 카메라 - 下个镜头 - 下個鏡頭 - - - Previous Camera - Vorherige Kamera - Poprzednia kamera - Câmera anterior - Предыдущая камера - Předchozí kamera - Anterior cámara - Precedente Camera - Caméra précédente - 前のカメラ - 이전 카메라 - 上个镜头 - 上個鏡頭 + + Projectiles + Geschosse + 弾道表示 + Proiettili + 顯示彈道 + 显示弹道 + 발사체 Next Unit @@ -800,7 +277,7 @@ Следующий юнит Následující jednotka Siguiente unidad - Prossima Unità + Unità Successiva Unité suivante 次のユニット 다음 인원 @@ -815,7 +292,7 @@ Предыдущий юнит Předchozí jednotka Anterior unidad - Precedente Unità + Unità Precedente Unité précédente 前のユニット 이전 인원 @@ -823,124 +300,22 @@ 上個單位 - Next Vision Mode - Nächster Sichtmodus - Następny tryb wizji - Próximo modo de visão - Следующий режим видения - Siguiente modo de visión - Následující mód zobrazení - Prossima Modalità Visiva - Mode de vision suivant - 次のビジョン モード - 다음 시야 모드 - 下个视觉模式 - 下個視覺模式 + Vision Mode + Sichtmodus + ビジョン モード + Modalità Visiva + 視覺模式 + 视觉模式 + 보기 모드 - - Previous Vision Mode - Vorheriger Sichtmodus - Poprzedni tryb wizji - Modo de visão anterior - Предыдущий режим видения - Anterior modo de visión - Předchozí mód zobrazení - Precedente Modalità Visiva - Mode de vision précédent - 前のビジョン モード - 이전 시야 모드 - 上个视觉模式 - 上個視覺模式 - - - Adjust Zoom - Vergrößerung einstellen - Reguluj zoom - Ajustar zoom - Настроить зум - Regulovat přiblížení - Ajustar aumento - Aggiusta Zoom - Ajuster le zoom - 拡大倍率を調節 - 줌 조절 - 调整倍率 - 調整倍率 - - - Adjust Speed - Geschwindigkeit einstellen - Reguluj prędkość - Ajuster velocidade - Настроить скорость - Regulovat rychlost - Ajustar velocidad - Aggiusta Velocità - Ajuster la vitesse - 速度を調節 - 속도 조절 - 调整速度 - 調整速度 - - - Increment Zoom - Vergrößern - Reguluj zoom (krok) - Incrementar zoom - Увеличить зум - Incrementar aumento - Regulovat přiblížení (pomalu) - Aumenta Zoom - Augmenter le zoom - 拡大倍率を増やす - 줌 증가 - 增加放大 - 增加放大 - - - Increment Speed - Geschwindkeit erhöhen - Reguluj prędkość (krok) - Incrementar velocidade - Увеличить скорость - Incrementar velocidad - Regulovat rychlost (pomalu) - Aumenta Velocità - Augmenter la vitesse - 速度を増やす - 속도 증가 - 增加速度 - 增加速度 - - - Reset Zoom - Vergrößerung zurücksetzen - Resetuj zoom - Redefinir zoom - Сбросить зум - Obnovit přiblížení - Reiniciar aumento - Resetta Zoom - RAZ zoom - 拡大倍率を初期化 - 줌 초기화 - 重置缩放 - 重置縮放 - - - Reset Speed - Geschwindigkeit zurücksetzen - Resetuj prędkość - Redefinir velocidade - Сбросить скорость - Obnovit rychlost - Reiniciar velocidad - Resetta Velocità - RAZ vitesse - 速度を初期化 - 속도 초기화 - 重置速度 - 重置速度 + + Slow Speed + Langsam + 速度低下 + Bassa Velocità + 慢速度 + 慢速度 + 느린 속도 diff --git a/addons/spectator/ui.hpp b/addons/spectator/ui.hpp new file mode 100644 index 0000000000..7a49c72a86 --- /dev/null +++ b/addons/spectator/ui.hpp @@ -0,0 +1,460 @@ +class RscButton; +class RscControlsGroup; +class RscControlsGroupNoScrollbars; +class RscListNBox { + class ScrollBar; +}; +class RscMapControl; +class RscPicture; +class RscPictureKeepAspect; +class RscText; +class RscToolbox; +class RscTree; +class EGVAR(common,CompassControl); + +// Based on RscDisplayEGSpectator (sadly Arma doesn't like display inheritance) +class GVAR(display) { + idd = IDD_SPEC_DISPLAY; + enableSimulation = 1; + movingEnable = 0; + closeOnMissionEnd = 1; + + onLoad = QUOTE(_this call FUNC(ui_handleLoad)); + + onKeyDown = QUOTE(_this call FUNC(ui_handleKeyDown)); + onKeyUp = QUOTE(_this call FUNC(ui_handleKeyUp)); + onMouseMoving = QUOTE(_this call FUNC(ui_handleMouseMoving)); + onChildDestroyed = QUOTE(_this call FUNC(ui_handleChildDestroyed)); + + class ControlsBackground { + class MouseHandler: RscText { + idc = IDC_MOUSE; + + onMouseButtonDown = QUOTE(_this call FUNC(ui_handleMouseButtonDown)); + onMouseButtonUp = QUOTE(if ((_this select 1) == 1) then { GVAR(holdingRMB) = false; };); + onMouseButtonDblClick = QUOTE(_this call FUNC(ui_handleMouseButtonDblClick)); + onMouseZChanged = QUOTE(_this call FUNC(ui_handleMouseZChanged)); + + text = ""; + x = "safeZoneXAbs"; + y = "safeZoneY"; + w = "safeZoneWAbs"; + h = "safeZoneH"; + colorBackground[] = {1,1,1,0}; + style = 16; + }; + }; + class Controls { + class List: RscTree { + idc = IDC_LIST; + + onMouseEnter = QUOTE([false] call FUNC(ui_fadeList)); + onMouseExit = QUOTE([true] call FUNC(ui_fadeList)); + onTreeSelChanged = QUOTE([ARR_2(false,_this)] call FUNC(ui_handleListClick)); + onTreeDblClick = QUOTE([ARR_2(true,_this)] call FUNC(ui_handleListClick)); + + x = "safeZoneX"; + y = safeZoneY + H_PART(1.5); + w = W_PART(13.5); + h = safeZoneH - H_PART(1.5); + + disableKeyboardSearch = 1; + multiselectEnabled = 0; + colorBorder[] = {0,0,0,0}; + colorBackground[] = {0,0,0,0.75}; + expandOnDoubleclick = 1; + fade = 0.8; + shadow = 1; + colorLines[] = {0,0,0,0}; + class ScrollBar { + width = 0; + height = 0; + scrollSpeed = 0.1; + color[] = {1,1,1,0}; + }; + }; + class Tabs: RscToolbox { + idc = IDC_TABS; + + //onToolBoxSelChanged = QUOTE(_this call FUNC(ui_handleTabSelected)); + onMouseEnter = QUOTE([false] call FUNC(ui_fadeList)); + onMouseExit = QUOTE([true] call FUNC(ui_fadeList)); + + x = "safeZoneX"; + y = "safezoneY"; + w = W_PART(13.5); + h = H_PART(1.5); + + fade = 0.5; + rows = 1; + columns = 1; + strings[] = {"$STR_A3_Spectator_Entities"}; + values[] = {0}; + sizeEx = H_PART(1); + colorBackground[] = {0,0,0,0.75}; + colorSelectedBg[] = {0,0,0,0.65}; + }; + class CameraTypesGroup: RscControlsGroupNoScrollbars { + idc = IDC_CAM_TYPES; + x = X_PART(15.5); + y = safezoneY + safezoneH - H_PART(2.38); + w = W_PART(8.6); + h = 2.6; + class controls { + class CameraTypesBackground: RscText { + x = W_PART(0.6); + y = H_PART(0.4); + w = W_PART(7.5); + h = H_PART(2); + colorBackground[] = {0,0,0,0.75}; + }; + class Free: RscButton { + style = 48; + idc = IDC_FREE; + + onButtonClick = QUOTE([MODE_FREE] call FUNC(cam_setCameraMode)); + + x = W_PART(1.3); + y = H_PART(0.8); + w = W_PART(1.63); + h = H_PART(1.37); + + colorBackground[] = {0,0,0,0}; + colorBackgroundDisabled[] = {0,0,0,0}; + colorBackgroundActive[] = {0,0,0,0}; + colorFocused[] = {0,0,0,0}; + text = CAM_ICON_FREE; + tooltip = "$STR_A3_Spectator_free_camera_tooltip"; + }; + class Follow: RscButton { + style = 48; + idc = IDC_FOLLOW; + + onButtonClick = QUOTE([MODE_FOLLOW] call FUNC(cam_setCameraMode)); + + x = W_PART(3.6); + y = H_PART(0.8); + w = W_PART(1.63); + h = H_PART(1.37); + + colorBackground[] = {0,0,0,0}; + colorBackgroundDisabled[] = {0,0,0,0}; + colorBackgroundActive[] = {0,0,0,0}; + colorFocused[] = {0,0,0,0}; + text = CAM_ICON_FOLLOW; + tooltip = "$STR_A3_Spectator_3pp_camera_tooltip"; + }; + class Fps: RscButton { + style = 48; + idc = IDC_FPS; + + onButtonClick = QUOTE([MODE_FPS] call FUNC(cam_setCameraMode)); + + x = W_PART(5.8); + y = H_PART(0.8); + w = W_PART(1.63); + h = H_PART(1.37); + + colorBackground[] = {0,0,0,0}; + colorBackgroundDisabled[] = {0,0,0,0}; + colorBackgroundActive[] = {0,0,0,0}; + colorFocused[] = {0,0,0,0}; + text = CAM_ICON_FPS; + tooltip = "$STR_A3_Spectator_1pp_camera_tooltip"; + + }; + }; + }; + class MapGroup: RscControlsGroupNoScrollbars { + idc = IDC_MAP_GROUP; + x = 0; + y = 0.1; + w = 1; + h = 0.8; + class controls { + class MapHeader: RscText { + x = 0; + y = 0; + w = 1; + h = 0.05; + colorBackground[] = {0,0,0,0.75}; + }; + class MapFooter: RscText { + idc = IDC_MAP_FOOTER; + x = 0; + y = 0.75; + w = 1; + h = 0.05; + text = ""; + style = 2; + colorBackground[] = {0,0,0,0.75}; + sizeEx = H_PART(1); + }; + class GameTimeText: RscText { + idc = IDC_TIME; + x = 0.01; + y = 0.76; + w = 0.29; + h = 0.03; + text = "00:00:00"; + sizeEx = H_PART(1); + }; + class MapTitle: RscText { + idc = IDC_MAP_TITLE; + x = 0.01; + y = 0.01; + w = 0.69; + h = 0.03; + text = ""; + colorText[] = {1,1,1,1}; + sizeEx = H_PART(1); + }; + class SpectatorsCount: RscText { + idc = IDC_MAP_SPEC_NUM; + x = 0.97; + y = 0.01; + w = 0.03; + h = 0.03; + text = ""; + colorText[] = {1,1,1,1}; + sizeEx = H_PART(1); + }; + class SpectatorsIcon: RscPictureKeepAspect { + x = 0.94; + y = 0.01; + w = 0.03; + h = 0.03; + text = CAM_ICON_FPS_SELECTED; + }; + }; + }; + class Map: RscMapControl { + idc = IDC_MAP; + + onDraw = QUOTE(_this call FUNC(ui_handleMapDraw)); + onMouseButtonClick = QUOTE(_this call FUNC(ui_handleMapClick)); + + x = 0; + y = 0.15; + w = 1; + h = 0.7; + + maxSatelliteAlpha = 0.75; + colorBackground[] = {1,1,1,1}; + }; + class HelpBackground: RscText { + idc = IDC_HELP_BACK; + x = safezoneX + safezoneW - W_PART(12); + y = safezoneY + safezoneH - H_PART(8); + w = W_PART(12); + h = H_PART(8); + colorBackground[] = {0,0,0,0.75}; + }; + class Help: RscListNBox { + class ListScrollBar: ScrollBar {}; + disableOverflow = 0; + rowHeight = H_PART(1); + idc = IDC_HELP; + x = safezoneX + safezoneW - W_PART(12); + y = safezoneY + safezoneH - H_PART(12); + w = W_PART(12); + h = H_PART(12); + }; + class FocusInfo: RscControlsGroupNoScrollbars { + idc = IDC_WIDGET; + x = X_PART(12.9); + y = Y_PART(24); + w = W_PART(14.2); + h = H_PART(3.5); + class controls { + class UpperBackground: RscText { + x = 0; + y = 0; + w = W_PART(14.2); + h = H_PART(1.4); + colorBackground[] = {0,0,0,0.75}; + }; + class StatsBackground: RscText { + x = 0; + y = H_PART(1.5); + w = W_PART(6); + h = H_PART(2); + colorBackground[] = {0,0,0,0.75}; + }; + class WeaponBackground: RscText { + x = W_PART(6.1); + y = H_PART(1.5); + w = W_PART(6); + h = H_PART(2); + colorBackground[] = {1,1,1,0.4}; + }; + class ThrowableBackground: RscText { + x = W_PART(12.2); + y = H_PART(1.5); + w = W_PART(2); + h = H_PART(2); + colorBackground[] = {1,1,1,0.4}; + }; + class Name: RscText { + shadow = 0; + idc = IDC_WIDGET_NAME; + text = ""; + x = W_PART(0.1); + y = H_PART(0.1); + w = W_PART(10.8); + h = H_PART(1.2); + sizeEx = H_PART(1); + }; + class VehiclePos: RscPictureKeepAspect { + idc = IDC_WIDGET_VEHICLE_POS; + text = ""; + x = W_PART(11); + y = H_PART(0.2); + w = W_PART(1); + h = H_PART(1); + }; + class VehicleType: RscPicture { + idc = IDC_WIDGET_VEHICLE; + text = ""; + x = W_PART(12.1); + y = H_PART(0.2); + w = W_PART(2); + h = H_PART(1); + }; + class UnitType: RscPictureKeepAspect { + idc = IDC_WIDGET_UNIT; + text = ""; + x = W_PART(13.1); + y = H_PART(0.2); + w = W_PART(1); + h = H_PART(1); + }; + class Kills: RscPictureKeepAspect { + text = "a3\Ui_f\data\IGUI\Cfg\MPTable\infantry_ca.paa"; + x = W_PART(0.1); + y = H_PART(1.6); + w = W_PART(0.8); + h = H_PART(0.8); + }; + class LandKills: RscPictureKeepAspect { + text = "a3\Ui_f\data\IGUI\Cfg\MPTable\soft_ca.paa"; + x = W_PART(1.1); + y = H_PART(1.6); + w = W_PART(0.8); + h = H_PART(0.8); + }; + class ArmoredKills: RscPictureKeepAspect { + text = "a3\Ui_f\data\IGUI\Cfg\MPTable\armored_ca.paa"; + x = W_PART(2.1); + y = H_PART(1.6); + w = W_PART(0.8); + h = H_PART(0.8); + }; + class AirKills: RscPictureKeepAspect { + text = "a3\Ui_f\data\IGUI\Cfg\MPTable\air_ca.paa"; + x = W_PART(3.1); + y = H_PART(1.6); + w = W_PART(0.8); + h = H_PART(0.8); + }; + class Deaths: RscPictureKeepAspect { + text = "a3\Ui_f\data\IGUI\Cfg\MPTable\killed_ca.paa"; + x = W_PART(4.1); + y = H_PART(1.6); + w = W_PART(0.8); + h = H_PART(0.8); + }; + class Total: RscPictureKeepAspect { + text = "a3\Ui_f\data\IGUI\Cfg\MPTable\total_ca.paa"; + x = W_PART(5.1); + y = H_PART(1.6); + w = W_PART(0.8); + h = H_PART(0.8); + }; + class Kills_Count: RscText { + style = 2; + shadow = 0; + idc = IDC_WIDGET_KILLS; + text = ""; + x = W_PART(0.1); + y = H_PART(2.5); + w = W_PART(0.8); + h = H_PART(0.9); + sizeEx = H_PART(0.7); + }; + class LandKills_Count: RscText { + style = 2; + shadow = 0; + idc = IDC_WIDGET_LAND; + text = ""; + x = W_PART(1.1); + y = H_PART(2.5); + w = W_PART(0.8); + h = H_PART(0.9); + sizeEx = H_PART(0.7); + }; + class ArmoredKills_Count: RscText { + style = 2; + shadow = 0; + idc = IDC_WIDGET_ARMORED; + text = ""; + x = W_PART(2.1); + y = H_PART(2.5); + w = W_PART(0.8); + h = H_PART(0.9); + sizeEx = H_PART(0.7); + }; + class AirKills_Count: RscText { + style = 2; + shadow = 0; + idc = IDC_WIDGET_AIR; + text = ""; + x = W_PART(3.1); + y = H_PART(2.5); + w = W_PART(0.8); + h = H_PART(0.9); + sizeEx = H_PART(0.7); + }; + class Deaths_Count: RscText { + style = 2; + shadow = 0; + idc = IDC_WIDGET_DEATHS; + text = ""; + x = W_PART(4.1); + y = H_PART(2.5); + w = W_PART(0.8); + h = H_PART(0.9); + sizeEx = H_PART(0.7); + }; + class Total_Count: RscText { + style = 2; + shadow = 0; + idc = IDC_WIDGET_TOTAL; + text = ""; + x = W_PART(5.1); + y = H_PART(2.5); + w = W_PART(0.8); + h = H_PART(0.9); + sizeEx = H_PART(0.7); + }; + class WeaponPicture: RscPictureKeepAspect { + idc = IDC_WIDGET_WEAPON; + text = ""; + x = W_PART(6.2); + y = H_PART(1.6); + w = W_PART(5.8); + h = H_PART(1.8); + }; + class ThrowablePicture: RscPictureKeepAspect { + idc = IDC_WIDGET_THROWABLE; + text = ""; + x = W_PART(12.3); + y = H_PART(1.6); + w = W_PART(1.8); + h = H_PART(1.8); + }; + }; + }; + class compass: EGVAR(common,CompassControl) {}; + }; +}; diff --git a/addons/spottingscope/CfgVehicles.hpp b/addons/spottingscope/CfgVehicles.hpp index fa2574cb8d..f360be45c9 100644 --- a/addons/spottingscope/CfgVehicles.hpp +++ b/addons/spottingscope/CfgVehicles.hpp @@ -18,6 +18,14 @@ class CfgVehicles { }; }; + class ThingX; + class ACE_SpottingScope_Tube: ThingX { + author = ECSTRING(common,ACETeam); + scope = 1; + displayName = CSTRING(DisplayName); + model = QPATHTOF(data\ace_spottingscope_tube.p3d); + }; + class LandVehicle; class StaticWeapon: LandVehicle { class Turrets; @@ -74,6 +82,21 @@ class CfgVehicles { getOutAction = "PlayerProne"; editorSubcategory = "EdSubcat_Turrets"; + threat[] = {0.7, 0.3, 0}; + accuracy = 0.12; + cost = 10000; + icon = "\A3\Static_F_Gamma\data\UI\map_StaticTurret_AT_CA.paa"; + + class SpeechVariants { + class Default { + speechSingular[] = {"veh_infantry_SF_s"}; + speechPlural[] = {"veh_infantry_SF_p"}; + }; + }; + textSingular = "$STR_A3_nameSound_veh_infantry_SF_s"; + textPlural = "$STR_A3_nameSound_veh_infantry_SF_p"; + nameSound = "veh_infantry_SF_s"; + class Turrets: Turrets { class MainTurret: MainTurret { minTurn = -45; @@ -123,6 +146,26 @@ class CfgVehicles { opticsDisablePeripherialVision = 1; }; }; + + // damage handling + armor = 80; + + class Damage { + tex[] = {}; + mat[] = { + QPATHTO_R(data\ace_spottingscope_metal.rvmat), + QPATHTO_R(data\ace_spottingscope_metal_damage.rvmat), + QPATHTO_R(data\ace_spottingscope_metal_destruct.rvmat), + QPATHTO_R(data\ace_spottingscope_glass.rvmat), + QPATHTO_R(data\ace_spottingscope_glass_damage.rvmat), + QPATHTO_R(data\ace_spottingscope_glass_destruct.rvmat), + QPATHTO_R(data\ace_spottingscope_rubber.rvmat), + QPATHTO_R(data\ace_spottingscope_rubber_damage.rvmat), + QPATHTO_R(data\ace_spottingscope_rubber_damage.rvmat) + }; + }; + + editorPreview = QPATHTOF(data\preview_spottingscope.jpg); }; class ACE_B_SpottingScope: ACE_SpottingScopeObject { @@ -152,6 +195,24 @@ class CfgVehicles { crew = "I_spotter_F"; }; + class ACE_B_T_SpottingScope: ACE_SpottingScopeObject { + author = ECSTRING(common,ACETeam); + _generalMacro = "ACE_B_T_SpottingScope"; + scope = 2; + side = 1; + faction = "BLU_T_F"; + crew = "B_T_Spotter_F"; + }; + + class ACE_O_T_SpottingScope: ACE_SpottingScopeObject { + author = ECSTRING(common,ACETeam); + _generalMacro = "ACE_O_T_SpottingScope"; + scope = 2; + side = 0; + faction = "OPF_T_F"; + crew = "O_T_Spotter_F"; + }; + class Item_Base_F; class ACE_Item_SpottingScope: Item_Base_F { author[] = {"Rocko", "Scubaman3D"}; @@ -159,6 +220,9 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(DisplayName); vehicleClass = "Items"; + editorCategory = "EdCat_Equipment"; + editorSubcategory = "EdSubcat_InventoryItems"; + editorPreview = QPATHTOF(data\preview_spottingscope.jpg); class TransportItems { MACRO_ADDITEM(ACE_SpottingScope,1); }; diff --git a/addons/spottingscope/CfgWeapons.hpp b/addons/spottingscope/CfgWeapons.hpp index acdf7c910f..9548b30aee 100644 --- a/addons/spottingscope/CfgWeapons.hpp +++ b/addons/spottingscope/CfgWeapons.hpp @@ -1,16 +1,17 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_SpottingScope: ACE_ItemCore { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(DisplayName); descriptionShort = ""; picture = QPATHTOF(UI\w_spottingscope_ca.paa); model = QPATHTOF(data\ace_spottingscope.p3d); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 40; }; }; diff --git a/addons/spottingscope/XEH_preInit.sqf b/addons/spottingscope/XEH_preInit.sqf index b47cf6628d..e80d5e4ef9 100644 --- a/addons/spottingscope/XEH_preInit.sqf +++ b/addons/spottingscope/XEH_preInit.sqf @@ -6,4 +6,14 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +["ACE_SpottingScopeObject", "killed", { + params ["_wreck"]; + + private _tube = "ACE_SpottingScope_tube" createVehicle [0,0,0]; + _tube setDir (getDir _wreck - 180); + _tube setPosASL AGLToASL (_wreck modelToWorld (_wreck selectionPosition "destructionEffect")); + _tube setVelocity [1 - random 2, 1 - random 2, 4]; + _tube addTorque (vectorNormalized [1 - random 2, 1 - random 2, 1 - random 2] vectorMultiply 4); +}] call CBA_fnc_addClassEventHandler; + ADDON = true; diff --git a/addons/spottingscope/config.cpp b/addons/spottingscope/config.cpp index 4fa5bd4d58..5e8576eb59 100644 --- a/addons/spottingscope/config.cpp +++ b/addons/spottingscope/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_B_SpottingScope", "ACE_O_SpottingScope", "ACE_I_SpottingScope", "ACE_Item_SpottingScope"}; + units[] = {"ACE_B_SpottingScope", "ACE_O_SpottingScope", "ACE_I_SpottingScope", "ACE_B_T_SpottingScope", "ACE_O_T_SpottingScope", "ACE_Item_SpottingScope"}; weapons[] = {"ACE_SpottingScope"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_apl", "ace_interaction"}; diff --git a/addons/spottingscope/data/ace_spottingscope.p3d b/addons/spottingscope/data/ace_spottingscope.p3d index 2298b9c8f9..74ded32045 100644 Binary files a/addons/spottingscope/data/ace_spottingscope.p3d and b/addons/spottingscope/data/ace_spottingscope.p3d differ diff --git a/addons/spottingscope/data/ace_spottingscope_glass.rvmat b/addons/spottingscope/data/ace_spottingscope_glass.rvmat index bce3c40b59..c23549f1c8 100644 --- a/addons/spottingscope/data/ace_spottingscope_glass.rvmat +++ b/addons/spottingscope/data/ace_spottingscope_glass.rvmat @@ -1,96 +1,89 @@ -class StageTI -{ - texture="a3\data_f\Default_ti_ca.paa"; +class StageTI { + texture = "a3\data_f\Default_ti_ca.paa"; }; -ambient[]={0.301,0.63999999,0.68000001,1}; -diffuse[]={0.301,0.63999999,0.68000001,1}; -forcedDiffuse[]={0.2,0.34999999,0.2,0}; -emmisive[]={0,0,0,1}; -specular[]={0.67450982,0.64313728,0.50196081,1}; -specularPower=550; -PixelShaderID="Super"; -VertexShaderID="Super"; -class Stage1 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +ambient[] = {0.301,0.63999999,0.68000001,1}; +diffuse[] = {0.301,0.63999999,0.68000001,1}; +forcedDiffuse[] = {0.2,0.34999999,0.2,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.67450982,0.64313728,0.50196081,1}; +specularPower = 550; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage2 -{ - texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; - uvSource="tex"; - class uvTransform - { - aside[]={6,0,0}; - up[]={0,6,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage2 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource = "tex"; + class uvTransform { + aside[] = {6,0,0}; + up[] = {0,6,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage3 -{ - texture="#(argb,8,8,3)color(0,0,0,0,MC)"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage3 { + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage4 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage4 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage5 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage5 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage6 -{ - texture="#(ai,32,128,1)fresnel(4.01,2.86)"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage6 { + texture = "#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage7 -{ - texture="a3\data_f\env_land_co.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; diff --git a/addons/spottingscope/data/ace_spottingscope_glass_damage.rvmat b/addons/spottingscope/data/ace_spottingscope_glass_damage.rvmat new file mode 100644 index 0000000000..18105269f8 --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_glass_damage.rvmat @@ -0,0 +1,84 @@ +class StageTI { + texture = "a3\data_f\default_ti_ca.paa"; +}; + +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.1,0.1,0.1,1}; +specularPower = 1000; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "a3\data_f\destruct\damage_glass_laminated_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,2,0}; + up[] = {-2,2,0}; + dir[] = {0,0,0}; + pos[] = {-0.05,0.7,0}; + }; +}; + +class Stage2 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,dt)"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,2,0}; + up[] = {-2,2,0}; + dir[] = {0,0,0}; + pos[] = {-0.05,0.7,0}; + }; +}; + +class Stage3 { + texture = "a3\data_f\destruct\damage_glass_laminated_ca.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,0,0}; + up[] = {0,2,0}; + dir[] = {0,0,0}; + pos[] = {-0.05,0.7,0}; + }; +}; + +class Stage4 { + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,1}; + }; +}; + +class Stage5 { + texture = "a3\data_f\destruct\damage_glass_laminated_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnel(1.1,0.4)"; + uvSource = "none"; +}; + +class Stage7 { + useWorldEnvMap = "true"; + texture = "a3\data_f\env_land_ca.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_glass_destruct.rvmat b/addons/spottingscope/data/ace_spottingscope_glass_destruct.rvmat new file mode 100644 index 0000000000..6b0e949b00 --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_glass_destruct.rvmat @@ -0,0 +1,78 @@ +class StageTI { + texture = "a3\data_f\default_ti_ca.paa"; +}; + +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.1,0.1,0.1,1}; +specularPower = 1000; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "a3\data_f\destruct\damage_glass_tempered_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,2,0}; + up[] = {-2,2,0}; + dir[] = {0,0,0}; + pos[] = {-0.05,0.7,0}; + }; +}; + +class Stage2 { + texture = "a3\data_f\destruct\damage_glass_tempered_ca.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,0,0}; + up[] = {0,2,0}; + dir[] = {0,0,0}; + pos[] = {-0.05,0.7,0}; + }; +}; + +class Stage3 { + texture = "a3\data_f\destruct\damage_glass_tempered_ca.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,0,0}; + up[] = {0,2,0}; + dir[] = {0,0,0}; + pos[] = {-0.05,0.7,0}; + }; +}; + +class Stage4 { + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,0,0}; + up[] = {0,2,0}; + dir[] = {0,0,1}; + pos[] = {0,0,1}; + }; +}; + +class Stage5 { + texture = "a3\data_f\destruct\damage_glass_tempered_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnel(1.1,0.4)"; + uvSource = "none"; +}; + +class Stage7 { + useWorldEnvMap = "true"; + texture = "a3\data_f\env_land_ca.paa"; + uvSource="none"; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_item.p3d b/addons/spottingscope/data/ace_spottingscope_item.p3d deleted file mode 100644 index d2de0edf1c..0000000000 Binary files a/addons/spottingscope/data/ace_spottingscope_item.p3d and /dev/null differ diff --git a/addons/spottingscope/data/ace_spottingscope_metal.rvmat b/addons/spottingscope/data/ace_spottingscope_metal.rvmat index 54cfcafeb8..cc610359b0 100644 --- a/addons/spottingscope/data/ace_spottingscope_metal.rvmat +++ b/addons/spottingscope/data/ace_spottingscope_metal.rvmat @@ -1,92 +1,85 @@ -ambient[]={1,1,1,1}; -diffuse[]={1,1,1,1}; -forcedDiffuse[]={0,0,0,0}; -emmisive[]={0,0,0,1}; -specular[]={0.2,0.2,0.2,0}; -specularPower=100; -PixelShaderID="Super"; -VertexShaderID="Super"; -class Stage1 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.2,0.2,0.2,0}; +specularPower = 100; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage2 -{ - texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; - uvSource="tex"; - class uvTransform - { - aside[]={6,0,0}; - up[]={0,6,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage2 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource = "tex"; + class uvTransform { + aside[] = {6,0,0}; + up[] = {0,6,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage3 -{ - texture="#(argb,8,8,3)color(0,0,0,0,MC)"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage3 { + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage4 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage4 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage5 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage5 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage6 -{ - texture="#(ai,32,128,1)fresnel(4.01,2.86)"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage6 { + texture = "#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage7 -{ - texture="a3\data_f\env_land_co.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; diff --git a/addons/spottingscope/data/ace_spottingscope_metal_damage.rvmat b/addons/spottingscope/data/ace_spottingscope_metal_damage.rvmat new file mode 100644 index 0000000000..e5f86e3252 --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_metal_damage.rvmat @@ -0,0 +1,85 @@ +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.2,0.2,0.2,0}; +specularPower = 100; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage2 { + texture = "a3\data_f\destruct\damage_metal_cdt.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {5,0,0}; + up[] = {0,5,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage3 { + texture = "a3\data_f\destruct\damage_metal_mc.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {3,0,0}; + up[] = {0,3,0}; + dir[] = {0,0,0}; + pos[] = {0.1,0.23,0}; + }; +}; + +class Stage4 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage5 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_metal_destruct.rvmat b/addons/spottingscope/data/ace_spottingscope_metal_destruct.rvmat new file mode 100644 index 0000000000..cb20b42b6e --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_metal_destruct.rvmat @@ -0,0 +1,85 @@ +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.2,0.2,0.2,0}; +specularPower = 100; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage2 { + texture = "a3\data_f\destruct\destruct_rust_cdt.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {8,8,0}; + up[] = {-8,8,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage3 { + texture = "a3\data_f\destruct\destruct_rust_mca.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {2,0,0}; + up[] = {0,2,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage4 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage5 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_rubber.rvmat b/addons/spottingscope/data/ace_spottingscope_rubber.rvmat index c31f850e7d..cce570415e 100644 --- a/addons/spottingscope/data/ace_spottingscope_rubber.rvmat +++ b/addons/spottingscope/data/ace_spottingscope_rubber.rvmat @@ -1,85 +1,79 @@ -ambient[]={1,1,1,1}; -diffuse[]={1,1,1,1}; -forcedDiffuse[]={0,0,0,0}; -emmisive[]={0,0,0,1}; -specular[]={0.25,0.25,0.25,1}; -specularPower=90; -PixelShaderID="Super"; -VertexShaderID="Super"; -class Stage1 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.25,0.25,0.25,1}; +specularPower = 90; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage2 -{ - texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; - uvSource="tex"; - class uvTransform - { - aside[]={6,0,0}; - up[]={0,6,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage2 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource = "tex"; + class uvTransform { + aside[] = {6,0,0}; + up[] = {0,6,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage3 -{ - texture="#(argb,8,8,3)color(0,0,0,0,MC)"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage3 { + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage4 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage4 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage5 -{ - texture="z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage5 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; -class Stage6 -{ - texture="#(ai,64,64,1)fresnel(1.5,1.22)"; - uvSource="none"; + +class Stage6 { + texture = "#(ai,64,64,1)fresnel(1.5,1.22)"; + uvSource = "none"; }; -class Stage7 -{ - texture="a3\data_f\env_land_co.paa"; - uvSource="tex"; - class uvTransform - { - aside[]={1,0,0}; - up[]={0,1,0}; - dir[]={0,0,0}; - pos[]={0,0,0}; - }; + +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; }; diff --git a/addons/spottingscope/data/ace_spottingscope_rubber_damage.rvmat b/addons/spottingscope/data/ace_spottingscope_rubber_damage.rvmat new file mode 100644 index 0000000000..b79659c7d7 --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_rubber_damage.rvmat @@ -0,0 +1,79 @@ +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,0}; +emmisive[] = {0,0,0,1}; +specular[] = {0.25,0.25,0.25,1}; +specularPower = 90; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage2 { + texture = "a3\data_f\destruct\destr_rubber_half_dt.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {5,0,0}; + up[] = {0,5,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage3 { + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform { + aside[] = {3,0,0}; + up[] = {0,3,0}; + dir[] = {0,0,0}; + pos[] = {0.1,0.23,0}; + }; +}; + +class Stage4 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage5 { + texture = "z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnel(1.5,1.22)"; + uvSource = "none"; +}; + +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,0}; + pos[] = {0,0,0}; + }; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_tube.p3d b/addons/spottingscope/data/ace_spottingscope_tube.p3d new file mode 100644 index 0000000000..c83199d50b Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_tube.p3d differ diff --git a/addons/spottingscope/data/material_dummy.p3d b/addons/spottingscope/data/material_dummy.p3d new file mode 100644 index 0000000000..ef8cd713ab Binary files /dev/null and b/addons/spottingscope/data/material_dummy.p3d differ diff --git a/addons/spottingscope/data/model.cfg b/addons/spottingscope/data/model.cfg index 71eb918bf7..86d50db6ca 100644 --- a/addons/spottingscope/data/model.cfg +++ b/addons/spottingscope/data/model.cfg @@ -1,10 +1,10 @@ -class CfgSkeletons -{ +class CfgSkeletons { class Default { isDiscrete = 1; skeletonInherit = ""; skeletonBones[] = {}; }; + class ace_spottingscope_skeleton: Default { isDiscrete = 1; skeletonInherit = "Default"; @@ -13,19 +13,23 @@ class CfgSkeletons "main_gun","main_turret", "leg_01","", "leg_02","", - "leg_03","" + "leg_03","", + "hideTurret","" }; }; }; + class CfgModels { class Default { sectionsInherit = ""; sections[] = {}; skeletonName = ""; }; + class ace_spottingscope: Default { skeletonName = "ace_spottingscope_skeleton"; sectionsInherit = "Default"; + class animations { class mainTurret { type = "rotationY"; @@ -51,20 +55,35 @@ class CfgModels { type = "rotation"; source = "fold_legs"; selection = "leg_01"; - axis="leg_01_axis"; + axis = "leg_01_axis"; minValue = 0; maxValue = 1; - angle0="rad +00"; - angle1="rad +55"; + angle0 = "rad +00"; + angle1 = "rad +55"; }; class leg_02: leg_01 { selection = "leg_02"; - axis="leg_02_axis"; + axis = "leg_02_axis"; }; class leg_03: leg_01 { selection = "leg_03"; - axis="leg_03_axis"; + axis = "leg_03_axis"; + }; + class hideTube { + type = "hide"; + source = "damage"; + selection = "main_gun"; + minValue = 0.0; + maxValue = 1.0; + hideValue = 1.0; + animPeriod = 0.0; + initPhase = 0.0; }; }; }; + + class ace_spottingscope_tube: Default { + skeletonName = "ace_spottingscope_skeleton"; + sectionsInherit = "Default"; + }; }; diff --git a/addons/spottingscope/data/preview_spottingscope.jpg b/addons/spottingscope/data/preview_spottingscope.jpg new file mode 100644 index 0000000000..ebd7a9d522 Binary files /dev/null and b/addons/spottingscope/data/preview_spottingscope.jpg differ diff --git a/addons/switchunits/ACE_Settings.hpp b/addons/switchunits/ACE_Settings.hpp index e3fc653cb2..31c74f2889 100644 --- a/addons/switchunits/ACE_Settings.hpp +++ b/addons/switchunits/ACE_Settings.hpp @@ -1,42 +1,50 @@ class ACE_Settings { class GVAR(enableSwitchUnits) { + category = CSTRING(DisplayName); value = 0; typeName = "BOOL"; }; class GVAR(switchToWest) { + category = CSTRING(DisplayName); displayName = CSTRING(SwitchToWest_DisplayName); description = CSTRING(SwitchToWest_Description); value = 0; typeName = "BOOL"; }; class GVAR(switchToEast) { + category = CSTRING(DisplayName); displayName = CSTRING(SwitchToEast_DisplayName); description = CSTRING(SwitchToEast_Description); value = 0; typeName = "BOOL"; }; class GVAR(switchToIndependent) { + category = CSTRING(DisplayName); displayName = CSTRING(SwitchToIndependent_DisplayName); description = CSTRING(SwitchToIndependent_Description); value = 0; typeName = "BOOL"; }; class GVAR(switchToCivilian) { + category = CSTRING(DisplayName); displayName = CSTRING(SwitchToCivilian_DisplayName); description = CSTRING(SwitchToCivilian_Description); value = 0; typeName = "BOOL"; }; class GVAR(enableSafeZone) { + category = CSTRING(DisplayName); displayName = CSTRING(EnableSafeZone_DisplayName); description = CSTRING(EnableSafeZone_Description); value = 1; typeName = "BOOL"; }; class GVAR(safeZoneRadius) { + category = CSTRING(DisplayName); displayName = CSTRING(SafeZoneRadius_DisplayName); description = CSTRING(SafeZoneRadius_Description); value = 100; typeName = "SCALAR"; + sliderSettings[] = {0, 1000, 100, 0}; }; }; diff --git a/addons/switchunits/CfgVehicles.hpp b/addons/switchunits/CfgVehicles.hpp index 1e12cc03d6..bb07eb541c 100644 --- a/addons/switchunits/CfgVehicles.hpp +++ b/addons/switchunits/CfgVehicles.hpp @@ -3,9 +3,9 @@ class CfgVehicles { class ACE_ModuleSwitchUnits: ACE_Module { author = ECSTRING(common,ACETeam); category = "ACE"; - displayName = CSTRING(Module_DisplayName); + displayName = CSTRING(DisplayName); function = FUNC(module); - scope = 2; + scope = 1; isGlobal = 1; icon = QPATHTOF(UI\Icon_Module_SwitchUnits_ca.paa); class Arguments { diff --git a/addons/switchunits/XEH_postInit.sqf b/addons/switchunits/XEH_postInit.sqf index dc143bc6ac..3e4fbdf46b 100644 --- a/addons/switchunits/XEH_postInit.sqf +++ b/addons/switchunits/XEH_postInit.sqf @@ -21,7 +21,7 @@ if (missionNamespace getVariable [QGVAR(EnableSwitchUnits), false]) then { [player] call FUNC(startSwitchUnits); } else { ["ace_settingChanged", { - PARAMS_2(_name,_value); + params ["_name", "_value"]; if ((_name == QGVAR(EnableSwitchUnits)) && {_value}) then { [player] call FUNC(startSwitchUnits); }; diff --git a/addons/switchunits/functions/fnc_module.sqf b/addons/switchunits/functions/fnc_module.sqf index 5170cebfb9..c7762855a4 100644 --- a/addons/switchunits/functions/fnc_module.sqf +++ b/addons/switchunits/functions/fnc_module.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -if !(isServer) exitWith {}; - params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; @@ -33,6 +31,6 @@ GVAR(Module) = true; [_logic, QGVAR(EnableSafeZone), "EnableSafeZone"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(SafeZoneRadius), "SafeZoneRadius"] call EFUNC(common,readSettingFromModule); -[QGVAR(EnableSwitchUnits), true, false, true] call EFUNC(common,setSetting); +["CBA_settings_setSettingMission", [QGVAR(EnableSwitchUnits), true, true]] call CBA_fnc_localEvent; INFO("SwitchUnits Module Initialized."); diff --git a/addons/switchunits/stringtable.xml b/addons/switchunits/stringtable.xml index b601d7bd12..57822047c8 100644 --- a/addons/switchunits/stringtable.xml +++ b/addons/switchunits/stringtable.xml @@ -1,6 +1,15 @@ - + + + Switch Units + Cambio Unità + 切換單位 + 切换单位 + ユニット切り替え + 병력 전환 + Einheitenwechsel + Switched unit Einheit gewechselt @@ -10,12 +19,12 @@ Cambiado de unidad Unité changée Egység átváltva - Cambia unità + Unità cambiata Trocado de unidade ユニットを切り替え - 인원으로 전환 切换单位 切換單位 + 인원 전환 Trying to switch @@ -45,24 +54,8 @@ Essa unidade está muito perto do inimigo. このユニットは敵に近すぎます。 그 인원은 적과 너무 가깝습니다. - 这单位太接近敌人了. - 這單位太接近敵人了. - - - SwitchUnits System - System zmiany stron - Sistema de cambio de unidad - Einheiten-Wechsel-System - Systém výměny stran - Sistema de troca de unidades - Système de changement d'unité - Egységváltó-rendszer - Переключение между юнитами - Sistema Cambio Unità - SwitchUnits システム - 인원전환 시스템 - 切换单位系统 - 切換單位系統 + 这单位太接近敌人了 + 這單位太接近敵人了 Switch to West? @@ -75,10 +68,10 @@ Átváltás BLUFOR-ra? На синих? Cambia per BLUFOR? - ウエストへ切り替えますか? - 서방으로 전환합니까? + 同盟軍へ切り替えますか? 切换至蓝方? 切換至藍方? + 청군으로 전환합니까? Allow switching to west units? @@ -91,10 +84,10 @@ Nyugat-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на синих юнитов? Consenti passaggio ad unità BLUFOR? - ウエスト側ユニットへ切り替えられるようにしますか? - 서방 인원으로 전환합니까? + 同盟軍側ユニットへ切り替えられるようにしますか? 允许切换至蓝方? 允許切換至藍方? + 청군 인원으로 전환합니까? Switch to East? @@ -107,10 +100,10 @@ Átváltás OPFOR-ra? На красных? Cambia per OPFOR? - イースト側へ切り替えますか? - 동방으로 전환합니까? + OPFOR軍側へ切り替えますか? 切换至红方? 切換至紅方? + 대항군으로 전환합니까? Allow switching to east units? @@ -123,10 +116,10 @@ Kelet-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на красных юнитов? Consenti passaggio ad unità OPFOR? - イースト側ユニットへ切り替えられるようにしますか? - 동방인원으로 전환합니까? + OPFOR軍側ユニットへ切り替えられるようにしますか? 允许切换至红方? 允許切換至紅方? + 대항군 인원으로 전환합니까? Switch to Independent? @@ -139,10 +132,10 @@ Átváltás INDFOR-ra? На независимых? Cambia per INDFOR? - インデペンデントへ切り替えますか? - 중립으로 전환합니까? + 独立軍へ切り替えますか? 切换至独立方? 切換至獨立方? + 독립군 으로 전환합니까? Allow switching to independent units? @@ -155,10 +148,10 @@ Független egységekre való váltás engedélyezése? Разрешить переключаться на независимых юнитов? Consenti passaggio ad unità INDFOR? - インデペンデント側ユニットへ切り替えられるようにしますか? - 중립 인원으로 전환합니까? + 独立軍側ユニットへ切り替えられるようにしますか? 允许切换至独立方? 允許切換至獨立方? + 독립군 인원으로 전환합니까? Switch to Civilian? @@ -171,7 +164,7 @@ Átváltás civilre? На гражданских? Cambia per Civili? - シビリアンへ切り替えますか? + 市民へ切り替えますか? 민간인으로 전환합니까? 切换至平民方? 切換至平民方? @@ -187,7 +180,7 @@ Civil egységekre való váltás engedélyezése? Разрешить переключаться на гражданских юнитов? Consenti passaggio ad unità civili? - シビリアン側ユニットへ切り替えられるようにしますか? + 市民側ユニットへ切り替えられるようにしますか? 민간인으로 전환하는걸 허가합니까? 允许切换至平民方? 允許切換至平民方? @@ -203,7 +196,7 @@ Biztonságos zóna engedélyezése? Безопасная зона Abilita Zona Sicura? - 安全地帯を有効にしますか? + 安全地帯を有効にしますか? 안전 지대 활성화? 启用安全区? 啟用安全區? @@ -219,10 +212,10 @@ Engedélyezve legyen-e egy biztonságos zóna az ellenségek körül? A játékosok nem tudnak a biztonságos zónán belüli egységekre váltani. Включить безопасную зону вокруг вражеских юнитов? Игроки не могут переключаться на юнитов, находящихся в безопасной зоне. Abilita una zona sicura attorno ad unità nemiche? I giocatori non possono cambiare ad unità dentro la zona sicura. - 敵ユニットから逃れる安全地帯を有効にしますか?プレイヤーは安全地帯内のユニットへ切り替えできません。 + 敵ユニットから逃れる安全地帯を有効にしますか?プレイヤーは安全地帯内のユニットへ切り替えできません。 적 주위로 안전 지대를 활성화합니까? 안전 지대 내에서는 플레이어가 인원 전환을 할 수 없습니다. - 启用敌方周围安全地带? 玩家不能切换到安全区内的单位. - 啟用敵方周圍安全地帶? 玩家不能切換到安全區內的單位. + 启用敌方周围安全地带? 玩家不能切换到安全区内的单位 + 啟用敵方周圍安全地帶? 玩家不能切換到安全區內的單位 Safe Zone Radius @@ -241,20 +234,20 @@ 安全區半徑 - The safe zone around players from a different team. Default: 200 - Promień bezpiecznej strefy wokół graczy z innych drużyn. Domyślnie: 200 - La zona segura alrededor de los jugadores de distintos equipos. Por defecto: 200 - Die Sicherheitszone um Spieler von einem anderen Team. Standard: 200 - Bezpečná zóna kolem hráče z jiných týmu. Výchozí: 200 - A zona segura ao redor dos jogadores de diferentes equipes. Padrão: 200 - Rayon de la zone sécurisée autour de joueurs d'équipe différentes. Défaut: 200 - A biztonságos zóna más csapatból lévő játékosok körül. Alapértelmezett: 200 - Радиус безопасной зоны вокруг ироков из противоположной команды. По-умолчанию: 200 - La zona sicura attorno ai giocatori di un team diverso. Default: 200 - 別のチームへのプレイヤーの周囲にある安全地帯の範囲。標準:200 - 다른 진영으로 부터의 플레이어 안전 지대. 기본설정: 200 - 安全区的范围. 预设值:200 - 安全區的範圍. 預設值:200 + The safe zone around players from a different team. Default: 100 + Promień bezpiecznej strefy wokół graczy z innych drużyn. Domyślnie: 100 + La zona segura alrededor de los jugadores de distintos equipos. Por defecto: 100 + Die Sicherheitszone um Spieler von einem anderen Team. Standard: 100 + Bezpečná zóna kolem hráče z jiných týmu. Výchozí: 100 + A zona segura ao redor dos jogadores de diferentes equipes. Padrão: 100 + Rayon de la zone sécurisée autour de joueurs d'équipe différentes. Défaut: 100 + A biztonságos zóna más csapatból lévő játékosok körül. Alapértelmezett: 100 + Радиус безопасной зоны вокруг ироков из противоположной команды. По-умолчанию: 100 + La zona sicura attorno ai giocatori di un team diverso. Default: 100 + 別のチームへのプレイヤーの周囲にある安全地帯の範囲。標準: 100 + 다른 진영으로 부터의 플레이어 안전 지대. 기본설정: 100 + 安全区的范围。预设值:100 + 安全區的範圍。預設值:100 Module allows you to switch side during the game. @@ -268,8 +261,8 @@ El módulo permite a las unidades cambiar de bando durante el juego. モジュールはゲームにおいて、陣営の切り替えを有効にします。 이 모듈은 당신을 게임 중에 진영을 바꿀 수 있게 해줍니다. - 此模块允许你在游戏中切换至另一方. - 此模塊允許你在遊戲中切換至另一方. + 此模块允许你在游戏中切换至另一方 + 此模塊允許你在遊戲中切換至另一方 diff --git a/addons/tacticalladder/CfgVehicles.hpp b/addons/tacticalladder/CfgVehicles.hpp index 564a034614..591f2c86af 100644 --- a/addons/tacticalladder/CfgVehicles.hpp +++ b/addons/tacticalladder/CfgVehicles.hpp @@ -21,6 +21,7 @@ class CfgVehicles { class Bag_Base; class ACE_TacticalLadder_Pack: Bag_Base { scope = 2; + author = ECSTRING(common,ACETeam); displayName = CSTRING(DisplayName); descriptionShort = ""; model = QPATHTOF(data\ace_tacticalladder_pack.p3d); diff --git a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf index f66dd79a25..098429bcec 100644 --- a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf @@ -24,6 +24,7 @@ if (_key != 1 || {isNull GVAR(ladder)}) exitWith {}; // enable running again [_unit, "forceWalk", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); detach GVAR(ladder); diff --git a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf index 3703fe1f47..9f1c5c14bb 100644 --- a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf @@ -20,11 +20,10 @@ params ["_unit", "_ladder"]; // enable running again [_unit, "forceWalk", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Ladder", false] call EFUNC(common,statusEffect_set); -private ["_pos1", "_pos2"]; - -_pos1 = getPosASL _ladder; -_pos2 = AGLToASL (_ladder modelToWorld (_ladder selectionPosition "check2")); +private _pos1 = getPosASL _ladder; +private _pos2 = AGLToASL (_ladder modelToWorld (_ladder selectionPosition "check2")); if (lineIntersects [_pos1, _pos2, _ladder]) exitWith {false}; diff --git a/addons/tacticalladder/functions/fnc_deployTL.sqf b/addons/tacticalladder/functions/fnc_deployTL.sqf index b0eb1e0f68..9df416dca7 100644 --- a/addons/tacticalladder/functions/fnc_deployTL.sqf +++ b/addons/tacticalladder/functions/fnc_deployTL.sqf @@ -21,16 +21,15 @@ if (backpack _unit != 'ACE_TacticalLadder_Pack') exitWith {}; removeBackpack _unit; -private ["_pos", "_offset", "_ladder"]; -_pos = _unit modelToWorld [0,0,0]; -_offset = if ((_unit call CBA_fnc_getUnitAnim select 0) == "prone") then { 1 } else {0.8}; +private _pos = _unit modelToWorld [0,0,0]; +private _offset = if ((_unit call CBA_fnc_getUnitAnim select 0) == "prone") then { 1 } else {0.8}; _pos set [0, (_pos select 0) + (sin getDir _unit) * _offset]; _pos set [1, (_pos select 1) + (cos getDir _unit) * _offset]; _pos set [2, [_unit] call CBA_fnc_realHeight]; -_ladder = "ACE_TacticalLadder" createVehicle _pos; +private _ladder = "ACE_TacticalLadder" createVehicle _pos; _ladder setPos _pos; _ladder setDir getDir _unit; diff --git a/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf b/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf index 4c46ea46c2..1e023b22b0 100644 --- a/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf @@ -17,6 +17,6 @@ params ["_unit"]; -if (!isNull (GETMVAR(GVAR(ladder),objNull)) && {GVAR(ladder) in attachedObjects _unit}) then { +if (!isNull GETMVAR(GVAR(ladder),objNull) && {GVAR(ladder) in attachedObjects _unit}) then { [_unit, GVAR(ladder)] call FUNC(cancelTLdeploy); }; diff --git a/addons/tacticalladder/functions/fnc_handleKilled.sqf b/addons/tacticalladder/functions/fnc_handleKilled.sqf index 742231900c..0983901010 100644 --- a/addons/tacticalladder/functions/fnc_handleKilled.sqf +++ b/addons/tacticalladder/functions/fnc_handleKilled.sqf @@ -17,6 +17,6 @@ params ["_unit"]; -if (!isNull (GETMVAR(ladder,objNull)) && {GVAR(ladder) in attachedObjects _unit}) then { +if (!isNull GETMVAR(ladder,objNull) && {GVAR(ladder) in attachedObjects _unit}) then { [_unit, GVAR(ladder)] call FUNC(cancelTLdeploy); }; diff --git a/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf b/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf index 713c75df7f..f2bac289d1 100644 --- a/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf +++ b/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -if (isNull (GETGVAR(ladder,objNull))) exitWith {}; +if (isNull GETGVAR(ladder,objNull)) exitWith {}; params ["_newPlayer", "_oldPlayer"]; diff --git a/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf b/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf index e7d4136526..ea8156a81d 100644 --- a/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf +++ b/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf @@ -20,10 +20,9 @@ params ["_scroll"]; if (isNull GVAR(ladder)) exitWith { false }; if (ACE_Modifier == 0) then { - private ["_currentStep"]; // Lengthening if (_scroll > 0) then { - _currentStep = GVAR(currentStep); + private _currentStep = GVAR(currentStep); if (_currentStep == 11) exitWith {}; _currentStep = _currentStep + 1; if (GVAR(ladder) animationPhase (format["extract_%1", _currentStep]) == 0) then { @@ -32,17 +31,17 @@ if (ACE_Modifier == 0) then { }; }; if (_scroll < 0) then { - _currentStep = GVAR(currentStep); + private _currentStep = GVAR(currentStep); if (_currentStep == 3) exitWith {}; if (GVAR(ladder) animationPhase (format["extract_%1", _currentStep]) == 1) then { GVAR(ladder) animate [format["extract_%1", _currentStep], 0]; GVAR(currentStep) = _currentStep - 1; }; }; -} else { +};// else { // Tilting (disabled due to sinking, interaction point offset and unsuitable animation) //GVAR(currentAngle) = 0 max (GVAR(currentAngle) + _scroll) min 30; //GVAR(ladder) animate ["rotate", GVAR(currentAngle)]; -}; +//}; true diff --git a/addons/tacticalladder/functions/fnc_handleUnconscious.sqf b/addons/tacticalladder/functions/fnc_handleUnconscious.sqf index 152f014602..9d6f8ad23e 100644 --- a/addons/tacticalladder/functions/fnc_handleUnconscious.sqf +++ b/addons/tacticalladder/functions/fnc_handleUnconscious.sqf @@ -17,6 +17,8 @@ params ["_unit"]; -if (!isNull (GETMVAR(ladder,objNull)) && {GVAR(ladder) in attachedObjects _unit}) then { +if (!local _unit) exitWith {}; + +if (!isNull GETMVAR(ladder,objNull) && {GVAR(ladder) in attachedObjects _unit}) then { [_unit, GVAR(ladder)] call FUNC(cancelTLdeploy); }; diff --git a/addons/tacticalladder/functions/fnc_positionTL.sqf b/addons/tacticalladder/functions/fnc_positionTL.sqf index c47733dd5a..a52211884c 100644 --- a/addons/tacticalladder/functions/fnc_positionTL.sqf +++ b/addons/tacticalladder/functions/fnc_positionTL.sqf @@ -22,6 +22,7 @@ params ["_unit", "_ladder"]; // prevent the placing unit from running [_unit, "forceWalk", "ACE_Ladder", true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Ladder", true] call EFUNC(common,statusEffect_set); { _ladder animate [_x, 0]; diff --git a/addons/tagging/CfgVehicles.hpp b/addons/tagging/CfgVehicles.hpp index 1ba838aab6..204e902641 100644 --- a/addons/tagging/CfgVehicles.hpp +++ b/addons/tagging/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Tagging); function = QFUNC(moduleInit); - scope = 2; + scope = 1; isGlobal = 1; icon = QPATHTOF(UI\Icon_Module_Tagging_ca.paa); class Arguments { diff --git a/addons/tagging/CfgWeapons.hpp b/addons/tagging/CfgWeapons.hpp index 1984b3b14a..4405696a08 100644 --- a/addons/tagging/CfgWeapons.hpp +++ b/addons/tagging/CfgWeapons.hpp @@ -1,6 +1,6 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_SpraypaintBlack : ACE_ItemCore { author = "jokoho48"; @@ -11,7 +11,7 @@ class CfgWeapons { scope = 2; hiddenSelections[] = {"camo"}; hiddenSelectionsTextures[] = {QPATHTOF(data\spraycanBlack_co.paa)}; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; }; diff --git a/addons/tagging/functions/fnc_moduleInit.sqf b/addons/tagging/functions/fnc_moduleInit.sqf index 8b2d42a010..7430ce4981 100644 --- a/addons/tagging/functions/fnc_moduleInit.sqf +++ b/addons/tagging/functions/fnc_moduleInit.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -if (!isServer) exitWith {}; - params ["_logic", "", "_activated"]; if (!_activated) exitWith {}; diff --git a/addons/tagging/functions/fnc_quickTag.sqf b/addons/tagging/functions/fnc_quickTag.sqf index 7f0a1d706e..63a93e9946 100644 --- a/addons/tagging/functions/fnc_quickTag.sqf +++ b/addons/tagging/functions/fnc_quickTag.sqf @@ -22,19 +22,22 @@ if (GVAR(quickTag) == 0) exitWith {}; params ["_unit"]; private _possibleTags = []; +private _useRandom = false; // Last Used if (GVAR(quickTag) == 1) then { private _lastUsedTagClass = _unit getVariable [QGVAR(lastUsedTag), nil]; - if (!isNil "_lastUsedTagClass") then { + if (isNil "_lastUsedTagClass") then { + _useRandom = true; + } else { private _lastUsedTag = GVAR(cachedTags) select {(_x select 0) == _lastUsedTagClass}; _possibleTags = _lastUsedTag; }; }; // Random X -if (GVAR(quickTag == 2)) then { +if ((GVAR(quickTag) == 2) || _useRandom) then { private _xTags = GVAR(cachedTags) select {(_x select 0) in ["ACE_XBlack", "ACE_XRed", "ACE_XGreen", "ACE_XBlue"]}; _possibleTags = _xTags; }; diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 4bf5707dcf..f9fc615d78 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -6,7 +6,7 @@ Маркировка タグ付け Tagowanie - Markierungssystem + Markierungssystem (Spraydose) 뿌리기 Marquage Marcamento @@ -22,15 +22,15 @@ 뿌리기 시스템의 기본사항을 설정합니다. Configure le fonctionnement par défaut du système de marquage. Configura quanto il sistema di marcamento agirà da se. - 定义喷漆系统预设设定. - 定義噴漆系統預設設定. + 定义喷漆系统预设设定 + 定義噴漆系統預設設定 - Quick Tag + Spray Paint - Quick Tag Быстрый маркер クイック タグ Szybkie tagowanie - Schnelle Markierung + Schnelle Markierung (Spraydose) 빠른 뿌리기 Marquage rapide Marcamento Rapido @@ -40,19 +40,19 @@ Action performed on main tag interaction point. Действие, выполняемое при выборе главного пункта меню маркировки. - インタラクション ポインにむけてタグ付けをします。 + インタラクション ポイントにむけてタグ付けをします。 Akcja wykonywana na głównym punkcie interakcji tagu. Aktion, die am Haupt-Interaktionspunkt ausgeführt werden soll. 이 동작은 상호작용에서 뿌리기를 할 수 있게 해준다 Action réalisé au point de marquage principal. Azione eseguita sul punto di interazione dei tag principali. - 直接喷漆在互动选单瞄准的点上. - 直接噴漆在互動選單瞄準的點上. + 直接喷漆在互动选单瞄准的点上。 + 直接噴漆在互動選單瞄準的點上。 Last Used Повторить последний - 最後の使用 + 前回と同じ Ostatnio użyte Zuletzt benutzt 최근 사용 @@ -64,7 +64,7 @@ Random X Случайный Х - 無作為な X印 + 無作為なX印 Losowy X Zufällig X 무작위 X @@ -87,7 +87,7 @@ Tag - Markieren + Markieren (Spraydose) Marcar Oznakuj Marca @@ -110,7 +110,7 @@ X černě X em preto Черный Х - 黒の X印 + 黒のX印 검정 X 黑色X标记 黑色X標記 @@ -125,7 +125,7 @@ X červeně X em vermelho Красный Х - 赤の X印 + 赤のX印 빨간 X 红色X标记 紅色X標記 @@ -140,7 +140,7 @@ X zeleně X em verde Зеленый Х - 緑の X印 + 緑のX印 초록 X 绿色X标记 綠色X標記 @@ -155,7 +155,7 @@ X modře X em azul Синий Х - 青の X印 + 青のX印 파랑 X 蓝色X标记 藍色X標記 @@ -232,8 +232,8 @@ Балончик спрея для рисования маркеров на стенах. スプレー缶は壁にタグ付できます。 벽에 뿌릴 수 있는 스프레이캔 입니다. - 喷漆可喷涂在墙壁上. - 噴漆可噴塗在牆壁上. + 喷漆可喷涂在墙壁上 + 噴漆可噴塗在牆壁上 diff --git a/addons/thermals/config.cpp b/addons/thermals/config.cpp index a61598929d..c9f3962821 100644 --- a/addons/thermals/config.cpp +++ b/addons/thermals/config.cpp @@ -26,12 +26,12 @@ class CfgVehicles { // so if a vehicle's engine starts, the entire model will begin to warm up at the rate of htMax up to a temperature of afMax, // likewise if it begins driving, the entire model will heat up at the rate specified by htMax to a maximum temperature of mfMax. class AllVehicles: All { - htMin=60; // Minimum half-cooling time (in seconds) - htMax=1800; // Maximum half-cooling time (in seconds) - afMax=70; // Maximum temperature in case the model is alive (in celsius) - mfMax=50; // Maximum temperature when the model is moving (in celsius) - mFact=0.0; // Metabolism factor - number from interval <0, 1> (0 - metabolism has no influence, 1 - metabolism has full influence (no other temperature source will be considered)) - tBody=0; // Metabolism temperature of the model (in celsius) + htMin = 60; // Minimum half-cooling time (in seconds) + htMax = 1800; // Maximum half-cooling time (in seconds) + afMax = 70; // Maximum temperature in case the model is alive (in celsius) + mfMax = 50; // Maximum temperature when the model is moving (in celsius) + mFact = 0.0; // Metabolism factor - number from interval <0, 1> (0 - metabolism has no influence, 1 - metabolism has full influence (no other temperature source will be considered)) + tBody = 0; // Metabolism temperature of the model (in celsius) }; class Animal; diff --git a/addons/trenches/CfgWeapons.hpp b/addons/trenches/CfgWeapons.hpp index 9f9049360a..de79bc277f 100644 --- a/addons/trenches/CfgWeapons.hpp +++ b/addons/trenches/CfgWeapons.hpp @@ -1,6 +1,6 @@ class CfgWeapons { - class InventoryItem_Base_F; class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; class ACE_EntrenchingTool: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -9,7 +9,7 @@ class CfgWeapons { model = QPATHTOEF(apl,ace_entrchtool.p3d); picture = QPATHTOF(ui\w_entrchtool_ca.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; }; diff --git a/addons/trenches/README.md b/addons/trenches/README.md index 7ebfbe238b..8b4a0d7a36 100644 --- a/addons/trenches/README.md +++ b/addons/trenches/README.md @@ -4,6 +4,16 @@ ace_trenches Adds item 'ACE_entrenchingtool' Adds 2 trenches; Envelope - Small & Envelop - Big +### Whitelist surfaces for digging +Single surfaces can be whitelisted by adding `ACE_canDig = 1` into `CfgSurfaces`. +Example: +```cpp +class CfgSurfaces { + class myAwesomeSurface { + ACE_canDig = 1; + }; +}; +``` ## Maintainers diff --git a/addons/trenches/functions/fnc_continueDiggingTrench.sqf b/addons/trenches/functions/fnc_continueDiggingTrench.sqf index 954eed1ca3..de961c73ff 100644 --- a/addons/trenches/functions/fnc_continueDiggingTrench.sqf +++ b/addons/trenches/functions/fnc_continueDiggingTrench.sqf @@ -79,7 +79,7 @@ if(_actualProgress == 0) then { }; private _progressLeft = (_actualProgress * 10) + 1; -private ["_i"]; + for "_i" from _progressLeft to 10 do { private _vectorDiffZ = 1 - (_i / 10); private _delay = _digTime * ((_i / 10) - _actualProgress); diff --git a/addons/trenches/functions/fnc_handleUnconscious.sqf b/addons/trenches/functions/fnc_handleUnconscious.sqf index 3407a5a029..c1f282d6c3 100644 --- a/addons/trenches/functions/fnc_handleUnconscious.sqf +++ b/addons/trenches/functions/fnc_handleUnconscious.sqf @@ -17,6 +17,8 @@ params ["_unit"]; +if (!local _unit) exitWith {}; + if (_unit getVariable [QGVAR(isPlacing), false]) then { [_unit] call FUNC(placeCancel); }; diff --git a/addons/trenches/functions/fnc_placeCancel.sqf b/addons/trenches/functions/fnc_placeCancel.sqf index b3d6bf78da..1eaf7298a1 100644 --- a/addons/trenches/functions/fnc_placeCancel.sqf +++ b/addons/trenches/functions/fnc_placeCancel.sqf @@ -22,6 +22,7 @@ if (_key != 1 || {GVAR(digPFH) == -1}) exitWith {}; // enable running again [_unit, "forceWalk", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); // delete placement dummy deleteVehicle GVAR(trench); diff --git a/addons/trenches/functions/fnc_placeConfirm.sqf b/addons/trenches/functions/fnc_placeConfirm.sqf index 7c3be2d901..08c774d8c9 100644 --- a/addons/trenches/functions/fnc_placeConfirm.sqf +++ b/addons/trenches/functions/fnc_placeConfirm.sqf @@ -19,6 +19,7 @@ params ["_unit"]; // enable running again [_unit, "forceWalk", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Trenches", false] call EFUNC(common,statusEffect_set); // remove dig pfh [GVAR(digPFH)] call CBA_fnc_removePerFrameHandler; @@ -50,9 +51,9 @@ private _v1 = _v3 vectorCrossProduct _v2; // Stick the trench to the ground _basePos set [2, getTerrainHeightASL _basePos]; private _minzoffset = 0; -private ["_ix","_iy"]; -for [{_ix = -_dx/2},{_ix <= _dx/2},{_ix = _ix + _dx/3}] do { - for [{_iy = -_dy/2},{_iy <= _dy/2},{_iy = _iy + _dy/3}] do { + +for [{private _ix = -_dx/2},{_ix <= _dx/2},{_ix = _ix + _dx/3}] do { + for [{private _iy = -_dy/2},{_iy <= _dy/2},{_iy = _iy + _dy/3}] do { private _pos = _basePos vectorAdd (_v2 vectorMultiply _ix) vectorAdd (_v1 vectorMultiply _iy); _minzoffset = _minzoffset min ((getTerrainHeightASL _pos) - (_pos select 2)); diff --git a/addons/trenches/functions/fnc_placeTrench.sqf b/addons/trenches/functions/fnc_placeTrench.sqf index 7ec97a0c41..94826fb346 100644 --- a/addons/trenches/functions/fnc_placeTrench.sqf +++ b/addons/trenches/functions/fnc_placeTrench.sqf @@ -28,6 +28,7 @@ TRACE_1("",GVAR(trenchPlacementData)); // prevent the placing unit from running [_unit, "forceWalk", "ACE_Trenches", true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_Trenches", true] call EFUNC(common,statusEffect_set); // create the trench private _trench = createVehicle [_noGeoModel, [0, 0, 0], [], 0, "NONE"]; @@ -67,9 +68,8 @@ GVAR(digPFH) = [{ // Stick the trench to the ground _basePos set [2, getTerrainHeightASL _basePos]; private _minzoffset = 0; - private ["_ix","_iy"]; - for [{_ix = -_dx/2},{_ix <= _dx/2},{_ix = _ix + _dx/3}] do { - for [{_iy = -_dy/2},{_iy <= _dy/2},{_iy = _iy + _dy/3}] do { + for [{private _ix = -_dx/2},{_ix <= _dx/2},{_ix = _ix + _dx/3}] do { + for [{private _iy = -_dy/2},{_iy <= _dy/2},{_iy = _iy + _dy/3}] do { private _pos = _basePos vectorAdd (_v2 vectorMultiply _ix) vectorAdd (_v1 vectorMultiply _iy); _minzoffset = _minzoffset min ((getTerrainHeightASL _pos) - (_pos select 2)); diff --git a/addons/trenches/functions/fnc_removeTrench.sqf b/addons/trenches/functions/fnc_removeTrench.sqf index 53059f34bf..d22db5d27e 100644 --- a/addons/trenches/functions/fnc_removeTrench.sqf +++ b/addons/trenches/functions/fnc_removeTrench.sqf @@ -64,7 +64,7 @@ private _fnc_onFailure = { [(_removeTimeLeft + 0.5), [_unit, _trench], _fnc_onFinish, _fnc_onFailure, localize LSTRING(RemovingTrench)] call EFUNC(common,progressBar); private _progressLeft = ((1 - _actualProgress) * 10) + 1; -private ["_i"]; + for "_i" from _progressLeft to 10 do { private _vectorDiffZ = _i / 10; private _delay = _removeTime * ((_i / 10) - (1 - _actualProgress)); diff --git a/addons/trenches/stringtable.xml b/addons/trenches/stringtable.xml index 161e3eae39..a0413a3346 100644 --- a/addons/trenches/stringtable.xml +++ b/addons/trenches/stringtable.xml @@ -1,11 +1,11 @@ - + Entrenching Tool Klappspaten Saperka - Pala + Pala da Trincea Pala para trincheras Outil de tranchée Polní lopatka @@ -20,7 +20,7 @@ Entrenching Tool Saperka, używana do budowy wnęk Mit dem Klappspaten können Erdwälle oder Gräben ausgehoben werden. - Pala + Pala da Trincea Pala para trincheras Outil de tranchée Polní lopatky se používají k zákopovým a jiným pracem. @@ -123,7 +123,7 @@ Confirm Dig Graben bestätigen Potwierdź kopanie - Conferma Scava + Conferma Scavo Confirmar cavado Confirmer la creusée Potvrdit kopání @@ -138,7 +138,7 @@ Cancel Dig Graben abbrechen Anuluj kopanie - Cancella Scava + Annulla Scavo Cancelar cavado Annuler la creusée Zrušit kopání @@ -190,7 +190,7 @@ 塹壕を掘りつづける Graben fortsetzen 계속해서 참호파기 - Continua a Scavare la Trincea + Continuando a Scavare la Trincea 继续盖掩体 繼續蓋掩體 @@ -204,7 +204,7 @@ 塹壕を消す Schützengraben entfernen 참호 제거 - Rimuove Trincea + Rimuovi Trincea 移除掩体 移除掩體 @@ -215,7 +215,7 @@ Retirement de la tranchée Убирание окопа Odstraňuji zákop - 塹壕を消している + 塹壕を消しています Entferne Schützengraben 참호 제거중... Rimuovendo la Trincea diff --git a/addons/tripod/CfgVehicles.hpp b/addons/tripod/CfgVehicles.hpp index b1d804e393..78d1f69fa7 100644 --- a/addons/tripod/CfgVehicles.hpp +++ b/addons/tripod/CfgVehicles.hpp @@ -49,12 +49,13 @@ class CfgVehicles { scope = 2; displayName = CSTRING(DisplayName); model = QPATHTOF(data\sniper_tripod.p3d); + icon = "\A3\Static_F_Gamma\data\UI\map_StaticTurret_AT_CA.paa"; class AnimationSources { class slide_down_tripod { source = "user"; animPeriod = 0.02; - initPhase = 0; + initPhase = 0.5; minValue = 0; maxValue = 1; }; @@ -65,15 +66,15 @@ class CfgVehicles { class ACE_Actions { class ACE_MainActions { - selection = ""; + selection = "interaction_point"; distance = 5; - condition = "true"; + condition = "(true)"; class ACE_Pickup { selection = ""; displayName = CSTRING(PickUp); distance = 5; - condition = "true"; + condition = "(true)"; statement = QUOTE([ARR_2(_player,_target)] call FUNC(pickup)); showDisabled = 0; exceptions[] = {}; @@ -85,7 +86,7 @@ class CfgVehicles { selection = ""; displayName = CSTRING(Adjust); distance = 5; - condition = "true"; + condition = "(true)"; //wait a frame to handle "Do When releasing action menu key" option: statement = QUOTE([ARR_2({_this call FUNC(adjust)}, [ARR_2(_player,_target)])] call CBA_fnc_execNextFrame); showDisabled = 0; @@ -95,5 +96,9 @@ class CfgVehicles { }; }; }; + + editorCategory = "EdCat_Supplies"; + editorSubcategory = QEGVAR(main,subcategory); + editorPreview = QPATHTOF(data\preview_tripod.jpg); }; }; diff --git a/addons/tripod/CfgWeapons.hpp b/addons/tripod/CfgWeapons.hpp index 3c5ca6d2b1..4e609f4f3d 100644 --- a/addons/tripod/CfgWeapons.hpp +++ b/addons/tripod/CfgWeapons.hpp @@ -1,16 +1,16 @@ class CfgWeapons { class ACE_ItemCore; - class InventoryItem_Base_F; + class CBA_MiscItem_ItemInfo; class ACE_Tripod: ACE_ItemCore { - author[] = {"Rocko", "Scubaman3D"}; + author = "Rocko, Scubaman3D"; scope = 2; displayName = CSTRING(DisplayName); descriptionShort = ""; model = QPATHTOF(data\w_sniper_tripod.p3d); picture = QPATHTOF(UI\w_sniper_tripod_ca.paa); - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 40; }; }; diff --git a/addons/tripod/XEH_postInit.sqf b/addons/tripod/XEH_postInit.sqf index 86fda03b48..9fbfaa6c8d 100644 --- a/addons/tripod/XEH_postInit.sqf +++ b/addons/tripod/XEH_postInit.sqf @@ -4,7 +4,7 @@ if (!hasInterface) exitWith {}; GVAR(adjustPFH) = -1; -GVAR(height) = 0; +GVAR(height) = 0.5; // Cancel adjustment if interact menu opens ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; diff --git a/addons/tripod/XEH_preInit.sqf b/addons/tripod/XEH_preInit.sqf index b47cf6628d..0b9469c746 100644 --- a/addons/tripod/XEH_preInit.sqf +++ b/addons/tripod/XEH_preInit.sqf @@ -6,4 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +["ACE_TripodObject", "killed", { + params ["_tripod"]; + [{deleteVehicle _this}, _tripod, 5] call CBA_fnc_waitAndExecute; +}] call CBA_fnc_addClassEventHandler; + ADDON = true; diff --git a/addons/tripod/data/model.cfg b/addons/tripod/data/model.cfg index ee81d26c8e..3770ac0f82 100644 --- a/addons/tripod/data/model.cfg +++ b/addons/tripod/data/model.cfg @@ -1,10 +1,10 @@ -class CfgSkeletons -{ +class CfgSkeletons { class Default { isDiscrete = 1; skeletonInherit = ""; skeletonBones[] = {}; }; + class ace_snipertripod_skeleton: Default { isDiscrete = 1; skeletonInherit = "Default"; @@ -13,21 +13,25 @@ class CfgSkeletons "leg_1","tripod", "leg_2","tripod", "leg_3","tripod", + "interaction_point","tripod", "leg_slide_1","leg_1", "leg_slide_2","leg_2", "leg_slide_3","leg_3" - }; + }; }; }; + class CfgModels { class Default { sectionsInherit = ""; sections[] = {}; skeletonName = ""; }; + class sniper_tripod: Default { skeletonName = "ace_snipertripod_skeleton"; sectionsInherit = "Default"; + class animations { class slide_down_tripod { type = "translation"; @@ -40,25 +44,25 @@ class CfgModels { maxValue = 1; sourceAddress = "clamp"; offset0 = 0; - offset1 = 0.855; + offset1 = 0.855; }; class retract_leg_1: slide_down_tripod { selection = "leg_slide_1"; begin = "slide_end_1"; end = "slide_start_1"; offset0 = 0; - offset1 = -0.95; + offset1 = -0.95; }; class retract_leg_2: retract_leg_1 { selection = "leg_slide_2"; begin = "slide_end_2"; - end = "slide_start_2"; + end = "slide_start_2"; }; class retract_leg_3: retract_leg_2 { selection = "leg_slide_3"; begin = "slide_end_3"; - end = "slide_start_3"; - }; + end = "slide_start_3"; + }; }; }; }; diff --git a/addons/tripod/data/preview_tripod.jpg b/addons/tripod/data/preview_tripod.jpg new file mode 100644 index 0000000000..e5c2298b85 Binary files /dev/null and b/addons/tripod/data/preview_tripod.jpg differ diff --git a/addons/tripod/data/sniper_tripod.p3d b/addons/tripod/data/sniper_tripod.p3d index 2cb6e43f2f..66931c6382 100644 Binary files a/addons/tripod/data/sniper_tripod.p3d and b/addons/tripod/data/sniper_tripod.p3d differ diff --git a/addons/tripod/functions/fnc_adjust.sqf b/addons/tripod/functions/fnc_adjust.sqf index b12f713ace..b81f9fa961 100644 --- a/addons/tripod/functions/fnc_adjust.sqf +++ b/addons/tripod/functions/fnc_adjust.sqf @@ -25,6 +25,7 @@ GVAR(adjustPFH) = [{ if (!(_unit getVariable [QGVAR(adjusting), false]) || {isNull _tripod} || {_unit distance _tripod > 5}) exitWith { call EFUNC(interaction,hideMouseHint); + [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); [_unit, "DefaultAction", _unit getVariable [QGVAR(Adjust), -1]] call EFUNC(common,removeActionEventHandler); @@ -37,6 +38,7 @@ GVAR(adjustPFH) = [{ }, 0, [_unit, _tripod]] call CBA_fnc_addPerFrameHandler; +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); // add mouse button action and hint [localize "STR_ACE_Tripod_Done", "", localize "STR_ACE_Tripod_ScrollAction"] call EFUNC(interaction,showMouseHint); diff --git a/addons/tripod/functions/fnc_handleUnconscious.sqf b/addons/tripod/functions/fnc_handleUnconscious.sqf index 0b43bd4b6b..01558d6389 100644 --- a/addons/tripod/functions/fnc_handleUnconscious.sqf +++ b/addons/tripod/functions/fnc_handleUnconscious.sqf @@ -17,6 +17,8 @@ params ["_unit"]; +if (!local _unit) exitWith {}; + if (_unit getVariable [QGVAR(adjusting), false]) then { _unit setVariable [QGVAR(adjusting), false, true]; }; diff --git a/addons/tripod/functions/fnc_place.sqf b/addons/tripod/functions/fnc_place.sqf index b4b6790ef6..0b63daeeec 100644 --- a/addons/tripod/functions/fnc_place.sqf +++ b/addons/tripod/functions/fnc_place.sqf @@ -27,21 +27,19 @@ if (stance _unit == "STAND") then { [{ params ["_unit"]; - private ["_direction", "_position", "_tripod"]; + private _direction = getDir _unit; + private _position = getPosASL _unit vectorAdd [0.8 * sin _direction, 0.8 * cos _direction, 0.02]; - _direction = getDir _unit; - _position = getPosASL _unit vectorAdd [0.8 * sin _direction, 0.8 * cos _direction, 0.02]; - - _tripod = "ACE_TripodObject" createVehicle [0, 0, 0]; + private _tripod = "ACE_TripodObject" createVehicle [0, 0, 0]; { - _tripod animate [_x, 1]; + _tripod animate [_x, 0.5]; } count ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; [{ (_this select 0) params ["_tripod", "_direction", "_position"]; - if (_tripod animationPhase "slide_down_tripod" == 1) then { + if (_tripod animationPhase "slide_down_tripod" == 0.5) then { _tripod setDir _direction; _tripod setPosASL _position; diff --git a/addons/tripod/script_component.hpp b/addons/tripod/script_component.hpp index 683cdf042d..ccd4119239 100644 --- a/addons/tripod/script_component.hpp +++ b/addons/tripod/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Tripod #include "\z\ace\addons\main\script_mod.hpp" -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE -// #define ENABLE_PERFORMANCE_COUNTERS +//#define DEBUG_MODE_FULL +//#define DISABLE_COMPILE_CACHE +//#define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_TRIPOD #define DEBUG_MODE_FULL diff --git a/addons/ui/CfgVehicles.hpp b/addons/ui/CfgVehicles.hpp index 563cf22ce1..4cafe37429 100644 --- a/addons/ui/CfgVehicles.hpp +++ b/addons/ui/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(ModuleName); function = QFUNC(moduleInit); - scope = 2; + scope = 1; isGlobal = 1; icon = QUOTE(PATHTOF(UI\Icon_Module_UI_ca.paa)); class Arguments { diff --git a/addons/ui/functions/fnc_moduleInit.sqf b/addons/ui/functions/fnc_moduleInit.sqf index 6a3e74aa67..a8328c653d 100644 --- a/addons/ui/functions/fnc_moduleInit.sqf +++ b/addons/ui/functions/fnc_moduleInit.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -if (!isServer) exitWith {}; - params ["_logic", "_units", "_activated"]; if (!_activated) exitWith {}; diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 6f3a3ecc2d..11013cf28b 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -34,13 +34,13 @@ Este módulo permite ligar ou desligar partes da interface do usuário Ce module permet le basculement de parties visibles de l'interface utlisateur Этот модуль позволяет переключать видимость элементов пользовательского интерфейса. - モジュールではユーザ インタフェイスの一部をトグル表示できます。 + モジュールではユーザ インタフェイスの一部表示を切り替えできます。 Moduł ten pozwala zmienić stan widoczności poszczególnych elementów UI. Dieses Modul erlaubt es, Teile der Benutzeroberfläche (UI) an- oder auszuschalten. 이 모듈은 사용자 인터페이스의 부분을 토글하는것을 가능케 해줍니다. Questo modulo consente di commutare parti di interfaccia utente visibili. - 此模块允许你调整使用者介面的任何一个元件. - 此模塊允許你調整使用者介面的任何一個元件. + 此模块允许你调整使用者介面的任何一个元件 + 此模塊允許你調整使用者介面的任何一個元件 Allow Selective UI @@ -48,7 +48,7 @@ Permitir IU Selecionável Permettre l'IU selective Включить настраиваемый интерфейс - 選択できるユーザ インタフェイスを有効化します + UI 選択性を許可 Zezwól na selektywne UI Erlaube selektives UI 선택적 사용자 인터페이스 허가 @@ -67,8 +67,8 @@ Erlaube Clients, ihr UI zu modifizieren. 클라이언트가 선택적 사용자 인터페이스 사용하는것을 허가합니다 Permette al client di modificare la propria UI. - 允许客户端自行调整使用者介面. - 允許客戶端自行調整使用者介面. + 允许客户端自行调整使用者介面 + 允許客戶端自行調整使用者介面 Soldier/Vehicle/Weapon Information @@ -471,7 +471,7 @@ Barra de Combustível do Veículo Barre d'éssence du véhicule Полоса топлива - 車両の給油計 + 車両の燃料計 Pasek paliwa Fahrzeug-Treibstoffleiste 차량 연료 막대 @@ -555,26 +555,26 @@ A modificação da interface do usuário está desabilitada. Modifications de l'interface utilisateur désactivé. Изменение пользовательского интерфейса запрещено. - 変更されたユーザ インタフェイスを無効化します。 + ユーザ インタフェイスの変更は無効化されています。 Modyfikacja interfejsu użytkownika jest wyłączona. Die Modifizierung des UI ist deaktiviert. 사용자 인터페이스 변경이 비활성화 되어있습니다. La modifica dell'Interfaccia Utente è disabilitata. - 自定使用者介面功能已关闭. - 自定使用者介面功能已關閉. + 自定使用者介面功能已关闭 + 自定使用者介面功能已關閉 Cannot modify a forced User Interface element. Não é possível modificar um elemento forçado da interface do usuário. Impossible de modifier un élément de l'interface utilisateur forcé. Невозможно изменить зафиксированный элемент пользовательского интерфейса. - ユーザー インタフェイス要素は変更できません。 + ユーザー インタフェイス要素の強制はできません。 Nie można modyfikować wymuszonego elementu interfejsu użytkownika. Gesperrte UI-Elemente können nicht modifiziert werden. 강제 사용자 인터페이스는 변경하실 수 없습니다. Impossibile modificare un elemento forzato d' Interfaccia Utente. - 无法编辑已被锁定的使用者介面元件. - 無法編輯已被鎖定的使用者介面元件. + 无法编辑已被锁定的使用者介面元件 + 無法編輯已被鎖定的使用者介面元件 diff --git a/addons/vector/functions/fnc_convertToTexturesDegree.sqf b/addons/vector/functions/fnc_convertToTexturesDegree.sqf index a7c81fe669..0a4fc349d3 100644 --- a/addons/vector/functions/fnc_convertToTexturesDegree.sqf +++ b/addons/vector/functions/fnc_convertToTexturesDegree.sqf @@ -34,8 +34,6 @@ if (GVAR(useMil)) then { _number = abs _number; if (_number isEqualTo 360) then {_number = 0}; - private ["_digit1", "_digit2", "_digit3", "_digit4"]; - private _digit1 = floor (_number / 100); private _digit2 = floor (_number / 10) - _digit1 * 10; private _digit3 = _number mod 10; diff --git a/addons/vector/functions/fnc_convertToTexturesDistance.sqf b/addons/vector/functions/fnc_convertToTexturesDistance.sqf index 5bad048022..0140e45a2e 100644 --- a/addons/vector/functions/fnc_convertToTexturesDistance.sqf +++ b/addons/vector/functions/fnc_convertToTexturesDistance.sqf @@ -13,28 +13,22 @@ * * Public: No */ - - #include "script_component.hpp" - -private ["_number", "_isNegative"]; - -_number = _this select 0; +params ["_number"]; _number = round _number; -_isNegative = _number < 0; +private _isNegative = _number < 0; _number = abs _number; if (_number >= 10000) exitWith { [QPATHTOF(rsc\vector_minus.paa), QPATHTOF(rsc\vector_minus.paa), QPATHTOF(rsc\vector_minus.paa), QPATHTOF(rsc\vector_minus.paa)] // return }; -private ["_digit1", "_digit2", "_digit3", "_digit4"]; -_digit1 = floor (_number / 1000); -_digit2 = floor (_number / 100) - _digit1 * 10; -_digit3 = floor (_number / 10) - _digit1 * 100 - _digit2 * 10; -_digit4 = _number mod 10; +private _digit1 = floor (_number / 1000); +private _digit2 = floor (_number / 100) - _digit1 * 10; +private _digit3 = floor (_number / 10) - _digit1 * 100 - _digit2 * 10; +private _digit4 = _number mod 10; if (_isNegative) then { diff --git a/addons/vector/functions/fnc_convertToTexturesFOS.sqf b/addons/vector/functions/fnc_convertToTexturesFOS.sqf index 3f5dd9a8da..58ce94547b 100644 --- a/addons/vector/functions/fnc_convertToTexturesFOS.sqf +++ b/addons/vector/functions/fnc_convertToTexturesFOS.sqf @@ -16,27 +16,21 @@ */ #include "script_component.hpp" - -private ["_number", "_coordinate", "_isNegative"]; - -_number = _this select 0; -_coordinate = _this select 1; +params ["_number", "_coordinate"]; _number = round (_number select _coordinate); -_isNegative = _number < 0; +private _isNegative = _number < 0; _number = abs _number; if (_number > 9999) exitWith { [QPATHTOF(rsc\vector_minus.paa), QPATHTOF(rsc\vector_minus.paa), QPATHTOF(rsc\vector_minus.paa), QPATHTOF(rsc\vector_minus.paa), QPATHTOF(rsc\vector_minus.paa)] // return }; -private ["_digit0", "_digit1", "_digit2", "_digit3", "_digit4"]; - -_digit0 = ""; -_digit1 = floor (_number / 1000); -_digit2 = floor (_number / 100) - _digit1 * 10; -_digit3 = floor (_number / 10) - _digit1 * 100 - _digit2 * 10; -_digit4 = _number mod 10; +private _digit0 = ""; +private _digit1 = floor (_number / 1000); +private _digit2 = floor (_number / 100) - _digit1 * 10; +private _digit3 = floor (_number / 10) - _digit1 * 100 - _digit2 * 10; +private _digit4 = _number mod 10; switch (_coordinate) do { case 0 : { diff --git a/addons/vector/functions/fnc_dataTransfer.sqf b/addons/vector/functions/fnc_dataTransfer.sqf index 06eab8803a..4a91a0636d 100644 --- a/addons/vector/functions/fnc_dataTransfer.sqf +++ b/addons/vector/functions/fnc_dataTransfer.sqf @@ -15,11 +15,9 @@ */ #include "script_component.hpp" -private ["_distance", "_direction", "_azimuth", "_inclination"]; - -_distance = call FUNC(getDistance); -_direction = call FUNC(getDirection); -_azimuth = _direction select 0; -_inclination = _direction select 1; +private _distance = call FUNC(getDistance); +private _direction = call FUNC(getDirection); +private _azimuth = _direction select 0; +private _inclination = _direction select 1; //Send Data to connected GPS [QGVAR(rangefinderData), [_distance, _azimuth, _inclination]] call CBA_fnc_localEvent; diff --git a/addons/vector/functions/fnc_getDistance.sqf b/addons/vector/functions/fnc_getDistance.sqf index d8e5d441df..7b62b5727b 100644 --- a/addons/vector/functions/fnc_getDistance.sqf +++ b/addons/vector/functions/fnc_getDistance.sqf @@ -19,12 +19,10 @@ #define MIN_DISTANCE 10 #define MAX_DISTANCE [6000, 9000] select GVAR(useFeet) -private ["_dlgVector", "_distance"]; - disableSerialization; -_dlgVector = GETUVAR(ACE_dlgVector,displayNull); +private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); -_distance = ctrlText (_dlgVector displayCtrl 151); +private _distance = ctrlText (_dlgVector displayCtrl 151); if (_distance == "----") exitWith {-1000}; diff --git a/addons/vector/functions/fnc_getFallOfShot.sqf b/addons/vector/functions/fnc_getFallOfShot.sqf index 5a0af98a77..db906ac660 100644 --- a/addons/vector/functions/fnc_getFallOfShot.sqf +++ b/addons/vector/functions/fnc_getFallOfShot.sqf @@ -16,23 +16,18 @@ #include "script_component.hpp" -private ["_distanceP1", "_directionP1", "_azimuthP1", "_inclinationP1", "_distanceP2", "_directionP2", "_azimuthP2", "_inclinationP2"]; +private _distanceP1 = GVAR(pData) select 0; +private _directionP1 = GVAR(pData) select 1; +private _azimuthP1 = _directionP1 select 0; +private _inclinationP1 = _directionP1 select 1; +private _distanceP2 = call FUNC(getDistance); +private _directionP2 = call FUNC(getDirection); +private _azimuthP2 = _directionP2 select 0; +private _inclinationP2 = _directionP2 select 1; -_distanceP1 = GVAR(pData) select 0; -_directionP1 = GVAR(pData) select 1; -_azimuthP1 = _directionP1 select 0; -_inclinationP1 = _directionP1 select 1; - -_distanceP2 = call FUNC(getDistance); -_directionP2 = call FUNC(getDirection); -_azimuthP2 = _directionP2 select 0; -_inclinationP2 = _directionP2 select 1; - -private ["_abscissa", "_ordinate", "_applicate"]; - -_abscissa = _distanceP1 * sin (_azimuthP1 - _azimuthP2); -_ordinate = _distanceP1 * cos (_inclinationP1 - _inclinationP2) - _distanceP2 * cos (_azimuthP1 - _azimuthP2); -_applicate = (sin _inclinationP2 * _distanceP2) - (sin _inclinationP1 * _distanceP1); +private _abscissa = _distanceP1 * sin (_azimuthP1 - _azimuthP2); +private _ordinate = _distanceP1 * cos (_inclinationP1 - _inclinationP2) - _distanceP2 * cos (_azimuthP1 - _azimuthP2); +private _applicate = (sin _inclinationP2 * _distanceP2) - (sin _inclinationP1 * _distanceP1); if (_distanceP1 < -999 || {_distanceP2 < -999}) exitWith { [-1000, -1000, -1000] // return diff --git a/addons/vector/functions/fnc_getHeightDistance.sqf b/addons/vector/functions/fnc_getHeightDistance.sqf index acae881928..003aefea51 100644 --- a/addons/vector/functions/fnc_getHeightDistance.sqf +++ b/addons/vector/functions/fnc_getHeightDistance.sqf @@ -16,13 +16,11 @@ #include "script_component.hpp" -private ["_distance", "_direction", "_azimuth", "_inclination"]; +private _distance = call FUNC(getDistance); +private _direction = call FUNC(getDirection); -_distance = call FUNC(getDistance); -_direction = call FUNC(getDirection); - -_azimuth = _direction select 0; -_inclination = _direction select 1; +private _azimuth = _direction select 0; +private _inclination = _direction select 1; if (_distance < -999) exitWith { [-1000, -1000] // return diff --git a/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf b/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf index a613e2e3ad..ce6716e4d3 100644 --- a/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf +++ b/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf @@ -16,28 +16,24 @@ #include "script_component.hpp" -private ["_distanceP1", "_directionP1", "_azimuthP1", "_inclinationP1", "_distanceP2", "_directionP2", "_azimuthP2", "_inclinationP2"]; +private _distanceP1 = GVAR(pData) select 0; +private _directionP1 = GVAR(pData) select 1; +private _azimuthP1 = _directionP1 select 0; +private _inclinationP1 = _directionP1 select 1; -_distanceP1 = GVAR(pData) select 0; -_directionP1 = GVAR(pData) select 1; -_azimuthP1 = _directionP1 select 0; -_inclinationP1 = _directionP1 select 1; +private _distanceP2 = call FUNC(getDistance); +private _directionP2 = call FUNC(getDirection); +private _azimuthP2 = _directionP2 select 0; +private _inclinationP2 = _directionP2 select 1; -_distanceP2 = call FUNC(getDistance); -_directionP2 = call FUNC(getDirection); -_azimuthP2 = _directionP2 select 0; -_inclinationP2 = _directionP2 select 1; +private _relDirection = sqrt ((_azimuthP1 - _azimuthP2) ^ 2 + (_inclinationP1 - _inclinationP2) ^ 2); +private _relDistance = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _relDirection); +private _relHeight = (sin _inclinationP1 * _distanceP1) - (sin _inclinationP2 * _distanceP2); +private _relLength = sqrt (_relDistance ^ 2 - _relHeight ^ 2); if (str(_relLength) == "-1.#IND") then {_relLength = 0}; -private ["_relDirection", "_relDistance", "_relHeight", "_relLength", "_lenghtP1", "_lenghtP2", "_relAzimuth"]; - -_relDirection = sqrt ((_azimuthP1 - _azimuthP2) ^ 2 + (_inclinationP1 - _inclinationP2) ^ 2); -_relDistance = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _relDirection); -_relHeight = (sin _inclinationP1 * _distanceP1) - (sin _inclinationP2 * _distanceP2); -_relLength = sqrt (_relDistance ^ 2 - _relHeight ^ 2); if (str(_relLength) == "-1.#IND") then {_relLength = 0}; - -_lenghtP1 = cos _inclinationP1 * _distanceP1; -_lenghtP2 = cos _inclinationP2 * _distanceP2; -_relAzimuth = (sin _azimuthP2 * _lenghtP2 - sin _azimuthP1 * _lenghtP1) atan2 (cos _azimuthP2 * _lenghtP2 - cos _azimuthP1 * _lenghtP1); +private _lenghtP1 = cos _inclinationP1 * _distanceP1; +private _lenghtP2 = cos _inclinationP2 * _distanceP2; +private _relAzimuth = (sin _azimuthP2 * _lenghtP2 - sin _azimuthP1 * _lenghtP1) atan2 (cos _azimuthP2 * _lenghtP2 - cos _azimuthP1 * _lenghtP1); if (_relAzimuth < 0) then {_relAzimuth = _relAzimuth + 360}; if (_distanceP1 < -999 || {_distanceP2 < -999}) exitWith { diff --git a/addons/vector/functions/fnc_getRelativeDistance.sqf b/addons/vector/functions/fnc_getRelativeDistance.sqf index 802a325848..f6815ea552 100644 --- a/addons/vector/functions/fnc_getRelativeDistance.sqf +++ b/addons/vector/functions/fnc_getRelativeDistance.sqf @@ -16,22 +16,19 @@ #include "script_component.hpp" -private ["_distanceP1", "_directionP1", "_azimuthP1", "_inclinationP1", "_distanceP2", "_directionP2", "_azimuthP2", "_inclinationP2"]; +private _distanceP1 = GVAR(pData) select 0; +private _directionP1 = GVAR(pData) select 1; +private _azimuthP1 = _directionP1 select 0; +private _inclinationP1 = _directionP1 select 1; -_distanceP1 = GVAR(pData) select 0; -_directionP1 = GVAR(pData) select 1; -_azimuthP1 = _directionP1 select 0; -_inclinationP1 = _directionP1 select 1; +private _distanceP2 = call FUNC(getDistance); +private _directionP2 = call FUNC(getDirection); +private _azimuthP2 = _directionP2 select 0; +private _inclinationP2 = _directionP2 select 1; -_distanceP2 = call FUNC(getDistance); -_directionP2 = call FUNC(getDirection); -_azimuthP2 = _directionP2 select 0; -_inclinationP2 = _directionP2 select 1; -private ["_relDirection", "_relDistance"]; - -_relDirection = sqrt ((_azimuthP1 - _azimuthP2) ^ 2 + (_inclinationP1 - _inclinationP2) ^ 2); -_relDistance = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _relDirection); +private _relDirection = sqrt ((_azimuthP1 - _azimuthP2) ^ 2 + (_inclinationP1 - _inclinationP2) ^ 2); +private _relDistance = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _relDirection); if (_distanceP1 < -999 || {_distanceP2 < -999}) exitWith { -1000 // return diff --git a/addons/vector/functions/fnc_getRelativeHeightLength.sqf b/addons/vector/functions/fnc_getRelativeHeightLength.sqf index 3471fce2ca..99cb828232 100644 --- a/addons/vector/functions/fnc_getRelativeHeightLength.sqf +++ b/addons/vector/functions/fnc_getRelativeHeightLength.sqf @@ -16,24 +16,19 @@ #include "script_component.hpp" -private ["_distanceP1", "_directionP1", "_azimuthP1", "_inclinationP1", "_distanceP2", "_directionP2", "_azimuthP2", "_inclinationP2"]; +private _distanceP1 = GVAR(pData) select 0; +private _directionP1 = GVAR(pData) select 1; +private _azimuthP1 = _directionP1 select 0; +private _inclinationP1 = _directionP1 select 1; +private _distanceP2 = call FUNC(getDistance); +private _directionP2 = call FUNC(getDirection); +private _azimuthP2 = _directionP2 select 0; +private _inclinationP2 = _directionP2 select 1; -_distanceP1 = GVAR(pData) select 0; -_directionP1 = GVAR(pData) select 1; -_azimuthP1 = _directionP1 select 0; -_inclinationP1 = _directionP1 select 1; - -_distanceP2 = call FUNC(getDistance); -_directionP2 = call FUNC(getDirection); -_azimuthP2 = _directionP2 select 0; -_inclinationP2 = _directionP2 select 1; - -private ["_azimuth", "_inclination", "_height", "_length"]; - -_azimuth = abs (_azimuthP1 - _azimuthP2); -_inclination = abs (_inclinationP1 - _inclinationP2); -_height = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _inclination); -_length = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _azimuth); +private _azimuth = abs (_azimuthP1 - _azimuthP2); +private _inclination = abs (_inclinationP1 - _inclinationP2); +private _height = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _inclination); +private _length = sqrt (_distanceP1 ^ 2 + _distanceP2 ^ 2 - 2 * _distanceP1 * _distanceP2 * cos _azimuth); if (_inclination < 0) then {_height = -1 * _height}; diff --git a/addons/vehiclelock/ACE_Settings.hpp b/addons/vehiclelock/ACE_Settings.hpp index f8a431410f..75073f4f8f 100644 --- a/addons/vehiclelock/ACE_Settings.hpp +++ b/addons/vehiclelock/ACE_Settings.hpp @@ -1,20 +1,25 @@ class ACE_Settings { class GVAR(defaultLockpickStrength) { + category = CSTRING(DisplayName); displayName = CSTRING(DefaultLockpickStrength_DisplayName); description = CSTRING(DefaultLockpickStrength_Description); value = 10; typeName = "SCALAR"; + sliderSettings[] = {-1, 60, 5, 1}; }; class GVAR(lockVehicleInventory) { + category = CSTRING(DisplayName); displayName = CSTRING(LockVehicleInventory_DisplayName); description = CSTRING(LockVehicleInventory_Description); value = 0; typeName = "BOOL"; }; class GVAR(vehicleStartingLockState) { + category = CSTRING(DisplayName); displayName = CSTRING(VehicleStartingLockState_DisplayName); description = CSTRING(VehicleStartingLockState_Description); value = -1; typeName = "SCALAR"; + sliderSettings[] = {-1, 2, -1, -1}; // ToDo: Make this a list? }; }; diff --git a/addons/vehiclelock/CfgVehicles.hpp b/addons/vehiclelock/CfgVehicles.hpp index fdf51fb106..8b38716c5c 100644 --- a/addons/vehiclelock/CfgVehicles.hpp +++ b/addons/vehiclelock/CfgVehicles.hpp @@ -28,6 +28,7 @@ distance = 4; \ condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(2,3)]}); \ statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)), [ARR_2(_target,false)], [_target])] call CBA_fnc_targetEvent); \ + exceptions[] = {"isNotSwimming"}; \ priority = 0.3; \ icon = QPATHTOF(ui\key_menuIcon_ca.paa); \ }; \ @@ -36,6 +37,7 @@ distance = 4; \ condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(0,1)]}); \ statement = QUOTE([ARR_3(QUOTE(QGVAR(setVehicleLock)), [ARR_2(_target,true)], [_target])] call CBA_fnc_targetEvent); \ + exceptions[] = {"isNotSwimming"}; \ priority = 0.2; \ icon = QPATHTOF(ui\key_menuIcon_ca.paa); \ }; \ @@ -44,6 +46,7 @@ distance = 4; \ condition = QUOTE([ARR_3(_player, _target, 'canLockpick')] call FUNC(lockpick)); \ statement = QUOTE([ARR_3(_player, _target, 'startLockpick')] call FUNC(lockpick)); \ + exceptions[] = {"isNotSwimming"}; \ priority = 0.1; \ }; \ }; \ @@ -61,6 +64,13 @@ class CfgVehicles { class Helicopter: Air { MACRO_LOCK_ACTIONS }; + class Motorcycle: LandVehicle { + MACRO_LOCK_ACTIONS + }; + class Ship; + class Ship_F: Ship { + MACRO_LOCK_ACTIONS + }; class Logic; class Module_F: Logic { @@ -72,8 +82,8 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(Module_DisplayName); function = QFUNC(moduleInit); - scope = 2; - isGlobal = 0; + scope = 1; + isGlobal = 1; isSingular = 1; icon = QPATHTOF(ui\Icon_Module_VehicleLock_ca.paa); functionPriority = 0; diff --git a/addons/vehiclelock/CfgWeapons.hpp b/addons/vehiclelock/CfgWeapons.hpp index 1d72a5538d..8c7f7b137a 100644 --- a/addons/vehiclelock/CfgWeapons.hpp +++ b/addons/vehiclelock/CfgWeapons.hpp @@ -1,6 +1,6 @@ class CfgWeapons { - class InventoryItem_Base_F; class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; class ACE_key_master: ACE_ItemCore { scopeArsenal = 0; @@ -10,7 +10,7 @@ class CfgWeapons { model = "\A3\weapons_F\ammo\mag_univ.p3d"; picture = QPATHTOF(ui\keyBlack.paa); scope = 2; - class ItemInfo: InventoryItem_Base_F { + class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0; }; }; diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index b45bf150f3..c7408bf5f5 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -18,8 +18,6 @@ */ #include "script_component.hpp" -private ["_previousMags","_newMags","_keyMagazine","_keyName"]; - if (!params [["_unit", objNull, [objNull]], ["_veh", objNull, [objNull]], ["_useCustom", false, [false]]]) exitWith { ERROR("Input wrong type"); }; @@ -29,15 +27,15 @@ if (isNull _unit) exitWith {ERROR("null unit");}; if (isNull _veh) exitWith {ERROR("null vehicle");}; if (_useCustom) then { - _previousMags = magazinesDetail _unit; + private _previousMags = magazinesDetail _unit; _unit addMagazine ["ACE_key_customKeyMagazine", 1]; //addMagazine array has global effects - _newMags = (magazinesDetail _unit) - _previousMags; + private _newMags = (magazinesDetail _unit) - _previousMags; if ((count _newMags) == 0) exitWith {ERROR("failed to add magazine (inventory full?)");}; - _keyMagazine = _newMags select 0; + private _keyMagazine = _newMags select 0; TRACE_2("setting up key on server",_veh,_keyMagazine); //Have the server run add the key to the vehicle's key array: [QGVAR(setupCustomKey), [_veh, _keyMagazine]] call CBA_fnc_serverEvent; } else { - _keyName = [_veh] call FUNC(getVehicleSideKey); + private _keyName = [_veh] call FUNC(getVehicleSideKey); _unit addItem _keyName; //addItem has global effects }; diff --git a/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf b/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf index eda75922c4..6642b12f8d 100644 --- a/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf +++ b/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf @@ -15,17 +15,15 @@ */ #include "script_component.hpp" -private ["_vehConfigSide","_vehSide","_returnValue"]; - params ["_veh"]; TRACE_1("params",_veh); if (isNull _veh) exitWith {ERROR("null vehicle"); "error"}; -_vehConfigSide = [_veh, true] call BIS_fnc_objectSide; -_vehSide = _veh getVariable [QGVAR(lockSide), _vehConfigSide]; +private _vehConfigSide = [_veh, true] call BIS_fnc_objectSide; +private _vehSide = _veh getVariable [QGVAR(lockSide), _vehConfigSide]; -_returnValue = ""; +private _returnValue = ""; switch (_vehSide) do { case (west): {_returnValue = "ACE_key_west"}; diff --git a/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf b/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf index b0835a6272..652cecadb8 100644 --- a/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf +++ b/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf @@ -25,13 +25,11 @@ TRACE_1("params",_vehicle); //If the module wasn't placed, just exit (needs to be in wait because objectInitEH is before moduleInit) if (GVAR(VehicleStartingLockState) == -1) exitWith {}; - private ["_lock"]; - params ["_vehicle"]; if ((_vehicle isKindOf "Car") || {_vehicle isKindOf "Tank"} || {_vehicle isKindOf "Helicopter"}) then { //set lock state (eliminates the ambigious 1-"Default" and 3-"Locked for Player" states) - _lock = switch (GVAR(VehicleStartingLockState)) do { + private _lock = switch (GVAR(VehicleStartingLockState)) do { case (0): { (locked _vehicle) in [2, 3] }; case (1): { true }; case (2): { false }; diff --git a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf index 390104cefc..bc566794fe 100644 --- a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf @@ -16,25 +16,23 @@ */ #include "script_component.hpp" -private ["_returnValue","_sideKeyName","_customKeys"]; - params ["_unit", "_veh"]; TRACE_2("params",_unit,_veh); if (isNull _unit) exitWith {ERROR("null unit"); false}; if (isNull _veh) exitWith {ERROR("null vehicle"); false}; -_returnValue = false; +private _returnValue = false; //Master can open anything "no matter what" if ("ACE_key_master" in (items _unit)) then {_returnValue = true}; //Check side key -_sideKeyName = [_veh] call FUNC(getVehicleSideKey); +private _sideKeyName = [_veh] call FUNC(getVehicleSideKey); if (_sideKeyName in (items _unit)) then {_returnValue = true}; //Check custom keys -_customKeys = _veh getVariable [QGVAR(customKeys), []]; +private _customKeys = _veh getVariable [QGVAR(customKeys), []]; { if (_x in (magazinesDetail _unit)) then {_returnValue = true;}; } forEach _customKeys; diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index 2ce856dd37..a08289454a 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -20,8 +20,6 @@ */ #include "script_component.hpp" -private ["_vehLockpickStrenth","_condition","_returnValue"]; - params ["_unit", "_veh", "_funcType"]; TRACE_3("params",_unit,_veh,_funcType); @@ -34,14 +32,14 @@ if ((locked _veh) == 0) exitWith {false}; //need lockpick item if (!("ACE_key_lockpick" in (items _unit))) exitWith {false}; -_vehLockpickStrenth = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; +private _vehLockpickStrenth = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; if (!(_vehLockpickStrenth isEqualType 0)) exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false}; //-1 indicates unpickable lock if (_vehLockpickStrenth < 0) exitWith {false}; //Condition check for progressBar -_condition = { +private _condition = { params ["_args"]; _args params ["_unit", "_veh"]; ((_unit distance _veh) < 5) && {(speed _veh) < 0.1} @@ -49,13 +47,13 @@ _condition = { if (!([[_unit, _veh]] call _condition)) exitWith {false}; -_returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"]; +private _returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"]; switch (_funcType) do { case "canLockpick": { _returnValue = !([_unit, _veh] call FUNC(hasKeyForVehicle)) && {(locked _veh) in [2, 3]}; }; case "startLockpick": { - [_vehLockpickStrenth, [_unit, _veh, "finishLockpick"], {(_this select 0) call FUNC(lockpick)}, {}, (localize LSTRING(Action_LockpickInUse)), _condition, ["isNotInside"]] call EFUNC(common,progressBar); + [_vehLockpickStrenth, [_unit, _veh, "finishLockpick"], {(_this select 0) call FUNC(lockpick)}, {}, (localize LSTRING(Action_LockpickInUse)), _condition, ["isNotInside", "isNotSwimming"]] call EFUNC(common,progressBar); }; case "finishLockpick": { [QGVAR(setVehicleLock), [_veh, false], [_veh]] call CBA_fnc_targetEvent; diff --git a/addons/vehiclelock/functions/fnc_moduleInit.sqf b/addons/vehiclelock/functions/fnc_moduleInit.sqf index b6c3f38426..cf9d1eb79c 100644 --- a/addons/vehiclelock/functions/fnc_moduleInit.sqf +++ b/addons/vehiclelock/functions/fnc_moduleInit.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -if (!isServer) exitWith {}; - params ["_logic", "_syncedUnits", "_activated"]; TRACE_3("params",_logic,_syncedUnits,_activated); diff --git a/addons/vehiclelock/functions/fnc_moduleSync.sqf b/addons/vehiclelock/functions/fnc_moduleSync.sqf index 82477f881c..569f4a0691 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -25,11 +25,9 @@ TRACE_3("params",_logic,_syncedObjects,_activated); if !(_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; [{ - private ["_listOfVehicles"]; - params ["_syncedObjects"]; - _listOfVehicles = []; + private _listOfVehicles = []; { if ((_x isKindOf "Car") || (_x isKindOf "Tank") || (_x isKindOf "Helicopter")) then { _listOfVehicles pushBack _x; diff --git a/addons/vehiclelock/stringtable.xml b/addons/vehiclelock/stringtable.xml index 7b39b616de..b6edabfc7a 100644 --- a/addons/vehiclelock/stringtable.xml +++ b/addons/vehiclelock/stringtable.xml @@ -1,6 +1,15 @@ - + + + Vehicle Lock + Blocco Veicolo + 載具上鎖 + 载具上锁 + 車両の施錠 + 차량 잠금 + Fahrzeugsperre + Unlock Vehicle Fahrzeug aufschließen @@ -10,7 +19,7 @@ Odemknout vozidlo Jármű nyitása Открыть машину - Sblocca il veicolo + Sblocca il Veicolo Destravar veículo 車両の鍵を開ける 차량 잠금열기 @@ -26,7 +35,7 @@ Zamknout vozidlo Jármű zárása Закрыть машину - Chiudi il veicolo a chiave + Chiudi il Veicolo a chiave Travar Veículo 車両を施錠 차량 잠그기 @@ -78,8 +87,8 @@ Uma chave específica que abre um veículo específico. カスタム キーは特定車両を開けられます。 특정 차량을 여는 특수 열쇠 - 使用指定的钥匙来开启特定的载具. - 使用指定的鑰匙來開啟特定的載具. + 使用指定的钥匙来开启特定的载具 + 使用指定的鑰匙來開啟特定的載具 A Master Key will open any lock, no matter what! @@ -94,8 +103,8 @@ Uma chave mestre irá abrir qualquer fechadura, não importa qual! マスター キーは全ての鍵を開けられます。 어떤 차량도 열 수 있는 마스터키 입니다! - 万用解锁钥匙, 能解锁任何载具. - 萬用解鎖鑰匙, 能解鎖任何載具. + 万用解锁钥匙,能解锁任何载具 + 萬用解鎖鑰匙,能解鎖任何載具 A lockpick set that can pick the locks of most vehicles. @@ -110,8 +119,8 @@ Um set de chave mixas que pode abrir a maioria dos veículos. ピッキング ツールでは多くの車両をこじ開けられます。 거의 모든 차량을 열 수 있게 해주는 해정도구 모음입니다. - 一组解锁钥匙 (可解锁大部份载具). - 一組解鎖鑰匙 (可解鎖大部份載具). + 一组解锁钥匙 (可解锁大部份载具) + 一組解鎖鑰匙 (可解鎖大部份載具) A key that should open most WEST vehicles. @@ -124,10 +133,10 @@ Ключ для открытия большинства машин Красных. Una chiave che apre la maggior parte dei veicoli occidentali Uma chave que abre a maioria dos veículos ocidentais - このキーは多くの WEST 車両を開けられます。 + このキーは多くの同盟軍車両を開けられます。 거의 모든 서방진영 차량을 여는 열쇠입니다. - 一组解锁钥匙 (可解锁大部份蓝方载具). - 一組解鎖鑰匙 (可解鎖大部份藍方載具). + 一组解锁钥匙 (可解锁大部份蓝方载具) + 一組解鎖鑰匙 (可解鎖大部份藍方載具) A key that should open most EAST vehicle. @@ -140,10 +149,10 @@ Ключ для открытия большинства машин Синих. Una chaive che apre la maggior parte dei veicoli orientali Uma chave que abre a maioria dos veículos orientais - このキーは多くの EAST 車両を開けられます。 + このキーは多くのOPFOR軍車両を開けられます。 거의 모든 동방진영 차량을 여는 열쇠입니다. - 一组解锁钥匙 (可解锁大部份红方载具). - 一組解鎖鑰匙 (可解鎖大部份紅方載具). + 一组解锁钥匙 (可解锁大部份红方载具) + 一組解鎖鑰匙 (可解鎖大部份紅方載具) A key that should open most INDEP vehicle. @@ -156,10 +165,10 @@ Ключ для открытия большинства машин Независимых. Una chaive che apre la maggior parte dei veicoli degli indipendenti Uma chave que abre a maioria dos veículos independentes - このキーは多くの INDEP 車両を開けられます。 + このキーは多くの独立軍車両を開けられます。 거의 모든 중립진영 차량을 여는 열쇠입니다. - 一组解锁钥匙 (可解锁大部份独立方载具). - 一組解鎖鑰匙 (可解鎖大部份獨立方載具). + 一组解锁钥匙 (可解锁大部份独立方载具) + 一組解鎖鑰匙 (可解鎖大部份獨立方載具) A key that should open most CIV vehicle. @@ -172,10 +181,10 @@ Ключ для открытия большинства машин Гражданских. Una chaive che apr ela maggior parte dei veicoli civili Uma chave que abre a maioria dos veículos civis. - このキーは多くの CIV 車両を開けられます。 + このキーは多くの市民車両を開けられます。 거의 모든 민간인 차량을 여는 열쇠입니다 - 一组解锁钥匙 (可解锁大部份平民载具). - 一組解鎖鑰匙 (可解鎖大部份平民載具). + 一组解锁钥匙 (可解锁大部份平民载具) + 一組解鎖鑰匙 (可解鎖大部份平民載具) Vehicle Lock Setup @@ -188,7 +197,7 @@ Jármű-zár beállítás Запирание транспорта Impostazioni Blocco Veicolo - 車両の施錠の設定 + 車両の施錠設定 차량 잠금 설정 载具上锁设置 載具上鎖設置 @@ -220,10 +229,10 @@ Bezárja a zárt járművek rakterét is Закрывать инвентарь транспорта, если транспорт закрыт Blocca l'inventario di un veicolo bloccato - 施錠されている車両の、開けないインベントリ + 施錠されている車両の開けないインベントリ 잠긴 차량의 소지품을 뒤지지못하게 합니다. - 上锁载具的车箱, 使玩家不能拿取/查看载具内的装备 - 上鎖載具的車箱, 使玩家不能拿取/查看載具內的裝備 + 上锁载具的车箱,使玩家不能拿取/查看载具内的装备 + 上鎖載具的車箱,使玩家不能拿取/查看載具內的裝備 Vehicle Starting Lock State @@ -252,7 +261,7 @@ Beállítja a zár-állapotot az összes járműhöz (eltávolítja az azonosíthatatlan zárállapotokat) Устанавливает начальное состояние замков всех транспортных средств (устраняет неоднозначные состояния) Imposta lo stato di blocco per tutti i veicoli (rimuove stati di blocco ambigui) - 全車両への鍵の状態を設定します。(あいまいな鍵の状態を削除) + 全車両へ鍵の状態を設定します。(あいまいな鍵の状態を削除) 모든 차량의 잠금 상태를 정합니다. (애매한 잠금 상태는 모두 없앱니다.) 设定所有载具的初始上锁状态 (移除不明确的锁定状态) 設定所有載具的初始上鎖狀態 (移除不明確的鎖定狀態) @@ -316,7 +325,7 @@ Alapértelmezett zártörő-erősség Сила отмычки по-умолчанию Durabilità Default del Grimaldello - ピッキング ツールの標準の有効度 + ピッキング ツールの能力設定 기본 해정도구 설정 预设开锁能力 預設開鎖能力 @@ -332,10 +341,10 @@ Alapértelmezett idő a zárfeltöréshez (másodpercben). Alapértelmezett: 10 Время для взлома замка отмычкой (в секундах). По-умолчанию: 10 Tempo Default richiesto per forzare serrature (in secondi). Default: 10 - ピッキング ツールに標準の時間を設定。(秒) 標準:10 + ピッキング ツールを使った作業時間の標準設定。(秒) 標準: 10 해정을 위해 들이는 기본시간입니다(초 단위). 기본설정: 10 - 开锁时间(秒). 预设:10 - 開鎖時間(秒). 預設:10 + 开锁时间(秒)。预设:10 + 開鎖時間(秒)。預設:10 Settings for lockpick strength and initial vehicle lock state. Removes ambiguous lock states. @@ -348,10 +357,10 @@ Beállítások a zártörő erősségére és alapértelmezett zár-állapotra a járműveken. Eltávolítja az azonosíthatatlan zár-állapotokat. Настройки силы отмычек и начальное состояние замков транспорта. Устраняет неоднозначные состояния замков. Impostazioni per resistenza iniziale delle serrature e stato di blocco dei veicoli. Rimuove stati di blocco ambigui. - ピッキング ツールの強さと車両の鍵の初期状態を設定できます。あいまいな鍵の状態を削除します。 + ピッキング ツールの能力と車両の鍵の初期状態を設定できます。あいまいな鍵の状態を削除します。 해정도구 설정과 시작시 차량의 잠금 상태 그리고 애매한 잠금 상태를 지우는 설정입니다. - 设定开锁能力和初始载具上锁状态. 移除不明确的锁定状态. - 設定開鎖能力和初始載具上鎖狀態. 移除不明確的鎖定狀態. + 设定开锁能力和初始载具上锁状态。移除不明确的锁定状态 + 設定開鎖能力和初始載具上鎖狀態。移除不明確的鎖定狀態 Vehicle Key Assign @@ -382,8 +391,8 @@ Sincronizza con veicoli e giocatori. Distribuirà chiavi ai giocatori per ogni veicolo sincronizzato. Valido solo per oggetti presenti ad inizio missione. 車両とプレイヤへ同期します。プレイヤへ同期された車両のカスタム キーを作ります。これはミッション開始時に作成されたオブジェクトでのみ有効です。 차량과 플레이어에게 동기화됩니다. 동기화된 차량은 플레이어에게 열쇠를 지급합니다. 오직 미션 시작시에 생긴 물체들만 유효합니다. - 可同步在载具与玩家身上. 将使被同步的玩家掌握其他被同步载具的钥匙. 此模块只会在任务刚开始时触发. - 可同步在載具與玩家身上. 將使被同步的玩家掌握其他被同步載具的鑰匙. 此模塊只會在任務剛開始時觸發. + 可同步在载具与玩家身上。将使被同步的玩家掌握其他被同步载具的钥匙。此模块只会在任务刚开始时触发。 + 可同步在載具與玩家身上。將使被同步的玩家掌握其他被同步載具的鑰匙。此模塊只會在任務剛開始時觸發。 diff --git a/addons/vehicles/CfgAmmo.hpp b/addons/vehicles/CfgAmmo.hpp index 96dd290625..8706a56570 100644 --- a/addons/vehicles/CfgAmmo.hpp +++ b/addons/vehicles/CfgAmmo.hpp @@ -1,25 +1,7 @@ class CfgAmmo { - - class Missile_AGM_02_F; - class M_Mo_120mm_AT: Missile_AGM_02_F { - cost = 400000; // Stop it from aiming at FUCKING RABBITS. - weaponLockSystem = 2; - }; - - class M_Mo_120mm_AT_LG: M_Mo_120mm_AT { - cost = 400000; - weaponLockSystem = 4; - }; - class MissileBase; class M_Mo_82mm_AT: MissileBase { - cost = 400000; - weaponLockSystem = 2; - }; - - class M_Mo_82mm_AT_LG: M_Mo_82mm_AT { - cost = 400000; - weaponLockSystem = 4; + cost = 400000; // Stop it from aiming at FUCKING RABBITS. }; }; diff --git a/addons/vehicles/CfgWeapons.hpp b/addons/vehicles/CfgWeapons.hpp index 78a82abccf..530a6913c7 100644 --- a/addons/vehicles/CfgWeapons.hpp +++ b/addons/vehicles/CfgWeapons.hpp @@ -46,24 +46,6 @@ class CfgWeapons { class far: close {}; }; - class autocannon_Base_F; - class autocannon_30mm_CTWS: autocannon_Base_F { - class AP: autocannon_Base_F { - magazines[] = {"60Rnd_30mm_APFSDS_shells","60Rnd_30mm_APFSDS_shells_Tracer_Red","60Rnd_30mm_APFSDS_shells_Tracer_Green","60Rnd_30mm_APFSDS_shells_Tracer_Yellow","140Rnd_30mm_MP_shells","140Rnd_30mm_MP_shells_Tracer_Red","140Rnd_30mm_MP_shells_Tracer_Green","140Rnd_30mm_MP_shells_Tracer_Yellow"}; - magazineReloadTime = 0; - }; - - muzzles[] = {"AP"}; - }; - class autocannon_40mm_CTWS: autocannon_Base_F { - class AP: autocannon_Base_F { - magazines[] = {"40Rnd_40mm_APFSDS_shells","40Rnd_40mm_APFSDS_Tracer_Red_shells","40Rnd_40mm_APFSDS_Tracer_Green_shells","40Rnd_40mm_APFSDS_Tracer_Yellow_shells","60Rnd_40mm_GPR_shells","60Rnd_40mm_GPR_Tracer_Red_shells","60Rnd_40mm_GPR_Tracer_Green_shells","60Rnd_40mm_GPR_Tracer_Yellow_shells"}; - magazineReloadTime = 0; - }; - - muzzles[] = {"AP"}; - }; - // make static weapons compatible with 100rnd mag variants class HMG_static: HMG_01 { magazines[] = {"500Rnd_127x99_mag","500Rnd_127x99_mag_Tracer_Red","500Rnd_127x99_mag_Tracer_Green","500Rnd_127x99_mag_Tracer_Yellow","200Rnd_127x99_mag","200Rnd_127x99_mag_Tracer_Red","200Rnd_127x99_mag_Tracer_Green","200Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Yellow"}; diff --git a/addons/vehicles/XEH_postInit.sqf b/addons/vehicles/XEH_postInit.sqf index c55fcf2544..2e54b2ea84 100644 --- a/addons/vehicles/XEH_postInit.sqf +++ b/addons/vehicles/XEH_postInit.sqf @@ -15,7 +15,7 @@ GVAR(isSpeedLimiter) = false; true } else { // Conditions: canInteract - if !([ACE_player, objNull, ["isnotinside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if !(ACE_player == driver vehicle ACE_player && {vehicle ACE_player isKindOf 'Car' || diff --git a/addons/viewdistance/ACE_Settings.hpp b/addons/viewdistance/ACE_Settings.hpp index 356c7d86f2..63c2a5d19a 100644 --- a/addons/viewdistance/ACE_Settings.hpp +++ b/addons/viewdistance/ACE_Settings.hpp @@ -39,6 +39,7 @@ class ACE_Settings { value = 10000; // Value, NOT index. 10000 is the maximum in A3 displayName = CSTRING(limit_DisplayName); description = CSTRING(limit_setting); + sliderSettings[] = {500, 12000, 10000, 0}; }; class GVAR(objectViewDistanceCoeff) { category = CSTRING(Module_DisplayName); diff --git a/addons/viewdistance/CfgVehicles.hpp b/addons/viewdistance/CfgVehicles.hpp index 4c6639370c..db82b7bd92 100644 --- a/addons/viewdistance/CfgVehicles.hpp +++ b/addons/viewdistance/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { category = "ACE"; function = QUOTE(DFUNC(initModule)); displayName = CSTRING(Module_DisplayName); - scope = 2; + scope = 1; isGlobal = 1; isSingular = 1; //icon = ""; // needs an icon diff --git a/addons/viewdistance/XEH_clientInit.sqf b/addons/viewdistance/XEH_clientInit.sqf index 1fed0bd818..eb609a40f9 100644 --- a/addons/viewdistance/XEH_clientInit.sqf +++ b/addons/viewdistance/XEH_clientInit.sqf @@ -26,4 +26,8 @@ if (!hasInterface) exitWith {}; ["vehicle",{ [false] call FUNC(adaptViewDistance); }] call CBA_fnc_addPlayerEventHandler; + ["ACE_controlledUAV", { + [false] call FUNC(adaptViewDistance); + }] call CBA_fnc_addEventHandler; + }] call CBA_fnc_addEventHandler; diff --git a/addons/viewdistance/functions/fnc_adaptViewDistance.sqf b/addons/viewdistance/functions/fnc_adaptViewDistance.sqf index 4816ee946e..0277b96244 100644 --- a/addons/viewdistance/functions/fnc_adaptViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_adaptViewDistance.sqf @@ -22,6 +22,12 @@ if (!GVAR(enabled) || isNull ACE_player) exitWith {}; private _vehicle = vehicle ACE_player; +ACE_controlledUAV params ["_uav"]; +if (!isNull _uav) then { + TRACE_1("using UAV",ACE_controlledUAV); + _vehicle = _uav; +}; + private _landVehicle = _vehicle isKindOf "LandVehicle" || {_vehicle isKindOf "Ship_F"}; private _airVehicle = _vehicle isKindOf "Air"; diff --git a/addons/viewdistance/functions/fnc_initModule.sqf b/addons/viewdistance/functions/fnc_initModule.sqf index 3afd3ccd6a..ad6b3852b4 100644 --- a/addons/viewdistance/functions/fnc_initModule.sqf +++ b/addons/viewdistance/functions/fnc_initModule.sqf @@ -18,8 +18,6 @@ #include "script_component.hpp" -if (!isServer) exitWith {}; - params ["_logic", "_units", "_activated"]; if (!_activated) exitWith { diff --git a/addons/viewdistance/stringtable.xml b/addons/viewdistance/stringtable.xml index 9985707422..7ea9bb1cce 100644 --- a/addons/viewdistance/stringtable.xml +++ b/addons/viewdistance/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -30,8 +30,8 @@ Consente di limitare la distanza visiva massima che può essere impostata dai giocatori. プレイヤーへ最大の視界距離を制限できます。 플레이어가 볼 수 있는 최대 시야를 제한합니다. - 允许玩家最大的可视距离. - 允許玩家最大的可視距離. + 允许玩家最大的可视距离 + 允許玩家最大的可視距離 Enable ACE viewdistance @@ -110,8 +110,8 @@ Limite per la distanza visiva del client impostato qui e può essere scavalcato dal modulo クライアントへの視界距離の設定や、それをモジュールにより上書きできます 클라이언트의 시야를 이 모듈로 치환할 수 있습니다. - 玩家的视距限制可在此设定, 也可透过模块改写 - 玩家的視距限制可在此設定, 也可透過模塊改寫 + 玩家的视距限制可在此设定,也可透过模块改写 + 玩家的視距限制可在此設定,也可透過模塊改寫 Client View Distance (On Foot) @@ -174,8 +174,8 @@ Cambia la distanza visiva in gioco quando il giocatore è in un veicolo terrestre. プレイヤーが車両の時の視界距離を変更します。 플레이어가 차량 내부일 경우의 시야를 바꿀 수 있습니다. - 改变玩家于地面载具内时的视野距离. - 改變玩家於地面載具內時的視野距離. + 改变玩家于地面载具内时的视野距离 + 改變玩家於地面載具內時的視野距離 Client View Distance (Air Vehicle) @@ -206,8 +206,8 @@ Cambia la distanza visiva in gioco quando il giocatore è in un mezzo aereo. プレイヤーが航空機に乗っている時の視界距離を変更します。 플레이어가 항공기 내부일 경우의 시야를 바꿀 수 있습니다. - 改变玩家于空中载具内时的视野距离. - 改變玩家於空中載具內時的視野距離. + 改变玩家于空中载具内时的视野距离 + 改變玩家於空中載具內時的視野距離 Dynamic Object View Distance @@ -238,8 +238,8 @@ Imposta la distanza visiva degli oggetti come un coefficiente basato sulla distanza visiva oppure basato sul campo visivo. 視野角を元にするか、視界距離によるオブジェクト描画距離を決定します。視野角を元にするオプションを有効化した場合、視野角により最低と最高値が変動します。 설정된 시야 혹은 시계(FoV)에 계수를 적용해 물체 시야를 적용합니다. 시계를 바탕으로 하는 옵션을 활성화할 경우 시계에 의한 최저와 최고치가 변동됩니다. - 设定物件可被观察的距离, 透过视野距离或是视野角度来决定. - 設定物件可被觀察的距離, 透過視野距離或是視野角度來決定. + 设定物件可被观察的距离,透过视野距离或是视野角度来决定。 + 設定物件可被觀察的距離,透過視野距離或是視野角度來決定。 Off diff --git a/addons/weaponselect/XEH_postInit.sqf b/addons/weaponselect/XEH_postInit.sqf index b19059cff1..4706363271 100644 --- a/addons/weaponselect/XEH_postInit.sqf +++ b/addons/weaponselect/XEH_postInit.sqf @@ -196,6 +196,18 @@ if (!hasInterface) exitWith {}; {false}, [10, [false, false, false]], false] call CBA_fnc_addKeybind; //9 Key +["ACE3 Vehicles", QGVAR(CollisionLights), localize LSTRING(CollisionLights), { + // Conditions: canInteract + if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + // Conditions: specific + if ((ACE_player isEqualTo (vehicle ACE_player)) || {ACE_player != (driver (vehicle ACE_player))}) exitWith {false}; + + // Statement + (vehicle ACE_player) setCollisionLight !(isCollisionLightOn (vehicle ACE_player)); + true +}, +{false}, +[0, [false, false, false]]] call CBA_fnc_addKeybind; // Register fire event handler ["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; diff --git a/addons/weaponselect/stringtable.xml b/addons/weaponselect/stringtable.xml index 94f80158f9..d2f17dfe35 100644 --- a/addons/weaponselect/stringtable.xml +++ b/addons/weaponselect/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -30,8 +30,8 @@ Mostra um hint ou texto ao lançar uma granada 手榴弾を投げるときに、ヒントか文で通知します。 수류탄 투척시 화면에 문자나 힌트를 표시합니다. - 投掷手榴弹时显示提示讯息. - 投擲手榴彈時顯示提示訊息. + 投掷手榴弹时显示提示讯息。 + 投擲手榴彈時顯示提示訊息。 Select Pistol @@ -364,10 +364,18 @@ Пустить дымовую завесу Lancia fumogeno Lançador de fumaça - 煙幕発射機を発射 + 発煙弾発射機を発射 연막발사기 박사 发射烟雾发射器 發射煙霧發射器 + + Toggle Collision Lights + Attiva Luci di Collisione + 충돌 표시등 토글 + 切換碰撞燈 + 切换碰撞灯 + 衝突防止灯を切り替え + diff --git a/addons/weather/ACE_Settings.hpp b/addons/weather/ACE_Settings.hpp index d3b9b1fd2e..e2eb4590b7 100644 --- a/addons/weather/ACE_Settings.hpp +++ b/addons/weather/ACE_Settings.hpp @@ -1,38 +1,24 @@ class ACE_Settings { - class GVAR(enableServerController) { - displayName = CSTRING(enableServerController_DisplayName); - description = CSTRING(enableServerController_Description); + class GVAR(enabled) { + category = CSTRING(Module_DisplayName); + displayName = CSTRING(enabled_DisplayName); + description = CSTRING(enabled_Description); typeName = "BOOL"; value = 1; }; - class GVAR(useACEWeather) { - displayName = CSTRING(useACEWeather_DisplayName); - description = CSTRING(useACEWeather_Description); - typeName = "BOOL"; - value = 1; - }; - class GVAR(syncRain) { - displayName = CSTRING(syncRain_DisplayName); - description = CSTRING(syncRain_Description); - typeName = "BOOL"; - value = 1; - }; - class GVAR(syncWind) { - displayName = CSTRING(syncWind_DisplayName); - description = CSTRING(syncWind_Description); - typeName = "BOOL"; - value = 1; - }; - class GVAR(syncMisc) { - displayName = CSTRING(syncMisc_DisplayName); - description = CSTRING(syncMisc_Description); - typeName = "BOOL"; - value = 1; - }; - class GVAR(serverUpdateInterval) { - displayName = CSTRING(serverUpdateInterval_DisplayName); - description = CSTRING(serverUpdateInterval_Description); + class GVAR(updateInterval) { + category = CSTRING(Module_DisplayName); + displayName = CSTRING(updateInterval_DisplayName); + description = CSTRING(updateInterval_Description); typeName = "SCALAR"; value = 60; + sliderSettings[] = {0, 300, 0, 0}; + }; + class GVAR(windSimulation) { + category = CSTRING(Module_DisplayName); + displayName = CSTRING(windSimulation_DisplayName); + description = CSTRING(windSimulation_Description); + typeName = "BOOL"; + value = 1; }; }; diff --git a/addons/weather/CfgVehicles.hpp b/addons/weather/CfgVehicles.hpp index ab3d408fdc..cab16183a8 100644 --- a/addons/weather/CfgVehicles.hpp +++ b/addons/weather/CfgVehicles.hpp @@ -1,7 +1,7 @@ class CfgVehicles { class ACE_Module; class GVAR(ModuleSettings): ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(Module_DisplayName); icon = QPATHTOF(UI\Icon_Module_Wind_ca.paa); category = "ACE"; @@ -12,42 +12,24 @@ class CfgVehicles { isTriggerActivated = 0; author = ECSTRING(common,ACETeam); class Arguments { - class enableServerController { - displayName = CSTRING(enableServerController_DisplayName); - description = CSTRING(enableServerController_Description); + class enabled { + displayName = CSTRING(enabled_DisplayName); + description = CSTRING(enabled_Description); typeName = "BOOL"; defaultValue = 1; }; - class useACEWeather { - displayName = CSTRING(useACEWeather_DisplayName); - description = CSTRING(useACEWeather_Description); - typeName = "BOOL"; - defaultValue = 1; - }; - class syncRain { - displayName = CSTRING(syncRain_DisplayName); - description = CSTRING(syncRain_Description); - typeName = "BOOL"; - defaultValue = 1; - }; - class syncWind { - displayName = CSTRING(syncWind_DisplayName); - description = CSTRING(syncWind_Description); - typeName = "BOOL"; - defaultValue = 1; - }; - class syncMisc { - displayName = CSTRING(syncMisc_DisplayName); - description = CSTRING(syncMisc_Description); - typeName = "BOOL"; - defaultValue = 1; - }; - class serverUpdateInterval { - displayName = CSTRING(serverUpdateInterval_DisplayName); - description = CSTRING(serverUpdateInterval_Description); + class updateInterval { + displayName = CSTRING(updateInterval_DisplayName); + description = CSTRING(updateInterval_Description); typeName = "NUMBER"; defaultValue = 60; }; + class windSimulation { + displayName = CSTRING(windSimulation_DisplayName); + description = CSTRING(windSimulation_Description); + typeName = "BOOL"; + defaultValue = 1; + }; }; class ModuleDescription { description = CSTRING(Module_Description); diff --git a/addons/weather/XEH_PREP.hpp b/addons/weather/XEH_PREP.hpp index b13b938892..48788c0546 100644 --- a/addons/weather/XEH_PREP.hpp +++ b/addons/weather/XEH_PREP.hpp @@ -12,12 +12,9 @@ PREP(calculateWindChill); PREP(calculateWindSpeed); PREP(displayWindInfo); PREP(getMapData); -PREP(getWind); PREP(initModuleSettings); PREP(initWind); -PREP(serverController); -PREP(updateAceWeather); PREP(updateHumidity); -PREP(updateRain); PREP(updateTemperature); +PREP(updateWeather); PREP(updateWind); diff --git a/addons/weather/XEH_postInit.sqf b/addons/weather/XEH_postInit.sqf index d2c6f3b7df..51350226e1 100644 --- a/addons/weather/XEH_postInit.sqf +++ b/addons/weather/XEH_postInit.sqf @@ -1,33 +1,5 @@ #include "script_component.hpp" -// Randomization -GVAR(temperatureShift) = 3 - random 6; -GVAR(badWeatherShift) = (random 1) ^ 2 * 10; -GVAR(humidityShift) = (5 - random 10) / 100; - -GVAR(wind_period_start_time) = CBA_missionTime; -GVAR(rain_period_start_time) = CBA_missionTime; - -GVAR(ACE_rain) = rain; - -"ACE_WIND_PARAMS" addPublicVariableEventHandler { GVAR(wind_period_start_time) = CBA_missionTime; }; -"ACE_RAIN_PARAMS" addPublicVariableEventHandler { GVAR(rain_period_start_time) = CBA_missionTime; }; -"ACE_MISC_PARAMS" addPublicVariableEventHandler { - if (!isServer) then { - TRACE_1("MISC PARAMS PVEH",ACE_MISC_PARAMS); - if (GVAR(syncMisc)) then { - 30 setLightnings (ACE_MISC_PARAMS select 0); - 30 setRainbow (ACE_MISC_PARAMS select 1); - 30 setFog (ACE_MISC_PARAMS select 2); - }; - GVAR(temperatureShift) = (ACE_MISC_PARAMS select 3); - GVAR(badWeatherShift) = (ACE_MISC_PARAMS select 4); - GVAR(humidityShift) = (ACE_MISC_PARAMS select 5); - call FUNC(updateTemperature); - call FUNC(updateHumidity); - }; -}; - GVAR(WindInfo) = false; ["ACE3 Common", QGVAR(WindInfoKey), localize LSTRING(WindInfoKeyToggle), { @@ -53,41 +25,3 @@ GVAR(WindInfo) = false; (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN", 2]; }, [0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) - -simulWeatherSync; - - - - -["ace_settingsInitialized",{ - TRACE_1("ace_settingsInitialized eh",GVAR(syncRain)); - - // update rain every frame: - if (GVAR(syncRain)) then { - addMissionEventHandler ["EachFrame", {0 setRain GVAR(ACE_rain)}]; - }; - - //Create a 1 sec delay PFEH to update wind/rain/temp/humidity: - - //If we don't sync rain, set next time to infinity - GVAR(nextUpdateRain) = if (GVAR(syncRain)) then {0} else {1e99}; - GVAR(nextUpdateTempAndHumidity) = 0; - [{ - BEGIN_COUNTER(weatherPFEH); - - [] call FUNC(updateWind); //Every 1 second - - if (CBA_missionTime >= GVAR(nextUpdateRain)) then { - [] call FUNC(updateRain); //Every 2 seconds - GVAR(nextUpdateRain) = 2 + CBA_missionTime; - }; - if (CBA_missionTime >= GVAR(nextUpdateTempAndHumidity)) then { - [] call FUNC(updateTemperature); //Every 20 seconds - [] call FUNC(updateHumidity); //Every 20 seconds - GVAR(nextUpdateTempAndHumidity) = 20 + CBA_missionTime; - }; - - END_COUNTER(weatherPFEH); - }, 1, []] call CBA_fnc_addPerFrameHandler; - -}] call CBA_fnc_addEventHandler; diff --git a/addons/weather/XEH_postServerInit.sqf b/addons/weather/XEH_postServerInit.sqf index cd1fca2c4c..433c161979 100644 --- a/addons/weather/XEH_postServerInit.sqf +++ b/addons/weather/XEH_postServerInit.sqf @@ -1,18 +1,16 @@ #include "script_component.hpp" -// Rain -GVAR(rain_next_period) = -1; -GVAR(rain_period_count) = 0; -GVAR(current_rain) = 0; -GVAR(rain_current_range) = -1+(random 2); - -// Wind -call FUNC(initWind); - ["ace_settingsInitialized", { - TRACE_2("ace_settingsInitialized eh",GVAR(enableServerController),GVAR(serverUpdateInterval)); + if (!GVAR(enabled)) exitWith {}; - if (GVAR(enableServerController)) then { - [FUNC(serverController), GVAR(serverUpdateInterval)] call CBA_fnc_addPerFrameHandler; + GVAR(temperatureShift) = random [-SD_TO_MIN_MAX(4), 0, SD_TO_MIN_MAX(4)]; // Gauss(0, 4) + GVAR(badWeatherShift) = random [-SD_TO_MIN_MAX(2) + 4, 4, 4 + SD_TO_MIN_MAX(2)]; // Gauss(4, 2) + GVAR(humidityShift) = random [-SD_TO_MIN_MAX(0.065), 0, SD_TO_MIN_MAX(0.065)]; // Gauss(0, 0.065) + + if (GVAR(windSimulation)) then { + call FUNC(initWind); + [FUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler; }; + [FUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler; + }] call CBA_fnc_addEventHandler; diff --git a/addons/weather/functions/fnc_calculateBarometricPressure.sqf b/addons/weather/functions/fnc_calculateBarometricPressure.sqf index 29b8fa7877..0749004c21 100644 --- a/addons/weather/functions/fnc_calculateBarometricPressure.sqf +++ b/addons/weather/functions/fnc_calculateBarometricPressure.sqf @@ -15,4 +15,4 @@ */ #include "script_component.hpp" -((1013.25 - 10 * overcast) * (1 - (0.0065 * (EGVAR(common,mapAltitude) + _this)) / (KELVIN(GVAR(currentTemperature)) + 0.0065 * EGVAR(common,mapAltitude))) ^ 5.255754495); +((1013.25 - 10 * GVAR(currentOvercast)) * (1 - (0.0065 * (EGVAR(common,mapAltitude) + _this)) / (KELVIN(GVAR(currentTemperature)) + 0.0065 * EGVAR(common,mapAltitude))) ^ 5.255754495); diff --git a/addons/weather/functions/fnc_calculateRoughnessLength.sqf b/addons/weather/functions/fnc_calculateRoughnessLength.sqf index 423f3fc3d6..5112cf4ef5 100644 --- a/addons/weather/functions/fnc_calculateRoughnessLength.sqf +++ b/addons/weather/functions/fnc_calculateRoughnessLength.sqf @@ -18,7 +18,7 @@ // Source: http://es.ucsc.edu/~jnoble/wind/extrap/index.html #define ROUGHNESS_LENGTHS [0.0002, 0.0005, 0.0024, 0.03, 0.055, 0.1, 0.2, 0.4, 0.8, 1.6] -private _windSource = _this vectorDiff ((vectorNormalized ACE_wind) vectorMultiply 25); +private _windSource = _this vectorDiff ((vectorNormalized wind) vectorMultiply 25); private _nearBuildings = count (_windSource nearObjects ["Building", 50]); private _isWater = surfaceIsWater _windSource; diff --git a/addons/weather/functions/fnc_calculateSpeedOfSound.sqf b/addons/weather/functions/fnc_calculateSpeedOfSound.sqf index f645ba2368..ed968d94f0 100644 --- a/addons/weather/functions/fnc_calculateSpeedOfSound.sqf +++ b/addons/weather/functions/fnc_calculateSpeedOfSound.sqf @@ -15,4 +15,4 @@ */ #include "script_component.hpp" -(331.3 + (0.6 * _this)) +(331.3 * sqrt(1 + (_this / 273.15))) diff --git a/addons/weather/functions/fnc_calculateWindSpeed.sqf b/addons/weather/functions/fnc_calculateWindSpeed.sqf index 206bc1d298..2f02c12852 100644 --- a/addons/weather/functions/fnc_calculateWindSpeed.sqf +++ b/addons/weather/functions/fnc_calculateWindSpeed.sqf @@ -26,18 +26,17 @@ private _fnc_polar2vect = { [_mag2D * sin(_dir), _mag2D * cos(_dir), _mag * sin(_elev)]; }; -private _windSpeed = vectorMagnitude ACE_wind; -private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); +private _windSpeed = vectorMagnitude wind; +private _windDir = (wind select 0) atan2 (wind select 1); private _windDirAdjusted = _windDir + 180; // Wind gradient if (_windGradientEnabled) then { if (_windSpeed > 0.05) then { private _height = (ASLToATL _position) select 2; - _height = 0 max _height min 20; - if (_height < 20) then { + if (_height > 0 && _height < 20) then { private _roughnessLength = _position call FUNC(calculateRoughnessLength); - _windSpeed = _windSpeed * abs(ln(_height / _roughnessLength) / ln(20 / _roughnessLength)); + _windSpeed = _windSpeed * (0 max (ln(_height / _roughnessLength) / ln(20 / _roughnessLength))); }; }; }; diff --git a/addons/weather/functions/fnc_displayWindInfo.sqf b/addons/weather/functions/fnc_displayWindInfo.sqf index 10a1e45861..a8409cb68a 100644 --- a/addons/weather/functions/fnc_displayWindInfo.sqf +++ b/addons/weather/functions/fnc_displayWindInfo.sqf @@ -55,7 +55,7 @@ TRACE_1("Starting Wind Info PFEH", GVAR(WindInfo)); private _playerDir = (ACE_player call CBA_fnc_headDir) select 0; - private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); + private _windDir = (wind select 0) atan2 (wind select 1); _windDir = 30 * (round(((_windDir - _playerDir + 360) % 360) / 30)); // Color Codes from https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale diff --git a/addons/weather/functions/fnc_getMapData.sqf b/addons/weather/functions/fnc_getMapData.sqf index 2b222c2d8b..dd086b8414 100644 --- a/addons/weather/functions/fnc_getMapData.sqf +++ b/addons/weather/functions/fnc_getMapData.sqf @@ -43,8 +43,9 @@ GVAR(TempDay) = [1, 3, 9, 14, 19, 23, 25, 24, 21, 13, 7, 2]; GVAR(TempNight) = [-4, -3, 0, 4, 9, 12, 14, 14, 10, 6, 2, -2]; GVAR(Humidity) = [82, 80, 78, 70, 71, 72, 70, 73, 78, 80, 83, 82]; -GVAR(currentTemperature) = 20; -GVAR(currentHumidity) = 0.5; +GVAR(currentTemperature) = 15; +GVAR(currentHumidity) = 0; +GVAR(currentOvercast) = 0; // Get all non inherited arrays to filter maps that inherit from Stratis/Altis/Tanoa private _nonInheritedArrays = configProperties [configFile >> "CfgWorlds" >> _worldName, "isArray _x", false]; diff --git a/addons/weather/functions/fnc_getWind.sqf b/addons/weather/functions/fnc_getWind.sqf deleted file mode 100644 index 2d29335026..0000000000 --- a/addons/weather/functions/fnc_getWind.sqf +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Author: ACE2 Team, Ruthberg - * Calculate current wind locally from the data broadcasted by the server - * - * Arguments: - * None - * - * Return Value: - * Wind - * - * Example: - * [] call ace_weather_fnc_getWind - * - * Public: No - */ -#include "script_component.hpp" - -if (isNil "ACE_WIND_PARAMS") exitWith { [0, 0, 0] }; - -ACE_WIND_PARAMS params ["_dir", "_dirChange", "_spd", "_spdChange", "_period"]; -//Wind _dir is the "source" of the wind [eg: "northerly wind": _dir = 0 -> wind = [0,-1,0];] - -private _periodPosition = (CBA_missionTime - GVAR(wind_period_start_time)) min _period; -private _periodPercent = _periodPosition / _period; - -_spd = _spd + _spdChange * _periodPercent; -_dir = _dir + _dirChange * _periodPercent; - -_dir = (360 + _dir) % 360; - -TRACE_1("PeriodStartTime",Round(GVAR(wind_period_start_time))); -TRACE_2("Dir: Current/Change",Round(_dir),Round(_dirChange)); -TRACE_2("Spd: Current/Change",Round(_spd * 10) / 10,Round(_spdChange * 10) / 10); -TRACE_3("Period/Position/Percent",Round(_period),Round(_periodPosition),Round(_periodPercent * 100) / 100); - -// TODO: Add some deterministic noise - -[-_spd * sin(_dir), -_spd * cos(_dir), 0] diff --git a/addons/weather/functions/fnc_initModuleSettings.sqf b/addons/weather/functions/fnc_initModuleSettings.sqf index f1e9c1d6fc..3334392156 100644 --- a/addons/weather/functions/fnc_initModuleSettings.sqf +++ b/addons/weather/functions/fnc_initModuleSettings.sqf @@ -22,18 +22,13 @@ params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; -// Control server side weather propagation -[_logic, QGVAR(enableServerController), "enableServerController"] call EFUNC(common,readSettingFromModule); - -// Overrides the default weather (editor, mission settings) with ACE weather (map based) -[_logic, QGVAR(useACEWeather), "useACEWeather"] call EFUNC(common,readSettingFromModule); - -// Control client side weather effects -[_logic, QGVAR(syncRain), "syncRain"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(syncWind), "syncWind"] call EFUNC(common,readSettingFromModule); // Wind, Gusts, Waves -[_logic, QGVAR(syncMisc), "syncMisc"] call EFUNC(common,readSettingFromModule); // Lightnings, Rainbow, Fog +// Turns the weather module on / off +[_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); // Server weather update interval -[_logic, QGVAR(serverUpdateInterval), "serverUpdateInterval"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(updateInterval), "updateInterval"] call EFUNC(common,readSettingFromModule); -GVAR(serverUpdateInterval) = 1 max GVAR(serverUpdateInterval) min 600; +// Turns the (map based) wind simulation on / off +[_logic, QGVAR(windSimulation), "windSimulation"] call EFUNC(common,readSettingFromModule); + +GVAR(updateInterval) = 1 max GVAR(updateInterval) min 600; diff --git a/addons/weather/functions/fnc_initWind.sqf b/addons/weather/functions/fnc_initWind.sqf index 634542c1e4..c40a6b4113 100644 --- a/addons/weather/functions/fnc_initWind.sqf +++ b/addons/weather/functions/fnc_initWind.sqf @@ -1,6 +1,6 @@ /* * Author: Ruthberg - * Inits the wind variables on mission start + * Inits the wind variables on the server (on mission start) * * Arguments: * None @@ -18,8 +18,6 @@ private _month = date select 1; private _windDirectionProbabilities = GVAR(WindDirectionProbabilities) select (_month - 1); -ACE_wind = [0, 0, 0]; - GVAR(wind_direction_reference) = random 360; private _sum = 0; for "_i" from 0 to 7 do { @@ -52,10 +50,14 @@ GVAR(max_wind_speed) = GVAR(WindSpeedMax) select (_month - 1); GVAR(max_wind_speed) = (GVAR(max_wind_speed) select 0) + (random (GVAR(max_wind_speed) select 1)) - (random (GVAR(max_wind_speed) select 1)); GVAR(max_wind_speed) = 0 max GVAR(max_wind_speed); +GVAR(wind_upper_span) = GVAR(max_wind_speed) - GVAR(mean_wind_speed); +GVAR(wind_lower_span) = GVAR(min_wind_speed) - GVAR(mean_wind_speed); + GVAR(current_wind_direction) = GVAR(wind_direction_reference); +GVAR(next_wind_direction) = GVAR(current_wind_direction); + GVAR(current_wind_speed) = GVAR(min_wind_speed) + (GVAR(max_wind_speed) - GVAR(min_wind_speed)) * (random 1); +GVAR(next_wind_speed) = GVAR(current_wind_speed); -GVAR(wind_period_count) = 0; -GVAR(wind_next_period) = -1; - -GVAR(wind_speed_debug_output) = []; +GVAR(last_wind_update) = 0; +GVAR(next_wind_udpate) = 0; diff --git a/addons/weather/functions/fnc_serverController.sqf b/addons/weather/functions/fnc_serverController.sqf deleted file mode 100644 index 79d2aab93e..0000000000 --- a/addons/weather/functions/fnc_serverController.sqf +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Author: Ruthberg - * Gather weather parameters and broadcast them to the clients - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_weather_fnc_serverController - * - * Public: No - */ -#include "script_component.hpp" - -if (GVAR(useACEWeather)) then { - // Use location based real world weather data - [] call FUNC(updateAceWeather); -} else { - // Simply replicate the server weather on the clients - if (GVAR(syncRain)) then { - ACE_RAIN_PARAMS = [rain, rain, GVAR(serverUpdateInterval)]; - publicVariable "ACE_RAIN_PARAMS"; - }; - if (GVAR(syncWind)) then { - //Wind _dir is the "source" of the wind [eg: "northerly wind": _dir = 0 -> wind = [0,-1,0];] - private _windDir = ((((wind select 0) atan2 (wind select 1)) + 180) % 360); - ACE_WIND_PARAMS = [_windDir, 0, vectorMagnitude wind, 0, GVAR(serverUpdateInterval)]; - publicVariable "ACE_WIND_PARAMS"; - }; - if (GVAR(syncMisc)) then { - ACE_MISC_PARAMS = [lightnings, rainbow, fogParams, GVAR(temperatureShift), GVAR(badWeatherShift), GVAR(humidityShift)]; - publicVariable "ACE_MISC_PARAMS"; - }; -}; diff --git a/addons/weather/functions/fnc_updateAceWeather.sqf b/addons/weather/functions/fnc_updateAceWeather.sqf deleted file mode 100644 index db8783cd83..0000000000 --- a/addons/weather/functions/fnc_updateAceWeather.sqf +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Author: ACE2 Team, esteldunedain, ruthberg - * Updates the wind and rain evolution on the server. Broadcasts the current and next values to the clients - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_weather_fnc_updateAceWeather - * - * Public: No - */ -#include "script_component.hpp" - -private _overcastMultiplier = 1 max (2* overcast) min 2; // 0 (@ overcast 0), 2 (@ overcast 1) - -// Rain simulation -if (GVAR(syncRain) && {GVAR(rain_period_count) > GVAR(rain_next_period)}) then { - - GVAR(rain_next_period) = ceil((1 + (random 10)) / _overcastMultiplier); - GVAR(rain_period_count) = 0; - - private _lastRain = GVAR(current_rain); - private _rainOverCast = 0; - - if (overcast >= 0.7) then { - _rainOverCast = (overcast - 0.7) / 0.3; - if (GVAR(current_rain) == 0) then { - // Initialize rain with a random strength depending on the current overcast value - GVAR(current_rain) = -0.25 + (random 0.75) + (random 0.5) * _rainOverCast; - }; - - GVAR(current_rain) = GVAR(current_rain) + GVAR(current_rain) * ((_rainOverCast * _overcastMultiplier) / 8) * GVAR(rain_current_range); - GVAR(current_rain) = 0 max GVAR(current_rain) min 1; - - GVAR(rain_current_range) = -1 + (random 2); - } else { - _rainOverCast = 1; - - GVAR(current_rain) = 0; - }; - - private _transitionTime = 1 + (_rainOverCast * 5) + (random (_rainOverCast * 20)); - - ACE_RAIN_PARAMS = [_lastRain, GVAR(current_rain), _transitionTime]; - TRACE_4("",_lastRain,_rainOverCast,_transitionTime,overcast); - - GVAR(rain_period_start_time) = CBA_missionTime; - publicVariable "ACE_RAIN_PARAMS"; -}; - -// Wind simulation -if (GVAR(syncWind) && {GVAR(wind_period_count) > GVAR(wind_next_period)}) then { - - GVAR(wind_next_period) = ceil((2 + (random 5)) / _overcastMultiplier); - GVAR(wind_period_count) = 0; - - private _windDirectionVariance = (90 - (random 180)) * (overcast ^ 2); - private _windDirection = (360 + GVAR(wind_direction_reference) + _windDirectionVariance) % 360; - private _windDirectionChange = _windDirection - GVAR(current_wind_direction); - if (_windDirectionChange > 180) then { - _windDirectionChange = _windDirectionChange - 360; - }; - if (_windDirectionChange < -180) then { - _windDirectionChange = 360 + _windDirectionChange; - }; - - private _windMaxDiff = GVAR(mean_wind_speed) - GVAR(max_wind_speed); - private _windMinDiff = GVAR(min_wind_speed) - GVAR(mean_wind_speed); - - private _ratioMax = (random 1) ^ 2; - private _ratioMin = (random 1) ^ 2; - - private _windSpeed = GVAR(current_wind_speed); - private _windSpeedChange = 0; - if ((random 1) < (0.3 max overcast)) then { - _windSpeed = GVAR(mean_wind_speed) + _windMaxDiff * _ratioMax + _windMinDiff * _ratioMin; - _windSpeedChange = _windSpeed - GVAR(current_wind_speed); - }; - - private _transitionTime = GVAR(wind_next_period) * GVAR(serverUpdateInterval); - - TRACE_5("dirCur/dirNew/spdCur/spdNew/period",GVAR(current_wind_direction),_windDirection,GVAR(current_wind_speed),_windSpeed,_transitionTime); - - ACE_WIND_PARAMS = [GVAR(current_wind_direction), - _windDirectionChange, - GVAR(current_wind_speed), - _windSpeedChange, - _transitionTime]; - - GVAR(current_wind_direction) = _windDirection; - GVAR(current_wind_speed) = _windSpeed; - - GVAR(wind_period_start_time) = CBA_missionTime; - publicVariable "ACE_WIND_PARAMS"; -}; - - -if (GVAR(syncMisc)) then { - ACE_MISC_PARAMS = [lightnings, rainbow, fogParams, GVAR(temperatureShift), GVAR(badWeatherShift), GVAR(humidityShift)]; - publicVariable "ACE_MISC_PARAMS"; -}; - -GVAR(rain_period_count) = GVAR(rain_period_count) + 1; -GVAR(wind_period_count) = GVAR(wind_period_count) + 1; diff --git a/addons/weather/functions/fnc_updateHumidity.sqf b/addons/weather/functions/fnc_updateHumidity.sqf index 79569e7367..24e0211ec8 100644 --- a/addons/weather/functions/fnc_updateHumidity.sqf +++ b/addons/weather/functions/fnc_updateHumidity.sqf @@ -1,6 +1,6 @@ /* * Author: ACE2 Team - * Updates GVAR(currentHumidity) + * Smoothly updates GVAR(currentHumidity) on the server (based on time of day and map data) * * Arguments: * None @@ -15,20 +15,18 @@ */ #include "script_component.hpp" -private _month = date select 1; - -GVAR(currentHumidity) = (GVAR(Humidity) select (_month - 1)) / 100; - -if ((rain > 0) && {overcast > 0.7}) then { +if (rain > 0 && overcast > 0.7) then { GVAR(currentHumidity) = 1; } else { + private _month = date select 1; + GVAR(currentHumidity) = (GVAR(Humidity) select (_month - 1)) / 100; + GVAR(currentHumidity) = GVAR(currentHumidity) + GVAR(humidityShift); private _avgTemperature = ((GVAR(TempDay) select (_month - 1)) + (GVAR(TempNight) select (_month - 1))) / 2; private _pS1 = 6.112 * exp((17.62 * _avgTemperature) / (243.12 + _avgTemperature)); private _PS2 = 6.112 * exp((17.62 * GVAR(currentTemperature)) / (243.12 + GVAR(currentTemperature))); GVAR(currentHumidity) = GVAR(currentHumidity) * _PS1 / _PS2; - GVAR(currentHumidity) = GVAR(currentHumidity) + GVAR(humidityShift); - - TRACE_1("humidityShift",GVAR(humidityShift)); }; GVAR(currentHumidity) = 0 max GVAR(currentHumidity) min 1; + +publicVariable QGVAR(currentHumidity); diff --git a/addons/weather/functions/fnc_updateRain.sqf b/addons/weather/functions/fnc_updateRain.sqf deleted file mode 100644 index eefa72cd99..0000000000 --- a/addons/weather/functions/fnc_updateRain.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Author: ACE2 Team, Ruthberg - * Updates rain based on ACE_RAIN_PARAMS - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call ace_weather_fnc_updateRain - * - * Public: No - */ -#include "script_component.hpp" - -if (!isNil "ACE_RAIN_PARAMS") then { - ACE_RAIN_PARAMS params ["_oldRain", "_newRain", "_period"]; - - private _periodPosition = (CBA_missionTime - GVAR(rain_period_start_time)) min _period; - private _periodPercent = (_periodPosition / _period) min 1; - - GVAR(ACE_Rain) = linearConversion [GVAR(rain_period_start_time), (GVAR(rain_period_start_time) + _period), CBA_missionTime, _oldRain, _newRain]; - - TRACE_3("Update Rain",rain,ACE_RAIN_PARAMS,GVAR(ACE_Rain)); -}; diff --git a/addons/weather/functions/fnc_updateTemperature.sqf b/addons/weather/functions/fnc_updateTemperature.sqf index 879e061574..7e597b1733 100644 --- a/addons/weather/functions/fnc_updateTemperature.sqf +++ b/addons/weather/functions/fnc_updateTemperature.sqf @@ -1,6 +1,6 @@ /* * Author: ACE2 Team - * Updates GVAR(currentTemperature) based on the map data + * Smoothly updates GVAR(currentTemperature) on the server (based on time of day and map data) * * Arguments: * None @@ -15,13 +15,11 @@ */ #include "script_component.hpp" -private _time = daytime; private _month = date select 1; - -private _timeRatio = abs(_time - 12) / 12; +private _timeRatio = abs(daytime - 12) / 12; GVAR(currentTemperature) = (GVAR(TempDay) select (_month - 1)) * (1 - _timeRatio) + (GVAR(TempNight) select (_month - 1)) * _timeRatio; -GVAR(currentTemperature) = GVAR(currentTemperature) + GVAR(temperatureShift) - GVAR(badWeatherShift) * overcast; +GVAR(currentTemperature) = GVAR(currentTemperature) + GVAR(temperatureShift) - GVAR(badWeatherShift) * GVAR(currentOvercast); GVAR(currentTemperature) = round(GVAR(currentTemperature) * 10) / 10; -TRACE_2("temperatureShift/badWeatherShift",GVAR(temperatureShift),GVAR(badWeatherShift)); +publicVariable QGVAR(currentTemperature); diff --git a/addons/weather/functions/fnc_updateWeather.sqf b/addons/weather/functions/fnc_updateWeather.sqf new file mode 100644 index 0000000000..8cb4633ef1 --- /dev/null +++ b/addons/weather/functions/fnc_updateWeather.sqf @@ -0,0 +1,43 @@ +/* + * Author: ACE2 Team, esteldunedain, Ruthberg + * Updates the weather evolution on the server. Broadcasts relevant weather information to the clients. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_weather_fnc_updateWeather + * + * Public: No + */ +#include "script_component.hpp" + +missionNamespace setVariable [QGVAR(currentOvercast), overcast, true]; + +[] call FUNC(updateTemperature); +[] call FUNC(updateHumidity); + +// Wind simulation +if (GVAR(windSimulation) && CBA_missionTime > GVAR(next_wind_udpate)) then { + + GVAR(current_wind_direction) = GVAR(next_wind_direction); + GVAR(current_wind_speed) = GVAR(next_wind_speed); + + private _transitionPeriod = GVAR(updateInterval) * (2 + (random 4)) / (1 + overcast); + GVAR(next_wind_udpate) = CBA_missionTime + _transitionPeriod; + + private _windDirectionVariance = (90 - (random 180)) * (overcast ^ 2); + GVAR(next_wind_direction) = (360 + GVAR(wind_direction_reference) + _windDirectionVariance) % 360; + + if ((random 1) < (0.3 max overcast)) then { + private _speedVariance = GVAR(wind_upper_span) * (random 1) ^ 2 + GVAR(wind_lower_span) * (random 1) ^ 2; + GVAR(next_wind_speed) = GVAR(mean_wind_speed) + _speedVariance; + }; + + GVAR(last_wind_update) = CBA_missionTime; + + TRACE_5("dirCur/dirNew/spdCur/spdNew/period",GVAR(current_wind_direction),GVAR(next_wind_direction),GVAR(current_wind_speed),GVAR(next_wind_speed),_transitionPeriod); +}; diff --git a/addons/weather/functions/fnc_updateWind.sqf b/addons/weather/functions/fnc_updateWind.sqf index a179c98dda..e4c3bbb033 100644 --- a/addons/weather/functions/fnc_updateWind.sqf +++ b/addons/weather/functions/fnc_updateWind.sqf @@ -1,6 +1,6 @@ /* * Author: ACE2 Team, Ruthberg - * Updates wind, gusts and waves based on ACE_wind + * Smoothly updates wind on the server (based on time of year and map data) * * Arguments: * None @@ -15,16 +15,7 @@ */ #include "script_component.hpp" -if (!GVAR(syncWind)) exitWith { ACE_wind = wind }; +private _speed = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_speed), GVAR(next_wind_speed), true]; +private _direction = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_direction), GVAR(next_wind_direction), true]; -ACE_wind = [] call FUNC(getWind); -setWind [ACE_wind select 0, ACE_wind select 1, true]; -2 setGusts 0; - -// Set waves: 0 when no wind, 1 when wind >= 16 m/s -private _newWaves = ((vectorMagnitude ACE_wind) / 16.0) min 1.0; -if (abs(_newWaves - waves) > 0.1) then { - 1 setWaves _newWaves; -}; - -TRACE_3("Wind/ACE_wind/Deviation(m/s)",wind,ACE_wind,Round((vectorMagnitude (ACE_wind vectorDiff wind)) * 1000) / 1000); +setWind [-_speed * sin(_direction), -_speed * cos(_direction), true]; diff --git a/addons/weather/init3DEN.sqf b/addons/weather/init3DEN.sqf index 1bae6c4d95..34b7dc2d5b 100644 --- a/addons/weather/init3DEN.sqf +++ b/addons/weather/init3DEN.sqf @@ -7,8 +7,6 @@ // we have to auto set these settings manually - on mission creation add3DENEventHandler ["onMissionNew", { set3DENMissionAttributes [ - ["Intel", "IntelRainIsForced", true], - ["Intel", "IntelLightningIsForced", true], ["Intel", "IntelWavesIsForced", true], ["Intel", "IntelWindIsForced", true] ]; diff --git a/addons/weather/stringtable.xml b/addons/weather/stringtable.xml index 3849a49b07..12ef0dc630 100644 --- a/addons/weather/stringtable.xml +++ b/addons/weather/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -28,7 +28,7 @@ Széladatok mutatása (pecek) Zobrazit údaje o větru (přep.) Mostrar informação do vento (alternar) - 風速を表示 (トグル) + 風速を表示 (切り替え) 바람 정보 표시 (토글) 显示风力资讯(切换) 顯示風力資訊(切換) @@ -65,39 +65,7 @@ 使用ACE天气模块来同步所有客户端的天气状态(多人游戏) 使用ACE天氣模塊來同步所有客戶端的天氣狀態(多人遊戲) - - Weather propagation - Zmiany pogody - Propagación del clima - Wetterübertragung - Změny počasí - Propagação do clima - Propagation de la météo - Időjárás-változás - Единая погода для всех - Propagazione Meteo - 天候の統一 - 기후 전파 - 天气状态广播 - 天氣狀態廣播 - - - Enables server side weather propagation - Aktywuje zmiany pogody po stronie serwera - Permite al servidor controlar la propagación del clima - Aktiviere serverseitige Wetterübertragung - Aktivuje změny počasí na straně serveru - Ativa propagação de clima via server - Active la propagation météo par le serveur - Engedélyezi a szerveroldali időjárás-változást - Включает управление погодой на серверной стороне - Abilita propagazione meteo lato server - サーバ側による天候の統一を有効化 - 서버의 기후를 전파합니다 - 启用伺服器的天气状态广播 - 啟用伺服器的天氣狀態廣播 - - + ACE Weather Pogoda ACE Clima ACE @@ -113,119 +81,16 @@ ACE 天气 ACE 天氣 - - Overrides the default weather (editor, mission settings) with ACE weather (map based) - Nadpisuje domyślne ustawienia pogody (edytor, wywiad) przy użyciu pogody ACE (zależna od mapy) - Sobreescribe el sistema climático por defecto (editor, ajustes de mision) con clima del ACE (basado en el mapa) - Überschreibt das Standardwetter (Editor, Missionseinstellungen) mit dem ACE-Wetter (kartenbasiert) - Přepíše výchozí počasí (editor, nastavení mise) s ACE počasím (podle mapy) - Sobreescreve o clima padrão (editor, ajustes de missão) pelo sistema de clima ACE (baseado por mapa) - Force la métao par défaut (éditeur, paramètres de mission) avec la météo ACE (basé sur la carte) - Felülbírálja az alapértelmezett időjárást (editor, küldetésbeállítások) az ACE időjárással (térkép-alapú) - Заменяет погоду по-умолчанию (из редактора, настроек миссии) погодой ACE (на основе карты) - Scavalca il meteo default (editor, parametri missione) con il meteo ACE (basato su mappa) - ACE 天候 (マップを元) による標準の天候 (エディタやミッション設定) を上書きします。 - 기존의 기후(에디터, 임무 설정)를 ACE 기후로 치환합니다. (지도에 따라) - 使ACE天气覆盖预设的天气 (编辑任务设置) - 使ACE天氣覆蓋預設的天氣 (編輯任務設置) + + Expands the existing weather by temperature, humidity and air pressure. + Erweitert das vorhandene Wetter um Temperatur, Luftfeuchtigkeit und Luftdruck. + Espande il tempo esistente per temperatura, umidità e pressione dell'aria. + 透過增加濕度、溫度與氣壓來增強天氣模擬的表現。 + 透过增加湿度、温度与气压来增强天气模拟的表现。 + 気温や湿度、大気圧によって既存の天候を拡張します。 + 온도, 습도 및 기압에 따라 기존 날씨를 확장합니다. - - Sync Rain - Synchronizuj deszcz - Sincronizar lluvia - Regen synchronisieren - Synchronizuj déšť - Sincronizar chuva - Synchronisation de la pluie - Eső szinkronizálása - Синхрониз. дождь - Sincronizza Pioggia - 降雨の同期 - 비 동기화 - 同步雨 - 同步雨 - - - Synchronizes rain - Synchronizuje deszcz - Sincroniza la lluvia - Synchronisiert den Regen - Synchronizace deště - Sincroniza a chuva - Synchronise la pluie - Szinkronizálja az esőt - Синхронизирует дождь - Sincronizza Pioggia - 降雨の同期 - 비를 동기화 합니다 - 同步雨 - 同步雨 - - - Sync Wind - Synchronizuj wiatr - Sincronizar viento - Wind synchronisieren - Synchronizuj vítr - Sincronizar vento - Synchronisation du vent - Szél szinkronizálása - Синхрониз. ветер - Sincronizza Vento - 風を同期 - 바람 동기화 - 同步风 - 同步風 - - - Synchronizes wind - Synchronizuje wiatr - Sincroniza el viento - Synchronisiert den Wind - Synchronizace větru - Sincroniza o vento - Synchronise le vent - Szinkronizálja a szelet - Синхронизирует ветер - Sincronizza Vento - 風を同期 - 바람을 동기화 합니다 - 同步风 - 同步風 - - - Sync Misc - Synchronizuj różne - Sincronizar otros - Sonstiges synchronisieren - Synchronizuj různé - Sincronizar outros - Synchronisation autres - Egyéb szinkronizálása - Синхрониз. прочее - Sincronizza Misto - その他を同期 - 기타 동기화 - 同步杂项 - 同步雜項 - - - Synchronizes lightnings, rainbow, fog,... - Synchronizuje pioruny, tęcze, mgłę,... - Sincroniza relampagos, arcoiris, niebla... - Synchronisiert Blitze, Regenbögen, Nebel,... - Synchronizace blesků, duhy, mlhy,... - Sincroniza relâmpagos, arco-íris, neblina... - Synchronise les éclairs, les arcs en ciel, le brouillard,... - Szinkronizálja a villámokat, szivárványokat, ködöt,... - Синхронизирует молнии, радугу, туман,... - Sincronizza lampi, arcobaleni, nebbia,... - ライティングや虹、霧などを同期 - 번개라던가, 무지개, 안개등을 동기화 합니다 - 同步闪电, 彩虹, 雾等等... - 同步閃電, 彩虹, 霧等等... - - + Update Interval Interwał aktualizacji Intervalo de actualización @@ -235,13 +100,13 @@ Intervalle de synchronisation Frissítési intervallum Интервал обновления - Intervallo Aggiornamenti + Intervallo Aggiornamento 更新間隔 갱신 간격 更新间隔 更新間隔 - + Defines the interval (seconds) between weather updates Określa interwał (sekundy) pomiędzy aktualizacjami pogody Defina el intervalo (en segundos) entre actualizacions de clima @@ -251,11 +116,29 @@ Défini un intervalle (secondes) entre deux synchronisations Megadja az intervallumot (másodpercben) az időjárás-frissítések között Определяет интервал (в секундах) между обновлениями погоды - Definisce l'intervallo (in secondi) tra aggiornamenti del meteo + Definisce l'intervallo(in secondi) tra aggiornamenti del meteo 天候を更新する間隔を定義します。(秒) 기후를 갱신 하는 간격을 초 단위로 정합니다. 设定天气更新的时间间隔(秒) 設定天氣更新的時間間隔(秒) + + Wind Simulation (map based) + Wind Simulation (kartenbasiert) + Simulazione del Vento (basato sulla mappa) + 風力模擬(基於地圖) + 风力模拟(基于地图) + 風シミュレーション (マップを基に) + 바람 시뮬레이션 (지도 기반) + + + Enables the map based wind simulation (overwrites vanilla wind) + Aktiviert die kartenbasierte Windsimulation (überschreibt Vanilla Wind) + Abilita la simulazione del vento basato sulla mappa (sovrascrive il vento vanilla) + 啟用後將遵照地圖特色進行風力模擬(覆蓋掉官方原版的風力模擬) + 启用后将遵照地图特色进行风力模拟(覆盖掉官方原版的风力模拟) + マップを基にした風シミュレーションを有効化 (標準の風を上書き) + 지도 기반의 바람 시뮬레이션을 활성화합니다 (바닐라 바람을 덮음) + diff --git a/addons/winddeflection/ACE_Settings.hpp b/addons/winddeflection/ACE_Settings.hpp index 2d6d7dfb3f..73c333479f 100644 --- a/addons/winddeflection/ACE_Settings.hpp +++ b/addons/winddeflection/ACE_Settings.hpp @@ -1,26 +1,24 @@ class ACE_Settings { class GVAR(enabled) { + category = CSTRING(windDeflection_DisplayName); displayName = CSTRING(deflectionModule_DisplayName); description = CSTRING(deflectionModule_Description); typeName = "BOOL"; value = 1; }; class GVAR(vehicleEnabled) { + category = CSTRING(windDeflection_DisplayName); displayName = CSTRING(vehicleEnabled_DisplayName); description = CSTRING(vehicleEnabled_Description); typeName = "BOOL"; value = 1; }; class GVAR(simulationInterval) { + category = CSTRING(windDeflection_DisplayName); displayName = CSTRING(simulationInterval_DisplayName); description = CSTRING(simulationInterval_Description); typeName = "SCALAR"; value = 0.05; - }; - class GVAR(simulationRadius) { - displayName = CSTRING(simulationRadius_DisplayName); - description = CSTRING(simulationRadius_Description); - typeName = "SCALAR"; - value = 3000; + sliderSettings[] = {0, 0.2, 0.05, 2}; }; }; diff --git a/addons/winddeflection/CfgVehicles.hpp b/addons/winddeflection/CfgVehicles.hpp index 866a00d9c1..e40d3eccbd 100644 --- a/addons/winddeflection/CfgVehicles.hpp +++ b/addons/winddeflection/CfgVehicles.hpp @@ -1,7 +1,7 @@ class CfgVehicles { class ACE_Module; class GVAR(ModuleSettings): ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(windDeflection_DisplayName); icon = QPATHTOF(UI\Icon_Module_Wind_ca.paa); category = "ACE"; @@ -30,15 +30,9 @@ class CfgVehicles { typeName = "NUMBER"; defaultValue = 0.05; }; - class simulationRadius { - displayName = CSTRING(simulationRadius_DisplayName); - description = CSTRING(simulationRadius_Description); - typeName = "NUMBER"; - defaultValue = 3000; - }; }; class ModuleDescription { description = CSTRING(windDeflection_Description); }; }; -}; \ No newline at end of file +}; diff --git a/addons/winddeflection/functions/fnc_handleFired.sqf b/addons/winddeflection/functions/fnc_handleFired.sqf index 2411c608d4..2ee6735053 100644 --- a/addons/winddeflection/functions/fnc_handleFired.sqf +++ b/addons/winddeflection/functions/fnc_handleFired.sqf @@ -18,9 +18,18 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && {_projectile isKindOf "BulletBase"} && {_unit isKindOf "Man"}) exitWith {false}; +if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && {_projectile isKindOf "BulletBase" && {_unit isKindOf "Man"}}) exitWith {false}; if (!((_projectile isKindOf "BulletBase") || {_projectile isKindOf "GrenadeBase"})) exitWith {false}; -if (_unit distance ACE_player > GVAR(simulationRadius)) exitWith {false}; +if (_unit distance ACE_player > 2000) exitWith {false}; + +private _abort = false; +if (!local _unit && {_projectile isKindOf "BulletBase"}) then { + private _ammoCount = (_unit ammo _muzzle) + 1; + private _tracersEvery = getNumber(configFile >> "CfgMagazines" >> _magazine >> "tracersEvery"); + private _lastRoundsTracer = getNumber(configFile >> "CfgMagazines" >> _magazine >> "lastRoundsTracer"); + _abort = _ammoCount > _lastRoundsTracer && {_tracersEvery == 0 || {(_ammoCount - _lastRoundsTracer) % _tracersEvery != 0}}; +}; +if (_abort) exitWith {false}; GVAR(trackedBullets) pushBack [_projectile, getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction")]; diff --git a/addons/winddeflection/functions/fnc_initModuleSettings.sqf b/addons/winddeflection/functions/fnc_initModuleSettings.sqf index 52847d15ee..f74ed869c6 100644 --- a/addons/winddeflection/functions/fnc_initModuleSettings.sqf +++ b/addons/winddeflection/functions/fnc_initModuleSettings.sqf @@ -25,6 +25,5 @@ if !(_activated) exitWith {}; [_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(vehicleEnabled), "vehicleEnabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(simulationInterval), "simulationInterval"] call EFUNC(common,readSettingFromModule); -[_logic, QGVAR(simulationRadius), "simulationRadius"] call EFUNC(common,readSettingFromModule); GVAR(simulationInterval) = 0 max GVAR(simulationInterval) min 0.2; diff --git a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf index 5920bbb3e4..8c55f6785f 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -24,7 +24,7 @@ _args params ["_lastTime"]; private _deltaT = CBA_missionTime - _lastTime; _args set [0, CBA_missionTime]; - private _isWind = (vectorMagnitude ACE_wind > 0); + private _isWind = (vectorMagnitude wind > 0); { _x params ["_bullet", "_airFriction"]; @@ -36,7 +36,7 @@ GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); } else { if (_isWind) then { - private _trueVelocity = _bulletVelocity vectorDiff ACE_wind; + private _trueVelocity = _bulletVelocity vectorDiff wind; private _trueSpeed = vectorMagnitude _trueVelocity; private _dragRef = _deltaT * _airFriction * _bulletSpeedSqr; diff --git a/addons/winddeflection/stringtable.xml b/addons/winddeflection/stringtable.xml index a9290c8ab0..932a4c76a1 100644 --- a/addons/winddeflection/stringtable.xml +++ b/addons/winddeflection/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -92,7 +92,7 @@ Szél-hárítás Отклонение ветром Deviazione del Vento - 風向による変化 + 風向の変化 풍향 변화 风偏 風偏 @@ -108,7 +108,7 @@ Szél-hárítás Отклонение ветром Deviazione del Vento - 風向による変化 + 風向の変化 풍향 변화 风偏 風偏 @@ -124,7 +124,7 @@ Engedélyezi a szél-hárítást Включает отклонение ветром Abilita deviazione del vento - 風向による変化を有効化 + 風向の変化を有効化 풍향 변화를 적용합니다 开启风偏效果 開啟風偏效果 @@ -156,7 +156,7 @@ Engedélyezi a szél-hárítást a statikus/jármű-lövészeknél Включает отклонение ветром для стрелков стационарных орудий и техники Abilita deviazione del vento per artiglieri di statiche/veicoli - 重火器や車両へ、風による変化を有効化 + 重火器や車両へ、風向の変化を有効化 차량이나 거치식 무기 사수에게 풍향 변화를 적용합니다 使风偏作用在固定式武器与载具炮手身上 使風偏作用在固定式武器與載具砲手身上 @@ -173,9 +173,9 @@ Интервал симуляции Intervallo Simulazione シミュレーションの間隔 - 재현 간격 模拟间隔 模擬間隔 + 시뮬레이션 간격 Defines the interval between every calculation step @@ -193,38 +193,6 @@ 定义每个计算之间的时间间隔 定義每個計算之間的時間間隔 - - Simulation Radius - Zasięg symulacji - Radio de simulación - Simulationsradius - Oblast simulace - Radio da Simulação - Rayon de simulation - Szimulációs hatókör - Радиус симуляции - Raggio Simulazione - シミュレーション半径 - 재현 범위 - 模拟半径 - 模擬半徑 - - - Defines the radius around the player (in meters) at which projectiles are wind deflected - Określa obszar naokoło gracza (w metrach), na którym pociski są znoszone przez wiatr - Define el radio alrededor del jugador (en metros) en el cual los proyectiles son desviados por el viento - Gibt den Radius (in Metern) um den Spieler an, in dem Projektile vom Wind beeinflusst werden - Definuje oblast kolem hráče (v metrech) v které je projektil ovlivněn větrem - Define o raio ao redor do jogador (em metros) em qual os projéteis são desviados pelo vento - Défini un rayon autour du joueur (en mètres) autour duquel les projectiles sont influencés par le vent - Meghatározza a játékos körüli hatókört (méterben), ahol a lövedékeket háríthatja a szél - Определяет радиус вокруг игрока (а метрах), в котором снаряды отклоняются ветром - Definisce il raggio attorno al giocatore (in metri) dove viene applicata la deviazione del vento ai proiettili - プレイヤーの周囲に適用させる風による弾道の変化の半径を定義します (メートル) - 플레이어 주위로 발사체가 풍향 변화의 영향을 받는 범위를 정합니다 (미터) - 定义玩家多少半径范围内(单位公尺)子弹会受到风偏的引响 - 定義玩家多少半徑範圍內(單位公尺)子彈會受到風偏的引響 - Wind influence on projectiles trajectory Wpływ wiatru na trajektorię lotu pocisków @@ -236,7 +204,7 @@ Szél hatása a lövedékek röppályájára Влияние втера на траекторию снарядов Influenza del vento sulla traiettoria dei proiettili - 風が弾道へ影響させます + 風を弾道へ影響させます 발사체의 궤도에 풍향 변화를 줍니다. 风力的大小会引响到弹道的轨迹 風力的大小會引響到彈道的軌跡 diff --git a/addons/yardage450/functions/fnc_acquireTarget.sqf b/addons/yardage450/functions/fnc_acquireTarget.sqf index d3709186c9..7aa5994f78 100644 --- a/addons/yardage450/functions/fnc_acquireTarget.sqf +++ b/addons/yardage450/functions/fnc_acquireTarget.sqf @@ -20,8 +20,6 @@ #define MAX_DISTANCE ([732, 800] select GVAR(useYards)) #define METERING_POINT_NUMBER 8 -private ["_result", "_distance", "_min", "_max", "_range"]; - GVAR(lasing) = true; GVAR(targetAcquired) = false; @@ -34,24 +32,17 @@ GVAR(distanceIndex) = -1; [_this select 1] call CBA_fnc_removePerFrameHandler; }; - _result = [eyePos ACE_player, ACE_player weaponDirection (currentWeapon ACE_player), ACE_player] call EFUNC(laser,shootRay); - _distance = _result select 1; - - _distance = _distance - 1 + (random 2); + ([eyePos ACE_player, ACE_player weaponDirection (currentWeapon ACE_player), ACE_player] call EFUNC(laser,shootRay)) params ["", "_distance"]; GVAR(distanceIndex) = (GVAR(distanceIndex) + 1) % METERING_POINT_NUMBER; - GVAR(distances) set [GVAR(distanceIndex), _distance]; + GVAR(distances) set [GVAR(distanceIndex), _distance - 1 + (random 2)]; if (count GVAR(distances) == METERING_POINT_NUMBER) then { - _min = MAX_DISTANCE; - _max = MIN_DISTANCE; - { - _min = _x min _min; - _max = _max max _x; - } forEach GVAR(distances); + private _min = selectMin GVAR(distances); + private _max = selectMax GVAR(distances); - if (abs(_max - _min) < 5) then { - _range = (_min + _max) / 2; + if (_max - _min < 5) then { + private _range = (_min + _max) / 2; if (_range >= MIN_DISTANCE && _range <= MAX_DISTANCE) then { GVAR(targetAcquired) = true; GVAR(targetRangeText) = Str(round(_range)); diff --git a/addons/yardage450/functions/fnc_turnOn.sqf b/addons/yardage450/functions/fnc_turnOn.sqf index 28e9c1da2d..59ed5c2ec8 100644 --- a/addons/yardage450/functions/fnc_turnOn.sqf +++ b/addons/yardage450/functions/fnc_turnOn.sqf @@ -9,7 +9,7 @@ * None * * Example: - * call ace_yardage450_fnc_acquireTarget + * call ace_yardage450_fnc_turnOn * * Public: No */ diff --git a/addons/zeus/ACE_Settings.hpp b/addons/zeus/ACE_Settings.hpp index b520b7a31a..0955fb135a 100644 --- a/addons/zeus/ACE_Settings.hpp +++ b/addons/zeus/ACE_Settings.hpp @@ -1,29 +1,34 @@ class ACE_Settings { class GVAR(zeusAscension) { + category = CSTRING(DisplayName); displayName = CSTRING(ascension_DisplayName); description = CSTRING(ascension_Description); typeName = "BOOL"; value = 0; }; class GVAR(zeusBird) { + category = CSTRING(DisplayName); displayName = CSTRING(bird_DisplayName); description = CSTRING(bird_Description); typeName = "BOOL"; value = 0; }; class GVAR(remoteWind) { + category = CSTRING(DisplayName); displayName = CSTRING(remoteWind_DisplayName); description = CSTRING(remoteWind_Description); typeName = "BOOL"; value = 0; }; class GVAR(radioOrdnance) { + category = CSTRING(DisplayName); displayName = CSTRING(radioOrdnance_DisplayName); description = CSTRING(radioOrdnance_Description); typeName = "BOOL"; value = 0; }; class GVAR(revealMines) { + category = CSTRING(DisplayName); displayName = CSTRING(revealMines_DisplayName); description = CSTRING(revealMines_Description); typeName = "SCALAR"; @@ -31,6 +36,7 @@ class ACE_Settings { values[] = {"$STR_A3_OPTIONS_DISABLED", CSTRING(revealMines_partial), CSTRING(revealMines_full)}; }; class GVAR(autoAddObjects) { + category = CSTRING(DisplayName); typeName = "BOOL"; value = 0; displayName = CSTRING(AddObjectsToCurator); diff --git a/addons/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 9918764462..49fcb9532a 100644 --- a/addons/zeus/CfgVehicles.hpp +++ b/addons/zeus/CfgVehicles.hpp @@ -16,7 +16,7 @@ class CfgVehicles { function = QFUNC(bi_moduleRemoteControl); }; class GVAR(moduleSettings): ACE_Module { - scope = 2; + scope = 1; displayName = CSTRING(Settings_DisplayName); icon = QPATHTOF(UI\Icon_Module_Zeus_Settings_ca.paa); category = "ACE"; @@ -98,14 +98,14 @@ class CfgVehicles { category = QGVAR(Repair); displayName = CSTRING(ModuleAddSpareTrack_DisplayName); function = QFUNC(moduleAddSpareTrack); - icon = QPATHTOF(UI\Icon_Module_Zeus_Medic_ca.paa);//@todo + icon = "a3\ui_f\data\IGUI\Cfg\Actions\repair_ca.paa"; }; class GVAR(moduleAddSpareWheel): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(Repair); displayName = CSTRING(ModuleAddSpareWheel_DisplayName); function = QFUNC(moduleAddSpareWheel); - icon = QPATHTOF(UI\Icon_Module_Zeus_Medic_ca.paa);//@todo + icon = "a3\ui_f\data\IGUI\Cfg\Actions\repair_ca.paa"; }; class GVAR(moduleAddOrRemoveFRIES): GVAR(moduleBase) { curatorCanAttach = 1; @@ -120,6 +120,13 @@ class CfgVehicles { function = QFUNC(moduleCaptive); icon = QPATHTOF(UI\Icon_Module_Zeus_Captive_ca.paa); }; + class GVAR(moduleConfigurePylons): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = ECSTRING(pylons,ConfigurePylons); + function = QFUNC(moduleConfigurePylons); + icon = "a3\data_f_jets\logos\jets_logo_small_ca.paa"; + }; class GVAR(moduleDefendArea): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); @@ -143,6 +150,13 @@ class CfgVehicles { displayName = CSTRING(ModuleGroupSide_DisplayName); curatorInfoType = QGVAR(RscGroupSide); }; + class GVAR(moduleLoadIntoCargo): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleLoadIntoCargo_DisplayName); + function = QFUNC(moduleLoadIntoCargo); + icon = "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa"; + }; class GVAR(modulePatrolArea): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); @@ -214,16 +228,45 @@ class CfgVehicles { function = QFUNC(moduleUnconscious); icon = QPATHTOF(UI\Icon_Module_Zeus_Unconscious_ca.paa); }; + class GVAR(moduleGarrison): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(AI); + displayName = CSTRING(ModuleGarrison_DisplayName); + curatorInfoType = QGVAR(RscGarrison); + icon = QPATHTOF(UI\Icon_Module_Zeus_Garrison_ca.paa); + }; + class GVAR(moduleUnGarrison): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(AI); + displayName = CSTRING(ModuleUnGarrison_DisplayName); + function = QFUNC(moduleUnGarrison); + icon = QPATHTOF(UI\Icon_Module_Zeus_UnGarrison_ca.paa); + }; + class GVAR(moduleToggleNvg): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(AI); + displayName = CSTRING(moduleToggleNVG_DisplayName); + curatorInfoType = QGVAR(RscToggleNvg); + }; + class GVAR(moduleToggleFlashlight): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(AI); + displayName = CSTRING(moduleToggleFlashlight_DisplayName); + curatorInfoType = QGVAR(RscToggleFlashlight); + }; class GVAR(AddFullArsenal): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(Utility); - displayName = CSTRING(moduleAddFullArsenal_displayName); + displayName = CSTRING(ModuleAddFullArsenal_DisplayName); function = QFUNC(moduleAddArsenal); }; class GVAR(RemoveFullArsenal): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(Utility); - displayName = CSTRING(moduleRemoveArsenal_displayName); + displayName = CSTRING(ModuleRemoveArsenal_DisplayName); function = QFUNC(moduleRemoveArsenal); }; + class ModuleArsenal_F: Module_F { + function=QFUNC(bi_moduleArsenal); + }; }; diff --git a/addons/zeus/XEH_PREP.hpp b/addons/zeus/XEH_PREP.hpp index a3f269f638..aba07e7114 100644 --- a/addons/zeus/XEH_PREP.hpp +++ b/addons/zeus/XEH_PREP.hpp @@ -1,5 +1,6 @@ PREP(addObjectToCurator); +PREP(bi_moduleArsenal); PREP(bi_moduleCurator); PREP(bi_moduleMine); PREP(bi_moduleProjectile); @@ -11,8 +12,11 @@ PREP(moduleAddSpareTrack); PREP(moduleAddSpareWheel); PREP(moduleAddOrRemoveFRIES); PREP(moduleCaptive); +PREP(moduleConfigurePylons); +PREP(moduleGarrison); PREP(moduleGlobalSetSkill); PREP(moduleGroupSide); +PREP(moduleLoadIntoCargo); PREP(moduleRemoveArsenal); PREP(moduleSearchNearby); PREP(moduleSetMedic); @@ -23,17 +27,23 @@ PREP(moduleSuppressiveFire); PREP(moduleSuppressiveFireLocal); PREP(moduleSurrender); PREP(moduleTeleportPlayers); +PREP(moduleToggleFlashlight); +PREP(moduleToggleNvg); PREP(moduleUnconscious); +PREP(moduleUnGarrison); PREP(moduleZeusSettings); PREP(showMessage); PREP(ui_attributeCargo); //PREP(ui_attributePosition); PREP(ui_attributeRadius); PREP(ui_defendArea); +PREP(ui_garrison); PREP(ui_editableObjects); PREP(ui_globalSetSkill); PREP(ui_groupSide); PREP(ui_patrolArea); PREP(ui_searchArea); PREP(ui_teleportPlayers); +PREP(ui_toggleFlashlight); +PREP(ui_toggleNvg); PREP(zeusAttributes); diff --git a/addons/zeus/XEH_postInit.sqf b/addons/zeus/XEH_postInit.sqf index adf3d75a9b..5929e8664e 100644 --- a/addons/zeus/XEH_postInit.sqf +++ b/addons/zeus/XEH_postInit.sqf @@ -16,6 +16,10 @@ QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); [QGVAR(moduleSearchNearby), CBA_fnc_searchNearby] call CBA_fnc_addEventHandler; [QGVAR(moduleSearchArea), CBA_fnc_taskSearchArea] call CBA_fnc_addEventHandler; [QGVAR(suppressiveFire), LINKFUNC(moduleSuppressiveFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(enableFlashlight), { + params ["_unit", "_mode"]; + _unit enableGunLights _mode; +}] call CBA_fnc_addEventHandler; // Editable object commands must be ran on server, this events are used in the respective module if (isServer) then { diff --git a/addons/zeus/config.cpp b/addons/zeus/config.cpp index d81ac5c074..5b764b6007 100644 --- a/addons/zeus/config.cpp +++ b/addons/zeus/config.cpp @@ -4,13 +4,20 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = { + QGVAR(moduleConfigurePylons), QGVAR(moduleDefendArea), QGVAR(moduleEditableObjects), QGVAR(moduleGlobalSetSkill), QGVAR(moduleGroupSide), + QGVAR(moduleLoadIntoCargo), QGVAR(modulePatrolArea), QGVAR(moduleSearchArea), QGVAR(moduleSearchNearby), + QGVAR(moduleGarrison), + QGVAR(moduleUnGarrison), + QGVAR(moduleTeleportPlayers), + QGVAR(moduleToggleNvg), + QGVAR(moduleToggleFlashlight), QGVAR(moduleSimulation), QGVAR(moduleSuppressiveFire), QGVAR(AddFullArsenal), @@ -19,12 +26,13 @@ class CfgPatches { }; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_common", "ace_ai"}; author = ECSTRING(common,ACETeam); authors[] = {"SilentSpike"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; + // Use additional CfgPatches to contextually remove modules from zeus class GVAR(captives): ADDON { units[] = { @@ -40,6 +48,11 @@ class CfgPatches { QGVAR(moduleSetMedicalFacility) }; }; + class GVAR(cargo): ADDON { + units[] = { + QGVAR(moduleLoadIntoCargo) + }; + }; class GVAR(cargoAndRepair): ADDON { units[] = { QGVAR(moduleAddSpareTrack), @@ -51,13 +64,20 @@ class CfgPatches { QGVAR(moduleAddOrRemoveFRIES) }; }; + class GVAR(pylons): ADDON { + units[] = { + QGVAR(moduleConfigurePylons) + }; + }; }; class ACE_Curator { GVAR(captives) = "ace_captives"; GVAR(medical) = "ace_medical"; + GVAR(cargo) = "ace_cargo"; GVAR(cargoAndRepair)[] = {"ace_cargo", "ace_repair"}; GVAR(fastroping) = "ace_fastroping"; + GVAR(pylons) = "ace_pylons"; }; #include "CfgFactionClasses.hpp" diff --git a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf new file mode 100644 index 0000000000..2990d42633 --- /dev/null +++ b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf @@ -0,0 +1,66 @@ +/* + * Author: Bohemia Interactive + * Module function to open a full arsenal on a unit + * Edited to use ACE arsenal when present, moved isPlayer check + * + * Arguments: + * 0: The module logic + * 1: Not used + * 2: activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, nil, true] call ace_zeus_fnc_bi_moduleArsenal + * + * Public: No +*/ + +#include "script_component.hpp" + +params ["_logic", "", "_activated"]; + +if (_activated && local _logic) then { + _unit = _logic getvariable ["bis_fnc_curatorAttachObject_object",objnull]; + + //--- Check if the unit is suitable + _error = ""; + switch true do { + case (isnull _unit): {_error = localize "str_a3_BIS_fnc_showCuratorFeedbackMessage_506";}; + case !(alive _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorDead";}; + case (isnull group _unit || !(side group _unit in [east,west,resistance,civilian])): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorBrain";}; + case (vehicle _unit != _unit || effectivecommander _unit != _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorVehicle";}; + }; + + if (_error == "") then { + if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { + if (!isPlayer _unit || {player == _unit}) then { + + [{ + params ["_unit"]; + + [_unit, _unit, true] call EFUNC(arsenal,openBox); + }, [_unit]] call CBA_fnc_directCall; + } else { + + [objNull, localize "str_a3_BIS_fnc_moduleArsenal_errorDead"] call bis_fnc_showCuratorFeedbackMessage; + }; + } else { + if !(isPlayer _unit) then { + + ([] call bis_fnc_rscLayer) cuttext ["","black out",0.5]; + ["#(argb,8,8,3)color(0,0,0,1)",false,nil,0,[0.5,0]] call bis_fnc_textTiles; + ["Open",[true,nil,_unit]] call bis_fnc_arsenal; + ([] call bis_fnc_rscLayer) cuttext ["","plain"]; + } else { + + [objNull, localize "str_a3_BIS_fnc_moduleArsenal_errorDead"] call bis_fnc_showCuratorFeedbackMessage; + }; + }; + } else { + + [objNull,_error] call bis_fnc_showCuratorFeedbackMessage; + }; + deleteVehicle _logic; +}; diff --git a/addons/zeus/functions/fnc_bi_moduleMine.sqf b/addons/zeus/functions/fnc_bi_moduleMine.sqf index 434130ffe6..1c85706d09 100644 --- a/addons/zeus/functions/fnc_bi_moduleMine.sqf +++ b/addons/zeus/functions/fnc_bi_moduleMine.sqf @@ -22,7 +22,7 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - _explosive = gettext (configFile >> "CfgVehicles" >> typeOf _logic >> "explosive"); + _explosive = gettext (configfile >> "cfgvehicles" >> typeof _logic >> "explosive"); if (_explosive != "") then { _explosive = createvehicle [_explosive,position _logic,[],0,"none"]; _explosive attachto [_logic]; @@ -44,7 +44,7 @@ if (_activated) then { //--- Show hint to curator who placed the object [[["Curator","PlaceMines"],nil,nil,nil,nil,nil,nil,true],"bis_fnc_advHint",_logic] call bis_fnc_mp; - waitUntil {sleep 0.1; isnull _explosive || isnull _logic || !alive _logic}; + waituntil {sleep 0.1; isnull _explosive || isnull _logic || !alive _logic}; if (isnull _logic) then {deletevehicle _explosive;} else {_explosive setdamage 1;}; deletevehicle _logic; }; diff --git a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf index eaad90c6d6..3d974c126c 100644 --- a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf +++ b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf @@ -20,33 +20,30 @@ #include "script_component.hpp" -_fnc_scriptNameParentTemp = if !(isNil '_fnc_scriptName') then {_fnc_scriptName} else {'BIS_fnc_moduleProjectile'}; -private _fnc_scriptNameParent = _fnc_scriptNameParentTemp; -_fnc_scriptNameParentTemp = nil; - -private _fnc_scriptName = 'BIS_fnc_moduleProjectile'; -scriptname _fnc_scriptName; - -params ["_logic", "_units", "_activated"]; +_logic = _this select 0; +_units = _this select 1; +_activated = _this select 2; if ({local _x} count (objectcurators _logic) > 0) then { //--- Reveal the circle to curators _logic hideobject false; _logic setpos position _logic; }; -if !(isserver) exitWith {}; +if !(isserver) exitwith {}; if (_activated) then { - _ammo = _logic getVariable ["type",gettext (configFile >> "CfgVehicles" >> typeOf _logic >> "ammo")]; + _ammo = _logic getvariable ["type",gettext (configfile >> "cfgvehicles" >> typeof _logic >> "ammo")]; if (_ammo != "") then { - _CfgAmmo = configFile >> "CfgAmmo" >> _ammo; - _dirVar = _fnc_scriptname + typeOf _logic; - _logic setdir (missionnamespace getVariable [_dirVar,direction _logic]); //--- Restore custom direction + _cfgAmmo = configfile >> "cfgammo" >> _ammo; + //if !(isclass _cfgAmmo) exitwith {["CfgAmmo class '%1' not found.",_ammo] call bis_fnc_error;}; + // It seems BI broke this part... + // _dirVar = _fnc_scriptname + typeof _logic; + // _logic setdir (missionnamespace getvariable [_dirVar,direction _logic]); //--- Restore custom direction _pos = getposatl _logic; _posAmmo = +_pos; _posAmmo set [2,0]; _dir = direction _logic; - _simulation = tolower gettext (configFile >> "CfgAmmo" >> _ammo >> "simulation"); + _simulation = tolower gettext (configfile >> "cfgammo" >> _ammo >> "simulation"); _altitude = 0; _velocity = []; _attach = false; @@ -107,15 +104,15 @@ if (_activated) then { }; }; }; - } forEach _entities; + } foreach _entities; }; }; - if (count _hint > 0 && {count objectCurators _logic > 0}) then { + if (count _hint > 0 && {count objectcurators _logic > 0}) then { [[_hint,nil,nil,nil,nil,nil,nil,true],"bis_fnc_advHint",objectcurators _logic] call bis_fnc_mp; }; if (count _velocity == 3) then { - _altitude = (_logic getVariable ["altitude",_altitude]) call bis_fnc_parsenumber; - _radio = _logic getVariable ["radio",_radio]; + _altitude = (_logic getvariable ["altitude",_altitude]) call bis_fnc_parsenumber; + _radio = _logic getvariable ["radio",_radio]; //--- Create projectile _posAmmo set [2,_altitude]; @@ -124,7 +121,7 @@ if (_activated) then { _projectile setvelocity _velocity; if (_attach) then {_projectile attachto [_logic,[0,0,_altitude]];}; - // Added by ace_zeus for ace_frag compatibility + // Added by ace_zeus for ace_frag compatibility if (!isNil QEFUNC(frag,addPfhRound)) then { [objNull, _ammo, _projectile, true] call EFUNC(frag,addPfhRound); }; @@ -143,13 +140,13 @@ if (_activated) then { //--- Update if (_attach) then { - waitUntil { + waituntil { _soundSource setposatl getposatl _projectile; sleep 1; isnull _projectile || isnull _logic }; } else { - waitUntil { + waituntil { _soundSource setposatl getposatl _projectile; if (getposatl _logic distance _pos > 0 || direction _logic != _dir) then { @@ -161,7 +158,7 @@ if (_activated) then { _projectile setposasl _posNew; _pos = getposatl _logic; _dir = direction _logic; - missionnamespace setVariable [_dirVar,_dir]; + missionnamespace setvariable [_dirVar,_dir]; }; sleep 0.1; isnull _projectile || isnull _logic @@ -180,7 +177,7 @@ if (_activated) then { } else { //--- Repeat to achieve permanent effect - _repeat = _logic getVariable ["repeat",0] > 0; + _repeat = _logic getvariable ["repeat",0] > 0; if (_repeat) then { [_logic,_units,_activated] call bis_fnc_moduleprojectile; } else { @@ -191,6 +188,6 @@ if (_activated) then { deletevehicle _logic; }; } else { - ["Cannot create projectile, 'ammo' config attribute is missing in %1",typeOf _logic] call bis_fnc_error; + ["Cannot create projectile, 'ammo' config attribute is missing in %1",typeof _logic] call bis_fnc_error; }; }; diff --git a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf index 6d2d3fd950..994b445d8d 100644 --- a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf +++ b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf @@ -34,13 +34,16 @@ if (_activated && local _logic && !isnull curatorcamera) then { if ((_mouseOver select 0) == typename objnull) then {_unit = _mouseOver select 1;}; _unit = effectivecommander _unit; + //--- Temp owner + private _tempOwner = _unit getvariable ["bis_fnc_moduleRemoteControl_owner", objnull]; + //--- Check if the unit is suitable _error = ""; if !(side group _unit in [east,west,resistance,civilian]) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorEmpty";}; if (isplayer _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer";}; if !(alive _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorDestroyed";}; if (isnull _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorNull";}; - if !(isnull (_unit getvariable ["bis_fnc_moduleRemoteControl_owner",objnull])) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorControl";}; + if (!isnull _tempOwner && {_tempOwner in allPlayers}) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorControl";}; if (isuavconnected vehicle _unit) then {_error = localize "str_a3_cfgvehicles_moduleremotecontrol_f_errorControl";}; if (_error == "") then { diff --git a/addons/zeus/functions/fnc_getModuleDestination.sqf b/addons/zeus/functions/fnc_getModuleDestination.sqf index d6a19d69b1..f29b42550c 100644 --- a/addons/zeus/functions/fnc_getModuleDestination.sqf +++ b/addons/zeus/functions/fnc_getModuleDestination.sqf @@ -5,10 +5,16 @@ * Arguments: * 0: The souce object * 1: Code to run when position is ready - * - Code is passed [0: Successful , 1: Object , 2: Position ASL ] - * 2: Text - * 3: Icon image file - * 4: Icon color + * - Code is passed + * 0: Successful + * 1: Object + * 2: Position ASL + * 3: State of Shift + * 4: State of Ctrl + * 5: State of Alt + * 2: Text (default: "") + * 3: Icon image file (default: "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa") + * 4: Icon color (default: [1,0,0,1]) * * Return Value: * None @@ -23,17 +29,22 @@ params ["_object", "_code", ["_text", ""], ["_icon", "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa"], ["_color", [1,0,0,1]]]; if (missionNamespace getVariable [QGVAR(moduleDestination_running), false]) exitWith { - [false, _object, [0,0,0]] call _code; + [false, _object, [0,0,0], false, false, false] call _code; ERROR("getModuleDestination already running"); }; GVAR(moduleDestination_running) = true; // Add mouse button eh for the zeus display (triggered from 2d or 3d) -GVAR(moduleDestination_displayEH) = [(findDisplay 312), "mouseButtonDown", { - params ["", "_mouseButton"]; +GVAR(moduleDestination_displayEHMouse) = [findDisplay 312, "mouseButtonDown", { + params ["", "_mouseButton", "", "", "_shift", "_ctrl", "_alt"]; + if (_mouseButton != 0) exitWith {}; // Only watch for LMB + + //IGNORE_PRIVATE_WARNING ["_thisArgs"] _thisArgs params ["_object", "_code"]; + + // Get mouse position on 2D map or 3D world private _mousePosASL = if (ctrlShown ((findDisplay 312) displayCtrl 50)) then { private _pos2d = (((findDisplay 312) displayCtrl 50) ctrlMapScreenToWorld getMousePosition); _pos2d set [2, getTerrainHeightASL _pos2d]; @@ -42,13 +53,39 @@ GVAR(moduleDestination_displayEH) = [(findDisplay 312), "mouseButtonDown", { AGLToASL (screenToWorld getMousePosition); }; TRACE_2("placed",_object,_mousePosASL); - [true, _object, _mousePosASL] call _code; + + [true, _object, _mousePosASL, _shift, _ctrl, _alt] call _code; GVAR(moduleDestination_running) = false; }, [_object, _code]] call CBA_fnc_addBISEventHandler; -// Add draw eh for the zeus map - draws the 2d icon and line +// Add key eh for the zeus display (triggered from 2d or 3d) +GVAR(moduleDestination_displayEHKeyboard) = [findDisplay 312, "KeyDown", { + params ["", "_keyCode", "_shift", "_ctrl", "_alt"]; + + if (_keyCode != 1) exitWith {}; // Only watch for ESC + + //IGNORE_PRIVATE_WARNING ["_thisArgs"] + _thisArgs params ["_object", "_code"]; + + // Get mouse position on 2D map or 3D world + private _mousePosASL = if (ctrlShown ((findDisplay 312) displayCtrl 50)) then { + private _pos2d = (((findDisplay 312) displayCtrl 50) ctrlMapScreenToWorld getMousePosition); + _pos2d set [2, getTerrainHeightASL _pos2d]; + _pos2d + } else { + AGLToASL (screenToWorld getMousePosition); + }; + TRACE_2("aborted",_object,_mousePosASL); + + [false, _object, _mousePosASL, _shift, _ctrl, _alt] call _code; + GVAR(moduleDestination_running) = false; + true +}, [_object, _code]] call CBA_fnc_addBISEventHandler; + +// Add draw EH for the zeus map - draws the 2D icon and line GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", { params ["_mapCtrl"]; + //IGNORE_PRIVATE_WARNING ["_thisArgs"] _thisArgs params ["_object", "_text", "_icon", "_color"]; private _pos2d = (((findDisplay 312) displayCtrl 50) ctrlMapScreenToWorld getMousePosition); @@ -56,12 +93,13 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", _mapCtrl drawLine [getPos _object, _pos2d, _color]; }, [_object, _text, _icon, _color]] call CBA_fnc_addBISEventHandler; +// Add draw EH for 3D camera view - draws the 3D icon and line [{ (_this select 0) params ["_object", "_code", "_text", "_icon", "_color"]; if ((isNull _object) || {isNull findDisplay 312} || {!isNull findDisplay 49}) then { TRACE_3("null-exit",isNull _object,isNull findDisplay 312,isNull findDisplay 49); GVAR(moduleDestination_running) = false; - [false, _object, [0,0,0]] call _code; + [false, _object, [0,0,0], false, false, false] call _code; }; if (GVAR(moduleDestination_running)) then { // Draw the 3d icon and line @@ -69,11 +107,13 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", drawIcon3D [_icon, _color, _mousePosAGL, 1.5, 1.5, 45, _text]; drawLine3D [_mousePosAGL, ASLtoAGL (getPosASL _object), _color];; } else { - TRACE_3("cleaning up",_this select 1, GVAR(moduleDestination_displayEH), GVAR(moduleDestination_mapDrawEH)); + TRACE_4("cleaning up",_this select 1,GVAR(moduleDestination_displayEHMouse),GVAR(moduleDestination_displayEHKeyboard),GVAR(moduleDestination_mapDrawEH)); (_this select 1) call CBA_fnc_removePerFrameHandler; - (findDisplay 312) displayRemoveEventHandler ["mouseButtonDown", GVAR(moduleDestination_displayEH)]; + (findDisplay 312) displayRemoveEventHandler ["mouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; + (findDisplay 312) displayRemoveEventHandler ["KeyDown", GVAR(moduleDestination_displayEHKeyboard)]; ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["draw", GVAR(moduleDestination_mapDrawEH)]; - GVAR(moduleDestination_displayEH) = nil; + GVAR(moduleDestination_displayEHMouse) = nil; + GVAR(moduleDestination_displayEHKeyboard) = nil; GVAR(moduleDestination_mapDrawEH) = nil; }; }, 0, [_object, _code, _text, _icon, _color]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf b/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf index 8c0c4370d2..05c5de668e 100644 --- a/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf +++ b/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf @@ -22,32 +22,26 @@ #include "script_component.hpp" -private ["_removeAddons", "_numCfgs", "_cfg", "_requiredAddon"]; - if !(isClass (configFile >> "ACE_Curator")) exitWith { ERROR("The ACE_Curator class does not exist") }; params ["_logic"]; -_removeAddons = []; -_numCfgs = count (configFile >> "ACE_Curator"); -for "_n" from 0 to (_numCfgs - 1) do { - _cfg = (configFile >> "ACE_Curator") select _n; - - if (isArray _cfg) then { - _requiredAddon = getArray _cfg; +private _removeAddons = []; +{ + private _addon = _x; + if (isArray _addon) then { { if !(isClass (configFile >> "CfgPatches" >> _x)) exitWith { - _removeAddons pushBack (configName _cfg); + _removeAddons pushBack (configName _addon); }; - } forEach _requiredAddon; + } forEach (getArray _addon); }; - if (isText _cfg) then { - _requiredAddon = getText _cfg; - if !(isClass (configFile >> "CfgPatches" >> _requiredAddon)) then { - _removeAddons pushBack (configName _cfg); + if (isText _addon) then { + if !(isClass (configFile >> "CfgPatches" >> getText _addon)) then { + _removeAddons pushBack (configName _addon); }; }; -}; +} forEach configProperties [configFile >> "ACE_Curator"]; _logic removeCuratorAddons _removeAddons; diff --git a/addons/zeus/functions/fnc_moduleAddArsenal.sqf b/addons/zeus/functions/fnc_moduleAddArsenal.sqf index b8eed64d76..68b5148521 100644 --- a/addons/zeus/functions/fnc_moduleAddArsenal.sqf +++ b/addons/zeus/functions/fnc_moduleAddArsenal.sqf @@ -29,9 +29,15 @@ switch (true) do { [LSTRING(OnlyAlive)] call FUNC(showMessage); }; default { - TRACE_1("BIS_fnc_arsenal: AmmoboxInit",_object); - // Global Effects: "Action to access the Arsenal will be added automatically on all clients." - ["AmmoboxInit", [_object, true]] call BIS_fnc_arsenal; + if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { + + [_object, true, true] call EFUNC(arsenal,initBox); + } else { + + TRACE_1("BIS_fnc_arsenal: AmmoboxInit",_object); + // Global Effects: "Action to access the Arsenal will be added automatically on all clients." + ["AmmoboxInit", [_object, true]] call BIS_fnc_arsenal; + }; }; }; diff --git a/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf b/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf index 5b05d256f4..6f60f80947 100644 --- a/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf +++ b/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf @@ -17,9 +17,9 @@ */ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; +params ["_logic"]; -if !(_activated && {local _logic}) exitWith {}; +if !(local _logic) exitWith {}; if !(["ace_fastroping"] call EFUNC(common,isModLoaded)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf index 56d3dca9d9..ed633c2033 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf @@ -17,9 +17,9 @@ */ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ace_cargo"] call EFUNC(common,isModLoaded) && ["ace_repair"] call EFUNC(common,isModLoaded)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf index da9327af7a..58cd6c1063 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf @@ -17,9 +17,9 @@ */ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ace_cargo"] call EFUNC(common,isModLoaded) && ["ace_repair"] call EFUNC(common,isModLoaded)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleCaptive.sqf b/addons/zeus/functions/fnc_moduleCaptive.sqf index dc216e6289..317c785f20 100644 --- a/addons/zeus/functions/fnc_moduleCaptive.sqf +++ b/addons/zeus/functions/fnc_moduleCaptive.sqf @@ -18,20 +18,19 @@ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_captive"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if (isNil QEFUNC(captives,setHandcuffed)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { - _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - _unit = effectivecommander (_mouseOver select 1); + private _unit = effectivecommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); @@ -39,7 +38,7 @@ if (isNil QEFUNC(captives,setHandcuffed)) then { if !(alive _unit) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { - _captive = GETVAR(_unit,EGVAR(captives,isHandcuffed),false); + private _captive = GETVAR(_unit,EGVAR(captives,isHandcuffed),false); // Event initalized by ACE_Captives [QEGVAR(captives,setHandcuffed), [_unit, !_captive], _unit] call CBA_fnc_targetEvent; }; diff --git a/addons/zeus/functions/fnc_moduleConfigurePylons.sqf b/addons/zeus/functions/fnc_moduleConfigurePylons.sqf new file mode 100644 index 0000000000..404605451e --- /dev/null +++ b/addons/zeus/functions/fnc_moduleConfigurePylons.sqf @@ -0,0 +1,37 @@ +/* + * Author: 654wak654 + * Opens the pylon configuration menu for the aircraft module is placed on. + * + * Arguments: + * 0: Module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleConfigurePylons + * + * Public: No + */ +#include "script_component.hpp" + +if (canSuspend) exitWith {[FUNC(moduleConfigurePylons), _this] call CBA_fnc_directCall;}; + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _aircraft = attachedTo _logic; + +deleteVehicle _logic; + +if (isNull _aircraft) exitWith { + [LSTRING(NothingSelected)] call FUNC(showMessage); +}; +if (!alive _aircraft) exitWith { + [LSTRING(OnlyAlive)] call FUNC(showMessage); +}; + +[_aircraft, true] call EFUNC(pylons,showDialog); diff --git a/addons/zeus/functions/fnc_moduleGarrison.sqf b/addons/zeus/functions/fnc_moduleGarrison.sqf new file mode 100644 index 0000000000..2762102d0c --- /dev/null +++ b/addons/zeus/functions/fnc_moduleGarrison.sqf @@ -0,0 +1,62 @@ +/* + * Author: alganthe + * Module calling the garrison function. + * + * Arguments: + * 0: Module logic + * 1: Position of the module + * 2: Radius of the task + * 3: Filling mode of the garrison function + * 4: Enable or not top down filling + * + * Return Value: + * None + * + * Example: + * [LOGIC, [2203.64, 2281.47, 1], 20, 2, true] call ace_zeus_fnc_moduleGarrison + * + * Public: No +*/ + +#include "script_component.hpp" + +params ["_logic", "_pos", "_radius" ,"_mode" , "_topDownMode", "_teleport"]; + +private _unit = (attachedTo _logic); +private _building = nearestBuilding (getPosASL _unit); + +// Handles errors +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +switch (false) do { + case !(isNull _unit): { + [LSTRING(NothingSelected)] call _fnc_errorAndClose; + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + case (_unit distance _building < 500): { + [LSTRING(BuildingTooFar)] call _fnc_errorAndClose; + }; +}; + +private _units = units _unit; +// Make sure all units are disembarked +{ + if (vehicle _x != _x) then { + moveOut _x; + }; +} forEach _units; + +[_pos, ["Building"], _units, _radius, _mode, _topDownMode, _teleport] call EFUNC(ai,garrison); + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf b/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf index ce864e85b0..1d4e2769b8 100644 --- a/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf +++ b/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf @@ -17,8 +17,8 @@ #include "script_component.hpp" -_this params ["_varName","_varValue"]; -_varValue params ["_general","_accuracy","_handling","_spotting","_cover","_combat"]; +params ["_varName", "_varValue"]; +_varValue params ["_general", "_accuracy", "_handling", "_spotting", "_cover", "_combat"]; TRACE_1("Params",_this); TRACE_6("AI settings updated",GVAR(GlobalSkillAI)); diff --git a/addons/zeus/functions/fnc_moduleGroupSide.sqf b/addons/zeus/functions/fnc_moduleGroupSide.sqf index 050b92a9fc..2a52df09da 100644 --- a/addons/zeus/functions/fnc_moduleGroupSide.sqf +++ b/addons/zeus/functions/fnc_moduleGroupSide.sqf @@ -17,7 +17,7 @@ #include "script_component.hpp" -params ["_unit","_newSide"]; +params ["_unit", "_newSide"]; private _side = side _unit; // Nothing to do here diff --git a/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf b/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf new file mode 100644 index 0000000000..33ceb703a1 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf @@ -0,0 +1,66 @@ +/* + * Author: 654wak654 + * Loads the object module is placed on into selected vehicle. + * + * Arguments: + * 0: Module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleLoadIntoCargo + * + * Public: No + */ +#include "script_component.hpp" + +if (canSuspend) exitWith {[FUNC(moduleLoadIntoCargo), _this] call CBA_fnc_directCall;}; + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _cargo = attachedTo _logic; + +deleteVehicle _logic; + +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { + [LSTRING(RequiresAddon)] call FUNC(showMessage); +}; +if (isNull _cargo) exitWith { + [LSTRING(NothingSelected)] call FUNC(showMessage); +}; +if (!alive _cargo) exitWith { + [LSTRING(OnlyAlive)] call FUNC(showMessage); +}; + +[ + _cargo, + { + params ["_successful", "_cargo", "_mousePosASL"]; + if (!_successful) exitWith {}; + + private _holder = (nearestObjects [ASLToAGL _mousePosASL, EGVAR(cargo,cargoHolderTypes), 5]) param [0, objNull]; + if (isNull _holder) exitWith { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + if (!alive _holder) exitWith { + [LSTRING(OnlyAlive)] call FUNC(showMessage); + }; + + private _displayName = [_cargo] call EFUNC(common,getName); + if ([_cargo, _holder] call EFUNC(cargo,loadItem)) then { + private _loadedItem = [localize ELSTRING(cargo,LoadedItem), "
", " "] call CBA_fnc_replace; + private _holderDisplayName = [_holder] call EFUNC(common,getName); + [_loadedItem, _displayName, _holderDisplayName] call FUNC(showMessage); + } else { + private _loadingFailed = [localize ELSTRING(cargo,LoadingFailed), "
", " "] call CBA_fnc_replace; + [_loadingFailed, _displayName] call FUNC(showMessage); + }; + }, + localize LSTRING(ModuleLoadIntoCargo_DisplayName), + "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa" +] call FUNC(getModuleDestination); diff --git a/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf index 9e267e4cf5..b14509c272 100644 --- a/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf +++ b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf @@ -30,11 +30,18 @@ switch (true) do { [LSTRING(OnlyAlive)] call FUNC(showMessage); }; default { - TRACE_1("Calling removeVirtualXXXCargo functions",_object); - [_object, (_object call BIS_fnc_getVirtualItemCargo), true] call BIS_fnc_removeVirtualItemCargo; - [_object, (_object call BIS_fnc_getVirtualWeaponCargo), true] call BIS_fnc_removeVirtualWeaponCargo; - [_object, (_object call BIS_fnc_getVirtualMagazineCargo), true] call BIS_fnc_removeVirtualMagazineCargo; - [_object, (_object call BIS_fnc_getVirtualBackpackCargo), true] call BIS_fnc_removeVirtualBackpackCargo; + + if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { + + [_object, true, true] call EFUNC(arsenal,removeBox); + } else { + + TRACE_1("Calling removeVirtualXXXCargo functions",_object); + [_object, (_object call BIS_fnc_getVirtualItemCargo), true] call BIS_fnc_removeVirtualItemCargo; + [_object, (_object call BIS_fnc_getVirtualWeaponCargo), true] call BIS_fnc_removeVirtualWeaponCargo; + [_object, (_object call BIS_fnc_getVirtualMagazineCargo), true] call BIS_fnc_removeVirtualMagazineCargo; + [_object, (_object call BIS_fnc_getVirtualBackpackCargo), true] call BIS_fnc_removeVirtualBackpackCargo; + }; }; }; diff --git a/addons/zeus/functions/fnc_moduleSearchNearby.sqf b/addons/zeus/functions/fnc_moduleSearchNearby.sqf index 30d545e6d9..a73dbd7fe8 100644 --- a/addons/zeus/functions/fnc_moduleSearchNearby.sqf +++ b/addons/zeus/functions/fnc_moduleSearchNearby.sqf @@ -18,9 +18,9 @@ #include "script_component.hpp" -params ["_logic","_units","_activated"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; //Validate the module target: private _unit = effectiveCommander (attachedTo _logic); diff --git a/addons/zeus/functions/fnc_moduleSetMedic.sqf b/addons/zeus/functions/fnc_moduleSetMedic.sqf index c9dba36e40..b2cd233bc7 100644 --- a/addons/zeus/functions/fnc_moduleSetMedic.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedic.sqf @@ -18,20 +18,19 @@ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_medicN"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { - _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - _unit = effectivecommander (_mouseOver select 1); + private _unit = effectivecommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); @@ -42,7 +41,7 @@ if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - _medicN = GETVAR(_unit,EGVAR(medical,medicClass),0); + private _medicN = GETVAR(_unit,EGVAR(medical,medicClass),0); if (_medicN < 1) then { _unit setVariable [QEGVAR(medical,medicClass), 1, true]; }; diff --git a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf index 479cfad803..4977b21986 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf @@ -18,20 +18,19 @@ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { - _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - _unit = (_mouseOver select 1); + private _unit = (_mouseOver select 1); if (_unit isKindOf "Man" || {!(_unit isKindOf "Building")}) then { [LSTRING(OnlyStructures)] call FUNC(showMessage); diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index c295b609d2..a819a15d9e 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -18,20 +18,19 @@ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_medicN"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { - _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - _unit = (_mouseOver select 1); + private _unit = (_mouseOver select 1); if (_unit isKindOf "Man" || {_unit isKindOf "Building"}) then { [LSTRING(OnlyVehicles)] call FUNC(showMessage); @@ -42,7 +41,7 @@ if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - _medicN = GETVAR(_unit,EGVAR(medical,medicClass),0); + private _medicN = GETVAR(_unit,EGVAR(medical,medicClass),0); if (_medicN < 1) then { _unit setVariable [QEGVAR(medical,medicClass), 1, true]; }; diff --git a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf index 1d510fec55..b2c9ba88a7 100644 --- a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf +++ b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf @@ -3,7 +3,7 @@ * Commands the selected unit or group to start suppressive fire on the unit, group or location the module is placed on * * Arguments: - * 0: The module logic + * 0: Module logic * 1: Synchronized units * 2: Activated * @@ -22,7 +22,7 @@ if (canSuspend) exitWith {[FUNC(moduleSuppressiveFire), _this] call CBA_fnc_dire params ["_logic", "_units", "_activated"]; -if !(_activated && local _logic) exitWith {}; +if !(_activated && {local _logic}) exitWith {}; // Validate the module target private _unit = effectiveCommander (attachedTo _logic); @@ -34,7 +34,7 @@ if (isNull _unit) exitWith { [LSTRING(NothingSelected)] call FUNC(showMessage); }; if (!alive _unit) exitWith { - [localize LSTRING(OnlyAlive)] call FUNC(showMessage); + [LSTRING(OnlyAlive)] call FUNC(showMessage); }; if ([_unit] call EFUNC(common,isPlayer)) exitWith { ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call FUNC(showMessage); @@ -43,8 +43,7 @@ if ([_unit] call EFUNC(common,isPlayer)) exitWith { [_unit, { params ["_successful", "_unit", "_mousePosASL"]; TRACE_3("getModuleDestination return",_successful,_unit,_mousePosASL); - if (!_successful) exitWith {}; - if (!alive _unit) exitWith {}; + if !(_successful && {alive _unit}) exitWith {}; private _vehicle = vehicle _unit; private _targetASL = _mousePosASL vectorAdd [0,0,0.6]; // mouse pos is at ground level zero, raise up a bit; @@ -117,4 +116,4 @@ if ([_unit] call EFUNC(common,isPlayer)) exitWith { }; #endif -}, (localize LSTRING(ModuleSuppressiveFire_DisplayName))] call FUNC(getModuleDestination); +}, localize LSTRING(ModuleSuppressiveFire_DisplayName)] call FUNC(getModuleDestination); diff --git a/addons/zeus/functions/fnc_moduleSurrender.sqf b/addons/zeus/functions/fnc_moduleSurrender.sqf index b97d2715ff..fceb72b57f 100644 --- a/addons/zeus/functions/fnc_moduleSurrender.sqf +++ b/addons/zeus/functions/fnc_moduleSurrender.sqf @@ -18,20 +18,19 @@ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_surrendering"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if (isNil QEFUNC(captives,setSurrendered)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { - _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - _unit = effectivecommander (_mouseOver select 1); + private _unit = effectivecommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); @@ -42,7 +41,7 @@ if (isNil QEFUNC(captives,setSurrendered)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - _surrendering = GETVAR(_unit,EGVAR(captives,isSurrendering),false); + private _surrendering = GETVAR(_unit,EGVAR(captives,isSurrendering),false); // Event initalized by ACE_Captives [QEGVAR(captives,setSurrendered), [_unit, !_surrendering], _unit] call CBA_fnc_targetEvent; }; diff --git a/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf b/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf new file mode 100644 index 0000000000..4ebfd5a1c0 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf @@ -0,0 +1,64 @@ +/* + * Author: alganthe + * Zeus module function to toggle Flashlights + * + * Arguments: + * 0: Logic object + * 1: Toggle mode + * 2: Add gear + * 3: Target of the toggle 0: blufor; 1: opfor; 2: indep; 3: civ; 4: selected group + * + * Return Value: + * None + * + * Example: + * [LOGIC, true, true, 4] call ace_zeus_fnc_moduleToggleFlashlight + * + * Public: No +*/ + +#include "script_component.hpp" + +params ["_logic", "_toggle", "_addGear", "_target"]; + +private _units = []; + +if (_target == 4) then { + _units = units (attachedTo _logic); +} else { + _units = allUnits select {alive _x && {side _x == ([blufor, opfor, independent, civilian] select _target)}}, +}; + +if (_toggle) then { + { + // enableGunLights doesn't work on players + if !(isPlayer _x || {(currentWeapon _x) isEqualTo ""}) then { + private _pointer = (_x weaponAccessories (currentWeapon _x)) select 1; + + if (!(_pointer isEqualTo "") && {isNull (configfile >> "CfgWeapons" >> _pointer >> "ItemInfo" >> "Pointer")}) then { + [QGVAR(enableFlashlight), [_x, "forceOn"], _x] call CBA_fnc_targetEvent; + + } else { + if (_addGear) then { + // Retrieve compatible items for the pointer slot + private _pointerSlotCompatible = [currentWeapon _x, "pointer"] call CBA_fnc_compatibleItems; + + // Get flashlights from the array above and select the first one + private _flashlight = (_pointerSlotCompatible select {isNull (configfile >> "CfgWeapons" >> _x >> "ItemInfo" >> "Pointer")}) select 0; + + [QEGVAR(common,addWeaponItem), [_x, (currentWeapon _x), _flashlight], _x] call CBA_fnc_targetEvent; + [QGVAR(enableFlashlight), [_x, "forceOn"], _x] call CBA_fnc_targetEvent; + }; + }; + }; + } foreach _units; + +} else { + { + if !(isPlayer _x || {(currentWeapon _x) isEqualTo ""}) then { + [QGVAR(enableFlashlight), [_x, "forceOff"], _x] call CBA_fnc_targetEvent; + }; + } foreach _units; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleToggleNvg.sqf b/addons/zeus/functions/fnc_moduleToggleNvg.sqf new file mode 100644 index 0000000000..16511063fe --- /dev/null +++ b/addons/zeus/functions/fnc_moduleToggleNvg.sqf @@ -0,0 +1,69 @@ +/* + * Author: alganthe + * Zeus module function to toggle NVGs + * + * Arguments: + * 0: Logic object + * 1: Toggle mode + * 2: Target of the toggle 0: blufor; 1: opfor; 2: indep; 3: civ; 4: selected group + * + * Return Value: + * None + * + * Example: + * [LOGIC, true, 4] call ace_zeus_fnc_moduleToggleNvg + * + * Public: No +*/ + +#include "script_component.hpp" + +params ["_logic", "_toggle", "_target"]; + +private _units = []; + +if (_target == 4) then { + _units = units (attachedTo _logic); +} else { + _units = allUnits select {alive _x && {side _x == ([blufor, opfor, independent, civilian] select _target)}}, +}; + +if (_toggle) then { + { + if (!isplayer _x && {hmd _x isEqualTo ""}) then { + private _cfgArray = getArray (configFile >> 'CfgVehicles' >> typeOf _x >>'linkedItems'); + + private _nvgClass = _cfgArray select {_x isKindOf ["NVGoggles",(configFile >> "CfgWeapons")]}; + private _nvgHelmet =_cfgArray select {count (getArray (configFile >> "CfgWeapons" >> _x >> "subItems")) > 0}; + + // Can't have more than 1 assigned by default + if (count _nvgClass == 1 || {count _nvgHelmet == 1}) then { + if (count _nvgHelmet == 1) then { + _x addHeadgear (_nvgHelmet select 0); + } else { + _x linkItem (_nvgClass select 0); + }; + + } else { + _x linkItem "NVGoggles"; + }; + }; + } foreach _units; + +} else { + { + if (!isplayer _x) then { + private _cfgArray = getArray (configFile >> 'CfgVehicles' >> typeOf _x >>'linkedItems'); + + private _nvgHelmet =_cfgArray select {count (getArray (configFile >> "CfgWeapons" >> _x >> "subItems")) > 0}; + + if (count _nvgHelmet == 1) then { + removeHeadgear _x; + } else { + _x unlinkItem (hmd _x); + }; + }; + } foreach _units; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleUnGarrison.sqf b/addons/zeus/functions/fnc_moduleUnGarrison.sqf new file mode 100644 index 0000000000..08fb7ada10 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleUnGarrison.sqf @@ -0,0 +1,51 @@ +/* + * Author: alganthe + * Un-garrison a garrisoned group. + * + * Arguments: + * 0: Module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleUngarrison + * + * Public: No +*/ + +#include "script_component.hpp" + +params ["_logic"]; + +if (!local _logic) exitWith {}; // Module is global + +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +private _unit = effectiveCommander (attachedTo _logic); + +switch (false) do { + case !(isNull _unit): { + [LSTRING(NothingSelected)] call _fnc_errorAndClose; + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + case !(isPlayer _unit): { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call _fnc_errorAndClose; + }; +}; +private _units = units _unit; + +[QEGVAR(ai,unGarrison), [_units], _units] call CBA_fnc_targetEvent; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleUnconscious.sqf b/addons/zeus/functions/fnc_moduleUnconscious.sqf index d99ef6cd27..1e0955997f 100644 --- a/addons/zeus/functions/fnc_moduleUnconscious.sqf +++ b/addons/zeus/functions/fnc_moduleUnconscious.sqf @@ -18,20 +18,19 @@ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_conscious"]; +params ["_logic"]; -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if (isNil QEFUNC(medical,setUnconscious)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { - _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); if ((_mouseOver select 0) != "OBJECT") then { [LSTRING(NothingSelected)] call FUNC(showMessage); } else { - _unit = effectivecommander (_mouseOver select 1); + private _unit = effectivecommander (_mouseOver select 1); if !(_unit isKindOf "CAManBase") then { [LSTRING(OnlyInfantry)] call FUNC(showMessage); @@ -39,7 +38,7 @@ if (isNil QEFUNC(medical,setUnconscious)) then { if !(alive _unit) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { - _conscious = GETVAR(_unit,ACE_isUnconscious,false); + private _conscious = GETVAR(_unit,ACE_isUnconscious,false); // Function handles locality for me [_unit, !_conscious, 10e10, true] call EFUNC(medical,setUnconscious); }; diff --git a/addons/zeus/functions/fnc_moduleZeusSettings.sqf b/addons/zeus/functions/fnc_moduleZeusSettings.sqf index b52c597c2c..8abd714824 100644 --- a/addons/zeus/functions/fnc_moduleZeusSettings.sqf +++ b/addons/zeus/functions/fnc_moduleZeusSettings.sqf @@ -18,9 +18,7 @@ #include "script_component.hpp" -params ["_logic", "_units", "_activated"]; - -if !(_activated) exitWith {}; +params ["_logic"]; [_logic, QGVAR(zeusAscension), "zeusAscension"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(zeusBird), "zeusBird"] call EFUNC(common,readSettingFromModule); diff --git a/addons/zeus/functions/fnc_showMessage.sqf b/addons/zeus/functions/fnc_showMessage.sqf index c91c90093a..755b9b6278 100644 --- a/addons/zeus/functions/fnc_showMessage.sqf +++ b/addons/zeus/functions/fnc_showMessage.sqf @@ -1,11 +1,11 @@ /* * Author: 654wak654 - * Shows a zeus message through the BIS function, handles localization. + * Shows a Zeus message through the BIS function, handles localization. * If multiple args are given, they get formatted. * * Arguments: - * 0: The message - * N: Anything + * 0: Message + * N: Anything (default: nil) * * Return Value: * None diff --git a/addons/zeus/functions/fnc_ui_attributePosition.sqf b/addons/zeus/functions/fnc_ui_attributePosition.sqf index e0396e2c03..ecd3458ac2 100644 --- a/addons/zeus/functions/fnc_ui_attributePosition.sqf +++ b/addons/zeus/functions/fnc_ui_attributePosition.sqf @@ -48,7 +48,7 @@ private _fnc_onDraw = { }; private _fnc_onMapClick = { - params ["_map","_button","_x","_y","_shift","_ctrl","_alt"]; + params ["_map","_button"]; if (_button == 0) then { private _display = ctrlParent _map; diff --git a/addons/zeus/functions/fnc_ui_garrison.sqf b/addons/zeus/functions/fnc_ui_garrison.sqf new file mode 100644 index 0000000000..cc5087de65 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_garrison.sqf @@ -0,0 +1,104 @@ +/* + * Author: alganthe + * Initalises the "Garrison" zeus module display. + * + * Arguments: + * 0: Garrison controls group + * + * Return Value: + * None + * + * Example: + * onSetFocus = "_this call ace_zeus_fnc_ui_garrison" + * + * Public: No +*/ + +#include "script_component.hpp" + +disableSerialization; + +params ["_control"]; + +//Generic Init: +private _display = ctrlparent _control; +private _ctrlButtonOK = _display displayctrl 1; //IDC_OK +private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +TRACE_1("logicObject",_logic); + +_control ctrlRemoveAllEventHandlers "setFocus"; + +// Handles errors +private _unit = effectiveCommander (attachedTo _logic); + +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + _display closeDisplay 0; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +switch (false) do { + case !(isNull _unit): { + [LSTRING(NothingSelected)] call _fnc_errorAndClose; + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + case !(isPlayer _unit): { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call _fnc_errorAndClose; + }; +}; + +//Specific on-load stuff: +private _listbox = _display displayCtrl 73063; +{ + _listbox lbSetValue [_listbox lbAdd (_x select 0), _x select 1]; +} forEach [ + [localize LSTRING(ModuleGarrison_FillingModeEven), 0], + [localize LSTRING(ModuleGarrison_FillingModeBuilding), 1], + [localize LSTRING(ModuleGarrison_FillingModeRandom), 2] +]; + +_listbox lbSetCurSel 0; + +//Specific on-load stuff: +(_display displayCtrl 73061) cbSetChecked (_logic getVariable ["TopDownFilling",false]); +(_display displayCtrl 73062) cbSetChecked (_logic getVariable ["Teleport",false]); + +private _fnc_onUnload = { + params ["_display"]; + + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + if (isNull _logic) exitWith {}; + + deleteVehicle _logic; +}; + +private _fnc_onConfirm = { + params [["_ctrlButtonOK", controlNull, [controlNull]]]; + + private _display = ctrlparent _ctrlButtonOK; + if (isNull _display) exitWith {}; + + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + if (isNull _logic) exitWith {}; + + private _lb = _display displayCtrl 73063; + + private _radius = GETVAR(_display,GVAR(radius),50); + private _position = GETVAR(_display,GVAR(position),getPos _logic); + private _mode = _lb lbValue (lbCurSel _lb); + private _TopDownFilling = cbChecked (_display displayCtrl 73061); + private _teleport = cbChecked (_display displayCtrl 73062); + + [_logic, _position ,_radius, _mode, _TopDownFilling, _teleport] call FUNC(moduleGarrison); +}; + +_display displayAddEventHandler ["unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_groupSide.sqf b/addons/zeus/functions/fnc_ui_groupSide.sqf index 90de9d06ca..e5720e0720 100644 --- a/addons/zeus/functions/fnc_ui_groupSide.sqf +++ b/addons/zeus/functions/fnc_ui_groupSide.sqf @@ -115,7 +115,7 @@ private _fnc_onUnload = { }; private _fnc_onConfirm = { - params [["_ctrlButtonOK", controlNull, [controlNull]]]; + params ["_ctrlButtonOK"]; private _display = ctrlparent _ctrlButtonOK; if (isNull _display) exitWith {}; diff --git a/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf new file mode 100644 index 0000000000..9dff6808e4 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf @@ -0,0 +1,133 @@ +/* + * Author: alganthe + * Initalises the `Toggle Flashlights` zeus module display + * + * Arguments: + * 0: Flashlight toggle controls group + * + * Return Value: + * None + * + * Example: + * onSetFocus = "_this call ace_zeus_fnc_ui_toggleFLashlight" + * + * Public: No +*/ + +#include "script_component.hpp" + +disableSerialization; + +params ["_control"]; + +//Generic Init: +private _display = ctrlparent _control; +private _ctrlButtonOK = _display displayctrl 1; //IDC_OK +private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +TRACE_1("logicObject",_logic); + +_control ctrlRemoveAllEventHandlers "setFocus"; + +private _unit = effectiveCommander (attachedTo _logic); + +// Handles errors +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + _display closeDisplay 0; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +if !(isNull _unit) then { + switch (false) do { + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + }; +}; + +//Specific on-load stuff: +private _comboBox = _display displayCtrl 56218; +private _comboBox2 = _display displayCtrl 56219; +private _comboBox3 = _display displayCtrl 56220; + +{ + _comboBox lbSetValue [_comboBox lbAdd (_x select 0), _x select 1]; +} forEach [ + [localize ELSTRING(common,Disabled), 0], + [localize ELSTRING(common,Enabled), 1] +]; + +if (isNull _unit) then { + { + _comboBox2 lbSetValue [_comboBox2 lbAdd (_x select 0), _x select 1]; + } forEach [ + ["BLUFOR", 0], + ["OPFOR", 1], + ["INDEP", 2], + ["CIV", 3] + ]; +} else { + { + _comboBox2 lbSetValue [_comboBox2 lbAdd (_x select 0), _x select 1]; + } forEach [ + [localize LSTRING(moduleToggleNVG_SelectedGroup), 4], + ["BLUFOR", 0], + ["OPFOR", 1], + ["INDEP", 2], + ["CIV", 3] + ]; +}; + +{ + _comboBox3 lbSetValue [_comboBox3 lbAdd (_x select 0), _x select 1]; +} foreach [ + [localize ELSTRING(common,Disabled), 0], + [localize ELSTRING(common,Enabled), 1] +]; + + +private _enabledDefault = false; +if (!isNull _unit) then { + _enabledDefault = _unit isFlashlightOn (currentWeapon _unit); +}; +_comboBox lbSetCurSel ([0,1] select _enabledDefault); +_comboBox2 lbSetCurSel 0; +_comboBox3 lbSetCurSel 0; + +private _fnc_onUnload = { + params ["_display"]; + + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + if (isNull _logic) exitWith {}; + + deleteVehicle _logic; +}; + +private _fnc_onConfirm = { + params [["_ctrlButtonOK", controlNull, [controlNull]]]; + + private _display = ctrlparent _ctrlButtonOK; + if (isNull _display) exitWith {}; + + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + if (isNull _logic) exitWith {}; + + private _combo1 = _display displayCtrl 56218; + private _combo2 = _display displayCtrl 56219; + private _combo3 = _display displayCtrl 56220; + + private _toggle = _combo1 lbValue (lbCurSel _combo1); + private _target = _combo2 lbValue (lbCurSel _combo2); + private _gear = _combo3 lbValue (lbCurSel _combo3); + + [_logic, _toggle == 1, _gear == 1, _target] call FUNC(moduleToggleFlashlight); +}; + +_display displayAddEventHandler ["unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_toggleNvg.sqf b/addons/zeus/functions/fnc_ui_toggleNvg.sqf new file mode 100644 index 0000000000..822e552dac --- /dev/null +++ b/addons/zeus/functions/fnc_ui_toggleNvg.sqf @@ -0,0 +1,122 @@ +/* + * Author: alganthe + * Initalises the `Toggle NVGs` zeus module display + * + * Arguments: + * 0: Nvg toggle controls group + * + * Return Value: + * None + * + * Example: + * onSetFocus = "_this call ace_zeus_fnc_ui_toggleNvg" + * + * Public: No +*/ + +#include "script_component.hpp" + +disableSerialization; + +params ["_control"]; + +//Generic Init: +private _display = ctrlparent _control; +private _ctrlButtonOK = _display displayctrl 1; //IDC_OK +private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +TRACE_1("logicObject",_logic); + +_control ctrlRemoveAllEventHandlers "setFocus"; + +private _unit = effectiveCommander (attachedTo _logic); + +// Handles errors +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + _display closeDisplay 0; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +if !(isNull _unit) then { + switch (false) do { + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + }; +}; + +//Specific on-load stuff: +private _comboBox = _display displayCtrl 92855; +private _comboBox2 = _display displayCtrl 92856; + +{ + _comboBox lbSetValue [_comboBox lbAdd (_x select 0), _x select 1]; +} forEach [ + [localize ELSTRING(common,Disabled), 0], + [localize ELSTRING(common,Enabled), 1] +]; + +if (isNull _unit) then { + { + _comboBox2 lbSetValue [_comboBox2 lbAdd (_x select 0), _x select 1]; + } forEach [ + ["BLUFOR", 0], + ["OPFOR", 1], + ["INDEP", 2], + ["CIV", 3] + ]; +} else { + { + _comboBox2 lbSetValue [_comboBox2 lbAdd (_x select 0), _x select 1]; + } forEach [ + [localize LSTRING(moduleToggleNVG_SelectedGroup), 4], + ["BLUFOR", 0], + ["OPFOR", 1], + ["INDEP", 2], + ["CIV", 3] + ]; +}; + + +private _enabledDefault = false; +if (!isNull _unit) then { + _enabledDefault = !(hmd _unit isEqualTo ""); +}; +_comboBox lbSetCurSel ([0,1] select _enabledDefault); +_comboBox2 lbSetCurSel 0; + +private _fnc_onUnload = { + params ["_display"]; + + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + if (isNull _logic) exitWith {}; + + deleteVehicle _logic; +}; + +private _fnc_onConfirm = { + params [["_ctrlButtonOK", controlNull, [controlNull]]]; + + private _display = ctrlparent _ctrlButtonOK; + if (isNull _display) exitWith {}; + + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + if (isNull _logic) exitWith {}; + + private _combo1 = _display displayCtrl 92855; + private _combo2 = _display displayCtrl 92856; + + private _toggle = _combo1 lbValue (lbCurSel _combo1); + private _target = _combo2 lbValue (lbCurSel _combo2); + + [_logic, _toggle == 1, _target] call FUNC(moduleToggleNvg); +}; + +_display displayAddEventHandler ["unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 9cd71c135b..7b34b84039 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -1,6 +1,14 @@ - + + + Zeus + Zeus + 宙斯 + 宙斯 + Zeus + 제우스 + Zeus Settings Ustawienia Zeusa @@ -28,10 +36,10 @@ Különböző beállítási lehetőségeket biztosít a Zeus részeihez. Позволяет контролировать различные аспекты Зевса. Fornisce controllo su vari aspetti di Zeus. - Zeus のさまざまな側面を強化します。 + Zeus の操作性をさまざまな側面から強化します。 Zeus에게 다양한 방면의 조작을 제공해줍니다 - 提供宙斯各个方面的控制权. - 提供宙斯各個方面的控制權. + 提供宙斯各个方面的控制权 + 提供宙斯各個方面的控制權 Ascension Messages @@ -46,8 +54,8 @@ Messaggi di Ascesa 転生表示 재림 메세지 - 上任宙斯讯息 - 上任宙斯訊息 + 宙斯上任讯息 + 宙斯上任訊息 Display global popup messages when a player is assigned as Zeus. @@ -62,8 +70,8 @@ Mostra messaggi popup globali quando un giocatore viene assegnato come Zeus. プレイヤーが Zeus になるとき、全体へポップアップ表示をおこないます。 플레이어가 Zeus 될 시 서버에 이를 알리는 팝업이 등장합니다. - 当一位玩家被指定为宙斯时显示全球讯息. - 當一位玩家被指定為宙斯時顯示全球訊息. + 当一位玩家被指定为宙斯时显示全域讯息 + 當一位玩家被指定為宙斯時顯示全域訊息 Zeus Eagle @@ -236,7 +244,7 @@ Elfogott állapot váltása Пленный (вкл./выкл.) Attivatore Prigioniero - 捕虜としてトグル + 捕虜として切り替え 포로 토글 切换俘虏 切換俘虜 @@ -256,6 +264,7 @@ Update Editable Objects + Aktualisiere bearbeitbare Objekte 編集可能なオブジェクトを更新 Aktualizuj edytowalne obiekty 수정 가능한 물체 갱신 @@ -266,6 +275,7 @@ All Curators + Alle Zeus' 全キュレーター 모든 큐레이터 Wszyscy kuratorzy @@ -276,6 +286,7 @@ Apply changes to all curators + Änderungen bei allen Zeus' aktualisieren 全キュレーターへ変更を適用 모든 큐레이터에 변화를 적용합니다 Zatwierdź zmiany dla wszystkich kuratorów @@ -286,6 +297,7 @@ Remove Objects + Entferne Objekte オブジェクトの削除 물체 삭제 Usuń obiekty @@ -296,6 +308,7 @@ Remove existing instead of adding new + Entfernt Bestehendes, statt Neues hinzuzufügen 新しく追加するために削除します 물체를 삭제합니다 Usuń istniejące zamiast dodawać nowe @@ -335,13 +348,13 @@ Change: general, commanding, courage Изменяет: general, commanding, courage Upravuje: general, commanding, courage - 変更:general, commanding, courage + 変更: general, commanding, courage Zmienia: ogólne, dowodzenie, odwaga Ändert: general, commanding, courage 변화: 전반적, 지휘, 사기 Cambia: generale, comando, - 改变: 战斗技巧, 指挥技巧, 勇气大小 - 改變: 戰鬥技巧, 指揮技巧, 勇氣大小 + 改变: 战斗技巧,指挥技巧,勇气大小 + 改變: 戰鬥技巧,指揮技巧,勇氣大小 Accuracy @@ -361,7 +374,7 @@ Change : aimingAccuracy Изменяет: aimingAccuracy Upravuje: aimingAccuracy - 変更:aimingAccuracy + 変更: aimingAccuracy Zmienia: precyzję celowania Ändert: aimingAccuracy 변화: 조준 명중률 @@ -387,13 +400,13 @@ Change : aimingShake, aimingSpeed, reloadSpeed Изменяет: aimingShake, aimingSpeed, reloadSpeed Upravuje: aimingShake, aimingSpeed, reloadSpeed - 変更:aimingShake, aimingSpeed, reloadSpeed + 変更: aimingShake, aimingSpeed, reloadSpeed Zmienia: drżenie broni, szybkość celowania, szybkość przeładowania Ändert: aimingShake, aimingSpeed, reloadSpeed 변화: 조준시 흔들림, 조준 속도, 재장전 속도 Cambia: aimingShake, aimingSpeed, reloadSpeed - 改变: 手晃幅度, 瞄准速度, 重新装填速度 - 改變: 手晃幅度, 瞄準速度, 重新裝填速度 + 改变: 手晃幅度,瞄准速度, 重新装填速度 + 改變: 手晃幅度,瞄準速度, 重新裝填速度 Spotting @@ -413,7 +426,7 @@ Change : spotDistance, spotTime Изменяет: spotDistance, spotTime Upravuje: spotDistance, spotTime - 変更:spotDistance, spotTime + 変更: spotDistance, spotTime Zmienia: zasięg rozpoznawania, czas rozpoznawania Ändert: spotDistance, spotTime 변화: 탐지 거리, 탐지까지의 시간 @@ -510,14 +523,15 @@ Kapituláló állapot váltása Сдавшийся (вкл./выкл.) Attivatore Resa - 捕虜としてトグル + 投降として切り替え 항복 토글 切换投降 切換投降 Add/Remove FRIES - FRUES の追加と削除 + FRIES Hinzufügen/Entfernen + FRIES の追加と削除 패스트로프 추가/제거 Dodaj/usuń FRIES Aj./Enlève FRIES @@ -527,23 +541,25 @@ %1 is not fastrope compatible. + %1 ist nicht FRIES-kompatibel. %1 はファストロープに対応していません。 %1은 패스트로프하기에 적합하지 않습니다. %1 nie jest kompatybilny ze zjazdem linowym. %1 n'est pas compatible. %1 non è compatibile con il fastrope. - %1无法使用快速绳降系统. - %1無法使用快速繩降系統. + %1无法使用快速绳降系统 + %1無法使用快速繩降系統 Unable to remove FRIES, ropes are deployed. + FRIES kann nicht entfernt werden, noch in Benutzung すでにロープが展開されているため、FRIES を削除できません。 패스트로프 제거 불가능, 줄이 이미 배치되었습니다. Nie można usunąć FRIES, liny są wypuszczone. Pas en mesure d'enlever le FRIES, les cordes ne sont pas déployées. Impossibile rimuovere le FRIES, le corde sono ancora dispiegate - 无法移除快速绳降系统, 因为绳索已被释放出来. - 無法移除快速繩降系統, 因為繩索已被釋放出來. + 无法移除快速绳降系统,因为绳索已被释放出来 + 無法移除快速繩降系統,因為繩索已被釋放出來 Teleport Players @@ -576,7 +592,7 @@ Téléporter le joueur sélectionné à la position du module Телепортирует выбранного игрока к местоположению модуля Teleportuje vybraného hráče na pozici modulu - 選択したプレイヤーをプレイヤーをモジュール位置へ移動します + 選択したプレイヤーをモジュール位置へ移動します Teleportuje wybranego gracza na pozycję modułu Teleportiert ausgewählten Spieler zur Position des Moduls 모듈의 위치로 플레이어 순간이동 @@ -621,7 +637,7 @@ Eszméletlen állapot váltása Без сознания (вкл./выкл.) Attivatore Incoscienza - 気絶をトグル + 気絶を切り替え 기절 토글 切换昏迷 切換昏迷 @@ -644,7 +660,7 @@ Chercher le bâtiment proche Обыскать ближайшие здания Prohledat nejbližší budovu - 近くの建物を創作します + 近くの建物を捜索します Przeszukaj najbliższy budynek Durchsuche nahegelegenes Gebäude 근처 건물 수색 @@ -699,8 +715,9 @@ Toggle Simulation + Ändere Simulation Przełącz symulację - シミュレーションをトグル + シミュレーションを切り替え 재현 토글 Bascule Simulation Attivatore Simulazione @@ -899,9 +916,9 @@ Требуется аддон, который отсутствует Richiede un addon che non è presente 要求されたアドオンは存在していません - 현재 없는 에드온을 필요로 합니다 需要一个不存在的插件 需要一個不存在的插件 + 현재 없는 애드온을 필요로 합니다 Add Objects to Curator @@ -938,7 +955,7 @@ Cargo : Груз: Náklad: - カーゴ: + カーゴ: Ładunek: Ladung: 화물: @@ -951,7 +968,7 @@ Position de la tâche Местоположение задания Pozice úkolu - タスクの位置 + タスク位置 Pozycja zadania Position der Aufgabe 작업 위치 @@ -1010,27 +1027,216 @@ Suppressive Fire + Unterdrückungsfeuer Fuoco di Soppressione Tir de suppression 制圧射撃 火力压制 火力壓制 + Ogień zaporowy + 엄호사격 - - Add full arsenal to object - Ajouter arsenal complet à l'objet - Aggiunge arsenale completo all'oggetto + + Add Full Arsenal + Füge ganzes Arsenal hinzu + Ajouter Arsenal Complet + Aggiungi Arsenale Completo オブジェクトに完全なアーセナルを追加 增加完整的虚拟军火库到物件上 增加完整的虛擬軍火庫到物件上 + Dodaj Wirtualny Arsenał + 아스날 놓기 - - Remove arsenal from object - Retirer arsenal de l'objet - Rimuove arsenale completo dall'oggetto + + Remove Arsenal + Entferne Arsenal + Retirer Arsenal + Rimuovi Arsenale オブジェクトからアーセナルを削除 移除物件上的虚拟军火库 移除物件上的虛擬軍火庫 + Usuń Wirtualny Arsenał + 아스날 제거 + + + Load into Cargo + In Frachtraum laden + Carica nel Cargo + カーゴに積み込み + 裝載到貨物中 + 装载到货物中 + 화물 싣기 + + + Toggle NVGs + Nachtsichtgeräte Hinzufügen/Entfernen + Basculer JVN + Attiva NVGs + 暗視装置の切り替え + 切換夜視鏡 + 切换夜视镜 + 야시경 토글 + + + NVG equipment + Nachtsichtgeräte + Equipment de vision nocturne + Attrezzatura NVG + 暗視装置 + 夜視鏡裝備 + 夜视镜装备 + 야시경 장비 + + + Add or remove NVGs from units + Nachtsichtgeräte Hinzufügen/Entfernen + Ajouter ou retirer JVN des unités + Aggiunge o rimuove NVGs alle unità + ユニットから暗視装置の追加と削除 + 增加或移除單位的夜視鏡 + 增加或移除单位的夜视镜 + 야시경 추가/제거 + + + Toggle NVG target + Wechsle Nachtsichtgeräteziel + Cible du basculement + Attiva obiettivo NVG + 選択先の暗視装置の切り替え + 切換目標的夜視鏡狀態 + 切换目标的夜视镜状态 + 목표의 야시경 토글 + + + Selected group + Ausgewählte Gruppe + Groupe sélectionné + Gruppo selezionato + 選択されたグループ + 選擇小隊 + 选择小队 + 그룹 선택 + + + Toggle flashlights + Ändere Taschenlampen + Basculer lampes torches + Attiva torce + フラッシュライトの切り替え + 切換手電筒 + 切换手电筒 + 손전등 토글 + + + Toggle flashlight target + Wechsle Nachtsichtgeräteziel + Cible du basculement + Attiva obiettivo torcia + 選択先のフラッシュライトの切り替え + 切換目標的手電筒狀態 + 切换目标的手电筒状态 + 목표의 손전등 토글 + + + Flashlight + Taschenlampe + Lampe torche + Torcia + フラッシュライト + 手電筒 + 手电筒 + 손전등 + + + Add gear + Ausrüstung hinzufügen + Ajouter équipement + Aggiungi equipaggiamento + 装備を追加 + 增加裝備 + 增加装备 + 장비 추가 + + + Garrison group + Garnir zone + 歩哨グループ + Proteggi gruppo + 佈置駐軍 + 布置驻军 + 그룹 주둔 + + + Fill from top to bottom + Remplir de haut en bas + 上から下まで占拠 + Riempi dall'alto al basso + 由上而下進行填滿 + 由上而下进行填满 + 위에서부터 채우기 + + + Fill buildings from the highest position first + Remplir les bâtiments par la position la plus haute d'abord + 建物を最も高い位置から占拠していきます + Riempi gli edifici dalla posizione più alta prima + 從建築物的最高點開始布置衛哨 + 从建筑物的最高点开始布置卫哨 + 건물의 높은 위치부터 먼저 채움 + + + Building filling mode + Mode de remplissage de bâtiment + 建物占拠モード + Modalità riempimento edifici + 駐軍填充建築物模式 + 驻军填充建筑物模式 + 건물 채우기 모드 + + + Even filling + Remplissage égal + 均一に占拠 + Riempimento uguale + 平均分配 + 平均分配 + 평균 채우기 + + + Building by building + Bâtiment par bâtiment + 建物から建物へ + Edificio per edificio + 一棟填滿後再換下一棟 + 一栋填满后再换下一栋 + 건물에서 건물로 + + + Random filling + Remplir au hasard + ランダムに占拠 + Riempimento casuale + 隨機分配 + 随机分配 + 무작위 채우기 + + + Teleport + Téléporter + テレポート + Teletrasporto + 傳送 + 传送 + 순간이동 + + + Un-garrison group + Dégarnir zone + 非歩哨グループ + Non proteggere gruppo + 解除駐軍駐守狀態 + 解除驻军驻守状态 + 주둔해제 diff --git a/addons/zeus/ui/Icon_Module_Zeus_Garrison_ca.paa b/addons/zeus/ui/Icon_Module_Zeus_Garrison_ca.paa new file mode 100644 index 0000000000..8410763fd0 Binary files /dev/null and b/addons/zeus/ui/Icon_Module_Zeus_Garrison_ca.paa differ diff --git a/addons/zeus/ui/Icon_Module_Zeus_UnGarrison_ca.paa b/addons/zeus/ui/Icon_Module_Zeus_UnGarrison_ca.paa new file mode 100644 index 0000000000..387b1b2884 Binary files /dev/null and b/addons/zeus/ui/Icon_Module_Zeus_UnGarrison_ca.paa differ diff --git a/addons/zeus/ui/RscAttributes.hpp b/addons/zeus/ui/RscAttributes.hpp index 27f89d89c0..2bb2c97d85 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -417,7 +417,6 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { }; }; - class GVAR(AttributeCargo): RscControlsGroupNoScrollbars { onSetFocus = QUOTE(_this call FUNC(ui_attributeCargo)); idc = -1; @@ -473,3 +472,199 @@ class RscDisplayAttributesVehicleEmpty: RscDisplayAttributes { }; }; }; + +class GVAR(RscGarrison): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscGarrison)))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscGarrison)))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class Garrison: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_garrison)); + idc = 73060; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(8.5); + class controls { + class radius: GVAR(AttributeRadius) {}; + class TopDownFillingTitle: Title { + idc = -1; + text = CSTRING(ModuleGarrison_TopDownFillingText); + toolTip = CSTRING(ModuleGarrison_TopDownFillingTooltip); + x = 0; + y = H_PART(1.2); + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0,0,0,0.5}; + }; + class TopDownFilling: RscCheckBox { + idc = 73061; + x = W_PART(10.1); + y = H_PART(1.2); + w = W_PART(1); + h = H_PART(1); + }; + class TeleportTitle: Title { + idc = -1; + text = CSTRING(ModuleGarrison_TeleportText); + x = 0; + y = H_PART(2.3); + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0,0,0,0.5}; + }; + class Teleport: RscCheckBox { + idc = 73062; + x = W_PART(10.1); + y = H_PART(2.3); + w = W_PART(1); + h = H_PART(1); + }; + class FillingModeTitle: RscText { + idc = -1; + text = CSTRING(ModuleGarrison_FillingModeText); + x = 0; + y = H_PART(3.5); + w = W_PART(26); + h = H_PART(1); + colorBackground[] = {0,0,0,0.5}; + }; + class FillingMode: RscListbox { + idc = 73063; + x = 0; + y = H_PART(4.5); + w = W_PART(26); + h = H_PART(4); + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; + +class GVAR(RscToggleNvg): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscToggleNvg)))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscToggleNvg)))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class ToggleNvg: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_toggleNvg)); + idc = 92854; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(3); + class controls { + class ToggleNvgTitle: Title { + idc = -1; + text = CSTRING(moduleToggleNVG_ToggleNvgTitle); + toolTip = CSTRING(moduleToggleNVG_ToggleNvgTitleTooltip); + x = H_PART(0); + y = H_PART(0); + w = W_PART(7); + }; + class ToggleNvgCombo: RscCombo { + idc = 92855; + x = H_PART(6); + y = H_PART(0); + w = W_PART(10.1); + h = H_PART(1); + }; + class ToggleNvgSideTitle: Title { + idc = -1; + text = CSTRING(moduleToggleNVG_ToggleNvgSide); + x = H_PART(0); + y = H_PART(1.2); + w = W_PART(7); + }; + class ToggleNvgSideCombo: RscCombo { + idc = 92856; + x = H_PART(6); + y = H_PART(1.2); + w = W_PART(10.1); + h = H_PART(1); + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; + +class GVAR(RscToggleFlashlight): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscToggleFlashlight)))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscToggleFlashlight)))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class ToggleFlashlight: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_toggleFlashlight)); + idc = 56217; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(5); + class controls { + class ToggleFlashlightTitle: Title { + idc = -1; + text = CSTRING(moduleToggleFlashlight_ToggleFlashlightTitle); + x = H_PART(0); + y = H_PART(0); + w = W_PART(7); + }; + class ToggleFlashlightCombo: RscCombo { + idc = 56218; + x = H_PART(6); + y = H_PART(0); + w = W_PART(10.1); + h = H_PART(1); + }; + class ToggleFlashlightSideTitle: Title { + idc = -1; + text = CSTRING(moduleToggleFlashlight_ToggleFlashlightSide); + x = H_PART(0); + y = H_PART(1.2); + w = W_PART(7); + }; + class ToggleFlashlightSideCombo: RscCombo { + idc = 56219; + x = H_PART(6); + y = H_PART(1.2); + w = W_PART(10.1); + h = H_PART(1); + }; + class ToggleFlashlightGearTitle: Title { + idc = -1; + text = CSTRING(moduleToggleFlashlight_ToggleFlashlightGear); + x = H_PART(0); + y = H_PART(2.4); + w = W_PART(7); + }; + class ToggleFlashlightGearCombo: RscCombo { + idc = 56220; + x = H_PART(6); + y = H_PART(2.4); + w = W_PART(10.1); + h = H_PART(1); + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000000..7616e4912c --- /dev/null +++ b/circle.yml @@ -0,0 +1,23 @@ +version: 2 +jobs: + build: + docker: + - image: python:3-alpine + steps: + - checkout + - run: + name: Validate SQF And Config style + command: python tools/sqf_validator.py && python tools/config_style_checker.py + deployment: + docker: + - image: python:3-alpine + branch: master + requires: + - build + steps: + - checkout + - deploy: + name: Deploy + command: | + pip install pygithub pygithub3 + python3 tools/deploy.py diff --git a/docs/Dockerfile b/docs/Dockerfile index 033cd89d67..d8ae94bc6a 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,17 +1,6 @@ -# Build: -# docker build -t ace3mod/jekyll . -# -# Run: -# docker run -it -p 4000:4000 -v $(pwd):/usr/src/app ace3mod/jekyll -# -# Run with --incremental flag: -# docker run -it -p 4000:4000 -v $(pwd):/usr/src/app ace3mod/jekyll --incremental +FROM phpcommunity/github-pages +LABEL maintainer "bux" -FROM starefossen/github-pages:latest -MAINTAINER bux +COPY ./entrypoint.sh /usr/src/app -COPY . /usr/src/app - -VOLUME "/usr/src/app" - -ENTRYPOINT ["jekyll", "serve", "--future", "--config", "_config_dev.yml", "-H", "0.0.0.0", "-P", "4000"] +ENTRYPOINT ["./entrypoint.sh"] diff --git a/docs/Gemfile b/docs/Gemfile index a760185427..053c27dc35 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -1,8 +1,2 @@ -source 'http://rubygems.org' - -#require 'json' -#require 'open-uri' -#versions = JSON.parse(open('http://pages.github.com/versions.json').read) - +source 'https://rubygems.org' gem 'github-pages' -#, versions['github-pages'] diff --git a/docs/README_DE.md b/docs/README_DE.md index 966cfcaca6..1a34aa0104 100644 --- a/docs/README_DE.md +++ b/docs/README_DE.md @@ -4,7 +4,7 @@

- ACE3 Version + ACE3 Version ACE3 Fehlermeldungen diff --git a/docs/README_PL.md b/docs/README_PL.md index e23c373e11..2ada5d6533 100644 --- a/docs/README_PL.md +++ b/docs/README_PL.md @@ -3,7 +3,7 @@

- ACE3 Wersja + ACE3 Wersja ACE3 Zagadnienia diff --git a/docs/_config.yml b/docs/_config.yml index 8c73e551f6..237d3d7348 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -8,17 +8,17 @@ ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 10 - patch: 2 - build: 22 + minor: 12 + patch: 1 + build: 30 acex: githubUrl: https://github.com/acemod/ACEX version: major: 3 - minor: 2 + minor: 3 patch: 0 - build: 4 + build: 6 markdown: kramdown @@ -36,7 +36,7 @@ lsi: false exclude: [src, .editorconfig, .gitignore, CNAME, Gemfile, Gemfile.lock, README.md] -gems: +plugins: - jekyll-redirect-from whitelist: diff --git a/docs/_config_dev.yml b/docs/_config_dev.yml index 30263a0285..0cf7b5256e 100644 --- a/docs/_config_dev.yml +++ b/docs/_config_dev.yml @@ -1,5 +1,3 @@ -#baseurl: /ACE3 - name: ACE3 description: ACE3 is a joint effort by the teams behind ACE 2, AGM and CSE to improve the realism and authenticity of Arma 3. keywords: Advanced Combat Enhancement 3, ACE, ACE3, Arma, Arma 3, Mod, Modification, Realism, AGM, CSE, Bohemia, Interactive @@ -10,17 +8,17 @@ ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 10 - patch: 2 - build: 22 + minor: 12 + patch: 1 + build: 31 acex: githubUrl: https://github.com/acemod/ACEX version: major: 3 - minor: 2 + minor: 3 patch: 0 - build: 4 + build: 6 markdown: kramdown @@ -38,7 +36,7 @@ lsi: false exclude: [src, .editorconfig, .gitignore, CNAME, Gemfile, Gemfile.lock, README.md] -gems: +plugins: - jekyll-redirect-from whitelist: diff --git a/docs/_includes/dependencies_list.md b/docs/_includes/dependencies_list.md index 4e2a3dc141..86c1ae1bb1 100644 --- a/docs/_includes/dependencies_list.md +++ b/docs/_includes/dependencies_list.md @@ -22,6 +22,10 @@ `ace_main` {% endif %} +{% if include.component == "arsenal" %} +`ace_common` +{% endif %} + {% if include.component == "atragmx" %} `ACE_Advanced_Ballistics`, `ACE_common`, `ACE_weather` {% endif %} @@ -206,6 +210,10 @@ `ace_common` {% endif %} +{% if include.component == "maverick" %} +`ace_missileguidance` +{% endif %} + {% if include.component == "medical" %} `ace_interaction`, `ace_apl` {% endif %} @@ -298,6 +306,10 @@ `ace_common` {% endif %} +{% if include.component == "pylons" %} +`ace_interact_menu` +{% endif %} + {% if include.component == "quickmount" %} `ace_common` {% endif %} @@ -431,7 +443,7 @@ {% endif %} {% if include.component == "zeus" %} -`ace_common` +`ace_common`, `ace_ai` {% endif %} {% if include.component == "compat_adr_97" %} @@ -494,10 +506,6 @@ `ace_common` {% endif %} -{% if include.component == "server" %} -`ace_common` -{% endif %} - {% if include.component == "tracers" %} `ace_ballistics` {% endif %} diff --git a/docs/_includes/dependenciesx_list.md b/docs/_includes/dependenciesx_list.md index 8f387be41d..1526c3e12c 100644 --- a/docs/_includes/dependenciesx_list.md +++ b/docs/_includes/dependenciesx_list.md @@ -1,3 +1,7 @@ +{% if include.component == "fortify" %} +`acex_main`, `ace_interaction` +{% endif %} + {% if include.component == "headless" %} `acex_main` {% endif %} @@ -9,4 +13,3 @@ {% if include.component == "viewrestriction" %} `acex_main` {% endif %} - diff --git a/docs/_posts/2017-07-14-ace3-version3100.md b/docs/_posts/2017-07-14-ace3-version3100.md new file mode 100644 index 0000000000..08cecb455a --- /dev/null +++ b/docs/_posts/2017-07-14-ace3-version3100.md @@ -0,0 +1,77 @@ +--- +title: ACEREP #00009 +description: Status report on ACE3 version 3.10.0 +parent: posts +image: /img/news/170714_jet_rearm.jpg +author: bux +layout: post +--- + +Last week we have released another big update to ACE3 (and a little hotfix too). ACE3 v3.10.0 (and v3.10.1) brought a numerous amount of additions, changes, fixes and improved translations. Following the release of [Jets DLC](https://arma3.com/dlc/jets) for Arma 3 a lot of things have changed on how we need to handle certain situations in the code and configuration. + + + +With Jets DLC focusing primarily on ... Jets ... this update we also focused a little bit more on aircraft. As an example we added rearm features to the new pylon system introduced with Jets DLC, we added settings to increase the fuel hose's length (for refueling on the carrier) and removed our custom flight model changes in favour of the constantly improved one's from vanilla Arma 3. + +

+ +Secondly Zeus has received new toys and improvements. One of which is to use AI to suppress positions and direct it using a slick new UI component we have developed for the Zeus interface. + + + + +
+ +### Intercept + +Back in [ACEREP #00004]({{site.baseUrl}}/2016/03/02/ace3-version350.html) we last spoke about Intercept a project that hooks into the Arma 3 game engine and calls scripting commands on an engine level (in C++) thus circumventing the SQF interpreter and saving valuable time executing the commands. + +
+
+ The intercept project's logo. +
+
+ +Though in June 2016 progress on Intercept had become stagnant as the main developer got started on his new job and time for intercept had become rather sparse. In may 2017 [@dedmen](https://github.com/dedmen){:target="_blank"} joined the project and Intercept has made a lot of progress since then. + +It has now reached a milestone where **100% of Arma 3 script commands** are available to be used and a lot of the core code was redesigned and refactored which also removed the latest hurdle in getting Intercept **whitelisted by BattlEye**. + +Besides just improving on existing code also new features have been added. The most notable being the ability to register one's own SQF commands so one can easily move small parts of one's SQF code directly to Intercept:, + +* [https://github.com/intercept/intercept/issues/10](https://github.com/intercept/intercept/issues/10){:target="_blank"} +* [https://github.com/intercept/intercept/wiki/Registered-Functions](https://github.com/intercept/intercept/wiki/Registered-Functions){:target="_blank"} + +64bit support and Linux server compatibility have been added to Intercept which was also important because now Intercept can use its full potential even on a server. + +The latest features currently in active development are cross plugin communication and a [rework of the eventhandler system](https://github.com/intercept/intercept/issues/3){:target="_blank"}. It allows doing the following: + +```cpp +// showing a message when a unit is being hit +// of who did the damage and how much damage has been inflicted +void intercept::post_init() { + static auto hitEH = addEventHandler(sqf::player(), + [](object unit, object causedBy, float damage, object instigator) { + sqf::system_chat(sqf::format({ "Ouch! %1 Hit me for %2!", causedBy, damage })); + }); +} +``` + +Thanks to [@senfo's](https://github.com/RZSenfo){:target="_blank"} ongoing investigations we might also be able to get real multi threading to SQF/Intercept. Making it possible to run some scripts in parallel. + +Intercept is already being used to create new scripting mods. [@dedmen is working on bringing LUA scripting to Arma](https://www.reddit.com/r/arma/comments/6dy7vg/lua_scripting_in_arma/){:target="_blank"}. +@overfl0, [@zakant](https://github.com/zakant){:target="_blank"} and @KoffeinFlummi are starting to bring Python scripting to life. + +What Intercept needs most right now are people trying it out, finding bugs and give ideas, and maybe even contribute to Intercept or any of the great child projects that are growing all around it. + +### The End Things +The change log for ACE3 v3.10.0 can be found here: [https://github.com/acemod/ACE3/releases/v3.10.0](https://github.com/acemod/ACE3/releases/v3.10.0){:target="_blank"} + +The change log for ACE3 v3.10.1 can be found here: [https://github.com/acemod/ACE3/releases/v3.10.1](https://github.com/acemod/ACE3/releases/v3.10.1){:target="_blank"} + +We are still in need for translations for some languages within the ACE3 project. Please have a look at [this GitHub issue to track the progress and what languages lack translations](https://github.com/acemod/ACE3/issues/367){:target="_blank"}. Any and all help with this is very appreciated. + +Make sure to [follow us on twitter](https://twitter.com/intent/follow?screen_name=ace3mod&tw_p=followbutton){:target="_blank"} and to [like our facebook page](https://www.facebook.com/ACE3Mod/){:target="_blank"}. diff --git a/docs/_posts/2017-12-20-cba-settings.md b/docs/_posts/2017-12-20-cba-settings.md new file mode 100644 index 0000000000..2cec527aae --- /dev/null +++ b/docs/_posts/2017-12-20-cba-settings.md @@ -0,0 +1,54 @@ +--- +title: Using CBA Settings in ACE3 +description: With v3.12.0 we are dropping the ACE3 Settings System and now are using CBA Settings +parent: posts +image: /img/news/171220_cbaPost2.jpg +author: Pabstmirror, bux +layout: post +--- + +As announced mid november the upcoming ACE3 release (v3.12.0) will make the transition to using [CBA Settings](https://github.com/CBATeam/CBA_A3/wiki/CBA-Settings-System){:target="_blank"} to control the many settings ACE3 has. + +We have tried to make the change as smooth as possible. + + + + + + +## Players + +All of your old (client settable) settings should transfer automatically. + +The biggest change is how to access the settings now; from the escape menu hit `OPTIONS` and then `ADDON OPTIONS`. + +## Mission Makers + +Old mission should still be fully compatible with ACE3 v3.12.0. + +However the old methods of changing settings (Setting Modules and `class ace_settings` in `description.ext`) are considered deprecated (old modules will still function, but new ones are no longer placeable). + +All settings are also subject to backwards incompatible changes with future ACE3 versions. We recommend switching to changing settings via the CBA Eden Editor interface and deleting any old ACE Setting modules. From Eden Editor click on the `SETTINGS` -> `ADDON OPTIONS`. + +## Server Admins + +`ace_server.pbo` / `ACE_ServerSettings` has been removed in ACE3 v3.12.0. + +Refer to CBA's [Server Settings](https://github.com/CBATeam/CBA_A3/wiki/CBA-Settings-System#server-settings){:target="_blank"} and [Userconfig](https://github.com/CBATeam/CBA_A3/wiki/CBA-Settings-System#userconfig){:target="_blank"} to change settings for your server. + +### Convert your current server settings + + + + + +## Addon / Script Makers + +- ACE3 will convert all config based settings to CBA Settings automatically (except `typeName = "ARRAY"`). +- Non-public function `ace_common_fnc_addSettings` has been removed. +- Non-public function `ace_common_fnc_setSetting` has changed and may not function as before. +- It is critical that calls to `ace_common_fnc_readSettingFromModule` are now done **globaly** instead of just on the server. + +It is also recommended to deprecate `(scope = 1;)` your custom setting modules. + +- ACE Events `ace_settingsInitialized` and `ace_settingChanged` will continue to work normally. diff --git a/docs/css/app.css b/docs/css/app.css index 6621799c85..8130470b22 100644 --- a/docs/css/app.css +++ b/docs/css/app.css @@ -1,4 +1,4 @@ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}meta.foundation-version{font-family:"/5.5.1/"}meta.foundation-mq-small{font-family:"/only screen/";width:0em}meta.foundation-mq-small-only{font-family:"/only screen and (max-width: 40em)/";width:0em}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}meta.foundation-mq-medium-only{font-family:"/only screen and (min-width:40.0625em) and (max-width:64em)/";width:40.0625em}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.0625em)/";width:64.0625em}meta.foundation-mq-large-only{font-family:"/only screen and (min-width:64.0625em) and (max-width:90em)/";width:64.0625em}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.0625em)/";width:90.0625em}meta.foundation-mq-xlarge-only{font-family:"/only screen and (min-width:90.0625em) and (max-width:120em)/";width:90.0625em}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.0625em)/";width:120.0625em}meta.foundation-data-attribute-namespace{font-family:false}html,body{height:100%}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html,body{font-size:100%}body{background:#fff;color:#222;padding:0;margin:0;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:400;font-style:normal;line-height:1.5;position:relative;cursor:auto}a:hover{cursor:pointer}img{max-width:100%;height:auto}img{-ms-interpolation-mode:bicubic}#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none !important}.left{float:left !important}.right{float:right !important}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.hide{display:none}.invisible{visibility:hidden}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}[class*="block-grid-"]{display:block;padding:0;margin:0 -.625rem}[class*="block-grid-"]:before,[class*="block-grid-"]:after{content:" ";display:table}[class*="block-grid-"]:after{clear:both}[class*="block-grid-"]>li{display:block;height:auto;float:left;padding:0 .625rem 1.25rem}@media only screen{.small-block-grid-1>li{width:100%;list-style:none}.small-block-grid-1>li:nth-of-type(1n){clear:none}.small-block-grid-1>li:nth-of-type(1n+1){clear:both}.small-block-grid-2>li{width:50%;list-style:none}.small-block-grid-2>li:nth-of-type(1n){clear:none}.small-block-grid-2>li:nth-of-type(2n+1){clear:both}.small-block-grid-3>li{width:33.3333333333%;list-style:none}.small-block-grid-3>li:nth-of-type(1n){clear:none}.small-block-grid-3>li:nth-of-type(3n+1){clear:both}.small-block-grid-4>li{width:25%;list-style:none}.small-block-grid-4>li:nth-of-type(1n){clear:none}.small-block-grid-4>li:nth-of-type(4n+1){clear:both}.small-block-grid-5>li{width:20%;list-style:none}.small-block-grid-5>li:nth-of-type(1n){clear:none}.small-block-grid-5>li:nth-of-type(5n+1){clear:both}.small-block-grid-6>li{width:16.6666666667%;list-style:none}.small-block-grid-6>li:nth-of-type(1n){clear:none}.small-block-grid-6>li:nth-of-type(6n+1){clear:both}.small-block-grid-7>li{width:14.2857142857%;list-style:none}.small-block-grid-7>li:nth-of-type(1n){clear:none}.small-block-grid-7>li:nth-of-type(7n+1){clear:both}.small-block-grid-8>li{width:12.5%;list-style:none}.small-block-grid-8>li:nth-of-type(1n){clear:none}.small-block-grid-8>li:nth-of-type(8n+1){clear:both}.small-block-grid-9>li{width:11.1111111111%;list-style:none}.small-block-grid-9>li:nth-of-type(1n){clear:none}.small-block-grid-9>li:nth-of-type(9n+1){clear:both}.small-block-grid-10>li{width:10%;list-style:none}.small-block-grid-10>li:nth-of-type(1n){clear:none}.small-block-grid-10>li:nth-of-type(10n+1){clear:both}.small-block-grid-11>li{width:9.0909090909%;list-style:none}.small-block-grid-11>li:nth-of-type(1n){clear:none}.small-block-grid-11>li:nth-of-type(11n+1){clear:both}.small-block-grid-12>li{width:8.3333333333%;list-style:none}.small-block-grid-12>li:nth-of-type(1n){clear:none}.small-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 40.0625em){.medium-block-grid-1>li{width:100%;list-style:none}.medium-block-grid-1>li:nth-of-type(1n){clear:none}.medium-block-grid-1>li:nth-of-type(1n+1){clear:both}.medium-block-grid-2>li{width:50%;list-style:none}.medium-block-grid-2>li:nth-of-type(1n){clear:none}.medium-block-grid-2>li:nth-of-type(2n+1){clear:both}.medium-block-grid-3>li{width:33.3333333333%;list-style:none}.medium-block-grid-3>li:nth-of-type(1n){clear:none}.medium-block-grid-3>li:nth-of-type(3n+1){clear:both}.medium-block-grid-4>li{width:25%;list-style:none}.medium-block-grid-4>li:nth-of-type(1n){clear:none}.medium-block-grid-4>li:nth-of-type(4n+1){clear:both}.medium-block-grid-5>li{width:20%;list-style:none}.medium-block-grid-5>li:nth-of-type(1n){clear:none}.medium-block-grid-5>li:nth-of-type(5n+1){clear:both}.medium-block-grid-6>li{width:16.6666666667%;list-style:none}.medium-block-grid-6>li:nth-of-type(1n){clear:none}.medium-block-grid-6>li:nth-of-type(6n+1){clear:both}.medium-block-grid-7>li{width:14.2857142857%;list-style:none}.medium-block-grid-7>li:nth-of-type(1n){clear:none}.medium-block-grid-7>li:nth-of-type(7n+1){clear:both}.medium-block-grid-8>li{width:12.5%;list-style:none}.medium-block-grid-8>li:nth-of-type(1n){clear:none}.medium-block-grid-8>li:nth-of-type(8n+1){clear:both}.medium-block-grid-9>li{width:11.1111111111%;list-style:none}.medium-block-grid-9>li:nth-of-type(1n){clear:none}.medium-block-grid-9>li:nth-of-type(9n+1){clear:both}.medium-block-grid-10>li{width:10%;list-style:none}.medium-block-grid-10>li:nth-of-type(1n){clear:none}.medium-block-grid-10>li:nth-of-type(10n+1){clear:both}.medium-block-grid-11>li{width:9.0909090909%;list-style:none}.medium-block-grid-11>li:nth-of-type(1n){clear:none}.medium-block-grid-11>li:nth-of-type(11n+1){clear:both}.medium-block-grid-12>li{width:8.3333333333%;list-style:none}.medium-block-grid-12>li:nth-of-type(1n){clear:none}.medium-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width: 64.0625em){.large-block-grid-1>li{width:100%;list-style:none}.large-block-grid-1>li:nth-of-type(1n){clear:none}.large-block-grid-1>li:nth-of-type(1n+1){clear:both}.large-block-grid-2>li{width:50%;list-style:none}.large-block-grid-2>li:nth-of-type(1n){clear:none}.large-block-grid-2>li:nth-of-type(2n+1){clear:both}.large-block-grid-3>li{width:33.3333333333%;list-style:none}.large-block-grid-3>li:nth-of-type(1n){clear:none}.large-block-grid-3>li:nth-of-type(3n+1){clear:both}.large-block-grid-4>li{width:25%;list-style:none}.large-block-grid-4>li:nth-of-type(1n){clear:none}.large-block-grid-4>li:nth-of-type(4n+1){clear:both}.large-block-grid-5>li{width:20%;list-style:none}.large-block-grid-5>li:nth-of-type(1n){clear:none}.large-block-grid-5>li:nth-of-type(5n+1){clear:both}.large-block-grid-6>li{width:16.6666666667%;list-style:none}.large-block-grid-6>li:nth-of-type(1n){clear:none}.large-block-grid-6>li:nth-of-type(6n+1){clear:both}.large-block-grid-7>li{width:14.2857142857%;list-style:none}.large-block-grid-7>li:nth-of-type(1n){clear:none}.large-block-grid-7>li:nth-of-type(7n+1){clear:both}.large-block-grid-8>li{width:12.5%;list-style:none}.large-block-grid-8>li:nth-of-type(1n){clear:none}.large-block-grid-8>li:nth-of-type(8n+1){clear:both}.large-block-grid-9>li{width:11.1111111111%;list-style:none}.large-block-grid-9>li:nth-of-type(1n){clear:none}.large-block-grid-9>li:nth-of-type(9n+1){clear:both}.large-block-grid-10>li{width:10%;list-style:none}.large-block-grid-10>li:nth-of-type(1n){clear:none}.large-block-grid-10>li:nth-of-type(10n+1){clear:both}.large-block-grid-11>li{width:9.0909090909%;list-style:none}.large-block-grid-11>li:nth-of-type(1n){clear:none}.large-block-grid-11>li:nth-of-type(11n+1){clear:both}.large-block-grid-12>li{width:8.3333333333%;list-style:none}.large-block-grid-12>li:nth-of-type(1n){clear:none}.large-block-grid-12>li:nth-of-type(12n+1){clear:both}}button,.button{border-style:solid;border-width:0;cursor:pointer;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:normal;margin:0 0 1.25rem;position:relative;text-decoration:none;text-align:center;-webkit-appearance:none;-moz-appearance:none;border-radius:0;display:inline-block;padding-top:1rem;padding-right:2rem;padding-bottom:1.0625rem;padding-left:2rem;font-size:1rem;background-color:#ba2619;border-color:#951e14;color:#fff;transition:background-color 300ms ease-out}button:hover,button:focus,.button:hover,.button:focus{background-color:#951e14}button:hover,button:focus,.button:hover,.button:focus{color:#fff}button.secondary,.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{background-color:#b9b9b9}button.secondary:hover,button.secondary:focus,.button.secondary:hover,.button.secondary:focus{color:#333}button.success,.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{background-color:#368a55}button.success:hover,button.success:focus,.button.success:hover,.button.success:focus{color:#fff}button.alert,.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{background-color:#cf2a0e}button.alert:hover,button.alert:focus,.button.alert:hover,.button.alert:focus{color:#fff}button.warning,.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{background-color:#cf6e0e}button.warning:hover,button.warning:focus,.button.warning:hover,.button.warning:focus{color:#fff}button.info,.button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{background-color:#61b6d9}button.info:hover,button.info:focus,.button.info:hover,.button.info:focus{color:#fff}button.large,.button.large{padding-top:1.125rem;padding-right:2.25rem;padding-bottom:1.1875rem;padding-left:2.25rem;font-size:1.25rem}button.small,.button.small{padding-top:.875rem;padding-right:1.75rem;padding-bottom:.9375rem;padding-left:1.75rem;font-size:.8125rem}button.tiny,.button.tiny{padding-top:.625rem;padding-right:1.25rem;padding-bottom:.6875rem;padding-left:1.25rem;font-size:.6875rem}button.expand,.button.expand{padding-right:0;padding-left:0;width:100%}button.left-align,.button.left-align{text-align:left;text-indent:.75rem}button.right-align,.button.right-align{text-align:right;padding-right:.75rem}button.radius,.button.radius{border-radius:3px}button.round,.button.round{border-radius:1000px}button.disabled,button[disabled],.button.disabled,.button[disabled]{background-color:#ba2619;border-color:#951e14;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#951e14}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{color:#fff}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus{background-color:#ba2619}button.disabled.secondary,button[disabled].secondary,.button.disabled.secondary,.button[disabled].secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333;cursor:default;opacity:.7;box-shadow:none}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#b9b9b9}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{color:#333}button.disabled.secondary:hover,button.disabled.secondary:focus,button[disabled].secondary:hover,button[disabled].secondary:focus,.button.disabled.secondary:hover,.button.disabled.secondary:focus,.button[disabled].secondary:hover,.button[disabled].secondary:focus{background-color:#e7e7e7}button.disabled.success,button[disabled].success,.button.disabled.success,.button[disabled].success{background-color:#43AC6A;border-color:#368a55;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#368a55}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{color:#fff}button.disabled.success:hover,button.disabled.success:focus,button[disabled].success:hover,button[disabled].success:focus,.button.disabled.success:hover,.button.disabled.success:focus,.button[disabled].success:hover,.button[disabled].success:focus{background-color:#43AC6A}button.disabled.alert,button[disabled].alert,.button.disabled.alert,.button[disabled].alert{background-color:#f04124;border-color:#cf2a0e;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#cf2a0e}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{color:#fff}button.disabled.alert:hover,button.disabled.alert:focus,button[disabled].alert:hover,button[disabled].alert:focus,.button.disabled.alert:hover,.button.disabled.alert:focus,.button[disabled].alert:hover,.button[disabled].alert:focus{background-color:#f04124}button.disabled.warning,button[disabled].warning,.button.disabled.warning,.button[disabled].warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff;cursor:default;opacity:.7;box-shadow:none}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#cf6e0e}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{color:#fff}button.disabled.warning:hover,button.disabled.warning:focus,button[disabled].warning:hover,button[disabled].warning:focus,.button.disabled.warning:hover,.button.disabled.warning:focus,.button[disabled].warning:hover,.button[disabled].warning:focus{background-color:#f08a24}button.disabled.info,button[disabled].info,.button.disabled.info,.button[disabled].info{background-color:#a0d3e8;border-color:#61b6d9;color:#333;cursor:default;opacity:.7;box-shadow:none}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#61b6d9}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{color:#fff}button.disabled.info:hover,button.disabled.info:focus,button[disabled].info:hover,button[disabled].info:focus,.button.disabled.info:hover,.button.disabled.info:focus,.button[disabled].info:hover,.button[disabled].info:focus{background-color:#a0d3e8}button::-moz-focus-inner{border:0;padding:0}@media only screen and (min-width: 40.0625em){button,.button{display:inline-block}}.clearing-thumbs,[data-clearing]{margin-bottom:0;margin-left:0;list-style:none}.clearing-thumbs:before,.clearing-thumbs:after,[data-clearing]:before,[data-clearing]:after{content:" ";display:table}.clearing-thumbs:after,[data-clearing]:after{clear:both}.clearing-thumbs li,[data-clearing] li{float:left;margin-right:10px}.clearing-thumbs[class*="block-grid-"] li,[data-clearing][class*="block-grid-"] li{margin-right:0}.clearing-blackout{background:#333;position:fixed;width:100%;height:100%;top:0;left:0;z-index:998}.clearing-blackout .clearing-close{display:block}.clearing-container{position:relative;z-index:998;height:100%;overflow:hidden;margin:0}.clearing-touch-label{position:absolute;top:50%;left:50%;color:#aaa;font-size:0.6em}.visible-img{height:95%;position:relative}.visible-img img{position:absolute;left:50%;top:50%;transform:translateY(-50%) translateX(-50%);-webkit-transform:translateY(-50%) translateX(-50%);-ms-transform:translateY(-50%) translateX(-50%);max-height:100%;max-width:100%}.clearing-caption{color:#ccc;font-size:.875em;line-height:1.3;margin-bottom:0;text-align:center;bottom:0;background:#333;width:100%;padding:10px 30px 20px;position:absolute;left:0}.clearing-close{z-index:999;padding-left:20px;padding-top:10px;font-size:30px;line-height:1;color:#ccc;display:none}.clearing-close:hover,.clearing-close:focus{color:#ccc}.clearing-assembled .clearing-container{height:100%}.clearing-assembled .clearing-container .carousel>ul{display:none}.clearing-feature li{display:none}.clearing-feature li.clearing-featured-img{display:block}@media only screen and (min-width: 40.0625em){.clearing-main-prev,.clearing-main-next{position:absolute;height:100%;width:40px;top:0}.clearing-main-prev>span,.clearing-main-next>span{position:absolute;top:50%;display:block;width:0;height:0;border:solid 12px}.clearing-main-prev>span:hover,.clearing-main-next>span:hover{opacity:0.8}.clearing-main-prev{left:0}.clearing-main-prev>span{left:5px;border-color:transparent;border-right-color:#ccc}.clearing-main-next{right:0}.clearing-main-next>span{border-color:transparent;border-left-color:#ccc}.clearing-main-prev.disabled,.clearing-main-next.disabled{opacity:0.3}.clearing-assembled .clearing-container .carousel{background:rgba(51,51,51,0.8);height:120px;margin-top:10px;text-align:center}.clearing-assembled .clearing-container .carousel>ul{display:inline-block;z-index:999;height:100%;position:relative;float:none}.clearing-assembled .clearing-container .carousel>ul li{display:block;width:120px;min-height:inherit;float:left;overflow:hidden;margin-right:0;padding:0;position:relative;cursor:pointer;opacity:0.4;clear:none}.clearing-assembled .clearing-container .carousel>ul li.fix-height img{height:100%;max-width:none}.clearing-assembled .clearing-container .carousel>ul li a.th{border:none;box-shadow:none;display:block}.clearing-assembled .clearing-container .carousel>ul li img{cursor:pointer !important;width:100% !important}.clearing-assembled .clearing-container .carousel>ul li.visible{opacity:1}.clearing-assembled .clearing-container .carousel>ul li:hover{opacity:0.8}.clearing-assembled .clearing-container .visible-img{background:#333;overflow:hidden;height:85%}.clearing-close{position:absolute;top:10px;right:20px;padding-left:0;padding-top:0}}form{margin:0 0 1rem}form .row .row{margin:0 -.5rem}form .row .row .column,form .row .row .columns{padding:0 .5rem}form .row .row.collapse{margin:0}form .row .row.collapse .column,form .row .row.collapse .columns{padding:0}form .row .row.collapse input{-webkit-border-bottom-right-radius:0;-webkit-border-top-right-radius:0;border-bottom-right-radius:0;border-top-right-radius:0}form .row input.column,form .row input.columns,form .row textarea.column,form .row textarea.columns{padding-left:.5rem}label{font-size:.875rem;color:#4d4c4c;cursor:pointer;display:block;font-weight:400;line-height:1.5;margin-bottom:0}label.right{float:none !important;text-align:right}label.inline{margin:0 0 1rem 0;padding:.5625rem 0}label small{text-transform:capitalize;color:#676767}.prefix,.postfix{display:block;position:relative;z-index:2;text-align:center;width:100%;padding-top:0;padding-bottom:0;border-style:solid;border-width:1px;overflow:visible;font-size:.875rem;height:2.3125rem;line-height:2.3125rem}.postfix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;border:none}.prefix.button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;text-align:center;border:none}.prefix.button.radius{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}.postfix.button.radius{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}.prefix.button.round{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}.postfix.button.round{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}span.prefix,label.prefix{background:#f2f2f2;border-right:none;color:#333;border-color:#ccc}span.postfix,label.postfix{background:#f2f2f2;border-left:none;color:#333;border-color:#ccc}input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="month"],input[type="week"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],input[type="color"],textarea{-webkit-appearance:none;border-radius:0;background-color:#fff;font-family:inherit;border-style:solid;border-width:1px;border-color:#ccc;box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);color:rgba(0,0,0,0.75);display:block;font-size:.875rem;margin:0 0 1rem 0;padding:.5rem;height:2.3125rem;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:all .15s linear}input[type="text"]:focus,input[type="password"]:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="email"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="time"]:focus,input[type="url"]:focus,input[type="color"]:focus,textarea:focus{background:#fafafa;border-color:#999;outline:none}input[type="text"]:disabled,input[type="password"]:disabled,input[type="date"]:disabled,input[type="datetime"]:disabled,input[type="datetime-local"]:disabled,input[type="month"]:disabled,input[type="week"]:disabled,input[type="email"]:disabled,input[type="number"]:disabled,input[type="search"]:disabled,input[type="tel"]:disabled,input[type="time"]:disabled,input[type="url"]:disabled,input[type="color"]:disabled,textarea:disabled{background-color:#ddd;cursor:default}input[type="text"][disabled],input[type="text"][readonly],fieldset[disabled] input[type="text"],input[type="password"][disabled],input[type="password"][readonly],fieldset[disabled] input[type="password"],input[type="date"][disabled],input[type="date"][readonly],fieldset[disabled] input[type="date"],input[type="datetime"][disabled],input[type="datetime"][readonly],fieldset[disabled] input[type="datetime"],input[type="datetime-local"][disabled],input[type="datetime-local"][readonly],fieldset[disabled] input[type="datetime-local"],input[type="month"][disabled],input[type="month"][readonly],fieldset[disabled] input[type="month"],input[type="week"][disabled],input[type="week"][readonly],fieldset[disabled] input[type="week"],input[type="email"][disabled],input[type="email"][readonly],fieldset[disabled] input[type="email"],input[type="number"][disabled],input[type="number"][readonly],fieldset[disabled] input[type="number"],input[type="search"][disabled],input[type="search"][readonly],fieldset[disabled] input[type="search"],input[type="tel"][disabled],input[type="tel"][readonly],fieldset[disabled] input[type="tel"],input[type="time"][disabled],input[type="time"][readonly],fieldset[disabled] input[type="time"],input[type="url"][disabled],input[type="url"][readonly],fieldset[disabled] input[type="url"],input[type="color"][disabled],input[type="color"][readonly],fieldset[disabled] input[type="color"],textarea[disabled],textarea[readonly],fieldset[disabled] textarea{background-color:#ddd;cursor:default}input[type="text"].radius,input[type="password"].radius,input[type="date"].radius,input[type="datetime"].radius,input[type="datetime-local"].radius,input[type="month"].radius,input[type="week"].radius,input[type="email"].radius,input[type="number"].radius,input[type="search"].radius,input[type="tel"].radius,input[type="time"].radius,input[type="url"].radius,input[type="color"].radius,textarea.radius{border-radius:3px}form .row .prefix-radius.row.collapse input,form .row .prefix-radius.row.collapse textarea,form .row .prefix-radius.row.collapse select,form .row .prefix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-radius.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse input,form .row .postfix-radius.row.collapse textarea,form .row .postfix-radius.row.collapse select,form .row .postfix-radius.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-bottom-left-radius:3px;border-top-left-radius:3px}form .row .postfix-radius.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-right-radius:3px}form .row .prefix-round.row.collapse input,form .row .prefix-round.row.collapse textarea,form .row .prefix-round.row.collapse select,form .row .prefix-round.row.collapse button{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}form .row .prefix-round.row.collapse .prefix{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse input,form .row .postfix-round.row.collapse textarea,form .row .postfix-round.row.collapse select,form .row .postfix-round.row.collapse button{border-radius:0;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px;border-bottom-left-radius:1000px;border-top-left-radius:1000px}form .row .postfix-round.row.collapse .postfix{border-radius:0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px;border-bottom-right-radius:1000px;border-top-right-radius:1000px}input[type="submit"]{-webkit-appearance:none;border-radius:0}textarea[rows]{height:auto}textarea{max-width:100%}select{-webkit-appearance:none !important;border-radius:0;background-color:#FAFAFA;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMTJweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIzcHgiIHZpZXdCb3g9IjAgMCA2IDMiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDYgMyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBvbHlnb24gcG9pbnRzPSI1Ljk5MiwwIDIuOTkyLDMgLTAuMDA4LDAgIi8+PC9zdmc+);background-position:100% center;background-repeat:no-repeat;border-style:solid;border-width:1px;border-color:#ccc;padding:.5rem;font-size:.875rem;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;color:rgba(0,0,0,0.75);line-height:normal;border-radius:0;height:2.3125rem}select::-ms-expand{display:none}select.radius{border-radius:3px}select:hover{background-color:#f3f2f2;border-color:#999}select:disabled{background-color:#ddd;cursor:default}select[multiple]{height:auto}input[type="file"],input[type="checkbox"],input[type="radio"],select{margin:0 0 1rem 0}input[type="checkbox"]+label,input[type="radio"]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type="file"]{width:100%}fieldset{border:1px solid #ddd;padding:1.25rem;margin:1.125rem 0}fieldset legend{font-weight:700;background:#fff;padding:0 .1875rem;margin:0;margin-left:-.1875rem}[data-abide] .error small.error,[data-abide] .error span.error,[data-abide] span.error,[data-abide] small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}[data-abide] span.error,[data-abide] small.error{display:none}span.error,small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}.error input,.error textarea,.error select{margin-bottom:0}.error input[type="checkbox"],.error input[type="radio"]{margin-bottom:1rem}.error label,.error label.error{color:#f04124}.error small.error{display:block;padding:.375rem .5625rem .5625rem;margin-top:-1px;margin-bottom:1rem;font-size:.75rem;font-weight:400;font-style:italic;background:#f04124;color:#fff}.error>label>small{color:#676767;background:transparent;padding:0;text-transform:capitalize;font-style:normal;font-size:60%;margin:0;display:inline}.error span.error-message{display:block}input.error,textarea.error,select.error{margin-bottom:0}label.error{color:#f04124}.row{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5rem}.row:before,.row:after{content:" ";display:table}.row:after{clear:both}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row.collapse .row{margin-left:0;margin-right:0}.row .row{width:auto;margin-left:-.9375rem;margin-right:-.9375rem;margin-top:0;margin-bottom:0;max-width:none}.row .row:before,.row .row:after{content:" ";display:table}.row .row:after{clear:both}.row .row.collapse{width:auto;margin:0;max-width:none}.row .row.collapse:before,.row .row.collapse:after{content:" ";display:table}.row .row.collapse:after{clear:both}.column,.columns{padding-left:.9375rem;padding-right:.9375rem;width:100%;float:left}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}@media only screen{.small-push-0{position:relative;left:0%;right:auto}.small-pull-0{position:relative;right:0%;left:auto}.small-push-1{position:relative;left:8.3333333333%;right:auto}.small-pull-1{position:relative;right:8.3333333333%;left:auto}.small-push-2{position:relative;left:16.6666666667%;right:auto}.small-pull-2{position:relative;right:16.6666666667%;left:auto}.small-push-3{position:relative;left:25%;right:auto}.small-pull-3{position:relative;right:25%;left:auto}.small-push-4{position:relative;left:33.3333333333%;right:auto}.small-pull-4{position:relative;right:33.3333333333%;left:auto}.small-push-5{position:relative;left:41.6666666667%;right:auto}.small-pull-5{position:relative;right:41.6666666667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{position:relative;right:50%;left:auto}.small-push-7{position:relative;left:58.3333333333%;right:auto}.small-pull-7{position:relative;right:58.3333333333%;left:auto}.small-push-8{position:relative;left:66.6666666667%;right:auto}.small-pull-8{position:relative;right:66.6666666667%;left:auto}.small-push-9{position:relative;left:75%;right:auto}.small-pull-9{position:relative;right:75%;left:auto}.small-push-10{position:relative;left:83.3333333333%;right:auto}.small-pull-10{position:relative;right:83.3333333333%;left:auto}.small-push-11{position:relative;left:91.6666666667%;right:auto}.small-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.small-1{width:8.3333333333%}.small-2{width:16.6666666667%}.small-3{width:25%}.small-4{width:33.3333333333%}.small-5{width:41.6666666667%}.small-6{width:50%}.small-7{width:58.3333333333%}.small-8{width:66.6666666667%}.small-9{width:75%}.small-10{width:83.3333333333%}.small-11{width:91.6666666667%}.small-12{width:100%}.small-offset-0{margin-left:0% !important}.small-offset-1{margin-left:8.3333333333% !important}.small-offset-2{margin-left:16.6666666667% !important}.small-offset-3{margin-left:25% !important}.small-offset-4{margin-left:33.3333333333% !important}.small-offset-5{margin-left:41.6666666667% !important}.small-offset-6{margin-left:50% !important}.small-offset-7{margin-left:58.3333333333% !important}.small-offset-8{margin-left:66.6666666667% !important}.small-offset-9{margin-left:75% !important}.small-offset-10{margin-left:83.3333333333% !important}.small-offset-11{margin-left:91.6666666667% !important}.small-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.small-centered,.columns.small-centered{margin-left:auto;margin-right:auto;float:none}.column.small-uncentered,.columns.small-uncentered{margin-left:0;margin-right:0;float:left}.column.small-centered:last-child,.columns.small-centered:last-child{float:none}.column.small-uncentered:last-child,.columns.small-uncentered:last-child{float:left}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right}.row.small-collapse>.column,.row.small-collapse>.columns{padding-left:0;padding-right:0}.row.small-collapse .row{margin-left:0;margin-right:0}.row.small-uncollapse>.column,.row.small-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}}@media only screen and (min-width: 40.0625em){.medium-push-0{position:relative;left:0%;right:auto}.medium-pull-0{position:relative;right:0%;left:auto}.medium-push-1{position:relative;left:8.3333333333%;right:auto}.medium-pull-1{position:relative;right:8.3333333333%;left:auto}.medium-push-2{position:relative;left:16.6666666667%;right:auto}.medium-pull-2{position:relative;right:16.6666666667%;left:auto}.medium-push-3{position:relative;left:25%;right:auto}.medium-pull-3{position:relative;right:25%;left:auto}.medium-push-4{position:relative;left:33.3333333333%;right:auto}.medium-pull-4{position:relative;right:33.3333333333%;left:auto}.medium-push-5{position:relative;left:41.6666666667%;right:auto}.medium-pull-5{position:relative;right:41.6666666667%;left:auto}.medium-push-6{position:relative;left:50%;right:auto}.medium-pull-6{position:relative;right:50%;left:auto}.medium-push-7{position:relative;left:58.3333333333%;right:auto}.medium-pull-7{position:relative;right:58.3333333333%;left:auto}.medium-push-8{position:relative;left:66.6666666667%;right:auto}.medium-pull-8{position:relative;right:66.6666666667%;left:auto}.medium-push-9{position:relative;left:75%;right:auto}.medium-pull-9{position:relative;right:75%;left:auto}.medium-push-10{position:relative;left:83.3333333333%;right:auto}.medium-pull-10{position:relative;right:83.3333333333%;left:auto}.medium-push-11{position:relative;left:91.6666666667%;right:auto}.medium-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.medium-1{width:8.3333333333%}.medium-2{width:16.6666666667%}.medium-3{width:25%}.medium-4{width:33.3333333333%}.medium-5{width:41.6666666667%}.medium-6{width:50%}.medium-7{width:58.3333333333%}.medium-8{width:66.6666666667%}.medium-9{width:75%}.medium-10{width:83.3333333333%}.medium-11{width:91.6666666667%}.medium-12{width:100%}.medium-offset-0{margin-left:0% !important}.medium-offset-1{margin-left:8.3333333333% !important}.medium-offset-2{margin-left:16.6666666667% !important}.medium-offset-3{margin-left:25% !important}.medium-offset-4{margin-left:33.3333333333% !important}.medium-offset-5{margin-left:41.6666666667% !important}.medium-offset-6{margin-left:50% !important}.medium-offset-7{margin-left:58.3333333333% !important}.medium-offset-8{margin-left:66.6666666667% !important}.medium-offset-9{margin-left:75% !important}.medium-offset-10{margin-left:83.3333333333% !important}.medium-offset-11{margin-left:91.6666666667% !important}.medium-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.medium-centered,.columns.medium-centered{margin-left:auto;margin-right:auto;float:none}.column.medium-uncentered,.columns.medium-uncentered{margin-left:0;margin-right:0;float:left}.column.medium-centered:last-child,.columns.medium-centered:last-child{float:none}.column.medium-uncentered:last-child,.columns.medium-uncentered:last-child{float:left}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right}.row.medium-collapse>.column,.row.medium-collapse>.columns{padding-left:0;padding-right:0}.row.medium-collapse .row{margin-left:0;margin-right:0}.row.medium-uncollapse>.column,.row.medium-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.3333333333%;right:auto}.pull-1{position:relative;right:8.3333333333%;left:auto}.push-2{position:relative;left:16.6666666667%;right:auto}.pull-2{position:relative;right:16.6666666667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.3333333333%;right:auto}.pull-4{position:relative;right:33.3333333333%;left:auto}.push-5{position:relative;left:41.6666666667%;right:auto}.pull-5{position:relative;right:41.6666666667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.3333333333%;right:auto}.pull-7{position:relative;right:58.3333333333%;left:auto}.push-8{position:relative;left:66.6666666667%;right:auto}.pull-8{position:relative;right:66.6666666667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.3333333333%;right:auto}.pull-10{position:relative;right:83.3333333333%;left:auto}.push-11{position:relative;left:91.6666666667%;right:auto}.pull-11{position:relative;right:91.6666666667%;left:auto}}@media only screen and (min-width: 64.0625em){.large-push-0{position:relative;left:0%;right:auto}.large-pull-0{position:relative;right:0%;left:auto}.large-push-1{position:relative;left:8.3333333333%;right:auto}.large-pull-1{position:relative;right:8.3333333333%;left:auto}.large-push-2{position:relative;left:16.6666666667%;right:auto}.large-pull-2{position:relative;right:16.6666666667%;left:auto}.large-push-3{position:relative;left:25%;right:auto}.large-pull-3{position:relative;right:25%;left:auto}.large-push-4{position:relative;left:33.3333333333%;right:auto}.large-pull-4{position:relative;right:33.3333333333%;left:auto}.large-push-5{position:relative;left:41.6666666667%;right:auto}.large-pull-5{position:relative;right:41.6666666667%;left:auto}.large-push-6{position:relative;left:50%;right:auto}.large-pull-6{position:relative;right:50%;left:auto}.large-push-7{position:relative;left:58.3333333333%;right:auto}.large-pull-7{position:relative;right:58.3333333333%;left:auto}.large-push-8{position:relative;left:66.6666666667%;right:auto}.large-pull-8{position:relative;right:66.6666666667%;left:auto}.large-push-9{position:relative;left:75%;right:auto}.large-pull-9{position:relative;right:75%;left:auto}.large-push-10{position:relative;left:83.3333333333%;right:auto}.large-pull-10{position:relative;right:83.3333333333%;left:auto}.large-push-11{position:relative;left:91.6666666667%;right:auto}.large-pull-11{position:relative;right:91.6666666667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.large-1{width:8.3333333333%}.large-2{width:16.6666666667%}.large-3{width:25%}.large-4{width:33.3333333333%}.large-5{width:41.6666666667%}.large-6{width:50%}.large-7{width:58.3333333333%}.large-8{width:66.6666666667%}.large-9{width:75%}.large-10{width:83.3333333333%}.large-11{width:91.6666666667%}.large-12{width:100%}.large-offset-0{margin-left:0% !important}.large-offset-1{margin-left:8.3333333333% !important}.large-offset-2{margin-left:16.6666666667% !important}.large-offset-3{margin-left:25% !important}.large-offset-4{margin-left:33.3333333333% !important}.large-offset-5{margin-left:41.6666666667% !important}.large-offset-6{margin-left:50% !important}.large-offset-7{margin-left:58.3333333333% !important}.large-offset-8{margin-left:66.6666666667% !important}.large-offset-9{margin-left:75% !important}.large-offset-10{margin-left:83.3333333333% !important}.large-offset-11{margin-left:91.6666666667% !important}.large-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.large-centered,.columns.large-centered{margin-left:auto;margin-right:auto;float:none}.column.large-uncentered,.columns.large-uncentered{margin-left:0;margin-right:0;float:left}.column.large-centered:last-child,.columns.large-centered:last-child{float:none}.column.large-uncentered:last-child,.columns.large-uncentered:last-child{float:left}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right}.row.large-collapse>.column,.row.large-collapse>.columns{padding-left:0;padding-right:0}.row.large-collapse .row{margin-left:0;margin-right:0}.row.large-uncollapse>.column,.row.large-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.3333333333%;right:auto}.pull-1{position:relative;right:8.3333333333%;left:auto}.push-2{position:relative;left:16.6666666667%;right:auto}.pull-2{position:relative;right:16.6666666667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.3333333333%;right:auto}.pull-4{position:relative;right:33.3333333333%;left:auto}.push-5{position:relative;left:41.6666666667%;right:auto}.pull-5{position:relative;right:41.6666666667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.3333333333%;right:auto}.pull-7{position:relative;right:58.3333333333%;left:auto}.push-8{position:relative;left:66.6666666667%;right:auto}.pull-8{position:relative;right:66.6666666667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.3333333333%;right:auto}.pull-10{position:relative;right:83.3333333333%;left:auto}.push-11{position:relative;left:91.6666666667%;right:auto}.pull-11{position:relative;right:91.6666666667%;left:auto}}.inline-list{margin:0 auto 1.0625rem auto;margin-left:-1.375rem;margin-right:0;padding:0;list-style:none;overflow:hidden}.inline-list>li{list-style:none;float:left;margin-left:1.375rem;display:block}.inline-list>li>*{display:block}.panel{border-style:solid;border-width:1px;border-color:#d8d8d8;margin-bottom:1.25rem;padding:1.25rem;background:#f2f2f2;color:#333}.panel>:first-child{margin-top:0}.panel>:last-child{margin-bottom:0}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6,.panel p,.panel li,.panel dl{color:#333}.panel h1,.panel h2,.panel h3,.panel h4,.panel h5,.panel h6{line-height:1;margin-bottom:.625rem}.panel h1.subheader,.panel h2.subheader,.panel h3.subheader,.panel h4.subheader,.panel h5.subheader,.panel h6.subheader{line-height:1.4}.panel.callout{border-style:solid;border-width:1px;border-color:#f6c4bf;margin-bottom:1.25rem;padding:1.25rem;background:#fdf0ef;color:#333}.panel.callout>:first-child{margin-top:0}.panel.callout>:last-child{margin-bottom:0}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6,.panel.callout p,.panel.callout li,.panel.callout dl{color:#333}.panel.callout h1,.panel.callout h2,.panel.callout h3,.panel.callout h4,.panel.callout h5,.panel.callout h6{line-height:1;margin-bottom:.625rem}.panel.callout h1.subheader,.panel.callout h2.subheader,.panel.callout h3.subheader,.panel.callout h4.subheader,.panel.callout h5.subheader,.panel.callout h6.subheader{line-height:1.4}.panel.callout a:not(.button){color:#ba2619}.panel.callout a:not(.button):hover,.panel.callout a:not(.button):focus{color:#a02116}.panel.radius{border-radius:3px}.side-nav{display:block;margin:0;padding:.875rem 0;list-style-type:none;list-style-position:outside;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif}.side-nav li{margin:0 0 .4375rem 0;font-size:.875rem;font-weight:400}.side-nav li a:not(.button){display:block;color:#ba2619;margin:0;padding:.4375rem .875rem}.side-nav li a:not(.button):hover,.side-nav li a:not(.button):focus{background:rgba(0,0,0,0.025);color:#e65346}.side-nav li.active>a:first-child:not(.button){color:#e65346;font-weight:400;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif}.side-nav li.divider{border-top:1px solid;height:0;padding:0;list-style:none;border-top-color:#fff}.side-nav li.heading{color:#ba2619;font-size:.875rem;font-weight:bold;text-transform:uppercase}table{background:#fff;margin-bottom:1.25rem;border:solid 1px #ddd;table-layout:auto}table caption{background:transparent;color:#222;font-size:1rem;font-weight:bold}table thead{background:#f5f5f5}table thead tr th,table thead tr td{padding:.5rem .625rem .625rem;font-size:.875rem;font-weight:700;color:#222}table tfoot{background:#f5f5f5}table tfoot tr th,table tfoot tr td{padding:.5rem .625rem .625rem;font-size:.875rem;font-weight:700;color:#222}table tr th,table tr td{padding:.5625rem .625rem;font-size:.875rem;color:#222;text-align:left}table tr.even,table tr.alt,table tr:nth-of-type(even){background:#F9F9F9}table thead tr th,table tfoot tr th,table tfoot tr td,table tbody tr th,table tbody tr td,table tr td{display:table-cell;line-height:1.125rem}.th{line-height:0;display:inline-block;border:solid 4px #fff;max-width:100%;box-shadow:0 0 0 1px rgba(0,0,0,0.2);transition:all 200ms ease-out}.th:hover,.th:focus{box-shadow:0 0 6px 1px rgba(186,38,25,0.5)}.th.radius{border-radius:3px}meta.foundation-mq-topbar{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}.contain-to-grid{width:100%;background:#333}.contain-to-grid .top-bar{margin-bottom:0}.fixed{width:100%;left:0;position:fixed;top:0;z-index:99}.fixed.expanded:not(.top-bar){overflow-y:auto;height:auto;width:100%;max-height:100%}.fixed.expanded:not(.top-bar) .title-area{position:fixed;width:100%;z-index:99}.fixed.expanded:not(.top-bar) .top-bar-section{z-index:98;margin-top:2.8125rem}.top-bar{overflow:hidden;height:2.8125rem;line-height:2.8125rem;position:relative;background:#333;margin-bottom:0}.top-bar ul{margin-bottom:0;list-style:none}.top-bar .row{max-width:none}.top-bar form,.top-bar input{margin-bottom:0}.top-bar input{height:1.75rem;padding-top:.35rem;padding-bottom:.35rem;font-size:.75rem}.top-bar .button,.top-bar button{padding-top:0.4125rem;padding-bottom:0.4125rem;margin-bottom:0;font-size:.75rem}@media only screen and (max-width: 40em){.top-bar .button,.top-bar button{position:relative;top:-1px}}.top-bar .title-area{position:relative;margin:0}.top-bar .name{height:2.8125rem;margin:0;font-size:16px}.top-bar .name h1,.top-bar .name h2,.top-bar .name h3,.top-bar .name h4,.top-bar .name p,.top-bar .name span{line-height:2.8125rem;font-size:1.0625rem;margin:0}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name p a,.top-bar .name span a{font-weight:400;color:#fff;width:75%;display:block;padding:0 .9375rem}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;text-transform:uppercase;font-size:.8125rem;font-weight:700;position:relative;display:block;padding:0 .9375rem;height:2.8125rem;line-height:2.8125rem}.top-bar .toggle-topbar.menu-icon{top:50%;margin-top:-16px}.top-bar .toggle-topbar.menu-icon a{height:34px;line-height:33px;padding:0 2.5rem 0 .9375rem;color:#fff;position:relative}.top-bar .toggle-topbar.menu-icon a span::after{content:"";position:absolute;display:block;height:0;top:50%;margin-top:-8px;right:.9375rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:16px}.top-bar .toggle-topbar.menu-icon a span:hover:after{box-shadow:0 0 0 1px "",0 7px 0 1px "",0 14px 0 1px ""}.top-bar.expanded{height:auto;background:transparent}.top-bar.expanded .title-area{background:#333}.top-bar.expanded .toggle-topbar a{color:#888}.top-bar.expanded .toggle-topbar a span::after{box-shadow:0 0 0 1px #888,0 7px 0 1px #888,0 14px 0 1px #888}.top-bar-section{left:0;position:relative;width:auto;transition:left 300ms ease-out}.top-bar-section ul{padding:0;width:100%;height:auto;display:block;font-size:16px;margin:0}.top-bar-section .divider,.top-bar-section [role="separator"]{border-top:solid 1px #1a1919;clear:both;height:1px;width:100%}.top-bar-section ul li{background:#333}.top-bar-section ul li>a{display:block;width:100%;color:#fff;padding:12px 0 12px 0;padding-left:.9375rem;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:.8125rem;font-weight:400;text-transform:none}.top-bar-section ul li>a.button{font-size:.8125rem;padding-right:.9375rem;padding-left:.9375rem;background-color:#ba2619;border-color:#951e14;color:#fff}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{background-color:#951e14}.top-bar-section ul li>a.button:hover,.top-bar-section ul li>a.button:focus{color:#fff}.top-bar-section ul li>a.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>a.button.secondary:hover,.top-bar-section ul li>a.button.secondary:focus{color:#333}.top-bar-section ul li>a.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{background-color:#368a55}.top-bar-section ul li>a.button.success:hover,.top-bar-section ul li>a.button.success:focus{color:#fff}.top-bar-section ul li>a.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>a.button.alert:hover,.top-bar-section ul li>a.button.alert:focus{color:#fff}.top-bar-section ul li>a.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>a.button.warning:hover,.top-bar-section ul li>a.button.warning:focus{color:#fff}.top-bar-section ul li>button{font-size:.8125rem;padding-right:.9375rem;padding-left:.9375rem;background-color:#ba2619;border-color:#951e14;color:#fff}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{background-color:#951e14}.top-bar-section ul li>button:hover,.top-bar-section ul li>button:focus{color:#fff}.top-bar-section ul li>button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{background-color:#b9b9b9}.top-bar-section ul li>button.secondary:hover,.top-bar-section ul li>button.secondary:focus{color:#333}.top-bar-section ul li>button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{background-color:#368a55}.top-bar-section ul li>button.success:hover,.top-bar-section ul li>button.success:focus{color:#fff}.top-bar-section ul li>button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{background-color:#cf2a0e}.top-bar-section ul li>button.alert:hover,.top-bar-section ul li>button.alert:focus{color:#fff}.top-bar-section ul li>button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{background-color:#cf6e0e}.top-bar-section ul li>button.warning:hover,.top-bar-section ul li>button.warning:focus{color:#fff}.top-bar-section ul li:hover:not(.has-form)>a{background-color:#555;background:#333;color:#fff}.top-bar-section ul li.active>a{background:#ba2619;color:#fff}.top-bar-section ul li.active>a:hover{background:#a02116;color:#fff}.top-bar-section .has-form{padding:.9375rem}.top-bar-section .has-dropdown{position:relative}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:transparent transparent transparent rgba(255,255,255,0.4);border-left-style:solid;margin-right:.9375rem;margin-top:-4.5px;position:absolute;top:50%;right:0}.top-bar-section .has-dropdown.moved{position:static}.top-bar-section .has-dropdown.moved>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important;width:100%}.top-bar-section .has-dropdown.moved>a:after{display:none}.top-bar-section .dropdown{padding:0;position:absolute;left:100%;top:0;z-index:99;display:block;position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}.top-bar-section .dropdown li{width:100%;height:auto}.top-bar-section .dropdown li a{font-weight:400;padding:8px .9375rem}.top-bar-section .dropdown li a.parent-link{font-weight:400}.top-bar-section .dropdown li.title h5,.top-bar-section .dropdown li.parent-link{margin-bottom:0;margin-top:0;font-size:1.125rem}.top-bar-section .dropdown li.title h5 a,.top-bar-section .dropdown li.parent-link a{color:#fff;display:block}.top-bar-section .dropdown li.title h5 a:hover,.top-bar-section .dropdown li.parent-link a:hover{background:none}.top-bar-section .dropdown li.has-form{padding:8px .9375rem}.top-bar-section .dropdown li .button,.top-bar-section .dropdown li button{top:auto}.top-bar-section .dropdown label{padding:8px .9375rem 2px;margin-bottom:0;text-transform:uppercase;color:#777;font-weight:700;font-size:.625rem}.js-generated{display:block}@media only screen and (min-width: 40.0625em){.top-bar{background:#333;overflow:visible}.top-bar:before,.top-bar:after{content:" ";display:table}.top-bar:after{clear:both}.top-bar .toggle-topbar{display:none}.top-bar .title-area{float:left}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name h5 a,.top-bar .name h6 a{width:auto}.top-bar input,.top-bar .button,.top-bar button{font-size:.875rem;position:relative;height:1.75rem;top:.53125rem}.top-bar.expanded{background:#333}.contain-to-grid .top-bar{max-width:62.5rem;margin:0 auto;margin-bottom:0}.top-bar-section{transition:none 0 0;left:0 !important}.top-bar-section ul{width:auto;height:auto !important;display:inline}.top-bar-section ul li{float:left}.top-bar-section ul li .js-generated{display:none}.top-bar-section li.hover>a:not(.button){background-color:#555;background:#333;color:#fff}.top-bar-section li:not(.has-form) a:not(.button){padding:0 .9375rem;line-height:2.8125rem;background:#333}.top-bar-section li:not(.has-form) a:not(.button):hover{background-color:#555;background:#333}.top-bar-section li.active:not(.has-form) a:not(.button){padding:0 .9375rem;line-height:2.8125rem;color:#fff;background:#ba2619}.top-bar-section li.active:not(.has-form) a:not(.button):hover{background:#a02116;color:#fff}.top-bar-section .has-dropdown>a{padding-right:2.1875rem !important}.top-bar-section .has-dropdown>a:after{content:"";display:block;width:0;height:0;border:inset 5px;border-color:rgba(255,255,255,0.4) transparent transparent transparent;border-top-style:solid;margin-top:-2.5px;top:1.40625rem}.top-bar-section .has-dropdown.moved{position:relative}.top-bar-section .has-dropdown.moved>.dropdown{display:block;position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}.top-bar-section .has-dropdown.hover>.dropdown,.top-bar-section .has-dropdown.not-click:hover>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.top-bar-section .has-dropdown>a:focus+.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.top-bar-section .has-dropdown .dropdown li.has-dropdown>a:after{border:none;content:"\00bb";top:1rem;margin-top:-1px;right:5px;line-height:1.2}.top-bar-section .dropdown{left:0;top:auto;background:transparent;min-width:100%}.top-bar-section .dropdown li a{color:#fff;line-height:2.8125rem;white-space:nowrap;padding:12px .9375rem;background:#333}.top-bar-section .dropdown li:not(.has-form):not(.active)>a:not(.button){color:#fff;background:#333}.top-bar-section .dropdown li:not(.has-form):not(.active):hover>a:not(.button){color:#fff;background-color:#555;background:#333}.top-bar-section .dropdown li label{white-space:nowrap;background:#333}.top-bar-section .dropdown li .dropdown{left:100%;top:0}.top-bar-section>ul>.divider,.top-bar-section>ul>[role="separator"]{border-bottom:none;border-top:none;border-right:solid 1px #4e4e4e;clear:none;height:2.8125rem;width:0}.top-bar-section .has-form{background:#333;padding:0 .9375rem;height:2.8125rem}.top-bar-section .right li .dropdown{left:auto;right:0}.top-bar-section .right li .dropdown li .dropdown{right:100%}.top-bar-section .left li .dropdown{right:auto;left:0}.top-bar-section .left li .dropdown li .dropdown{left:100%}.no-js .top-bar-section ul li:hover>a{background-color:#555;background:#333;color:#fff}.no-js .top-bar-section ul li:active>a{background:#ba2619;color:#fff}.no-js .top-bar-section .has-dropdown:hover>.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}.no-js .top-bar-section .has-dropdown>a:focus+.dropdown{display:block;position:static !important;height:auto;width:auto;overflow:visible;clip:auto;position:absolute !important}}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}@media only screen and (max-width: 40em){.small-only-text-left{text-align:left !important}.small-only-text-right{text-align:right !important}.small-only-text-center{text-align:center !important}.small-only-text-justify{text-align:justify !important}}@media only screen{.small-text-left{text-align:left !important}.small-text-right{text-align:right !important}.small-text-center{text-align:center !important}.small-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em) and (max-width: 64em){.medium-only-text-left{text-align:left !important}.medium-only-text-right{text-align:right !important}.medium-only-text-center{text-align:center !important}.medium-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.0625em){.medium-text-left{text-align:left !important}.medium-text-right{text-align:right !important}.medium-text-center{text-align:center !important}.medium-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em) and (max-width: 90em){.large-only-text-left{text-align:left !important}.large-only-text-right{text-align:right !important}.large-only-text-center{text-align:center !important}.large-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.0625em){.large-text-left{text-align:left !important}.large-text-right{text-align:right !important}.large-text-center{text-align:center !important}.large-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em) and (max-width: 120em){.xlarge-only-text-left{text-align:left !important}.xlarge-only-text-right{text-align:right !important}.xlarge-only-text-center{text-align:center !important}.xlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.0625em){.xlarge-text-left{text-align:left !important}.xlarge-text-right{text-align:right !important}.xlarge-text-center{text-align:center !important}.xlarge-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em) and (max-width: 99999999em){.xxlarge-only-text-left{text-align:left !important}.xxlarge-only-text-right{text-align:right !important}.xxlarge-only-text-center{text-align:center !important}.xxlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.0625em){.xxlarge-text-left{text-align:left !important}.xxlarge-text-right{text-align:right !important}.xxlarge-text-center{text-align:center !important}.xxlarge-text-justify{text-align:justify !important}}div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}a{color:#ba2619;text-decoration:none;line-height:inherit}a:hover,a:focus{color:#a02116}a img{border:none}p{font-family:inherit;font-weight:400;font-size:1rem;line-height:1.6;margin-bottom:1.25rem;text-rendering:optimizeLegibility}p.lead{font-size:1.21875rem;line-height:1.6}p aside{font-size:.875rem;line-height:1.35;font-style:italic}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-weight:700;font-style:normal;color:#222;text-rendering:optimizeLegibility;margin-top:.2rem;margin-bottom:.5rem;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-size:80%;color:#6f6f6f;line-height:0}h1{font-size:1.5625rem}h2{font-size:1.25rem}h3{font-size:1.0625rem}h4{font-size:.9375rem}h5{font-size:1rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;font-weight:400;margin-top:.2rem;margin-bottom:.5rem}hr{border:solid #ddd;border-width:1px 0 0;clear:both;margin:1.25rem 0 1.1875rem;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:700;line-height:inherit}small{font-size:80%;line-height:inherit}code{font-family:Consolas,"Liberation Mono",Courier,monospace;font-weight:400;color:#333;background-color:rgba(0,0,0,0.04);border-width:1px;border-style:none;border-color:rgba(0,0,0,0.04);padding:.125rem .3125rem .0625rem}ul,ol,dl{font-size:1rem;line-height:1.6;margin-bottom:1.25rem;list-style-position:outside;font-family:inherit}ul{margin-left:1.1rem}ul.no-bullet{margin-left:0}ul.no-bullet li ul,ul.no-bullet li ol{margin-left:1.25rem;margin-bottom:0;list-style:none}ul li ul,ul li ol{margin-left:1.25rem;margin-bottom:0}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square;margin-left:1.1rem}ul.circle{list-style-type:circle;margin-left:1.1rem}ul.disc{list-style-type:disc;margin-left:1.1rem}ul.no-bullet{list-style:none}ol{margin-left:1.4rem}ol li ul,ol li ol{margin-left:1.25rem;margin-bottom:0}dl dt{margin-bottom:.3rem;font-weight:700}dl dd{margin-bottom:.75rem}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222;cursor:help}abbr{text-transform:none}abbr[title]{border-bottom:1px dotted #ddd}blockquote{margin:0 0 1.25rem;padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.8125rem;color:#555}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:#555}blockquote,blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;margin:0 0 1.25rem 0;border:1px solid #ddd;padding:.625rem .75rem}.vcard li{margin:0;display:block}.vcard .fn{font-weight:700;font-size:.9375rem}.vevent .summary{font-weight:700}.vevent abbr{cursor:default;text-decoration:none;font-weight:700;border:none;padding:0 .0625rem}@media only screen and (min-width: 40.0625em){h1,h2,h3,h4,h5,h6{line-height:1.4}h1{font-size:1.875rem}h2{font-size:1.5625rem}h3{font-size:1.375rem}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:1rem}}@media only screen{.show-for-small-only,.show-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.hide-for-small-only,.hide-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.visible-for-small-only,.visible-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-small-only,.hidden-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.show-for-small-only,table.show-for-small-up,table.show-for-small,table.show-for-small-down,table.hide-for-medium-only,table.hide-for-medium-up,table.hide-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.show-for-small-only,thead.show-for-small-up,thead.show-for-small,thead.show-for-small-down,thead.hide-for-medium-only,thead.hide-for-medium-up,thead.hide-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.show-for-small-only,tbody.show-for-small-up,tbody.show-for-small,tbody.show-for-small-down,tbody.hide-for-medium-only,tbody.hide-for-medium-up,tbody.hide-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.show-for-small-only,tr.show-for-small-up,tr.show-for-small,tr.show-for-small-down,tr.hide-for-medium-only,tr.hide-for-medium-up,tr.hide-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.show-for-small-only,td.show-for-small-only,th.show-for-small-up,td.show-for-small-up,th.show-for-small,td.show-for-small,th.show-for-small-down,td.show-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.hide-for-medium-up,td.hide-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 40.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.show-for-medium-only,.show-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.show-for-medium-only,table.show-for-medium-up,table.show-for-medium,table.show-for-medium-down,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.show-for-medium-only,thead.show-for-medium-up,thead.show-for-medium,thead.show-for-medium-down,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.show-for-medium-only,tbody.show-for-medium-up,tbody.show-for-medium,tbody.show-for-medium-down,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.show-for-medium-only,tr.show-for-medium-up,tr.show-for-medium,tr.show-for-medium-down,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.show-for-medium-only,td.show-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.show-for-medium,td.show-for-medium,th.show-for-medium-down,td.show-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.hide-for-large-up,td.hide-for-large-up,th.hide-for-large,td.hide-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 64.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.show-for-large-only,.show-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.hide-for-large-only,.hide-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.visible-for-large-only,.visible-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.show-for-large-only,table.show-for-large-up,table.show-for-large,table.show-for-large-down,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.show-for-large-only,thead.show-for-large-up,thead.show-for-large,thead.show-for-large-down,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.show-for-large-only,tbody.show-for-large-up,tbody.show-for-large,tbody.show-for-large-down,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.show-for-large-only,tr.show-for-large-up,tr.show-for-large,tr.show-for-large-down,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.show-for-large-only,td.show-for-large-only,th.show-for-large-up,td.show-for-large-up,th.show-for-large,td.show-for-large,th.show-for-large-down,td.show-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.hide-for-xlarge-up,td.hide-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 90.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.show-for-xlarge-only,table.show-for-xlarge-up,table.show-for-xlarge,table.show-for-xlarge-down,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.hide-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.show-for-xlarge-only,thead.show-for-xlarge-up,thead.show-for-xlarge,thead.show-for-xlarge-down,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.hide-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.show-for-xlarge-only,tbody.show-for-xlarge-up,tbody.show-for-xlarge,tbody.show-for-xlarge-down,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.hide-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.show-for-xlarge-only,tr.show-for-xlarge-up,tr.show-for-xlarge,tr.show-for-xlarge-down,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.hide-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.show-for-xlarge-only,td.show-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.show-for-xlarge,td.show-for-xlarge,th.show-for-xlarge-down,td.show-for-xlarge-down,th.hide-for-xxlarge-only,td.hide-for-xxlarge-only,th.hide-for-xxlarge-up,td.hide-for-xxlarge-up,th.hide-for-xxlarge,td.hide-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}@media only screen and (min-width: 120.0625em){.hide-for-small-only,.show-for-small-up,.hide-for-small,.hide-for-small-down,.hide-for-medium-only,.show-for-medium-up,.hide-for-medium,.hide-for-medium-down,.hide-for-large-only,.show-for-large-up,.hide-for-large,.hide-for-large-down,.hide-for-xlarge-only,.show-for-xlarge-up,.hide-for-xlarge,.hide-for-xlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up,.show-for-xxlarge,.show-for-xxlarge-down{display:inherit !important}.show-for-small-only,.hide-for-small-up,.show-for-small,.show-for-small-down,.show-for-medium-only,.hide-for-medium-up,.show-for-medium,.show-for-medium-down,.show-for-large-only,.hide-for-large-up,.show-for-large,.show-for-large-down,.show-for-xlarge-only,.hide-for-xlarge-up,.show-for-xlarge,.show-for-xlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-down{display:none !important}.hidden-for-small-only,.visible-for-small-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-medium-only,.visible-for-medium-up,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-large-only,.visible-for-large-up,.hidden-for-large,.hidden-for-large-down,.hidden-for-xlarge-only,.visible-for-xlarge-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-down{position:static !important;height:auto;width:auto;overflow:visible;clip:auto}.visible-for-small-only,.hidden-for-small-up,.visible-for-small,.visible-for-small-down,.visible-for-medium-only,.hidden-for-medium-up,.visible-for-medium,.visible-for-medium-down,.visible-for-large-only,.hidden-for-large-up,.visible-for-large,.visible-for-large-down,.visible-for-xlarge-only,.hidden-for-xlarge-up,.visible-for-xlarge,.visible-for-xlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-down{position:absolute !important;height:1px;width:1px;overflow:hidden;clip:rect(1px, 1px, 1px, 1px)}table.hide-for-small-only,table.show-for-small-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-medium-only,table.show-for-medium-up,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-large-only,table.show-for-large-up,table.hide-for-large,table.hide-for-large-down,table.hide-for-xlarge-only,table.show-for-xlarge-up,table.hide-for-xlarge,table.hide-for-xlarge-down,table.show-for-xxlarge-only,table.show-for-xxlarge-up,table.show-for-xxlarge,table.show-for-xxlarge-down{display:table !important}thead.hide-for-small-only,thead.show-for-small-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-medium-only,thead.show-for-medium-up,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-large-only,thead.show-for-large-up,thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-xlarge-only,thead.show-for-xlarge-up,thead.hide-for-xlarge,thead.hide-for-xlarge-down,thead.show-for-xxlarge-only,thead.show-for-xxlarge-up,thead.show-for-xxlarge,thead.show-for-xxlarge-down{display:table-header-group !important}tbody.hide-for-small-only,tbody.show-for-small-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-medium-only,tbody.show-for-medium-up,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-large-only,tbody.show-for-large-up,tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-xlarge-only,tbody.show-for-xlarge-up,tbody.hide-for-xlarge,tbody.hide-for-xlarge-down,tbody.show-for-xxlarge-only,tbody.show-for-xxlarge-up,tbody.show-for-xxlarge,tbody.show-for-xxlarge-down{display:table-row-group !important}tr.hide-for-small-only,tr.show-for-small-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-medium-only,tr.show-for-medium-up,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-large-only,tr.show-for-large-up,tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-xlarge-only,tr.show-for-xlarge-up,tr.hide-for-xlarge,tr.hide-for-xlarge-down,tr.show-for-xxlarge-only,tr.show-for-xxlarge-up,tr.show-for-xxlarge,tr.show-for-xxlarge-down{display:table-row}th.hide-for-small-only,td.hide-for-small-only,th.show-for-small-up,td.show-for-small-up,th.hide-for-small,td.hide-for-small,th.hide-for-small-down,td.hide-for-small-down,th.hide-for-medium-only,td.hide-for-medium-only,th.show-for-medium-up,td.show-for-medium-up,th.hide-for-medium,td.hide-for-medium,th.hide-for-medium-down,td.hide-for-medium-down,th.hide-for-large-only,td.hide-for-large-only,th.show-for-large-up,td.show-for-large-up,th.hide-for-large,td.hide-for-large,th.hide-for-large-down,td.hide-for-large-down,th.hide-for-xlarge-only,td.hide-for-xlarge-only,th.show-for-xlarge-up,td.show-for-xlarge-up,th.hide-for-xlarge,td.hide-for-xlarge,th.hide-for-xlarge-down,td.hide-for-xlarge-down,th.show-for-xxlarge-only,td.show-for-xxlarge-only,th.show-for-xxlarge-up,td.show-for-xxlarge-up,th.show-for-xxlarge,td.show-for-xxlarge,th.show-for-xxlarge-down,td.show-for-xxlarge-down{display:table-cell !important}}.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.hide-for-landscape,table.show-for-portrait{display:table !important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group !important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group !important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row !important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell !important}@media only screen and (orientation: landscape){.show-for-landscape,.hide-for-portrait{display:inherit !important}.hide-for-landscape,.show-for-portrait{display:none !important}table.show-for-landscape,table.hide-for-portrait{display:table !important}thead.show-for-landscape,thead.hide-for-portrait{display:table-header-group !important}tbody.show-for-landscape,tbody.hide-for-portrait{display:table-row-group !important}tr.show-for-landscape,tr.hide-for-portrait{display:table-row !important}td.show-for-landscape,td.hide-for-portrait,th.show-for-landscape,th.hide-for-portrait{display:table-cell !important}}@media only screen and (orientation: portrait){.show-for-portrait,.hide-for-landscape{display:inherit !important}.hide-for-portrait,.show-for-landscape{display:none !important}table.show-for-portrait,table.hide-for-landscape{display:table !important}thead.show-for-portrait,thead.hide-for-landscape{display:table-header-group !important}tbody.show-for-portrait,tbody.hide-for-landscape{display:table-row-group !important}tr.show-for-portrait,tr.hide-for-landscape{display:table-row !important}td.show-for-portrait,td.hide-for-landscape,th.show-for-portrait,th.hide-for-landscape{display:table-cell !important}}.show-for-touch{display:none !important}.hide-for-touch{display:inherit !important}.touch .show-for-touch{display:inherit !important}.touch .hide-for-touch{display:none !important}table.hide-for-touch{display:table !important}.touch table.show-for-touch{display:table !important}thead.hide-for-touch{display:table-header-group !important}.touch thead.show-for-touch{display:table-header-group !important}tbody.hide-for-touch{display:table-row-group !important}.touch tbody.show-for-touch{display:table-row-group !important}tr.hide-for-touch{display:table-row !important}.touch tr.show-for-touch{display:table-row !important}td.hide-for-touch{display:table-cell !important}.touch td.show-for-touch{display:table-cell !important}th.hide-for-touch{display:table-cell !important}.touch th.show-for-touch{display:table-cell !important}.print-only{display:none !important}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.hide-on-print{display:none !important}.print-only{display:block !important}.hide-for-print{display:none !important}.show-for-print{display:inherit !important}}@media print{.show-for-print{display:block}.hide-for-print{display:none}table.show-for-print{display:table !important}thead.show-for-print{display:table-header-group !important}tbody.show-for-print{display:table-row-group !important}tr.show-for-print{display:table-row !important}td.show-for-print{display:table-cell !important}th.show-for-print{display:table-cell !important}}.slick-slider{position:relative;display:block;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;overflow:hidden;display:block;margin:0;padding:0}.slick-list:focus{outline:none}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-track,.slick-slider .slick-list{-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}.slick-track{position:relative;left:0;top:0;display:block}.slick-track:before,.slick-track:after{content:"";display:table}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{float:left;height:100%;min-height:1px;display:none}[dir="rtl"] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-loading .slick-list{background:#fff url("../img/ajax-loader.gif") center center no-repeat}.slick-prev,.slick-next{position:absolute;display:block;height:20px;width:20px;line-height:0;font-size:0;cursor:pointer;background:transparent;color:transparent;top:50%;margin-top:-10px;padding:0;border:none;outline:none}.slick-prev:hover,.slick-prev:focus,.slick-next:hover,.slick-next:focus{outline:none;background:transparent;color:transparent}.slick-prev:hover:before,.slick-prev:focus:before,.slick-next:hover:before,.slick-next:focus:before{opacity:1}.slick-prev.slick-disabled:before,.slick-next.slick-disabled:before{opacity:.25}.slick-prev:before,.slick-next:before{font-family:"FontAwesome";font-size:20px;line-height:1;color:#ba2619;opacity:.75;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-prev{left:15px}[dir="rtl"] .slick-prev{left:auto;right:15px}.slick-prev:before{content:""}[dir="rtl"] .slick-prev:before{content:""}.slick-next{right:15px}[dir="rtl"] .slick-next{left:15px;right:auto}.slick-next:before{content:""}[dir="rtl"] .slick-next:before{content:""}.slick-slider{margin-bottom:30px}.slick-dots{margin:0;position:absolute;bottom:30px;list-style:none;display:block;text-align:center;padding:0;width:100%}.slick-dots li{position:relative;display:inline-block;height:20px;width:20px;margin:0 5px;padding:0;cursor:pointer}.slick-dots li button{border:0;background:transparent;display:block;height:20px;width:20px;outline:none;line-height:0;font-size:0;color:transparent;padding:5px;cursor:pointer}.slick-dots li button:hover,.slick-dots li button:focus{outline:none}.slick-dots li button:hover:before,.slick-dots li button:focus:before{opacity:1}.slick-dots li button:before{position:absolute;top:0;left:0;content:"";width:20px;height:20px;font-family:"FontAwesome";font-size:12px;line-height:20px;text-align:center;color:#000;opacity:.25;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-dots li.slick-active button:before{color:#ba2619;opacity:.75}/*! * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url("./fonts/fontawesome-webfont.eot?v=4.4.0");src:url("./fonts/fontawesome-webfont.eot?#iefix&v=4.4.0") format("embedded-opentype"),url("./fonts/fontawesome-webfont.woff2?v=4.4.0") format("woff2"),url("./fonts/fontawesome-webfont.woff?v=4.4.0") format("woff"),url("./fonts/fontawesome-webfont.ttf?v=4.4.0") format("truetype"),url("./fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.maxWidth{width:100%}.hidden{display:none}*{transition:all 0.15s ease}body{background-color:#333}body>main{padding:2.5rem 0;background-color:#fff}@media only screen and (max-width: 40em){body>main{padding:1.25rem 0}}body>main img{margin-bottom:1.25rem}@media only screen and (max-width: 40em){aside{margin-bottom:1.5rem}}@media only screen and (max-width: 40em){.row{overflow:hidden}}body>footer{background-color:#333;padding:2.5rem 0;color:#999}body>footer p,body>footer h1,body>footer h2,body>footer h3,body>footer h4,body>footer h5,body>footer h6{color:inherit}body>footer a{color:#e23424}code{font-size:85%;color:inherit !important;overflow-x:scroll;-webkit-overflow-scrolling:touch}.highlight{border:solid 1px #ddd;background:#fff;padding:1em;line-height:23px;margin-bottom:30px;white-space:pre;overflow-x:auto;word-break:inherit;word-wrap:inherit;background:#ffffff}@media only screen and (max-width: 40em){.highlight{overflow-x:scroll;-webkit-overflow-scrolling:touch}}.highlight code{background-color:transparent;border:none;padding:0}.highlight td{padding:8px 15px}.highlight .gl{background:#fafafa;border-right:1px solid #ddd;color:#999;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.highlight .c{color:#999988;font-style:italic}.highlight .err{color:#a61717;background-color:#e3d2d2}.highlight .k{font-weight:bold}.highlight .o{font-weight:bold}.highlight .cm{color:#999988;font-style:italic}.highlight .cp{color:#999999;font-weight:bold}.highlight .c1{color:#999988;font-style:italic}.highlight .cs{color:#999999;font-weight:bold;font-style:italic}.highlight .gd{color:#000000;background-color:#ffdddd}.highlight .gd .x{color:#000000;background-color:#ffaaaa}.highlight .ge{font-style:italic}.highlight .gr{color:#aa0000}.highlight .gh{color:#999999}.highlight .gi{color:#000000;background-color:#ddffdd}.highlight .gi .x{color:#000000;background-color:#aaffaa}.highlight .go{color:#888888}.highlight .gp{color:#555555}.highlight .gs{font-weight:bold}.highlight .gu{color:#aaaaaa}.highlight .gt{color:#aa0000}.highlight .kc{font-weight:bold}.highlight .kd{font-weight:bold}.highlight .kp{font-weight:bold}.highlight .kr{font-weight:bold}.highlight .kt{color:#445588;font-weight:bold}.highlight .m{color:#009999}.highlight .s{color:#d14}.highlight .na{color:#008080}.highlight .nb{color:#0086B3}.highlight .nc{color:#445588;font-weight:bold}.highlight .no{color:#008080}.highlight .ni{color:#800080}.highlight .ne{color:#990000;font-weight:bold}.highlight .nf{color:#990000;font-weight:bold}.highlight .nn{color:#555555}.highlight .nt{color:#000080}.highlight .nv{color:#008080}.highlight .ow{font-weight:bold}.highlight .w{color:#bbbbbb}.highlight .mf{color:#009999}.highlight .mh{color:#009999}.highlight .mi{color:#009999}.highlight .mo{color:#009999}.highlight .sb{color:#d14}.highlight .sc{color:#d14}.highlight .sd{color:#d14}.highlight .s2{color:#d14}.highlight .se{color:#d14}.highlight .sh{color:#d14}.highlight .si{color:#d14}.highlight .sx{color:#d14}.highlight .sr{color:#009926}.highlight .s1{color:#d14}.highlight .ss{color:#990073}.highlight .bp{color:#999999}.highlight .vc{color:#008080}.highlight .vg{color:#008080}.highlight .vi{color:#008080}.highlight .il{color:#009999}kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.social__icons{margin-bottom:10px}.social__icon{display:inline-block;margin-right:10px}.slider picture img{width:100%}.videoWrapper{position:relative;padding-top:56.25%;margin-bottom:1.25rem}.videoWrapper iframe{position:absolute;top:0;left:0;width:100%;height:100%}.icon{position:relative;top:1px;display:inline-block;width:16px;height:16px}.icon-color{border:1px solid #aaa}.icon-color-white{background-color:#fff}.icon-color-black{background-color:#000}.icon-color-red{background-color:#ba2619}.toc-header{margin-bottom:0}#toc{display:block;margin:1rem 0 0 0}#toc>ol{margin-left:0}#toc>ol>li{margin-bottom:0.5rem}#toc ol{list-style-type:none}.clickable-header{cursor:pointer}.clickable-header:hover{text-decoration:underline}.top-level-header{display:inline-block}.back-to-top{position:relative;margin-left:8px;cursor:pointer;top:-3px}.contentSearch{margin-bottom:30px}@media only screen and (max-width: 40em){.contentSearch{margin-bottom:5px}}.contentSearch-wrapper{position:relative}.contentSearch-wrapper.small-collapse{margin:0 !important}.liveSearch-field{margin-bottom:0 !important}.liveSearch-button{margin-bottom:0}.liveSearch-result-list{position:absolute;width:100%;height:auto;background:white;border:1px #ccc;border-style:none solid solid solid;z-index:99;margin:0;list-style-type:none}@media only screen and (max-width: 40em){.liveSearch-result-list{position:relative}}.liveSearch-result-list li a{-webkit-transition:all 0.15s ease;transition:all 0.15s ease;padding:4px 10px;display:block;width:100%;height:100%;line-height:1.2}.liveSearch-result-list li a:hover{background-color:#eee}.liveSearch-result-list li a:first-child{padding-top:8px}.liveSearch-result-list li a:last-child{padding-bottom:8px}.searchPage-result-list{line-height:1.2;list-style-type:none}.searchPage-result-list li{margin-bottom:20px}@media only screen and (max-width: 40em){.searchPage-result-list li{margin-bottom:15px}}.searchPage-result-list li a{font-weight:bold;color:#1a0dab}.searchPage-result-list li a:hover{color:#1a0dab;text-decoration:underline}.searchPage-result-list li .url{color:#006621}@media only screen and (max-width: 40em){.searchPage-result-list li .additionalInfo{display:none}}.article-list{margin:0;padding:0;list-style-type:none}.article-list header h1{font-size:1.5rem}article header{margin-bottom:0.5rem}article header h1{margin-bottom:0}article .meta{font-size:0.9em}.table-wrapper{width:100%;overflow-y:auto;_overflow:auto;margin:0 0 1em} + */@font-face{font-family:'FontAwesome';src:url("./fonts/fontawesome-webfont.eot?v=4.4.0");src:url("./fonts/fontawesome-webfont.eot?#iefix&v=4.4.0") format("embedded-opentype"),url("./fonts/fontawesome-webfont.woff2?v=4.4.0") format("woff2"),url("./fonts/fontawesome-webfont.woff?v=4.4.0") format("woff"),url("./fonts/fontawesome-webfont.ttf?v=4.4.0") format("truetype"),url("./fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.maxWidth{width:100%}.hidden{display:none}*{transition:all 0.15s ease}body{background-color:#333}body>main{padding:2.5rem 0;background-color:#fff}@media only screen and (max-width: 40em){body>main{padding:1.25rem 0}}body>main img{margin-bottom:1.25rem}@media only screen and (max-width: 40em){aside{margin-bottom:1.5rem}}@media only screen and (max-width: 40em){.row{overflow:hidden}}body>footer{background-color:#333;padding:2.5rem 0;color:#999}body>footer p,body>footer h1,body>footer h2,body>footer h3,body>footer h4,body>footer h5,body>footer h6{color:inherit}body>footer a{color:#e23424}code{font-size:85%;color:inherit !important;overflow-x:scroll;-webkit-overflow-scrolling:touch}pre.highlight{border:solid 1px #ddd;background:#fff;padding:1em;line-height:23px;margin-bottom:30px;white-space:pre;overflow-x:auto;word-break:inherit;word-wrap:inherit;background:#ffffff}@media only screen and (max-width: 40em){pre.highlight{overflow-x:scroll;-webkit-overflow-scrolling:touch}}pre.highlight code{background-color:transparent;border:none;padding:0}pre.highlight td{padding:8px 15px}pre.highlight .gl{background:#fafafa;border-right:1px solid #ddd;color:#999;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}pre.highlight .c{color:#999988;font-style:italic}pre.highlight .err{color:#a61717;background-color:#e3d2d2}pre.highlight .k{font-weight:bold}pre.highlight .o{font-weight:bold}pre.highlight .cm{color:#999988;font-style:italic}pre.highlight .cp{color:#999999;font-weight:bold}pre.highlight .c1{color:#999988;font-style:italic}pre.highlight .cs{color:#999999;font-weight:bold;font-style:italic}pre.highlight .gd{color:#000000;background-color:#ffdddd}pre.highlight .gd .x{color:#000000;background-color:#ffaaaa}pre.highlight .ge{font-style:italic}pre.highlight .gr{color:#aa0000}pre.highlight .gh{color:#999999}pre.highlight .gi{color:#000000;background-color:#ddffdd}pre.highlight .gi .x{color:#000000;background-color:#aaffaa}pre.highlight .go{color:#888888}pre.highlight .gp{color:#555555}pre.highlight .gs{font-weight:bold}pre.highlight .gu{color:#aaaaaa}pre.highlight .gt{color:#aa0000}pre.highlight .kc{font-weight:bold}pre.highlight .kd{font-weight:bold}pre.highlight .kp{font-weight:bold}pre.highlight .kr{font-weight:bold}pre.highlight .kt{color:#445588;font-weight:bold}pre.highlight .m{color:#009999}pre.highlight .s{color:#d14}pre.highlight .na{color:#008080}pre.highlight .nb{color:#0086B3}pre.highlight .nc{color:#445588;font-weight:bold}pre.highlight .no{color:#008080}pre.highlight .ni{color:#800080}pre.highlight .ne{color:#990000;font-weight:bold}pre.highlight .nf{color:#990000;font-weight:bold}pre.highlight .nn{color:#555555}pre.highlight .nt{color:#000080}pre.highlight .nv{color:#008080}pre.highlight .ow{font-weight:bold}pre.highlight .w{color:#bbbbbb}pre.highlight .mf{color:#009999}pre.highlight .mh{color:#009999}pre.highlight .mi{color:#009999}pre.highlight .mo{color:#009999}pre.highlight .sb{color:#d14}pre.highlight .sc{color:#d14}pre.highlight .sd{color:#d14}pre.highlight .s2{color:#d14}pre.highlight .se{color:#d14}pre.highlight .sh{color:#d14}pre.highlight .si{color:#d14}pre.highlight .sx{color:#d14}pre.highlight .sr{color:#009926}pre.highlight .s1{color:#d14}pre.highlight .ss{color:#990073}pre.highlight .bp{color:#999999}pre.highlight .vc{color:#008080}pre.highlight .vg{color:#008080}pre.highlight .vi{color:#008080}pre.highlight .il{color:#009999}kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.social__icons{margin-bottom:10px}.social__icon{display:inline-block;margin-right:10px}.slider picture img{width:100%}.videoWrapper{position:relative;padding-top:56.25%;margin-bottom:1.25rem}.videoWrapper iframe{position:absolute;top:0;left:0;width:100%;height:100%}.icon{position:relative;top:1px;display:inline-block;width:16px;height:16px}.icon-color{border:1px solid #aaa}.icon-color-white{background-color:#fff}.icon-color-black{background-color:#000}.icon-color-red{background-color:#ba2619}.toc-header{margin-bottom:0}#toc{display:block;margin:1rem 0 0 0}#toc>ol{margin-left:0}#toc>ol>li{margin-bottom:0.5rem}#toc ol{list-style-type:none}.clickable-header{cursor:pointer}.clickable-header:hover{text-decoration:underline}.top-level-header{display:inline-block}.back-to-top{position:relative;margin-left:8px;cursor:pointer;top:-3px}.contentSearch{margin-bottom:30px}@media only screen and (max-width: 40em){.contentSearch{margin-bottom:5px}}.contentSearch-wrapper{position:relative}.contentSearch-wrapper.small-collapse{margin:0 !important}.liveSearch-field{margin-bottom:0 !important}.liveSearch-button{margin-bottom:0}.liveSearch-result-list{position:absolute;width:100%;height:auto;background:white;border:1px #ccc;border-style:none solid solid solid;z-index:99;margin:0;list-style-type:none}@media only screen and (max-width: 40em){.liveSearch-result-list{position:relative}}.liveSearch-result-list li a{-webkit-transition:all 0.15s ease;transition:all 0.15s ease;padding:4px 10px;display:block;width:100%;height:100%;line-height:1.2}.liveSearch-result-list li a:hover{background-color:#eee}.liveSearch-result-list li a:first-child{padding-top:8px}.liveSearch-result-list li a:last-child{padding-bottom:8px}.searchPage-result-list{line-height:1.2;list-style-type:none}.searchPage-result-list li{margin-bottom:20px}@media only screen and (max-width: 40em){.searchPage-result-list li{margin-bottom:15px}}.searchPage-result-list li a{font-weight:bold;color:#1a0dab}.searchPage-result-list li a:hover{color:#1a0dab;text-decoration:underline}.searchPage-result-list li .url{color:#006621}@media only screen and (max-width: 40em){.searchPage-result-list li .additionalInfo{display:none}}.article-list{margin:0;padding:0;list-style-type:none}.article-list header h1{font-size:1.5rem}article header{margin-bottom:0.5rem}article header h1{margin-bottom:0}article .meta{font-size:0.9em}.table-wrapper{width:100%;overflow-y:auto;_overflow:auto;margin:0 0 1em} diff --git a/docs/docker-compose.yml b/docs/docker-compose.yml index 9999a5b6e8..0795ef1b5c 100644 --- a/docs/docker-compose.yml +++ b/docs/docker-compose.yml @@ -1,9 +1,13 @@ -version: '2' +version: "3.2" services: docs: - build: . - restart: always + container_name: ace3mod_jekyll + build: + context: . + dockerfile: Dockerfile + environment: + - JEKYLLARGS=--incremental ports: - "4000:4000" volumes: diff --git a/docs/entrypoint.sh b/docs/entrypoint.sh new file mode 100644 index 0000000000..d15c7f7baa --- /dev/null +++ b/docs/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +jekyll serve --future --config _config_dev.yml -H 0.0.0.0 -P 4000 ${JEKYLLARGS} diff --git a/docs/img/news/170714_jet_rearm.jpg b/docs/img/news/170714_jet_rearm.jpg new file mode 100644 index 0000000000..4c1de1ba42 Binary files /dev/null and b/docs/img/news/170714_jet_rearm.jpg differ diff --git a/docs/img/news/170714_logo-intercept.png b/docs/img/news/170714_logo-intercept.png new file mode 100644 index 0000000000..a279195750 Binary files /dev/null and b/docs/img/news/170714_logo-intercept.png differ diff --git a/docs/img/news/171220_cbaPost2.jpg b/docs/img/news/171220_cbaPost2.jpg new file mode 100644 index 0000000000..c55c64c47e Binary files /dev/null and b/docs/img/news/171220_cbaPost2.jpg differ diff --git a/docs/img/scope_module.jpg b/docs/img/scope_module.jpg deleted file mode 100644 index 19629bddd7..0000000000 Binary files a/docs/img/scope_module.jpg and /dev/null differ diff --git a/docs/img/wiki/feature/ab_module.jpg b/docs/img/wiki/feature/ab_module.jpg deleted file mode 100644 index 70d2ec52b5..0000000000 Binary files a/docs/img/wiki/feature/ab_module.jpg and /dev/null differ diff --git a/docs/img/wiki/feature/ab_module1.jpg b/docs/img/wiki/feature/ab_module1.jpg new file mode 100644 index 0000000000..2eb900ee3c Binary files /dev/null and b/docs/img/wiki/feature/ab_module1.jpg differ diff --git a/docs/img/wiki/feature/atragmx3.png b/docs/img/wiki/feature/atragmx31.png similarity index 50% rename from docs/img/wiki/feature/atragmx3.png rename to docs/img/wiki/feature/atragmx31.png index dd4a1800e1..58afd1863e 100644 Binary files a/docs/img/wiki/feature/atragmx3.png and b/docs/img/wiki/feature/atragmx31.png differ diff --git a/docs/img/wiki/feature/atragmx31a.png b/docs/img/wiki/feature/atragmx31a.png new file mode 100644 index 0000000000..39ee84200c Binary files /dev/null and b/docs/img/wiki/feature/atragmx31a.png differ diff --git a/docs/img/wiki/feature/atragmx4.png b/docs/img/wiki/feature/atragmx4.png deleted file mode 100644 index 7db5b69077..0000000000 Binary files a/docs/img/wiki/feature/atragmx4.png and /dev/null differ diff --git a/docs/img/wiki/feature/atragmx41.png b/docs/img/wiki/feature/atragmx41.png new file mode 100644 index 0000000000..d89f6c1757 Binary files /dev/null and b/docs/img/wiki/feature/atragmx41.png differ diff --git a/docs/img/wiki/feature/atragmx5.png b/docs/img/wiki/feature/atragmx5.png new file mode 100644 index 0000000000..6cba04cdd5 Binary files /dev/null and b/docs/img/wiki/feature/atragmx5.png differ diff --git a/docs/img/wiki/feature/scope_module.jpg b/docs/img/wiki/feature/scope_module.jpg deleted file mode 100644 index 19629bddd7..0000000000 Binary files a/docs/img/wiki/feature/scope_module.jpg and /dev/null differ diff --git a/docs/img/wiki/feature/scope_module1.jpg b/docs/img/wiki/feature/scope_module1.jpg new file mode 100644 index 0000000000..4f5f8829f2 Binary files /dev/null and b/docs/img/wiki/feature/scope_module1.jpg differ diff --git a/docs/img/wiki/feature/simplified_zeroing.jpg b/docs/img/wiki/feature/simplified_zeroing.jpg new file mode 100644 index 0000000000..55a6ba6b20 Binary files /dev/null and b/docs/img/wiki/feature/simplified_zeroing.jpg differ diff --git a/docs/js/footer.min.js b/docs/js/footer.min.js index c12f82fe62..7e9a86bd64 100644 --- a/docs/js/footer.min.js +++ b/docs/js/footer.min.js @@ -1,7 +1,7 @@ -window.Modernizr=function(a,b,c){function d(a){o.cssText=a}function e(a,b){return typeof a===b}var f,g,h,i="2.8.3",j={},k=!0,l=b.documentElement,m="modernizr",n=b.createElement(m),o=n.style,p=({}.toString,{}),q=[],r=q.slice,s={}.hasOwnProperty;h=e(s,"undefined")||e(s.call,"undefined")?function(a,b){return b in a&&e(a.constructor.prototype[b],"undefined")}:function(a,b){return s.call(a,b)},Function.prototype.bind||(Function.prototype.bind=function(a){var b=this;if("function"!=typeof b)throw new TypeError;var c=r.call(arguments,1),d=function(){if(this instanceof d){var e=function(){};e.prototype=b.prototype;var f=new e,g=b.apply(f,c.concat(r.call(arguments)));return Object(g)===g?g:f}return b.apply(a,c.concat(r.call(arguments)))};return d});for(var t in p)h(p,t)&&(g=t.toLowerCase(),j[g]=p[t](),q.push((j[g]?"":"no-")+g));return j.addTest=function(a,b){if("object"==typeof a)for(var d in a)h(a,d)&&j.addTest(d,a[d]);else{if(a=a.toLowerCase(),j[a]!==c)return j;b="function"==typeof b?b():b,"undefined"!=typeof k&&k&&(l.className+=" "+(b?"":"no-")+a),j[a]=b}return j},d(""),n=f=null,function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=s.elements;return"string"==typeof a?a.split(" "):a}function e(a){var b=r[a[p]];return b||(b={},q++,a[p]=q,r[q]=b),b}function f(a,c,d){if(c||(c=b),k)return c.createElement(a);d||(d=e(c));var f;return f=d.cache[a]?d.cache[a].cloneNode():o.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!f.canHaveChildren||n.test(a)||f.tagUrn?f:d.frag.appendChild(f)}function g(a,c){if(a||(a=b),k)return a.createDocumentFragment();c=c||e(a);for(var f=c.frag.cloneNode(),g=0,h=d(),i=h.length;g",j="hidden"in a,k=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(a){j=!0,k=!0}}();var s={elements:m.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:l,shivCSS:m.shivCSS!==!1,supportsUnknownElements:k,shivMethods:m.shivMethods!==!1,type:"default",shivDocument:i,createElement:f,createDocumentFragment:g};a.html5=s,i(b)}(this,b),j._version=i,l.className=l.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(k?" js "+q.join(" "):""),j}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==q.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=r.shift();s=1,a?a.t?o(function(){("c"==a.t?m.injectCss:m.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):s=0}function i(a,c,d,e,f,i,j){function k(b){if(!n&&g(l.readyState)&&(t.r=n=1,!s&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&o(function(){v.removeChild(l)},50);for(var d in A[c])A[c].hasOwnProperty(d)&&A[c][d].onload()}}var j=j||m.errorTimeout,l=b.createElement(a),n=0,q=0,t={t:d,s:c,e:f,a:i,x:j};1===A[c]&&(q=1,A[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,q)},r.splice(e,0,t),"img"!=a&&(q||2===A[c]?(v.insertBefore(l,u?null:p),o(k,j)):A[c].push(l))}function j(a,b,c,d,f){return s=0,b=b||"j",e(a)?i("c"==b?x:w,a,b,this.i++,c,d,f):(r.splice(this.i++,0,a),1==r.length&&h()),this}function k(){var a=m;return a.loader={load:j,i:0},a}var l,m,n=b.documentElement,o=a.setTimeout,p=b.getElementsByTagName("script")[0],q={}.toString,r=[],s=0,t="MozAppearance"in n.style,u=t&&!!b.createRange().compareNode,v=u?n:p.parentNode,n=a.opera&&"[object Opera]"==q.call(a.opera),n=!!b.attachEvent&&!n,w=t?"object":n?"script":"img",x=n?"script":w,y=Array.isArray||function(a){return"[object Array]"==q.call(a)},z=[],A={},B={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}};m=function(a){function b(a){var b,c,d,a=a.split("!"),e=z.length,f=a.pop(),g=a.length,f={url:f,origUrl:f,prefixes:a};for(c=0;ca._pfLastSize)&&(a._pfLastSize=a.offsetWidth,d=a.sizes,a.sizes+=",100vw",setTimeout(function(){a.sizes=d}))},e=function(){var a,b=document.querySelectorAll("picture > img, img[srcset][sizes]");for(a=0;a2.7?h=c+1:(f=b-c,e=Math.pow(a-.6,1.5),g=f*e,d&&(g+=.1*e),h=a+g):h=c>1?Math.sqrt(a*b):a,h>c}function h(a){var b,c=s.getSet(a),d=!1;"pending"!==c&&(d=r,c&&(b=s.setRes(c),s.applySetCandidate(b,a))),a[s.ns].evaled=d}function i(a,b){return a.res-b.res}function j(a,b,c){var d;return!c&&b&&(c=a[s.ns].sets,c=c&&c[c.length-1]),d=k(b,c),d&&(b=s.makeUrl(b),a[s.ns].curSrc=b,a[s.ns].curCan=d,d.res||aa(d,d.set.sizes)),d}function k(a,b){var c,d,e;if(a&&b)for(e=s.parseSet(b),a=s.makeUrl(a),c=0;c=l)return n;g=c(V),h=[],","===g.slice(-1)?(g=g.replace(W,""),e()):f()}}function n(a){function b(a){function b(){f&&(g.push(f),f="")}function c(){g[0]&&(h.push(g),g=[])}for(var e,f="",g=[],h=[],i=0,j=0,k=!1;;){if(e=a.charAt(j),""===e)return b(),c(),h;if(k){if("*"===e&&"/"===a[j+1]){k=!1,j+=2,b();continue}j+=1}else{if(d(e)){if(a.charAt(j-1)&&d(a.charAt(j-1))||!f){j+=1;continue}if(0===i){b(),j+=1;continue}e=" "}else if("("===e)i+=1;else if(")"===e)i-=1;else{if(","===e){b(),c(),j+=1;continue}if("/"===e&&"*"===a.charAt(j+1)){k=!0,j+=2;continue}}f+=e,j+=1}}}function c(a){return!!(k.test(a)&&parseFloat(a)>=0)||(!!l.test(a)||("0"===a||"-0"===a||"+0"===a))}var e,f,g,h,i,j,k=/^(?:[+-]?[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?(?:ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmin|vmax|vw)$/i,l=/^calc\((?:[0-9a-z \.\+\-\*\/\(\)]+)\)$/i;for(f=b(a),g=f.length,e=0;e35,G="currentSrc",H=/\s+\+?\d+(e\d+)?w/,I=/(\([^)]+\))?\s*(.+)/,J=a.picturefillCFG,K="position:absolute;left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;overflow:hidden;clip:rect(0px, 0px, 0px, 0px)",L="font-size:100%!important;",M=!0,N={},O={},P=a.devicePixelRatio,Q={px:1,in:96},R=b.createElement("a"),S=!1,T=/^[ \t\n\r\u000c]+/,U=/^[, \t\n\r\u000c]+/,V=/^[^ \t\n\r\u000c]+/,W=/[,]+$/,X=/^\d+$/,Y=/^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/,Z=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d||!1):a.attachEvent&&a.attachEvent("on"+b,c)},$=function(a){var b={};return function(c){return c in b||(b[c]=a(c)),b[c]}},_=function(){var a=/^([\d\.]+)(em|vw|px)$/,b=function(){for(var a=arguments,b=0,c=a[0];++b in a;)c=c.replace(a[b],a[++b]);return c},c=$(function(a){return"return "+b((a||"").toLowerCase(),/\band\b/g,"&&",/,/g,"||",/min-([a-z-\s]+):/g,"e.$1>=",/max-([a-z-\s]+):/g,"e.$1<=",/calc([^)]+)/g,"($1)",/(\d+[\.]*[\d]*)([a-z]+)/g,"($1 * e.$2)",/^(?!(e.[a-z]|[0-9\.&=|><\+\-\*\(\)\/])).*/gi,"")+";"});return function(b,d){var e;if(!(b in N))if(N[b]=!1,d&&(e=b.match(a)))N[b]=e[1]*Q[e[2]];else try{N[b]=new Function("e",c(b))(Q)}catch(a){}return N[b]}}(),aa=function(a,b){return a.w?(a.cWidth=s.calcListLength(b||"100vw"),a.res=a.w/a.cWidth):a.res=a.d,a},ba=function(a){if(t){var c,d,e,f=a||{};if(f.elements&&1===f.elements.nodeType&&("IMG"===f.elements.nodeName.toUpperCase()?f.elements=[f.elements]:(f.context=f.elements,f.elements=null)),c=f.elements||s.qsa(f.context||b,f.reevaluate||f.reselect?s.sel:s.selShort),e=c.length){for(s.setupRun(f),S=!0,d=0;dimg,img[srcset]",s.sel=s.selShort,s.cfg=B,s.DPR=P||1,s.u=Q,s.types=A,s.setSize=u,s.makeUrl=$(function(a){return R.href=a,R.href}),s.qsa=function(a,b){return"querySelector"in a?a.querySelectorAll(b):[]},s.matchesMedia=function(){return a.matchMedia&&(matchMedia("(min-width: 0.1em)")||{}).matches?s.matchesMedia=function(a){return!a||matchMedia(a).matches}:s.matchesMedia=s.mMQ,s.matchesMedia.apply(this,arguments)},s.mMQ=function(a){return!a||_(a)},s.calcLength=function(a){var b=_(a,!0)||!1;return b<0&&(b=!1),b},s.supportsType=function(a){return!a||A[a]},s.parseSize=$(function(a){var b=(a||"").match(I);return{media:b&&b[1],length:b&&b[2]}}),s.parseSet=function(a){return a.cands||(a.cands=m(a.srcset,a)),a.cands},s.getEmValue=function(){var a;if(!p&&(a=b.body)){var c=b.createElement("div"),d=z.style.cssText,e=a.style.cssText;c.style.cssText=K,z.style.cssText=L,a.style.cssText=L,a.appendChild(c),p=c.offsetWidth,a.removeChild(c),p=parseFloat(p,10),z.style.cssText=d,a.style.cssText=e}return p||16},s.calcListLength=function(a){if(!(a in O)||B.uT){var b=s.calcLength(n(a));O[a]=b?b:Q.width}return O[a]},s.setRes=function(a){var b;if(a){b=s.parseSet(a);for(var c=0,d=b.length;cp,n||(l.cached=!0,l.res>=p&&(h=l))),!h)for(a.sort(i),f=a.length,h=a[f-1],d=0;d=p){e=d-1,h=a[e]&&(n||k!==s.makeUrl(c.url))&&g(a[e].res,c.res,p,a[e].cached)?a[e]:c;break}h&&(m=s.makeUrl(h.url),o.curSrc=m,o.curCan=h,m!==k&&s.setSrc(b,h),s.setSize(b))}},s.setSrc=function(a,b){var c;a.src=b.url,"image/svg+xml"===b.set.type&&(c=a.style.width,a.style.width=a.offsetWidth+1+"px",a.offsetWidth+1&&(a.style.width=c))},s.getSet=function(a){var b,c,d,e=!1,f=a[s.ns].sets;for(b=0;b0&&b-1 in a)}function d(a,b,c){if(fa.isFunction(b))return fa.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return fa.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(pa.test(b))return fa.filter(b,a,c);b=fa.filter(b,a)}return fa.grep(a,function(a){return _.call(b,a)>-1!==c})}function e(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function f(a){var b={};return fa.each(a.match(va)||[],function(a,c){b[c]=!0}),b}function g(){X.removeEventListener("DOMContentLoaded",g),a.removeEventListener("load",g),fa.ready()}function h(){this.expando=fa.expando+h.uid++}function i(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Ca,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c||"false"!==c&&("null"===c?null:+c+""===c?+c:Ba.test(c)?fa.parseJSON(c):c)}catch(a){}Aa.set(a,b,c)}else c=void 0;return c}function j(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return fa.css(a,b,"")},i=h(),j=c&&c[3]||(fa.cssNumber[b]?"":"px"),k=(fa.cssNumber[b]||"px"!==j&&+i)&&Ea.exec(fa.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,fa.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}function k(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&fa.nodeName(a,b)?fa.merge([a],c):c}function l(a,b){for(var c=0,d=a.length;d>c;c++)za.set(a[c],"globalEval",!b||za.get(b[c],"globalEval"))}function m(a,b,c,d,e){for(var f,g,h,i,j,m,n=b.createDocumentFragment(),o=[],p=0,q=a.length;q>p;p++)if(f=a[p],f||0===f)if("object"===fa.type(f))fa.merge(o,f.nodeType?[f]:f);else if(La.test(f)){for(g=g||n.appendChild(b.createElement("div")),h=(Ia.exec(f)||["",""])[1].toLowerCase(),i=Ka[h]||Ka._default,g.innerHTML=i[1]+fa.htmlPrefilter(f)+i[2],m=i[0];m--;)g=g.lastChild;fa.merge(o,g.childNodes),g=n.firstChild,g.textContent=""}else o.push(b.createTextNode(f));for(n.textContent="",p=0;f=o[p++];)if(d&&fa.inArray(f,d)>-1)e&&e.push(f);else if(j=fa.contains(f.ownerDocument,f),g=k(n.appendChild(f),"script"),j&&l(g),c)for(m=0;f=g[m++];)Ja.test(f.type||"")&&c.push(f);return n}function n(){return!0}function o(){return!1}function p(){try{return X.activeElement}catch(a){}}function q(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)q(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=o;else if(!e)return this;return 1===f&&(g=e,e=function(a){return fa().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=fa.guid++)),a.each(function(){fa.event.add(this,b,e,d,c)})}function r(a,b){return fa.nodeName(a,"table")&&fa.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function s(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function t(a){var b=Sa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function u(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(za.hasData(a)&&(f=za.access(a),g=za.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)fa.event.add(b,e,j[e][c])}Aa.hasData(a)&&(h=Aa.access(a),i=fa.extend({},h),Aa.set(b,i))}}function v(a,b){var c=b.nodeName.toLowerCase();"input"===c&&Ha.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function w(a,b,c,d){b=Z.apply([],b);var e,f,g,h,i,j,l=0,n=a.length,o=n-1,p=b[0],q=fa.isFunction(p);if(q||n>1&&"string"==typeof p&&!da.checkClone&&Ra.test(p))return a.each(function(e){var f=a.eq(e);q&&(b[0]=p.call(this,e,f.html())),w(f,b,c,d)});if(n&&(e=m(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(g=fa.map(k(e,"script"),s),h=g.length;n>l;l++)i=e,l!==o&&(i=fa.clone(i,!0,!0),h&&fa.merge(g,k(i,"script"))),c.call(a[l],i,l);if(h)for(j=g[g.length-1].ownerDocument,fa.map(g,t),l=0;h>l;l++)i=g[l],Ja.test(i.type||"")&&!za.access(i,"globalEval")&&fa.contains(j,i)&&(i.src?fa._evalUrl&&fa._evalUrl(i.src):fa.globalEval(i.textContent.replace(Ta,"")))}return a}function x(a,b,c){for(var d,e=b?fa.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||fa.cleanData(k(d)),d.parentNode&&(c&&fa.contains(d.ownerDocument,d)&&l(k(d,"script")),d.parentNode.removeChild(d));return a}function y(a,b){var c=fa(b.createElement(a)).appendTo(b.body),d=fa.css(c[0],"display");return c.detach(),d}function z(a){var b=X,c=Va[a];return c||(c=y(a,b),"none"!==c&&c||(Ua=(Ua||fa("