diff --git a/.gibot.yml b/.gibot.yml new file mode 100644 index 0000000000..b3a565a5e4 --- /dev/null +++ b/.gibot.yml @@ -0,0 +1,56 @@ +stages: + mark_for_closing: + days: 30 + labels: + - status/need more info + - status/invalid + - status/can't reproduce + - status/wontfix + exclude: + - 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.' + - 'Thank you. :robot:' + action: + close: false + comment: true + assign_label: + - status/marked for cleanup + clean_up: + days: 7 + labels: + - 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.' + - 'If this has been closed in error, please create a comment below and we can reopen this issue. Note that you may need to provide additional information that was requested.' + - 'Thank you. :robot:' + action: + close: true + comment: true + assign_label: + - status/closed by bot + remove_label: + - status/marked for cleanup + remind_about_old_ticket: + days: 365 + labels: + - kind/bug + - kind/critical bug + exclude: + - 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: + - status/inactive diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 28549dd503..b56ddb134a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,8 +3,10 @@ **ACE3 Version:** `3.x.x` (stable / dev + commit hash) **Mods:** -- `@CBA_A3` -- `@ace` +``` +- CBA_A3 +- ace +``` **Description:** - Add a detailed description of the error. This makes it easier for us to fix the issue. @@ -20,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/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2dbbc268af..69565c700e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,4 +2,4 @@ - Describe what this pull request will do - Each change in a separate line - Include documentation if applicable -- Respect the [Development Guidelines](http://ace3mod.com/wiki/development/) +- Respect the [Development Guidelines](https://ace3mod.com/wiki/development/) diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000000..6d1d741bbd --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1,20 @@ +# No issues and PRs without labels +issues=false +pr-wo-labels=false + +# Issues are disabled, don't fetch them +max-issues=0 + +# Label filters +exclude-labels=by design,can't reproduce,duplicate,question,invalid,wontfix,ignore changelog + +# Tag is created before generating changelog for release candidates +unreleased=false + +# No section labels, we only want a list of merged PRs (label separation only works for Issues) +simple-list=true + +# Misc +author=false +compare-link=false +header-label=## Change Log Summary diff --git a/.gitignore b/.gitignore index 5aebbbd408..1d60d27088 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ texHeaders.bin *.swo *.biprivatekey Thumbs.db +CHANGELOG.md diff --git a/.lgtm b/.lgtm deleted file mode 100644 index 6bcc0cd7b8..0000000000 --- a/.lgtm +++ /dev/null @@ -1,3 +0,0 @@ -approvals = 1 -pattern = "(?i)LGTM|(?i):\\+1:|(?i):shipit:" -self_approval_off = true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 90c037b514..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,30 +0,0 @@ -branches: - only: - - master - - release -language: python -python: -- '3.4' -before_script: -- if [ -n "${GH_TOKEN}" ] && [ "${TRAVIS_BRANCH}" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then - pip install pygithub; - pip install pygithub3; - fi -script: -- python3 tools/sqf_validator.py -- python3 tools/config_style_checker.py -- if [ -n "${GH_TOKEN}" ] && [ "${TRAVIS_BRANCH}" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then - python3 tools/deploy.py; - fi -env: - global: - - secure: cdxkn5cAx+s1C9Ne5m+odEhde1uuSg6XGMDgepN4DwSAJwtMnUv3ZmDebd5YJC1raZJdep+n09Cj0GoTNICQRkco50DxHKHYNad41wetY0tn0cs9gmPYzyFE5q4vuWiQ47dlGhQQ7IJDyX0nU++gG5E50/PhlZfebdedGSprN/4= -notifications: - slack: - rooms: - - secure: byZMNBl8PMlgjT9NA1WmhgCdGfX4b3g1kA0vEiwfm+IFNlx7BiM4J/5rp6zV/jV470xl/epAejx2tsa5SdTyFbO87NH63ILJSt5QnjUZjRuGKSutFs9WE671DtZkPRSJXHS4N6x802PRkyBz/84/lsc34FWvHvjwOuYAtOcJRFk= - - secure: V22TNaLWV+yUNWqR7c6HVvIxkRDz7Dyz9xqa43FY8iFgvNL4Q/X69h5DYHU/ILNFM00tx8OBjtPRbcjWQ+F6eY8Sje/A2axJAU+qNurAvoyiTahXUprdUUpPdkgXWuSRTZ9kALxOq5e11RC8XUietghoMcl8zPcqdrZCOOKgoEM= - on_success: change - email: - on_success: never - on_failure: change diff --git a/AUTHORS.txt b/AUTHORS.txt index 31ca447733..c3c4d7f12e 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,4 +1,4 @@ -# ACE3 CONTRIBUTOR LIST +# ACE3 CONTRIBUTOR LIST # If you contributed, but are not listed here, contact me: # koffeinflummi@gmail.com # @@ -29,6 +29,7 @@ Walter Pearce # CONTRIBUTORS [BIG]Bull 11RDP-LoupVert +654wak654 ACCtomeek adam3adam Adanteh @@ -37,7 +38,9 @@ Aggr094 alef Aleksey EpMAK Yermakov Alganthe +Andrea "AtixNeon" Verano Anthariel +Anton Arkhir Asgar Serran BaerMitUmlaut @@ -49,6 +52,8 @@ Brakoviejo Brisse Brostrom.A | Evul BullHorn +chris579 +classicarma Clon1998 Codingboy Coren @@ -60,6 +65,7 @@ Drill Dudakov aka [OMCB]Kaban Drofseh Dslyecxi +ElTyranos eRazeri evromalarkey F3 Project @@ -83,26 +89,35 @@ Harakhti havena Hawkins Head +Hybrid V +john681611 Karneck Kavinsky +Keithen Kllrt legman Legolasindar "Viper" licht-im-Norden87 looter +Lugubrious Hatchling +Luigi "Luigium" Myrini Macusercom MarcBook meat +mharis001 Michail Nikolaev MikeMatrix nic547 nikolauska nomisum OnkelDisMaster +Orbis2358 oscarmolinadev PaxJaromeMalues +Phyma pokertour Professor +QuickDagger rakowozz ramius86 Raspu86 @@ -116,11 +131,14 @@ System98 SzwedzikPL Tachi Tessa Elieff +Timi007 Toaster Tonic Tourorist +Tuupertunut Valentin Torikian voiper VyMajoris(W-Cephei) Winter +xrufix zGuba diff --git a/README.md b/README.md index 4af32fd2a2..868201c9bf 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

- ACE3 Version + ACE3 Version ACE3 Issues @@ -18,17 +18,17 @@ ACE3 License - - ACE3 Slack + + ACE3 Slack - - ACE3 Build Status + + ACE3 Build Status

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 705a90b2ef..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 new file mode 100644 index 0000000000..f1802ce5e8 Binary files /dev/null and b/ace_advanced_ballistics_x64.dll differ diff --git a/ace_break_line_x64.dll b/ace_break_line_x64.dll new file mode 100644 index 0000000000..d021bf25d2 Binary files /dev/null and b/ace_break_line_x64.dll differ diff --git a/ace_clipboard_x64.dll b/ace_clipboard_x64.dll new file mode 100644 index 0000000000..db7730f0fe Binary files /dev/null and b/ace_clipboard_x64.dll differ diff --git a/ace_fcs_x64.dll b/ace_fcs_x64.dll new file mode 100644 index 0000000000..4ee8dc1d89 Binary files /dev/null and b/ace_fcs_x64.dll differ diff --git a/ace_medical_x64.dll b/ace_medical_x64.dll new file mode 100644 index 0000000000..a903cddfe9 Binary files /dev/null and b/ace_medical_x64.dll differ diff --git a/ace_parse_imagepath_x64.dll b/ace_parse_imagepath_x64.dll new file mode 100644 index 0000000000..8d154117c5 Binary files /dev/null and b/ace_parse_imagepath_x64.dll differ diff --git a/addons/advanced_ballistics/ACE_Settings.hpp b/addons/advanced_ballistics/ACE_Settings.hpp index 9815cc8491..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); @@ -69,13 +39,7 @@ class ACE_Settings { displayName = CSTRING(simulationInterval_DisplayName); description = CSTRING(simulationInterval_Description); typeName = "SCALAR"; - value = 0.0; - }; - class GVAR(simulationRadius) { - category = CSTRING(DisplayName); - displayName = CSTRING(simulationRadius_DisplayName); - description = CSTRING(simulationRadius_Description); - typeName = "SCALAR"; - value = 3000; + value = 0.05; + sliderSettings[] = {0, 0.2, 0.05, 2}; }; }; diff --git a/addons/advanced_ballistics/CfgVehicles.hpp b/addons/advanced_ballistics/CfgVehicles.hpp index 804a6e9236..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); @@ -71,17 +45,11 @@ class CfgVehicles { displayName = CSTRING(simulationInterval_DisplayName); description = CSTRING(simulationInterval_Description); typeName = "NUMBER"; - defaultValue = 0.0; - }; - class simulationRadius { - displayName = CSTRING(simulationRadius_DisplayName); - description = CSTRING(simulationRadius_Description); - typeName = "NUMBER"; - defaultValue = 3000; + defaultValue = 0.05; }; }; 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 96aef4a93d..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", { @@ -39,7 +26,7 @@ if (!hasInterface) exitWith {}; { _x params ["_modPBO", "_compatPBO"]; if ((isClass (configFile >> "CfgPatches" >> _modPBO)) && {!isClass (configFile >> "CfgPatches" >> _compatPBO)}) then { - ACE_LOGWARNING_2("Weapon Mod [%1] missing ace compat pbo [%2] (from @ace\optionals)",_modPBO,_compatPBO); + WARNING_2("Weapon Mod [%1] missing ace compat pbo [%2] (from @ace\optionals)",_modPBO,_compatPBO); }; } forEach [ ["RH_acc","ace_compat_rh_acc"], @@ -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/XEH_preInit.sqf b/addons/advanced_ballistics/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/advanced_ballistics/XEH_preInit.sqf +++ b/addons/advanced_ballistics/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf index 19cd55c98e..791fdb5040 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -10,26 +11,24 @@ * Return Value: * muzzle velocity shift - m/s * + * Example: + * [[], 5] call ace_advanced_ballistics_fnc_calcilateAmmoTemperatureVelocityShift + * * Public: No */ -#include "script_component.hpp" 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_calculateAtmosphericCorrection.sqf b/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf index 2b90767a4f..b574698931 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -13,9 +14,11 @@ * Return Value: * corrected ballistic coefficient * + * Example: + * [2, 5, 5, 0.5, "ASM"] call ace_advanced_ballistics_fnc_calculateAtmosphericCorrection + * * Public: No */ -#include "script_component.hpp" params ["_ballisticCoefficient", "_temperature"/*in C*/, "_pressure"/*in hPa*/, "_relativeHumidity"/*as ratio 0-1*/, "_atmosphereModel"/*"ICAO" or "ASM"*/]; diff --git a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf index 1f8a7e6eb9..e28ccd2523 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: Ruthberg, MikeMatrix, joko // Jonas * * Calculates the muzzle velocity shift caused by different barrel lengths * * Arguments: - * 0: barrel length - mm + * 0: barrel length - mm * 1: muzzle velocity lookup table - m/s * 2: barrel length lookup table - mm * 3: muzzle velocity - m/s @@ -12,26 +13,23 @@ * Return Value: * muzzle velocity shift - m/s * + * Example: + * [5, [0,5], [0,5], 5] call ace_advanced_ballistics_fnc_calculateBarrelLengthVelocityShift + * * Public: No */ -#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 @@ -43,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_calculateRetardation.sqf b/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf index 0bd801c6b9..184ee6970d 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -11,9 +12,11 @@ * Return Value: * retardation - m/(s^2) * + * Example: + * [5, 20, 10] call ace_advanced_ballistics_fnc_calculateRetardation + * * Public: No */ -#include "script_component.hpp" // Source: GNU Exterior Ballistics diff --git a/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf b/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf index 07fc7c67c9..cf6dbb03b1 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -15,9 +16,11 @@ * Return Value: * stability factor * + * Example: + * [1, 2, 3, 4, 5, 6, 7] call ace_advanced_ballistics_fnc_calculateStabilityFactor + * * Public: No */ -#include "script_component.hpp" params ["_caliber", "_bulletLength", "_bulletMass", "_barrelTwist", "_muzzleVelocity", "_temperature", "_barometricPressure"]; diff --git a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf index 4d344e8bfe..d2f5cba98f 100644 --- a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf +++ b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf @@ -1,3 +1,5 @@ +#define DEBUG_MODE_FULL +#include "script_component.hpp" /* * Author: esteldunedain * @@ -10,10 +12,20 @@ * Return Value: * None * + * Example: + * [] call ace_advanced_ballistics_fnc_diagnoseWeapons + * * Public: No */ -#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 { @@ -21,9 +33,7 @@ for "_i" from 0 to (count _cfgWeapons)-1 do { 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 [TYPE_WEAPON_PRIMARY, TYPE_WEAPON_HANDGUN]) then { private _weaponInitSpeed = getNumber (_weaponConfig >> "initSpeed"); private _magazines = getArray (_weaponConfig >> "magazines"); { @@ -44,16 +54,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_displayProtractor.sqf b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf index 528b3e2e97..714aaa31ef 100644 --- a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf +++ b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [] call ace_advanced_ballistics_fnc_displayProtractor + * * Public: No */ -#include "script_component.hpp" #define __dsp (uiNamespace getVariable "RscProtractor") #define __ctrl1 (__dsp displayCtrl 132950) diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index 6a9c7ce243..0c18ae539e 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Ruthberg, joko // Jonas * Handle the PFH for Bullets @@ -8,29 +9,26 @@ * Return Value: * None * + * Example: + * [] call ace_advanced_ballistics_fnc_handleFirePFH + * * Public: No */ -#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 7085224771..b1f9898b6d 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Ruthberg * @@ -9,109 +10,117 @@ * Return Value: * None * + * Example: + * [] call ace_advanced_ballistics_fnc_handleFired + * * 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); -// 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 || !(GVAR(extensionAvailable))) exitWith { - if (missionNamespace getVariable [QEGVAR(windDeflection,enabled), false]) then { - EGVAR(windDeflection,trackedBullets) pushBack [_projectile, getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction")]; - }; }; +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; -_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 4898c51c10..83e11175d3 100644 --- a/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf +++ b/addons/advanced_ballistics/functions/fnc_initModuleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Ruthberg * Module for adjusting the advanced ballistics settings @@ -10,23 +11,21 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_advanced_ballistics_fnc_initModuleSettings + * * Public: No */ -#include "script_component.hpp" 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 9fed872a6b..5c634cadff 100644 --- a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf +++ b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Initializes the advanced ballistics dll extension with terrain data @@ -8,48 +9,51 @@ * Return Value: * None * + * Example: + * [] call ace_advanced_ballistics_fnc_initializeTerrainExtension + * * Public: No */ -#include "script_component.hpp" 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); #ifdef DEBUG_MODE_FULL systemChat "AdvancedBallistics: Terrain already initialized"; #endif }; -_mapGrids = ceil(_mapSize / 50) + 1; -_gridCells = _mapGrids * _mapGrids; +private _mapGrids = ceil(_mapSize / 50) + 1; +private _gridCells = _mapGrids * _mapGrids; GVAR(currentGrid) = 0; +INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldName); + [{ params ["_args","_idPFH"]; _args params ["_mapGrids", "_gridCells", "_initStartTime"]; if (GVAR(currentGrid) >= _gridCells) exitWith { + 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 646096683a..13b4692452 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -7,48 +8,54 @@ * ammo - classname * * Return Value: - * 0: _airFriction - * 1: _caliber - * 2: _bulletLength - * 3: _bulletMass - * 4: _transonicStabilityCoef - * 5: _dragModel - * 6: _ballisticCoefficients - * 7: _velocityBoundaries - * 8: _atmosphereModel - * 9: _ammoTempMuzzleVelocityShifts - * 10: _muzzleVelocityTable - * 11: _barrelLengthTable + * 0: _airFriction + * 1: _caliber + * 2: _bulletLength + * 3: _bulletMass + * 4: _transonicStabilityCoef + * 5: _dragModel + * 6: _ballisticCoefficients + * 7: _velocityBoundaries + * 8: _atmosphereModel + * 9: _ammoTempMuzzleVelocityShifts + * 10: _muzzleVelocityTable + * 11: _barrelLengthTable + * + * Example: + * ["ammo"] call ace_advanced_ballistics_fnc_readAmmoDataFromConfig * * Public: No */ -#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"]; -_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 _ammoConfig = configFile >> "CfgAmmo" >> _this; + +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"); @@ -59,7 +66,7 @@ if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then { if (_inheritedBarrelConfig || _inheritedTempConfig) then { private _parentConfig = inheritsFrom _ammoConfig; private _parentSpeed = getNumber (_parentConfig >> "typicalSpeed"); - ACE_LOGWARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig, _parentSpeed); + WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig, _parentSpeed); if (_parentSpeed <= 0) exitWith {//Handle weird or null parent _muzzleVelocityTable = []; _ammoTempMuzzleVelocityShifts = []; @@ -86,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 7c97e10bda..dbc9999824 100644 --- a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -7,18 +8,20 @@ * weapon - classname * * Return Value: - * 0: _barrelTwist - * 1: _twistDirection - * 2: _barrelLength + * 0: _barrelTwist + * 1: _twistDirection + * 2: _barrelLength + * + * Example: + * ["weapon"] call ace_advanced_ballistics_fnc_readWeaponDataFromConfig * * Public: No */ -#include "script_component.hpp" 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 { @@ -26,10 +29,10 @@ 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]; -uiNamespace setVariable [format[QGVAR(%1), _weapon], _result]; +uiNamespace setVariable [format[QGVAR(%1), _this], _result]; _result diff --git a/addons/advanced_ballistics/script_component.hpp b/addons/advanced_ballistics/script_component.hpp index bc8baa3121..bbd659670f 100644 --- a/addons/advanced_ballistics/script_component.hpp +++ b/addons/advanced_ballistics/script_component.hpp @@ -4,9 +4,10 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS +#define DEBUG_INIT_SPEEDS + #ifdef DEBUG_ENABLED_ADVANCEDBALLISTICS #define DEBUG_MODE_FULL #endif @@ -17,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) @@ -28,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 b3399357c3..263f66876f 100644 --- a/addons/advanced_ballistics/stringtable.xml +++ b/addons/advanced_ballistics/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Széladatok mutatása Zobrazit údaje o větru Mostrar Informação do Vento + 風の情報を表示する + 바람의 정보를 표시 + 顯示風況 + 显示风况 Show Protractor @@ -24,6 +28,10 @@ Szögmérő mutatása Zobrazit úhloměr Mostrar Transferidor + 分度器を表示する + 각도기 표시 + 顯示量角器 + 显示量角器 Advanced Ballistics @@ -36,6 +44,10 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata + アドバンスド バリスティックス + 고급 탄도학 + 先進彈道系統 + 先进弹道系统 Advanced Ballistics @@ -48,6 +60,10 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata + アドバンスド バリスティックス + 고급 탄도학 + 先進彈道系統 + 先进弹道系统 Enables advanced ballistics @@ -60,126 +76,30 @@ 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 + 총구속도 변화적용 + 啟用槍口初速變化 + 启用枪口初速变化 + Activer les variations de la vitesse initiale - - 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 degradare 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 + 각 사격 사이에 총구속도 변화를 시뮬레이션 합니다. + 模擬每發子彈的槍口初速都略有不同 + 模拟每发子弹的枪口初速都略有不同 + Simule les légères variations Enable Ammo Temperature Simulation @@ -192,6 +112,10 @@ Lőszer-hő szimuláció engedélyezése Симуляция температуры для боеприпасов Abilita simulazione della temperatura delle munizioni + 弾薬温度のシミュレーションを有効化する + 탄약 온도 구현 적용 + 啟用彈藥溫度模擬系統 + 启用弹药温度模拟系统 Muzzle velocity varies with ammo temperature @@ -203,7 +127,11 @@ La température de la munition influe sur la vélocité intiale A kezdősebesség a lőszer hőmérsékletétől függően változó Начальная скорость пули зависит от температуры - Velocità alla volata varia con la temperatura delle munizioni + La velocità dello sparo varia a seconda della temperatura delle munizioni + 弾薬の温度により銃口初速を変動させます。 + 탄약 온도에 비례해 총구 속도가 달라집니다 + 子彈初速將隨彈藥溫度而有所變化 + 子弹初速将随弹药温度而有所变化 Enable Barrel Length Simulation @@ -216,6 +144,10 @@ Csőhossz-szimuláció engedélyezése Симуляция длины ствола Abilita simulazione della lunghezza della canna + 銃身長のシミュレーションを有効化する + 총열 길이 구현 적용 + 啟用槍管長度模擬系統 + 启用枪管长度模拟系统 Muzzle velocity varies with barrel length @@ -227,7 +159,11 @@ La longueur du canon influe sur la vélocité initale A kezdősebesség a cső hosszától függően változó Начальная скорость пули зависит от длины ствола - Velocità alla volata varia con la lunghezza della canna + La velocità di sparo varia a seconda della lunghezza della canna + 銃身長により銃口初速を変動させます。 + 총구 속도가 총열에 비례해 달라집니다 + 子彈初速將隨槍管長度而有所變化 + 子弹初速将随枪管长度而有所变化 Enable Bullet Trace Effect @@ -239,7 +175,11 @@ Activer l'effet balle traçante Nyomkövető-effekt engedélyezése Следы пуль - Abilita effetto di tracciatura dei proiettili + Abilita effetto dei Proiettili Traccianti + 弾丸の軌跡エフェクトを有効化する + 예광탄 효과 적용 + 啟用曳光彈效果 + 启用曳光弹效果 Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics) @@ -251,7 +191,11 @@ Active une tracante pour les munitions de gros calibre (seulement visible en utilisant des optiques avancées) Engedélyezi a nagy kaliberű lövedékek nyomának vizuális követését (csak nagy teljesítményű optikán keresztül látható) Включает эффект следов пуль для больших калибров (видны только через мощную оптику) - Abilita effetto di tracciatura per proiettili di alto calibro (visibile solo attraverso ottiche ad alto potenziale) + Abilita effetto dei proiettili traccianti di alto calibro (visibile solo attraverso ottiche ad alto potenziale) + 大口径弾の軌跡エフェクトを有効化します。 (高性能光学機器を介してのみ見ることができます) + 대구경 탄환에 예광탄 효과를 적용합니다(오직 고성능 조준경 사용시에만 보입니다) + 啟用曳光彈效果給大口徑子彈 (只有透過高倍率光學瞄鏡才能看到) + 启用曳光弹效果给大口径子弹 (只有透过高倍率光学瞄镜才能看到) Simulation Interval @@ -264,18 +208,26 @@ Szimuláció intervalluma Интервал симуляции Intervallo Simulazione + シミュレーションの間隔 + 구현 간격 + 模擬間隔 + 模拟间隔 - 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 Meghatározza a számítási lépések közötti időintervallumot Определяет временной интервал между вычислениями Definisce l'intervallo tra ogni step di calcolo + 各計算毎の間隔を定義します。 + 각 계산 단위의 간격을 정의합니다 + 定義每個模擬計算之間的時間間隔 + 定义每个模拟计算之间的时间间隔 Simulation Radius @@ -288,6 +240,10 @@ Szimuláció hatóköre Радиус симуляции Raggio Simulazione + シミュレーションの範囲 + 구현 범위 + 模擬半徑 + 模拟半径 Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles @@ -300,6 +256,10 @@ Meghatározza a játékos körüli hatókört (méterben), ahol a lövedékek fejlett ballisztikát használnak Определяет радиус вокруг игрока (в метрах), в котором продвинутая баллистика применяется к снарядам Definisce il raggio attorno al giocatore (in metri) per cui la Balistica Avanzata è applicata ai proiettili + アドバンスド バリスティックスの適用半径範囲 (プレイヤー中心、メートル単位) を定義します。 + 플레이어 주위의 발사체를 고급 탄도학으로 정의하는 범위를 정합니다(미터) + 以玩家的半徑距離(公尺)定義先進彈道系統啟用範圍 + 以玩家的半径距离(公尺)定义先进弹道系统启用范围 This module enables advanced ballistics simulation - meaning the trajectory of projectiles is influenced by variables like air temperature, atmospheric pressure, humidity, gravity, the type of ammunition and the weapon from which it was fired. @@ -312,6 +272,10 @@ Этот модуль включает симуляцию продвинутой баллистики - при этом на траекторию полета снаряда влияют различные параметры, такие как температура воздуха, атмосферное давление, влажность, гравитация, тип боеприпаса и оружия, из которого произвели выстрел. Este módulo permite la simulación balística avanzada - es decir, la trayectoria de los proyectiles está influenciada por variables como la temperatura del aire, la presión atmosférica, la humedad, la gravedad, el tipo de municiones y el arma desde el que fue disparada. 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 + アドバンスド バリスティックスのシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。 + 이 모듈은 고급 탄도학을 적용시킵니다 - 이는 발사체의 궤적이 기온, 대기압, 습도, 중력, 탄환의 종류와 어느 무기에서 발사되는지에 따라 영향을 받습니다. + 該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響 + 该模块实现先进的弹道仿真 - 这意味着子弹的轨迹是由空气温度、大气压力、湿度、重力、弹药类型以及射击的武器所影响 - \ No newline at end of file + diff --git a/addons/advanced_fatigue/ACE_Settings.hpp b/addons/advanced_fatigue/ACE_Settings.hpp index 8242e16111..0590e68efb 100644 --- a/addons/advanced_fatigue/ACE_Settings.hpp +++ b/addons/advanced_fatigue/ACE_Settings.hpp @@ -1,45 +1,20 @@ class ACE_Settings { class GVAR(enabled) { - category = "Advanced Fatigue"; - displayName = CSTRING(Enabled); - description = CSTRING(Enabled_Description); - typeName = "BOOL"; - value = 1; + movedToSQF = 1; }; class GVAR(enableStaminaBar) { - category = "Advanced Fatigue"; - displayName = CSTRING(EnableStaminaBar); - description = CSTRING(EnableStaminaBar_Description); - typeName = "BOOL"; - value = 1; - isClientSettable = 1; + movedToSQF = 1; }; class GVAR(performanceFactor) { - category = "Advanced Fatigue"; - displayName = CSTRING(PerformanceFactor); - description = CSTRING(PerformanceFactor_Description); - typeName = "SCALAR"; - value = 1; + movedToSQF = 1; }; class GVAR(recoveryFactor) { - category = "Advanced Fatigue"; - displayName = CSTRING(RecoveryFactor); - description = CSTRING(RecoveryFactor_Description); - typeName = "SCALAR"; - value = 1; + movedToSQF = 1; }; class GVAR(loadFactor) { - category = "Advanced Fatigue"; - displayName = CSTRING(LoadFactor); - description = CSTRING(LoadFactor_Description); - typeName = "SCALAR"; - value = 1; + movedToSQF = 1; }; class GVAR(terrainGradientFactor) { - category = "Advanced Fatigue"; - displayName = CSTRING(TerrainGradientFactor); - description = CSTRING(TerrainGradientFactor_Description); - typeName = "SCALAR"; - value = 1; + movedToSQF = 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/XEH_PREP.hpp b/addons/advanced_fatigue/XEH_PREP.hpp index 1ec7705695..c6250516f5 100644 --- a/addons/advanced_fatigue/XEH_PREP.hpp +++ b/addons/advanced_fatigue/XEH_PREP.hpp @@ -5,6 +5,6 @@ PREP(getMetabolicCosts); PREP(handleEffects); PREP(handlePlayerChanged); PREP(handleStaminaBar); +PREP(mainLoop); PREP(moduleSettings); -PREP(pfhMain); PREP(removeDutyFactor); diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index 2eff26abdf..fba0de9052 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -12,39 +12,38 @@ if (!hasInterface) exitWith {}; GVAR(ppeBlackout) ppEffectCommit 0.4; // - GVAR updating and initialization ----------------------------------------- - if !(isNull ACE_player) then { - [ACE_player, objNull] call FUNC(handlePlayerChanged); - }; - ["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; + ["unit", FUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; + + ["visibleMap", { + params ["", "_visibleMap"]; // command visibleMap is updated one frame later + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; + _staminaBarContainer ctrlShow ((!_visibleMap) && {(vehicle ACE_player) == ACE_player}); + }, true] call CBA_fnc_addPlayerEventHandler; + ["vehicle", { + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; + _staminaBarContainer ctrlShow ((!visibleMap) && {(vehicle ACE_player) == ACE_player}); + }, true] call CBA_fnc_addPlayerEventHandler; // - Duty factors ------------------------------------------------------------- - [QEGVAR(medical,pain), { - 1 + (((_this getVariable [QEGVAR(medical,pain), 0]) min 1) / 10) - }] call FUNC(addDutyFactor); - [QEGVAR(medical,bloodVolume), { - 2 - (((_this getVariable [QEGVAR(medical,bloodVolume), 100]) min 100) / 100) - }] call FUNC(addDutyFactor); - [QEGVAR(dragging,isCarrying), { - if (_this getVariable [QEGVAR(dragging,isCarrying), false]) then { - 3 - } else { - 1 - }; - }] call FUNC(addDutyFactor); - [QEGVAR(weather,temperature), { - (((missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]) - 35) / 10) max 2 min 1 - }] call FUNC(addDutyFactor); - - // - Add main PFH ------------------------------------------------------------- - [FUNC(pfhMain), 1, []] call CBA_fnc_addPerFrameHandler; -}] call CBA_fnc_addEventHandler; - -["ace_settingChanged", { - params ["_name", "_value"]; - - if (_name == QGVAR(enableStaminaBar) && {!_value}) then { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlSetFade 1; - _staminaBarContainer ctrlCommit 0; + if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 + linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; + }] call FUNC(addDutyFactor); + [QEGVAR(medical,bloodVolume), { // 100->1.0, 90->1.1, 80->1.2 + linearConversion [100, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 100]), 1, 2, true]; + }] call FUNC(addDutyFactor); }; + if (["ACE_Dragging"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(dragging,isCarrying), { + [1, 3] select (_this getVariable [QEGVAR(dragging,isCarrying), false]); + }] call FUNC(addDutyFactor); + }; + if (["ACE_Weather"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(weather,temperature), { // 35->1, 45->2 + linearConversion [35, 45, (missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]), 1, 2, true]; + }] call FUNC(addDutyFactor); + }; + + // - Add main loop at 1 second interval ------------------------------------------------------------- + [FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; }] call CBA_fnc_addEventHandler; diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index 9b799a0816..1cb60db917 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -2,8 +2,11 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" -//#include "initSettings.sqf" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40); GVAR(dutyList) = [[], []]; diff --git a/addons/advanced_fatigue/config.cpp b/addons/advanced_fatigue/config.cpp index db947b5815..47d56d6ab2 100644 --- a/addons/advanced_fatigue/config.cpp +++ b/addons/advanced_fatigue/config.cpp @@ -7,7 +7,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; - author = CSTRING(ACETeam); + author = ECSTRING(common,ACETeam); authors[] = {"BaerMitUmlaut"}; url = ECSTRING(main,URL); VERSION_CONFIG; diff --git a/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf b/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf index 74a42d55cf..e2f87f3080 100644 --- a/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf +++ b/addons/advanced_fatigue/functions/fnc_addDutyFactor.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Adds a duty factor. @@ -8,8 +9,12 @@ * * Return Value: * None + * + * Example: + * ["ID", 5] call ace_advanced_fatigue_fnc_addDutyFactor + * + * Public: No */ -#include "script_component.hpp" params [["_id", "", [""]], ["_factor", 1, [0, {}]]]; if (_id == "" || {_factor isEqualTo 1}) exitWith {}; diff --git a/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf b/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf index 773e240494..157f683018 100644 --- a/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf +++ b/addons/advanced_fatigue/functions/fnc_createStaminaBar.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Creates the stamina bar. @@ -7,8 +8,12 @@ * * Return Value: * None + * + * Example: + * [DISPLAY] call ace_advanced_fatigue_fnc_createStaminaBar + * + * Public: No */ -#include "script_component.hpp" params ["_display"]; private _staminaBar = _display ctrlCreate [QGVAR(StaminaBarContainer), -1]; diff --git a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf index b91e8a09bf..717161b890 100644 --- a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf +++ b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Calculates the duty of the current animation. @@ -14,21 +15,22 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_animName"]; private _duty = 1; private _animType = _animName select [1, 3]; GVAR(isSwimming) = false; +GVAR(isProne) = (stance _unit) == "PRONE"; -if (_animType in ["idl", "mov"]) then { +if (_animType in ["idl", "mov", "adj"]) then { switch (_animName select [5, 3]) do { case ("knl"): { _duty = 1.5; }; case ("pne"): { - _duty = 12; + _duty = 10; + GVAR(isProne) = true; // #4880 - Unarmed sprint->prone has wrong `stance` }; default { _duty = 1; @@ -47,9 +49,15 @@ if (_animType in ["idl", "mov"]) then { }; } else { // swimming and diving - if (_animType in ["swm", "ssw", "bsw", "dve", "sdv", "bdv"]) then { - _duty = 5; - GVAR(isSwimming) = true; + switch (true) do { + case (_animType in ["swm", "ssw", "bsw"]): { + _duty = 6.5; + GVAR(isSwimming) = true; + }; + case (_animType in ["dve", "sdv", "bdv"]): { + _duty = 2.5; + GVAR(isSwimming) = true; + }; }; }; diff --git a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf index fd2234d1f2..0e0ce7de04 100644 --- a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf +++ b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Calculates the current metabolic costs for a unit. @@ -15,21 +16,10 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_velocity"]; -private _virtualLoad = 0; -{ - _virtualLoad = _virtualLoad + (_x getVariable [QEGVAR(movement,vLoad), 0]); -} forEach [ - _unit, - uniformContainer _unit, - vestContainer _unit, - backpackContainer _unit -]; +private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor); -private _gearMass = ((loadAbs _unit + _virtualLoad) * 0.1 / 2.2046) * GVAR(loadFactor); -private _terrainFactor = 1; private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2)); private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor); private _duty = GVAR(animDuty); @@ -50,12 +40,12 @@ if (_velocity > 2) then { ( 2.10 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) + + (SIM_BODYMASS + _gearMass) * (0.90 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) ) * 0.23 * _duty } else { ( 1.05 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) + + (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) ) * 0.23 * _duty }; diff --git a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf index e23b9d86cd..3733517f36 100644 --- a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Handles any audible, visual and physical effects of fatigue. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_fatigue", "_speed", "_overexhausted"]; #ifdef DEBUG_MODE_FULL @@ -58,7 +58,18 @@ if (GVAR(ppeBlackoutLast) == 1) then { // - Physical effects --------------------------------------------------------- if (GVAR(isSwimming)) exitWith { - _unit setAnimSpeedCoef (1 - _fatigue / 3); + _unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true]; + + if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + } else { + if ((!isSprintAllowed _unit) && {_fatigue < 0.7}) then { + [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + }; + }; +}; +if ((getAnimSpeedCoef _unit) != 1) then { + _unit setAnimSpeedCoef 1; }; if (_overexhausted) then { @@ -79,12 +90,12 @@ if (_overexhausted) then { switch (stance _unit) do { case ("CROUCH"): { - _unit setCustomAimCoef (1.0 + _fatigue ^ 2 * 0.1); + [_unit, QUOTE(ADDON), (1.0 + _fatigue ^ 2 * 0.1) * GVAR(swayFactor)] call EFUNC(common,setAimCoef); }; case ("PRONE"): { - _unit setCustomAimCoef (1.0 + _fatigue ^ 2 * 2.0); + [_unit, QUOTE(ADDON), (1.0 + _fatigue ^ 2 * 2.0) * GVAR(swayFactor)] call EFUNC(common,setAimCoef); }; default { - _unit setCustomAimCoef (1.5 + _fatigue ^ 2 * 3.0); + [_unit, QUOTE(ADDON), (1.5 + _fatigue ^ 2 * 3.0) * GVAR(swayFactor)] call EFUNC(common,setAimCoef); }; }; diff --git a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf index c275b91cc8..0cea426eef 100644 --- a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf +++ b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Handles switching units (once on init and afterwards via Zeus). @@ -8,13 +9,20 @@ * * Return Value: * None + * + * Example: + * [newbob, oldbob] call ace_advanced_fatigue_fnc_handlePlayerChanged + * + * Public: No */ -#include "script_component.hpp" params ["_newUnit", "_oldUnit"]; +TRACE_2("unit changed",_newUnit,_oldUnit); if !(isNull _oldUnit) then { _oldUnit enableStamina true; _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; + _oldUnit setVariable [QGVAR(animHandler), nil]; + TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); _oldUnit setVariable [QGVAR(ae1Reserve), GVAR(ae1Reserve)]; _oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)]; @@ -30,6 +38,7 @@ if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { private _animHandler = _newUnit addEventHandler ["AnimChanged", { GVAR(animDuty) = _this call FUNC(getAnimDuty); }]; + TRACE_1("add new",_animHandler); _newUnit setVariable [QGVAR(animHandler), _animHandler]; }; @@ -50,7 +59,6 @@ GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower); GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362; GVAR(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362; -GVAR(anPathwayPower) = GVAR(peakPower) - _ae1PathwayPower - _ae2PathwayPower; GVAR(ppeBlackoutLast) = 100; GVAR(lastBreath) = 0; diff --git a/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf b/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf index 2f865ac821..73ba6179a9 100644 --- a/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleStaminaBar.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Handles visual changes of the stamina bar. @@ -7,8 +8,12 @@ * * Return Value: * None + * + * Example: + * [0.5] call ace_advanced_fatigue_fnc_handleStaminaBar + * + * Public: No */ -#include "script_component.hpp" params ["_stamina"]; private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf new file mode 100644 index 0000000000..1d3b215b54 --- /dev/null +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -0,0 +1,81 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut + * Main looping function that updates fatigue values. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_advanced_fatigue_fnc_mainLoop + * + * Public: No + */ +if (!alive ACE_player) exitWith { // Dead people don't breath, Will also handle null (Map intros) + [FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; + _staminaBarContainer ctrlSetFade 1; + _staminaBarContainer ctrlCommit 1; +}; + +private _currentWork = REE; +private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6; + +// fix #4481. Diving to the ground is recorded as PRONE stance with running speed velocity. Cap maximum speed to fix. +if (GVAR(isProne)) then { + _currentSpeed = _currentSpeed min 1.5; +}; + +if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then { + _currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts); + _currentWork = _currentWork max REE; +}; + +// Calculate muscle damage increase +// Note: Muscle damage recovery is ignored as it takes multiple days +GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004; +private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage)); + +// Calculate available power +private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; +private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; + +// Calculate how much power is consumed from each reserve +private _ae1Power = _currentWork min _ae1PathwayPowerFatigued; +private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued; +private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0; + +// Remove ATP from reserves for current work +GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP; +GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP; +GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP; +// Increase anearobic fatigue +GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1; + +// Aerobic ATP reserve recovery +GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0; +GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0; + +// Anaerobic ATP reserver and fatigue recovery +GVAR(anReserve) = ((GVAR(anReserve) + + (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) / GVAR(VO2MaxPower) * 56.7 * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) +) min AN_MAXRESERVE) max 0; + +GVAR(anFatigue) = ((GVAR(anFatigue) + - (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) +) min 1) max 0; + +private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; +private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE; +private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage); + +[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects); + +if (GVAR(enableStaminaBar)) then { + [GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar); +}; + +[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf b/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf index 275e4b7907..ab2742fb75 100644 --- a/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf +++ b/addons/advanced_fatigue/functions/fnc_moduleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Initializes the module settings. @@ -7,8 +8,12 @@ * * Return Value: * None + * + * Example: + * [MODULE] call ace_advanced_fatigue_fnc_moduleSettings + * + * Public: No */ -#include "script_component.hpp" params ["_logic"]; [_logic, QGVAR(enabled), "Enabled"] call EFUNC(common,readSettingFromModule); diff --git a/addons/advanced_fatigue/functions/fnc_pfhMain.sqf b/addons/advanced_fatigue/functions/fnc_pfhMain.sqf deleted file mode 100644 index 49db4646af..0000000000 --- a/addons/advanced_fatigue/functions/fnc_pfhMain.sqf +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Author: BaerMitUmlaut - * Main perFrameHandler that updates fatigue values. - * - * Arguments: - * None - * - * Return Value: - * None - */ -#include "script_component.hpp" -if (isNull ACE_player) exitWith {}; // Map intros - -private _currentWork = REE; -private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6; -if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then { - _currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts); - _currentWork = _currentWork max REE; -}; - -// Calculate muscle damage increase -// Note: Muscle damage recovery is ignored as it takes multiple days -GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004; -private _muscleIntegrity = 1 - GVAR(muscleDamage); - -// Calculate available power -private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * sqrt _muscleIntegrity; -private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * sqrt _muscleIntegrity; - -// Calculate how much power is consumed from each reserve -private _ae1Power = _currentWork min _ae1PathwayPowerFatigued; -private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued; -private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0; - -// Remove ATP from reserves for current work -GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP; -GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP; -GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP; -// Increase anearobic fatigue -GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1; - -// Aerobic ATP reserve recovery -GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0; -GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0; - -// Anaerobic ATP reserver and fatigue recovery -GVAR(anReserve) = ((GVAR(anReserve) - + (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) / GVAR(VO2MaxPower) * 56.7 * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) -) min AN_MAXRESERVE) max 0; - -GVAR(anFatigue) = ((GVAR(anFatigue) - - (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) -) min 1) max 0; - -private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; -private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE; -private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage); - -[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects); - -if (GVAR(enableStaminaBar)) then { - [GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar); -}; diff --git a/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf b/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf index 0a67f318ac..aacba72dd8 100644 --- a/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf +++ b/addons/advanced_fatigue/functions/fnc_removeDutyFactor.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Removes a duty factor. @@ -7,8 +8,12 @@ * * Return Value: * None + * + * Example: + * ["ID"] call ace_advanced_fatigue_fnc_removeDutyFactor + * + * Public: No */ -#include "script_component.hpp" params [["_id", "", [""]]]; GVAR(dutyList) params ["_idList", "_factorList"]; diff --git a/addons/advanced_fatigue/initSettings.sqf b/addons/advanced_fatigue/initSettings.sqf index d6c8acd0db..8f4e5f0c9a 100644 --- a/addons/advanced_fatigue/initSettings.sqf +++ b/addons/advanced_fatigue/initSettings.sqf @@ -2,7 +2,7 @@ QGVAR(enabled), "CHECKBOX", [LSTRING(Enabled), LSTRING(Enabled_Description)], - "ACE3 Advanced Fatigue", + LSTRING(DisplayName), true, true ] call CBA_Settings_fnc_init; @@ -11,7 +11,7 @@ QGVAR(enableStaminaBar), "CHECKBOX", [LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)], - "ACE3 Advanced Fatigue", + LSTRING(DisplayName), true, true, { if (!_this) then { @@ -26,8 +26,8 @@ QGVAR(performanceFactor), "SLIDER", [LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)], - "ACE3 Advanced Fatigue", - [0, 2, 1, 1], + LSTRING(DisplayName), + [0, 5, 1, 1], true ] call CBA_Settings_fnc_init; @@ -35,8 +35,8 @@ QGVAR(recoveryFactor), "SLIDER", [LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)], - "ACE3 Advanced Fatigue", - [0, 2, 1, 1], + LSTRING(DisplayName), + [0, 5, 1, 1], true ] call CBA_Settings_fnc_init; @@ -44,8 +44,8 @@ QGVAR(loadFactor), "SLIDER", [LSTRING(LoadFactor), LSTRING(LoadFactor_Description)], - "ACE3 Advanced Fatigue", - [0, 2, 1, 1], + LSTRING(DisplayName), + [0, 5, 1, 1], true ] call CBA_Settings_fnc_init; @@ -53,7 +53,16 @@ QGVAR(terrainGradientFactor), "SLIDER", [LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)], - "ACE3 Advanced Fatigue", - [0, 2, 1, 1], + LSTRING(DisplayName), + [0, 5, 1, 1], + true +] call CBA_Settings_fnc_init; + +[ + QGVAR(swayFactor), + "SLIDER", + [LSTRING(SwayFactor), LSTRING(SwayFactor_Description)], + LSTRING(DisplayName), + [0, 5, 1, 1], true ] call CBA_Settings_fnc_init; diff --git a/addons/advanced_fatigue/script_component.hpp b/addons/advanced_fatigue/script_component.hpp index bed86c1be8..fcc8abd3c0 100644 --- a/addons/advanced_fatigue/script_component.hpp +++ b/addons/advanced_fatigue/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_ADVANCED_FATIGUE diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index 900a5a7b18..fe2b21c40c 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -1,57 +1,171 @@ + + ACE Advanced Fatigue + ACE Erweiterte Ausdauer + ACE 進階疲勞 + ACE 进阶疲劳 + ACE アドバンスド ファティーグ + ACE Fatica Avanzata + ACE 고급 피로도 + Performance Factor Leistungsfaktor + パフォーマンス因数 + Współczynnik wydolności + 성능 요인 + Facteur de performance + Fattore Prestazione + 體力值 + 体力值 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 Erholungsfaktor + 回復因数 + Współczynnik regeneracji + 회복 요인 + Facteur de récupération + Fattore Recupero + 回復值 + 回复值 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 Gewichtsfaktor + 重量因数 + Współczynnik masy ekwipunku + 부담 요인 + Facteur d'encombrement + Fattore Caricamento + 負重量 + 负重量 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, 代表装备的重量将不会影响到玩家的体力表现 Terrain Gradient Factor Terrainsteigungsfaktor + 地形勾配因数 + Współczynnik terenu + 지형 경사도 요인 + Facteur d'inclinaison du terrain + Fattore Pendenza Terreno + 地形陡峭影響值 + 地形陡峭影响值 Sets how much steep terrain increases stamina loss. Higher means higher stamina loss. Beeinflusst, wie stark Steigungen den Ausdauerverbrauch erhöhen. Ein höherer Wert erhöht den Ausdauerverbrauch. + 急勾配の地形がどれだけスタミナ消費を増大させるかを設定します。 値が高ければ高いほど、スタミナ消費が大きくなります。 + Wpływa na to w jakim stopniu stromy teren wpływa na utratę wytrzymałości. Więcej oznacza szybszą utratę wytrzymałości. + 경사도에 따라 얼마나 피로해지는지를 정합니다. 값이 클수록 더 많은 피로를 유발합니다. + 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. + 設定陡峭的地形將會影響多少體力的流失,值越高代表體力流失越快 + 设定陡峭的地形将会影响多少体力的流,失值越高代表体力流失越快 + + + Sway factor + 手ぶれ因数 + 抖动因数 + 抖動因素 + Fattore di oscillazione + + + Influences the amount of weapon sway. Higher means more sway. + 武器を持つ手のぶれ度合いを設定します。 値が高ければ高いほど、手ぶれが強くなります。 + 影响手持武器的晃动程度,数值越高,抖动的越厉害. + 影響手持武器晃動程度,數值越高抖動越厲害 + Influenza l'ammontare di oscillazione dell'arma. Maggiore significa più oscillazione. Enabled Aktiv + アドバンスド ファティーグを有効化する + Włączone + 활성화 + Activé + Abilitato + 啟用 + 启用 Enables/disables Advanced Fatigue. Aktiviert/deaktiviert Advanced Fatigue. + アドバンスド ファティーグを有効化します。 + Włącza/wyłącza zaawansowaną wytrzymałość + 고급 피로도 활성화/비활성화 + Active/désactive la fatigue avancée. + Abilita/disabilita la Fatica Avanzata. + 啟用/關閉進階體力. + 启用/关闭进阶体力. Show stamina bar Zeige Ausdauerleiste + スタミナバーを表示する + Pokaż pasek wytrzymałości + 피로도 막대 + Afficher la barre d'endurance + Mostra barra stamina + 顯示體力條 + 显示体力条 Shows the stamina bar. Zeigt die Ausdauerleiste an. + スタミナバーを表示します。 + Pokazuje pasek wytrzymałości. + 피로도 막대를 보여줍니다. + 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/CfgEventHandlers.hpp b/addons/advanced_throwing/CfgEventHandlers.hpp index 9426fa861e..0d3301d6e0 100644 --- a/addons/advanced_throwing/CfgEventHandlers.hpp +++ b/addons/advanced_throwing/CfgEventHandlers.hpp @@ -12,6 +12,6 @@ class Extended_PreInit_EventHandlers { class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE(call COMPILE_FILE(XEH_postInitClient)); + init = QUOTE(call COMPILE_FILE(XEH_postInit)); }; }; diff --git a/addons/advanced_throwing/CfgVehicles.hpp b/addons/advanced_throwing/CfgVehicles.hpp index 6eab1b7501..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 { @@ -58,8 +58,9 @@ class CfgVehicles { class ACE_Actions { class GVAR(pickUp) { displayName = CSTRING(PickUp); - condition = QUOTE(_player call FUNC(canPrepare)); + 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 new file mode 100644 index 0000000000..7c0a194267 --- /dev/null +++ b/addons/advanced_throwing/XEH_postInit.sqf @@ -0,0 +1,125 @@ +#include "script_component.hpp" + +// Fired XEH +[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; + +// Exit on HC +if (!hasInterface) exitWith {}; + +// Ammo/Magazines look-up hash for correctness of initSpeed +GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; +{ + { + private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); + if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; }; + } count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")); + nil +} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); + + +// Add keybinds +["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), { + // Condition + if (!([ACE_player] call FUNC(canPrepare))) exitWith {false}; + if (EGVAR(common,isReloading)) exitWith {true}; + + // Statement + [ACE_player] call FUNC(prepare); + + true +}, {false}, [34, [true, false, false]], false] call CBA_fnc_addKeybind; // Shift + G + +["ACE3 Weapons", QGVAR(dropModeToggle), localize LSTRING(DropModeToggle), { + // Condition + if (!(ACE_player getVariable [QGVAR(inHand), false]) || {underwater ACE_player}) exitWith {false}; + + // Statement + private _currentDropMode = ACE_player getVariable [QGVAR(dropMode), false]; + ACE_player setVariable [QGVAR(dropMode), !_currentDropMode]; + + ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening + call FUNC(updateControlsHint); // Change controls hint for MMB + true +}, {false}, [34, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + G + +["ACE3 Weapons", QGVAR(dropModeHold), localize LSTRING(DropModeHold), { + // Condition + if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false}; + + // Statement + ACE_player setVariable [QGVAR(dropMode), true]; + ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening + call FUNC(updateControlsHint); // Change controls hint for MMB + true +}, { + // Condition + if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false}; + + // Statement + ACE_player setVariable [QGVAR(dropMode), false]; + call FUNC(updateControlsHint); // Change controls hint for MMB + true +}, [0, [false, false, false]], false] call CBA_fnc_addKeybind; // Empty + + +// Event handlers +["unit", { + [_this select 1, "Player changed"] call FUNC(exitThrowMode); +}] call CBA_fnc_addPlayerEventhandler; + +["visibleMap", { + params ["", "_visibleMap"]; // command visibleMap is updated one frame later + if (_visibleMap && {ACE_player getVariable [QGVAR(inHand), false]}) then { + [ACE_player, "Opened Map"] call FUNC(exitThrowMode); + }; +}] call CBA_fnc_addPlayerEventhandler; + + +["ace_interactMenuOpened", { + // Exit if advanced throwing is disabled (pick up only supports advanced throwing) + if (!GVAR(enabled)) exitWith {}; + + if (ACE_player getVariable [QGVAR(inHand), false]) then { + [ACE_player, "Interact menu opened"] call FUNC(exitThrowMode); + } else { + params ["_interactionType"]; + // Ignore self-interaction menu, when in vehicle and when pick up is disabled + if (GVAR(enablePickUp) && {_interactionType == 0} && {vehicle ACE_player == ACE_player}) then { + // Show pick up actions on CfgAmmo's + call FUNC(renderPickUpInteraction); + }; + }; +}] call CBA_fnc_addEventHandler; + + +// Set last thrown time on Vanilla Throwing and Advanced Throwing +["ace_firedPlayer", { + //IGNORE_PRIVATE_WARNING ["_unit", "_weapon"]; + if (_weapon == "Throw") then { + _unit setVariable [QGVAR(lastThrownTime), CBA_missionTime]; + }; +}] call CBA_fnc_addEventHandler; + + +// Display handlers +["KeyDown", {_this call FUNC(onKeyDown)}] call CBA_fnc_addDisplayHandler; +["MouseButtonDown", {_this call FUNC(onMouseButtonDown)}] call CBA_fnc_addDisplayHandler; +["MouseZChanged", {_this call FUNC(onMouseScroll)}] call CBA_fnc_addDisplayHandler; + + +#ifdef DRAW_THROW_PATH +GVAR(predictedPath) = []; +GVAR(flightPath) = []; + +addMissionEventHandler ["Draw3D", { // Blue is predicted before throw, red is real + { + _x params ["", "_newTrajAGL"]; + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [0,0,1,1], _newTrajAGL, 1, 1, 0, "", 2]; + } forEach GVAR(predictedPath); + { + _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/XEH_postInitClient.sqf b/addons/advanced_throwing/XEH_postInitClient.sqf deleted file mode 100644 index 75df42bf34..0000000000 --- a/addons/advanced_throwing/XEH_postInitClient.sqf +++ /dev/null @@ -1,107 +0,0 @@ -#include "script_component.hpp" - -// Exit on HC -if (!hasInterface) exitWith {}; - -// Ammo/Magazines look-up hash for correctness of initSpeed -GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; -{ - { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - GVAR(ammoMagLookup) setVariable [_ammo, _x]; - } count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")); - nil -} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); - - -// Add keybinds -["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), { - // Condition - if (!([ACE_player] call FUNC(canPrepare))) exitWith {false}; - - // Statement - [ACE_player] call FUNC(prepare); - - true -}, {false}, [34, [true, false, false]], false] call CBA_fnc_addKeybind; // Shift + G - -["ACE3 Weapons", QGVAR(dropModeToggle), localize LSTRING(DropModeToggle), { - // Condition - if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false}; - - // Statement - private _currentDropMode = ACE_player getVariable [QGVAR(dropMode), false]; - ACE_player setVariable [QGVAR(dropMode), !_currentDropMode]; - - ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening - call FUNC(updateControlsHint); // Change controls hint for MMB - true -}, {false}, [34, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + G - -["ACE3 Weapons", QGVAR(dropModeHold), localize LSTRING(DropModeHold), { - // Condition - if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false}; - - // Statement - ACE_player setVariable [QGVAR(dropMode), true]; - ACE_player setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; // Reset for consistency when opening - call FUNC(updateControlsHint); // Change controls hint for MMB - true -}, { - // Condition - if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false}; - - // Statement - ACE_player setVariable [QGVAR(dropMode), false]; - call FUNC(updateControlsHint); // Change controls hint for MMB - true -}, [0, [false, false, false]], false] call CBA_fnc_addKeybind; // Empty - - -// Event handlers -["unit", { - [_this select 1, "Player changed"] call FUNC(exitThrowMode); -}] call CBA_fnc_addPlayerEventhandler; - -["ace_interactMenuOpened", { - // Exit if advanced throwing is disabled (pick up only supports advanced throwing) - if (!GVAR(enabled)) exitWith {}; - - if (ACE_player getVariable [QGVAR(inHand), false]) then { - [ACE_player, "Interact menu opened"] call FUNC(exitThrowMode); - } else { - params ["_interactionType"]; - // Ignore self-interaction menu, when in vehicle and when pick up is disabled - if (GVAR(enablePickUp) && {_interactionType == 0} && {vehicle ACE_player == ACE_player}) then { - // Show pick up actions on CfgAmmo's - call FUNC(renderPickUpInteraction); - }; - }; -}] call CBA_fnc_addEventHandler; - - -// Fired XEH -[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; - - -// Display handlers -["KeyDown", {_this call FUNC(onKeyDown)}] call CBA_fnc_addDisplayHandler; -["MouseButtonDown", {_this call FUNC(onMouseButtonDown)}] call CBA_fnc_addDisplayHandler; -["MouseZChanged", {_this call FUNC(onMouseScroll)}] call CBA_fnc_addDisplayHandler; - - -#ifdef DRAW_THROW_PATH -GVAR(predictedPath) = []; -GVAR(flightPath) = []; - -addMissionEventHandler ["Draw3D", { // Blue is predicted before throw, red is real - { - _x params ["", "_newTrajAGL"]; - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [0,0,1,1], _newTrajAGL, 1, 1, 0, "", 2]; - } forEach GVAR(predictedPath); - { - _newTrajAGL = _x; - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _newTrajAGL, 1, 1, 0, "", 2]; - } forEach GVAR(flightPath) -}]; -#endif diff --git a/addons/advanced_throwing/XEH_preInit.sqf b/addons/advanced_throwing/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/advanced_throwing/XEH_preInit.sqf +++ b/addons/advanced_throwing/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; 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 396fd7ea5c..c3fdce974f 100644 --- a/addons/advanced_throwing/functions/fnc_canPrepare.sqf +++ b/addons/advanced_throwing/functions/fnc_canPrepare.sqf @@ -1,9 +1,11 @@ +#include "script_component.hpp" /* * Author: Jonpas * Checks if a throwable can be prepared. * * Arguments: * 0: Unit + * 1: Ignore Last Thrown Time (default: false) * * Return Value: * Can Prepare @@ -13,19 +15,25 @@ * * Public: No */ -#include "script_component.hpp" -params ["_unit"]; +params ["_unit", ["_ignoreLastThrownTime", false]]; + +// Don't delay when picking up +if (_ignoreLastThrownTime) then { + _unit setVariable [QGVAR(lastThrownTime), -1]; +}; GVAR(enabled) && -#ifndef DEBUG_MODE_FULL -{_unit getVariable [QGVAR(lastThrownTime), CBA_missionTime - 3] < CBA_missionTime - 2} && // Prevent throwing in quick succession -#else +#ifdef ALLOW_QUICK_THROW {true} && +#else +{_unit getVariable [QGVAR(lastThrownTime), CBA_missionTime - 3] < CBA_missionTime - 2} && // Prevent throwing in quick succession #endif {!(call EFUNC(common,isFeatureCameraActive))} && -{!EGVAR(common,isReloading)} && -{[_unit, objNull, ["isNotInside", "isNotSitting"/*, "isNotOnLadder"*/]] call EFUNC(common,canInteractWith)} && // Ladder needs positioning fixes on throw -{_unit call CBA_fnc_canUseWeapon} // Disable in non-FFV seats due to surface detection issues +{[_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_canThrow.sqf b/addons/advanced_throwing/functions/fnc_canThrow.sqf index 1f5ef20d45..e5211dd33c 100644 --- a/addons/advanced_throwing/functions/fnc_canThrow.sqf +++ b/addons/advanced_throwing/functions/fnc_canThrow.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Checks if a throwable can be thrown. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/advanced_throwing/functions/fnc_drawArc.sqf b/addons/advanced_throwing/functions/fnc_drawArc.sqf index 53398f7b2f..906650627f 100644 --- a/addons/advanced_throwing/functions/fnc_drawArc.sqf +++ b/addons/advanced_throwing/functions/fnc_drawArc.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Zapat, Dslyecxi, Jonpas * Draws throw arc. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" // Disable drawing when intersecting with the vehicle if !([ACE_player] call FUNC(canThrow)) exitWith { @@ -47,11 +47,15 @@ for "_i" from 0.05 to 1.45 step 0.1 do { if (_newTrajASL distance (getPosASLVisual ACE_player) <= 20) then { if ((ASLToATL _newTrajASL) select 2 <= 0) then { - _cross = 1 + _cross = 1; // 1: Distance Limit (Green) } else { // Even vanilla throwables go through glass, only "GEOM" LOD will stop it but that will also stop it when there is glass in a window - if (lineIntersects [_prevTrajASL, _newTrajASL]) then { - _cross = 2; + if (lineIntersects [_prevTrajASL, _newTrajASL]) then { // Checks the "VIEW" LOD + _cross = 2; // 2: View LOD Block (Red) + } else { + if (!((lineIntersectsSurfaces [_prevTrajASL, _newTrajASL, _activeThrowable, ACE_player, true, 1, "GEOM", "FIRE"]) isEqualTo [])) then { + _cross = 3; // 3: GEOM/FIRE LOD Block (Yellow) - pass a3 bulding glass, but blocked on some CUP glass + }; }; }; @@ -60,10 +64,10 @@ for "_i" from 0.05 to 1.45 step 0.1 do { private _movePerc = linearConversion [3, 0, vectorMagnitude (velocity ACE_player), 0, 1, true]; _alpha = _alpha * _movePerc; - private _col = [ [1, 1, 1, _alpha], [0, 1, 0, _alpha], [1, 0, 0, _alpha] ] select _cross; + 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 14fbb567d2..42d52b7153 100644 --- a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf +++ b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas, SilentSpike * Handles drawing the currently selected or cooked throwable. @@ -13,9 +14,8 @@ * * Public: No */ -#include "script_component.hpp" -if (dialog || {!(ACE_player getVariable [QGVAR(inHand), false])} || {!([ACE_player] call FUNC(canPrepare))}) exitWith { +if (dialog || {!(ACE_player getVariable [QGVAR(inHand), false])} || {!([ACE_player, true] call FUNC(canPrepare))}) exitWith { [ACE_player, "In dialog or no throwable in hand or cannot prepare throwable"] call FUNC(exitThrowMode); }; @@ -36,6 +36,11 @@ if (_throwable isEqualTo [] && {!_primed}) exitWith { private _throwableMag = _throwable param [0, "#none"]; +// If not primed, double check we actually have the magazine in inventory +if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwableMag in (vestItems ACE_player)} || {_throwableMag in (backpackItems ACE_player)})}) exitWith { + [ACE_player, "No valid throwable (glitched currentThrowable)"] call FUNC(exitThrowMode); +}; + // Get correct throw power for primed grenade if (_primed) then { private _ammoType = typeOf _activeThrowable; @@ -63,7 +68,7 @@ private _power = linearConversion [0, 180, _phi - 30, 1, 0.3, true]; ACE_player setVariable [QGVAR(throwSpeed), _throwSpeed * _power]; #ifdef DEBUG_MODE_FULL -hintSilent format ["Heading: %1\nPower: %2\nSpeed: %3\nThrowMag: %4", _phi, _power, _throwSpeed * _power, _throwableMag]; +hintSilent format ["Heading: %1\nPower: %2\nSpeed: %3\nThrowMag: %4\nMuzzle: %5", _phi, _power, _throwSpeed * _power, _throwableMag, ACE_player getVariable [QGVAR(activeMuzzle), ""]]; #endif private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo"); @@ -71,16 +76,25 @@ private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag if (!([ACE_player] call FUNC(canThrow)) && {!_primed}) exitWith { if (!isNull _activeThrowable) then { deleteVehicle _activeThrowable; + // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) + ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1]; }; }; if (isNull _activeThrowable || {(_throwableType != typeOf _activeThrowable) && {!_primed}}) then { if (!isNull _activeThrowable) then { deleteVehicle _activeThrowable; + // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) + ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1]; }; _activeThrowable = _throwableType createVehicleLocal [0, 0, 0]; _activeThrowable enableSimulation false; ACE_player setVariable [QGVAR(activeThrowable), _activeThrowable]; + + // Set muzzle ammo to 0 to block vanilla throwing (can only be 0 or 1) + private _muzzle = _throwableMag call FUNC(getMuzzle); + ACE_player setAmmo [_muzzle, 0]; + ACE_player setVariable [QGVAR(activeMuzzle), _muzzle]; }; // Exit in case of explosion in hand @@ -114,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_exitThrowMode.sqf b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf index fd6cb7b998..ffe1110dc2 100644 --- a/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf +++ b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas * Exits throw mode. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_reason"]; TRACE_2("params",_unit,_reason); @@ -25,13 +25,26 @@ if !(_unit getVariable [QGVAR(inHand), false]) exitWith {}; systemChat format ["Exit Throw Mode: %1", _reason]; #endif +private _activeThrowable = _unit getVariable [QGVAR(activeThrowable), objNull]; if !(_unit getVariable [QGVAR(primed), false]) then { - deleteVehicle (_unit getVariable [QGVAR(activeThrowable), objNull]); + deleteVehicle _activeThrowable; +} else { + _unit setVariable [QGVAR(lastThrownTime), CBA_missionTime]; + // Fix floating for throwables without proper physics (eg. IR Grenade) + _activeThrowable setVelocity [0, 0, -0.1]; + + // Set thrower + private _instigator = (getShotParents _activeThrowable) param [1, _unit]; // getShotParents could be [] on replaced grenades (like IR chemlight) + [QEGVAR(common,setShotParents), [_activeThrowable, _unit, _instigator]] call CBA_fnc_serverEvent; }; +// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) +_unit setAmmo [_unit getVariable [QGVAR(activeMuzzle), ""], 1]; + _unit setVariable [QGVAR(inHand), false]; _unit setVariable [QGVAR(primed), false]; _unit setVariable [QGVAR(activeThrowable), objNull]; +_unit setVariable [QGVAR(activeMuzzle), ""]; _unit setVariable [QGVAR(throwType), THROW_TYPE_DEFAULT]; _unit setVariable [QGVAR(throwSpeed), THROW_SPEED_DEFAULT]; _unit setVariable [QGVAR(dropMode), false]; diff --git a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf index 030ec25ccb..03ac62f6d2 100644 --- a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf +++ b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Retrieve muzzle name from config. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_magazineClassname"]; diff --git a/addons/advanced_throwing/functions/fnc_moduleInit.sqf b/addons/advanced_throwing/functions/fnc_moduleInit.sqf index 2130319067..3f5d3bbd3f 100644 --- a/addons/advanced_throwing/functions/fnc_moduleInit.sqf +++ b/addons/advanced_throwing/functions/fnc_moduleInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Initializes the Advanced Throwing module. @@ -13,12 +14,8 @@ * Example: * [logic, [unit1, unit2], true] call ace_advanced_throwing_fnc_moduleInit * - * Public: - * No + * Public: No */ -#include "script_component.hpp" - -if (!isServer) exitWith {}; params ["_logic", "_units", "_activated"]; @@ -30,4 +27,4 @@ if (!_activated) exitWith {}; [_logic, QGVAR(enablePickUp), "enablePickUp"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(enablePickUpAttached), "enablePickUpAttached"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO_1("Advanced Throwing Module Initialized. Enabled: %1",GVAR(enabled)); +INFO_1("Advanced Throwing Module Initialized. Enabled: %1",GVAR(enabled)); diff --git a/addons/advanced_throwing/functions/fnc_onKeyDown.sqf b/addons/advanced_throwing/functions/fnc_onKeyDown.sqf index 42fab8fc1a..d0f8404203 100644 --- a/addons/advanced_throwing/functions/fnc_onKeyDown.sqf +++ b/addons/advanced_throwing/functions/fnc_onKeyDown.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas * Key down event. @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {false}; diff --git a/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf b/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf index e13ed52290..69abb9641b 100644 --- a/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf +++ b/addons/advanced_throwing/functions/fnc_onMouseButtonDown.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas * Mouse button down event. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {}; diff --git a/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf b/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf index b06d198380..f56b153557 100644 --- a/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf +++ b/addons/advanced_throwing/functions/fnc_onMouseScroll.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas * Mouse scroll wheel changed event. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if !(ACE_player getVariable [QGVAR(inHand), false]) exitWith {}; diff --git a/addons/advanced_throwing/functions/fnc_pickUp.sqf b/addons/advanced_throwing/functions/fnc_pickUp.sqf index 2238ea1893..9fd49486d1 100644 --- a/addons/advanced_throwing/functions/fnc_pickUp.sqf +++ b/addons/advanced_throwing/functions/fnc_pickUp.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Picks up a throwable from the ground. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_helper", "_unit"]; TRACE_2("params",_helper,_unit); diff --git a/addons/advanced_throwing/functions/fnc_prepare.sqf b/addons/advanced_throwing/functions/fnc_prepare.sqf index b9e75ea480..393f8301d3 100644 --- a/addons/advanced_throwing/functions/fnc_prepare.sqf +++ b/addons/advanced_throwing/functions/fnc_prepare.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas * Prepares throwable or selects the next. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); @@ -23,12 +23,15 @@ if (_unit getVariable [QGVAR(inHand), false]) exitWith { TRACE_1("inHand",_unit); if (!(_unit getVariable [QGVAR(primed), false])) then { TRACE_1("not primed",_unit); + // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) + // selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles) + ACE_player setAmmo [ACE_player getVariable [QGVAR(activeMuzzle), ""], 1]; [_unit] call EFUNC(weaponselect,selectNextGrenade); }; }; // Try selecting next throwable if none currently selected -if ((isNull (_unit getVariable [QGVAR(activeThrowable), objNull])) && {(currentThrowable _unit) isEqualTo []} && {!([_unit] call EFUNC(weaponselect,selectNextGrenade))}) exitWith { +if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThrowable _unit) isEqualTo []} && {!([_unit] call EFUNC(weaponselect,selectNextGrenade))}) exitWith { TRACE_1("no throwables",_unit); }; diff --git a/addons/advanced_throwing/functions/fnc_prime.sqf b/addons/advanced_throwing/functions/fnc_prime.sqf index 84a3b0465a..22681d3ebc 100644 --- a/addons/advanced_throwing/functions/fnc_prime.sqf +++ b/addons/advanced_throwing/functions/fnc_prime.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas * Primes the throwable, creates global throwable vehicle and throws Fired XEH. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", ["_showHint", false]]; TRACE_2("params",_unit,_showHint); @@ -26,7 +26,16 @@ private _throwableMag = (currentThrowable _unit) select 0; _unit removeItem _throwableMag; private _throwableType = getText (configFile >> "CfgMagazines" >> _throwableMag >> "ammo"); -private _muzzle = _throwableMag call FUNC(getMuzzle); +private _muzzle = _unit getVariable [QGVAR(activeMuzzle), ""]; + +// Set muzzle ammo to 0 to block vanilla throwing (can only be 0 or 1), removeItem above resets it +_unit setAmmo [_muzzle, 0]; + +// Handle weird scripted grenades (RHS) which could cause unexpected behaviour +private _nonInheritedCfg = configProperties [configFile >> "CfgAmmo" >> _throwableType, 'configName _x == QGVAR(replaceWith)', false]; +if ((count _nonInheritedCfg) == 1) then { + _throwableType = getText (_nonInheritedCfg select 0); +}; // Create actual throwable globally private _activeThrowableOld = _unit getVariable [QGVAR(activeThrowable), objNull]; @@ -45,6 +54,9 @@ deleteVehicle _activeThrowableOld; _activeThrowable // projectile ]] call CBA_fnc_globalEvent; +// Set prime instigator +[QEGVAR(common,setShotParents), [_activeThrowable, _unit, _unit]] call CBA_fnc_serverEvent; + if (_showHint) then { // Show primed hint private _displayNameShort = getText (configFile >> "CfgMagazines" >> _throwableMag >> "displayNameShort"); diff --git a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf index 7e9e5486dc..5b7d2c9f0b 100644 --- a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf +++ b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror, Jonpas * When interact_menu starts rendering (from "interact_keyDown" event). @@ -7,14 +8,13 @@ * None * * Return Value: - * Nothing + * None * * Example: * call ace_advanced_throwing_fnc_renderPickUpInteraction * * Public: No */ -#include "script_component.hpp" [{ params ["_args", "_idPFH"]; @@ -22,15 +22,19 @@ // isNull is necessarry to prevent rare error when ending mission with interact key down if (EGVAR(interact_menu,keyDown) && {!isNull ACE_player}) then { - // Rescan when player moved >5 meters from last pos, nearObjects is costly + // Rescan when player moved >5 meters from last pos, nearObjects can be costly with a lot of objects around if ((getPosASL ACE_player) distance _setPosition > 5) then { - // IR throwbles inherit from GrenadeCore, others from GrenadeHand, IR Chemlights are special snowflakes + // Grenades inherit from GrenadeHand, IR throwbles from IRStrobeBase, IR Chemlights are special snowflakes + // nearEntities does not see throwables _nearThrowables = ACE_player nearObjects ["GrenadeHand", PICK_UP_DISTANCE]; - _nearThrowables append (ACE_player nearObjects ["GrenadeCore", PICK_UP_DISTANCE]); + _nearThrowables append (ACE_player nearObjects ["IRStrobeBase", PICK_UP_DISTANCE]); _nearThrowables append (ACE_player nearObjects ["ACE_Chemlight_IR_Dummy", PICK_UP_DISTANCE]); { - if (!(_x in _throwablesHelped) && {GVAR(enablePickUpAttached) || {!GVAR(enablePickUpAttached) && {isNull (attachedTo _x)}}}) then { + if (!(_x in _throwablesHelped) && + {!(_x isKindOf "SmokeShellArty")} && {!(_x isKindOf "G_40mm_Smoke")} && // All smokes inherit from "GrenadeHand" >> "SmokeShell" + {GVAR(enablePickUpAttached) || {!GVAR(enablePickUpAttached) && {isNull (attachedTo _x)}}} + ) then { TRACE_2("Making PickUp Helper",_x,typeOf _x); private _pickUpHelper = QGVAR(pickUpHelper) createVehicleLocal [0, 0, 0]; diff --git a/addons/advanced_throwing/functions/fnc_throw.sqf b/addons/advanced_throwing/functions/fnc_throw.sqf index 0d92a4a7c0..3bc69be882 100644 --- a/addons/advanced_throwing/functions/fnc_throw.sqf +++ b/addons/advanced_throwing/functions/fnc_throw.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, Jonpas * Throw selected throwable. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); @@ -49,13 +49,28 @@ 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); }; - _unit setVariable [QGVAR(lastThrownTime), CBA_missionTime]; - // Invoke listenable event ["ace_throwableThrown", [_unit, _activeThrowable]] call CBA_fnc_localEvent; }, [ @@ -69,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/functions/fnc_throwFiredXEH.sqf b/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf index a98551f220..80dbc2f973 100644 --- a/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf +++ b/addons/advanced_throwing/functions/fnc_throwFiredXEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: CBA Team * Throws Fired XEH. @@ -19,7 +20,6 @@ * * Public: No */ -#include "script_component.hpp" TRACE_1("Fired",_this); diff --git a/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf b/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf index 12170b5346..3dcb516c32 100644 --- a/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf +++ b/addons/advanced_throwing/functions/fnc_updateControlsHint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Updates controls hints based on current state. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (!GVAR(showMouseControls)) exitWith {}; diff --git a/addons/advanced_throwing/script_component.hpp b/addons/advanced_throwing/script_component.hpp index abea16868f..c6ce7dcb84 100644 --- a/addons/advanced_throwing/script_component.hpp +++ b/addons/advanced_throwing/script_component.hpp @@ -3,9 +3,9 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define DRAW_THROW_PATH +// #define ALLOW_QUICK_THROW // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_ADVANCED_THROWING @@ -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 1c3729d06e..a060927076 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -1,89 +1,257 @@ - + Advanced Throwing Улучшенный бросок гранат + アドバンスド スローイング + Zaawansowane rzucanie + Erweitertes Wurfsystem + 고급 투척 + Lancé amélioré + Lancio Avanzato + 進階投擲 + 进阶投掷 Allows changing advanced throwing behaviour. Позволяет настраивать поведение улучшенного броска гранат. + アドバンスド スローイングの動作挙動を変更します。 + Zezwala na zmianę zachowania zaawansowanego trybu rzucania. + Erlaubt es, das Verhalten des erweiterten Wurfsystems zu ändern. + 고급 투척 행위를 허가합니다 + 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 + 고급 투척 활성화 + Active le lancé amélioré + Abilita Lancio Avanzato + 啟用進階投擲 + 启用进阶投掷 Enables advanced throwing system. Включает систему улучшенного броска. + アドバンスド スローイングを有効化します。 + Aktywuje system zaawansowanego rzucania. + Aktiviert das erweiterte Wurfsystem. + 고급 투척을 활성화 합니다 + Active le système de lancé amélioré. + Abilita il sistema di lancio avanzato. + 啟用進階投擲系統 + 启用进阶投掷系统 Show Throw Arc Показать траекторию броска + 投てき軌道を表示する + Pokaż trasę lotu + Zeige Wurfbogen + 투척 궤적 표시 + Afficher l'arc de lancé + Mostra Arco di Tiro + 顯示投擲軌道 + 显示投掷轨道 Enables visualization of the throw arc (where throwable will fly). Включает визуализацию траектории броска (как полетит граната). + 投てき軌道 (投てき物がどこに飛ぶか) の表示を有効化します。 + Wyświetla wizualizację trasy przelotu granatu. + Aktiviert die Visualisierung des Wurfbogens (wohin das Objekt geworfen werden wird). + 투척 궤도를 시각화 합니다(투척물이 어디로 갈지) + 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 Показывать управление мышью + 投てきのマウス操作を表示する + Pokaż podpowiedzi sterowania myszą + Zeige Maussteuerung beim Werfen + 마우스 조작 표시 + Afficher les contrôles à la souris du lancé + Mostra Comandi Mouse Lancio + 顯示滑鼠投擲控制提示 + 显示滑鼠投掷控制提示 Enables visual cues for mouse controls when throwable is prepared. Включает отображение подсказок по управлению мышью, когда граната подготовлена. + 投てき物を構える時、マウス操作の説明表示を有効化します。 + Wyświetla podpowiedzi sterowania myszą kiedy obiekt miotany jest w ręku. + Aktiviert visuelle Hinweise zur Maussteuerung, wenn ein Objekt zum Werfen vorbereitet wird. + 투척물을 준비시 마우스 조작을 시각화해서 보여줍니다 + 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 + 투척물 줍기 활성화 + Active la récupération des objets lancés + Abilita Raccogli Oggetti + 啟用可撿取地面投擲物 + 启用可捡取地面投掷物 Enables ability to pick up throwables from the ground. Включает возможность подбирать гранаты с земли. + 地面に落ちている投てき物を拾い上げる機能を有効化します。 + Umożliwia podnoszenie obiektów miotanych z ziemi. + Aktiviert die Möglichkeit, geworfene Objekte wieder vom Boden aufzuheben. + 땅에 떨어진 투척물을 주울 수 있게 해줍니다. + 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 + 부착 투척물 줍기 활성화 + Active le ramassage d'objets lançables attachés + Abilita Raccogli Oggetti Lanciabili da altri Oggetti + 啟用可撿取附著投擲物 + 启用可捡取附着投掷物 Enables ability to pick up throwables from attached objects. Включает возможность подбирать гранаты, прикрепленные к объектам. + 取り付けられた投てき物を、取り付け先から拾い上げる機能を有効化します。 + Umożliwia podnoszenie obiektów miotanych przyczepionych do innych obiektów. + Aktiviert die Möglichkeit, befestigte Wurfobjekte erneut aufzunehmen. + 부착된 투척물을 주울 수 있게 해줍니다. + 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 + 투척물 준비/변경 + Préparer/changer d'objet + Prepara/Cambia Oggetto lanciabile + 準備/變更投擲物 + 准备/变更投掷物 Throwable Drop Mode (Hold) Режим броска гранаты (удерживать) + 投てきモード (押している間) + Tryb upuszczania ob. miotanego (przytrzymaj) + Wurfobjekt Fallmodus (halten) + 투척물 떨어뜨리기 모드(꾹눌러서) + Mode de lancé de l'objet (Tenir) + Modalità Oggetto Gettabile (Mantenere) + 投擲模式 (按住) + 投掷模式 (按住) Throwable Drop Mode (Toggle) Режим броска гранаты (переключить) + 投てきモード (切り替え) + Tryb upuszczania ob. miotanego (przełącz) + Wurfobjekt Fallmodus (umschalten) + 투척물 떨어뜨리기 모드(토글) + Mode de lancé de l'objet (Basculer) + Modalità Oggetto lanciabile Gettabile (Interruttore) + 投擲模式 (切換) + 投掷模式 (切换) Primed Подготовлена + 点火 + Odbezpieczony + Scharf gemacht + 뇌관 작동 + Amorcer + Armato + 引信開始燃燒 + 引信开始燃烧 Throw Бросить + 投げる + Rzuć + Werfen + 던지기 + Lancer + Lanciare + 投擲 + 投掷 (Scroll) Change Mode (Скролл) Изменить режим + (スクロール) モード変更 + (Kółko m.) zmień tryb + (Scrollen) Modus wechseln + (마우스 휠) 모드 변경 + (Molette souris) Changer de mode + (Scorrere) Cambio Modalità + (滾輪) 變更模式 + (滚轮) 变更模式 (Scroll) Extend (Скролл) Увеличить + (スクロール) 腕を伸ばす + (Kółko m.) przedłuż + (Scrollen) Erweitern + (마우스 휠) 연장 + (Molette souris) Etendre + (Scorrere) Estendere + (滾輪) 延長 + (滚轮) 延长 (Click) Cook (Клик) Подготовить + (クリック) 点火する + (Kliknięcie) Odbezpiecz + (Klicken) Abkochen + (클릭) 예열 + (Clique) Dégoupiller + (Click) Arma + (點擊) 提早拉開引信 + (点击) 提早拉开引信 Pick Up Подобрать + 拾い上げる + Podnieś + Aufheben + 줍기 + Ramasser + Raccogli + 撿取 + 捡取 diff --git a/addons/ai/CfgAISkill.hpp b/addons/ai/CfgAISkill.hpp deleted file mode 100644 index c01b5eb96e..0000000000 --- a/addons/ai/CfgAISkill.hpp +++ /dev/null @@ -1,28 +0,0 @@ - -/* - * Documentation: - * https://community.bistudio.com/wiki/AI_Sub-skills - * - * The idea here is to reduce the AI's godlike aiming - * capabilties while retaining it's high intelligence. - * The AI should be smart enough to move through a town, - * but also be 'human' in their reaction time and aim. - * - * Note: All these values can still be adjusted via - * scripts, these arrays just change what 0 & 1 - * are for setSkill. - */ - -class CfgAISkill { - aimingAccuracy[] = {0,0, 1,0.8}; // {0,0,1,1}; v1.26 defaults - aimingShake[] = {0,0, 1,0.6}; // {0,0,1,1}; - aimingSpeed[] = {0,0, 1,0.7}; // {0,0.5,1,1}; - commanding[] = {0,0, 1,0.8}; // {0,0,1,1}; - courage[] = {0,0, 1,0.7}; // {0,0,1,1}; - endurance[] = {0,0, 1,0.7}; // {0,0,1,1}; - general[] = {0,0, 1,0.9}; // {0,0,1,1}; - // apparently breaks rapid firing in single fire mode for players - //reloadSpeed[] = {0,0, 1,0.8}; // {0,0,1,1}; - spotDistance[] = {0,0, 1,0.9}; // {0,0.2,1,0.4}; - spotTime[] = {0,0, 1,0.7}; // {0,0,1,0.7}; -}; 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/CfgWeapons.hpp b/addons/ai/CfgWeapons.hpp index be3245cce3..01d8d5f9c2 100644 --- a/addons/ai/CfgWeapons.hpp +++ b/addons/ai/CfgWeapons.hpp @@ -2,8 +2,6 @@ // weapon config changes, by commy2 /* documentation: -aiDispersionCoefX = 1.0 Dispersion multiplier for AI units (axis X - left to right). -aiDispersionCoefY = 1.0 Dispersion multiplier for AI units (axis Y - top-down). aiRateOfFire = 5.0 Delay between shots at given aiRateOfFireDistance. aiRateOfFireDistance = 500 At shorter distance delay (aiRateOfFire) goes linearly to zero. */ @@ -15,19 +13,12 @@ class Mode_FullAuto; class CfgWeapons { // rifles - class RifleCore; - class Rifle: RifleCore { - aiDispersionCoefX = 6; - aiDispersionCoefY = 6; - }; - - class Rifle_Base_F: Rifle {}; - class Rifle_Long_Base_F: Rifle_Base_F {}; + class Rifle_Base_F; + class Rifle_Short_Base_F; + class Rifle_Long_Base_F; // MX class arifle_MX_Base_F: Rifle_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; modes[] += {"ACE_Burst_far"}; class Single: Mode_SemiAuto { @@ -70,8 +61,6 @@ class CfgWeapons { // MX carbine class arifle_MXC_F: arifle_MX_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; class Single: Single { minRange = 120; // 2; @@ -143,8 +132,6 @@ class CfgWeapons { // MX machine gun class arifle_MX_SW_F: arifle_MX_Base_F { - aiDispersionCoefY = 24.0; - aiDispersionCoefX = 21.0; // Shit is still broken //modes[] += {"ACE_Burst_far"}; modes[] = {"Single","manual","close","short","medium","far_optic1","far_optic2","ACE_Burst_far"}; @@ -180,8 +167,6 @@ class CfgWeapons { // Katiba class arifle_Katiba_Base_F: Rifle_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; modes[] += {"ACE_Burst_far"}; class Single: Mode_SemiAuto { @@ -224,8 +209,6 @@ class CfgWeapons { // Katiba carbine class arifle_Katiba_C_F: arifle_Katiba_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; class Single: Single { minRange = 120; // 2; @@ -268,8 +251,6 @@ class CfgWeapons { // F2002 class mk20_base_F: Rifle_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; modes[] += {"ACE_Burst_far"}; class Single: Mode_SemiAuto { @@ -316,8 +297,6 @@ class CfgWeapons { // F2002 carbine class arifle_Mk20C_F: mk20_base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; class Single: Single { minRange = 120; // 2; @@ -358,8 +337,6 @@ class CfgWeapons { // TAR-20 class Tavor_base_F: Rifle_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; modes[] += {"ACE_Burst_far"}; class Single: Mode_SemiAuto { @@ -407,8 +384,6 @@ class CfgWeapons { // TAR-21 class arifle_TRG21_F: Tavor_base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; class Single: Single { minRange = 120; // 2; @@ -457,8 +432,6 @@ class CfgWeapons { // SDAR class SDAR_base_F: Rifle_Base_F { - aiDispersionCoefY = 28.0; - aiDispersionCoefX = 20.0; class Single: Mode_SemiAuto { minRange = 10; //2; @@ -470,9 +443,7 @@ class CfgWeapons { }; // PD2000 - class pdw2000_base_F: Rifle_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; + class pdw2000_base_F: Rifle_Short_Base_F { class Single: Mode_SemiAuto { minRange = 100; //2; @@ -484,9 +455,7 @@ class CfgWeapons { }; // Vector - class SMG_01_Base: Rifle_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; + class SMG_01_Base: Rifle_Short_Base_F { class Single: Mode_SemiAuto { minRange = 50; //2; @@ -498,9 +467,7 @@ class CfgWeapons { }; // Scorpion EVO - class SMG_02_base_F: Rifle_Base_F { - aiDispersionCoefY = 18.0; - aiDispersionCoefX = 12.0; + class SMG_02_base_F: Rifle_Short_Base_F { class Single: Mode_SemiAuto { minRange = 50; //2; @@ -515,8 +482,6 @@ class CfgWeapons { // Stoner class LMG_Mk200_F: Rifle_Long_Base_F { - aiDispersionCoefY = 24.0; - aiDispersionCoefX = 21.0; modes[] += {"ACE_Burst_far"}; class medium; @@ -544,8 +509,6 @@ class CfgWeapons { // Negev class LMG_Zafir_F: Rifle_Long_Base_F { - aiDispersionCoefY = 23.0; - aiDispersionCoefX = 19.0; modes[] += {"ACE_Burst_far"}; class Single: Mode_SemiAuto { @@ -719,8 +682,6 @@ class CfgWeapons { // marksmen medium mg class MMG_01_base_F: Rifle_Long_Base_F { - aiDispersionCoefY = 25.0; - aiDispersionCoefX = 20.0; modes[] += {"ACE_Burst_far"}; class manual; @@ -745,8 +706,6 @@ class CfgWeapons { }; class MMG_02_base_F: Rifle_Long_Base_F { - aiDispersionCoefY = 20.0; - aiDispersionCoefX = 15.0; modes[] += {"ACE_Burst_far"}; class manual; diff --git a/addons/ai/README.md b/addons/ai/README.md index 40b4e776a4..e3175b1006 100644 --- a/addons/ai/README.md +++ b/addons/ai/README.md @@ -1,7 +1,7 @@ ace_ai ====== -Minor changes of AI skill and overhaul of AI firing modes of vanilla weapons, encouraging the AI to use full-auto and bursts more often. +Overhaul of AI firing modes of vanilla weapons, encouraging the AI to use full-auto and bursts more often. ## Maintainers 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..4ce37fd314 --- /dev/null +++ b/addons/ai/XEH_postInit.sqf @@ -0,0 +1,109 @@ +#include "script_component.hpp" + +[QGVAR(AISection), { + params [["_units", [], [[]]], ["_sections", [], [[]]], ["_bool", true, [true]]]; + { + private _section = _x; + { + if (_bool) then { + _x enableAI _section; + LOG_3("%1 enableAI %2 | ID: %3",_x,_section,clientOwner); + } else { + _x disableAI _section; + LOG_3("%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 setDestination [_pos, "LEADER PLANNED", true]; + _unit doMove _pos; + LOG_3("%1 doMove %2 | ID: %3",_unit,_pos,clientOwner); + } forEach _unitsArray; +}] call CBA_fnc_addEventHandler; + +[QGVAR(setBehaviour), { + params ["_groupsArray", "_behaviour"]; + { + _x setBehaviour _behaviour; + LOG_3("%1 setBehaviour %2 | ID: %3",_x,_behaviour,clientOwner); + } forEach _groupsArray; +}] call CBA_fnc_addEventHandler; + +[QGVAR(enableAttack), { + params ["_unitsArray", "_mode"]; + { + _x enableAttack _mode; + LOG_3("%1 enableAttack %2 | ID: %3",_x,_mode,clientOwner); + } forEach _unitsArray; +}] call CBA_fnc_addEventHandler; + +[QGVAR(setUnitPos), { + params ["_unit", "_mode"]; + _unit setUnitPos _mode; +}] call CBA_fnc_addEventHandler; + +[QGVAR(setSpeedMode), { + params ["_unit", "_mode"]; + _unit setSpeedMode _mode; +}] call CBA_fnc_addEventHandler; + +[QGVAR(setCombatMode), { + params ["_unit", "_mode"]; + _unit setCombatMode _mode; +}] call CBA_fnc_addEventHandler; + +[QGVAR(allowFleeing), { + params ["_unit", "_cowardice"]; + _unit allowFleeing _cowardice; +}] call CBA_fnc_addEventHandler; + +[QGVAR(enableGunLights), { + params ["_unit", "_mode"]; + _unit enableGunLights _mode; +}] 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 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/laser_selfdesignate/XEH_preStart.sqf b/addons/ai/XEH_preStart.sqf similarity index 100% rename from addons/laser_selfdesignate/XEH_preStart.sqf rename to addons/ai/XEH_preStart.sqf diff --git a/addons/ai/config.cpp b/addons/ai/config.cpp index 60bf7184a4..bc3b2df4ac 100644 --- a/addons/ai/config.cpp +++ b/addons/ai/config.cpp @@ -14,5 +14,5 @@ class CfgPatches { }; }; -#include "CfgAISkill.hpp" #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..5e5c34d19a --- /dev/null +++ b/addons/ai/functions/fnc_garrison.sqf @@ -0,0 +1,278 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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..586c7b1f20 --- /dev/null +++ b/addons/ai/functions/fnc_garrisonMove.sqf @@ -0,0 +1,149 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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..8391c7f8e3 --- /dev/null +++ b/addons/ai/functions/fnc_unGarrison.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +/* + * 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 + * +*/ + +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 08d24079ba..9a0afcf434 100644 --- a/addons/ai/script_component.hpp +++ b/addons/ai/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #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..ccf55310b1 --- /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/CfgAmmo.hpp b/addons/aircraft/CfgAmmo.hpp index 2c3701b8e0..0da9c7760f 100644 --- a/addons/aircraft/CfgAmmo.hpp +++ b/addons/aircraft/CfgAmmo.hpp @@ -1,4 +1,3 @@ - class CfgAmmo { class BulletBase; class B_20mm : BulletBase { @@ -11,11 +10,11 @@ class CfgAmmo { explosive = 1.8; tracersEvery = 3; tracerEndTime = 3.5; - CraterEffects = "ExploAmmoCrater"; explosionEffects = "ExploAmmoExplosion"; model = "\A3\Weapons_f\Data\bullettracer\tracer_red"; }; + class ACE_20mm_HE : B_20mm {}; class ACE_20mm_AP : B_20mm { hit = 50; @@ -40,30 +39,20 @@ class CfgAmmo { // also adjust tracer, "muh lightshow"; also adjust splash damage radius class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { - hit = 80; - indirectHit = 12; - indirectHitRange = 3; //2; - caliber = 1.4; - deflecting = 3; - fuseDistance = 3; - tracerStartTime = 0.02; - timeToLive = 40; + hit = 80; // default: 180 + indirectHit = 12; // default: 4 + indirectHitRange = 3; // default: 3 + caliber = 1.4; // default: 5 + deflecting = 3; // default: 5 + fuseDistance = 3; // default: 10 + tracerStartTime = 0.02; // default: 0.1 + timeToLive = 40; // default: 6 }; - // helper projectiles to simulate a rof > fps - class ACE_Gatling_30mm_HE_Plane_CAS_01_Deploy: Gatling_30mm_HE_Plane_CAS_01_F { - simulation = "shotSubmunitions"; - triggerTime = 0; - submunitionAmmo = "ACE_Gatling_30mm_HE_Plane_CAS_01_Sub"; - submunitionConeType[] = {"custom", {{0,0}, {0,0}, {0,0}} }; - }; - - class ACE_Gatling_30mm_HE_Plane_CAS_01_Sub: Gatling_30mm_HE_Plane_CAS_01_F {}; - // adjust damage and splash damage, closer to bluefor gatling with same caliber class Cannon_30mm_HE_Plane_CAS_02_F: Gatling_30mm_HE_Plane_CAS_01_F { - hit = 70; //40; - indirectHit = 11; //14; - indirectHitRange = 3; + hit = 70; // default: 150 + indirectHit = 11; // default: 4 + indirectHitRange = 3; // default: 3 }; }; 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/CfgMagazines.hpp b/addons/aircraft/CfgMagazines.hpp index b09bac6943..19797b53d8 100644 --- a/addons/aircraft/CfgMagazines.hpp +++ b/addons/aircraft/CfgMagazines.hpp @@ -1,9 +1,7 @@ - class CfgMagazines { // shoot helper object to tripple rof class VehicleMagazine; class 1000Rnd_Gatling_30mm_Plane_CAS_01_F: VehicleMagazine { - ammo = "ACE_Gatling_30mm_HE_Plane_CAS_01_Deploy"; count = 1170; }; diff --git a/addons/aircraft/CfgVehicles.hpp b/addons/aircraft/CfgVehicles.hpp index 9839149b3d..5d3d705db6 100644 --- a/addons/aircraft/CfgVehicles.hpp +++ b/addons/aircraft/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class All { class Turrets; @@ -11,7 +10,6 @@ class CfgVehicles { }; class Air: AllVehicles {}; - class Helicopter: Air { class Turrets { class MainTurret; @@ -19,13 +17,11 @@ class CfgVehicles { }; class Plane: Air {}; - class ParachuteBase: Helicopter { class Turrets; }; class UAV: Plane {}; - class Helicopter_Base_F: Helicopter { class Turrets: Turrets { class CopilotTurret; @@ -37,53 +33,27 @@ class CfgVehicles { class Turrets: Turrets { class CopilotTurret; }; - //class UserActions; }; class Heli_Light_01_base_F: Helicopter_Base_H { - lockDetectionSystem = 0; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; + incomingMissileDetectionSystem = 16; // Vanilla: 0 class Turrets: Turrets { class CopilotTurret: CopilotTurret { - canEject = 1; showHMD = 1; }; }; }; - class Heli_Light_01_unarmed_base_F: Heli_Light_01_base_F {}; - - class B_Heli_Light_01_F: Heli_Light_01_unarmed_base_F { - /*class Turrets: Turrets { - class CopilotTurret: CopilotTurret {}; - };*/ - }; - class Heli_Light_01_armed_base_F: Heli_Light_01_base_F { - lockDetectionSystem = 0; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; - - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - }; + incomingMissileDetectionSystem = 16; // Vanilla: 0 }; - - class B_Heli_Light_01_armed_F: Heli_Light_01_armed_base_F {}; - class Heli_Light_02_base_F: Helicopter_Base_H { - driverCanEject = 1; - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - magazines[] = {"2000Rnd_762x51_Belt_T_Green","12Rnd_PG_missiles","168Rnd_CMFlare_Chaff_Magazine"}; + 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; }; }; @@ -97,248 +67,81 @@ class CfgVehicles { #include "Heli_Attack_01_base_F.hpp" - class B_Heli_Attack_01_F: Heli_Attack_01_base_F {}; - class Heli_Attack_02_base_F: Helicopter_Base_F { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; - - class Turrets: Turrets { - class MainTurret: MainTurret { - canEject = 1; - }; - }; + incomingMissileDetectionSystem = 16; // Vanilla: 24 }; class Heli_Transport_01_base_F: Helicopter_Base_H { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; + incomingMissileDetectionSystem = 16; // Vanilla: 24 class Turrets: Turrets { class CopilotTurret: CopilotTurret { - canEject = 1; showHMD = 1; }; + class MainTurret: MainTurret { - magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; - canEject = 1; + magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; // Switch gun magazine to 7.62mm from 6.5mm }; + class RightDoorGun: MainTurret { - magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; - canEject = 1; + magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; // Switch gun magazine to 7.62mm from 6.5mm }; }; - - /*class UserActions { - class DoorL1_Open { - available = 1; - condition = "((this doorPhase 'door_L') == 0) AND Alive(this) AND driver this != player AND gunner this != player"; - }; - class DoorR1_Open: DoorL1_Open { - condition = "((this doorPhase 'door_R') == 0) AND Alive(this) AND driver this != player AND gunner this != player"; - }; - class DoorL1_Close: DoorL1_Open { - condition = "((this doorPhase 'door_L') > 0) AND Alive(this) AND driver this != player AND gunner this != player"; - }; - class DoorR1_Close: DoorL1_Close { - condition = "((this doorPhase 'door_R') > 0) AND Alive(this) AND driver this != player AND gunner this != player"; - }; - };*/ }; class Heli_Transport_02_base_F: Helicopter_Base_H { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; + incomingMissileDetectionSystem = 16; // Vanilla: 24 class Turrets: Turrets { class CopilotTurret: CopilotTurret { - canEject = 1; showHMD = 1; }; }; - - /*class UserActions: UserActions { - class DoorL1_Open { - available = 1; - condition = "this animationPhase ""door_back_L"" < 0.5 AND Alive(this)"; - }; - class DoorR1_Open: DoorL1_Open { - condition = "this animationPhase ""door_back_R"" < 0.5 AND Alive(this)"; - }; - class DoorL1_Close: DoorL1_Open { - condition = "this animationPhase ""door_back_L"" > 0.5 AND Alive(this)"; - }; - class DoorR1_Close: DoorL1_Close { - condition = "this animationPhase ""door_back_R"" > 0.5 AND Alive(this)"; - }; - class CargoRamp_Open: DoorL1_Open { - userActionID = 52; - displayName = CSTRING(OpenCargoRamp); - textToolTip = CSTRING(OpenCargoRamp); - position = "action_cargoramp"; - radius = 3.0; - condition = "this animationPhase ""cargoramp_open"" < 0.5 AND Alive(this)"; - statement = "this animateDoor ['cargoramp_open', 1]"; - }; - class CargoRamp_Close: DoorL1_Close { - userActionID = 55; - displayName = CSTRING(CloseCargoRamp); - textToolTip = CSTRING(CloseCargoRamp); - position = "action_cargoramp"; - radius = 3.0; - condition = "this animationPhase ""cargoramp_open"" > 0.5 AND Alive(this)"; - statement = "this animateDoor ['cargoramp_open', 0]"; - }; - };*/ }; - class Heli_light_03_base_F: Helicopter_Base_F {}; - class I_Heli_light_03_base_F: Heli_light_03_base_F { - lockDetectionSystem = 0; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; - weapons[] = {"M134_minigun","missiles_DAR","CMFlareLauncher", "ACE_AIR_SAFETY" }; - magazines[] = {"5000Rnd_762x51_Yellow_Belt","24Rnd_missiles","168Rnd_CMFlare_Chaff_Magazine"}; + class Heli_light_03_base_F: Helicopter_Base_F { + lockDetectionSystem = 0; // Vanilla: 12 + incomingMissileDetectionSystem = 16; // Vanilla: 24 class Turrets: Turrets { class MainTurret: MainTurret { - canEject = 1; showHMD = 1; - gunBeg = "commanderview"; - gunEnd = "laserstart"; - memoryPointGun = "laserstart"; - stabilizedInAxes = 3; - weapons[] = {"Laserdesignator_mounted"}; - soundServo[] = {"",0.01,1,30}; + weapons[] = {"Laserdesignator_mounted"}; // Add Laser Designator magazines[] = {"Laserbatteries"}; - inGunnerMayFire = 1; }; }; }; - class I_Heli_light_03_F: Heli_light_03_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret {}; - }; - }; - - class Heli_light_03_unarmed_base_F: Heli_light_03_base_F {}; - - class I_Heli_light_03_unarmed_F: Heli_light_03_unarmed_base_F {}; class Plane_CAS_01_base_F: Plane_Base_F { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - - class Turrets; - - #include + lockDetectionSystem = 12; // Vanilla: 8 + incomingMissileDetectionSystem = 16; // Vanilla: 24 }; class Plane_CAS_02_base_F: Plane_Base_F { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - - class Turrets; - - #include + lockDetectionSystem = 12; // Vanilla: 8 + incomingMissileDetectionSystem = 16; // Vanilla: 24 }; class Plane_Fighter_03_base_F: Plane_Base_F { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - - class Turrets; - - #include - }; - - class UAV_01_base_F: Helicopter_Base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ + lockDetectionSystem = 12; // Vanilla: 8 + incomingMissileDetectionSystem = 16; // Vanilla: 24 }; class UAV_02_base_F: UAV { - weapons[] = {}; + weapons[] = {}; // Remove flare launcher magazines[] = {}; - - class Turrets { - class MainTurret; - }; }; class UAV_02_CAS_base_F: UAV_02_base_F { - weapons[] = {}; + weapons[] = {}; // Remove flare launcher magazines[] = {}; - - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ }; - class Heli_Transport_03_base_F: Helicopter_Base_H {}; - class B_Heli_Transport_03_base_F: Heli_Transport_03_base_F { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; - - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - //class MainTurret: MainTurret {}; - class RightDoorGun: MainTurret {}; - }; + class Heli_Transport_03_base_F: Helicopter_Base_H { + incomingMissileDetectionSystem = 16; // Vanilla: 24 }; - - class B_Heli_Transport_03_unarmed_base_F: Heli_Transport_03_base_F { - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - //class MainTurret: MainTurret {}; - //class RightDoorGun: MainTurret {}; - }; - }; - class Heli_Transport_04_base_F: Helicopter_Base_H { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; - - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - class LoadmasterTurret: MainTurret { - canEject = 1; - }; - }; - }; - - class O_Heli_Transport_04_bench_F: Heli_Transport_04_base_F { - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - class LoadmasterTurret: LoadmasterTurret { - canEject = 1; - }; - }; - }; - - class O_Heli_Transport_04_covered_F: Heli_Transport_04_base_F { - class Turrets: Turrets { - class CopilotTurret: CopilotTurret { - canEject = 1; - }; - class LoadmasterTurret: LoadmasterTurret { - canEject = 1; - }; - }; + incomingMissileDetectionSystem = 16; // Vanilla: 24 }; }; diff --git a/addons/aircraft/CfgWeapons.hpp b/addons/aircraft/CfgWeapons.hpp index e97889eabf..5543925b5b 100644 --- a/addons/aircraft/CfgWeapons.hpp +++ b/addons/aircraft/CfgWeapons.hpp @@ -1,13 +1,8 @@ - -class Mode_SemiAuto; -class Mode_Burst; class Mode_FullAuto; class CfgWeapons { - class RocketPods; - class ACE_AIR_SAFETY : RocketPods - { + class ACE_AIR_SAFETY : RocketPods { CanLock = 0; displayName = "SAFE"; displayNameMagazine = "SAFE"; @@ -21,18 +16,6 @@ class CfgWeapons { magazineReloadTime = 0.1; }; - // Manual Switching Of Flare Mode - class SmokeLauncher; - class CMFlareLauncher: SmokeLauncher { - modes[] = {"Single","Burst","AIBurst"}; - class Single: Mode_SemiAuto { - reloadTime = 0.1; - }; - class Burst: Mode_Burst { - displayName = CSTRING(CMFlareLauncher_Burst_Name); - }; - }; - // bigger mag for comanche class CannonCore; class gatling_20mm: CannonCore { @@ -43,6 +26,7 @@ class CfgWeapons { reloadTime = 0.023; //0.04; dispersion = 0.006; //0.0022; }; + class close: manual {}; class short: close {}; class medium: close {}; @@ -57,18 +41,22 @@ class CfgWeapons { dispersion = 0.006; displayName = CSTRING(gatling_20mm_Name); }; + class close: close { reloadTime = 0.04; dispersion = 0.006; }; + class short: short { reloadTime = 0.04; dispersion = 0.006; }; + class medium: medium { reloadTime = 0.04; dispersion = 0.006; }; + class far: far { reloadTime = 0.04; dispersion = 0.006; @@ -78,14 +66,13 @@ class CfgWeapons { // buff gatling rof class MGunCore; class MGun: MGunCore {}; - class LMG_RCWS: MGun {}; - class LMG_Minigun: LMG_RCWS { class manual: MGun { reloadTime = 0.075; //0.015; dispersion = 0.00093; //0.006; }; + class close: manual {}; class short: close {}; class medium: close {}; @@ -94,10 +81,12 @@ class CfgWeapons { class LMG_Minigun_heli: LMG_Minigun { showAimCursorInternal = 0; + class manual: manual { reloadTime = 0.015; //0.033; Note: This is a way to fast ROF (requires over 60 FPS) @todo dispersion = 0.006; //0.0087; }; + class close: manual {}; class short: close {}; class medium: close {}; @@ -110,30 +99,11 @@ class CfgWeapons { dispersion = 0.0064; //0.0023; multiplier = 1; }; + class HighROF: LowROF { reloadTime = 0.02; //0.03; dispersion = 0.0064; //0.0023; multiplier = 1; }; - class close: HighROF {}; - class short: close {}; - class medium: LowROF {}; - class far: medium {}; - }; - - class Gatling_30mm_Plane_CAS_01_F: CannonCore { - autoFire = 1; - burst = 1; - class LowROF: Mode_FullAuto { - autoFire = 0; - burst = 22; //65; - reloadTime = 0.0462; //0.0154; //0.034; - multiplier = 3; - }; - class close: LowROF {}; - class near: close {}; - class short: close {}; - class medium: close {}; - class far: close {}; }; }; diff --git a/addons/aircraft/Heli_Attack_01_base_F.hpp b/addons/aircraft/Heli_Attack_01_base_F.hpp index f56cda1fd8..7e59abad48 100644 --- a/addons/aircraft/Heli_Attack_01_base_F.hpp +++ b/addons/aircraft/Heli_Attack_01_base_F.hpp @@ -1,896 +1,14 @@ class Heli_Attack_01_base_F: Helicopter_Base_F { - lockDetectionSystem = 12; - incomingMissileDetectionSystem = 16; - driverCanEject = 1; - - class MFD - { - class AirplaneHUD - { - class Bones{}; - class Draw{}; - topLeft = "HUD_top_left"; - topRight = "HUD_top_right"; - bottomLeft = "HUD_bottom_left"; - borderLeft = 0; - borderRight = 0; - borderTop = 0; - borderBottom = 0; - color[] = {0.15,1,0.15,1}; - enableParallax = 0; - helmetMountedDisplay = 1; - helmetPosition[] = {0,0,0}; - helmetRight[] = {0,0,0}; - helmetDown[] = {0,0,0}; - }; - class ACE_HUD_1 - { - topLeft = "HUD_top_left"; - topRight = "HUD_top_right"; - bottomLeft = "HUD_bottom_left"; - borderLeft = 0; - borderRight = 0; - borderTop = 0; - borderBottom = 0; - color[] = {0.15,1,0.15,1}; - enableParallax = 0; - class Bones - { - class GunnerAim - { - type = "vector"; - source = "weapon"; - pos0[] = {0.5,"0.9 - 0.04 + 0.012"}; - pos10[] = {"0.5 + 0.0111","0.9 - 0.04 + 0.012 + 0.0133"}; - }; - class Target - { - source = "target"; - type = "vector"; - pos0[] = {0.5,0.5}; - pos10[] = {0.85,0.85}; - }; - class Velocity - { - type = "vector"; - source = "velocity"; - pos0[] = {0.5,0.5}; - pos10[] = {0.65,0.65}; - }; - class Velocity_slip - { - type = "vector"; - source = "velocity"; - pos0[] = {0.5,0.845}; - pos10[] = {0.53,0.845}; - }; - class VspeedBone - { - type = "linear"; - source = "vspeed"; - sourceScale = 1; - min = -10; - max = 10; - minPos[] = {0.93,0.2}; - maxPos[] = {0.93,0.8}; - }; - class RadarAltitudeBone - { - type = "linear"; - source = "altitudeAGL"; - sourceScale = 1; - min = 0; - max = 60; - minPos[] = {0.965,0.2}; - maxPos[] = {0.965,0.8}; - }; - class HorizonBankRot - { - type = "rotational"; - source = "horizonBank"; - center[] = {0.5,0.5}; - min = -3.1416; - max = 3.1416; - minAngle = -180; - maxAngle = 180; - aspectRatio = 1; - }; - class ForwardVec - { - type = "vector"; - source = "forward"; - pos0[] = {0,0}; - pos10[] = {0.25,0.25}; - }; - class WeaponAim - { - type = "vector"; - source = "weapon"; - pos0[] = {0.5,0.5}; - pos10[] = {0.75,0.75}; - }; - class Level0 - { - type = "horizon"; - pos0[] = {0.5,0.5}; - pos10[] = {0.78,0.78}; - angle = 0; - }; - class LevelP5: Level0 - { - angle = 5; - }; - class LevelM5: Level0 - { - angle = -5; - }; - class LevelP10: Level0 - { - angle = 10; - }; - class LevelM10: Level0 - { - angle = -10; - }; - class LevelP15: Level0 - { - angle = 15; - }; - class LevelM15: Level0 - { - angle = -15; - }; - class LevelP20: Level0 - { - angle = 20; - }; - class LevelM20: Level0 - { - angle = -20; - }; - class LevelP25: Level0 - { - angle = 25; - }; - class LevelM25: Level0 - { - angle = -25; - }; - class LevelP30: Level0 - { - angle = 30; - }; - class LevelM30: Level0 - { - angle = -30; - }; - class LevelP35: Level0 - { - angle = 35; - }; - class LevelM35: Level0 - { - angle = -35; - }; - class LevelP40: Level0 - { - angle = 40; - }; - class LevelM40: Level0 - { - angle = -40; - }; - class LevelP45: Level0 - { - angle = 45; - }; - class LevelM45: Level0 - { - angle = -45; - }; - class LevelP50: Level0 - { - angle = 50; - }; - class LevelM50: Level0 - { - angle = -50; - }; - }; - class Draw - { - color[] = {0.18,1,0.18}; - alpha = 1; - condition = "on"; - class Horizont - { - clipTL[] = {0.15,0.15}; - clipBR[] = {0.85,0.85}; - class Dimmed - { - class Level0 - { - type = "line"; - points[] = {{ "Level0",{ -0.42,0 },1 },{ "Level0",{ -0.38,0 },1 },{ },{ "Level0",{ -0.37,0 },1 },{ "Level0",{ -0.33,0 },1 },{ },{ "Level0",{ -0.32,0 },1 },{ "Level0",{ -0.28,0 },1 },{ },{ "Level0",{ -0.27,0 },1 },{ "Level0",{ -0.23,0 },1 },{ },{ "Level0",{ -0.22,0 },1 },{ "Level0",{ -0.18,0 },1 },{ },{ "Level0",{ -0.17,0 },1 },{ "Level0",{ -0.13,0 },1 },{ },{ "Level0",{ -0.12,0 },1 },{ "Level0",{ -0.08,0 },1 },{ },{ "Level0",{ 0.42,0 },1 },{ "Level0",{ 0.38,0 },1 },{ },{ "Level0",{ 0.37,0 },1 },{ "Level0",{ 0.33,0 },1 },{ },{ "Level0",{ 0.32,0 },1 },{ "Level0",{ 0.28,0 },1 },{ },{ "Level0",{ 0.27,0 },1 },{ "Level0",{ 0.23,0 },1 },{ },{ "Level0",{ 0.22,0 },1 },{ "Level0",{ 0.18,0 },1 },{ },{ "Level0",{ 0.17,0 },1 },{ "Level0",{ 0.13,0 },1 },{ },{ "Level0",{ 0.12,0 },1 },{ "Level0",{ 0.08,0 },1 }}; - }; - }; - }; - class HorizonBankRot - { - type = "line"; - width = 3; - points[] = {{ "HorizonBankRot",{ 0,0.25 },1 },{ "HorizonBankRot",{ -0.01,0.23 },1 },{ "HorizonBankRot",{ 0.01,0.23 },1 },{ "HorizonBankRot",{ 0,0.25 },1 }}; - }; - class Static_HAD_BOX - { - clipTL[] = {0,1}; - clipBR[] = {1,0}; - type = "line"; - width = 5; - points[] = {{ { "0.5-0.1","0.9-0.04" },1 },{ { "0.5-0.1","0.9+0.04" },1 },{ { "0.5+0.1","0.9+0.04" },1 },{ { "0.5+0.1","0.9-0.04" },1 },{ { "0.5-0.1","0.9-0.04" },1 },{ },{ { "0.5-0.1","0.9-0.04+0.012" },1 },{ { "0.5-0.092","0.9-0.04+0.012" },1 },{ },{ { "0.5+0.1","0.9-0.04+0.012" },1 },{ { "0.5+0.092","0.9-0.04+0.012" },1 },{ },{ { 0.5,"0.9-0.04" },1 },{ { 0.5,"0.9-0.032" },1 },{ },{ { 0.5,"0.9+0.04" },1 },{ { 0.5,"0.9+0.032" },1 },{ }}; - }; - class Gunner_HAD - { - type = "line"; - width = 6; - points[] = {{ "GunnerAim",{ -0.015,-0.008 },1 },{ "GunnerAim",{ -0.015,0.008 },1 },{ "GunnerAim",{ 0.015,0.008 },1 },{ "GunnerAim",{ 0.015,-0.008 },1 },{ "GunnerAim",{ -0.015,-0.008 },1 }}; - }; - class Slip_ball_group - { - class Slip_bars - { - type = "line"; - width = 4; - points[] = {{ { "0.5-0.018","0.9-0.04" },1 },{ { "0.5-0.018","0.9-0.075" },1 },{ },{ { "0.5+0.018","0.9-0.04" },1 },{ { "0.5+0.018","0.9-0.075" },1 }}; - }; - class Slip_ball - { - type = "line"; - width = 6; - points[] = {{ "Velocity_slip",1,{ "0 * 0.75","-0.02 * 0.75" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.75","-0.01732 * 0.75" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.75","-0.0099999998 * 0.75" },1 },{ "Velocity_slip",1,{ "0.02 * 0.75","0 * 0.75" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.75","0.0099999998 * 0.75" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.75","0.01732 * 0.75" },1 },{ "Velocity_slip",1,{ "0 * 0.75","0.02 * 0.75" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.75","0.01732 * 0.75" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.75","0.0099999998 * 0.75" },1 },{ "Velocity_slip",1,{ "-0.02 * 0.75","0 * 0.75" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.75","-0.0099999998 * 0.75" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.75","-0.01732 * 0.75" },1 },{ "Velocity_slip",1,{ "0 * 0.75","-0.02 * 0.75" },1 },{ },{ "Velocity_slip",1,{ "0 * 0.6","-0.02 * 0.6" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.6","-0.01732 * 0.6" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.6","-0.0099999998 * 0.6" },1 },{ "Velocity_slip",1,{ "0.02 * 0.6","0 * 0.6" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.6","0.0099999998 * 0.6" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.6","0.01732 * 0.6" },1 },{ "Velocity_slip",1,{ "0 * 0.6","0.02 * 0.6" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.6","0.01732 * 0.6" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.6","0.0099999998 * 0.6" },1 },{ "Velocity_slip",1,{ "-0.02 * 0.6","0 * 0.6" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.6","-0.0099999998 * 0.6" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.6","-0.01732 * 0.6" },1 },{ "Velocity_slip",1,{ "0 * 0.6","-0.02 * 0.6" },1 },{ },{ "Velocity_slip",1,{ "0 * 0.5","-0.02 * 0.5" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.5","-0.01732 * 0.5" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.5","-0.0099999998 * 0.5" },1 },{ "Velocity_slip",1,{ "0.02 * 0.5","0 * 0.5" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.5","0.0099999998 * 0.5" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.5","0.01732 * 0.5" },1 },{ "Velocity_slip",1,{ "0 * 0.5","0.02 * 0.5" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.5","0.01732 * 0.5" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.5","0.0099999998 * 0.5" },1 },{ "Velocity_slip",1,{ "-0.02 * 0.5","0 * 0.5" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.5","-0.0099999998 * 0.5" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.5","-0.01732 * 0.5" },1 },{ "Velocity_slip",1,{ "0 * 0.5","-0.02 * 0.5" },1 },{ },{ "Velocity_slip",1,{ "0 * 0.4","-0.02 * 0.4" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.4","-0.01732 * 0.4" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.4","-0.0099999998 * 0.4" },1 },{ "Velocity_slip",1,{ "0.02 * 0.4","0 * 0.4" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.4","0.0099999998 * 0.4" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.4","0.01732 * 0.4" },1 },{ "Velocity_slip",1,{ "0 * 0.4","0.02 * 0.4" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.4","0.01732 * 0.4" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.4","0.0099999998 * 0.4" },1 },{ "Velocity_slip",1,{ "-0.02 * 0.4","0 * 0.4" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.4","-0.0099999998 * 0.4" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.4","-0.01732 * 0.4" },1 },{ "Velocity_slip",1,{ "0 * 0.4","-0.02 * 0.4" },1 },{ },{ "Velocity_slip",1,{ "0 * 0.30","-0.02 * 0.30" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.30","-0.01732 * 0.30" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.30","-0.0099999998 * 0.30" },1 },{ "Velocity_slip",1,{ "0.02 * 0.30","0 * 0.30" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.30","0.0099999998 * 0.30" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.30","0.01732 * 0.30" },1 },{ "Velocity_slip",1,{ "0 * 0.30","0.02 * 0.30" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.30","0.01732 * 0.30" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.30","0.0099999998 * 0.30" },1 },{ "Velocity_slip",1,{ "-0.02 * 0.30","0 * 0.30" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.30","-0.0099999998 * 0.30" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.30","-0.01732 * 0.30" },1 },{ "Velocity_slip",1,{ "0 * 0.30","-0.02 * 0.30" },1 },{ },{ "Velocity_slip",1,{ "0 * 0.20","-0.02 * 0.20" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.20","-0.01732 * 0.20" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.20","-0.0099999998 * 0.20" },1 },{ "Velocity_slip",1,{ "0.02 * 0.20","0 * 0.20" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.20","0.0099999998 * 0.20" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.20","0.01732 * 0.20" },1 },{ "Velocity_slip",1,{ "0 * 0.20","0.02 * 0.20" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.20","0.01732 * 0.20" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.20","0.0099999998 * 0.20" },1 },{ "Velocity_slip",1,{ "-0.02 * 0.20","0 * 0.20" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.20","-0.0099999998 * 0.20" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.20","-0.01732 * 0.20" },1 },{ "Velocity_slip",1,{ "0 * 0.20","-0.02 * 0.20" },1 },{ },{ "Velocity_slip",1,{ "0 * 0.1","-0.02 * 0.1" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.1","-0.01732 * 0.1" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.1","-0.0099999998 * 0.1" },1 },{ "Velocity_slip",1,{ "0.02 * 0.1","0 * 0.1" },1 },{ "Velocity_slip",1,{ "0.01732 * 0.1","0.0099999998 * 0.1" },1 },{ "Velocity_slip",1,{ "0.0099999998 * 0.1","0.01732 * 0.1" },1 },{ "Velocity_slip",1,{ "0 * 0.1","0.02 * 0.1" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.1","0.01732 * 0.1" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.1","0.0099999998 * 0.1" },1 },{ "Velocity_slip",1,{ "-0.02 * 0.1","0 * 0.1" },1 },{ "Velocity_slip",1,{ "-0.01732 * 0.1","-0.0099999998 * 0.1" },1 },{ "Velocity_slip",1,{ "-0.0099999998 * 0.1","-0.01732 * 0.1" },1 },{ "Velocity_slip",1,{ "0 * 0.1","-0.02 * 0.1" },1 }}; - }; - }; - class Centerline - { - type = "line"; - width = 5; - points[] = {{ { 0.5,0.48 },1 },{ { 0.5,0.45 },1 },{ },{ { 0.5,0.52 },1 },{ { 0.5,0.55 },1 },{ },{ { 0.48,0.5 },1 },{ { 0.45,0.5 },1 },{ },{ { 0.52,0.5 },1 },{ { 0.55,0.5 },1 },{ }}; - }; - class WeaponName - { - type = "text"; - source = "weapon"; - sourceScale = 1; - align = "right"; - scale = 1; - pos[] = {{ 0.61,0.86 },1}; - right[] = {{ 0.65,0.86 },1}; - down[] = {{ 0.61,0.9 },1}; - }; - class Ammo_GUN - { - type = "group"; - condition = "mgun"; - class Ammo_count_GUN - { - type = "text"; - source = "ammo"; - sourceScale = 1; - align = "right"; - scale = 1; - pos[] = {{ 0.61,0.89 },1}; - right[] = {{ 0.65,0.89 },1}; - down[] = {{ 0.61,0.93 },1}; - }; - }; - class Ammo_RKT - { - type = "group"; - condition = "rocket"; - class Ammo_count_RKT - { - type = "text"; - source = "ammo"; - sourceScale = 1; - align = "right"; - scale = 1; - pos[] = {{ 0.61,0.89 },1}; - right[] = {{ 0.65,0.89 },1}; - down[] = {{ 0.61,0.93 },1}; - }; - }; - class Ammo_AGM - { - type = "group"; - condition = "AAmissile"; - class Ammo_count_AGM - { - type = "text"; - source = "ammo"; - sourceScale = 1; - align = "right"; - scale = 1; - pos[] = {{ 0.61,0.89 },1}; - right[] = {{ 0.65,0.89 },1}; - down[] = {{ 0.61,0.93 },1}; - }; - }; - class Ammo_AAM - { - type = "group"; - condition = "ATmissile"; - class Ammo_count_AAM - { - type = "text"; - source = "ammo"; - sourceScale = 1; - align = "right"; - scale = 1; - pos[] = {{ 0.61,0.89 },1}; - right[] = {{ 0.65,0.89 },1}; - down[] = {{ 0.61,0.93 },1}; - }; - }; - class Ammo_Bomb - { - type = "group"; - condition = "Bomb"; - class Ammo_count_Bomb - { - type = "text"; - source = "ammo"; - sourceScale = 1; - align = "right"; - scale = 1; - pos[] = {{ 0.61,0.89 },1}; - right[] = {{ 0.65,0.89 },1}; - down[] = {{ 0.61,0.93 },1}; - }; - }; - class LightsGroup - { - type = "group"; - condition = "lights"; - class LightsText - { - type = "text"; - source = "static"; - text = "LIGHTS"; - align = "right"; - scale = 1; - pos[] = {{ 0.03,"0.53 + 0.055" },1}; - right[] = {{ 0.07,"0.53 + 0.055" },1}; - down[] = {{ 0.03,"0.53 + 0.095" },1}; - }; - }; - class CollisionLightsGroup - { - type = "group"; - condition = "collisionlights"; - class CollisionLightsText - { - type = "text"; - source = "static"; - text = "A-COL"; - align = "right"; - scale = 1; - pos[] = {{ 0.03,"0.53 + 0.105" },1}; - right[] = {{ 0.07,"0.53 + 0.105" },1}; - down[] = {{ 0.03,"0.53 + 0.145" },1}; - }; - }; - class GearGroup - { - type = "group"; - condition = "ils"; - class GearText - { - type = "text"; - source = "static"; - text = "GEAR"; - align = "right"; - scale = 1; - pos[] = {{ 0.03,"0.53 + 0.155" },1}; - right[] = {{ 0.07,"0.53 + 0.155" },1}; - down[] = {{ 0.03,"0.53 + 0.195" },1}; - }; - }; - class ATMissileTOFGroup - { - condition = "ATmissile"; - type = "group"; - class TOFtext - { - type = "text"; - align = "right"; - source = "static"; - text = "TOF="; - scale = 1; - pos[] = {{ 0.61,0.92 },1}; - right[] = {{ 0.65,0.92 },1}; - down[] = {{ 0.61,0.96 },1}; - }; - class TOFnumber - { - type = "text"; - source = "targetDist"; - sourcescale = 0.0025; - align = "right"; - scale = 1; - pos[] = {{ 0.69,0.92 },1}; - right[] = {{ 0.73,0.92 },1}; - down[] = {{ 0.69,0.96 },1}; - }; - }; - class LaserTOFGroup - { - condition = "Bomb"; - type = "group"; - class TOFtext - { - type = "text"; - align = "right"; - source = "static"; - text = "TOF="; - scale = 1; - pos[] = {{ 0.61,0.92 },1}; - right[] = {{ 0.65,0.92 },1}; - down[] = {{ 0.61,0.96 },1}; - }; - class TOFnumber - { - type = "text"; - source = "targetDist"; - sourcescale = 0.0025; - align = "right"; - scale = 1; - pos[] = {{ 0.69,0.92 },1}; - right[] = {{ 0.73,0.92 },1}; - down[] = {{ 0.69,0.96 },1}; - }; - }; - class RocketTOFGroup - { - condition = "Rocket"; - type = "group"; - class TOFtext - { - type = "text"; - align = "right"; - source = "static"; - text = "TOF="; - scale = 1; - pos[] = {{ 0.61,0.92 },1}; - right[] = {{ 0.65,0.92 },1}; - down[] = {{ 0.61,0.96 },1}; - }; - class TOFnumber - { - type = "text"; - source = "targetDist"; - sourcescale = 0.0025; - align = "right"; - scale = 1; - pos[] = {{ 0.69,0.92 },1}; - right[] = {{ 0.73,0.92 },1}; - down[] = {{ 0.69,0.96 },1}; - }; - }; - class RangeNumber - { - type = "text"; - source = "targetDist"; - sourceScale = 1; - align = "left"; - scale = 1; - pos[] = {{ 0.39,0.89 },1}; - right[] = {{ 0.43,0.89 },1}; - down[] = {{ 0.39,0.93 },1}; - }; - class RangeText - { - type = "text"; - source = "static"; - text = "RNG"; - align = "left"; - scale = 1; - pos[] = {{ 0.39,0.86 },1}; - right[] = {{ 0.43,0.86 },1}; - down[] = {{ 0.39,0.9 },1}; - }; - class SpeedNumber - { - type = "text"; - align = "right"; - scale = 1; - source = "speed"; - sourceScale = 3.6; - pos[] = {{ 0.03,0.475 },1}; - right[] = {{ 0.08,0.475 },1}; - down[] = {{ 0.03,0.525 },1}; - }; - class TorqueNumber - { - condition = "simulRTD"; - class Torque_number - { - type = "text"; - align = "left"; - scale = 1; - source = "rtdRotorTorque"; - sourceScale = 290; - pos[] = {{ 0.065,0.175 },1}; - right[] = {{ 0.115,0.175 },1}; - down[] = {{ 0.065,0.225 },1}; - }; - class Torquetext - { - type = "text"; - source = "static"; - text = "%"; - align = "right"; - scale = 1; - pos[] = {{ 0.07,0.175 },1}; - right[] = {{ 0.12,0.175 },1}; - down[] = {{ 0.07,0.225 },1}; - }; - }; - class AltNumber: SpeedNumber - { - align = "right"; - source = "altitudeAGL"; - sourceScale = 1; - pos[] = {{ 0.83,0.475 },1}; - right[] = {{ 0.88,0.475 },1}; - down[] = {{ 0.83,0.525 },1}; - }; - class ASLNumber - { - type = "text"; - source = "altitudeASL"; - sourceScale = 1; - align = "right"; - scale = 1; - pos[] = {{ 0.835,0.18 },1}; - right[] = {{ 0.875,0.18 },1}; - down[] = {{ 0.835,0.22 },1}; - }; - class VspeedScalePosta - { - type = "line"; - width = 5; - points[] = {{ { 0.98,0.2 },1 },{ { 1,0.2 },1 },{ },{ { 0.93,0.2 },1 },{ { 0.95,0.2 },1 },{ },{ { 0.98,0.35 },1 },{ { 1,0.35 },1 },{ },{ { 0.93,0.35 },1 },{ { 0.95,0.35 },1 },{ },{ { 0.94,0.38 },1 },{ { 0.95,0.38 },1 },{ },{ { 0.94,0.41 },1 },{ { 0.95,0.41 },1 },{ },{ { 0.94,0.44 },1 },{ { 0.95,0.44 },1 },{ },{ { 0.94,0.47 },1 },{ { 0.95,0.47 },1 },{ },{ { 0.98,0.5 },1 },{ { 1,0.5 },1 },{ },{ { 0.93,0.5 },1 },{ { 0.95,0.5 },1 },{ },{ { 0.94,0.53 },1 },{ { 0.95,0.53 },1 },{ },{ { 0.94,0.56 },1 },{ { 0.95,0.56 },1 },{ },{ { 0.94,0.59 },1 },{ { 0.95,0.59 },1 },{ },{ { 0.94,0.62 },1 },{ { 0.95,0.62 },1 },{ },{ { 0.98,0.65 },1 },{ { 1,0.65 },1 },{ },{ { 0.93,0.65 },1 },{ { 0.95,0.65 },1 },{ },{ { 0.99,0.68 },1 },{ { 0.98,0.68 },1 },{ },{ { 0.99,0.71 },1 },{ { 0.98,0.71 },1 },{ },{ { 0.99,0.74 },1 },{ { 0.98,0.74 },1 },{ },{ { 0.99,0.77 },1 },{ { 0.98,0.77 },1 },{ },{ { 0.98,0.8 },1 },{ { 1,0.8 },1 },{ },{ { 0.93,0.8 },1 },{ { 0.95,0.8 },1 },{ }}; - }; - class RadarAltitudeBand - { - clipTL[] = {0,0.2}; - clipBR[] = {1,0.8}; - hideValue = 201; - class radarbanda - { - type = "line"; - width = 17; - points[] = {{ "RadarAltitudeBone",{ 0,0 },1 },{ "RadarAltitudeBone",{ 0,0.6 },1 }}; - }; - }; - class VspeedBand - { - type = "line"; - width = 3; - points[] = {{ "VspeedBone",{ -0.01,0 },1 },{ "VspeedBone",{ -0.025,-0.015 },1 },{ "VspeedBone",{ -0.025,0.015 },1 },{ "VspeedBone",{ -0.01,0 },1 },{ }}; - }; - class HeadingNumber: SpeedNumber - { - source = "heading"; - sourceScale = 1; - align = "center"; - pos[] = {{ 0.5,0.045 },1}; - right[] = {{ 0.56,0.045 },1}; - down[] = {{ 0.5,"0.045 + 0.06" },1}; - }; - class Center_box - { - type = "line"; - width = 1.5; - points[] = {{ { 0.45,"0.02 + 0.085 - 0.06" },1 },{ { "0.45 + 0.10","0.02 + 0.085 - 0.06" },1 },{ { "0.45 + 0.10","0.02 + 0.085" },1 },{ { 0.45,"0.02 + 0.085" },1 },{ { 0.45,"0.02 + 0.085 - 0.06" },1 }}; - }; - class HeadingArrow - { - type = "line"; - width = 7; - points[] = {{ { "0.5","0.128 + 0.03" },1 },{ { 0.5,0.128 },1 }}; - }; - class HeadingScale_LEFT - { - clipTL[] = {0,0}; - clipBR[] = {0.45,1}; - class Heading_group - { - type = "scale"; - horizontal = 1; - source = "heading"; - sourceScale = 1; - width = 5; - top = 0.12; - center = 0.5; - bottom = 0.88; - lineXleft = "0.03 + 0.085"; - lineYright = "0.02 + 0.085"; - lineXleftMajor = "0.04 + 0.085"; - lineYrightMajor = "0.02 + 0.085"; - majorLineEach = 3; - numberEach = 3; - step = 10; - stepSize = "0.05"; - align = "center"; - scale = 1; - pos[] = {0.12,"0.0 + 0.065"}; - right[] = {0.16,"0.0 + 0.065"}; - down[] = {0.12,"0.04 + 0.065"}; - }; - }; - class HeadingScale_RIGHT - { - clipTL[] = {0.55,0}; - clipBR[] = {1,1}; - class Heading_group - { - type = "scale"; - horizontal = 1; - source = "heading"; - sourceScale = 1; - width = 5; - top = 0.12; - center = 0.5; - bottom = 0.88; - lineXleft = "0.03 + 0.085"; - lineYright = "0.02 + 0.085"; - lineXleftMajor = "0.04 + 0.085"; - lineYrightMajor = "0.02 + 0.085"; - majorLineEach = 3; - numberEach = 3; - step = 10; - stepSize = "0.05"; - align = "center"; - scale = 1; - pos[] = {0.12,"0.0 + 0.065"}; - right[] = {0.16,"0.0 + 0.065"}; - down[] = {0.12,"0.04 + 0.065"}; - }; - }; - class HeadingScale_BOTTOM - { - clipTL[] = {0.45,"0.02 + 0.085"}; - clipBR[] = {"0.45 + 0.10",1}; - class Heading_group - { - type = "scale"; - horizontal = 1; - source = "heading"; - sourceScale = 1; - width = 5; - top = 0.12; - center = 0.5; - bottom = 0.88; - lineXleft = "0.03 + 0.085"; - lineYright = "0.02 + 0.085"; - lineXleftMajor = "0.04 + 0.085"; - lineYrightMajor = "0.02 + 0.085"; - majorLineEach = 3; - numberEach = 3; - step = 10; - stepSize = "0.05"; - align = "center"; - scale = 1; - pos[] = {0.12,"0.0 + 0.065"}; - right[] = {0.16,"0.0 + 0.065"}; - down[] = {0.12,"0.04 + 0.065"}; - }; - }; - class Fuel_Text - { - type = "text"; - source = "static"; - text = "Fuel"; - align = "right"; - scale = 1; - pos[] = {{ 0.03,0.9 },1}; - right[] = {{ 0.07,0.9 },1}; - down[] = {{ 0.03,0.94 },1}; - }; - class Fuel_Number - { - type = "text"; - source = "fuel"; - sourceScale = 100; - align = "right"; - scale = 1; - pos[] = {{ 0.1,0.9 },1}; - right[] = {{ 0.14,0.9 },1}; - down[] = {{ 0.1,0.94 },1}; - }; - }; - helmetMountedDisplay = 1; - helmetPosition[] = {-0.04,0.04,0.1}; - helmetRight[] = {0.08,0,0}; - helmetDown[] = {0,-0.08,0}; - }; - class ACE_HUD_2 - { - topLeft = "HUD_top_left"; - topRight = "HUD_top_right"; - bottomLeft = "HUD_bottom_left"; - borderLeft = 0; - borderRight = 0; - borderTop = 0; - borderBottom = 0; - color[] = {0.15,1,0.15,1}; - enableParallax = 0; - class Bones - { - class Velocity - { - type = "vector"; - source = "velocity"; - pos0[] = {0.5,0.5}; - pos10[] = {0.75,0.75}; - }; - class ForwardVec1 - { - type = "vector"; - source = "forward"; - pos0[] = {0,0}; - pos10[] = {0.25,0.25}; - }; - class ForwardVec - { - type = "vector"; - source = "forward"; - pos0[] = {0,0}; - pos10[] = {0.253,0.253}; - }; - class WeaponAim - { - type = "vector"; - source = "weapon"; - pos0[] = {0.5,0.5}; - pos10[] = {0.753,0.753}; - }; - class WeaponAim1 - { - type = "vector"; - source = "weapon"; - pos0[] = {0,0}; - pos10[] = {0.253,0.23}; - }; - class Target - { - type = "vector"; - source = "target"; - pos0[] = {0.5,0.5}; - pos10[] = {0.753,0.753}; - }; - class RadarContact - { - type = "fixed"; - pos[] = {0,0}; - }; - }; - class Draw - { - color[] = {0.18,1,0.18}; - alpha = 1; - condition = "on"; - class PlaneMovementCrosshair - { - type = "line"; - width = 7; - points[] = {{ "ForwardVec1",1,"Velocity",1,{ 0,-0.02 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0.01,-0.01732 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0.01732,-0.01 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0.02,0 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0.01732,0.01 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0.01,0.01732 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0,0.02 },1 },{ "ForwardVec1",1,"Velocity",1,{ -0.01,0.01732 },1 },{ "ForwardVec1",1,"Velocity",1,{ -0.01732,0.01 },1 },{ "ForwardVec1",1,"Velocity",1,{ -0.02,0 },1 },{ "ForwardVec1",1,"Velocity",1,{ -0.01732,-0.01 },1 },{ "ForwardVec1",1,"Velocity",1,{ -0.01,-0.01732 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0,-0.02 },1 },{ },{ "ForwardVec1",1,"Velocity",1,{ 0.04,0 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0.02,0 },1 },{ },{ "ForwardVec1",1,"Velocity",1,{ -0.04,0 },1 },{ "ForwardVec1",1,"Velocity",1,{ -0.02,0 },1 },{ },{ "ForwardVec1",1,"Velocity",1,{ 0,-0.04 },1 },{ "ForwardVec1",1,"Velocity",1,{ 0,-0.02 },1 }}; - }; - class Gunner_AIM - { - type = "group"; - class Circle - { - type = "line"; - width = 6; - points[] = {{ "ForwardVec",1,"WeaponAim",1,{ 0,-0.015 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0,-0.03 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0,-0.0325 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0,-0.0475 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0,0.015 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0,0.03 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0,0.0325 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0,0.0475 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ -0.015,0 },1 },{ "ForwardVec",1,"WeaponAim",1,{ -0.03,0 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ -0.0325,0 },1 },{ "ForwardVec",1,"WeaponAim",1,{ -0.0475,0 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0.015,0 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0.03,0 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0.0325,0 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0.0475,0 },1 }}; - }; - }; - class GunCross - { - condition = "mgun"; - class Circle - { - type = "line"; - width = 9; - points[] = {{ "ForwardVec",1,"WeaponAim",1,{ 0,-0.05 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0,-0.015 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0,0.015 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0,0.05 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ -0.05,0 },1 },{ "ForwardVec",1,"WeaponAim",1,{ -0.015,0 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0.015,0 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0.05,0 },1 },{ }}; - }; - }; - class RocketCross - { - condition = "rocket"; - width = 6; - class Circle - { - type = "line"; - width = 6; - points[] = {{ "ForwardVec",1,"WeaponAim",1,{ -0.05,-0.08 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0.05,-0.08 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ 0,-0.08 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0,0.08 },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ -0.05,0.08 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0.05,0.08 },1 },{ }}; - }; - }; - class AT_Aim - { - condition = "ATmissile"; - width = 2; - class Circle - { - type = "line"; - width = 2; - points[] = {{ "ForwardVec",1,"WeaponAim",1,{ -0.1,-0.1 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0.1,-0.1 },1 },{ "ForwardVec",1,"WeaponAim",1,{ 0.1,0.1 },1 },{ "ForwardVec",1,"WeaponAim",1,{ -0.1,0.1 },1 },{ "ForwardVec",1,"WeaponAim",1,{ -0.1,-0.1 },1 }}; - }; - }; - class AA_aim - { - condition = "AAmissile"; - class Circle - { - type = "line"; - width = 2.5; - points[] = {{ "ForwardVec",1,"WeaponAim",1,{ "0 / 4","-0.248559 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0434 / 4","-0.244781 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0855 / 4","-0.233571 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.125 / 4","-0.215252 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1607 / 4","-0.190396 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1915 / 4","-0.159774 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2165 / 4","-0.12428 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.234925 / 4","-0.0850072 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2462 / 4","-0.0431499 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.25 / 4","0 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2462 / 4","0.0431499 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.234925 / 4","0.0850072 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2165 / 4","0.12428 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1915 / 4","0.159774 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1607 / 4","0.190396 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.125 / 4","0.215252 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0855 / 4","0.233571 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0434 / 4","0.244781 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0 / 4","0.248559 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0434 / 4","0.244781 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0855 / 4","0.233571 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.125 / 4","0.215252 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1607 / 4","0.190396 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1915 / 4","0.159774 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2165 / 4","0.12428 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.234925 / 4","0.0850072 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2462 / 4","0.0431499 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.25 / 4","0 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2462 / 4","-0.0431499 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.234925 / 4","-0.0850072 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2165 / 4","-0.12428 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1915 / 4","-0.159774 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1607 / 4","-0.190396 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.125 / 4","-0.215252 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0855 / 4","-0.233571 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0434 / 4","-0.244781 / 4" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0 / 4","-0.248559 / 4" },1 },{ },{ "ForwardVec",1,"WeaponAim",1,{ "0 / 2","-0.248559 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0434 / 2","-0.244781 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0855 / 2","-0.233571 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.125 / 2","-0.215252 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1607 / 2","-0.190396 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1915 / 2","-0.159774 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2165 / 2","-0.12428 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.234925 / 2","-0.0850072 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2462 / 2","-0.0431499 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.25 / 2","0 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2462 / 2","0.0431499 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.234925 / 2","0.0850072 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.2165 / 2","0.12428 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1915 / 2","0.159774 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.1607 / 2","0.190396 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.125 / 2","0.215252 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0855 / 2","0.233571 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0.0434 / 2","0.244781 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0 / 2","0.248559 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0434 / 2","0.244781 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0855 / 2","0.233571 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.125 / 2","0.215252 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1607 / 2","0.190396 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1915 / 2","0.159774 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2165 / 2","0.12428 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.234925 / 2","0.0850072 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2462 / 2","0.0431499 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.25 / 2","0 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2462 / 2","-0.0431499 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.234925 / 2","-0.0850072 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.2165 / 2","-0.12428 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1915 / 2","-0.159774 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.1607 / 2","-0.190396 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.125 / 2","-0.215252 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0855 / 2","-0.233571 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "-0.0434 / 2","-0.244781 / 2" },1 },{ "ForwardVec",1,"WeaponAim",1,{ "0 / 2","-0.248559 / 2" },1 }}; - }; - }; - class TargetACQ - { - type = "line"; - width = 2; - points[] = {{ "ForwardVec",1,"target",{ 0,-0.06 },1 },{ "ForwardVec",1,"target",{ 0,-0.055 },1 },{ },{ "ForwardVec",1,"target",{ 0,-0.05 },1 },{ "ForwardVec",1,"target",{ 0,-0.045 },1 },{ },{ "ForwardVec",1,"target",{ 0,-0.04 },1 },{ "ForwardVec",1,"target",{ 0,-0.035 },1 },{ },{ "ForwardVec",1,"target",{ 0,-0.03 },1 },{ "ForwardVec",1,"target",{ 0,-0.025 },1 },{ },{ "ForwardVec",1,"target",{ 0,-0.02 },1 },{ "ForwardVec",1,"target",{ 0,-0.015 },1 },{ },{ "ForwardVec",1,"target",{ 0,-0.01 },1 },{ "ForwardVec",1,"target",{ 0,-0.005 },1 },{ },{ "ForwardVec",1,"target",{ 0,0 },1 },{ "ForwardVec",1,"target",{ 0,0 },1 },{ },{ "ForwardVec",1,"target",{ 0,0.06 },1 },{ "ForwardVec",1,"target",{ 0,0.055 },1 },{ },{ "ForwardVec",1,"target",{ 0,0.05 },1 },{ "ForwardVec",1,"target",{ 0,0.045 },1 },{ },{ "ForwardVec",1,"target",{ 0,0.04 },1 },{ "ForwardVec",1,"target",{ 0,0.035 },1 },{ },{ "ForwardVec",1,"target",{ 0,0.03 },1 },{ "ForwardVec",1,"target",{ 0,0.025 },1 },{ },{ "ForwardVec",1,"target",{ 0,0.02 },1 },{ "ForwardVec",1,"target",{ 0,0.015 },1 },{ },{ "ForwardVec",1,"target",{ 0,0.01 },1 },{ "ForwardVec",1,"target",{ 0,0.005 },1 },{ },{ "ForwardVec",1,"target",{ -0.06,0 },1 },{ "ForwardVec",1,"target",{ -0.055,0 },1 },{ },{ "ForwardVec",1,"target",{ -0.05,0 },1 },{ "ForwardVec",1,"target",{ -0.045,0 },1 },{ },{ "ForwardVec",1,"target",{ -0.04,0 },1 },{ "ForwardVec",1,"target",{ -0.035,0 },1 },{ },{ "ForwardVec",1,"target",{ -0.03,0 },1 },{ "ForwardVec",1,"target",{ -0.025,0 },1 },{ },{ "ForwardVec",1,"target",{ -0.02,0 },1 },{ "ForwardVec",1,"target",{ -0.015,0 },1 },{ },{ "ForwardVec",1,"target",{ -0.01,0 },1 },{ "ForwardVec",1,"target",{ -0.005,0 },1 },{ },{ "ForwardVec",1,"target",{ 0.06,0 },1 },{ "ForwardVec",1,"target",{ 0.055,0 },1 },{ },{ "ForwardVec",1,"target",{ 0.05,0 },1 },{ "ForwardVec",1,"target",{ 0.045,0 },1 },{ },{ "ForwardVec",1,"target",{ 0.04,0 },1 },{ "ForwardVec",1,"target",{ 0.035,0 },1 },{ },{ "ForwardVec",1,"target",{ 0.03,0 },1 },{ "ForwardVec",1,"target",{ 0.025,0 },1 },{ },{ "ForwardVec",1,"target",{ 0.02,0 },1 },{ "ForwardVec",1,"target",{ 0.015,0 },1 },{ },{ "ForwardVec",1,"target",{ 0.01,0 },1 },{ "ForwardVec",1,"target",{ 0.005,0 },1 },{ }}; - }; - class RadarTargets - { - type = "radar"; - pos0[] = {0.5,0.5}; - pos10[] = {0.753,0.753}; - width = 2.5; - points[] = {{ "ForwardVec",1,"RadarContact",{ -0.01,-0.01 },1 },{ "ForwardVec",1,"RadarContact",{ 0.01,-0.01 },1 },{ "ForwardVec",1,"RadarContact",{ 0.01,0.01 },1 },{ "ForwardVec",1,"RadarContact",{ -0.01,0.01 },1 },{ "ForwardVec",1,"RadarContact",{ -0.01,-0.01 },1 }}; - }; - }; - helmetMountedDisplay = 1; - helmetPosition[] = {-0.035,0.035,0.1}; - helmetRight[] = {0.07,0,0}; - helmetDown[] = {0,-0.07,0}; - }; - }; + incomingMissileDetectionSystem = 16; // Vanilla: 24 class Turrets: Turrets { class MainTurret: MainTurret { - weapons[] = {"ACE_gatling_20mm_Comanche","missiles_DAGR","missiles_ASRAAM", "ACE_AIR_SAFETY"}; - magazines[] = {"ACE_500Rnd_20mm_shells_Comanche","4Rnd_AAA_missiles","24Rnd_PG_missiles"}; - - outGunnerMayFire = 1; - commanding = -1; - primaryGunner = 1; - gunnerOpticsModel = ""; - gunnerOpticsEffect[] = {"TankCommanderOptics1"}; - gunnerForceOptics = 0; + weapons[] = {"ACE_gatling_20mm_Comanche", "missiles_DAGR", "missiles_ASRAAM"}; + magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "4Rnd_AAA_missiles", "24Rnd_PG_missiles"}; turretInfoType = "Rsc_ACE_Helo_UI_Turret"; - showAllTargets = 2; - discretedistance[] = {100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,3000}; - discretedistanceinitindex = 3; - copilotHasFlares = 1; - directionStabilized = 1; - isCopilot = 1; - showHMD = 1; - CanEject = 1; - startEngine = 0; - minElev = -51; - maxElev = 9; - initElev = 6; - minTurn = -120; - maxTurn = 120; - initTurn = 0; - class OpticsIn - { + + class OpticsIn { delete Narrow; delete Medium; delete Wide; @@ -906,13 +24,14 @@ class Heli_Attack_01_base_F: Helicopter_Base_F { initFov = 0.466; minFov = 0.466; maxFov = 0.466; - visionMode[] = {"Normal","Ti"}; - thermalMode[] = {0,1}; - gunnerOpticsColor[] = {0,0,0,1}; + visionMode[] = {"Normal", "Ti"}; + thermalMode[] = {0, 1}; + gunnerOpticsColor[] = {0, 0, 0, 1}; directionStabilized = 0; horizontallyStabilized = 1; gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_wide_F"; }; + class ACE_Wide: ACE_WideUnstabilized { opticsDisplayName = "W"; initAngleX = 0; @@ -924,50 +43,50 @@ class Heli_Attack_01_base_F: Helicopter_Base_F { initFov = 0.466; minFov = 0.466; maxFov = 0.466; - visionMode[] = {"Normal","Ti"}; - thermalMode[] = {0,1}; - gunnerOpticsColor[] = {0,0,0,1}; + visionMode[] = {"Normal", "Ti"}; + thermalMode[] = {0, 1}; + gunnerOpticsColor[] = {0, 0, 0, 1}; directionStabilized = 1; horizontallyStabilized = 1; gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_wide_F"; }; + class ACE_Medium: ACE_Wide { opticsDisplayName = "M"; initFov = 0.093; minFov = 0.093; maxFov = 0.093; - gunnerOpticsColor[] = {0,0,0,1}; + gunnerOpticsColor[] = {0, 0, 0, 1}; directionStabilized = 1; horizontallyStabilized = 1; gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_medium_F"; }; + class ACE_Narrow: ACE_Wide { opticsDisplayName = "N"; initFov = 0.029; minFov = 0.029; maxFov = 0.029; - gunnerOpticsColor[] = {0,0,0,1}; + gunnerOpticsColor[] = {0, 0, 0, 1}; directionStabilized = 1; horizontallyStabilized = 1; gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_narrow_F"; - }; + class ACE_Narrower: ACE_Wide { opticsDisplayName = "Z"; initFov = 0.01; minFov = 0.01; maxFov = 0.01; - gunnerOpticsColor[] = {0,0,0,1}; + gunnerOpticsColor[] = {0, 0, 0, 1}; directionStabilized = 1; horizontallyStabilized = 1; gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_narrow_F"; - }; }; - class OpticsOut - { - class Monocular - { + + class OpticsOut { + class Monocular { initAngleX = 0; minAngleX = -30; maxAngleX = 30; @@ -990,8 +109,19 @@ class Heli_Attack_01_base_F: Helicopter_Base_F { class Gatling { weapon = "ACE_gatling_20mm_Comanche"; }; + class Muzzle_flash { weapon = "ACE_gatling_20mm_Comanche"; }; }; }; + +class Heli_Attack_01_dynamicLoadout_base_F: Heli_Attack_01_base_F { + class Turrets: Turrets { + class MainTurret: MainTurret { + weapons[] = {"ACE_gatling_20mm_Comanche"}; + magazines[] = {"ACE_500Rnd_20mm_shells_Comanche"}; + }; + }; +}; + diff --git a/addons/aircraft/README.md b/addons/aircraft/README.md index 3db71ca51a..c1bf72b3d7 100644 --- a/addons/aircraft/README.md +++ b/addons/aircraft/README.md @@ -1,7 +1,7 @@ ace_aircraft ============ -Changes to air weaponry, flight models and HUDs. +Changes to air weaponry, ejection and HUDs. - Contributions by Kimi (geraldbolso1899) for HUD updates diff --git a/addons/aircraft/RscInGameUI.hpp b/addons/aircraft/RscInGameUI.hpp index d3ef60c6b6..67116a7b62 100644 --- a/addons/aircraft/RscInGameUI.hpp +++ b/addons/aircraft/RscInGameUI.hpp @@ -10,572 +10,568 @@ class HScrollbar; class RscLadderPicture; class RscControlsGroupNoScrollbars; - -class RscInGameUI -{ +class RscInGameUI { class RscUnitInfo; - class Rsc_ACE_Helo_UI_Turret: RscUnitInfo - { + class Rsc_ACE_Helo_UI_Turret: RscUnitInfo { idd = 300; - controls[] = {"CA_IGUI_elements_group","CA_VehicleToggles"}; + controls[] = {"CA_IGUI_elements_group", "CA_VehicleToggles"}; + class VScrollbar; class HScrollbar; - class CA_IGUI_elements_group: RscControlsGroup - { + class CA_IGUI_elements_group: RscControlsGroup { idc = 170; - class VScrollbar: VScrollbar - { + + class VScrollbar: VScrollbar { width = 0; }; - class HScrollbar: HScrollbar - { + + class HScrollbar: HScrollbar { height = 0; }; - x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; - y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; - w = "53.5 * (0.01875 * SafezoneH)"; - h = "40 * (0.025 * SafezoneH)"; - class controls - { - class CA_Distance: RscText - { + + x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; + y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; + w = "53.5 * (0.01875 * SafezoneH)"; + h = "40 * (0.025 * SafezoneH)"; + + class controls { + class CA_Distance: RscText { idc = 151; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; - x = "24.78 * (0.01875 * SafezoneH)"; - y = "30.88 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "24.78 * (0.01875 * SafezoneH)"; + y = "30.88 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class CA_Speed: RangeText - { + + class CA_Speed: RangeText { idc = 188; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "120"; - x = "14.78 * (0.01875 * SafezoneH)"; - y = "30.88 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "14.78 * (0.01875 * SafezoneH)"; + y = "30.88 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class CA_Alt: RangeText - { + + class CA_Alt: RangeText { idc = 189; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "3825"; - x = "34.78 * (0.01875 * SafezoneH)"; - y = "30.88 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "34.78 * (0.01875 * SafezoneH)"; + y = "30.88 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class CA_VisionMode: RscText - { + + class CA_VisionMode: RscText { idc = 152; style = 0; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "VIS"; - x = "12.58 * (0.01875 * SafezoneH)"; - y = "8 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "12.58 * (0.01875 * SafezoneH)"; + y = "8 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class CA_FlirMode: RscText - { + + class CA_FlirMode: RscText { idc = 153; style = 0; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "BHOT"; - x = "15.78 * (0.01875 * SafezoneH)"; - y = "8 * (0.025 * SafezoneH)"; - w = "4.5 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "15.78 * (0.01875 * SafezoneH)"; + y = "8 * (0.025 * SafezoneH)"; + w = "4.5 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class ValueGrid: RangeText - { + + class ValueGrid: RangeText { idc = 172; font = "EtelkaMonospacePro"; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; - x = "12.20 * (0.01875 * SafezoneH)"; - y = "3.5 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "12.20 * (0.01875 * SafezoneH)"; + y = "3.5 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class TextTADS: RangeText - { + + class TextTADS: RangeText { idc = 1010; text = "TADS"; font = "EtelkaMonospacePro"; style = 2; shadow = 0; - x = "12.30 * (0.01875 * SafezoneH)"; - y = "5 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "12.30 * (0.01875 * SafezoneH)"; + y = "5 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class ValueTime: RangeText - { + + class ValueTime: RangeText { idc = 190; text = "20:28:35"; font = "EtelkaMonospacePro"; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; - x = "12.1 * (0.01875 * SafezoneH)"; - y = "6.5 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "12.1 * (0.01875 * SafezoneH)"; + y = "6.5 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class CA_Laser: RscText - { + + class CA_Laser: RscText { idc = 158; style = "0x30 + 0x800"; - sizeEx = "0.038*SafezoneH"; + sizeEx = "0.038 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = QPATHTOF(data\Helo_LaserON.paa); - x = "20.45 * (0.01875 * SafezoneH)"; - y = "14.1 * (0.025 * SafezoneH)"; - w = "12.5 * (0.01875 * SafezoneH)"; - h = "12 * (0.025 * SafezoneH)"; + x = "20.45 * (0.01875 * SafezoneH)"; + y = "14.1 * (0.025 * SafezoneH)"; + w = "12.5 * (0.01875 * SafezoneH)"; + h = "12 * (0.025 * SafezoneH)"; }; - class CA_Heading: RscText - { + + class CA_Heading: RscText { idc = 156; style = 0; - sizeEx = "0.038*SafezoneH"; + sizeEx = "0.038 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "023"; - x = "24.83 * (0.01875 * SafezoneH)"; - y = "6 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "24.83 * (0.01875 * SafezoneH)"; + y = "6 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; }; }; }; - class Rsc_ACE_Helo_UI_01: RscUnitInfo - { - controls[] = {"WeaponInfoControlsGroupRight","CA_TextFlaresMode","CA_TextFlares","CA_VehicleToggles","CA_Radar"}; + + class Rsc_ACE_Helo_UI_01: RscUnitInfo { + controls[] = {"WeaponInfoControlsGroupRight", "CA_TextFlaresMode", "CA_TextFlares", "CA_VehicleToggles", "CA_Radar"}; }; - class Rsc_ACE_Helo_UI_02: RscUnitInfo - { - controls[] = {"CA_TextFlaresMode","CA_TextFlares","CA_VehicleToggles","CA_Radar"}; + + class Rsc_ACE_Helo_UI_02: RscUnitInfo { + controls[] = {"CA_TextFlaresMode", "CA_TextFlares", "CA_VehicleToggles", "CA_Radar"}; }; - class Rsc_ACE_Drones_UI_Turret: RscUnitInfo - { + + class Rsc_ACE_Drones_UI_Turret: RscUnitInfo { idd = 300; - controls[] = {"CA_Zeroing","CA_IGUI_elements_group","CA_VehicleToggles"}; - class CA_IGUI_elements_group: RscControlsGroup - { + controls[] = {"CA_Zeroing", "CA_IGUI_elements_group", "CA_VehicleToggles"}; + + class CA_IGUI_elements_group: RscControlsGroup { idc = 170; - class VScrollbar: VScrollbar - { + + class VScrollbar: VScrollbar { width = 0; }; - class HScrollbar: HScrollbar - { + + class HScrollbar: HScrollbar { height = 0; }; - x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; - y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; - w = "53.5 * (0.01875 * SafezoneH)"; - h = "40 * (0.025 * SafezoneH)"; - class controls - { - class CA_Distance: RscText - { + + x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; + y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; + w = "53.5 * (0.01875 * SafezoneH)"; + h = "40 * (0.025 * SafezoneH)"; + + class controls { + class CA_Distance: RscText { idc = 151; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; - x = "24.78 * (0.01875 * SafezoneH)"; - y = "30.88 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "24.78 * (0.01875 * SafezoneH)"; + y = "30.88 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class CA_Speed: RangeText - { + + class CA_Speed: RangeText { idc = 188; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "120"; - x = "14.78 * (0.01875 * SafezoneH)"; - y = "30.88 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "14.78 * (0.01875 * SafezoneH)"; + y = "30.88 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class CA_Alt: RangeText - { + + class CA_Alt: RangeText { idc = 189; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "3825"; - x = "34.78 * (0.01875 * SafezoneH)"; - y = "30.88 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "34.78 * (0.01875 * SafezoneH)"; + y = "30.88 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class ValueTime: RangeText - { + + class ValueTime: RangeText { idc = 190; text = "20:28:35"; font = "EtelkaMonospacePro"; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; - x = "1.75 * (0.01875 * SafezoneH)"; - y = "10.5 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "1.75 * (0.01875 * SafezoneH)"; + y = "10.5 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class CA_VisionMode: RscText - { + + class CA_VisionMode: RscText { idc = 152; style = 0; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "VIS"; align = "right"; - x = "2.6 * (0.01875 * SafezoneH)"; - y = "12.0 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.0 * (0.025 * SafezoneH)"; + x = "2.6 * (0.01875 * SafezoneH)"; + y = "12.0 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.0 * (0.025 * SafezoneH)"; }; - class CA_FlirMode: RscText - { + + class CA_FlirMode: RscText { idc = 153; style = 0; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "BHOT"; align = "right"; - x = "6.18 * (0.01875 * SafezoneH)"; - y = "12.0 * (0.025 * SafezoneH)"; - w = "4.5 * (0.01875 * SafezoneH)"; - h = "1.0 * (0.025 * SafezoneH)"; + x = "6.18 * (0.01875 * SafezoneH)"; + y = "12.0 * (0.025 * SafezoneH)"; + w = "4.5 * (0.01875 * SafezoneH)"; + h = "1.0 * (0.025 * SafezoneH)"; }; - class TgT_Grid_text: RangeText - { + + class TgT_Grid_text: RangeText { idc = 1005; text = "TGT:"; font = "EtelkaMonospacePro"; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; - x = "1.20 * (0.01875 * SafezoneH)"; - y = "13.5 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "1.20 * (0.01875 * SafezoneH)"; + y = "13.5 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class TGT_ValueGrid: RangeText - { + + class TGT_ValueGrid: RangeText { idc = 172; font = "EtelkaMonospacePro"; - colorText[] = {0.706,0.0745,0.0196,0.8}; + colorText[] = {0.706, 0.0745, 0.0196, 0.8}; style = 2; sizeEx = "0.0295*SafezoneH"; shadow = 0; - x = "5.20 * (0.01875 * SafezoneH)"; - y = "13.5 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "5.20 * (0.01875 * SafezoneH)"; + y = "13.5 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class OWN_Grid_text: RangeText - { + + class OWN_Grid_text: RangeText { idc = 1005; text = "OWN:"; font = "EtelkaMonospacePro"; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; - x = "1.20 * (0.01875 * SafezoneH)"; - y = "15 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "1.20 * (0.01875 * SafezoneH)"; + y = "15 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class OWN_ValueGrid: RangeText - { + + class OWN_ValueGrid: RangeText { idc = 171; font = "EtelkaMonospacePro"; - colorText[] = {0.15,1,0.15,0.8}; + colorText[] = {0.15, 1, 0.15, 0.8}; style = 2; - sizeEx = "0.0295*SafezoneH"; + sizeEx = "0.0295 * SafezoneH"; shadow = 0; - x = "5.20 * (0.01875 * SafezoneH)"; - y = "15 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "5.20 * (0.01875 * SafezoneH)"; + y = "15 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class CA_Laser: RscText - { + + class CA_Laser: RscText { idc = 158; style = "0x30 + 0x800"; - sizeEx = "0.038*SafezoneH"; + sizeEx = "0.038 * SafezoneH"; shadow = 0; align = "right"; font = "EtelkaMonospacePro"; text = QPATHTOF(data\Helo_LaserON.paa); - x = "20.45 * (0.01875 * SafezoneH)"; - y = "14.1 * (0.025 * SafezoneH)"; - w = "12.5 * (0.01875 * SafezoneH)"; - h = "12 * (0.025 * SafezoneH)"; + x = "20.45 * (0.01875 * SafezoneH)"; + y = "14.1 * (0.025 * SafezoneH)"; + w = "12.5 * (0.01875 * SafezoneH)"; + h = "12 * (0.025 * SafezoneH)"; }; - class CA_Heading: RscText - { + + class CA_Heading: RscText { idc = 156; style = 0; - sizeEx = "0.038*SafezoneH"; + sizeEx = "0.038 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; text = "023"; align = "right"; - x = "25 * (0.01875 * SafezoneH)"; - y = "5 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "25 * (0.01875 * SafezoneH)"; + y = "5 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; }; }; }; - class Rsc_ACE_Drones_UI_Pilots: RscUnitInfo - { + + class Rsc_ACE_Drones_UI_Pilots: RscUnitInfo { idd = 300; - controls[] = {"WeaponInfoControlsGroupRight","CA_BackgroundVehicle","CA_BackgroundVehicleTitle","CA_BackgroundVehicleTitleDark","CA_BackgroundFuel","CA_Vehicle","CA_VehicleRole","CA_HitZones","CA_SpeedBackground","CA_SpeedUnits","CA_Speed","CA_ValueFuel","CA_AltBackground","CA_AltUnits","CA_Alt","CA_VehicleToggles","CA_Radar","DriverOpticsGroup"}; - class DriverOpticsGroup: RscControlsGroup - { + controls[] = {"WeaponInfoControlsGroupRight", "CA_BackgroundVehicle", "CA_BackgroundVehicleTitle", "CA_BackgroundVehicleTitleDark", "CA_BackgroundFuel", "CA_Vehicle", "CA_VehicleRole", "CA_HitZones", "CA_SpeedBackground", "CA_SpeedUnits", "CA_Speed", "CA_ValueFuel", "CA_AltBackground", "CA_AltUnits", "CA_Alt", "CA_VehicleToggles", "CA_Radar", "DriverOpticsGroup"}; + + class DriverOpticsGroup: RscControlsGroup { idc = 392; - class VScrollbar: VScrollbar - { + + class VScrollbar: VScrollbar { width = 0; }; - class HScrollbar: HScrollbar - { + + class HScrollbar: HScrollbar { height = 0; }; - x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; - y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; - w = "53.5 * (0.01875 * SafezoneH)"; - h = "40 * (0.025 * SafezoneH)"; - class controls - { - class TextGrid: RscText - { + x = "0 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH) / 2))"; + y = "0 * (0.025 * SafezoneH) + (SafezoneY)"; + w = "53.5 * (0.01875 * SafezoneH)"; + h = "40 * (0.025 * SafezoneH)"; + + class controls { + class TextGrid: RscText { style = 0; - sizeEx = "0.02*SafezoneH"; + sizeEx = "0.02 * SafezoneH"; shadow = 0; font = "EtelkaMonospacePro"; idc = 1005; text = "GRID:"; - x = "5.8 * (0.01875 * SafezoneH)"; - y = "31.8 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "5.8 * (0.01875 * SafezoneH)"; + y = "31.8 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class ValueGrid: TextGrid - { + + class ValueGrid: TextGrid { idc = 189; text = "382546"; - x = "10.3 * (0.01875 * SafezoneH)"; - y = "31.8 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "10.3 * (0.01875 * SafezoneH)"; + y = "31.8 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class TextTime: TextGrid - { + + class TextTime: TextGrid { idc = 1010; text = "TIME [UTC]:"; - x = "5.8 * (0.01875 * SafezoneH)"; - y = "32.6 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "5.8 * (0.01875 * SafezoneH)"; + y = "32.6 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class ValueTime: TextGrid - { + + class ValueTime: TextGrid { idc = 101; text = "20:28:35"; - x = "10 * (0.01875 * SafezoneH)"; - y = "32.6 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "10 * (0.01875 * SafezoneH)"; + y = "32.6 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class TextMag: TextGrid - { + + class TextMag: TextGrid { idc = 1011; text = "CAM MAG:"; - x = "5.8 * (0.01875 * SafezoneH)"; - y = "7 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "5.8 * (0.01875 * SafezoneH)"; + y = "7 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class OpticsZoom: TextGrid - { + + class OpticsZoom: TextGrid { idc = 192; text = "28x"; - x = "10.3 * (0.01875 * SafezoneH)"; - y = "7 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "10.3 * (0.01875 * SafezoneH)"; + y = "7 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class BorderLineSpdTop: RscPicture - { + + class BorderLineSpdTop: RscPicture { idc = 1203; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\border_line_ca.paa"; - x = "3.343 * (0.01875 * SafezoneH)"; - y = "12.4 * (0.025 * SafezoneH)"; - w = "3 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "3.343 * (0.01875 * SafezoneH)"; + y = "12.4 * (0.025 * SafezoneH)"; + w = "3 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class BorderLineSpdBottom: RscPicture - { + + class BorderLineSpdBottom: RscPicture { idc = 1207; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\border_line_ca.paa"; - x = "3.343 * (0.01875 * SafezoneH)"; - y = "26.5 * (0.025 * SafezoneH)"; - w = "3 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "3.343 * (0.01875 * SafezoneH)"; + y = "26.5 * (0.025 * SafezoneH)"; + w = "3 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class BorderLineAltTop: RscPicture - { + + class BorderLineAltTop: RscPicture { idc = 1205; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\border_line_ca.paa"; - x = "47.16 * (0.01875 * SafezoneH)"; - y = "12.4 * (0.025 * SafezoneH)"; - w = "3 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "47.16 * (0.01875 * SafezoneH)"; + y = "12.4 * (0.025 * SafezoneH)"; + w = "3 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class BorderLineAltBottom: RscPicture - { + + class BorderLineAltBottom: RscPicture { idc = 1206; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\border_line_ca.paa"; - x = "47.16 * (0.01875 * SafezoneH)"; - y = "26.5 * (0.025 * SafezoneH)"; - w = "3 * (0.01875 * SafezoneH)"; - h = "1 * (0.025 * SafezoneH)"; + x = "47.16 * (0.01875 * SafezoneH)"; + y = "26.5 * (0.025 * SafezoneH)"; + w = "3 * (0.01875 * SafezoneH)"; + h = "1 * (0.025 * SafezoneH)"; }; - class TextSpd: TextGrid - { + + class TextSpd: TextGrid { idc = 1004; text = "SPD"; - x = "4.8 * (0.01875 * SafezoneH)"; - y = "11.8 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "4.8 * (0.01875 * SafezoneH)"; + y = "11.8 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class SpeedValueBorder: RscPicture - { + + class SpeedValueBorder: RscPicture { idc = 1200; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\altimeter_value_ca.paa"; - x = "6.3 * (0.01875 * SafezoneH)"; - y = "19 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "2 * (0.025 * SafezoneH)"; + x = "6.3 * (0.01875 * SafezoneH)"; + y = "19 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "2 * (0.025 * SafezoneH)"; }; - class CA_Speed: TextGrid - { + + class CA_Speed: TextGrid { idc = 190; sizeEx = "0.03*SafezoneH"; text = "120"; - x = "7.5 * (0.01875 * SafezoneH)"; - y = "19.5 * (0.025 * SafezoneH)"; - w = "6 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "7.5 * (0.01875 * SafezoneH)"; + y = "19.5 * (0.025 * SafezoneH)"; + w = "6 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class AnalogueSpeed: RscLadderPicture - { + + class AnalogueSpeed: RscLadderPicture { idc = 384; topValue = 1312; bottomValue = -345; visibleRange = -1; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\UAVspeedLadder_ca.paa"; - x = "1.5 * (0.01875 * SafezoneH)"; - y = "13 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "14 * (0.025 * SafezoneH)"; + x = "1.5 * (0.01875 * SafezoneH)"; + y = "13 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "14 * (0.025 * SafezoneH)"; }; - class TextAlt: TextGrid - { + + class TextAlt: TextGrid { idc = 1006; text = "ALT"; - x = "46.9 * (0.01875 * SafezoneH)"; - y = "11.8 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "46.9 * (0.01875 * SafezoneH)"; + y = "11.8 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class AltValueBorder: RscPicture - { + + class AltValueBorder: RscPicture { idc = 1201; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\airspeed_value_ca.paa"; - x = "42.25 * (0.01875 * SafezoneH)"; - y = "19 * (0.025 * SafezoneH)"; - w = "5 * (0.01875 * SafezoneH)"; - h = "2 * (0.025 * SafezoneH)"; + x = "42.25 * (0.01875 * SafezoneH)"; + y = "19 * (0.025 * SafezoneH)"; + w = "5 * (0.01875 * SafezoneH)"; + h = "2 * (0.025 * SafezoneH)"; }; - class CA_Alt: TextGrid - { + + class CA_Alt: TextGrid { idc = 191; - sizeEx = "0.03*SafezoneH"; + sizeEx = "0.03 * SafezoneH"; style = 1; text = "3825"; - x = "43 * (0.01875 * SafezoneH)"; - y = "19.5 * (0.025 * SafezoneH)"; - w = "3.2 * (0.01875 * SafezoneH)"; - h = "1.2 * (0.025 * SafezoneH)"; + x = "43 * (0.01875 * SafezoneH)"; + y = "19.5 * (0.025 * SafezoneH)"; + w = "3.2 * (0.01875 * SafezoneH)"; + h = "1.2 * (0.025 * SafezoneH)"; }; - class AnalogueAlt: RscLadderPicture - { + + class AnalogueAlt: RscLadderPicture { idc = 385; topValue = 14430; bottomValue = -2110; visibleRange = -1; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\UAValtLadder_ca.paa"; - x = "47 * (0.01875 * SafezoneH)"; - y = "13 * (0.025 * SafezoneH)"; - w = "2.5 * (0.01875 * SafezoneH)"; - h = "14 * (0.025 * SafezoneH)"; + x = "47 * (0.01875 * SafezoneH)"; + y = "13 * (0.025 * SafezoneH)"; + w = "2.5 * (0.01875 * SafezoneH)"; + h = "14 * (0.025 * SafezoneH)"; }; - class AnalogueHorizon: RscLadderPicture - { + + class AnalogueHorizon: RscLadderPicture { idc = 383; topValue = 90; bottomValue = -90; visibleRange = -1; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\horizon_ladder_ca.paa"; - x = "16.75 * (0.01875 * SafezoneH)"; - y = "5 * (0.025 * SafezoneH)"; - w = "20 * (0.01875 * SafezoneH)"; - h = "30 * (0.025 * SafezoneH)"; + x = "16.75 * (0.01875 * SafezoneH)"; + y = "5 * (0.025 * SafezoneH)"; + w = "20 * (0.01875 * SafezoneH)"; + h = "30 * (0.025 * SafezoneH)"; }; - class HorizonCenter: RscPicture - { + + class HorizonCenter: RscPicture { idc = 1202; text = "\A3\Ui_f\data\IGUI\Cfg\HelicopterHUD\horizon_aircraft_ca.paa"; - x = "24.75 * (0.01875 * SafezoneH)"; - y = "19 * (0.025 * SafezoneH)"; - w = "4 * (0.01875 * SafezoneH)"; - h = "2 * (0.025 * SafezoneH)"; + x = "24.75 * (0.01875 * SafezoneH)"; + y = "19 * (0.025 * SafezoneH)"; + w = "4 * (0.01875 * SafezoneH)"; + h = "2 * (0.025 * SafezoneH)"; }; }; }; }; -}; \ No newline at end of file +}; 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/sitting/XEH_preStart.sqf b/addons/aircraft/XEH_preStart.sqf similarity index 100% rename from addons/sitting/XEH_preStart.sqf rename to addons/aircraft/XEH_preStart.sqf diff --git a/addons/aircraft/config.cpp b/addons/aircraft/config.cpp index 863797ebeb..21b8d9b3c9 100644 --- a/addons/aircraft/config.cpp +++ b/addons/aircraft/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); - authors[] = {"KoffeinFlummi","Crusty","commy2","jaynus","Kimi"}; + authors[] = {"KoffeinFlummi", "Crusty", "commy2", "jaynus", "Kimi"}; url = ECSTRING(main,URL); VERSION_CONFIG; @@ -18,7 +18,8 @@ class CfgPatches { }; #include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" #include "CfgMagazines.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" -#include "RscInGameUI.hpp" \ No newline at end of file +#include "RscInGameUI.hpp" diff --git a/addons/aircraft/flightmodel_alca.hpp b/addons/aircraft/flightmodel_alca.hpp deleted file mode 100644 index 09785e22e7..0000000000 --- a/addons/aircraft/flightmodel_alca.hpp +++ /dev/null @@ -1,24 +0,0 @@ - -acceleration = 300; -maxSpeed = 936; -irScanRangeMin = 500; -irScanRangeMax = 5000; -aileronSensitivity = 0.64; -elevatorSensitivity = 0.682; -rudderInfluence = 0.001; -aileronControlsSensitivityCoef = 3; -elevatorControlsSensitivity = 2; -rudderControlsSensitivityoef = 4; -elevatorCoef[] = {0.6,0.73,0.62,0.52,0.39,0.33,0.28}; -aileronCoef[] = {0.5,0.68,0.75,0.86,0.92,0.96,1}; -rudderCoef[] = {0.9,0.75,0.58,0.45,0.38,0.35,0.3}; -envelope[] = {0,0.06,1.2,3,3.6,3.75,3.65,3.45,3.3,2.8,2.4,1.9,1.5}; -angleOfIndicence = 0.0523599; //determines velocity vector behaviour, how quickly it catches up with where your nose is pointing, I think -draconicForceXCoef = 7.5; //max angle of attack, lower value gives higher aoa -draconicForceYCoef = 0.2198; //Something to do with bleed off of speed, low values seem to increase bleed off -draconicForceZCoef = 5.12; //???? -draconicTorqueXCoef = 0.18; //resistance to elevator input, also impacts speed degradation -draconicTorqueYCoef = 0.000017; -thrustCoef[] = {1.3,1.27,1.24,1.2,1.17,1.15,1.13,1.1,1.06,1,0.94,0.72,0.51,0.4,0.25,0}; -gunAimDown = 0.029; -flapsFrictionCoef = 0.32; diff --git a/addons/aircraft/flightmodel_thunderbolt.hpp b/addons/aircraft/flightmodel_thunderbolt.hpp deleted file mode 100644 index 2446e166bc..0000000000 --- a/addons/aircraft/flightmodel_thunderbolt.hpp +++ /dev/null @@ -1,22 +0,0 @@ - -maxSpeed = 736; -aileronSensitivity = 0.85; -elevatorSensitivity = 0.75; -rudderInfluence = 0.001; -aileronControlsSensitivityCoef = 3; -elevatorControlsSensitivity = 2; -rudderControlsSensitivityoef = 4; -elevatorCoef[] = {0.7,0.75,0.75,0.65,0.55,0.45,0.35}; -aileronCoef[] = {0.6,0.85,0.88,0.92,0.95,0.97,1}; -rudderCoef[] = {0.8,0.75,0.65,0.5,0.4,0.33,0.3}; -flapsFrictionCoef = 0.35; -angleOfIndicence = 0.0523599; -draconicForceXCoef = 9.5; -draconicForceYCoef = 0.56; -draconicForceZCoef = 0.1; -draconicTorqueXCoef = 0.58; -draconicTorqueYCoef = 0.00013; -envelope[] = {0,0,0.75,2.4,3.6,3.8,3.7,3.2,2.2,1.7,0.9}; -thrustCoef[] = {1,1.2,1.3,1.25,1.06,1.01,1,0.92,0.75,0.65,0.5,0.25,0}; -acceleration = 265; -landingSpeed = 220; diff --git a/addons/aircraft/flightmodel_yak.hpp b/addons/aircraft/flightmodel_yak.hpp deleted file mode 100644 index bcf5a4cfd0..0000000000 --- a/addons/aircraft/flightmodel_yak.hpp +++ /dev/null @@ -1,21 +0,0 @@ - -maxSpeed = 1059; -acceleration = 300; -aileronSensitivity = 0.635; -elevatorSensitivity = 0.814; -rudderInfluence = 0.001; -aileronControlsSensitivityCoef = 3; -elevatorControlsSensitivity = 2; -rudderControlsSensitivityoef = 4; -elevatorCoef[] = {0.6,0.76,0.7,0.65,0.58,0.47,0.43}; -aileronCoef[] = {0.5,0.85,0.87,0.89,0.92,0.95,1}; -rudderCoef[] = {0.8,0.7,0.6,0.5,0.4,0.32,0.27}; -angleOfIndicence = 0.0523599; -draconicForceXCoef = 7.6; -draconicForceYCoef = 0.75; -draconicForceZCoef = 0.085; -draconicTorqueXCoef = 0.815; -draconicTorqueYCoef = 0.000152; -envelope[] = {0,0.446,1.5,3.9,5.2,4.8,4.2,3.5,2,1,0.5}; -thrustCoef[] = {1,1.2,1.7,1.7,1.65,1.54,1.32,1.1,0.95,0.75,0.5,0.35,0}; -flapsFrictionCoef = 0.32; diff --git a/addons/aircraft/functions/fnc_canShowEject.sqf b/addons/aircraft/functions/fnc_canShowEject.sqf new file mode 100644 index 0000000000..6ec13d2bb9 --- /dev/null +++ b/addons/aircraft/functions/fnc_canShowEject.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * 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 + */ + +#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..8ec9e33ade --- /dev/null +++ b/addons/aircraft/functions/fnc_initEjectAction.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Add Eject action to vehicle if needed. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_aircraft_fnc_initEjectAction + * + * Public: No + */ + +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/aircraft/script_component.hpp b/addons/aircraft/script_component.hpp index e2379c0791..3f4510881e 100644 --- a/addons/aircraft/script_component.hpp +++ b/addons/aircraft/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_AIRCRAFT diff --git a/addons/aircraft/stringtable.xml b/addons/aircraft/stringtable.xml index 5516551d42..0c52397242 100644 --- a/addons/aircraft/stringtable.xml +++ b/addons/aircraft/stringtable.xml @@ -1,18 +1,6 @@ - + - - Burst - Feuerstoß - Ráfaga - Seria - Dávka - Rafale - Очередь - Sorozat - Rajada - Raffica - XM301 XM301 @@ -24,6 +12,10 @@ XM301 XM301 XM301 + XM301 + XM301 + XM301 + XM301 Open Cargo Door @@ -36,6 +28,10 @@ Открыть грузовой отсек Apri la rampa di carico Abrir porta de carga + カーゴ ドアを開く + 화물칸 개방 + 開啟貨艙門 + 开启货舱门 Close Cargo Door @@ -48,6 +44,10 @@ Закрыть грузовой отсек Chiudi la rampa di carico Fechar porta de carga + カーゴ ドアを閉じる + 화물칸 폐쇄 + 關閉貨艙門 + 关闭货舱门 - \ No newline at end of file + 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/apl/script_component.hpp b/addons/apl/script_component.hpp index 969c9dca7f..a0e82fb2d2 100644 --- a/addons/apl/script_component.hpp +++ b/addons/apl/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_APL 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/ACE_Arsenal_Stats.hpp b/addons/arsenal/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..885daa843f --- /dev/null +++ b/addons/arsenal/ACE_Arsenal_Stats.hpp @@ -0,0 +1,104 @@ +class GVAR(stats) { + class statBase { + scope = 1; + priority = 0; + stats[] = {}; + displayName = ""; + showBar = 0; + showText = 0; + barStatement = ""; + textStatement = ""; + condition = "true"; + tabs[] = {{}, {}}; + }; + class ACE_bananaPotassium: statBase { + scope = 2; + displayName= CSTRING(statPotassium); + showBar = 1; + barStatement = "1"; + condition = QUOTE((configName (_this select 1)) == 'ACE_Banana'); + tabs[] = {{}, {7}}; + }; + class ACE_mass: statBase { + scope = 2; + displayName= "$STR_a3_rscdisplayarsenal_stat_weight"; + showText = 1; + textStatement = QUOTE([ARR_2(_this select 0, _this select 1)] call FUNC(statTextStatement_mass)); + tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {0,1,2,3,4,5,6,7}}; + }; + class ACE_rateOfFire: statBase { + scope = 2; + priority = 5; + stats[] = {"reloadTime"}; + displayName= "$STR_a3_rscdisplayarsenal_stat_rof"; + showBar = 1; + showText = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-1.4, 0.31)], [ARR_2(1, 0.01)])])] call FUNC(statBarStatement_rateOfFIre)); + textStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-1.4, 0.31)], false)])] call FUNC(statTextStatement_rateOfFire)); + tabs[] = {{0,1}, {}}; + }; + class ACE_accuracy: statBase { + scope = 2; + priority = 4; + stats[] = {"dispersion"}; + displayName = "$STR_a3_rscdisplayarsenal_stat_dispersion"; + showBar = 1; + showText = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(-4, -1.7)], [ARR_2(1, 0.01)], true)])] call FUNC(statBarStatement_accuracy)); + textStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-4, -1.7)], false)])] call FUNC(statTextStatement_accuracy)); + tabs[] = {{0,1}, {}}; + }; + class ACE_maxZeroing: statBase { + scope = 2; + priority = 3; + stats[] = {"maxZeroing"}; + displayName = "$STR_a3_rscdisplayarsenal_stat_range"; + showBar = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 2500)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + tabs[] = {{0,1,2}, {}}; + }; + class ACE_impact: statBase { + scope = 2; + priority = 2; + stats[] = {"hit", "initSpeed"}; + displayName = "$STR_a3_rscdisplayarsenal_stat_impact"; + showBar = 1; + barStatement = QUOTE([ARR_3(_this select 0, _this select 1, [ARR_3([ARR_2(0, 3.2)], [ARR_2(-1, 1100)], 2006)])] call FUNC(statBarStatement_impact)); + tabs[] = {{0,1,2}, {}}; + }; + class ACE_scopeMagnification: statBase { + scope = 2; + priority = 2; + displayName = CSTRING(statMagnification); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_scopeMag)); + tabs[] = {{}, {0}}; + }; + class ACE_ballisticProtection: statBase { + scope = 2; + priority = 5; + stats[] = {"passthrough"}; + displayName = "$STR_a3_rscdisplayarsenal_stat_passthrough"; + showBar = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 0.63)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + tabs[] = {{3,4,6}, {}}; + }; + class ACE_explosiveResistance: statBase { + scope = 2; + priority = 4; + stats[] = {"armor"}; + displayName = "$STR_a3_rscdisplayarsenal_stat_armor"; + showBar = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 0.80)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + tabs[] = {{3,4,6}, {}}; + }; + class ACE_load: statBase { + scope = 2; + priority = 3; + stats[] = {"maximumLoad"}; + displayName = "$STR_a3_rscdisplayarsenal_stat_load"; + showBar = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 500)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default)); + tabs[] = {{3,4,5}, {}}; + }; +}; diff --git a/addons/arsenal/Cfg3DEN.hpp b/addons/arsenal/Cfg3DEN.hpp new file mode 100644 index 0000000000..ceb3cee926 --- /dev/null +++ b/addons/arsenal/Cfg3DEN.hpp @@ -0,0 +1,188 @@ +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 = QUOTE(if (!is3DEN) then {GVAR(defaultLoadoutsList) = _value};); + defaultValue = "[]"; + validate = "none"; + wikiType = "[[Array]]"; + }; + }; + }; + }; + }; + }; + class Attributes { + class GVAR(attribute): ctrlControlsGroupNoScrollbars { + idc = -1; + // onLoad fixes attributeLoad not happening on multiple selection with different attribute + onLoad = QUOTE(private _objects = get3DENSelected 'object'; if (count _objects > 1) then {[ARR_2(_this select 0,((_objects select 0) get3DENAttribute QQGVAR(attribute)) select 0)] call FUNC(attributeLoad)}); + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(130 * ATTRIBUTE_W); + h = QUOTE(106.83 * ATTRIBUTE_H); + attributeLoad = QUOTE([ARR_2(_this,+_value)] call FUNC(attributeLoad)); + attributeSave = QUOTE(uiNamespace getVariable [ARR_2(QQGVAR(attributeValue),[ARR_2([], 0)])]); + class controls { + class ModeTitle: ctrlStatic { + idc = -1; + text = CSTRING(Mode); + x = QUOTE(5 * ATTRIBUTE_W); + y = QUOTE(0); + w = QUOTE(125 * ATTRIBUTE_W); + h = QUOTE(5 * ATTRIBUTE_H); + }; + class Mode: ctrlToolbox { + idc = IDC_ATTRIBUTE_MODE; + onToolBoxSelChanged = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0), _this select 1)] call FUNC(attributeMode)); + x = QUOTE(5 * ATTRIBUTE_W); + y = QUOTE(5 * ATTRIBUTE_H); + w = QUOTE(125 * ATTRIBUTE_W); + h = QUOTE(5 * ATTRIBUTE_H); + rows = 1; + columns = 2; + strings[] = {CSTRING(Whitelist), CSTRING(Blacklist)}; + }; + class ItemsTitle: ModeTitle { + text = CSTRING(Items); + y = QUOTE(10 * ATTRIBUTE_H); + }; + class Category: ctrlToolboxPictureKeepAspect { + idc = IDC_ATTRIBUTE_CATEGORY; + onToolBoxSelChanged = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddItems)); + x = QUOTE(5 * ATTRIBUTE_W); + y = QUOTE(15 * ATTRIBUTE_H); + w = QUOTE(125 * ATTRIBUTE_W); + h = QUOTE(20.83 * ATTRIBUTE_H); + rows = 2; + columns = 12; + strings[] = { + "\a3\Ui_F_Curator\Data\RscCommon\RscAttributeInventory\filter_0_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\SecondaryWeapon_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Handgun_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemOptic_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemAcc_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemMuzzle_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemBipod_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMagAll_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Headgear_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Uniform_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Vest_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Backpack_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Goggles_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\NVGs_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Binoculars_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Map_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Compass_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Radio_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Watch_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\GPS_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoThrow_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoPut_ca.paa", + "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMisc_ca.paa" + }; + }; + class ListBackground: ctrlStatic { + idc = -1; + x = QUOTE(5 * ATTRIBUTE_W); + y = QUOTE(35.83 * ATTRIBUTE_H); + w = QUOTE(125 * ATTRIBUTE_W); + h = QUOTE(65 * ATTRIBUTE_H); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class List: ctrlListNBox { + idc = IDC_ATTRIBUTE_LIST; + idcLeft = IDC_ATTRIBUTE_LIST_LEFT; + idcRight = IDC_ATTRIBUTE_LIST_RIGHT; + onLBDblClick = QUOTE(_this call FUNC(attributeDblClick)); + x = QUOTE(5 * ATTRIBUTE_W); + y = QUOTE(35.83 * ATTRIBUTE_H); + w = QUOTE(125 * ATTRIBUTE_W); + h = QUOTE(65 * ATTRIBUTE_H); + drawSideArrows = 1; + disableOverflow = 1; + columns[] = {0.05, 0.15, 0.85}; + }; + class ArrowLeft: ctrlButton { + idc = IDC_ATTRIBUTE_LIST_LEFT; + onButtonClick = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0),false)] call FUNC(attributeSelect)); + text = SYMBOL_ITEM_NONE; + font = "RobotoCondensedBold"; + x = QUOTE(-1); + y = QUOTE(-1); + w = QUOTE(5 * ATTRIBUTE_W); + H = QUOTE(5 * ATTRIBUTE_H); + }; + class ArrowRight: ArrowLeft { + idc = IDC_ATTRIBUTE_LIST_RIGHT; + onButtonClick = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0),true)] call FUNC(attributeSelect)); + text = SYMBOL_ITEM_VIRTUAL; + }; + class SearchButton: ctrlButtonPicture { + idc = IDC_ATTRIBUTE_SEARCH_BUTTON; + onButtonClick = QUOTE(((ctrlParentControlsGroup (_this select 0)) controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR) ctrlSetText ''; [ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddItems)); + text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; + x = QUOTE(5 * ATTRIBUTE_W); + y = QUOTE(101.83 * ATTRIBUTE_H); + w = QUOTE(5 * ATTRIBUTE_W); + h = QUOTE(5 * ATTRIBUTE_H); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class SearchBar: ctrlEdit { + idc = IDC_ATTRIBUTE_SEARCHBAR; + onKeyUp = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddItems)); + x = QUOTE(11 * ATTRIBUTE_W); + y = QUOTE(101.83 * ATTRIBUTE_H); + w = QUOTE(55 * ATTRIBUTE_W); + h = QUOTE(5 * ATTRIBUTE_H); + }; + class ClearButton: ctrlButton { + idc = IDC_ATTRIBUTE_CLEAR_BUTTON; + onButtonClick = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeClear)); + text = "$STR_disp_arcmap_clear"; + x = QUOTE(105 * ATTRIBUTE_W); + y = QUOTE(101.83 * ATTRIBUTE_H); + w = QUOTE(25 * ATTRIBUTE_W); + h = QUOTE(5 * ATTRIBUTE_H); + colorBackground[] = {0, 0, 0, 0.6}; + }; + class ExportButton: ClearButton { + idc = IDC_ATTRIBUTE_EXPORT_BUTTON; + onButtonClick = QUOTE(copyToClipboard str ((uiNamespace getVariable [ARR_2(QQGVAR(attributeValue),[ARR_2([],0)])]) select 0)); + text = CSTRING(buttonExportText); + tooltip = CSTRING(AttributeExport_Tooltip); + x = QUOTE(79 * ATTRIBUTE_W); + }; + }; + }; + }; + class Object { + class AttributeCategories { + class ADDON { + displayName = CSTRING(Mission); + collapsed = 1; + class Attributes { + class ADDON { + property = QGVAR(attribute); + control = QGVAR(attribute); + displayName = CSTRING(Mission); + tooltip = ""; + expression = QUOTE(if (!is3DEN) then {[ARR_2(_this,+_value)] call FUNC(attributeInit)}); + defaultValue = "[[], 0]"; + condition = "1 - objectControllable"; + wikiType = "[[Array]]"; + validate = "none"; + value = 0; + }; + }; + }; + }; + }; +}; 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..233abc56f8 --- /dev/null +++ b/addons/arsenal/XEH_PREP.hpp @@ -0,0 +1,69 @@ +PREP(addDefaultLoadout); +PREP(addListBoxItem); +PREP(addStat); +PREP(addVirtualItems); +PREP(attributeAddItems); +PREP(attributeClear); +PREP(attributeDblClick); +PREP(attributeInit); +PREP(attributeLoad); +PREP(attributeMode); +PREP(attributeSelect); +PREP(buttonCargo); +PREP(buttonClearAll); +PREP(buttonExport); +PREP(buttonHide); +PREP(buttonImport); +PREP(buttonLoadoutsDelete); +PREP(buttonLoadoutsLoad); +PREP(buttonLoadoutsRename); +PREP(buttonLoadoutsSave); +PREP(buttonLoadoutsShare); +PREP(buttonStats); +PREP(buttonStatsPage); +PREP(clearSearchbar); +PREP(compileStats); +PREP(fillLeftPanel); +PREP(fillLoadoutsList); +PREP(fillRightPanel); +PREP(handleLoadoutsSearchbar); +PREP(handleMouse); +PREP(handleScrollWheel); +PREP(handleSearchbar); +PREP(handleStats); +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(removeStat); +PREP(removeVirtualItems); +PREP(scanConfig); +PREP(showItem); +PREP(sortPanel); +PREP(statBarStatement_accuracy); +PREP(statBarStatement_default); +PREP(statBarStatement_impact); +PREP(statBarStatement_rateOfFIre); +PREP(statTextStatement_accuracy); +PREP(statTextStatement_mass); +PREP(statTextStatement_rateOfFire); +PREP(statTextStatement_scopeMag); +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..41f5f4cf88 --- /dev/null +++ b/addons/arsenal/XEH_preInit.sqf @@ -0,0 +1,63 @@ +#include "script_component.hpp" +#include "defines.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; +[QGVAR(enableIdentityTabs), "CHECKBOX", localize LSTRING(enableIdentityTabsSettings), localize LSTRING(settingCategory), true, true] 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; + +[QGVAR(statsToggle), { + params ["_display", "_showStats"]; + + private _statsCtrlGroupCtrl = _display displayCtrl IDC_statsBox; + private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage; + private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage; + private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage; + + private _statsButtonCtrl = _display displayCtrl IDC_statsButton; + private _statsButtonCloseCtrl = _display displayCtrl IDC_statsButtonClose; + + { + _x ctrlShow (GVAR(showStats) && {_showStats}); + } forEach [ + _statsCtrlGroupCtrl, + _statsPreviousPageCtrl, + _statsNextPageCtrl, + _statsCurrentPageCtrl, + _statsButtonCloseCtrl + ]; + + _statsButtonCtrl ctrlShow (!GVAR(showStats) && {_showStats}) +}] call CBA_fnc_addEventHandler; + +[QGVAR(statsButton), { + _this call FUNC(buttonStats); +}] call CBA_fnc_addEventHandler; + +[QGVAR(statsChangePage), { + _this call FUNC(buttonStatsPage); +}] call CBA_fnc_addEventHandler; + + +[QGVAR(displayStats), { + _this call FUNC(handleStats); +}] call CBA_fnc_addEventHandler; + +call FUNC(compileStats); + +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..32bc41d254 --- /dev/null +++ b/addons/arsenal/config.cpp @@ -0,0 +1,21 @@ +#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", "mharis001"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "ui\RscAttributes.hpp" +#include "Cfg3DEN.hpp" +#include "CfgEventHandlers.hpp" +#include "RscDisplayMain.hpp" +#include "ACE_Arsenal_Stats.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..6bc200b32f --- /dev/null +++ b/addons/arsenal/defines.hpp @@ -0,0 +1,412 @@ +// 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 IDC_statsBox 51 +#define IDC_statsTitle1 5101 +#define IDC_statsBackground1 5102 +#define IDC_statsBar1 5103 +#define IDC_statsText1 5104 +#define IDC_statsTitle2 5105 +#define IDC_statsBackground2 5106 +#define IDC_statsBar2 5107 +#define IDC_statsText2 5108 +#define IDC_statsTitle3 5109 +#define IDC_statsBackground3 5110 +#define IDC_statsBar3 5111 +#define IDC_statsText3 5112 +#define IDC_statsTitle4 5113 +#define IDC_statsBackground4 5114 +#define IDC_statsBar4 5115 +#define IDC_statsText4 5116 +#define IDC_statsTitle5 5117 +#define IDC_statsBackground5 5118 +#define IDC_statsBar5 5119 +#define IDC_statsText5 5120 +#define IDC_statsPreviousPage 52 +#define IDC_statsNextPage 53 +#define IDC_statsCurrentPage 54 +#define IDC_statsButton 55 +#define IDC_statsButtonClose 56 + +#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 + +// 3DEN Attribute +#define ATTRIBUTE_W (pixelW * pixelGrid * 0.5) +#define ATTRIBUTE_H (pixelH * pixelGrid * 0.5) + +#define IDC_ATTRIBUTE_MODE 8100 +#define IDC_ATTRIBUTE_CATEGORY 8101 +#define IDC_ATTRIBUTE_LIST 8102 +#define IDC_ATTRIBUTE_LIST_LEFT 8103 +#define IDC_ATTRIBUTE_LIST_RIGHT 8104 +#define IDC_ATTRIBUTE_SEARCH_BUTTON 8105 +#define IDC_ATTRIBUTE_SEARCHBAR 8106 +#define IDC_ATTRIBUTE_CLEAR_BUTTON 8107 +#define IDC_ATTRIBUTE_EXPORT_BUTTON 8108 + +#define SYMBOL_ITEM_NONE "−" +#define SYMBOL_ITEM_REMOVE "×" +#define SYMBOL_ITEM_VIRTUAL "∞" + +#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\ +];\ +{\ + _x = _display displayCtrl _x;\ + _x ctrlSetPosition [\ + safezoneX + safezoneW - 93 * GRID_W,\ + safezoneY + 14 * GRID_H,\ + 80 * GRID_W,\ + safezoneH - 28 * GRID_H\ + ];\ + _x ctrlCommit 0;\ +} foreach [\ + IDC_blockRightFrame,\ + IDC_blockRighttBackground\ +]; + +#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\ +];\ +{\ + _x = _display displayCtrl _x;\ + _x ctrlSetPosition [\ + safezoneX + safezoneW - 93 * GRID_W,\ + safezoneY + 14 * GRID_H,\ + 80 * GRID_W,\ + safezoneH - 34 * GRID_H\ + ];\ + _x ctrlCommit 0;\ +} foreach [\ + IDC_blockRightFrame,\ + IDC_blockRighttBackground\ +]; + +#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\ + (_weaponsArray select 0) findIf {_x == _item} > -1 ||\ + {(_weaponsArray select 1) findIf {_x == _item} > -1} ||\ + {(_weaponsArray select 2) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 9) findIf {_x == _item} > -1} ||\ + {(_accsArray select 0) findIf {_x == _item} > -1} ||\ + {(_accsArray select 1 findIf {_x == _item} > -1)} ||\ + {(_accsArray select 2) findIf {_x == _item} > -1} ||\ + {(_accsArray select 3) findIf {_x == _item} > -1} + +#define CHECK_ASSIGNED_ITEMS\ + (GVAR(virtualItems) select 10) findIf {_x == _item} > -1 ||\ + {(GVAR(virtualItems) select 11) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 12) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 13) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 14) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 8) findIf {_x == _item} > -1} + +#define CHECK_CONTAINER\ + (GVAR(virtualItems) select 4) findIf {_x == _item} > -1 ||\ + {(GVAR(virtualItems) select 5) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 6) findIf {_x == _item} > -1} + +#define CLASS_CHECK_ITEM\ + isClass (_weaponCfg >> _item) ||\ + {isClass (_vehcCfg >> _item)} ||\ + {isClass (_glassesCfg >> _item)} ||\ + {isClass (_magCfg >> _item)} + +#define CHECK_CONTAINER_ITEMS\ + (GVAR(virtualItems) select 3) findIf {_x == _item} > -1 ||\ + {(_accsArray select 0) findIf {_x == _item} > -1} ||\ + {(_accsArray select 1) findIf {_x == _item} > -1} ||\ + {(_accsArray select 2) findIf {_x == _item} > -1} ||\ + {(_accsArray select 3) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 4) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 5) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 6) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 7) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 8) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 10) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 11) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 12) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 13) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 14) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 15) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 16) findIf {_x == _item} > -1} ||\ + {(GVAR(virtualItems) select 17) findIf {_x == _item} > -1} + +#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_addDefaultLoadout.sqf b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf new file mode 100644 index 0000000000..2c18a38ca6 --- /dev/null +++ b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Adds a loadout to the "Default Loadouts" list. + * If a loadout with the same name exists, it is overwritten. + * + * Arguments: + * 0: Name of loadout + * 1: getUnitLoadout array + * + * Return Value: + * None + * + * Example: + * ["Squad Leader", getUnitLoadout sql1] call ace_arsenal_fnc_addDefaultLoadout + * + * Public: Yes +*/ + +params [["_name", "", [""]], ["_loadout", [], [[]], 10]]; + +if (isNil QGVAR(defaultLoadoutsList)) then { + GVAR(defaultLoadoutsList) = []; +}; + +private _loadoutIndex = (+(GVAR(defaultLoadoutsList))) findIf {(_x select 0) == _name}; +if (_loadoutIndex == -1) then { + GVAR(defaultLoadoutsList) pushBack [_name, _loadout]; +} else { + GVAR(defaultLoadoutsList) set [_loadoutIndex, [_name, _loadout]]; +}; diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf new file mode 100644 index 0000000000..8a3fb1491f --- /dev/null +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -0,0 +1,62 @@ +#include "script_component.hpp" +/* + * 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 +*/ +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_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf new file mode 100644 index 0000000000..61e361fd0f --- /dev/null +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -0,0 +1,99 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Add a stat to ACE Arsenal. + * + * Arguments: + * 0: Tabs to add the stat to (ARRAY of ARRAYS) + * 0.1: Left tab indexes (ARRAY of NUMBERS) + * 0.2 Right tab indexes (ARRAY of NUMBERS) + * 1: Stat class (STRING) (A unique string for each stat) + * 2: Config entries to pass (ARRAY of STRINGS) + * 3: Title (STRING) + * 4: Show bar / show text bools (ARRAY of BOOLS) + * 4.1 Show bar (BOOL) + * 4.2 Show text (BOOL) + * 5: Array of statements (ARRAY of ARRAYS) + * 5.1: Bar code (CODE) + * 5.2 Text code (CODE) + * 5.3 Condition code (CODE) + * 6: Priority (NUMBER) (Optional) + * + * Return Value: + * 0: Array of IDs (ARRAY of STRINGS) + * + * Example: + * [[[0,1,2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { + params ["_statsArray", "_itemCfg"]; + getNumber (_itemCfg >> _statsArray select 0) + }, {true}]] call ACE_arsenal_fnc_addStat + * + * Public: Yes +*/ +params [ + ["_tabs", [[], []], [[]], 2], + ["_class", "", [""]], + ["_stats", [], [[]]], + ["_title", "", [""]], + ["_bools", [false, false], [[]], 2], + ["_statements", [{}, {}, {true}], [[]], 3], + ["_priority", 0, [0]] +]; + +_tabs params [ + ["_leftTabs", [], [[]]], + ["_rightTabs", [], [[]]] +]; + +_bools params [["_showBar", false, [false]], ["_showText", false, [false]]]; + +_statements params [ + ["_barStatement", {}, [{}]], + ["_textStatement", {}, [{}]], + ["_condition", {true}, [{}]] +]; + +call FUNC(compileStats); + +private _returnArray = []; + +private _fnc_addToTabs = { + params ["_tabsList", "_tabsToAddTo", "_sideString", "_returnIndex"]; + { + private _currentTab = _tabsList select _x; + + private _finalID = [_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""; + + if ({{_x select 0 == _finalID} count _x > 0} count _currentTab > 0) then { + TRACE_1("A stat with this ID already exists", _finalID); + } else { + + private _arrayToSave = +_finalArray; + _arrayToSave set [0, _finalID]; + _returnArray pushBack _finalID; + + // Add to existing page if there's enough space, otherwise create a new page + if ({count _x < 5} count _currentTab > 0) then { + { + if (count _x < 5) exitWith { + (_currentTab select _forEachIndex) append [_arrayToSave]; + }; + } foreach _currentTab; + } else { + _currentTab pushBack [_arrayToSave]; + }; + }; + } foreach _tabsToAddTo; +}; + +private _finalArray = ["", _stats, _title, [_showBar, _showText], [_barStatement, _textStatement, _condition], _priority]; + +if (count _leftTabs > 0) then { + [GVAR(statsListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; +}; + +if (count _rightTabs > 0) then { + [GVAR(statsListRightPanel), _rightTabs, "R", 1] call _fnc_addToTabs; +}; + +_returnArray diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf new file mode 100644 index 0000000000..ff5865bb6b --- /dev/null +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -0,0 +1,225 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * 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 +*/ + +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 [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} && + {!(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])} + ): { + switch (getNumber (_configItemInfo >> "type")) do { + case TYPE_OPTICS: { + (_cargo select 1) select 0 pushBackUnique _x; + }; + case TYPE_FLASHLIGHT: { + (_cargo select 1) select 1 pushBackUnique _x; + }; + case TYPE_MUZZLE: { + (_cargo select 1) select 2 pushBackUnique _x; + }; + case TYPE_BIPOD: { + (_cargo select 1) select 3 pushBackUnique _x; + }; + }; + }; + /* Headgear */ + case (isClass (_configItemInfo) && + {getNumber (_configItemInfo >> "type") == TYPE_HEADGEAR}): { + (_cargo select 3) pushBackUnique _x; + }; + /* Uniform */ + case (isClass (_configItemInfo) && + {getNumber (_configItemInfo >> "type") == TYPE_UNIFORM}): { + (_cargo select 4) pushBackUnique _x; + }; + /* Vest */ + case (isClass (_configItemInfo) && + {getNumber (_configItemInfo >> "type") == TYPE_VEST}): { + (_cargo select 5) pushBackUnique _x; + }; + /* NVgs */ + case (_simulationType == "NVGoggles"): { + (_cargo select 8) pushBackUnique _x; + }; + /* Binos */ + case (_simulationType == "Binocular" || + {(_simulationType == 'Weapon') && {(getNumber (_configCfgWeapons >> _x >> 'type') == TYPE_BINOCULAR_AND_NVG)}}): { + (_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") == TYPE_UAV_TERMINAL}): { + (_cargo select 14) pushBackUnique _x; + }; + /* Weapon, at the bottom to avoid adding binos */ + case (isClass (_configCfgWeapons >> _x >> "WeaponSlotsInfo") && + {getNumber (_configCfgWeapons >> _x >> 'type') != TYPE_BINOCULAR_AND_NVG}): { + switch (getNumber (_configCfgWeapons >> _x >> "type")) do { + case TYPE_WEAPON_PRIMARY: { + (_cargo select 0) select 0 pushBackUnique ([_x] call bis_fnc_baseWeapon); + }; + case TYPE_WEAPON_HANDGUN: { + (_cargo select 0) select 2 pushBackUnique ([_x] call bis_fnc_baseWeapon); + }; + case TYPE_WEAPON_SECONDARY: { + (_cargo select 0) select 1 pushBackUnique ([_x] call bis_fnc_baseWeapon); + }; + }; + }; + /* Misc items */ + case ( + isClass (_configItemInfo) && + ((getNumber (_configItemInfo >> "type")) in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && + {(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])}) || + {(getNumber (_configItemInfo >> "type")) in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {(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 [TYPE_MAGAZINE_PRIMARY_AND_THROW,TYPE_MAGAZINE_SECONDARY_AND_PUT,1536,TYPE_MAGAZINE_HANDGUN_AND_GL]) && + {!(_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_attributeAddItems.sqf b/addons/arsenal/functions/fnc_attributeAddItems.sqf new file mode 100644 index 0000000000..edc62ea6ed --- /dev/null +++ b/addons/arsenal/functions/fnc_attributeAddItems.sqf @@ -0,0 +1,122 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: mharis001 + * Populates 3DEN attribute listbox with items of given category. + * + * Arguments: + * 0: Attribute controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL, 0] call ace_arsenal_fnc_attributeAddItems + * + * Public: No + */ + +params ["_controlsGroup"]; + +private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) - 1; +private _filter = toLower ctrlText (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR); +private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); +private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; +TRACE_3("Populating list",_category,_filter,_attributeValue); + +_attributeValue params ["_attributeItems", "_attributeMode"]; +private _modeSymbol = [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode; + +// Clear listbox +private _listbox = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_LIST; +lnbClear _listbox; + +// Exit with current items (no specific category) +if (_category == -1) exitWith { + { + // Get appropriate config for each item (different since items can be from any category) + private _config = switch (true) do { + case (_x in (_configItems select 2)); + case (_x in (_configItems select 15)); + case (_x in (_configItems select 16)): { + configFile >> "CfgMagazines" >> _x; + }; + case (_x in (_configItems select 6)): { + configFile >> "CfgVehicles" >> _x; + }; + case (_x in (_configItems select 7)): { + configFile >> "CfgGlasses" >> _x; + }; + default { + configFile >> "CfgWeapons" >> _x; + }; + }; + + // Add item if not filtered + private _displayName = getText (_config >> "displayName"); + if (toLower _displayName find _filter > -1) then { + private _picture = getText (_config >> "picture"); + private _index = _listbox lnbAddRow ["", _displayName, _modeSymbol]; + _listbox lnbSetData [[_index, 1], _x]; + _listbox lnbSetPicture [[_index, 0], _picture]; + _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; + }; + } forEach _attributeItems; + + _listbox lnbSort [1]; +}; + +// Get list of category items +private _categoryItems = switch (true) do { + case (_category < 3): { + _configItems select 0 select _category; + }; + case (_category < 7): { + _configItems select 1 select (_category - 3); + }; + default { + _configItems select (_category - 5); + }; +}; + +// Get config for current category +private _config = switch (true) do { + case (_category in [7, 20, 21]): { + configFile >> "CfgMagazines"; + }; + case (_category == 11): { + configFile >> "CfgVehicles"; + }; + case (_category == 12): { + configFile >> "CfgGlasses"; + }; + default { + configFile >> "CfgWeapons"; + }; +}; + +// Populate listbox with category items +{ + // Add item if not filtered + private _displayName = getText (_config >> _x >> "displayName"); + if (toLower _displayName find _filter > -1) then { + private _picture = getText (_config >> _x >> "picture"); + private _symbol = SYMBOL_ITEM_NONE; + private _alpha = 0.5; + + // Change symbol and alpha if item already selected + if (_x in _attributeItems) then { + _symbol = _modeSymbol; + _alpha = 1; + }; + + private _index = _listbox lnbAddRow ["", _displayName, _symbol]; + _listbox lnbSetData [[_index, 1], _x]; + _listbox lnbSetPicture [[_index, 0], _picture]; + _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; + _listbox lnbSetColor [[_index, 1], [1, 1, 1, _alpha]]; + _listbox lnbSetColor [[_index, 2], [1, 1, 1, _alpha]]; + }; +} forEach _categoryItems; + +_listbox lnbSort [1]; diff --git a/addons/arsenal/functions/fnc_attributeClear.sqf b/addons/arsenal/functions/fnc_attributeClear.sqf new file mode 100644 index 0000000000..a0a8cb070d --- /dev/null +++ b/addons/arsenal/functions/fnc_attributeClear.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: mharis001 + * Clears all items from current category in 3DEN attribute. + * + * Arguments: + * 0: Attribute controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_arsenal_fnc_attributeClear + * + * Public: No + */ + +params ["_controlsGroup"]; + +private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) - 1; +private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; +TRACE_1("Handling clear button",_category); + +// Remove all if no specific category +if (_category == -1) then { + _attributeValue set [0, []]; +} else { + // Find category items and remove from list + private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); + private _categoryItems = switch (true) do { + case (_category < 3): { + _configItems select 0 select _category; + }; + case (_category < 7): { + _configItems select 1 select (_category - 3); + }; + default { + _configItems select (_category - 5); + }; + }; + _attributeValue set [0, (_attributeValue select 0) - _categoryItems]; +}; + +// Refresh the list after clear +[_controlsGroup] call FUNC(attributeAddItems); diff --git a/addons/arsenal/functions/fnc_attributeDblClick.sqf b/addons/arsenal/functions/fnc_attributeDblClick.sqf new file mode 100644 index 0000000000..6cb9314bcf --- /dev/null +++ b/addons/arsenal/functions/fnc_attributeDblClick.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Handles double clicking a row in 3DEN attribute listbox. + * + * Arguments: + * 0: Listbox + * 1: Row index + * + * Return Value: + * None + * + * Example: + * [CONTROL, 0] call ace_arsenal_fnc_attributeDblClick + * + * Public: No + */ + +params ["_listbox", "_currentRow"]; +TRACE_1("Double click toggle",_currentRow); + +// Get toggle mode (add or remove item) +private _itemClassname = _listbox lnbData [_currentRow, 1]; +private _addItem = !(_itemClassname in ((uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]) select 0)); + +[ctrlParentControlsGroup _listbox, _addItem] call FUNC(attributeSelect); diff --git a/addons/arsenal/functions/fnc_attributeInit.sqf b/addons/arsenal/functions/fnc_attributeInit.sqf new file mode 100644 index 0000000000..8c1556fcd6 --- /dev/null +++ b/addons/arsenal/functions/fnc_attributeInit.sqf @@ -0,0 +1,40 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Initializes the objects 3DEN attribute at scenario start. + * + * Arguments: + * 0: Attribute target + * 1: Attribute value + * + * Return Value: + * None + * + * Example: + * [box, [[], 1]] call ace_arsenal_fnc_attributeInit + * + * Public: No + */ + +params ["_object", "_value"]; +_value params ["_items", "_mode"]; +TRACE_2("Initializing object with attribute",_object,_value); + +if (_mode > 0) then { + // Blacklist: add full arsenal and take items away + [_object, true, true] call FUNC(initBox); + + // Need to delay removal by 2 frames + [{ + [{ + params ["_object", "_items"]; + [_object, _items, true] call FUNC(removeVirtualItems); + }, _this] call CBA_fnc_execNextFrame; + }, [_object, _items]] call CBA_fnc_execNextFrame; +} else { + // Exit on whitelist mode with no items + if (_items isEqualTo []) exitWith {}; + + // Whitelist: add only selected items + [_object, _items, true] call FUNC(initBox); +}; diff --git a/addons/arsenal/functions/fnc_attributeLoad.sqf b/addons/arsenal/functions/fnc_attributeLoad.sqf new file mode 100644 index 0000000000..b2b3f13b1e --- /dev/null +++ b/addons/arsenal/functions/fnc_attributeLoad.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: mharis001 + * Initializes the 3DEN attribute. + * + * Arguments: + * 0: Attribute controls group + * 1: Attribute value + * + * Return Value: + * None + * + * Example: + * [CONTROL, [[], 0]] call ace_arsenal_fnc_attributeLoad + * + * Public: No + */ + +params ["_controlsGroup", "_value"]; +TRACE_1("Initializing 3DEN attribute",_value); + +// Store working attribute value +uiNamespace setVariable [QGVAR(attributeValue), _value]; + +// Handle selected mode +if (_value select 1 > 0) then { + (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_MODE) lbSetCurSel 1; + (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_LIST_RIGHT) ctrlSetText SYMBOL_ITEM_REMOVE; +}; + +[_controlsGroup] call FUNC(attributeAddItems); diff --git a/addons/arsenal/functions/fnc_attributeMode.sqf b/addons/arsenal/functions/fnc_attributeMode.sqf new file mode 100644 index 0000000000..807fea2ec4 --- /dev/null +++ b/addons/arsenal/functions/fnc_attributeMode.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: mharis001 + * Handles changing the mode in 3DEN attribute. + * + * Arguments: + * 0: Attribute controls group + * 1: Mode + * + * Return Value: + * None + * + * Example: + * [CONTROL, 0] call ace_arsenal_fnc_attributeMode + * + * Public: No + */ + +params ["_controlsGroup", "_mode"]; +TRACE_1("Changing attribute mode",_mode); + +// Store mode change +private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; +_attributeValue set [1, _mode]; + +// Change right list button and refresh list items with new mode +(_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_LIST_RIGHT) ctrlSetText ([SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _mode); +[_controlsGroup] call FUNC(attributeAddItems); diff --git a/addons/arsenal/functions/fnc_attributeSelect.sqf b/addons/arsenal/functions/fnc_attributeSelect.sqf new file mode 100644 index 0000000000..7af0ecc764 --- /dev/null +++ b/addons/arsenal/functions/fnc_attributeSelect.sqf @@ -0,0 +1,49 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: mharis001 + * Handles adding/removing an item from 3DEN attribute list. + * + * Arguments: + * 0: Attribute controls group + * 1: Add (true) or remove (false) item + * + * Return Value: + * None + * + * Example: + * [CONTROL, true] call ace_arsenal_fnc_attributeSelect + * + * Public: No + */ + +params ["_controlsGroup", "_addItem"]; + +// Get item class from listbox +private _listbox = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_LIST; +private _currentRow = lnbCurSelRow _listbox; +private _itemClassname = _listbox lnbData [_currentRow, 1]; +TRACE_2("Handling item selection",_itemClassname,_addItem); + +private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; +_attributeValue params ["_attributeItems", "_attributeMode"]; + +private _findItem = _attributeItems find _itemClassname; + +// Add item if not already in list +if (_addItem && {_findItem < 0}) exitWith { + _attributeItems pushBack _itemClassname; + // Change symbol and increase alpha + _listbox lnbSetText [[_currentRow, 2], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode]; + _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 1]]; + _listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 1]]; +}; + +// Remove item if in list +if (!_addItem && {_findItem > -1}) exitWith { + _attributeItems deleteAt _findItem; + // Change symbol and reduce alpha + _listbox lnbSetText [[_currentRow, 2], SYMBOL_ITEM_NONE]; + _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 0.5]]; + _listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 0.5]]; +}; diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf new file mode 100644 index 0000000000..cc8cdf45bf --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -0,0 +1,92 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * 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 +*/ + +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..8e1d70d6eb --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonClearAll.sqf @@ -0,0 +1,62 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Clear the current container. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ + +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..86caf418e3 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonExport.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Export current loadout / default loadouts list to clipboard. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ + +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); +}; + +[QGVAR(loadoutExported), [_display, GVAR(shiftState)]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonHide.sqf b/addons/arsenal/functions/fnc_buttonHide.sqf new file mode 100644 index 0000000000..23e4f7d081 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonHide.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Hide / show arsenal interface. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ + +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, + IDC_statsButton, + IDC_statsPreviousPage, + IDC_statsNextPage, + IDC_statsCurrentPage, + IDC_statsButtonClose +]; + +[QGVAR(statsToggle), [_display, _showToggle]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonImport.sqf b/addons/arsenal/functions/fnc_buttonImport.sqf new file mode 100644 index 0000000000..3eefba41a4 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonImport.sqf @@ -0,0 +1,104 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Import loadout / default loadouts list from clipboard. + * + * Arguments: + * 0: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ + +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 call FUNC(addDefaultLoadout); + }; + } 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); + }; +}; + +[QGVAR(loadoutImported), [_display, (GVAR(shiftState) && {is3DEN})]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf new file mode 100644 index 0000000000..a1d39b1423 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf @@ -0,0 +1,55 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Delete / unshare loadout currently selected. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ + +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..0a2faccc54 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf @@ -0,0 +1,99 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Load selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ + +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"); + + if (_simulationType != "NVGoggles") then { + if (_simulationType == "ItemGps" || _simulationType == "Weapon") then { + GVAR(currentItems) set [14, _x]; + } else { + + private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch"] 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); + +[QGVAR(onLoadoutLoad), [_loadout, _loadoutName]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf new file mode 100644 index 0000000000..a1f9294669 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf @@ -0,0 +1,70 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Rename selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ + +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..78e02431a4 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf @@ -0,0 +1,288 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Save selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ + +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 _loadoutIndex = _data findIf {(_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 (_loadoutIndex == -1) then { + _data pushBack [_editBoxContent, _loadout]; + } else { + _data set [_loadoutIndex, [[_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 _loadoutIndex = _data findIf {(_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 (_loadoutIndex == -1) then { + GVAR(defaultLoadoutsList) pushBack [_editBoxContent, _loadout]; + } else { + GVAR(defaultLoadoutsList) set [_loadoutIndex, [[_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 (_loadoutIndex == -1) then { + _data pushBack [_editBoxContent, _curSelLoadout]; + } else { + _data set [_loadoutIndex, [[_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 (_loadoutIndex == -1) then { + _data pushBack [_editBoxContent, _loadout]; + } else { + _data set [_loadoutIndex, [[_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..a9a1dd9d08 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf @@ -0,0 +1,55 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Share selected loadout. + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ + +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_buttonStats.sqf b/addons/arsenal/functions/fnc_buttonStats.sqf new file mode 100644 index 0000000000..0eaac78a41 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonStats.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Toggle the stats control group + * + * Arguments: + * 0: Arsenal display + * 1: Button control + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_display"]; + +(_display displayCtrl IDC_statsButton) ctrlShow GVAR(showStats); +GVAR(showStats) = !GVAR(showStats); + +{ + (_display displayCtrl _x) ctrlShow GVAR(showStats); +} foreach [ + IDC_statsBox, + IDC_statsPreviousPage, + IDC_statsNextPage, + IDC_statsCurrentPage, + IDC_statsButtonClose +]; + diff --git a/addons/arsenal/functions/fnc_buttonStatsPage.sqf b/addons/arsenal/functions/fnc_buttonStatsPage.sqf new file mode 100644 index 0000000000..48c9b4715e --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonStatsPage.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles the previous / next page buttons for stats + * + * Arguments: + * 0: Arsenal display + * 1: Previous or next (false = previous, true = next) + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_display", "_control", "_nextPage"]; + +TRACE_1("control enabled", ctrlEnabled _control); +if !(ctrlEnabled _control) exitWith {}; + +GVAR(statsInfo) params ["_isLeftPanel", "_statsIndex", "_panelControl", "_curSel", "_itemCfg"]; + +private _pageList = [GVAR(statsPagesRight), GVAR(statsPagesLeft)] select (_isLeftPanel); +private _newPageNumber = [(_pageList select _statsIndex) - 1, (_pageList select _statsIndex) + 1] select _nextPage; + +_pageList set [_statsIndex, _newPageNumber]; + +[QGVAR(displayStats), [_display, _panelControl, _curSel, _itemCfg]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_clearSearchbar.sqf b/addons/arsenal/functions/fnc_clearSearchbar.sqf new file mode 100644 index 0000000000..a6b7b534dc --- /dev/null +++ b/addons/arsenal/functions/fnc_clearSearchbar.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Clear the provided searchbar. + * + * Arguments: + * 0: Arsenal display + * 1: Searchbar control + * 2: Right button state + * + * Return Value: + * None + * + * Public: No +*/ + +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_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf new file mode 100644 index 0000000000..40c9d7cfa5 --- /dev/null +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -0,0 +1,135 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Create the internal stats arrays when needed for the first time + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +if (!isNil QGVAR(statsListLeftPanel)) exitWith {}; + +private _fnc_addToTabs = { + params ["_tabsList", "_tabsToAddTo", "_sideString"]; + { + private _currentTab = _tabsList select _x; + private _availablePagesCount = {count _x < 5} count _currentTab; + + private _arrayToSave = +_finalArray; + _arrayToSave set [0, ([_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString "")]; + + if (_availablePagesCount > 0) then { + + { + if (count _x < 5) exitWith { + (_currentTab select _forEachIndex) append [_arrayToSave]; + }; + } foreach _currentTab; + } else { + _currentTab pushBack [_arrayToSave]; + }; + } foreach _tabsToAddTo; +}; + +private _fnc_sortLists = { + params ["_tabsList"]; + + { + private _page = _x; + { + { + reverse _x; + } foreach _x; + + _x sort false; + + { + reverse _x; + } foreach _x; + } foreach _page; + } foreach _tabsList; +}; + +private _statsListLeftPanel = [ + [[]], // Primary 0 + [[]], // Handgun 1 + [[]], // Launcher 2 + [[]], // Uniform 3 + [[]], // Vests 4 + [[]], // Backpacks 5 + [[]], // Headgear 6 + [[]], // Goggles 7 + [[]], // NVGs 8 + [[]], // Binoculars 9 + [[]], // Map 10 + [[]], // GPS 11 + [[]], // Radio 12 + [[]], // Compass 13 + [[]] // Watch 14 +]; + +private _statsListRightPanel = [ + [[]], // Optics 0 + [[]], // Side accs 1 + [[]], // Muzzle 2 + [[]], // Bipod 3 + [[]], // Mag 4 + [[]], // Throw 5 + [[]], // Put 6 + [[]] // Misc 7 +]; + +//------------------------- Config handling +private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> QGVAR(stats)); + +{ + private _finalArray = []; + + private _class = configName _x; + private _stats = getArray (_x >> "stats"); + private _displayName = getText (_x >> "displayName"); + private _showBar = getNumber (_x >> "showBar") == 1; + private _showText = getNumber (_x >> "showText") == 1; + private _condition = getText (_x >> "condition"); + private _priority = getNumber (_x >> "priority"); + (getArray (_x >> "tabs")) params ["_leftTabsList", "_rightTabsList"]; + + if (_condition != "") then { + _condition = compile _condition; + }; + + _finalArray = ["", _stats, _displayName, [_showBar, _showText], [{}, {}, _condition], _priority]; + + if (_showBar) then { + private _barStatement = compile (getText (_x >> "barStatement")); + (_finalArray select 4) set [0, _barStatement]; + }; + + if (_showText) then { + private _textStatement = compile (getText (_x >> "textStatement")); + (_finalArray select 4) set [1, _textStatement]; + }; + + TRACE_3("stats array", _finalArray, _leftTabsList, _rightTabsList); + + if (count _leftTabsList > 0) then { + [_statsListLeftPanel, _leftTabsList, "L"] call _fnc_addToTabs; + }; + + if (count _rightTabsList > 0) then { + [_statsListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; + }; +} foreach _configEntries; + +[_statsListLeftPanel] call _fnc_sortLists; +[_statsListRightPanel] call _fnc_sortLists; + +//------------------------- Config Handling + +missionNamespace setVariable [QGVAR(statsListLeftPanel), _statsListLeftPanel]; +missionNamespace setVariable [QGVAR(statsListRightPanel), _statsListRightPanel]; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf new file mode 100644 index 0000000000..5009f46e3a --- /dev/null +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -0,0 +1,205 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Fill left panel. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ + +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; + +// Force a "refresh" animation of the panel +_ctrlPanel ctrlSetFade 1; +_ctrlPanel ctrlCommit 0; +_ctrlPanel ctrlSetFade 0; +_ctrlPanel 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")); + + { + private _displayName = getText (_x >> "displayName"); + private _className = configName _x; + private _lbAdd = _ctrlPanel lbAdd _displayName; + + _ctrlPanel lbSetData [_lbAdd, _className]; + _ctrlPanel lbSetPicture [_lbAdd, getText (_x >> "texture")]; + _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; + } foreach ("true" configClasses (missionConfigFile >> "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..433f0304df --- /dev/null +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -0,0 +1,126 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Fill loadouts list. + * + * Arguments: + * 0: Loadouts display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ + +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); + +// Force a "refresh" animation of the panel +_contentPanelCtrl ctrlSetFade 1; +_contentPanelCtrl ctrlCommit 0; +_contentPanelCtrl ctrlSetFade 0; +_contentPanelCtrl ctrlCommit FADE_DELAY; + +_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}); +}; + +[QGVAR(loadoutsListFilled), [_display, _control]] call CBA_fnc_localEvent; + +_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..a5f60c593c --- /dev/null +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -0,0 +1,367 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Fill right panel. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ + +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; + { + ((_compatibleMagazines select _index) select _subIndex) pushBackUnique (configName (configFile >> "CfgMagazines" >> _x)) + } foreach ([getArray (_weaponConfig >> _x >> "magazines"), getArray (_weaponConfig >> "magazines")] select (_x == "this")); + + // Magazine groups + { + private _magazineGroups = uiNamespace getVariable [QGVAR(magazineGroups),["#CBA_HASH#",[],[],[]]]; + private _magArray = [_magazineGroups, toLower _x] call CBA_fnc_hashGet; + {((_compatibleMagazines select _index) select _subIndex) pushBackUnique _x} forEach _magArray; + } foreach ([getArray (_weaponConfig >> _x >> "magazineWell"), getArray (_weaponConfig >> "magazineWell")] 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; + }; +}; + +// Force a "refresh" animation of the panel +_ctrlPanel ctrlSetFade 1; +_ctrlPanel ctrlCommit 0; +_ctrlPanel ctrlSetFade 0; +_ctrlPanel ctrlCommit FADE_DELAY; + +_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); + }; +}; + +(_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..2911e7aa19 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles keyboard inputs inside the searchbars text boxes. + * + * Arguments: + * 0: Loadouts display + * 1: Searchbar control + * + * Return Value: + * None + * + * Public: No +*/ + +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..7d2fa2c9e2 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleMouse.sqf @@ -0,0 +1,68 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * 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 +*/ + +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)]; + + 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..0fec3e7c5b --- /dev/null +++ b/addons/arsenal/functions/fnc_handleScrollWheel.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handle the mouse wheel. + * + * Arguments: + * 0: Not used + * 1: Mousewheel Z position + * + * Return Value: + * None + * + * Public: No +*/ + +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..5632006f43 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleSearchbar.sqf @@ -0,0 +1,92 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles keyboard inputs inside the searchbars text boxes. + * + * Arguments: + * 0: Arsenal display + * 1: Searchbar control + * + * Return Value: + * None + * + * Public: No +*/ + +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_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf new file mode 100644 index 0000000000..0c57f6c721 --- /dev/null +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -0,0 +1,244 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles the stats control group + * + * Arguments: + * 0: Arsenal display + * 1: Current panel control + * 2: Current panel selection + * 3: Item config entry + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_display", "_control", "_curSel", "_itemCfg"]; + +private _statsBoxCtrl = _display displayCtrl IDC_statsBox; +private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage; +private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage; +private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage; + +private _hideUnusedFnc = { + params ["_numbers"]; + + { + private _statsTitleCtrl = _display displayCtrl (5101 + ((_x - 1) * 4)); + private _statsTitleIDC = ctrlIDC _statsTitleCtrl; + + private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); + private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); + private _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3); + + { + _x ctrlSetFade 1; + _x ctrlCommit 0; + } forEach [ + _statsTitleCtrl, + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; + } forEach _numbers; +}; + +if !(isNil "_itemCfg") then { + + private _handleStatsFnc = { + params ["_statsIndex", "_leftPanel"]; + + // Get the proper list and page + if (_leftPanel) then { + [true, (GVAR(statsListLeftPanel)) select _statsIndex, GVAR(statsPagesLeft) select _statsIndex] + } else { + [false, (GVAR(statsListRightPanel)) select _statsIndex, GVAR(statsPagesRight) select _statsIndex] + } params ["_isLeftPanel", "_statsArray", "_currentPage"]; + + private _statsList = _statsArray select _currentPage; + + private _statsCount = 0; + + // Handle titles, bars and text + _statsList = _statsList select [0, 5]; + if !(_statsList isEqualTo []) then { + { + _x params ["_ID", "_configEntry", "_title", "_bools", "_statements"]; + _bools params ["_showBar", "_showText"]; + _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; + + private _statsTitleCtrl = _display displayCtrl (5101 + _forEachIndex * 4); + private _statsTitleIDC = ctrlIDC _statsTitleCtrl; + private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); + private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); + private _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3); + + _statsCount = _statsCount + 1; + _statsTitleCtrl ctrlSetText _title; + _statsTitleCtrl ctrlSetFade 0; + + // Handle bars + if (_showBar) then { + _statsBarCtrl progressSetPosition ([_configEntry, _itemCfg] call _barStatement); + + _statsBackgroundCtrl ctrlSetFade 0; + _statsBarCtrl ctrlSetFade 0; + } else { + _statsBackgroundCtrl ctrlSetFade 1; + _statsBarCtrl ctrlSetFade 1; + }; + + // Handle text entries + if (_showText) then { + private _textStatementResult = [_configEntry, _itemCfg] call _textStatement; + + if (_textStatementResult isEqualtype "") then { + _statsTextCtrl ctrlSetText _textStatementResult; + } else { + _statsTextCtrl ctrlSetText (str _textStatementResult); + }; + _statsTextCtrl ctrlSetTextColor ([[1,1,1,1], [0,0,0,1]] select (_showBar)); + + _statsTextCtrl ctrlSetFade 0; + } else { + _statsTextCtrl ctrlSetFade 1; + }; + + { + _x ctrlCommit 0; + } forEach [ + _statsTitleCtrl, + _statsBackgroundCtrl, + _statsBarCtrl, + _statsTextCtrl + ]; + } forEach (_statsList select { + _x params ["_ID","_configEntry", "_title", "_bools", "_statements"]; + _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; + + ([_configEntry, _itemCfg] call _condition) + }); + }; + + // Resize the window + [[1, 2, 3, 4, 5] select [_statsCount, 5]] call _hideUnusedFnc; + _statsBoxCtrl ctrlSetPosition [ + (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, + safezoneY + 1.8 * GRID_H, + 47 * GRID_W, + ([11, (10 * _statsCount) + 5] select (_statsCount > 0)) * GRID_H + ]; + _statsBoxCtrl ctrlCommit 0; + + GVAR(statsInfo) = [_isLeftPanel, _statsIndex, _control, _curSel, _itemCfg]; + + // Toggle page buttons + _statsPreviousPageCtrl ctrlEnable !(_currentPage == 0); + _statsNextPageCtrl ctrlEnable !(_currentPage + 1 >= count _statsArray); + _statsCurrentPageCtrl ctrlSetText ([localize LSTRING(page), str (_currentPage + 1)] joinString " "); + + { + _x ctrlSetFade 0; + _x ctrlCommit 0; + } forEach [ + _statsPreviousPageCtrl, + _statsNextPageCtrl, + _statsCurrentPageCtrl + ]; + }; + + if (ctrlIDC _control == IDC_leftTabContent) then { + + if ([IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsigna] find GVAR(currentLeftPanel) > -1) then { + + [[1, 2, 3, 4, 5]] call _hideUnusedFnc; + _statsBoxCtrl ctrlSetPosition [ + (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, + safezoneY + 1.8 * GRID_H, + 47 * GRID_W, + 11 * GRID_H + ]; + _statsBoxCtrl ctrlCommit 0; + + { + _x ctrlSetFade 1; + _x ctrlCommit 0; + } forEach [ + _statsPreviousPageCtrl, + _statsNextPageCtrl, + _statsCurrentPageCtrl + ]; + } else { + [[ + IDC_buttonPrimaryWeapon, + IDC_buttonHandgun, + IDC_buttonSecondaryWeapon, + IDC_buttonUniform, + IDC_buttonVest, + IDC_buttonBackpack, + IDC_buttonHeadgear, + IDC_buttonGoggles, + IDC_buttonNVG, + IDC_buttonBinoculars, + IDC_buttonMap, + IDC_buttonGPS, + IDC_buttonRadio, + IDC_buttonCompass, + IDC_buttonWatch + ] find GVAR(currentLeftPanel), true] call _handleStatsFnc; + }; + } else { + + switch (GVAR(currentRightPanel)) do { + case IDC_buttonOptic: { + [0, false] call _handleStatsFnc; + }; + case IDC_buttonItemAcc: { + [1, false] call _handleStatsFnc; + }; + case IDC_buttonMuzzle: { + [2, false] call _handleStatsFnc; + }; + case IDC_buttonBipod: { + [3, false] call _handleStatsFnc; + }; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: { + [4, false] call _handleStatsFnc; + }; + case IDC_buttonThrow: { + [5, false] call _handleStatsFnc; + }; + case IDC_buttonPut: { + [6, false] call _handleStatsFnc; + }; + case IDC_buttonMisc: { + [7, false] call _handleStatsFnc; + }; + }; + }; +} else { + + [[1, 2, 3, 4, 5]] call _hideUnusedFnc; + _statsBoxCtrl ctrlSetPosition [ + (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, + safezoneY + 1.8 * GRID_H, + 47 * GRID_W, + 11 * GRID_H + ]; + _statsBoxCtrl ctrlCommit 0; + + { + _x ctrlSetFade 1; + _x ctrlCommit 0; + } forEach [ + _statsPreviousPageCtrl, + _statsNextPageCtrl, + _statsCurrentPageCtrl + ]; +}; diff --git a/addons/arsenal/functions/fnc_initBox.sqf b/addons/arsenal/functions/fnc_initBox.sqf new file mode 100644 index 0000000000..1343a20f63 --- /dev/null +++ b/addons/arsenal/functions/fnc_initBox.sqf @@ -0,0 +1,61 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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] 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..85a848c3bd --- /dev/null +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -0,0 +1,79 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * 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 +*/ + +params ["_display", "_control", "_curSel" ,"_itemCfg"]; + +private _ctrlInfo = _display displayCtrl IDC_infoBox; + +if (isClass _itemCfg) then { + + _ctrlInfo ctrlSetFade 0; + _ctrlInfo ctrlCommit FADE_DELAY; + + [QGVAR(displayStats), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; + + // 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 { + [QGVAR(displayStats), [_display, _control, -1, nil]] call CBA_fnc_localEvent; + + _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..df5d8a5804 --- /dev/null +++ b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf @@ -0,0 +1,79 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles tab changing for the loadouts display. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * + * Return Value: + * None + * + * Public: No +*/ + +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; + +[QGVAR(loadoutsTabChanged), [_display, _control]] call CBA_fnc_localEvent; + +[_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..8fbd48748f --- /dev/null +++ b/addons/arsenal/functions/fnc_message.sqf @@ -0,0 +1,54 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Displays messages in arsenal. + * + * Arguments: + * 0: Arsenal display + * 1: Message + * + * Return Value: + * None + * + * Public: No +*/ + +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..f4ad7dfed8 --- /dev/null +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -0,0 +1,107 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * onUnLoad EH for arsenal. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +(_this select 1) params ["", "_exitCode"]; + +private _cameraData = [getposAtl GVAR(camera), (getposAtl GVAR(camera)) vectorFromTo (getposAtl GVAR(cameraHelper))]; + +[QGVAR(displayClosed), []] call CBA_fnc_localEvent; +removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; + +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 (!(isnull curatorCamera) && {ACE_player == player}) then { + curatorcamera cameraEffect ["internal","back"]; + } else { + GVAR(camera) cameraEffect ["terminate","back"]; + ACE_player switchCamera GVAR(cameraView); + }; +}; + +deleteVehicle GVAR(cameraHelper); +camDestroy GVAR(camera); + +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; +}; + +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(showStats) = nil; +GVAR(statsPagesLeft) = nil; +GVAR(statsPagesRight) = nil; +GVAR(statsInfo) = nil; + +GVAR(center) = nil; +GVAR(centerNotPlayer) = nil; + +[QUOTE(ADDON), []] call EFUNC(common,showHud); diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf new file mode 100644 index 0000000000..222232b1de --- /dev/null +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -0,0 +1,347 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * onLoad EH for arsenal. + * + * Arguments: + * 0: Ignored + * 1: Arguments + * 1.1: Arsenal display + * + * Return Value: + * None + * + * Public: No +*/ + +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; + +GVAR(showStats) = true; +GVAR(statsPagesLeft) = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; +GVAR(statsPagesRight) = [0, 0, 0, 0, 0, 0, 0, 0]; +GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; + +// 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"); + + if (_simulationType != "NVGoggles") then { + if (_simulationType == "ItemGps" || _simulationType == "Weapon") then { + GVAR(currentItems) set [14, _x]; + } else { + + private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch"] 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), [_display]] 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 +]; + +// Handle stats +private _statsBoxCtrl = _display displayCtrl IDC_statsBox; +_statsBoxCtrl ctrlSetPosition [ + (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, + safezoneY + 1.8 * GRID_H, + 47 * GRID_W, + 11 * GRID_H +]; +_statsBoxCtrl ctrlEnable false; +_statsBoxCtrl ctrlCommit 0; + +(_display displayCtrl IDC_statsButton) ctrlShow false; + +// Disable import in MP +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"; +[QUOTE(ADDON), [false, true, true, true, true, true, true, false, true, true]] call EFUNC(common,showHud); + +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"); +} else { + GVAR(centerNotPlayer) = (GVAR(center) != player); + + { + private _ctrl = _display displayCtrl _x; + _ctrl ctrlEnable GVAR(enableIdentityTabs); + _ctrl ctrlSetFade ([0.6, 0] select GVAR(enableIdentityTabs)); + _ctrl ctrlCommit 0; + } forEach [ + IDC_buttonFace, + IDC_buttonVoice, + IDC_buttonInsigna + ]; +}; + +//--------------- 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..a66ab3784d --- /dev/null +++ b/addons/arsenal/functions/fnc_onKeyDown.sqf @@ -0,0 +1,206 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" +/* + * 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 +*/ + +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 / export classname + case (_keyPressed == DIK_C && {_ctrlState}): { + if (GVAR(leftTabFocus) || {GVAR(rightTabFocus)} || {GVAR(rightTabLnBFocus)}) then { + switch true do { + case (GVAR(leftTabFocus)): { + private _control = (_display displayCtrl IDC_leftTabContent); + _control lbData (lbCurSel _control) + }; + case (GVAR(rightTabFocus)): { + private _control = (_display displayCtrl IDC_rightTabContent); + _control lbData (lbCurSel _control) + }; + case (GVAR(rightTabLnBFocus)): { + private _control = (_display displayCtrl IDC_rightTabContentListnBox); + _control lnbData [(lnbCurSelRow _control), 0] + }; + } params ["_className"]; + + "ace_clipboard" callExtension (_className + ";"); + "ace_clipboard" callExtension "--COMPLETE--"; + + [_display, localize LSTRING(exportedClassnameText)] call FUNC(message); + } else { + [_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]; + }; + // Panel up down + case (_keyPressed in [DIK_UP, DIK_DOWN]): { + if (GVAR(leftTabFocus) || {GVAR(rightTabFocus)} || {GVAR(rightTabLnBFocus)}) then { + _return = false; + }; + }; + // Right panel lnb + and - buttons + case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { + if (GVAR(rightTabLnBFocus)) then { + [_display, [1, 0] select (_keyPressed == DIK_LEFT)] call FUNC(buttonCargo); + }; + }; + }; + } 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); + }; + }; + }; + }; +}; + +_return diff --git a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf new file mode 100644 index 0000000000..1b25ad4945 --- /dev/null +++ b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * onUnLoad EH for arsenal loadouts display. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +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); + +[QGVAR(loadoutsDisplayClosed), []] call CBA_fnc_localEvent; + +[_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..d22124359d --- /dev/null +++ b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf @@ -0,0 +1,62 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * onLoad EH for arsenal loadouts display. + * + * Arguments: + * 0: Ignored + * 1: Arguments + * 1.1: Loadouts display + * + * Return Value: + * None + * + * Public: No +*/ + +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; +}; + +[QGVAR(loadoutsDisplayOpened), [_display]] call CBA_fnc_localEvent; + +[_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..acc1d12741 --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -0,0 +1,426 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles selection changes on the left panel. + * + * Arguments: + * 0: Left panel control + * 1: Left panel selection + * + * Return Value: + * None + * + * Public: No +*/ + +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]}); + +private _fnc_clearPreviousWepMags = { + 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)]; +}; + +switch (GVAR(currentLeftPanel)) do { + + case IDC_buttonPrimaryWeapon : { + private _baseWeapon = ((GVAR(currentItems) select 0) call bis_fnc_baseWeapon); + + if (_item == "") then { + call _fnc_clearPreviousWepMags; + + GVAR(center) removeWeapon (primaryWeapon GVAR(center)); + GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [0, _item]; + + TOGGLE_RIGHT_PANEL_HIDE + } else { + if ((GVAR(currentItems) select 0) != _item && {_baseWeapon != _item}) then { + call _fnc_clearPreviousWepMags; + + private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; + GVAR(center) addWeaponGlobal _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]; + }; + + 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 (_item == "") then { + call _fnc_clearPreviousWepMags; + + GVAR(center) removeWeapon (handgunWeapon GVAR(center)); + GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [2, _item]; + + TOGGLE_RIGHT_PANEL_HIDE + } else { + if ((GVAR(currentItems) select 2) != _item && {_baseWeapon != _item}) then { + call _fnc_clearPreviousWepMags; + + private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; + GVAR(center) addWeaponGlobal _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]; + }; + + 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 (_item == "") then { + call _fnc_clearPreviousWepMags; + + GVAR(center) removeWeapon (secondaryWeapon GVAR(center)); + GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [1, _item]; + TOGGLE_RIGHT_PANEL_HIDE + } else { + if ((GVAR(currentItems) select 1) != _item && {_baseWeapon != _item}) then { + call _fnc_clearPreviousWepMags; + + private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; + GVAR(center) addWeaponGlobal _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]; + }; + + 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 { + if ((GVAR(currentItems) select 3) != _item) then { + 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 { + + if ((GVAR(currentItems) select 4) != _item) then { + 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 { + + if ((GVAR(currentItems) select 5) != _item) then { + 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 { + + if ((GVAR(currentItems) select 6) != _item) then { + removeBackpack GVAR(center); + GVAR(center) addBackpackGlobal _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 { + if ((GVAR(currentItems) select 7) != _item) then { + 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 { + if ((GVAR(currentItems) select 8) != _item) then { + 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 { + if ((GVAR(currentItems) select 9) != _item) then { + GVAR(center) addWeaponGlobal _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 { + if ((GVAR(currentItems) select 10) != _item) then { + 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 { + if ((GVAR(currentItems) select 11) != _item) then { + 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 { + if ((GVAR(currentItems) select 12) != _item) then { + 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 { + if ((GVAR(currentItems) select 13) != _item) then { + 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 { + if ((GVAR(currentItems) select 14) != _item) then { + 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 + + private _unitInsigniaConfig = (configFile >> "CfgUnitInsignia" >> _item); + + if (configName _unitInsigniaConfig isEqualTo "") then { + [_display, _control, _curSel, (missionConfigFile >> "CfgUnitInsignia" >> _item)] call FUNC(itemInfo); + } else { + [_display, _control, _curSel, _unitInsigniaConfig] 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..529f69da75 --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf @@ -0,0 +1,103 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles selection changes on loadouts panel. + * + * Arguments: + * 0: Loadouts panel control + * 1: Loadouts panel selection + * + * Return Value: + * None + * + * Public: No +*/ + +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..a2d83dceba --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -0,0 +1,77 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles selection changes on the right panel. + * + * Arguments: + * 0: Right panel control + * 1: Right panel selection + * + * Return Value: + * None + * + * Public: No +*/ + +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..c2b14c6462 --- /dev/null +++ b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf @@ -0,0 +1,51 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Handles selection changes on the right panel (listnbox). + * + * Arguments: + * 0: Right panel control + * 1: Right panel selection + * + * Return Value: + * None + * + * Public: No +*/ + +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..103ec870e1 --- /dev/null +++ b/addons/arsenal/functions/fnc_open3DEN.sqf @@ -0,0 +1,17 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Replace the 3DEN "edit loadout" menu action + * + * Arguments: + * None + * + * Return Value: + * None + * + * + * Public: No +*/ + +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..ce02e6e343 --- /dev/null +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -0,0 +1,58 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +params [["_object", objNull, [objNull]], ["_center", objNull, [objNull]], ["_mode", false, [false]]]; + +if ( + isNull _object || + {isNull _center} || + {!(_center isKindOf "CAManBase")} || + {!(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..0e403eae92 --- /dev/null +++ b/addons/arsenal/functions/fnc_portVALoadouts.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: alganthe + * Port VA loadouts to ACE Arsenal. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: Yes +*/ + +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..ed4ec7de4d --- /dev/null +++ b/addons/arsenal/functions/fnc_removeBox.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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_removeStat.sqf b/addons/arsenal/functions/fnc_removeStat.sqf new file mode 100644 index 0000000000..79f2173798 --- /dev/null +++ b/addons/arsenal/functions/fnc_removeStat.sqf @@ -0,0 +1,60 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Remove a stat from ACE Arsenal. + * + * Arguments: + * 0: Array of IDs (ARRAY) + * + * Return Value: + * None + * + * Example: + * [["scopeStatL00","scopeStatL01","scopeStatL02","scopeStatR07"]] call ace_arsenal_fnc_removeStat; + * + * Public: Yes +*/ + +params ["_IDList"]; + +call FUNC(compileStats); + +{ + private _currentID = _x; + private _stringCount = count _currentID; + private _side = _currentID select [_stringCount - 3, 1]; + private _tab = _currentID select [_stringCount - 2, 2]; + _tab = parseNumber _tab; + + private _tabToChange = if (_side == "R") then { + GVAR(statsListRightPanel) select _tab + } else { + GVAR(statsListLeftPanel) select _tab + }; + + { + _x deleteAt (_x findIf {_x select 0 == _currentID}); + } foreach _tabToChange; +} foreach _IDList; + +// Clear empty pages +private _fnc_deleteEmptyPage = { + params ["_list"]; + { + private _evaluatedTab = _forEachIndex; + { + if (count _x == 0) then { + _markedForDeletion pushBack [_evaluatedTab, _forEachIndex]; + }; + } foreach _x; + + { + (_list select (_x select 0)) deleteAt (_x select 1); + } foreach _markedForDeletion; + } foreach (_this select 0); +}; + +private _markedForDeletion = []; + +[GVAR(statsListLeftPanel)] call _fnc_deleteEmptyPage; +[GVAR(statsListRightPanel)] call _fnc_deleteEmptyPage; diff --git a/addons/arsenal/functions/fnc_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf new file mode 100644 index 0000000000..d96d16e3d6 --- /dev/null +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -0,0 +1,82 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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..840c56d514 --- /dev/null +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -0,0 +1,188 @@ +#include "script_component.hpp" +/* + * Author: Dedmen + * Cache an array of all the compatible items for arsenal. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +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 _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 [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} && + {!(configName _x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])} + ): { + + //Convert type to array index + (_cargo select 1) select ([TYPE_OPTICS,TYPE_FLASHLIGHT,TYPE_MUZZLE,TYPE_BIPOD] find _itemInfoType) pushBackUnique _className; + }; + /* Headgear */ + case (_itemInfoType == TYPE_HEADGEAR): { + (_cargo select 3) pushBackUnique _className; + }; + /* Uniform */\ + case (_itemInfoType == TYPE_UNIFORM): { + (_cargo select 4) pushBackUnique _className; + }; + /* Vest */ + case (_itemInfoType == TYPE_VEST): { + (_cargo select 5) pushBackUnique _className; + }; + /* NVgs */ + case (_simulationType == "NVGoggles"): { + (_cargo select 8) pushBackUnique _className; + }; + /* Binos */ + case (_simulationType == "Binocular" || + ((_simulationType == 'Weapon') && {(getNumber (_x >> 'type') == TYPE_BINOCULAR_AND_NVG)})): { + (_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 (_itemInfoType == TYPE_UAV_TERMINAL): { + (_cargo select 14) pushBackUnique _className; + }; + /* Weapon, at the bottom to avoid adding binos */ + case (isClass (_x >> "WeaponSlotsInfo") && + {getNumber (_x >> 'type') != TYPE_BINOCULAR_AND_NVG}): { + switch (getNumber (_x >> "type")) do { + case TYPE_WEAPON_PRIMARY: { + (_cargo select 0) select 0 pushBackUnique (_className call bis_fnc_baseWeapon); + }; + case TYPE_WEAPON_HANDGUN: { + (_cargo select 0) select 2 pushBackUnique (_className call bis_fnc_baseWeapon); + }; + case TYPE_WEAPON_SECONDARY: { + (_cargo select 0) select 1 pushBackUnique (_className call bis_fnc_baseWeapon); + }; + }; + }; + /* Misc items */ + case ( + _hasItemInfo && + (_itemInfoType in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && + {(_className isKindOf ["CBA_MiscItem", (_configCfgWeapons)])}) || + {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {(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 [TYPE_MAGAZINE_PRIMARY_AND_THROW,TYPE_MAGAZINE_SECONDARY_AND_PUT,1536,TYPE_MAGAZINE_HANDGUN_AND_GL]) && + {!(_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; + }; + }; +} 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]; + +private _magazineGroups = [[],[]] call CBA_fnc_hashCreate; + +private _cfgMagazines = configFile >> "CfgMagazines"; + +{ + private _magList = []; + { + private _magazines = (getArray _x) select {isClass (_cfgMagazines >> _x)}; //filter out non-existent magazines + _magazines = _magazines apply {configName (_cfgMagazines >> _x)}; //Make sure classname case is correct + _magList append _magazines; + } foreach configProperties [_x, "isArray _x", true]; + + [_magazineGroups, toLower configName _x, _magList arrayIntersect _magList] call CBA_fnc_hashSet; +} foreach configProperties [(configFile >> "CfgMagazineWells"), "isClass _x", 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..d9bf74f061 --- /dev/null +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -0,0 +1,75 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Change unit animation / play sound preview. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +if (GVAR(centerNotPlayer)) exitWith {}; + +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..5d3a2af017 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -0,0 +1,73 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe, Dedmen + * Sort arsenal panel. + * + * Arguments: + * 0: Panel's control to sort + * 1: Sorting mode + * + * Return Value: + * None + * + * Public: No +*/ + +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: { + for "_i" from 0 to (((lnbsize _panel) select 0) - 1) do { + _panel lnbSetText [[_i, 2], str (parseNumber (_panel lnbText [_i, 2]) / 1000)]; + }; + + _panel lnbSort [2, true]; + + + for "_i" from 0 to (((lnbsize _panel) select 0) - 1) do { + _panel lnbSetText [[_i, 2], str (parseNumber (_panel lnbText [_i, 2]) * 1000)]; + }; + }; + }; + + 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_statBarStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf new file mode 100644 index 0000000000..141cc262ad --- /dev/null +++ b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Accuracy bar statement. + * + * Arguments: + * 0: stats array (ARRAY) + * 1: item config path (CONFIG) + * 2: Args + * 2.1: Stat limits (ARRAY of BOOL) + * 2.2: Bar limits (ARRAY of SCALAR) + * + * Return Value: + * Number + * + * Public: No +*/ + +params ["_stat", "_config", "_args"]; +_args params ["_statMinMax", "_barLimits"]; + +private _fireModes = getArray (_config >> "modes"); +private _dispersion = []; + +{ + _dispersion pushBackUnique log (getNumber (_config >> _x >> "dispersion")); +} foreach _fireModes; + +_dispersion sort true; + +linearConversion [_statMinMax select 0, _statMinMax select 1, _dispersion param [0, 0], _barLimits select 0, _barLimits select 1] diff --git a/addons/arsenal/functions/fnc_statBarStatement_default.sqf b/addons/arsenal/functions/fnc_statBarStatement_default.sqf new file mode 100644 index 0000000000..4eb0a36f98 --- /dev/null +++ b/addons/arsenal/functions/fnc_statBarStatement_default.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Generic bar statement for stats. + * + * Arguments: + * 0: stat (STRING) + * 1: item config path (CONFIG) + * 2: Args for configExtreme + * 2.1: Stat limits (ARRAY of BOOL) + * 2.2: Bar limits (ARRAY of SCALAR) + * 2.3: Evaluate as a logarithmic number (BOOL) + * + * Return Value: + * Number + * + * Public: Yes +*/ + +params ["_stat", "_config", "_args"]; +_args params ["_statMinMax", "_barLimits", "_configExtremeBool"]; + +private _statValues = [ + [_config], + [_stat], + [_configExtremeBool], + [_statMinMax select 0] +] call BIS_fnc_configExtremes; + +linearConversion [_statMinMax select 0, _statMinMax select 1, (_statValues select 1) select 0, _barLimits select 0, _barLimits select 1] diff --git a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf new file mode 100644 index 0000000000..c8839e85c2 --- /dev/null +++ b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Impact bar statement. + * + * Arguments: + * 0: stats array (ARRAY) + * 1: item config path (CONFIG) + * 2: Args for configExtreme + * 2.1: Stat limits (ARRAY of BOOL) + * 2.2: Bar limits (ARRAY of SCALAR) + * 2.3: Evaluate as a logarithmic number (BOOL) + * + * Return Value: + * Number + * + * Public: No +*/ + +params ["_stats", "_config", "_args"]; +_args params ["_hitMinMax", "_initSpeedMinMax", "_launcherTabIDC"]; + +private _statValues = [ + [_config], + _stats, + [true, false], + [_hitMinMax select 0, _initSpeedMinMax select 0] +] call BIS_fnc_configExtremes; +(_statValues select 1) params ["_hit", "_initSpeed"]; + +_hit = linearConversion [_hitMinMax select 0, _hitMinMax select 1, _hit, 0.01, 1]; +_initSpeed = linearConversion [_initSpeedMinMax select 0, _initSpeedMinMax select 1, _initSpeed, 0.01, 1]; + +[sqrt(_hit^2 * _initSpeed), _hit] select (GVAR(currentLeftPanel) == _launcherTabIDC) diff --git a/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf new file mode 100644 index 0000000000..8e2bd5fef8 --- /dev/null +++ b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Rate of fire bar statement. + * + * Arguments: + * 0: stats array (ARRAY) + * 1: item config path (CONFIG) + * 2: Args + * 2.1: Stat limits (ARRAY of BOOL) + * 2.2: Bar limits (ARRAY of SCALAR) + * + * Return Value: + * Number + * + * Public: No +*/ + +params ["_stat", "_config", "_args"]; +_args params ["_statMinMax", "_barLimits"]; + +private _fireModes = getArray (_config >> "modes"); +private _fireRate = []; + +{ + _fireRate pushBackUnique log (getNumber (_config >> _x >> "reloadTime")); +} foreach _fireModes; + +_fireRate sort true; + +linearConversion [_statMinMax select 0, _statMinMax select 1, _fireRate param [0, 0], _barLimits select 0, _barLimits select 1] diff --git a/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf new file mode 100644 index 0000000000..cb2687097b --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Accuracy text statement. + * + * Arguments: + * 0: stat (STRING) + * 1: item config path (CONFIG) + * 2: Args for configExtreme + * 2.1: Stat limits (ARRAY of BOOL) + * 2.2: Evaluate as a logarithmic number (BOOL) + * + * Return Value: + * Number + * + * Public: No +*/ + +params ["_stat", "_config", "_args"]; +_args params ["_statMinMax", "_configExtremeBool"]; + +private _fireModes = getArray (_config >> "modes"); +private _dispersion = []; + +{ + if (getNumber (_config >> _x >> "showToPlayer") != 0) then { + _dispersion pushBackUnique (getNumber (_config >> _x >> "dispersion")); + }; +} foreach _fireModes; + +_dispersion sort true; +_dispersion = _dispersion param [0, 0]; + +format ["%1 MIL (%2 MOA)", (_dispersion * 1000) toFixed 2, (_dispersion / pi * 10800) ToFixed 1]; diff --git a/addons/arsenal/functions/fnc_statTextStatement_mass.sqf b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf new file mode 100644 index 0000000000..9c2a0501a6 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Text statement for the mass stat. + * + * Arguments: + * 0: not used + * 1: item config path (CONFIG) + * + * Return Value: + * String to display + * + * Public: No +*/ + +params ["", "_config"]; + +private _mass = getNumber (_config >> "mass"); + +if (_mass == 0 && {isClass (_config >> "itemInfo")}) then { + _mass = getNumber (_config >> "itemInfo" >> "mass"); +}; + +if (_mass == 0 && {isClass (_config >> "WeaponSlotsInfo")}) then { + _mass = getNumber (_config >> "WeaponSlotsInfo" >> "mass"); +}; + +format ["%1kg (%2lb)",((_mass * 0.1 * (1/2.2046) * 100) / 100) ToFixed 2, ((_mass * 0.1 * 100) / 100) ToFixed 2] diff --git a/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf b/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf new file mode 100644 index 0000000000..46f66fd52a --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Rate of fire text statement. + * + * Arguments: + * 0: stat (STRING) + * 1: item config path (CONFIG) + * 2: Args for configExtreme + * 2.1: Stat limits (ARRAY of BOOL) + * 2.2: Evaluate as a logarithmic number (BOOL) + * + * Return Value: + * Number + * + * Public: No +*/ + +params ["_stat", "_config", "_args"]; +_args params ["_statMinMax", "_configExtremeBool"]; + +private _fireModes = getArray (_config >> "modes"); +private _fireRate = []; + +{ + _fireRate pushBackUnique (getNumber (_config >> _x >> "reloadTime")); +} foreach _fireModes; + +_fireRate sort true; +_fireRate = _fireRate param [0, 0]; + +format ["%1 rpm", round (60 / _fireRate)] diff --git a/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf b/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf new file mode 100644 index 0000000000..f817ff6c3f --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Text statement for the scope magnification stat. + * + * Arguments: + * 0: not used + * 1: item config path (CONFIG) + * + * Return Value: + * String to display + * + * Public: No + */ + +params ["", "_config"]; +TRACE_1("statTextStatement_scopeMag",_config); + +private _minZoom = 999; // FOV, so smaller is more zoomed in +{ + _minZoom = _minZoom min (getNumber (_x >> "opticsZoomMin")); +} forEach configProperties [_config >> "ItemInfo" >> "OpticsModes"]; + +if (_minZoom in [0, 999]) exitWith {"?"}; + +format ["%1x", (0.25/_minZoom) toFixed 1] diff --git a/addons/arsenal/functions/fnc_updateCamPos.sqf b/addons/arsenal/functions/fnc_updateCamPos.sqf new file mode 100644 index 0000000000..66bad37936 --- /dev/null +++ b/addons/arsenal/functions/fnc_updateCamPos.sqf @@ -0,0 +1,21 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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)]; diff --git a/addons/arsenal/functions/fnc_updateRightPanel.sqf b/addons/arsenal/functions/fnc_updateRightPanel.sqf new file mode 100644 index 0000000000..8114b8a568 --- /dev/null +++ b/addons/arsenal/functions/fnc_updateRightPanel.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Update the right panel (listnbox). + * + * Arguments: + * 0: Right panel control + * 1: Max load of the current container + * + * Return Value: + * None + * + * Public: No +*/ + +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..7405950631 --- /dev/null +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -0,0 +1,118 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Update the list of unique items. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +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..e7ce4fe0a6 --- /dev/null +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -0,0 +1,239 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe + * Verify the provided loadout. + * + * Arguments: + * 0: Loadout (getUnitLoadout format) + * + * Return Value: + * Verified loadout and missing / unavailable items list and count + * + * Public: No +*/ + +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 _mag; + _dataPath set [_forEachIndex, []]; + _unavailableItemsAmount = _unavailableItemsAmount + 1; + }; + } else { + + _nullItemsList pushBackUnique _mag; + _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..5b24421c20 --- /dev/null +++ b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf @@ -0,0 +1,115 @@ +#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]); + + if ((_player getVariable ["cba_projectile_firedEhId", -1]) != -1) then { + _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..3da2fa4b57 --- /dev/null +++ b/addons/arsenal/stringtable.xml @@ -0,0 +1,813 @@ + + + + + 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 equipaggiamento 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 武器庫 + ACE Arsenale + ACE 아스날 + 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 + 記錄遺失/無法使用的項目到RPT檔案中 + 记录遗失/无法使用的项目到RPT档案中 + + + Unable to open ACE arsenal + Impossible d'ouvrir ACE arsenal + Kann ACE-Arsenal nicht anzeigen + Impossibile aprire l'arsenale ACE + ACE 武器庫を開けません + 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 아스날로 가져오기 + 匯入BI原廠虛擬軍火庫的裝備到ACE虛擬軍火庫中 + 汇入BI原厂虚拟军火库的装备到ACE虚拟军火库中 + Importa l'arsenale virtuale BI nell'arsenale 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"と名付けてください。 + 플레이어 유닛을 사용할 수 없습니다! 유닛을 놓고 "플레이어"라고 표시하십시오. + 沒有可用的玩家單位!請擺放一個單位並設定成"玩家" + 没有可用的玩家单位!请摆放一个单位并设定成"玩家"。 + Non ci sono giocatori! Poisziona una unità e impostala come "Giocatore". + + + No loadouts to import. + Aucun loadout à importer. + Keine Ausrüstungen zum Importieren + 取り込みする装備がありません。 + 가져올 로드 아웃이 없습니다. + 沒有裝備被匯入 + 没有装备被汇入。 + Non ci sono equipaggiamenti da importare. + + + ACE Arsenal + ACE-Arsenal + ACE 武器庫 + ACE 아스날 + ACE虛擬軍火庫 + ACE虚拟军火库 + Arsenale ACE + + + Return to ACE Arsenal. + Zurück zum ACE-Arsenal. + ACE 武器庫へ戻ります。 + ACE 아스날로 돌아가기 + 返回到ACE虛擬軍火庫 + 返回到ACE虚拟军火库。 + Torna all'arsenale 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을 사용하여 다른 무기와 장비를 시험해보십시오. + 使用ACE虛擬軍火庫來嘗試不同的武器與裝備 + 使用ACE虚拟军火库来尝试不同的武器与装备。 + Usa l'arsenale ACE per provare armi ed equipaggiamenti vari. + + + Try weapons and equipment and create your own loadouts. + Probiere verschiedene Waffen und Ausrüstung aus und stelle dir eigene Ausrüstungsprofile zusammen. + さまざまな武器と装備を試して、あなただけの装備を作成してください。 + 무기와 장비를 사용해보고 자신의 로드아웃을 만듭니다. + 嘗試不同的武器與裝備來組合你個人的裝備配置 + 尝试不同的武器与装备来组合你个人的装备配置。 + Prova armi ed equipaggiamenti e creai i tuoi equipaggiamenti personalizzati. + + + Open the loadouts screen + Affiche la page des équipements + 開啟裝備選單 + 开启装备选单 + 装備画面を開く + Apri la pagina degli equipaggiamenti + + + Export current / default loadouts + Exporte l'équipement actuel ou la liste d'équipements de base + 匯出當前/預設的裝備 + 汇出当前/预设的装备 + 現在 / 標準装備を出力 + Esporta l'equipaggiamento attuale oppure la lista degli equipaggiamenti di base + + + Import current / default loadouts + Importer l'équipement actuel ou la liste d'équipements de base + 匯入當前/預設的裝備 + 汇入当前/预设的装备 + 現在 / 標準装備を取込 + Importa l'equipaggiamento attuale oppure la lista degli equipaggiamenti di base + + + Potassium levels + Taux de potassium + カリウム レベル + 钾水平 + 鉀水平 + Ilvello di potassio + + + Magnification + 放大倍率 + Grossissement + Aumento + Ingrandimento + Powiększenie + Увеличение + Vergrößerung + Zvětšení + Aumentox + 배율 + 放大倍数 + 拡大倍率 + Büyütme + + + Page + Page + ページ + 页面 + 頁面 + Pagina + + + Enable the faces / voices / insignias tabs + Activer les onglets faces / voix / insignes + 顔 / 声 / 記章タブを有効化 + 启用脸谱/声音/徽章/选项 + 啟用臉譜/聲音/徽章選項 + Abilita volti, voci e insegne + + + Empty the selected container + Vider le conteneur selectionné + 選択されたコンテナは空です + 选择的箱子是空的 + 清空選擇的箱子 + Svuota il contenitore selezionato + + + Exported class name to clipboard + Nom de classe exporté dans le presse papier + クリップボードへクラスネームを出力 + 将种类复制到剪贴板 + 輸出 class name 到剪貼簿上 + Copiato il nome della classe negli appunti + + + Mode + 模式 + Mode + Modo + Modalità + Tryb + Режим + Modus + Režim + Modo + 모드 + 模式 + モード + Mod + + + Whitelist + Biała lista + Lista blanca + Whitelist + Seznam povolených + Lista branca + Liste blanche + Fehérlista + Вайтлист + Lista Bianca + 許可リスト + 화이트리스트 + 白名單 + 白名单 + + + Blacklist + 禁止リスト + Lista Nera + + + Items + 物品 + Objets + Objetos + Oggetti + Przedmioty + Предметы + Gegenstände + Předměty + Itens + 물품 + 物品 + アイテム + Eşyalar + + + Export current items list as an array for use in scripts + スクリプト用に現在のアイテム リストをアレイで出力します + Esporta l'attuale lista di elementi come un array, per essere usati negli script + + + diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp new file mode 100644 index 0000000000..2794e42119 --- /dev/null +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -0,0 +1,1119 @@ +#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 statsBox: RscControlsGroupNoScrollbars { + idc = IDC_statsBox; + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); + y = QUOTE(safezoneY + 1.8 * GRID_H); + w = QUOTE(47 * GRID_W); + h = QUOTE(55 * GRID_H); + class controls { + class statsStaticBackground1: ctrlStaticBackground { + idc = -1; + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(47 * GRID_W); + h = QUOTE(55 * GRID_H); + colorBackground[]={0.1,0.1,0.1,0.5}; + }; + class statsStaticBackground2: ctrlStaticBackground { + idc = -1; + x = QUOTE(0); + y = QUOTE(0); + w = QUOTE(47 * GRID_W); + h = QUOTE(5 * GRID_H); + colorBackground[]={0.1,0.1,0.1,0.8}; + }; + class statsTitle1: RscText { + idc = IDC_statsTitle1; + fade = 1; + x = QUOTE(0 * GRID_W); + y = QUOTE(5 * GRID_H); + w = QUOTE(45 * GRID_W); + h = QUOTE(5 * GRID_H); + colorBackground[]={0,0,0,0}; + colorText[]={0.7,0.7,0.7,1}; + sizeEx = QUOTE(5 * GRID_H); + text = ""; + }; + class statsBackground1: ctrlStaticBackground { + idc = IDC_statsBackground1; + fade = 1; + x = QUOTE(1 * GRID_W); + y = QUOTE(10 * GRID_H); + w = QUOTE(45 * GRID_W); + h = QUOTE(4 * GRID_H); + colorBackground[]={1,1,1,0.15}; + }; + class statsBar1: ctrlProgress { + idc = IDC_statsBar1; + fade = 1; + style = 0; + texture = "#(argb,8,8,3)color(1,1,1,1)"; + colorBar[] = {1,1,1,1}; + colorFrame[] = {0,0,0,0}; + x = QUOTE(1 * GRID_W); + y = QUOTE(10 * GRID_H); + w = QUOTE(45 * GRID_W); + h = QUOTE(4 * GRID_H); + }; + class statsText1: RscText { + idc = IDC_statsText1; + shadow=0; + fade = 1; + colorShadow[]={1,1,1,1}; + colorText[]={0,0,0,1}; + x = QUOTE(0 * GRID_W); + y = QUOTE(10 * GRID_H); + w = QUOTE(45 * GRID_W); + h = QUOTE(4 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + text = ""; + }; + class statsTitle2: statsTitle1 { + idc = IDC_statsTitle2; + y = QUOTE(15 * GRID_H); + }; + class statsBackground2: statsBackground1 { + idc = IDC_statsBackground2; + y = QUOTE(20 * GRID_H); + }; + class statsBar2: statsBar1 { + idc = IDC_statsBar2; + y = QUOTE(20 * GRID_H); + }; + class statsText2: statsText1 { + idc = IDC_statsText2; + y = QUOTE(20 * GRID_H); + }; + class statsTitle3: statsTitle1 { + idc = IDC_statsTitle3; + y = QUOTE(25 * GRID_H); + }; + class statsBackground3: statsBackground1 { + idc = IDC_statsBackground3; + y = QUOTE(30 * GRID_H); + }; + class statsBar3: statsBar1 { + idc = IDC_statsBar3; + y = QUOTE(30 * GRID_H); + }; + class statsText3: statsText1 { + idc = IDC_statsText3; + y = QUOTE(30 * GRID_H); + }; + class statsTitle4: statsTitle1 { + idc = IDC_statsTitle4; + y = QUOTE(35 * GRID_H); + }; + class statsBackground4: statsBackground1 { + idc = IDC_statsBackground4; + y = QUOTE(40 * GRID_H); + }; + class statsBar4: statsBar1 { + idc = IDC_statsBar4; + y = QUOTE(40 * GRID_H); + }; + class statsText4: statsText1 { + idc = IDC_statsText4; + y = QUOTE(40 * GRID_H); + }; + class statsTitle5: statsTitle1 { + idc = IDC_statsTitle5; + y = QUOTE(45 * GRID_H); + }; + class statsBackground5: statsBackground1 { + idc = IDC_statsBackground5; + y = QUOTE(50 * GRID_H); + }; + class statsBar5: statsBar1 { + idc = IDC_statsBar5; + y = QUOTE(50 * GRID_H); + colorBackground[]={1,1,1,0.15}; + }; + class statsText5: statsText1 { + idc = IDC_statsText5; + y = QUOTE(50 * GRID_H); + }; + }; + }; + class statsButton: ctrlButton { + idc = IDC_statsButton; + style= 2; + text=">"; + onButtonClick = QUOTE(ARR_2([QQGVAR(statsButton), [ctrlParent (_this select 0)]]) call CBA_fnc_localEvent); + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); + y = QUOTE(safezoneY + 1.8 * GRID_H); + w = QUOTE(6 * GRID_W); + h = QUOTE(6 * GRID_H); + sizeEx = QUOTE(5 * GRID_H); + }; + class statsPreviousPage: ctrlButton { + idc = IDC_statsPreviousPage; + style= 2; + text="<"; + colorBackground[]={0,0,0,0}; + colorBackgroundDisabled[]= {0,0,0,0}; + onButtonClick = QUOTE(ARR_2([QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0), _this select 0, false)]]) call CBA_fnc_localEvent); + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP); + y = QUOTE(safezoneY + 1.8 * GRID_H); + w = QUOTE(5 * GRID_W); + h = QUOTE(5 * GRID_H); + sizeEx = QUOTE(5.5 * GRID_H); + }; + class statsNextPage: statsPreviousPage { + idc = IDC_statsNextPage; + text = ">"; + onButtonClick = QUOTE(ARR_2([QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0), _this select 0, true)]]) call CBA_fnc_localEvent); + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 30 * GRID_W); + }; + class statsCurrentPage: RscText { + idc = IDC_statsCurrentPage; + style = ST_CENTER; + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 5 * GRID_W); + y = QUOTE(safezoneY + 1.8 * GRID_H); + w = QUOTE(25 * GRID_W); + h = QUOTE(5 * GRID_H); + colorBackground[]={0,0,0,0}; + shadow=2; + sizeEx = QUOTE(5 * GRID_H); + text = ""; + }; + class statsButtonClose: ctrlButtonPicture { + idc = IDC_statsButtonClose; + colorBackground[]={0,0,0,0}; + text="\a3\3DEN\Data\Displays\Display3DEN\search_end_ca.paa"; + onButtonClick = QUOTE(ARR_2([QQGVAR(statsButton), [ctrlParent (_this select 0)]]) call CBA_fnc_localEvent); + x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 42 * GRID_W); + y = QUOTE(safezoneY + 1.8 * GRID_H); + w = QUOTE(5 * GRID_W); + h = QUOTE(5 * 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 - 28 * 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 * 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); + sizeEx = 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); + tooltip = CSTRING(buttonClearContainerTooltip); + 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); + sizeEx = QUOTE(6 * 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); + sizeEx = QUOTE(6 * 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..1d580c679e --- /dev/null +++ b/addons/arsenal/ui/RscCommon.hpp @@ -0,0 +1,303 @@ +// 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 { + items[]= {"aceArsenal", "virtualArsenal"}; + }; + class virtualArsenal { + text = "BI Virtual Arsenal"; + action= QUOTE(['arsenal'] call bis_fnc_3DENEntityMenu); + value=0; + data="Arsenal"; + opensNewWindow=1; + }; + class aceArsenal: virtualArsenal { + text = "ACE 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/CfgVehicles.hpp b/addons/atragmx/CfgVehicles.hpp index 6e8a136a03..ae37e7bb00 100644 --- a/addons/atragmx/CfgVehicles.hpp +++ b/addons/atragmx/CfgVehicles.hpp @@ -8,7 +8,6 @@ class CfgVehicles { condition = QUOTE(call FUNC(can_show)); statement = QUOTE(call FUNC(create_dialog)); showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\ATRAG_Icon.paa); exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; }; 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 625cd68deb..834c4eb8af 100644 --- a/addons/atragmx/RscTitles.hpp +++ b/addons/atragmx/RscTitles.hpp @@ -2,6 +2,10 @@ #define ST_RIGHT 1 #define ST_CENTER 2 +#define ST_WITH_RECT 160 + +#define LB_TEXTURES 0x10 + class ATragMX_RscText { idc=-1; type=0; @@ -48,7 +52,6 @@ class ATragMX_RscButton { shadow=0; }; class ATragMX_RscEdit { - access=0; type=2; style=ST_RIGHT; x=0; @@ -93,7 +96,7 @@ class ATragMX_RscToolbox { class ATragMX_RscListBox { idc=-1; type=5; - style=0; + style=LB_TEXTURES; font="TahomaB"; sizeEx=0.028; rowHeight=0.03; @@ -113,13 +116,14 @@ class ATragMX_RscListBox { soundSelect[]={"",0.09,1}; class ScrollBar { - color[]={1,1,1,0.6}; - colorActive[]={1,1,1,1}; - colorDisabled[]={1,1,1,0.3}; - //thumb="\ca\ui\data\igui_scrollbar_thumb_ca.paa"; - //arrowFull="\ca\ui\data\igui_arrow_top_active_ca.paa"; - //arrowEmpty="\ca\ui\data\igui_arrow_top_ca.paa"; - //border="\ca\ui\data\igui_border_scroll_ca.paa"; + width=0.05; + color[]={0.15,0.21,0.23,0.3}; + colorActive[]={0.15,0.21,0.23,0.3}; + colorDisabled[]={0.15,0.21,0.23,0.3}; + arrowEmpty="\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull="\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + border="\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + thumb="\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; }; class ListScrollBar : ScrollBar { @@ -128,7 +132,6 @@ class ATragMX_RscListBox { class ATragMX_RscListNBox: ATragMX_RscListBox { idc=-1; type=102; - columns[]={0.0, 0.225, 0.475, 0.7}; drawSideArrows=0; idcLeft=-1; idcRight=-1; @@ -350,6 +353,7 @@ class ATragMX_Display { colorBackground[]={0.15,0.21,0.23,0.3}; colorFocused[]={0.15,0.21,0.23,0.2}; text="MV"; + action=QUOTE(0 call FUNC(toggle_muzzle_velocity_data)); }; class TEXT_MUZZLE_VELOCITY_OUTPUT: TEXT_BORE_HEIGHT_OUTPUT { idc=130; @@ -383,18 +387,18 @@ class ATragMX_Display { y=0.265*safezoneH+safezoneY+0.320; text=""; }; - class TEXT_BAROMETRIC_PRESSURE: TEXT_AIR_FRICTION { + class TEXT_BAROMETRIC_PRESSURE: TEXT_TEMPERATURE { idc=21; x=0.550*safezoneW+safezoneX+0.20; + y=0.265*safezoneH+safezoneY+0.355; text="BP"; }; class TEXT_BAROMETRIC_PRESSURE_OUTPUT: TEXT_TEMPERATURE_OUTPUT { idc=210; y=0.265*safezoneH+safezoneY+0.355; }; - class TEXT_RELATIVE_HUMIDITY: TEXT_AIR_FRICTION { + class TEXT_RELATIVE_HUMIDITY: TEXT_BAROMETRIC_PRESSURE { idc=22; - x=0.550*safezoneW+safezoneX+0.20; y=0.265*safezoneH+safezoneY+0.390; text="RH"; }; @@ -526,7 +530,7 @@ class ATragMX_Display { }; class TEXT_ELEVATION_OUTPUT_ABSOLUTE: ATragMX_RscText { idc=400; - style=160; + style=ST_WITH_RECT+ST_RIGHT; sizeEx=0.025; w=0.065; h=0.032; @@ -606,17 +610,40 @@ class ATragMX_Display { class TEXT_SCOPE_CLICK_NUMBER: TEXT_GUN_LIST { idc=2001; style=ST_CENTER; - w=0.03; + w=0.025; x=0.550*safezoneW+safezoneX+0.27; text="4"; action=QUOTE(call FUNC(toggle_solution_setup)); }; - class TEXT_CALCULATE: TEXT_SCOPE_UNIT { + class TEXT_OPTIONS: TEXT_GUN_LIST { idc=3000; style=ST_RIGHT; x=0.550*safezoneW+safezoneX+0.3; - text="Calc"; - action=QUOTE(call FUNC(calculate_target_solution)); + text="Options"; + action=QUOTE(false call FUNC(toggle_option_menu)); + }; + class TEXT_OPTIONS_BACKGROUND: ATragMX_RscButton { + idc=3001; + colorBackground[]={0.15,0.21,0.23,0.2}; + colorBackgroundActive[]={0.15,0.21,0.23,0.2}; + colorFocused[]={0.15,0.21,0.23,0.2}; + x=0.550*safezoneW+safezoneX+0.105; + y=0.265*safezoneH+safezoneY+0.17; + w=0.3; + h=0.535; + offsetPressedX=0.0; + offsetPressedY=0.0; + action=QUOTE(false call FUNC(toggle_option_menu)); + }; + class TEXT_OPTIONS_LIST_OUTPUT: ATragMX_RscListBox { + idc=3002; + style=0; + w=0.17; + h=0.28; + x=0.550*safezoneW+safezoneX+0.225; + y=0.265*safezoneH+safezoneY+0.355; + sizeEx=0.025; + onMouseButtonClick=QUOTE(true call FUNC(toggle_option_menu)); }; class TEXT_RANGE_CARD_SCOPE_UNIT: TEXT_GUN_PROFILE { @@ -666,6 +693,7 @@ class ATragMX_Display { }; class TEXT_RANGE_CARD_OUTPUT: ATragMX_RscListNBox { idc=5007; + columns[]={0.0, 0.225, 0.475, 0.7}; idcLeft=50061; idcRight=50062; w=0.285; @@ -674,16 +702,17 @@ class ATragMX_Display { y=0.265*safezoneH+safezoneY+0.27; }; - class TEXT_GUN_LIST_OUTPUT: ATragMX_RscListBox { + class TEXT_GUN_LIST_OUTPUT: ATragMX_RscListNBox { idc=6000; + columns[]={-0.05}; w=0.16; h=0.45; x=0.550*safezoneW+safezoneX+0.11; y=0.265*safezoneH+safezoneY+0.24; - sizeEx=0.025; + sizeEx=0.018; colorSelectBackground[]={0.15,0.21,0.23,0.3}; colorSelectBackground2[]={0.15,0.21,0.23,0.3}; - onMouseButtonDblClick=QUOTE(true call FUNC(toggle_gun_list)); + onLBDblClick=QUOTE(true call FUNC(toggle_gun_list)); }; class TEXT_GUN_LIST_COLUMN_CAPTION: TEXT_GUN_PROFILE { idc=6001; @@ -766,8 +795,9 @@ class ATragMX_Display { class TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE: TEXT_TARGET_RANGE_ASSIST_MEASUREMENT_METHOD { idc=7003; style=ST_RIGHT; - x=0.550*safezoneW+safezoneX+0.10; + x=0.550*safezoneW+safezoneX+0.092; y=0.265*safezoneH+safezoneY+0.4; + w=0.128; text="Target Size"; }; class TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE { @@ -874,22 +904,22 @@ class ATragMX_Display { class TEXT_TARGET_SPEED_ASSIST_TARGET_RANGE: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE { idc=8000; - x=0.550*safezoneW+safezoneX+0.13; + x=0.550*safezoneW+safezoneX+0.12; text="Target Range"; }; class TEXT_TARGET_SPEED_ASSIST_NUM_TICKS: TEXT_TARGET_RANGE_ASSIST_IMAGE_SIZE { idc=8001; - x=0.550*safezoneW+safezoneX+0.13; + x=0.550*safezoneW+safezoneX+0.12; text="Num Ticks"; }; class TEXT_TARGET_SPEED_ASSIST_TIME: TEXT_TARGET_RANGE_ASSIST_ANGLE { idc=8002; - x=0.550*safezoneW+safezoneX+0.13; + x=0.550*safezoneW+safezoneX+0.12; text="Time (secs)"; }; class TEXT_TARGET_SPEED_ASSIST_TARGET_ESTIMATED_SPEED: TEXT_TARGET_RANGE_ASSIST_ESTIMATED_RANGE { idc=8003; - x=0.550*safezoneW+safezoneX+0.13; + x=0.550*safezoneW+safezoneX+0.12; text="Est Speed"; }; class TEXT_TARGET_SPEED_ASSIST_TARGET_RANGE_INPUT: TEXT_TARGET_RANGE_ASSIST_TARGET_SIZE_INPUT { @@ -1040,6 +1070,8 @@ class ATragMX_Display { x=0.550*safezoneW+safezoneX+0.12; y=0.265*safezoneH+safezoneY+0.28; text=""; + onKeyDown=QUOTE(call FUNC(trim_gun_name)); + onKeyUp=QUOTE(call FUNC(trim_gun_name)); }; class TEXT_ADD_NEW_GUN_OK: ATragMX_RscButton { idc=11002; @@ -1468,5 +1500,343 @@ class ATragMX_Display { y=0.265*safezoneH+safezoneY+0.55; action=QUOTE(0 call FUNC(toggle_solution_setup)); }; + + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE: TEXT_BORE_HEIGHT { + idc=16000; + w=0.22; + y=0.265*safezoneH+safezoneY+0.25; + sizeEx=0.022; + text="Temperature"; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE { + idc=16001; + x=0.550*safezoneW+safezoneX+0.215; + sizeEx=0.022; + text="Muzzle velocity"; + }; + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1: ATragMX_RscEdit { + idc=160021; + w=0.082; + h=0.035; + x=0.550*safezoneW+safezoneX+0.128; + y=0.265*safezoneH+safezoneY+0.29; + text="0"; + }; + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_2: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { + idc=160022; + y=0.265*safezoneH+safezoneY+0.325; + }; + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_3: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { + idc=160023; + y=0.265*safezoneH+safezoneY+0.360; + }; + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_4: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { + idc=160024; + y=0.265*safezoneH+safezoneY+0.395; + }; + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_5: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { + idc=160025; + y=0.265*safezoneH+safezoneY+0.430; + }; + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_6: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { + idc=160026; + y=0.265*safezoneH+safezoneY+0.465; + }; + class TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_7: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { + idc=160027; + y=0.265*safezoneH+safezoneY+0.500; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_1: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_1 { + idc=160031; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_2: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_2 { + idc=160032; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_3: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_3 { + idc=160033; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_4: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_4 { + idc=160034; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_5: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_5 { + idc=160035; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_6: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_6 { + idc=160036; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_MUZZLE_VELOCITY_DATA_MUZZLE_VELOCITY_INPUT_7: TEXT_MUZZLE_VELOCITY_DATA_TEMPERATURE_INPUT_7 { + idc=160037; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_MUZZLE_VELOCITY_DATA_CLEAR: TEXT_TARGET_DATA_NEXT { + idc=16004; + style=ST_CENTER; + h=0.035; + y=0.265*safezoneH+safezoneY+0.3625; + text="Clear"; + action=QUOTE(call FUNC(clear_muzzle_velocity_data)); + }; + class TEXT_MUZZLE_VELOCITY_DATA_QUESTIONMARK: TEXT_MUZZLE_VELOCITY_DATA_CLEAR { + idc=16005; + y=0.265*safezoneH+safezoneY+0.430; + text="?"; + action=""; + }; + class TEXT_MUZZLE_VELOCITY_DATA_DONE: TEXT_TARGET_DATA_DONE { + idc=16006; + action=QUOTE(1 call FUNC(toggle_muzzle_velocity_data)); + }; + class TEXT_MUZZLE_VELOCITY_DATA_CANCEL: TEXT_TARGET_DATA_CANCEL { + idc=16007; + action=QUOTE(0 call FUNC(toggle_muzzle_velocity_data)); + }; + class TEXT_MUZZLE_VELOCITY_DATA_PREV: TEXT_TARGET_DATA_PREV { + idc=16008; + }; + class TEXT_MUZZLE_VELOCITY_DATA_NEXT: TEXT_TARGET_DATA_NEXT { + idc=16009; + }; + + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE: TEXT_BORE_HEIGHT { + idc=17000; + w=0.22; + x=0.550*safezoneW+safezoneX+0.15; + y=0.265*safezoneH+safezoneY+0.25; + sizeEx=0.022; + text="Meters"; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE { + idc=17001; + x=0.550*safezoneW+safezoneX+0.235; + sizeEx=0.022; + text="BC-Coef"; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1: ATragMX_RscEdit { + idc=170021; + w=0.082; + h=0.035; + x=0.550*safezoneW+safezoneX+0.128; + y=0.265*safezoneH+safezoneY+0.29; + text="0"; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_2: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { + idc=170022; + y=0.265*safezoneH+safezoneY+0.325; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_3: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { + idc=170023; + y=0.265*safezoneH+safezoneY+0.360; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_4: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { + idc=170024; + y=0.265*safezoneH+safezoneY+0.395; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_5: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { + idc=170025; + y=0.265*safezoneH+safezoneY+0.430; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_6: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { + idc=170026; + y=0.265*safezoneH+safezoneY+0.465; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_7: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { + idc=170027; + y=0.265*safezoneH+safezoneY+0.500; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_1: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_1 { + idc=170031; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_2: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_2 { + idc=170032; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_3: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_3 { + idc=170033; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_4: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_4 { + idc=170034; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_5: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_5 { + idc=170035; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_6: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_6 { + idc=170036; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_C1_BALLISTIC_COEFFICIENT_INPUT_7: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DISTANCE_INPUT_7 { + idc=170037; + x=0.550*safezoneW+safezoneX+0.225; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_QUESTIONMARK: TEXT_TARGET_DATA_NEXT { + idc=17004; + style=ST_CENTER; + w=0.04; + h=0.035; + y=0.265*safezoneH+safezoneY+0.35; + text="?"; + action=""; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_CLEAR: TEXT_C1_BALLISTIC_COEFFICIENT_DATA_QUESTIONMARK { + idc=17005; + w=0.07; + y=0.265*safezoneH+safezoneY+0.4175; + text="Clear"; + action=QUOTE(call FUNC(clear_c1_ballistic_coefficient_data)); + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_DONE: TEXT_TARGET_DATA_DONE { + idc=17006; + action=QUOTE(1 call FUNC(toggle_c1_ballistic_coefficient_data)); + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_CANCEL: TEXT_TARGET_DATA_CANCEL { + idc=17007; + action=QUOTE(0 call FUNC(toggle_c1_ballistic_coefficient_data)); + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_PREV: TEXT_TARGET_DATA_PREV { + idc=17008; + }; + class TEXT_C1_BALLISTIC_COEFFICIENT_DATA_NEXT: TEXT_TARGET_DATA_NEXT { + idc=17009; + }; + + class TEXT_TRUING_DROP_ZERO_RANGE: ATragMX_RscText { + idc=18000; + style=ST_LEFT; + x=0.550*safezoneW+safezoneX+0.115; + y=0.265*safezoneH+safezoneY+0.220; + w=0.135; + h=0.03; + sizeEx=0.025; + text="ZR=100meters"; + }; + class TEXT_TRUING_DROP_DROP_UNIT: TEXT_TRUING_DROP_ZERO_RANGE { + idc=18001; + style=ST_LEFT; + x=0.550*safezoneW+safezoneX+0.25; + text="Drop=mil"; + }; + class TEXT_TRUING_DROP_TARGET_RANGE: TEXT_TRUING_DROP_ZERO_RANGE { + idc=18002; + y=0.265*safezoneH+safezoneY+0.35; + sizeEx=0.027; + text="Target Range"; + }; + class TEXT_TRUING_DROP_DROP: TEXT_TRUING_DROP_TARGET_RANGE { + idc=18003; + w=0.07; + y=0.265*safezoneH+safezoneY+0.40; + text="Drop"; + }; + class TEXT_TRUING_DROP_MUZZLE_VELOCITY: TEXT_TRUING_DROP_DROP { + idc=18004; + y=0.265*safezoneH+safezoneY+0.50; + text="MV"; + }; + class TEXT_TRUING_DROP_C1_BALLISTIC_COEFFICIENT: TEXT_TRUING_DROP_DROP { + idc=18005; + y=0.265*safezoneH+safezoneY+0.55; + text="C1"; + }; + class TEXT_TRUING_DROP_DROP_OUTPUT: ATragMX_RscEdit { + idc=18006; + style=ST_WITH_RECT+ST_RIGHT; + colorBackground[]={0.15,0.21,0.23,0.3}; + colorDisabled[]={0,0,0,1}; + w=0.06; + y=0.265*safezoneH+safezoneY+0.40; + x=0.550*safezoneW+safezoneX+0.17; + text=""; + }; + class TEXT_TRUING_DROP_MUZZLE_VELOCITY_OUTPUT: TEXT_TRUING_DROP_DROP_OUTPUT { + idc=18007; + y=0.265*safezoneH+safezoneY+0.50; + text=""; + }; + class TEXT_TRUING_DROP_C1_BALLISTIC_COEFFICIENT_OUTPUT: TEXT_TRUING_DROP_DROP_OUTPUT { + idc=18008; + y=0.265*safezoneH+safezoneY+0.55; + text=""; + }; + class TEXT_TRUING_DROP_SUPER: TEXT_TARGET_A { + idc=18009; + w=0.06; + x=0.550*safezoneW+safezoneX+0.25; + y=0.265*safezoneH+safezoneY+0.30; + text="SUPER"; + action=QUOTE(GVAR(truingDropMode) = 0; call FUNC(update_truing_drop_selection)); + }; + class TEXT_TRUING_DROP_SUB: TEXT_TRUING_DROP_SUPER { + idc=18010; + x=0.550*safezoneW+safezoneX+0.32; + text="SUB"; + action=QUOTE(GVAR(truingDropMode) = 1; call FUNC(update_truing_drop_selection)); + }; + class TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT: ATragMX_RscEdit { + idc=18011; + style=ST_WITH_RECT+ST_RIGHT; + colorDisabled[]={0,0,0,0.6}; + w=0.06; + x=0.550*safezoneW+safezoneX+0.25; + y=0.265*safezoneH+safezoneY+0.35; + }; + class TEXT_TRUING_DROP_TARGET_RANGE_SUB_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT { + idc=18012; + x=0.550*safezoneW+safezoneX+0.32; + }; + class TEXT_TRUING_DROP_DROP_SUPER_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT { + idc=18013; + y=0.265*safezoneH+safezoneY+0.40; + }; + class TEXT_TRUING_DROP_DROP_SUB_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUB_INPUT { + idc=18014; + y=0.265*safezoneH+safezoneY+0.40; + }; + class TEXT_TRUING_DROP_CALC: TEXT_GUN_LIST { + idc=18015; + style=ST_CENTER; + w=0.11; + x=0.550*safezoneW+safezoneX+0.26; + y=0.265*safezoneH+safezoneY+0.45; + text="Calc"; + action=QUOTE(true call FUNC(calculate_truing_drop)); + }; + class TEXT_TRUING_DROP_MV_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUPER_INPUT { + idc=18016; + y=0.265*safezoneH+safezoneY+0.50; + }; + class TEXT_TRUING_DROP_C1_BALLISTIC_COEFFICIENT_INPUT: TEXT_TRUING_DROP_TARGET_RANGE_SUB_INPUT { + idc=18017; + y=0.265*safezoneH+safezoneY+0.55; + }; + class TEXT_TRUING_DROP_ACCEPT: TEXT_GUN_LIST { + idc=18018; + w=0.085; + h=0.04; + x=0.550*safezoneW+safezoneX+0.125; + y=0.265*safezoneH+safezoneY+0.60; + text="Accept"; + action=QUOTE(1 call FUNC(toggle_truing_drop)); + }; + class TEXT_TRUING_DROP_CANCEL: TEXT_TRUING_DROP_ACCEPT { + idc=18019; + x=0.550*safezoneW+safezoneX+0.210; + text="Cancel"; + action=QUOTE(0 call FUNC(toggle_truing_drop)); + }; + class TEXT_TRUING_DROP_RESTORE: TEXT_TRUING_DROP_CANCEL { + idc=18020; + x=0.550*safezoneW+safezoneX+0.29525; + text="Restore"; + action=QUOTE(true call FUNC(restore_truing_drop)); + }; }; }; diff --git a/addons/atragmx/XEH_PREP.hpp b/addons/atragmx/XEH_PREP.hpp index 20900711c3..b61258c008 100644 --- a/addons/atragmx/XEH_PREP.hpp +++ b/addons/atragmx/XEH_PREP.hpp @@ -1,13 +1,17 @@ PREP(add_new_gun); +PREP(calculate_distance_at_velocity); PREP(calculate_range_card); PREP(calculate_solution); PREP(calculate_target_range_assist); PREP(calculate_target_solution); PREP(calculate_target_speed_assist); +PREP(calculate_truing_drop); PREP(can_show); PREP(change_gun); PREP(change_target_slot); +PREP(clear_c1_ballistic_coefficient_data); +PREP(clear_muzzle_velocity_data); PREP(clear_user_data); PREP(create_dialog); PREP(cycle_gun_list); @@ -18,17 +22,30 @@ PREP(cycle_scope_unit); PREP(cycle_target_size_units); PREP(cycle_target_speed_direction); PREP(delete_gun); +PREP(evaluate_option_menu_input); 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); +PREP(recalculate_muzzle_velocity); PREP(reset_relative_click_memory); PREP(restore_atmo_default); +PREP(restore_truing_drop); PREP(restore_user_data); PREP(save_gun); +PREP(shift_c1_ballistic_coefficient_data); +PREP(shift_muzzle_velocity_data); PREP(show_add_new_gun); PREP(show_atmo_env_data); +PREP(show_c1_ballistic_coefficient_data); PREP(show_gun_ammo_data); PREP(show_gun_list); PREP(show_main_page); +PREP(show_muzzle_velocity_data); PREP(show_range_card); PREP(show_range_card_setup); PREP(show_solution_setup); @@ -36,24 +53,36 @@ PREP(show_target_data); PREP(show_target_range_assist); PREP(show_target_speed_assist); PREP(show_target_speed_assist_timer); +PREP(show_truing_drop); PREP(sord); +PREP(store_gun_list); PREP(store_user_data); PREP(target_speed_assist_timer); PREP(toggle_atmo_env_data); +PREP(toggle_c1_ballistic_coefficient_data); +PREP(toggle_coriolis); PREP(toggle_gun_ammo_data); PREP(toggle_gun_list); +PREP(toggle_muzzle_velocity_data); +PREP(toggle_option_menu); PREP(toggle_range_card); PREP(toggle_range_card_setup); PREP(toggle_solution_setup); PREP(toggle_target_data); PREP(toggle_target_range_assist); PREP(toggle_target_speed_assist); +PREP(toggle_truing_drop); +PREP(trim_gun_name); +PREP(true_c1_ballistic_coefficient); +PREP(true_muzzle_velocity); PREP(update_atmosphere); PREP(update_atmo_env_data); PREP(update_atmo_selection); +PREP(update_c1_ballistic_coefficient_data); PREP(update_gun); PREP(update_gun_ammo_data); PREP(update_inclination_angle); +PREP(update_muzzle_velocity_data); PREP(update_range_card); PREP(update_relative_click_memory); PREP(update_result); @@ -62,6 +91,8 @@ PREP(update_solution_setup); PREP(update_target); PREP(update_target_data); PREP(update_target_selection); +PREP(update_truing_drop_data); +PREP(update_truing_drop_selection); PREP(update_unit_selection); PREP(update_zero_range); PREP(on_close_dialog); diff --git a/addons/atragmx/XEH_postInit.sqf b/addons/atragmx/XEH_postInit.sqf index 4a68aac749..9034016212 100644 --- a/addons/atragmx/XEH_postInit.sqf +++ b/addons/atragmx/XEH_postInit.sqf @@ -2,53 +2,7 @@ #include "initKeybinds.sqf" -if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == ATRAGMX_PROFILE_NAMESPACE_VERSION && count (profileNamespace getVariable ["ACE_ATragMX_gunList", []]) > 0) then { - GVAR(gunList) = profileNamespace getVariable "ACE_ATragMX_gunList"; -} else { - // 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 - GVAR(gunList) = [["12.7x108mm" , 820, 100, 0.0657485, -0.00063800, 3.81, 0, 2, 10, 120, 0, 0, 48.28, 12.7, 38.10, 0.630, 1, "ASM" ], - - ["12.7x99mm AMAX" , 860, 100, 0.0611565, -0.00036645, 3.81, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 38.10, 1.050, 1, "ASM" ], - ["12.7x99mm" , 900, 100, 0.0582418, -0.00057503, 3.81, 0, 2, 10, 120, 0, 0, 41.92, 12.7, 38.10, 0.670, 1, "ASM" ], - ["12.7x99mm API" , 900, 100, 0.0582418, -0.00057503, 3.81, 0, 2, 10, 120, 0, 0, 41.99, 12.9, 38.10, 0.670, 1, "ASM" ], - - ["12.7x54mm" , 300, 100, 0.3394630, -0.00019268, 3.81, 0, 2, 10, 120, 0, 0, 48.60, 12.7, 24.13, 1.050, 1, "ASM" ], - - [".408 Chey Tac" , 910, 100, 0.0569400, -0.00038944, 3.81, 0, 2, 10, 120, 0, 0, 26.57, 10.4, 33.02, 0.970, 1, "ASM" ], - - ["9.3×64mm" , 870, 100, 0.0619295, -0.00108571, 3.81, 0, 2, 10, 120, 0, 0, 14.90, 9.30, 35.56, 0.368, 1, "ASM" ], - - [".338LM 250gr" , 880, 100, 0.0598469, -0.00059133, 3.81, 0, 2, 10, 120, 0, 0, 16.20, 8.58, 25.40, 0.322, 7, "ICAO"], - [".338LM 300gr" , 800, 100, 0.0677343, -0.00052190, 3.81, 0, 2, 10, 120, 0, 0, 19.44, 8.58, 25.40, 0.381, 7, "ICAO"], - [".338LM API526" , 895, 100, 0.0588865, -0.00069611, 3.81, 0, 2, 10, 120, 0, 0, 16.39, 8.58, 25.40, 0.560, 1, "ASM" ], - - [".300WM Mk248 Mod0" , 900, 100, 0.0584442, -0.00070530, 3.81, 0, 2, 10, 120, 0, 0, 12.31, 7.80, 25.40, 0.268, 7, "ICAO"], - [".300WM Mk248 Mod1" , 867, 100, 0.0610738, -0.00061188, 3.81, 0, 2, 10, 120, 0, 0, 14.26, 7.80, 25.40, 0.310, 7, "ICAO"], - [".300WM Berger OTM" , 853, 100, 0.0622179, -0.00053733, 3.81, 0, 2, 10, 120, 0, 0, 14.90, 7.80, 25.40, 0.368, 7, "ICAO"], - - ["7.62x54mmR" , 800, 100, 0.0691878, -0.00100023, 3.81, 0, 2, 10, 120, 0, 0, 9.849, 7.92, 24.13, 0.400, 1, "ICAO"], - - ["7.62x51mm M80" , 810, 100, 0.0679374, -0.00100957, 3.81, 0, 2, 10, 120, 0, 0, 9.461, 7.82, 25.40, 0.200, 7, "ICAO"], - ["7.62x51mm M118LR" , 780, 100, 0.0710319, -0.00082828, 3.81, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.243, 7, "ICAO"], - ["7.62x51mm Mk316" , 780, 100, 0.0710319, -0.00082029, 3.81, 0, 2, 10, 120, 0, 0, 11.34, 7.82, 25.40, 0.243, 7, "ICAO"], - ["7.62x51mm Mk319" , 910, 100, 0.0584524, -0.00102338, 3.81, 0, 2, 10, 120, 0, 0, 8.424, 7.82, 25.40, 0.377, 1, "ICAO"], - ["7.62x51mm M993" , 930, 100, 0.0570316, -0.00107148, 3.81, 0, 2, 10, 120, 0, 0, 8.230, 7.82, 25.40, 0.359, 1, "ICAO"], - ["7.62x51mm Subsonic", 320, 100, 0.3059680, -0.00049899, 3.81, 0, 2, 10, 120, 0, 0, 12.96, 7.82, 25.40, 0.235, 7, "ICAO"], - - ["6.5x39mm" , 800, 100, 0.0683482, -0.00075308, 3.81, 0, 2, 10, 120, 0, 0, 7.970, 6.71, 22.86, 0.263, 7, "ICAO"], - ["6.5x47mm Lapua" , 800, 100, 0.0682221, -0.00067037, 3.81, 0, 2, 10, 120, 0, 0, 9.007, 6.71, 22.86, 0.290, 7, "ICAO"], - ["6.5mm Creedmor" , 840, 100, 0.0636501, -0.00060887, 3.81, 0, 2, 10, 120, 0, 0, 9.072, 6.71, 22.86, 0.317, 7, "ICAO"], - - ["5.56x45mm M855" , 870, 100, 0.0626386, -0.00126466, 3.81, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.151, 7, "ASM" ], - ["5.56x45mm Mk262" , 820, 100, 0.0671481, -0.00109563, 3.81, 0, 2, 10, 120, 0, 0, 4.990, 5.70, 17.78, 0.361, 1, "ASM" ], - ["5.56x45mm Mk318" , 880, 100, 0.0615937, -0.00123318, 3.81, 0, 2, 10, 120, 0, 0, 4.018, 5.70, 17.78, 0.307, 1, "ASM" ], - ["5.56x45mm M995" , 869, 100, 0.0626713, -0.00123272, 3.81, 0, 2, 10, 120, 0, 0, 4.536, 5.70, 17.78, 0.310, 1, "ASM" ]]; - - [] call FUNC(clear_user_data); - profileNamespace setVariable ["ACE_ATragMX_gunList", GVAR(gunList)]; -}; - -[] call FUNC(init); -[] call FUNC(restore_user_data); +GVAR(active) = false; +GVAR(initialised) = false; [QEGVAR(vector,rangefinderData), {_this call FUNC(sord)}] call CBA_fnc_addEventHandler; diff --git a/addons/atragmx/XEH_preInit.sqf b/addons/atragmx/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/atragmx/XEH_preInit.sqf +++ b/addons/atragmx/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/atragmx/config.cpp b/addons/atragmx/config.cpp index aec53ba837..125d4a488e 100644 --- a/addons/atragmx/config.cpp +++ b/addons/atragmx/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {"ACE_Item_ATragMX"}; weapons[] = {"ACE_ATragMX"}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ACE_common", "ACE_weather"}; + requiredAddons[] = {"ACE_Advanced_Ballistics", "ACE_common", "ACE_weather"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg"}; url = ECSTRING(main,URL); @@ -18,7 +18,3 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "RscTitles.hpp" - -class ACE_newEvents { - RangerfinderData = QEGVAR(vector,rangefinderData); -}; diff --git a/addons/atragmx/functions/fnc_add_new_gun.sqf b/addons/atragmx/functions/fnc_add_new_gun.sqf index dbc85cc27f..94415852f9 100644 --- a/addons/atragmx/functions/fnc_add_new_gun.sqf +++ b/addons/atragmx/functions/fnc_add_new_gun.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Adds a new (default) gun profile to the profileNamespace @@ -6,22 +7,24 @@ * Nothing * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_add_new_gun * * Public: No */ -#include "script_component.hpp" + +call FUNC(trim_gun_name); private _gunName = ctrlText 11001; + if (_gunName != "") then { - private _gunProfileEntry = [_gunName, 810, 100, 0.0679, -0.0010350, 3.81, 0, 2, 10, 120, 0, 0, 9.525, 7.82, 25.40, 0.393, 1, "ICAO"], + private _gunProfileEntry = [_gunName, 810, 100, 0.0679, -0.0010350, 3.81, 0, 2, 10, 120, 0, 0, 9.525, 7.82, 25.40, 0.393, 1, "ICAO", [[-15,0],[0,0],[10,0],[15,0],[25,0],[30,0],[35,0]], [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true]; GVAR(gunList) = GVAR(gunList) + [_gunProfileEntry]; - lbAdd [6000, _gunProfileEntry select 0]; + lbAdd [6000, _gunName]; - profileNamespace setVariable ["ACE_ATragMX_gunList", GVAR(gunList)]; + call FUNC(store_gun_list); }; diff --git a/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf new file mode 100644 index 0000000000..1f06d79988 --- /dev/null +++ b/addons/atragmx/functions/fnc_calculate_distance_at_velocity.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Calculates distance at which the bullet velocity drops below the threshold velocity + * + * Arguments: + * theshold velocity + * + * Return Value: + * distance + * + * Example: + * 403 call ace_atragmx_fnc_calculate_distance_at_velocity + * + * Public: No + */ + +#define __DELTA_T 0.001 + +if (isNil QGVAR(targetSolutionInput)) exitWith { 0 }; + +private _thresholdVelocity = _this; +private _velocity = GVAR(targetSolutionInput) select 4; + +if (_velocity <= _thresholdVelocity) exitWith { 0 }; + +private _distance = 0; + +while {_velocity > _thresholdVelocity} do { + private _bc = GVAR(targetSolutionInput) select 14; + private _dragModel = GVAR(targetSolutionInput) select 15; + 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); +}; + +_distance diff --git a/addons/atragmx/functions/fnc_calculate_range_card.sqf b/addons/atragmx/functions/fnc_calculate_range_card.sqf index 0b6d0a177b..473e49a8a1 100644 --- a/addons/atragmx/functions/fnc_calculate_range_card.sqf +++ b/addons/atragmx/functions/fnc_calculate_range_card.sqf @@ -1,75 +1,35 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the range card output based on the current data set * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_calculate_range_card * * Public: No */ -#include "script_component.hpp" -[] call FUNC(parse_input); +GVAR(rangeCardData) = []; -GVAR(workingMemory) params ["", - "_muzzleVelocity", "", - "_scopeBaseAngle", - "_airFriction", - "_boreHeight", "", "", "", "", "", "", - "_bulletMass", - "_bulletDiameter", - "_barrelTwist", - "_bc", - "_dragModel", - "_atmosphereModel" -]; - -private _twistDirection = 0; -if (_barrelTwist > 0) then { - _twistDirection = 1; -} else { - if (_barrelTwist < 0) then { - _twistDirection = -1; - }; -}; -_barrelTwist = abs _barrelTwist; - -private _altitude = GVAR(altitude); -private _temperature = GVAR(temperature); -private _barometricPressure = GVAR(barometricPressure); -private _relativeHumidity = GVAR(relativeHumidity); -if (!GVAR(atmosphereModeTBH)) then { - _barometricPressure = 1013.25 * (1 - (0.0065 * _altitude) / (273.15 + _temperature + 0.0065 * _altitude)) ^ 5.255754495; - _relativeHumidity = 50; -}; - -private _bulletLength = 45.72; -private _stabilityFactor = 1.5; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - if (_bulletDiameter > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then { - _stabilityFactor = [_bulletDiameter, _bulletLength, _bulletMass, _barrelTwist * 10, _muzzleVelocity, _temperature, _barometricPressure] call EFUNC(advanced_ballistics,calculateStabilityFactor); - }; -}; - -private _latitude = GVAR(latitude) select GVAR(currentTarget); -private _directionOfFire = GVAR(directionOfFire) select GVAR(currentTarget); -private _windSpeed1 = (GVAR(windSpeed1) select GVAR(currentTarget)); -private _windSpeed2 = (GVAR(windSpeed2) select GVAR(currentTarget)); -private _windDirection = (GVAR(windDirection) select GVAR(currentTarget)); -private _inclinationAngle = (GVAR(inclinationAngle) select GVAR(currentTarget)); -private _targetSpeed = (GVAR(targetSpeed) select GVAR(currentTarget)); private _targetRange = GVAR(rangeCardEndRange); if (GVAR(currentUnit) == 1) then { _targetRange = _targetRange / 1.0936133; }; -GVAR(rangeCardData) = []; +private _solutionInput = +GVAR(targetSolutionInput); +_solutionInput set [ 8, round(_solutionInput select 4)]; +_solutionInput set [13, _targetRange]; +_solutionInput set [17, true]; -private _result = [_scopeBaseAngle, _bulletMass, _boreHeight, _airFriction, _muzzleVelocity, _temperature, _barometricPressure, _relativeHumidity, 1000, - [_windSpeed1, _windSpeed2], _windDirection, _inclinationAngle, _targetSpeed, _targetRange, _bc, _dragModel, _atmosphereModel, true, _stabilityFactor, _twistDirection, _latitude, _directionOfFire] call FUNC(calculate_solution); +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 d98c46c5fb..3c854499d9 100644 --- a/addons/atragmx/functions/fnc_calculate_solution.sqf +++ b/addons/atragmx/functions/fnc_calculate_solution.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the fireing solution @@ -41,7 +42,6 @@ * * Public: No */ -#include "script_component.hpp" params [ "_scopeBaseAngle", "_bulletMass", "_boreHeight", "_airFriction", "_muzzleVelocity", "_temperature", "_barometricPressure", "_relativeHumidity", "_simSteps", "_windSpeed", @@ -51,33 +51,34 @@ params [ ]; _windSpeed params ["_windSpeed1", "_windSpeed2"]; -private ["_bulletPos", "_bulletVelocity", "_bulletAccel", "_bulletSpeed", "_gravity", "_deltaT"]; -_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", "_rangeFactor"]; -_n = 0; -_range = 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; @@ -85,27 +86,18 @@ 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 = [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel] call EFUNC(advanced_ballistics,calculateAtmosphericCorrection); + _bc = parseNumber(("ace_advanced_ballistics" callExtension format["atmosphericCorrection:%1:%2:%3:%4:%5", _bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel])); }; -private ["_speedTotal", "_stepsTotal", "_speedAverage"]; -_speedTotal = 0; -_stepsTotal = 0; -_speedAverage = 0; - -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); }; -_TOF = 0; - _bulletPos set [0, 0]; _bulletPos set [1, 0]; _bulletPos set [2, -(_boreHeight / 100)]; @@ -117,19 +109,11 @@ _bulletVelocity set [2, Sin(_scopeBaseAngle) * _muzzleVelocity]; while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { _bulletSpeed = vectorMagnitude _bulletVelocity; - _speedTotal = _speedTotal + _bulletSpeed; - _stepsTotal = _stepsTotal + 1; - _speedAverage = (_speedTotal / _stepsTotal); - _trueVelocity = _bulletVelocity vectorDiff _wind1; _trueSpeed = vectorMagnitude _trueVelocity; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - private _drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then { - parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed])) - } else { - ([_dragModel, _bc, _trueSpeed] call EFUNC(advanced_ballistics,calculateRetardation)) - }; + 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); @@ -137,29 +121,32 @@ while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { _bulletAccel = _bulletAccel vectorAdd _gravity; + _lastBulletPos = _bulletPos; + _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply (_deltaT * 0.5)); _bulletVelocity = _bulletVelocity vectorAdd (_bulletAccel vectorMultiply _deltaT); - _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply _deltaT); + _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply (_deltaT * 0.5)); _TOF = _TOF + _deltaT; if (_storeRangeCardData) then { _range = GVAR(rangeCardStartRange) + _n * GVAR(rangeCardIncrement); if ((_bulletPos select 1) * _rangeFactor >= _range && _range <= GVAR(rangeCardEndRange)) then { - if ((_bulletPos select 1) > 0) then { - _elevation = - atan((_bulletPos select 2) / (_bulletPos select 1)); - _windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1)); - _windDrift = (_wind2 select 0) * (_TOF - (_range / _rangeFactor) / _muzzleVelocity); - _windage2 = - atan(_windDrift / (_bulletPos select 1)); - }; - if (_range != 0) then { - _lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _range); + _trueRange = _range / _rangeFactor; + if (_trueRange != 0) then { + _tx = (_lastBulletPos select 0) + (_trueRange - (_lastBulletPos select 1)) * ((_bulletPos select 0) - (_lastBulletPos select 0)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); + _tz = (_lastBulletPos select 2) + (_trueRange - (_lastBulletPos select 1)) * ((_bulletPos select 2) - (_lastBulletPos select 2)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); + _elevation = - atan(_tz / _trueRange); + _windage1 = - atan(_tx / _trueRange); + _windDrift = (_wind2 select 0) * (_TOF - _trueRange / _muzzleVelocity); + _windage2 = - atan(_windDrift / _trueRange); + _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _trueRange); }; _kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); _kineticEnergy = _kineticEnergy * 0.737562149; if ((missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) && (_bulletPos select 1) > 0) then { // Coriolis - _horizontalDeflection = 0.0000729 * ((_bulletPos select 1) ^ 2) * sin(_latitude) / _speedAverage; + _horizontalDeflection = 0.0000729 * (_bulletPos select 1) * _TOF * sin(_latitude); _horizontalCoriolis = - atan(_horizontalDeflection / (_bulletPos select 1)); _windage1 = _windage1 + _horizontalCoriolis; _windage2 = _windage2 + _horizontalCoriolis; @@ -180,15 +167,14 @@ while {_TOF < 15 && (_bulletPos select 1) < _targetRange} do { }; }; -if ((_bulletPos select 1) > 0) then { - _elevation = - atan((_bulletPos select 2) / (_bulletPos select 1)); - _windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1)); - _windDrift = (_wind2 select 0) * (_TOF - _targetRange / _muzzleVelocity); - _windage2 = - atan(_windDrift / (_bulletPos select 1)); -}; - if (_targetRange != 0) then { - _lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _targetRange); + _tx = (_lastBulletPos select 0) + (_targetRange - (_lastBulletPos select 1)) * ((_bulletPos select 0) - (_lastBulletPos select 0)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); + _tz = (_lastBulletPos select 2) + (_targetRange - (_lastBulletPos select 1)) * ((_bulletPos select 2) - (_lastBulletPos select 2)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); + _elevation = - atan(_tz / _targetRange); + _windage1 = - atan(_tx / _targetRange); + _windDrift = (_wind2 select 0) * (_TOF - _targetRange / _muzzleVelocity); + _windage2 = - atan(_windDrift / _targetRange); + _lead = (_targetSpeed * _TOF) / (Tan(MRAD_TO_DEG(1)) * _targetRange); }; _kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); @@ -196,7 +182,7 @@ _kineticEnergy = _kineticEnergy * 0.737562149; if ((missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) && (_bulletPos select 1) > 0) then { // Coriolis - _horizontalDeflection = 0.0000729 * ((_bulletPos select 1) ^ 2) * sin(_latitude) / _speedAverage; + _horizontalDeflection = 0.0000729 * (_bulletPos select 1) * _TOF * sin(_latitude); _horizontalCoriolis = - atan(_horizontalDeflection / (_bulletPos select 1)); _windage1 = _windage1 + _horizontalCoriolis; _windage2 = _windage2 + _horizontalCoriolis; diff --git a/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf b/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf index e59cdee37d..51f00cdaaf 100644 --- a/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_range_assist.sqf @@ -1,22 +1,22 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the target range and updates the output fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_calculate_target_range_assist * * Public: No */ -#include "script_component.hpp" private _angle = parseNumber(ctrlText 7012); -private _targetSize = parseNumber(ctrlText 7010); +private _targetSize = abs(parseNumber(ctrlText 7010)); if (GVAR(rangeAssistUseTargetHeight)) then { _targetSize = _targetSize * cos(_angle); }; @@ -43,7 +43,7 @@ switch (GVAR(rangeAssistImageSizeUnit)) do { _imageSize = _imageSize / 60 / 1.047; }; }; -private _estRange = parseNumber(ctrlText 7013); +private _estRange = abs(parseNumber(ctrlText 7013)); if (GVAR(currentUnit) == 1) then { _estRange = _estRange / 1.0936133; }; @@ -52,7 +52,7 @@ switch (_this) do { case 0: { _targetSize = tan(_imageSize) * _estRange; - if (GVAR(rangeAssistUseTargetHeight)) then { + if (GVAR(rangeAssistUseTargetHeight) && cos(_angle) != 0) then { _targetSize = _targetSize / cos(_angle); }; @@ -71,7 +71,9 @@ switch (_this) do { ctrlSetText [7010, Str(Round(_targetSize * 100) / 100)]; }; case 1: { - _imageSize = atan(_targetSize / _estRange); + if (_estRange > 0) then { + _imageSize = atan(_targetSize / _estRange); + }; switch (GVAR(rangeAssistImageSizeUnit)) do { case 0: { @@ -88,7 +90,9 @@ switch (_this) do { ctrlSetText [7011, Str(Round(_imageSize * 100) / 100)]; }; case 2: { - _estRange = _targetSize / tan(_imageSize); + if (tan(_imageSize) != 0) then { + _estRange = _targetSize / tan(_imageSize); + }; ctrlSetText [7013, Str(Round(_estRange))]; }; diff --git a/addons/atragmx/functions/fnc_calculate_target_solution.sqf b/addons/atragmx/functions/fnc_calculate_target_solution.sqf index 8bd844938f..775467f5de 100644 --- a/addons/atragmx/functions/fnc_calculate_target_solution.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_solution.sqf @@ -1,37 +1,35 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the fireing solution and updates the result input/output fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_calculate_target_solution * * Public: No */ -#include "script_component.hpp" [] 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,38 +39,36 @@ 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 = 45.72; -_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); -private ["_result"]; -_result = [_scopeBaseAngle, _bulletMass, _boreHeight, _airFriction, _muzzleVelocity, _temperature, _barometricPressure, _relativeHumidity, 1000, - [_windSpeed1, _windSpeed2], _windDirection, _inclinationAngle, _targetSpeed, _targetRange, _bc, _dragModel, _atmosphereModel, false, _stabilityFactor, _twistDirection, _latitude, _directionOfFire] call FUNC(calculate_solution); +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]; + +private _result = GVAR(targetSolutionInput) call FUNC(calculate_solution); GVAR(elevationOutput) set [GVAR(currentTarget), _result select 0]; GVAR(windage1Output) set [GVAR(currentTarget), (_result select 1) select 0]; @@ -80,5 +76,8 @@ GVAR(windage2Output) set [GVAR(currentTarget), (_result select 1) select 1]; GVAR(leadOutput) set [GVAR(currentTarget), _result select 2]; GVAR(tofOutput) set [GVAR(currentTarget), _result select 3]; GVAR(velocityOutput) set [GVAR(currentTarget), _result select 4]; +GVAR(verticalCoriolisOutput) set [GVAR(currentTarget), _result select 6]; +GVAR(horizontalCoriolisOutput) set [GVAR(currentTarget), _result select 7]; +GVAR(spinDriftOutput) set [GVAR(currentTarget), _result select 8]; [] call FUNC(update_result); diff --git a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf index c3a4dac24f..1e28a82339 100644 --- a/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_calculate_target_speed_assist.sqf @@ -1,26 +1,24 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the target speed and updates the output fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_calculate_target_speed_assist * * Public: No */ -#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 new file mode 100644 index 0000000000..be6ebd1eda --- /dev/null +++ b/addons/atragmx/functions/fnc_calculate_truing_drop.sqf @@ -0,0 +1,107 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Calculates the truing drop and updates the output fields + * + * Arguments: + * parse input + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_calculate_truing_drop + * + * Public: No + */ + +private _parseInput = _this; + +private _transonicRange = GVAR(truingDropRangeData) select 0; +private _subsonicRange = GVAR(truingDropRangeData) select 1; +private _transonicDrop = GVAR(truingDropDropData) select 1; +private _subsonicDrop = GVAR(truingDropDropData) select 2; + +if (_parseInput) then { + _transonicRange = 0 max abs(parseNumber(ctrlText 18011)) min 4000; + _subsonicRange = 0 max abs(parseNumber(ctrlText 18012)) min 4000; + if (GVAR(currentUnit) != 2) then { + _transonicRange = _transonicRange * 0.9144; + _subsonicRange = _subsonicRange * 0.9144; + }; + _transonicRange = Round(_transonicRange); + _subsonicRange = Round(_subsonicRange); + + _subsonicRange = _transonicRange max _subsonicRange; + + _transonicDrop = -100 max parseNumber(ctrlText 18013) min 100; + _subsonicDrop = -100 max parseNumber(ctrlText 18014) min 100; + private _dropUnit = GVAR(currentScopeUnit); + if (_dropUnit == 3) then { + switch (GVAR(currentScopeClickUnit)) do { + case 0: { _dropUnit = 1; }; + case 1: { _dropUnit = 2; }; + case 2: { _dropUnit = 0; }; + }; + }; + switch (_dropUnit) do { + case 0: { + _transonicDrop = MRAD_TO_MOA(_transonicDrop); + _subsonicDrop = MRAD_TO_MOA(_subsonicDrop); + }; + case 2: { + _transonicDrop = _transonicDrop / 1.047; + _subsonicDrop = _subsonicDrop / 1.047; + }; + }; + _transonicDrop = Round(_transonicDrop * 100) / 100; + _subsonicDrop = Round(_subsonicDrop * 100) / 100; + + _subsonicDrop = _transonicDrop max _subsonicDrop; +}; + +if ((GVAR(truingDropDropData) select 0) == 0 || {!([_transonicRange, _subsonicRange] isEqualTo GVAR(truingDropRangeData))}) then { + if (isNil QGVAR(targetSolutionInput)) then { + call FUNC(calculate_target_solution); + }; + private _solutionInput = +GVAR(targetSolutionInput); + + if (_transonicRange == 0) then { + _transonicRange = Round(403 call FUNC(calculate_distance_at_velocity)); + }; + _solutionInput set [13, _transonicRange]; + private _result1 = _solutionInput call FUNC(calculate_solution); + _transonicDrop = Round((_result1 select 0) * 100) / 100; + GVAR(truingDropRangeData) set [0, _transonicRange]; + GVAR(truingDropDropData) set [1, _transonicDrop]; + GVAR(truingDropReferenceDropData) set [0, _transonicDrop]; + + private _speedOfSound = (_solutionInput select 5) call EFUNC(weather,calculateSpeedOfSound); + if (_subsonicRange == 0) then { + _subsonicRange = _speedOfSound call FUNC(calculate_distance_at_velocity); + if (GVAR(currentUnit) == 2) then { + _subsonicRange = _subsonicRange + 200; + } else { + _subsonicRange = _subsonicRange + 200 * 1.0936133; + }; + _subsonicRange = Round(_subsonicRange); + }; + _solutionInput set [13, _subsonicRange]; + private _result2 = _solutionInput call FUNC(calculate_solution); + _subsonicDrop = Round((_result2 select 0) * 100) / 100; + GVAR(truingDropRangeData) set [1, _subsonicRange]; + GVAR(truingDropDropData) set [2, _subsonicDrop]; + GVAR(truingDropReferenceDropData) set [1, _subsonicDrop]; +} else { + if (_transonicDrop != GVAR(truingDropDropData) select 1 || _subsonicDrop != GVAR(truingDropDropData) select 2) then { + GVAR(truingDropDropData) set [1, _transonicDrop]; + GVAR(truingDropDropData) set [2, _subsonicDrop]; + if (GVAR(truingDropMode) == 0) then { + call FUNC(true_muzzle_velocity); + } else { + call FUNC(true_c1_ballistic_coefficient); + }; + }; +}; + +call FUNC(update_truing_drop_data); diff --git a/addons/atragmx/functions/fnc_can_show.sqf b/addons/atragmx/functions/fnc_can_show.sqf index 7054e85cf9..6d3ed1f6ec 100644 --- a/addons/atragmx/functions/fnc_can_show.sqf +++ b/addons/atragmx/functions/fnc_can_show.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Tests if the ATragMX dialog can be shown * * Arguments: - * Nothing + * None * * Return Value: * can_show @@ -13,6 +14,5 @@ * * Public: No */ -#include "script_component.hpp" (("ACE_ATragMX" in (uniformItems ACE_player)) || ("ACE_ATragMX" in (vestItems ACE_player))) && !(underwater ACE_player); diff --git a/addons/atragmx/functions/fnc_change_gun.sqf b/addons/atragmx/functions/fnc_change_gun.sqf index babd4e733c..9b3863420b 100644 --- a/addons/atragmx/functions/fnc_change_gun.sqf +++ b/addons/atragmx/functions/fnc_change_gun.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Selects a new gun profile and updates the gun column and the result input/output fields @@ -8,14 +9,13 @@ * update display * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_change_gun * * Public: No */ -#include "script_component.hpp" params ["_gunID", "_restoreMemory", "_updateDisplay"]; @@ -26,6 +26,12 @@ if (_restoreMemory) then { }; GVAR(currentGun) = _gunID; +[false, false] call FUNC(recalculate_muzzle_velocity); +if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + false call FUNC(restore_truing_drop); + [false, false] call FUNC(recalculate_c1_ballistic_coefficient); +}; + if (_updateDisplay) then { lbSetCurSel [6000, GVAR(currentGun)]; }; @@ -37,6 +43,8 @@ GVAR(currentScopeClickNumber) = 1 max (GVAR(workingMemory) select 8) min 10; if (_updateDisplay) then { [] call FUNC(update_gun); [] call FUNC(update_gun_ammo_data); + [] call FUNC(update_muzzle_velocity_data); + [] call FUNC(update_c1_ballistic_coefficient_data); }; GVAR(elevationOutput) set [GVAR(currentTarget), 0]; @@ -45,6 +53,9 @@ GVAR(windage2Output) set [GVAR(currentTarget), 0]; GVAR(leadOutput) set [GVAR(currentTarget), 0]; GVAR(tofOutput) set [GVAR(currentTarget), 0]; GVAR(velocityOutput) set [GVAR(currentTarget), 0]; +GVAR(verticalCoriolisOutput) set [GVAR(currentTarget), 0]; +GVAR(horizontalCoriolisOutput) set [GVAR(currentTarget), 0]; +GVAR(spinDriftOutput) set [GVAR(currentTarget), 0]; if (_updateDisplay) then { [] call FUNC(calculate_target_solution); diff --git a/addons/atragmx/functions/fnc_change_target_slot.sqf b/addons/atragmx/functions/fnc_change_target_slot.sqf index a867749f21..71118748d9 100644 --- a/addons/atragmx/functions/fnc_change_target_slot.sqf +++ b/addons/atragmx/functions/fnc_change_target_slot.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Selects a target slot (A, B, C or D) @@ -6,20 +7,17 @@ * target * * Return Value: - * Nothing + * None * * Example: * 2 call ace_atragmx_fnc_change_target_slot * * Public: No */ -#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); +call FUNC(calculate_target_solution); diff --git a/addons/atragmx/functions/fnc_clear_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_clear_c1_ballistic_coefficient_data.sqf new file mode 100644 index 0000000000..22aa0ac3f8 --- /dev/null +++ b/addons/atragmx/functions/fnc_clear_c1_ballistic_coefficient_data.sqf @@ -0,0 +1,21 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Clears the c1 ballistic coefficient data fields + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_clear_c1_ballistic_coefficient_data + * + * Public: No + */ + +// Distances +{ctrlSetText [_x, "0"]} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; +// Ballistic Coefficients +{ctrlSetText [_x, "0"]} forEach [170031, 170032, 170033, 170034, 170035, 170036, 170037]; diff --git a/addons/atragmx/functions/fnc_clear_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_clear_muzzle_velocity_data.sqf new file mode 100644 index 0000000000..4e686202e1 --- /dev/null +++ b/addons/atragmx/functions/fnc_clear_muzzle_velocity_data.sqf @@ -0,0 +1,21 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Clears the muzzle velocity data fields + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_clear_muzzle_velocity_data + * + * Public: No + */ + +// Temperatures +{ctrlSetText [_x, "0"]} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; +// Muzzle velocities +{ctrlSetText [_x, "0"]} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; diff --git a/addons/atragmx/functions/fnc_clear_user_data.sqf b/addons/atragmx/functions/fnc_clear_user_data.sqf index 308b5bbf12..e166b56880 100644 --- a/addons/atragmx/functions/fnc_clear_user_data.sqf +++ b/addons/atragmx/functions/fnc_clear_user_data.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Removes all user data from the profileNamespace * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_clear_user_data * * Public: No */ -#include "script_component.hpp" profileNamespace setVariable ["ACE_ATragMX_gunList", nil]; @@ -28,6 +28,7 @@ profileNamespace setVariable ["ACE_ATragMX_temperature", nil]; profileNamespace setVariable ["ACE_ATragMX_barometricPressure", nil]; profileNamespace setVariable ["ACE_ATragMX_relativeHumidity", nil]; +profileNamespace setVariable ["ACE_ATragMX_showCoriolis", nil]; profileNamespace setVariable ["ACE_ATragMX_showWind2", nil]; profileNamespace setVariable ["ACE_ATragMX_latitude", nil]; profileNamespace setVariable ["ACE_ATragMX_directionOfFire", nil]; @@ -42,4 +43,4 @@ profileNamespace setVariable ["ACE_ATragMX_targetRange", nil]; profileNamespace setVariable ["ACE_ATragMX_rangeCardStartRange", nil]; profileNamespace setVariable ["ACE_ATragMX_rangeCardEndRange", nil]; profileNamespace setVariable ["ACE_ATragMX_rangeCardIncrement", nil]; -profileNamespace setVariable ["ACE_ATragMX_rangeCardCurrentColumn", nil]; \ No newline at end of file +profileNamespace setVariable ["ACE_ATragMX_rangeCardCurrentColumn", nil]; diff --git a/addons/atragmx/functions/fnc_create_dialog.sqf b/addons/atragmx/functions/fnc_create_dialog.sqf index 2eee7c1824..2b1975b567 100644 --- a/addons/atragmx/functions/fnc_create_dialog.sqf +++ b/addons/atragmx/functions/fnc_create_dialog.sqf @@ -1,23 +1,33 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Creates the ATragMX dialog * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_create_dialog * * Public: No */ -#include "script_component.hpp" #define __dsp (uiNamespace getVariable "ATragMX_Display") #define __ctrlBackground (__dsp displayCtrl 720000) +// Do all initialisation now +if (!GVAR(initialised)) then { + [] call FUNC(initGunList); + [] call FUNC(init); + [] call FUNC(restore_user_data); + [] call FUNC(read_gun_list_entries_from_config); + GVAR(initialised) = true; + TRACE_1("",GVAR(initialised)); +}; + if (GVAR(active)) exitWith { false }; if (underwater ACE_player) exitWith { false }; if (!("ACE_ATragMX" in (uniformItems ACE_player)) && !("ACE_ATragMX" in (vestItems ACE_player))) exitWith { false }; @@ -30,8 +40,10 @@ GVAR(showMainPage) call FUNC(show_main_page); GVAR(showAddNewGun) call FUNC(show_add_new_gun); GVAR(showAtmoEnvData) call FUNC(show_atmo_env_data); +GVAR(showC1BallisticCoefficientData) call FUNC(show_c1_ballistic_coefficient_data); GVAR(showGunAmmoData) call FUNC(show_gun_ammo_data); GVAR(showGunList) call FUNC(show_gun_list); +GVAR(showMuzzleVelocityData) call FUNC(show_muzzle_velocity_data); GVAR(showRangeCard) call FUNC(show_range_card); if (GVAR(showRangeCard)) then { ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 5001); @@ -43,6 +55,7 @@ GVAR(showTargetData) call FUNC(show_target_data); GVAR(showTargetRangeAssist) call FUNC(show_target_range_assist); GVAR(showTargetSpeedAssist) call FUNC(show_target_speed_assist); GVAR(showTargetSpeedAssistTimer) call FUNC(show_target_speed_assist_timer); +GVAR(showTruingDrop) call FUNC(show_truing_drop); [GVAR(currentGun), false, true] call FUNC(change_gun); @@ -50,6 +63,13 @@ GVAR(showTargetSpeedAssistTimer) call FUNC(show_target_speed_assist_timer); lbAdd [6000, _x select 0]; } forEach GVAR(gunList); +ctrlShow [3001, false]; +ctrlShow [3002, false]; + +{ + (__dsp displayCtrl _x) ctrlEnable false; +} forEach [18006, 18007, 18008]; + GVAR(active) = true; GVAR(DialogPFH) = [{ diff --git a/addons/atragmx/functions/fnc_cycle_gun_list.sqf b/addons/atragmx/functions/fnc_cycle_gun_list.sqf index 1cc22abb45..7d0c6b5ab4 100644 --- a/addons/atragmx/functions/fnc_cycle_gun_list.sqf +++ b/addons/atragmx/functions/fnc_cycle_gun_list.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Cycles through the gun list @@ -6,14 +7,13 @@ * step * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_cycle_scope_unit * * Public: No */ -#include "script_component.hpp" if (!(GVAR(showMainPage) || GVAR(showGunList))) exitWith {}; diff --git a/addons/atragmx/functions/fnc_cycle_image_size_units.sqf b/addons/atragmx/functions/fnc_cycle_image_size_units.sqf index ce91f818c6..70b35ec58c 100644 --- a/addons/atragmx/functions/fnc_cycle_image_size_units.sqf +++ b/addons/atragmx/functions/fnc_cycle_image_size_units.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Cycles through the image size units @@ -6,14 +7,13 @@ * step * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_cycle_image_size_units * * Public: No */ -#include "script_component.hpp" GVAR(rangeAssistImageSizeUnit) = (GVAR(rangeAssistImageSizeUnit) + 1) % (count GVAR(rangeAssistImageSizeUnits)); ctrlSetText [7015, GVAR(rangeAssistImageSizeUnits) select GVAR(rangeAssistImageSizeUnit)]; diff --git a/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf b/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf index 49b4ad0ffa..65361b9860 100644 --- a/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf +++ b/addons/atragmx/functions/fnc_cycle_num_ticks_units.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Cycles through the num ticks units @@ -6,14 +7,13 @@ * step * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_cycle_num_ticks_units * * Public: No */ -#include "script_component.hpp" GVAR(speedAssistNumTicksUnit) = (GVAR(speedAssistNumTicksUnit) + 1) % (count GVAR(speedAssistNumTicksUnits)); ctrlSetText [8009, GVAR(speedAssistNumTicksUnits) select GVAR(speedAssistNumTicksUnit)]; diff --git a/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf b/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf index dc572ede19..b9432996cb 100644 --- a/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf +++ b/addons/atragmx/functions/fnc_cycle_range_card_columns.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Cycles through the range card columns * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_cycle_range_card_columns * * Public: No */ -#include "script_component.hpp" GVAR(rangeCardCurrentColumn) = (GVAR(rangeCardCurrentColumn) + 1) % (count GVAR(rangeCardLastColumns)); diff --git a/addons/atragmx/functions/fnc_cycle_scope_unit.sqf b/addons/atragmx/functions/fnc_cycle_scope_unit.sqf index d83236bc78..74c5a37dd4 100644 --- a/addons/atragmx/functions/fnc_cycle_scope_unit.sqf +++ b/addons/atragmx/functions/fnc_cycle_scope_unit.sqf @@ -1,24 +1,24 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Cycles through the scope units * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_cycle_scope_unit * * Public: No */ -#include "script_component.hpp" - -[] call FUNC(parse_input); GVAR(currentScopeUnit) = (GVAR(currentScopeUnit) + 1) % (count GVAR(scopeUnits)); GVAR(workingMemory) set [6, GVAR(currentScopeUnit)]; +true call FUNC(show_main_page); + [] call FUNC(update_scope_unit); [] call FUNC(update_result); diff --git a/addons/atragmx/functions/fnc_cycle_target_size_units.sqf b/addons/atragmx/functions/fnc_cycle_target_size_units.sqf index f44d2a5343..36165ddae5 100644 --- a/addons/atragmx/functions/fnc_cycle_target_size_units.sqf +++ b/addons/atragmx/functions/fnc_cycle_target_size_units.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Cycles through the target size units @@ -6,14 +7,13 @@ * step * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_cycle_target_size_units * * Public: No */ -#include "script_component.hpp" GVAR(rangeAssistTargetSizeUnit) = (GVAR(rangeAssistTargetSizeUnit) + 1) % (count GVAR(rangeAssistTargetSizeUnits)); ctrlSetText [7014, GVAR(rangeAssistTargetSizeUnits) select GVAR(rangeAssistTargetSizeUnit)]; diff --git a/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf b/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf index 568dbcec53..42d3232d54 100644 --- a/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf +++ b/addons/atragmx/functions/fnc_cycle_target_speed_direction.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Cycles through the target directions left/right * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_cycle_target_direction * * Public: No */ -#include "script_component.hpp" if ((ctrlText 140051) == ">") then { ctrlSetText [140051, "<"]; diff --git a/addons/atragmx/functions/fnc_delete_gun.sqf b/addons/atragmx/functions/fnc_delete_gun.sqf index 42970d7aab..b5c209717d 100644 --- a/addons/atragmx/functions/fnc_delete_gun.sqf +++ b/addons/atragmx/functions/fnc_delete_gun.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Deletes the currently selected gun profile from the profileNamespace * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_delete_gun * * Public: No */ -#include "script_component.hpp" private _index = lbCurSel 6000; @@ -28,4 +28,4 @@ GVAR(gunList) = GVAR(gunList) - [0]; lbDelete [6000, _index]; -profileNamespace setVariable ["ACE_ATragMX_gunList", GVAR(gunList)]; +call FUNC(store_gun_list); diff --git a/addons/atragmx/functions/fnc_evaluate_option_menu_input.sqf b/addons/atragmx/functions/fnc_evaluate_option_menu_input.sqf new file mode 100644 index 0000000000..bcbd2b87c5 --- /dev/null +++ b/addons/atragmx/functions/fnc_evaluate_option_menu_input.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Evalutes input from the option menu + * + * Arguments: + * option menu id + * + * Return Value: + * None + * + * Example: + * 1 call ace_atragmx_fnc_evaluate_option_menu_input + * + * Public: No + */ + +params ["_optionID"]; + +switch (_optionID) do { + case 0: {}; // Accuracy 1st + case 1: { 0 call FUNC(toggle_muzzle_velocity_data); }; // MuzVel Table + case 2: { 0 call FUNC(toggle_c1_ballistic_coefficient_data); }; // Bal Coef Table + case 3: { 0 call FUNC(toggle_target_speed_assist); }; // Target Speed Est + case 4: { 0 call FUNC(toggle_target_range_assist); }; // Target Range Est + case 5: { 0 call FUNC(toggle_truing_drop); }; // Truing Drop + case 6: { 0 call FUNC(toggle_coriolis); }; // Show Coriolis + case 7: { 0 call FUNC(toggle_solution_setup); }; // Set Clicks + case 8: {}; // Gun Note +}; diff --git a/addons/atragmx/functions/fnc_init.sqf b/addons/atragmx/functions/fnc_init.sqf index 30b17ebf90..2dcd34d493 100644 --- a/addons/atragmx/functions/fnc_init.sqf +++ b/addons/atragmx/functions/fnc_init.sqf @@ -1,21 +1,20 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Inits all global variables with the default values * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_init * * Public: No */ -#include "script_component.hpp" -GVAR(active) = false; GVAR(workingMemory) = +(GVAR(gunList) select 0); @@ -52,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]; @@ -65,18 +64,35 @@ GVAR(targetSpeedDirection) = [1, 1, 1, 1]; GVAR(targetRange) = [0, 0, 0, 0]; GVAR(showWind2) = false; +GVAR(showCoriolis) = false; GVAR(elevationOutput) = [0, 0, 0, 0]; GVAR(windage1Output) = [0, 0, 0, 0]; GVAR(windage2Output) = [0, 0, 0, 0]; GVAR(leadOutput) = [0, 0, 0, 0]; GVAR(tofOutput) = [0, 0, 0, 0]; GVAR(velocityOutput) = [0, 0, 0, 0]; +GVAR(verticalCoriolisOutput) = [0, 0, 0, 0]; +GVAR(horizontalCoriolisOutput) = [0, 0, 0, 0]; +GVAR(spinDriftOutput) = [0, 0, 0, 0]; + +GVAR(truingDropMode) = 0; +GVAR(truingDropRangeData) = [0, 0]; +GVAR(truingDropDropData) = [0, 0, 0]; +GVAR(truingDropReferenceDropData) = [0, 0, 0]; +GVAR(truingDropC1) = 0; +GVAR(truingDropMuzzleVelocity) = 0; + +GVAR(targetSolutionInput) = nil; + +GVAR(targetRangeDirtyFlag) = false; GVAR(showMainPage) = true; GVAR(showAddNewGun) = false; GVAR(showAtmoEnvData) = false; +GVAR(showC1BallisticCoefficientData) = false; GVAR(showGunAmmoData) = false; GVAR(showGunList) = false; +GVAR(showMuzzleVelocityData) = false; GVAR(showRangeCard) = false; GVAR(showRangeCardSetup) = false; GVAR(showSolutionSetup) = false; @@ -84,3 +100,4 @@ GVAR(showTargetData) = false; GVAR(showTargetRangeAssist) = false; GVAR(showTargetSpeedAssist) = false; GVAR(showTargetSpeedAssistTimer) = false; +GVAR(showTruingDrop) = false; diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf new file mode 100644 index 0000000000..3ffcaf976c --- /dev/null +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -0,0 +1,83 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Inits the gun list from user profile + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_initGunList + * + * Public: No + */ + +LOG_2("Trying to load gunlist from profile [Version: %1][Count: %2]", profileNamespace getVariable [ARR_2(QGVAR(profileNamespaceVersion), 'none')], count (profileNamespace getVariable [ARR_2(QGVAR(gunList), [])])); + +private _resetGunList = true; +if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == ATRAGMX_PROFILE_NAMESPACE_VERSION && {count (profileNamespace getVariable ["ACE_ATragMX_gunList", []]) > 0}) then { + GVAR(gunList) = profileNamespace getVariable "ACE_ATragMX_gunList"; + _resetGunList = false; + { + // Verify each gun has correct param type + if (!(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false])) exitWith { + _resetGunList = true; + }; + } forEach GVAR(gunList); +}; + +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.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.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.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.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.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.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.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.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" , 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.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.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.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.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.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.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_insert_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_insert_c1_ballistic_coefficient_data.sqf new file mode 100644 index 0000000000..69d23b4e43 --- /dev/null +++ b/addons/atragmx/functions/fnc_insert_c1_ballistic_coefficient_data.sqf @@ -0,0 +1,55 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Inserts entry in the c1 ballistic coefficient vs. distance interpolation table + * + * Arguments: + * transonic range - + * subsonic range - + * c1 ballistic coefficient - + * + * Return Value: + * None + * + * Example: + * [800, 0.485] call ace_atragmx_fnc_insert_c1_ballistic_coefficient_data + * + * Public: No + */ + +params ["_transonicRange", "_subsonicRange", "_c1"]; + +private _entries = {(_x select 1) > 0} count (GVAR(workingMemory) select 19); + +if (_entries > 0) then { + // Insert + private _insertIndex = 0; + private _minDiff = 10000; + { + if (_minDiff > 0 && {(((GVAR(workingMemory) select 19) select _forEachIndex) select 1) == 0}) then { + _insertIndex = _forEachIndex; + _minDiff = 0; + }; + private _tr = ((GVAR(workingMemory) select 19) select _forEachIndex) select 0; + private _diff = abs(_subsonicRange - _tr); + if (_diff == 0) exitWith { + _insertIndex = _forEachIndex; + }; + if (_diff < _minDiff) then { + _insertIndex = _forEachIndex; + _minDiff = _diff; + }; + } forEach (GVAR(workingMemory) select 19); + + (GVAR(workingMemory) select 19) set [_insertIndex, [_subsonicRange, 0.1 max _c1 min 2.0]]; +} else { + // Reset + private _zeroRange = GVAR(workingMemory) select 2; + private _bc = GVAR(workingMemory) select 15; + GVAR(workingMemory) set [19, [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]]]; + (GVAR(workingMemory) select 19) set [0, [_zeroRange, _bc]]; + (GVAR(workingMemory) select 19) set [1, [_transonicRange + (_subsonicRange - _transonicRange) * 0.75, _bc]]; + (GVAR(workingMemory) select 19) set [2, [_subsonicRange, 0.1 max _c1 min 2.0]]; +}; + +call FUNC(update_c1_ballistic_coefficient_data); diff --git a/addons/atragmx/functions/fnc_insert_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_insert_muzzle_velocity_data.sqf new file mode 100644 index 0000000000..0e508e37e1 --- /dev/null +++ b/addons/atragmx/functions/fnc_insert_muzzle_velocity_data.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Inserts entry in the muzzle velocity vs. temperature interpolation table + * + * Arguments: + * temperature - + * muzzle velocity - + * + * Return Value: + * None + * + * Example: + * [10, 800] call ace_atragmx_fnc_insert_muzzle_velocity_data + * + * Public: No + */ + +params ["_temperature", "_muzzleVelocity"]; + +private _insertIndex = 0; +private _minDiff = 1000; +{ + if (_minDiff > 0 && {(((GVAR(workingMemory) select 18) select _forEachIndex) select 1) == 0}) then { + _insertIndex = _forEachIndex; + _minDiff = 0; + }; + private _t = ((GVAR(workingMemory) select 18) select _forEachIndex) select 0; + private _diff = abs(_temperature - _t); + if (_diff == 0) exitWith { + _insertIndex = _forEachIndex; + }; + if (_diff < _minDiff) then { + _insertIndex = _forEachIndex; + _minDiff = _diff; + }; +} forEach (GVAR(workingMemory) select 18); + +(GVAR(workingMemory) select 18) set [_insertIndex, [_temperature, 0 max _muzzleVelocity min 1400]]; + +call FUNC(update_muzzle_velocity_data); 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..3d0b348874 --- /dev/null +++ b/addons/atragmx/functions/fnc_lookup_c1_ballistic_coefficient.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * 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_on_close_dialog.sqf b/addons/atragmx/functions/fnc_on_close_dialog.sqf index fca60574a9..d9ebf1cb00 100644 --- a/addons/atragmx/functions/fnc_on_close_dialog.sqf +++ b/addons/atragmx/functions/fnc_on_close_dialog.sqf @@ -1,5 +1,20 @@ #include "script_component.hpp" +/* + * Author: ACE-Team + * On close Dialog + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_on_close_dialog + * + * Public: No + */ uiNamespace setVariable ['ATragMX_Display', nil]; GVAR(active) = false; -[GVAR(DialogPFH)] call CBA_fnc_removePerFrameHandler; \ No newline at end of file +[GVAR(DialogPFH)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/atragmx/functions/fnc_parse_input.sqf b/addons/atragmx/functions/fnc_parse_input.sqf index 61a8caea6a..d03b8bd186 100644 --- a/addons/atragmx/functions/fnc_parse_input.sqf +++ b/addons/atragmx/functions/fnc_parse_input.sqf @@ -1,38 +1,114 @@ +#include "script_component.hpp" /* * Author: Ruthberg - * Parses all input fields in the gun, atmosphere and target column and the result input fields + * Parses all input fields in the gun-, atmosphere- and target column, the result input fields and the muzzle velocity data input fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_parse_input * * Public: No */ -#include "script_component.hpp" -GVAR(altitude) = -1000 max parseNumber(ctrlText 130030) min 20000; -GVAR(temperature) = -50 max parseNumber(ctrlText 130040) min 160; -GVAR(barometricPressure) = 10 max parseNumber(ctrlText 130050) min 1350; -GVAR(relativeHumidity) = (0 max parseNumber(ctrlText 130060) min 100) / 100; +// Muzzle velocity vs. temperature interpolation data +{ + private _temperature = parseNumber(ctrlText _x); + if (GVAR(currentUnit) != 2) then { + _temperature = -50 max _temperature min 160; + _temperature = (_temperature - 32) / 1.8; + } else { + _temperature = -50 max _temperature min 71; + }; + ((GVAR(workingMemory) select 18) select _forEachIndex) set [0, _temperature]; +} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; +{ + private _muzzleVelocity = abs(parseNumber(ctrlText _x)); + if (_muzzleVelocity > 0) then { + if (GVAR(currentUnit) != 2) then { + _muzzleVelocity = 300 max _muzzleVelocity min 4500; + _muzzleVelocity = _muzzleVelocity * 0.3048; + } else { + _muzzleVelocity = 100 max _muzzleVelocity min 1400; + }; + }; + ((GVAR(workingMemory) select 18) select _forEachIndex) set [1, _muzzleVelocity]; +} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; + +// C1 coefficient vs. distance interpolation data +{ + private _distance = abs(parseNumber(ctrlText _x)); + if (_distance > 0) then { + if (GVAR(currentUnit) == 1) then { + _distance = 25 max _distance min 4000; + _distance = _distance * 0.9144; + } else { + _distance = 25 max _distance min 3700; + }; + }; + ((GVAR(workingMemory) select 19) select _forEachIndex) set [0, _distance]; +} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; +{ + private _c1 = abs(parseNumber(ctrlText _x)); + if (_c1 > 0) then { + _c1 = 0.1 max _c1 min 2.0; + }; + ((GVAR(workingMemory) select 19) select _forEachIndex) set [1, _c1]; +} forEach [170031, 170032, 170033, 170034, 170035, 170036, 170037]; + +GVAR(altitude) = parseNumber(ctrlText 130030); +GVAR(temperature) = parseNumber(ctrlText 130040); +GVAR(barometricPressure) = parseNumber(ctrlText 130050); +GVAR(relativeHumidity) = parseNumber(ctrlText 130060) / 100; if (GVAR(currentUnit) != 2) then { + GVAR(altitude) = -1000 max GVAR(altitude) min 20000; + GVAR(temperature) = -50 max GVAR(temperature) min 160; + GVAR(barometricPressure) = 10 max GVAR(barometricPressure) min 40; GVAR(altitude) = GVAR(altitude) * 0.3048; GVAR(temperature) = (GVAR(temperature) - 32) / 1.8; GVAR(barometricPressure) = GVAR(barometricPressure) * 33.86389; +} else { + GVAR(altitude) = -300 max GVAR(altitude) min 6100; + GVAR(temperature) = -50 max GVAR(temperature) min 71; + GVAR(barometricPressure) = 340 max GVAR(barometricPressure) min 1350; }; -private ["_inclinationAngleCosine", "_inclinationAngleDegree"]; +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; + _targetSpeed = 0 max _targetSpeed min 50; + _windSpeed1 = _windSpeed1 * 0.44704; + _windSpeed2 = _windSpeed2 * 0.44704; + _targetSpeed = _targetSpeed * 0.44704; +} else { + _windSpeed1 = 0 max _windSpeed1 min 25; + _windSpeed2 = 0 max _windSpeed2 min 25; + _targetSpeed = 0 max _targetSpeed min 25; +}; +if (GVAR(currentUnit) == 1) then { + _targetRange = 25 max _targetRange min 4000; + _targetRange = _targetRange * 0.9144; +} 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), 0 max abs(parseNumber(ctrlText 140020)) min 50]; -GVAR(windSpeed2) set [GVAR(currentTarget), 0 max abs(parseNumber(ctrlText 140021)) min 50]; +GVAR(windSpeed1) set [GVAR(currentTarget), _windSpeed1]; +GVAR(windSpeed2) set [GVAR(currentTarget), _windSpeed2]; GVAR(windDirection) set [GVAR(currentTarget), 1 max Round(parseNumber(ctrlText 140030)) min 12]; -_inclinationAngleCosine = 0.5 max parseNumber(ctrlText 140041) min 1; -_inclinationAngleDegree = -60 max round(parseNumber(ctrlText 140040)) min 60; +GVAR(targetSpeed) set [GVAR(currentTarget), _targetSpeed]; +GVAR(targetRange) set [GVAR(currentTarget), _targetRange]; +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 { @@ -40,66 +116,76 @@ if (_inclinationAngleDegree != GVAR(inclinationAngle) select GVAR(currentTarget) GVAR(inclinationAngle) set [GVAR(currentTarget), round(acos(_inclinationAngleCosine))]; }; }; -GVAR(targetSpeed) set [GVAR(currentTarget), 0 max abs(parseNumber(ctrlText 140050)) min 50]; if ((ctrlText 140051) == ">") then { GVAR(targetSpeedDirection) set [GVAR(currentTarget), +1]; } else { GVAR(targetSpeedDirection) set [GVAR(currentTarget), -1]; }; -GVAR(targetRange) set [GVAR(currentTarget), 0 max abs(parseNumber(ctrlText 140060)) min 4000]; -if (GVAR(currentUnit) != 2) then { - GVAR(windSpeed1) set [GVAR(currentTarget), (GVAR(windSpeed1) select GVAR(currentTarget)) * 0.44704]; - GVAR(windSpeed2) set [GVAR(currentTarget), (GVAR(windSpeed2) select GVAR(currentTarget)) * 0.44704]; - GVAR(targetSpeed) set [GVAR(currentTarget), (GVAR(targetSpeed) select GVAR(currentTarget)) * 0.44704]; -}; -if (GVAR(currentUnit) == 1) then { - GVAR(targetRange) set [GVAR(currentTarget), (GVAR(targetRange) select GVAR(currentTarget)) * 0.9144]; -}; -private ["_boreHeight", "_bulletMass", "_bulletDiameter", "_airFriction", "_rifleTwist", "_muzzleVelocity", "_zeroRange"]; -_boreHeight = parseNumber(ctrlText 120000); -_bulletMass = parseNumber(ctrlText 120010); -_bulletDiameter = parseNumber(ctrlText 120020) * 10; +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 parseNumber(ctrlText 120030) min 2; + _airFriction = 0.1 max _airFriction min 2; } else { - _airFriction = parseNumber(ctrlText 120030) / -1000; + _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; + _bulletDiameter = 0.1 max _bulletDiameter min 1.0; + _rifleTwist = 1 max _rifleTwist min 36; + _muzzleVelocity = 300 max _muzzleVelocity min 4500; _boreHeight = _boreHeight * 2.54; _bulletMass = _bulletMass * 0.06479891; _bulletDiameter = _bulletDiameter * 2.54; _rifleTwist = _rifleTwist * 2.54; - _muzzleVelocity = _muzzleVelocity / 3.2808399; + _muzzleVelocity = _muzzleVelocity * 0.3048; +} else { + _boreHeight = 0.1 max _boreHeight min 10; + _bulletMass = 1 max _bulletMass min 100; + _bulletDiameter = 0.1 max _bulletDiameter min 2.5; + _rifleTwist = 1 max _rifleTwist min 75; + _muzzleVelocity = 100 max _muzzleVelocity min 1400; }; +_zeroRange = 25 max _zeroRange min 1000; if (GVAR(currentUnit) == 1) then { - _zeroRange = _zeroRange / 1.0936133; + _zeroRange = _zeroRange * 0.9144; }; -_boreHeight = 0.1 max _boreHeight min 10; -_bulletMass = 1 max _bulletMass min 100; -_bulletDiameter = 1 max _bulletDiameter min 25; -_muzzleVelocity = 100 max _muzzleVelocity min 1400; -_zeroRange = 0 max _zeroRange min 1000; GVAR(workingMemory) set [5, _boreHeight]; GVAR(workingMemory) set [12, _bulletMass]; -GVAR(workingMemory) set [13, _bulletDiameter]; +GVAR(workingMemory) set [13, _bulletDiameter * 10]; GVAR(workingMemory) set [14, _rifleTwist]; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + if (_airFriction != GVAR(workingMemory) select 15) then { + (_airFriction - (GVAR(workingMemory) select 15)) call FUNC(shift_c1_ballistic_coefficient_data); + }; GVAR(workingMemory) set [15, _airFriction]; } else { GVAR(workingMemory) set [4, _airFriction]; }; +if (_muzzleVelocity != GVAR(workingMemory) select 1) then { + (_muzzleVelocity - (GVAR(workingMemory) select 1)) call FUNC(shift_muzzle_velocity_data); +}; 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); [] call FUNC(update_atmo_env_data); [] call FUNC(update_target); [] call FUNC(update_target_data); +[] call FUNC(update_muzzle_velocity_data); +[] call FUNC(update_c1_ballistic_coefficient_data); [] call FUNC(store_user_data); diff --git a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf new file mode 100644 index 0000000000..3ae566557b --- /dev/null +++ b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf @@ -0,0 +1,123 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Reads gun list entries from the config and appends them to the gun list + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_read_gun_list_entries_from_config + * + * Public: No + */ + +private _validate_preset = { + private _valid = true; + if (count _this != 20) then { + private _errorMsg = format ["Invalid preset array size: %1", count _this]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 0 == "") then { + ERROR("Invalid gun profile name"); + _valid = false; + }; + if (count (_this select 0) > 14) then { + WARNING("Gun profile name too long (max. allowed 14 characters)"); + }; + if (_this select 1 < 0 || _this select 1 > 1400) then { + private _errorMsg = format ["Invalid muzzle velocity: %1", _this select 1]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 2 < 25 || _this select 2 > 1000) then { + private _errorMsg = format ["Invalid zero range: %1", _this select 2]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 4 > 0) then { + private _errorMsg = format ["Invalid airFriction value: %1", _this select 4]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 5 < 0.1 || _this select 5 > 10) then { + private _errorMsg = format ["Invalid bore height value: %1", _this select 4]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 12 < 1 || _this select 12 > 100) then { + private _errorMsg = format ["Invalid bullet weight: %1", _this select 12]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 13 < 1 || _this select 13 > 25) then { + private _errorMsg = format ["Invalid bullet diameter: %1", _this select 13]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 14 < 1 || _this select 14 > 75) then { + private _errorMsg = format ["Invalid rifle twist: %1", _this select 14]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 15 < 0.1 || _this select 15 > 2.0) then { + private _errorMsg = format ["Invalid ballistic coefficient: %1", _this select 15]; + ERROR(_errorMsg); + _valid = false; + }; + if (_this select 16 != 1) then { + private _errorMsg = format ["Invalid drag model: %1", _this select 16]; + ERROR(_errorMsg); + _valid = false; + }; + if (!((_this select 17) in ["ASM", "ICAO"])) then { + private _errorMsg = format ["Invalid atmosphere model: %1", _this select 17]; + ERROR(_errorMsg); + _valid = false; + }; + if (count (_this select 18) != 7) then { + private _errorMsg = format ["Invalid muzzle velocity table array size: %1", count (_this select 18)]; + ERROR(_errorMsg); + _valid = false; + } else { + { + if (count _x != 2) exitWith { + private _errorMsg = format ["Invalid muzzle velocity table subarray size: %1", count _x]; + ERROR(_errorMsg); + _valid = false; + }; + } forEach (_this select 18); + }; + if (count (_this select 19) != 7) then { + private _errorMsg = format ["Invalid drag coefficient table array size: %1", count (_this select 19)]; + ERROR(_errorMsg); + _valid = false; + } else { + { + if (count _x != 2) exitWith { + private _errorMsg = format ["Invalid drag coefficient table subarray size: %1", count _x]; + ERROR(_errorMsg); + _valid = false; + }; + } forEach (_this select 19); + }; + _valid +}; + +{ + private _preset = _x >> "preset"; + + if (isArray(_preset)) then { + private _gun = getArray _preset; + + if (_gun call _validate_preset) then { + _gun set [0, (_gun select 0) select [0, 14]]; + _gun set [20, false]; + GVAR(gunList) = GVAR(gunList) + [_gun]; + }; + }; +} forEach ("true" configClasses (configFile >> "ACE_ATragMX_Presets")); diff --git a/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf new file mode 100644 index 0000000000..273d73a3e3 --- /dev/null +++ b/addons/atragmx/functions/fnc_recalculate_c1_ballistic_coefficient.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Recalculates the c1 ballistic coefficient based on the current target range + * + * Arguments: + * parse input + * update display + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_recalculate_c1_ballistic_coefficient + * + * Public: No + */ + +params ["_parseInput", "_updateDisplay"]; + +if (_parseInput) then { + [] call FUNC(parse_input); +}; + +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]; + if (_updateDisplay) then { + call FUNC(update_gun); + call FUNC(update_gun_ammo_data); + }; +}; diff --git a/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf new file mode 100644 index 0000000000..c46cd9ab16 --- /dev/null +++ b/addons/atragmx/functions/fnc_recalculate_muzzle_velocity.sqf @@ -0,0 +1,56 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Recalculates the muzzle velocity based on the muzzle velocity vs. temperature interpolation input + * + * Arguments: + * parse input + * update display + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_recalculate_muzzle_velocity + * + * Public: No + */ + +params ["_parseInput", "_updateDisplay"]; + +if (_parseInput) then { + [] call FUNC(parse_input); +}; + +private _lookupTable = []; +{ + if ((_x select 1) > 0) then { + _lookupTable pushBack _x; + }; +} forEach (GVAR(workingMemory) select 18); + +private _lookupTableSize = count _lookupTable; +if (_lookupTableSize < 2) exitWith {}; +_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) >= GVAR(temperature)) exitWith {}; +}; + +(_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]; + if (_updateDisplay) then { + call FUNC(update_gun); + call FUNC(update_gun_ammo_data); + }; +}; diff --git a/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf b/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf index 489e832ea2..4a847123df 100644 --- a/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf +++ b/addons/atragmx/functions/fnc_reset_relative_click_memory.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Resets the relative click memory and updates the result input/output fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_reset_relative_click_memory * * Public: No */ -#include "script_component.hpp" GVAR(workingMemory) set [10, 0]; GVAR(workingMemory) set [11, 0]; diff --git a/addons/atragmx/functions/fnc_restore_atmo_default.sqf b/addons/atragmx/functions/fnc_restore_atmo_default.sqf index 08b7c56d86..9b03c337b2 100644 --- a/addons/atragmx/functions/fnc_restore_atmo_default.sqf +++ b/addons/atragmx/functions/fnc_restore_atmo_default.sqf @@ -1,25 +1,25 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Restores the atmospheric data defaults * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_restore_atmo_default * * Public: No */ -#include "script_component.hpp" 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_truing_drop.sqf b/addons/atragmx/functions/fnc_restore_truing_drop.sqf new file mode 100644 index 0000000000..301c94f7a8 --- /dev/null +++ b/addons/atragmx/functions/fnc_restore_truing_drop.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Restores the truing drop defaults + * + * Arguments: + * update display + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_restore_truing_drop + * + * Public: No + */ + +private _updateDisplay = _this; + +GVAR(truingDropMode) = 0; +GVAR(truingDropRangeData) = [0, 0]; +GVAR(truingDropDropData) = [0, 0, 0]; +GVAR(truingDropReferenceDropData) = [0, 0, 0]; +GVAR(truingDropC1) = 0; +GVAR(truingDropMuzzleVelocity) = 0; + +// Resets input fields +call FUNC(update_truing_drop_selection); + +if (_updateDisplay) then { + // Repopulates input fields + false call FUNC(calculate_truing_drop); +}; diff --git a/addons/atragmx/functions/fnc_restore_user_data.sqf b/addons/atragmx/functions/fnc_restore_user_data.sqf index 896455ec7a..beb2c50c4d 100644 --- a/addons/atragmx/functions/fnc_restore_user_data.sqf +++ b/addons/atragmx/functions/fnc_restore_user_data.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Reads user data from profileNamespace * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_restore_user_data * * Public: No */ -#include "script_component.hpp" GVAR(currentUnit) = 0 max (profileNamespace getVariable ["ACE_ATragMX_currentUnit", 2]) min 2; [(profileNamespace getVariable ["ACE_ATragMX_currentGun", 0]), true, false] call FUNC(change_gun); @@ -23,9 +23,10 @@ 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]; GVAR(latitude) = profileNamespace getVariable ["ACE_ATragMX_latitude", [38, 38, 38, 38]]; GVAR(directionOfFire) = profileNamespace getVariable ["ACE_ATragMX_directionOfFire", [0, 0, 0, 0]]; GVAR(windSpeed1) = profileNamespace getVariable ["ACE_ATragMX_windSpeed1", [0, 0, 0, 0]]; diff --git a/addons/atragmx/functions/fnc_save_gun.sqf b/addons/atragmx/functions/fnc_save_gun.sqf index 64fe17e4c4..2560dbd42b 100644 --- a/addons/atragmx/functions/fnc_save_gun.sqf +++ b/addons/atragmx/functions/fnc_save_gun.sqf @@ -1,22 +1,21 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Saves the currently select gun profile into the profileNamespace * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_save_gun * * Public: No */ -#include "script_component.hpp" -private ["_index"]; -_index = 0 max (lbCurSel 6000); +private _index = 0 max (lbCurSel 6000); GVAR(gunList) set [_index, +GVAR(workingMemory)]; @@ -25,4 +24,4 @@ lbClear 6000; lbAdd [6000, _x select 0]; } forEach GVAR(gunList); -profileNamespace setVariable ["ACE_ATragMX_gunList", GVAR(gunList)]; +call FUNC(store_gun_list); diff --git a/addons/atragmx/functions/fnc_shift_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_shift_c1_ballistic_coefficient_data.sqf new file mode 100644 index 0000000000..95ac59b705 --- /dev/null +++ b/addons/atragmx/functions/fnc_shift_c1_ballistic_coefficient_data.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Shifts all c1 ballistic coefficient entries in the c1 ballistic coefficient vs. distance interpolation table + * + * Arguments: + * ballistic coefficient - + * + * Return Value: + * None + * + * Example: + * 10 call ace_atragmx_fnc_shift_c1_ballistic_coefficient_data + * + * Public: No + */ + +if (_this == 0) exitWith {}; + +{ + private _c1 = _x select 1; + if (_c1 > 0) then { + ((GVAR(workingMemory) select 19) select _forEachIndex) set [1, 0.1 max (_c1 + _this) min 2]; + } +} forEach (GVAR(workingMemory) select 19); diff --git a/addons/atragmx/functions/fnc_shift_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_shift_muzzle_velocity_data.sqf new file mode 100644 index 0000000000..4d4e4d2b22 --- /dev/null +++ b/addons/atragmx/functions/fnc_shift_muzzle_velocity_data.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Shifts all muzzle velocity entries in the muzzle velocity vs. temperature interpolation table + * + * Arguments: + * velocity - + * + * Return Value: + * None + * + * Example: + * 10 call ace_atragmx_fnc_shift_muzzle_velocity_data + * + * Public: No + */ + +if (_this == 0) exitWith {}; + +{ + private _velocity = _x select 1; + if (_velocity > 0) then { + ((GVAR(workingMemory) select 18) select _forEachIndex) set [1, 0 max (_velocity + _this) min 1400]; + } +} forEach (GVAR(workingMemory) select 18); diff --git a/addons/atragmx/functions/fnc_show_add_new_gun.sqf b/addons/atragmx/functions/fnc_show_add_new_gun.sqf index b5b0f29a18..a00860490b 100644 --- a/addons/atragmx/functions/fnc_show_add_new_gun.sqf +++ b/addons/atragmx/functions/fnc_show_add_new_gun.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides add new gun controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_add_new_gun + * false call ace_atragmx_fnc_show_add_new_gun * * Public: No */ -#include "script_component.hpp" GVAR(showAddNewGun) = _this; diff --git a/addons/atragmx/functions/fnc_show_atmo_env_data.sqf b/addons/atragmx/functions/fnc_show_atmo_env_data.sqf index 56f75f7844..b07843e18a 100644 --- a/addons/atragmx/functions/fnc_show_atmo_env_data.sqf +++ b/addons/atragmx/functions/fnc_show_atmo_env_data.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the atmosphere and environmental data controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: * false call ace_atragmx_fnc_show_atmo_env_data * * Public: No */ -#include "script_component.hpp" GVAR(showAtmoEnvData) = _this; diff --git a/addons/atragmx/functions/fnc_show_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_show_c1_ballistic_coefficient_data.sqf new file mode 100644 index 0000000000..34f598ac6c --- /dev/null +++ b/addons/atragmx/functions/fnc_show_c1_ballistic_coefficient_data.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Shows/Hides the c1 ballistic coefficient data controls + * + * Arguments: + * visible - + * + * Return Value: + * None + * + * Example: + * false call ace_atragmx_fnc_show_c1_ballistic_coefficient_data + * + * Public: No + */ + +GVAR(showC1BallisticCoefficientData) = _this; + +{ctrlShow [_x, _this]} forEach [17000, 17001, 170021, 170022, 170023, 170024, 170025, 170026, 170027, 170031, 170032, 170033, 170034, 170035, 170036, 170037, 17004, 17005, 17006, 17007, 17008, 17009]; + +if (_this) then { + if (GVAR(currentUnit) != 1) then { + ctrlSetText [17000, "Meters"]; + } else { + ctrlSetText [17000, "Yards"]; + }; + ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 170031); + [] call FUNC(update_c1_ballistic_coefficient_data); +}; diff --git a/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf b/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf index dfab6da238..108108a14c 100644 --- a/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_show_gun_ammo_data.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the gun ammo data controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: * false call ace_atragmx_fnc_show_gun_ammo_data * * Public: No */ -#include "script_component.hpp" GVAR(showGunAmmoData) = _this; diff --git a/addons/atragmx/functions/fnc_show_gun_list.sqf b/addons/atragmx/functions/fnc_show_gun_list.sqf index ce3b3bae3a..714e9a0d12 100644 --- a/addons/atragmx/functions/fnc_show_gun_list.sqf +++ b/addons/atragmx/functions/fnc_show_gun_list.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the gun list controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_gun_list + * false call ace_atragmx_fnc_show_gun_list * * Public: No */ -#include "script_component.hpp" GVAR(showGunList) = _this; diff --git a/addons/atragmx/functions/fnc_show_main_page.sqf b/addons/atragmx/functions/fnc_show_main_page.sqf index 486ea1655a..7b12af4439 100644 --- a/addons/atragmx/functions/fnc_show_main_page.sqf +++ b/addons/atragmx/functions/fnc_show_main_page.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the main menu controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_main_page + * false call ace_atragmx_fnc_show_main_page * * Public: No */ -#include "script_component.hpp" GVAR(showMainPage) = _this; @@ -21,6 +21,18 @@ GVAR(showMainPage) = _this; 500, 501, 502, 503, 600, 601, 602, 603, 1000, 1001, 1002, 1003, 1004, 2000, 2001, 3000, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008]; if (_this) then { + if (GVAR(showCoriolis)) then { + ctrlSetText [4003, "Hold"]; + ctrlSetText [4004, "Cor"]; + ctrlSetText [4005, "Spin"]; + {ctrlShow [_x, false]} forEach [402, 4006, 4007]; + } else { + ctrlSetText [4003, "Abs"]; + ctrlSetText [4004, "Rel"]; + ctrlSetText [4005, "Cur"]; + private _visible = (GVAR(currentScopeUnit) == 3); + {ctrlShow [_x, _visible]} forEach [401, 402, 411, 412, 4004, 4005, 4006, 4007]; + }; if (GVAR(atmosphereModeTBH)) then { {ctrlShow [_x, false]} forEach [23, 230]; } else { diff --git a/addons/atragmx/functions/fnc_show_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_show_muzzle_velocity_data.sqf new file mode 100644 index 0000000000..e12263d36f --- /dev/null +++ b/addons/atragmx/functions/fnc_show_muzzle_velocity_data.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Shows/Hides the muzzle velocity data controls + * + * Arguments: + * visible - + * + * Return Value: + * None + * + * Example: + * false call ace_atragmx_fnc_show_muzzle_velocity_data + * + * Public: No + */ + +GVAR(showMuzzleVelocityData) = _this; + +{ctrlShow [_x, _this]} forEach [16000, 16001, 160021, 160022, 160023, 160024, 160025, 160026, 160027, 160031, 160032, 160033, 160034, 160035, 160036, 160037, 16004, 16005, 16006, 16007, 16008, 16009]; + +if (_this) then { + ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 160031); + [] call FUNC(update_muzzle_velocity_data); +}; diff --git a/addons/atragmx/functions/fnc_show_range_card.sqf b/addons/atragmx/functions/fnc_show_range_card.sqf index 7709589beb..02f65164bb 100644 --- a/addons/atragmx/functions/fnc_show_range_card.sqf +++ b/addons/atragmx/functions/fnc_show_range_card.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the range card controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_range_card + * false call ace_atragmx_fnc_show_range_card * * Public: No */ -#include "script_component.hpp" GVAR(showRangeCard) = _this; diff --git a/addons/atragmx/functions/fnc_show_range_card_setup.sqf b/addons/atragmx/functions/fnc_show_range_card_setup.sqf index f4d55f33d1..183e115b1b 100644 --- a/addons/atragmx/functions/fnc_show_range_card_setup.sqf +++ b/addons/atragmx/functions/fnc_show_range_card_setup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the range card setup controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_range_card_setup + * false call ace_atragmx_fnc_show_range_card_setup * * Public: No */ -#include "script_component.hpp" GVAR(showRangeCardSetup) = _this; diff --git a/addons/atragmx/functions/fnc_show_solution_setup.sqf b/addons/atragmx/functions/fnc_show_solution_setup.sqf index 761df45e6f..4eafd38a31 100644 --- a/addons/atragmx/functions/fnc_show_solution_setup.sqf +++ b/addons/atragmx/functions/fnc_show_solution_setup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the solution setup controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: * false call ace_atragmx_fnc_show_solution_setup * * Public: No */ -#include "script_component.hpp" GVAR(showSolutionSetup) = _this; diff --git a/addons/atragmx/functions/fnc_show_target_data.sqf b/addons/atragmx/functions/fnc_show_target_data.sqf index f1b432edf8..6987047cbf 100644 --- a/addons/atragmx/functions/fnc_show_target_data.sqf +++ b/addons/atragmx/functions/fnc_show_target_data.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target data controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: * false call ace_atragmx_fnc_show_target_data * * Public: No */ -#include "script_component.hpp" GVAR(showTargetData) = _this; diff --git a/addons/atragmx/functions/fnc_show_target_range_assist.sqf b/addons/atragmx/functions/fnc_show_target_range_assist.sqf index d910271aa4..89453c9134 100644 --- a/addons/atragmx/functions/fnc_show_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_show_target_range_assist.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target range assist controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_target_range_assist + * false call ace_atragmx_fnc_show_target_range_assist * * Public: No */ -#include "script_component.hpp" GVAR(showTargetRangeAssist) = _this; diff --git a/addons/atragmx/functions/fnc_show_target_speed_assist.sqf b/addons/atragmx/functions/fnc_show_target_speed_assist.sqf index c5a23eb1b7..267c3676b6 100644 --- a/addons/atragmx/functions/fnc_show_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_show_target_speed_assist.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target speed assist controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_target_speed_assist + * false call ace_atragmx_fnc_show_target_speed_assist * * Public: No */ -#include "script_component.hpp" GVAR(showTargetSpeedAssist) = _this; diff --git a/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf index a731dd194d..fca074547f 100644 --- a/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_show_target_speed_assist_timer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows/Hides the target speed assist timer controls @@ -6,14 +7,13 @@ * visible - * * Return Value: - * Nothing + * None * * Example: - * call ace_atragmx_fnc_show_target_speed_assist_timer + * false call ace_atragmx_fnc_show_target_speed_assist_timer * * Public: No */ -#include "script_component.hpp" GVAR(showTargetSpeedAssistTimer) = _this; diff --git a/addons/atragmx/functions/fnc_show_truing_drop.sqf b/addons/atragmx/functions/fnc_show_truing_drop.sqf new file mode 100644 index 0000000000..ca69346c49 --- /dev/null +++ b/addons/atragmx/functions/fnc_show_truing_drop.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Shows/Hides the truing drop controls + * + * Arguments: + * visible - + * + * Return Value: + * None + * + * Example: + * false call ace_atragmx_fnc_show_truing_drop + * + * Public: No + */ + +GVAR(showTruingDrop) = _this; + +{ctrlShow [_x, _this]} forEach [18000, 18001, 18002, 18003, 18004, 18005, 18006, 18007, 18008, 18009, 18010, 18011, 18012, 18013, 18014, 18015, 18016, 18017, 18018, 18019, 18020]; + +if (_this) then { + if (GVAR(currentUnit) == 2) then { + ctrlSetText [18000, format["ZR=%1meters", Round(GVAR(workingMemory) select 2)]]; + } else { + ctrlSetText [18000, format["ZR=%1yards", Round((GVAR(workingMemory) select 2) * 1.0936133)]]; + }; + private _dropUnit = GVAR(currentScopeUnit); + if (_dropUnit == 3) then { + switch (GVAR(currentScopeClickUnit)) do { + case 0: { _dropUnit = 1; }; + case 1: { _dropUnit = 2; }; + case 2: { _dropUnit = 0; }; + }; + }; + switch (_dropUnit) do { + case 0: { ctrlSetText [18001, "Drop=mils"]; }; + case 1: { ctrlSetText [18001, "Drop=tmoa"]; }; + case 2: { ctrlSetText [18001, "Drop=smoa"]; }; + }; + false call FUNC(calculate_truing_drop); + call FUNC(update_truing_drop_selection); +}; diff --git a/addons/atragmx/functions/fnc_sord.sqf b/addons/atragmx/functions/fnc_sord.sqf index b342072018..a6c3d2b5b8 100644 --- a/addons/atragmx/functions/fnc_sord.sqf +++ b/addons/atragmx/functions/fnc_sord.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Handles incoming data packets from the Vectronix Vector LRF @@ -8,17 +9,20 @@ * 2: Inclination (Degrees) * * Return Value: - * Nothing + * None * * Example: * [1000, 45, 1] call ace_microdagr_fnc_recieveRangefinderData * * Public: No */ -#include "script_component.hpp" + +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_store_gun_list.sqf b/addons/atragmx/functions/fnc_store_gun_list.sqf new file mode 100644 index 0000000000..d5c3d7657d --- /dev/null +++ b/addons/atragmx/functions/fnc_store_gun_list.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Saves the persistent gun list entries into profileNamespace + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_store_user_data + * + * Public: No + */ + +private _gunList = []; +{ + if (_x select 20) then { + _gunList pushBack _x; + }; +} forEach GVAR(gunList); + +profileNamespace setVariable ["ACE_ATragMX_gunList", _gunList]; diff --git a/addons/atragmx/functions/fnc_store_user_data.sqf b/addons/atragmx/functions/fnc_store_user_data.sqf index 5cfe7f2ae0..09b710e1d4 100644 --- a/addons/atragmx/functions/fnc_store_user_data.sqf +++ b/addons/atragmx/functions/fnc_store_user_data.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Saves user data into profileNamespace * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_store_user_data * * Public: No */ -#include "script_component.hpp" profileNamespace setVariable ["ACE_ATragMX_profileNamespaceVersion", ATRAGMX_PROFILE_NAMESPACE_VERSION]; @@ -28,6 +28,7 @@ profileNamespace setVariable ["ACE_ATragMX_barometricPressure", GVAR(barometricP profileNamespace setVariable ["ACE_ATragMX_relativeHumidity", GVAR(relativeHumidity)]; profileNamespace setVariable ["ACE_ATragMX_showWind2", GVAR(showWind2)]; +profileNamespace setVariable ["ACE_ATragMX_showCoriolis", GVAR(showCoriolis)]; profileNamespace setVariable ["ACE_ATragMX_latitude", GVAR(latitude)]; profileNamespace setVariable ["ACE_ATragMX_directionOfFire", GVAR(directionOfFire)]; profileNamespace setVariable ["ACE_ATragMX_windSpeed1", GVAR(windSpeed1)]; @@ -41,4 +42,4 @@ profileNamespace setVariable ["ACE_ATragMX_targetRange", GVAR(targetRange)]; profileNamespace setVariable ["ACE_ATragMX_rangeCardStartRange", GVAR(rangeCardStartRange)]; profileNamespace setVariable ["ACE_ATragMX_rangeCardEndRange", GVAR(rangeCardEndRange)]; profileNamespace setVariable ["ACE_ATragMX_rangeCardIncrement", GVAR(rangeCardIncrement)]; -profileNamespace setVariable ["ACE_ATragMX_rangeCardCurrentColumn", GVAR(rangeCardCurrentColumn)]; \ No newline at end of file +profileNamespace setVariable ["ACE_ATragMX_rangeCardCurrentColumn", GVAR(rangeCardCurrentColumn)]; diff --git a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf index d270dbf4c3..69be94dd8f 100644 --- a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows and starts the target speed assist timer * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_target_speed_assist_timer * * Public: No */ -#include "script_component.hpp" if !(ctrlVisible 9000) then { diff --git a/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf b/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf index 87e973c7c0..6f2fc11e27 100644 --- a/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_atmo_env_data.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the atmospheric data screen on/off @@ -6,21 +7,24 @@ * Apply new data? * * Return Value: - * Nothing + * None * * Example: * 1 call ace_atragmx_fnc_toggle_atmo_env_data * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 13000) then { false call FUNC(show_atmo_env_data); true call FUNC(show_main_page); if (_this == 1) then { + GVAR(truingDropDropData) set [0, 0]; + [true, true] call FUNC(recalculate_muzzle_velocity); call FUNC(calculate_target_solution); + } else { + call FUNC(update_atmo_env_data); }; } else { true call FUNC(show_atmo_env_data); diff --git a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf new file mode 100644 index 0000000000..088658b747 --- /dev/null +++ b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Toggles the c1 ballistic coefficient data screen on/off + * + * Arguments: + * Apply new data? + * + * Return Value: + * None + * + * Example: + * 1 call ace_atragmx_fnc_toggle_c1_ballistic_coefficient_data + * + * Public: No + */ + +if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; + +if (ctrlVisible 17000) then { + false call FUNC(show_c1_ballistic_coefficient_data); + true call FUNC(show_main_page); + + if (_this == 1) then { + [true, true] call FUNC(recalculate_c1_ballistic_coefficient); + call FUNC(calculate_target_solution); + } else { + call FUNC(update_c1_ballistic_coefficient_data); + }; +} else { + true call FUNC(show_c1_ballistic_coefficient_data); + false call FUNC(show_main_page); +}; diff --git a/addons/atragmx/functions/fnc_toggle_coriolis.sqf b/addons/atragmx/functions/fnc_toggle_coriolis.sqf new file mode 100644 index 0000000000..aad845ce35 --- /dev/null +++ b/addons/atragmx/functions/fnc_toggle_coriolis.sqf @@ -0,0 +1,19 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Toggles the coriolis and spin drift output on/off + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_toggle_coriolis + * + * Public: No + */ + +GVAR(showCoriolis) = !GVAR(showCoriolis); +true call FUNC(show_main_page); diff --git a/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf b/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf index f3eb814da7..1be813fec6 100644 --- a/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_gun_ammo_data.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the gun ammo data screen on/off @@ -6,22 +7,24 @@ * Apply new data? * * Return Value: - * Nothing + * None * * Example: * 1 call ace_atragmx_fnc_toggle_gun_ammo_data * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 12000) then { false call FUNC(show_gun_ammo_data); true call FUNC(show_main_page); if (_this == 1) then { + GVAR(truingDropDropData) set [0, 0]; call FUNC(update_zero_range); call FUNC(calculate_target_solution); + } else { + call FUNC(update_gun_ammo_data); }; } else { true call FUNC(show_gun_ammo_data); diff --git a/addons/atragmx/functions/fnc_toggle_gun_list.sqf b/addons/atragmx/functions/fnc_toggle_gun_list.sqf index e5dbf54bd5..291faf98a4 100644 --- a/addons/atragmx/functions/fnc_toggle_gun_list.sqf +++ b/addons/atragmx/functions/fnc_toggle_gun_list.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the gun list screen on/off @@ -6,14 +7,13 @@ * change gun? * * Return Value: - * Nothing + * None * * Example: * false call ace_atragmx_fnc_toggle_gun_list * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 6000) then { false call FUNC(show_gun_list); diff --git a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf new file mode 100644 index 0000000000..64aadc62cb --- /dev/null +++ b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Toggles the muzzle velocity data screen on/off + * + * Arguments: + * Apply new data? + * + * Return Value: + * None + * + * Example: + * 1 call ace_atragmx_fnc_toggle_muzzle_velocity_data + * + * Public: No + */ + +if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; + +if (ctrlVisible 16000) then { + false call FUNC(show_muzzle_velocity_data); + true call FUNC(show_main_page); + + if (_this == 1) then { + [true, true] call FUNC(recalculate_muzzle_velocity); + call FUNC(calculate_target_solution); + } else { + call FUNC(update_muzzle_velocity_data); + }; +} else { + true call FUNC(show_muzzle_velocity_data); + false call FUNC(show_main_page); +}; diff --git a/addons/atragmx/functions/fnc_toggle_option_menu.sqf b/addons/atragmx/functions/fnc_toggle_option_menu.sqf new file mode 100644 index 0000000000..c39846f466 --- /dev/null +++ b/addons/atragmx/functions/fnc_toggle_option_menu.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Toggles the option menu on/off + * + * Arguments: + * open menu item + * + * Return Value: + * None + * + * Example: + * 1 call ace_atragmx_fnc_toggle_option_menu + * + * Public: No + */ + +if (ctrlVisible 3001) then { + if (_this) then { + private _optionID = lbCurSel 3002; + if (_optionID > 0) then { + ctrlShow [3001, false]; + ctrlShow [3002, false]; + [_optionID] call FUNC(evaluate_option_menu_input); + }; + } else { + ctrlShow [3001, false]; + ctrlShow [3002, false]; + }; +} else { + lbClear 3002; + + lbAdd [3002, "Accuracy 1st"]; + lbAdd [3002, "Muz Vel Table"]; + lbAdd [3002, "Drag Coef Table"]; + lbAdd [3002, "Target Speed Est"]; + lbAdd [3002, "Target Range Est"]; + lbAdd [3002, "Truing Drop"]; + if (GVAR(showCoriolis)) then { + lbAdd [3002, "Show Coriolis *"]; + } else { + lbAdd [3002, "Show Coriolis"]; + }; + lbAdd [3002, "Set Clicks"]; + lbAdd [3002, "Gun Note"]; + + lbSetCurSel [3002, 0]; + + ctrlShow [3001, true]; + ctrlShow [3002, true]; + + ctrlSetFocus ((uiNamespace getVariable ["ATragMX_Display", displayNull]) displayCtrl 3002); +}; diff --git a/addons/atragmx/functions/fnc_toggle_range_card.sqf b/addons/atragmx/functions/fnc_toggle_range_card.sqf index 7d8b7a0239..f34b60c146 100644 --- a/addons/atragmx/functions/fnc_toggle_range_card.sqf +++ b/addons/atragmx/functions/fnc_toggle_range_card.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the range card screen on/off * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_toggle_range_card * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 5006) then { false call FUNC(show_range_card); diff --git a/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf b/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf index 96c31459b2..fb98cfcb0e 100644 --- a/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf +++ b/addons/atragmx/functions/fnc_toggle_range_card_setup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the range card setup screen on/off @@ -6,14 +7,13 @@ * Apply new range card settings * * Return Value: - * Nothing + * None * * Example: * 1 call ace_atragmx_fnc_toggle_range_card_setup * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 10000) then { false call FUNC(show_range_card_setup); diff --git a/addons/atragmx/functions/fnc_toggle_solution_setup.sqf b/addons/atragmx/functions/fnc_toggle_solution_setup.sqf index 5372b205d0..11c3c0f4bc 100644 --- a/addons/atragmx/functions/fnc_toggle_solution_setup.sqf +++ b/addons/atragmx/functions/fnc_toggle_solution_setup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the solution setup screen on/off @@ -6,14 +7,13 @@ * Apply new data? * * Return Value: - * Nothing + * None * * Example: * 1 call ace_atragmx_fnc_toggle_solution_setup * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 15000) then { false call FUNC(show_solution_setup); diff --git a/addons/atragmx/functions/fnc_toggle_target_data.sqf b/addons/atragmx/functions/fnc_toggle_target_data.sqf index 2cfa2f8df5..ecfcab2c41 100644 --- a/addons/atragmx/functions/fnc_toggle_target_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_data.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the target data screen on/off @@ -6,14 +7,13 @@ * Apply new data? * * Return Value: - * Nothing + * None * * Example: * 1 call ace_atragmx_fnc_toggle_target_data * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 14000) then { false call FUNC(show_target_data); @@ -21,6 +21,8 @@ if (ctrlVisible 14000) then { if (_this == 1) then { call FUNC(calculate_target_solution); + } else { + call FUNC(update_target_data); }; } else { true call FUNC(show_target_data); diff --git a/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf b/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf index 83d2daa95f..ac1934ee3e 100644 --- a/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_range_assist.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the target range assist screen on/off @@ -6,14 +7,13 @@ * update range? * * Return Value: - * Nothing + * None * * Example: * 1 call ace_atragmx_fnc_toggle_target_range_assist * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 7000) then { false call FUNC(show_target_range_assist); diff --git a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf index 4d1680d195..47d14a32d9 100644 --- a/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf +++ b/addons/atragmx/functions/fnc_toggle_target_speed_assist.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Toggles the target speed assist screen on/off @@ -6,14 +7,13 @@ * update speed? * * Return Value: - * Nothing + * None * * Example: * 1 call ace_atragmx_fnc_toggle_target_speed_assist * * Public: No */ -#include "script_component.hpp" if (ctrlVisible 8000) then { false call FUNC(show_target_speed_assist); @@ -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_toggle_truing_drop.sqf b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf new file mode 100644 index 0000000000..dbacceb52f --- /dev/null +++ b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Toggles the truing drop screen on/off + * + * Arguments: + * Apply new data? + * + * Return Value: + * None + * + * Example: + * 1 call ace_atragmx_fnc_toggle_truing_drop + * + * Public: No + */ + +if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; + +if (ctrlVisible 18000) then { + false call FUNC(show_truing_drop); + true call FUNC(show_main_page); + + if (_this == 1) then { + if (GVAR(truingDropMode) == 0) then { + [GVAR(temperature), GVAR(truingDropMuzzleVelocity)] call FUNC(insert_muzzle_velocity_data); + [false, true] call FUNC(recalculate_muzzle_velocity); + } else { + [GVAR(truingDropRangeData) select 0, GVAR(truingDropRangeData) select 1, GVAR(truingDropC1)] call FUNC(insert_c1_ballistic_coefficient_data); + [false, true] call FUNC(recalculate_c1_ballistic_coefficient); + }; + call FUNC(calculate_target_solution); + } else { + call FUNC(update_truing_drop_data); + }; +} else { + false call FUNC(show_main_page); + true call FUNC(show_truing_drop); +}; diff --git a/addons/atragmx/functions/fnc_trim_gun_name.sqf b/addons/atragmx/functions/fnc_trim_gun_name.sqf new file mode 100644 index 0000000000..46f20bede6 --- /dev/null +++ b/addons/atragmx/functions/fnc_trim_gun_name.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Trims the gun name input field + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_trim_gun_name + * + * Public: No + */ + +ctrlSetText [11001, (ctrlText 11001) select [0, 14]]; diff --git a/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf b/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf new file mode 100644 index 0000000000..8a6046d1d8 --- /dev/null +++ b/addons/atragmx/functions/fnc_true_c1_ballistic_coefficient.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Trues the c1 ballistic coefficient + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_true_c1_ballistic_coefficient + * + * Public: No + */ + +private _referenceDrop = GVAR(truingDropDropData) select 0; +private _actualDrop = GVAR(truingDropDropData) select 2; + +if (Round(_actualDrop * 10) / 10 == Round(_referenceDrop * 10) / 10) exitWith {}; + +private _step = 0.01; +if (_actualDrop > _referenceDrop) then { + _step = -0.01; +}; + +private _solutionInput = +GVAR(targetSolutionInput); +_solutionInput set [ 8, 200]; +_solutionInput set [13, GVAR(truingDropRangeData) select 1]; +private _c1 = _solutionInput select 14; + +{ + _step = _step * _x; + while { _actualDrop * _step < _referenceDrop * _step } do { + _c1 = _c1 + _step; + _solutionInput set [14, _c1]; + private _result = _solutionInput call FUNC(calculate_solution); + _referenceDrop = (_result select 0); + }; +} forEach [1, -0.1]; + +GVAR(truingDropC1) = _c1; diff --git a/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf b/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf new file mode 100644 index 0000000000..cee3af2536 --- /dev/null +++ b/addons/atragmx/functions/fnc_true_muzzle_velocity.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Trues the muzzle velocity + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_true_muzzle_velocity + * + * Public: No + */ + +private _referenceDrop = GVAR(truingDropDropData) select 0; +private _actualDrop = GVAR(truingDropDropData) select 1; + +if (Round(_actualDrop * 10) / 10 == Round(_referenceDrop * 10) / 10) exitWith {}; + +private _step = 10; +if (_actualDrop > _referenceDrop) then { + _step = -10; +}; + +private _solutionInput = +GVAR(targetSolutionInput); +_solutionInput set [ 8, 200]; +_solutionInput set [13, GVAR(truingDropRangeData) select 0]; +private _muzzleVelocity = _solutionInput select 4; + +{ + _step = _step * _x; + while { _actualDrop * _step < _referenceDrop * _step } do { + _muzzleVelocity = _muzzleVelocity + _step; + _solutionInput set [4, _muzzleVelocity]; + private _result = _solutionInput call FUNC(calculate_solution); + _referenceDrop = (_result select 0); + }; +} forEach [1, -0.1]; + +GVAR(truingDropMuzzleVelocity) = _muzzleVelocity; diff --git a/addons/atragmx/functions/fnc_update_atmo_env_data.sqf b/addons/atragmx/functions/fnc_update_atmo_env_data.sqf index 7cd34754da..27a1e1510b 100644 --- a/addons/atragmx/functions/fnc_update_atmo_env_data.sqf +++ b/addons/atragmx/functions/fnc_update_atmo_env_data.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the atmospheric data fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_atmo_env_data * * Public: No */ -#include "script_component.hpp" ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 13007); diff --git a/addons/atragmx/functions/fnc_update_atmo_selection.sqf b/addons/atragmx/functions/fnc_update_atmo_selection.sqf index 18036178b4..caa7c206cc 100644 --- a/addons/atragmx/functions/fnc_update_atmo_selection.sqf +++ b/addons/atragmx/functions/fnc_update_atmo_selection.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the atmospheric data input method * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_atmo_selection * * Public: No */ -#include "script_component.hpp" ((uiNamespace getVariable "ATragMX_Display") displayCtrl 13001) ctrlEnable true; ((uiNamespace getVariable "ATragMX_Display") displayCtrl 13002) ctrlEnable true; diff --git a/addons/atragmx/functions/fnc_update_atmosphere.sqf b/addons/atragmx/functions/fnc_update_atmosphere.sqf index be7565bda7..438dfe04f2 100644 --- a/addons/atragmx/functions/fnc_update_atmosphere.sqf +++ b/addons/atragmx/functions/fnc_update_atmosphere.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates all atmosphere column input fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_atmosphere * * Public: No */ -#include "script_component.hpp" if (GVAR(currentUnit) == 2) then { ctrlSetText [200, Str(Round(GVAR(temperature) * 10) / 10)]; diff --git a/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf new file mode 100644 index 0000000000..a7a20d31df --- /dev/null +++ b/addons/atragmx/functions/fnc_update_c1_ballistic_coefficient_data.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Updates the c1 ballistic coefficient data fields + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_update_c1_ballistic_coefficient_data + * + * Public: No + */ + +// Distances +if (GVAR(currentUnit) != 1) then { + {ctrlSetText [_x, Str(Round(((GVAR(workingMemory) select 19) select _forEachIndex) select 0))]} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; +} else { + {ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 19) select _forEachIndex) select 0) * 1.0936133))]} forEach [170021, 170022, 170023, 170024, 170025, 170026, 170027]; +}; +// Ballistic coefficients +{ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 19) select _forEachIndex) select 1) * 1000) / 1000)]} forEach [170031, 170032, 170033, 170034, 170035, 170036, 170037]; diff --git a/addons/atragmx/functions/fnc_update_gun.sqf b/addons/atragmx/functions/fnc_update_gun.sqf index aa1f8c44bf..2df4bbe1ee 100644 --- a/addons/atragmx/functions/fnc_update_gun.sqf +++ b/addons/atragmx/functions/fnc_update_gun.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates all gun column input fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_gun * * Public: No */ -#include "script_component.hpp" ctrlSetText [1000, GVAR(workingMemory) select 0]; if (GVAR(currentUnit) != 2) then { @@ -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 6332506006..3a2c1a8106 100644 --- a/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf +++ b/addons/atragmx/functions/fnc_update_gun_ammo_data.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the gun ammo data fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_gun_ammo_data * * Public: No */ -#include "script_component.hpp" ctrlSetFocus ((uiNamespace getVariable "ATragMX_Display") displayCtrl 12008); @@ -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)]; @@ -68,7 +68,7 @@ if (GVAR(currentUnit) == 2) then { ctrlSetText [12000, "Bore (inches)"]; ctrlSetText [12001, "Bullet Weight (grains)"]; ctrlSetText [12002, "Bullet Diam (inches)"]; - ctrlSetText [12004, "Rifle Twist (inches/trn)"]; + ctrlSetText [12004, "Rifle Twist (in/trn)"]; ctrlSetText [12005, "Muzzle Velocity (feet/sec)"]; }; diff --git a/addons/atragmx/functions/fnc_update_inclination_angle.sqf b/addons/atragmx/functions/fnc_update_inclination_angle.sqf index ea5599bf2d..f0150c1cfe 100644 --- a/addons/atragmx/functions/fnc_update_inclination_angle.sqf +++ b/addons/atragmx/functions/fnc_update_inclination_angle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the inclination angle input fields @@ -6,18 +7,16 @@ * Reference input field ID * * Return Value: - * Nothing + * None * * Example: * 0 call ace_atragmx_fnc_update_inclination_angle * * Public: No */ -#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_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf new file mode 100644 index 0000000000..55453ce6e9 --- /dev/null +++ b/addons/atragmx/functions/fnc_update_muzzle_velocity_data.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Updates the muzzle velocity data fields + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_update_muzzle_velocity_data + * + * Public: No + */ + +if (GVAR(currentUnit) == 2) then { + // Temperatures + {ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 18) select _forEachIndex) select 0) * 10) / 10)]} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; + // Muzzle velocities + {ctrlSetText [_x, Str(Round(((GVAR(workingMemory) select 18) select _forEachIndex) select 1))]} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; +} else { + // Temperatures + {ctrlSetText [_x, Str(Round(((((GVAR(workingMemory) select 18) select _forEachIndex) select 0) * 1.8 + 32) * 10) / 10)]} forEach [160021, 160022, 160023, 160024, 160025, 160026, 160027]; + // Muzzle velocities + {ctrlSetText [_x, Str(Round((((GVAR(workingMemory) select 18) select _forEachIndex) select 1) * 3.2808399))]} forEach [160031, 160032, 160033, 160034, 160035, 160036, 160037]; +}; diff --git a/addons/atragmx/functions/fnc_update_range_card.sqf b/addons/atragmx/functions/fnc_update_range_card.sqf index e8c910ca74..3af37cf3f6 100644 --- a/addons/atragmx/functions/fnc_update_range_card.sqf +++ b/addons/atragmx/functions/fnc_update_range_card.sqf @@ -1,22 +1,21 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the range card listbox content * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_range_card * * Public: No */ -#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_relative_click_memory.sqf b/addons/atragmx/functions/fnc_update_relative_click_memory.sqf index 1dc534ce4b..ae847d6c13 100644 --- a/addons/atragmx/functions/fnc_update_relative_click_memory.sqf +++ b/addons/atragmx/functions/fnc_update_relative_click_memory.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the relative click memory * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_relative_click_memory * * Public: No */ -#include "script_component.hpp" GVAR(workingMemory) set [10, (GVAR(elevationOutput) select GVAR(currentTarget))]; GVAR(workingMemory) set [11, (GVAR(windage1Output) select GVAR(currentTarget))]; diff --git a/addons/atragmx/functions/fnc_update_result.sqf b/addons/atragmx/functions/fnc_update_result.sqf index 2b6ca29e23..21c192549c 100644 --- a/addons/atragmx/functions/fnc_update_result.sqf +++ b/addons/atragmx/functions/fnc_update_result.sqf @@ -1,46 +1,56 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the result input and output fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_result * * Public: No */ -#include "script_component.hpp" -private ["_elevationAbs", "_elevationRel", "_elevationCur", "_windageAbs", "_wind2", "_windageRel", "_windageCur", "_lead", "_clickSize", "_clickNumber", "_clickInterval"]; -_elevationAbs = GVAR(elevationOutput) select GVAR(currentTarget); -_windageAbs = GVAR(windage1Output) select GVAR(currentTarget); +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); -_elevationCur = GVAR(workingMemory) select 10; -_windageCur = GVAR(workingMemory) select 11; +if (GVAR(showCoriolis)) then { + _elevationRel = GVAR(verticalCoriolisOutput) select GVAR(currentTarget); + _windageRel = GVAR(horizontalCoriolisOutput) select GVAR(currentTarget); -_elevationRel = _elevationAbs - _elevationCur; -_windageRel = _windageAbs - _windageCur; + _windageCur = GVAR(spinDriftOutput) select GVAR(currentTarget); +} else { + _elevationCur = GVAR(workingMemory) select 10; + _windageCur = GVAR(workingMemory) select 11; -_lead = GVAR(leadOutput) select GVAR(currentTarget); + _elevationRel = _elevationAbs - _elevationCur; + _windageRel = _windageAbs - _windageCur; +}; + +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; @@ -55,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_scope_unit.sqf b/addons/atragmx/functions/fnc_update_scope_unit.sqf index 46db8c40c4..05f7f85b93 100644 --- a/addons/atragmx/functions/fnc_update_scope_unit.sqf +++ b/addons/atragmx/functions/fnc_update_scope_unit.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the scope unit fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_scope_unit * * Public: No */ -#include "script_component.hpp" ctrlSetText [2000, GVAR(scopeUnits) select GVAR(currentScopeUnit)]; ctrlSetText [2001, Str(GVAR(currentScopeClickNumber))]; @@ -26,4 +26,4 @@ if (GVAR(currentScopeUnit) == 3) then { } else { ctrlSetText [5000, GVAR(scopeUnits) select GVAR(currentScopeUnit)]; ctrlShow [2001, false]; -}; \ No newline at end of file +}; diff --git a/addons/atragmx/functions/fnc_update_solution_setup.sqf b/addons/atragmx/functions/fnc_update_solution_setup.sqf index 204a844c9d..37ea36c069 100644 --- a/addons/atragmx/functions/fnc_update_solution_setup.sqf +++ b/addons/atragmx/functions/fnc_update_solution_setup.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates all solution setup input fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_solution_setup * * Public: No */ -#include "script_component.hpp" {((uiNamespace getVariable "ATragMX_Display") displayCtrl _x) ctrlEnable true} forEach [15001, 15002, 15003, 15004, 15005, 15006, 15008, 15009, 15010]; diff --git a/addons/atragmx/functions/fnc_update_target.sqf b/addons/atragmx/functions/fnc_update_target.sqf index ef2ef1de5c..72e6e1f208 100644 --- a/addons/atragmx/functions/fnc_update_target.sqf +++ b/addons/atragmx/functions/fnc_update_target.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates all target column input fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_target * * Public: No */ -#include "script_component.hpp" if (GVAR(showWind2)) then { if (GVAR(currentUnit) != 2) then { diff --git a/addons/atragmx/functions/fnc_update_target_data.sqf b/addons/atragmx/functions/fnc_update_target_data.sqf index 6fa9035a62..ce4b5cb924 100644 --- a/addons/atragmx/functions/fnc_update_target_data.sqf +++ b/addons/atragmx/functions/fnc_update_target_data.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates all target column input fields * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_target * * Public: No */ -#include "script_component.hpp" ctrlSetText [140000, Str(Round((GVAR(latitude) select GVAR(currentTarget)) * 100) / 100)]; ctrlSetText [140010, Str(Round((GVAR(directionOfFire) select GVAR(currentTarget)) * 100) / 100)]; diff --git a/addons/atragmx/functions/fnc_update_target_selection.sqf b/addons/atragmx/functions/fnc_update_target_selection.sqf index d9fd6002c9..55f39c80fe 100644 --- a/addons/atragmx/functions/fnc_update_target_selection.sqf +++ b/addons/atragmx/functions/fnc_update_target_selection.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates all input fields based on the currently selected target * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_target_selection * * Public: No */ -#include "script_component.hpp" {((uiNamespace getVariable "ATragMX_Display") displayCtrl _x) ctrlEnable true} forEach [500, 501, 502, 503]; diff --git a/addons/atragmx/functions/fnc_update_truing_drop_data.sqf b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf new file mode 100644 index 0000000000..d331523432 --- /dev/null +++ b/addons/atragmx/functions/fnc_update_truing_drop_data.sqf @@ -0,0 +1,77 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Updates the truing drop data fields + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_update_truing_drop_data + * + * Public: No + */ + +if (GVAR(currentUnit) == 2) then { + ctrlSetText [18011, Str(Round(GVAR(truingDropRangeData) select 0))]; + ctrlSetText [18012, Str(Round(GVAR(truingDropRangeData) select 1))]; +} else { + ctrlSetText [18011, Str(Round((GVAR(truingDropRangeData) select 0) * 1.0936133))]; + ctrlSetText [18012, Str(Round((GVAR(truingDropRangeData) select 1) * 1.0936133))]; +}; + +if (GVAR(truingDropMode) == 0) then { + GVAR(truingDropDropData) set [0, GVAR(truingDropReferenceDropData) select 0]; +} else { + GVAR(truingDropDropData) set [0, GVAR(truingDropReferenceDropData) select 1]; +}; + +private _dropUnit = GVAR(currentScopeUnit); +if (_dropUnit == 3) then { + switch (GVAR(currentScopeClickUnit)) do { + case 0: { _dropUnit = 1; }; + case 1: { _dropUnit = 2; }; + case 2: { _dropUnit = 0; }; + }; +}; + +private _dropData = +GVAR(truingDropDropData); + +switch (_dropUnit) do { + case 0: { + _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]; + _dropData set [1, (_dropData select 1) * 1.047]; + _dropData set [2, (_dropData select 2) * 1.047]; + }; +}; + +ctrlSetText [18006, Str(Round((_dropData select 0) * 100) / 100)]; +ctrlSetText [18013, Str(Round((_dropData select 1) * 100) / 100)]; +ctrlSetText [18014, Str(Round((_dropData select 2) * 100) / 100)]; + +if (GVAR(currentUnit) != 2) then { + ctrlSetText [18007, Str(Round((GVAR(workingMemory) select 1) * 3.2808399))]; + ctrlSetText [18016, Str(Round((GVAR(workingMemory) select 1) * 3.2808399))]; + if (GVAR(truingDropMuzzleVelocity) > 0) then { + ctrlSetText [18016, Str(Round(GVAR(truingDropMuzzleVelocity) * 3.2808399))]; + }; +} else { + ctrlSetText [18007, Str(Round(GVAR(workingMemory) select 1))]; + ctrlSetText [18016, Str(Round(GVAR(workingMemory) select 1))]; + if (GVAR(truingDropMuzzleVelocity) > 0) then { + ctrlSetText [18016, Str(Round(GVAR(truingDropMuzzleVelocity)))]; + }; +}; +ctrlSetText [18008, Str(Round((GVAR(workingMemory) select 15) * 1000) / 1000)]; +ctrlSetText [18017, Str(Round((GVAR(workingMemory) select 15) * 1000) / 1000)]; +if (GVAR(truingDropC1) > 0) then { + ctrlSetText [18017, Str(Round(GVAR(truingDropC1) * 1000) / 1000)]; +}; diff --git a/addons/atragmx/functions/fnc_update_truing_drop_selection.sqf b/addons/atragmx/functions/fnc_update_truing_drop_selection.sqf new file mode 100644 index 0000000000..f2fffd8fe3 --- /dev/null +++ b/addons/atragmx/functions/fnc_update_truing_drop_selection.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Updates the truing drop input method + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_atragmx_fnc_update_truing_drop_selection + * + * Public: No + */ + +#define __dsp (uiNamespace getVariable "ATragMX_Display") + +(__dsp displayCtrl 18009) ctrlEnable true; +(__dsp displayCtrl 18010) ctrlEnable true; + +if (GVAR(truingDropMode) == 0) then { + (__dsp displayCtrl 18009) ctrlEnable false; + { + (__dsp displayCtrl _x) ctrlEnable true; + } forEach [18011, 18013, 18016]; + { + (__dsp displayCtrl _x) ctrlEnable false; + } forEach [18012, 18014, 18017]; + ctrlSetFocus (__dsp displayCtrl 18011); +} else { + (__dsp displayCtrl 18010) ctrlEnable false; + { + (__dsp displayCtrl _x) ctrlEnable true; + } forEach [18012, 18014, 18017]; + { + (__dsp displayCtrl _x) ctrlEnable false; + } forEach [18011, 18013, 18016]; + ctrlSetFocus (__dsp displayCtrl 18012); +}; + +[] call FUNC(update_truing_drop_data); diff --git a/addons/atragmx/functions/fnc_update_unit_selection.sqf b/addons/atragmx/functions/fnc_update_unit_selection.sqf index 77d96bfdd6..ab3edb9256 100644 --- a/addons/atragmx/functions/fnc_update_unit_selection.sqf +++ b/addons/atragmx/functions/fnc_update_unit_selection.sqf @@ -1,19 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates all input fields based on the currently selected unit * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_unit_selection * * Public: No */ -#include "script_component.hpp" ((uiNamespace getVariable "ATragMX_Display") displayCtrl 600) ctrlEnable true; ((uiNamespace getVariable "ATragMX_Display") displayCtrl 601) ctrlEnable true; @@ -27,5 +27,7 @@ [] call FUNC(update_atmo_env_data); [] call FUNC(update_target); [] call FUNC(update_target_data); +[] call FUNC(update_muzzle_velocity_data); +[] call FUNC(update_c1_ballistic_coefficient_data); [] call FUNC(update_result); diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index 299c321d33..4de6370591 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -1,50 +1,47 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the scope base angle based on the zero range input * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * call ace_atragmx_fnc_update_zero_range * * Public: No */ -#include "script_component.hpp" -private ["_scopeBaseAngle"]; -_scopeBaseAngle = (GVAR(workingMemory) select 3); +[] 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 = Round(parseNumber(ctrlText 120060)); -if (GVAR(currentUnit) == 1) then { - _zeroRange = _zeroRange / 1.0936133; -}; -if (_zeroRange < 10) exitWith { - GVAR(workingMemory) set [2, _zeroRange]; - GVAR(workingMemory) set [3, 0]; +if (!GVAR(atmosphereModeTBH)) then { + _barometricPressure = 1013.25 * (1 - (0.0065 * _altitude) / (273.15 + _temperature + 0.0065 * _altitude)) ^ 5.255754495; + _relativeHumidity = 0.5; }; -private ["_altitude", "_temperature", "_barometricPressure", "_relativeHumidity"]; -_altitude = GVAR(altitude); -_temperature = GVAR(temperature); -_barometricPressure = GVAR(barometricPressure); -_relativeHumidity = GVAR(relativeHumidity); - -private ["_result"]; -_result = [_scopeBaseAngle, _bulletMass, _boreHeight, _airFriction, _muzzleVelocity, _temperature, _barometricPressure, _relativeHumidity, 1000, [0, 0], 0, 0, 0, _zeroRange, _bc, _dragModel, _atmosphereModel, false, 1.5, 0, 0, 0] call FUNC(calculate_solution); +private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { + 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 ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel]; + (parseNumber _zeroAngle) +}; GVAR(workingMemory) set [2, _zeroRange]; -GVAR(workingMemory) set [3, _scopeBaseAngle + (_result select 0) / 60]; +GVAR(workingMemory) set [3, _scopeBaseAngle]; 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 d5da1ee973..ad25ee5b09 100644 --- a/addons/atragmx/script_component.hpp +++ b/addons/atragmx/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_ATRAGMX @@ -17,4 +16,4 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ATRAGMX_PROFILE_NAMESPACE_VERSION 1.7 +#define ATRAGMX_PROFILE_NAMESPACE_VERSION 2.2 diff --git a/addons/atragmx/stringtable.xml b/addons/atragmx/stringtable.xml index c4f358f5bc..4c11ea8add 100644 --- a/addons/atragmx/stringtable.xml +++ b/addons/atragmx/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ ATragMX ATragMX ATragMX + ATragMX + ATragMX + ATragMX + ATragMX Open ATragMX @@ -24,6 +28,10 @@ ATragMX elővétele Otevřít ATragMX Abrir ATragMX + ATragMX を開く + ATragMX 열기 + 開啟ATragMX + 开启ATragMX Rugged PDA with ATragMX @@ -36,6 +44,10 @@ Megerősített PDA, ATragMX-el PDA s ATragMX PDA Robusto com ATragMX + ATragMX 付きの携行型端末 + ATragMX가 달린 PDA + 裝有軍用PDA的ATragMX + 装有军用PDA的ATragMX Open ATragMX @@ -48,6 +60,10 @@ ATragMX elővétele Otevřít ATragMX Abrir ATragMX + ATragMX を開く + ATragMX 열기 + 開啟ATragMX + 开启ATragMX - \ No newline at end of file + diff --git a/addons/attach/CfgVehicles.hpp b/addons/attach/CfgVehicles.hpp index 1e0c0f3e71..744a0db2ad 100644 --- a/addons/attach/CfgVehicles.hpp +++ b/addons/attach/CfgVehicles.hpp @@ -5,22 +5,18 @@ class GVAR(AttachVehicle) { \ displayName = CSTRING(AttachDetach); \ condition = QUOTE(_this call FUNC(canAttach)); \ - insertChildren = QUOTE(_this call FUNC(getChildrenAttachActions)); \ - exceptions[] = {}; \ + insertChildren = QUOTE(_this call FUNC(getChildrenActions)); \ + exceptions[] = {"isNotSwimming"}; \ showDisabled = 0; \ - priority = 0; \ icon = QPATHTOF(UI\attach_ca.paa); \ - distance = 4.5; \ }; \ class GVAR(DetachVehicle) { \ 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); \ - distance = 4.5; \ }; \ }; \ }; @@ -56,19 +52,17 @@ class CfgVehicles { class GVAR(Attach) { displayName = CSTRING(AttachDetach); condition = QUOTE(_this call FUNC(canAttach)); - insertChildren = QUOTE(_this call FUNC(getChildrenAttachActions)); - exceptions[] = {"isNotDragging"}; + insertChildren = QUOTE(_this call FUNC(getChildrenActions)); + exceptions[] = {"isNotDragging", "isNotSwimming"}; showDisabled = 0; - priority = 5; icon = QPATHTOF(UI\attach_ca.paa); }; class GVAR(Detach) { 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/XEH_PREP.hpp b/addons/attach/XEH_PREP.hpp index 5dedc2254e..85915b4f45 100644 --- a/addons/attach/XEH_PREP.hpp +++ b/addons/attach/XEH_PREP.hpp @@ -1,9 +1,8 @@ - PREP(attach); PREP(canAttach); PREP(canDetach); PREP(detach); -PREP(getChildrenAttachActions); +PREP(getChildrenActions); PREP(handleGetIn); PREP(handleGetOut); PREP(handleKilled); diff --git a/addons/attach/XEH_preInit.sqf b/addons/attach/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/attach/XEH_preInit.sqf +++ b/addons/attach/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/attach/config.cpp b/addons/attach/config.cpp index cadc84705b..f862a008a2 100644 --- a/addons/attach/config.cpp +++ b/addons/attach/config.cpp @@ -19,7 +19,3 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "GUI_VirtualAmmo.hpp" - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; -}; \ No newline at end of file diff --git a/addons/attach/functions/fnc_attach.sqf b/addons/attach/functions/fnc_attach.sqf index 366a43d900..21652f296d 100644 --- a/addons/attach/functions/fnc_attach.sqf +++ b/addons/attach/functions/fnc_attach.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: eRazeri, esteldunedain, PabstMirror * Attach an item to the unit @@ -8,57 +9,54 @@ * 2: Array containing a string of the attachable item * * Return Value: - * Nothing + * None * * Example: * [bob, bob, ["light"]] call ace_attach_fnc_attach; * * Public: No */ -#include "script_component.hpp" 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: - private []; - _model = getText (configFile >> "CfgAmmo" >> _itemVehClass >> "model"); + private _model = getText (configFile >> "CfgAmmo" >> _itemVehClass >> "model"); if (_model == "") then { _model = getText (configFile >> "CfgVehicles" >> _itemVehClass >> "model"); }; @@ -68,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; @@ -96,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: @@ -104,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 37d92e8908..00e7b34e8a 100644 --- a/addons/attach/functions/fnc_canAttach.sqf +++ b/addons/attach/functions/fnc_canAttach.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if a unit can attach a specific item. @@ -15,19 +16,16 @@ * * Public: No */ -#include "script_component.hpp" 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) < 7} && -{alive _attachToVehicle} && -{(count _attachedObjects) < _attachLimit} && +{(_attachToVehicle distance _player) < 10} && +{alive _attachToVehicle} && +{(count _attachedObjects) < _attachLimit} && {_itemClassname in ((itemsWithMagazines _player) + [""])}; diff --git a/addons/attach/functions/fnc_canDetach.sqf b/addons/attach/functions/fnc_canDetach.sqf index d9796a5a5c..8ff4ef3249 100644 --- a/addons/attach/functions/fnc_canDetach.sqf +++ b/addons/attach/functions/fnc_canDetach.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if a unit has an item attached and if it can remove that item. @@ -14,19 +15,16 @@ * * Public: No */ -#include "script_component.hpp" params ["_attachToVehicle", "_unit"]; TRACE_2("params",_attachToVehicle,_unit); if ((vehicle _unit) != _unit) exitWith {false}; -_attachedList = _attachToVehicle getVariable [QGVAR(attached), []]; +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 4ff4f9fbd6..5ff12967ce 100644 --- a/addons/attach/functions/fnc_detach.sqf +++ b/addons/attach/functions/fnc_detach.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: eRazeri and esteldunedain * Detach an item from a unit @@ -7,28 +8,25 @@ * 1: unit doing the detaching (player) * * Return Value: - * Nothing + * None * * Example: * [car, bob] call ace_attach_fnc_detach * * Public: No */ -#include "script_component.hpp" 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 { @@ -69,7 +67,7 @@ if (toLower _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then detach _x; deleteVehicle _x; } forEach (attachedObjects _attachedObject); - + // Delete attached item detach _attachedObject; deleteVehicle _attachedObject; @@ -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_getChildrenActions.sqf b/addons/attach/functions/fnc_getChildrenActions.sqf new file mode 100644 index 0000000000..22b4c28892 --- /dev/null +++ b/addons/attach/functions/fnc_getChildrenActions.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" +/* + * Author: Garth de Wet (LH), PabstMirror, mharis001 + * Returns children actions for attachable items. + * + * Arguments: + * 0: Target + * 1: Player + * + * Return Value: + * Actions + * + * Example: + * [_target, _player] call ace_attach_fnc_getChildrenActions + * + * Public: No + */ + +params ["_target", "_player"]; +TRACE_2("params",_target,_player); + +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgWeapons = configFile >> "CfgWeapons"; + +private _actions = []; + +private _magazines = magazines _player; +{ + private _config = _cfgMagazines >> _x; + if (getText (_config >> "ACE_Attachable") != "") then { + private _displayName = getText (_config >> "displayName"); + private _picture = getText (_config >> "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]; + }; +} forEach (_magazines arrayIntersect _magazines); + +{ + private _config = _cfgWeapons >> _x; + if (getText (_config >> "ACE_Attachable") != "") then { + private _displayName = getText (_config >> "displayName"); + private _picture = getText (_config >> "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]; + }; +} forEach (_player call EFUNC(common,uniqueItems)); + +_actions diff --git a/addons/attach/functions/fnc_getChildrenAttachActions.sqf b/addons/attach/functions/fnc_getChildrenAttachActions.sqf deleted file mode 100644 index 0b2e4e705c..0000000000 --- a/addons/attach/functions/fnc_getChildrenAttachActions.sqf +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Author: Garth de Wet (LH), PabstMirror - * Show the ammo counts for a static weapon. - * Called from "insertChildren" on interact_menu - * - * Arguments: - * 0: Target - * 1: Player - * - * Return Value: - * ChildActiosn - * - * Example: - * [player, player] call ace_attach_fnc_getChildrenAttachActions - * - * Public: No - */ -#include "script_component.hpp" - -private ["_listed", "_actions", "_item", "_displayName", "_picture", "_action"]; -params ["_target","_player"]; -TRACE_2("params",_target,_player); - -_listed = []; -_actions = []; - -{ - if !(_x in _listed) then { - _listed pushBack _x; - _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); - _actions pushBack [_action, [], _target]; - }; - }; -} forEach (magazines _player); - -{ - if !(_x in _listed) then { - _listed pushBack _x; - _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); - _actions pushBack [_action, [], _target]; - }; - }; -} forEach (items _player); - -_actions diff --git a/addons/attach/functions/fnc_handleGetIn.sqf b/addons/attach/functions/fnc_handleGetIn.sqf index 0d39a00718..b2203958a0 100644 --- a/addons/attach/functions/fnc_handleGetIn.sqf +++ b/addons/attach/functions/fnc_handleGetIn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles when a unit gets in to a vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["", "", "_unit"]; TRACE_1("params",_unit); diff --git a/addons/attach/functions/fnc_handleGetOut.sqf b/addons/attach/functions/fnc_handleGetOut.sqf index 8eaebd6b21..4e1dac1e89 100644 --- a/addons/attach/functions/fnc_handleGetOut.sqf +++ b/addons/attach/functions/fnc_handleGetOut.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles when a unit gets in to a vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["", "", "_unit"]; TRACE_1("params",_unit); diff --git a/addons/attach/functions/fnc_handleKilled.sqf b/addons/attach/functions/fnc_handleKilled.sqf index 81c2d659d4..0aaf0b03cb 100644 --- a/addons/attach/functions/fnc_handleKilled.sqf +++ b/addons/attach/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles when vehicle or man is killed. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_deadUnit"]; TRACE_1("params",_deadUnit); diff --git a/addons/attach/functions/fnc_placeApprove.sqf b/addons/attach/functions/fnc_placeApprove.sqf index 922136107e..d0101695b4 100644 --- a/addons/attach/functions/fnc_placeApprove.sqf +++ b/addons/attach/functions/fnc_placeApprove.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Pabst Mirror (based on Explosive attach by Garth de Wet (LH)) * Approves placement of the lightObject, scans for an appropriate location and attaches @@ -16,47 +17,55 @@ * 5: Starting Pos of dummy item * * Return Value: - * Nothing + * None * * Example: * No * * Public: No */ -#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 aa6165ae8e..2b341f106a 100644 --- a/addons/attach/script_component.hpp +++ b/addons/attach/script_component.hpp @@ -2,9 +2,9 @@ #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 CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_ATTACH diff --git a/addons/attach/stringtable.xml b/addons/attach/stringtable.xml index 1ab8d61dc5..252f25e4ed 100644 --- a/addons/attach/stringtable.xml +++ b/addons/attach/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Attacca l'oggetto Tárgy hozzácsatolása Прикрепить предмет + アイテムを取り付ける + 물건 부착 + 附掛裝備>> + 附挂装备>> Attach @@ -24,6 +28,10 @@ Attacca Hozzácsatolás Прикрепить + 取り付ける + 부착 + 附掛 + 附挂 Detach item @@ -36,6 +44,10 @@ Stacca l'oggetto Tárgy lecsatolása Отсоединить + アイテムを外す + 분리 + 取下裝備 + 取下装备 IR Strobe Attached @@ -48,6 +60,10 @@ Strobo IR attaccata Infravörös jeladó hozzácsatolva ИК-маяк прикреплён + 赤外線ストロボを取り付けました + 적외선 스트로브 부착됨 + 已附掛紅外線頻閃器 + 已附挂红外线频闪器 IR Strobe Detached @@ -60,6 +76,10 @@ Strobo IR staccata Infravörös jeladó lecsatolva ИК-маяк отсоединён + 赤外線ストロボを外しました + 적외선 스트로브 분리됨 + 已取下紅外線頻閃器 + 已取下红外线频闪器 IR Grenade Attached @@ -72,6 +92,10 @@ Granata IR attaccata Infravörös gránát hozzácsatolva ИК-граната прикреплена + 赤外線グレネードを取り付けました + 적외선 수류탄 부착됨 + 已附掛紅外線手榴彈 + 已附挂红外线手榴弹 IR Grenade Detached @@ -84,6 +108,10 @@ Granata IR staccata Infravörös gránát lecsatolva ИК-граната отсоединена + 赤外線グレネードを外しました + 적외선 수류탄 분리됨 + 已取下紅外線手榴彈 + 已取下红外线手榴弹 Chemlight Attached @@ -96,6 +124,10 @@ Chemlight attaccata Chemlight hozzácsatolva Химсвет прикреплён + ケミライトを取り付けました + 켐라이트 부착됨 + 已附掛螢光棒 + 已附挂萤光棒 Chemlight Detached @@ -108,6 +140,10 @@ Chemlight staccata Chemlight hozzácsatolva Химсвет отсоединён + ケミライトを外しました + 켐라이트 분리됨 + 已取下螢光棒 + 已取下萤光棒 No inventory space @@ -120,6 +156,10 @@ Non hai più spazio Nincs több hely В инвентаре нет места + インベントリに空きがない + 넣을 공간이 없음 + 無可用空間 + 无可用空间 IR Strobe @@ -132,6 +172,10 @@ Strobo IR Infravörös jeladó ИК-маяк + 赤外線ストロボ + 적외선 스트로브 + 紅外線頻閃器 + 红外线频闪器 IR Strobe allows you to signal your position through a pulsating beacon only visible with NVGs. @@ -144,6 +188,10 @@ La Strobo IR è una luce stroboscopica che ti permette di segnalare la tua posizione grazie all'emissione di impulsi ad infrarossi visibili solo con i visori notturni. Az infravörös jeladóval megjelölheted a helyzetedet úgy, hogy annak pulzáló fénye csak éjjellátó készülékkel látható. ИК-маяк позволяет сигнализировать о своём местоположении через пульсирующий свет, видимый только через ПНВ. + 赤外線ストロボはあなたの位置を知らせますが、夜間暗視装置を介してでしか見れません。 + 적외선 스트로브는 자신의 위치를 반짝이면서 표시합니다. 이는 야간투시경으로 밖에 보지 못합니다. + 紅外線閃頻器,藉由紅外線閃頻信號來辨識你的位置,僅能使用夜視系統來辨識紅外線信號 + 红外线闪频器,藉由红外线闪频信号来辨识你的位置,仅能使用夜视系统来辨识红外线信号 Place @@ -156,6 +204,10 @@ Posiziona Elhelyez Установить + 置く + 두기 + 放置 + 放置 Cancel @@ -168,6 +220,10 @@ Annulla Mégse Отмена + やめる + 취소 + 取消 + 取消 Attach Failed @@ -180,6 +236,10 @@ Przyczepianie nie powiodło się Hozzácsatolás sikertelen Non si attacca + 取り付けに失敗しました + 부착 실패 + 附掛失敗 + 附挂失败 %1<br/>Attached @@ -192,6 +252,10 @@ %1<br/>attaccata %1<br/>hozzácsatolva %1<br/>присоединен(-а) + %1<br/>を取り付けました + %1<br/>부착됨 + %1<br/>已附掛 + %1<br/>已附挂 %1<br/>Detached @@ -204,6 +268,10 @@ %1<br/>staccata %1<br/>lecsatolva %1<br/>отсоединен(-а) + %1<br/>を外しました + %1<br/>분리됨 + %1<br/>已取下 + %1<br/>已取下 diff --git a/addons/backpacks/XEH_preInit.sqf b/addons/backpacks/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/backpacks/XEH_preInit.sqf +++ b/addons/backpacks/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/backpacks/config.cpp b/addons/backpacks/config.cpp index 80439533e2..9b63e4df9f 100644 --- a/addons/backpacks/config.cpp +++ b/addons/backpacks/config.cpp @@ -15,7 +15,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" - -class ACE_newEvents { - backpackOpened = "ace_backpackOpened"; -}; diff --git a/addons/backpacks/functions/fnc_backpackOpened.sqf b/addons/backpacks/functions/fnc_backpackOpened.sqf index 8b4e05c20e..92897d72f5 100644 --- a/addons/backpacks/functions/fnc_backpackOpened.sqf +++ b/addons/backpacks/functions/fnc_backpackOpened.sqf @@ -1,18 +1,21 @@ +#include "script_component.hpp" /* * Author: commy2 * Someone opened your backpack. Play sound and camshake. Execute locally. * * Arguments: - * 0: Who accessed your inventory? (Object) - * 1: Unit that wields the backpack (Object) - * 2: The backpack object (Object) + * 0: Who accessed your inventory? + * 1: Unit that wields the backpack + * 2: The backpack object * * Return Value: * None * + * Example: + * [bob, kevin, backpack] call ace_backpacks_fnc_backpackOpened + * * Public: No */ -#include "script_component.hpp" params ["_target", "_backpack"]; diff --git a/addons/backpacks/functions/fnc_isBackpack.sqf b/addons/backpacks/functions/fnc_isBackpack.sqf index aa12b85ad9..a101a514e9 100644 --- a/addons/backpacks/functions/fnc_isBackpack.sqf +++ b/addons/backpacks/functions/fnc_isBackpack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the given backpack is an actual backpack that can store items. Parachute, static weapon packs, etc. will return false. @@ -8,9 +9,11 @@ * Return Value: * Boolean * + * Example: + * [bob] call ace_backpacks_fnc_isBackpack + * * Public: Yes */ -#include "script_component.hpp" params [["_backpack", objNull, [objNull, ""]]]; diff --git a/addons/backpacks/functions/fnc_onOpenInventory.sqf b/addons/backpacks/functions/fnc_onOpenInventory.sqf index 0857f6b7ab..bfb380efe2 100644 --- a/addons/backpacks/functions/fnc_onOpenInventory.sqf +++ b/addons/backpacks/functions/fnc_onOpenInventory.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle the open inventory event. Camshake and sound on target client. @@ -7,11 +8,13 @@ * 1: Backpack * * Return Value: - * false. Always open the inventory dialog. (Bool) + * false. Always open the inventory dialog. + * + * Example: + * [bob, backpack] call ace_backpacks_fnc_onOpenInventory * * Public: No */ -#include "script_component.hpp" params ["_unit", "_backpack"]; diff --git a/addons/backpacks/script_component.hpp b/addons/backpacks/script_component.hpp index 6cfb663dd2..1720d55d64 100644 --- a/addons/backpacks/script_component.hpp +++ b/addons/backpacks/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_BACKPACKS diff --git a/addons/ballistics/ACE_Arsenal_Stats.hpp b/addons/ballistics/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..620c0fb2bc --- /dev/null +++ b/addons/ballistics/ACE_Arsenal_Stats.hpp @@ -0,0 +1,69 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_barrelTwist: statBase { + scope = 2; + priority = 1; + stats[] = {"ACE_barrelTwist"}; + displayName= CSTRING(statBarrelTwist); + showText = 1; + textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _barrelTwist = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelTwist toFixed 0, (_barrelTwist / 25.4) toFixed 1)]); + tabs[] = {{0,1}, {}}; + }; + class ACE_barrelLength: statBase { + scope = 2; + priority = 0; + stats[] = {"ACE_barrelLength"}; + displayName = CSTRING(statBarrelLength); + showText = 1; + textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _barrelLength = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelLength toFixed 0, (_barrelLength / 25.4) toFixed 1)]); + tabs[] = {{0,1}, {}}; + }; + class ACE_ammo: statBase { + scope = 2; + priority = 5; + stats[] = {"ammo", "displayName"}; + displayName = "$STR_dn_ammo"; + showText = 1; + textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _ammoDisplayName = getText (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 1); [ARR_2(_ammoDisplayName, getText (_config >> _stat select 0))] select (_ammoDisplayName == '')); + tabs[] = {{}, {4}}; + }; + class ACE_ballisticCoef: statBase { + scope = 2; + priority = 4; + stats[] = {"ACE_dragModel","ACE_ballisticCoefficients", "ACE_standardAtmosphere"}; + displayName= CSTRING(statBallisticCoef); + showText= 1; + textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoCfg = (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo'))); private _ballisticCoef = getArray (_ammoCfg >> _stat select 1); _ballisticCoef sort false; format [ARR_4('%1 G%2 (%3)', _ballisticCoef select 0 ,getNumber (_ammoCfg >> _stat select 0), getText (_ammoCfg >> _stat select 2))]); + condition = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoCfg = (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo'))); !(getArray (_ammoCfg >> _stat select 1) isEqualTo [])); + tabs[] ={{}, {4}}; + }; + class ACE_bulletMass: statBase { + scope = 2; + priority = 3; + stats[] = {"ACE_bulletMass"}; + displayName = CSTRING(statBulletMass); + showText = 1; + textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoWeight = getNumber (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 0); format [ARR_3('%1g (%2gr)', _ammoWeight toFixed 1, (_ammoWeight * 15.43) toFixed 1)]); + condition = QUOTE(params[ARR_2('_stat', '_config')]; getNumber (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 0) > 0); + tabs[] = {{}, {4}}; + }; + class ACE_magMuzzleVelocity: statBase { + scope = 2; + priority = 3; + stats[] = {"initSpeed"}; + displayName= CSTRING(statMuzzleVelocity); + showText= 1; + textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _initSpeed = getNumber (_config >> _stat select 0); format [ARR_3('%1 m/s (%2 ft/s)', _initSpeed, (_initSpeed * 3.28084) toFixed 0)]); + condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0); + tabs[] = {{}, {4}}; + }; + class ACE_weaponMuzzleVelocity: statBase { + scope = 2; + priority = 3; + stats[] = {"initSpeed"}; + displayName= CSTRING(statMuzzleVelocity); + showText = 1; + textStatement = QUOTE([ARR_2(_this select 0, _this select 1)] call FUNC(statTextStatement_weaponMuzzleVelocity)); + tabs[] = {{0,1}, {}}; + }; +}; diff --git a/addons/ballistics/CfgAmmo.hpp b/addons/ballistics/CfgAmmo.hpp index 0819f8aa4b..5b25f70f71 100644 --- a/addons/ballistics/CfgAmmo.hpp +++ b/addons/ballistics/CfgAmmo.hpp @@ -7,9 +7,7 @@ class CfgAmmo { }; class B_556x45_Ball : BulletBase { - airFriction=-0.00126466; - hit=8; - typicalSpeed=750; + airFriction=-0.00130094; tracerScale = 1; tracerStartTime=0.073; // M856 tracer burns out to 800m tracerEndTime=1.57123; // Time in seconds calculated with ballistics calculator @@ -25,14 +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; - caliber=0.8; - deflecting=18; - hit=11; - typicalSpeed=836; + 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[]={}; @@ -42,11 +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; - caliber=0.8; - deflecting=18; - hit=9; - typicalSpeed=886; + airFriction=-0.0012588; ACE_caliber=5.69; ACE_bulletLength=23.012; ACE_bulletMass=4.0176; @@ -59,11 +50,8 @@ 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; - deflecting=18; - hit=6; - typicalSpeed=869; ACE_caliber=5.69; ACE_bulletLength=23.012; ACE_bulletMass=4.5359237; @@ -79,12 +67,8 @@ class CfgAmmo { class ACE_B_556x45_Ball_Tracer_Dim: B_556x45_Ball_Tracer_Red { nvgOnly = 1; }; - class ACE_545x39_Ball_7N6M : B_556x45_Ball { - airFriction=-0.00114744; - caliber=0.6; - deflecting=18; - hit=7; - typicalSpeed=880; + class B_545x39_Ball_F : BulletBase { + airFriction=-0.00119458; ACE_caliber=5.588; ACE_bulletLength=21.59; ACE_bulletMass=3.42792; @@ -93,35 +77,27 @@ class CfgAmmo { ACE_velocityBoundaries[]={}; ACE_standardAtmosphere="ICAO"; ACE_dragModel=7; - ACE_muzzleVelocities[]={780, 880, 920}; - ACE_barrelLengths[]={254.0, 414.02, 508.0}; - }; - class B_556x45_Ball_Tracer_Green; - class ACE_545x39_Ball_7T3M : B_556x45_Ball_Tracer_Green { - airFriction=-0.00114744; - caliber=0.6; - deflecting=18; - hit=7; - typicalSpeed=883; - tracerStartTime=0.073; // 7T3M tracer burns out to 850m - tracerEndTime=1.70236; // Time in seconds calculated with ballistics calculator - ACE_caliber=5.588; - ACE_bulletLength=21.59; - ACE_bulletMass=3.22704; - 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.168}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=7; - ACE_muzzleVelocities[]={785, 883, 925}; - ACE_barrelLengths[]={254.0, 414.02, 508.0}; + ACE_muzzleVelocities[]={735, 883, 892}; + ACE_barrelLengths[]={206.5, 414.02, 508.0}; }; class B_56x15_dual: BulletBase { tracerScale = 0.5; }; + class B_580x42_Ball_F: BulletBase { + airFriction=-0.00121087; + ACE_caliber=5.9944; + ACE_bulletLength=24.2; + ACE_bulletMass=4.15; + 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.156}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={790, 930, 950}; + ACE_barrelLengths[]={369.0, 463.0, 600.0}; + }; class B_65x39_Caseless : BulletBase { - airFriction=-0.00075308; - typicalSpeed=800; + airFriction=-0.00077363; tracerScale = 1.1; //1.0; ACE_caliber=6.706; ACE_bulletLength=32.893; @@ -143,12 +119,12 @@ class CfgAmmo { nvgOnly = 1; }; class ACE_65x47_Ball_Scenar: B_65x39_Caseless { - airFriction=-0.00067037; - typicalSpeed=820 ; + 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[]={}; @@ -158,12 +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; - typicalSpeed=860 ; + 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[]={}; @@ -177,9 +153,7 @@ class CfgAmmo { tracerScale = 1.1; //1.0; }; class B_762x51_Ball : BulletBase { - airFriction=-0.00100957; - typicalSpeed=833; - hit=9; + 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 @@ -199,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[]={}; @@ -215,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[]={}; @@ -231,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[]={}; @@ -247,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; @@ -263,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; @@ -278,62 +255,15 @@ class CfgAmmo { ACE_muzzleVelocities[]={305, 325, 335, 340}; ACE_barrelLengths[]={406.4, 508.0, 609.6, 660.4}; }; - class ACE_30_06_M1_Ball : B_762x51_Ball { - airFriction=-0.00080900; - typicalSpeed=800; - caliber=2.0; - hit=10; - ACE_caliber=7.823; - ACE_bulletLength=30.734; - ACE_bulletMass=11.2752; - 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.494}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={700, 785, 800, 830, 840}; - ACE_barrelLengths[]={254.0, 406.4, 508.0, 609.6, 660.4}; - }; - class ACE_7_Remington_Magnum_Ball : B_762x51_Ball { - airFriction=-0.00056738; - typicalSpeed=820; - caliber=2.1; - hit=8; - ACE_caliber=7.214; - ACE_bulletLength=38.837; - ACE_bulletMass=11.664; - 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.345}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=7; - ACE_muzzleVelocities[]={720, 780, 812, 822, 830}; - ACE_barrelLengths[]={254.0, 406.4, 508.0, 609.6, 660.4}; - }; - class ACE_243_Winchester_Ball : B_762x51_Ball { - airFriction=-0.00067875; - typicalSpeed=915; - caliber=2.3; - hit=6; - ACE_caliber=6.172; - ACE_bulletLength=32.563; - ACE_bulletMass=11.664; - 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.278}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=7; - ACE_muzzleVelocities[]={830, 875, 900, 915, 920}; - ACE_barrelLengths[]={254.0, 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[]={}; @@ -343,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[]={}; @@ -359,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[]={}; @@ -375,8 +307,8 @@ class CfgAmmo { ACE_barrelLengths[]={508.0, 609.6, 660.4}; }; class B_762x54_Ball: B_762x51_Ball { - airFriction=-0.00100023; - typicalSpeed=820; + airFriction=-0.00101071; + typicalSpeed=835; ACE_caliber=7.925; ACE_bulletLength=28.956; ACE_bulletMass=9.8496; @@ -385,30 +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}; - }; - class ACE_762x54_Ball_7N14 : B_762x51_Ball { - airFriction=-0.00100023; - caliber=1.5; - hit=15; - typicalSpeed=820; - ACE_caliber=7.925; - ACE_bulletLength=28.956; - ACE_bulletMass=9.8496; - 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.4}; - 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; - caliber=1.5; - hit=15; + airFriction=-0.00103739; typicalSpeed=800; tracerStartTime=0.073; // Based on the 7T2 which burns three seconds tracerEndTime=3; @@ -420,30 +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 ACE_762x35_Ball : B_762x51_Ball { - airFriction=-0.00128942; - caliber=1.5; - hit=11; - typicalSpeed=790; - ACE_caliber=7.823; - ACE_bulletLength=29.286; - ACE_bulletMass=8.1; - 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.349, 0.338, 0.330, 0.310}; - ACE_velocityBoundaries[]={792, 610, 488}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={620, 655, 675}; - ACE_barrelLengths[]={228.6, 406.4, 508.0}; - }; - class ACE_762x39_Ball : B_762x51_Ball { - airFriction=-0.00151621; - hit=12; - caliber=1.5; - typicalSpeed=716; + class B_762x39_Ball_F : BulletBase { + airFriction=-0.00154815; ACE_caliber=7.823; ACE_bulletLength=28.956; ACE_bulletMass=7.9704; @@ -455,29 +350,9 @@ class CfgAmmo { ACE_muzzleVelocities[]={650, 716, 750}; ACE_barrelLengths[]={254.0, 414.02, 508.0}; }; - class ACE_762x39_Ball_57N231P : B_762x54_Tracer_Green { - airFriction=-0.00151621; - hit=12; - caliber=1.5; - typicalSpeed=716; - tracerStartTime = 0.073; //57N231P tracer burns out to 800m - tracerEndTime = 2.082; //Time in seconds calculated with ballistics calculator - ACE_caliber=7.823; - ACE_bulletLength=28.956; - ACE_bulletMass=7.5816; - 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.275}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={650, 716, 750}; - ACE_barrelLengths[]={254.0, 414.02, 508.0}; - }; class B_9x21_Ball : BulletBase { - airFriction=-0.00226847; - typicalSpeed=390; + airFriction=-0.00211064; tracerScale = 0.5; - hit=6; ACE_caliber=9.042; ACE_bulletLength=15.494; ACE_bulletMass=7.452; @@ -486,31 +361,14 @@ class CfgAmmo { ACE_velocityBoundaries[]={}; ACE_standardAtmosphere="ICAO"; ACE_dragModel=1; - ACE_muzzleVelocities[]={440, 460, 480}; - ACE_barrelLengths[]={101.6, 127.0, 228.6}; + ACE_muzzleVelocities[]={380, 390, 420, 435}; + ACE_barrelLengths[]={93.5, 101.6, 127.0, 228.6}; }; class B_9x21_Ball_Tracer_Green: B_9x21_Ball { tracerScale = 0.5; }; - class ACE_9x18_Ball_57N181S : B_9x21_Ball { - hit=5; - airFriction=-0.00190333; - typicalSpeed=298; - ACE_caliber=9.271; - ACE_bulletLength=15.494; - ACE_bulletMass=6.00048; - 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.125}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={298, 330, 350}; - ACE_barrelLengths[]={96.52, 127.0, 228.6}; - }; class ACE_9x19_Ball : B_9x21_Ball { - airFriction=-0.0018577; - typicalSpeed=370; - hit=6; + airFriction=-0.00201185; ACE_caliber=9.017; ACE_bulletLength=15.494; ACE_bulletMass=8.0352; @@ -522,57 +380,12 @@ class CfgAmmo { ACE_muzzleVelocities[]={340, 370, 400}; ACE_barrelLengths[]={101.6, 127.0, 228.6}; }; - class ACE_10x25_Ball : B_9x21_Ball { - airFriction=-0.00181928; - typicalSpeed=425; - hit=7; - ACE_caliber=12.7; - ACE_bulletLength=19.406; - ACE_bulletMass=10.692; - 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.189}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ICAO"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={360, 400, 430}; - ACE_barrelLengths[]={101.6, 117.094, 228.6}; - }; - class ACE_765x17_Ball: B_9x21_Ball { - airFriction=-0.00163356; - typicalSpeed=282; - hit=7; - ACE_caliber=7.938; - ACE_bulletLength=15.494; - ACE_bulletMass=4.212; - 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.118}; - ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={282, 300, 320}; - ACE_barrelLengths[]={101.6, 127.0, 228.6}; - }; - class ACE_303_Ball : ACE_762x51_Ball_M118LR { - airFriction=-0.0008349; - typicalSpeed=761; - caliber=2.0; - ACE_caliber=7.899; - ACE_bulletLength=31.166; - ACE_bulletMass=11.2752; - 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.499, 0.493, 0.48}; - ACE_velocityBoundaries[]={671, 549}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={748, 761, 765}; - ACE_barrelLengths[]={508.0, 609.6, 660.4}; - }; class B_93x64_Ball : BulletBase { - airFriction=-0.00108571; - typicalSpeed=880; + 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[]={}; @@ -583,42 +396,46 @@ class CfgAmmo { }; class B_408_Ball : BulletBase { timeToLive=10; - airFriction=-0.00038944; - typicalSpeed=910; - tracerScale = 1.3; //1.2; + airFriction=-0.00046249; + tracerScale = 1.3; ACE_caliber=10.363; - ACE_bulletLength=54.0; - ACE_bulletMass=26.568; + 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.97}; + ACE_ballisticCoefficients[]={0.434}; ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={910}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={867}; ACE_barrelLengths[]={736.6}; }; - class ACE_106x83mm_Ball : B_408_Ball { + class ACE_408_Ball : BulletBase { timeToLive=10; - airFriction=-0.00052047; - ACE_caliber=10.566; - ACE_bulletLength=53.061; - ACE_bulletMass=25.7904; + 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.72}; + ACE_ballisticCoefficients[]={0.279}; ACE_velocityBoundaries[]={}; - ACE_standardAtmosphere="ASM"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={960}; + ACE_standardAtmosphere="ICAO"; + ACE_dragModel=7; + ACE_muzzleVelocities[]={1067}; ACE_barrelLengths[]={736.6}; }; class B_338_Ball : BulletBase { timeToLive=10; - airFriction=-0.00059133; - typicalSpeed=915; + 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[]={}; @@ -628,8 +445,7 @@ class CfgAmmo { ACE_barrelLengths[]={508.0, 660.4, 711.2}; }; class B_338_NM_Ball : BulletBase { - airFriction=-0.00052201; - typicalSpeed=820; + airFriction=-0.00053639; ACE_caliber=8.585; ACE_bulletLength=43.18; ACE_bulletMass=19.44; @@ -643,13 +459,14 @@ 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.381}; + ACE_ballisticCoefficients[]={0.368}; ACE_velocityBoundaries[]={}; ACE_standardAtmosphere="ICAO"; ACE_dragModel=7; @@ -658,26 +475,26 @@ 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.560}; + ACE_ballisticCoefficients[]={0.290}; ACE_velocityBoundaries[]={}; ACE_standardAtmosphere="ICAO"; - ACE_dragModel=1; - ACE_muzzleVelocities[]={880, 915, 925}; - ACE_barrelLengths[]={508.0, 660.4, 711.2}; + ACE_dragModel=7; + ACE_muzzleVelocities[]={880, 895, 900}; + ACE_barrelLengths[]={508.0, 685.8, 711.2}; }; class B_127x33_Ball: BulletBase { tracerScale = 1.3; //1.2; }; class B_127x54_Ball : BulletBase { - airFriction=-0.00019268; - typicalSpeed=300; + airFriction=-0.00019568; tracerScale = 1.3;// ACE_caliber=12.954; ACE_bulletLength=64.516; @@ -692,12 +509,12 @@ class CfgAmmo { }; class B_127x99_Ball : BulletBase { timeToLive=10; - airFriction=-0.00057503; - typicalSpeed=900; + 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[]={}; @@ -706,16 +523,16 @@ class CfgAmmo { ACE_muzzleVelocities[]={900}; ACE_barrelLengths[]={736.6}; }; - class ACE_127x99_API : BulletBase { + class ACE_127x99_API : B_127x99_Ball { timeToLive=10; - airFriction=-0.00057503; - typicalSpeed=900; + 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[]={}; @@ -726,12 +543,12 @@ class CfgAmmo { }; class ACE_127x99_Ball_AMAX : B_127x99_Ball { timeToLive=10; - airFriction=-0.00036645; - typicalSpeed=860; + 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[]={}; @@ -742,8 +559,7 @@ class CfgAmmo { }; class B_127x108_Ball : BulletBase { timeToLive=10; - airFriction=-0.00063800; - typicalSpeed=820; + airFriction=-0.00065098; tracerScale = 1.3; //1.5; ACE_caliber=12.979; ACE_bulletLength=64.008; @@ -756,9 +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; - typicalSpeed=250; + airFriction=-0.00082143; tracerScale = 0.6; ACE_caliber=11.481; ACE_bulletLength=17.272; @@ -771,6 +590,19 @@ class CfgAmmo { ACE_muzzleVelocities[]={230, 250, 285}; ACE_barrelLengths[]={101.6, 127.0, 228.6}; }; + class B_50BW_Ball_F : BulletBase { + airFriction=-0.00205896; + ACE_caliber=12.7; + ACE_bulletLength=24.13; + ACE_bulletMass=21.7076; + 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.21}; + ACE_velocityBoundaries[]={}; + ACE_standardAtmosphere="ASM"; + ACE_dragModel=1; + ACE_muzzleVelocities[]={510, 550, 596}; + ACE_barrelLengths[]={304.8, 406.4, 609.6}; + }; class B_19mm_HE: BulletBase { tracerScale = 1; }; diff --git a/addons/ballistics/CfgEventHandlers.hpp b/addons/ballistics/CfgEventHandlers.hpp new file mode 100644 index 0000000000..93e3311cf2 --- /dev/null +++ b/addons/ballistics/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +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)); + }; +}; diff --git a/addons/ballistics/CfgMagazines.hpp b/addons/ballistics/CfgMagazines.hpp index 931a6c2309..a89cf7022d 100644 --- a/addons/ballistics/CfgMagazines.hpp +++ b/addons/ballistics/CfgMagazines.hpp @@ -2,15 +2,24 @@ class CfgMagazines { class CA_Magazine; + class VehicleMagazine; + + class 30Rnd_580x42_Mag_F: CA_Magazine { + initSpeed = 950; + }; + class 20Rnd_650x39_Cased_Mag_F: CA_Magazine { + 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"; @@ -20,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); @@ -29,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 { @@ -47,7 +57,27 @@ class CfgMagazines { descriptionShort = CSTRING(30Rnd_65x39_caseless_green_mag_Tracer_DimDescription); }; + class 30Rnd_545x39_Mag_F: CA_Magazine { + initSpeed = 735; + }; + 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); @@ -55,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); @@ -71,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); @@ -84,8 +112,19 @@ class CfgMagazines { picture = "\A3\weapons_f\data\ui\m_20stanag_red_ca.paa"; }; + class 200Rnd_556x45_Box_F: CA_Magazine { + initSpeed = 889; + }; + class 200Rnd_556x45_Box_Red_F: 200Rnd_556x45_Box_F { + initSpeed = 869; + }; + + class 30Rnd_762x39_Mag_F: CA_Magazine { + initSpeed = 716; + }; + class 20Rnd_762x51_Mag: CA_Magazine { - initSpeed = 833; + initSpeed = 827; }; class 10Rnd_762x51_Mag: 20Rnd_762x51_Mag { initSpeed = 833; @@ -119,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 { @@ -164,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); @@ -173,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); @@ -181,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); @@ -190,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); @@ -198,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); @@ -206,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); @@ -214,23 +253,43 @@ 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 = 826; displayName = CSTRING(30Rnd_65x47_Scenar_mag_Name); displayNameShort = CSTRING(30Rnd_65x47_Scenar_mag_NameShort); descriptionShort = CSTRING(30Rnd_65x47_Scenar_mag_Description); }; + class ACE_20Rnd_65x47_Scenar_mag: 20Rnd_650x39_Cased_Mag_F { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65x47_Ball_Scenar"; + initSpeed = 826; + displayName = CSTRING(20Rnd_65x47_Scenar_mag_Name); + displayNameShort = CSTRING(20Rnd_65x47_Scenar_mag_NameShort); + descriptionShort = CSTRING(20Rnd_65x47_Scenar_mag_Description); + }; class ACE_30Rnd_65_Creedmor_mag: 30Rnd_65x39_caseless_mag { author = ECSTRING(common,ACETeam); ammo = "ACE_65_Creedmor_Ball"; + initSpeed = 857; displayName = CSTRING(30Rnd_65_Creedmor_mag_Name); displayNameShort = CSTRING(30Rnd_65_Creedmor_mag_NameShort); descriptionShort = CSTRING(30Rnd_65_Creedmor_mag_Description); }; - class 10Rnd_338_Mag; + class ACE_20Rnd_65_Creedmor_mag: 20Rnd_650x39_Cased_Mag_F { + author = ECSTRING(common,ACETeam); + ammo = "ACE_65_Creedmor_Ball"; + 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: CA_Magazine { + initSpeed = 880; + }; class ACE_10Rnd_338_300gr_HPBT_Mag: 10Rnd_338_Mag { author = ECSTRING(common,ACETeam); ammo = "ACE_338_Ball"; @@ -247,8 +306,23 @@ class CfgMagazines { descriptionShort = CSTRING(10Rnd_338_API526_Mag_Description); initSpeed = 880; }; + + class 7Rnd_408_Mag: CA_Magazine { + initSpeed = 867; + }; + class ACE_7Rnd_408_305gr_Mag: 7Rnd_408_Mag { + author = ECSTRING(common,ACETeam); + ammo = "ACE_408_Ball"; + displayName = CSTRING(7Rnd_408_305gr_Mag_Name); + displayNameShort = CSTRING(7Rnd_408_305gr_Mag_NameShort); + descriptionShort = CSTRING(7Rnd_408_305gr_Mag_Description); + initSpeed = 1067; + }; 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"; @@ -276,39 +350,47 @@ class CfgMagazines { class 30Rnd_9x21_Mag: CA_Magazine { - initSpeed = 450; + 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 = 450; + initSpeed = 430; + }; + class 10Rnd_9x21_Mag: 16Rnd_9x21_Mag { + initSpeed = 430; }; class ACE_16Rnd_9x19_mag: 16Rnd_9x21_Mag { author = ECSTRING(common,ACETeam); @@ -320,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); @@ -328,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/CfgVehicles.hpp b/addons/ballistics/CfgVehicles.hpp index bb50dcdc2e..c6a40301f2 100644 --- a/addons/ballistics/CfgVehicles.hpp +++ b/addons/ballistics/CfgVehicles.hpp @@ -13,7 +13,9 @@ class CfgVehicles { class NATO_Box_Base; class Box_NATO_Wps_F: NATO_Box_Base { class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); }; }; @@ -26,6 +28,7 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_30Rnd_556x45_Stanag_Tracer_Dim,1); MACRO_ADDMAGAZINE(ACE_10Rnd_338_300gr_HPBT_Mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_API526_Mag,4); + MACRO_ADDMAGAZINE(ACE_7Rnd_408_305gr_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_API_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_AMAX_Mag,4); @@ -34,7 +37,9 @@ class CfgVehicles { class Box_NATO_Ammo_F: NATO_Box_Base { class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x51_M118LR_Mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_762x51_M118LR_Mag,4); @@ -46,6 +51,7 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_20Rnd_762x51_Mag_Tracer_Dim,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_300gr_HPBT_Mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_API526_Mag,4); + MACRO_ADDMAGAZINE(ACE_7Rnd_408_305gr_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_API_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_AMAX_Mag,4); @@ -67,6 +73,7 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_20Rnd_762x51_M993_AP_Mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_300gr_HPBT_Mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_API526_Mag,4); + MACRO_ADDMAGAZINE(ACE_7Rnd_408_305gr_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_API_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_AMAX_Mag,4); @@ -76,7 +83,9 @@ class CfgVehicles { class ReammoBox_F; class B_supplyCrate_F: ReammoBox_F { class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x51_M118LR_Mag,4); MACRO_ADDMAGAZINE(ACE_20Rnd_762x51_M118LR_Mag,4); @@ -92,7 +101,9 @@ class CfgVehicles { class EAST_Box_Base; class Box_East_Wps_F: EAST_Box_Base { class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); }; @@ -102,7 +113,9 @@ class CfgVehicles { class TransportMagazines { MACRO_ADDMAGAZINE(ACE_30Rnd_556x45_Stanag_Tracer_Dim,1); MACRO_ADDMAGAZINE(ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); }; @@ -110,7 +123,9 @@ class CfgVehicles { class Box_East_Ammo_F: EAST_Box_Base { class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); }; @@ -118,7 +133,9 @@ class CfgVehicles { class Box_East_Support_F: EAST_Box_Base { class TransportMagazines { - MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,6); + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_762x54_Tracer_mag,4); }; @@ -182,7 +199,9 @@ class CfgVehicles { class C_supplyCrate_F: ReammoBox_F { class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); }; }; @@ -217,10 +236,13 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim,4); MACRO_ADDMAGAZINE(ACE_100Rnd_65x39_caseless_mag_Tracer_Dim,4); MACRO_ADDMAGAZINE(ACE_200Rnd_65x39_cased_Box_Tracer_Dim,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65x47_Scenar_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65x47_Scenar_mag,4); + MACRO_ADDMAGAZINE(ACE_20Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_30Rnd_65_Creedmor_mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_300gr_HPBT_Mag,4); MACRO_ADDMAGAZINE(ACE_10Rnd_338_API526_Mag,4); + MACRO_ADDMAGAZINE(ACE_7Rnd_408_305gr_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_API_Mag,4); MACRO_ADDMAGAZINE(ACE_5Rnd_127x99_AMAX_Mag,4); diff --git a/addons/ballistics/CfgWeapons.hpp b/addons/ballistics/CfgWeapons.hpp index 8586aa8216..a2a0e0ff1d 100644 --- a/addons/ballistics/CfgWeapons.hpp +++ b/addons/ballistics/CfgWeapons.hpp @@ -9,87 +9,137 @@ class CfgWeapons { class MMG_01_base_F; class MMG_02_base_F; class Rifle_Base_F; - class Rifle_Long_Base_F; - class MuzzleSlot; - - /* Long Rifles */ + class Rifle_Short_Base_F: Rifle_Base_F {}; + class Rifle_Long_Base_F: Rifle_Base_F {}; + // 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_06_base_F: Rifle_Long_Base_F { + // MX + class arifle_MX_Base_F: Rifle_Base_F { class Single: Mode_SemiAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(0.90); }; class FullAuto: Mode_FullAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(0.90); }; }; - class DMR_05_base_F: Rifle_Long_Base_F { + // KH2002 Sama + class arifle_katiba_Base_F: Rifle_Base_F { class Single: Mode_SemiAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(0.90); }; class FullAuto: Mode_FullAuto { - dispersion = 0.00029; // radians. Equal to 1.00 MOA. + dispersion = MOA_TO_RAD(0.90); }; }; - class DMR_04_base_F: Rifle_Long_Base_F { + // CTAR-21 + class Tavor_base_F: Rifle_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. + dispersion = MOA_TO_RAD(1.12); }; class FullAuto: Mode_FullAuto { - dispersion = 0.00032; // radians. Equal to 1.10 MOA. + dispersion = MOA_TO_RAD(1.12); + }; + }; + + // F2000 + class mk20_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); }; }; + // 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", @@ -99,10 +149,19 @@ class CfgWeapons { "ACE_100Rnd_65x39_caseless_mag_Tracer_Dim", "ACE_30Rnd_65x39_caseless_mag_Tracer_Dim" }; - initSpeed = -1.0; - ACE_barrelTwist=228.6; - ACE_barrelLength=406.4; + 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", @@ -111,172 +170,342 @@ class CfgWeapons { "ACE_30Rnd_65x47_Scenar_mag", "ACE_30Rnd_65_Creedmor_mag" }; - initSpeed = -1.018; - ACE_barrelTwist=228.6; - ACE_barrelLength=457.2; + 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); }; }; + // HK416A5 11" + class arifle_SPAR_01_base_F: Rifle_Base_F { + magazines[] = { + "30Rnd_556x45_Stanag", + "30Rnd_556x45_Stanag_green", + "30Rnd_556x45_Stanag_red", + "30Rnd_556x45_Stanag_Tracer_Red", + "30Rnd_556x45_Stanag_Tracer_Green", + "30Rnd_556x45_Stanag_Tracer_Yellow", + "ACE_30Rnd_556x45_Stanag_M995_AP_mag", + "ACE_30Rnd_556x45_Stanag_Mk262_mag", + "ACE_30Rnd_556x45_Stanag_Mk318_mag", + "ACE_30Rnd_556x45_Stanag_Tracer_Dim" + }; + initSpeed = -0.869636; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 264.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.12); + }; - /* Katiba */ - class arifle_katiba_Base_F: Rifle_Base_F {}; + class FullAuto: Mode_FullAuto { + dispersion = MOA_TO_RAD(1.12); + }; + }; + // HK416A5 14.5" + class arifle_SPAR_02_base_F: Rifle_Base_F { + initSpeed = -0.999864; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 368.0; + class Single: Mode_SemiAuto { + dispersion = MOA_TO_RAD(1.12); + }; - /* Other */ + 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", + "ACE_20Rnd_762x51_Mag_Tracer", + "ACE_20Rnd_762x51_Mag_Tracer_Dim", + "ACE_20Rnd_762x51_Mk316_Mod_0_Mag", + "ACE_20Rnd_762x51_M118LR_Mag", + "ACE_20Rnd_762x51_Mk319_Mod_0_Mag", + "ACE_20Rnd_762x51_M993_AP_Mag", + "ACE_20Rnd_762x51_Mag_SD" + }; + 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); + }; + }; + + // 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.9763; - ACE_barrelTwist=177.8; - ACE_barrelLength=317.5; + initSpeed = -0.999327; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 317.5; }; - class LMG_Zafir_F: Rifle_Long_Base_F { - initSpeed = -1.0; - ACE_barrelTwist=304.8; - ACE_barrelLength=459.74; - }; - class Tavor_base_F: Rifle_Base_F {}; - class mk20_base_F: Rifle_Base_F {}; - /* SMGs */ + // Negev NG7 + class LMG_Zafir_F: Rifle_Long_Base_F { + initSpeed = -1.00048; + ACE_barrelTwist = 304.8; + ACE_barrelLength = 459.74; + }; + + // M249 SPW + class LMG_03_base_F: Rifle_Long_Base_F { + initSpeed = -1.00051; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 414.02; + }; + + // RFB SDAR class SDAR_base_F: Rifle_Base_F { - initSpeed = -0.989; 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); }; }; - class pdw2000_base_F: Rifle_Base_F {}; - class SMG_01_Base: Rifle_Base_F {}; - class SMG_02_base_F: Rifle_Base_F {}; - - /* Pistols */ class Pistol; class Pistol_Base_F: Pistol {}; + // P99 class hgun_P07_F: Pistol_Base_F { - initSpeed = -0.9778; - ACE_barrelTwist=254.0; - ACE_barrelLength=101.6; + initSpeed = -0.906977; + ACE_barrelTwist = 254.0; + ACE_barrelLength = 101.6; }; + // MP-443 Grach class hgun_Rook40_F: Pistol_Base_F { - initSpeed = -1.0; - ACE_barrelTwist=254.0; - ACE_barrelLength=111.76; + initSpeed = -0.934884; + ACE_barrelTwist = 254.0; + ACE_barrelLength = 111.76; }; + // Custom Covert II class hgun_ACPC2_F: Pistol_Base_F { - initSpeed = -1.0; - ACE_barrelTwist=406.4; - ACE_barrelLength=127.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; - ACE_barrelTwist=406.4; - ACE_barrelLength=114.3; + 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; - ACE_barrelTwist=406.4; - ACE_barrelLength=76.2; + initSpeed = -0.905512; + ACE_barrelTwist = 406.4; + ACE_barrelLength = 76.2; }; + + // Makarov PM + class hgun_Pistol_01_F: Pistol_Base_F { + initSpeed = -0.883721; + ACE_barrelTwist = 254.0; + ACE_barrelLength = 93.5; + }; + + class pdw2000_base_F: Rifle_Short_Base_F {}; + + // CPW class hgun_PDW2000_F: pdw2000_base_F { - initSpeed = -1.157; - ACE_barrelTwist=228.6; - ACE_barrelLength=177.8; + initSpeed = -0.994186; + ACE_barrelTwist = 228.6; + ACE_barrelLength = 177.8; }; + + // 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.0; + ACE_barrelTwist = 199.898; + ACE_barrelLength = 414.02; + }; + + // AK12 + class arifle_AK12_base_F: Rifle_Base_F { + 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 = 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 = -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.08; - ACE_barrelTwist=203.2; - ACE_barrelLength=728.98; + 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.07; - ACE_barrelTwist=203.2; - ACE_barrelLength=680.72; + 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.08; - ACE_barrelTwist=203.2; - ACE_barrelLength=728.98; + 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.99; - ACE_barrelTwist=228.6; - ACE_barrelLength=368.3; + 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; - ACE_barrelTwist=228.6; - ACE_barrelLength=368.3; + 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.965; - ACE_barrelTwist=203.2; - ACE_barrelLength=266.7; + 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", @@ -291,15 +520,28 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.989; - ACE_barrelTwist=285.75; - ACE_barrelLength=457.2; + initSpeed = -0.998321; + ACE_barrelTwist = 285.75; + ACE_barrelLength = 457.2; }; - class SMG_02_F: SMG_02_base_F { - initSpeed = -1.054; - ACE_barrelTwist=254.0; - ACE_barrelLength=195.58; + + 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 = -0.943783; + ACE_barrelTwist = 254.0; + ACE_barrelLength = 115.0; + }; + + // CTAR-21 class arifle_TRG20_F: Tavor_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -313,10 +555,12 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.95; - ACE_barrelTwist=177.8; - ACE_barrelLength=381.0; + initSpeed = -0.961496; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 381.0; }; + + // TAR-21 class arifle_TRG21_F: Tavor_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -330,10 +574,19 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.989; - ACE_barrelTwist=177.8; - ACE_barrelLength=459.74; + 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", @@ -347,16 +600,12 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.989; - ACE_barrelTwist=177.8; - ACE_barrelLength=459.74; + 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", @@ -370,10 +619,12 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.98; - ACE_barrelTwist=177.8; - ACE_barrelLength=441.96; + initSpeed = -0.992849; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 441.96; }; + + // F2000 Tactical class arifle_Mk20C_F: mk20_base_F { magazines[] = { "30Rnd_556x45_Stanag", @@ -387,10 +638,19 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.956; - ACE_barrelTwist=177.8; - ACE_barrelLength=406.4; + 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", @@ -404,24 +664,32 @@ class CfgWeapons { "ACE_30Rnd_556x45_Stanag_Mk318_mag", "ACE_30Rnd_556x45_Stanag_Tracer_Dim" }; - initSpeed = -0.956; - ACE_barrelTwist=177.8; - ACE_barrelLength=406.4; + initSpeed = -0.974297; + ACE_barrelTwist = 177.8; + ACE_barrelLength = 406.4; }; + + class SMG_01_Base: Rifle_Short_Base_F {}; + + // Vector SMG class SMG_01_F: SMG_01_Base { - initSpeed = -1.016; - ACE_barrelTwist=406.4; - ACE_barrelLength=139.7; + 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; - ACE_barrelTwist=241.3; - ACE_barrelLength=609.6; + 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", @@ -433,22 +701,23 @@ class CfgWeapons { "ACE_20Rnd_762x51_M993_AP_Mag", "ACE_20Rnd_762x51_Mag_SD" }; - initSpeed = -0.9724; - ACE_barrelTwist=304.8; - ACE_barrelLength=457.2; + 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", + "ACE_7Rnd_408_305gr_Mag" + }; initSpeed = -1.0; - ACE_barrelTwist=330.2; - ACE_barrelLength=736.6; + ACE_barrelTwist = 330.2; + ACE_barrelLength = 736.6; }; + + // GM6 Lynx class srifle_GM6_F: GM6_base_F { magazines[] = { "5Rnd_127x108_Mag", @@ -458,9 +727,11 @@ class CfgWeapons { "ACE_5Rnd_127x99_AMAX_Mag" }; initSpeed = -1.0; - ACE_barrelTwist=381.0; - ACE_barrelLength=730; + ACE_barrelTwist = 381.0; + ACE_barrelLength = 730; }; + + // Noreen "Bad News" ULR class srifle_DMR_02_F: DMR_02_base_F { magazines[] = { "10Rnd_338_Mag", @@ -470,10 +741,12 @@ class CfgWeapons { "ACE_20Rnd_762x67_Mk248_Mod_1_Mag", "ACE_20Rnd_762x67_Berger_Hybrid_OTM_Mag" }; - initSpeed = -0.962; - ACE_barrelTwist=254.0; - ACE_barrelLength=508.0; + 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", @@ -485,20 +758,26 @@ class CfgWeapons { "ACE_20Rnd_762x51_M993_AP_Mag", "ACE_20Rnd_762x51_Mag_SD" }; - initSpeed = -0.9843; - ACE_barrelTwist=254.0; - ACE_barrelLength=508.0; + 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; + 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; + ACE_barrelTwist = 359.918; + ACE_barrelLength = 620.014; }; + + // M14 class srifle_DMR_06_camo_F: DMR_06_base_F { magazines[] = { "20Rnd_762x51_Mag", @@ -510,19 +789,23 @@ class CfgWeapons { "ACE_20Rnd_762x51_M993_AP_Mag", "ACE_20Rnd_762x51_Mag_SD" }; - initSpeed = -0.9916; - ACE_barrelTwist=304.8; - ACE_barrelLength=558.8; + initSpeed = -0.999395; + ACE_barrelTwist = 304.8; + ACE_barrelLength = 558.8; }; + + // HK121 class MMG_01_hex_F: MMG_01_base_F { - initSpeed = -1.0; - ACE_barrelTwist=359.918; - ACE_barrelLength=549.91; + 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; - ACE_barrelLength=609.6; + ACE_barrelTwist = 234.95; + ACE_barrelLength = 609.6; }; class HMG_127 : LMG_RCWS { @@ -531,8 +814,8 @@ class CfgWeapons { }; class HMG_M2: HMG_01 { initSpeed = -1.0; - ACE_barrelTwist=304.8; - ACE_barrelLength=1143.0; + ACE_barrelTwist = 304.8; + ACE_barrelLength = 1143.0; }; /* Silencers */ diff --git a/addons/ballistics/XEH_PREP.hpp b/addons/ballistics/XEH_PREP.hpp new file mode 100644 index 0000000000..812a51e6f6 --- /dev/null +++ b/addons/ballistics/XEH_PREP.hpp @@ -0,0 +1 @@ +PREP(statTextStatement_weaponMuzzleVelocity); diff --git a/addons/ballistics/XEH_preInit.sqf b/addons/ballistics/XEH_preInit.sqf new file mode 100644 index 0000000000..63f3d7fe7e --- /dev/null +++ b/addons/ballistics/XEH_preInit.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; diff --git a/addons/ballistics/XEH_preStart.sqf b/addons/ballistics/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/ballistics/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/ballistics/config.cpp b/addons/ballistics/config.cpp index 7f63a36dd2..0dc8289901 100644 --- a/addons/ballistics/config.cpp +++ b/addons/ballistics/config.cpp @@ -14,7 +14,9 @@ class CfgPatches { }; }; +#include "CfgEventHandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf new file mode 100644 index 0000000000..4d0f04b209 --- /dev/null +++ b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: Alganthe + * Text statement for the weapon muzzle velocity stat + * + * Arguments: + * 0: Not used + * 1: item config path (CONFIG) + * + * Return Value: + * String to display + * + * Public: No +*/ + +params ["", "_config"]; + +if (EGVAR(arsenal,currentLeftPanel) == 2002) then { + private _primaryMag = primaryWeaponMagazine EGVAR(arsenal,center); + + [primaryWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]] +} else { + private _primaryMag = handgunMagazine EGVAR(arsenal,center); + + [handgunWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]] +} params ["_weapon", "_magazine"]; + +if (_magazine isEqualTo "") then { + localize "str_empty"; +} else { + private _ammoCfg = (configFile >> "CfgAmmo" >> (getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"))); + private _barrelLength = getNumber (_config >> "ACE_barrelLength"); + private _muzzleVelocityTable = getArray (_ammoCfg >> "ACE_muzzleVelocities"); + private _barrelLengthTable = getArray (_ammoCfg >> "ACE_barrelLengths"); + + if (_barrelLength != 0 && {count _muzzleVelocityTable > 0} && {count _barrelLengthTable > 0}) then { + private _muzzleVelocity = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); + + format ["%1 m/s (%2 ft/s)", _muzzleVelocity toFixed 0, (_muzzleVelocity * 3.28084) toFixed 0] + } else { + localize "str_empty"; + }; +}; diff --git a/addons/ballistics/functions/script_component.hpp b/addons/ballistics/functions/script_component.hpp new file mode 100644 index 0000000000..a257e3d384 --- /dev/null +++ b/addons/ballistics/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\ballistics\script_component.hpp" diff --git a/addons/ballistics/script_component.hpp b/addons/ballistics/script_component.hpp index 0b2f31da6a..a1b54b53b4 100644 --- a/addons/ballistics/script_component.hpp +++ b/addons/ballistics/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_BALLISTICS diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index b51303fa6d..a222c19779 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -1,6 +1,103 @@ - + + + + 6.5x47mm 20Rnd Mag (HPBT Scenar) + Ch. 6,5x47mm 20Cps (HPBT Scenar) + Cargador de 20 balas de 6.5x47mm (HPBT Scenar) + Magazynek 6,5x47mm 20rd (HPBT Scenar) + Магазин из 20-ти 6,5x47 мм (экспансивные Scenar) + 6,5x47mm 20-Patronen-Magazin (HPBT Scenar) + 6.5x47mm 20Rnd Mag (HPBT Scenar) + 6.5x47mm 20náb. Zásobník (HPBT Scenar) + Carregador 6.5x47mm com 20 cartuchos (HPBT Scenar) + 6,5x47mm 20-lövedékes tár (HPBT Scenar) + 6.5x47mm 20発入り 弾倉 (HPBT Scenar) + 20발들이 6.5x47mm (HPBT Scenar) + 6.5x47mm 20發 彈匣 (Lapua 空尖艇尾狙擊專用彈) + 6.5x47mm 20发 弹匣 (Lapua 空尖艇尾狙击专用弹) + + + 6.5mm Lapua + 6,5mm Lapua + 6.5mm Lapua + 6,5mm Lapua + 6,5 мм Lapua + 6,5mm Lapua + 6.5mm Lapua + 6.5mm Lapua + 6.5mm Lapua + 6,5mm Lapua + 6.5mm Lapua + 6.5mm Lapua + 6.5mm Lapua 空尖艇尾狙擊專用彈 + 6.5mm Lapua 空尖艇尾狙击专用弹 + + + Caliber: 6.5x47mm (HPBT Scenar)<br />Rounds: 20<br />Used in: QBU-88 + Calibre: 6,5x47mm (HPBT Scenar)<br />Cartouches: 20 + Calibre: 6.5x47mm (HPBT Scenar)<br />Balas: 20<br />Se usa en: QBU-88 + Kaliber: 6,5x47mm (HPBT Scenar)<br />Pociski: 20 + Калибр: 6,5x47 мм (экспансивные Scenar)<br />Патронов: 20<br />Используются с: QBU-88 + Kaliber: 6,5x47mm (HPBT Scenar)<br />Patronen: 20<br />Eingesetzt von: QBU-88 + Calibro: 6.5x47mm (HPBT Scenar)<br />Munizioni: 20<br />In uso su: QBU-88 + Ráže: 6.5x47mm (HPBT Scenar)<br />Nábojů: 20<br />Použití u: QBU-88 + Calibre: 6.5x47mm (HPBT Scenar)<br/>Cartuchos: 20<br/>Usado em: QBU-88 + Kaliber: 6,5x47mm (HPBT Scenar)<br />Lövedékek: 20<br />Használható: QBU-88 + 口径: 6.5x47mm (HPBT Scenar)<br />装填数: 20<br />次で使用: QBU-88 + 구경: 6.5x47mm (HPBT Scenar)<br />장탄수: 20<br />사용처: QBU-88 + 口徑: 6.5x47mm (Lapua 空尖艇尾狙擊專用彈)<br />發數: 20<br />使用於: QBU-88 + 口径: 6.5x47mm (Lapua 空尖艇尾狙击专用弹)<br />发数: 20<br />使用于: QBU-88 + + + 6.5mm Creedmor 20Rnd Mag + Magazynek 6,5mm Creedmor 20rd + 6.5mm Creedmor 20Rnd Mag + Магазин из 20-ти 6,5 мм Creedmor + 6,5mm Creedmor 20-Patronen-Magazin + Cargador de 20 balas Creedmor de 6.5mm + Ch. 6,5mm Creedmor 20Cps + 6.5mm Creedmor 20náb. Zásobník + Carregador 6.5mm com 20 cartuchos Creedmor + 6,5mm Creedmor 20-lövedékes tár + 6.5mm Creedmor 20発入り 弾倉 + 20발들이 6.5mm Creedmor 탄창 + 6.5mm 20發 彈匣 (Creedmor 狙擊專用彈) + 6.5mm 20发 弹匣 (Creedmor 狙击专用弹) + + + 6.5mm CM + 6,5mm CM + 6.5mm CM + 6,5mm CM + 6,5 мм CM + 6,5mm CM + 6.5mm CM + 6.5mm CM + 6.5mm CM + 6,5mm CM + 6.5mm CM + 6.5mm CM + 6.5mm CM 狙擊專用彈 + 6.5mm CM 狙击专用弹 + + + Caliber: 6.5x47mm Creedmor<br />Rounds: 20<br />Used in: QBU-88 + Kaliber: 6,5x47mm Creedmor<br />Pociski: 20<br />Używany w: QBU-88 + Kaliber: 6,5x47mm Creedmor<br />Patronen: 20<br />Eingesetzt von: QBU-88 + Calibre: 6,5x47mm Creedmor <br />Cartouches: 20<br />Utilisé avec: QBU-88 + Calibro: 6.5mm Creedmor<br />Munizioni: 20<br />In uso su: QBU-88 + Calibre: 6.5mm Creedmor<br />Balas: 20<br />Se usa en: QBU-88 + Калибр: 6,5x47мм Creedmor<br />Патронов: 20<br />Используются c: QBU-88 + Ráže: 6.5x47mm Creedmor<br />Nábojů: 20<br />Použití u: QBU-88 + Calibre: 6.5x47mm Creedmor<br/>Cartuchos: 20<br/>Usado em: QBU-88 + Kaliber: 6,5x47mm Creedmor<br />Lövedékek: 20<br />Használható: QBU-88 + 口径: 6.5x47mm Creedmor<br />装填数: 20<br />次で使用: QBU-88 + 구경: 6.5x47mm Creedmor<br />장탄수: 20<br />사용처: QBU-88 + 口徑: 6.5x47mm Creedmor 狙擊專用彈<br />發數: 20<br />使用於: QBU-88 + 口径: 6.5x47mm Creedmor 狙击专用弹<br />发数: 20<br />使用于: QBU-88 + 6.5mm 30Rnd Tracer IR-DIM Mag @@ -13,6 +110,10 @@ Carregador de 30 projéteis traçantes IR-DIM de 6,5mm Caricatore 6.5mm 30Rnd Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих + 6.5mm 30発入り IR-DIM曳光弾 弾倉 + 30발들이 6.5mm IR-DIM 예광탄 탄창 + 6.5mm 30發 低視度紅外線曳光彈 彈匣 + 6.5mm 30发 低视度红外线曳光弹 弹匣 6.5mm IR-DIM @@ -25,6 +126,10 @@ 6,5mm IR-DIM 6.5mm IR-DIM 6,5 мм ИК-трассирующие + 6.5mm IR-DIM曳光弾 + 6.5mm IR-DIM 예광탄 + 6.5mm 低視紅外曳光彈 + 6.5mm 低视红外曳光弹 Caliber: 6.5x39mm Tracer IR-DIM<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL @@ -37,6 +142,10 @@ Calibre: 6,5x39mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL Calibro: 6.5x39mm Traccianti IR-DIM <br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL + 口径: 6.5x39mm 曳光弾 IR-DIM<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL + 구경: 6.5x39mm IR-DIM 예광탄<br />장탄수: 30<br />사용처: MX/C/M/SW/3GL + 口徑: 6.5x39mm 低視度紅外線曳光彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL + 口径: 6.5x39mm 低视度红外线曳光弹<br />发数: 30<br />使用于: MX/C/M/SW/3GL 6.5mm 30Rnd SD Mag @@ -49,6 +158,10 @@ Carregador de 30 projéteis SD de 6,5mm Caricatore 6.5mm 30Rnd Sil. Магазин из 30-ти 6,5 мм дозвуковых + 6.5mm 30発入り 亜音速弾 弾倉 + 30발들이 6.5mm 아음속탄 탄창 + 6.5mm 30發 消音彈 彈匣 + 6.5mm 30发 消音弹 弹匣 6.5mm SD @@ -61,6 +174,10 @@ 6,5mm SD 6.5mm Sil. 6,5 мм дозвуковые + 6.5mm 亜音速弾 + 6.5mm 아음속탄 + 6.5mm 消音彈 + 6.5mm 消音弹 Caliber: 6.5x39mm SD<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL @@ -73,6 +190,10 @@ Calibre: 6,5x39mm SD<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL Calibro: 6.5x39mm Sil.<br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм дозвуковые<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL + 口径: 6.5x39mm 亜音速弾<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL + 구경: 6.5x39mm SD<br />장탄수: 30<br />사용처: MX/C/M/SW/3GL + 口徑: 6.5x39mm 消音彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL + 口径: 6.5x39mm 消音弹<br />发数: 30<br />使用于: MX/C/M/SW/3GL 6.5mm 30Rnd AP Mag @@ -85,6 +206,10 @@ Carregador de 30 projéteis AP de 6,5mm Caricatore 6.5mm 30Rnd AP Магазин из 30-ти 6,5 мм бронебойных + 6.5mm 30 発入り徹甲弾 弾倉 + 30발들이 6.5mm 철갑탄 탄창 + 6.5mm 30發 穿甲彈 彈匣 + 6.5mm 30发 穿甲弹 弹匣 6.5mm AP @@ -97,6 +222,10 @@ 6,5mm AP 6.5mm AP 6,5 мм бронебойные + 6.5mm 徹甲弾 + 6.5mm 철갑탄 + 6.5mm 穿甲彈 + 6.5mm 穿甲弹 Caliber: 6.5x39mm AP<br />Rounds: 30<br />Used in: MX/C/M/SW/3GL @@ -109,6 +238,10 @@ Calibre: 6,5x39mm AP<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL Calibro: 6.5x39mm AP<br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм бронебойные<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL + 口径: 6.5x39mm 徹甲弾<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL + 구경: 6.5x39mm 철갑탄<br />장탄수: 30<br />사용처: MX/C/M/SW/3GL + 口徑: 6.5x39mm 穿甲彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL + 口径: 6.5x39mm 穿甲弹<br />发数: 30<br />使用于: MX/C/M/SW/3GL @@ -122,6 +255,10 @@ Carregador de 30 projéteis traçantes IR-DIM de 6,5mm Caricatore 6.5mm 30Rnd Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих + 6.5mm 30発入り IR-DIM曳光弾 弾倉 + 30발들이 6.5mm IR-DIM 예광탄 탄창 + 6.5mm 30發 低視度紅外線曳光彈 彈匣 + 6.5mm 30发 低视度红外线曳光弹 弹匣 6.5mm IR-DIM @@ -134,6 +271,10 @@ 6,5mm IR-DIM 6.5mm IR-DIM 6,5 мм ИК-трассирующие + 6.5mm IR-DIM曳光弾 + 6.5mm IR-DIM 예광탄 + 6.5mm 低視紅外曳光彈 + 6.5mm 低视红外曳光弹 Caliber: 6.5x39mm Tracer IR-DIM<br />Rounds: 30<br />Used in: Katiba @@ -146,6 +287,10 @@ Calibre: 6,5x39mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: Katiba Calibro: 6.5x39mm Tracciant IR-DIM<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: Katiba + 口径: 6.5x39mm IR-DIM曳光弾<br />装填数: 30<br />次で使用: Katiba + 구경: 6.5x39mm IR-DIM 예광탄<br />장탄수: 30<br />사용처: Katiba + 口徑: 6.5x39mm 低視度紅外線曳光彈<br />發數: 30<br />使用於: Katiba + 口径: 6.5x39mm 低视度红外线曳光弹<br />发数: 30<br />使用于: Katiba 6.5mm 30Rnd SD Mag @@ -158,6 +303,10 @@ Carregador de 30 projéteis SD de 6,5mm Caricatore 6.5mm 30Rnd Sil. Магазин из 30-ти 6,5 мм дозвуковых + 6.5mm 30発入り 亜音速弾 弾倉 + 30발들이 6.5mm 아음속탄 탄창 + 6.5mm 30發 消音彈 彈匣 + 6.5mm 30发 消音弹 弹匣 6.5mm SD @@ -170,6 +319,10 @@ 6,5mm SD 6.5mm Sil. 6,5 мм дозвуковые + 6.5mm 亜音速弾 + 6.5mm 아음속탄 + 6.5mm 消音彈 + 6.5mm 消音弹 Caliber: 6.5x39mm SD<br />Rounds: 30<br />Used in: Katiba @@ -182,6 +335,10 @@ Calibre: 6,5x39mm SD<br />Projéteis: 30<br />Usado em: Katiba Calibro: 6.5x39mm Sil.<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм дозвуковые<br />Патронов: 30<br />Используются с: Katiba + 口径: 6.5x39mm 亜音速弾<br />装填数: 30<br />次で使用: Katiba + 구경: 6.5x39mm 아음속탄<br />장탄수: 30<br />사용처: Katiba + 口徑: 6.5x39mm 消音彈<br />發數: 30<br />使用於: Katiba + 口径: 6.5x39mm 消音弹<br />发数: 30<br />使用于: Katiba 6.5mm 30Rnd AP Mag @@ -194,6 +351,10 @@ Carregador de 30 projéteis AP de 6,5mm Caricatore 6.5mm 30Rnd AP Магазин из 30-ти 6,5 мм бронебойных + 6.5mm 30 発入り徹甲弾 弾倉 + 30발들이 6.5mm 철갑탄 탄창 + 6.5mm 30發 穿甲彈 彈匣 + 6.5mm 30发 穿甲弹 弹匣 6.5mm AP @@ -206,6 +367,10 @@ 6,5mm AP 6.5mm AP 6,5 мм бронебойные + 6.5mm 徹甲弾 + 6.5mm 철갑탄 + 6.5mm 穿甲彈 + 6.5mm 穿甲弹 Caliber: 6.5x39mm AP<br />Rounds: 30<br />Used in: Katiba @@ -218,6 +383,10 @@ Calibre: 6,5x39mm AP<br />Projéteis: 30<br />Usado em: Katiba Calibro: 6.5x39mm AP<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм бронебойные<br />Патронов: 30<br />Используются с: Katiba + 口径: 6.5x39mm 徹甲弾<br />装填数: 30<br />次で使用: Katiba + 구경: 6.5x39mm 철갑탄<br />장탄수: 30<br />사용처: Katiba + 口徑: 6.5x39mm 穿甲彈<br />發數: 30<br />使用於: Katiba + 口径: 6.5x39mm 穿甲弹<br />发数: 30<br />使用于: Katiba @@ -231,6 +400,10 @@ Carregador de 30 projéteis traçantes IR-DIM de 5,56mm Caricatore 5.56mm 30rnd Traccianti IR-DIM Магазин из 30-ти 5,56 мм ИК-трассирующих + 5.56mm 30発入り IR-DIM曳光弾 弾倉 + 30발 들이 5.56mm IR-DIM 예광탄 탄창 + 5.56mm 30發 低視度紅外線曳光彈 彈匣 + 5.56mm 30发 低视度红外线曳光弹 弹匣 5.56mm IR-DIM @@ -243,6 +416,10 @@ 5,56mm IR-DIM 5.56mm IR-DIM 5,56 мм ИК-трассирующие + 5.56mm IR-DIM曳光弾 + 5.56mm IR-DIM 예광탄 + 5.56mm 低視紅外曳光彈 + 5.56mm 低视红外曳光弹 Caliber: 5.56x45mm Tracer IR-DIM<br />Rounds: 30<br />Used in: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR @@ -255,6 +432,10 @@ Calibre: 5,56x45mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR Calibro: 5.56x45mm Traccianti IR-DIM<br />Munizioni: 30<br />In uso su: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR Калибр: 5,56x45 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 口径: 5.56x45mm IR-DIM曳光弾<br />装填数: 30<br />次で使用: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 구경: 5.56x45mm IR-DIM 예광탄<br />장탄수: 30<br />사용처: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 口徑: 5.56x45mm 低視度紅外線曳光彈<br />發數: 30<br />使用於: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 口径: 5.56x45mm 低视度红外线曳光弹<br />发数: 30<br />使用于: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR @@ -268,6 +449,10 @@ Carregador de 20 projéteis traçantes de 7,62mm Caricatore 7.62mm 20Rnd Traccianti Магазин из 20-ти 7,62 мм трассирующих + 7.62mm 20発入り 曳光弾 + 20발들이 7.62mm 예광탄 탄창 + 7.62mm 20發 曳光彈 彈匣 + 7.62mm 20发 曳光弹 弹匣 7.62mm Tracer @@ -280,6 +465,10 @@ 7,62mm Traçante 7.62mm Traccianti 7,62 мм трассирущие + 7.62mm 曳光弾 + 7.62mm 예광탄 + 7.62mm 曳光彈 + 7.62mm 曳光弹 Caliber: 7.62x51mm Tracer<br />Rounds: 20<br />Used in: Mk18 ABR @@ -292,6 +481,10 @@ Calibre: 7,62x51mm Traçante<br />Projéteis: 20<br />Usado em: Mk18 ABR Calibro: 7.62x51mm Traccianti<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм трассирующие<br />Патронов: 20<br />Используются с: Mk18 ABR + 口径: 7.62x51mm 曳光弾<br />装填数: 20<br />次で使用: Mk18 ABR + 구경: 7.62x51mm 예광탄<br />장탄수: 20<br />사용처: Mk18 ABR + 口徑: 7.62x51mm 曳光彈<br />發數: 20<br />使用於: Mk18 ABR + 口径: 7.62x51mm 曳光弹<br />发数: 20<br />使用于: Mk18 ABR 7.62mm 20rnd Tracer IR-DIM Mag @@ -304,6 +497,10 @@ Carregador de 20 projéteis IR-DIM de 7,62mm Caricatore 7.62mm 20rnd Traccianti IR-DIM Магазин из 20-ти 7,62 мм ИК-трассирующих + 7.62mm 20発入り IR-DIM曳光弾 + 20발들이 7.62mm IR-DIM 예광탄 탄창 + 7.62mm 20發 低視度紅外線曳光彈 彈匣 + 7.62mm 20发 低视度红外线曳光弹 弹匣 7.62mm IR-DIM @@ -316,6 +513,10 @@ 7,62mm IR-DIM 7.62mm IR-DIM 7,62 мм ИК-трассирующие + 7.62mm IR-DIM曳光弾 + 7.62mm IR-DIM 예광탄 + 7.62mm 低視紅外曳光彈 + 7.62mm 低视红外曳光弹 Caliber: 7.62x51mm Tracer IR-DIM<br />Rounds: 20<br />Used in: Mk18 ABR @@ -328,6 +529,10 @@ Calibre: 7,62x51mm Traçante IR-DIM<br />Projéteis: 20<br />Usado em: Mk18 ABR Calibro: 7.62x51mm Traccianti IR-DIM<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм ИК-трассирующие<br />Патронов: 20<br />Используются с: Mk18 ABR + 口径: 7.62x51mm IR-DIM曳光弾<br />装填数: 20<br />次で使用: Mk18 ABR + 구경: 7.62x51mm IR-DIM 예광탄<br />장탄수: 20<br />사용처: Mk18 ABR + 口徑: 7.62x51mm 低視度紅外線曳光彈<br />發數: 20<br />使用於: Mk18 ABR + 口径: 7.62x51mm 低视度红外线曳光弹<br />发数: 20<br />使用于: Mk18 ABR 7.62mm 20Rnd SD Mag @@ -340,6 +545,10 @@ Carregador de 20 projéteis SD de 7,62mm Caricatore 7.62mm 20Rnd Sil. Магазин из 20-ти 7,62 мм дозвуковых + 7.62mm 20発入り 亜音速弾 弾倉 + 20발들이 7.62mm 아음속탄 탄창 + 7.62mm 20發 消音彈 彈匣 + 7.62mm 20发 消音弹 弹匣 7.62mm SD @@ -352,6 +561,10 @@ 7,62mm SD 7.62mm Sil. 7,62 мм дозвуковые + 7.62mm 亜音速弾 + 7.62mm 아음속탄 + 7.62mm 消音彈 + 7.62mm 消音弹 Caliber: 7.62x51mm SD<br />Rounds: 20<br />Used in: Mk18 ABR @@ -364,6 +577,10 @@ Calibre: 7,62x51mm SD<br />Projéteis: 20<br />Usado em: Mk18 ABR Calibro: 7.62x51mm Sil.<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм дозвуковые<br />Патронов: 20<br />Используются с: Mk18 ABR + 口径: 7.62x51mm 亜音速弾<br />装填数: 20<br />次で使用: Mk18 ABR + 구경: 7.62x51mm SD<br />장탄수: 20<br />사용처: Mk18 ABR + 口徑: 7.62x51mm 消音彈<br />發數: 20<br />使用於: Mk18 ABR + 口径: 7.62x51mm 消音弹<br />发数: 20<br />使用于: Mk18 ABR @@ -377,6 +594,10 @@ .338 NM 130náb. Svítící Pás Cinto de munição .338 NM com 130 cartuchos .338 NM 130-lövedékes nyomkövető heveder + .338 NM 130発入り 曳光弾ベルト + 130발들이 .338 NM 예광탄 벨트 + .338 NM 130發 曳光彈 彈鏈 + .338 NM 130发 曳光弹 弹链 .338 NM Tracer @@ -389,6 +610,10 @@ .338 NM 130Rnd Tracciante .338 NM Traçante .338 NM nyomkövető + .338 NM 曳光弾 + .338 NM 예광탄 + .338 NM 曳光彈 + .338 NM 曳光弹 Caliber: .338 Norma Magnum Tracer<br />Rounds: 130<br />Used in: SPMG @@ -401,6 +626,10 @@ Ráže: .338 Noma Magnum Svítící<br />Nábojů: 130<br />Použití u: LWMMG Calibre: .338 Norma Magnum Traçante<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum nyomkövető<br />Lövedékek: 130<br />Használható: SPMG + 口径: .338 Norma Magnum 曳光弾<br />装填数: 130<br />次で使用: SPMG + 구경: .338 Norma 매그넘 예광탄<br />장탄수: 130<br />사용처: SPMG + 口徑: .338 Norma Magnum 曳光彈<br />發數: 130<br />使用於: SPMG + 口径: .338 Norma Magnum 曳光弹<br />发数: 130<br />使用于: SPMG .338 NM 130Rnd IR-DIM Belt @@ -413,6 +642,10 @@ .338 NM 130náb. IR-DIM Pás Cinto de munição traçante .338 NM IR-DIM com 130 cartuchos .338 NM 130-lövedékes infravörös nyomkövető heveder + .338 NM 130発入り IR-DIM曳光弾ベルト + 130발들이 .338 NM IR-DIM 예광탄 벨트 + .338 NM 130發 低視度紅外線曳光彈 彈鏈 + .338 NM 130发 低视度红外线曳光弹 弹链 .338 NM IR-DIM @@ -425,6 +658,10 @@ .338 NM IR-DIM .338 NM IR-DIM .338 NM infravörös nyomkövető + .338 NM IR-DIM曳光弾 + .338 NM IR-DIM 예광탄 + .338 NM 低視紅外曳光彈 + .338 NM 低视红外曳光弹 Caliber: .338 Norma Magnum Tracer IR-DIM<br />Rounds: 130<br />Used in: SPMG @@ -437,6 +674,10 @@ Ráže: .338 Noma Magnum Svítící IR-DIM<br />Nábojů: 130<br />Použití u: LWMMG Calibre: .338 Norma Magnum Traçante IR-DIM<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum infravörös nyomkövető<br />Lövedékek: 130<br />Használható: SPMG + 口径: .338 Norma Magnum IR-DIM曳光弾<br />装填数: 130<br />次で使用: SPMG + 구경: .338 Norma 매그넘 IR-DIM 예광탄<br />장탄수: 130<br />사용처: SPMG + 口徑: .338 Norma Magnum 低視度紅外線曳光彈<br />發數: 130<br />使用於: SPMG + 口径: .338 Norma Magnum 低视度红外线曳光弹<br />发数: 130<br />使用于: SPMG .338 NM 130Rnd AP Belt @@ -449,6 +690,10 @@ .338 NM 130náb. AP Pás Cinto de munição .338 NM com 130 cartuchos AP .338 NM 130-lövedékes páncéltörő heveder + .338 NM 130発入り 徹甲弾ベルト + 130발들이 .338 NM 철갑탄 벨트 + .338 NM 130發 穿甲彈 彈鏈 + .338 NM 130发 穿甲弹 弹链 .338 NM AP @@ -461,6 +706,10 @@ .338 NM AP .338 NM AP .338 NM páncéltörő + .338 NM 徹甲弾 + .338 NM 철갑탄 + .338 NM 穿甲彈 + .338 NM 穿甲弹 Caliber: .338 Norma Magnum AP<br />Rounds: 130<br />Used in: SPMG @@ -473,188 +722,252 @@ Ráže: .338 Noma Magnum AP<br />Nábojů: 130<br />Použití u: LWMMG Calibre: .338 Norma Magnum AP<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum páncéltörő<br />Lövedékek: 130<br />Használható: SPMG + 口径: .338 Norma Magnum 徹甲弾<br />装填数: 130<br />次で使用: SPMG + 구경: .338 Norma 매그넘 철갑탄<br />장탄수: 130<br />사용처: SPMG + 口徑: .338 Norma Magnum 穿甲彈<br />發數: 130<br />使用於: SPMG + 口径: .338 Norma Magnum 穿甲弹<br />发数: 130<br />使用于: SPMG 9.3mm 10Rnd Tracer Mag 9,3mm 10-Patronen-Magazin Leuchtspur Magazynek 9.3mm 10rd Smugacz - Ch. 9.3mm 10Cps Traçante + Ch. 9,3mm 10Cps Traçante Cargador de 10 balas trazadoras de 9.3mm Магазин из 10-ти 9,3 мм трассирующих 9.3mm 10Rnd Tracer Mag 9.3mm 10náb. Svítící Zásobník Carregador de 10 cartuchos 9.3mm traçantes 9,3mm 10-lövedékes nyomkövető tár + 9.3mm 10発入り 曳光弾 弾倉 + 10발들이 9.3mm 예광탄 탄창 + 9.3mm 10發 曳光彈 彈匣 + 9.3mm 10发 曳光弹 弹匣 9.3mm Tracer 9,3mm Leuchtspur 9,3mm Smugacz 9.3mm Svítící - 9.3mm Traçante + 9,3mm Traçante 9.3mm Trazadora 9,3 мм трассирующие 9.3mm Tracer 9.3mm Traçante 9,3mm nyomkövető + 9.3mm 曳光弾 + 9.3mm 예광탄 + 9.3mm 曳光彈 + 9.3mm 曳光弹 Caliber: 9.3x64mm Tracer<br />Rounds: 10<br />Used in: Cyrus Kaliber: 9,3x64mm Leuchtspur<br />Patronen: 10<br />Eingesetzt von: Cyrus Kaliber: 9,3x64mm Smugacz<br />Pociski: 10<br />Używany w: Cyrus - Calibre: 9.3x64mm Traçante<br />Cartouches: 10<br />Utilisé avec: Cyrus + Calibre: 9,3x64mm Traçante<br />Cartouches: 10<br />Utilisé avec: Cyrus Calibre: 9.3x64mm trazadora<br />Balas: 10<br />Se usa en: Cyrus Калибр: 9,3x64 мм трассирующие<br />Патронов: 10<br />Используются с: Cyrus Calibro: 9.3x64mm Tracer<br />Munizioni: 10<br />In uso su: Cyrus Ráže: 9.3x64mm Svítící<br />Nábojů: 10<br />Použití u: Cyrus Calibre: 9.3x64mm Traçante<br />Cartuchos: 10<br />Usado em: Cyrus Kaliber: 9,3x64mm nyomkövető<br />Lövedékek: 10<br />Használható: Cyrus + 口径: 9.3x64mm 曳光弾<br />装填数: 10<br />次で使用: Cyrus + 구경: 9.3x64mm 예광탄<br />장탄수: 10<br />사용처: Cyrus + 口徑: 9.3x64mm 曳光彈<br />發數: 10<br />使用於: Cyrus + 口径: 9.3x64mm 曳光弹<br />发数: 10<br />使用于: Cyrus 9.3mm 10Rnd Tracer IR-DIM Mag 9,3mm 10-Patronen-Magazin Leuchtspur IR-DIM Magazynek 9,3mm 10rd Smugacz IR-DIM - Ch. 9.3mm 10Cps Traçante IR-DIM + Ch. 9,3mm 10Cps Traçante IR-DIM Cargador de 10 balas trazadoras IR-DIM de 9.3mm Магазин из 10-ти 9,3 мм ИК-трассирующих 9.3mm 10Rnd Tracciante IR-DIM Mag 9.3mm 10náb. Svítící IR-DIM Zásobník Carregador de 10 cartuchos 9.3mm traçantes IR-DIM 9,3mm 10-lövedékes infravörös nyomkövető tár + 9.3mm 10発入り IR-DIM曳光弾 弾倉 + 10발들이 9.3mm IR-DIM 예광탄 탄창 + 9.3mm 10發 低視度紅外線曳光彈 彈匣 + 9.3mm 10发 低视度红外线曳光弹 弹匣 9.3mm IR-DIM 9,3mm IR-DIM 9,3mm IR-DIM 9.3mm IR-DIM - 9.3mm IR-DIM + 9,3mm IR-DIM 9.3mm IR-DIM 9,3 мм ИК-трассирующие 9.3mm IR-DIM 9.3mm IR-DIM 9,3mm infravörös nyomkövető + 9.3mm IR-DIM曳光弾 + 9.3mm IR-DIM 예광탄 + 9.3mm 低視紅外曳光彈 + 9.3mm 低视红外曳光弹 Caliber: 9.3x64mm Tracer IR-DIM<br />Rounds: 10<br />Used in: Cyrus Kaliber: 9,3x64mm Leuchtspur IR-DIM<br />Patronen: 10<br />Eingesetzt von: Cyrus Kaliber: 9,3x64mm Smugacz IR-DIM<br />Pociski: 10<br />Używany w: Cyrus - Calibre: 9.3x64mm Traçante IR-DIM<br />Cartouches: 10<br />Utilisé avec: Cyrus + Calibre: 9,3x64mm Traçante IR-DIM<br />Cartouches: 10<br />Utilisé avec: Cyrus Calibre: 9.3x64mm trazadora IR-DIM<br />Balas: 10<br />Se usa en: Cyrus Калибр: 9,3x64 мм ИК-трассирующие<br />Патронов: 10<br />Используются с: Cyrus Calibro: 9.3x64mm Tracciante IR-DIM<br />Munizioni: 10<br />In uso su: Cyrus Ráže: 9.3x64mm Svítící IR-DIM<br />Nábojů: 10<br />Použití u: Cyrus Calibre: 9.3x64mm Traçante IR-DIM<br />Cartuchos: 10<br />Usado em: Cyrus Kaliber: 9,3x64mm infravörös nyomkövető<br />Lövedékek: 10<br /> Használható: Cyrus + 口径: 9.3x64mm IR-DIM曳光弾<br />装填数: 10<br />次で使用: Cyrus + 구경: 9.3x64mm IR-DIM 예광탄<br />장탄수: 10<br />사용처: Cyrus + 口徑: 9.3x64mm 低視度紅外線曳光彈<br />發數: 10<br />使用於: Cyrus + 口径: 9.3x64mm 低视度红外线曳光弹<br />发数: 10<br />使用于: Cyrus 9.3mm 150Rnd Tracer Belt 9,3mm 150-Patronen-Gurt Leuchtspur Taśma 9,3mm 150rd Smugacz - Bande 9.3mm 150Cps Traçante + Bande 9,3mm 150Cps Traçante Cinta de 150 balas trazadoras de 9.3mm Лента из 150-ти 9,3 мм трассирующих 9.3mm 150Rnd Tracer Belt 9.3mm 150náb. Svítící Pás Cinto de munição traçante 9.3mm com 150 cartuchos 9,3mm 150-lövedékes nyomkövető heveder + 9.3mm 150発入り 曳光弾ベルト + 150발들이 9.3mm 예광탄 벨트 + 9.3mm 150發 曳光彈 彈鏈 + 9.3mm 150发 曳光弹 弹链 9.3mm Tracer 9,3mm Leuchtspur 9,3mm Smugacz 9.3mm Svítící - 9.3mm Traçante + 9,3mm Traçante 9.3mm Trazadora 9,3 мм трассирующие 9.3mm Tracciante 9.3mm Traçante 9,3mm nyomkövető + 9.3mm 曳光弾 + 9.3mm 예광탄 + 9.3mm 曳光彈 + 9.3mm 曳光弹 Caliber: 9.3x64mm Tracer<br />Rounds: 150<br />Used in: Navid Kaliber: 9,3x64mm Leuchtspur<br />Patronen: 150<br />Eingesetzt von: Navid Kaliber: 9,3x64mm Smugacz<br />Pociski: 150<br />Używane w: Navid - Calibre: 9.3x64mm Traçante<br />Cartouches: 150<br />Utilisé avec: Navid + Calibre: 9,3x64mm Traçante<br />Cartouches: 150<br />Utilisé avec: Navid Calibre: 9.3x64mm trazadora<br />Balas: 150<br />Se usa en: Navid Калибр: 9,3x64 мм трассирующие<br />Патронов: 150<br />Используются с: Навид Calibro: 9.3x64mm Tracciante<br />Munizioni: 150<br />In uso su: Navid Ráže: 9.3x64mm Svítící<br />Nábojů: 150<br />Použití u: HK121 Calibre: 9.3x64mm Traçante<br />Cartuchos: 150<br />Usado em: Navid Kaliber: 9,3x64mm nyomkövető<br />Lövedékek: 150<br />Használható: Navid + 口径: 9.3x64mm 曳光弾<br />装填数: 150<br />次で使用: Navid + 구경: 9.3x64mm 예광탄<br />장탄수: 150<br />사용처: Navid + 口徑: 9.3x64mm 曳光彈<br />發數: 150<br />使用於: Navid + 口径: 9.3x64mm 曳光弹<br />发数: 150<br />使用于: Navid 9.3mm 150Rnd Tracer IR-DIM Belt 9,3mm 150-Patronen-Gurt Leuchtspur IR-DIM Taśma 9,3mm 150rd Smugacz IR-DIM - Bande 9.3mm 150Cps Traçante IR-DIM + Bande 9,3mm 150Cps Traçante IR-DIM Cinta de 150 balas trazadoras IR-DIM de 9.3mm Лента из 150-ти 9,3 мм ИК-трассирующих 9.3mm 150Rnd Tracciante IR-DIM Belt 9.3mm 150náb. Svítící IR-DIM Pás Cinto de munição traçante 9.3mm IR-DIM com 150 cartuchos 9,3mm 150-lövedékes infravörös nyomkövető heveder + 9.3mm 150発入り IR-DIM曳光弾ベルト + 150발들이 9.3mm IR-DIM 예광탄 벨트 + 9.3mm 150發 低視度紅外線曳光彈 彈鏈 + 9.3mm 150发 低视度红外线曳光弹 弹链 9.3mm IR-DIM 9,3mm IR-DIM 9,3mm IR-DIM 9.3mm IR-DIM - 9.3mm IR-DIM + 9,3mm IR-DIM 9.3mm IR-DIM 9,3 мм ИК-трассирующие 9.3mm IR-DIM 9.3mm IR-DIM 9,3mm infravörös nyomkövető + 9.3mm IR-DIM曳光弾 + 9.3mm IR-DIM 예광탄 + 9.3mm 低視紅外曳光彈 + 9.3mm 低视红外曳光弹 Caliber: 9.3x64mm Tracer IR-DIM<br />Rounds: 150<br />Used in: Navid Kaliber: 9,3x64mm Leuchtspur IR-DIM<br />Patronen: 150<br />Eingesetzt von: Navid Kaliber: 9,3x64mm Smugacz IR-DIM<br />Pociski: 150<br />Używane w: Navid - Calibre: 9.3x64mm Traçante IR-DIM<br />Cartouches: 150<br />Utilisé avec: Navid + Calibre: 9,3x64mm Traçante IR-DIM<br />Cartouches: 150<br />Utilisé avec: Navid Calibre: 9.3x64mm trazadora IR-DIM<br />Balas: 150<br />Se usa en: Navid Калибр: 9,3x64 мм ИК-трассирующие<br />Патронов: 150<br />Используются с: Навид Calibro: 9.3x64mm Tracciante IR-DIM<br />Munizioni: 150<br />In uso su: Navid Ráže: 9.3x64mm Svítící IR-DIM<br />Nábojů: 150<br />Použití u: HK121 Calibre: 9.3x64mm Traçante IR-DIM<br />Cartuchos: 150<br />Usado em: Navid Kaliber: 9,3x64mm infravörös nyomkövető<br />Lövedékek: 150<br />Használható: Navid + 口径: 9.3x64mm IR-DIM曳光弾<br />装填数: 150<br />次で使用: Navid + 구경: 9.3x64mm IR-DIM 예광탄<br />장탄수: 150<br />사용처: Navid + 口徑: 9.3x64mm 低視度紅外線曳光彈<br />發數: 150<br />使用於: Navid + 口径: 9.3x64mm 低视度红外线曳光弹<br />发数: 150<br />使用于: Navid 9.3mm 150Rnd AP Belt 9,3mm 150-Patronen-Gurt Hartkern Taśma 9,3mm 150rd AP - Bande 9.3mm 150Cps AP + Bande 9,3mm 150Cps AP Cinta de 150 balas AP de 9.3mm Лента из 150-ти 9,3 мм бронебойных 9.3mm 150Rnd AP Belt 9.3mm 150náb. AP Pás Cinto de munição 9.3mm AP com 150 cartuchos 9,3mm 150-lövedékes páncéltörő heveder + 9.3mm 150発入り 徹甲弾ベルト + 150발들이 9.3mm 철갑탄 벨트 + 9.3mm 150發 穿甲彈 彈鏈 + 9.3mm 150发 穿甲弹 弹链 9.3mm AP 9,3mm AP 9,3mm AP 9.3mm AP - 9.3mm AP + 9,3mm AP 9.3mm AP 9,3 мм бронебойные 9.3mm AP 9.3mm AP 9,3mm páncéltörő + 9.3mm 徹甲弾 + 9.3mm 철갑탄 + 9.3mm 穿甲彈 + 9.3mm 穿甲弹 Caliber: 9.3x64mm AP<br />Rounds: 150<br />Used in: Navid Kaliber: 9,3x64mm Hartkern<br />Patronen: 150<br />Eingesetzt von: Navid Kaliber: 9,3x64mm AP<br />Pociski: 150<br />Używane w: Navid - Calibre: 9.3x64mm AP<br />Cartouches: 150<br />Utilisé avec: Navid + Calibre: 9,3x64mm AP<br />Cartouches: 150<br />Utilisé avec: Navid Calibre: 9.3x64mm AP<br />Balas: 150<br />Se usa en: Navid Калибр: 9,3x64 мм бронебойные<br />Патронов: 150<br />Используются с: Навид Calibro: 9.3x64mm AP<br />Munizioni: 150<br />In uso su: Navid Ráže: 9.3x64mm AP<br />Nábojů: 150<br />Použití u: HK121 Calibre: 9.3x64mm AP<br />Cartuchos: 150<br />Usado em: Navid Kaliber: 9,3x64mm páncéltörő<br />Lövedékek: 150<br />Használható: Navid + 口径: 9.3x64mm 徹甲弾<br />装填数: 150<br />次で使用: Navid + 구경: 9.3x64mm 철갑탄<br />장탄수: 150<br />사용처: Navid + 口徑: 9.3x64mm 穿甲彈<br />發數: 150<br />使用於: Navid + 口径: 9.3x64mm 穿甲弹<br />发数: 150<br />使用于: Navid 9x19mm 16Rnd Mag @@ -667,6 +980,10 @@ 9x19mm 16náb. Zásobník Carregador de 16 cartuchos 9x19mm 9x19mm 16-lövedékes tár + 9x19mm 16発入り 弾倉 + 16발들이 9x19mm 탄창 + 9x19mm 16發 彈匣 + 9x19mm 16发 弹匣 9x19mm @@ -679,6 +996,10 @@ 9x19mm 9x19mm 9x19mm + 9x19mm + 9x19mm + 9x19mm + 9x19mm 9x19mm 30Rnd Mag @@ -691,6 +1012,10 @@ 9x19mm 30náb. Zásobník Carregador de 16 cartuchos 9x19mm 9x19mm 16-lövedékes tár + 9x19mm 30発入り 弾倉 + 30발들이 9x19mm 탄창 + 9x19mm 30發 彈匣 + 9x19mm 30发 弹匣 9x19mm 30Rnd Mag @@ -703,6 +1028,10 @@ 9x19mm 30náb. Zásobník Carregador de 30 cartuchos 9x19mm 9x19mm 30-lövedékes tár + 9x19mm 30発入り 弾倉 + 30발들이 9x19mm 탄창 + 9x19mm 30發 彈匣 + 9x19mm 30发 弹匣 9x19mm @@ -715,6 +1044,10 @@ 9x19mm 9x19mm 9x19mm + 9x19mm + 9x19mm + 9x19mm + 9x19mm 9x19mm 30Rnd Mag @@ -727,11 +1060,15 @@ 9x19mm 30náb. Zásobník Carregador de 30 cartuchos 9x19mm 9x19mm 30-lövedékes tár + 9x19mm 30発入り 弾倉 + 30발들이 9x19mm 탄창 + 9x19mm 30發 彈匣 + 9x19mm 30发 弹匣 7.62x54mm 10Rnd Tracer Mag Magazynek 7,62x54mm 10rd Smugacz - Ch. 7.62x54mm 10Rnd Traçante + Ch. 7,62x54mm 10Cps Traçante Cargador de 10 balas trazadoras de 7.62x54mm Магазин из 10-ти 7,62 мм ИК-трассирующих 7,62x54mm 10-Patronen-Magazin Leuchtspur @@ -739,11 +1076,15 @@ 7.62x54mm 10náb. Svítící Zásobník Carregador com 10 cartuchos 7.62x54mm Traçante 7,62x54mm 10-lövedékes nyomkövető tár + 7.62x54mm 10発入り 曳光弾 弾倉 + 10발들이 7.62x54mm 예광탄 탄창 + 7.62x54mm 10發 曳光彈 彈匣 + 7.62x54mm 10发 曳光弹 弹匣 7.62mm 7,62mm - 7.62mm + 7,62mm 7.62mm 7,62 мм 7,62mm @@ -751,11 +1092,15 @@ 7.62mm 7.62mm 7,62mm + 7.62mm + 7.62mm + 7.62mm + 7.62mm 7.62x54mm 10Rnd Tracer Mag Magazynek 7,62x54mm 10rd Smugacz - Ch. 7.62x54mm 10Cps Traçante + Ch. 7,62x54mm 10Cps Traçante Cargador de 10 balas trazadoras de 7.62x54mm Магазин из 10-ти 7,62 мм ИК-трассирующих 7,62x54mm 10-Patronen-Magazin Leuchtspur @@ -763,11 +1108,15 @@ 7.62x54mm 10náb. Svítící Zásobník Carregador com 10 cartuchos 7.62x54mm Traçante 7,62x54mm 10-lövedékes nyomkövető tár + 7.62x54mm 10発入り 曳光弾 弾倉 + 10발들이 7.62x54mm 예광탄 탄창 + 7.62x54mm 10發 曳光彈 彈匣 + 7.62x54mm 10发 曳光弹 弹匣 6.5mm 100Rnd Tracer IR-DIM Mag Magazynek 6,5mm 100rd Smugacz IR-DIM - Ch. 6.5mm 100Rnd Traçante IR-DIM + Ch. 6,5mm 100Cps Traçante IR-DIM Cargador de 100 balas trazadoras IR-DIM de 6.5mm Магазин из 100 6,5 мм ИК-трассирующих 6,5mm 100-Patronen-Magazin IR-DIM Leuchtspur @@ -775,11 +1124,15 @@ 6.5mm 100náb. Svítící IR-DIM Zásobník Carregador com 100 cartuchos 6.5mm IR-DIM Traçante 6,5mm 100-lövedékes infravörös nyomkövető tár + 6.5mm 100発入り IR-DIM曳光弾 弾倉 + 100발들이 6.5mm IR-DIM 예광탄 탄창 + 6.5mm 100發 低視度紅外線曳光彈 彈匣 + 6.5mm 100发 低视度红外线曳光弹 弹匣 6.5mm IR-DIM 6,5mm IR-DIM - 6.5mm IR-DIM + 6,5mm IR-DIM 6.5mm IR-DIM 6,5 мм ИК-трассирующие 6,5mm IR-DIM @@ -787,11 +1140,15 @@ 6.5mm IR-DIM 6.5mm IR-DIM 6,5mm infravörös nyomkövető + 6.5mm IR-DIM曳光弾 + 6.5mm IR-DIM 예광탄 + 6.5mm 低視紅外曳光彈 + 6.5mm 低视红外曳光弹 6.5mm 100Rnd Tracer IR-DIM Mag<br />Rounds: 100<br />Used in: MX LSW Magazynek 6,5mm 100rd Smugacz IR-DIM - Ch. 6.5mm 100Rnd Traçante IR-DIM<br />Cartouches: 100<br />Utilisé avec: MX LSW + Ch. 6,5mm 100Cps Traçante IR-DIM<br />Cartouches: 100<br />Utilisé avec: MX LSW Cargador de 100 balas trazadoras IR-DIM de 6.5mm Магазин из 100 6,5 мм ИК-трассирующих 6,5mm 100-Patronen-Magazin IR-DIM Leuchtspur<br />Patronen: 100<br />Eingesetzt von: MXLSW @@ -799,11 +1156,15 @@ 6.5mm 100náb. Svítící IR-DIM Zásobník<br />Nábojů: 100<br />Použití u: MX LSW Carregador 6.5mm 100 Cartuchos Traçantes IR-DIM<br />Cartuchos: 100<br />Usado em: MX LSW 6.5mm 100-lövedékes infravörös nyomkövető tár<br />Lövedékek: 100<br />Használható: MX LSW + 6.5mm 100発入り IR-DIM曳光弾 弾倉<br />装填数: 100<br />次で使用: MX LSW + 100발들이 6.5mm IR-DIM 예광탄 탄창<br />장탄수: 100<br />사용처: MX LSW + 6.5mm 100發 低視度紅外線曳光彈<br />發數: 100<br />使用於: MX LSW + 6.5mm 100发 低视度红外线曳光弹<br />发数: 100<br />使用于: MX LSW 6.5mm 200Rnd Tracer IR-DIM Belt Magazynek 6,5mm 200rd Smugacz IR-DIM - Bande 6.5mm 200Rnd Traçante IR-DIM + Bande 6,5mm 200Cps Traçante IR-DIM Cinta de 200 balas trazadoras IR-DIM de 6.5mm Магазин из 200-т 6,5 мм ИК-трассирующих 6,5mm 200-Patronen-Gurt IR-DIM Leuchtspur @@ -811,11 +1172,15 @@ 6.5mm 200náb. Svítící IR-DIM Pás Cinto de munição traçante 6.5mm IR-DIM com 200 cartuchos 6,5mm 200-lövedékes infravörös nyomkövető heveder + 6.5mm 200発入り IR-DIM曳光弾ベルト + 200발들이 6.5mm IR-DIM 예광탄 탄창 + 6.5mm 200發 低視度紅外線曳光彈 彈鏈 + 6.5mm 200发 低视度红外线曳光弹 弹链 6.5mm IR-DIM 6,5mm IR-DIM - 6.5mm IR-DIM + 6,5mm IR-DIM 6.5mm IR-DIM 6,5 мм ИК-трассирующие 6,5mm IR-DIM @@ -823,6 +1188,10 @@ 6.5mm IR-DIM 6.5mm IR-DIM 6,5mm infravörös nyomkövető + 6.5mm IR-DIM曳光弾 + 6.5mm IR-DIM 예광탄 + 6.5mm 低視紅外曳光彈 + 6.5mm 低视红外曳光弹 6.5mm 200Rnd Tracer IR-DIM Belt<br />Rounds: 200<br />Used in: Stoner 99 LMG @@ -835,11 +1204,15 @@ 6.5mm 200náb. Svítící IR-DIM Pás<br />Nábojů: 200<br />Použití u: Stoner 99 LMG Cinto de munição traçante 6.5mm IR-DIM com 200 cartuchos<br />Cartuchos: 200<br />Usado em: Stoner 99 LMG 6.5mm 200-lövedékes infravörös nyomkövető heveder<br />Lövedékek: 200<br />Használható: Stoner 99 LMG + 6.5mm 200発入り IR-DIM曳光弾ベルト<br />装填数: 200<br />次で使用: Stoner 99 LMG + 200발들이 6.5mm IR-DIM 예광탄 벨트<br />장탄수: 200<br />사용처: Stoner 99 LMG + 6.5mm 200發 低視度紅外線曳光彈<br />發數: 200<br />使用於: Stoner 99 LMG + 6.5mm 200发 低视度红外线曳光弹<br />发数: 200<br />使用于: Stoner 99 LMG 5.56mm 30Rnd Mag (Mk262) Magazynek 5,56mm 30rd Mk262 - 5.56mm 30Cps (Mk262) + 5,56mm 30Cps (Mk262) Cargador de 30 balas de 5.56mm (Mk262) Магазин из 30-ти 5.56 мм Mk262 5,56mm 30-Patronen-Magazin (Mk262) @@ -847,11 +1220,15 @@ 5.56mm 30náb. Zásobník (Mk262) Carregador 5.56mm com 30 cartuchos (Mk262) 5,56mm 30-lövedékes tár (Mk262) + 5.56mm 30発入り 弾倉 (Mk262) + 30발들이 5.56mm 탄창 (Mk262) + 5.56mm 30發 彈匣 (Mk262 狙擊專用彈) + 5.56mm 30发 弹匣 (Mk262 狙击专用弹) 5.56mm Mk262 5,56mm Mk262 - 5.56mm Mk262 + 5,56mm Mk262 5.56mm Mk262 5,56 мм Mk262 5,56mm Mk262 @@ -859,11 +1236,15 @@ 5.56mm Mk262 5.56mm Mk262 5,56mm Mk262 + 5.56mm Mk262 + 5.56mm Mk262 + 5.56mm Mk262 狙擊專用彈 + 5.56mm Mk262 狙击专用弹 Caliber: 5.56x45mm NATO (Mk262)<br />Rounds: 30 Kaliber: 5,56x45mm NATO (Mk262)<br />Pociski: 30 - Calibre: 5.56x45mm NATO (Mk262)<br />Cartouches: 30 + Calibre: 5,56x45mm NATO (Mk262)<br />Cartouches: 30 Calibre: 5.56x45mm NATO (Mk262)<br />Balas: 30 Калибр: 5,56x45 мм NATO (Mk262)<br />Патронов: 30 Kaliber: 5,56x45mm NATO (Mk262)<br />Patronen: 30 @@ -871,11 +1252,15 @@ Ráže: 5.56x45mm NATO (Mk262)<br />Nábojů: 30 Calibre: 5.56x45mm NATO (Mk262)<br/>Cartuchos: 30 Kaliber: 5,56x45mm NATO (Mk262)<br />Lövedékek: 30 + 口径: 5.56x45mm NATO (Mk262)<br />装填数: 30 + 구경: 5.56x45mm NATO (Mk262)<br />장탄수: 30 + 口徑: 5.56x45mm NATO標準 (Mk262 狙擊專用彈)<br />發數: 30 + 口径: 5.56x45mm NATO标准 (Mk262 狙击专用弹)<br />发数: 30 5.56mm 30Rnd Mag (Mk318) Magazynek 5,56mm 30rd (Mk318) - Ch. 5.56mm 30Cps (Mk318) + Ch. 5,56mm 30Cps (Mk318) Cargador de 30 balas de 5.56mm (Mk318) Магазин из 30-ти 5.56 мм (Mk318) 5,56mm 30-Patronen-Magazin (Mk318) @@ -883,11 +1268,15 @@ 5.56mm 30Rnd Zásobník (Mk318) Carregador 5.56mm com 30 cartuchos (Mk318) 5,56mm 30-lövedékes tár (Mk318) + 5.56mm 30発入り 弾倉 (Mk318) + 30발들이 5.56mm 탄창 (Mk318) + 5.56mm 30發 彈匣 (Mk318 特戰專用彈) + 5.56mm 30发 弹匣 (Mk318 特战专用弹) 5.56mm Mk318 5,56mm Mk318 - 5.56mm Mk318 + 5,56mm Mk318 5.56mm Mk318 5.56 мм Mk318 5,56mm Mk318 @@ -895,11 +1284,15 @@ 5.56mm Mk318 5.56mm Mk318 5,56mm Mk318 + 5.56mm Mk318 + 5.56mm Mk318 + 5.56mm Mk318 特戰專用彈 + 5.56mm Mk318 特战专用弹 Caliber: 5.56x45mm NATO (Mk318)<br />Rounds: 30 Kaliber: 5,56x45mm NATO (Mk318)<br />Pociski: 30 - Calibre: 5.56x45mm NATO (Mk318)<br />Cartouches: 30 + Calibre: 5,56x45mm NATO (Mk318)<br />Cartouches: 30 Calibre: 5.56x45mm NATO (Mk318)<br />Balas: 30 Калибр: 5,56x45 мм NATO (Mk318)<br />Патронов: 30 Kaliber: 5,56x45mm NATO (Mk318)<br />Patronen: 30 @@ -907,11 +1300,15 @@ Ráže: 5.56x45mm NATO (Mk318)<br />Nábojů: 30 Calibre: 5.56x45mm NATO (Mk318)<br/>Cartuchos: 30 Kaliber: 5,56x45mm NATO (Mk318)<br />Lövedékek: 30 + 口径: 5.56x45mm NATO (Mk318)<br />装填数: 30 + 구경: 5.56x45mm NATO (Mk318)<br />장탄수: 30 + 口徑: 5.56x45mm NATO標準 (Mk318 特戰專用彈)<br />發數: 30 + 口径: 5.56x45mm NATO标准 (Mk318 特战专用弹)<br />发数: 30 5.56mm 30Rnd Mag (M995 AP) Magazynek 5,56mm 30rd (M995 AP) - Ch. 5.56mm 30Cps (M995 AP) + Ch. 5,56mm 30Cps (M995 AP) Cargador de 30 balas de 5.56mm (M995 AP) Магазин из 30-ти 5.56 мм (M995 бронебойные) 5,56mm 30-Patronen-Magazin (M995AP) @@ -919,11 +1316,15 @@ 5.56mm 30náb. Zásobník (M995 AP) Carregador 5.56mm com 30 cartuchos (M995 AP) 5,56mm 30-lövedékes tár (M995 páncéltörő) + 5.56mm 30発入り 弾倉 (M995 徹甲弾) + 30발들이 5.56mm 탄창 (Mk995 철갑탄) + 5.56mm 30發 彈匣 (M995 穿甲彈) + 5.56mm 30发 弹匣 (M995 穿甲弹) 5.56mm AP 5,56mm AP - 5.56mm AP + 5,56mm AP 5.56mm AP 5.56 мм бронебойные 5,56mm AP @@ -931,11 +1332,15 @@ 5.56mm AP 5.56mm M995 AP 5,56mm páncéltörő + 5.56mm 徹甲弾 + 5.56mm 철갑탄 + 5.56mm M995 穿甲彈 + 5.56mm M995 穿甲弹 Caliber: 5.56x45mm NATO (M995 AP)<br />Rounds: 30 Kaliber: 5,56x45mm NATO (M995 AP)<br />Pociski: 30 - Calibre: 5.56x45mm NATO (M995 AP)<br />Cartouches: 30 + Calibre: 5,56x45mm NATO (M995 AP)<br />Cartouches: 30 Calibre: 5.56x45mm NATO (M995 AP)<br />Balas: 30 Калибр: 5,56x45 мм NATO (M995 бронебойные)<br />Патронов: 30 Kaliber: 5,56x45mm NATO (M995 AP)<br />Patronen: 30 @@ -943,11 +1348,15 @@ Ráže: 5.56x45mm NATO (M995 AP)<br />Nábojů: 30 Calibre: 5.56x45mm NATO (M995 AP)<br/>Cartuchos: 30 Kaliber: 5,56x45mm NATO (M995 páncéltörő)<br />Lövedékek: 30 + 口径: 5.56x45mm NATO (M995 徹甲弾)<br />装填数: 30 + 구경: 5.56x45mm NATO (Mk995 철갑탄)<br />장탄수: 30 + 口徑: 5.56x45mm NATO標準 (M995 穿甲彈)<br />發數: 30 + 口径: 5.56x45mm NATO标准 (M995 穿甲弹)<br />发数: 30 7.62mm 10Rnd Mag (M118LR) Magazynek 7,62mm 10rd (M118LR) - Ch. 7.62mm 10Cps (M118LR) + Ch. 7,62mm 10Cps (M118LR) Cargador de 10 balas de 7.62mm (M118LR) Магазин из 10-ти 7,62 мм (M118LR) 7,62mm 10-Patronen-Magazin (M118LR) @@ -955,11 +1364,15 @@ 7.62mm 10náb. Zásobník (M118LR) Carregador 7.62mm com 10 cartuchos (M118LR) 7,62mm 10-lövedékes tár (M118LR) + 7.62mm 10発入り 弾倉 (M118LR) + 10발들이 7.62mm 탄창 (M118LR) + 7.62mm 10發 彈匣 (M118LR 狙擊專用彈) + 7.62mm 10发 弹匣 (M118LR 狙击专用弹) 7.62mm M118LR 7,62mm M118LR - 7.62mm M118LR + 7,62mm M118LR 7.62mm M118LR 7,62 мм M118LR 7,62mm M118LR @@ -967,11 +1380,15 @@ 7.62mm M118LR 7.62mm M118LR 7,62mm M118LR + 7.62mm M118LR + 7.62mm M118LR + 7.62mm M118LR 狙擊專用彈 + 7.62mm M118LR 狙击专用弹 Caliber: 7.62x51mm NATO (M118LR)<br />Rounds: 10 Kaliber: 7,62x51mm NATO (M118LR)<br />Pociski: 10 - Calibre: 7.62x51mm NATO (M118LR)<br />Cartouches: 10 + Calibre: 7,62x51mm NATO (M118LR)<br />Cartouches: 10 Calibre: 7.62x51mm NATO (M118LR)<br />Balas: 10 Калибр: 7,62x51 мм NATO (M118LR)<br />Патронов: 10 Kaliber: 7,62x51mm NATO (M118LR)<br />Patronen: 10 @@ -979,11 +1396,15 @@ Ráže: 7.62x51mm NATO (M118LR)<br />Nábojů: 10 Calibre: 7.26x51mm NATO (M118LR)<br/>Cartuchos: 10 Kaliber: 7,62x51mm NATO (M118LR)<br />Lövedékek: 10 + 口径: 7.62x51mm NATO (M118LR)<br />装填数: 10 + 구경: 7.62x51mm NATO (M118LR)<br />장탄수: 10 + 口徑: 7.62x51mm NATO標準 (M118LR 狙擊專用彈)<br />發數: 10 + 口径: 7.62x51mm NATO标准 (M118LR 狙击专用弹)<br />发数: 10 7.62mm 20Rnd Mag (M118LR) Magazynek 7,62mm 20rd (M118LR) - Ch. 7.62mm 20Cps (M118LR) + Ch. 7,62mm 20Cps (M118LR) Cargador de 20 balas de 7.62mm (M118LR) Магазин из 20-ти 7,62 мм (M118LR) 7,62mm 20-Patronen-Magazin (M118LR) @@ -991,11 +1412,15 @@ 7.62mm 20náb. Zásobník (M118LR) Carregador 7.62mm com 20 cartuchos (M118LR) 7,62mm 20-lövedékes tár (M118LR) + 7.62mm 20発入り 弾倉 (M118LR) + 20발들이 7.62mm 탄창 (M118LR) + 7.62mm 20發 彈匣 (M118LR 狙擊專用彈) + 7.62mm 20发 弹匣 (M118LR 狙击专用弹) 7.62mm M118LR 7,62mm M118LR - 7.62mm M118LR + 7,62mm M118LR 7.62mm M118LR 7,62 мм M118LR 7,62mm M118LR @@ -1003,6 +1428,10 @@ 7.62mm M118LR 7.62mm M118LR 7,62mm M118LR + 7.62mm M118LR + 7.62mm M118LR + 7.62mm M118LR 狙擊專用彈 + 7.62mm M118LR 狙击专用弹 Caliber: 7.62x51mm NATO (M118LR)<br />Rounds: 20 @@ -1015,11 +1444,15 @@ Ráže: 7.62x51mm NATO (M118LR)<br />Nábojů: 20 Calibre: 7.26x51mm NATO (M118LR)<br/>Cartuchos: 20 Kaliber: 7,62x51mm NATO (M118LR)<br />Lövedékek: 20 + 口径: 7.62x51mm NATO (M118LR)<br />装填数: 20 + 구경: 7.62x51mm NATO (M118LR)<br />장탄수: 20 + 口徑: 7.62x51mm NATO標準 (M118LR 狙擊專用彈)<br />發數: 20 + 口径: 7.62x51mm NATO标准 (M118LR 狙击专用弹)<br />发数: 20 7.62mm 10Rnd Mag (Mk316 Mod 0) Magazynek 7,62mm 10rd (Mk316 Mod 0) - Ch. 7.62mm 10Cps (Mk316 Mod 0) + Ch. 7,62mm 10Cps (Mk316 Mod 0) Cargador de 10 balas de 7.62mm (Mk316 Mod 0) Магазин из 10-ти 7,62 мм (Mk316 Mod 0) 7,62mm 10-Patronen-Magazin (Mk316 Mod 0) @@ -1027,11 +1460,15 @@ 7.62mm 10náb. Zásobník (Mk316 Mod 0) Carregador 7.62mm com 10 cartuchos (Mk316 Mod 0) 7,62mm 10-lövedékes tár (Mk316 Mod 0) + 7.62mm 10発入り 弾倉 (Mk316 Mod 0) + 10발들이 7.62mm 탄창 (Mk316 Mod 0) + 7.62mm 10發 彈匣 (Mk316 Mod 0 狙擊專用彈) + 7.62mm 10发 弹匣 (Mk316 Mod 0 狙击专用弹) 7.62mm Mk316 7,62mm Mk316 - 7.62mm Mk316 + 7,62mm Mk316 7.62mm Mk316 7,62 мм Mk316 7,62mm Mk316 @@ -1039,11 +1476,15 @@ 7.62mm Mk316 7.62mm Mk316 7,62mm Mk316 + 7.62mm Mk316 + 7.62mm Mk316 + 7.62mm Mk316 狙擊專用彈 + 7.62mm Mk316 狙击专用弹 Caliber: 7.62x51mm NATO (Mk316 Mod 0)<br />Rounds: 10 Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Pociski: 10 - Calibre: 7.62x51mm NATO (Mk316 Mod 0)<br />Cartouches: 10 + Calibre: 7,62x51mm NATO (Mk316 Mod 0)<br />Cartouches: 10 Calibre: 7.62x51mm NATO (Mk316 Mod 0)<br />Balas: 10 Калибр: 7,62x51 мм NATO (Mk316 Mod 0)<br />Патронов: 10 Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Patronen: 10 @@ -1051,11 +1492,15 @@ Ráže: 7.62x51mm NATO (Mk316 Mod 0)<br />Nábojů: 10 Calibre: 7.26x51mm NATO (Mk316 Mod 0)<br/>Cartuchos: 10 Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Lövedékek: 10 + 口径: 7.62x51mm NATO (Mk316 Mod 0)<br />装填数: 10 + 구경: 7.62x51mm NATO (Mk316 Mod 0)<br />장탄수: 10 + 口徑: 7.62x51mm NATO標準 (Mk316 Mod 0 狙擊專用彈)<br />發數: 10 + 口径: 7.62x51mm NATO标准 (Mk316 Mod 0 狙击专用弹)<br />发数: 10 7.62mm 20Rnd Mag (Mk316 Mod 0) Magazynek 7,62mm 20rd (Mk316 Mod 0) - Ch. 7.62mm 20Cps (Mk316 Mod 0) + Ch. 7,62mm 20Cps (Mk316 Mod 0) Cargador de 20 balas de 7.62mm (Mk316 Mod 0) Магазин из 20-ти 7,62 мм (Mk316 Mod 0) 7,62mm 20-Patronen-Magazin (Mk316 Mod 0) @@ -1063,11 +1508,15 @@ 7.62mm 20náb. Zásobník (Mk316 Mod 0) Carregador 7.62mm com 20 cartuchos (Mk316 Mod 0) 7,62mm 20-lövedékes tár (Mk316 Mod 0) + 7.62mm 20発入り 弾倉 (Mk316 Mod 0) + 20발들이 7.62mm 탄창 (Mk316 Mod 0) + 7.62mm 20發 彈匣 (Mk316 Mod 0 狙擊專用彈) + 7.62mm 20发 弹匣 (Mk316 Mod 0 狙击专用弹) 7.62mm Mk316 7,62mm Mk316 - 7.62mm Mk316 + 7,62mm Mk316 7.62mm Mk316 7,62 мм Mk316 7,62mm Mk316 @@ -1075,11 +1524,15 @@ 7.62mm Mk316 7.62mm Mk316 7,62mm Mk316 + 7.62mm Mk316 + 7.62mm Mk316 + 7.62mm Mk316 狙擊專用彈 + 7.62mm Mk316 狙击专用弹 Caliber: 7.62x51mm NATO (Mk316 Mod 0)<br />Rounds: 20 Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Pociski: 20 - Calibre: 7.62x51mm NATO (Mk316 Mod 0)<br />Cartouches: 20 + Calibre: 7,62x51mm NATO (Mk316 Mod 0)<br />Cartouches: 20 Calibre: 7.62x51mm NATO (Mk316 Mod 0)<br />Balas: 20 Калибр: 7,62x51 мм NATO (Mk316 Mod 0)<br />Патронов: 20 Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Patronen: 20 @@ -1087,11 +1540,15 @@ Ráže: 7.62x51mm NATO (Mk316 Mod 0)<br />Nábojů: 20 Calibre: 7.26x51mm NATO (Mk316 Mod 0)<br/>Cartuchos: 20 Kaliber: 7,62x51mm NATO (Mk316 Mod 0)<br />Lövedékek: 20 + 口径: 7.62x51mm NATO (Mk316 Mod 0)<br />装填数: 20 + 구경: 7.62x51mm NATO (Mk316 Mod 0)<br />장탄수: 20 + 口徑: 7.62x51mm NATO標準 (Mk316 Mod 0 狙擊專用彈)<br />發數: 20 + 口径: 7.62x51mm NATO标准 (Mk316 Mod 0 狙击专用弹)<br />发数: 20 7.62mm 10Rnd Mag (Mk319 Mod 0) Magazynek 7,62mm 10rd (Mk319 Mod 0) - Ch. 7.62mm 10Cps (Mk319 Mod 0) + Ch. 7,62mm 10Cps (Mk319 Mod 0) Cargador de 10 balas de 7.62mm (Mk319 Mod 0) Магазин из 10-ти 7,62 мм (Mk319 Mod 0) 7,62mm 10-Patronen-Magazin (Mk319 Mod 0) @@ -1099,11 +1556,15 @@ 7.62mm 10náb. Zásobník (Mk319 Mod 0) Carregador 7.62mm com 10 cartuchos (Mk319 Mod 0) 7,62mm 10-lövedékes tár (Mk319 Mod 0) + 7.62mm 10発入り 弾倉 (Mk319 Mod 0) + 10발들이 7.62mm 탄창 (Mk319 Mod 0) + 7.62mm 10發 彈匣 (Mk319 Mod 0 特戰專用彈) + 7.62mm 10发 弹匣 (Mk319 Mod 0 特战专用弹) 7.62mm Mk319 7,62mm Mk319 - 7.62mm Mk319 + 7,62mm Mk319 7.62mm Mk319 7,62 мм Mk319 7,62mm Mk319 @@ -1111,11 +1572,15 @@ 7.62mm Mk319 7.62mm Mk319 7,62mm Mk319 + 7.62mm Mk319 + 7.62mm Mk319 + 7.62mm Mk319 特戰專用彈 + 7.62mm Mk319 特战专用弹 Caliber: 7.62x51mm NATO (Mk319 Mod 0)<br />Rounds: 10 Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Pociski: 10 - Calibre: 7.62x51mm NATO (Mk319 Mod 0)<br />Cartouches: 10 + Calibre: 7,62x51mm NATO (Mk319 Mod 0)<br />Cartouches: 10 Calibre: 7.62x51mm NATO (Mk319 Mod 0)<br />Balas: 10 Калибр: 7,62x51 мм NATO (Mk319 Mod 0)<br />Патронов: 10 Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Patronen: 10 @@ -1123,11 +1588,15 @@ Ráže: 7.62x51mm NATO (Mk319 Mod 0)<br />Nábojů: 10 Calibre: 7.26x51mm NATO (Mk319 Mod 0)<br/>Cartuchos: 10 Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Lövedékek: 10 + 口径: 7.62x51mm NATO (Mk319 Mod 0)<br />装填数: 10 + 구경: 7.62x51mm NATO (Mk319 Mod 0)<br />장탄수: 10 + 口徑: 7.62x51mm NATO標準 (Mk319 Mod 0 特戰專用彈)<br />發數: 10 + 口径: 7.62x51mm NATO标准 (Mk319 Mod 0 特战专用弹)<br />发数: 10 7.62mm 20Rnd Mag (Mk319 Mod 0) Magazynek 7,62mm 20rd (Mk319 Mod 0) - Ch. 7.62mm 20Cps (Mk319 Mod 0) + Ch. 7,62mm 20Cps (Mk319 Mod 0) Cargador de 20 balas de 7.62mm (Mk319 Mod 0) Магазин из 20-ти 7,62 мм (Mk319 Mod 0) 7,62mm 20-Patronen-Magazin (Mk319 Mod 0) @@ -1135,11 +1604,15 @@ 7.62mm 20náb. Zásobník (Mk319 Mod 0) Carregador 7.62mm com 20 cartuchos (Mk319 Mod 0) 7,62mm 20-lövedékes tár (Mk319 Mod 0) + 7.62mm 20発入り 弾倉 (Mk319 Mod 0) + 20발들이 7.62mm 탄창 (Mk319 Mod 0) + 7.62mm 20發 彈匣 (Mk319 Mod 0 特戰專用彈) + 7.62mm 20发 弹匣 (Mk319 Mod 0 特战专用弹) 7.62mm Mk319 7,62mm Mk319 - 7.62mm Mk319 + 7,62mm Mk319 7.62mm Mk319 7,62 мм Mk319 7,62mm Mk319 @@ -1147,11 +1620,15 @@ 7.62mm Mk319 7.62mm Mk319 7,62mm Mk319 + 7.62mm Mk319 + 7.62mm Mk319 + 7.62mm Mk319 特戰專用彈 + 7.62mm Mk319 特战专用弹 Caliber: 7.62x51mm NATO (Mk319 Mod 0)<br />Rounds: 20 Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Pociski: 20 - Calibre: 7.62x51mm NATO (Mk319 Mod 0)<br />Cartouches: 20 + Calibre: 7,62x51mm NATO (Mk319 Mod 0)<br />Cartouches: 20 Calibre: 7.62x51mm NATO (Mk319 Mod 0)<br />Balas: 20 Калибр: 7,62x51 мм NATO (Mk319 Mod 0)<br />Патронов: 20 Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Patronen: 20 @@ -1159,11 +1636,15 @@ Ráže: 7.62x51mm NATO (Mk319 Mod 0)<br />Nábojů: 20 Calibre: 7.26x51mm NATO (Mk319 Mod 0)<br/>Cartuchos: 20 Kaliber: 7,62x51mm NATO (Mk319 Mod 0)<br />Lövedékek: 20 + 口径: 7.62x51mm NATO (Mk319 Mod 0)<br />装填数: 20 + 구경: 7.62x51mm NATO (Mk319 Mod 0)<br />장탄수: 20 + 口徑: 7.62x51mm NATO標準 (Mk319 Mod 0 特戰專用彈)<br />發數: 20 + 口径: 7.62x51mm NATO标准 (Mk319 Mod 0 特战专用弹)<br />发数: 20 7.62mm 10Rnd Mag (M993 AP) Magazynek 7,62mm 10rd (M993 AP) - Ch. 7.62mm 10Cps (M993 AP) + Ch. 7,62mm 10Cps (M993 AP) Cargador de 10 balas de 7.62mm (M993 AP) Магазин из 10-ти 7,62 мм (M993 бронебойные) 7,62mm 10-Patronen-Magazin (M993 AP) @@ -1171,11 +1652,15 @@ 7.62 10náb. Zásobník (M993 AP) Carregador 7.62mm com 10 cartuchos (M993 AP) 7,62mm 10-lövedékes tár (M993 páncéltörő) + 7.62mm 10発入り 弾倉 (M993 徹甲弾) + 10발들이 7.62mm 탄창 (M993 철갑탄) + 7.62mm 10發 彈匣 (M993 穿甲專用彈) + 7.62mm 10发 弹匣 (M993 穿甲专用弹) 7.62mm AP 7,62mm AP - 7.62mm AP + 7,62mm AP 7.62mm AP 7,62mm бронебойные 7,62mm AP @@ -1183,11 +1668,15 @@ 7.62mm AP 7.62mm AP 7,62mm páncéltörő + 7.62mm 徹甲弾 + 7.62mm 철갑탄 + 7.62mm M993 穿甲專用彈 + 7.62mm M993 穿甲专用弹 Caliber: 7.62x51mm NATO (M993 AP)<br />Rounds: 10 Kaliber: 7,62x51mm NATO (M993 AP)<br />Pociski: 10 - Calibre: 7.62x51mm NATO (M993 AP)<br />Cartouches: 10 + Calibre: 7,62x51mm NATO (M993 AP)<br />Cartouches: 10 Calibre: 7.62x51mm NATO (M993 AP)<br />Balas: 10 Калибр: 7,62x51 мм NATO (M993 бронебойные)<br />Патронов: 10 Kaliber: 7,62x51mm NATO (M993 AP)<br />Patronen: 10 @@ -1195,11 +1684,15 @@ Ráže: 7.62x51mm NATO (M993 AP)<br />Nábojů: 10 Calibre: 7.26x51mm NATO (M993 AP)<br/>Cartuchos: 10 Kaliber: 7,62x51mm NATO (M993 páncéltörő)<br />Lövedékek: 10 + 口径: 7.62x51mm NATO (Mk319 Mod 0)<br />装填数: 10 + 구경: 7.62x51mm NATO (M993 철갑탄)<br />장탄수: 10 + 口徑: 7.62x51mm NATO標準 (M993 穿甲專用彈)<br />發數: 10 + 口径: 7.62x51mm NATO标准 (M993 穿甲专用弹)<br />发数: 10 7.62mm 20Rnd Mag (M993 AP) Magazynek 7,62mm 20rd (M993 AP) - Ch. 7.62mm 20Cps (M993 AP) + Ch. 7,62mm 20Cps (M993 AP) Cargador de 20 balas de 7.62mm (M993 AP) Магазин из 20-ти 7,62 мм (M993 бронебойные) 7,62mm 20-Patronen-Magazin (M993 AP) @@ -1207,11 +1700,15 @@ 7.62mm 20náb. Zásobník (M993 AP) Carregador 7.62mm com 20 cartuchos (M993 AP) 7,62mm 20-lövedékes tár (M993 páncéltörő) + 7.62mm 20発入り 弾倉 (M993 徹甲弾) + 20발들이 7.62mm 탄창 (M993 철갑탄) + 7.62mm 20發 彈匣 (M993 穿甲專用彈) + 7.62mm 20发 弹匣 (M993 穿甲专用弹) 7.62mm AP 7,62mm AP - 7.62mm AP + 7,62mm AP 7.62mm AP 7,62 мм бронебойные 7,62mm AP @@ -1219,11 +1716,15 @@ 7.62mm AP 7.62mm AP 7,62mm páncéltörő + 7.62mm 徹甲弾 + 7.62mm 철갑탄 + 7.62mm M993 穿甲專用彈 + 7.62mm M993 穿甲专用弹 Caliber: 7.62x51mm NATO (M993 AP)<br />Rounds: 20 Kaliber: 7,62x51mm NATO (M993 AP)<br />Pociski: 20 - Calibre: 7.62x51mm NATO (M993 AP)<br />Cartouches: 20 + Calibre: 7,62x51mm NATO (M993 AP)<br />Cartouches: 20 Калибр: 7,62x51 мм NATO (M993 бронебойные)<br />Патронов: 20 Kaliber: 7,62x51mm NATO (M993 AP)<br />Patronen: 20 Calibro: 7.62x51 mm NATO (M993 AP)<br />Munizioni: 20 @@ -1231,11 +1732,15 @@ Ráže: 7.62x51mm NATO (M993 AP)<br />Nábojů: 20 Calibre: 7.26x51mm NATO (M993 AP)<br/>Cartuchos: 20 Kaliber: 7,62x51mm NATO (M993 páncéltörő)<br />Lövedékek: 20 + 口径: 7.62x51mm NATO (M993 徹甲弾)<br />装填数: 20 + 구경: 7.62x51mm NATO (M993 철갑탄)<br />장탄수: 20 + 口徑: 7.62x51mm NATO標準 (M993 穿甲專用彈)<br />發數: 20 + 口径: 7.62x51mm NATO标准 (M993 穿甲专用弹)<br />发数: 20 7.62mm 20Rnd Mag (Mk248 Mod 0) Magazynek 7,62mm 20rd (Mk248 Mod 0) - Ch. 7.62mm 20Cps (Mk248 Mod 0) + Ch. 7,62mm 20Cps (Mk248 Mod 0) Cargador de 20 balas de 7.62mm (Mk248 Mod 0) Магазин из 20-ти 7,62 мм (Mk248 Mod 0) 7,62mm 20-Patronen-Magazin (Mk248 Mod 0) @@ -1243,11 +1748,15 @@ 7.62mm 20náb. Zásobník (Mk248 Mod 0) Carregador 7.62mm com 20 cartuchos (Mk248 Mod 0) 7,62mm 20-lövedékes tár (Mk248 Mod 0) + 7.62mm 20発入り 弾倉 (Mk248 Mod 0) + 20발들이 7.62mm 탄창 (Mk248 Mod 0) + 7.62mm 20發 彈匣 (Mk248 Mod 0 狙擊專用彈) + 7.62mm 20发 弹匣 (Mk248 Mod 0 狙击专用弹) 7.62mm Mk248 7,62mm Mk248 - 7.62mm Mk248 + 7,62mm Mk248 7.62mm Mk248 7,62 мм Mk248 7,62mm Mk248 @@ -1255,11 +1764,15 @@ 7.62mm Mk248 7.62mm Mk248 7,62mm Mk248 + 7.62mm Mk248 + 7.62mm Mk248 + 7.62mm Mk248 狙擊專用彈 + 7.62mm Mk248 狙击专用弹 Caliber: 7.62x67mm NATO (Mk248 Mod 0)<br />Rounds: 20 Kaliber: 7,62x67mm NATO (Mk248 Mod 0)<br />Pociski: 20 - Calibre: 7.62x67mm NATO (Mk248 Mod 0)<br />Cartouches: 20 + Calibre: 7,62x67mm NATO (Mk248 Mod 0)<br />Cartouches: 20 Calibre: 7.62x67mm NATO (Mk248 Mod 0)<br />Balas: 20 Калибр: 7,62x67 мм NATO (Mk248 Mod 0)<br />Патронов: 20 Kaliber: 7,62x51mm NATO (Mk248 Mod 0)<br />Patronen: 20 @@ -1267,11 +1780,15 @@ Ráže: 7.62x67mm NATO (Mk248 Mod 0)<br />Nábojů: 20 Calibre: 7.26x67mm NATO (Mk248 Mod 0)<br/>Cartuchos: 20 Kaliber: 7,62x51mm NATO (Mk248 Mod 0)<br />Lövedékek: 20 + 口径: 7.62x67mm NATO (Mk248 Mod 0)<br />装填数: 20 + 구경: 7.62x51mm NATO (Mk248 Mod 0)<br />장탄수: 20 + 口徑: 7.62x67mm NATO標準 (Mk248 Mod 0 狙擊專用彈)<br />發數: 20 + 口径: 7.62x67mm NATO标准 (Mk248 Mod 0 狙击专用弹)<br />发数: 20 7.62mm 20Rnd Mag (Mk248 Mod 1) Magazynek 7,62mm 20rd (Mk248 Mod 1) - Ch. 7.62mm 20Cps (Mk248 Mod 1) + Ch. 7,62mm 20Cps (Mk248 Mod 1) Cargador de 20 balas de 7.62mm (Mk248 Mod 1) Магазин из 20-ти 7,62 мм (Mk248 Mod 1) 7,62mm 20-Patronen-Magazin (Mk248 Mod 1) @@ -1279,11 +1796,15 @@ 7.62mm 20náb. Zásobník (Mk248 Mod 1) Carregador 7.62mm com 20 cartuchos (Mk248 Mod 1) 7,62mm 20-lövedékes tár (Mk248 Mod 1) + 7.62mm 20発入り 弾倉 (Mk248 Mod 1) + 20발들이 7.62mm 탄창 (Mk248 Mod 1) + 7.62mm 20發 彈匣 (Mk248 Mod 1 狙擊專用彈) + 7.62mm 20发 弹匣 (Mk248 Mod 1 狙击专用弹) 7.62mm Mk248 7,62mm Mk248 - 7.62mm Mk248 + 7,62mm Mk248 7.62mm Mk248 7,62 мм Mk248 7,62mm Mk248 @@ -1291,11 +1812,15 @@ 7.62mm Mk248 7.62mm Mk248 7,62mm Mk248 + 7.62mm Mk248 + 7.62mm Mk248 + 7.62mm Mk248 狙擊專用彈 + 7.62mm Mk248 狙击专用弹 Caliber: 7.62x67mm NATO (Mk248 Mod 1)<br />Rounds: 20 Kaliber: 7,62x67mm NATO (Mk248 Mod 1)<br />Pociski: 20 - Calibre: 7.62x67mm NATO (Mk248 Mod 1)<br />Cartouches: 20 + Calibre: 7,62x67mm NATO (Mk248 Mod 1)<br />Cartouches: 20 Calibre: 7.62x67mm NATO (Mk248 Mod 1)<br />Balas: 20 Калибр: 7,62x67 мм NATO (Mk248 Mod 1)<br />Патронов: 20 Kaliber: 7,62x51mm NATO (Mk248 Mod 1)<br />Patronen: 20 @@ -1303,11 +1828,15 @@ Ráže: 7.62x67mm NATO (Mk248 Mod 1)<br />Nábojů: 20 Calibre: 7.26x67mm NATO (Mk248 Mod 1)<br/>Cartuchos: 20 Kaliber: 7,62x51mm NATO (Mk248 Mod 1)<br />Lövedékek: 20 + 口径: 7.62x67mm NATO (Mk248 Mod 1)<br />装填数: 20 + 구경: 7.62x51mm NATO (Mk248 Mod 1)<br />장탄수: 20 + 口徑: 7.62x67mm NATO標準 (Mk248 Mod 1 狙擊專用彈)<br />發數: 20 + 口径: 7.62x67mm NATO标准 (Mk248 Mod 1 狙击专用弹)<br />发数: 20 7.62mm 20Rnd Mag (Berger Hybrid OTM) Magazynek 7,62mm 20rd (Berger Hybrid OTM) - Ch. 7.62 20Cps (Berger Hybrid OTM) + Ch. 7,62 20Cps (Berger Hybrid OTM) Cargador de 20 balas de 7.62mm (Berger Hybrid OTM) Магазин из 20-ти 7,62 мм (Berger Hybrid OTM) 7,62mm 20-Patronen-Magazin (Berger Hybrid OTM) @@ -1315,11 +1844,15 @@ 7.62mm 20náb. Zásobník (Berger Hybrid OTM) Carregador 7.62mm com 20 cartuchos (Berger Hybrid OTM) 7,62mm 20-lövedékes tár (Berger Hybrid OTM) + 7.62mm 20発入り 弾倉 (Berger Hybrid OTM) + 20발들이 7.62mm 탄창 (Berger Hybrid OTM) + 7.62mm 20發 彈匣 (Berger Hybrid 空尖比賽專用彈) + 7.62mm 20发 弹匣 (Berger Hybrid 空尖比赛专用弹) 7.62mm OTM 7,62mm OTM - 7.62mm OTM + 7,62mm OTM 7.62mm OTM 7,62 мм OTM 7,62mm OTM @@ -1327,11 +1860,15 @@ 7.62mm OTM 7.62mm OTM 7,62mm OTM + 7.62mm OTM + 7.62mm OTM + 7.62mm 空尖比賽專用彈 + 7.62mm 空尖比赛专用弹 Caliber: 7.62x67mm NATO (Berger Hybrid OTM)<br />Rounds: 20 Kaliber: 7,62x67mm NATO (Berger Hybrid OTM)<br />Pociski: 20 - Calibre: 7.62x67mm NATO (Berger Hybrid OTM)<br />Cartouches: 20 + Calibre: 7,62x67mm NATO (Berger Hybrid OTM)<br />Cartouches: 20 Calibre: 7.62x67mm NATO (Berger Hybrid OTM)<br />Balas: 20 Калибр: 7,62x67 мм NATO (Berger Hybrid OTM)<br />Патронов: 20 Kaliber: 7,62x67mm NATO (Berger Hybrid OTM)<br />Patronen: 20 @@ -1339,10 +1876,14 @@ Ráže: 7.62x67mm NATO (Berger Hybrid OTM)<br />Nábojů: 20 Calibre: 7.26x67mm NATO (Berger Hybrid OTM)<br/>Cartuchos: 20 Kaliber: 7,62x67mm NATO (Berger Hybrid OTM)<br />Lövedékek: 20 + 口径: 7.62x67mm NATO (Berger Hybrid OTM)<br />装填数: 20 + 구경: 7.62x51mm NATO (Berger Hybrid OTM)<br />장탄수: 20 + 口徑: 7.62x67mm NATO標準 (Berger Hybrid 空尖比賽專用彈)<br />發數: 20 + 口径: 7.62x67mm NATO标准 (Berger Hybrid 空尖比赛专用弹)<br />发数: 20 6.5x47mm 30Rnd Mag (HPBT Scenar) - Ch. 6.5x47mm 30Cps (HPBT Scenar) + Ch. 6,5x47mm 30Cps (HPBT Scenar) Cargador de 30 balas de 6.5x47mm (HPBT Scenar) Magazynek 6,5x47mm 30rd (HPBT Scenar) Магазин из 30-ти 6,5x47 мм (экспансивные Scenar) @@ -1351,10 +1892,14 @@ 6.5x47mm 30náb. Zásobník (HPBT Scenar) Carregador 6.5x47mm com 30 cartuchos (HPBT Scenar) 6,5x47mm 30-lövedékes tár (HPBT Scenar) + 6.5x47mm 30発入り 弾倉 (HPBT Scenar) + 30발들이 6.5x47mm 탄창 (HPBT Scenar) + 6.5x47mm 30發 彈匣 (Lapua 空尖艇尾狙擊專用彈) + 6.5x47mm 30发 弹匣 (Lapua 空尖艇尾狙击专用弹) 6.5mm Lapua - 6.5mm Lapua + 6,5mm Lapua 6.5mm Lapua 6,5mm Lapua 6,5 мм Lapua @@ -1363,10 +1908,14 @@ 6.5mm Lapua 6.5mm Lapua 6,5mm Lapua + 6.5mm Lapua + 6.5mm Lapua + 6.5mm Lapua 空尖艇尾狙擊專用彈 + 6.5mm Lapua 空尖艇尾狙击专用弹 Caliber: 6.5x47mm (HPBT Scenar)<br />Rounds: 30<br />Used in: MXM - Calibre: 6.5x47mm (HPBT Scenar)<br />Cartouches: 30 + Calibre: 6,5x47mm (HPBT Scenar)<br />Cartouches: 30 Calibre: 6.5x47mm (HPBT Scenar)<br />Balas: 30<br />Se usa en: MXM Kaliber: 6,5x47mm (HPBT Scenar)<br />Pociski: 30 Калибр: 6,5x47 мм (экспансивные Scenar)<br />Патронов: 30<br />Используются с: MXM @@ -1375,6 +1924,10 @@ Ráže: 6.5x47mm (HPBT Scenar)<br />Nábojů: 30<br />Použití u: MXM Calibre: 6.5x47mm (HPBT Scenar)<br/>Cartuchos: 30<br/>Usado em: MXM Kaliber: 6,5x47mm (HPBT Scenar)<br />Lövedékek: 30<br />Használható: MXM + 口径: 6.5x47mm (HPBT Scenar)<br />装填数: 30<br />次で使用: MXM + 구경: 6.5x47mm (HPBT Scenar)<br />장탄수: 30<br />사용처: MXM + 口徑: 6.5x47mm (Lapua 空尖艇尾狙擊專用彈)<br />發數: 30<br />使用於: MXM + 口径: 6.5x47mm (Lapua 空尖艇尾狙击专用弹)<br />发数: 30<br />使用于: MXM 6.5mm Creedmor 30Rnd Mag @@ -1383,14 +1936,18 @@ Магазин из 30-ти 6,5 мм Creedmor 6,5mm Creedmor 30-Patronen-Magazin Cargador de 30 balas Creedmor de 6.5mm - Ch. 6.5mm Creedmor 30Cps + Ch. 6,5mm Creedmor 30Cps 6.5mm Creedmor 30náb. Zásobník Carregador 6.5mm com 30 cartuchos Creedmor 6,5mm Creedmor 30-lövedékes tár + 6.5mm Creedmor 30発入り 弾倉 + 30발들이 6.5mm Creedmor 탄창 + 6.5mm 30發 彈匣 (Creedmor 狙擊專用彈) + 6.5mm 30发 弹匣 (Creedmor 狙击专用弹) 6.5mm CM - 6.5mm CM + 6,5mm CM 6.5mm CM 6,5mm CM 6,5 мм CM @@ -1399,54 +1956,74 @@ 6.5mm CM 6.5mm CM 6,5mm CM + 6.5mm CM + 6.5mm CM + 6.5mm CM 狙擊專用彈 + 6.5mm CM 狙击专用弹 Caliber: 6.5x47mm Creedmor<br />Rounds: 30<br />Used in: MXM Kaliber: 6,5x47mm Creedmor<br />Pociski: 30<br />Używany w: MXM Kaliber: 6,5x47mm Creedmor<br />Patronen: 30<br />Eingesetzt von: MXM - Calibre: 6.5x47mm Creedmor <br />Cartouches: 30<br />Utilisé avec: MXM + Calibre: 6,5x47mm Creedmor <br />Cartouches: 30<br />Utilisé avec: MXM Calibro: 6.5mm Creedmor<br />Munizioni: 30<br />In uso su: MXM Calibre: 6.5mm Creedmor<br />Balas: 30<br />Se usa en: MXM Калибр: 6,5x47мм Creedmor<br />Патронов: 30<br />Используются c: MXM Ráže: 6.5x47mm Creedmor<br />Nábojů: 30<br />Použití u: MXM Calibre: 6.5x47mm Creedmor<br/>Cartuchos: 30<br/>Usado em: MXM Kaliber: 6,5x47mm Creedmor<br />Lövedékek: 30<br />Használható: MXM + 口径: 6.5x47mm Creedmor<br />装填数: 30<br />次で使用: MXM + 구경: 6.5x47mm Creedmor<br />장탄수: 30<br />사용처: MXM + 口徑: 6.5x47mm Creedmor 狙擊專用彈<br />發數: 30<br />使用於: MXM + 口径: 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 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 Scenar + .338 Scenar + .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 + 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) @@ -1459,6 +2036,10 @@ .338 10náb. Zásobník (API526) Carregador .338 (API526) com 10 cartuchos .338 10-lövedékes tár (API526) + .338 10発入り 弾倉 (API526) + 10발들이 .338 탄창 (API526) + .338 10發 彈匣 (API526 穿甲燃燒彈) + .338 10发 弹匣 (API526 穿甲燃烧弹) .338 AP @@ -1471,10 +2052,14 @@ .338 AP .338 AP .338 páncéltörő + .338 徹甲弾 + .338 철갑탄 + .338 API526 穿甲燃燒彈 + .338 API526 穿甲燃烧弹 Caliber: 8.6x70mm (API526)<br />Rounds: 10 - Calibre: 8.6x70mm (API526)<br />Cartouches: 10 + Calibre: 8,6x70mm (API526)<br />Cartouches: 10 Calibre: 8.6x70mm (API526)<br />Balas: 10 Kaliber: 8,6x70mm (API526)<br />Pociski: 10 Калибр: 8,6x70 мм (API526)<br />Патронов: 10 @@ -1483,10 +2068,62 @@ Ráže: 8.6x70mm (API526)<br />Nábojů: 10 Calibre: 8.6x70mm (API526)<br/>Cartuchos: 10 Kaliber: 8,6x70mm (API526)<br />Lövedékek: 10 + 口径: 8.6x70mm (API526)<br />装填数: 10 + 구경: 8.6x70mm (API526)<br />장탄수: 10 + 口徑: 8.6x70mm (API526 穿甲燃燒彈)<br />發數: 10 + 口径: 8.6x70mm (API526 穿甲燃烧弹)<br />发数: 10 + + + .408 7Rnd Mag (305gr) + Ch. .408 7Cps (305gr) + Cargador de 7 balas de .408 (305gr) + Magazynek .408 7rd (305gr) + Магазин из 7-ти .408 (305gr) + .408 7-Patronen-Magazin (305gr) + .408 7Rnd Mag (305gr) + .408 7náb. Zásobník (305gr) + Carregador .408 (305gr) com 7 cartuchos + .408 7-lövedékes tár (305gr) + .408 7発入り 弾倉 (305gr) + 7발들이 .408 탄창 (305gr) + .408 7發 彈匣 (305公克) + .408 7发 弹匣 (305公克) + + + .408 + .408 + .408 + .408 + .408 + .408 + .408 + .408 + .408 + .408 + .408 + .408 + .408 + .408 + + + Caliber: .408 CheyTac (305gr)<br />Rounds: 7 + Calibre: .408 CheyTac (305gr)<br />Cartouches: 7 + Calibre: .408 CheyTac (305gr)<br />Balas: 7 + Kaliber: .408 CheyTac (305gr)<br />Pociski: 7 + Калибр: .408 CheyTac (305gr)<br />Патронов: 7 + Kaliber: .408 CheyTac (305gr)<br />Patronen: 7 + Calibro: .408 CheyTac (305gr)<br />Munizioni: 7 + Ráže: .408 CheyTac (305gr)<br />Nábojů: 7 + Calibre: .408 CheyTac (305gr)<br/>Cartuchos: 7 + Kaliber: .408 CheyTac (305gr)<br />Lövedékek: 7 + 口径: .408 CheyTac (305gr)<br />装填数: 7 + 구경: .408 CheyTac (305gr)<br />장탄수: 7 + 口徑: .408 夏伊戰術狙擊彈 (305公克)<br />發數: 7 + 口径: .408 夏伊战术狙击弹 (305公克)<br />发数: 7 12.7x99mm 5Rnd Mag - Ch. 12.7x99mm 5Cps + Ch. 12,7x99mm 5Cps Cargador de 5 balas de 12.7x99mm Magazynek 12,7x99mm 5rd Магазин из 5-ти 12,7x99 мм @@ -1495,10 +2132,14 @@ 12.7x99mm 5náb. Zásobník Carregador 12.7x99mm com 5 cartuchos 12,7x99mm 5-lövedékes tár + 12.7x99mm 5発入り 弾倉 + 5발들이 12.7x99mm 탄창 + 12.7x99mm 5發 彈匣 + 12.7x99mm 5发 弹匣 12.7mm - 12.7mm + 12,7mm 12.7mm 12,7mm 12,7 мм @@ -1507,6 +2148,10 @@ 12.7mm 12.7mm 12,7mm + 12.7mm + 12.7mm + 12.7mm + 12.7mm Caliber: 12.7x99mm<br />Rounds: 5 @@ -1519,10 +2164,14 @@ Ráže: 12.7x99mm<br />Nábojů: 5 Calibre: 12.7x99mm<br/>Cartuchos: 5 Kaliber: 12,7x99mm<br />Lövedékek: 5 + 口径: 12.7x99mm<br />装填数: 5 + 구경: 12.7x99mm<br />장탄수: 5 + 口徑: 12.7x99mm<br />發數: 5 + 口径: 12.7x99mm<br />发数: 5 12.7x99mm API 5Rnd Mag - Ch. 12.7x99mm API 5Cps + Ch. 12,7x99mm API 5Cps Cargador de 5 balas de 12.7x99mm API Magazynek 12,7x99mm API 5rd 12.7x99mm API 5Rnd Mag @@ -1531,10 +2180,14 @@ 12.7x99mm API 5náb. Zásobník Carregador 12.7x99mm API com 5 cartuchos 12,7x99mm 5-lövedékes tár (páncéltörő-gyújtó) + 12.7x99mm 5発入り焼夷徹甲弾 弾倉 + 5발들이 12.7x99mm 철갑소이탄 탄창 + 12.7x99mm 穿甲燃燒彈 5發 彈匣 + 12.7x99mm 穿甲燃烧弹 5发 弹匣 12.7mm API - 12.7mm API + 12,7mm API 12.7mm API 12,7mm API 12.7mm API @@ -1543,10 +2196,14 @@ 12.7mm API 12.7mm API 12,7mm páncéltörő-gyújtó + 12.7mm 焼夷徹甲弾 + 12.7mm 철갑소이탄 + 12.7mm 穿甲燃燒彈 + 12.7mm 穿甲燃烧弹 Caliber: 12.7x99mm API<br />Rounds: 5 - Calibre: 12.7x99mm API<br />Cartouches: 5 + Calibre: 12,7x99mm API<br />Cartouches: 5 Calibre: 12.7x99mm API<br />Balas: 5 Kaliber: 12,7x99mm API<br />Pociski: 5 Калибр: 12,7x99 мм бронебойно-зажигательные<br />Патронов: 5 @@ -1555,10 +2212,14 @@ Ráže: 12.7x99mm API<br />Nábojů: 5 Calibre: 12.7x99mm API<br/>Cartuchos: 5 Kaliber: 12,7x99mm API<br />Lövedékek: 5 + 口径: 12.7x99mm 焼夷徹甲弾<br />装填数: 5 + 구경: 12.7x99mm 철갑소이탄<br />장탄수: 5 + 口徑: 12.7x99mm 穿甲燃燒彈<br />發數: 5 + 口径: 12.7x99mm 穿甲燃烧弹<br />发数: 5 12.7x99mm 5Rnd Mag (AMAX) - Ch. 12.7x99mm 5Cps (AMAX) + Ch. 12,7x99mm 5Cps (AMAX) Cargador de 5 balas de 12.7x99mm (AMAX) Magazynek 12,7x99mm 5rd (AMAX) Магазин из 5-ти 12,7x99 мм (A-MAX) @@ -1567,10 +2228,14 @@ 12.7x99mm 5náb. Zásobník (AMAX) Carregador 12.7x99mm (AMAX) com 5 cartuchos 12,7x99mm 5-lövedékes tár (AMAX) + 12.7x99mm 5発入り 弾倉 (AMAX) + 5발들이 12.7x99mm 탄창 (AMAX) + 12.7x99mm 5發 彈匣 (AMAX 比賽專用彈) + 12.7x99mm 5发 弹匣 (AMAX 比赛专用弹) 12.7mm - 12.7mm + 12,7mm 12.7mm 12,7mm 12,7 мм @@ -1579,10 +2244,14 @@ 12.7mm 12.7mm 12,7mm + 12.7mm + 12.7mm + 12.7mm AMAX 比賽專用彈 + 12.7mm AMAX 比赛专用弹 Caliber: 12.7x99mm (AMAX)<br />Rounds: 5 - Calibre: 12.7x99mm (AMAX)<br />Cartouches: 5 + Calibre: 12,7x99mm (AMAX)<br />Cartouches: 5 Calibre: 12.7x99mm (AMAX)<br />Balas: 5 Kaliber: 12,7x99mm (AMAX)<br />Pociski: 5 Калибр: 12,7x99 мм (A-MAX)<br />Патронов: 5 @@ -1591,6 +2260,10 @@ Ráže: 12.7x99mm (AMAX)<br />Nábojů: 5 Calibre: 12.7x99mm (AMAX)<br/>Cartuchos: 5 Kaliber: 12,7x99mm (AMAX)<br />Lövedékek: 5 + 口径: 12.7x99mm (AMAX)<br />装填数: 5 + 구경: 12.7x99mm (AMAX)<br />장탄수: 5 + 口徑: 12.7x99mm (AMAX 比賽專用彈)<br />發數: 5 + 口径: 12.7x99mm (AMAX 比赛专用弹)<br />发数: 5 [ACE] Ammo Supply Crate @@ -1603,6 +2276,49 @@ [ACE] Lőszeres láda [ACE] Ящик с боеприпасами [ACE] Cassa munizioni + [ACE] 弾薬物資箱 + [ACE] 탄약 보급 상자 + [ACE] 彈藥補給箱 + [ACE] 弹药补给箱 + + + Barrel twist + 銃身の転度 + 膛线缠距 + 膛線扭度 + Rigatura della canna + + + Barrel length + Longueur du canon + 銃身長 + 身管长度 + 槍管長度 + Lunghezza della canna + + + Ballistic coefficient + Coefficient ballistique + 弾道係数 + 弹道系数 + 彈道係數 + Coefficente balistico + + + Bullet mass + Masse d'une balle + 弾丸重量 + 弹头重量 + 彈頭重量 + Massa del proiettile + + + Muzzle velocity + Vitesse à la bouche + 銃口初速 + 枪口初速 + 槍口初速 + Velocità iniziale - \ No newline at end of file + 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..d000ad6083 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,37 +27,35 @@ 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; }; class ACE_StopEscorting { displayName = CSTRING(StopEscorting); 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; }; class ACE_LoadCaptive { displayName = CSTRING(LoadCaptive); 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)); - priority = 1.2; + exceptions[] = {"isNotSwimming"}; }; }; }; @@ -68,26 +65,23 @@ 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; }; class ACE_StartSurrenderingSelf { 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); }; class ACE_StopSurrenderingSelf { 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,8 +95,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"}; \ - priority = 1.2; \ + exceptions[] = {"isNotEscorting", "isNotSwimming"}; \ }; \ }; \ }; @@ -151,7 +144,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 +160,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 +178,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 +215,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/XEH_preInit.sqf b/addons/captives/XEH_preInit.sqf index 81657a8960..641da1f5c8 100644 --- a/addons/captives/XEH_preInit.sqf +++ b/addons/captives/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(captivityEnabled) = false; diff --git a/addons/captives/config.cpp b/addons/captives/config.cpp index b879e906fa..e9055e896a 100644 --- a/addons/captives/config.cpp +++ b/addons/captives/config.cpp @@ -20,11 +20,3 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "CfgEden.hpp" - -class ACE_newEvents { - SetSurrendered = QGVAR(setSurrendered); - SetHandcuffed = QGVAR(setHandcuffed); - MoveOutCaptive = QGVAR(moveOutCaptive); - MoveInCaptive = QGVAR(moveInCaptive); - CaptiveStatusChanged = "ace_captiveStatusChanged"; -}; diff --git a/addons/captives/functions/fnc_addLoadCaptiveActions.sqf b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf new file mode 100644 index 0000000000..81710f161d --- /dev/null +++ b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..72ac745517 100644 --- a/addons/captives/functions/fnc_canApplyHandcuffs.sqf +++ b/addons/captives/functions/fnc_canApplyHandcuffs.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able to apply handcuffs @@ -14,18 +15,17 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; //Check sides, Player has cableTie, target is alive and not already handcuffed (GVAR(allowHandcuffOwnSide) || {(side _unit) != (side _target)}) && -{"ACE_CableTie" in (items _unit)} && +{"ACE_CableTie" in (_unit call EFUNC(common,uniqueItems))} && {alive _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_canEscortCaptive.sqf b/addons/captives/functions/fnc_canEscortCaptive.sqf index a7c799905e..cb5fdd4972 100644 --- a/addons/captives/functions/fnc_canEscortCaptive.sqf +++ b/addons/captives/functions/fnc_canEscortCaptive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Tests if can escort target (attach) @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; //Alive, handcuffed, not being escored, and not unconscious diff --git a/addons/captives/functions/fnc_canFriskPerson.sqf b/addons/captives/functions/fnc_canFriskPerson.sqf index d164f13ac3..c086afa0c7 100644 --- a/addons/captives/functions/fnc_canFriskPerson.sqf +++ b/addons/captives/functions/fnc_canFriskPerson.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Checks the conditions for being able to frisk a unit @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/captives/functions/fnc_canLoadCaptive.sqf b/addons/captives/functions/fnc_canLoadCaptive.sqf index a59c2e3be6..2129b36f5a 100644 --- a/addons/captives/functions/fnc_canLoadCaptive.sqf +++ b/addons/captives/functions/fnc_canLoadCaptive.sqf @@ -1,23 +1,26 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit can load the target object into a vehicle. * * 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_canRemoveHandcuffs.sqf b/addons/captives/functions/fnc_canRemoveHandcuffs.sqf index e36ba5cd5b..37dc156bf0 100644 --- a/addons/captives/functions/fnc_canRemoveHandcuffs.sqf +++ b/addons/captives/functions/fnc_canRemoveHandcuffs.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able to remove handcuffs @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/captives/functions/fnc_canStopEscorting.sqf b/addons/captives/functions/fnc_canStopEscorting.sqf index cfafb5a0e8..01010c8f97 100644 --- a/addons/captives/functions/fnc_canStopEscorting.sqf +++ b/addons/captives/functions/fnc_canStopEscorting.sqf @@ -1,20 +1,20 @@ +#include "script_component.hpp" /* * 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 * * Public: No */ -#include "script_component.hpp" params ["_unit", ["_target", objNull]]; diff --git a/addons/captives/functions/fnc_canSurrender.sqf b/addons/captives/functions/fnc_canSurrender.sqf index 2b58b54d2d..bec8edca04 100644 --- a/addons/captives/functions/fnc_canSurrender.sqf +++ b/addons/captives/functions/fnc_canSurrender.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able switch surrender states @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_newSurrenderState"]; diff --git a/addons/captives/functions/fnc_canUnloadCaptive.sqf b/addons/captives/functions/fnc_canUnloadCaptive.sqf index 82fc0a8429..3c5b302529 100644 --- a/addons/captives/functions/fnc_canUnloadCaptive.sqf +++ b/addons/captives/functions/fnc_canUnloadCaptive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit can unload a captive from the vehicle. @@ -14,8 +15,8 @@ * * Public: No */ -#include "script_component.hpp" 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_doApplyHandcuffs.sqf b/addons/captives/functions/fnc_doApplyHandcuffs.sqf index d80ffc40a1..1731151ead 100644 --- a/addons/captives/functions/fnc_doApplyHandcuffs.sqf +++ b/addons/captives/functions/fnc_doApplyHandcuffs.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Checks the conditions for being able to apply handcuffs @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/captives/functions/fnc_doEscortCaptive.sqf b/addons/captives/functions/fnc_doEscortCaptive.sqf index e0d3ae8fa6..86d597aabe 100644 --- a/addons/captives/functions/fnc_doEscortCaptive.sqf +++ b/addons/captives/functions/fnc_doEscortCaptive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Nic547 * Attaches a Captive to the _unit @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target","_state"]; @@ -30,9 +30,9 @@ if (_state) then { _unit setVariable [QGVAR(escortedUnit), _target, true]; //Add Actionmenu to release captive - _actionID = _unit addAction [format ["%1", localize LSTRING(StopEscorting)], + 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_doFriskPerson.sqf b/addons/captives/functions/fnc_doFriskPerson.sqf index d3ddecfd13..58e7131e72 100644 --- a/addons/captives/functions/fnc_doFriskPerson.sqf +++ b/addons/captives/functions/fnc_doFriskPerson.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Open the select menu with the "personal" items of a frisked unit. It only shows "handgunWeapon", "uniformItems", "vestItems", "backpackItems" and "assignedItems" because every other item is visible on the character @@ -7,14 +8,13 @@ * 1: unit * * Return Value: - * Nothing + * None * * Example: * [player, bob] call ACE_captives_fnc_doFristPerson; * * Public: No */ -#include "script_component.hpp" params ["_player", "_unit"]; diff --git a/addons/captives/functions/fnc_doLoadCaptive.sqf b/addons/captives/functions/fnc_doLoadCaptive.sqf index 2a8bc055ec..e4e3b5f45b 100644 --- a/addons/captives/functions/fnc_doLoadCaptive.sqf +++ b/addons/captives/functions/fnc_doLoadCaptive.sqf @@ -1,50 +1,45 @@ +#include "script_component.hpp" /* * Author: commy2 * Unit loads the target object into a vehicle. (logic same as canLoadCaptive) * * 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: - * Nothing + * 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 {ERROR("");}; +if (isNull _target || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {WARNING("");}; if (isNull _vehicle) then { - //Looking at a captive unit, search for nearby vehicles with valid seats: - { - // 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; }; }; -if (isNull _vehicle) exitWith {ERROR("");}; +if (isNull _vehicle) exitWith {WARNING("Could not find vehicle to load captive");}; _unit setVariable [QGVAR(isEscorting), false, true]; [QGVAR(moveInCaptive), [_target, _vehicle], [_target]] call CBA_fnc_targetEvent; diff --git a/addons/captives/functions/fnc_doRemoveHandcuffs.sqf b/addons/captives/functions/fnc_doRemoveHandcuffs.sqf index 7f445440ba..a5623535d2 100644 --- a/addons/captives/functions/fnc_doRemoveHandcuffs.sqf +++ b/addons/captives/functions/fnc_doRemoveHandcuffs.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Remove handcuffs from a target @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/captives/functions/fnc_doUnloadCaptive.sqf b/addons/captives/functions/fnc_doUnloadCaptive.sqf index fd4375e4b7..8f78b7b323 100644 --- a/addons/captives/functions/fnc_doUnloadCaptive.sqf +++ b/addons/captives/functions/fnc_doUnloadCaptive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Unit unloads a captive from a vehicle. @@ -7,14 +8,13 @@ * 1: A captive loaded in a vehicle * * Return Value: - * Nothing + * None * * Example: * [bob, prisoner] call ACE_captives_fnc_doUnloadCaptive * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf index cf67614f91..7c9daf1080 100644 --- a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf +++ b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Finds a free cargo seat, searching non FFV first @@ -13,55 +14,24 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; TRACE_1("params", _vehicle); -_vehicleConfig = configFile >> "CfgVehicles" >> (typeOf _vehicle); +scopeName "main"; -_proxyOrder = getArray (_vehicleConfig >> "getInProxyOrder"); -_transportSoldier = getNumber (_vehicleConfig >> "transportSoldier"); -_realCargoCount = if (isArray (_vehicleConfig >> "getInProxyOrder")) then {count _proxyOrder} else {_transportSoldier}; - -//Find FFV turrets: -_ffvCargoIndexes = []; { - _turretConfig = [_vehicleConfig, _x] call EFUNC(common,getTurretConfigPath); - _isCargoProxy = ((getText (_turretConfig >> "proxyType")) == "CPCargo") && {isNumber (_turretConfig >> "proxyIndex")}; - - if (_isCargoProxy) then { - _proxyCargoIndex = getNumber (_turretConfig >> "proxyIndex"); - _cargoIndex = _proxyOrder find _proxyCargoIndex; - _ffvCargoIndexes pushBack _cargoIndex; + _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; + if (isNull _unit && {_role == "cargo"} && {_cargoIndex > -1} && {!_isPersonTurret}) then { + [_cargoIndex, false] breakOut "main"; }; -} forEach (allTurrets [_vehicle, true]); +} forEach (fullCrew [_vehicle, "", true]); -//Find Empty Seats: -_occupiedSeats = []; { - _x params ["", "", "_xIndex"]; - if (_xIndex > -1) then {_occupiedSeats pushBack _xIndex;}; -} forEach (fullCrew _vehicle); - -TRACE_3("Searching for empty seat",_realCargoCount,_ffvCargoIndexes,_occupiedSeats); - -_emptyCargoSeatReturn = [-1, false]; - -//First seach for non-ffv seats: -for "_index" from 0 to (_realCargoCount - 1) do { - if ((!(_index in _ffvCargoIndexes)) && {!(_index in _occupiedSeats)}) exitWith { - _emptyCargoSeatReturn = [_index, false]; + _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; + if (isNull _unit && {_cargoIndex > -1}) then { + [_cargoIndex, true] breakOut "main"; }; -}; +} forEach (fullCrew [_vehicle, "", true]); -//Only use FFV if none found: -if (_emptyCargoSeatReturn isEqualTo [-1, false]) then { - for "_index" from 0 to (_realCargoCount - 1) do { - if (!(_index in _occupiedSeats)) exitWith { - _emptyCargoSeatReturn = [_index, true]; - }; - }; -}; - -_emptyCargoSeatReturn +[-1, false] diff --git a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf index 2f55d51fc3..bdd61f6686 100644 --- a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Nic547, commy2 * Restart the handcuffing animation if it got interrupted. Called from a AnimChanged EH. @@ -6,15 +7,15 @@ * 0: The Unit * 1: New animation * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, "movearm"] call ACE_captives_fnc_handleAnimChangedHandcuffed + * * Public: No */ - -#include "script_component.hpp" - params ["_unit", "_newAnimation"]; TRACE_2("AnimChanged",_unit,_newAnimation); if (_unit == (vehicle _unit)) then { @@ -23,7 +24,7 @@ if (_unit == (vehicle _unit)) then { [_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation); }; } else { - _turretPath = []; + private _turretPath = []; { _x params ["_xUnit", "", "", "_xTurretPath"]; if (_unit == _xUnit) exitWith {_turretPath = _xTurretPath}; diff --git a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf index cf17d8b873..08d6369ed6 100644 --- a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Nic547, commy2 * Restart the surrendering animation if it got interrupted. Called from a AnimChanged EH. @@ -6,15 +7,15 @@ * 0: The Unit * 1: New animation * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, "movearm"] call ACE_captives_fnc_handleAnimChangedSurrendered + * * Public: No */ - -#include "script_component.hpp" - params ["_unit", "_newAnimation"]; TRACE_2("AnimChanged",_unit,_newAnimation); diff --git a/addons/captives/functions/fnc_handleGetIn.sqf b/addons/captives/functions/fnc_handleGetIn.sqf index d89049a031..96a32031af 100644 --- a/addons/captives/functions/fnc_handleGetIn.sqf +++ b/addons/captives/functions/fnc_handleGetIn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handles when a unit gets in to a vehicle. Release escorted captive when entering a vehicle @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "","_unit"]; TRACE_2("params",_vehicle,_unit); @@ -31,7 +31,7 @@ if (local _unit) then { if (_unit getVariable [QGVAR(isHandcuffed), false]) then { //Need to force animation for FFV turrets - _turretPath = []; + private _turretPath = []; { _x params ["_xUnit", "", "", "_xTurretPath"]; if (_unit == _xUnit) exitWith {_turretPath = _xTurretPath}; diff --git a/addons/captives/functions/fnc_handleGetOut.sqf b/addons/captives/functions/fnc_handleGetOut.sqf index 7ec510dbf1..7f5de6f330 100644 --- a/addons/captives/functions/fnc_handleGetOut.sqf +++ b/addons/captives/functions/fnc_handleGetOut.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handles when a captive unit gets out of a vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "", "_unit"]; TRACE_2("params",_vehicle,_unit); diff --git a/addons/captives/functions/fnc_handleKilled.sqf b/addons/captives/functions/fnc_handleKilled.sqf new file mode 100644 index 0000000000..39158ae662 --- /dev/null +++ b/addons/captives/functions/fnc_handleKilled.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: Jonpas + * Called when a unit dies. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [bob] call ace_captives_fnc_handleKilled + * + * Public: No + */ + +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_handleLocal.sqf b/addons/captives/functions/fnc_handleLocal.sqf index 693eb844fd..be92b1c7dc 100644 --- a/addons/captives/functions/fnc_handleLocal.sqf +++ b/addons/captives/functions/fnc_handleLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Called when a unit switched locality @@ -6,15 +7,15 @@ * 0: The Unit * 1: Is local * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, true] call ACE_captives_fnc_handleLocal + * * Public: No */ - -#include "script_component.hpp" - params ["_unit", "_local"]; // Make sure that if the unit is captive or surrendered it has a AnimChanged EH running ONLY on the machine that owns it @@ -26,7 +27,7 @@ if (_local) then { if (_unit getVariable [QGVAR(handcuffAnimEHID), -1] != -1) exitWith {}; // Otherwise, restart the AnimChanged EH in the new machine - private _animChangedEHID = _unit addEventHandler ["AnimChanged", DFUNC(handleAnimChangedHandcuffed)]; + private _animChangedEHID = _unit addEventHandler ["AnimChanged", {call FUNC(handleAnimChangedHandcuffed)}]; TRACE_2("Adding animChangedEH",_unit,_animChangedEHID); _unit setVariable [QGVAR(handcuffAnimEHID), _animChangedEHID]; }; @@ -37,7 +38,7 @@ if (_local) then { if (_unit getVariable [QGVAR(surrenderAnimEHID), -1] != -1) exitWith {}; // Otherwise, restart the AnimChanged EH in the new machine - private _animChangedEHID = _unit addEventHandler ["AnimChanged", DFUNC(handleAnimChangedSurrendered)]; + private _animChangedEHID = _unit addEventHandler ["AnimChanged", {call FUNC(handleAnimChangedSurrendered)}]; TRACE_2("Adding animChangedEH",_unit,_animChangedEHID); _unit setVariable [QGVAR(surrenderAnimEHID), _animChangedEHID]; }; diff --git a/addons/captives/functions/fnc_handleOnUnconscious.sqf b/addons/captives/functions/fnc_handleOnUnconscious.sqf index 456161d9de..745b651a0d 100644 --- a/addons/captives/functions/fnc_handleOnUnconscious.sqf +++ b/addons/captives/functions/fnc_handleOnUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, PabstMirror * Handles the "ace_unconscious" event @@ -7,14 +8,13 @@ * 0: Is Unconsisisiouses * * Return Value: - * Nothing + * None * * Example: * [bob, true] call ACE_captives_fnc_handleOnUnconscious * * Public: No */ -#include "script_component.hpp" params ["_unit","_isUnconc"]; diff --git a/addons/captives/functions/fnc_handlePlayerChanged.sqf b/addons/captives/functions/fnc_handlePlayerChanged.sqf index 3ff0e00752..c6adce4f84 100644 --- a/addons/captives/functions/fnc_handlePlayerChanged.sqf +++ b/addons/captives/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handles playerChanged. Resets "showHUD" based on handcuff status @@ -14,14 +15,13 @@ * * Public: No */ -#include "script_component.hpp" params ["_newUnit","_oldUnit"]; //set showHUD based on new unit status: if ((_newUnit getVariable [QGVAR(isHandcuffed), false]) || {_newUnit getVariable [QGVAR(isSurrendering), false]}) then { TRACE_1("Player Change (showHUD false)",_newUnit); - ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); + ["captive", [false, false, false, false, false, false, false, false, false, true]] call EFUNC(common,showHud); } else { TRACE_1("Player Change (showHUD true)",_newUnit); ["captive", []] call EFUNC(common,showHud); //same as showHud true; diff --git a/addons/captives/functions/fnc_handleRespawn.sqf b/addons/captives/functions/fnc_handleRespawn.sqf index b95438fa22..3643eb4393 100644 --- a/addons/captives/functions/fnc_handleRespawn.sqf +++ b/addons/captives/functions/fnc_handleRespawn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 PabstMirror * Fix, because captiveNum doesn't reset properly on respawn @@ -7,16 +8,16 @@ * 1: Corpse * * Return Value: - * Nothing + * None * * Example: * [alive, body] call ACE_captives_fnc_handleRespawn; * * Public: No */ -#include "script_component.hpp" params ["_unit","_dead"]; +TRACE_2("handleRespawn",_unit,_dead); if (!local _unit) exitWith {}; @@ -46,7 +47,7 @@ if (_respawn > 3) then { }; [_unit, "setCaptive", QGVAR(Surrendered), false] call EFUNC(common,statusEffect_set); - if (_oldUnit getVariable [QGVAR(isEscorting), false]) then { - _oldUnit setVariable [QGVAR(isEscorting), false, true]; + if (_unit getVariable [QGVAR(isEscorting), false]) then { + _unit setVariable [QGVAR(isEscorting), false, true]; }; }; diff --git a/addons/captives/functions/fnc_handleUnitInitPost.sqf b/addons/captives/functions/fnc_handleUnitInitPost.sqf index 52957acd68..2f189e2ffb 100644 --- a/addons/captives/functions/fnc_handleUnitInitPost.sqf +++ b/addons/captives/functions/fnc_handleUnitInitPost.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * handle captive and unconsciousness state and prevent grenades @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf b/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf index 433c1fc259..df78c9773f 100644 --- a/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf +++ b/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles ZeusDisplayChanged event @@ -8,18 +9,17 @@ * 1: Display is now open * * Return Value: - * Nothing + * None * * Example: * [bob1, false] call ACE_captives_fnc_handleZeusDisplayChanged * * Public: No */ -#include "script_component.hpp" if ((ACE_player getVariable [QGVAR(isHandcuffed), false]) || {ACE_player getVariable [QGVAR(isSurrendering), false]}) then { TRACE_1("Player Change (showHUD false)",ACE_player); - ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); + ["captive", [false, false, false, false, false, false, false, false, false, true]] call EFUNC(common,showHud); } else { TRACE_1("Player Change (showHUD true)",ACE_player); ["captive", []] call EFUNC(common,showHud); //same as showHud true; diff --git a/addons/captives/functions/fnc_moduleHandcuffed.sqf b/addons/captives/functions/fnc_moduleHandcuffed.sqf index b2e0b431b3..1cd50dd4ce 100644 --- a/addons/captives/functions/fnc_moduleHandcuffed.sqf +++ b/addons/captives/functions/fnc_moduleHandcuffed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Module Function to make a unit handcuffed (can be called from editor) @@ -9,14 +10,13 @@ * 2: Activated * * Return Value: - * Nothing + * None * * Example: * [objNull, [player], true] call ace_captives_fnc_moduleHandcuffed * * Public: No */ -#include "script_component.hpp" params ["_logic", "_units", "_activated"]; diff --git a/addons/captives/functions/fnc_moduleSettings.sqf b/addons/captives/functions/fnc_moduleSettings.sqf index fc8c76721f..d31a57a43d 100644 --- a/addons/captives/functions/fnc_moduleSettings.sqf +++ b/addons/captives/functions/fnc_moduleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Module for captivity settings @@ -8,13 +9,15 @@ * Return Value: * None * + * Example: + * [LOGIC] call ace_captives_fnc_moduleSettings + * * Public: No */ -#include "script_component.hpp" - 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/functions/fnc_moduleSurrender.sqf b/addons/captives/functions/fnc_moduleSurrender.sqf index c4482ce904..ab31ea6bc9 100644 --- a/addons/captives/functions/fnc_moduleSurrender.sqf +++ b/addons/captives/functions/fnc_moduleSurrender.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Module Function to make a unit surrender (can be called from editor) @@ -9,14 +10,13 @@ * 2: Activated * * Return Value: - * Nothing + * None * * Example: * [objNull, [player], true] call ace_captives_fnc_moduleSurrender * * Public: No */ -#include "script_component.hpp" params ["_logic", "_units", "_activated"]; diff --git a/addons/captives/functions/fnc_setHandcuffed.sqf b/addons/captives/functions/fnc_setHandcuffed.sqf index 1859bfb0b1..5e0b634544 100644 --- a/addons/captives/functions/fnc_setHandcuffed.sqf +++ b/addons/captives/functions/fnc_setHandcuffed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Nic547, commy2 * Handcuffs a unit. @@ -7,20 +8,19 @@ * 1: True to take captive, false to release captive * * Return Value: - * Nothing + * None * * Example: * [bob, true] call ACE_captives_fnc_setHandcuffed; * * Public: No */ -#include "script_component.hpp" params ["_unit","_state"]; TRACE_2("params",_unit,_state); if (!local _unit) exitWith { - ERROR("running setHandcuffed on remote unit"); + WARNING("running setHandcuffed on remote unit"); }; if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith { @@ -35,7 +35,7 @@ if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith { }; if ((_unit getVariable [QGVAR(isHandcuffed), false]) isEqualTo _state) exitWith { - ERROR("setHandcuffed: current state same as new"); + WARNING("setHandcuffed: current state same as new"); }; if (_state) then { @@ -50,7 +50,7 @@ if (_state) then { _unit setVariable [QGVAR(CargoIndex), ((vehicle _unit) getCargoIndex _unit), true]; if (_unit == ACE_player) then { - ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); + ["captive", [false, false, false, false, false, false, false, false, false, true]] call EFUNC(common,showHud); }; // fix anim on mission start (should work on dedicated servers) @@ -73,7 +73,7 @@ if (_state) then { TRACE_1("removing animChanged EH",_animChangedEHID); _unit removeEventHandler ["AnimChanged", _animChangedEHID]; }; - _animChangedEHID = _unit addEventHandler ["AnimChanged", DFUNC(handleAnimChangedHandcuffed)]; + _animChangedEHID = _unit addEventHandler ["AnimChanged", {call FUNC(handleAnimChangedHandcuffed)}]; TRACE_2("Adding animChangedEH",_unit,_animChangedEHID); _unit setVariable [QGVAR(handcuffAnimEHID), _animChangedEHID]; diff --git a/addons/captives/functions/fnc_setSurrendered.sqf b/addons/captives/functions/fnc_setSurrendered.sqf index 6acd3436aa..a9b4ef85a7 100644 --- a/addons/captives/functions/fnc_setSurrendered.sqf +++ b/addons/captives/functions/fnc_setSurrendered.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 PabstMirror * Lets a unit surrender @@ -7,20 +8,19 @@ * 1: True to surrender, false to un-surrender * * Return Value: - * Nothing + * None * * Example: * [Pierre, true] call ACE_captives_fnc_setSurrendered; * * Public: No */ -#include "script_component.hpp" params ["_unit","_state"]; TRACE_2("params",_unit,_state); if (!local _unit) exitWith { - ERROR("running surrender on remote unit"); + WARNING("running surrender on remote unit"); }; if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith { @@ -35,19 +35,19 @@ if !(missionNamespace getVariable [QGVAR(captivityEnabled), false]) exitWith { }; if ((_unit getVariable [QGVAR(isSurrendering), false]) isEqualTo _state) exitWith { - ERROR("Surrender: current state same as new"); + WARNING("Surrender: current state same as new"); }; if (_state) then { - if ((vehicle _unit) != _unit) exitWith {ERROR("Cannot surrender while mounted");}; - if (_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {ERROR("Cannot surrender while handcuffed");}; + if ((vehicle _unit) != _unit) exitWith {WARNING("Cannot surrender while mounted");}; + if (_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {WARNING("Cannot surrender while handcuffed");}; _unit setVariable [QGVAR(isSurrendering), true, true]; [_unit, "setCaptive", QGVAR(Surrendered), true] call EFUNC(common,statusEffect_set); if (_unit == ACE_player) then { - ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); + ["captive", [false, false, false, false, false, false, false, false, false, true]] call EFUNC(common,showHud); }; [_unit] call EFUNC(common,fixLoweredRifleAnimation); @@ -64,7 +64,7 @@ if (_state) then { TRACE_1("removing animChanged EH",_animChangedEHID); _unit removeEventHandler ["AnimChanged", _animChangedEHID]; }; - _animChangedEHID = _unit addEventHandler ["AnimChanged", DFUNC(handleAnimChangedSurrendered)]; + _animChangedEHID = _unit addEventHandler ["AnimChanged", {call FUNC(handleAnimChangedSurrendered)}]; _unit setVariable [QGVAR(surrenderAnimEHID), _animChangedEHID]; }; }, [_unit], 0.01] call CBA_fnc_waitAndExecute; diff --git a/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf b/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf index dbd3e0af5c..6089625961 100644 --- a/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf +++ b/addons/captives/functions/fnc_vehicleCaptiveMoveIn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Loads a captive into a vehicle @@ -7,22 +8,21 @@ * 1: The Vehicle * * Return Value: - * Nothing + * None * * Example: * [bob, car1] call ACE_captives_fnc_vehicleCaptiveMoveIn; * * Public: No */ -#include "script_component.hpp" params ["_target","_vehicle"]; TRACE_2("params",_target,_vehicle); -_getSeat = [_vehicle] call FUNC(findEmptyNonFFVCargoSeat); +private _getSeat = [_vehicle] call FUNC(findEmptyNonFFVCargoSeat); TRACE_1("free cargo seat",_getSeat); _getSeat params ["_cargoIndex"]; -if (_cargoIndex == -1) exitWith {ERROR("cargo index -1");}; +if (_cargoIndex == -1) exitWith {WARNING("cargo index -1");}; _target moveInCargo [_vehicle, _cargoIndex]; _target assignAsCargoIndex [_vehicle, _cargoIndex]; diff --git a/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf b/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf index ce44b5926f..f26ff45370 100644 --- a/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf +++ b/addons/captives/functions/fnc_vehicleCaptiveMoveOut.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Unloads a captive from a vehicle. @@ -6,14 +7,13 @@ * 0: Captive Unit being unloaded * * Return Value: - * Nothing + * None * * Example: * [bob] call ACE_captives_fnc_vehicleCaptiveMoveOut; * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); diff --git a/addons/captives/script_component.hpp b/addons/captives/script_component.hpp index 415ca8f4fd..c0cbefe5b2 100644 --- a/addons/captives/script_component.hpp +++ b/addons/captives/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_CAPTIVES diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index fbb3d11541..eb11930bcd 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -1,6 +1,15 @@ - + + + Captives + Gefangene + Prigionieri + 俘虜 + 俘虏 + 捕虜 + 포로설정 + Take Prisoner Gefangen nehmen @@ -12,6 +21,10 @@ Tomar Prisioneiro Foglyul ejtés Взять в плен + 捕虜にする + 포박하기 + 逮捕俘虜 + 逮捕俘虏 Free Prisoner @@ -24,6 +37,10 @@ Libertar Prisioneiro Fogoly szabadon engedése Освободить пленника + 捕虜を解放する + 풀어주기 + 釋放俘虜 + 释放俘虏 Escort Prisoner @@ -36,6 +53,10 @@ Escoltar Prisioneiro Fogoly kísérése Конвоировать пленника + 捕虜を移動させる + 포로 호송하기 + 護送俘虜 + 护送俘虏 Release Prisoner @@ -48,6 +69,10 @@ Largar Prisioneiro Fogoly elengedése Прекратить конвоирование + 捕虜を解放する + 포로 풀어주기 + 停止護送俘虜 + 停止护送俘虏 You need to take him as prisoner first! @@ -60,6 +85,10 @@ Você deve tomá-lo como prisioneiro primeiro! Először foglyul kell ejtened őt! Вы должны сначала взять его в плен! + 捕虜を取っている必要があります! + 먼저 포로로 만들어야합니다! + 你必須先逮捕他! + 你必须先逮捕他! Load Captive @@ -72,6 +101,10 @@ Загрузить пленного Embarcar Prisioneiro Fai salire il prigioniero + 捕虜を乗せる + 포로 태우기 + 將俘虜放入載具 + 将俘虏放入载具 Unload Captive @@ -84,6 +117,10 @@ Выгрузить пленного Desembarcar Prisioneiro Fai scendere il prigioniero + 捕虜を降ろす + 포로 내리기 + 將俘虜帶出載具 + 将俘虏带出载具 Cable Tie @@ -96,6 +133,10 @@ Fascietta Gyorskötöző Кабельная стяжка + ケーブル タイ + 케이블 타이 + 束線帶 + 束线带 Cable ties that allow you to restrain prisoners. @@ -108,6 +149,10 @@ Fascetta per arrestare i prigionieri Gyorskötöző, emberek foglyulejtéséhez használható. Кабельные стяжки позволяют связывать пленников. + ケーブル タイは捕虜を制圧できます。 + 케이블 타이는 포로를 구류시킬때 씁니다. + 束線帶可以綁住俘虜 + 束线带可以绑住俘虏 Inventory of frisked person @@ -120,6 +165,10 @@ Инвентарь обысканного человека Inventário da pessoa revistada Inventario della persona perquisita + 捕虜の持ち物を確認する + 검문당한 사람의 소지품 + 搜身選單 + 搜身选单 Frisk person @@ -132,6 +181,10 @@ Обыскать человека Revistar Perquisisci la persona + 捕虜の持ち物 + 검문당한사람 + 搜身 + 搜身 Surrender @@ -144,6 +197,10 @@ Сдаться Megadás Arrenditi + 投降 + 투항 + 投降 + 投降 Stop Surrendering @@ -156,6 +213,10 @@ Прекратить сдачу в плен Megadás abbahagyása Smetti di arrenderti + 投降をやめる + 투항하는것을 멈춤 + 停止投降 + 停止投降 Make Unit Surrender @@ -168,6 +229,10 @@ Egység kapitulálása Заставить юнита сдаться Fai arrendere l'unità + ユニットを投降させる + 투항시키기 + 使單位投降 + 使单位投降 Sync a unit to make them surrender. @@ -180,6 +245,10 @@ Egység szinkronizálása, hogy kapituláljon. Синхронизируйте с юнитами, чтобы заставить их сдаться в плен. Sincronizza una unità per farla arrendere. + 同期されたユニットを投降させます。 + 투항시키기 위해 동기화합니다. + 同步此模塊到一個單位,使該單位投降 + 同步此模块到一个单位,使该单位投降 Make Unit Handcuffed @@ -191,10 +260,14 @@ Metti manette all'unità 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. Синхронизируйте с юнитами, чтобы сделать их связанными. @@ -202,6 +275,10 @@ Sincronizza un'unità per metterle le manette. Sincroniza una unidad para hacer que esté esposada. Synchronisez une unité pour la rendre captive. + 同期されたユニットを拘束させます。 + 수갑을 채우기 위해 동기화합니다. + 使單位戴上手銬 + 使单位戴上手铐 Captives Settings @@ -214,6 +291,10 @@ Fogoly-beállítások Настройки пленения Impostazioni Prigionieri + 拘束の設定 + 포박 설정 + 俘虜設定 + 俘虏设定 Controls settings for surrender and cable ties @@ -226,6 +307,10 @@ Szabályozza a kapituláció és bilincselés beállításait Управляет настройками сдачи в плен и связывания Controlla le impostazioni per la resa e le manette + 投降したユニットや拘束されたユニットの扱いを設定します。 + 투항과 케이블 타이에 관련한 설정 + 定義投降與束帶等設定 + 定义投降与束带等设定 Can handcuff own side @@ -238,18 +323,26 @@ Saját oldal megbilincselhető Связать союзника Puoi ammanettare unità alleate + 拘束ユニットを自陣営へ + 자기편을 포박 할 수 있습니다. + 可以銬住同陣營隊友 + 可以铐住同阵营队友 Can players cabletie units on their own side 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 + プレイヤーが拘束したユニットの陣営を自陣営に変更させます。 + 자기편에게 케이블타이를 사용할 수 있게합니다 + 玩家可以使用束線帶銬住同陣營隊友 + 玩家可以使用束线带铐住同阵营队友 Allow surrendering @@ -262,6 +355,10 @@ Kapituláció engedélyezése Сдаться в плен Permetti Resa + 投降を許可 + 투항 활성화 + 允許投降 + 允许投降 Players can surrender after holstering their weapon @@ -274,6 +371,10 @@ 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 + プレイヤーは武器を収めたあと投降できるようにします。 + 비무장한 플레이어가 투항할 수 있게 합니다 + 玩家能在收起自己武器後投降 + 玩家能在收起自己武器后投降 Require surrendering @@ -285,6 +386,10 @@ Vzdávání vyžadováno Richiedi Resa Requiert la reddition + 投降を必要とする + 투항 필요 + 要求目標投降 + 要求目标投降 Require Players to surrender before they can be arrested @@ -296,6 +401,10 @@ Vyžaduje, aby se hráč nejdříve vzdal, poté může být spoután 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 @@ -307,6 +416,10 @@ Pouze vzdávání Solo Resa Reddition seulement + 投降中のみ + 투항 중에만 + 只能在投降狀態 + 只能在投降状态 Surrendering or No weapon @@ -318,6 +431,37 @@ Vzdávání nebo beze zbraně Resa o senza armi Capitulation ou desarmé + 投降中か非武装時 + 투항 중 혹은 비무장 + 投降或無武器狀態 + 投降或无武器状态 + + + 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 574000155e..fb039373a5 100644 --- a/addons/cargo/ACE_Settings.hpp +++ b/addons/cargo/ACE_Settings.hpp @@ -1,9 +1,8 @@ class ACE_Settings { class GVAR(enable) { - displayName = CSTRING(ModuleSettings_enable); - description = CSTRING(ModuleSettings_enable_Description); - typeName = "BOOL"; - value = 1; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; + }; + class GVAR(paradropTimeCoefficent) { + movedToSQF = 1; }; }; diff --git a/addons/cargo/CfgEden.hpp b/addons/cargo/CfgEden.hpp new file mode 100644 index 0000000000..9144ba458b --- /dev/null +++ b/addons/cargo/CfgEden.hpp @@ -0,0 +1,37 @@ +class Cfg3DEN { + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class GVAR(space) { + displayName = CSTRING(space_edenName); + tooltip = CSTRING(space_edenDesc); + property = QGVAR(space); + control = "Edit"; + + expression = QUOTE([ARR_2(_this,_value)] call DFUNC(setSpace);); + defaultValue = QUOTE(GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(space),0)); + + validate = "number"; + condition = "objectHasInventoryCargo"; + typeName = "NUMBER"; + }; + class GVAR(size) { + displayName = CSTRING(size_edenName); + tooltip = CSTRING(size_edenDesc); + property = QGVAR(size); + control = "Edit"; + + // Expression only runs on the server, must handle actions for all machines and future JIPs (Why BI?!) + expression = QUOTE([ARR_2(_this,_value)] call DFUNC(setSize);); + defaultValue = QUOTE(GET_NUMBER(configFile >> 'CfgVehicles' >> typeOf _this >> QQGVAR(size),-1)); + + validate = "number"; + condition = "1-objectBrain"; + typeName = "NUMBER"; + }; + }; + }; + }; + }; +}; diff --git a/addons/cargo/CfgEventHandlers.hpp b/addons/cargo/CfgEventHandlers.hpp index 45f6d48997..823dc87470 100644 --- a/addons/cargo/CfgEventHandlers.hpp +++ b/addons/cargo/CfgEventHandlers.hpp @@ -24,52 +24,3 @@ class Extended_Killed_EventHandlers { }; }; }; - -//Need initPost or we have problems with setVariable with 'ACE_Cargo' -class Extended_InitPost_EventHandlers { - class ThingX { - class ADDON { - init = QUOTE(_this call DFUNC(initObject); _this call DFUNC(initVehicle)); - }; - }; - class Land_PaperBox_closed_F { - class ADDON { - init = QUOTE(_this call DFUNC(initObject); _this call DFUNC(initVehicle)); - }; - }; - class PlasticCase_01_base_F { - class ADDON { - init = QUOTE(_this call DFUNC(initObject); _this call DFUNC(initVehicle)); - }; - }; - class LandVehicle { - class ADDON { - init = QUOTE(_this call DFUNC(initVehicle)); - }; - }; - class Air { - class ADDON { - init = QUOTE(_this call DFUNC(initVehicle)); - }; - }; - class Ship_F { - class ADDON { - init = QUOTE(_this call DFUNC(initVehicle)); - }; - }; - class ACE_ConcertinaWireCoil { - class ADDON { - init = QUOTE(_this call DFUNC(initObject)); - }; - }; - class Land_PortableLight_single_F { - class ADDON { - init = QUOTE(_this call DFUNC(initObject)); - }; - }; - class StaticWeapon { - class ADDON { - init = QUOTE(_this call DFUNC(initObject)); - }; - }; -}; diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index 9d4c34182f..d3a800040e 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"; @@ -26,6 +26,12 @@ class CfgVehicles { typeName = "BOOL"; defaultValue = 1; }; + class paradropTimeCoefficent { + displayName = CSTRING(paradropTimeCoefficent); + description = CSTRING(paradropTimeCoefficent_description); + typeName = "SCALAR"; + defaultValue = 2.5; + }; }; class ModuleDescription { @@ -33,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; @@ -194,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; @@ -259,12 +247,17 @@ class CfgVehicles { GVAR(space) = 4; }; - // jets + // planes (off by default as most are attack jets) class Plane: Air { GVAR(space) = 0; GVAR(hasCargo) = 0; }; + class Plane_Base_F: Plane {}; + class Plane_Civil_01_base_F: Plane_Base_F { // Tanoa Civilian Prop Plane + GVAR(space) = 2; + GVAR(hasCargo) = 1; + }; class VTOL_Base_F; class VTOL_01_base_F: VTOL_Base_F { GVAR(space) = 4; @@ -274,12 +267,20 @@ class CfgVehicles { GVAR(space) = 4; 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; @@ -316,26 +317,6 @@ class CfgVehicles { GVAR(canLoad) = 1; }; - // Taru pods - class Pod_Heli_Transport_04_base_F; - class Land_Pod_Heli_Transport_04_ammo_F: Pod_Heli_Transport_04_base_F { - GVAR(space) = 8; - GVAR(hasCargo) = 1; - }; - class Land_Pod_Heli_Transport_04_box_F: Pod_Heli_Transport_04_base_F { - GVAR(space) = 20; - GVAR(hasCargo) = 1; - }; - class Land_Pod_Heli_Transport_04_repair_F: Pod_Heli_Transport_04_base_F { - GVAR(space) = 12; - GVAR(hasCargo) = 1; - }; - class Pod_Heli_Transport_04_crewed_base_F; - class Land_Pod_Heli_Transport_04_medevac_F: Pod_Heli_Transport_04_crewed_base_F { - GVAR(space) = 8; - GVAR(hasCargo) = 1; - }; - class StaticMortar; class Mortar_01_base_F: StaticMortar { GVAR(size) = 2; // 1 = small, 2 = large @@ -349,6 +330,9 @@ class CfgVehicles { GVAR(size) = 2; // 1 = small, 2 = large GVAR(canLoad) = 1; }; + class Land_RepairDepot_01_base_F: ReammoBox_F { // TanksDLC - Repair Depo Thing (probably too big to safely unload) + GVAR(canLoad) = 0; + }; //"Supply Box" - Small Pallets class B_supplyCrate_F: ReammoBox_F { GVAR(size) = 6; @@ -364,8 +348,57 @@ class CfgVehicles { class CargoNet_01_base_F: Slingload_base_F { //Slingload pallets GVAR(size) = 6; }; - class Slingload_01_Base_F: Slingload_base_F { //Huron 20ft containers + + //Huron 20ft containers + class Slingload_01_Base_F: Slingload_base_F { GVAR(canLoad) = 0; + GVAR(size) = -1; + }; + class B_Slingload_01_Cargo_F: Slingload_01_Base_F { // Huron Cargo + GVAR(space) = 20; + GVAR(hasCargo) = 1; + }; + class B_Slingload_01_Ammo_F: Slingload_01_Base_F { // Huron Ammo + GVAR(space) = 8; + GVAR(hasCargo) = 1; + }; + class B_Slingload_01_Medevac_F: Slingload_01_Base_F { // Huron Medevac + GVAR(space) = 8; + GVAR(hasCargo) = 1; + }; + class B_Slingload_01_Repair_F: Slingload_01_Base_F { // Huron Repair + GVAR(space) = 12; + GVAR(hasCargo) = 1; + }; + + // Taru pods + class Pod_Heli_Transport_04_base_F: Slingload_base_F { + GVAR(canLoad) = 0; + GVAR(size) = -1; + }; + class Land_Pod_Heli_Transport_04_ammo_F: Pod_Heli_Transport_04_base_F { + GVAR(space) = 8; + GVAR(hasCargo) = 1; + }; + class Land_Pod_Heli_Transport_04_box_F: Pod_Heli_Transport_04_base_F { + GVAR(space) = 20; + GVAR(hasCargo) = 1; + }; + class Land_Pod_Heli_Transport_04_repair_F: Pod_Heli_Transport_04_base_F { + GVAR(space) = 12; + GVAR(hasCargo) = 1; + }; + class Pod_Heli_Transport_04_crewed_base_F: StaticWeapon { + GVAR(canLoad) = 0; + GVAR(size) = -1; + }; + class Land_Pod_Heli_Transport_04_covered_F: Pod_Heli_Transport_04_crewed_base_F { + GVAR(space) = 8; + GVAR(hasCargo) = 1; + }; + class Land_Pod_Heli_Transport_04_medevac_F: Pod_Heli_Transport_04_crewed_base_F { + GVAR(space) = 8; + GVAR(hasCargo) = 1; }; //Plastic and metal case @@ -384,6 +417,12 @@ 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 RoadCone_F: ThingX { GVAR(size) = 1; @@ -393,6 +432,22 @@ class CfgVehicles { GVAR(size) = 2; }; + class Lamps_base_F; + class Land_PortableLight_single_F: Lamps_base_F { + GVAR(size) = 2; + GVAR(canLoad) = 1; + }; + class FloatingStructure_F; + class Land_Camping_Light_F: FloatingStructure_F { + GVAR(size) = 0.2; + GVAR(canLoad) = 1; + }; + class Land_Camping_Light_off_F: ThingX { + GVAR(size) = 0.2; + GVAR(canLoad) = 1; + }; + + class Scrapyard_base_F; class Land_PaperBox_closed_F: Scrapyard_base_F { class EventHandlers { @@ -528,16 +583,6 @@ class CfgVehicles { GVAR(size) = 50; }; - class Ruins_F; - class Land_Cargo20_military_ruins_F: Ruins_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(space) = 49; - GVAR(size) = 50; - }; - class Land_Cargo20_orange_F: Cargo_base_F { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; @@ -644,15 +689,6 @@ class CfgVehicles { GVAR(size) = 100; }; - class Land_Cargo40_military_ruins_F: Ruins_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(space) = 99; - GVAR(size) = 100; - }; - class Land_Cargo40_orange_F: Cargo_base_F { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; @@ -702,7 +738,7 @@ class CfgVehicles { GVAR(size) = 100; }; - // small + // Small class Land_CargoBox_V1_F: ThingX { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; @@ -723,10 +759,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 8224ec0029..154956c74a 100644 --- a/addons/cargo/XEH_PREP.hpp +++ b/addons/cargo/XEH_PREP.hpp @@ -1,20 +1,19 @@ - PREP(addCargoItem); -PREP(canLoad); +PREP(addCargoVehiclesActions); PREP(canLoadItemIn); PREP(canUnloadItem); -PREP(findNearestVehicle); PREP(getCargoSpaceLeft); PREP(getSizeItem); 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); PREP(startUnload); PREP(unloadItem); diff --git a/addons/cargo/XEH_postInit.sqf b/addons/cargo/XEH_postInit.sqf index 6b7320d5ae..829991ee87 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -50,4 +50,102 @@ _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 +[QGVAR(initObject), DFUNC(initObject)] call CBA_fnc_addEventHandler; +[QGVAR(initVehicle), DFUNC(initVehicle)] call CBA_fnc_addEventHandler; + + +GVAR(vehicleAction) = [ + QGVAR(openMenu), localize LSTRING(openMenu), "", + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + GVAR(interactionVehicle) = _target; + GVAR(interactionParadrop) = false; + createDialog QGVAR(menu); + }, + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + 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)} + } +] call EFUNC(interact_menu,createAction); + +GVAR(objectAction) = [ + QGVAR(load), localize LSTRING(loadObject), "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa", + { + params ["_target", "_player"]; + [_player, _target] call FUNC(startLoadIn); + }, + { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + GVAR(enable) && + {(_target getVariable [QGVAR(canLoad), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(canLoad))]) in [true, 1]} && + {locked _target < 2} && + {alive _target} && + {[_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} && + {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} + } count (nearestObjects [_player, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)])} + }, + LINKFUNC(addCargoVehiclesActions) +] call EFUNC(interact_menu,createAction); + + +private _initVehicleClasses = ["ThingX", "LandVehicle", "Air", "Ship_F"]; +private _initObjectClasses = ["ThingX", "StaticWeapon"]; +{ + [_x, "initPost", DFUNC(initVehicle), nil, nil, true] call CBA_fnc_addClassEventHandler; +} forEach _initVehicleClasses; +{ + [_x, "initPost", DFUNC(initObject), nil, nil, true] call CBA_fnc_addClassEventHandler; +} forEach _initObjectClasses; + +// find all remaining configured classes and init them +{ + private _class = configName _x; + // init vehicle + if ( + 1 == getNumber (_x >> QGVAR(hasCargo)) + && {{if (_class isKindOf _x) exitWith {false}; true} forEach _initVehicleClasses} + ) then { + if (_class isKindOf "Static") then { + if (2 == getNumber (_x >> "scope")) then { + [_class, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToClass); + GVAR(initializedVehicleClasses) pushBack _class; + }; + } else { + [_class, "initPost", DFUNC(initVehicle), nil, nil, true] call CBA_fnc_addClassEventHandler; + _initVehicleClasses pushBack _class; + }; + }; + // init object + if ( + 1 == getNumber (_x >> QGVAR(canLoad)) + && {{if (_class isKindOf _x) exitWith {false}; true} forEach _initObjectClasses} + ) then { + if (_class isKindOf "Static") then { + if (2 == getNumber (_x >> "scope")) then { + [_class, 0, ["ACE_MainActions"], GVAR(objectAction)] call EFUNC(interact_menu,addActionToClass); + GVAR(initializedItemClasses) pushBack _class; + }; + } else { + [_class, "initPost", DFUNC(initObject), nil, nil, true] call CBA_fnc_addClassEventHandler; + _initObjectClasses pushBack _class; + }; + }; +} forEach ("true" configClasses (configFile >> "CfgVehicles")); diff --git a/addons/cargo/XEH_preInit.sqf b/addons/cargo/XEH_preInit.sqf index a24ce048b5..3d7ac380c2 100644 --- a/addons/cargo/XEH_preInit.sqf +++ b/addons/cargo/XEH_preInit.sqf @@ -2,9 +2,14 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" GVAR(initializedItemClasses) = []; GVAR(initializedVehicleClasses) = []; +GVAR(cargoHolderTypes) = ["Car", "Air", "Tank", "Ship", "Cargo_base_F", "Land_PaperBox_closed_F"]; ADDON = true; diff --git a/addons/cargo/config.cpp b/addons/cargo/config.cpp index c368cab8d5..31f01ffd72 100644 --- a/addons/cargo/config.cpp +++ b/addons/cargo/config.cpp @@ -15,16 +15,7 @@ class CfgPatches { }; #include "ACE_Settings.hpp" +#include "CfgEden.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "menu.hpp" - -class ACE_newEvents { - LoadCargo = "ace_loadCargo"; - cargoUnloaded = "ace_cargoUnloaded"; - cargoLoaded = "ace_cargoLoaded"; - AddCargoByClass = "ace_addCargo"; - ServerUnloadCargo = QGVAR(serverUnload); - UnloadCargo = "ace_unloadCargo"; - cargoAddedByClass = "ace_cargoAdded"; -}; diff --git a/addons/cargo/functions/fnc_addCargoItem.sqf b/addons/cargo/functions/fnc_addCargoItem.sqf index 6e1b311098..8be00818c6 100644 --- a/addons/cargo/functions/fnc_addCargoItem.sqf +++ b/addons/cargo/functions/fnc_addCargoItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Jonpas * Adds a cargo item to the vehicle. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]]]; TRACE_3("params",_itemClass,_vehicle,_amount); diff --git a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf new file mode 100644 index 0000000000..ab362e63f4 --- /dev/null +++ b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Create actions for nearest vehicles with cargo. + * + * Arguments: + * 0: Target + * + * Return Value: + * Child actions + * + * Example: + * [cursorObject] call ace_cargo_fnc_addCargoVehiclesActions + * + * Public: No + */ + +params ["_target"]; + +private _statement = { + params ["_target", "_player", "_vehicle"]; + [_player, _target, _vehicle] call FUNC(startLoadIn); +}; + +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]; + (_hasCargoConfig || {_hasCargoPublic}) && {_x != _target} && + {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} +}; + +[_vehicles, _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/cargo/functions/fnc_canLoad.sqf b/addons/cargo/functions/fnc_canLoad.sqf deleted file mode 100644 index f576ea3e79..0000000000 --- a/addons/cargo/functions/fnc_canLoad.sqf +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Author: Glowbal - * Check if player can load an item into the nearest vehicle. - * - * Arguments: - * 0: Player - * 1: Object to load - * - * Return Value: - * Can load - * - * Example: - * [player, object] call ace_cargo_fnc_canLoad - * - * Public: No - */ -#include "script_component.hpp" - -params ["_player", "_object"]; -TRACE_2("params",_player,_object); - -if (!([_player, _object, []] call EFUNC(common,canInteractWith))) exitWith {false}; - -private _nearestVehicle = [_player] call FUNC(findNearestVehicle); - -if (_nearestVehicle isKindOf "Cargo_Base_F" || isNull _nearestVehicle) then { - { - if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_nearestVehicle = _x}; - } forEach (nearestObjects [_player, ["Cargo_base_F", "Land_PaperBox_closed_F"], MAX_LOAD_DISTANCE]); -}; - -if (isNull _nearestVehicle) exitWith {false}; - -if ((locked _nearestVehicle) >= 2) exitWith {false}; - -[_object, _nearestVehicle] call FUNC(canLoadItemIn) diff --git a/addons/cargo/functions/fnc_canLoadItemIn.sqf b/addons/cargo/functions/fnc_canLoadItemIn.sqf index e2bb1ecc4d..f7bc696d35 100644 --- a/addons/cargo/functions/fnc_canLoadItemIn.sqf +++ b/addons/cargo/functions/fnc_canLoadItemIn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if item can be loaded into other Object. @@ -5,6 +6,7 @@ * Arguments: * 0: Item * 1: Holder Object (Vehicle) + * 2: Ignore interaction distance and stability checks * * Return Value: * Can load in @@ -14,11 +16,15 @@ * * Public: No */ -#include "script_component.hpp" -params [["_item", "", [objNull,""]], "_vehicle"]; +params [["_item", "", [objNull,""]], "_vehicle", ["_ignoreInteraction", false]]; -if (speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}) exitWith {TRACE_1("vehicle not stable",_vehicle); false}; +if ((!_ignoreInteraction) && {speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}}) exitWith {TRACE_1("vehicle not stable",_vehicle); false}; + +if (_item isEqualType objNull && {{alive _x && {getText (configFile >> "CfgVehicles" >> typeOf _x >> "simulation") != "UAVPilot"}} count crew _item > 0}) exitWith { + TRACE_1("item is occupied",_item); + false +}; private _itemSize = [_item] call FUNC(getSizeItem); private _validItem = false; @@ -29,10 +35,11 @@ if (_item isEqualType "") then { } else { _validItem = (alive _item) && - {(_item distance _vehicle) <= MAX_LOAD_DISTANCE}; + {_ignoreInteraction || {([_item, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}}; }; _validItem && {_itemSize > 0} && {alive _vehicle} && -{_itemSize <= ([_vehicle] call FUNC(getCargoSpaceLeft))} +{_itemSize <= ([_vehicle] call FUNC(getCargoSpaceLeft))} && +{locked _vehicle < 2} diff --git a/addons/cargo/functions/fnc_canUnloadItem.sqf b/addons/cargo/functions/fnc_canUnloadItem.sqf index 1e8753cc27..311f3cb36d 100644 --- a/addons/cargo/functions/fnc_canUnloadItem.sqf +++ b/addons/cargo/functions/fnc_canUnloadItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, ViperMaul * Check if item can be unloaded. @@ -5,7 +6,7 @@ * Arguments: * 0: loaded Object * 1: Object - * 2: Unloader (player) + * 2: Unloader (player) (default: objNull) * * Return Value: * Can be unloaded @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_item", "_vehicle", ["_unloader", objNull]]; TRACE_2("params",_item,_vehicle); diff --git a/addons/cargo/functions/fnc_findNearestVehicle.sqf b/addons/cargo/functions/fnc_findNearestVehicle.sqf deleted file mode 100644 index 6d5b7ce1a8..0000000000 --- a/addons/cargo/functions/fnc_findNearestVehicle.sqf +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Author: Glowbal - * Get nearest vehicle from unit, priority: Car-Air-Tank-Ship. - * - * Arguments: - * 0: Unit - * - * Return Value: - * Vehicle in Distance - * - * Example: - * [unit] call ace_cargo_fnc_findNearestVehicle - * - * Public: No - */ -#include "script_component.hpp" - -params ["_unit"]; - -private _loadCar = nearestObject [_unit, "car"]; -if (_unit distance _loadCar <= MAX_LOAD_DISTANCE) exitWith {_loadCar}; - -private _loadHelicopter = nearestObject [_unit, "air"]; -if (_unit distance _loadHelicopter <= MAX_LOAD_DISTANCE) exitWith {_loadHelicopter}; - -private _loadTank = nearestObject [_unit, "tank"]; -if (_unit distance _loadTank <= MAX_LOAD_DISTANCE) exitWith {_loadTank}; - -private _loadShip = nearestObject [_unit, "ship"]; -if (_unit distance _loadShip <= MAX_LOAD_DISTANCE) exitWith {_loadShip}; - -private _loadContainer = nearestObject [_unit,"Cargo_base_F"]; -if (_unit distance _loadContainer <= MAX_LOAD_DISTANCE) exitWith {_loadContainer}; - -objNull diff --git a/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf b/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf index 7e8594ffe4..d9452d4b01 100644 --- a/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf +++ b/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the cargo space left on object. @@ -13,9 +14,8 @@ * * Public: No */ -#include "script_component.hpp" params ["_object"]; // TRACE_1("params",_object); -_object getVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeOf _object >> QGVAR(space))] +(_object getVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeOf _object >> QGVAR(space))]) max 0 diff --git a/addons/cargo/functions/fnc_getSizeItem.sqf b/addons/cargo/functions/fnc_getSizeItem.sqf index c53c05ee28..5d66e59b72 100644 --- a/addons/cargo/functions/fnc_getSizeItem.sqf +++ b/addons/cargo/functions/fnc_getSizeItem.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: Glowbal + * Author: Glowbal, SilentSpike * Get the cargo size of an object. * * Arguments: @@ -13,27 +14,16 @@ * * Public: No */ -#include "script_component.hpp" params ["_item"]; -scopeName "return"; - -private _isVirtual = (_item isEqualType ""); -private _itemClass = if (_isVirtual) then {_item} else {typeOf _item}; -private _config = (configFile >> "CfgVehicles" >> _itemClass >> QGVAR(size)); - -if (_isVirtual) then { - if (isNumber _config) then { - (getNumber _config) breakOut "return"; - }; +// Virtual items are much easier to deal with +if (_item isEqualType "") then { + CARGO_SIZE(_item) } else { - if (!isNil {_item getVariable QGVAR(size)}) then { - (_item getVariable QGVAR(size)) breakOut "return"; - }; - if (isNumber _config) then { - (getNumber _config) breakOut "return"; + if (isNil {_item getVariable QGVAR(size)}) then { + CARGO_SIZE(typeOf _item) + } else { + _item getVariable QGVAR(size) }; }; - --1 diff --git a/addons/cargo/functions/fnc_handleDestroyed.sqf b/addons/cargo/functions/fnc_handleDestroyed.sqf index 88b3cb9351..2818e71e07 100644 --- a/addons/cargo/functions/fnc_handleDestroyed.sqf +++ b/addons/cargo/functions/fnc_handleDestroyed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handle object being destroyed. Only runs on server. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; TRACE_1("params",_vehicle); diff --git a/addons/cargo/functions/fnc_initObject.sqf b/addons/cargo/functions/fnc_initObject.sqf index 92403b8dd9..611e3e6391 100644 --- a/addons/cargo/functions/fnc_initObject.sqf +++ b/addons/cargo/functions/fnc_initObject.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: Glowbal + * Author: Glowbal, SilentSpike * Initializes variables for loadable objects. Called from init EH. * * Arguments: @@ -13,34 +14,36 @@ * * Public: No */ -#include "script_component.hpp" params ["_object"]; private _type = typeOf _object; TRACE_2("params",_object,_type); -if ((_object getVariable [QGVAR(canLoad), getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(canLoad))]) != 1) exitWith {}; +// If object had size given to it via eden/public then override config canLoad setting +private _canLoadPublic = _object getVariable [QGVAR(canLoad), false]; +if (!(_canLoadPublic isEqualType false)) then { + WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_object,_type,QGVAR(canLoad),_canLoadPublic); +}; +private _canLoadConfig = getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(canLoad)) == 1; -// do nothing if the class is already initialized +// Nothing to do here if object can't be loaded +if !(_canLoadConfig || {_canLoadPublic in [true, 1]}) exitWith {}; + +// Servers and HCs do not require action menus (beyond this point) +if !(hasInterface) exitWith {}; + +// Unnecessary to add actions to an object class that's already got them if (_type in GVAR(initializedItemClasses)) exitWith {}; -GVAR(initializedItemClasses) pushBack _type; +if (_object getVariable [QGVAR(initObject),false]) exitWith {}; -TRACE_1("Adding load cargo action to class", _type); - -private _condition = { - GVAR(enable) && - {(_target getVariable [QGVAR(canLoad), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(canLoad))]) == 1} && - {locked _target < 2} && - {alive _target} && - {[_player, _target, []] call EFUNC(common,canInteractWith)} +// Objects given size via eden have their actions added to the object +// So this function may run for multiple of the same class in that case +if (_canLoadConfig) then { + GVAR(initializedItemClasses) pushBack _type; + TRACE_1("Adding load cargo action to class", _type); + [_type, 0, ["ACE_MainActions"], GVAR(objectAction)] call EFUNC(interact_menu,addActionToClass); +} else { + _object setVariable [QGVAR(initObject),true]; + TRACE_1("Adding load cargo action to object", _object); + [_object, 0, ["ACE_MainActions"], GVAR(objectAction)] call EFUNC(interact_menu,addActionToObject); }; -private _statement = { - params ["_target", "_player"]; - [_player, _target] call FUNC(startLoadIn); -}; -private _text = localize LSTRING(loadObject); -private _icon = QPATHTOF(UI\Icon_load.paa); - -private _action = [QGVAR(load), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction); -[_type, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToClass); - diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index c65a9bddbc..60f204cb75 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Initializes vehicle, adds open cargo menu action if available. @@ -13,15 +14,30 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; TRACE_1("params", _vehicle); private _type = typeOf _vehicle; -if (getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(hasCargo)) != 1) exitWith {}; +// If vehicle had space given to it via eden/public then override config hasCargo setting +private _hasCargoPublic = _vehicle getVariable [QGVAR(hasCargo), false]; +private _hasCargoConfig = getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(hasCargo)) == 1; +// Nothing to do here if vehicle has no cargo space +if !(_hasCargoConfig || _hasCargoPublic) exitWith {}; + +// Check if cargo is in cargo holder types (checked when trying to search for loadable objects) +private _addCargoType = true; +{ + if (_type isKindOf _x) exitWith {_addCargoType = false}; +} forEach GVAR(cargoHolderTypes); +TRACE_2("",_addCargoType,_type); +if (_addCargoType) then { + GVAR(cargoHolderTypes) pushBack _type; +}; + +// Vehicle can have default ace cargo in its config if (isServer) then { { if (isClass _x) then { @@ -33,32 +49,29 @@ if (isServer) then { } count ("true" configClasses (configFile >> "CfgVehicles" >> _type >> "ACE_Cargo" >> "Cargo")); }; -// do nothing if the class is already initialized +// Servers and HCs do not require action menus (beyond this point) +if !(hasInterface) exitWith {}; + +// Unnecessary to add actions to a vehicle class that's already got them if (_type in GVAR(initializedVehicleClasses)) exitWith {}; -// set class as initialized -GVAR(initializedVehicleClasses) pushBack _type; +if (_vehicle getVariable [QGVAR(initVehicle),false]) exitWith {}; -if (!hasInterface) exitWith {}; - -TRACE_1("Adding unload cargo action to class", _type); - -private _condition = { - GVAR(enable) && {locked _target < 2} && {alive _target} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} +// Vehicles given cargo via eden have their actions added to the object +// So this function may run for multiple of the same class in that case +if (_hasCargoConfig) then { + GVAR(initializedVehicleClasses) pushBack _type; + TRACE_1("Adding unload cargo action to class", _type); + [_type, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToClass); +} else { + _vehicle setVariable [QGVAR(initVehicle),true]; + TRACE_1("Adding unload cargo action to object", _vehicle); + [_vehicle, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToObject); }; -private _statement = { - GVAR(interactionVehicle) = _target; - GVAR(interactionParadrop) = false; - createDialog QGVAR(menu); -}; -private _text = localize LSTRING(openMenu); -private _icon = ""; - -private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction); -[_type, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToClass); // Add the paradrop self interaction for planes and helicopters if (_vehicle isKindOf "Air") then { private _condition = { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(enable) && {[_player, _target, []] call EFUNC(common,canInteractWith)} && { private _turretPath = _player call CBA_fnc_turretPath; (_player == (driver _target)) || // pilot @@ -66,6 +79,7 @@ if (_vehicle isKindOf "Air") then { {_turretPath in (getArray (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(loadmasterTurrets)))}} // loadMaster turret from config }; private _statement = { + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(interactionVehicle) = _target; GVAR(interactionParadrop) = true; createDialog QGVAR(menu); @@ -74,5 +88,9 @@ if (_vehicle isKindOf "Air") then { private _icon = ""; private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction); - [_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); // self action on the vehicle + if (_hasCargoConfig) then { + [_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); // self action on the vehicle + } else { + [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + }; }; diff --git a/addons/cargo/functions/fnc_loadItem.sqf b/addons/cargo/functions/fnc_loadItem.sqf index 1d59cc1e64..73056ef43f 100644 --- a/addons/cargo/functions/fnc_loadItem.sqf +++ b/addons/cargo/functions/fnc_loadItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Load object into vehicle. @@ -6,6 +7,7 @@ * Arguments: * 0: Item * 1: Vehicle + * 2: Ignore interaction distance and stability checks * * Return Value: * Object loaded @@ -13,14 +15,13 @@ * Example: * [object, vehicle] call ace_cargo_fnc_loadItem * - * Public: No + * Public: Yes */ -#include "script_component.hpp" -params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]]]; +params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]], ["_ignoreInteraction", false]]; TRACE_2("params",_item,_vehicle); -if !([_item, _vehicle] call FUNC(canLoadItemIn)) exitWith {TRACE_2("cannot load",_item,_vehicle); false}; +if !([_item, _vehicle, _ignoreInteraction] call FUNC(canLoadItemIn)) exitWith {TRACE_2("cannot load",_item,_vehicle); false}; private _loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded pushBack _item; @@ -36,6 +37,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 27513a1864..0000000000 --- a/addons/cargo/functions/fnc_makeLoadable.sqf +++ /dev/null @@ -1,47 +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" - -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 { - ACE_LOGERROR("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]; -}; - -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 bcc6307863..0000000000 --- a/addons/cargo/functions/fnc_moduleMakeLoadable.sqf +++ /dev/null @@ -1,34 +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); - -if ((isNull _logic) || {!_activated}) exitWith {}; -if (_objects isEqualTo []) exitWith { - ACE_LOGWARNING_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 c4b6baea3d..ce73678e9e 100644 --- a/addons/cargo/functions/fnc_moduleSettings.sqf +++ b/addons/cargo/functions/fnc_moduleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Module for adjusting the cargo settings @@ -15,14 +16,12 @@ * * Public: No */ -#include "script_component.hpp" - -if (!isServer) exitWith {}; params ["_logic", "", "_activated"]; if (!_activated) exitWith {}; [_logic, QGVAR(enable), "enable"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(paradropTimeCoefficent), "paradropTimeCoefficent"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO("Cargo Module Initialized."); +INFO("Cargo Module Initialized."); diff --git a/addons/cargo/functions/fnc_onMenuOpen.sqf b/addons/cargo/functions/fnc_onMenuOpen.sqf index 852729e529..d611d18ff2 100644 --- a/addons/cargo/functions/fnc_onMenuOpen.sqf +++ b/addons/cargo/functions/fnc_onMenuOpen.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handle the UI data display. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; @@ -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; }; @@ -44,7 +44,13 @@ if (GVAR(interactionParadrop)) then { lbClear _ctrl; { private _class = if (_x isEqualType "") then {_x} else {typeOf _x}; - _ctrl lbAdd (getText(configfile >> "CfgVehicles" >> _class >> "displayName")); + private _displayName = getText (configfile >> "CfgVehicles" >> _class >> "displayName"); + if (GVAR(interactionParadrop)) then { + _ctrl lbAdd format ["%1 (%2s)", _displayName, GVAR(paradropTimeCoefficent) * ([_class] call FUNC(getSizeItem))]; + } else { + _ctrl lbAdd _displayName; + }; + true } count _loaded; diff --git a/addons/cargo/functions/fnc_paradropItem.sqf b/addons/cargo/functions/fnc_paradropItem.sqf index deec93b95e..961b2f7c36 100644 --- a/addons/cargo/functions/fnc_paradropItem.sqf +++ b/addons/cargo/functions/fnc_paradropItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: marc_book, commy2, CAA-Picard * Unload and paradrop object from plane or helicopter. @@ -6,7 +7,7 @@ * 0: Object * 1: Vehicle * - * Return value: + * Return Value: * Object unloaded * * Example: @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_item", "_vehicle"]; TRACE_2("params",_item,_vehicle); @@ -31,10 +31,10 @@ private _cargoSpace = [_vehicle] call FUNC(getCargoSpaceLeft); private _itemSize = [_item] call FUNC(getSizeItem); _vehicle setVariable [QGVAR(space), (_cargoSpace + _itemSize), true]; -(boundingBoxReal q2) params ["_bb1", "_bb2"]; -private _distBehind = ((_bb1 select 1) min (_bb2 select 1)) - 3; // 3 meters behind max bounding box +(boundingBoxReal _vehicle) params ["_bb1", "_bb2"]; +private _distBehind = ((_bb1 select 1) min (_bb2 select 1)) - 4; // 4 meters behind max bounding box TRACE_1("",_distBehind); -private _posBehindVehicleAGL = _vehicle modelToWorld [0, _distBehind, -1]; +private _posBehindVehicleAGL = _vehicle modelToWorld [0, _distBehind, -2]; private _itemObject = if (_item isEqualType objNull) then { @@ -44,12 +44,12 @@ 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 }; -_newItem setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply 10)); +_itemObject setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply -5)); // open parachute and ir light effect [{ @@ -57,13 +57,16 @@ _newItem setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vectorDi if (isNull _item || {getPos _item select 2 < 1}) exitWith {}; - private _itemPosASL = getPosASL _item; - private _itemVelocity = velocity _item; private _parachute = createVehicle ["B_Parachute_02_F", [0,0,0], [], 0, "CAN_COLLIDE"]; - _item attachTo [_parachute, [0,0,0.2]]; - _parachute setPosASL _itemPosASL; - _parachute setVelocity _itemVelocity; + // cannot use setPos on parachutes without them closing down + _parachute attachTo [_item, [0,0,0]]; + detach _parachute; + + private _velocity = velocity _item; + + _item attachTo [_parachute, [0,0,1]]; + _parachute setVelocity _velocity; private _light = "Chemlight_yellow" createVehicle [0,0,0]; _light attachTo [_item, [0,0,0]]; @@ -87,6 +90,15 @@ _newItem setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vectorDi }, 1, [_itemObject]] call CBA_fnc_addPerFrameHandler; +[ + [ + LSTRING(UnloadedItem), + getText (configFile >> "CfgVehicles" >> typeOf _itemObject >> "displayName"), + getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName") + ], + 3 +] call EFUNC(common,displayTextStructured); + // Invoke listenable event ["ace_cargoUnloaded", [_item, _vehicle, "paradrop"]] call CBA_fnc_globalEvent; diff --git a/addons/cargo/functions/fnc_removeCargoItem.sqf b/addons/cargo/functions/fnc_removeCargoItem.sqf new file mode 100644 index 0000000000..ede9c68c94 --- /dev/null +++ b/addons/cargo/functions/fnc_removeCargoItem.sqf @@ -0,0 +1,70 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 new file mode 100644 index 0000000000..9c9cc34f39 --- /dev/null +++ b/addons/cargo/functions/fnc_setSize.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +/* + * Author: SilentSpike + * Set the cargo size of any object. Has global effect. + * Adds the load action menu if necessary. + * Negative size makes unloadable. + * + * Arguments: + * 0: Object + * 1: Cargo size + * + * Return Value: + * None + * + * Example: + * [cursorTarget, 3] call ace_cargo_fnc_setSize + * + * Public: Yes + */ + +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSize), _this]; +}; + +params [ + ["_object",objNull,[objNull]], + ["_size",nil,[0]] // Default can't be a number since all are valid +]; +TRACE_2("setSize",_object,_size); + +// Nothing to do here +if ( + (isNil "_size") || + {isNull _object} || + {_size == _object getVariable [QGVAR(size), CARGO_SIZE(typeOf _object)]} +) exitWith {}; + +// Apply new size globally +// Necessary to update value, even if unloadable, as API could be used again +_object setVariable [QGVAR(canLoad), _size >= 0, true]; +_object setVariable [QGVAR(size), _size, true]; + +// If no size no need for load action +if (_size < 0) exitWith {}; + +// If an existing ID is present, load action has already been added globally +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 new file mode 100644 index 0000000000..1b3743cf9f --- /dev/null +++ b/addons/cargo/functions/fnc_setSpace.sqf @@ -0,0 +1,56 @@ +#include "script_component.hpp" +/* + * Author: SilentSpike + * Set the cargo space of any object. Has global effect. + * Adds the cargo action menu if necessary. + * + * Arguments: + * 0: Object + * 1: Cargo space + * + * Return Value: + * None + * + * Example: + * [vehicle player, 20] call ace_cargo_fnc_setSpace + * + * Public: Yes + */ + +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSpace), _this]; +}; + +params [ + ["_vehicle",objNull,[objNull]], + ["_space",nil,[0]] // Default can't be a number since all are valid +]; +TRACE_2("setSpace",_vehicle,_size); + +// Nothing to do here +if ( + (isNil "_space") || + {isNull _vehicle} || + {_space == _vehicle getVariable [QGVAR(space), CARGO_SPACE(typeOf _vehicle)]} +) exitWith {}; + +// Apply new space globally +// Necessary to update value, even if no space, as API could be used again +_vehicle setVariable [QGVAR(hasCargo), _space > 0, true]; +_vehicle setVariable [QGVAR(space), _space, true]; + +// If no cargo space no need for cargo menu +if (_space <= 0) exitWith {}; + +// If an existing ID is present, cargo menu has already been added globally +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 466471c375..178d2fff25 100644 --- a/addons/cargo/functions/fnc_startLoadIn.sqf +++ b/addons/cargo/functions/fnc_startLoadIn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Start load item. @@ -5,6 +6,7 @@ * Arguments: * 0: Player * 1: Object + * 2: Vehicle (Optional) * * Return Value: * Load ProgressBar Started @@ -14,17 +16,15 @@ * * Public: No */ -#include "script_component.hpp" -params ["_player", "_object"]; -TRACE_2("params",_player,_object); +params ["_player", "_object", ["_cargoVehicle", objNull]]; +TRACE_3("params",_player,_object,_cargoVehicle); -private _vehicle = [_player] call FUNC(findNearestVehicle); - -if ((isNull _vehicle) || {_vehicle isKindOf "Cargo_Base_F"}) then { +private _vehicle = _cargoVehicle; +if (isNull _vehicle) then { { if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_vehicle = _x}; - } forEach (nearestObjects [_player, ["Cargo_base_F", "Land_PaperBox_closed_F"], 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_startUnload.sqf b/addons/cargo/functions/fnc_startUnload.sqf index 8631449b9e..eedf3b2efa 100644 --- a/addons/cargo/functions/fnc_startUnload.sqf +++ b/addons/cargo/functions/fnc_startUnload.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Start unload action. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; @@ -28,13 +28,18 @@ private _ctrl = _display displayCtrl 100; private _selected = (lbCurSel _ctrl) max 0; if (count _loaded <= _selected) exitWith {}; -private _item = _loaded select _selected; //This can be an object or a classname string +private _item = _loaded select _selected; // This can be an object or a classname string if (GVAR(interactionParadrop)) exitWith { + // If drop time is 0 don't show a progress bar + if (GVAR(paradropTimeCoefficent) == 0) exitWith { + [QGVAR(paradropItem), [_item, GVAR(interactionVehicle)]] call CBA_fnc_localEvent; + }; + // Start progress bar - paradrop private _size = [_item] call FUNC(getSizeItem); [ - 2.5 * _size, + GVAR(paradropTimeCoefficent) * _size, [_item, GVAR(interactionVehicle), ACE_player], { (_this select 0) params ["_item", "_target", "_player"]; diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index ce84772c1f..6f0f97cb43 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, ViperMaul * Unload object from vehicle. @@ -5,24 +6,22 @@ * Arguments: * 0: Item * 1: Vehicle + * 2: Unloader (default: objNull) * * Return Value: - * Object unloaded + * Object was unloaded * * Example: * [object, vehicle] call ace_cargo_fnc_unloadItem * - * Public: No + * Public: Yes */ -#include "script_component.hpp" params ["_item", "_vehicle", ["_unloader", objNull]]; TRACE_3("params",_item,_vehicle,_unloader); -private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item}; - //This covers testing vehicle stability and finding a safe position -private _emptyPosAGL = [_vehicle, _itemClass, _unloader] call EFUNC(common,findUnloadPosition); +private _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition); TRACE_1("findUnloadPosition",_emptyPosAGL); if ((count _emptyPosAGL) != 3) exitWith { @@ -37,7 +36,7 @@ if ((count _emptyPosAGL) != 3) exitWith { private _loaded = _vehicle getVariable [QGVAR(loaded), []]; if !(_item in _loaded) exitWith { - ACE_LOGERROR_3("Tried to unload item [%1] not in vehicle[%2] cargo[%3]", _item, _vehicle, _loaded); + ERROR_3("Tried to unload item [%1] not in vehicle[%2] cargo[%3]", _item, _vehicle, _loaded); false }; @@ -54,7 +53,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/functions/fnc_validateCargoSpace.sqf b/addons/cargo/functions/fnc_validateCargoSpace.sqf index 6e3d79cf8d..b83ccfe93a 100644 --- a/addons/cargo/functions/fnc_validateCargoSpace.sqf +++ b/addons/cargo/functions/fnc_validateCargoSpace.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Validate the vehicle cargo space. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; TRACE_1("params",_vehicle); diff --git a/addons/cargo/initSettings.sqf b/addons/cargo/initSettings.sqf new file mode 100644 index 0000000000..3a9f70070a --- /dev/null +++ b/addons/cargo/initSettings.sqf @@ -0,0 +1,19 @@ +// CBA Settings [ADDON: ace_cargo]: + +[ + QGVAR(enable), "CHECKBOX", + [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize LSTRING(openMenu)], + true, // default value + true, // isGlobal + {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(paradropTimeCoefficent), "SLIDER", + [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize LSTRING(openMenu)], + [0,10,2.5,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(paradropTimeCoefficent), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; 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 905a8b0613..d5cee60c39 100644 --- a/addons/cargo/script_component.hpp +++ b/addons/cargo/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_CARGO @@ -17,4 +16,10 @@ #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}) + +// Default cargo size is -1 as 0 is a valid size +#define CARGO_SIZE(classname) GET_NUMBER(configFile >> "CfgVehicles" >> (classname) >> QGVAR(size),-1) +#define CARGO_SPACE(classname) GET_NUMBER(configFile >> "CfgVehicles" >> (classname) >> QGVAR(space),0) diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 251220fd1c..0bcd784d0d 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ Cargar Carica Charger + 積み込む + 싣기 + 裝載 + 装载 Unload @@ -22,6 +26,10 @@ Descargar Scarica Décharger + 下ろす + 내리기 + 卸載 + 卸载 Cargo @@ -33,6 +41,10 @@ Carga Cargo Cargaison + カーゴ + 화물 + 貨物 + 货物 Cargo Menu @@ -44,6 +56,10 @@ Menu de carga Menù Cargo Menu de cargaison + カーゴ メニュー + 화물 메뉴 + 貨物選單 + 货物选单 Cargo space left: %1 @@ -55,6 +71,10 @@ Espacio de carga restante: %1 Spazio cargo rimanente: %1 Espace de cargaison restant : %1 + カーゴの空き容量: %1 + 선적 공간 남음: %1 + 貨物剩餘空間: %1 + 货物剩余空间: %1 Enable Cargo @@ -66,6 +86,10 @@ Habilitar carga Abilita Cargo Activer la mise en cargaison + カーゴを有効化 + 화물 활성화 + 啟用貨物裝載 + 启用货物装载 Enable the load in cargo module @@ -77,6 +101,10 @@ Umožňuje naložit předměty do nákladového prostoru vozidla Abilita il modulo di caricamento in cargo Active le chargement de cargaison dans un vehicule + カーゴ モジュールで積み込みを有効化 + 화물 모듈에 싣기를 활성화합니다 + 啟用貨物裝載功能 + 启用货物装载功能 Cargo Settings @@ -88,6 +116,10 @@ Ajustes de carga Impostazioni Cargo Paramètres de cargaison + カーゴ設定 + 화물 설정 + 貨物設定 + 货物设定 Configure the cargo module settings @@ -99,6 +131,10 @@ Konfigurace nákladního modulu Configura le impostazioni del modulo cargo Configure les paramètres du module de cargaison + カーゴ モジュールの設定を構成 + 화물 모듈의 환경 설정을 바꿉니다 + 配置貨物模塊設定 + 配置货物模块设定 %1<br/>loaded into<br/>%2 @@ -111,6 +147,10 @@ %1<br/>caricato su<br/>%2 %1<br/>berakodva ide:<br/>%2 %1<br/>загружен в<br/>%2 + %1<br/>は<br/>%2へ積み込まれました + %1<br/>는<br/>%2 에 실림 + %1<br/>裝載至<br/>%2 + %1<br/>装载至<br/>%2 Unloaded<br/>%1 from<br/>%2 @@ -123,6 +163,10 @@ Hai scaricato<br/>%1 da<br/>%2 1%<br/>kirakodva ebből:<br/>%2 %1<br/>разгружен из<br/>%2 + <br/>%1が<br/>%2から降ろされました + %1<br/>는<br/>%2 에서 내려짐 + 從<br/>%2卸載<br/>%1 + 从<br/>%2卸载<br/>%1 Loading Cargo @@ -134,6 +178,10 @@ Caricando Cargando Chargement de la cargaison + カーゴへ積み込んでいます + 화물 싣기 + 裝載貨物中 + 装载货物中 Unloading Cargo @@ -145,6 +193,10 @@ Scaricando Descargando Déchargement de la cargaison + カーゴから降ろしています + 화물 내리기 + 卸載貨物中 + 卸载货物中 %1<br/>could not be loaded @@ -156,6 +208,10 @@ %1<br/>non può essere caricato %1<br/>no pudo ser cargado %1<br /> n'a pas pu être chargé + %1<br/>は積み込めませんでした + %1<br/>이 실릴 수가 없습니다 + %1<br/>無法被裝載 + %1<br/>无法被装载 %1<br/>could not be unloaded @@ -167,47 +223,94 @@ %1<br/>non può essere scaricato %1<br/>no pudo ser descargado %1<br /> n'a pas pu être déchargé + %1<br/>は降ろせませんでした + %1<br/>이 내려질 수가 없습니다 + %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 - Сделать объект загружаемым + + Cargo Space + Frachtraum + Spazio Cargo + カーゴ スペース + 貨物空間 + 货物空间 + Przestrzeń ładunkowa + 화물 공간 - - 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 - Делает синхронизированный объект загружаемым для модуля перевозки грузов. + + 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 + 이 차량/컨테이너에서 사용가능한 화물 공간 - - Object's Size - Objektgröße - Rozmiar obiektu - Dimensioni dell'oggetto - Tamaño del objeto - Taille de l'objet - Velikost objektu - Tamanho do objeto - Размер объекта + + 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 Türlast + 空中投下 + Zrzut zaopatrzenia + 공중 투하 + Largage aérien + Lancio Aereo + 空投 + 空投 Unlevel Flight Schieflage + 機体が水平ではありません + Nierówny lot + 기체가 수평이 아닙니다 + Rétablir l'assiette + Volo non Livellato + 此架飛機並無保持水平飛行 + 此架飞机并无保持水平飞行 + + + 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. + 화물을 공중 투하 하는데 얼마나 걸리는 시간 설정 - \ No newline at end of file + diff --git a/addons/chemlights/CfgVehicles.hpp b/addons/chemlights/CfgVehicles.hpp index 62aee70724..9fd05d84b9 100644 --- a/addons/chemlights/CfgVehicles.hpp +++ b/addons/chemlights/CfgVehicles.hpp @@ -2,7 +2,6 @@ class CBA_Extended_EventHandlers; class CfgVehicles { - class Man; class CAManBase: Man { class ACE_SelfActions { @@ -12,18 +11,17 @@ 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; }; }; }; }; - + class Thing; class ThingX; - + class ACE_Chemlight_IR_Marker: Thing { author = ECSTRING(common,ACETeam); displayName = "ACE Chemlight IR Marker"; @@ -49,7 +47,7 @@ class CfgVehicles { useFlare = 0; }; }; - + class ACE_Chemlight_IR_Dummy: ThingX { ACE_Attachable = "ACE_G_Chemlight_IR"; author = ECSTRING(common,ACETeam); @@ -62,7 +60,7 @@ class CfgVehicles { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; }; - + class Item_Base_F; class ACE_Item_Chemlight_Shield: Item_Base_F { @@ -78,7 +76,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Green: Item_Base_F { scope = 2; scopeCurator = 2; @@ -92,7 +90,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Red: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Red_DisplayName); class TransportItems { @@ -102,7 +100,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Blue: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Blue_DisplayName); class TransportItems { @@ -112,7 +110,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Yellow: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Yellow_DisplayName); class TransportItems { @@ -122,7 +120,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_Orange: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_Orange_DisplayName); class TransportItems { @@ -132,7 +130,7 @@ class CfgVehicles { }; }; }; - + class ACE_Item_Chemlight_Shield_White: ACE_Item_Chemlight_Shield_Green { displayName = CSTRING(Shield_White_DisplayName); class TransportItems { @@ -154,13 +152,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 +170,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 +188,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 +206,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 +233,7 @@ class CfgVehicles { MACRO_ADDMAGAZINE(ACE_Chemlight_IR,20); }; }; - + class ACE_Box_Chemlights: NATO_Box_Base { scope = 2; accuracy = 1; @@ -246,11 +244,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 +262,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 de5fc8aea5..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); @@ -44,8 +44,8 @@ class CfgWeapons { descriptionShort = CSTRING(Shield_Empty_DescriptionShort); model = "\A3\weapons_F\ammo\mag_univ.p3d"; picture = QPATHTOF(UI\ace_chemlight_shield_x_ca.paa); - scope = 1; - class ItemInfo: InventoryItem_Base_F { + scope = 2; + 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/XEH_preInit.sqf b/addons/chemlights/XEH_preInit.sqf index 7d00e938cf..7fe826a174 100644 --- a/addons/chemlights/XEH_preInit.sqf +++ b/addons/chemlights/XEH_preInit.sqf @@ -3,6 +3,8 @@ ADDON = false; LOG(MSG_INIT); +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/chemlights/functions/fnc_compileChemlightMenu.sqf b/addons/chemlights/functions/fnc_compileChemlightMenu.sqf index 74b0a154c9..c8cccb88bd 100644 --- a/addons/chemlights/functions/fnc_compileChemlightMenu.sqf +++ b/addons/chemlights/functions/fnc_compileChemlightMenu.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Compile list of chemlight classnames and add to the "Chemlight shield" parent menu. @@ -7,7 +8,7 @@ * 1: Player * 2: Parameters * - * Return value: + * Return Value: * None * * Example: @@ -16,8 +17,6 @@ * Public: No */ -#include "script_component.hpp" - params ["", "_player", "_args"]; private _actions = []; @@ -29,7 +28,7 @@ private _chemlights = [_player] call FUNC(getShieldComponents); private _icon = getText (_config >> "picture"); private _shieldClass = getText (_config >> "ACE_Chemlight_Shield"); private _displayName = getText (configFile >> "CfgWeapons" >> _shieldClass >> "displayName"); - + _displayName = format [localize LSTRING(Action_Prepare), _displayName]; private _statement = {_this call FUNC(prepShield)}; diff --git a/addons/chemlights/functions/fnc_getShieldComponents.sqf b/addons/chemlights/functions/fnc_getShieldComponents.sqf index be089b261c..f372241599 100644 --- a/addons/chemlights/functions/fnc_getShieldComponents.sqf +++ b/addons/chemlights/functions/fnc_getShieldComponents.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Check a unit for whether they're carrying a chemlight shield and a chemlight. @@ -5,7 +6,7 @@ * Arguments: * 0: Unit to check * - * Return value: + * Return Value: * List of carried chemlight classnames * * Example: @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit"]; private _components = []; private _items = itemsWithMagazines _unit; diff --git a/addons/chemlights/functions/fnc_initIR.sqf b/addons/chemlights/functions/fnc_initIR.sqf index f2ff4b02d3..29532f41f1 100644 --- a/addons/chemlights/functions/fnc_initIR.sqf +++ b/addons/chemlights/functions/fnc_initIR.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Spawn IR marker for dummy IR physX object. @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_dummy"]; private _chemlightClass = getText (configFile >> "CfgVehicles" >> typeOf _dummy >> "ACE_Attachable"); diff --git a/addons/chemlights/functions/fnc_isIRClass.sqf b/addons/chemlights/functions/fnc_isIRClass.sqf index 69643a89fe..3d2021749e 100644 --- a/addons/chemlights/functions/fnc_isIRClass.sqf +++ b/addons/chemlights/functions/fnc_isIRClass.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Check if an ammo classname is an IR chemlight. @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params [["_input", "", ["", objNull]]]; private _class = if (typeName _input == "OBJECT") then {typeOf _input} else {_input}; diff --git a/addons/chemlights/functions/fnc_prepShield.sqf b/addons/chemlights/functions/fnc_prepShield.sqf index 52623d6488..3f4f09d430 100644 --- a/addons/chemlights/functions/fnc_prepShield.sqf +++ b/addons/chemlights/functions/fnc_prepShield.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Combine a chemlight shield item and a chemlight item into a light. @@ -7,7 +8,7 @@ * 1: Activator Unit (player) * 2: Chemlight class, chemlight shield class * - * Return value: + * Return Value: * None * * Example: @@ -16,8 +17,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_target", "_unit", "_args"]; _args params ["_chemlight", "_shieldClass"]; diff --git a/addons/chemlights/functions/fnc_removeIR.sqf b/addons/chemlights/functions/fnc_removeIR.sqf index b7f6a0001e..1c40a5b126 100644 --- a/addons/chemlights/functions/fnc_removeIR.sqf +++ b/addons/chemlights/functions/fnc_removeIR.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Kill chemlight and any dummy objects attached to it. @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_chemlight", "_lightMarker"]; if (!isNull _lightMarker) then { diff --git a/addons/chemlights/functions/fnc_throwEH.sqf b/addons/chemlights/functions/fnc_throwEH.sqf index 18215c9846..2bedff7cb7 100644 --- a/addons/chemlights/functions/fnc_throwEH.sqf +++ b/addons/chemlights/functions/fnc_throwEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, voiper * Fired EH, for handling chemlight ThrowMuzzles. @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_weapon", "", "", "_ammo", "", "_projectile"]; if ((_weapon != "Throw") || {!(_ammo isKindOf ["Chemlight_base", configFile >> "CfgAmmo"])}) exitWith {}; @@ -27,8 +26,8 @@ if (isNull _projectile) then { if (local _unit) then { if ([_ammo] call FUNC(isIRClass)) then { - // Handle advancedThrowing: - if ((ace_player getVariable [QEGVAR(advancedThrowing,activeThrowable), objNull]) == _projectile) then { + // Handle Advanced Throwing + if ((ACE_player getVariable [QEGVAR(advanced_throwing,activeThrowable), objNull]) == _projectile) then { [_projectile, _ammo, true] call FUNC(throwIR); // direct call if we are priming with adv throw } else { [{_this call FUNC(throwIR)}, [_projectile, _ammo]] call CBA_fnc_execNextFrame; diff --git a/addons/chemlights/functions/fnc_throwIR.sqf b/addons/chemlights/functions/fnc_throwIR.sqf index 0148b0d669..b507c8e5b1 100644 --- a/addons/chemlights/functions/fnc_throwIR.sqf +++ b/addons/chemlights/functions/fnc_throwIR.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Create and throw IR chemlight. @@ -5,19 +6,17 @@ * 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 */ -#include "script_component.hpp" - params ["_projectile", "_ammo", ["_replaceAdvThrowable", false]]; private _config = configFile >> "CfgAmmo" >> _ammo; @@ -32,5 +31,5 @@ _dummy setPosATL _pos; _dummy setVelocity _velocity; if (_replaceAdvThrowable) then { - ace_player setVariable [QEGVAR(advancedThrowing,activeThrowable), _dummy]; + ACE_player setVariable [QEGVAR(advanced_throwing,activeThrowable), _dummy]; }; diff --git a/addons/chemlights/script_component.hpp b/addons/chemlights/script_component.hpp index 8648a3e065..324af2c55c 100644 --- a/addons/chemlights/script_component.hpp +++ b/addons/chemlights/script_component.hpp @@ -3,7 +3,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_CHEMLIGHTS diff --git a/addons/chemlights/stringtable.xml b/addons/chemlights/stringtable.xml index 4be6323287..f995d66492 100644 --- a/addons/chemlights/stringtable.xml +++ b/addons/chemlights/stringtable.xml @@ -1,151 +1,450 @@ - + Chemlights + ケミライト + Świetliki + Knicklichter + 켐라이트 + Cyalumes + Luce chimica + 螢光棒 + 萤光棒 - Prepare %1 - + %1 をつかう + Przygotuj %1 + %1 vorbereiten + %1 준비 + Prépare %1 + Prepara %1 + 使用%1 + 使用%1 + %1<br/>Prepared + %1<br/>をつかった + %1<br/>Przygotowany + %1<br/>vorbereitet + %1<br/>준비됨 + %1<br/>prêt + %1 <br/> Preparata + %1<br/>已使用 + %1<br/>已使用 - No inventory space Kein Platz im Inventar Sin espacio en inventario Brak miejsca w ekwipunku - Pas de place dans l'inventaire + Pas de place Nedostatek místa v inventáři Sem espaço no inventário - Non hai più spazio + Nessuno spazio nell'inventario Nincs több hely В инвентаре нет места + インベントリに空きがありません + 소지품 공간이 없음 + 已無存放空間 + 已无存放空间 - [ACE] Chemlights + [ACE] ケミライト + [ACE] Świetliki + [ACE] Knicklichter + [ACE] 켐라이트 + [ACE] Cyalume + [ACE] Luci chimiche + [ACE] 螢光棒 + [ACE] 萤光棒 - Chemlight (Orange) + ケミライト (オレンジ) + Świetlik (pomarańczowy) + Knicklicht (orange) + 켐라이트 (주황) + Cyalume (orange) + Luce chimica (Arancione) + 螢光棒 (橘色) + 萤光棒 (橘色) Orange Light + オレンジ色 + Pomarańczowe światło + Oranges Knicklicht + 주황색 + Lum. orange + Luce Arancione + 橘色光 + 橘色光 Type: Light - Orange<br />Rounds: 1<br />Used in: Hand + 種類: 照明 - オレンジ<br />装填数: 1<br />次で使用: 携帯 + Typ: Światło - pomarańczowe<br/>Pociski: 1<br/>Używany w: ręce + Typ: Licht - orange<br />Anzahl: 1<br />Benutzt in: Hand + 종류:밝은 오렌지<br />수량: 1<br />사용처: 손 + Type: Lumière - orange<br />Nbre: 1<br /> À main + Tipo: Luce - Arancione<br/>Rimanenti: 1<br/>Usata in: Mano + 類型: 光 - 橘色<br />發數: 1<br />使用於: 手 + 类型: 光 - 橘色<br />发数: 1<br />使用于: 手 - Chemlight (White) + ケミライト (白) + Świetlik (biały) + Knicklicht (weiß) + 켐라이트 (하양) + Cyalume (blanc) + Luce chimica (Bianca) + 螢光棒 (白色) + 萤光棒 (白色) White Light + 白色 + Białe światło + Weißes Knicklicht + 하얀색 + Lum. blanche + Luce Bianca + 白色光 + 白色光 Type: Light - White<br />Rounds: 1<br />Used in: Hand + 種類: 照明 - 白<br />装填数: 1<br />次で使用: 携帯 + Typ: Światło - białe<br/>Pociski: 1<br/>Używany w: ręce + Typ: Licht - weiß<br />Anzahl: 1<br />Benutzt in: Hand + 종류:하얀색<br />수량: 1<br />사용처: 손 + Type: Lumière - blanche<br />Nbre: 1<br /> À main + Tipo: Luce - Bianca<br/>Rimanenti: 1<br/>Usata in: Mano + 類型: 光 - 白色<br />發數: 1<br />使用於: 手 + 类型: 光 - 白色<br />发数: 1<br />使用于: 手 - Chemlight (Hi Red) + ケミライト (高輝度 赤) + Świetlik (jaskrawy czerwony) + Knicklicht (rot, hell) + 켐라이트 (밝은 빨간색) + Cyalume (Hi rouge) + Luce chimica (Hi Rossa) + 螢光棒 (超亮紅色) + 萤光棒 (超亮红色) Red Hi Light + 高輝度の赤色 + Jaskrawe czerwone światło + Helles, rotes Knicklicht + 밝은 빨간색 + Lum. rouge haute intensité + Luce Hi Rossa + 超亮紅色光 + 超亮红色光 Type: Light - Red Hi (5 minute)<br />Rounds: 1<br />Used in: Hand + 種類: 照明 - 高輝度 赤 (5分間)<br />装填数: 1<br />次で使用: 携帯 + Typ: Światło - jaskrawe czerwone (5 minut)<br/>Pociski: 1<br/>Używany w: ręce + Typ: Licht - rot, hell (5 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand + 종류: 밝은 빨간색 (5분)<br />수량: 1<br />사용처: 손 + Type: Lumière - rouge Hi (5 minutes)<br />Nbre: 1<br /> À main + Tipo: Luce - Rossa Hi (5 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + 類型: 光 - 超亮紅色 (5分鐘)<br />發數: 1<br />使用於: 手 + 类型: 光 - 超亮红色 (5分钟)<br />发数: 1<br />使用于: 手 - Chemlight (Hi Yellow) + ケミライト (高輝度 黄) + Świetlik (jaskrawy żółty) + Knicklicht (gelb, hell) + 켐라이트 (밝은 노란색) + Cyalume (Hi jaune) + Luce chimica (Hi Gialla) + 螢光棒 (超亮黃色) + 萤光棒 (超亮黄色) Yellow Hi Light + 高輝度の黄色 + Jaskrawe żółte światło + Helles, gelbes Knicklicht + 밝은 노란색 + Lum. jaune haute intensité + Luce Hi Gialla + 超亮黃色光 + 超亮黄色光 Type: Light - Yellow Hi (5 minute)<br />Rounds: 1<br />Used in: Hand + 種類: 照明 - 高輝度 黄 (5分間)<br />装填数: 1<br />次で使用: 携帯 + Typ: Światło - jaskrawe żółte (5 minut)<br/>Pociski: 1<br/>Używany w: ręce + Typ: Licht - gelb, hell (5 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand + 종류:밝은 노란색 (5분)<br />수량: 1<br />사용처: Hand + Type: Lumière - Jaune Hi (5 minutes)Nbre: 1<br /> À main + Tipo: Luce - Gialla Hi (5 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + 類型: 光 - 超亮黃色 (5分鐘)<br />發數: 1<br />使用於: 手 + 类型: 光 - 超亮黄色 (5分钟)<br />发数: 1<br />使用于: 手 - Chemlight (Hi Orange) + ケミライト (高輝度 オレンジ) + Świetlik (jaskrawy pomarańczowy) + Knicklicht (orange, hell) + 켐라이트 (밝은 주황색) + Cyalume (Hi orange) + Luce chimica (Hi Arancione) + 螢光棒 (超亮橘色) + 萤光棒 (超亮橘色) Orange Hi Light + 高輝度のオレンジ + Jaskrawe pomarańczowe światło + Helles, oranges Knicklicht + 밝은 주황색 + Lum. orange haute intensité + Luce Hi Arancione + 超亮橘色光 + 超亮橘色光 Type: Light - Orange Hi (5 minute)<br />Rounds: 1<br />Used in: Hand + 種類: 照明 - 高輝度 オレンジ (5分間)<br />装填数: 1<br />次で使用: 携帯 + Typ: Światło - jaskrawe pomarańczowe (5 minut)<br/>Pociski: 1<br/>Używany w: ręce + Typ: Licht - orange, hell (5 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand + 종류: 밝은 주황색 (5분)<br />수량: 1<br />사용처: 손 + Type: Lumière - orange Hi (5 minutes)<br />Nbre: 1<br /> À main + Tipo: Luce - Arancione Hi (5 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + 類型: 光 - 超亮橘色 (5分鐘)<br />發數: 1<br />使用於: 手 + 类型: 光 - 超亮橘色 (5分钟)<br />发数: 1<br />使用于: 手 - Chemlight (Hi White) + ケミライト (高輝度 白) + Świetlik (jaskrawy biały) + Knicklicht (weiß, hell) + 켐라이트 (밝은 하얀색) + Cyalume (Hi blanc) + Luce chimica (Hi Bianca) + 螢光棒 (超亮白色) + 萤光棒 (超亮白色) White Hi Light + 高輝度の白色 + Jaskrawe białe światło + Helles, weißes Knicklicht + 밝은 하얀색 + Lum. blanche haute intensité + Luce Hi Bianca + 超亮白色光 + 超亮白色光 Type: Light - White Hi (5 minute)<br />Rounds: 1<br />Used in: Hand + 種類: 照明 - 高輝度 白 (5分間)<br />装填数: 1<br />次で使用: 携帯 + Typ: Światło - jaskrawe białe (5 minut)<br/>Pociski: 1<br/>Używany w: ręce + Typ: Licht - weiß, hell (5 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand + 종류: 밝은 하얀색 (5분)<br />수량: 1<br />사용처: 손 + Type: Lumière - blanche Hi (5 minutes)<br />Nbre: 1<br /> À main + Tipo: Luce - Bianca Hi (5 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + 類型: 光 - 超亮白色 (5分鐘)<br />發數: 1<br />使用於: 手 + 类型: 光 - 超亮白色 (5分钟)<br />发数: 1<br />使用于: 手 - Chemlight (IR) + ケミライト (IR) + Świetlik (podczerwony) + Knicklicht (IR) + 켐라이트 (적외선) + Cyalume (IR) + Luce chimica (IR) + 螢光棒 (紅外線) + 萤光棒 (红外线) IR Light + 赤外線光 + Światło podczerwone + IR-Knicklicht + 적외선 켐라이트 + Lumière IR + Luce IR + 紅外線光 + 红外线光 Type: Light - Infrared<br />Rounds: 1<br />Used in: Hand + 種類: 照明 - 赤外線<br />装填数: 1<br />次で使用: 携帯 + Typ: Światło - podczerwone<br/>Pociski: 1<br/>Używany w: ręce + Typ: Licht - infrarot<br />Anzahl: 1<br />Benutzt in: Hand + 종류: 적외선<br />수량: 1<br />사용처: 손 + Type: Lumière - infrarouge<br />Nbre: 1<br /> À main + Tipo: Luce - Infrarossi<br />Usata in: Mano + 類型: 光 - 紅外線<br />發數: 1<br />使用於: 手 + 类型: 光 - 红外线<br />发数: 1<br />使用于: 手 - Chemlight Shield (Empty) + ケミライト シールド (空) + Osłona na świetlik (pusta) + Knicklicht-Abschirmung (leer) + 켐라이트 쉴드 (비어있음) + Étui cyalume (vide) + Scudo Luce chimica (Vuoto) + 螢光棒保護殼 (空) + 萤光棒保护壳 (空) Shield for chemlights. Combine with chemlight to prepare reading light. + ケミライトを入れられます。シールドとケミライトを組み合わせることで、照明にもなりえます。 + Osłona na świetliki. Połącz ją ze świetlikiem by stworzyć lampkę do czytania. + Abschirmung für Knicklichter. Mit Knicklicht kombinieren, um Leselicht zu erhalten. + 켐라이트를 위한 가림막입니다. 켐라이트와 같이 사용하여 읽을 때 씁니다. + Étui pour cyalume. Combiné avec un cyalume pour obtennir un lampe de lecture. + Scudo per luci chimiche. Combina con una luce chimica per una luce da lettura. + 螢光棒的保護殼. 與螢光棒結合後可充當閱讀燈 + 萤光棒的保护壳. 与萤光棒结合后可充当阅读灯. - Chemlight Shield (Green) + ケミライト シールド (緑) + Osłona na świetlik (zielona) + Knicklicht-Abschirmung (grün) + 켐라이트 쉴드 (초록) + Étui cyalume (vert) + Scudo Luce Chimica (Verde) + 螢光棒保護殼 (綠色) + 萤光棒保护壳 (绿色) Green reading light. + 緑色の照明。 + Zielona lampka. + Grünes Leselicht. + 초록빛 조명 + Lampe d'orientation verte. + Luce da lettura Verde. + 綠色閱讀燈 + 绿色阅读灯。 - Chemlight Shield (Red) + ケミライト シールド (赤) + Osłona na świetlik (czerwona) + Knicklicht-Abschirmung (rot) + 켐라이트 쉴드 (빨강) + Étui cyalume (rouge) + Scudo Luce Chimica (Rossa) + 螢光棒保護殼 (紅色) + 萤光棒保护壳 (红色) Red reading light. + 赤色の照明。 + Czerwona lampka. + Rotes Leselicht. + 빨간색 조명 + Lampe d'orientation rouge. + Luce da lettura Rossa. + 紅色閱讀燈 + 红色阅读灯。 - Chemlight Shield (Blue) + ケミライト シールド (青) + Osłona na świetlik (niebieska) + Knicklicht-Abschirmung (blau) + 켐라이트 쉴드 (파랑) + Étui cyalume (bleu) + Scudo Luce Chimica (Blu) + 螢光棒保護殼 (藍色) + 萤光棒保护壳 (蓝色) Blue reading light. + 青色の照明。 + Niebieska lampka. + Blaues Leselicht. + 파란색 조명 + Lampe d'orientation bleue. + Luce da lettura Blu. + 藍色閱讀燈 + 蓝色阅读灯。 - - + Chemlight Shield (Yellow) + ケミライト シールド (黄) + Osłona na świetlik (żółta) + Knicklicht-Abschirmung (gelb) + 켐라이트 쉴드 (노랑) + Étui cyalume (jaune) + Scudo Luce Chimica (Gialla) + 螢光棒保護殼 (黃色) + 萤光棒保护壳 (黄色) Yellow reading light. + 黄色の照明。 + Żółta lampka. + Gelbes Leselicht. + 노란색 조명 + Lampe d'orientation jaune. + Luce da lettura Gialla. + 黃色閱讀燈 + 黄色阅读灯。 - Chemlight Shield (Orange) + ケミライト シールド (オレンジ) + Osłona na świetlik (pomarańczowa) + Knicklicht-Abschirmung (orange) + 켐라이트 쉴드 (주황) + Étui cyalume (orange) + Scudo Luce Chimica (Arancione) + 螢光棒保護殼 (橘色) + 萤光棒保护壳 (橘色) Orange reading light. + オレンジの照明。 + Pomarańczowa lampka. + Oranges Leselicht. + 주황색 조명 + Lampe d'orientation orange. + Luce da lettura Arancione. + 橘色閱讀燈 + 橘色阅读灯。 - Chemlight Shield (White) + ケミライト シールド (白) + Osłona na świetlik (biała) + Knicklicht-Abschirmung (weiß) + 켐라이트 쉴드 (하양) + Étui cyalume (blanc) + Scudo Luce Chimica (Bianca) + 螢光棒保護殼 (白色) + 萤光棒保护壳 (白色) White reading light. + 白の照明。 + Biała lampka. + Weißes Leselicht. + 주황색 조명 + Lampe d'orientation blanche. + Luce da lettura Bianca. + 白色閱讀燈 + 白色阅读灯。 - \ No newline at end of file + 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/CfgEden.hpp b/addons/common/CfgEden.hpp index 1b833b0342..a58896b6fc 100644 --- a/addons/common/CfgEden.hpp +++ b/addons/common/CfgEden.hpp @@ -8,4 +8,14 @@ class Cfg3DEN { }; }; }; + + class Group { + class AttributeCategories { + class ace_attributes { + displayName = CSTRING(Options); + collapsed = 1; + class Attributes {}; + }; + }; + }; }; diff --git a/addons/common/CfgEventHandlers.hpp b/addons/common/CfgEventHandlers.hpp index 895b3fd13a..fa4f3dcacd 100644 --- a/addons/common/CfgEventHandlers.hpp +++ b/addons/common/CfgEventHandlers.hpp @@ -23,6 +23,9 @@ class Extended_DisplayLoad_EventHandlers { class RscDisplayMission { ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); }; + class RscUnitInfo { + ADDON = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); + }; }; class Extended_InitPost_EventHandlers { diff --git a/addons/common/CfgLocationTypes.hpp b/addons/common/CfgLocationTypes.hpp index 15b56c120c..163c1e5a88 100644 --- a/addons/common/CfgLocationTypes.hpp +++ b/addons/common/CfgLocationTypes.hpp @@ -4,7 +4,7 @@ class CfgLocationTypes { class ACE_HashLocation { color[] = {0,0,0,0}; - drawStyle = "bananas"; + drawStyle = "WARNING-ACE_HashLocation_is_deprecated"; // Replaced by CBA_fnc_createNamespace font = "RobotoCondensed"; importance = 5; name = "HashLocation"; diff --git a/addons/common/CfgUIGrids.hpp b/addons/common/CfgUIGrids.hpp new file mode 100644 index 0000000000..295a9098eb --- /dev/null +++ b/addons/common/CfgUIGrids.hpp @@ -0,0 +1,20 @@ +class CfgUIGrids { + class IGUI { + class Presets { + class Arma3 { + class Variables { + grid_ACE_displayText[] = {{((safezoneX + safezoneW) - (10 *(((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 *(((safezoneW / safezoneH) min 1.2) / 40)),safeZoneY + 0.175 * safezoneH, (10 *(((safezoneW / safezoneH) min 1.2) / 40)), (3 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))}, "(((safezoneW / safezoneH) min 1.2) / 40)","((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"}; + }; + }; + }; + + class Variables { + class grid_ACE_displayText { + displayName = "ACE Hint"; + description = "Textual in game feedback to the player."; + preview = QPATHTOF(UI\ACE_Hint_Preview_ca.paa); + saveToProfile[] = {0,1}; + }; + }; + }; +}; diff --git a/addons/common/CfgVehicles.hpp b/addons/common/CfgVehicles.hpp index 1e958027be..396d80b5c1 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); @@ -147,4 +147,32 @@ class CfgVehicles { scope = 1; maximumLoad = 1E6; }; + + class FlagCarrier_Asym; + class ACE_Flag_Black: FlagCarrier_Asym { + author = CSTRING(ACETeam); + displayName = CSTRING(FlagBlack); + scope = 2; + scopeCurator = 2; + editorPreview = QPATHTOF(data\ace_flag_black_preview.jpg); + class EventHandlers { + init = QUOTE((_this select 0) setFlagTexture QUOTE(QPATHTOF(data\ace_flag_black_ca.paa))); + }; + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + condition = "true"; + position = "[-0.1, -0.35, -2.6]"; + distance = 2; + }; + }; + }; + class ACE_Flag_White: ACE_Flag_Black { + author = CSTRING(ACETeam); + displayName = CSTRING(FlagWhite); + editorPreview = QPATHTOF(data\ace_flag_white_preview.jpg); + class EventHandlers { + init = QUOTE((_this select 0) setFlagTexture QUOTE(QPATHTOF(data\ace_flag_white_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/HintConfig.hpp b/addons/common/HintConfig.hpp index 04c6995318..e3912e56f3 100644 --- a/addons/common/HintConfig.hpp +++ b/addons/common/HintConfig.hpp @@ -2,8 +2,24 @@ class RscStructuredText; class RscMapControl; +class ctrlStructuredText; + +class GVAR(debug_structuredText): ctrlStructuredText { + sizeEx = "16 * pixelH"; + size = "16 * pixelH"; +}; class RscTitles { + class GVAR(watchVariableUI) { + idd = -1; + onLoad = QUOTE(with uiNameSpace do {GVAR(watchVariableUI) = _this select 0};); + movingEnable = 0; + duration = 999999; + fadeIn = "false"; + fadeOut = "false"; + class controls {}; + }; + class ACE_RscHint { idd = -1; onLoad = "uiNamespace setVariable ['ACE_ctrlHint', (_this select 0) displayCtrl 1];"; 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/RscInfoType.hpp b/addons/common/RscInfoType.hpp index 97d4b325e9..9da45d0ec2 100644 --- a/addons/common/RscInfoType.hpp +++ b/addons/common/RscInfoType.hpp @@ -1,27 +1,24 @@ class RscInGameUI { - class RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); - }; - + class RscUnitInfo; class RscUnitInfoNoHUD { onLoad = QUOTE([ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Any')])] call CBA_fnc_localEvent;); }; class RscUnitInfoSoldier: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSoldier', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Soldier')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSoldier', _this select 0)];); }; class RscUnitInfoTank: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgVehicle', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Vehicle')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgVehicle', _this select 0)];); }; class RscUnitInfoAirNoWeapon: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Aircraft')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft', _this select 0)];); }; class RscUnitInfoAir: RscUnitInfoAirNoWeapon { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Aircraft')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgAircraft', _this select 0)];); }; class RscUnitInfo_AH64D_gunner { @@ -33,11 +30,11 @@ class RscInGameUI { }; class RscUnitInfoSubmarine: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSubmarine', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Submarine')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgSubmarine', _this select 0)];); }; class RscUnitInfoShip: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgShip', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Ship')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgShip', _this select 0)];); }; class RscWeaponEmpty { @@ -97,7 +94,7 @@ class RscInGameUI { }; class RscUnitInfoParachute: RscUnitInfo { - onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgParachute', _this select 0)]; [ARR_2('ace_infoDisplayChanged', [ARR_2(_this select 0, 'Parachute')])] call CBA_fnc_localEvent;); + onLoad = QUOTE([ARR_4(""onLoad"",_this,""RscUnitInfo"",'IGUI')] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable [ARR_2('ACE_dlgParachute', _this select 0)];); }; class RscUnitVehicle { diff --git a/addons/common/UI/ACE_Hint_Preview_ca.paa b/addons/common/UI/ACE_Hint_Preview_ca.paa new file mode 100644 index 0000000000..19e592edde Binary files /dev/null and b/addons/common/UI/ACE_Hint_Preview_ca.paa differ 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 d8b22a8198..c070623893 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -1,16 +1,26 @@ +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); PREP(ambientBrightness); +PREP(arithmeticGetResult); +PREP(arithmeticSetSource); PREP(ASLToPosition); PREP(binarizeNumber); PREP(blurScreen); PREP(cachedCall); +PREP(canDig); PREP(canGetInPosition); PREP(canInteractWith); PREP(changeProjectileDirection); @@ -34,11 +44,11 @@ PREP(displayTextPicture); PREP(displayTextStructured); PREP(doAnimation); PREP(doGesture); +PREP(dummy); PREP(dropBackpack); PREP(endRadioTransmission); PREP(eraseCache); PREP(errorMessage); -PREP(execNextFrame); PREP(findUnloadPosition); PREP(firedEH); PREP(fixCollision); @@ -64,6 +74,7 @@ PREP(getMGRSdata); PREP(getName); PREP(getNumberMagazinesIn); PREP(getPitchBankYaw); +PREP(getPylonTurret); PREP(getSettingData); PREP(getStaminaBarControl); PREP(getTargetAzimuthAndInclination); @@ -74,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); @@ -85,12 +98,10 @@ PREP(hadamardProduct); PREP(handleEngine); PREP(handleModifierKey); PREP(handleModifierKeyUp); -PREP(handleScrollWheel); PREP(hasItem); PREP(hasMagazine); PREP(headBugFix); PREP(hideUnit); -PREP(insertionSort); PREP(interpolateFromArray); PREP(inTransitionAnim); PREP(isAwake); @@ -98,20 +109,19 @@ PREP(isEngineer); PREP(isEOD); PREP(isFeatureCameraActive); PREP(isInBuilding); +PREP(isMedic); PREP(isModLoaded); PREP(isPlayer); -PREP(isUnderwater); +PREP(isSwimming); 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); @@ -124,7 +134,6 @@ PREP(playerSide); PREP(positionToASL); PREP(progressBar); PREP(readSettingFromModule); -PREP(readSettingsFromParamsArray); PREP(receiveRequest); PREP(removeCanInteractWithCondition); PREP(removeSpecificMagazine); @@ -132,9 +141,11 @@ PREP(requestCallback); PREP(resetAllDefaults); PREP(restoreVariablesJIP); PREP(runAfterSettingsInit); +PREP(runTests); PREP(sanitizeString); PREP(sendRequest); PREP(serverLog); +PREP(setAimCoef); PREP(setApproximateVariablePublic); PREP(setDefinedVariable); PREP(setDisableUserInputStatus); @@ -142,9 +153,9 @@ PREP(setHearingCapability); PREP(setName); PREP(setParameter); PREP(setPitchBankYaw); +PREP(setPlayerOwner); PREP(setProne); PREP(setSetting); -PREP(setSettingFromConfig); PREP(setVariableJIP); PREP(setVariablePublic); PREP(setVolume); @@ -158,7 +169,7 @@ PREP(statusEffect_sendEffects); PREP(statusEffect_set); PREP(stringCompare); PREP(stringToColoredText); -PREP(stringRemoveWhiteSpace); +PREP(switchPersistentLaser); PREP(switchToGroupSide); PREP(throttledPublicVariable); PREP(toBin); @@ -167,13 +178,13 @@ PREP(toHex); PREP(toNumber); PREP(unhideUnit); PREP(uniqueElements); +PREP(uniqueItems); PREP(unloadPerson); PREP(unloadPersonLocal); PREP(unmuteUnit); PREP(useItem); PREP(useMagazine); -PREP(waitAndExecute); -PREP(waitUntilAndExecute); +PREP(watchVariable); PREP(waveHeightAt); PREP(translateToWeaponSpace); @@ -183,14 +194,12 @@ PREP(translateToModelSpace); PREP(worldToScreenBounds); // config items -PREP(getConfigType); PREP(getItemType); PREP(getWeaponType); PREP(getWeaponModes); PREP(getWeaponMuzzles); // config objects -PREP(getConfigTypeObject); PREP(getConfigGunner); PREP(getConfigCommander); PREP(getSelectionsWithoutHitPoints); @@ -211,10 +220,6 @@ PREP(getTurretsFFV); PREP(getTurretsOther); PREP(hasHatch); -// missing inventory commands -PREP(binocularMagazine); -PREP(removeBinocularMagazine); - // ACE_Debug PREP(getChildren); PREP(getDisplayConfigName); @@ -224,15 +229,6 @@ PREP(showUser); PREP(dumpPerformanceCounters); PREP(dumpArray); -PREP(globalEvent); -PREP(addEventHandler); -PREP(objectEvent); -PREP(targetEvent); -PREP(serverEvent); -PREP(localEvent); -PREP(removeEventHandler); -PREP(removeAlLEventHandlers); - // Synchronized Events PREP(syncedEventPFH); PREP(addSyncedEventHandler); @@ -247,17 +243,8 @@ PREP(_handleRequestAllSyncedEvents); // other eventhandlers PREP(addActionEventHandler); PREP(addActionMenuEventHandler); -PREP(addScrollWheelEventHandler); PREP(addMapMarkerCreatedEventHandler); PREP(removeActionEventHandler); PREP(removeActionMenuEventHandler); -PREP(removeScrollWheelEventHandler); PREP(removeMapMarkerCreatedEventHandler); - -// hashes -PREP(hashCreate); -PREP(hashSet); -PREP(hashGet); -PREP(hashHasKey); -PREP(hashRem); diff --git a/addons/common/XEH_missionDisplayLoad.sqf b/addons/common/XEH_missionDisplayLoad.sqf index a07c301288..f1657703c0 100644 --- a/addons/common/XEH_missionDisplayLoad.sqf +++ b/addons/common/XEH_missionDisplayLoad.sqf @@ -1,4 +1,3 @@ #include "script_component.hpp" -call COMPILE_FILE(init_handleScrollWheel); call COMPILE_FILE(init_handleModifierKey); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index a930fba126..ce6126cba7 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -19,37 +19,64 @@ //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); + // May report nil. Default to factor 1. + private _vis = [_object getUnitTrait "camouflageCoef"] param [0, 1]; + 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]; @@ -65,7 +92,7 @@ if (isServer) then { if ((!isNil "_zeusLogic") && {!isNull _zeusLogic}) then { { if ((_x getvariable ["bis_fnc_moduleRemoteControl_owner", objnull]) isEqualTo _dcPlayer) exitWith { - ACE_LOGINFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`", [_x] call FUNC(getName), _dcPlayer, _x); + INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`", [_x] call FUNC(getName), _dcPlayer, _x); _x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true]; }; nil @@ -74,24 +101,10 @@ 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"]; - ACE_LOGINFO_2("Headbug Used: Name: %1, Animation: %2",_profileName,_animation); + INFO_2("Headbug Used: Name: %1, Animation: %2",_profileName,_animation); }] call CBA_fnc_addEventHandler; [QGVAR(fixCollision), FUNC(fixCollision)] call CBA_fnc_addEventHandler; @@ -123,6 +136,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; @@ -133,6 +147,7 @@ if (isServer) then { if (isServer) then { [QGVAR(hideObjectGlobal), {(_this select 0) hideObjectGlobal (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(enableSimulationGlobal), {(_this select 0) enableSimulationGlobal (_this select 1)}] call CBA_fnc_addEventHandler; + [QGVAR(setShotParents), {(_this select 0) setShotParents [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; ["ace_setOwner", {(_this select 0) setOwner (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(serverLog), FUNC(serverLog)] call CBA_fnc_addEventHandler; }; @@ -146,7 +161,7 @@ if (isServer) then { // Handle JIP scenario if (!isServer) then { ["ace_playerJIP", { - ACE_LOGINFO("JIP event synchronization initialized"); + INFO("JIP event synchronization initialized"); ["ACEa", [player]] call CBA_fnc_serverEvent; }] call CBA_fnc_addEventHandler; } else { @@ -170,8 +185,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]; }; @@ -190,60 +205,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]; - ACE_LOGINFO("Waiting on settings from server..."); - }; - }; - - [_this select 1] call CBA_fnc_removePerFrameHandler; - - ACE_LOGINFO("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); - }; - - ACE_LOGINFO("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; - ACE_LOGINFO_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; /***************************************************************************/ @@ -282,11 +243,11 @@ enableCamShake true; params ["_newPlayer","_oldPlayer"]; if (alive _newPlayer) then { - [_newPlayer] call FUNC(setName); + [FUNC(setName), [_newPlayer]] call CBA_fnc_execNextFrame; }; if (alive _oldPlayer) then { - [_oldPlayer] call FUNC(setName); + [FUNC(setName), [_oldPlayer]] call CBA_fnc_execNextFrame; }; }] call CBA_fnc_addPlayerEventHandler; @@ -295,82 +256,14 @@ enableCamShake true; // Set up numerous eventhanders for player controlled units ////////////////////////////////////////////////// -// It is possible that CBA_fnc_addPlayerEventHandler has allready been called and run -// We will NOT get any events for the initial state, so manually set ACE_player -if (!isNull (missionNamespace getVariable ["cba_events_oldUnit", objNull])) then { - // INFO("CBA_fnc_addPlayerEventHandler has already run - manually setting ace_player"); //ToDo CBA 3.1 - diag_log text "[ACE-Common - CBA_fnc_addPlayerEventHandler has already run - manually setting ace_player"; - ACE_player = cba_events_oldUnit; -}; - -// "playerChanged" event +TRACE_1("adding unit playerEH to set ace_player",isNull cba_events_oldUnit); ["unit", { ACE_player = (_this select 0); - ["ace_playerChanged", _this] call CBA_fnc_localEvent; -}] call CBA_fnc_addPlayerEventHandler; +}, true] call CBA_fnc_addPlayerEventHandler; -// "playerVehicleChanged" event -["vehicle", { - ["ace_playerVehicleChanged", _this] call CBA_fnc_localEvent; -}] call CBA_fnc_addPlayerEventHandler; - -// "playerTurretChanged" event -["turret", { - ["ace_playerTurretChanged", _this] call CBA_fnc_localEvent; -}] call CBA_fnc_addPlayerEventHandler; - -// "playerWeaponChanged" event -["weapon", { - ["ace_playerWeaponChanged", _this] call CBA_fnc_localEvent; -}] call CBA_fnc_addPlayerEventHandler; - -// "playerInventoryChanged" event +// Clear uniqueItems cache on loadout change ["loadout", { - private _fnc_getAllGear = { - if (isNull _this) exitWith {[ - "", - "", - "", [], - "", [], - "", [], - "", ["","","",""], [], - "", ["","","",""], [], - "", ["","","",""], [], - [], - "", - "" - ]}; - - [ - headgear _this, - goggles _this, - uniform _this, uniformItems _this, - vest _this, vestItems _this, - backpack _this, backpackItems _this, - primaryWeapon _this, primaryWeaponItems _this, primaryWeaponMagazine _this, - secondaryWeapon _this, secondaryWeaponItems _this, secondaryWeaponMagazine _this, - handgunWeapon _this, handgunItems _this, handgunMagazine _this, - assignedItems _this, - binocular _this, - _this call CBA_fnc_binocularMagazine - ] - }; - - ["ace_playerInventoryChanged", [ACE_player, ACE_player call _fnc_getAllGear]] call CBA_fnc_localEvent; -}] call CBA_fnc_addPlayerEventHandler; - -// "playerVisionModeChanged" event -["visionMode", { - ["ace_playerVisionModeChanged", _this] call CBA_fnc_localEvent; -}] call CBA_fnc_addPlayerEventHandler; - -// "cameraViewChanged" event -["cameraView", { - ["ace_cameraViewChanged", _this] call CBA_fnc_localEvent; -}] call CBA_fnc_addPlayerEventHandler; - -["visibleMap", { - ["ace_visibleMapChanged", _this] call CBA_fnc_localEvent; + GVAR(uniqueItemsCache) = nil; }] call CBA_fnc_addPlayerEventHandler; GVAR(OldIsCamera) = false; @@ -389,6 +282,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 @@ -427,7 +363,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); @@ -445,7 +383,9 @@ GVAR(isReloading) = false; private _weapon = currentWeapon ACE_player; if (_weapon != "") then { - private _gesture = getText (configfile >> "CfgWeapons" >> _weapon >> "reloadAction"); + private _muzzle = currentMuzzle ACE_player; + private _wpnConfig = configFile >> "CfgWeapons" >> _weapon; + private _gesture = getText ([_wpnConfig >> _muzzle, _wpnConfig] select (_weapon isEqualTo _muzzle) >> "reloadAction"); if (_gesture == "") exitWith {}; //Ignore weapons with no reload gesture (binoculars) private _isLauncher = _weapon isKindOf ["Launcher", configFile >> "CfgWeapons"]; private _config = ["CfgGesturesMale", "CfgMovesMaleSdr"] select _isLauncher; @@ -530,8 +470,8 @@ GVAR(deviceKeyCurrentIndex) = -1; ["ACE3 Equipment", QGVAR(cycleDevice), (localize "STR_ACE_Common_cycleHandheldDevices"), { [1] call FUNC(deviceKeyFindValidIndex); if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false}; - _displayName = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 0); - _iconImage = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 1); + private _displayName = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 0); + private _iconImage = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 1); [_displayName, _iconImage] call FUNC(displayTextPicture); true }, diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index eca1aebf36..c29a0b5df4 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -3,10 +3,13 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +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) = []; @@ -16,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) = []; @@ -40,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 74e5691973..44af1ee7ce 100644 --- a/addons/common/config.cpp +++ b/addons/common/config.cpp @@ -3,7 +3,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_Box_Misc", "ACE_bananaItem"}; + units[] = {"ACE_Box_Misc", "ACE_bananaItem", "ACE_Flag_Black", "ACE_Flag_White"}; weapons[] = {"ACE_ItemCore","ACE_FakePrimaryWeapon", "ACE_Banana"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_main","ace_modules"}; @@ -14,70 +14,6 @@ class CfgPatches { }; }; -// This class will be deprecated in version 3.8.0 -class ACE_newEvents { - // Status effect events - forceWalk = QGVAR(forceWalk); - blockSprint = QGVAR(blockSprint); - setCaptive = QGVAR(setCaptive); - blockDamage = QGVAR(blockDamage); - blockEngine = QGVAR(blockEngine); - - // Public listenable events - PlayerJip = "ace_playerJIP"; - activeCameraChanged = "ace_activeCameraChanged"; - visibleMapChanged = "ace_visibleMapChanged"; - cameraViewChanged = "ace_cameraViewChanged"; - playerVisionModeChanged = "ace_playerVisionModeChanged"; - playerInventoryChanged = "ace_playerInventoryChanged"; - playerWeaponChanged = "ace_playerWeaponChanged"; - playerTurretChanged = "ace_playerTurretChanged"; - playerVehicleChanged = "ace_playerVehicleChanged"; - playerChanged = "ace_playerChanged"; - SettingsInitialized = "ace_settingsInitialized"; - SettingChanged = "ace_settingChanged"; - firedNonPlayerVehicle = "ace_firedNonPlayerVehicle"; - firedPlayerVehicleNonLocal = "ace_firedPlayerVehicleNonLocal"; - firedPlayerVehicle = "ace_firedPlayerVehicle"; - firedNonPlayer = "ace_firedNonPlayer"; - firedPlayerNonLocal = "ace_firedPlayerNonLocal"; - firedPlayer = "ace_firedPlayer"; - unloadPersonEvent = "ace_unloadPersonEvent"; - loadPersonEvent = "ace_loadPersonEvent"; - useItem = "ace_useItem"; - infoDisplayChanged = "ace_infoDisplayChanged"; - - // Internal callable events - setStatusEffect = QGVAR(setStatusEffect); - HeadbugFixUsed = QGVAR(headbugFixUsed); - InitSettingsFromModules = QGVAR(initSettingsFromModules); - enableSimulationGlobal = QGVAR(enableSimulationGlobal); - hideObjectGlobal = QGVAR(hideObjectGlobal); - fixPosition = QGVAR(fixPosition); - fixFloating = QGVAR(fixFloating); - fixCollision = QGVAR(fixCollision); - unlockVehicle = QGVAR(unlockVehicle); - lockVehicle = QGVAR(lockVehicle); - displayTextPicture = QGVAR(displayTextPicture); - displayTextStructured = QGVAR(displayTextStructured); - setVanillaHitPointDamage = QGVAR(setVanillaHitPointDamage); - setVectorDirAndUp = QGVAR(setVectorDirAndUp); - switchMove = QGVAR(switchMove); - playMoveNow = QGVAR(playMoveNow); - playMove = QGVAR(playMove); - setVelocity = QGVAR(setVelocity); - selectLeader = QGVAR(selectLeader); - setSpeaker = QGVAR(setSpeaker); - engineOn = QGVAR(engineOn); - setFuel = QGVAR(setFuel); - setDir = QGVAR(setDir); - - // Events framework - SEH_s = "ACEs"; - SEH = "ACEe"; - SEH_all = "ACEa"; -}; - #include "CfgEventHandlers.hpp" #include "CfgLocationTypes.hpp" @@ -109,7 +45,6 @@ class ACE_Rsc_Control_Base { idc = 1; type = 0; style = 48; - access = 0; lineSpacing = 0; moving = 1; text = ""; @@ -129,28 +64,14 @@ class ACE_Rsc_Control_Base { #include #include #include - -class CfgUIGrids { - class IGUI { - class Presets { - class Arma3 { - class Variables { - grid_ACE_displayText[] = {{((safezoneX + safezoneW) - (10 *(((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 *(((safezoneW / safezoneH) min 1.2) / 40)),safeZoneY + 0.175 * safezoneH, (10 *(((safezoneW / safezoneH) min 1.2) / 40)), (2 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))}, "(((safezoneW / safezoneH) min 1.2) / 40)","((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"}; - }; - }; - }; - - class Variables { - class grid_ACE_displayText { - displayName = "ACE Hint"; - description = "Textual in game feedback to the player."; - preview = "\a3\Ui_f\data\GUI\Cfg\UIGrids\grid_hint_ca.paa"; - saveToProfile[] = {0,1}; - }; - }; - }; -}; +#include "CompassControl.hpp" +#include "CfgUIGrids.hpp" class ACE_Extensions { extensions[] = {}; }; + +class ACE_Tests { + vehicleTransportInventory = QPATHTOF(dev\test_vehicleInventory.sqf); + mapConfigs = QPATHTOF(dev\test_mapConfigs.sqf); +}; diff --git a/addons/common/data/ace_flag_black_ca.paa b/addons/common/data/ace_flag_black_ca.paa new file mode 100644 index 0000000000..54d314bd84 Binary files /dev/null and b/addons/common/data/ace_flag_black_ca.paa differ diff --git a/addons/common/data/ace_flag_black_preview.jpg b/addons/common/data/ace_flag_black_preview.jpg new file mode 100644 index 0000000000..fd997b356a Binary files /dev/null and b/addons/common/data/ace_flag_black_preview.jpg differ diff --git a/addons/common/data/ace_flag_white_ca.paa b/addons/common/data/ace_flag_white_ca.paa new file mode 100644 index 0000000000..5c665922b4 Binary files /dev/null and b/addons/common/data/ace_flag_white_ca.paa differ diff --git a/addons/common/data/ace_flag_white_preview.jpg b/addons/common/data/ace_flag_white_preview.jpg new file mode 100644 index 0000000000..3dba63e190 Binary files /dev/null and b/addons/common/data/ace_flag_white_preview.jpg differ 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_ASLToPosition.sqf b/addons/common/functions/fnc_ASLToPosition.sqf index a5afb1db75..81e99ef8c3 100644 --- a/addons/common/functions/fnc_ASLToPosition.sqf +++ b/addons/common/functions/fnc_ASLToPosition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Converts ASL to Arma "Position" @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [1, 2, 3] call ace_common_fnc_ASLToPosition + * * Public: No */ -#include "script_component.hpp" if (surfaceIsWater _this) then { _this diff --git a/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf index 763874de82..dfdbe4db54 100644 --- a/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf +++ b/addons/common/functions/fnc__handleRequestAllSyncedEvents.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: jaynus * Handles a server-side request for synchronization ALL events on JIP to a client. @@ -8,13 +9,16 @@ * Return Value: * Event is successed * + * Example: + * [bob] call ace_common_fnc__handleRequestAllSyncedEvents + * * Public: No */ -#include "script_component.hpp" params ["_client"]; [GVAR(syncedEvents), { + //IGNORE_PRIVATE_WARNING ["_key", "_value"]; _value params ["", "_eventLog"]; ["ACEs", [_key, _eventLog], _client] call CBA_fnc_targetEvent; diff --git a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf index 131ae56f7f..1e038c40bc 100644 --- a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf @@ -1,21 +1,25 @@ +#include "script_component.hpp" /* * Author: jaynus * Receives either requests for synchronization from clients, or the synchronization data from the server. * - * Arguments [Client] : + * Arguments [Client]: * 0: eventName * 1: eventLog * - * Arguments [Server] : + * Arguments [Server]: * 0: eventName * 1: client * * Return Value: * Event is successed * + * Example: + * ["name", [LOG]] call ace_common_fnc__handleRequestSyncedEvent //Client + * ["name", bob] call ace_common_fnc__handleRequestSyncedEvent//Server + * * Public: No */ -#include "script_component.hpp" //SEH_s if (isServer) then { @@ -23,7 +27,7 @@ if (isServer) then { params ["_eventName", "_client"]; if !([GVAR(syncedEvents), _eventName] call CBA_fnc_hashHasKey) exitWith { - ACE_LOGERROR_1("Request for synced event - key [%1] not found.", _eventName); + ERROR_1("Request for synced event - key [%1] not found.", _eventName); false }; @@ -42,7 +46,7 @@ if (isServer) then { false } count _eventLog; - ACE_LOGINFO_1("[%1] synchronized",_eventName); + INFO_1("[%1] synchronized",_eventName); }; true diff --git a/addons/common/functions/fnc__handleSyncedEvent.sqf b/addons/common/functions/fnc__handleSyncedEvent.sqf index b818ed257c..a7fa657a5f 100644 --- a/addons/common/functions/fnc__handleSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleSyncedEvent.sqf @@ -1,8 +1,9 @@ +#include "script_component.hpp" /* * Author: jaynus * Handles synced events being received. Server will log them, and server/client will execute them. * - * Arguments [Client] : + * Arguments: [Client] * 0: eventName * 1: arguments * 2: ttl @@ -10,14 +11,16 @@ * Return Value: * Boolean of success * + * Example: + * [bob] call ace_common_fnc__handleSyncedEvent + * * Public: No */ -#include "script_component.hpp" params ["_name", "_args", "_ttl"]; if !([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { - ACE_LOGERROR_1("Synced event key [%1] not found (_handleSyncedEvent).", _name); + ERROR_1("Synced event key [%1] not found (_handleSyncedEvent).", _name); false }; diff --git a/addons/common/functions/fnc_actionKeysNamesConverted.sqf b/addons/common/functions/fnc_actionKeysNamesConverted.sqf index fae1fb939e..53ebba0cd6 100644 --- a/addons/common/functions/fnc_actionKeysNamesConverted.sqf +++ b/addons/common/functions/fnc_actionKeysNamesConverted.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Reports same as actionKeysNames(Array) but in a format processable by "keyDown". @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define LAST_DIK 250 #define PLACEHOLDER_PLUS "" diff --git a/addons/common/functions/fnc_addActionEventHandler.sqf b/addons/common/functions/fnc_addActionEventHandler.sqf index 56d2de16db..8fafef07cf 100644 --- a/addons/common/functions/fnc_addActionEventHandler.sqf +++ b/addons/common/functions/fnc_addActionEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Add an addAction event to a unit. Used to handle multiple addAction events. Global arguments, local effects. Does only work for player controlled units. @@ -11,9 +12,11 @@ * Return Value: * ID of the action (used to remove it later) * + * Example: + * [bob, "DefaultAction", "condition", "execute"] call ace_common_fnc_addActionEventHandler + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_action", "_condition", "_statement"]; diff --git a/addons/common/functions/fnc_addActionMenuEventHandler.sqf b/addons/common/functions/fnc_addActionMenuEventHandler.sqf index c86cf45f17..67d531c22e 100644 --- a/addons/common/functions/fnc_addActionMenuEventHandler.sqf +++ b/addons/common/functions/fnc_addActionMenuEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Add an addAction event to a unit. Used to handle multiple addAction events and add a action to the mouse wheel menu. Global arguments, local effects. Does only work for player controlled units. @@ -15,9 +16,11 @@ * Return Value: * ID of the action (used to remove it later) * + * Example: + * [bob, "Title", "DefaultAction", "condition", "execute", "conditionmenu", "executemenu", 5] call ace_common_fnc_addActionMenuEventHandler + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_displayName", "_action", "_condition", "_statement", "_condition2", "_statement2", ["_priority", 0]]; diff --git a/addons/common/functions/fnc_addCanInteractWithCondition.sqf b/addons/common/functions/fnc_addCanInteractWithCondition.sqf index 294dac1c72..5db1a79a3d 100644 --- a/addons/common/functions/fnc_addCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_addCanInteractWithCondition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Add a condition that gets checked by ace_common_fnc_canInteractWith. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * ["ID", {Condition}] call ace_common_fnc_addCanInteractWithCondition + * * Public: No */ -#include "script_component.hpp" params ["_conditionName", "_conditionFunc"]; diff --git a/addons/common/functions/fnc_addEventHandler.sqf b/addons/common/functions/fnc_addEventHandler.sqf deleted file mode 100644 index 6ded410c87..0000000000 --- a/addons/common/functions/fnc_addEventHandler.sqf +++ /dev/null @@ -1,14 +0,0 @@ -#define DEBUG_MODE_FULL -#include "script_component.hpp" - -params ["_eventName", "_eventCode"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -[_eventName, _eventCode] call CBA_fnc_addEventHandler; - -ACE_DEPRECATED("ace_common_fnc_addEventHandler","3.8.0","CBA_fnc_addEventHandler"); diff --git a/addons/common/functions/fnc_addLineToDebugDraw.sqf b/addons/common/functions/fnc_addLineToDebugDraw.sqf index f0a643e922..3056d750d6 100644 --- a/addons/common/functions/fnc_addLineToDebugDraw.sqf +++ b/addons/common/functions/fnc_addLineToDebugDraw.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Add line to draw on debug @@ -7,11 +8,16 @@ * 1: End point ASL * 2: Color * + * Return Value: * None * + * Example: + * [[0,0,0], [1,1,0], [1,0,0,1]] call ace_common_fnc_addLineToDebugDraw; + * * Public: No */ -#include "script_component.hpp" + +params ["_startASL", "_endASL", "_color"]; if (isNil QGVAR(debugLines)) then { GVAR(debugLines) = []; @@ -19,30 +25,23 @@ if (isNil QGVAR(debugLines)) then { }; if (count GVAR(debugLines) < 100) then { - GVAR(debugLines) pushBack _this; + GVAR(debugLines) pushBack [ASLtoAGL _startASL, ASLtoAGL _endASL, _color]; GVAR(debugLinesIndex) = 0; } else { - GVAR(debugLines) set [GVAR(debugLinesIndex), _this]; + GVAR(debugLines) set [GVAR(debugLinesIndex), [ASLtoAGL _startASL, ASLtoAGL _endASL, _color]]; GVAR(debugLinesIndex) = (GVAR(debugLinesIndex) + 1) mod 100; }; if (isNil QGVAR(debugDrawHandler)) then { GVAR(debugDrawHandler) = addMissionEventHandler ["Draw3D", { - if (count GVAR(debugLines) == 0) exitWith { + if (GVAR(debugLines) isEqualTo []) exitWith { removeMissionEventHandler ["Draw3D", GVAR(debugDrawHandler)]; GVAR(debugDrawHandler) = nil; }; { - _p0 = _x select 0; - if (!surfaceIsWater _p0) then { - _p0 = ASLtoATL _p0; - }; - _p1 = _x select 1; - if (!surfaceIsWater _p1) then { - _p1 = ASLtoATL _p1; - }; - drawLine3D [_p0, _p1, _x select 2]; + _x params ["_start", "_end", "_color"]; + drawLine3D [_start, _end, _color]; } forEach GVAR(debugLines); }]; }; diff --git a/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf b/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf index 2201426e48..c698d30272 100644 --- a/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf +++ b/addons/common/functions/fnc_addMapMarkerCreatedEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Add a map marker creation event handler. @@ -8,9 +9,11 @@ * Return Value: * ID of the event script (used to remove it later). * + * Example: + * ["bob"] call ace_common_fnc_addMapMarkerCreatedEventHandler + * * Public: Yes */ -#include "script_component.hpp" params ["_statement"]; diff --git a/addons/common/functions/fnc_addScrollWheelEventHandler.sqf b/addons/common/functions/fnc_addScrollWheelEventHandler.sqf deleted file mode 100644 index 2a9b26e71c..0000000000 --- a/addons/common/functions/fnc_addScrollWheelEventHandler.sqf +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Author: commy2 - * Add an event handler that executes every time the scroll wheel is used. This is needed, because adding a MouseZ display event handler to display 46 will break in save games. - * _this will be [Interval] where 'Interval' is a number. - * - * Arguments: - * 0: Code to execute - * - * Return Value: - * ID of the event script (used to remove it later). - * - * Public: Yes - */ -#include "script_component.hpp" - -params ["_statement"]; - -ACE_DEPRECATED("ace_common_fnc_addScrollWheelEventHandler", "3.8.0", "'MouseZChanged' Display EventHandler"); - -if (_statement isEqualType "") then { - _statement = compile _statement; -}; - -private _actionsVar = missionNamespace getVariable ["ACE_EventHandler_ScrollWheel", [-1, [], []]]; - -_actionsVar params ["_id", "_actionIDs", "_actions"]; - -_id = _id + 1; - -_actionIDs pushBack _id; -_actions pushBack _statement; - -missionNamespace setVariable ["ACE_EventHandler_ScrollWheel", [_id, _actionIDs, _actions]]; - -_id diff --git a/addons/common/functions/fnc_addSetting.sqf b/addons/common/functions/fnc_addSetting.sqf deleted file mode 100644 index c4b97ddcce..0000000000 --- a/addons/common/functions/fnc_addSetting.sqf +++ /dev/null @@ -1,40 +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 - * - * 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_addSyncedEventHandler.sqf b/addons/common/functions/fnc_addSyncedEventHandler.sqf index 6499f96ff4..3dd4f03152 100644 --- a/addons/common/functions/fnc_addSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_addSyncedEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: jaynus * Register an event handler for an ACE synced event @@ -15,12 +16,11 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_name", "_handler", ["_ttl", 0]]; if ([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { - ACE_LOGERROR_1("Duplicate synced event [%1] creation.",_name); + ERROR_1("Duplicate synced event [%1] creation.",_name); false }; diff --git a/addons/common/functions/fnc_addToInventory.sqf b/addons/common/functions/fnc_addToInventory.sqf index 9d796d6018..b8b5f93635 100644 --- a/addons/common/functions/fnc_addToInventory.sqf +++ b/addons/common/functions/fnc_addToInventory.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Adds an item, weapon, or magazine to the unit's inventory or places it in a weaponHolder if no space. @@ -12,15 +13,18 @@ * 0: Added to player * 1: weaponholder * + * Example: + * [bob, "classname", "", 5] call ace_common_fnc_addToInventory + * * Public: Yes */ -#include "script_component.hpp" 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": { @@ -131,7 +135,7 @@ switch (_type select 0) do { default { _addedToUnit = false; - ACE_LOGWARNING_2("Incorrect item type passed to %1, passed: %2",QFUNC(AddToInventory),_type); + WARNING_2("Incorrect item type passed to %1, passed: %2",QFUNC(AddToInventory),_type); }; }; diff --git a/addons/common/functions/fnc_ambientBrightness.sqf b/addons/common/functions/fnc_ambientBrightness.sqf index 4ec2840e47..608c35dfef 100644 --- a/addons/common/functions/fnc_ambientBrightness.sqf +++ b/addons/common/functions/fnc_ambientBrightness.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, idea by Falke * Returns a brightness value depending on the sun and moon state. Ranges from 0 to 1 (dark ... bright). @@ -8,8 +9,10 @@ * Return Value: * Ambient brightness * + * Example: + * [] call ace_common_fnc_ambientBrightness + * * Public: Yes */ -#include "script_component.hpp" (sunOrMoon * sunOrMoon * (1 - overcast * 0.25) + (moonIntensity / 5) * (1 - overcast)) min 1 diff --git a/addons/common/functions/fnc_arithmeticGetResult.sqf b/addons/common/functions/fnc_arithmeticGetResult.sqf new file mode 100644 index 0000000000..418d510d66 --- /dev/null +++ b/addons/common/functions/fnc_arithmeticGetResult.sqf @@ -0,0 +1,68 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets arithmetic result from a set. + * + * Arguments: + * 0: Namespace + * 1: Number Set ID + * 2: Operation (sum, product, min, max, avg) + * + * Return Value: + * Value + * + * Example: + * [ace_player, "ace_aimCoefficents", "product"] call ace_common_fnc_arithmeticGetResult + * [missionNameSpace, "ace_hearing", "min"] call ace_common_fnc_arithmeticGetResult + * + * Public: Yes + */ + +params ["_namespace", "_setID", "_op"]; +TRACE_3("params",_namespace,_setID,_op); + +private _data = (_namespace getVariable _setID) param [2, []]; + +switch (_op) do { + case ("sum"): { + private _result = 0; + { + _result = _result + (call _x); + nil + } count _data; + _result // return + }; + case ("product"): { + private _result = 1; + { + _result = _result * (call _x); + nil + } count _data; + _result // return + }; + case ("min"): { + private _result = 1e99; + { + _result = _result min (call _x); + nil + } count _data; + _result // return + }; + case ("max"): { + private _result = -1e99; + { + _result = _result max (call _x); + nil + } count _data; + _result // return + }; + case ("avg"): { + private _result = 0; + { + _result = _result + (call _x); + nil + } count _data; + _result / (count _data); // return + }; + default {3735928559}; +}; diff --git a/addons/common/functions/fnc_arithmeticSetSource.sqf b/addons/common/functions/fnc_arithmeticSetSource.sqf new file mode 100644 index 0000000000..0d7503aa90 --- /dev/null +++ b/addons/common/functions/fnc_arithmeticSetSource.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Adds or removes a source to an arithmetic set. + * + * Arguments: + * 0: Namespace + * 1: Number Set ID + * 2: Source + * 3: Code that returns a number (can access var _namespace) [use {} to remove] + * + * Return Value: + * None + * + * Example: + * [missionNameSpace, "ace_hearing", "myMission", {0.5}] call ace_common_fnc_arithmeticSetSource + * [ace_player, "ace_aimCoefficents", "ace_medical", {linearConversion [0,1,(_namespace getVariable "ace_medical_pain",1,0.2,true]}] call ace_common_fnc_arithmeticSetSource + * + * Public: Yes + */ + +params ["_namespace", "_setID", "_source", "_variable"]; +TRACE_4("params",_namespace,_setID,_source,_variable); + +private _hash = _namespace getVariable _setID; +if (isNil "_hash") then { + _hash = [] call CBA_fnc_hashCreate; + _namespace setVariable [_setID, _hash]; +}; +if (_variable isEqualTo {}) then { + TRACE_1("removing",_source); + [_hash, _source] call CBA_fnc_hashRem; +} else { + TRACE_2("adding",_source,_variable); + [_hash, _source, _variable] call CBA_fnc_hashSet; +}; + +nil diff --git a/addons/common/functions/fnc_assignObjectsInList.sqf b/addons/common/functions/fnc_assignObjectsInList.sqf index 5724521a7b..764675fa5f 100644 --- a/addons/common/functions/fnc_assignObjectsInList.sqf +++ b/addons/common/functions/fnc_assignObjectsInList.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Loops through a string and filters out object names/variables to assign a value for given variable. @@ -18,7 +19,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_list", "_variable", "_setting", "_global", ["_vehicle", false]]; diff --git a/addons/common/functions/fnc_assignedItemFix.sqf b/addons/common/functions/fnc_assignedItemFix.sqf index 9a4ac5bf47..3f523f4a59 100644 --- a/addons/common/functions/fnc_assignedItemFix.sqf +++ b/addons/common/functions/fnc_assignedItemFix.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Initialized the assigned item fix. @@ -8,15 +9,17 @@ * Return Value: * None * - * Public : No + * Example: + * call ace_common_fnc_assignedItemFix + * + * Public: No */ -#include "script_component.hpp" -ACE_isMapEnabled = call {private _config = missionConfigFile >> "showMap"; !isNumber _config || {getNumber _config == 1}}; // default value is 1, so do isNumber check first -ACE_isCompassEnabled = call {private _config = missionConfigFile >> "showCompass"; !isNumber _config || {getNumber _config == 1}}; -ACE_isWatchEnabled = call {private _config = missionConfigFile >> "showWatch"; !isNumber _config || {getNumber _config == 1}}; -ACE_isRadioEnabled = call {private _config = missionConfigFile >> "showRadio"; !isNumber _config || {getNumber _config == 1}}; -ACE_isGPSEnabled = call {private _config = missionConfigFile >> "showGPS"; !isNumber _config || {getNumber _config == 1}}; +ACE_isMapEnabled = getMissionConfigValue ["showMap", 1] in [true, 1]; +ACE_isCompassEnabled = getMissionConfigValue ["showCompass", 1] in [true, 1]; +ACE_isWatchEnabled = getMissionConfigValue ["showWatch", 1] in [true, 1]; +ACE_isRadioEnabled = getMissionConfigValue ["showRadio", 1] in [true, 1]; +ACE_isGPSEnabled = getMissionConfigValue ["showGPS", 1] in [true, 1]; GVAR(AssignedItems) = []; GVAR(AssignedItemsInfo) = []; diff --git a/addons/common/functions/fnc_binarizeNumber.sqf b/addons/common/functions/fnc_binarizeNumber.sqf index 0945afa770..780551756c 100644 --- a/addons/common/functions/fnc_binarizeNumber.sqf +++ b/addons/common/functions/fnc_binarizeNumber.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get a binary equivalent of a decimal number. @@ -9,9 +10,11 @@ * Return Value: * Booleans * + * Example: + * [5, 5] call ace_common_fnc_binarizeNumber + * * Public: Yes */ -#include "script_component.hpp" params ["_number", ["_minLength", 8]]; diff --git a/addons/common/functions/fnc_binocularMagazine.sqf b/addons/common/functions/fnc_binocularMagazine.sqf deleted file mode 100644 index aacac7c142..0000000000 --- a/addons/common/functions/fnc_binocularMagazine.sqf +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Author: commy2 - * Returns the magazine of the units rangefinder. - * - * Arguments: - * 0: Unit - * - * Return Value: - * Magazine of the units binocular - * - * Example: - * player call ace_common_fnc_binocularMagazine - * - * Public: Yes - */ -#include "script_component.hpp" - -ACE_DEPRECATED("ace_common_fnc_binocularMagazine","3.8.0","CBA_fnc_binocularMagazine"); - -_this call CBA_fnc_binocularMagazine diff --git a/addons/common/functions/fnc_blurScreen.sqf b/addons/common/functions/fnc_blurScreen.sqf index 4a6c0d3cb4..339a1138e6 100644 --- a/addons/common/functions/fnc_blurScreen.sqf +++ b/addons/common/functions/fnc_blurScreen.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: Glowbal * Blurs screen. * * Arguments: * 0: ID - * 1: Show? + * 1: Show? * * Return Value: * None @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" if (!hasInterface) exitWith {}; diff --git a/addons/common/functions/fnc_cachedCall.sqf b/addons/common/functions/fnc_cachedCall.sqf index 8ff6744a54..728303d6cd 100644 --- a/addons/common/functions/fnc_cachedCall.sqf +++ b/addons/common/functions/fnc_cachedCall.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain, Jaynus * Returns the result of the function and caches it up to a given time or event @@ -13,16 +14,18 @@ * Return Value: * Result of the function * + * Example: + * [[array]], {dothings}, NAMESPACE, "UID", 5, "clear"] call ace_common_fnc_cachedCall + * * Public: No */ -#include "script_component.hpp" params ["_params", "_function", "_namespace", "_uid", "_duration", "_event"]; if ((_namespace getVariable [_uid, [-99999]]) select 0 < diag_tickTime) then { _namespace setVariable [_uid, [diag_tickTime + _duration, _params call _function]]; - // Does the cache needs to be cleared on an event? + // Does the cache need to be cleared on an event? if (!isNil "_event") then { private _varName = format [QGVAR(clearCache_%1), _event]; private _cacheList = missionNamespace getVariable _varName; @@ -33,11 +36,12 @@ if ((_namespace getVariable [_uid, [-99999]]) select 0 < diag_tickTime) then { missionNamespace setVariable [_varName, _cacheList]; [_event, { - // _eventName is defined on the function that calls the event #ifdef DEBUG_MODE_FULL - ACE_LOGINFO_1("Clear cached variables on event: %1",_eventName); + INFO_1("Clear cached variables on event: %1",_eventName); #endif // Get the list of caches to clear + //IGNORE_PRIVATE_WARNING ["_eventName"]; + // _eventName is defined on the function that calls the event private _varName = format [QGVAR(clearCache_%1), _eventName]; private _cacheList = missionNamespace getVariable [_varName, []]; // Erase all the cached results @@ -54,9 +58,9 @@ if ((_namespace getVariable [_uid, [-99999]]) select 0 < diag_tickTime) then { }; #ifdef DEBUG_MODE_FULL - ACE_LOGINFO_2("Calculated result: %1 %2",_namespace,_uid); + INFO_2("Calculated result: %1 %2",_namespace,_uid); } else { - ACE_LOGINFO_2("Cached result: %1 %2",_namespace,_uid); + INFO_2("Cached result: %1 %2",_namespace,_uid); #endif }; diff --git a/addons/common/functions/fnc_canDig.sqf b/addons/common/functions/fnc_canDig.sqf new file mode 100644 index 0000000000..e96b44a478 --- /dev/null +++ b/addons/common/functions/fnc_canDig.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg, commy2 + * Checks if the player can dig on the surface below (enough dust). + * + * Arguments: + * 0: Unit + * + * Return Value: + * Can Dig + * + * Example: + * [ACE_player] call ace_common_fnc_canDig + * + * Public: No + */ + +params ["_unit"]; + +private _posASL = getPosASL _unit; + +if ((getPosATL _unit) select 2 > 0.05 || // Walking on objects, such as buildings, pavements, etc. + {surfaceIsWater _posASL} // posATL in low water (not as low to allow awalking) is negative +) exitWith {false}; + +private _surfaceClass = (surfaceType _posASL) select [1]; +private _config = configFile >> "CfgSurfaces" >> _surfaceClass; +private _surfaceType = getText (_config >> "soundEnviron"); +private _surfaceDust = getNumber (_config >> "dust"); + +TRACE_2("Surface",_surfaceType,_surfaceDust); + +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_canGetInPosition.sqf b/addons/common/functions/fnc_canGetInPosition.sqf index c470337d6a..22d885b38c 100644 --- a/addons/common/functions/fnc_canGetInPosition.sqf +++ b/addons/common/functions/fnc_canGetInPosition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Is the unit able to enter the vehicle in the given position? @@ -7,15 +8,16 @@ * 1: The vehicle to be entered * 2: Position. Can be "Driver", "Pilot", "Gunner", "Commander", "Copilot", "Turret", "FFV", "Codriver" or "Cargo" * 3: Check current distance to vehicles memory point? (default: false) - * 4: Index. "Turret", "FFV", "Codriver" and "Cargo" support this optional parameter. Which position should be taken. - * Note: This index is diffrent from Armas "cargoIndex". (default: next free index) + * 4: Index. "Turret", "FFV", "Codriver" and "Cargo" support this optional parameter. Which position should be taken. Note: This index is different from Armas "cargoIndex". (default: next free index) * * Return Value: * None * + * Example: + * [bob, car, "Pilot", true, "Turret"] call ace_common_fnc_canGetInPosition + * * Public: No */ -#include "script_component.hpp" #define CANGETINDRIVER (isNull (driver _vehicle) || {!alive driver _vehicle}) && {!lockedDriver _vehicle} && {getNumber (_config >> "isUav") != 1} #define CANGETINTURRETINDEX (isNull (_vehicle turretUnit _turret) || {!alive (_vehicle turretUnit _turret)}) && {!(_vehicle lockedTurret _turret)} && {getNumber (_config >> "isUav") != 1} diff --git a/addons/common/functions/fnc_canInteractWith.sqf b/addons/common/functions/fnc_canInteractWith.sqf index 7603452965..b67e57964f 100644 --- a/addons/common/functions/fnc_canInteractWith.sqf +++ b/addons/common/functions/fnc_canInteractWith.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit can interact. @@ -8,11 +9,13 @@ * 2: Exceptions. What general conditions are to skip? (default: []) * * Return Value: - * Unit can interact? + * Unit can interact? + * + * Example: + * [bob, target, []] call ace_common_fnc_canInteractWith * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_target", ["_exceptions", []]]; diff --git a/addons/common/functions/fnc_cbaSettings.sqf b/addons/common/functions/fnc_cbaSettings.sqf new file mode 100644 index 0000000000..4eb84d54da --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -0,0 +1,114 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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); + }; + }; +}; + +private _missionSettingsConfig = missionConfigFile >> "ACE_Settings"; +_countOptions = count _missionSettingsConfig; +TRACE_1("Reading settings from missionConfigFile",_countOptions); +for "_index" from 0 to (_countOptions - 1) do { + private _optionEntry = _missionSettingsConfig 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 + INFO_1("Creating new CBA setting for ace_setting from mission config [%1]",_settingName); + [_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..14d2b8c35a --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf @@ -0,0 +1,129 @@ +#define DEBUG_MODE_FULL +#include "script_component.hpp" +/* + * 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 + */ + +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")]; + _cbaValueInfoHint = "[values, titles, defaultIndex]"; + } 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)}", _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..ef529de955 --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf @@ -0,0 +1,104 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..2a2974ef24 --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..703e0263dc --- /dev/null +++ b/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf @@ -0,0 +1,42 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_changeProjectileDirection.sqf b/addons/common/functions/fnc_changeProjectileDirection.sqf index 89a8988306..f355662598 100644 --- a/addons/common/functions/fnc_changeProjectileDirection.sqf +++ b/addons/common/functions/fnc_changeProjectileDirection.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Adjust a projectiles velocity and dir + up vector. @@ -11,9 +12,11 @@ * Return Value: * None * + * Example: + * [bullet, 2, 5, 3] call ace_common_fnc_changeProjectileDirection + * * Public: No */ -#include "script_component.hpp" params ["_projectile", "_adjustDir", "_adjustUp", ["_adjustSpeed",0]]; diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index 9d5a2436c1..62a344952f 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Compares version numbers of PBOs and DLLs. @@ -8,24 +9,31 @@ * Return Value: * None * + * Example: + * call ace_common_fnc_checkFiles + * * Public: No */ -#include "script_component.hpp" /////////////// // check addons /////////////// private _version = getText (configFile >> "CfgPatches" >> "ace_main" >> "versionStr"); -ACE_LOGINFO_1("ACE is version %1.",_version); +INFO_1("ACE is version %1.",_version); //CBA Versioning check - close main display if using incompatible version private _cbaVersionAr = getArray (configFile >> "CfgPatches" >> "cba_main" >> "versionAr"); -private _cbaRequiredAr = (getArray (configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> "ACE" >> "dependencies" >> "CBA")) select 1; -ACE_LOGINFO_2("CBA is version %1 [min required %2]",_cbaVersionAr,_cbaRequiredAr); +private _cbaRequiredAr = getArray (configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> "ACE" >> "dependencies" >> "CBA") select 1; + +private _cbaVersionStr = _cbaVersionAr joinString "."; +private _cbaRequiredStr = _cbaRequiredAr joinString "."; + +INFO_2("CBA is version %1 (min required %2)",_cbaVersionStr,_cbaRequiredStr); + if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) then { - private _errorMsg = format ["CBA Version [%1] is outdated [required %2]", _cbaVersionAr, _cbaRequiredAr]; - ACE_LOGERROR(_errorMsg); + private _errorMsg = format ["CBA version %1 is outdated (required %2)", _cbaVersionStr, _cbaRequiredStr]; + ERROR(_errorMsg); if (hasInterface) then { ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); }; @@ -36,39 +44,60 @@ private _addons = "true" configClasses (configFile >> "CfgPatches");// _addons = _addons apply {toLower configName _x};// _addons = _addons select {_x find "ace_" == 0}; +private _oldCompats = []; { if (getText (configFile >> "CfgPatches" >> _x >> "versionStr") != _version) then { private _errorMsg = format ["File %1.pbo is outdated.", _x]; - ACE_LOGERROR(_errorMsg); + ERROR(_errorMsg); - if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + if ((_x select [0, 10]) != "ace_compat") then { + if (hasInterface) then { + ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + }; + } else { + _oldCompats pushBack _x; // Don't block game if it's just an old compat pbo }; }; false } count _addons; +if (!(_oldCompats isEqualTo [])) then { + [{ + // Lasts for ~10 seconds + ERROR_WITH_TITLE_1("The following ACE compatiblity PBOs are outdated", "%1", _this); + }, _oldCompats, 1] call CBA_fnc_waitAndExecute; +}; /////////////// // check dlls /////////////// if (toLower (productVersion select 6) in ["linux", "osx"]) then { - ACE_LOGINFO_2("Operating system does not support DLL file format"); + INFO_2("Operating system does not support DLL file format"); } else { { private _versionEx = _x callExtension "version"; if (_versionEx == "") then { - private _errorMsg = format ["Extension %1.dll not installed.", _x]; + private _extension = ".dll"; - ACE_LOGERROR(_errorMsg); + 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); if (hasInterface) then { ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); }; } else { // Print the current extension version - ACE_LOGINFO_2("Extension version: %1: %2",_x,_versionEx); + INFO_2("Extension version: %1: %2",_x,_versionEx); }; false } count getArray (configFile >> "ACE_Extensions" >> "extensions"); @@ -97,7 +126,7 @@ if (isMultiplayer) then { if (_version != GVAR(ServerVersion)) then { private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _version]; - ACE_LOGERROR(_errorMsg); + ERROR(_errorMsg); if (hasInterface) then { ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); @@ -106,9 +135,9 @@ if (isMultiplayer) then { _addons = _addons - GVAR(ServerAddons); if !(_addons isEqualTo []) then { - _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons]; + private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons]; - ACE_LOGERROR(_errorMsg); + ERROR(_errorMsg); if (hasInterface) then { ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); diff --git a/addons/common/functions/fnc_checkPBOs.sqf b/addons/common/functions/fnc_checkPBOs.sqf index 1328624a0c..b45fae45d6 100644 --- a/addons/common/functions/fnc_checkPBOs.sqf +++ b/addons/common/functions/fnc_checkPBOs.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Used to execute the checkPBOs module without placing the module. Don't use this together with the module. @@ -14,9 +15,11 @@ * Return Value: * None * + * Example: + * [0, false, ""] call ace_common_fnc_checkPBOs + * * Public: Yes */ -#include "script_component.hpp" params ["_mode", ["_checkAll", false], ["_whitelist", "", [""]]]; TRACE_3("params",_mode,_checkAll,_whitelist); @@ -63,7 +66,7 @@ if (!isServer) then { //[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - ACE_LOGERROR(_error); + ERROR(_error); if (_mode < 2) then { _text = composeText [lineBreak, parseText format ["%1", _text]]; diff --git a/addons/common/functions/fnc_claim.sqf b/addons/common/functions/fnc_claim.sqf index 214de6052b..5c291c78da 100644 --- a/addons/common/functions/fnc_claim.sqf +++ b/addons/common/functions/fnc_claim.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Unit claims the ownership over an object. This is used to prevent multiple players from draging the same ammo box or using up the same wheel when repairing etc. @@ -10,16 +11,18 @@ * Return Value: * None * + * Example: + * [bob, flag, true] call ace_common_fnc_claim + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", ["_lockTarget", false]]; private _owner = _target getVariable [QGVAR(owner), objNull]; if (!isNull _owner && {!isNull _unit} && {_unit != _owner}) then { - ACE_LOGERROR("Claiming already owned object."); + ERROR("Claiming already owned object."); }; // transfer this immediately @@ -27,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_codeToString.sqf b/addons/common/functions/fnc_codeToString.sqf index 62e4cb5698..b938148220 100644 --- a/addons/common/functions/fnc_codeToString.sqf +++ b/addons/common/functions/fnc_codeToString.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Removes the brackets around a code and returns the code as a string. It does nothing if the code is already a string. @@ -8,9 +9,11 @@ * Return Value: * Code * + * Example: + * ["bob"] call ace_common_fnc_codeToString + * * Public: Yes */ -#include "script_component.hpp" params ["_code"]; if (_code isEqualType "") exitWith {_code}; diff --git a/addons/common/functions/fnc_createOrthonormalReference.sqf b/addons/common/functions/fnc_createOrthonormalReference.sqf index e45bf269aa..d705086e85 100644 --- a/addons/common/functions/fnc_createOrthonormalReference.sqf +++ b/addons/common/functions/fnc_createOrthonormalReference.sqf @@ -1,8 +1,9 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Returns a orthonormal system of reference aligned with the supplied vector * - * Arguments: + * Arguments: * Vector to align the coordinate system with * * Return Value: @@ -10,9 +11,11 @@ * 1: Normalized Cross Product Vector * 2: Vector Cross Product * + * Example: + * [[0,0,0]] call ace_common_fnc_createOrthonormalReference + * * Public: Yes */ -#include "script_component.hpp" [_this] params [["_vector", [0,0,1], [[]], 3]]; diff --git a/addons/common/functions/fnc_currentChannel.sqf b/addons/common/functions/fnc_currentChannel.sqf index a78e2b0204..350f91c9a2 100644 --- a/addons/common/functions/fnc_currentChannel.sqf +++ b/addons/common/functions/fnc_currentChannel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns the current radio / chat / marker channel. @@ -8,9 +9,11 @@ * Return Value: * The current channel ("group", "side", "global", "command", "vehicle", "direct", "custom_X") * + * Example: + * [] call ace_common_fnc_currentChannel + * * Public: Yes */ -#include "script_component.hpp" #define CHANNELS ["global", "side", "command", "group", "vehicle", "direct"] #define CHANNELS_LOCALIZED [localize "str_channel_global", localize "str_channel_side", localize "str_channel_command", localize "str_channel_group", localize "str_channel_vehicle", localize "str_channel_direct"] diff --git a/addons/common/functions/fnc_debug.sqf b/addons/common/functions/fnc_debug.sqf index 019ce2abff..2e08a19faf 100644 --- a/addons/common/functions/fnc_debug.sqf +++ b/addons/common/functions/fnc_debug.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Print logging messages through the ACE framework. @@ -9,9 +10,11 @@ * Return Value: * Message is Printed * + * Example: + * [bob, 2] call ace_common_fnc_debug + * * Public: Yes */ -#include "script_component.hpp" #define DEFAULT_LOGGING_LEVEL -1 #define DEFAULT_TEXT_DISPLAY -1 diff --git a/addons/common/functions/fnc_debugModule.sqf b/addons/common/functions/fnc_debugModule.sqf index 125887183e..90ad5ab6ba 100644 --- a/addons/common/functions/fnc_debugModule.sqf +++ b/addons/common/functions/fnc_debugModule.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * ? @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * call ace_common_fnc_debugModule + * * Public: No */ -#include "script_component.hpp" params ["_entity"]; diff --git a/addons/common/functions/fnc_defineVariable.sqf b/addons/common/functions/fnc_defineVariable.sqf index 35a1e96d31..ba12d1c426 100644 --- a/addons/common/functions/fnc_defineVariable.sqf +++ b/addons/common/functions/fnc_defineVariable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Define a variable for the ACE variable framework @@ -13,9 +14,11 @@ * Return Value: * None * + * Example: + * ["bob", 1, true, "category", 1, true] call ace_common_fnc_defineVariable + * * Public: Yes */ -#include "script_component.hpp" params ["_name", "_value", "_defaultGlobal", "_category", ["_code", 0], ["_persistent", false]]; diff --git a/addons/common/functions/fnc_deprecateComponent.sqf b/addons/common/functions/fnc_deprecateComponent.sqf index 21905e8e4e..a723b733ec 100644 --- a/addons/common/functions/fnc_deprecateComponent.sqf +++ b/addons/common/functions/fnc_deprecateComponent.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Mark a component as deprecated and switches it to a new component if that is available @@ -15,7 +16,6 @@ * Example: * [["ace_sitting", "ace_sitting_enabled"], ["acex_sitting", "acex_sitting_enabled"], "3.7.0"] call ace_common_fnc_deprecateComponent; */ -#include "script_component.hpp" params ["_oldComponent", "_newComponent", "_version"]; @@ -40,20 +40,20 @@ if (_isDeprecatedLoaded && {!_isReplacementLoaded}) then { private _message = format[ "Component %1 is deprecated. It has been replaced by %2. The component %1 is no longer usable on this version. ", _oldComponentName, _newComponentName, _version]; systemChat format["ACE [ERROR] - %1", _message]; - ACE_LOGERROR(_message); + ERROR(_message); }; case (_componentMajor >= _major && {_componentMinor >= _minor-1}): { // Removed the next this version private _message = format[ "Component %1 is deprecated. It is replaced by %2. Please disable %1 and make use of %2. " + "The component (%1) will no longer be available from version %3 and later.", _oldComponentName, _newComponentName, _version]; systemChat format["ACE [WARNING] - %1", _message]; - ACE_LOGWARNING(_message); + WARNING(_message); }; case (_componentMajor == _major && {_componentMinor >= _minor - 2}): { // we are in a version leading up to removal private _message = format[ "Component %1 is deprecated. It is replaced by %2. Please disable %1 and make use of %2. " + "The component (%1) will no longer be available from version %3 and later.", _oldComponentName, _newComponentName, _version]; - ACE_LOGWARNING(_message); + WARNING(_message); }; default { }; diff --git a/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf b/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf index 02135e59db..1e8ea86a53 100644 --- a/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf +++ b/addons/common/functions/fnc_deviceKeyFindValidIndex.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Finds next valid index for the device array. * * Arguments: - * 0: Offset from currentIndex (use 1 to find next valid after current) or a displayName string (default: 0) + * 0: Offset from currentIndex (use 1 to find next valid after current) or a displayName string (default: 0) * * Return Value: * The new index (-1 if no valid) @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params [["_searchOffsetOrName", 0]]; @@ -28,7 +28,7 @@ if (_searchOffsetOrName isEqualType "") then { } forEach GVAR(deviceKeyHandlingArray); } else { if (count GVAR(deviceKeyHandlingArray) > 0) then { - _baseIndex = [GVAR(deviceKeyCurrentIndex) + _searchOffsetOrName, 0] select (GVAR(deviceKeyCurrentIndex) == -1); + private _baseIndex = [GVAR(deviceKeyCurrentIndex) + _searchOffsetOrName, 0] select (GVAR(deviceKeyCurrentIndex) == -1); for "_offset" from _baseIndex to (count GVAR(deviceKeyHandlingArray) - 1 + _baseIndex) do { private _realIndex = _offset % (count GVAR(deviceKeyHandlingArray)); diff --git a/addons/common/functions/fnc_deviceKeyRegisterNew.sqf b/addons/common/functions/fnc_deviceKeyRegisterNew.sqf index ce012fc3aa..2e6dbbee99 100644 --- a/addons/common/functions/fnc_deviceKeyRegisterNew.sqf +++ b/addons/common/functions/fnc_deviceKeyRegisterNew.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Finds next valid index for the device array. @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_displayName", "_iconImage", "_conditionCode", "_toggleCode", "_closeCode"]; diff --git a/addons/common/functions/fnc_disableAI.sqf b/addons/common/functions/fnc_disableAI.sqf index 5dc3cdfbb2..88b6f2bd49 100644 --- a/addons/common/functions/fnc_disableAI.sqf +++ b/addons/common/functions/fnc_disableAI.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Disables/Enables AI @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_disable", true, [false]]]; @@ -30,7 +30,7 @@ if !([_unit] call EFUNC(common,isPlayer)) then { } else { //Sanity check to make sure we don't enable unconsious AI if (_unit getVariable ["ace_isunconscious", false] && alive _unit) exitWith { - ACE_LOGERROR("Enabling AI for unconsious unit"); + ERROR("Enabling AI for unconsious unit"); }; _unit enableAI "MOVE"; diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index 8e28edc5f0..44468641f3 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Disables key input. ESC can still be pressed to open the menu. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [true] call ace_common_fnc_disableUserInput + * * Public: No */ -#include "script_component.hpp" params ["_state"]; diff --git a/addons/common/functions/fnc_displayIcon.sqf b/addons/common/functions/fnc_displayIcon.sqf index ff8598d056..11e9f5d6e7 100644 --- a/addons/common/functions/fnc_displayIcon.sqf +++ b/addons/common/functions/fnc_displayIcon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Draw progress bar and execute given function if succesful. @@ -18,7 +19,6 @@ * * Public: Yes */ -#include "script_component.hpp" // positions for the icon UI #define RIGHT_SIDE (safezoneW + safezoneX) diff --git a/addons/common/functions/fnc_displayText.sqf b/addons/common/functions/fnc_displayText.sqf index ee22f6949a..f34a0cdfcd 100644 --- a/addons/common/functions/fnc_displayText.sqf +++ b/addons/common/functions/fnc_displayText.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Display a message. @@ -11,9 +12,11 @@ * Return Value: * None * + * Example: + * ["Message", true, 5, 2] call ace_common_fnc_displayText + * * Public: Yes */ -#include "script_component.hpp" params ["_text", ["_sound", false], ["_delay", 2], ["_priority", 0]]; diff --git a/addons/common/functions/fnc_displayTextPicture.sqf b/addons/common/functions/fnc_displayTextPicture.sqf index b0c42824be..b25945382f 100644 --- a/addons/common/functions/fnc_displayTextPicture.sqf +++ b/addons/common/functions/fnc_displayTextPicture.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, Glowbal * Display a structured text with image. @@ -18,7 +19,6 @@ * * Public: Yes */ -#include "script_component.hpp" params [["_text", ""], ["_image", "", [""]], ["_imageColor", [1,1,1], [[]]], ["_target", ACE_player, [objNull]], ["_size", 2, [0]]]; diff --git a/addons/common/functions/fnc_displayTextStructured.sqf b/addons/common/functions/fnc_displayTextStructured.sqf index e952fce9a4..e54e481b5a 100644 --- a/addons/common/functions/fnc_displayTextStructured.sqf +++ b/addons/common/functions/fnc_displayTextStructured.sqf @@ -1,23 +1,25 @@ +#include "script_component.hpp" /* - * Author: commy2, Glowbal + * Author: commy2, Glowbal, GitHawk * Display a structured text. * * Arguments: * 0: Text * 1: Size of the textbox (default: 1.5) * 2: Target Unit. Will only display if target is the player controlled object (default: ACE_player) + * 3: Custom Width (default: 10) * * Return Value: * None * * Example: - * + * [["Test: %1", 123], 1.5] call ace_common_fnc_displayTextStructured + * ["wow", 1, ace_player, 3] call ace_common_fnc_displayTextStructured * * Public: Yes */ -#include "script_component.hpp" -params [["_text", ""], ["_size", 1.5, [0]], ["_target", ACE_player, [objNull]]]; +params [["_text", ""], ["_size", 1.5, [0]], ["_target", ACE_player, [objNull]], ["_width", 10, [0]]]; if (_target != ACE_player) exitWith {}; @@ -47,25 +49,23 @@ private _ctrlHint = uiNamespace getVariable "ACE_ctrlHint"; _ctrlHint ctrlSetBackgroundColor GVAR(displayTextColor); _ctrlHint ctrlSetTextColor GVAR(displayTextFontColor); -/* -// This does not function at the moment. Has been disabled until it fixed. + +// Use profile settings from CfgUIGrids.hpp private _xPos = profilenamespace getVariable ["IGUI_GRID_ACE_displayText_X", ((safezoneX + safezoneW) - (10 *(((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 *(((safezoneW / safezoneH) min 1.2) / 40))]; private _yPos = profilenamespace getVariable ["IGUI_GRID_ACE_displayText_Y", safeZoneY + 0.175 * safezoneH]; -private _wPos = profilenamespace getVariable ["IGUI_GRID_ACE_displayText_W", (10 *(((safezoneW / safezoneH) min 1.2) / 40))]; -private _hPos = profilenamespace getVariable ["IGUI_GRID_ACE_displayText_H", (2 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))]; -*/ +private _wPos = (_width *(((safezoneW / safezoneH) min 1.2) / 40)); +private _hPos = _size * (2 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)); -private _xPos = ((safezoneX + safezoneW) - (10 *(((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 *(((safezoneW / safezoneH) min 1.2) / 40)); -private _yPos = safeZoneY + 0.175 * safezoneH; -private _wPos = (10 *(((safezoneW / safezoneH) min 1.2) / 40)); -private _hPos = (2 *((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)); +// Ensure still in bounds for large width/height +_xPos = safezoneX max (_xPos min (safezoneX + safezoneW - _wPos)); +_yPos = safeZoneY max (_yPos min (safeZoneY + safezoneH - _hPos)); // Zeus Interface Open and Display would be under the "CREATE" list if (!isNull curatorCamera) then { _xPos = _xPos min ((safezoneX + safezoneW - 12.5 * (((safezoneW / safezoneH) min 1.2) / 40)) - _wPos); }; -private _position = [_xPos, _yPos, _wPos, _size * _hPos]; +private _position = [_xPos, _yPos, _wPos, _hPos]; _ctrlHint ctrlSetPosition _position; _ctrlHint ctrlCommit 0; diff --git a/addons/common/functions/fnc_doAnimation.sqf b/addons/common/functions/fnc_doAnimation.sqf index 720518d003..678f4d4ef7 100644 --- a/addons/common/functions/fnc_doAnimation.sqf +++ b/addons/common/functions/fnc_doAnimation.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Execute an animation. This is used to not break things like the unconsciousness animation. @@ -19,7 +20,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_animation", ["_priority", 0], ["_force", false]]; TRACE_4("params",_unit,_animation,_priority,_force); diff --git a/addons/common/functions/fnc_doGesture.sqf b/addons/common/functions/fnc_doGesture.sqf index 9805beffc7..3aa4656cfd 100644 --- a/addons/common/functions/fnc_doGesture.sqf +++ b/addons/common/functions/fnc_doGesture.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Play a gesture. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_animation", ["_priority", 0]]; TRACE_3("params",_unit,_animation,_priority); diff --git a/addons/common/functions/fnc_dropBackpack.sqf b/addons/common/functions/fnc_dropBackpack.sqf index b0d77af7d5..38f1be8a52 100644 --- a/addons/common/functions/fnc_dropBackpack.sqf +++ b/addons/common/functions/fnc_dropBackpack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Drops a backback. Also returns the ground wepaon holder object of the dropped backpack. @@ -8,9 +9,11 @@ * Return Value: * Ground wepaon holder with backpack * + * Example: + * [unit] call ace_common_fnc_dropBackpack + * * Public: Yes */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_dummy.sqf b/addons/common/functions/fnc_dummy.sqf new file mode 100644 index 0000000000..a70fed35c0 --- /dev/null +++ b/addons/common/functions/fnc_dummy.sqf @@ -0,0 +1,12 @@ +/* + * Author: SilentSpike + * A dummy function which does nothing. Can be useful. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No + */ diff --git a/addons/common/functions/fnc_dumpArray.sqf b/addons/common/functions/fnc_dumpArray.sqf index b274f1119e..4997ad119a 100644 --- a/addons/common/functions/fnc_dumpArray.sqf +++ b/addons/common/functions/fnc_dumpArray.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: ? * Dumps an array to the RPT, showing the depth of each element. * * Arguments: * 0: Array to be dumped - * 1: Depth + * 1: Depth (default: 0) * * Return Value: * None @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_var", ["_depth", 0, [0]]]; diff --git a/addons/common/functions/fnc_dumpPerformanceCounters.sqf b/addons/common/functions/fnc_dumpPerformanceCounters.sqf index ec6f225ce4..2dad092a2c 100644 --- a/addons/common/functions/fnc_dumpPerformanceCounters.sqf +++ b/addons/common/functions/fnc_dumpPerformanceCounters.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: ? * Dumps performance counter statistics into Logs. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * call ace_common_fnc_dumpPerformanceCounters + * * Public: No */ -#include "script_component.hpp" diag_log text format ["REGISTERED ACE PFH HANDLERS"]; diag_log text format ["-------------------------------------------"]; diff --git a/addons/common/functions/fnc_endRadioTransmission.sqf b/addons/common/functions/fnc_endRadioTransmission.sqf index 4597426d67..16985a8773 100644 --- a/addons/common/functions/fnc_endRadioTransmission.sqf +++ b/addons/common/functions/fnc_endRadioTransmission.sqf @@ -1,7 +1,8 @@ +#include "script_component.hpp" /* * 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 @@ -9,9 +10,13 @@ * Return Value: * None * + * Example: + * call ace_common_fnc_endRadioTransmission + * * Public: No */ -#include "script_component.hpp" + +["ace_endRadioTransmissions"] call CBA_fnc_localEvent; // ACRE if (isClass (configFile >> "CfgPatches" >> "acre_main")) then { diff --git a/addons/common/functions/fnc_eraseCache.sqf b/addons/common/functions/fnc_eraseCache.sqf index ae988ced28..79eb4444fa 100644 --- a/addons/common/functions/fnc_eraseCache.sqf +++ b/addons/common/functions/fnc_eraseCache.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Deletes a cached result @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [NAMESPACE, "UID"] call ace_common_fnc_eraseCache + * * Public: No */ -#include "script_component.hpp" params ["_namespace", "_uid"]; diff --git a/addons/common/functions/fnc_errorMessage.sqf b/addons/common/functions/fnc_errorMessage.sqf index 88e0a3b90f..c062c8836c 100644 --- a/addons/common/functions/fnc_errorMessage.sqf +++ b/addons/common/functions/fnc_errorMessage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI) * Stops simulation and opens a textbox with error message. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * call ace_common_fnc_errorMessage + * * Public: No */ -#include "script_component.hpp" disableSerialization; endLoadingScreen; @@ -35,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_execNextFrame.sqf b/addons/common/functions/fnc_execNextFrame.sqf deleted file mode 100644 index c1c4b81592..0000000000 --- a/addons/common/functions/fnc_execNextFrame.sqf +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Author: esteldunedain - * Executes a code on the next frame - * - * Arguments: - * 0: Code to execute - * 1: Parameters to run the code with - * - * Return Value: - * PFH handler ID - * - * Public: Yes - */ -#include "script_component.hpp" - -ACE_DEPRECATED("ace_common_fnc_execNextFrame","3.8.0","CBA_fnc_execNextFrame"); - -_this call CBA_fnc_execNextFrame; diff --git a/addons/common/functions/fnc_findUnloadPosition.sqf b/addons/common/functions/fnc_findUnloadPosition.sqf index c3b0dc3f34..22e23c7f2b 100644 --- a/addons/common/functions/fnc_findUnloadPosition.sqf +++ b/addons/common/functions/fnc_findUnloadPosition.sqf @@ -1,25 +1,24 @@ +#include "script_component.hpp" /* * 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 + * 1: Cargo or + * 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 */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" //Number of tests run (effects performance in worst case scenarior where nothing is found VERSUES reliably finding a pos): #define MAX_TESTS 75 @@ -27,8 +26,8 @@ //Manual collision tests (count and radius): #define COL_TEST_COUNT 12 -params ["_vehicle", "_typeOfCargo", ["_theUnloader", objNull], ["_maxDistance", 10], ["_checkVehicleIsStable", true]]; -TRACE_5("params",_vehicle,_typeOfCargo,_theUnloader,_maxDistance,_checkVehicleIsStable); +params ["_vehicle", "_cargo", ["_theUnloader", objNull], ["_maxDistance", 10], ["_checkVehicleIsStable", true]]; +TRACE_5("params",_vehicle,_cargo,_theUnloader,_maxDistance,_checkVehicleIsStable); scopeName "main"; @@ -40,12 +39,22 @@ if (_checkVehicleIsStable) then { }; private _radiusOfItem = 1; -if (_typeOfCargo isKindOf "CAManBase") then { +if (_cargo isKindOf "CAManBase") then { _radiusOfItem = 1.1; } else { //`sizeOf` is unreliable, and does not work with object types that don't exist on map, so estimate size based on cargo size - if (isNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size))) then { - _radiusOfItem = (((getNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size))) ^ 0.35) max 0.75); + private _typeOfCargo = if (_cargo isEqualType "") then {_cargo} else {typeOf _cargo}; + private _itemSize = if (isNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size)) && {getNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size)) != -1}) then { + getNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size)); + } else { + if (["ace_cargo"] call FUNC(isModLoaded)) then { + [_cargo] call EFUNC(cargo,getSizeItem); + } else { + _radiusOfItem; + }; + }; + if (_itemSize != -1) then { + _radiusOfItem = (_itemSize ^ 0.35) max 0.75; }; }; diff --git a/addons/common/functions/fnc_firedEH.sqf b/addons/common/functions/fnc_firedEH.sqf index 29e58a4c6a..22a64f5c23 100644 --- a/addons/common/functions/fnc_firedEH.sqf +++ b/addons/common/functions/fnc_firedEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Unfied handling of weapon fire @@ -14,9 +15,11 @@ * Return Value: * None * + * Example: + * [bob, "gun", "muzzle", "single", "ammo", "magazine", "bullet"] call ace_common_fnc_firedEH + * * Public: No */ -#include "script_component.hpp" BEGIN_COUNTER(firedEH); diff --git a/addons/common/functions/fnc_fixCollision.sqf b/addons/common/functions/fnc_fixCollision.sqf index 3b3b16a9f9..ee61d83c35 100644 --- a/addons/common/functions/fnc_fixCollision.sqf +++ b/addons/common/functions/fnc_fixCollision.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Attempt to fix PhysX collisions causing unreasonable impact forces and damage. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_fixCollision + * * Public: No */ -#include "script_component.hpp" // allowDamage requires local object if (!local _this) exitWith {}; diff --git a/addons/common/functions/fnc_fixFloating.sqf b/addons/common/functions/fnc_fixFloating.sqf index 5a00aa3863..03e7933e2e 100644 --- a/addons/common/functions/fnc_fixFloating.sqf +++ b/addons/common/functions/fnc_fixFloating.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Attempt to fix floating physx with disabled damage after setPosXXX commands. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [object] call ace_common_fnc_fixFloating + * * Public: No */ -#include "script_component.hpp" params ["_object"]; diff --git a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf index 9e230b00ad..d89a3978c6 100644 --- a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf +++ b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Fixes the lowered rifle animation @@ -6,14 +7,13 @@ * 0: Unit * * Return Value: - * Nothing + * None * * Example: * [ACE_player] call ace_common_fnc_fixLoweredRifleAnimation * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_fixPosition.sqf b/addons/common/functions/fnc_fixPosition.sqf index 883a502c4e..ac152cf5c9 100644 --- a/addons/common/functions/fnc_fixPosition.sqf +++ b/addons/common/functions/fnc_fixPosition.sqf @@ -1,6 +1,6 @@ +#include "script_component.hpp" /* - * 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: @@ -9,32 +9,40 @@ * Return Value: * None * + * Example: + * bob call ace_common_fnc_fixPosition + * * Public: No */ -#include "script_component.hpp" // 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_getAllDefinedSetVariables.sqf b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf index a5d973767f..eeb96002d1 100644 --- a/addons/common/functions/fnc_getAllDefinedSetVariables.sqf +++ b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Returns an 2d array of all variables that have been set on the object @@ -14,9 +15,11 @@ * 3: publicFlag * 4: peristentFlag * + * Example: + * [bob, ""] call ace_common_fnc_getAllDefinedSetVariables + * * Public: Yes */ -#include "script_component.hpp" params ["_object", ["_category", ""]]; diff --git a/addons/common/functions/fnc_getChildren.sqf b/addons/common/functions/fnc_getChildren.sqf index f2930b015d..998d0b4399 100644 --- a/addons/common/functions/fnc_getChildren.sqf +++ b/addons/common/functions/fnc_getChildren.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Obtain children of a config entry @@ -7,10 +8,12 @@ * * Return Value: * Parent Entry Class Children + + * Example: + * [bob] call ace_common_fnc_getChildren * * Public: Yes */ -#include "script_component.hpp" params ["_name", "_cfgClass"]; diff --git a/addons/common/functions/fnc_getConfigCommander.sqf b/addons/common/functions/fnc_getConfigCommander.sqf index d4a53905b8..f3d011c57a 100644 --- a/addons/common/functions/fnc_getConfigCommander.sqf +++ b/addons/common/functions/fnc_getConfigCommander.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the commander config of a vehicles turret. @@ -7,10 +8,12 @@ * * Return Value: * Commander config + + * Example: + * [car] call ace_common_fnc_getConfigCommander * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/common/functions/fnc_getConfigGunner.sqf b/addons/common/functions/fnc_getConfigGunner.sqf index abbbd5f014..732256b8a1 100644 --- a/addons/common/functions/fnc_getConfigGunner.sqf +++ b/addons/common/functions/fnc_getConfigGunner.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the gunner config of a vehicles turret. @@ -8,9 +9,11 @@ * Return Value: * Gunner config * + * Example: + * [car] call ace_common_fnc_getConfigGunner + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/common/functions/fnc_getConfigType.sqf b/addons/common/functions/fnc_getConfigType.sqf deleted file mode 100644 index 34aaa03172..0000000000 --- a/addons/common/functions/fnc_getConfigType.sqf +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Author: commy2 - * Determins type of item. Can be CfgMagaines, CfgWeapons or CfgGlasses. - * - * Arguments: - * 0: Item Classname - * - * Return Value: - * Config category ("CfgWeapons", "CfgMagazines", "CfgGlasses", "") - * - * Public: Yes - */ -#include "script_component.hpp" - -ACE_DEPRECATED("ace_common_fnc_getConfigType","3.8.0","CBA_fnc_getItemConfig"); - -configName (configHierarchy (_item call CBA_fnc_getItemConfig) param [1, configNull]) diff --git a/addons/common/functions/fnc_getConfigTypeObject.sqf b/addons/common/functions/fnc_getConfigTypeObject.sqf deleted file mode 100644 index 92a6d43a42..0000000000 --- a/addons/common/functions/fnc_getConfigTypeObject.sqf +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Author: commy2 - * Determins type of object. Can be CfgVehicles or CfgAmmo. - * - * Arguments: - * 0: Object classname - * - * Return Value: - * Config category ("CfgWeapons", "Cfgmagazines", "CfgGlasses", "") - * - * Public: Yes - */ -#include "script_component.hpp" - -ACE_DEPRECATED("ace_common_fnc_getConfigTypeObject","3.8.0","CBA_fnc_getObjectConfig"); - -configName (configHierarchy (_item call CBA_fnc_getObjectConfig) param [1, configNull]) diff --git a/addons/common/functions/fnc_getDeathAnim.sqf b/addons/common/functions/fnc_getDeathAnim.sqf index 60aaf3bc0c..8fb72e0a21 100644 --- a/addons/common/functions/fnc_getDeathAnim.sqf +++ b/addons/common/functions/fnc_getDeathAnim.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, PabstMirror * Get the death animation for the unit at current time @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_getDefaultAnim.sqf b/addons/common/functions/fnc_getDefaultAnim.sqf index c2c0e1e7c4..9fea3e15df 100644 --- a/addons/common/functions/fnc_getDefaultAnim.sqf +++ b/addons/common/functions/fnc_getDefaultAnim.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the Defualt animation for the unit @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_getDefinedVariable.sqf b/addons/common/functions/fnc_getDefinedVariable.sqf index 32a75edb5e..7e20570cc1 100644 --- a/addons/common/functions/fnc_getDefinedVariable.sqf +++ b/addons/common/functions/fnc_getDefinedVariable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Grabs a variable. If variable has not been set, attempts to use default defined value @@ -9,9 +10,11 @@ * Return Value: * Value of variable or default value, if the variable is undefined * + * Example: + * [bob, "var"] call ace_common_fnc_getDefinedVariable + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_variable", "_defaultValue"]; diff --git a/addons/common/functions/fnc_getDefinedVariableDefault.sqf b/addons/common/functions/fnc_getDefinedVariableDefault.sqf index c6f4f7711c..edae4ef3ef 100644 --- a/addons/common/functions/fnc_getDefinedVariableDefault.sqf +++ b/addons/common/functions/fnc_getDefinedVariableDefault.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the variable default value @@ -8,9 +9,11 @@ * Return Value: * Default value of variable * + * Example: + * ["name"] call ace_common_fnc_getDefinedVariableDefault + * * Public: Yes */ -#include "script_component.hpp" params ["_varName"]; diff --git a/addons/common/functions/fnc_getDefinedVariableInfo.sqf b/addons/common/functions/fnc_getDefinedVariableInfo.sqf index adcb70c6ee..f6aeca0df9 100644 --- a/addons/common/functions/fnc_getDefinedVariableInfo.sqf +++ b/addons/common/functions/fnc_getDefinedVariableInfo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the variable Informations @@ -8,9 +9,11 @@ * Return Value: * Variable Metadata * + * Example: + * ["var"] call ace_common_fnc_getDefinedVariableInfo + * * Public: No */ -#include "script_component.hpp" params ["_varName"]; diff --git a/addons/common/functions/fnc_getDisplayConfigName.sqf b/addons/common/functions/fnc_getDisplayConfigName.sqf index 1660bbf804..f952d5c385 100644 --- a/addons/common/functions/fnc_getDisplayConfigName.sqf +++ b/addons/common/functions/fnc_getDisplayConfigName.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get display classnames from config with given idd. @@ -8,11 +9,13 @@ * Return Value: * Display Classnames * + * Example: + * [5] call ace_common_fnc_getDisplayConfigName + * * Public: Yes * * Note: Really slow due to iteration through whole config. Meant for debugging. */ -#include "script_component.hpp" params ["_idd"]; diff --git a/addons/common/functions/fnc_getDoorTurrets.sqf b/addons/common/functions/fnc_getDoorTurrets.sqf index 533e2a7489..93b0360042 100644 --- a/addons/common/functions/fnc_getDoorTurrets.sqf +++ b/addons/common/functions/fnc_getDoorTurrets.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Returns all turret indecies of door gunners. @@ -8,9 +9,11 @@ * Return Value: * All turret indecies of the Vehicle * + * Example: + * [car] call ace_common_fnc_getDoorTurrets + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; @@ -23,7 +26,7 @@ private _doorTurrets = []; _config = [_config, _x] call FUNC(getTurretConfigPath); - if (getNumber (_config >> "isCopilot" == 0) && {count getArray (_config >> "weapons") > 0}) then { + if (((getNumber (_config >> "isCopilot")) == 0) && {count getArray (_config >> "weapons") > 0}) then { _doorTurrets pushBack _x; }; false diff --git a/addons/common/functions/fnc_getFirstObjectIntersection.sqf b/addons/common/functions/fnc_getFirstObjectIntersection.sqf index c4cc46ab9b..1120707b2b 100644 --- a/addons/common/functions/fnc_getFirstObjectIntersection.sqf +++ b/addons/common/functions/fnc_getFirstObjectIntersection.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Returns the the first intersection with terrain between two positions. @todo rewrite using lineIntersectsSurfaces? @@ -11,9 +12,11 @@ * 0: Intersects * 1: Intersection Position ASL * + * Example: + * [[1,2,3], [0,0,5], 5] call ace_common_fnc_getFirstObjectIntersection + * * Public: Yes */ -#include "script_component.hpp" params ["_source", "_destination", "_accuracy"]; diff --git a/addons/common/functions/fnc_getFirstTerrainIntersection.sqf b/addons/common/functions/fnc_getFirstTerrainIntersection.sqf index 27a6f3c613..989486b1ac 100644 --- a/addons/common/functions/fnc_getFirstTerrainIntersection.sqf +++ b/addons/common/functions/fnc_getFirstTerrainIntersection.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Returns the the first intersection with an object between two positions. @todo rewrite using lineIntersectsSurfaces? @@ -11,9 +12,11 @@ * 0: Intersects * 1: Intersection Position ASL * + * Example: + * [[1,2,3], [0,0,5], 5] call ace_common_fnc_getFirstTerrainIntersection + * * Public: Yes */ -#include "script_component.hpp" params ["_source", "_destination", "_accuracy"]; diff --git a/addons/common/functions/fnc_getGunner.sqf b/addons/common/functions/fnc_getGunner.sqf index c11f2882ca..bd65c49ed4 100644 --- a/addons/common/functions/fnc_getGunner.sqf +++ b/addons/common/functions/fnc_getGunner.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns gunner using specified weapon type in vehicle. Only works if all turrets have different weapons. @@ -9,9 +10,11 @@ * Return Value: * Gunner * + * Example: + * [car, "gun"] call ace_common_fnc_getGunner + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]], ["_weapon", "", [""]]]; diff --git a/addons/common/functions/fnc_getInPosition.sqf b/addons/common/functions/fnc_getInPosition.sqf index 5d6e5d71b5..a45b5546a6 100644 --- a/addons/common/functions/fnc_getInPosition.sqf +++ b/addons/common/functions/fnc_getInPosition.sqf @@ -1,19 +1,22 @@ +#include "script_component.hpp" /* * Author: commy2 * Move unit into given vehicle position or switch to that position if the unit is already inside the vehicle. - * - * Arguments: + * + * Arguments: * 0: Unit * 1: Vehicle * 2: Position ("Driver", "Pilot", "Gunner", "Commander", "Copilot", "Turret", "FFV", "Codriver", "Cargo") * 3: Index (only applies to "Turret", "FFV", "Codriver", "Cargo") (default: next free index) - * - * Return Value: + * + * Return Value: * None * + * Example: + * [unit, vehicle, "Driver", 5] call ace_common_fnc_getInPosition + * * Public: Yes */ -#include "script_component.hpp" #define CANGETINDRIVER (isNull (driver _vehicle) || {!alive driver _vehicle}) && {!lockedDriver _vehicle} && {getNumber (_config >> "isUav") != 1} #define CANGETINTURRETINDEX (isNull (_vehicle turretUnit _turret) || {!alive (_vehicle turretUnit _turret)}) && {!(_vehicle lockedTurret _turret)} && {getNumber (_config >> "isUav") != 1} diff --git a/addons/common/functions/fnc_getItemType.sqf b/addons/common/functions/fnc_getItemType.sqf index eb5015e20a..5212c6d57e 100644 --- a/addons/common/functions/fnc_getItemType.sqf +++ b/addons/common/functions/fnc_getItemType.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns item type of given classname. @@ -9,9 +10,11 @@ * 0: Type ("weapon", "item", "magazine", "") * 1: Item Description * + * Example: + * ["tire"] call ace_common_fnc_getItemType + * * Public: Yes */ -#include "script_component.hpp" params ["_item"]; @@ -35,35 +38,35 @@ private _default = ["item", "magazine"] select (_cfgType == "CfgMagazines"); switch (true) do { case (_type == 0): {[_default, "unknown"]}; - case (_type == 2^0): {["weapon", "primary"]}; - case (_type == 2^1): {["weapon", "handgun"]}; - case (_type == 2^2): {["weapon", "secondary"]}; - case (_type < 2^4): {["weapon", "unknown"]}; - case (_type == 2^4): {["magazine", "handgun"]}; // handgun - case (_type == 2^8): {["magazine", "primary"]}; // rifle - case (_type == 2^9): {["magazine", "secondary"]}; // rpg, mg, mines + case (_type == TYPE_WEAPON_PRIMARY): {["weapon", "primary"]}; + case (_type == TYPE_WEAPON_HANDGUN): {["weapon", "handgun"]}; + case (_type == TYPE_WEAPON_SECONDARY): {["weapon", "secondary"]}; + case (_type < TYPE_MAGAZINE_HANDGUN_AND_GL): {["weapon", "unknown"]}; + case (_type == TYPE_MAGAZINE_HANDGUN_AND_GL): {["magazine", "handgun"]}; // handgun + case (_type == TYPE_MAGAZINE_PRIMARY_AND_THROW): {["magazine", "primary"]}; // rifle + case (_type == TYPE_MAGAZINE_SECONDARY_AND_PUT): {["magazine", "secondary"]}; // rpg, mg, mines //case (_type < 2^11): {["magazine", "unknown"]}; - case (_type == 101): {["item", "muzzle"]}; - case (_type == 201): {["item", "optics"]}; - case (_type == 301): {["item", "flashlight"]}; - case (_type == 302): {["item", "under"]}; // czech for bipod item - case (_type == 401): {["item", "first_aid_kit"]}; - case (_type == 501): {["item", "fins"]}; // not implemented - case (_type == 601): {["item", "breathing_bomb"]}; // not implemented - case (_type == 603): {["item", "goggles"]}; - case (_type == 604): {["item", "scuba"]}; // not implemented - case (_type == 605): {["item", "headgear"]}; - case (_type == 611): {["item", "radio"]}; - case (_type == 616): {["item", "hmd"]}; - case (_type == 617): {["item", "binocular"]}; - case (_type == 619): {["item", "medikit"]}; - case (_type == 620): {["item", "toolkit"]}; - case (_type == 621): {["item", "uav_terminal"]}; - case (_type == 701): {["item", "vest"]}; - case (_type == 801): {["item", "uniform"]}; + case (_type == TYPE_MUZZLE): {["item", "muzzle"]}; + case (_type == TYPE_OPTICS): {["item", "optics"]}; + case (_type == TYPE_FLASHLIGHT): {["item", "flashlight"]}; + case (_type == TYPE_BIPOD): {["item", "under"]}; // czech for bipod item + case (_type == TYPE_FIRST_AID_KIT): {["item", "first_aid_kit"]}; + case (_type == TYPE_FINS): {["item", "fins"]}; // not implemented + case (_type == TYPE_BREATHING_BOMB): {["item", "breathing_bomb"]}; // not implemented + case (_type == TYPE_GOGGLE): {["item", "goggles"]}; + case (_type == TYPE_SCUBA): {["item", "scuba"]}; // not implemented + case (_type == TYPE_HEADGEAR): {["item", "headgear"]}; + case (_type == TYPE_RADIO): {["item", "radio"]}; + case (_type == TYPE_HMD): {["item", "hmd"]}; + case (_type == TYPE_BINOCULAR): {["item", "binocular"]}; + case (_type == TYPE_MEDIKIT): {["item", "medikit"]}; + case (_type == TYPE_TOOLKIT): {["item", "toolkit"]}; + case (_type == TYPE_UAV_TERMINAL): {["item", "uav_terminal"]}; + case (_type == TYPE_VEST): {["item", "vest"]}; + case (_type == TYPE_UNIFORM): {["item", "uniform"]}; - case (_type == 2^12): { + case (_type == TYPE_BINOCULAR_AND_NVG): { switch (toLower _simulation) do { case ("weapon"): {["weapon", "binocular"]}; case ("binocular"): {["weapon", "binocular"]}; @@ -73,8 +76,8 @@ switch (true) do { }; }; - case (_type == 2^16): {["weapon", "vehicle"]}; - case (_type == 2^17): { + case (_type == TYPE_WEAPON_VEHICLE): {["weapon", "vehicle"]}; + case (_type == TYPE_ITEM): { switch (toLower _simulation) do { case ("itemmap"): {["item", "map"]}; case ("itemgps"): {["item", "gps"]}; diff --git a/addons/common/functions/fnc_getLightProperties.sqf b/addons/common/functions/fnc_getLightProperties.sqf index a376dff841..002868dd4e 100644 --- a/addons/common/functions/fnc_getLightProperties.sqf +++ b/addons/common/functions/fnc_getLightProperties.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Read properties of given vehicles light. @@ -13,9 +14,11 @@ * 3: Light inner angle * 4: Light outer angle * + * Example: + * [car, "light"] call ace_common_fnc_getLightProperties + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle", "_light"]; diff --git a/addons/common/functions/fnc_getLightPropertiesWeapon.sqf b/addons/common/functions/fnc_getLightPropertiesWeapon.sqf index 44c866e67f..fca17dd51f 100644 --- a/addons/common/functions/fnc_getLightPropertiesWeapon.sqf +++ b/addons/common/functions/fnc_getLightPropertiesWeapon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Read properties of given flashlight. @@ -12,9 +13,11 @@ * 3: Light inner angle * 4: Light outer angle * + * Example: + * ["flashlight"] call ace_common_fnc_getLightPropertiesWeapon + * * Public: Yes */ -#include "script_component.hpp" params ["_weapon"]; diff --git a/addons/common/functions/fnc_getMGRSdata.sqf b/addons/common/functions/fnc_getMGRSdata.sqf index 6b29b6625a..f6ca81175b 100644 --- a/addons/common/functions/fnc_getMGRSdata.sqf +++ b/addons/common/functions/fnc_getMGRSdata.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: VKing * Gets the current map's MGRS grid zone designator and 100km square. @@ -12,22 +13,24 @@ * 1: 100km square * 2: GZD + 100km sq. as a single string * + * Example: + * ["worldName"] call ace_common_fnc_getMGRSdata + * * Public: No */ -#include "script_component.hpp" 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); if (!(_mapData isEqualTo [])) then { _lat = _mapData select 0; - _alt = _mapData select 1; + _altitude = _mapData select 1; }; -TRACE_2("Latitude and Altitude",_lat,_alt); +TRACE_2("Latitude and Altitude",_lat,_altitude); private _UTM = [_long, _lat] call BIS_fnc_posDegToUTM; private _easting = _UTM select 0; diff --git a/addons/common/functions/fnc_getMapData.sqf b/addons/common/functions/fnc_getMapData.sqf index 7d7bef817f..b4cb56d75f 100644 --- a/addons/common/functions/fnc_getMapData.sqf +++ b/addons/common/functions/fnc_getMapData.sqf @@ -9,6 +9,9 @@ * 0: Latitude * 1: Altitude * + * Example: + * ["altis"] call ace_common_fnc_getMapData + * * Public: No */ @@ -21,72 +24,91 @@ _map = toLower _map; if (_map in ["tanoa"]) exitWith { [-18, 0] }; if (_map in ["altis"]) exitWith { [40, 0] }; if (_map in ["stratis"]) exitWith { [40, 0] }; +if (_map in ["malden", "abel"]) exitWith { [38.8, 0] }; // 1.72 Malden and CWR2 Malden -if (_map in ["abbottabad"]) exitWith { [34, 1256] }; //Abbottabad elevation 1256m (Wikipedia) -if (_map in ["abel"]) exitWith { [39, 0] }; //CWR2 Malden +if (_map in ["abbottabad"]) exitWith { [34, 1256] }; // Abbottabad elevation 1256m (Wikipedia) 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] }; +if (_map in ["blud_cordelia"]) exitWith { [12, 5] }; // Trung Si if (_map in ["bootcamp_acr"]) exitWith { [50, 0] }; if (_map in ["bornholm"]) exitWith { [55, 0] }; if (_map in ["bozcaada"]) exitWith { [40, 0] }; -if (_map in ["cain"]) exitWith { [40, 0] }; //CWR2 Kolgujev +if (_map in ["cain"]) exitWith { [40, 0] }; // CWR2 Kolgujev if (_map in ["caribou"]) exitWith { [68, 0] }; -if (_map in ["cartercity"]) exitWith { [43, 130] }; //Pecher, based on Grozny (1995 - 1996) elevation 130m (Wikipedia) +if (_map in ["cartercity"]) exitWith { [43, 130] }; // Pecher, based on Grozny (1995 - 1996) elevation 130m (Wikipedia) if (_map in ["catalina"]) exitWith { [33, 0] }; if (_map in ["chernarus", "chernarus_summer", "chernarus_winter"]) exitWith { [50, 0] }; if (_map in ["chernobylzone", "chernobylzonea2"]) exitWith { [51, 0] }; if (_map in ["clafghan"]) exitWith { [34, 640] }; -if (_map in ["dakrong"]) exitWith { [16, 0] }; //Unsung Mod +if (_map in ["colleville"]) exitWith { [49, 0] }; // IFA3LITE, Omaha Beach 1944 +if (_map in ["csj_lawlands", "uns_dong_ha"]) exitWith { [12, 0] }; // Unsung Mod +if (_map in ["csj_sea"]) exitWith { [15, 0] }; // Unsung Mod +if (_map in ["dakrong"]) exitWith { [16, 0] }; // Unsung Mod if (_map in ["desert_e"]) exitWith { [40, 800] }; -if (_map in ["desert_island"]) exitWith { [40, 0] }; //CWR2 Desert Island -if (_map in ["dya"]) exitWith { [34, 110] }; //Diyala Iraq - default elevationOffset -if (_map in ["eden"]) exitWith { [45, 0] }; //CWR2 Everon +if (_map in ["desert_island"]) exitWith { [40, 0] }; // CWR2 Desert Island +if (_map in ["dya"]) exitWith { [34, 110] }; // Diyala Iraq - default elevationOffset +if (_map in ["eden"]) exitWith { [45, 0] }; // CWR2 Everon if (_map in ["esseker"]) exitWith { [43, 2000] }; -if (_map in ["evergreen"]) exitWith { [41, 0] }; //Burgazada, Turkey - default elevationOffset +if (_map in ["evergreen"]) exitWith { [41, 0] }; // Burgazada, Turkey - default elevationOffset if (_map in ["fallujah"]) exitWith { [33, 0] }; if (_map in ["fata"]) exitWith { [33, 1347] }; if (_map in ["gorgona"]) exitWith { [43, 0] }; -if (_map in ["hellskitchen", "hellskitchens"]) exitWith { [32, 900] }; //Sangin summer, Sangin winter - Sangin elevation 888m (Wikipedia) +if (_map in ["hellskitchen", "hellskitchens"]) exitWith { [32, 900] }; // Sangin summer, Sangin winter - Sangin elevation 888m (Wikipedia) if (_map in ["hindukush"]) exitWith { [36, 0] }; +if (_map in ["i44_omaha_v2"]) exitWith { [49, 0] }; if (_map in ["imrali", "imralispring"]) exitWith { [40, 0] }; if (_map in ["intro"]) exitWith { [40, 0] }; if (_map in ["isladuala3"]) exitWith { [-19, 0] }; -if (_map in ["jacobi"]) exitWith { [34, 2000] }; //default elevationOffset +if (_map in ["jacobi"]) exitWith { [34, 2000] }; // default elevationOffset if (_map in ["kapaulio"]) exitWith { [0, 0] }; -if (_map in ["kerama"]) exitWith { [26, 0] }; //Kerama Islands, Japan - default elevationOffset +if (_map in ["kerama"]) exitWith { [26, 0] }; // Kerama Islands, Japan - default elevationOffset +if (_map in ["khe_sanh"]) exitWith { [17, 0] }; // Unsung Mod if (_map in ["kholm"]) exitWith { [36, 0] }; -if (_map in ["kidal"]) exitWith { [18, 0] }; //Kidal, Mali - default elevationOffset +if (_map in ["kidal"]) exitWith { [18, 0] }; // Kidal, Mali - default elevationOffset if (_map in ["koplic"]) exitWith { [42, 0] }; if (_map in ["kunduz"]) exitWith { [37, 0] }; -if (_map in ["lingor", "lingor3"]) exitWith { [-4, 0] }; +if (_map in ["lingor", "lingor3", "dingor"]) exitWith { [-4, 0] }; if (_map in ["lost", "lostw"]) exitWith { [60, 0] }; +if (_map in ["lythium"]) exitWith { [34, 0] }; if (_map in ["malvinas"]) exitWith { [-52, 0] }; +if (_map in ["marenice"]) exitWith { [51, 0] }; // CSA38 Mod (Czechoslovak army 1938 - Munich crisis), Lisatian Mountains. if (_map in ["mcn_aliabad"]) exitWith { [36, 0] }; +if (_map in ["mcn_neaville", "mcn_neaville_winter"]) exitWith { [45, 0] }; // I44: Neaville, I44: Neaville (Winter) if (_map in ["mef_alaska"]) exitWith { [60, 5] }; +if (_map in ["mog"]) exitWith { [2, 0] }; // Mogadishu, Somalia if (_map in ["mountains_acr"]) exitWith { [35, 2000] }; +if (_map in ["mske"]) exitWith { [35, 0] }; // MSKE 2017 +if (_map in ["nam2"]) exitWith { [14, 0] }; if (_map in ["namalsk"]) exitWith { [65, 0] }; if (_map in ["napf", "napfwinter"]) exitWith { [47, 0] }; -if (_map in ["newyork_lumnuon"]) exitWith { [41, 5] }; //Governer´s Island, New York - default elevationOffset -if (_map in ["noe"]) exitWith { [45, 0] }; //CWR2 Nogova -if (_map in ["panthera3"]) exitWith { [46, 0] }; -if (_map in ["pianosa_aut"]) exitWith { [43, 0] }; //Pianosa, Italy - default elevationOffset -if (_map in ["pja305"]) exitWith { [0, 0] }; //G.O.S N'Ziwasogo -if (_map in ["pja306"]) exitWith { [35, 0] }; //G.O.S Kalu Khan -if (_map in ["pja307"]) exitWith { [17, 0] }; //F.S.F Daryah -if (_map in ["pja308"]) exitWith { [36, 0] }; //G.O.S Gunkizli -if (_map in ["pja310"]) exitWith { [36, 0] }; //G.O.S Al Rayak -if (_map in ["pja312"]) exitWith { [16, 0] }; //G.O.S Song Bin Tanh +if (_map in ["newyork_lumnuon"]) exitWith { [41, 5] }; // Governer´s Island, New York - default elevationOffset +if (_map in ["noe"]) exitWith { [45, 0] }; // CWR2 Nogova +if (_map in ["panthera3", "winthera3"]) exitWith { [46, 0] }; +if (_map in ["phu_bai", "rockwall", "us101_cao_bang"]) exitWith { [14, 0] }; // Unsung Mod +if (_map in ["pianosa_aut"]) exitWith { [43, 0] }; // Pianosa, Italy - default elevationOffset +if (_map in ["pja305"]) exitWith { [0, 0] }; // G.O.S N'Ziwasogo +if (_map in ["pja306"]) exitWith { [35, 0] }; // G.O.S Kalu Khan +if (_map in ["pja307"]) exitWith { [17, 0] }; // F.S.F Daryah +if (_map in ["pja308"]) exitWith { [36, 0] }; // G.O.S Gunkizli +if (_map in ["pja310"]) exitWith { [36, 0] }; // G.O.S Al Rayak +if (_map in ["pja312"]) exitWith { [16, 0] }; // G.O.S Song Bin Tanh +if (_map in ["pja314"]) exitWith { [46, 0] }; // G.O.S Leskovets +if (_map in ["pja319"]) exitWith { [20, 0] }; // G.O.S N'Djenahoud, Ennedi Massif (Republic of Chad) +if (_map in ["plr_bulge"]) exitWith { [49, 0] }; // I44: Battle of the Bulge if (_map in ["porquerolles"]) exitWith { [43, 0] }; if (_map in ["porto"]) exitWith { [40, 0] }; if (_map in ["provinggrounds_pmc"]) exitWith { [35, 100] }; if (_map in ["reshmaan"]) exitWith { [35, 2000] }; -if (_map in ["rungsat"]) exitWith { [10, 0] }; //Unsung Mod +if (_map in ["rungsat"]) exitWith { [10, 0] }; // Unsung Mod if (_map in ["sara", "sara_dbe1"]) exitWith { [40, 0] }; if (_map in ["saralite"]) exitWith { [40, 0] }; -if (_map in ["sb3"]) exitWith { [53, 25] }; //TrpUebPl Einfelde Nord (Munster North Training Area, Germany) - default elevationOffset +if (_map in ["sb3"]) exitWith { [53, 25] }; // TrpUebPl Einfelde Nord (Munster North Training Area, Germany) - default elevationOffset if (_map in ["sfp_sturko"]) exitWith { [56, 0] }; if (_map in ["sfp_wamako"]) exitWith { [14, 0] }; if (_map in ["shapur_baf"]) exitWith { [35, 100] }; @@ -94,14 +116,17 @@ if (_map in ["sugarlake"]) exitWith { [29, 0] }; if (_map in ["takistan"]) exitWith { [35, 2000] }; if (_map in ["thirsk"]) exitWith { [65, 0] }; if (_map in ["tilos"]) exitWith { [36, 0] }; +if (_map in ["uhao"]) exitWith { [21, 0] }; +if (_map in ["uns_idv", "uns_ptv"]) exitWith { [13, 0] }; // Unsung Mod if (_map in ["utes"]) exitWith { [50, 0] }; -if (_map in ["vt5"]) exitWith { [61, 100] }; //Vt5, Suomi Finland - default elevationOffset +if (_map in ["vt5"]) exitWith { [61, 100] }; // Valtatie 5, Finland - default elevationOffset if (_map in ["wake"]) exitWith { [19, 0] }; if (_map in ["waziristan"]) exitWith { [33, 0] }; -if (_map in ["wintermap"]) exitWith { [61, 0] }; //Nordkvingo - default elevationOffset -if (_map in ["wintertown", "wintertowna3"]) exitWith { [39, 600] }; //U.S. state Kansas mean elevation 610m (Wikipedia) +if (_map in ["wintermap"]) exitWith { [61, 0] }; // Nordkvingo - default elevationOffset +if (_map in ["wintertown", "wintertowna3"]) exitWith { [39, 600] }; // U.S. state Kansas mean elevation 610m (Wikipedia) if (_map in ["woodland_acr"]) exitWith { [50, 0] }; if (_map in ["xcam_prototype"]) exitWith { [35, 0] }; +if (_map in ["xcam_taunus"]) exitWith { [50, 0] }; if (_map in ["zargabad"]) exitWith { [35, 2000] }; [] //Return empty array if we have no specific data for the map diff --git a/addons/common/functions/fnc_getMapGridData.sqf b/addons/common/functions/fnc_getMapGridData.sqf index be87a8585b..c329c0b3f9 100644 --- a/addons/common/functions/fnc_getMapGridData.sqf +++ b/addons/common/functions/fnc_getMapGridData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Finds real x/y offset and map step for a 10 digit grid @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" GVAR(mapGridData) = []; @@ -47,7 +47,7 @@ if (toLower _formatX find "a" != -1) then {_letterGrid = true}; if (toLower _formatY find "a" != -1) then {_letterGrid = true}; if (_letterGrid) exitWith { - ACE_LOGWARNING_3("Map Grid Warning (%1) - Map uses letter grids [%2, %3]",worldName,_formatX,_formatY); + WARNING_3("Map Grid Warning (%1) - Map uses letter grids [%2, %3]",worldName,_formatX,_formatY); }; //Start at [0, 500] and move north until we get a change in grid @@ -64,19 +64,17 @@ while {_startGrid == _originGrid} do { private _realOffsetY = (parseNumber (_originGrid select [count _formatX, count _formatY])) * _stepY + _heightOffset - 1; //Calculate MGRS 10digit step - they should both be 1 meter: -_stepXat5 = _stepX * 10 ^ ((count _formatX) - 5); -_stepYat5 = -1 * _stepY * 10 ^ ((count _formatY) - 5); +private _stepXat5 = _stepX * 10 ^ ((count _formatX) - 5); +private _stepYat5 = -1 * _stepY * 10 ^ ((count _formatY) - 5); if (_stepYat5 < 0) then { - ACE_LOGWARNING_1("Map Grid Warning (%1) - Northing is reversed.",worldName); + TRACE_1("Northing is reversed",worldName); }; - if (_stepXat5 != 1) then { - ACE_LOGWARNING_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 { - ACE_LOGWARNING_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_getMapGridFromPos.sqf b/addons/common/functions/fnc_getMapGridFromPos.sqf index 8604d68fa6..defee04e57 100644 --- a/addons/common/functions/fnc_getMapGridFromPos.sqf +++ b/addons/common/functions/fnc_getMapGridFromPos.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: VKing, PabstMirror * Gets a 10-digit map grid for the given world position @@ -15,7 +16,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_pos", ["_returnSingleString", false]]; diff --git a/addons/common/functions/fnc_getMapPosFromGrid.sqf b/addons/common/functions/fnc_getMapPosFromGrid.sqf index 96960a844d..d4469b56cc 100644 --- a/addons/common/functions/fnc_getMapPosFromGrid.sqf +++ b/addons/common/functions/fnc_getMapPosFromGrid.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Gets position from grid cords @@ -6,7 +7,7 @@ * 0: Grid Cords * 1: Grid center (true), Grid Bottom Right (false) (default: true) * - * Return values: + * Return Value: * Position * * Example: @@ -14,12 +15,11 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_inputString", ["_getCenterOfGrid", true]]; if (count GVAR(mapGridData) == 0) exitWith { - ACE_LOGERROR("Map has bad data, falling back to BIS_fnc_gridToPos"); + ERROR("Map has bad data, falling back to BIS_fnc_gridToPos"); (_this call BIS_fnc_gridToPos) select 0 }; diff --git a/addons/common/functions/fnc_getMarkerType.sqf b/addons/common/functions/fnc_getMarkerType.sqf index 0da7f1a46e..ed551e4c1b 100644 --- a/addons/common/functions/fnc_getMarkerType.sqf +++ b/addons/common/functions/fnc_getMarkerType.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Get the apropriate marker for a group. * * Arguments: - * 0: Group + * 0: Group * * Return Value: * Marker Type * + * Example: + * ["GROUP"] call ace_common_fnc_getmarkerType + * * Public: No */ -#include "script_component.hpp" params ["_group"]; diff --git a/addons/common/functions/fnc_getName.sqf b/addons/common/functions/fnc_getName.sqf index 4c49e8dc11..0bcce9d2c8 100644 --- a/addons/common/functions/fnc_getName.sqf +++ b/addons/common/functions/fnc_getName.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns the name of the object. Used to prevent issues with the name command. @@ -15,7 +16,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", ["_showEffective", false], ["_useRaw", false]]; diff --git a/addons/common/functions/fnc_getNumberMagazinesIn.sqf b/addons/common/functions/fnc_getNumberMagazinesIn.sqf index 87f92979eb..7beaf3ee37 100644 --- a/addons/common/functions/fnc_getNumberMagazinesIn.sqf +++ b/addons/common/functions/fnc_getNumberMagazinesIn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Count magazines of unit. @@ -9,9 +10,11 @@ * Return Value: * Magazine amount * + * Example: + * [bob, "magazine"] call ace_common_fnc_getNumberMagazinesIn + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_magazine"]; @@ -21,11 +24,14 @@ if (_unit isKindOf "CAManBase") then { _return = {_x == _magazine} count magazines _unit; } else { { - _return = _return + {_x == _magazine} count magazines _x; + _return = _return + ({_x == _magazine} count magazines _x); false } count crew _unit; - _return = _return + ({_x == _magazine} count getMagazineCargo _unit); + (getMagazineCargo _unit) params [["_magNames", []], ["_magCount", []]]; + { + if (_magazine == _x) exitWith {_return = _return + (_magCount select _forEachIndex)}; + } forEach _magNames; }; _return diff --git a/addons/common/functions/fnc_getPitchBankYaw.sqf b/addons/common/functions/fnc_getPitchBankYaw.sqf index 89fab8d92b..6cdec367de 100644 --- a/addons/common/functions/fnc_getPitchBankYaw.sqf +++ b/addons/common/functions/fnc_getPitchBankYaw.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Returns pitch, bank, yaw for given vehicle in degrees. @@ -10,9 +11,11 @@ * 1: bank * 2: yaw * + * Example: + * [plane] call ace_common_fnc_getPitchBankYaw + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/common/functions/fnc_getPylonTurret.sqf b/addons/common/functions/fnc_getPylonTurret.sqf new file mode 100644 index 0000000000..b27e6eb582 --- /dev/null +++ b/addons/common/functions/fnc_getPylonTurret.sqf @@ -0,0 +1,63 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_getReflectorsWithSelections.sqf b/addons/common/functions/fnc_getReflectorsWithSelections.sqf index 248050486c..97feca6e19 100644 --- a/addons/common/functions/fnc_getReflectorsWithSelections.sqf +++ b/addons/common/functions/fnc_getReflectorsWithSelections.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * @@ -12,9 +13,11 @@ * 0: Light Hitpoints * 1: Selections * + * Example: + * [car] call ace_common_fnc_getReflectorsWithSelections + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf b/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf index b46ec308ec..5c30245732 100644 --- a/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf +++ b/addons/common/functions/fnc_getSelectionsWithoutHitPoints.sqf @@ -1,15 +1,20 @@ +#include "script_component.hpp" /* * Author: commy2 * * Returns all damageable selections without hitpoints of any vehicle. * * Arguments: - * 0: A vehicle, not the classname (Object) + * 0: A vehicle, not the classname * * Return Value: - * The selections without hitpoints, i.e. reflectors. (Array) + * The selections without hitpoints, i.e. reflectors. + * + * Example: + * [car] call ace_common_fnc_getSelectionsWithoutHitPoints + * + * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/common/functions/fnc_getSettingData.sqf b/addons/common/functions/fnc_getSettingData.sqf index ae9dd5351e..79ee4f3264 100644 --- a/addons/common/functions/fnc_getSettingData.sqf +++ b/addons/common/functions/fnc_getSettingData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Returns the metadata of a setting if it exists @@ -6,7 +7,7 @@ * 0: Setting Name * * Return Value: - * Setting Data (Array) + * Setting Data * 0: Name * 1: Type Name * 2: Is Client Settable @@ -17,9 +18,11 @@ * 7: Default Value * 8: Localized Category * + * Example: + * ["setting"] call ace_common_fnc_getSettingData + * * Public: No */ -#include "script_component.hpp" params ["_name"]; diff --git a/addons/common/functions/fnc_getStaminaBarControl.sqf b/addons/common/functions/fnc_getStaminaBarControl.sqf index 1fa747fef6..a426a7f933 100644 --- a/addons/common/functions/fnc_getStaminaBarControl.sqf +++ b/addons/common/functions/fnc_getStaminaBarControl.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns the control of the Stamina Bar from Arma 1.54. @@ -8,8 +9,10 @@ * Return Value: * Stamina Bar control * + * Example: + * call ace_common_fnc_getStaminaBarControl + * * Public: No */ -#include "script_component.hpp" (uiNamespace getVariable [QGVAR(dlgStaminaBar), displayNull]) displayCtrl IDC_STAMINA_BAR diff --git a/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf b/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf index 0d2343bec9..3a4da0326f 100644 --- a/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf +++ b/addons/common/functions/fnc_getTargetAzimuthAndInclination.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get players viewing direction and slope. @@ -9,9 +10,11 @@ * 0: Azimuth * 1: Inclination * + * Example: + * [] call ace_common_fnc_getTargetAzimuthAndInclination + * * Public: Yes */ -#include "script_component.hpp" private _position = ATLToASL positionCameraToWorld [0, 0, 0]; private _direction = ATLToASL positionCameraToWorld [0, 0, 1]; diff --git a/addons/common/functions/fnc_getTargetDistance.sqf b/addons/common/functions/fnc_getTargetDistance.sqf index 000f0ae31d..ff6d2cc198 100644 --- a/addons/common/functions/fnc_getTargetDistance.sqf +++ b/addons/common/functions/fnc_getTargetDistance.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: VKing * Get the distance to the next object the player is looking at. Used for laser distance measurements. @@ -10,9 +11,11 @@ * Return Value: * Distance in meters * + * Example: + * [5,20000,56] call ace_common_fnc_getTargetDistance + * * Public: Yes */ -#include "script_component.hpp" params [["_accuracy",1], ["_maxDistance",5000], ["_minDistance",0]]; diff --git a/addons/common/functions/fnc_getTargetObject.sqf b/addons/common/functions/fnc_getTargetObject.sqf index ed757dedf4..a15cd309be 100644 --- a/addons/common/functions/fnc_getTargetObject.sqf +++ b/addons/common/functions/fnc_getTargetObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the nearest object the player is looking at. Used for laser designator instead of cursorTarget. @@ -8,9 +9,11 @@ * Return Value: * Nearest object in line of sight, objNull if none are found * + * Example: + * [56] call ace_common_fnc_getTargetObject + * * Public: Yes */ -#include "script_component.hpp" params ["_maxDistance"]; diff --git a/addons/common/functions/fnc_getTurnedOnLights.sqf b/addons/common/functions/fnc_getTurnedOnLights.sqf index a996e146d2..a40832d61d 100644 --- a/addons/common/functions/fnc_getTurnedOnLights.sqf +++ b/addons/common/functions/fnc_getTurnedOnLights.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns all turned on lights of any vehicle or streetlamp. @@ -8,9 +9,11 @@ * Return Value: * All burning lights * + * Example: + * [car] call ace_common_fnc_getTurnedOnLights + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/common/functions/fnc_getTurretCommander.sqf b/addons/common/functions/fnc_getTurretCommander.sqf index 3e7f09215f..49d0798d35 100644 --- a/addons/common/functions/fnc_getTurretCommander.sqf +++ b/addons/common/functions/fnc_getTurretCommander.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the turret index of a vehicles commander. @@ -8,9 +9,11 @@ * Return Value: * Vehicle commander turrent indecies * + * Example: + * [car] call ace_common_fnc_getTurretCommander + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getTurretConfigPath.sqf b/addons/common/functions/fnc_getTurretConfigPath.sqf index 95d0773fd3..aee865b3fb 100644 --- a/addons/common/functions/fnc_getTurretConfigPath.sqf +++ b/addons/common/functions/fnc_getTurretConfigPath.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the config path of a vehicles turret. @@ -9,9 +10,11 @@ * Return Value: * Turret config * + * Example: + * [CfgVehicle, [Array]] call ace_common_fnc_getTurretConfigPath + * * Public: Yes */ -#include "script_component.hpp" params ["_config", "_turretIndex"]; diff --git a/addons/common/functions/fnc_getTurretCopilot.sqf b/addons/common/functions/fnc_getTurretCopilot.sqf index 49002cc40e..7207ac5b17 100644 --- a/addons/common/functions/fnc_getTurretCopilot.sqf +++ b/addons/common/functions/fnc_getTurretCopilot.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the turret index of a vehicles copilot. @@ -8,9 +9,11 @@ * Return Value: * Vehicle Copilot Turret indecies * + * Example: + * [car] call ace_common_fnc_getTurretCopilot + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getTurretDirection.sqf b/addons/common/functions/fnc_getTurretDirection.sqf index 1de8af459e..78db8bc8e6 100644 --- a/addons/common/functions/fnc_getTurretDirection.sqf +++ b/addons/common/functions/fnc_getTurretDirection.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: jaynus * Get the absolute turret direction for FOV/PIP turret. @@ -10,9 +11,11 @@ * 0: Position ASL * 1: Direction * + * Example: + * [car, [5,6,5]] call ace_common_fnc_getTurretDirection + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle", "_position"]; @@ -38,5 +41,5 @@ if (_pov == "pip0_pos") then { _povDir = _gunBeginPos vectorDiff _gunEndPos; }; - +_povDir = vectorNormalized _povDir; [_povPos, _povDir] diff --git a/addons/common/functions/fnc_getTurretGunner.sqf b/addons/common/functions/fnc_getTurretGunner.sqf index 4a26e2c03d..180a10914e 100644 --- a/addons/common/functions/fnc_getTurretGunner.sqf +++ b/addons/common/functions/fnc_getTurretGunner.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the turret index of a vehicles gunner. @@ -8,9 +9,11 @@ * Return Value: * Vehicle Gunner Turret indecies * + * Example: + * [car] call ace_common_fnc_getTurretGunner + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getTurretIndex.sqf b/addons/common/functions/fnc_getTurretIndex.sqf index df2d540873..423f2e6289 100644 --- a/addons/common/functions/fnc_getTurretIndex.sqf +++ b/addons/common/functions/fnc_getTurretIndex.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the turret index of a units current turret. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getTurretsFFV.sqf b/addons/common/functions/fnc_getTurretsFFV.sqf index 5c36e20197..0ae04a3032 100644 --- a/addons/common/functions/fnc_getTurretsFFV.sqf +++ b/addons/common/functions/fnc_getTurretsFFV.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the turret indices of ffv turrets. @@ -8,9 +9,11 @@ * Return Value: * Vehicle FFV Turret indecies * + * Example: + * [car] call ace_common_fnc_getTurretsFFV + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getTurretsOther.sqf b/addons/common/functions/fnc_getTurretsOther.sqf index ef2a1278dc..c84b50d842 100644 --- a/addons/common/functions/fnc_getTurretsOther.sqf +++ b/addons/common/functions/fnc_getTurretsOther.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the turret indices of other turrets (not gunner, commander, copilot or ffv). @@ -8,9 +9,11 @@ * Return Value: * Vehicle Other Turret indecies * + * Example: + * [car] call ace_common_fnc_getTurretsOther + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getUavControlPosition.sqf b/addons/common/functions/fnc_getUavControlPosition.sqf index c98004c7e7..9d6f6de9f2 100644 --- a/addons/common/functions/fnc_getUavControlPosition.sqf +++ b/addons/common/functions/fnc_getUavControlPosition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Returns the seat position of a UAV that the unit is activly controling. @@ -16,7 +17,6 @@ * * Public: Yes */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getVehicleCargo.sqf b/addons/common/functions/fnc_getVehicleCargo.sqf index 68599c919b..82442700a2 100644 --- a/addons/common/functions/fnc_getVehicleCargo.sqf +++ b/addons/common/functions/fnc_getVehicleCargo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the vehicle cargo positions. Codrivers and ffv positions are not listed. @@ -8,9 +9,11 @@ * Return Value: * Vehicle cargo positions * + * Example: + * [car] call ace_common_fnc_getVehicleCargo + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getVehicleCodriver.sqf b/addons/common/functions/fnc_getVehicleCodriver.sqf index a1cc5814e1..8deef3f9cd 100644 --- a/addons/common/functions/fnc_getVehicleCodriver.sqf +++ b/addons/common/functions/fnc_getVehicleCodriver.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the vehicle codriver positions. @@ -8,9 +9,11 @@ * Return Value: * Vehicle codriver positions * + * Example: + * ["car"] call ace_common_fnc_getVehicleCodriver + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getVehicleCrew.sqf b/addons/common/functions/fnc_getVehicleCrew.sqf index adb0e9701a..af699d3b6b 100644 --- a/addons/common/functions/fnc_getVehicleCrew.sqf +++ b/addons/common/functions/fnc_getVehicleCrew.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns array of crew member objects. @@ -9,9 +10,11 @@ * Return Value: * Crew * + * Example: + * [car, ["driver"]] call ace_common_fnc_getVehicleCrew + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle", ["_types", ["driver", "commander", "gunner", "turret", "cargo", "ffv"]]]; diff --git a/addons/common/functions/fnc_getVehicleIcon.sqf b/addons/common/functions/fnc_getVehicleIcon.sqf new file mode 100644 index 0000000000..ce17a66bc2 --- /dev/null +++ b/addons/common/functions/fnc_getVehicleIcon.sqf @@ -0,0 +1,47 @@ +#include "script_component.hpp" +/* + * 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 + */ +#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/common/functions/fnc_getVehicleUAVCrew.sqf b/addons/common/functions/fnc_getVehicleUAVCrew.sqf index 2b2281ed10..45d151bc30 100644 --- a/addons/common/functions/fnc_getVehicleUAVCrew.sqf +++ b/addons/common/functions/fnc_getVehicleUAVCrew.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns array of uav dummy ais. @@ -8,9 +9,11 @@ * Return Value: * UAV Dummy Crew * + * Example: + * [car] call ace_common_fnc_getVehicleUAVCrew + * * Public: Yes */ -#include "script_component.hpp" params [["_vehicle", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_getVersion.sqf b/addons/common/functions/fnc_getVersion.sqf index 24773240b7..8f9e39e360 100644 --- a/addons/common/functions/fnc_getVersion.sqf +++ b/addons/common/functions/fnc_getVersion.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the version number of the current ACE build. @@ -8,8 +9,10 @@ * Return Value: * ACE Version * + * Example: + * [] call ace_common_fnc_getVersion + * * Public: Yes */ -#include "script_component.hpp" getText (configFile >> "CfgPatches" >> "ACE_main" >> "version") // return diff --git a/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf b/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf index f7c7909e01..83df3782e4 100644 --- a/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf +++ b/addons/common/functions/fnc_getWeaponAzimuthAndInclination.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get local players weapon direction and slope. @@ -9,9 +10,11 @@ * 0: Azimuth * 1: Inclination * + * Example: + * ["gun"] call ace_common_fnc_getWeaponAzimuthAndInclination + * * Public: Yes */ -#include "script_component.hpp" params ["_weapon"]; diff --git a/addons/common/functions/fnc_getWeaponIndex.sqf b/addons/common/functions/fnc_getWeaponIndex.sqf index 0e24f190a5..b4e94e678f 100644 --- a/addons/common/functions/fnc_getWeaponIndex.sqf +++ b/addons/common/functions/fnc_getWeaponIndex.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the index of the weapon. @@ -13,9 +14,11 @@ * 2 = handgun * -1 = other * + * Example: + * [bob, "gun"] call ace_common_fnc_getWeaponIndex + * * Public: Yes */ - #include "script_component.hpp" params ["_unit", "_weapon"]; diff --git a/addons/common/functions/fnc_getWeaponModes.sqf b/addons/common/functions/fnc_getWeaponModes.sqf index 48755d3a9b..93a8614f7f 100644 --- a/addons/common/functions/fnc_getWeaponModes.sqf +++ b/addons/common/functions/fnc_getWeaponModes.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the available firing modes of a weapon. Will ignore the AI helper modes. @@ -8,9 +9,11 @@ * Return Value: * Firing Modes * + * Example: + * ["gun"] call ace_common_fnc_getWeaponModes + * * Public: Yes */ -#include "script_component.hpp" params [["_weapon", "", [""]]]; diff --git a/addons/common/functions/fnc_getWeaponMuzzles.sqf b/addons/common/functions/fnc_getWeaponMuzzles.sqf index e252d879f9..264ad2b405 100644 --- a/addons/common/functions/fnc_getWeaponMuzzles.sqf +++ b/addons/common/functions/fnc_getWeaponMuzzles.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the muzzles of a weapon. @@ -8,9 +9,11 @@ * Return Value: * All weapon muzzles * + * Example: + * ["gun"] call ace_common_fnc_getWeaponMuzzles + * * Public: Yes */ -#include "script_component.hpp" params [["_weapon", "", [""]]]; diff --git a/addons/common/functions/fnc_getWeaponState.sqf b/addons/common/functions/fnc_getWeaponState.sqf index 73e5897236..219f52d369 100644 --- a/addons/common/functions/fnc_getWeaponState.sqf +++ b/addons/common/functions/fnc_getWeaponState.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Return current state of the weapon. Attachments and magazines with ammo. @@ -12,9 +13,11 @@ * 2: Magazines * 3: Ammo * + * Example: + * [bob, "gun"] call ace_common_fnc_getWeaponState + * * Public: Yes */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_weapon", nil, [""]]]; @@ -42,4 +45,4 @@ private _ammo = _muzzles apply {0}; false } count magazinesAmmoFull _unit; -[_attachments, _muzzles, _magazines, _ammo]; +[_attachments, _muzzles, _magazines, _ammo]; diff --git a/addons/common/functions/fnc_getWeaponType.sqf b/addons/common/functions/fnc_getWeaponType.sqf index 5666ea5bc0..1b3e8fd331 100644 --- a/addons/common/functions/fnc_getWeaponType.sqf +++ b/addons/common/functions/fnc_getWeaponType.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check what kind of weapon the given class name is. @@ -12,9 +13,11 @@ * 3 = handgun * -1 = other * + * Example: + * ["gun"] call ace_common_fnc_getWeaponType + * * Public: Yes */ -#include "script_component.hpp" params ["_weapon"]; diff --git a/addons/common/functions/fnc_getWeight.sqf b/addons/common/functions/fnc_getWeight.sqf new file mode 100644 index 0000000000..5fc92b7703 --- /dev/null +++ b/addons/common/functions/fnc_getWeight.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: commy2 + * Returns the weight (from the loadAbs command) in lbs/kg (based on user option) + * + * Arguments: + * 0: The Unit (usually the player) + * 1: Force a return type + * + * Return Value: + * The return value + * + * Example: + * [player] call ace_common_fnc_getWeight + * + * Public: No + */ + +params ["_unit", ["_useImperial", false, [false, 0]]]; + +private _virtualLoad = 0; + +{ + _virtualLoad = _virtualLoad + (_x getVariable [QEGVAR(movement,vLoad), 0]); +} forEach [ + _unit, + uniformContainer _unit, + vestContainer _unit, + backpackContainer _unit +]; + +private _weight = (loadAbs _unit + _virtualLoad) * 0.1; + +//Return +if (_useImperial in [true, 1]) then { + format ["%1lb", (round (_weight * 100)) / 100] +} else { + format ["%1kg", (round (_weight * (1/2.2046) * 100)) / 100] +}; diff --git a/addons/common/functions/fnc_getWindDirection.sqf b/addons/common/functions/fnc_getWindDirection.sqf index 7341ea9c1d..cb10e18f85 100644 --- a/addons/common/functions/fnc_getWindDirection.sqf +++ b/addons/common/functions/fnc_getWindDirection.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get the compass direction the wind is blowing from. @@ -8,9 +9,11 @@ * Return Value: * Wind cardinal direction * + * Example: + * [] call ace_common_fnc_getWindDirection + * * Public: Yes */ -#include "script_component.hpp" localize ([ LSTRING(S), diff --git a/addons/common/functions/fnc_getZoom.sqf b/addons/common/functions/fnc_getZoom.sqf index f4113198a7..26144da81e 100644 --- a/addons/common/functions/fnc_getZoom.sqf +++ b/addons/common/functions/fnc_getZoom.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns a value depending on current zoom level. @@ -8,10 +9,12 @@ * Return Value: * Zoom * + * Example: + * [] call ace_common_fnc_getZoom + * * Public: Yes */ -#include "script_component.hpp" if (!hasInterface) exitWith {0}; -(0.5 - ((worldToScreen positionCameraToWorld [0, 1, 1]) select 1)) * (getResolution select 5) +(0.5 - ((worldToScreen positionCameraToWorld [0, 1, 1]) select 1)) * (getResolution select 5) diff --git a/addons/common/functions/fnc_globalEvent.sqf b/addons/common/functions/fnc_globalEvent.sqf deleted file mode 100644 index b58a0f092c..0000000000 --- a/addons/common/functions/fnc_globalEvent.sqf +++ /dev/null @@ -1,14 +0,0 @@ -#define DEBUG_MODE_FULL -#include "script_component.hpp" - -params ["_eventName", "_eventArgs"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -[_eventName, _eventArgs] call CBA_fnc_globalEvent; - -ACE_DEPRECATED("ace_common_fnc_globalEvent","3.8.0","CBA_fnc_globalEvent"); diff --git a/addons/common/functions/fnc_goKneeling.sqf b/addons/common/functions/fnc_goKneeling.sqf index 9e7aed708a..e9317cc74e 100644 --- a/addons/common/functions/fnc_goKneeling.sqf +++ b/addons/common/functions/fnc_goKneeling.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * 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 @@ -8,14 +9,16 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_goKneeling + * * Public: No */ -#include "script_component.hpp" 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_hadamardProduct.sqf b/addons/common/functions/fnc_hadamardProduct.sqf index cdaf707395..07295dcef9 100644 --- a/addons/common/functions/fnc_hadamardProduct.sqf +++ b/addons/common/functions/fnc_hadamardProduct.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Returns the Hadamard Product of two vectors. @@ -10,9 +11,11 @@ * Return Value: * Hadamard Product * + * Example: + * [[0,0,0], [1,1,1]] call ace_common_fnc_hadamardProduct + * * Public: Yes */ -#include "script_component.hpp" params ["_vector1", "_vector2"]; diff --git a/addons/common/functions/fnc_handleEngine.sqf b/addons/common/functions/fnc_handleEngine.sqf index 829ad5bb49..40574c69c6 100644 --- a/addons/common/functions/fnc_handleEngine.sqf +++ b/addons/common/functions/fnc_handleEngine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Blocks turning on the vehicles engine if set by the status effect handler. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, "running"] call ace_common_fnc_handleEngine + * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_engineOn"]; if (local _vehicle && {_engineOn} && {_vehicle getVariable [QGVAR(blockEngine), false]}) then { diff --git a/addons/common/functions/fnc_handleModifierKey.sqf b/addons/common/functions/fnc_handleModifierKey.sqf index bfb7e84931..1440a7849e 100644 --- a/addons/common/functions/fnc_handleModifierKey.sqf +++ b/addons/common/functions/fnc_handleModifierKey.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handles key down event for modifier key. @@ -8,9 +9,11 @@ * Return Value: * None * - * Public : No + * Example: + * call ace_common_fnc_handleModifierKey + * + * Public: No */ -#include "script_component.hpp" if (_this select 3) then {ACE_modifier = 1}; diff --git a/addons/common/functions/fnc_handleModifierKeyUp.sqf b/addons/common/functions/fnc_handleModifierKeyUp.sqf index ffa5855115..9ab3cadf7d 100644 --- a/addons/common/functions/fnc_handleModifierKeyUp.sqf +++ b/addons/common/functions/fnc_handleModifierKeyUp.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handles key up event for modifier key. @@ -8,9 +9,11 @@ * Return Value: * None * - * Public : No + * Example: + * call ace_common_fnc_handleModifierKeyUp + * + * Public: No */ -#include "script_component.hpp" ACE_modifier = 0; diff --git a/addons/common/functions/fnc_handleScrollWheel.sqf b/addons/common/functions/fnc_handleScrollWheel.sqf deleted file mode 100644 index 037b7b640b..0000000000 --- a/addons/common/functions/fnc_handleScrollWheel.sqf +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Author: commy2 - * Handles MouseZChanged event. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Public : No - */ -#include "script_component.hpp" - -{ - [_this select 1] call _x; - false -} count ((missionNamespace getVariable ["ACE_EventHandler_ScrollWheel", [-1, [], []]]) select 2); - -nil diff --git a/addons/common/functions/fnc_hasHatch.sqf b/addons/common/functions/fnc_hasHatch.sqf index e39c52f897..90053f43d9 100644 --- a/addons/common/functions/fnc_hasHatch.sqf +++ b/addons/common/functions/fnc_hasHatch.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if unit is in a vehicle position where it can turn in or out. @@ -8,9 +9,11 @@ * Return Value: * Unit has a hatch? * + * Example: + * [bob] call ace_common_fnc_hasHatch + * * Public: Yes */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]]]; diff --git a/addons/common/functions/fnc_hasItem.sqf b/addons/common/functions/fnc_hasItem.sqf index 8ca785d78e..9ae4e7ec63 100644 --- a/addons/common/functions/fnc_hasItem.sqf +++ b/addons/common/functions/fnc_hasItem.sqf @@ -1,20 +1,21 @@ +#include "script_component.hpp" /* * 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 * - * Public: yes + * Example: + * [bob, "item"] call ace_common_fnc_hasItem * - * Note: Case sensitive + * Public: Yes */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_item", "", [""]]]; -_item in items _unit // return +_item in (_unit call EFUNC(common,uniqueItems)) diff --git a/addons/common/functions/fnc_hasMagazine.sqf b/addons/common/functions/fnc_hasMagazine.sqf index eaa9bc0556..fceee87c11 100644 --- a/addons/common/functions/fnc_hasMagazine.sqf +++ b/addons/common/functions/fnc_hasMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if given unit has a magazine of given classname @@ -9,11 +10,13 @@ * Return Value: * has Magazine * + * Example: + * [bob, "magazine"] call ace_common_fnc_hasMagazine + * * Public: yes * * Note: Case sensitive */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_magazine", "", [""]]]; diff --git a/addons/common/functions/fnc_hashCreate.sqf b/addons/common/functions/fnc_hashCreate.sqf deleted file mode 100644 index c3ff836573..0000000000 --- a/addons/common/functions/fnc_hashCreate.sqf +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Author: ? - * Returns an empty hash structure - * - * Arguments: - * None - * - * Return Value: - * Empty Hash Structure - * - * Public: No - */ -#include "script_component.hpp" - -ACE_DEPRECATED(QFUNC(hashCreate),"3.8.0","CBA_fnc_hashCreate"); - -[[],[]] diff --git a/addons/common/functions/fnc_hashGet.sqf b/addons/common/functions/fnc_hashGet.sqf deleted file mode 100644 index e7bee04eec..0000000000 --- a/addons/common/functions/fnc_hashGet.sqf +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Author: ? - * Returns value attached to key in given hash. - * - * Arguments: - * 0: Hash - * 1: Key - * - * Return Value: - * Value - * - * Public: No - */ -#include "script_component.hpp" - -ACE_DEPRECATED(QFUNC(hashGet),"3.8.0","CBA_fnc_hashGet"); - -params ["_hash", "_key"]; - -ERRORDATA(2); -private _val = nil; -try { - if(VALIDHASH(_hash)) then { - private _index = (_hash select 0) find _key; - if(_index != -1) then { - _val = (_hash select 1) select _index; - if(IS_STRING(_val) && {_val == "ACREHASHREMOVEDONOTUSETHISVAL"}) then { - _val = nil; - }; - }; - } else { - ERROR("Input hash is not valid"); - }; -} catch { - HANDLECATCH; -}; - -if (isNil "_val") exitWith { nil }; - -_val diff --git a/addons/common/functions/fnc_hashHasKey.sqf b/addons/common/functions/fnc_hashHasKey.sqf deleted file mode 100644 index 65c1517e4f..0000000000 --- a/addons/common/functions/fnc_hashHasKey.sqf +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Author: ? - * ? - * - * Arguments: - * ? - * - * Return Value: - * ? - * - * Public: ? - */ -#include "script_component.hpp" - -ACE_DEPRECATED(QFUNC(hashHasKey),"3.8.0","CBA_fnc_hashHasKey"); - -// diag_log text format["%1 HASH HAS KEY: %2", diag_tickTime, _this]; - -params ["_hash", "_key"]; - -ERRORDATA(2); -private _val = false; -try { - if(VALIDHASH(_hash)) then { - private _index = (_hash select 0) find _key; - if(_index != -1) then { - _val = true; - }; - } else { - ERROR("Input hash is not valid"); - }; -} catch { - HANDLECATCH; -}; -_val diff --git a/addons/common/functions/fnc_hashRem.sqf b/addons/common/functions/fnc_hashRem.sqf deleted file mode 100644 index a09f87ee2e..0000000000 --- a/addons/common/functions/fnc_hashRem.sqf +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Author: ? - * ? - * - * Arguments: - * ? - * - * Return Value: - * ? - * - * Public: ? - */ -#include "script_component.hpp" - -ACE_DEPRECATED(QFUNC(hashRem),"3.8.0","CBA_fnc_hashRem"); - -params ["_hash", "_key"]; - -ERRORDATA(2); -private _val = nil; -try { - if(VALIDHASH(_hash)) then { - private _index = (_hash select 0) find _key; - if(_index != -1) then { - (_hash select 1) set[_index, "ACREHASHREMOVEDONOTUSETHISVAL"]; - // is this hash is not part of a hash list? - // if it is we need to leave the keys intact. - if((count _hash) == 2) then { - // if this is a standalone hash then we can clean it up - (_hash select 0) set[_index, "ACREHASHREMOVEDONOTUSETHISVAL"]; - _hash set[0, ((_hash select 0) - ["ACREHASHREMOVEDONOTUSETHISVAL"])]; - _hash set[1, ((_hash select 1) - ["ACREHASHREMOVEDONOTUSETHISVAL"])]; - }; - }; - } else { - ERROR("Input hash is not valid"); - }; -} catch { - HANDLECATCH; -}; -true diff --git a/addons/common/functions/fnc_hashSet.sqf b/addons/common/functions/fnc_hashSet.sqf deleted file mode 100644 index 8344b50f92..0000000000 --- a/addons/common/functions/fnc_hashSet.sqf +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Author: ? - * ? - * - * Arguments: - * ? - * - * Return Value: - * ? - * - * Public: ? - */ -#include "script_component.hpp" - -ACE_DEPRECATED(QFUNC(hashSet),"3.8.0","CBA_fnc_hashSet"); - -// diag_log text format["%1 HASH SET: %2", diag_tickTime, _this]; - -params ["_hash", "_key", "_val"]; - -ERRORDATA(3); -try { - if(VALIDHASH(_hash)) then { - private _index = (_hash select 0) find _key; - if(_index == -1) then { - _index = (_hash select 0) find "ACREHASHREMOVEDONOTUSETHISVAL"; - if(_index == -1) then { - _index = (count (_hash select 0)); - }; - (_hash select 0) set[_index, _key]; - }; - (_hash select 1) set[_index, _val]; - } else { - ERROR("Input hash is not valid"); - }; -} catch { - HANDLECATCH; -}; diff --git a/addons/common/functions/fnc_headBugFix.sqf b/addons/common/functions/fnc_headBugFix.sqf index 07a1652b1b..edea791f24 100644 --- a/addons/common/functions/fnc_headBugFix.sqf +++ b/addons/common/functions/fnc_headBugFix.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: rocko * Fixes animation issues that may get you stuck @@ -8,11 +9,13 @@ * Return Value: * None * + * Example: + * [] call ace_common_fnc_headBugFix + * * Public: Yes * * Note: Has to be spawned not called */ -#include "script_component.hpp" private _unit = ACE_player; private _anim = animationState _unit; diff --git a/addons/common/functions/fnc_hideUnit.sqf b/addons/common/functions/fnc_hideUnit.sqf index e0adb201c3..e67f68dcc3 100644 --- a/addons/common/functions/fnc_hideUnit.sqf +++ b/addons/common/functions/fnc_hideUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike (based on muteUnit) * Globally hides a unit. This allows the handling of more than one reason to hide an object globally. @@ -7,14 +8,13 @@ * 1: Reason to hide the unit * * Return Value: - * nil + * None * * Example: * [ACE_Player, "SpectatorMode"] call ace_common_fnc_hideUnit * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_reason"]; diff --git a/addons/common/functions/fnc_inTransitionAnim.sqf b/addons/common/functions/fnc_inTransitionAnim.sqf index fd90291d73..5999bcbe27 100644 --- a/addons/common/functions/fnc_inTransitionAnim.sqf +++ b/addons/common/functions/fnc_inTransitionAnim.sqf @@ -1,15 +1,18 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if given unit is in a transitional animation * * Arguments: - * 0: A soldier + * 0: A soldier * * Return Value: - * + * Boolean + * + * Example: + * [bob] call ace_common_fnc_inTransitionAnim * * Public: Yes */ -#include "script_component.hpp" getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> animationState (_this select 0) >> "looped") == 0 // return diff --git a/addons/common/functions/fnc_insertionSort.sqf b/addons/common/functions/fnc_insertionSort.sqf deleted file mode 100644 index 1b664e1fd6..0000000000 --- a/addons/common/functions/fnc_insertionSort.sqf +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Author: Ruthberg - * Sorts an array of numbers - * - * Arguments: - * 0: array - * 1: ascending (optional) - * - * Return Value: - * sortedArray (ARRAY) - * - * Public: No - */ -#include "script_component.hpp" - -ACE_DEPRECATED(QFUNC(insertionSort),"3.8.0","sort"); - -params [["_list", [], [[]]], ["_ascending", true, [false]]]; - -_list = + _list; // copy array to not alter the original one -_list sort _ascending; -_list diff --git a/addons/common/functions/fnc_interpolateFromArray.sqf b/addons/common/functions/fnc_interpolateFromArray.sqf index 07207071e7..851d368d37 100644 --- a/addons/common/functions/fnc_interpolateFromArray.sqf +++ b/addons/common/functions/fnc_interpolateFromArray.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Interpolates between two set points in a curve. @@ -9,13 +10,15 @@ * Return Value: * Interpolation result * + * Example: + * [[0,1], 5] call ace_common_fnc_interpolateFromArray + * * Public: Yes */ -#include "script_component.hpp" params ["_array", "_value"]; private _min = _array select floor _value; private _max = _array select ceil _value; -_min + (_max - _min) * (_value % 1) // return +linearConversion [0, 1, _value % 1, _min, _max] // return diff --git a/addons/common/functions/fnc_isAwake.sqf b/addons/common/functions/fnc_isAwake.sqf index 1179ced02f..916f545685 100644 --- a/addons/common/functions/fnc_isAwake.sqf +++ b/addons/common/functions/fnc_isAwake.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if unit is awake. Will be false when death or unit is unconscious. @@ -8,9 +9,11 @@ * Return Value: * if unit is awake * + * Example: + * [bob] call ace_common_fnc_isAwake + * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_isEOD.sqf b/addons/common/functions/fnc_isEOD.sqf index ee82cf2068..226d315e36 100644 --- a/addons/common/functions/fnc_isEOD.sqf +++ b/addons/common/functions/fnc_isEOD.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth de Wet (LH) * Checks whether the passed unit is an explosive specialist. @@ -16,8 +17,7 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; -_unit getVariable ["ACE_isEOD", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "canDeactivateMines") == 1] // return +_unit getVariable ["ACE_isEOD", _unit getUnitTrait "explosiveSpecialist"] // return diff --git a/addons/common/functions/fnc_isEngineer.sqf b/addons/common/functions/fnc_isEngineer.sqf index 01eabfc0b3..1805bb50e5 100644 --- a/addons/common/functions/fnc_isEngineer.sqf +++ b/addons/common/functions/fnc_isEngineer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: marc_book, edited by commy2 * Checks if a unit is an engineer. @@ -13,11 +14,10 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; -private _isEngineer = _unit getVariable ["ACE_isEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer") == 1]; +private _isEngineer = _unit getVariable ["ACE_isEngineer", _unit getUnitTrait "engineer"]; //Handle ace_repair modules setting this to a number if (_isEngineer isEqualType 0) then {_isEngineer = _isEngineer > 0}; diff --git a/addons/common/functions/fnc_isFeatureCameraActive.sqf b/addons/common/functions/fnc_isFeatureCameraActive.sqf index 7d282109b2..00e3db699a 100644 --- a/addons/common/functions/fnc_isFeatureCameraActive.sqf +++ b/addons/common/functions/fnc_isFeatureCameraActive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Sniperwolf572 * Checks if one of the following common feature cameras is active: @@ -5,6 +6,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) @@ -21,14 +23,15 @@ * * Public: Yes */ -#include "script_component.hpp" !( isNull curatorCamera && // Curator - {isNull (GETMVAR(EGVAR(spectator,camera),objNull))} && // 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 + {GETMVAR(EGVAR(huntir,stop),true)} && // ACE Hunt IR + {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_isInBuilding.sqf b/addons/common/functions/fnc_isInBuilding.sqf index d4a9307cd6..4b843fcea4 100644 --- a/addons/common/functions/fnc_isInBuilding.sqf +++ b/addons/common/functions/fnc_isInBuilding.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit is in a building. Will return true if the unit is sitting in a bush. @@ -8,9 +9,11 @@ * Return Value: * Is the unit in a building? * + * Example: + * [bob] call ace_common_fnc_isInBuilding + * * Public: Yes */ -#include "script_component.hpp" #define CHECK_DISTANCE 10 diff --git a/addons/common/functions/fnc_isMedic.sqf b/addons/common/functions/fnc_isMedic.sqf new file mode 100644 index 0000000000..9618a15548 --- /dev/null +++ b/addons/common/functions/fnc_isMedic.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * 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 + */ + +params ["_unit"]; + +private _isMedic = _unit getVariable [QEGVAR(medical,medicClass), getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "attendant")]; + +_isMedic > 0 diff --git a/addons/common/functions/fnc_isModLoaded.sqf b/addons/common/functions/fnc_isModLoaded.sqf index 46e1bc03a8..b69086e39d 100644 --- a/addons/common/functions/fnc_isModLoaded.sqf +++ b/addons/common/functions/fnc_isModLoaded.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check in cfgPatches if modification is loaded @@ -8,9 +9,11 @@ * Return Value: * if modification is loaded * + * Example: + * ["class"] call ace_common_fnc_isModLoaded + * * Public: Yes */ -#include "script_component.hpp" params [["_modName", "", [""]]]; diff --git a/addons/common/functions/fnc_isPlayer.sqf b/addons/common/functions/fnc_isPlayer.sqf index fe265bd925..8aabbd3bc0 100644 --- a/addons/common/functions/fnc_isPlayer.sqf +++ b/addons/common/functions/fnc_isPlayer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578, commy2, akalegman * Checks if a unit is a player / curator controlled unit. @@ -15,7 +16,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", ["_excludeRemoteControlled", false]]; diff --git a/addons/common/functions/fnc_isSwimming.sqf b/addons/common/functions/fnc_isSwimming.sqf new file mode 100644 index 0000000000..c7b290a65c --- /dev/null +++ b/addons/common/functions/fnc_isSwimming.sqf @@ -0,0 +1,20 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 deleted file mode 100644 index 637ed49f3d..0000000000 --- a/addons/common/functions/fnc_isUnderwater.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Author: Glowbal - * Check if unit's head is underwater - * - * Arguments: - * 0: Unit - * - * Return Value: - * If unit's head is underwater - * - * Public: Yes - */ -#include "script_component.hpp" - -params [["_unit", objNull, [objNull]]]; - -private _return = false; - -if (surfaceIsWater getPosASL _unit) then { - private _pos = _unit modelToWorldVisual (_unit selectionPosition "head"); - - if (_pos select 2 < 0) then { - _return = true; - }; -}; - -_return diff --git a/addons/common/functions/fnc_lightIntensityFromObject.sqf b/addons/common/functions/fnc_lightIntensityFromObject.sqf index a495897dea..538246b537 100644 --- a/addons/common/functions/fnc_lightIntensityFromObject.sqf +++ b/addons/common/functions/fnc_lightIntensityFromObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Calculate light intensity object 1 recieves from object 2 @@ -7,11 +8,13 @@ * 1: Object that emits light * * Return Value: - * Brightest light level + * Brightest light level + * + * Example: + * [reciever, giver] call ace_common_fnc_lightIntensityFromObject * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_lightSource"]; @@ -76,6 +79,21 @@ if (_lightSource isKindOf "CAManBase") then { } forEach _lights; + if (isCollisionLightOn _lightSource) then { + private _markerLights = [ + _lightSource, + {configProperties [configFile >> "CfgVehicles" >> typeOf _this >> "MarkerLights", "isClass _x", true]}, + uiNamespace, + format [QEGVAR(cache,MarkerLights_%1), typeOf _lightSource], + 1E11 + ] call FUNC(cachedCall); + { + private _position = _lightSource modelToWorld (_lightSource selectionPosition getText (_x >> "name")); + private _distance = _unitPos distance _position; + _lightLevel = _lightLevel max (linearConversion [0, 10, _distance, 1, 0, true] * linearConversion [0, 1300, getNumber (_x >> "intensity"), 0, 1, true]); + } forEach _markerLights; + }; + // handle campfires if (inflamed _lightSource) then { private _distance = _unitPos distance position _lightSource; diff --git a/addons/common/functions/fnc_loadPerson.sqf b/addons/common/functions/fnc_loadPerson.sqf index f8a4456b96..466387cc72 100644 --- a/addons/common/functions/fnc_loadPerson.sqf +++ b/addons/common/functions/fnc_loadPerson.sqf @@ -1,34 +1,32 @@ +#include "script_component.hpp" /* * 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 * * Public: Yes */ -#include "script_component.hpp" #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 db0248a901..109e7e8e77 100644 --- a/addons/common/functions/fnc_loadPersonLocal.sqf +++ b/addons/common/functions/fnc_loadPersonLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Load a person, local @@ -10,15 +11,17 @@ * Return Value: * None * + * Example: + * [bob, car, kevin] call ace_common_fnc_loadPersonLocal + * * Public: Yes */ -#include "script_component.hpp" 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 46b0134740..0000000000 --- a/addons/common/functions/fnc_loadSettingsFromProfile.sqf +++ /dev/null @@ -1,37 +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 - * - * 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 6a2711c2a7..0000000000 --- a/addons/common/functions/fnc_loadSettingsLocalizedText.sqf +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Author: Glowbal - * Parse all settings and load the localized displayName and description for all text - * - * Arguments: - * None - * - * Return Value: - * None - * - * 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 { - ACE_LOGWARNING_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 { - ACE_LOGWARNING_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 { - ACE_LOGWARNING_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 4498c9d058..0000000000 --- a/addons/common/functions/fnc_loadSettingsOnServer.sqf +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Author: esteldunedain - * Load the parameters on the server. - * Config < Server UserConfig < Mission Config - * - * Arguments: - * None - * - * Return Value: - * None - * - * 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_localEvent.sqf b/addons/common/functions/fnc_localEvent.sqf deleted file mode 100644 index fb473b75b8..0000000000 --- a/addons/common/functions/fnc_localEvent.sqf +++ /dev/null @@ -1,13 +0,0 @@ -#include "script_component.hpp" - -params ["_eventName", "_eventArgs"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -[_eventName, _eventArgs] call CBA_fnc_localEvent; - -ACE_DEPRECATED("ace_common_fnc_localEvent","3.8.0","CBA_fnc_localEvent"); diff --git a/addons/common/functions/fnc_moduleCheckPBOs.sqf b/addons/common/functions/fnc_moduleCheckPBOs.sqf index 4585682496..583441d4d2 100644 --- a/addons/common/functions/fnc_moduleCheckPBOs.sqf +++ b/addons/common/functions/fnc_moduleCheckPBOs.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Initializes the check-PBOs module. @@ -10,11 +11,11 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_common_fnc_moduleCheckPBOs + * * Public: No */ -#include "script_component.hpp" - -if !(isServer) exitWith {}; params ["_logic", "_units", "_activated"]; @@ -24,4 +25,4 @@ if !(_activated) exitWith {}; [_logic, QGVAR(checkPBOsCheckAll), "CheckAll" ] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(checkPBOsWhitelist), "Whitelist" ] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO_1("Check-PBOs Module Initialized. Mode: %1.",GVAR(checkPBOsAction)); +INFO_1("Check-PBOs Module Initialized. Mode: %1.",GVAR(checkPBOsAction)); diff --git a/addons/common/functions/fnc_moduleLSDVehicles.sqf b/addons/common/functions/fnc_moduleLSDVehicles.sqf index 8a6cb90eca..97ce3833eb 100644 --- a/addons/common/functions/fnc_moduleLSDVehicles.sqf +++ b/addons/common/functions/fnc_moduleLSDVehicles.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, joko // Jonas * Nothing to see here, move along. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob, target, []] call ace_common_fnc_moduleLSDVehicles + * * Public: No */ -#include "script_component.hpp" params ["", "_units", "_activated"]; @@ -56,4 +59,4 @@ if (isNil QGVAR(LSD_PFH)) then { }, 0.02, [0]] call CBA_fnc_addPerFrameHandler; }; -ACE_LOGINFO("WEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED."); +INFO("WEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEED."); diff --git a/addons/common/functions/fnc_monitor.sqf b/addons/common/functions/fnc_monitor.sqf index 8aef62895c..17d3087c53 100644 --- a/addons/common/functions/fnc_monitor.sqf +++ b/addons/common/functions/fnc_monitor.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * hint retun value of given function every frame @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [{code}] call ace_common_fnc_monitor + * * Public: Yes */ -#include "script_component.hpp" if (!isNil QGVAR(MonitorFnc)) then { [GVAR(MonitorFnc)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/common/functions/fnc_muteUnit.sqf b/addons/common/functions/fnc_muteUnit.sqf index 11c18aedd7..fe65a56492 100644 --- a/addons/common/functions/fnc_muteUnit.sqf +++ b/addons/common/functions/fnc_muteUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Mutes the unit. It won't trigger auto generated chat messages either. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, "because"] call ace_common_fnc_muteUnit + * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_reason"]; diff --git a/addons/common/functions/fnc_muteUnitHandleInitPost.sqf b/addons/common/functions/fnc_muteUnitHandleInitPost.sqf index 53e8d4d5b7..4681ca73aa 100644 --- a/addons/common/functions/fnc_muteUnitHandleInitPost.sqf +++ b/addons/common/functions/fnc_muteUnitHandleInitPost.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Applies speaker changes on init post. Used because setSpeaker is broken on init. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_muteUnitHandleInitPost + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_muteUnitHandleRespawn.sqf b/addons/common/functions/fnc_muteUnitHandleRespawn.sqf index ceb0614116..b507e7ec1d 100644 --- a/addons/common/functions/fnc_muteUnitHandleRespawn.sqf +++ b/addons/common/functions/fnc_muteUnitHandleRespawn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Applies speaker changes on respawn. Used because speaker is respawning breaks the speaker on non-local clients. Also resets the public object variable (broken for JIP clients, that join after respawn) @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_muteUnitHandleRespawn + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf new file mode 100644 index 0000000000..30b0594b30 --- /dev/null +++ b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 b90f0eefd7..ff4cd23977 100644 --- a/addons/common/functions/fnc_numberToDigits.sqf +++ b/addons/common/functions/fnc_numberToDigits.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: commy2 + * Author: commy2, SilentSpike * Transforms a number to an array of the correspondending digits. * * Arguments: @@ -9,30 +10,14 @@ * Return Value: * Digits. The maximum count is six digits. * + * Example: + * [5, 5] call ace_common_fnc_numberToDigits + * * Public: Yes */ -#include "script_component.hpp" 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 7e2c78f8b4..35b0d0fd9b 100644 --- a/addons/common/functions/fnc_numberToDigitsString.sqf +++ b/addons/common/functions/fnc_numberToDigitsString.sqf @@ -1,32 +1,21 @@ +#include "script_component.hpp" /* * Author: commy2 * Transforms a number to an string of the correspondending digits. * * Arguments: * 0: Number to 'digitize' - * 1: Set the minimal length of the returned string. Useful for getting left hand zeroes. (Number, optional) + * 1: Set the minimal length of the returned string. Useful for getting left hand zeroes. (Optional) * * Return Value: * Digits. The maximum length is six digits. * + * Example: + * [5, 5] call ace_common_fnc_numberToDigitsString + * * Public: Yes */ -#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_numberToString.sqf b/addons/common/functions/fnc_numberToString.sqf index 1cb2f521f8..8d5aaa09a1 100644 --- a/addons/common/functions/fnc_numberToString.sqf +++ b/addons/common/functions/fnc_numberToString.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Converts a number to a string without losing as much precission as str or format. @@ -8,9 +9,11 @@ * Return Value: * The number as string * + * Example: + * [5] call ace_common_fnc_numberToString + * * Public: Yes */ -#include "script_component.hpp" params ["_number"]; diff --git a/addons/common/functions/fnc_objectEvent.sqf b/addons/common/functions/fnc_objectEvent.sqf deleted file mode 100644 index 878b0d80d1..0000000000 --- a/addons/common/functions/fnc_objectEvent.sqf +++ /dev/null @@ -1,13 +0,0 @@ -#include "script_component.hpp" - -params ["_eventName", "_eventTargets", "_eventArgs"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -[_eventName, _eventArgs, _eventTargets] call CBA_fnc_targetEvent; - -ACE_DEPRECATED("ace_common_fnc_objectEvent","3.8.0","CBA_fnc_targetEvent"); diff --git a/addons/common/functions/fnc_onAnswerRequest.sqf b/addons/common/functions/fnc_onAnswerRequest.sqf index 8c77719256..5613e5d1bc 100644 --- a/addons/common/functions/fnc_onAnswerRequest.sqf +++ b/addons/common/functions/fnc_onAnswerRequest.sqf @@ -1,16 +1,21 @@ +#include "script_component.hpp" /* * Author: Glowbal * N/A * * Arguments: - * ? + * 0: Unit + * 1: ID? + * 2: Accepted * * Return Value: - * ? + * None + * + * Example: + * [bob, "ID", true] call ace_common_fnc_onAnswerRequest * * Public: No */ -#include "script_component.hpp" params ["_unit", "_id", "_accepted"]; diff --git a/addons/common/functions/fnc_owned.sqf b/addons/common/functions/fnc_owned.sqf index e352795c5e..e216b10c39 100644 --- a/addons/common/functions/fnc_owned.sqf +++ b/addons/common/functions/fnc_owned.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Counterpart of ace_common_fnc_claim. Check if the given object is claimed by another unit. @@ -6,11 +7,13 @@ * 0: Any object. * * Return Value: - * Is this object claimed by someone? + * Is this object claimed by someone? + * + * Example: + * [bob] call ace_common_fnc_owned * * Public: No */ -#include "script_component.hpp" params ["_target"]; diff --git a/addons/common/functions/fnc_parseList.sqf b/addons/common/functions/fnc_parseList.sqf index fc92605682..d3e2871f44 100644 --- a/addons/common/functions/fnc_parseList.sqf +++ b/addons/common/functions/fnc_parseList.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Jonpas * Makes a list from a string using comma as a delimiter, optionally trim or remove whitespace and check each for object existence. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_list", ["_removeWhitespace", false], ["_checkNil", false]]; @@ -28,7 +28,7 @@ private _whitespaceList = []; { if (_removeWhitespace) then { - _whitespaceList pushBack ([_x] call FUNC(stringRemoveWhiteSpace)); + _whitespaceList pushBack ([_x] call CBA_fnc_removeWhitespace); } else { _whitespaceList pushBack ([_x] call CBA_fnc_trim); }; diff --git a/addons/common/functions/fnc_playConfigSound3D.sqf b/addons/common/functions/fnc_playConfigSound3D.sqf index 6253f75fb4..ee8d81f2c9 100644 --- a/addons/common/functions/fnc_playConfigSound3D.sqf +++ b/addons/common/functions/fnc_playConfigSound3D.sqf @@ -1,35 +1,43 @@ +#include "script_component.hpp" /* * 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: + * ["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 { - ACE_LOGERROR_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_player.sqf b/addons/common/functions/fnc_player.sqf index 1a268515a7..d691741e53 100644 --- a/addons/common/functions/fnc_player.sqf +++ b/addons/common/functions/fnc_player.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578, commy2 * Returns the player or curator controlled unit. @@ -9,8 +10,10 @@ * Return Value: * Player controlled unit * + * Example: + * [] call ace_common_fnc_player + * * Public: Yes */ -#include "script_component.hpp" missionNamespace getVariable ["bis_fnc_moduleRemoteControl_unit", player] diff --git a/addons/common/functions/fnc_playerSide.sqf b/addons/common/functions/fnc_playerSide.sqf index 3a7ce5bba9..6d42df6511 100644 --- a/addons/common/functions/fnc_playerSide.sqf +++ b/addons/common/functions/fnc_playerSide.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Return the current side of the player @@ -8,8 +9,10 @@ * Return Value: * current local side * + * Example: + * [] call ace_common_fnc_playerSide + * * Public: Yes */ -#include "script_component.hpp" side group ACE_player diff --git a/addons/common/functions/fnc_positionToASL.sqf b/addons/common/functions/fnc_positionToASL.sqf index 267bbf2353..8d0586e097 100644 --- a/addons/common/functions/fnc_positionToASL.sqf +++ b/addons/common/functions/fnc_positionToASL.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Converts Arma "Position" to ASL @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [1, 1, 1] call ace_common_fnc_positionToASL + * * Public: Yes */ -#include "script_component.hpp" if (surfaceIsWater _this) then { _this diff --git a/addons/common/functions/fnc_progressBar.sqf b/addons/common/functions/fnc_progressBar.sqf index 7103dd08e4..9b52796569 100644 --- a/addons/common/functions/fnc_progressBar.sqf +++ b/addons/common/functions/fnc_progressBar.sqf @@ -1,26 +1,26 @@ +#include "script_component.hpp" /* * Author: commy2, Glowbal, PabstMirror * Draw progress bar and execute given function if succesful. * Finish/Failure/Conditional are all passed [_args, _elapsedTime, _totalTime, _errorCode] * * Arguments: - * 0: NUMBER - Total Time (in game "time" seconds) - * 1: ARRAY - Arguments, passed to condition, fail and finish - * 2: CODE or STRING - On Finish: Code called or STRING raised as event. - * 3: CODE or STRING - On Failure: Code called or STRING raised as event. - * 4: STRING - (Optional) Localized Title - * 5: CODE - (Optional) Code to check each frame - * 6: ARRAY - (Optional) Exceptions for checking EFUNC(common,canInteractWith) + * 0: Total Time (in game "time" seconds) + * 1: Arguments, passed to condition, fail and finish + * 2: On Finish: Code called or STRING raised as event. + * 3: On Failure: Code called or STRING raised as event. + * 4: (Optional) Localized Title + * 5: Code to check each frame (Optional) + * 6: Exceptions for checking EFUNC(common,canInteractWith) (Optional) * * Return Value: - * Nothing + * None * * Example: * [5, [], {Hint "Finished!"}, {hint "Failure!"}, "My Title"] call ace_common_fnc_progressBar * * Public: Yes */ -#include "script_component.hpp" params ["_totalTime", "_args", "_onFinish", "_onFail", ["_localizedTitle", ""], ["_condition", {true}], ["_exceptions", []]]; diff --git a/addons/common/functions/fnc_readSettingFromModule.sqf b/addons/common/functions/fnc_readSettingFromModule.sqf index 3e2a5d862e..d61671d604 100644 --- a/addons/common/functions/fnc_readSettingFromModule.sqf +++ b/addons/common/functions/fnc_readSettingFromModule.sqf @@ -1,7 +1,9 @@ +#define DEBUG_MODE_FULL +#include "script_component.hpp" /* * 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 @@ -11,17 +13,22 @@ * Return Value: * None * + * Example: + * [MODULE, "Param", "paramname"] call ace_common_fnc_readSettingFromModule + * * Public: No */ -#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 { - ACE_LOGWARNING_2("Warning in %1 module: %2 setting is missing. Probably an obsolete version of the module is used in the mission.",typeOf _logic,_moduleVariable); + 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); }; private _value = _logic getVariable _moduleVariable; @@ -29,10 +36,15 @@ if (_value isEqualTo -1) then { //3den missions will save modules with value = 0 as -1 //If the setting has a "values" array, we should be able to assume that -1 is not a valid number as it would not be a valid index for the array if (isArray (configFile >> "ACE_Settings" >> _settingName >> "values")) then { - ACE_LOGWARNING_2("Module For Setting [%1] is saved as (-1), switching to (0) - missionVersion [%2]",_settingName,missionVersion); + WARNING_2("Module For Setting [%1] is saved as (-1), switching to (0) - missionVersion [%2]",_settingName,missionVersion); _value = 0; }; }; -// 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 e158ae5c81..277ba23a5d 100644 --- a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf +++ b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf @@ -1,3 +1,5 @@ +#define DEBUG_MODE_FULL +#include "script_component.hpp" /* * Author: PabstMirror * Read settins from paramsArray that have a ACE_setting = 1. @@ -14,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" //paramsArray is a normal variable not a command private _paramsArray = missionnamespace getVariable ["paramsArray", []]; @@ -32,32 +33,35 @@ TRACE_1("Reading missionConfigFile params",_paramsArray); // Check if the variable is already defined if (isNil _settingName) exitWith { - ACE_LOGERROR_1("readSettingsFromParamsArray - param [%1] is not an ace_setting", _settingName); + 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 {ACE_LOGWARNING_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 { - ACE_LOGWARNING_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_receiveRequest.sqf b/addons/common/functions/fnc_receiveRequest.sqf index 1bb48428df..e2f25ed734 100644 --- a/addons/common/functions/fnc_receiveRequest.sqf +++ b/addons/common/functions/fnc_receiveRequest.sqf @@ -1,16 +1,23 @@ +#include "script_component.hpp" /* * Author: Glowbal * N/A * * Arguments: - * ? + * 0: caller + * 1: target + * 2: requestID + * 3: Message + * 4: callback (NOT USED) * * Return Value: * None * + * Example: + * [bob, kevin, "ID", "Message", {Callback}] call ace_common_fnc_recieveRequest + * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target", "_requestID", "_requestMessage", "_callBack"]; diff --git a/addons/common/functions/fnc_removeActionEventHandler.sqf b/addons/common/functions/fnc_removeActionEventHandler.sqf index 60e551590d..e536adc191 100644 --- a/addons/common/functions/fnc_removeActionEventHandler.sqf +++ b/addons/common/functions/fnc_removeActionEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Remove an addAction event from a unit. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [bob, "DefaultAction", 5] call ace_common_fnc_removeActionEventHandler + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_action", "_id"]; diff --git a/addons/common/functions/fnc_removeActionMenuEventHandler.sqf b/addons/common/functions/fnc_removeActionMenuEventHandler.sqf index 943e3b4e22..ed072db89a 100644 --- a/addons/common/functions/fnc_removeActionMenuEventHandler.sqf +++ b/addons/common/functions/fnc_removeActionMenuEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Remove an addAction menu event from a unit. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [bob, "DefaultAction", 5] call ace_common_fnc_removeActionMenuEventHandler + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_action", "_id"]; diff --git a/addons/common/functions/fnc_removeAllEventHandlers.sqf b/addons/common/functions/fnc_removeAllEventHandlers.sqf deleted file mode 100644 index 958923f808..0000000000 --- a/addons/common/functions/fnc_removeAllEventHandlers.sqf +++ /dev/null @@ -1,14 +0,0 @@ -#include "script_component.hpp" - -params ["_eventName"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -CBA_events_eventNamespace setVariable [_eventName,nil]; -CBA_events_eventHashes setVariable [_eventName,nil]; - -ACE_DEPRECATED("ace_common_fnc_removeAllEventHandlers","3.8.0","N/A (remove events individually w/ CBA_fnc_removeEventHandler)"); diff --git a/addons/common/functions/fnc_removeBinocularMagazine.sqf b/addons/common/functions/fnc_removeBinocularMagazine.sqf deleted file mode 100644 index 4f1e0fcdd6..0000000000 --- a/addons/common/functions/fnc_removeBinocularMagazine.sqf +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Author: commy2 - * Removes the magazine of the units rangefinder. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Example: - * player call ace_common_fnc_removeBinocularMagazine - * - * Public: Yes - */ -#include "script_component.hpp" - -ACE_DEPRECATED("ace_common_fnc_removeBinocularMagazine","3.8.0","CBA_fnc_removeBinocularMagazine"); - -_this call CBA_fnc_removeBinocularMagazine diff --git a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf index b267e84557..4538a67fb0 100644 --- a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Remove a condition that gets checked by ace_common_fnc_canInteractWith. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * ["ID"] call ace_common_fnc_removeCanInteractWithCondition + * * Public: No */ -#include "script_component.hpp" params ["_conditionName"]; diff --git a/addons/common/functions/fnc_removeEventHandler.sqf b/addons/common/functions/fnc_removeEventHandler.sqf deleted file mode 100644 index ff89571a6e..0000000000 --- a/addons/common/functions/fnc_removeEventHandler.sqf +++ /dev/null @@ -1,13 +0,0 @@ -#include "script_component.hpp" - -params ["_eventName", "_eventCode"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -[_eventName, _eventCode] call CBA_fnc_removeEventHandler; - -ACE_DEPRECATED("ace_common_fnc_removeEventHandler","3.8.0","CBA_fnc_removeEventHandler"); diff --git a/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf b/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf index 825281c3e0..2a95b0f4d7 100644 --- a/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf +++ b/addons/common/functions/fnc_removeMapMarkerCreatedEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Remove a map marker creation event handler. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [5] call ace_common_fnc_removeMapMarkerCreatedEventHandler + * * Public: Yes */ -#include "script_component.hpp" params ["_id"]; diff --git a/addons/common/functions/fnc_removeScrollWheelEventHandler.sqf b/addons/common/functions/fnc_removeScrollWheelEventHandler.sqf deleted file mode 100644 index d7a8ae28cc..0000000000 --- a/addons/common/functions/fnc_removeScrollWheelEventHandler.sqf +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Author: commy2 - * Remove a scroll wheel event handler. - * - * Arguments: - * 0: ID of the event handler - * - * Return Value: - * None - * - * Public: Yes - */ -#include "script_component.hpp" - -params ["_id"]; - -private _actionsVar = missionNamespace getVariable ["ACE_EventHandler_ScrollWheel", [-1, [], []]]; - -_actionsVar params ["_currentId", "_actionIDs", "_actions"]; - -_id = _actionIDs find _id; - -if (_id == -1) exitWith {}; - -_actionIDs set [_id, -1]; -_actionIDs = _actionIDs - [-1]; - -_actions set [_id, []];//{} -_actions = _actions - [[]];//[{}] - -missionNamespace setVariable ["ACE_EventHandler_ScrollWheel", [_currentId, _actionIDs, _actions]]; diff --git a/addons/common/functions/fnc_removeSpecificMagazine.sqf b/addons/common/functions/fnc_removeSpecificMagazine.sqf index 4ca5eec6d7..141aa28526 100644 --- a/addons/common/functions/fnc_removeSpecificMagazine.sqf +++ b/addons/common/functions/fnc_removeSpecificMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Removes a magazine from the unit that has an specific ammo count @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [bob, "magazine", 5] call ace_common_fnc_removeSpecificMagazine + * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_magazineType", "", [""]], ["_ammoCount", 0, [0]]]; diff --git a/addons/common/functions/fnc_removeSyncedEventHandler.sqf b/addons/common/functions/fnc_removeSyncedEventHandler.sqf index 157b9699e4..5e9eb48aa7 100644 --- a/addons/common/functions/fnc_removeSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_removeSyncedEventHandler.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: jaynus * Remove a synced event handler @@ -6,16 +7,18 @@ * 0: Name * * Return Value: - * Boolean of success + * Boolean of success + * + * Example: + * ["bob"] call ace_common_fnc_removeSyncedEventHandler * * Public: No */ -#include "script_component.hpp" params ["_name"]; if !([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { - ACE_LOGERROR_1("Synced event key [%1] not found (removeSyncedEventHandler).", _name); + ERROR_1("Synced event key [%1] not found (removeSyncedEventHandler).", _name); false }; diff --git a/addons/common/functions/fnc_requestCallback.sqf b/addons/common/functions/fnc_requestCallback.sqf index 399f50466d..6729c19a6d 100644 --- a/addons/common/functions/fnc_requestCallback.sqf +++ b/addons/common/functions/fnc_requestCallback.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* * Author: Glowbal * N/A * * Arguments: - * ? + * ? * * Return Value: - * ? + * ? + * + * Example: + * [bob] call ace_common_fnc_requestCallback * * Public: No */ -#include "script_component.hpp" params ["_info", "_accepted"]; diff --git a/addons/common/functions/fnc_requestSyncedEvent.sqf b/addons/common/functions/fnc_requestSyncedEvent.sqf index e35c1e3645..44b633b9de 100644 --- a/addons/common/functions/fnc_requestSyncedEvent.sqf +++ b/addons/common/functions/fnc_requestSyncedEvent.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: jaynus * Send a request to synchronize an event name from the client->server. Execute on client only. @@ -6,11 +7,13 @@ * 0: eventName * * Return Value: - * Boolean of success + * Boolean of success + * + * Example: + * ["event"] call ace_common_fnc_requestSyncedEvent * * Public: No */ -#include "script_component.hpp" params ["_eventName"]; diff --git a/addons/common/functions/fnc_resetAllDefaults.sqf b/addons/common/functions/fnc_resetAllDefaults.sqf index 6432f3759e..dc638e4947 100644 --- a/addons/common/functions/fnc_resetAllDefaults.sqf +++ b/addons/common/functions/fnc_resetAllDefaults.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* * Author: Glowbal * reset all variables that have been defined * * Arguments: - * ? + * 0: Unit * * Return Value: - * ? + * ? + * + * Example: + * [bob] call ace_common_fnc_resetAllDefaults * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_restoreVariablesJIP.sqf b/addons/common/functions/fnc_restoreVariablesJIP.sqf index 39626514bb..0c0617be77 100644 --- a/addons/common/functions/fnc_restoreVariablesJIP.sqf +++ b/addons/common/functions/fnc_restoreVariablesJIP.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Called from respawn eventhandler. Resets all public object namespace variables that are added via FUNC(setVariableJIP). @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_restoreVariablesJIP + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_runAfterSettingsInit.sqf b/addons/common/functions/fnc_runAfterSettingsInit.sqf index 15631a626a..f989501dd5 100644 --- a/addons/common/functions/fnc_runAfterSettingsInit.sqf +++ b/addons/common/functions/fnc_runAfterSettingsInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Executes code after setting are initilized. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_func", "_params"]; diff --git a/addons/common/functions/fnc_runTests.sqf b/addons/common/functions/fnc_runTests.sqf new file mode 100644 index 0000000000..4e937d87b6 --- /dev/null +++ b/addons/common/functions/fnc_runTests.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_sanitizeString.sqf b/addons/common/functions/fnc_sanitizeString.sqf index 6e0db2cda2..3517c5086a 100644 --- a/addons/common/functions/fnc_sanitizeString.sqf +++ b/addons/common/functions/fnc_sanitizeString.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain, based on Killzone-Kid code * Removes quotation marks to avoid exploits and optionally html tags from text to avoid conflicts with structured text. @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_string", ["_removeTags", false]]; diff --git a/addons/common/functions/fnc_sendRequest.sqf b/addons/common/functions/fnc_sendRequest.sqf index a0c505c575..cfa52de068 100644 --- a/addons/common/functions/fnc_sendRequest.sqf +++ b/addons/common/functions/fnc_sendRequest.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Send a request to an unit and execute code based upon results. @@ -5,16 +6,18 @@ * Arguments: * 0: caller * 1: target - * 2: requestID (STRING) - * 3: requestMessage Will be localized for other target object. (STRING) - * 4: callback Code called upon accept or decline. (CODE) + * 2: requestID + * 3: requestMessage Will be localized for other target object. + * 4: callback Code called upon accept or decline. * * Return Value: * None * + * Example: + * [bob, kevin, "ID", "Message", {callback}] call ace_common_fnc_sendRequest + * * Public: Yes */ -#include "script_component.hpp" params ["_caller", "_target", "_requestID", "_requestMessage", "_callBack"]; diff --git a/addons/common/functions/fnc_serverEvent.sqf b/addons/common/functions/fnc_serverEvent.sqf deleted file mode 100644 index 5b116e9661..0000000000 --- a/addons/common/functions/fnc_serverEvent.sqf +++ /dev/null @@ -1,13 +0,0 @@ -#include "script_component.hpp" - -params ["_eventName", "_eventArgs"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -[_eventName, _eventArgs] call CBA_fnc_serverEvent; - -ACE_DEPRECATED("ace_common_fnc_serverEvent","3.8.0","CBA_fnc_serverEvent"); diff --git a/addons/common/functions/fnc_serverLog.sqf b/addons/common/functions/fnc_serverLog.sqf index af7485c494..183e110071 100644 --- a/addons/common/functions/fnc_serverLog.sqf +++ b/addons/common/functions/fnc_serverLog.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Log a RPT messaged on just the server @@ -13,7 +14,6 @@ * * Public: no */ -#include "script_component.hpp" params [["_msg", "", [""]]]; diff --git a/addons/common/functions/fnc_setAimCoef.sqf b/addons/common/functions/fnc_setAimCoef.sqf new file mode 100644 index 0000000000..5680918dfa --- /dev/null +++ b/addons/common/functions/fnc_setAimCoef.sqf @@ -0,0 +1,51 @@ +#include "script_component.hpp" +/* + * Author: xrufix, Glowbal + * Handle set AimCoef calls. Will use the highest available setting. + * + * Arguments: + * 0: Unit + * 1: Unique ID + * 2: Aim coefficient (a higher value causes more shaking) + * 3: Add (true) or remove (false) (default: true) + * + * Return Value: + * None + * + * Example: + * [player, "ace_advanced_fatigue", 1, true] call ace_common_fnc_setAimCoef + * + * Public: Yes + */ + +params ["_unit", "_id", "_setting", ["_add", true]]; + +private _exists = false; +private _highestCoef = 1; +private _map = _unit getVariable [QGVAR(setAimCoefMap), []]; + +_map = _map select { + _x params ["_xID", "_xSetting"]; + if (_id == _xID) then { + _exists = true; + if (_add) then { + _x set [1, _setting]; + _highestCoef = _highestCoef max _setting; + true + } else { + false + }; + } else { + _highestCoef = _highestCoef max _xSetting; + true + }; +}; + +if (!_exists && _add) then { + _highestCoef = _highestCoef max _setting; + _map pushBack [_id, _setting]; +}; + +// Update the value +_unit setVariable [QGVAR(setAimCoefMap), _map]; +_unit setCustomAimCoef _highestCoef; diff --git a/addons/common/functions/fnc_setApproximateVariablePublic.sqf b/addons/common/functions/fnc_setApproximateVariablePublic.sqf index 549dea9eb4..562bdfd1c8 100644 --- a/addons/common/functions/fnc_setApproximateVariablePublic.sqf +++ b/addons/common/functions/fnc_setApproximateVariablePublic.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Publish a variable if it's different enough from the previously published value. @@ -9,15 +10,13 @@ * 3: Absolute tolerance * * Return Value: - * Nothing. + * None * * Example: * [player, "balls", 2, 0.1] call ace_common_fnc_setApproximateVariablePublic; * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params ["_object", "_varName", "_value", "_tolerance"]; TRACE_4("params",_object,_varName,_value,_tolerance); diff --git a/addons/common/functions/fnc_setDefinedVariable.sqf b/addons/common/functions/fnc_setDefinedVariable.sqf index 6f1f0c2e58..4800958048 100644 --- a/addons/common/functions/fnc_setDefinedVariable.sqf +++ b/addons/common/functions/fnc_setDefinedVariable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * setVariable value @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [bob, "var", 5] call ace_common_fnc_setDefinedVariable + * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_variable", "_value", "_global"]; diff --git a/addons/common/functions/fnc_setDisableUserInputStatus.sqf b/addons/common/functions/fnc_setDisableUserInputStatus.sqf index ec475f744f..3fdc185325 100644 --- a/addons/common/functions/fnc_setDisableUserInputStatus.sqf +++ b/addons/common/functions/fnc_setDisableUserInputStatus.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Disables the user input. Works stacked. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * ["id", true] call ace_common_fnc_setDisableUserInputStatus + * * Public: Yes */ -#include "script_component.hpp" params ["_id", "_disable"]; diff --git a/addons/common/functions/fnc_setHearingCapability.sqf b/addons/common/functions/fnc_setHearingCapability.sqf index 5b1e7a5a3a..5fdb5b1272 100644 --- a/addons/common/functions/fnc_setHearingCapability.sqf +++ b/addons/common/functions/fnc_setHearingCapability.sqf @@ -1,11 +1,12 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handle set volume calls. Will use the lowest available volume setting. * * Arguments: - * 0: id - * 1: settings - * 2: add [true] OR remove [false] (default: true) + * 0: ID + * 1: Settings + * 2: Add (true) or remove (false) (default: true) * * Return Value: * None @@ -15,7 +16,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_id", "_setting", ["_add", true]]; @@ -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_setName.sqf b/addons/common/functions/fnc_setName.sqf index 1b2b515ec2..d725dcc30d 100644 --- a/addons/common/functions/fnc_setName.sqf +++ b/addons/common/functions/fnc_setName.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Sets the name variable of the object. Used to prevent issues with the name command. @@ -8,11 +9,14 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_setName + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; +TRACE_3("setName",_unit,alive _unit,name _unit); if (isNull _unit || {!alive _unit}) exitWith {}; diff --git a/addons/common/functions/fnc_setParameter.sqf b/addons/common/functions/fnc_setParameter.sqf index b24e2506b5..f7b2ca579f 100644 --- a/addons/common/functions/fnc_setParameter.sqf +++ b/addons/common/functions/fnc_setParameter.sqf @@ -1,19 +1,22 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Sets the value of an ACE_Parameter and makes it public. * * Arguments: * 0: Parameter name - * 1: Value + * 1: Value * * Return Value: * None * + * Example: + * ["Name", 5] call ace_common_fnc_setParameter + * * Public: Yes * * Deprecated */ -#include "script_component.hpp" params ["_name", "_value"]; diff --git a/addons/common/functions/fnc_setPitchBankYaw.sqf b/addons/common/functions/fnc_setPitchBankYaw.sqf index fecc16208c..debe133484 100644 --- a/addons/common/functions/fnc_setPitchBankYaw.sqf +++ b/addons/common/functions/fnc_setPitchBankYaw.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Bohemia Interactive edit by KoffeinFlummi * Sets the value of an ACE_Parameter and makes it public. @@ -11,9 +12,11 @@ * Return Value: * None * + * Example: + * [bob, 1, 2, 3] call ace_common_fnc_setPitchBankYaw + * * Public: Yes */ -#include "script_component.hpp" params ["_object", "_aroundX", "_aroundY", "_aroundZ"]; diff --git a/addons/common/functions/fnc_setPlayerOwner.sqf b/addons/common/functions/fnc_setPlayerOwner.sqf new file mode 100644 index 0000000000..c15974098b --- /dev/null +++ b/addons/common/functions/fnc_setPlayerOwner.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Sets the player's owner id as a variable on his player ojbect. + * Should be called on all machines (including server) + * Note: Needs to wait for CBA_clientID to be recieved from server. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_common_fnc_setPlayerOwner + * + * Public: No + */ + +if (missionNameSpace getVariable [QGVAR(setPlayerOwnerRunning), false]) exitWith {}; +GVAR(setPlayerOwnerRunning) = true; + +if (isServer) then { + addMissionEventHandler ["HandleDisconnect", { + params ["_dcPlayer"]; + TRACE_1("HandleDisconnect eh",_dcPlayer); + if (!isNil {_dcPlayer getVariable QGVAR(playerOwner)}) then { + _dcPlayer setVariable [QGVAR(playerOwner), nil, true]; + }; + }]; +}; + +if (hasInterface) then { + [{ + (!isNil "CBA_clientID") && {CBA_clientID > -1} + }, { + TRACE_1("CBA_clientID ready",CBA_clientID); + + ["unit", { + params ["_newUnit", "_oldUnit"]; + TRACE_2("unit changed",_newUnit,_oldUnit); + if ((_oldUnit getVariable [QGVAR(playerOwner), -1]) == CBA_clientID) then { + _oldUnit setVariable [QGVAR(playerOwner), nil, true]; + }; + if (alive _newUnit) then { + _newUnit setVariable [QGVAR(playerOwner), CBA_clientID, true]; + }; + }, true] call CBA_fnc_addPlayerEventHandler; + + }, []] call CBA_fnc_waitUntilAndExecute; +}; + diff --git a/addons/common/functions/fnc_setProne.sqf b/addons/common/functions/fnc_setProne.sqf index c40b0de254..f12545290c 100644 --- a/addons/common/functions/fnc_setProne.sqf +++ b/addons/common/functions/fnc_setProne.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Force a unit to go prone @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_setProne + * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/common/functions/fnc_setSetting.sqf b/addons/common/functions/fnc_setSetting.sqf index 5a56b385a7..a50cf89214 100644 --- a/addons/common/functions/fnc_setSetting.sqf +++ b/addons/common/functions/fnc_setSetting.sqf @@ -1,3 +1,5 @@ +#define DEBUG_MODE_FULL +#include "script_component.hpp" /* * Author: esteldunedain * Change the value of an existing setting if it was not previously forced. Force if neccesary. @@ -18,68 +20,17 @@ * * Public: No */ -#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 { - ACE_LOGERROR_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 { - ACE_LOGINFO_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 { - ACE_LOGWARNING_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 {ACE_LOGERROR_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 ac7a0f4875..0000000000 --- a/addons/common/functions/fnc_setSettingFromConfig.sqf +++ /dev/null @@ -1,114 +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 - * - * 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_setVariableJIP.sqf b/addons/common/functions/fnc_setVariableJIP.sqf index 35e8c0d116..857bd1b9b9 100644 --- a/addons/common/functions/fnc_setVariableJIP.sqf +++ b/addons/common/functions/fnc_setVariableJIP.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Sets a public object namespace variable that gets reset with the same value after respawn, so JIP clients keep the value. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [bob, "varname", 5] call ace_common_fnc_setVariableJIP + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_varName", "_value"]; diff --git a/addons/common/functions/fnc_setVariablePublic.sqf b/addons/common/functions/fnc_setVariablePublic.sqf index 5eeff87aee..067765fc27 100644 --- a/addons/common/functions/fnc_setVariablePublic.sqf +++ b/addons/common/functions/fnc_setVariablePublic.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 and CAA-Picard and joko and PabstMirror * Publish a variable, but wait a certain amount of time before allowing it to be published it again. @@ -9,15 +10,13 @@ * 3: Embargo delay (Optional. Default: 1) * * Return Value: - * Nothing. + * None * * Example: * [player, "balls", 2, 1] call ace_common_fnc_setVariablePublic; * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params ["_object", "_varName", "_value", ["_delay", 1]]; TRACE_4("params",_object,_varName,_value,_delay); @@ -48,6 +47,7 @@ TRACE_2("Starting Embargo", _varName, _delay); //If value at start of embargo doesn't equal current, then broadcast and start new embargo if (!(_value isEqualTo _curValue)) then { + _this set [2, _curValue]; _this call FUNC(setVariablePublic); }; }, _this, _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/common/functions/fnc_setVolume.sqf b/addons/common/functions/fnc_setVolume.sqf index 37e1f04cfa..0ab00e26be 100644 --- a/addons/common/functions/fnc_setVolume.sqf +++ b/addons/common/functions/fnc_setVolume.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Sets the volume of the game, including third party radio modifications such as TFAR and ACRE. @@ -8,11 +9,13 @@ * Return Value: * None * + * Example: + * [true] call ace_common_fnc_setVolume + * * Public: Yes * * Note: Uses player */ -#include "script_component.hpp" #define MUTED_LEVEL 0.2 #define NORMAL_LEVEL 1 diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index 98b9801b3f..86d9e3be8e 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -1,11 +1,12 @@ +#include "script_component.hpp" /* * 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) @@ -15,34 +16,36 @@ * - menu: Boolean - show commanding menu (hides HC related menus) * - group: Boolean - show group info bar (hides squad leader info bar) * - cursors: Boolean - show HUD weapon cursors (connected with scripted HUD) + * - panels: Boolean - show vehicle panels / GPS + * - ???: Boolean - Possibly related to changelog entry `Added: A new showKillConfirmations parameter for the showHud command` * * Return Value: * Resulting ShowHud Array * * Example: - * ["hideHud", [false, true, true, true, true, true, true, false]] call ace_common_fnc_showHud; //This is equivalent to the old showHud false + * ["hideHud", [false, true, true, true, true, true, true, false, true, true]] call ace_common_fnc_showHud; //This is equivalent to the old showHud false * [] call ace_common_fnc_showHud; //sets `showHud` and returns the result array used * * Public: Yes */ -#include "script_component.hpp" if (!hasInterface) exitWith {[-1]}; -params [["_reason", "", [""]], ["_mask", [], [[]], [0,8]]]; +params [["_reason", "", [""]], ["_mask", [], [[]]]]; if (isArray (missionConfigFile >> "showHUD")) then { //(showHud = 0;) is fine - the array is the problem - ACE_LOGWARNING("showHUD[] in Description.ext breaks the showHud command"); + WARNING("showHUD[] in Description.ext breaks the showHud command"); }; if (_reason != "") then { _reason = toLower _reason; if (_mask isEqualTo []) then { - TRACE_2("Setting", _reason, _mask); + TRACE_2("Removing", _reason, _mask); [GVAR(showHudHash), _reason] call CBA_fnc_hashRem; } else { - TRACE_2("Removing", _reason, _mask); + while {(count _mask) < 10} do { _mask pushBack true; }; + TRACE_2("Setting", _reason, _mask); [GVAR(showHudHash), _reason, _mask] call CBA_fnc_hashSet; }; }; @@ -50,7 +53,7 @@ if (_reason != "") then { GVAR(showHudHash) params ["", "_reasons", "_masks"]; private _resultMask = []; -for "_index" from 0 to 7 do { +for "_index" from 0 to 9 do { private _set = true; //Default to true { if (!(_x select _index)) exitWith { diff --git a/addons/common/functions/fnc_showUser.sqf b/addons/common/functions/fnc_showUser.sqf index 2e7af12a3f..a30c7cada3 100644 --- a/addons/common/functions/fnc_showUser.sqf +++ b/addons/common/functions/fnc_showUser.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * hint the Variable ACE_isUsedBy from the input Object every frame @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_common_fnc_showUser + * * Public: No */ -#include "script_component.hpp" if (!isNil QGVAR(showUserPFH)) then { [GVAR(showUserPFH)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/common/functions/fnc_statusEffect_addType.sqf b/addons/common/functions/fnc_statusEffect_addType.sqf index b5d6c1e879..6be61967d9 100644 --- a/addons/common/functions/fnc_statusEffect_addType.sqf +++ b/addons/common/functions/fnc_statusEffect_addType.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Adds a status effect that will be handled. @@ -8,21 +9,19 @@ * 2: Common Effect Reaons to pre-seed durring init * * Return Value: - * Nothing + * None * * Example: * ["setCaptive", true, []] call ace_common_fnc_statusEffect_addType * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params [["_name", "", [""]], ["_isGlobal", false, [false]], ["_commonReasonsArray", [], [[]]]]; TRACE_3("params",_name,_isGlobal,_commonReasonsArray); -if (_name == "") exitWith {ACE_LOGERROR_1("addStatusEffect - Bad Name %1", _this)}; -if (_name in GVAR(statusEffect_Names)) exitWith {ACE_LOGWARNING_1("addStatusEffect - Effect Already Added (note, will not update global bit) %1", _this)}; +if (_name == "") exitWith {ERROR_1("addStatusEffect - Bad Name %1", _this)}; +if (_name in GVAR(statusEffect_Names)) exitWith {WARNING_1("addStatusEffect - Effect Already Added (note, will not update global bit) %1", _this)}; GVAR(statusEffect_Names) pushBack _name; GVAR(statusEffect_isGlobal) pushBack _isGlobal; diff --git a/addons/common/functions/fnc_statusEffect_get.sqf b/addons/common/functions/fnc_statusEffect_get.sqf index 2d7e17e0ec..683c235214 100644 --- a/addons/common/functions/fnc_statusEffect_get.sqf +++ b/addons/common/functions/fnc_statusEffect_get.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Retrives list of current status effects @@ -16,8 +17,6 @@ * * Public: Yes */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params [["_object", objNull, [objNull]], ["_effectName", "", [""]]]; TRACE_2("params",_object,_effectName); diff --git a/addons/common/functions/fnc_statusEffect_localEH.sqf b/addons/common/functions/fnc_statusEffect_localEH.sqf index 5490029a3b..9f5cd7c42a 100644 --- a/addons/common/functions/fnc_statusEffect_localEH.sqf +++ b/addons/common/functions/fnc_statusEffect_localEH.sqf @@ -1,25 +1,25 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles locality switch, runs a respawn check and then reapplies all effect events. * * Arguments: * 0: vehicle that it will be attached to (player or vehicle) + * 1: isLocal * * Return Value: - * Nothing + * None * * Example: * [player, true] call ace_common_fnc_statusEffect_localEH * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params ["_object", "_isLocal"]; TRACE_2("params",_object,_isLocal); -//Only run this after the settings are initialized +//Only run this after the settings are initialized //Need to wait for all EH to be installed (local event will happen between pre and post init) if !(GVAR(settingsInitFinished)) exitWith { TRACE_1("pushing to runAtSettingsInitialized", _this); diff --git a/addons/common/functions/fnc_statusEffect_resetVariables.sqf b/addons/common/functions/fnc_statusEffect_resetVariables.sqf index 2a307c84e5..b819174753 100644 --- a/addons/common/functions/fnc_statusEffect_resetVariables.sqf +++ b/addons/common/functions/fnc_statusEffect_resetVariables.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Resets all effect numbers to 0 when an object respawns (but does not apply the effect event). @@ -6,15 +7,13 @@ * 0: vehicle that it will be attached to (player or vehicle) * * Return Value: - * Nothing + * None * * Example: * [player, true] call ace_common_fnc_statusEffect_resetVariables * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params [["_object", objNull, [objNull]], ["_setObjectRef", false, [false]]]; TRACE_2("params",_object,_setObjectRef); diff --git a/addons/common/functions/fnc_statusEffect_respawnEH.sqf b/addons/common/functions/fnc_statusEffect_respawnEH.sqf index 92717b68c7..56fe38b6a8 100644 --- a/addons/common/functions/fnc_statusEffect_respawnEH.sqf +++ b/addons/common/functions/fnc_statusEffect_respawnEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles the Respawn Event Handler to reset effects. @@ -6,20 +7,18 @@ * 0: vehicle that it will be attached to (player or vehicle) * * Return Value: - * Nothing + * None * * Example: * [player, objNull] call ace_common_fnc_statusEffect_respawnEH * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params ["_object"]; TRACE_1("params",_object); -//Only run this after the settings are initialized +//Only run this after the settings are initialized //Need to wait for all EH to be installed (local event will happen between pre and post init) if !(GVAR(settingsInitFinished)) exitWith { TRACE_1("pushing to runAtSettingsInitialized", _this); diff --git a/addons/common/functions/fnc_statusEffect_sendEffects.sqf b/addons/common/functions/fnc_statusEffect_sendEffects.sqf index f82ab10427..dae88d35e4 100644 --- a/addons/common/functions/fnc_statusEffect_sendEffects.sqf +++ b/addons/common/functions/fnc_statusEffect_sendEffects.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Sends all status effects for an object (can be run on non-local objects) @@ -7,15 +8,13 @@ * 1: Effect name (or "" to send all) * * Return Value: - * Nothing + * None * * Example: * [player, ""] call ace_common_fnc_statusEffect_sendEffects * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params [["_object", objNull, [objNull]], ["_effectName", "", [""]]]; TRACE_2("params",_object,_effectName); diff --git a/addons/common/functions/fnc_statusEffect_set.sqf b/addons/common/functions/fnc_statusEffect_set.sqf index a0be8d8719..ff8fa8565a 100644 --- a/addons/common/functions/fnc_statusEffect_set.sqf +++ b/addons/common/functions/fnc_statusEffect_set.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Adds or removes an id to a status effect and will send an event to apply. @@ -9,15 +10,13 @@ * 3: Is Set (true adds/false removes) * * Return Value: - * Nothing + * None * * Example: * [player, "setCaptive", "reason1", true] call ace_common_fnc_statusEffect_set * * Public: Yes */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params [["_object", objNull, [objNull]], ["_effectName", "", [""]], ["_ID", "", [""]], ["_set", true, [false]]]; TRACE_4("params",_object,_effectName,_ID,_set); @@ -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_stringCompare.sqf b/addons/common/functions/fnc_stringCompare.sqf index ad3073eb1e..9a0955b27a 100644 --- a/addons/common/functions/fnc_stringCompare.sqf +++ b/addons/common/functions/fnc_stringCompare.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bovine3dom * Determines whether one string matches another and how many characters match. Case insensitive. @@ -7,11 +8,13 @@ * 1: stringB * * Return Value: - * Number of matching characters >NUMBER> + * Number of matching characters + * + * Example: + * ["a", "b"] call ace_common_fnc_stringCompare * * Public: Yes */ -#include "script_component.hpp" params ["_string", "_searchTerm"]; diff --git a/addons/common/functions/fnc_stringRemoveWhiteSpace.sqf b/addons/common/functions/fnc_stringRemoveWhiteSpace.sqf deleted file mode 100644 index 47c9375d43..0000000000 --- a/addons/common/functions/fnc_stringRemoveWhiteSpace.sqf +++ /dev/null @@ -1,20 +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"]; - -(_string splitString " ") joinString "" diff --git a/addons/common/functions/fnc_stringToColoredText.sqf b/addons/common/functions/fnc_stringToColoredText.sqf index e6e19e4869..c7eaaaecb3 100644 --- a/addons/common/functions/fnc_stringToColoredText.sqf +++ b/addons/common/functions/fnc_stringToColoredText.sqf @@ -1,28 +1,33 @@ +#include "script_component.hpp" /* * Author: commy2 * Create a centered, colored text. * * Arguments: * 0: Text - * 1: Color + * 1: Color * * Return Value: * Text * + * Example: + * ["text", [0, 1, 2]] call ace_common_fnc_stringToColoredText + * * Public: Yes */ -#include "script_component.hpp" params ["_string", "_color"]; _string = format ["%1", _string]; -_color = ( - [255 * (_color select 0), 2] call FUNC(toHex) -) + ( - [255 * (_color select 1), 2] call FUNC(toHex) -) + ( - [255 * (_color select 2), 2] call FUNC(toHex) -); +if (_color isEqualType []) then { + _color = "#" + ( + [255 * (_color select 0), 2] call FUNC(toHex) + ) + ( + [255 * (_color select 1), 2] call FUNC(toHex) + ) + ( + [255 * (_color select 2), 2] call FUNC(toHex) + ); +}; -parseText format ["%1", _string, _color] +parseText format ["%2", _color, _string] diff --git a/addons/common/functions/fnc_switchPersistentLaser.sqf b/addons/common/functions/fnc_switchPersistentLaser.sqf new file mode 100644 index 0000000000..2e2fb7505b --- /dev/null +++ b/addons/common/functions/fnc_switchPersistentLaser.sqf @@ -0,0 +1,67 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Controls persistent laser state. + * + * Arguments: + * 0: Enabled + * + * Return Value: + * None + * + * Example: + * true call ace_common_fnc_switchPersistentLaser + * + * Public: No + */ + +params ["_enabled"]; + +if (!_enabled) exitWith { + if (isNil QGVAR(laserKeyDownEH)) exitWith {}; + ["KeyDown", GVAR(laserKeyDownEH)] call CBA_fnc_removeDisplayHandler; + ["loadout", GVAR(laserLoadoutEH)] call CBA_fnc_removePlayerEventHandler; + ["turret", GVAR(laserTurretEH)] call CBA_fnc_removePlayerEventHandler; + ["vehicle", GVAR(laserVehicleEH)] call CBA_fnc_removePlayerEventHandler; + ["weapon", GVAR(laserWeaponEH)] 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 == 1) 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(laserLoadoutEH) = ["loadout", _laserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserTurretEH) = ["turret", _laserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserVehicleEH) = ["vehicle", _laserEH] call CBA_fnc_addPlayerEventHandler; +GVAR(laserWeaponEH) = ["weapon", _laserEH] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/common/functions/fnc_switchToGroupSide.sqf b/addons/common/functions/fnc_switchToGroupSide.sqf index 3a559a7a65..842bdffabd 100644 --- a/addons/common/functions/fnc_switchToGroupSide.sqf +++ b/addons/common/functions/fnc_switchToGroupSide.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Stack group switches. Will always trace back to original group. @@ -11,11 +12,13 @@ * Return Value: * None * + * Example: + * [bob, true, "id", SIDE] call ace_common_fnc_switchToGroupSide + * * Public: Yes */ -#include "script_component.hpp" -params [["_unit", objNull], ["_switch", false], ["_id", ""], ["_side", side _unit]]; +params [["_unit", objNull], ["_switch", false], ["_id", ""], ["_side", sideUnknown]]; private _previousGroupsList = _unit getVariable [QGVAR(previousGroupSwitchTo), []]; diff --git a/addons/common/functions/fnc_syncedEvent.sqf b/addons/common/functions/fnc_syncedEvent.sqf index 7b7a0094cf..9ddb071dac 100644 --- a/addons/common/functions/fnc_syncedEvent.sqf +++ b/addons/common/functions/fnc_syncedEvent.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: jaynus * Call and propegate a synced event @@ -10,14 +11,16 @@ * Return Value: * Boolean of success * + * Example: + * ["bob", [args], 5] call ace_common_fnc_syncedEvent + * * Public: No */ -#include "script_component.hpp" params ["_name", "_args", ["_ttl", 0]]; if !([GVAR(syncedEvents), _name] call CBA_fnc_hashHasKey) exitWith { - ACE_LOGERROR_1("Synced event key [%1] not found (syncedEvent).", _name); + ERROR_1("Synced event key [%1] not found (syncedEvent).", _name); false }; diff --git a/addons/common/functions/fnc_syncedEventPFH.sqf b/addons/common/functions/fnc_syncedEventPFH.sqf index 8fcd143536..6d5d2ea12c 100644 --- a/addons/common/functions/fnc_syncedEventPFH.sqf +++ b/addons/common/functions/fnc_syncedEventPFH.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: ? + * Author: ACE-Team * * ? * @@ -7,11 +8,13 @@ * ? * * Return Value: - * ? + * None * - * Public: ? + * Example: + * [?] call ace_common_fnc_syncedEventPFH + * + * Public: No */ -#include "script_component.hpp" if (!isServer) exitWith {false}; diff --git a/addons/common/functions/fnc_targetEvent.sqf b/addons/common/functions/fnc_targetEvent.sqf deleted file mode 100644 index 8cce931547..0000000000 --- a/addons/common/functions/fnc_targetEvent.sqf +++ /dev/null @@ -1,13 +0,0 @@ -#include "script_component.hpp" - -params ["_eventName", "_eventTargets", "_eventArgs"]; - -private _newName = getText (configFile >> "ACE_newEvents" >> _eventName); -if (_newName != "") then { - TRACE_2("Switching Names",_eventName,_newName); - _eventName = _newName; -}; - -[_eventName,_eventArgs,_eventTargets] call CBA_fnc_targetEvent; - -ACE_DEPRECATED("ace_common_fnc_targetEvent","3.8.0","CBA_fnc_targetEvent"); diff --git a/addons/common/functions/fnc_throttledPublicVariable.sqf b/addons/common/functions/fnc_throttledPublicVariable.sqf index 3aaa3c8f47..abfcfc8c8c 100644 --- a/addons/common/functions/fnc_throttledPublicVariable.sqf +++ b/addons/common/functions/fnc_throttledPublicVariable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Schedules the publishment of an object variable to reduce network overhead @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_varName", "_maxDelay"]; @@ -27,7 +27,7 @@ if (isNil QGVAR(publishSchedId)) then { GVAR(publishSchedId) = [{ if (diag_tickTime > GVAR(publishNextTime)) then { { - _x params [_unit, _varName]; + _x params ["_unit", "_varName"]; _unit setVariable [_varName, _unit getVariable _varName, true]; false } count GVAR(publishVarNames); diff --git a/addons/common/functions/fnc_toBin.sqf b/addons/common/functions/fnc_toBin.sqf index f8ec0bac68..c5da7ece8e 100644 --- a/addons/common/functions/fnc_toBin.sqf +++ b/addons/common/functions/fnc_toBin.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Converts number to binary number @@ -8,9 +9,11 @@ * Return Value: * A binary number as string * + * Example: + * [5] call ace_common_fnc_toBin + * * Public: Yes */ -#include "script_component.hpp" params ["_number", ["_minLength", 1]]; diff --git a/addons/common/functions/fnc_toBitmask.sqf b/addons/common/functions/fnc_toBitmask.sqf index 333e5c737b..2d46811c6b 100644 --- a/addons/common/functions/fnc_toBitmask.sqf +++ b/addons/common/functions/fnc_toBitmask.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Convert an array of booleans into a number. @@ -8,9 +9,11 @@ * Return Value: * Bitmask * + * Example: + * [[true, false]] call ace_common_fnc_toBitmask + * * Public: Yes */ -#include "script_component.hpp" private _result = 0; diff --git a/addons/common/functions/fnc_toHex.sqf b/addons/common/functions/fnc_toHex.sqf index c558aab04b..f9c82be373 100644 --- a/addons/common/functions/fnc_toHex.sqf +++ b/addons/common/functions/fnc_toHex.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, esteldunedain * Converts number to hexadecimal number @@ -8,9 +9,11 @@ * Return Value: * A hexadecimal number as string * + * Example: + * [154] call ace_common_fnc_toHex + * * Public: Yes */ -#include "script_component.hpp" params ["_number"]; diff --git a/addons/common/functions/fnc_toNumber.sqf b/addons/common/functions/fnc_toNumber.sqf index c375dfb02e..14e8179a63 100644 --- a/addons/common/functions/fnc_toNumber.sqf +++ b/addons/common/functions/fnc_toNumber.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth de Wet (LH) * Takes a string/number and returns the number. @@ -6,14 +7,13 @@ * 0: Value to attempt to convert to number or if number simply return number. * * Return Value: - * + * Number * * Example: * number = ["102"] call ace_common_fnc_toNumber; * * Public: Yes */ -#include "script_component.hpp" params ["_value"]; diff --git a/addons/common/functions/fnc_translateToModelSpace.sqf b/addons/common/functions/fnc_translateToModelSpace.sqf index 309387086f..843c710c8d 100644 --- a/addons/common/functions/fnc_translateToModelSpace.sqf +++ b/addons/common/functions/fnc_translateToModelSpace.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* - * Author: ? + * Author: ACE-Team * ? * * Arguments: - * ? + * * * Return Value: - * ? + * Something * - * Public: ? + * Example: + * [UNKNOWN] call ace_common_fnc_translateToModelSpace + * + * Public: No */ -#include "script_component.hpp" params ["_object", "_matrix", "_offset"]; diff --git a/addons/common/functions/fnc_translateToWeaponSpace.sqf b/addons/common/functions/fnc_translateToWeaponSpace.sqf index fab3fe6a3c..4f4bbeae3b 100644 --- a/addons/common/functions/fnc_translateToWeaponSpace.sqf +++ b/addons/common/functions/fnc_translateToWeaponSpace.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* - * Author: ? + * Author: ACE-Team * ? * * Arguments: - * ? + * * * Return Value: - * ? + * Unknown * - * Public: ? + * Example: + * [UNKOWN] call ace_common_fnc_translateToWeaponSpace + * + * Public: No */ -#include "script_component.hpp" params ["_object", "_matrix", "_offset"]; diff --git a/addons/common/functions/fnc_unhideUnit.sqf b/addons/common/functions/fnc_unhideUnit.sqf index cb988cde1b..b6d669366e 100644 --- a/addons/common/functions/fnc_unhideUnit.sqf +++ b/addons/common/functions/fnc_unhideUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike (based on unmuteUnit) * Globally unhides a unit. Only unhides if the last reason was removed. @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_reason"]; diff --git a/addons/common/functions/fnc_uniqueElements.sqf b/addons/common/functions/fnc_uniqueElements.sqf index 471ba47457..5aad721d48 100644 --- a/addons/common/functions/fnc_uniqueElements.sqf +++ b/addons/common/functions/fnc_uniqueElements.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Make a copy of an array with only the unique elements. @@ -8,9 +9,11 @@ * Return Value: * Copy of original array * + * Example: + * [[array]] call ace_common_fnc_uniqueElements + * * Public: Yes */ -#include "script_component.hpp" params [["_array", [], [[]]]]; diff --git a/addons/common/functions/fnc_uniqueItems.sqf b/addons/common/functions/fnc_uniqueItems.sqf new file mode 100644 index 0000000000..48f91831b9 --- /dev/null +++ b/addons/common/functions/fnc_uniqueItems.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Returns list of unique items in a unit's inventory. + * Items are cached if unit is ACE_player. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Items + * + * Example: + * [_player] call ace_common_fnc_uniqueItems + * + * Public: No + */ + +params ["_unit"]; + +private _fnc_getItems = { + private _items = (getItemCargo uniformContainer _unit) select 0; + _items append ((getItemCargo vestContainer _unit) select 0); + _items append ((getItemCargo backpackContainer _unit) select 0); + + _items arrayIntersect _items +}; + +// Use cached items list if unit is ACE_player +if (_unit isEqualTo ACE_player) then { + private _items = GVAR(uniqueItemsCache); + if (isNil "_items") then { + _items = call _fnc_getItems; + GVAR(uniqueItemsCache) = _items; + }; + +_items +} else { + call _fnc_getItems; +}; diff --git a/addons/common/functions/fnc_unloadPerson.sqf b/addons/common/functions/fnc_unloadPerson.sqf index 716f46dc8e..b744cbc272 100644 --- a/addons/common/functions/fnc_unloadPerson.sqf +++ b/addons/common/functions/fnc_unloadPerson.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Unload a person from a vehicle @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define GROUP_SWITCH_ID QFUNC(loadPerson) diff --git a/addons/common/functions/fnc_unloadPersonLocal.sqf b/addons/common/functions/fnc_unloadPersonLocal.sqf index 2939edad18..74b8b8c39e 100644 --- a/addons/common/functions/fnc_unloadPersonLocal.sqf +++ b/addons/common/functions/fnc_unloadPersonLocal.sqf @@ -1,18 +1,21 @@ +#include "script_component.hpp" /* * Author: ViperMaul * 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 * * Public: No */ -#include "script_component.hpp" #define GROUP_SWITCH_ID QFUNC(loadPerson) @@ -24,7 +27,7 @@ private _emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,find TRACE_1("findUnloadPosition",_emptyPos); if (count _emptyPos != 3) exitwith { - ACE_LOGWARNING_4("Could not find unload pos %1-ASL: %2 isTouchingGround: %3 Speed: %4",_vehicle, getPosASL _vehicle, isTouchingGround _vehicle, speed _vehicle); + WARNING_4("Could not find unload pos %1-ASL: %2 isTouchingGround: %3 Speed: %4",_vehicle, getPosASL _vehicle, isTouchingGround _vehicle, speed _vehicle); if ((!isNull _unloader) && {[_unloader] call FUNC(isPlayer)}) then { //display text saying there are no safe places to exit the vehicle [QGVAR(displayTextStructured), [localize LSTRING(NoRoomToUnload)], [_unloader]] call CBA_fnc_targetEvent; diff --git a/addons/common/functions/fnc_unmuteUnit.sqf b/addons/common/functions/fnc_unmuteUnit.sqf index b6d673cfd5..03a7a33e23 100644 --- a/addons/common/functions/fnc_unmuteUnit.sqf +++ b/addons/common/functions/fnc_unmuteUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Unmutes the unit. Only unmutes if the last reason was removed. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, "because"] call ace_common_fnc_unmuteUnit + * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_reason"]; diff --git a/addons/common/functions/fnc_useItem.sqf b/addons/common/functions/fnc_useItem.sqf index 2d2116b38f..ba4e668792 100644 --- a/addons/common/functions/fnc_useItem.sqf +++ b/addons/common/functions/fnc_useItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Use item @@ -9,9 +10,11 @@ * Return Value: * if item has been used. * + * Example: + * [bob, "gun"] call ace_common_fnc_useItem + * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_item", ["_vehicleUsage", false]]; @@ -19,7 +22,7 @@ private _return = false; if !(_vehicleUsage) then { if (_item != "") then { - if (_item in items _unit) then { + if (_item in (_unit call EFUNC(common,uniqueItems))) then { _unit removeItem _item; _return = true; } else { diff --git a/addons/common/functions/fnc_useMagazine.sqf b/addons/common/functions/fnc_useMagazine.sqf index 4dc6136fa6..109f01f996 100644 --- a/addons/common/functions/fnc_useMagazine.sqf +++ b/addons/common/functions/fnc_useMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Use magazine @@ -9,9 +10,11 @@ * Return Value: * if magazine has been used. * + * Example: + * [bob, "magazine"] call ace_common_fnc_useMagazine + * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_magazine", ["_vehicleUsage", false]]; diff --git a/addons/common/functions/fnc_waitAndExecute.sqf b/addons/common/functions/fnc_waitAndExecute.sqf deleted file mode 100644 index 1ac0d3f54d..0000000000 --- a/addons/common/functions/fnc_waitAndExecute.sqf +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Author: esteldunedain - * Executes a code once with a given game time delay, using a PFH - * - * Arguments: - * 0: Code to execute - * 1: Parameters to run the code with - * 2: Delay in seconds before executing the code - * - * Return Value: - * None - * - * Example: - * [{(_this select 0) setVelocity [0,0,200];}, [player], 10] call ace_common_fnc_waitAndExecute - * - * Public: Yes - */ -#include "script_component.hpp" - -ACE_DEPRECATED("ace_common_fnc_waitAndExecute","3.8.0","CBA_fnc_waitAndExecute"); - -_this call CBA_fnc_waitAndExecute; diff --git a/addons/common/functions/fnc_waitUntilAndExecute.sqf b/addons/common/functions/fnc_waitUntilAndExecute.sqf deleted file mode 100644 index 52c596c70a..0000000000 --- a/addons/common/functions/fnc_waitUntilAndExecute.sqf +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Author: joko // Jonas - * Executes a code once with after the Condition is True, using a PFH - * - * Arguments: - * 0: Condition - * 1: Code to execute - * 2: Parameters to run the code with - * - * Return Value: - * None - * - * Example: - * [{(_this select 0) == vehicle (_this select 0)}, {(_this select 0) setDamage 1;}, [ACE_player]] call ace_common_fnc_waitUntilAndExecute - * - * Public: No - */ -#include "script_component.hpp" - -ACE_DEPRECATED("ace_common_fnc_waitUntilAndExecute","3.8.0","CBA_fnc_waitUntilAndExecute"); - -_this call CBA_fnc_waitUntilAndExecute; - -nil diff --git a/addons/common/functions/fnc_watchVariable.sqf b/addons/common/functions/fnc_watchVariable.sqf new file mode 100644 index 0000000000..6fa86dc9bc --- /dev/null +++ b/addons/common/functions/fnc_watchVariable.sqf @@ -0,0 +1,148 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Shows multiple watched variables on the main display (for easy debugging). + * + * Arguments: + * 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) + * For Anything else: + * 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 + * + * Public: Yes + */ + +#define TEXT_HEIGHT 16 + +params [["_name", "", [""]],["_code", {}, [{}]], ["_mods", [], [[]]]]; +TRACE_3("params",_name,_code,_mods); + +if (!hasInterface) exitWith {}; + +if (canSuspend) exitWith { // Ensure atomic - (fix `disableSerialization` error when called from init.sqf) + [FUNC(watchVariable), _this] call CBA_fnc_directCall; +}; + +if (isNull (findDisplay 46)) exitWith { + TRACE_1("waiting for main display to be ready",isNull (findDisplay 46)); + [{!isNull (findDisplay 46)}, {_this call FUNC(watchVariable);}, _this] call CBA_fnc_waitUntilAndExecute; +}; + +if (_code isEqualTo {}) then {TRACE_1("using title as code",_title); _code = compile _name;}; + +private _trackedDisplay = uiNamespace getVariable [QGVAR(watchVariableUI), displayNull]; +if (isNull _trackedDisplay) then { + TRACE_1("creating display and adding PFEH",time); + QGVAR(watchVariableUI) cutRsc [QGVAR(watchVariableUI), "PLAIN", 1, true]; + + [{ + private _trackedDisplay = uiNamespace getVariable [QGVAR(watchVariableUI), displayNull]; + private _varArray = _trackedDisplay getVariable [QGVAR(vars), []]; + TRACE_1("updating watched variables",count _varArray); + { + _x params ["_ctrlGroup", "_code", "_showDelta", "_lastNumber", "_barMin", "_barMax"]; + private _result = [] call _code; + if (isNil "_result") then { + (_ctrlGroup controlsGroupCtrl 1) ctrlSetStructuredText parseText format ["NIL"]; + } else { + if (_result isEqualType 0) then { + (_ctrlGroup controlsGroupCtrl 2) progressSetPosition linearConversion [_barMin, _barMax, _result, 0, 1, true]; + if (_showDelta) then { + private _delta = _result - _lastNumber; + _x set [3, _result]; + if (_delta < 0) then { + (_ctrlGroup controlsGroupCtrl 1) ctrlSetStructuredText parseText format ["%1 (%2)", _result, _delta]; + } else { + (_ctrlGroup controlsGroupCtrl 1) ctrlSetStructuredText parseText format ["%1 (%2)", _result, _delta]; + }; + } else { + (_ctrlGroup controlsGroupCtrl 1) ctrlSetStructuredText parseText format ["%1", _result]; + }; + } else { + (_ctrlGroup controlsGroupCtrl 1) ctrlSetStructuredText parseText format ["%1", _result]; + }; + }; + } forEach _varArray; + }, 1, []] call CBA_fnc_addPerFrameHandler; +}; + +// Add curent call: + +private _trackedDisplay = uiNamespace getVariable [QGVAR(watchVariableUI), displayNull]; +private _varArray = _trackedDisplay getVariable [QGVAR(vars), []]; +private _freePositionY = _trackedDisplay getVariable [QGVAR(freePosition), safeZoneY + 100 * pixelH]; + +private _height = 2 * TEXT_HEIGHT * pixelH; + +private _ctrlGroup = _trackedDisplay ctrlCreate ["ctrlControlsGroupNoScrollbars", -1]; + +private _ctrlBackground = (_trackedDisplay ctrlCreate ["ctrlStaticBackground", -1, _ctrlGroup]); +_ctrlBackground ctrlSetBackgroundColor [0.2, 0.2, 0.2, 0.5]; + +private _ctrlTitle = (_trackedDisplay ctrlCreate ["ctrlStatic", -1, _ctrlGroup]); +_ctrlTitle ctrlSetFontHeight (TEXT_HEIGHT * pixelH); +_ctrlTitle ctrlSetFont "EtelkaMonospacePro"; +_ctrlTitle ctrlSetPosition [0, 0, 300 * pixelW, TEXT_HEIGHT * pixelW]; +_ctrlTitle ctrlCommit 0; +_ctrlTitle ctrlSetText _name; + +if ((_mods param [0, true, [0, false]]) isEqualType false) then { + _mods params [["_showDelta", true, [false]], ["_barMin", 0, [0]], ["_barMax", 0, [0]]]; + TRACE_3("adding number",_barMin,_barMax,_showDelta); + + if (_barMin != _barMax) then { + TRACE_2("creating bar",_barMin,_barMax); + private _ctrlSlider = _trackedDisplay ctrlCreate ["RscProgress", 2, _ctrlGroup]; + _ctrlSlider ctrlSetPosition [0 * pixelW, TEXT_HEIGHT * pixelH, 300 * pixelW, TEXT_HEIGHT * pixelH]; + _ctrlSlider ctrlSetFade 0.25; + _ctrlSlider ctrlSetTextColor [0, 0, 0.2, 1]; + _ctrlSlider ctrlCommit 0; + }; + + private _ctrlResultText = _trackedDisplay ctrlCreate [QGVAR(debug_structuredText), 1, _ctrlGroup]; + _ctrlResultText ctrlSetPosition [25 * pixelW, TEXT_HEIGHT * pixelH, 275 * pixelW, TEXT_HEIGHT * pixelH]; + _ctrlResultText ctrlCommit 0; + + _varArray pushBack [_ctrlGroup, _code, _showDelta, 0, _barMin, _barMax]; + +} else { + _mods params [["_lines", 1, [1]]]; + _lines = _lines max 1; + TRACE_1("adding text",_lines); + + private _ctrlResultText = _trackedDisplay ctrlCreate [QGVAR(debug_structuredText), 1, _ctrlGroup]; + _ctrlResultText ctrlSetPosition [25 * pixelW, TEXT_HEIGHT * pixelH, 275 * pixelW, _lines * TEXT_HEIGHT * pixelH]; + _ctrlResultText ctrlCommit 0; + + _height = (1 + _lines) * TEXT_HEIGHT * pixelH; + + _varArray pushBack [_ctrlGroup, _code, false, -1, 0, 0]; +}; + +_trackedDisplay setVariable [QGVAR(vars), _varArray]; + +_ctrlGroup ctrlSetPosition [safeZoneX, _freePositionY, 300 * pixelW, _height]; +_ctrlGroup ctrlCommit 0; +_ctrlBackground ctrlSetPosition [0, 0, 300 * pixelW, _height]; +_ctrlBackground ctrlCommit 0; + + +_freePositionY = _freePositionY + _height + 5 * pixelH; +_trackedDisplay setVariable [QGVAR(freePosition), _freePositionY]; + +nil diff --git a/addons/common/functions/fnc_waveHeightAt.sqf b/addons/common/functions/fnc_waveHeightAt.sqf index c140b1ce94..969f4fc87e 100644 --- a/addons/common/functions/fnc_waveHeightAt.sqf +++ b/addons/common/functions/fnc_waveHeightAt.sqf @@ -1,17 +1,19 @@ +#include "script_component.hpp" /* * Author: jaynus * Gets the wave height at a specific location. Uses a logic, so may be performance iffy * * Arguments: - * 0: Position ASL to get height at + * 0: Position ASL to get height at * * Return Value: - * Wave height in meters + * Wave height in meters * + * Example: + * [[5, 2, 5]]] call ace_common_fnc_waveHeightAt * * Public: No */ -#include "script_component.hpp" params ["_position"]; diff --git a/addons/common/functions/fnc_worldToScreenBounds.sqf b/addons/common/functions/fnc_worldToScreenBounds.sqf index 65b0164ca0..74c19d0b4e 100644 --- a/addons/common/functions/fnc_worldToScreenBounds.sqf +++ b/addons/common/functions/fnc_worldToScreenBounds.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: zGuba 2011 * Function helper for framing objects on screen. @@ -19,9 +20,11 @@ * 2: Maximal X * 3: Maximal Y * + * Example: + * [bob, [5, 5, 5], [6, 6, 6]] call ace_common_fnc_worldToScreenBounds + * * Public: No */ -#include "script_component.hpp" params ["_object", "_margins", "_offsets"]; @@ -38,13 +41,13 @@ _bounds params ["_boundsMin", "_boundsMax"]; _boundsMin params ["_boundsMinX", "_boundsMinY", "_boundsMinZ"]; _boundsMax params ["_boundsMaxX", "_boundsMaxY", "_boundsMaxZ"]; -_boundsMinX = _boundsMinX - _marginsX + _offsetsX; -_boundsMinY = _boundsMinY - _marginsY + _offsetsY; -_boundsMinZ = _boundsMinZ - _marginsZ + _offsetsZ; +_boundsMinX = ((_boundsMinX - _marginsX) min 0) + _offsetsX; +_boundsMinY = ((_boundsMinY - _marginsY) min 0) + _offsetsY; +_boundsMinZ = ((_boundsMinZ - _marginsZ) min 0) + _offsetsZ; -_boundsMaxX = _boundsMaxX + _marginsX + _offsetsX; -_boundsMaxY = _boundsMaxY + _marginsY + _offsetsY; -_boundsMaxZ = _boundsMaxZ + _marginsZ + _offsetsZ; +_boundsMaxX = ((_boundsMaxX + _marginsX) max 0) + _offsetsX; +_boundsMaxY = ((_boundsMaxY + _marginsY) max 0) + _offsetsY; +_boundsMaxZ = ((_boundsMaxZ + _marginsZ) max 0) + _offsetsZ; private _boundsCorners = [ [_boundsMinX, _boundsMinY, _boundsMinZ], diff --git a/addons/common/functions/script_component.hpp b/addons/common/functions/script_component.hpp index bb0d2d5dff..6a1bf9154d 100644 --- a/addons/common/functions/script_component.hpp +++ b/addons/common/functions/script_component.hpp @@ -1,13 +1 @@ #include "\z\ace\addons\common\script_component.hpp" - -#define VALIDHASH(hash) (IS_ARRAY(hash) && {(count hash) >= 2} && {IS_ARRAY(hash select 0)} && {IS_ARRAY(hash select 1)}) -#define ERROR(msg) throw msg + format[" @ %1:%2", _callFrom, _lineNo] -#define HANDLECATCH diag_log text _exception; assert(exception=="") - -#define ERRORDATA(c) private ["_callFrom", "_lineNo"];\ - _callFrom = "";\ - _lineNo = -1;\ - if((count _this) > c) then {\ - _callFrom = _this select c;\ - _lineNo = _this select c+1;\ - }; 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/init_handleModifierKey.sqf b/addons/common/init_handleModifierKey.sqf index 7fe2be6476..364146c551 100644 --- a/addons/common/init_handleModifierKey.sqf +++ b/addons/common/init_handleModifierKey.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Initializes the modifier key handler. @@ -10,7 +11,6 @@ * * Public : No */ -#include "script_component.hpp" _this spawn {// waitUntil {!isNull findDisplay 46};// diff --git a/addons/common/init_handleScrollWheel.sqf b/addons/common/init_handleScrollWheel.sqf deleted file mode 100644 index 0acb84a5f2..0000000000 --- a/addons/common/init_handleScrollWheel.sqf +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Author: commy2 - * Initializes the MouseZChanged eventhandler. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Public : No - */ -#include "script_component.hpp" - -disableSerialization; - -params ["_display"]; - -_display displayAddEventHandler ["MouseZChanged", QUOTE(_this call FUNC(handleScrollWheel))]; diff --git a/addons/common/script_component.hpp b/addons/common/script_component.hpp index f5dec2fd55..9eb8af601f 100644 --- a/addons/common/script_component.hpp +++ b/addons/common/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_COMMON @@ -20,3 +19,18 @@ #define VERSION_CONFIG_COMMON VERSION_CONFIG;\ versionDesc = "ACE 3";\ versionAct = QUOTE(call COMPILE_FILE(init_versionTooltip)) + + +#define DIG_SURFACE_BLACKLIST [ \ + "concrete", "concrete_exp", "concrete_int", "int_concrete", "int_concrete_exp", \ + "pavement_exp", "int_pavement_exp", \ + "tiling", "tiles_int", "int_tiles", \ + "roof_tin", "roof_tiles", "rooftiles_exp", \ + "tarmac", "asphalt_exp", \ + "stones_exp", "rock", "stony", \ + "metal", "gridmetal_exp", "metalplate_exp", "int_metalplate_exp", "metal_int", "wavymetal", "wavymetal_exp", "int_metal", "steel_exp", \ + "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 6267ed08b2..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,20 +63,20 @@ 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; } } forEach _files; // display and log error messages - _fnc_cutComma = { - _string = _this; + private _fnc_cutComma = { + 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 1b988ca488..ce2e76344e 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -1,6 +1,15 @@ - + + + Common + Allgemein + Comune + 全般 + 通用 + 通用 + 일반 + ACE-Team ACE-Team @@ -12,6 +21,10 @@ ACE-Team ACE-Team ACE-Team + ACE-チーム + ACE-Team + ACE-製作團隊 + ACE-制作团队 Save @@ -24,6 +37,10 @@ Salvar Mentés Salva + 保存 + 저장 + 儲存 + 储存 Cancel @@ -36,6 +53,10 @@ Cancelar Mégse Annulla + 中止 + 취소 + 取消 + 取消 ACE Options @@ -48,6 +69,10 @@ Opções do ACE ACE Beállítások Opzioni ACE + ACE オプション + ACE 옵션 + ACE設定選項 + ACE设定选项 @@ -61,6 +86,10 @@ N É N + + + + NNE @@ -73,6 +102,10 @@ NNE ÉÉK NNE + 北北東 + 북북동 + 北北東 + 北北东 NE @@ -85,6 +118,10 @@ NE ÉK NE + 北東 + 북동 + 東北 + 东北 ENE @@ -97,6 +134,10 @@ LNE KÉK ENE + 東北東 + 동북동 + 東北東 + 东北东 E @@ -109,6 +150,10 @@ L K E + + + + ESE @@ -121,6 +166,10 @@ LSE KDK ESE + 東南東 + 동남동 + 東南東 + 东南东 SE @@ -133,6 +182,10 @@ SE DK SE + 南東 + 남동 + 東南 + 东南 SSE @@ -145,6 +198,10 @@ SSE DDK SSE + 南南東 + 남남동 + 南南東 + 南南东 S @@ -157,6 +214,10 @@ S D S + + + + SSW @@ -169,6 +230,10 @@ SSO DDNy SSO + 南南西 + 남남서 + 南南西 + 南南西 SW @@ -181,6 +246,10 @@ SO DNy SO + 南西 + 남서 + 西南 + 西南 WSW @@ -193,6 +262,10 @@ OSO NyDNy OSO + 西南西 + 서남서 + 西南西 + 西南西 W @@ -205,6 +278,10 @@ O Ny O + 西 + + 西 + 西 WNW @@ -217,6 +294,10 @@ ONO NyÉNy ONO + 北北西 + 서북서 + 西北西 + 西北西 NW @@ -229,6 +310,10 @@ NO ÉNy NO + 北西 + 북서 + 西北 + 西北 NNW @@ -241,6 +326,10 @@ NNO ÉÉNy NNO + 北北西 + 북북서 + 北北西 + 北北西 Action cancelled. @@ -253,6 +342,10 @@ Ação cancelada. Művelet megszakítva. Azione cancellata. + 動作を中止した。 + 행동 취소됨. + 動作已被取消 + 动作已被取消 [ACE] Miscellaneous Items @@ -265,6 +358,10 @@ [ACE] Itens diversos [ACE] Egyéb tárgyak [ACE] Oggetti vari + [ACE] その他アイテム + [ACE] 기타 물품. + [ACE] 雜項 + [ACE] 杂项 Disable Command Menu @@ -277,6 +374,10 @@ Parancsnoki menü kikapcsolása Disabilita menù di comando Desabilitar menu de comando + 指揮メニューを無効化 + 지휘 메뉴 종료 + 關閉命令選單 + 关闭命令选单 Unknown @@ -289,6 +390,10 @@ Sconosciuto Inconnu Desconhecido + 不明 + 알 수 없음 + 未知的 + 未知的 No Voice @@ -301,6 +406,10 @@ Senza voce Pas de voix Sem voz + 音声なし + 무음 + 沒聲音 + 没声音 Accept Requests @@ -313,6 +422,10 @@ Kérések elfogadása Aceitar Pedido Accetta la richiesta + 要求を受け入れ + 요청 수락 + 接受請求 + 接受请求 Decline Requests @@ -325,6 +438,10 @@ Kérések elutasítása Rejeitar pedido Rifiuta la richiesta + 要求を拒否 + 요청 거부 + 拒絕請求 + 拒绝请求 Accept Requests send by other players. These can be requests to use / share equipment, perform certain actions. @@ -337,6 +454,10 @@ Accepter les requêtes d'autres joueurs. Comme l'utilisation / l'échange d'équipement, la réalisation d'actions. Más játékosok általi kérések elfogadása. Ezek a kérések vonatkozhatnak a felszerelés használatára/megosztására, valamint különböző cselekményekre. 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. @@ -349,6 +470,34 @@ Rejeter les requêtes d'autres joueurs. Comme l'utilisation / l'échange d'équipement, la réalisation d'actions. Más játékosok általi kérések elutasítása. Ezek a kérések vonatkozhatnak a felszerelés használatára/megosztására, valamint különböző cselekményekre. 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 @@ -361,6 +510,10 @@ Pomocné ikony Visszajelző ikonok Ícones de Feedback + フィードバック アイコン + 피드백 아이콘 + 回饋圖標 + 回馈图标 Select the position of or disable the feedback icons on your screen. These icons will show to provide extra feedback on your character status and actions performed. @@ -373,6 +526,10 @@ Nastavuje pozici nebo vypíná pomocné ikony. Tyto ikony ukazují extra informace ke stavu postavy a vykonávaných činností. Itt beállítható a visszajelző ikonok képernyőn lévő helyzete és jelenléte. Ezek az ikonok extra visszajelzést biztosítanak a karaktered állapotán és végrehajtott cselekvésein. 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 @@ -385,6 +542,10 @@ Pozice ukazetele průběhu činnosti Állapotjelző sáv helyzete Local da barra de progresso + プログレス バーの位置 + 진행 막대의 위치 + 進度欄位置 + 进度栏位置 Set the desired location of the progress bar on your screen. @@ -397,6 +558,10 @@ Nastavuje pozici ukazetele průběhu činnosti na vaší obrazovce. Itt beállítható az állapotjelző sáv képernyődön lévő helyzete. Define o local desejado da barra de progresso na sua tela. + 画面上に表示されるプログレス バーの位置を設定できます。 + 진행 막대를 원하는 곳에 배치합니다. + 設定進度欄在畫面中的位置 + 设定进度栏在画面中的位置 Hint Background color @@ -409,6 +574,10 @@ Barva pozadí nápovědy Súgó háttérszíne Cor do fundo da hint + ヒントの背景色 + 힌트 배경색 + 提示的背景顏色 + 提示的背景颜色 The color of the background from the ACE hints. @@ -421,6 +590,10 @@ Barva pozadí ACE nápovědy. Az ACE-súgók hátterének színe. A cor de fundo das hints do ACE. + ACE によるヒントの背景色を指定します。 + ACE힌트의 배경색을 정합니다. + 設定ACE提示的背景顏色. + 设定ACE提示的背景颜色. Hint text font color @@ -433,10 +606,14 @@ Barva fontu nápovědy. Súgószöveg betűinek színe Cor do do texto da hint + ヒント文章の色 + 힌트 글씨색 + 提示文字的顏色 + 提示文字的颜色 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. Цвет шрифта текста всплывающих подсказок АСЕ. Этот цвет является стандартным для всего текста, транслирующегося через систему подсказок АСЕ, если не установлено другого цвета для текста подсказок. @@ -445,6 +622,30 @@ Barva fontu ACE nápověd. Toto je standardní barva pro všechen text zobrazovaný ACE nápovědami, pokud nemá nápověda žádnou specifikanou barvu. Az ACE-súgók betűkészletének színek. Ez a szín alapértelmezett az összes szövegre az ACE-súgórendszerben, ha a súgószöveg maga nem ad meg más színt. 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系统的预设颜色。 + + + 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 @@ -457,6 +658,10 @@ Banane Banán Banana + 甘蕉 + 바나나 + 香蕉 + 香蕉 A banana is an edible fruit, botanically a berry, produced by several kinds of large herbaceous flowering plants in the genus Musa. @@ -469,6 +674,10 @@ Rodzaj roślin z rodziny bananowatych, obejmujący około 80 gatunków.<br />Przedstawiciele są typowymi przedstawicielami flory międzyzwrotnikowej Azji, Afryki i Australii.<br />Część gatunków dostarcza jadalnych owoców. Słowo banan pochodzi prawdopodobnie od arabskiego słowa banan, co oznacza palec, lub afrykańskiego języka wolof, w którym rośliny te określa się mianem banaana. Une banane est un fruit qui, d'un point de vue botanique, fait partie du groupe des baies. Produite par plusieurs sortes de grandes plantes à fleurs herbacées du type Musa. 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),为芭蕉科芭蕉属小果野蕉及野蕉的人工栽培杂交种,为多年生草本植物。果实长有棱; 果皮黄色,果肉白色,味道香甜。主要生长在热带、亚热带地区。原产于亚洲东南部热带、亚热带地区。 Check PBOs @@ -481,6 +690,10 @@ PBO-k ellenőrzése Проверка аддонов Controlla PBO + PBO を検査 + PBO 검사 + 檢查PBO檔 + 检查PBO档 Check addon integrity with server and do selected action if an addon is missing. @@ -492,6 +705,10 @@ Выполняет проверку версий аддонов ACE у подключаемых игроков Ce module contrôle si les PBOs de chaque joueur sont corrects Controlla l'integrità degli addon con il server ed esegui l'azione selezionata se un addon è mancante + サーバがアドオンの整合性を検査し、もし不備があれば実行する動作を選択できます。 + 서버 에드온의 무결성을 검사하고 사라진 에드온이 있을경우 행동을 선택합니다. + 檢查客戶端與伺服器端的模組清單是否一致且完整,並提供訊息表示遺失的模組 + 检查客户端与伺服器端的模组清单是否一致且完整,并提供讯息表示遗失的模组。 Action @@ -504,6 +721,10 @@ Cselekvés Действие Azione + 動作 + 작동 + 動作 + 动作 What to do with people who do not have the right PBOs? @@ -516,6 +737,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档时,将采取何种动作? Warn once @@ -528,6 +753,10 @@ Egyszeri figyelmeztetés Предупредить один раз Avverti una volta + 一度の警告 + 경고 한 번 + 警告 (一次) + 警告 (一次) Warn (permanent) @@ -540,6 +769,10 @@ Figyelmeztetés (tartós) Предупреждать (постоянно) Avverti (permanente) + 警告 (永久的) + 경고 (영구적) + 警告 (持續) + 警告 (持续) Kick @@ -552,6 +785,10 @@ Kirúgás Кикнуть Kick + 排除 + 추방 + 踢除 + 踢除 Check all addons @@ -564,6 +801,10 @@ Összes bővítmény ellenőrzése Проверять все аддоны Controlla tutti gli addon + 全アドオンを検査 + 모든 에드온 검사 + 檢查所有模組 + 检查所有模组 Check all addons instead of only those of ACE? @@ -576,6 +817,10 @@ 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를 제외한 모든 모드를 검사할까요? + 檢查包含ACE之外的其他模組? + 检查包含ACE之外的其他模组? Whitelist @@ -588,6 +833,10 @@ Fehérlista Вайтлист доп. аддонов Lista Bianca + 許可制 + 화이트리스트 + 白名單 + 白名单 What addons are allowed regardless? @@ -600,6 +849,10 @@ Milyen bővítmények vannak feltétlenül engedélyezve? Какие аддоны дополнительно разрешены? Quali addon sono permessi in ogni caso? + どのようなアドオンを許可しますか? + 허가되는 에드온은 어느것입니까? + 哪些模組是可被允許/忽略的? + 哪些模组是可被允许/忽略的? LSD Vehicles @@ -612,6 +865,10 @@ LSD járművek Транспорт под LSD Veicoli LSD + LSD 車両 + LSD 차량 + 迷幻載具 + 迷幻载具 Adds LSD effect to synchronized vehicle @@ -624,6 +881,10 @@ LSD-effekt hozzáadása a szinkronizált járművekhez Добавляет эффект LSD (мигание всеми цветами радуги) синхронизированным транспортным средствам Aggiunge effetti LSD ai veicoli sincronizzati + 同期されたオブジェクトに LSD の効果を追加します + 동기화된 차량에 LSD효과를 추가합니다. + 使被同步的載具產生瘋狂的迷幻效果。(後果自負) + 使被同步的载具产生疯狂的迷幻效果。(后果自负) Toggle Handheld Device @@ -636,6 +897,10 @@ Kézi eszköz kapcsolása Включить портативное устройство Apri dispositivo palmare + デバイスを常に表示 + 휴대장치 토글 + 切換手持裝備 + 切换手持装备 Close Handheld Device @@ -648,6 +913,10 @@ Kézi eszköz bezárása Закрыть портативное устройство Chiudi dispositivo palmare + デバイスを閉じる + 휴대장치 닫기 + 關閉手持裝備 + 关闭手持装备 Cycle Handheld Devices @@ -660,6 +929,10 @@ Kézi eszköz váltása Следующее портативное устройство Cicla tra dispositivi palmari + 表示するデバイスを変える + 휴대장치 순환 + 循環切換手持裝備 + 循环切换手持装备 Disabled @@ -671,6 +944,10 @@ Desativado Откл. Desactivado + 無効化 + 비활성화 + 停用 + 停用 Enabled @@ -682,6 +959,10 @@ Ativado Вкл. Activado + 有効化 + 활성화 + 啟用 + 启用 Yes @@ -694,6 +975,10 @@ Igen Sim Si + はい + + + No @@ -706,6 +991,10 @@ Nem Não No + いいえ + 아니오 + + Vehicles only @@ -717,6 +1006,10 @@ Solo vehículos Solo veicoli Vehicules seulement + 車両のみ + 차량 전용 + 只有載具 + 只有载具 Do Not Force @@ -728,72 +1021,100 @@ Не обязывать Non forzare Ne pas forcer + 強制しない + 강제하지 말것 + 不要強行 + 不要强行 - ACE3 Equipment - ACE-Ausrüstung - ACE3 Wyposażenie - Equipamentos ACE3 - ACE3 Снаряжение - ACE3 Vybavení - ACE3 Equipo - Equipaggiamento ACE3 - ACE3 Equipement + 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 + 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 + 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 + 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 + 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 + 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 @@ -805,6 +1126,74 @@ Nedostatek místa k vyložení Sem espaço para descarregar Нет места для выгрузки + 降ろすための空間がありません + 沒有空間可卸載 + 没有空间可卸载 + 언로드 할 공간이 없습니다. + + + Toggle + переключить + переключить + Basculer + Cambiar + Cambia + Umschalten + pecek + přep. + alternar + 切り替え + 토글 + 切換 + 切换 + + + Weight: + Gewicht: + Peso: + Poids : + Waga: + Váha: + Peso: + Peso: + Súly: + Вес: + 重量: + 무게: + 重量: + 重量: + + + Allow turning down music + Erlaube Musik leiser stellen + 음악 끄기 허용 + 允許調低音樂音量 + 允许调低音乐音量 + 音楽の音量低下を許可 + Permesso di abbassare la musica + + + Allow ACE scripts to turn down the music. + Erlaube ACE-Skripten, die Musik leiser zu stellen. + ACE 스크립트가 음악을 끌 수 있습니다. + 允許ACE腳本去控制音樂的音量 + 允许ACE脚本去控制音乐的音量。 + ACE スプリントへ音量低下を許可します。 + Permetti agli script di ACEdi abbassare la musica. + + + Flag (ACE - Black) + 旗帜(ACE-黑色): + 旗幟(ACE-黑色) + Bandiera (ACE - Nera) + 旗 (ACE - 黒) + + + Flag (ACE - White) + 旗帜(ACE-白色): + 旗幟(ACE-白色) + Bandiera (ACE - Bianca) + 旗 (ACE - 白) - \ No newline at end of file + 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/CfgVehicles.hpp b/addons/concertina_wire/CfgVehicles.hpp index d7f5d0d82a..0bc5a31e59 100644 --- a/addons/concertina_wire/CfgVehicles.hpp +++ b/addons/concertina_wire/CfgVehicles.hpp @@ -90,7 +90,6 @@ class CfgVehicles { statement = QUOTE([ARR_2(_target,_player)] call FUNC(dismount)); showDisabled = 0; exceptions[] = {}; - priority = 5; icon = QPATHTOF(UI\icon_sandbag_ca.paa); }; }; @@ -137,7 +136,6 @@ class CfgVehicles { statement = QUOTE([ARR_2({_this call FUNC(deploy)}, [ARR_2(_target,_player)])] call CBA_fnc_execNextFrame); showDisabled = 0; exceptions[] = {}; - priority = 5; icon = QPATHTOF(UI\icon_sandbag_ca.paa); }; }; 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 dc6424f172..0000000000 --- a/addons/concertina_wire/XEH_init.sqf +++ /dev/null @@ -1,3 +0,0 @@ -#include "script_component.hpp" -params ["_wire"]; -_wire addEventHandler ["HandleDamage", FUNC(handleDamage)]; diff --git a/addons/concertina_wire/XEH_preInit.sqf b/addons/concertina_wire/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/concertina_wire/XEH_preInit.sqf +++ b/addons/concertina_wire/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/concertina_wire/config.cpp b/addons/concertina_wire/config.cpp index 326c1cd0ea..438822a93b 100644 --- a/addons/concertina_wire/config.cpp +++ b/addons/concertina_wire/config.cpp @@ -16,7 +16,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; -}; diff --git a/addons/concertina_wire/functions/fnc_deploy.sqf b/addons/concertina_wire/functions/fnc_deploy.sqf index 67b3584de2..6ff782fb8e 100644 --- a/addons/concertina_wire/functions/fnc_deploy.sqf +++ b/addons/concertina_wire/functions/fnc_deploy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * @@ -10,11 +11,13 @@ * Return Value: * None * + * Example: + * [coil, bob] call ace_concertina_wire_fnc_deploy + * * Public: No */ -#include "script_component.hpp" -PARAMS_2(_wirecoil,_unit); +params ["_wirecoil", "_unit"]; private _wireNoGeo = "ACE_ConcertinaWireNoGeo" createVehicle [0,0,0]; { @@ -62,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; @@ -75,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_dismount.sqf b/addons/concertina_wire/functions/fnc_dismount.sqf index 9dcd50cc4a..487c5685a4 100644 --- a/addons/concertina_wire/functions/fnc_dismount.sqf +++ b/addons/concertina_wire/functions/fnc_dismount.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [wire, bob] call ace_concertina_wire_fnc_dismount + * * Public: No */ -#include "script_component.hpp" // If the cursorMenu is open, the loading bar will fail. If we execute the function one frame later, it will work fine if (uiNamespace getVariable [QEGVAR(interact_menu,cursorMenuOpened),false]) exitWith { @@ -23,7 +26,7 @@ if (uiNamespace getVariable [QEGVAR(interact_menu,cursorMenuOpened),false]) exit params ["_wire", "_unit"]; private _config = (configFile >> "CfgVehicles" >> typeOf _unit); -private _delay = [120, 60] select (getNumber (_config >> "engineer") == 1 || {getNumber (_config >> "canDeactivateMines") == 1}); +private _delay = [45, 30] select ([_unit] call EFUNC(common,isEngineer) || {[_unit] call EFUNC(common,isEOD)}); // TODO: Animation? [ diff --git a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf index a3f5081271..4611aea0f3 100644 --- a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf +++ b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * @@ -9,11 +10,13 @@ * Return Value: * None * + * Example: + * [wire] call ace_concertina_wire_fnc_dismountSuccess + * * Public: No */ -#include "script_component.hpp" -PARAMS_1(_wire); +params ["_wire"]; { _wire animate [_x, 1]; @@ -24,12 +27,11 @@ PARAMS_1(_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_handleDamage.sqf b/addons/concertina_wire/functions/fnc_handleDamage.sqf index 43a04641dd..958354250b 100644 --- a/addons/concertina_wire/functions/fnc_handleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_handleDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * @@ -13,9 +14,11 @@ * Return Value: * None * + * Example: + * [wire, "selection", 5, source, "scrap"] call ace_concertina_wire_fnc_handleDamage + * * Public: No */ -#include "script_component.hpp" params ["_wire", "", "_damage", "_source", ""]; if (_damage < 0.5) exitWith { 0 }; diff --git a/addons/concertina_wire/functions/fnc_handleInit.sqf b/addons/concertina_wire/functions/fnc_handleInit.sqf new file mode 100644 index 0000000000..a602281af1 --- /dev/null +++ b/addons/concertina_wire/functions/fnc_handleInit.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" +/* + * Author: Rocko + * Handles wire Init + * + * Arguments: + * 0: wire + * + * Return Value: + * None + * + * Example: + * [wire] call ace_concertina_wire_fnc_handleInit + * + * Public: No + */ +params ["_wire"]; +_wire addEventHandler ["HandleDamage", {call FUNC(handleDamage)}]; diff --git a/addons/concertina_wire/functions/fnc_handleKilled.sqf b/addons/concertina_wire/functions/fnc_handleKilled.sqf index 7fb5ef6e1b..33f00ebe13 100644 --- a/addons/concertina_wire/functions/fnc_handleKilled.sqf +++ b/addons/concertina_wire/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko * @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [wire, car] call ace_concertina_wire_fnc_handleKilled + * * Public: No */ -#include "script_component.hpp" params ["_wire", "_killer"]; TRACE_2("params",_wire,_killer); diff --git a/addons/concertina_wire/functions/fnc_vehicleDamage.sqf b/addons/concertina_wire/functions/fnc_vehicleDamage.sqf index e5732f7000..6482ea718a 100644 --- a/addons/concertina_wire/functions/fnc_vehicleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_vehicleDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko * Handles vehicle damage from hitting wire @@ -9,15 +10,15 @@ * Return Value: * None * + * Example: + * [wire, car] call ace_concertina_wire_fnc_vehicleDamage + * * Public: No */ -#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 }; @@ -35,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)], @@ -52,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"; @@ -73,6 +74,8 @@ if (_mode == 0) then { }; }; +private _parts = []; + if (_mode == 1) then { switch (true) do { case (_vehicle isKindOf "Tank"): { @@ -92,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]; }; @@ -104,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/concertina_wire/script_component.hpp b/addons/concertina_wire/script_component.hpp index 38af41b899..81da52dd2a 100644 --- a/addons/concertina_wire/script_component.hpp +++ b/addons/concertina_wire/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_CONCERTINA_WIRE diff --git a/addons/concertina_wire/stringtable.xml b/addons/concertina_wire/stringtable.xml index 616879f31e..d4e4f78c96 100644 --- a/addons/concertina_wire/stringtable.xml +++ b/addons/concertina_wire/stringtable.xml @@ -9,9 +9,13 @@ Alambre de espino Fill barbelé Ostnatý drát - Filo spinato di concertina + Filo a concertina Concertina wire Arame farpado + 鉄条網 + 철조망 + 鐵絲網 + 铁丝网 Concertina Wire Coil @@ -21,9 +25,13 @@ Bobina de alambre de espino Bobine de fil barbelé Svitek ostnatého drátu - Bobina di concertina + Bobina di filo a concertina Concertina wire coil Bobina de arame farpado + 鉄条網コイル + 윤형 철조망 + 鐵絲網捲 + 铁丝网卷 Dismount Concertina Wire @@ -33,9 +41,13 @@ Desmontar alambre de espino Démonter le fil barbelé Svinout ostnatý drát - Smonta la concertina + Smonta il filo a concertina Dismount Concertina wire Desmontar arame farpado + 鉄条網をほどく + 철조망 해체 + 卸下鐵絲網 + 卸下铁丝网 Deploy Concertina Wire @@ -45,9 +57,13 @@ Desplegar alambre de espino Mettre en place le fil barbelé Rozvinout ostnatý drát - Posa il filo di concertina + Piazza il filo a concertina Deploy Concertina wire Colocar arame farpado + 鉄条網を置く + 철조망 배치 + 佈署鐵絲網 + 布署铁丝网 - \ No newline at end of file + diff --git a/addons/cookoff/ACE_Settings.hpp b/addons/cookoff/ACE_Settings.hpp index df96613ee0..304aaf48e0 100644 --- a/addons/cookoff/ACE_Settings.hpp +++ b/addons/cookoff/ACE_Settings.hpp @@ -1,9 +1,40 @@ class ACE_Settings { class GVAR(enable) { + category = CSTRING(displayName); displayName = CSTRING(enable_name); description = CSTRING(enable_tooltip); + value = 0; + 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/CfgAmmo.hpp b/addons/cookoff/CfgAmmo.hpp new file mode 100644 index 0000000000..952ec22322 --- /dev/null +++ b/addons/cookoff/CfgAmmo.hpp @@ -0,0 +1,33 @@ +class CfgAmmo { + class ShellBase; + class ace_ammoExplosion: ShellBase { + hit = 10; + indirectHit = 0.5; + indirectHitRange = 1; + soundHit[] = {"", 1, 1, 0}; + typicalSpeed = 100; + explosive = 0; + cost = 300; + model = "\A3\Weapons_F\empty.p3d"; + airFriction = 0; + timeToLive = 1; + explosionTime = 0.001; + soundFly[] = {"",1,1}; + soundEngine[] = {"",1,4}; + explosionEffects = "ExploAmmoExplosion"; + }; + + class SmallSecondary; + class ACE_ammoExplosionLarge: SmallSecondary { + soundHit[] = {"", 1, 1, 0}; + model = "\A3\Weapons_F\empty.p3d"; + soundFly[] = {"",1,1}; + soundEngine[] = {"",1,4}; + soundHit1[] = {"",1,1,1}; + soundHit2[] = {"",1,1,1}; + soundHit3[] = {"",1,1,1}; + supersonicCrackFar[] = {"",1,1,1}; + supersonicCrackNear[] = {"",1,1,1}; + craterEffects = "ImpactEffectsMedium"; + }; +}; diff --git a/addons/cookoff/CfgCloudlets.hpp b/addons/cookoff/CfgCloudlets.hpp index 9b262c75c1..c167177705 100644 --- a/addons/cookoff/CfgCloudlets.hpp +++ b/addons/cookoff/CfgCloudlets.hpp @@ -52,3 +52,30 @@ class CfgCloudlets { destroyOnWaterSurfaceOffset = 0; }; }; + +class GVAR(ExploAmmoExplosion) { + class ExploAmmoFlash { + position[] = {0,0,0}; + simulation = "particles"; + type = "ExploAmmoFlash"; + intensity = 1; + interval = 1; + lifeTime = 1; + }; + class LightExplosion { + simulation = "light"; + type = "SparksLight"; + position[] = {0,0,0}; + intensity = 1; + interval = 1; + lifeTime = 0.15; + }; + class ExploAmmoSmoke { + position[] = {0,0,0}; + simulation = "particles"; + type = "AutoCannonFired"; + intensity = 1.5; + interval = 1.5; + lifeTime = 1.5; + }; +}; diff --git a/addons/cookoff/CfgEden.hpp b/addons/cookoff/CfgEden.hpp new file mode 100644 index 0000000000..04e7762a41 --- /dev/null +++ b/addons/cookoff/CfgEden.hpp @@ -0,0 +1,31 @@ + +class Cfg3DEN { + class Object { + class AttributeCategories { + class ace_attributes { + class Attributes { + class GVAR(enable) { + property = QGVAR(enable); + control = "Checkbox"; + displayName = CSTRING(enable_name); + 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 = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };); + }; + }; + }; + }; + }; +}; diff --git a/addons/cookoff/CfgSFX.hpp b/addons/cookoff/CfgSFX.hpp index 0e10644729..0d670ead86 100644 --- a/addons/cookoff/CfgSFX.hpp +++ b/addons/cookoff/CfgSFX.hpp @@ -1,9 +1,18 @@ class CfgSFX { - class GVAR(CookOff) { - name = QGVAR(cookoff); - sounds[] = {QGVAR(cookoff)}; - GVAR(cookoff)[] = {PATHTOF(sounds\cookoff.wss),6,1.8,400,1,0,0,0}; + class GVAR(CookOff_low) { + name = QGVAR(cookoff_low); + sound[] = {QPATHTOF(sounds\cookoff_low_pressure.ogg),6,1,400,1,0,0,0}; + sounds[] = {"sound"}; + titles[] = {}; empty[] = {"",0,0,0,0,0,0,0}; }; + class GVAR(CookOff_mid): GVAR(CookOff_low) { + name = QGVAR(cookoff_mid); + sound[] = {QPATHTOF(sounds\cookoff_mid_pressure.ogg),6,1,400,1,0,0,0}; + }; + class GVAR(CookOff_high): GVAR(CookOff_low) { + name = QGVAR(cookoff_high); + sound[] = {QPATHTOF(sounds\cookoff_high_pressure.ogg),6,1,400,1,0,0,0}; + }; }; diff --git a/addons/cookoff/CfgVehicles.hpp b/addons/cookoff/CfgVehicles.hpp index 845eb55d94..7a682ca9d0 100644 --- a/addons/cookoff/CfgVehicles.hpp +++ b/addons/cookoff/CfgVehicles.hpp @@ -1,49 +1,65 @@ class CfgVehicles { class Sound; - class GVAR(Sound): Sound { + class GVAR(Sound_low): Sound { author = ECSTRING(common,ACETeam); _generalMacro = QGVAR(Sound); scope = 1; - sound = QGVAR(CookOff); + sound = QGVAR(CookOff_low); + }; + + class GVAR(Sound_mid): GVAR(Sound_low) { + sound = QGVAR(CookOff_mid); + }; + class GVAR(Sound_high): GVAR(Sound_low) { + sound = QGVAR(CookOff_high); }; class ThingX; class GVAR(Turret_MBT_01): ThingX { author = ECSTRING(common,ACETeam); - _generalMacro = QGVAR(TurretDummy); + _generalMacro = QGVAR(Turret_MBT_01); scope = 1; + displayName = CSTRING(generic_turret_wreck); model = "\A3\Structures_F\Wrecks\Wreck_Slammer_turret_F.p3d"; + icon = "\A3\armor_f_gamma\MBT_01\Data\ui\map_slammer_mk4_ca.paa"; }; class GVAR(Turret_MBT_02): ThingX { author = ECSTRING(common,ACETeam); - _generalMacro = QGVAR(TurretDummy); + _generalMacro = QGVAR(Turret_MBT_02); scope = 1; + displayName = CSTRING(generic_turret_wreck); model = "\A3\Structures_F\Wrecks\Wreck_T72_turret_F.p3d"; + icon = "\A3\armor_f_gamma\MBT_02\Data\UI\map_MBT_02_ca.paa"; }; class Tank; class Tank_F: Tank { - GVAR(ammoLocation) = "HitTurret"; + GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; + GVAR(probability) = 0.5; }; - - class MBT_01_base_F: Tank_F { - GVAR(ammoLocation) = "HitHull"; - }; - class APC_Tracked_01_base_F: Tank_F { - GVAR(ammoLocation) = "HitHull"; + class MBT_02_base_F: Tank_F { + GVAR(ammoLocation) = "HitTurret"; }; class Car_F; class Wheeled_APC_F: Car_F { - GVAR(ammoLocation) = "HitTurret"; + 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}}; @@ -53,4 +69,20 @@ class CfgVehicles { class O_MBT_02_cannon_F: O_MBT_02_base_F { GVAR(turret)[] = {QGVAR(Turret_MBT_02),{0,-1,0}}; }; + + class MRAP_01_base_F: Car_F { + GVAR(engineSmokeOffset)[] = {0,-2,0}; + }; + + class MRAP_02_base_F: Car_F { + GVAR(engineSmokeOffset)[] = {0,-2,0}; + }; + + class MRAP_03_base_F: Car_F { + GVAR(engineSmokeOffset)[] = {0,-2,0}; + }; + + class Quadbike_01_base_F: Car_F { + GVAR(engineSmokeOffset)[] = {0,1,0}; + }; }; diff --git a/addons/cookoff/XEH_PREP.hpp b/addons/cookoff/XEH_PREP.hpp index 5b744f9221..f1deb8eaed 100644 --- a/addons/cookoff/XEH_PREP.hpp +++ b/addons/cookoff/XEH_PREP.hpp @@ -2,5 +2,7 @@ PREP(handleDamage); PREP(engineFire); PREP(cookOff); +PREP(cookOffBox); PREP(blowOffTurret); -PREP(secondaryExplosions); +PREP(detonateAmmunition); +PREP(getVehicleAmmo); diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index 411f9d5a78..fad901982d 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -2,58 +2,109 @@ [QGVAR(engineFire), FUNC(engineFire)] call CBA_fnc_addEventHandler; [QGVAR(cookOff), FUNC(cookOff)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffBox), FUNC(cookOffBox)] call CBA_fnc_addEventHandler; GVAR(cacheTankDuplicates) = call CBA_fnc_createNamespace; // cookoff and burning engine ["Tank", "init", { params ["_vehicle"]; + private _typeOf = typeOf _vehicle; + if (isNil {GVAR(cacheTankDuplicates) getVariable _typeOf}) then { private _hitpoints = (getAllHitPointsDamage _vehicle param [0, []]) apply {toLower _x}; private _duplicateHitpoints = []; + { if ((_x != "") && {_x in (_hitpoints select [0,_forEachIndex])}) then { _duplicateHitpoints pushBack _forEachIndex; }; } forEach _hitpoints; + TRACE_2("dupes",_typeOf,_duplicateHitpoints); GVAR(cacheTankDuplicates) setVariable [_typeOf, _duplicateHitpoints]; }; _vehicle addEventHandler ["HandleDamage", { - if (GVAR(enable)) then { + if ((_this select 0) getVariable [QGVAR(enable), GVAR(enable)]) then { ["tank", _this] call FUNC(handleDamage); }; }]; }, nil, nil, true] call CBA_fnc_addClassEventHandler; ["Wheeled_APC_F", "init", { - (_this select 0) addEventHandler ["HandleDamage", { - if (GVAR(enable)) then { + params ["_vehicle"]; + + private _typeOf = typeOf _vehicle; + + if (isNil {GVAR(cacheTankDuplicates) getVariable _typeOf}) then { + private _hitpoints = (getAllHitPointsDamage _vehicle param [0, []]) apply {toLower _x}; + private _duplicateHitpoints = []; + + { + if ((_x != "") && {_x in (_hitpoints select [0,_forEachIndex])}) then { + _duplicateHitpoints pushBack _forEachIndex; + }; + } forEach _hitpoints; + + TRACE_2("dupes",_typeOf,_duplicateHitpoints); + GVAR(cacheTankDuplicates) setVariable [_typeOf, _duplicateHitpoints]; + }; + + _vehicle addEventHandler ["HandleDamage", { + if ((_this select 0) getVariable [QGVAR(enable), GVAR(enable)]) then { ["tank", _this] call FUNC(handleDamage); }; }]; }, nil, nil, true] call CBA_fnc_addClassEventHandler; ["Car", "init", { - (_this select 0) addEventHandler ["HandleDamage", { - if (GVAR(enable)) then { + params ["_vehicle"]; + + _vehicle addEventHandler ["HandleDamage", { + if ((_this select 0) getVariable [QGVAR(enable), GVAR(enable)]) then { ["car", _this] call FUNC(handleDamage); }; }]; }, nil, ["Wheeled_APC_F"], true] call CBA_fnc_addClassEventHandler; +["ReammoBox_F", "init", { + (_this select 0) addEventHandler ["HandleDamage", { + if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then { + ["box", _this] call FUNC(handleDamage); + }; + }]; +}, nil, nil, true] call CBA_fnc_addClassEventHandler; + // secondary explosions ["AllVehicles", "killed", { - if (GVAR(enable)) then { - (_this select 0) call FUNC(secondaryExplosions); + params ["_vehicle"]; + if (_vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)]) then { + if (GVAR(ammoCookoffDuration) == 0) exitWith {}; + ([_vehicle] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; + [_vehicle, _mags, _total] call FUNC(detonateAmmunition); }; -}, nil, ["Man"]] call CBA_fnc_addClassEventHandler; +}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler; // blow off turret effect ["Tank", "killed", { - if (GVAR(enable)) then { - (_this select 0) call FUNC(blowOffTurret); + if ((_this select 0) getVariable [QGVAR(enable),GVAR(enable)]) then { + if (random 1 < 0.15) then { + (_this select 0) call FUNC(blowOffTurret); + }; }; }] call CBA_fnc_addClassEventHandler; + +// event to add a turret to a curator if the vehicle already belonged to that curator +if (isServer) then { + [QGVAR(addTurretToEditable), { + params ["_vehicle", "_turret"]; + + { + if (_vehicle in curatorEditableObjects _x) then { + _x addCuratorEditableObjects [[_turret], false]; + }; + } forEach allCurators; + }] call CBA_fnc_addEventHandler; +}; diff --git a/addons/cookoff/XEH_preInit.sqf b/addons/cookoff/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/cookoff/XEH_preInit.sqf +++ b/addons/cookoff/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/cookoff/config.cpp b/addons/cookoff/config.cpp index 902f02740d..0673efaffe 100644 --- a/addons/cookoff/config.cpp +++ b/addons/cookoff/config.cpp @@ -8,15 +8,17 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); - authors[] = {"commy2"}; + authors[] = {"commy2", "Glowbal"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; #include "ACE_Settings.hpp" +#include "CfgEden.hpp" #include "CfgEventHandlers.hpp" +#include "CfgAmmo.hpp" #include "CfgCloudlets.hpp" #include "CfgSFX.hpp" #include "CfgVehicles.hpp" diff --git a/addons/cookoff/functions/fnc_blowOffTurret.sqf b/addons/cookoff/functions/fnc_blowOffTurret.sqf index 1ff505f7ef..2d76463e8d 100644 --- a/addons/cookoff/functions/fnc_blowOffTurret.sqf +++ b/addons/cookoff/functions/fnc_blowOffTurret.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Blow off turret effect. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" // delayed so the object is spawned after the model changes to a wreck // the sudden change in the model would cause nearby physx objects to get stuck @@ -30,4 +30,7 @@ _turret setVectorUp [random 1, random 1, 1]; _turret setVelocity [random 7, random 7, 8 + random 5]; + + // add turret to all curators that already own the wreck + [QGVAR(addTurretToEditable), [_vehicle, _turret]] call CBA_fnc_serverEvent; }, _this, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf index a9984235dd..c19f968c47 100644 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ b/addons/cookoff/functions/fnc_cookOff.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Start a cook-off in the given vehicle. @@ -9,18 +10,19 @@ * None * * Example: - * (vehicle player) call ace_cookoff_fnc_cookOff + * [(vehicle player)] call ace_cookoff_fnc_cookOff * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; _vehicle setVariable [QGVAR(isCookingOff), true]; -[QGVAR(cookOff), _vehicle] call CBA_fnc_remoteEvent; +if (local _vehicle) then { + [QGVAR(cookOff), _vehicle] call CBA_fnc_remoteEvent; +}; [{ params ["_vehicle"]; @@ -29,7 +31,7 @@ _vehicle setVariable [QGVAR(isCookingOff), true]; private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {!((_vehicle selectionPosition _x) isEqualTo [0,0,0])}; if (_positions isEqualTo []) then { - ACE_LOGWARNING_1("no valid selection for cookoff found. %1", typeOf _vehicle); + WARNING_1("no valid selection for cookoff found. %1", typeOf _vehicle); _positions pushBack "#noselection"; }; @@ -89,7 +91,9 @@ _vehicle setVariable [QGVAR(isCookingOff), true]; } forEach _positions; if (isServer) then { - private _sound = createSoundSource [QGVAR(Sound), position _vehicle, [], 0]; + 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]; _effects pushBack _sound; }; @@ -105,15 +109,19 @@ _vehicle setVariable [QGVAR(isCookingOff), true]; DEC(_counter); if (_counter > 0) then { - [_fnc_FlameEffect, [_vehicle, _fnc_FlameEffect, _counter], 0.4] call CBA_fnc_waitAndExecute + [_fnc_FlameEffect, [_vehicle, _fnc_FlameEffect, _counter], FLAME_EFFECT_DELAY] call CBA_fnc_waitAndExecute }; }; - [_vehicle, _fnc_FlameEffect, 12] call _fnc_FlameEffect; // recursive function + // Recursive function, occurs for duration of cookoff + [_vehicle, _fnc_FlameEffect, ceil(COOKOFF_TIME/FLAME_EFFECT_DELAY)] call _fnc_FlameEffect; + + private _randomPosition = _vehicle getPos [100, random 360]; { if (local _x && {!(_x call EFUNC(common,isPlayer))}) then { - _x action ["Eject", _vehicle]; + _x leaveVehicle _vehicle; + _x doMove _randomPosition; }; } forEach crew _vehicle; @@ -127,6 +135,6 @@ _vehicle setVariable [QGVAR(isCookingOff), true]; if (local _vehicle) then { _vehicle setDamage 1; }; - }, [_vehicle, _effects], 4 + random 1] call CBA_fnc_waitAndExecute; - }, [_vehicle, _effects, _positions], 3 + random 2] call CBA_fnc_waitAndExecute; -}, _vehicle, 0.5 + random 0.3] call CBA_fnc_waitAndExecute; + }, [_vehicle, _effects], COOKOFF_TIME] call CBA_fnc_waitAndExecute; // TODO: Randomise cook off time with locality in mind + }, [_vehicle, _effects, _positions], SMOKE_TIME] call CBA_fnc_waitAndExecute; +}, _vehicle, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf new file mode 100644 index 0000000000..8f6ef7f2f0 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBox.sqf @@ -0,0 +1,74 @@ +#include "script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, SilentSpike + * Start a cook-off in the given ammo box. + * + * Arguments: + * 0: Ammo box + * + * Return Value: + * None + * + * Example: + * [_box] call ace_cookoff_fnc_cookOffBox + * + * Public: No + */ + +params ["_box"]; + +if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; +_box setVariable [QGVAR(isCookingOff), true]; + +if (local _box) then { + [QGVAR(cookOffBox), _box] call CBA_fnc_remoteEvent; +}; + +[{ + params ["_box"]; + + // Box will start smoking + private _smoke = "#particlesource" createVehicleLocal [0,0,0]; + _smoke setParticleClass "AmmoSmokeParticles2"; + _smoke attachTo [_box, [0,0,0]]; + + private _effects = [_smoke]; + + if (isServer) then { + private _sound = createSoundSource ["Sound_Fire", position _box, [], 0]; + _effects pushBack _sound; + }; + + [{ + params ["_box", "_effects"]; + + // These functions are smart and do all the cooking off work + if (local _box) then { + 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; + }; + + // Light the fire (also handles lighting) + private _fire = "#particlesource" createVehicleLocal [0,0,0]; + _fire setParticleClass "AmmoBulletCore"; + _fire attachTo [_box, [0,0,0]]; + + _effects pushBack _fire; + + [{ + params ["_box", "_effects"]; + + { + deleteVehicle _x; + } forEach _effects; + + if (local _box) then { + _box setDamage 1; + }; + }, [_box, _effects], COOKOFF_TIME_BOX] call CBA_fnc_waitAndExecute; // TODO: Change so that box is alive until no ammo left, with locality in mind + }, [_box, _effects], SMOKE_TIME] call CBA_fnc_waitAndExecute; +}, _box, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_detonateAmmunition.sqf b/addons/cookoff/functions/fnc_detonateAmmunition.sqf new file mode 100644 index 0000000000..f77a2755fd --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunition.sqf @@ -0,0 +1,133 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Detonates ammunition from a vehicle until no ammo left + * + * Arguments: + * 0: vehicle + * 1: Ammo Array + * 0: Magazine Classname + * 1: Ammo Count + * 2: Total Ammo Count + * + * Return Value: + * None + * + * Example: + * [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition + * + * Public: No + */ +#define MAX_TIME_BETWEEN_AMMO_DET 25 + +params ["_vehicle", "_magazines", "_totalAmmo"]; + +if (isNull _vehicle) exitWith {}; // vehicle got deleted +if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore +if (underwater _vehicle) exitWith {}; + +private _magazineIndex = floor random(count _magazines); +private _magazine = _magazines select _magazineIndex; +_magazine params ["_magazineClassname", "_amountOfMagazines"]; + +if (_amountOfMagazines > 0) exitWith { + private _removed = _amountOfMagazines min floor(1 + random(6 / GVAR(ammoCookoffDuration))); + + _amountOfMagazines = _amountOfMagazines - _removed; + if (_amountOfMagazines <= 0) then { + _magazines deleteAt _magazineIndex; + } else { + _magazine set [1, _amountOfMagazines]; // clear out the magazine + }; + private _timeBetweenAmmoDetonation = (((random 10) / (sqrt _totalAmmo)) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; + TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); + _totalAmmo = _totalAmmo - _removed; + + private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClassname >> "ammo"); + private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; + + private _speedOfAmmo = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "initSpeed"); + private _simType = getText (_ammoCfg >> "simulation"); + + private _effect2pos = _vehicle selectionPosition "destructionEffect2"; + + private _spawnProjectile = { + params ["_vehicle", "_ammo", "_speed", "_flyAway"]; + + private _spawnPos = _vehicle modelToWorld [-0.2 + (random 0.4), -0.2 + (random 0.4), random 3]; + if (_spawnPos select 2 < 0) then { + _spawnPos set [2, 0]; + }; + + private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; + if (_flyAway) then { + private _vectorAmmo = [(-1 + (random 2)), (-1 + (random 2)), -0.2 + (random 1)]; + private _velVec = _vectorAmmo vectorMultiply _speed; + _projectile setVectorDir _velVec; + _projectile setVelocity _velVec; + } else { + _projectile setDamage 1; + }; + + _projectile; + }; + + private _speed = random (_speedOfAmmo / 10) max 1; + + if (toLower _simType == "shotbullet") then { + private _sound = selectRandom [QUOTE(PATHTO_R(sounds\light_crack_close.wss)), QUOTE(PATHTO_R(sounds\light_crack_close_filtered.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))]; + playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1250]; + + if (random 1 < 0.6) then { + [_vehicle, _ammo, _speed, true] call _spawnProjectile; + }; + }; + if (toLower _simType == "shotshell") then { + private _sound = selectRandom [QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))]; + playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1300]; + + if (random 1 < 0.15) then { + [_vehicle, _ammo, _speed, random 1 < 0.15] call _spawnProjectile; + }; + }; + if (toLower _simType == "shotgrenade") then { + if (random 1 < 0.9) then { + _speed = 0; + }; + [_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile; + }; + if (toLower _simType in ["shotrocket", "shotmissile", "shotsubmunitions"]) then { + if (random 1 < 0.1) then { + private _sound = selectRandom [QUOTE(PATHTO_R(sounds\cannon_crack_close.wss)), QUOTE(PATHTO_R(sounds\cannon_crack_close_filtered.wss))]; + playSound3D [_sound, objNull, false, (getPosASL _vehicle), 3, 1, 1600]; + + [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; + } else { + createvehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; + }; + }; + if (toLower _simType in ["shotdirectionalbomb", "shotmine"]) then { + if (random 1 < 0.5) then { + // Not all explosives detonate on destruction, some have scripted alternatives + private _scripted = getNumber (_ammoCfg >> "triggerWhenDestroyed") == 1; + if !(_scripted) then { + _ammo = getText (_ammoCfg >> "ace_explosives_Explosive"); + }; + + // If a scripted alternative doesn't exist use generic explosion + if (_ammo != "") then { + [_vehicle, _ammo, 0, false] call _spawnProjectile; + } else { + createvehicle ["SmallSecondary", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; + }; + }; + }; + if (toLower _simType == "shotilluminating") then { + if (random 1 < 0.15) then { + [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; + }; + }; + + [FUNC(detonateAmmunition), [_vehicle, _magazines, _totalAmmo], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; +}; +ERROR_1("mag with no ammo - %1", _magazine); diff --git a/addons/cookoff/functions/fnc_engineFire.sqf b/addons/cookoff/functions/fnc_engineFire.sqf index f9598fe7cf..6ed6920b7c 100644 --- a/addons/cookoff/functions/fnc_engineFire.sqf +++ b/addons/cookoff/functions/fnc_engineFire.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Start fire in engine block of a car. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; @@ -24,11 +24,17 @@ if (local _vehicle) then { [QGVAR(engineFire), _vehicle] call CBA_fnc_remoteEvent; }; +private _offset = getArray (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(engineSmokeOffset)); + +if (_offset isEqualTo []) then { + _offset = [0,0,0]; +}; + private _position = [ 0, - (boundingBoxReal _vehicle select 1 select 1) - 4, + (boundingBoxReal _vehicle select 1 select 1) - 2, (boundingBoxReal _vehicle select 0 select 2) + 2 -]; +] vectorAdd _offset; private _smoke = "#particlesource" createVehicleLocal [0,0,0]; _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; diff --git a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf new file mode 100644 index 0000000000..810084fe71 --- /dev/null +++ b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf @@ -0,0 +1,61 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets all magazines inside of a vehicle. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * 0: Ammo Array + * 0: Magazine Classname + * 1: Ammo Count + * 1: Total Ammo Count + * + * Example: + * [vehicle player] call ace_cookoff_fnc_getVehicleAmmo + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_1("getVehicleAmmo",_vehicle); + +private _ammoToDetonate = []; +private _totalAmmo = 0; + +// Get ammo from turrets +{ + _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; + }; +} forEach (magazinesAllTurrets _vehicle); + +// Get ammo from cargo space +{ + _x params ["_mag", "_count"]; + if (_count > 0) then { + _ammoToDetonate pushBack [_mag, _count]; + _totalAmmo = _totalAmmo + _count; + }; +} forEach (magazinesAmmoCargo _vehicle); + +// Get ammo from transportAmmo / ace_rearm +private _vehCfg = configFile >> "CfgVehicles" >> typeOf _vehicle; + +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]; + _totalAmmo = _totalAmmo + 2000; + _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100]; + _totalAmmo = _totalAmmo + 100; +}; + +[_ammoToDetonate, _totalAmmo] diff --git a/addons/cookoff/functions/fnc_handleDamage.sqf b/addons/cookoff/functions/fnc_handleDamage.sqf index 2a0f2d54bc..e9765805cb 100644 --- a/addons/cookoff/functions/fnc_handleDamage.sqf +++ b/addons/cookoff/functions/fnc_handleDamage.sqf @@ -1,22 +1,22 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Handles all incoming damage for tanks (including wheeled APCs). * * Arguments: - * HandleDamage EH + * HandleDamage EH * * Return Value: - * Damage to be inflicted. + * Damage to be inflicted. * * Example: * _this call ace_cookoff_fnc_handleDamage * * Public: No */ -#include "script_component.hpp" params ["_simulationType", "_thisHandleDamage"]; -_thisHandleDamage params ["_vehicle", "", "_damage", "", "_ammo", "_hitIndex"]; +_thisHandleDamage params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"]; // it's already dead, who cares? if (damage _vehicle >= 1) exitWith {}; @@ -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; @@ -58,20 +58,31 @@ if (_simulationType == "car") exitWith { if (_simulationType == "tank") exitWith { // determine ammo storage location - private _ammoLocationHitpoint = getText (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ammoLocation)); + private _ammoLocationHitpoint = getText (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ammoLocation)); if (_hitIndex in (GVAR(cacheTankDuplicates) getVariable (typeOf _vehicle))) then { _hitpoint = "#subturret"; }; - + // 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 ["hitbody", "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; }; }; @@ -82,3 +93,37 @@ if (_simulationType == "tank") exitWith { _damage }; }; + +if (_simulationType == "box") exitWith { + if (_hitpoint == "#structural" && _damage > 0.5) then { + // Almost always catch fire when hit by an explosive + if (IS_EXPLOSIVE_AMMO(_ammo)) then { + _vehicle call FUNC(cookOffBox); + } else { + // Need magazine to check for tracers + private _mag = ""; + if (_source == _shooter) then { + _mag = currentMagazine _source; + } else { + _mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath); + }; + private _magCfg = configFile >> "CfgMagazines" >> _mag; + + // Magazine could have changed during flight time (just ignore if so) + if (getText (_magCfg >> "ammo") == _ammo) then { + // If magazine's tracer density is high enough then low chance for cook off + private _tracers = getNumber (_magCfg >> "tracersEvery"); + if (_tracers >= 1 && {_tracers <= 4}) then { + if (random 1 < _oldDamage*0.05) then { + _vehicle call FUNC(cookOffBox); + }; + }; + }; + }; + + // prevent destruction, let cook-off handle it if necessary + _damage min 0.89 + } else { + _damage + }; +}; diff --git a/addons/cookoff/functions/fnc_secondaryExplosions.sqf b/addons/cookoff/functions/fnc_secondaryExplosions.sqf deleted file mode 100644 index 01a2fa3b3f..0000000000 --- a/addons/cookoff/functions/fnc_secondaryExplosions.sqf +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Author: Maddmatt, commy2 - * Generate an amount of secondary explosions - * - * Arguments: - * 0: Vehicle - * 1: Amount - * - * Return Value: - * None - * - * Public: No - */ -#include "script_component.hpp" - -#define SECONDARIES_DELAY (1 + random 45) - -params ["_vehicle", "_amount"]; - -if (isNil "_amount") then { - // calculate amount of secondary explosions if not specified - _amount = 0; - - { - _x params ["_magazine", "_count"]; - - private _ammo = getText (_magazine call CBA_fnc_getItemConfig >> "ammo"); - - if (IS_EXPLOSIVE_AMMO(_ammo)) then { - if (_ammo isKindOf "ShellBase") then { - ADD(_amount,_count); - } else { - ADD(_amount,_count/50); - }; - }; - } forEach magazinesAmmo _vehicle; -}; - -if (_amount <= 0) exitWith {}; - -private _fnc_secondaryExplosion = { - params ["_vehicle", "_amount", "_fnc_secondaryExplosion"]; - - private _position = _vehicle modelToWorld (_vehicle selectionPosition "destructionEffect2"); - - // these CfgAmmo objects are always global - "SmallSecondary" createVehicle _position; - - DEC(_amount); - - if (!isNull _vehicle && {_amount > 0}) then { - [_fnc_secondaryExplosion, [_vehicle, _amount, _fnc_secondaryExplosion], SECONDARIES_DELAY] call CBA_fnc_waitAndExecute; - }; -}; - -[_fnc_secondaryExplosion, [_vehicle, _amount, _fnc_secondaryExplosion], SECONDARIES_DELAY] call CBA_fnc_waitAndExecute; - -nil - -/*SencondaryExplosion - SecondaryExp - SecondarySmoke - GrenadeExploLight -*/ diff --git a/addons/cookoff/script_component.hpp b/addons/cookoff/script_component.hpp index 91afa5df3c..5daa0e8330 100644 --- a/addons/cookoff/script_component.hpp +++ b/addons/cookoff/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_COOKOFF @@ -18,3 +17,13 @@ #include "\z\ace\addons\main\script_macros.hpp" #define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) + +// Stages of cookoff in order (in seconds) +// Should be no un-synced randomness in these as the effects must be ran on each client +#define IGNITE_TIME 3 +#define SMOKE_TIME 10.5 +#define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files +#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn + +// Delay between flame effect for players in a cooking off vehicle +#define FLAME_EFFECT_DELAY 0.4 diff --git a/addons/cookoff/sounds/cannon_crack_close.wss b/addons/cookoff/sounds/cannon_crack_close.wss new file mode 100644 index 0000000000..b45ea96ab0 Binary files /dev/null and b/addons/cookoff/sounds/cannon_crack_close.wss differ diff --git a/addons/cookoff/sounds/cannon_crack_close_filtered.wss b/addons/cookoff/sounds/cannon_crack_close_filtered.wss new file mode 100644 index 0000000000..4ddb18539b Binary files /dev/null and b/addons/cookoff/sounds/cannon_crack_close_filtered.wss differ diff --git a/addons/cookoff/sounds/cookoff.wss b/addons/cookoff/sounds/cookoff.wss deleted file mode 100644 index 11b9d55194..0000000000 Binary files a/addons/cookoff/sounds/cookoff.wss and /dev/null differ diff --git a/addons/cookoff/sounds/cookoff_high_pressure.ogg b/addons/cookoff/sounds/cookoff_high_pressure.ogg new file mode 100644 index 0000000000..ebcffaf9ce Binary files /dev/null and b/addons/cookoff/sounds/cookoff_high_pressure.ogg differ diff --git a/addons/cookoff/sounds/cookoff_low_pressure.ogg b/addons/cookoff/sounds/cookoff_low_pressure.ogg new file mode 100644 index 0000000000..89439e21a7 Binary files /dev/null and b/addons/cookoff/sounds/cookoff_low_pressure.ogg differ diff --git a/addons/cookoff/sounds/cookoff_mid_pressure.ogg b/addons/cookoff/sounds/cookoff_mid_pressure.ogg new file mode 100644 index 0000000000..b82cbcf4e1 Binary files /dev/null and b/addons/cookoff/sounds/cookoff_mid_pressure.ogg differ diff --git a/addons/cookoff/sounds/heavy_crack_close.wss b/addons/cookoff/sounds/heavy_crack_close.wss new file mode 100644 index 0000000000..95cc68d90e Binary files /dev/null and b/addons/cookoff/sounds/heavy_crack_close.wss differ diff --git a/addons/cookoff/sounds/heavy_crack_close_filtered.wss b/addons/cookoff/sounds/heavy_crack_close_filtered.wss new file mode 100644 index 0000000000..1b4520cd4a Binary files /dev/null and b/addons/cookoff/sounds/heavy_crack_close_filtered.wss differ diff --git a/addons/cookoff/sounds/light_crack_close.wss b/addons/cookoff/sounds/light_crack_close.wss new file mode 100644 index 0000000000..ef284f24ef Binary files /dev/null and b/addons/cookoff/sounds/light_crack_close.wss differ diff --git a/addons/cookoff/sounds/light_crack_close_filtered.wss b/addons/cookoff/sounds/light_crack_close_filtered.wss new file mode 100644 index 0000000000..b1c76fa8ed Binary files /dev/null and b/addons/cookoff/sounds/light_crack_close_filtered.wss differ diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index f4738765f9..4f13296ac6 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -1,17 +1,138 @@ - + + + Cook off + Esplosione + 殉爆效果 + 殉爆效果 + 誘爆 + 쿡오프 + Durchzündung + Enable cook off - Cook-off ermöglichen + Durchzündung ermöglichen Povolit explozi munice Включить воспламенение + 誘爆を有効化 + 쿡오프 현상 활성화 + Aktywuj efekty samozapłonu amunicji + Active le cook-off + Abilita Esplosione + 開啟殉爆效果 + 开启殉爆效果 Enables cook off and related vehicle destruction effects. - Ermöglicht Cook-off 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. Включает воспламенение и сопутствующие эффекты повреждения техники. + 誘爆を有効化し、車両が誘爆によって破壊されていきます。 + 쿡오프 현상을 활성화 하고 관련된 차량에 폭발 이펙트를 적용합니다. + 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) + Épave (tourelle) + Restos (torreta) + Rottami (torretta) + Wrak (wieżyczka) + Обломки (башня) + Wrack (Geschützturm) + Vrak (věž) + Wreck (Turret) + Ruínas (torre) + 잔해(포탑) + 残骸 (砲塔) + 殘骸 (砲塔) + 残骸 (炮塔) + + + Enable ammo box cook off + 弾薬箱に誘爆を有効化 + Durchzündung für Munitionskisten ermöglichen + 탄약 상자 쿡오프 현상 활성화 + Aktywuj samozapłon skrzyń z amunicją + Cook-off caisses de munitions + Abilita esplosione cassa munizioni + 開啟彈藥箱殉爆效果 + 开启弹药箱殉爆效果 + + + Enables cooking off of ammo boxes. + 弾薬箱が誘爆するようになります。 + 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 + 弾薬の誘爆を有効化 + Durchzündung für Munition ermöglichen + 탄약 쿡오프 현상 활성화 + Aktywuj samozapłon amunicji + Active le cook-off des munitions + Abilita Esplosione munizioni + 開啟彈藥殉爆效果 + 开启弹药殉爆效果 + + + Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. + 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。 + 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/CfgVehicles.hpp b/addons/dagr/CfgVehicles.hpp index 89bfd8af4e..6b0188a178 100644 --- a/addons/dagr/CfgVehicles.hpp +++ b/addons/dagr/CfgVehicles.hpp @@ -8,7 +8,6 @@ class CfgVehicles { condition = QUOTE([ARR_2(_player,'ACE_DAGR')] call EFUNC(common,hasItem)); statement = QUOTE(call FUNC(menuInit)); showDisabled = 0; - priority = 0.1; icon = QPATHTOF(UI\DAGR_Icon.paa); exceptions[] = {"isNotInside", "isNotSitting"}; class GVAR(toggle) { @@ -16,7 +15,6 @@ class CfgVehicles { condition = QUOTE([ARR_2(_player,'ACE_DAGR')] call EFUNC(common,hasItem)); statement = QUOTE(call FUNC(toggleOverlay)); showDisabled = 0; - priority = 0.2; icon = QPATHTOF(UI\DAGR_Icon.paa); exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; }; 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/XEH_preInit.sqf b/addons/dagr/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/dagr/XEH_preInit.sqf +++ b/addons/dagr/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/dagr/config.cpp b/addons/dagr/config.cpp index f84f4aeb38..b923c3ea94 100644 --- a/addons/dagr/config.cpp +++ b/addons/dagr/config.cpp @@ -19,7 +19,3 @@ class CfgPatches { #include "CfgWeapons.hpp" #include "Dialog.hpp" #include "RscTitles.hpp" - -class ACE_newEvents { - RangerfinderData = QEGVAR(vector,rangefinderData); -}; diff --git a/addons/dagr/functions/fnc_handleRangeFinderData.sqf b/addons/dagr/functions/fnc_handleRangeFinderData.sqf index 59e10a1711..4d9447240b 100644 --- a/addons/dagr/functions/fnc_handleRangeFinderData.sqf +++ b/addons/dagr/functions/fnc_handleRangeFinderData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rosuto, Ruthberg * Handles incoming data packets from the Vectronix Vector LRF @@ -8,18 +9,17 @@ * 2: Inclination (Degrees) * * Return Value: - * Nothing + * None * * Example: * [1000, 45, 1] call ace_dagr_fnc_handleRangeFinderData * * Public: No */ -#include "script_component.hpp" #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_menuInit.sqf b/addons/dagr/functions/fnc_menuInit.sqf index c4aa989854..0425f1f4d2 100644 --- a/addons/dagr/functions/fnc_menuInit.sqf +++ b/addons/dagr/functions/fnc_menuInit.sqf @@ -1,18 +1,18 @@ +#include "script_component.hpp" /* * Author: Rosuto, Ruthberg * Creates the DAGR menu dialog * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * * Public: No */ -#include "script_component.hpp" #define __dsp (uiNamespace getVariable "DAGR_MENU") #define __F1 266874 diff --git a/addons/dagr/functions/fnc_outputData.sqf b/addons/dagr/functions/fnc_outputData.sqf index 0fcc3ccbda..a5816e472d 100644 --- a/addons/dagr/functions/fnc_outputData.sqf +++ b/addons/dagr/functions/fnc_outputData.sqf @@ -1,18 +1,19 @@ +#include "script_component.hpp" /* * Author: Rosuto * DAGR data output loop * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: + * call ace_dagr_fnc_outputData * * Public: No */ -#include "script_component.hpp" 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; @@ -30,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; @@ -40,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 23996c46b4..ce2ca2a04c 100644 --- a/addons/dagr/functions/fnc_outputVector.sqf +++ b/addons/dagr/functions/fnc_outputVector.sqf @@ -1,20 +1,19 @@ -/* +#include "script_component.hpp" +/* * Author: Rosuto * DAGR vector output loop * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: + * call ace_dagr_fnc_outputVector * * Public: No */ -#include "script_component.hpp" - -private ["_xGrid", "_yGrid", "_dagrGrid", "_bearing", "_dagrDist", "_dagrElevation", "_dagrTime", "_elevation", "_xCoord", "_yCoord"]; 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; @@ -37,7 +36,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; @@ -46,7 +45,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; }; @@ -54,37 +53,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 d36f222a51..41518a0560 100644 --- a/addons/dagr/functions/fnc_outputWP.sqf +++ b/addons/dagr/functions/fnc_outputWP.sqf @@ -1,18 +1,19 @@ -/* +#include "script_component.hpp" +/* * Author: Rosuto * DAGR waypoint output loop * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: + * call ace_dagr_fnc_outputWP * * Public: No */ -#include "script_component.hpp" 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; @@ -30,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; @@ -40,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) }; @@ -65,21 +64,25 @@ 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 ((_WPpos vectorDiff _MYpos) call CBA_fnc_vectDir); + 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)) + }); // Output __gridControl ctrlSetText format ["%1", _dagrGrid]; diff --git a/addons/dagr/functions/fnc_toggleOverlay.sqf b/addons/dagr/functions/fnc_toggleOverlay.sqf index d48a83ae51..c0e229d745 100644 --- a/addons/dagr/functions/fnc_toggleOverlay.sqf +++ b/addons/dagr/functions/fnc_toggleOverlay.sqf @@ -1,18 +1,19 @@ +#include "script_component.hpp" /* * Author: Rosuto, Ruthberg * Toggles the DAGR overlay * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: + * call ace_dagr_fnc_toggleOverlay * * Public: No */ -#include "script_component.hpp" GVAR(run) = !GVAR(run); 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/script_component.hpp b/addons/dagr/script_component.hpp index e392295765..4fadaf982c 100644 --- a/addons/dagr/script_component.hpp +++ b/addons/dagr/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_DAGR diff --git a/addons/dagr/stringtable.xml b/addons/dagr/stringtable.xml index 01b43391ab..c364eedabe 100644 --- a/addons/dagr/stringtable.xml +++ b/addons/dagr/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ DAGR DAGR DAGR + DAGR + DAGR + 軍用GPS接收器 + 军用GPS接收器 Configure DAGR @@ -22,6 +26,10 @@ Konfigurovat DAGR Configura DAGR Configurer le DAGR + DAGR を設定 + DAGR 설정 + 設定軍用GPS接收器 + 设定军用GPS接收器 Toggle DAGR @@ -33,6 +41,10 @@ Přepnout DAGR Apri DAGR Activer/Desactiver le DAGR + DAGR を常に表示 + DAGR 토글 + 切換軍用GPS接收器 + 切换军用GPS接收器 Defense Advanced GPS Receiver @@ -44,6 +56,10 @@ Defense Advanced GPS Receiver Defense Advanced GPS Receiver Defense Advanced GPS Receiver + アドバンスド DAGR の受信を定義します + 국방 고급위성항법시스템 수신기 + 軍用高級防禦GPS接收器 + 军用高级防御GPS接收器 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/XEH_preInit.sqf b/addons/disarming/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/disarming/XEH_preInit.sqf +++ b/addons/disarming/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/disarming/config.cpp b/addons/disarming/config.cpp index d8f249a9c6..e38f4346ab 100644 --- a/addons/disarming/config.cpp +++ b/addons/disarming/config.cpp @@ -19,8 +19,3 @@ class CfgPatches { #include "CfgWeapons.hpp" #include "gui_disarm.hpp" - -class ACE_newEvents { - DisarmDebugCallback = QGVAR(debugCallback); - DisarmDropItems = QGVAR(dropItems); -}; diff --git a/addons/disarming/functions/fnc_canBeDisarmed.sqf b/addons/disarming/functions/fnc_canBeDisarmed.sqf index 9be20db7f4..ab41729f6a 100644 --- a/addons/disarming/functions/fnc_canBeDisarmed.sqf +++ b/addons/disarming/functions/fnc_canBeDisarmed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -14,18 +15,15 @@ * * Public: No */ -#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..2468e454fd 100644 --- a/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf +++ b/addons/disarming/functions/fnc_canPlayerDisarmUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -15,9 +16,8 @@ * * Public: No */ -#include "script_component.hpp" 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 c9eb920084..4c8fb3bf2d 100644 --- a/addons/disarming/functions/fnc_disarmDropItems.sqf +++ b/addons/disarming/functions/fnc_disarmDropItems.sqf @@ -1,32 +1,30 @@ +#include "script_component.hpp" /* * Author: PabstMirror * * 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: - * Nothing + * None * * Example: * [player, cursorTarget, ["ace_bandage"]] call ace_disarming_fnc_disarmDropItems * * Public: No */ -#include "script_component.hpp" #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_eventCallerFinish.sqf b/addons/disarming/functions/fnc_eventCallerFinish.sqf index bf1daee2f0..60629b221f 100644 --- a/addons/disarming/functions/fnc_eventCallerFinish.sqf +++ b/addons/disarming/functions/fnc_eventCallerFinish.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -16,11 +17,10 @@ * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target", "_errorMsg"]; if (_caller != ACE_player) exitWith {}; systemChat format ["Debug-Caller: Disarm finished from [%1] with code [%2]", _target, _errorMsg]; -ACE_LOGINFO_2("%1 - eventCallerFinish: %2",CBA_missionTime,_this); +INFO_2("%1 - eventCallerFinish: %2",CBA_missionTime,_this); diff --git a/addons/disarming/functions/fnc_eventTargetFinish.sqf b/addons/disarming/functions/fnc_eventTargetFinish.sqf index 4b7487d47c..b750fd51b1 100644 --- a/addons/disarming/functions/fnc_eventTargetFinish.sqf +++ b/addons/disarming/functions/fnc_eventTargetFinish.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -10,18 +11,17 @@ * 2: errorMsg * * Return Value: - * Nothing + * None * * Example: * [player1, player2, "Someting fucked up"] call ace_disarming_fnc_eventTargetFinish * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target", "_errorMsg"]; if (_errorMsg != "") then { - ACE_LOGINFO_2("%1 - eventTargetFinish: %2",CBA_missionTime,_this); + INFO_2("%1 - eventTargetFinish: %2",CBA_missionTime,_this); [QGVAR(debugCallback), [_caller, _target, _errorMsg], [_caller]] call CBA_fnc_targetEvent; }; diff --git a/addons/disarming/functions/fnc_eventTargetStart.sqf b/addons/disarming/functions/fnc_eventTargetStart.sqf index 77dfd9d271..e63289cf20 100644 --- a/addons/disarming/functions/fnc_eventTargetStart.sqf +++ b/addons/disarming/functions/fnc_eventTargetStart.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -10,14 +11,13 @@ * 2: type of disarm * * Return Value: - * Nothing + * None * * Example: - * eventTargetStart + * [bob, kevin, "disarm"] call ace_disarming_fnc_eventTargetStart * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target", "_listOfObjectsToRemove"]; diff --git a/addons/disarming/functions/fnc_getAllGearContainer.sqf b/addons/disarming/functions/fnc_getAllGearContainer.sqf index 105be91a9e..be46d66e5e 100644 --- a/addons/disarming/functions/fnc_getAllGearContainer.sqf +++ b/addons/disarming/functions/fnc_getAllGearContainer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target"]; diff --git a/addons/disarming/functions/fnc_getAllGearUnit.sqf b/addons/disarming/functions/fnc_getAllGearUnit.sqf index bdd1ff0bf9..db066ad5d8 100644 --- a/addons/disarming/functions/fnc_getAllGearUnit.sqf +++ b/addons/disarming/functions/fnc_getAllGearUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -14,13 +15,10 @@ * * Public: No */ -#include "script_component.hpp" 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..0b66009949 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target"]; #define DEFUALTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" //Sanity Checks @@ -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 82b9645850..fadbb2d914 100644 --- a/addons/disarming/functions/fnc_showItemsInListbox.sqf +++ b/addons/disarming/functions/fnc_showItemsInListbox.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -8,14 +9,13 @@ * 1: ItemArray [["itemClassnames"],[counts]] * * Return Value: - * Nothing + * None * * Example: * [theListBox, [["ace_bandage"],[2]]] call ace_disarming_fnc_showItemsInListbox * * Public: No */ -#include "script_component.hpp" disableSerialization; @@ -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..60d851b973 100644 --- a/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf +++ b/addons/disarming/functions/fnc_verifyMagazinesMoved.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * @@ -19,9 +20,8 @@ * * Public: No */ -#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/disarming/script_component.hpp b/addons/disarming/script_component.hpp index 7bd87ade59..56dda33d5f 100644 --- a/addons/disarming/script_component.hpp +++ b/addons/disarming/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_DISARMING diff --git a/addons/disarming/stringtable.xml b/addons/disarming/stringtable.xml index dfa030273a..30f9fa4b85 100644 --- a/addons/disarming/stringtable.xml +++ b/addons/disarming/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Ouvrir l'inventaire Felszerelés megtekintése Abrir inventário + インベントリを開く + 소지품 열기 + 開啟裝備 + 开启装备 diff --git a/addons/disposable/CfgMagazines.hpp b/addons/disposable/CfgMagazines.hpp index d9ad0508db..6204b330e4 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/disposable/CfgWeapons.hpp b/addons/disposable/CfgWeapons.hpp index 0ca6763d63..731910b704 100644 --- a/addons/disposable/CfgWeapons.hpp +++ b/addons/disposable/CfgWeapons.hpp @@ -5,6 +5,7 @@ class CfgWeapons { magazines[] = {"ACE_PreloadedMissileDummy"}; // The dummy magazine }; class ACE_launch_NLAW_Used_F: launch_NLAW_F { // the used tube should be a sub class of the disposable launcher + EGVAR(nlaw,enabled) = 0; // disable guidance for the disposabled tube scope = 1; ACE_isUsedLauncher = 1; author = ECSTRING(common,ACETeam); diff --git a/addons/disposable/XEH_preInit.sqf b/addons/disposable/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/disposable/XEH_preInit.sqf +++ b/addons/disposable/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/disposable/functions/fnc_replaceATWeapon.sqf b/addons/disposable/functions/fnc_replaceATWeapon.sqf index 58c58a6056..a5ad1196f2 100644 --- a/addons/disposable/functions/fnc_replaceATWeapon.sqf +++ b/addons/disposable/functions/fnc_replaceATWeapon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux, commy2 * Replace the disposable launcher with the used dummy. Called from the unified fired EH. @@ -6,14 +7,13 @@ * None. Parameters inherited from EFUNC(common,firedEH) * * Return Value: - * Nothing + * None * * Example: * [fromBisFiredEH] call ace_disposable_fnc_replaceATWeapon; * * 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); diff --git a/addons/disposable/functions/fnc_takeLoadedATWeapon.sqf b/addons/disposable/functions/fnc_takeLoadedATWeapon.sqf index bd6dec057c..3f12d610d3 100644 --- a/addons/disposable/functions/fnc_takeLoadedATWeapon.sqf +++ b/addons/disposable/functions/fnc_takeLoadedATWeapon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle the take event. Add a dummy magazine if a disposable rocket launcher is taken. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); diff --git a/addons/disposable/functions/fnc_updateInventoryDisplay.sqf b/addons/disposable/functions/fnc_updateInventoryDisplay.sqf index 9908c86186..7ab2d18d75 100644 --- a/addons/disposable/functions/fnc_updateInventoryDisplay.sqf +++ b/addons/disposable/functions/fnc_updateInventoryDisplay.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux, commy2 * Hide or show the secondary weapon magazine inventory slot to prevent unloading of dummy magazines. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; params ["_player", ["_display",(findDisplay 602),[displayNull]]]; diff --git a/addons/disposable/script_component.hpp b/addons/disposable/script_component.hpp index 32402bc3e5..c2f4c833ab 100644 --- a/addons/disposable/script_component.hpp +++ b/addons/disposable/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_ATTACH diff --git a/addons/disposable/stringtable.xml b/addons/disposable/stringtable.xml index ac2b76ee7f..f41b2cad88 100644 --- a/addons/disposable/stringtable.xml +++ b/addons/disposable/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -10,8 +10,12 @@ Lanzador utilizado Elhasznált kilövőcső Отстрелянная труба - Tubo usato + Lanciatore usato Tubo utilizado + 使用済み + 사용함 + 使用過的火箭筒 + 使用过的火箭筒 Used disposable rocket launcher @@ -24,6 +28,10 @@ Отстрелянная одноразовая пусковая установка Lanciarazzi monouso già utilizzato Lança foguetes descartável utilizado + 使い終わったロケット ランチャーの筒部分 + 사용한 일회용 발사관 + 使用過的一次性火箭發射器 + 使用过的一次性火箭发射器 Preloaded Missile Dummy @@ -36,6 +44,10 @@ Предзаряженная ракетная болванка Missile inerte precaricato Míssel inerte pré-carregado + 仮置きのミサイルをあらかじめ装填 + 임시로 미사일을 미리 장전 + 預裝訓練導彈 + 预装训练导弹 - \ No newline at end of file + diff --git a/addons/dogtags/CfgUIGrids.hpp b/addons/dogtags/CfgUIGrids.hpp new file mode 100644 index 0000000000..f9216ac2ea --- /dev/null +++ b/addons/dogtags/CfgUIGrids.hpp @@ -0,0 +1,29 @@ +class CfgUIGrids { + class IGUI { + class Presets { + class Arma3 { + class Variables { + GVAR(grid)[] = { + { + (safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W, + safeZoneY + 0.175 * safeZoneH, + 8 * GUI_GRID_W, + 8 * GUI_GRID_H + }, + GUI_GRID_W, + GUI_GRID_H + }; + }; + }; + }; + class Variables { + class GVAR(grid) { + displayName = COMPONENT_NAME; + description = CSTRING(IGUI_Description); + preview = QPATHTOF(ui\igui_preview.paa); + saveToProfile[] = {0, 1}; + canResize = 0; + }; + }; + }; +}; diff --git a/addons/dogtags/CfgVehicles.hpp b/addons/dogtags/CfgVehicles.hpp index 9757ac1c53..cc56410699 100644 --- a/addons/dogtags/CfgVehicles.hpp +++ b/addons/dogtags/CfgVehicles.hpp @@ -2,30 +2,30 @@ class CfgVehicles { class Man; class CAManBase: Man { class ACE_Actions { - class ACE_MainActions { - class ACE_Dogtag { - displayName = CSTRING(itemName); - condition = ""; - statement = ""; + class ACE_Dogtag { + 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); + selection = "neck"; + class ACE_CheckDogtag { + 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; + icon = QPATHTOF(data\dogtag_icon_ca.paa); + }; + class ACE_TakeDogtag { + 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); - class ACE_CheckDogtag { - displayName = CSTRING(checkDogtag); - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckDogtag)); - statement = QUOTE([ARR_2(_player,_target)] call FUNC(checkDogtag)); - showDisabled = 0; - priority = 3; - icon = QPATHTOF(data\dogtag_icon_ca.paa); - }; - class ACE_TakeDogtag { - displayName = CSTRING(takeDogtag); - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeDogtag)); - statement = QUOTE([ARR_2(_player,_target)] call FUNC(takeDogtag)); - showDisabled = 0; - priority = 3; - icon = QPATHTOF(data\dogtag_icon_ca.paa); - }; }; }; }; @@ -35,7 +35,8 @@ class CfgVehicles { displayName = CSTRING(checkItem); condition = "true"; statement = ""; - insertChildren = QUOTE(_this call DFUNC(addDogtagActions)); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; + insertChildren = QUOTE(_player call DFUNC(addDogtagActions)); }; }; }; diff --git a/addons/dogtags/CfgWeapons.hpp b/addons/dogtags/CfgWeapons.hpp index 4e37db74db..ec8d9e6ee4 100644 --- a/addons/dogtags/CfgWeapons.hpp +++ b/addons/dogtags/CfgWeapons.hpp @@ -4,13 +4,13 @@ scope = 1; \ scopeArsenal = 0; \ scopeCurator = 0; \ - descriptionShort = QUOTE(DOGTAGID); \ + descriptionShort = CSTRING(itemName); \ GVAR(tagID) = DOGTAGID; \ } 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/Dogtag.hpp b/addons/dogtags/Dogtag.hpp deleted file mode 100644 index d783ec15b0..0000000000 --- a/addons/dogtags/Dogtag.hpp +++ /dev/null @@ -1,72 +0,0 @@ -class RscPicture; -class RscStructuredText; - -class RscTitles { - class GVAR(singleTag) { - idd = -1; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(tag),_this select 0)]); - onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(tag),nil)]); - movingEnable = false; - duration = 5; - fadeIn = 0.2; - fadeOut = 0.2; - - class controls { - class background: RscPicture { - idc = 1000; - text = QUOTE(PATHTOF(data\dogtagSingle.paa)); - sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; - colorText[] = {1, 1, 1, 1}; - colorBackground[] = {0, 0, 0, 0}; - x = ((safezoneX + safezoneW) - (10 * (((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 * (((safezoneW / safezoneH) min 1.2) / 40)); - y = safeZoneY + 0.175 * safezoneH; - w = (8 * (((safezoneW / safezoneH) min 1.2) / 40)); - h = (8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)); - font = "EtelkaMonospacePro"; - }; - class nickname: RscStructuredText { - idc = 1001; - text = ""; - sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; - colorText[] = {1, 1, 1, 1}; - colorBackground[] = {0, 0, 0, 0}; - x = ((safezoneX + safezoneW) - (8.4 * (((safezoneW / safezoneH) min 1.2) / 40)) - 2.9 * (((safezoneW / safezoneH) min 1.2) / 40)); - y = safeZoneY + 0.24 * safezoneH; - w = (5.9 * (((safezoneW / safezoneH) min 1.2) / 40)); - h = (3 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)); - font = "RobotoCondensed"; - class Attributes { - font = "RobotoCondensed"; - color = "#EEEEEE"; - align = "left"; - valign = "middle"; - shadow = 2; - shadowColor = "#3f4345"; - size = "0.80"; - }; - }; - }; - }; - class GVAR(doubleTag): GVAR(singleTag) { - idd = -1; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(tag),_this select 0)]); - onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(tag),nil)]); - - class controls: controls { - class background: background { - text = QUOTE(PATHTOF(data\dogtagDouble.paa)); - }; - class nickname: nickname { - class Attributes: Attributes { - font = "RobotoCondensed"; - color = "#EEEEEE"; - align = "left"; - valign = "middle"; - shadow = 2; - shadowColor = "#3f4345"; - size = "0.80"; - }; - }; - }; - }; -}; diff --git a/addons/dogtags/RscTitles.hpp b/addons/dogtags/RscTitles.hpp new file mode 100644 index 0000000000..97549c856e --- /dev/null +++ b/addons/dogtags/RscTitles.hpp @@ -0,0 +1,64 @@ +class RscPicture; +class RscStructuredText; + +class RscTitles { + class GVAR(singleTag) { + idd = -1; + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(tag),_this select 0)]); + onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(tag),nil)]); + fadeIn = 0.2; + fadeOut = 0.2; + duration = 5; + movingEnable = 0; + class controls { + class background: RscPicture { + idc = 1000; + x = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', (safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W]; + y = profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', safeZoneY + 0.175 * safeZoneH]; + w = 8 * GUI_GRID_W; + h = 8 * GUI_GRID_H; + text = QPATHTOF(data\dogtagSingle.paa); + colorText[] = {1, 1, 1, 1}; + }; + class nickname: RscStructuredText { + idc = 1001; + text = ""; + sizeEx = GUI_GRID_H; + colorText[] = {1, 1, 1, 1}; + colorBackground[] = {0, 0, 0, 0}; + x = 1.6 * GUI_GRID_W + (profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),X)', (safeZoneX + safeZoneW) - 12.9 * GUI_GRID_W]); + y = 0.065 * safeZoneH + (profileNamespace getVariable ['TRIPLES(IGUI,GVAR(grid),Y)', safeZoneY + 0.175 * safeZoneH]); + w = 5.9 * GUI_GRID_W; + h = 3 * GUI_GRID_H; + font = "RobotoCondensed"; + class Attributes { + font = "RobotoCondensed"; + color = "#EEEEEE"; + align = "left"; + valign = "middle"; + shadow = 2; + shadowColor = "#3f4345"; + size = "0.80"; + }; + }; + }; + }; + class GVAR(doubleTag): GVAR(singleTag) { + class controls: controls { + class background: background { + text = QPATHTOF(data\dogtagDouble.paa); + }; + class nickname: nickname { + class Attributes: Attributes { + font = "RobotoCondensed"; + color = "#EEEEEE"; + align = "left"; + valign = "middle"; + shadow = 2; + shadowColor = "#3f4345"; + size = "0.80"; + }; + }; + }; + }; +}; diff --git a/addons/dogtags/XEH_PREP.hpp b/addons/dogtags/XEH_PREP.hpp index 33e42ba191..5917600139 100644 --- a/addons/dogtags/XEH_PREP.hpp +++ b/addons/dogtags/XEH_PREP.hpp @@ -1,3 +1,4 @@ + PREP(addDogtagActions); PREP(addDogtagItem); PREP(bloodType); @@ -11,3 +12,4 @@ PREP(sendDogtagData); PREP(showDogtag); PREP(ssn); PREP(takeDogtag); +PREP(disableFactionDogtags); diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index 729ae7eb04..02d2db862b 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -10,25 +10,27 @@ // - Adding actions via config would create a dependency if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (hasInterface) then { - private _checkTagAction = [ - "ACE_CheckDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(checkDogtag)], - QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(checkDogtag)}, - {!isNil {_target getVariable QGVAR(dogtagData)}} - ] call ace_interact_menu_fnc_createAction; + "ACE_CheckDogtag", + format ["%1: %2", localize LSTRING(itemName), localize LSTRING(checkDogtag)], + QPATHTOF(data\dogtag_icon_ca.paa), + {[_player,_target] call FUNC(checkDogtag)}, + {!isNil {_target getVariable QGVAR(dogtagData)}} + ] call EFUNC(interact_menu,createAction); + ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _checkTagAction] call EFUNC(interact_menu,addActionToClass); private _takeTagAction = [ - "ACE_TakeDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(takeDogtag)], - QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(takeDogtag)}, - {(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}} - ] call ace_interact_menu_fnc_createAction; + "ACE_TakeDogtag", + format ["%1: %2", localize LSTRING(itemName), localize LSTRING(takeDogtag)], + QPATHTOF(data\dogtag_icon_ca.paa), + {[_player,_target] call FUNC(takeDogtag)}, + {(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}} + ] call EFUNC(interact_menu,createAction); + ["ACE_bodyBagObject", 0, ["ACE_MainActions"], _takeTagAction] call EFUNC(interact_menu,addActionToClass); }; + if (isServer) then { ["ace_placedInBodyBag", { params ["_target", "_bodyBag"]; @@ -43,3 +45,36 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { }] call CBA_fnc_addEventHandler; }; }; + +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/XEH_preInit.sqf b/addons/dogtags/XEH_preInit.sqf index a7feade1c3..a7a080b91e 100644 --- a/addons/dogtags/XEH_preInit.sqf +++ b/addons/dogtags/XEH_preInit.sqf @@ -2,6 +2,10 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; +GVAR(disabledFactions) = [] call CBA_fnc_createNamespace; + ADDON = true; diff --git a/addons/dogtags/config.cpp b/addons/dogtags/config.cpp index a3ad6b7cf0..dad0107953 100644 --- a/addons/dogtags/config.cpp +++ b/addons/dogtags/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); authors[] = {"SzwedzikPL"}; url = ECSTRING(main,URL); @@ -17,4 +17,5 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" -#include "Dogtag.hpp" +#include "RscTitles.hpp" +#include "CfgUIGrids.hpp" diff --git a/addons/dogtags/functions/fnc_addDogtagActions.sqf b/addons/dogtags/functions/fnc_addDogtagActions.sqf index 05f136830c..2911b27a92 100644 --- a/addons/dogtags/functions/fnc_addDogtagActions.sqf +++ b/addons/dogtags/functions/fnc_addDogtagActions.sqf @@ -1,43 +1,38 @@ +#include "script_component.hpp" /* - * Author: SzwedzikPL - * Creates one action per dogtag. + * Author: SzwedzikPL, mharis001 + * Returns children actions for checking dogtags in player's inventory. * * Arguments: - * 0: Target - * 1: Player + * 0: Player * * Return Value: - * Children actions + * Actions * * Example: - * _childrenActions = [unit, player] call ace_dogtags_fnc_addDogtagActions + * [_player] call ace_dogtags_fnc_addDogtagActions * * Public: No */ -#include "script_component.hpp" -params ["_target", "_player"]; +params ["_player"]; -//Get all dogtags and their ids -private _unitDogtags = []; -private _unitDogtagIDs = []; -{ - private _id = getNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(tagID)); - if (_id > 0) then { - _unitDogtags pushBack _x; - _unitDogtagIDs pushBack _id; - }; -} forEach items _player; +private _fnc_getActions = { + private _actions = []; + private _cfgWeapons = configFile >> "CfgWeapons"; -//Create action children for all dogtags -private _actions = []; -{ - private _tagID = _unitDogtagIDs select _forEachIndex; - private _displayName = format ["%1 #%2", getText (configFile >> "CfgWeapons" >> _x >> "displayName"), _tagID]; - private _picture = getText (configFile >> "CfgWeapons" >> _x >> "picture"); + { + private _config = _cfgWeapons >> _x; + if (getNumber (_config >> QGVAR(tagID)) > 0) then { + private _displayName = getText (_config >> "displayName"); + private _picture = getText (_config >> "picture"); - private _action = [_x, _displayName, _picture, {_this call FUNC(checkDogtagItem)}, {true}, {}, _x] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _player]; -} forEach _unitDogtags; + private _action = [_x, _displayName, _picture, FUNC(checkDogtagItem), {true}, {}, _x] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _player]; + }; + } forEach (_player call EFUNC(common,uniqueItems)); -_actions + _actions +}; + +[[], _fnc_getActions, _player, QGVAR(actionsCache), 9999, "cba_events_loadoutEvent"] call EFUNC(common,cachedCall); diff --git a/addons/dogtags/functions/fnc_addDogtagItem.sqf b/addons/dogtags/functions/fnc_addDogtagItem.sqf index e734b6f38f..acecd6b252 100644 --- a/addons/dogtags/functions/fnc_addDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_addDogtagItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Adds dogtag item to unit (triggered by server). @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_item", "_dogtagData"]; @@ -24,4 +24,8 @@ if (_item == "") exitWith {}; _dogtagData params ["_nickName"]; private _displayText = format [localize LSTRING(takeDogtagSuccess), _nickName]; -[_displayText] call EFUNC(common,displayText); + +// display message +[{ + [_this, 2.5] call EFUNC(common,displayTextStructured); +}, _displayText, DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_bloodType.sqf b/addons/dogtags/functions/fnc_bloodType.sqf index a7cafbd1fd..46e75ee7f9 100644 --- a/addons/dogtags/functions/fnc_bloodType.sqf +++ b/addons/dogtags/functions/fnc_bloodType.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Reports a blood type depending on the units name. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define BLOOD_TYPES ["O POS", "O NEG", "A POS", "A NEG", "B POS", "B NEG", "AB POS", "AB NEG"] diff --git a/addons/dogtags/functions/fnc_canCheckDogtag.sqf b/addons/dogtags/functions/fnc_canCheckDogtag.sqf index 66a25c94b0..8abbf8858d 100644 --- a/addons/dogtags/functions/fnc_canCheckDogtag.sqf +++ b/addons/dogtags/functions/fnc_canCheckDogtag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Checks if dogtag can be checked. @@ -14,10 +15,12 @@ * * Public: No */ -#include "script_component.hpp" params ["_player", "_target"]; if (isNull _target) exitWith {false}; +// check if disabled for faction +if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; + (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_canTakeDogtag.sqf b/addons/dogtags/functions/fnc_canTakeDogtag.sqf index 33a3ef055f..8bcad4a73d 100644 --- a/addons/dogtags/functions/fnc_canTakeDogtag.sqf +++ b/addons/dogtags/functions/fnc_canTakeDogtag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Checks if dogtag can be taken. @@ -14,10 +15,12 @@ * * Public: No */ -#include "script_component.hpp" params ["_player", "_target"]; if (isNull _target) exitWith {false}; +// check if disabled for faction +if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; + (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_checkDogtag.sqf b/addons/dogtags/functions/fnc_checkDogtag.sqf index 7b703b995c..fb722361a4 100644 --- a/addons/dogtags/functions/fnc_checkDogtag.sqf +++ b/addons/dogtags/functions/fnc_checkDogtag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Checks unit dogtag. @@ -14,11 +15,29 @@ * * Public: No */ -#include "script_component.hpp" params ["_player", "_target"]; +// animation +_player call EFUNC(common,goKneeling); + +// sound +private _position = AGLToASL (_target modelToWorld (_target selectionPosition "neck")); + +playSound3D [ + selectRandom RUSTLING_SOUNDS, + objNull, + false, + _position, + 1, + 1, + 50 +]; + +// display dogtag private _doubleTags = (_target getVariable [QGVAR(dogtagTaken), objNull]) != _target; private _dogTagData = [_target] call FUNC(getDogTagData); -[QGVAR(showDogtag), [_dogTagData, _doubleTags]] call CBA_fnc_localEvent; +[{ + [QGVAR(showDogtag), _this] call CBA_fnc_localEvent; +}, [_dogTagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_checkDogtagItem.sqf b/addons/dogtags/functions/fnc_checkDogtagItem.sqf index 237c4cf4b1..8ce7864774 100644 --- a/addons/dogtags/functions/fnc_checkDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_checkDogtagItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Check dogtag self menu action. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_player", "_target", "_item"]; diff --git a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf new file mode 100644 index 0000000000..c299af3a7d --- /dev/null +++ b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf @@ -0,0 +1,20 @@ +#include "script_component.hpp" +/* + * Author: commy2 + * Disable this faction from using dogtags. + * + * Arguments: + * 0: Faction + * + * Return Value: + * None + * + * Example: + * "CIV_F" call ace_dogtags_fnc_disableFactionDogtags + * + * Public: Yes + */ + +params [["_faction", "", [""]]]; + +GVAR(disabledFactions) setVariable [_faction, true]; diff --git a/addons/dogtags/functions/fnc_getDogtagData.sqf b/addons/dogtags/functions/fnc_getDogtagData.sqf index 607426fda4..d566daf64b 100644 --- a/addons/dogtags/functions/fnc_getDogtagData.sqf +++ b/addons/dogtags/functions/fnc_getDogtagData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Get unit dogtag data. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target"]; diff --git a/addons/dogtags/functions/fnc_getDogtagItem.sqf b/addons/dogtags/functions/fnc_getDogtagItem.sqf index 9c21ce0c54..22a0561937 100644 --- a/addons/dogtags/functions/fnc_getDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_getDogtagItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Server: creates new dogtag item and send it to client. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" if(!isServer) exitWith {}; @@ -26,7 +26,7 @@ private _allDogtagDatas = missionNamespace getVariable [QGVAR(allDogtagDatas), [ private _nextID = count _allDogtags + 1; -if (_nextID > 999) exitWith {ACE_LOGERROR("Ran out of IDs");}; +if (_nextID > 999) exitWith {ERROR("Ran out of IDs");}; private _dogTagData = [_target] call FUNC(getDogTagData); private _item = format ["ACE_dogtag_%1", _nextID]; diff --git a/addons/dogtags/functions/fnc_sendDogtagData.sqf b/addons/dogtags/functions/fnc_sendDogtagData.sqf index 34665fdfee..c43cf04dab 100644 --- a/addons/dogtags/functions/fnc_sendDogtagData.sqf +++ b/addons/dogtags/functions/fnc_sendDogtagData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Server: returns to client data on given dogtag. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" if (!isServer) exitWith {}; diff --git a/addons/dogtags/functions/fnc_showDogtag.sqf b/addons/dogtags/functions/fnc_showDogtag.sqf index aac4557f64..8e7bec620c 100644 --- a/addons/dogtags/functions/fnc_showDogtag.sqf +++ b/addons/dogtags/functions/fnc_showDogtag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Shows dogtag. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; diff --git a/addons/dogtags/functions/fnc_ssn.sqf b/addons/dogtags/functions/fnc_ssn.sqf index 330d4c00d2..3da972ecd8 100644 --- a/addons/dogtags/functions/fnc_ssn.sqf +++ b/addons/dogtags/functions/fnc_ssn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Reports a social security number generated from the units name. @@ -13,12 +14,13 @@ * * Public: No */ -#include "script_component.hpp" 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/functions/fnc_takeDogtag.sqf b/addons/dogtags/functions/fnc_takeDogtag.sqf index 0b779c029b..464f282334 100644 --- a/addons/dogtags/functions/fnc_takeDogtag.sqf +++ b/addons/dogtags/functions/fnc_takeDogtag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * If dogtag is not already taken triggers event on server. @@ -15,12 +16,30 @@ * * Public: No */ -#include "script_component.hpp" params ["_player", "_target"]; +// animation +_player call EFUNC(common,goKneeling); + +// sound +private _position = AGLToASL (_target modelToWorld (_target selectionPosition "neck")); + +playSound3D [ + selectRandom RUSTLING_SOUNDS, + objNull, + false, + _position, + 1, + 1, + 50 +]; + +// display message if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { - [localize LSTRING(dogtagAlreadyTaken)] call EFUNC(common,displayText); + [{ + [_this, 2.5] call EFUNC(common,displayTextStructured); + }, localize LSTRING(dogtagAlreadyTaken), DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; } else { _target setVariable [QGVAR(dogtagTaken), _target, true]; [QGVAR(getDogtagItem), [_player, _target]] call CBA_fnc_serverEvent; diff --git a/addons/dogtags/script_component.hpp b/addons/dogtags/script_component.hpp index c5912f2d2c..67e70b9dd2 100644 --- a/addons/dogtags/script_component.hpp +++ b/addons/dogtags/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_DOGTAGS @@ -16,3 +15,14 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#include "\a3\ui_f\hpp\defineCommonGrids.inc" + +#define DOGTAG_SHOW_DELAY 1 + +#define RUSTLING_SOUNDS [\ + "a3\sounds_f\characters\ingame\AinvPknlMstpSlayWpstDnon_medic.wss",\ + "a3\sounds_f\characters\ingame\AinvPknlMstpSlayWrflDnon_medic.wss",\ + "a3\sounds_f\characters\ingame\AinvPpneMstpSlayWpstDnon_medic.wss",\ + "a3\sounds_f\characters\ingame\AinvPpneMstpSlayWrflDnon_medic.wss"\ +] diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index 328baf53b6..e0ef31163a 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -6,36 +6,84 @@ Nieśmiertelnik Жетон Identifikační známka + ドッグ タグ + Hundemarke + 군번줄 + Plaque d'identification + Piastrina + 兵籍牌 + 兵籍牌 Check Dog Tag Sprawdź nieśmiertelnik Проверить жетон Zkontrolovat známku + ドッグ タグを見る + Hundemarke prüfen + 군번줄 확인 + Vérifier les plaques d'identification + Controlla Piastrina + 檢查兵籍牌 + 检查兵籍牌 Check Sprawdź Проверить Zkontroluj + 見る + Prüfen + 확인 + Vérifier + Controlla + 檢查 + 检查 Take Zabierz Взять Vezmi + 取る + Nehmen + 회수 + Prendre + Prendi + 拿取 + 拿取 Dogtag taken from %1... Zabrałeś nieśmiertelnik %1... Жетон снят с %1... Sebral jsem známku od %1... + %1からドッグ タグを取っています・・・ + Hundemarke von %1 genommen ... + %1로부터 군번줄을 회수했습니다... + Plaque d'identification pris sur %1... + Piastrina presa da %1... + 從%1身上拿取兵籍牌... + 从%1身上拿取兵籍牌... Somebody else has already taken the dogtag... 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... + Qualcun altro ha già preso la piastrina... + 已經有人把他的兵籍牌拿走了... + 已经有人把他的兵籍牌拿走了... + + + Onscreen display for checking dogtags + 在畫面中顯示檢查兵籍牌 + 確認中のドッグタグを画面上で表示します + Display su schermo per il controllo delle piastrine - \ No newline at end of file + diff --git a/addons/dogtags/ui/igui_preview.paa b/addons/dogtags/ui/igui_preview.paa new file mode 100644 index 0000000000..2ea65eb129 Binary files /dev/null and b/addons/dogtags/ui/igui_preview.paa differ diff --git a/addons/dragging/CfgEventHandlers.hpp b/addons/dragging/CfgEventHandlers.hpp index 6b8f0004b9..424c2a3fed 100644 --- a/addons/dragging/CfgEventHandlers.hpp +++ b/addons/dragging/CfgEventHandlers.hpp @@ -38,6 +38,11 @@ class Extended_Init_EventHandlers { init = QUOTE(_this call DFUNC(initObject)); }; }; + class Land_Camping_Light_F { + class ADDON { + init = QUOTE(_this call DFUNC(initObject)); + }; + }; }; class Extended_Killed_EventHandlers { diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index c8e3c7284a..9d5389efd8 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -30,6 +30,45 @@ class CfgVehicles { GVAR(dragDirection) = 0; }; + // Big 1.70 and 1.84 Autonomous AA Turrets + class StaticMGWeapon; + class AAA_System_01_base_F: StaticMGWeapon { // Praetorian 1C (aka Phalanx CIWS) + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class SAM_System_01_base_F: StaticMGWeapon { // Mk49 Spartan + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class SAM_System_02_base_F: StaticMGWeapon { // Mk21 Centurion + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class SAM_System_03_base_F: StaticMGWeapon { // MIM-145 Defender + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class SAM_System_04_base_F: StaticMGWeapon { // S-750 Rhea + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class B_Ship_Gun_01_base_F: StaticMGWeapon { // Mk45 Hammer + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class B_Ship_MRLS_01_base_F: StaticMGWeapon { // Mk41 VLS + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class Radar_System_01_base_F: StaticMGWeapon { // AN/MPQ-105 Radar + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + class Radar_System_02_base_F: StaticMGWeapon { // R-750 Cronus Radar + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; + // ammo boxes class ThingX; class Items_base_F; @@ -52,6 +91,10 @@ class CfgVehicles { GVAR(canCarry) = 0; GVAR(canDrag) = 0; }; + class Pod_Heli_Transport_04_crewed_base_F: StaticWeapon { + GVAR(canCarry) = 0; + GVAR(canDrag) = 0; + }; class EAST_Box_Base: ReammoBox_F { GVAR(canCarry) = 1; @@ -188,7 +231,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 { @@ -213,4 +273,24 @@ class CfgVehicles { GVAR(dragPosition)[] = {0,1.2,0}; GVAR(dragDirection) = 180; }; + class FloatingStructure_F; + class Land_Camping_Light_F: FloatingStructure_F { + GVAR(canCarry) = 1; + // if y < 0.9 player gets damage + GVAR(carryPosition)[] = {0,0.9,1}; + GVAR(carryDirection) = 0; + + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,0.7,0}; + GVAR(dragDirection) = 0; + }; + class Land_Camping_Light_off_F: ThingX { + GVAR(canCarry) = 1; + GVAR(carryPosition)[] = {0,0.9,1}; + GVAR(carryDirection) = 0; + + GVAR(canDrag) = 1; + GVAR(dragPosition)[] = {0,0.7,0}; + GVAR(dragDirection) = 0; + }; }; diff --git a/addons/dragging/XEH_preInit.sqf b/addons/dragging/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/dragging/XEH_preInit.sqf +++ b/addons/dragging/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/dragging/functions/fnc_canCarry.sqf b/addons/dragging/functions/fnc_canCarry.sqf index 381940a9df..4e09cedbdc 100644 --- a/addons/dragging/functions/fnc_canCarry.sqf +++ b/addons/dragging/functions/fnc_canCarry.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if unit can carry the object. Doesn't check weight. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index b45a7d1d14..81a8537586 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if unit can drag the object. Doesn't check weight. @@ -14,11 +15,10 @@ * * Public: No */ -#include "script_component.hpp" 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..2d42ae6244 100644 --- a/addons/dragging/functions/fnc_canDrop.sqf +++ b/addons/dragging/functions/fnc_canDrop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if unit can drop the object. @@ -14,10 +15,9 @@ * * Public: No */ -#include "script_component.hpp" 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_canDrop_carry.sqf b/addons/dragging/functions/fnc_canDrop_carry.sqf index 3d3732f62d..89be866ea6 100644 --- a/addons/dragging/functions/fnc_canDrop_carry.sqf +++ b/addons/dragging/functions/fnc_canDrop_carry.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if unit can drop the carried object. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/dragging/functions/fnc_carryObject.sqf b/addons/dragging/functions/fnc_carryObject.sqf index 985f3ddab6..f7976079b3 100644 --- a/addons/dragging/functions/fnc_carryObject.sqf +++ b/addons/dragging/functions/fnc_carryObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Carry an object. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; TRACE_2("params",_unit,_target); diff --git a/addons/dragging/functions/fnc_carryObjectPFH.sqf b/addons/dragging/functions/fnc_carryObjectPFH.sqf index 963921efa7..6361dcc66d 100644 --- a/addons/dragging/functions/fnc_carryObjectPFH.sqf +++ b/addons/dragging/functions/fnc_carryObjectPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * PFH for Carry Object @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" #ifdef DEBUG_ENABLED_DRAGGING systemChat format ["%1 carryObjectPFH running", CBA_missionTime]; diff --git a/addons/dragging/functions/fnc_dragObject.sqf b/addons/dragging/functions/fnc_dragObject.sqf index 77b4fc703b..347eb857db 100644 --- a/addons/dragging/functions/fnc_dragObject.sqf +++ b/addons/dragging/functions/fnc_dragObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Drag an object. Called from ace_dragging_fnc_startDrag @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; TRACE_2("params",_unit,_target); diff --git a/addons/dragging/functions/fnc_dragObjectPFH.sqf b/addons/dragging/functions/fnc_dragObjectPFH.sqf index 08aeba738b..dd18e0c825 100644 --- a/addons/dragging/functions/fnc_dragObjectPFH.sqf +++ b/addons/dragging/functions/fnc_dragObjectPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * PFH for Drag Object @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" #ifdef DEBUG_ENABLED_DRAGGING systemChat format ["%1 dragObjectPFH running", CBA_missionTime]; diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index f060c8d088..fde2a7f6d7 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Drop a dragged object. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; TRACE_2("params",_unit,_target); @@ -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..ae7bd3598e 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Drop a carried object. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; TRACE_2("params",_unit,_target); @@ -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..cd06b8a884 100644 --- a/addons/dragging/functions/fnc_getWeight.sqf +++ b/addons/dragging/functions/fnc_getWeight.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: L-H, edited by commy2, rewritten by joko // Jonas * Returns the weight of a crate. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_object"]; @@ -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 935a6d3652..7fa242ae16 100644 --- a/addons/dragging/functions/fnc_handleAnimChanged.sqf +++ b/addons/dragging/functions/fnc_handleAnimChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle the animaion for a Unit for Dragging Module @@ -14,7 +15,8 @@ * * Public: No */ -#include "script_component.hpp" + +//IGNORE_PRIVATE_WARNING ["_thisArgs", "_thisID"]; // From CBA_fnc_addBISEventHandler; params ["_unit", "_anim"]; _thisArgs params ["_realUnit"]; @@ -28,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_handleKilled.sqf b/addons/dragging/functions/fnc_handleKilled.sqf index 36bda60b78..672869d3c9 100644 --- a/addons/dragging/functions/fnc_handleKilled.sqf +++ b/addons/dragging/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle death of the dragger @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); diff --git a/addons/dragging/functions/fnc_handlePlayerChanged.sqf b/addons/dragging/functions/fnc_handlePlayerChanged.sqf index a0d9e63449..a404660106 100644 --- a/addons/dragging/functions/fnc_handlePlayerChanged.sqf +++ b/addons/dragging/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle player changes. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_newPlayer", "_oldPlayer"]; TRACE_2("params",_newPlayer,_oldPlayer); diff --git a/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf b/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf index a8df6b5b7d..7d07583ddf 100644 --- a/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf +++ b/addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle the Weapon Changed Event @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon"]; TRACE_2("params",_unit,_weapon); diff --git a/addons/dragging/functions/fnc_handleScrollWheel.sqf b/addons/dragging/functions/fnc_handleScrollWheel.sqf index e3a30ea9e0..9c444add21 100644 --- a/addons/dragging/functions/fnc_handleScrollWheel.sqf +++ b/addons/dragging/functions/fnc_handleScrollWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: L-H, commy2 * Handles raising and lowering the dragged weapon to be able to place it on top of objects. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_scrollAmount"]; @@ -30,15 +30,19 @@ 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]; // move up/down object and reattach at current position detach _carriedItem; -_carriedItem setPosATL _position; -_carriedItem attachTo [_unit]; + +// Uses this method of selecting position because setPosATL did not have immediate effect +private _positionChange = _position vectorDiff (getPosASL _carriedItem); +private _selectionPosition = _unit worldToModel (ASLtoAGL getPosWorld _carriedItem); +_selectionPosition = _selectionPosition vectorAdd _positionChange; +_carriedItem attachTo [_unit, _selectionPosition]; //reset the carry direction private _direction = _carriedItem getVariable [QGVAR(carryDirection), 0]; diff --git a/addons/dragging/functions/fnc_handleUnconscious.sqf b/addons/dragging/functions/fnc_handleUnconscious.sqf index 2e891b01c6..ba399aee49 100644 --- a/addons/dragging/functions/fnc_handleUnconscious.sqf +++ b/addons/dragging/functions/fnc_handleUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle the Unconscious of a Unit while Dragging @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/dragging/functions/fnc_initObject.sqf b/addons/dragging/functions/fnc_initObject.sqf index d36ffe9339..8e352a00bb 100644 --- a/addons/dragging/functions/fnc_initObject.sqf +++ b/addons/dragging/functions/fnc_initObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Initialize variables for drag or carryable objects. Called from init EH. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_object"]; diff --git a/addons/dragging/functions/fnc_initPerson.sqf b/addons/dragging/functions/fnc_initPerson.sqf index c8c26a4f8c..c9365710dd 100644 --- a/addons/dragging/functions/fnc_initPerson.sqf +++ b/addons/dragging/functions/fnc_initPerson.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Initialize variables for drag or carryable persons. Called from init EH. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/dragging/functions/fnc_isObjectOnObject.sqf b/addons/dragging/functions/fnc_isObjectOnObject.sqf index cec6ce764e..00c2823e4a 100644 --- a/addons/dragging/functions/fnc_isObjectOnObject.sqf +++ b/addons/dragging/functions/fnc_isObjectOnObject.sqf @@ -6,9 +6,9 @@ * 0: Object * * Return Value: - * + * Boolean * - * Example; + * Example: * [player] call ace_dragging_fnc_isObjectOnObject * * Public: No diff --git a/addons/dragging/functions/fnc_setCarryable.sqf b/addons/dragging/functions/fnc_setCarryable.sqf index 4de52e7bd8..12e2b74a8c 100644 --- a/addons/dragging/functions/fnc_setCarryable.sqf +++ b/addons/dragging/functions/fnc_setCarryable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Enable the object to be carried. @@ -16,7 +17,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_object", "_enableCarry", "_position", "_direction"]; diff --git a/addons/dragging/functions/fnc_setDraggable.sqf b/addons/dragging/functions/fnc_setDraggable.sqf index 1fbcb995dc..36f42dd9f6 100644 --- a/addons/dragging/functions/fnc_setDraggable.sqf +++ b/addons/dragging/functions/fnc_setDraggable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Enable the object to be dragged. @@ -5,8 +6,8 @@ * Arguments: * 0: Any object * 1: true to enable dragging, false to disable - * 2: Position offset for attachTo command (Array, optinal; default: [0,0,0]) - * 3: Direction in degree to rotate the object after attachTo (Number, optional; default: 0) + * 2: Position offset for attachTo command (optinal; default: [0,0,0]) + * 3: Direction in degree to rotate the object after attachTo (optional; default: 0) * * Return Value: * None @@ -16,9 +17,8 @@ * * Public: Yes */ -#include "script_component.hpp" -//IGNORE_PRIVATE_WARNING("_player", "_target"); +//IGNORE_PRIVATE_WARNING ["_player", "_target"]; params ["_object", "_enableDrag", "_position", "_direction"]; if (isNil "_position") then { diff --git a/addons/dragging/functions/fnc_startCarry.sqf b/addons/dragging/functions/fnc_startCarry.sqf index 1890dbac1a..5d7bc86815 100644 --- a/addons/dragging/functions/fnc_startCarry.sqf +++ b/addons/dragging/functions/fnc_startCarry.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Start the carrying process. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; TRACE_2("params",_unit,_target); @@ -51,13 +51,15 @@ if (_target isKindOf "CAManBase") then { } else { // select no weapon and stop sprinting - _unit action ["SwitchWeapon", _unit, _unit, 99]; + _unit action ["SwitchWeapon", _unit, _unit, 299]; [_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation); [_unit, "forceWalk", "ACE_dragging", true] call EFUNC(common,statusEffect_set); }; +[_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_startCarryPFH.sqf b/addons/dragging/functions/fnc_startCarryPFH.sqf index 007469d960..89f9f232ed 100644 --- a/addons/dragging/functions/fnc_startCarryPFH.sqf +++ b/addons/dragging/functions/fnc_startCarryPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Carry PFH @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" #ifdef DEBUG_ENABLED_DRAGGING systemChat format ["%1 startCarryPFH running", CBA_missionTime]; diff --git a/addons/dragging/functions/fnc_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index cf08074d94..b926a972ce 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Start the dragging process. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; TRACE_2("params",_unit,_target); @@ -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..614b6a8741 100644 --- a/addons/dragging/functions/fnc_startDragPFH.sqf +++ b/addons/dragging/functions/fnc_startDragPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Drag PFH @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" #ifdef DEBUG_ENABLED_DRAGGING systemChat format ["%1 startDragPFH running", CBA_missionTime]; @@ -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 13915637ab..01b466972f 100644 --- a/addons/dragging/script_component.hpp +++ b/addons/dragging/script_component.hpp @@ -2,10 +2,9 @@ #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 CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_DRAGGING diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index 94757299cc..95a17c60b0 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Arrastar Trascina Húzás + 引きずる + 끌기 + 拖拉 + 拖拉 Release @@ -24,6 +28,10 @@ Soltar Lascia Elengedés + はなす + 놓기 + 放開 + 放开 Drag/Release Object @@ -36,6 +44,10 @@ Arrastar/Soltar Objeto Trascina/Lascia Oggetto Húzás/Elengedés Objektum + オブジェクトを引きずる/はなす + 물건 끌기/놓기 + 拖拉/放開物品 + 拖拉/放开物品 Item too heavy @@ -48,6 +60,10 @@ Предмет слишком тяжёлый Předmět je moc těžký Az objektum túl nehéz + アイテムが重すぎます + 물체가 너무 무겁습니다 + 此物品過重 + 此物品过重 Carry @@ -60,6 +76,10 @@ Felvevés Trasporta Нести + 運ぶ + 업기 + 背起 + 背起 Raise/Lower @@ -71,6 +91,10 @@ Alza/Abbassa Subir/Bajar Lever/Baisser + 上げる/下げる + 높이기/낮추기 + 提高/下降 + 提高/下降 diff --git a/addons/explosives/ACE_Arsenal_Stats.hpp b/addons/explosives/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..cde27f3bde --- /dev/null +++ b/addons/explosives/ACE_Arsenal_Stats.hpp @@ -0,0 +1,13 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_explosiveRange: statBase { + scope = 2; + priority = 1; + stats[] = {QGVAR(Range)}; + displayName = CSTRING(statExploRange); + showText = 1; + textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _exploRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)', _exploRangeStat, (_exploRangeStat / 0.3048) toFixed 1)]); + condition = QUOTE(params [ARR_2('', '_config')]; (getNumber (_config >> QQGVAR(Detonator))) > 0); + tabs[] = {{}, {7}}; + }; +}; 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..e9c717504e 100644 --- a/addons/explosives/ACE_Triggers.hpp +++ b/addons/explosives/ACE_Triggers.hpp @@ -1,13 +1,19 @@ class ACE_Triggers { - /* onPlace parameters: -0: OBJECT - unit placing -1: OBJECT - Placed explosive -2: STRING - Magazine classname -3: ARRAY - vars -Last Index: ACE_Triggers config of trigger type. -onSetup parameters: -0: STRING - Magazine Classname - */ + /* onPlace Parameters: + * 0: Unit placing + * 1: Explosive + * 2: Magazine classname + * 3: Additional arguments + * - Same as those passed to FUNC(placeExplosive) for specific trigger type + * - Last element is ACE_Triggers config of the trigger type + * + * onSetup Parameters: + * 0: Explosive + * 1: Magazine classname + * + * For both, expected return type is BOOL. + * True indicates manual handling of explosive setup/placement. + */ class Command { isAttachable = 1; displayName = CSTRING(clacker_displayName); @@ -44,19 +50,19 @@ onSetup parameters: isAttachable = 0; displayName = CSTRING(IRSensor); picture = QPATHTOF(Data\UI\PressurePlate.paa); - onPlace = "false"; + onPlace = QUOTE(false); }; class Timer { isAttachable = 1; displayName = CSTRING(timerName); picture = QPATHTOF(data\UI\Timer.paa); - onPlace = QUOTE([ARR_2(_this select 1,(_this select 3) select 0)] call FUNC(startTimer);false); - onSetup = QUOTE(_this call FUNC(openTimerSetUI);true); + onPlace = QUOTE([ARR_2(_this select 1, _this select 3 select 0)] call FUNC(startTimer); false); + onSetup = QUOTE(_this call FUNC(openTimerUI)); }; class Tripwire { 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 05780b706a..c79030d2ab 100644 --- a/addons/explosives/CfgAmmo.hpp +++ b/addons/explosives/CfgAmmo.hpp @@ -15,10 +15,6 @@ class CfgAmmo { class APERSMine_Range_Ammo: MineBase; class ATMine_Range_Ammo: MineBase; - class UnderwaterMine_Range_Ammo: MineBase; - class UnderwaterMineAB_Range_Ammo: UnderwaterMine_Range_Ammo; - class UnderwaterMinePDM_Range_Ammo: UnderwaterMine_Range_Ammo; - class DirectionalBombCore: TimeBombCore; class DirectionalBombBase: DirectionalBombCore; @@ -27,10 +23,13 @@ class CfgAmmo { class PipeBombCore: TimeBombCore; class PipeBombBase: PipeBombCore; */ + // GVAR(size) = 0; is small size + // GVAR(size) = 1; is large size class DirectionalBombBase; class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { GVAR(magazine) = "ClaymoreDirectionalMine_Remote_Mag"; GVAR(Explosive) = "ClaymoreDirectionalMine_Remote_Ammo_Scripted"; + GVAR(size) = 0; GVAR(defuseObjectPosition)[] = {0, 0, 0.038}; soundActivation[] = {"", 0, 0, 0}; soundDeactivation[] = {"", 0, 0, 0}; @@ -39,6 +38,7 @@ class CfgAmmo { class APERSTripMine_Wire_Ammo: DirectionalBombBase { GVAR(defuseObjectPosition)[] = {-1.415, 0, 0.12}; + GVAR(size) = 0; }; class ACE_FlareTripMine_Wire_Ammo: APERSTripMine_Wire_Ammo { @@ -58,16 +58,18 @@ class CfgAmmo { distance = 0; }; }; - + class F_20mm_Red; class ACE_TripFlare_FlareEffect: F_20mm_Red { triggerTime = 0.1; + GVAR(size) = 0; }; class SLAMDirectionalMine_Wire_Ammo: DirectionalBombBase { indirectHitRange = 20; GVAR(explodeOnDefuseChance) = 1; GVAR(magazine) = "SLAMDirectionalMine_Wire_Mag"; + GVAR(size) = 0; }; class ACE_SLAMDirectionalMine_Command_Ammo: SLAMDirectionalMine_Wire_Ammo { mineTrigger = "RemoteTrigger"; @@ -88,7 +90,8 @@ 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}; soundDeactivation[] = {"", 0, 0, 0}; @@ -98,7 +101,8 @@ 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}; soundDeactivation[] = {"", 0, 0, 0}; @@ -110,6 +114,7 @@ class CfgAmmo { triggerWhenDestroyed = 1; GVAR(explodeOnDefuseChance) = 0.02; GVAR(magazine) = "IEDUrbanBig_Remote_Mag"; + GVAR(size) = 1; soundTrigger[] = {"A3\Sounds_F\weapons\mines\mech_trigger_1", 0.8, 1, 40}; }; class ACE_IEDUrbanBig_Command_Ammo: IEDUrbanBig_Remote_Ammo { @@ -123,6 +128,7 @@ class CfgAmmo { triggerWhenDestroyed = 1; GVAR(explodeOnDefuseChance) = 0.02; GVAR(magazine) = "IEDUrbanSmall_Remote_Mag"; + GVAR(size) = 0; soundTrigger[] = {"A3\Sounds_F\weapons\mines\mech_trigger_1", 0.8, 1, 40}; }; class ACE_IEDUrbanSmall_Command_Ammo: IEDUrbanSmall_Remote_Ammo { @@ -136,6 +142,7 @@ class CfgAmmo { triggerWhenDestroyed = 1; GVAR(explodeOnDefuseChance) = 0.02; GVAR(magazine) = "IEDLandBig_Remote_Mag"; + GVAR(size) = 1; soundTrigger[] = {"A3\Sounds_F\weapons\mines\mech_trigger_1", 0.8, 1, 40}; }; class ACE_IEDLandBig_Command_Ammo: IEDLandBig_Remote_Ammo { @@ -149,6 +156,7 @@ class CfgAmmo { triggerWhenDestroyed = 1; GVAR(explodeOnDefuseChance) = 0.02; GVAR(magazine) = "IEDLandSmall_Remote_Mag"; + GVAR(size) = 0; soundTrigger[] = {"A3\Sounds_F\weapons\mines\mech_trigger_1", 0.8, 1, 40}; }; class ACE_IEDLandSmall_Command_Ammo: IEDLandSmall_Remote_Ammo { @@ -157,4 +165,22 @@ 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}; + }; + class MineBase; + class UnderwaterMine_Range_Ammo: MineBase { + GVAR(size) = 1; + }; }; diff --git a/addons/explosives/CfgEventHandlers.hpp b/addons/explosives/CfgEventHandlers.hpp index ced23c6b56..d2137371ec 100644 --- a/addons/explosives/CfgEventHandlers.hpp +++ b/addons/explosives/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); @@ -24,7 +23,7 @@ class Extended_Killed_EventHandlers { class Extended_Take_EventHandlers { class CAManBase { - GVAR(takeHandler) = QUOTE([ARR_3(_this select 0, _this select 1, _this select 2)] call FUNC(onInventoryChanged)); + GVAR(takeHandler) = QUOTE(call FUNC(onInventoryChanged)); }; }; class Extended_Put_EventHandlers { @@ -38,3 +37,9 @@ class Extended_DisplayLoad_EventHandlers { ADDON = QUOTE(_this call COMPILE_FILE(XEH_missionDisplayLoad)); }; }; + +class Extended_Init_EventHandlers { + class ACE_Explosives_Place_SLAM { + ADDON = QUOTE(params ['_mine']; if (local _mine) then {_mine setCenterOfMass [ARR_3(0,-0.035,0.05)]; _mine setMass 5}); + }; +}; 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 f2b6ece8db..97562dc836 100644 --- a/addons/explosives/CfgVehicles.hpp +++ b/addons/explosives/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CBA_Extended_EventHandlers; class CfgVehicles { @@ -11,19 +10,15 @@ class CfgVehicles { statement = ""; exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; showDisabled = 1; - priority = 4; icon = QPATHTOF(UI\Explosives_Menu_ca.paa); insertChildren = QUOTE([_player] call FUNC(addTransmitterActions);); - //Sub-menu items class ACE_Place { displayName = CSTRING(Place); - condition = QUOTE((vehicle _player == _player) and {[_player] call FUNC(hasExplosives)}); statement = ""; - insertChildren = QUOTE([_player] call FUNC(addExplosiveActions);); + condition = "true"; exceptions[] = {"isNotSwimming"}; - showDisabled = 1; icon = QPATHTOF(UI\Place_Explosive_ca.paa); - priority = 1; + insertChildren = QUOTE(_player call FUNC(addExplosiveActions)); }; class ACE_Cellphone { displayName = CSTRING(cellphone_displayName); @@ -32,7 +27,6 @@ class CfgVehicles { exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; showDisabled = 0; icon = QPATHTOF(Data\UI\Cellphone_UI.paa); - priority = 0.8; }; }; }; @@ -60,11 +54,11 @@ class CfgVehicles { icon = QPATHTOF(UI\Defuse_ca.paa); }; }; - }; + }; class ACE_DefuseObject_Large: ACE_DefuseObject { class ACE_Actions: ACE_Actions { class ACE_Defuse: ACE_Defuse { - distance = 1.5; + distance = 2; }; }; }; @@ -95,7 +89,6 @@ class CfgVehicles { insertChildren = QUOTE([ARR_3(_target getVariable QUOTE(QGVAR(class)),_target,_player)] call FUNC(addTriggerActions);); showDisabled = 0; exceptions[] = {"isNotSwimming"}; - priority = 5; icon = QPATHTOF(UI\Explosives_Menu_ca.paa); }; class ACE_PickUp { @@ -105,7 +98,6 @@ class CfgVehicles { statement = QUOTE([ARR_2(_player,_target getVariable QUOTE(QGVAR(class)))] call EFUNC(common,addToInventory);deleteVehicle _target;); showDisabled = 0; exceptions[] = {"isNotSwimming"}; - priority = 5; icon = "\A3\ui_f\data\IGUI\Cfg\Actions\Obsolete\ui_action_takemine_ca.paa"; }; }; @@ -164,6 +156,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..56ef154661 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 { - allowedSlots[] = {801,701,901}; + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + class ACE_ExplosiveItem: CBA_MiscItem_ItemInfo { + allowedSlots[] = {TYPE_UNIFORM,TYPE_VEST,TYPE_BACKPACK}; //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..cd06abff5b 100644 --- a/addons/explosives/ExplosivesUI.hpp +++ b/addons/explosives/ExplosivesUI.hpp @@ -1,19 +1,4 @@ -#define GUI_GRID_X (0) -#define GUI_GRID_Y (0) -#define GUI_GRID_W (0.025) -#define GUI_GRID_H (0.04) - -#define ST_CENTER 0x02 -#define X_OFFSET 0.25 - -class RscText; -class RscButton; -class RscXSliderH; -class IGUIBack; -class RscPicture; -class RscEdit; - -class Rsc_ACE_CallScreen_Edit:RscEdit { +class Rsc_ACE_CallScreen_Edit: RscEdit { canModify = 1; colorBackground[] = {0,0,0,0}; colorText[] = {0,0,0,1}; @@ -32,7 +17,7 @@ class Rsc_ACE_CallScreen_Edit:RscEdit { w = 0.0825 * safezoneW; h = 0.044 * safezoneH; }; -class Rsc_ACE_HiddenButton:RscButton { +class Rsc_ACE_HiddenButton: RscButton { colorText[] = {0, 0, 0, 0}; colorDisabled[] = {0, 0, 0, 0}; colorBackground[] = {0, 0, 0, 0}; @@ -46,66 +31,7 @@ class Rsc_ACE_HiddenButton:RscButton { shadow = 0; }; -class Rsc_ACE_Timer_Slider:RscXSliderH { - x = 0.4; - y = 0.2; - w = 0.3; - h = "1*((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - colorBackground[] = {0,0,0,0.5}; -}; - -class RscACE_SelectTimeUI { - idd = 8854; - movingEnable = 0; - class controls { - class back:IGUIBack { - x = X_OFFSET; - y = 0; - w = 0.5; - h = 0.2; - colorBackground[] = {0, 0, 0, 0.5}; - }; - class header: RscText{ - idc = 8870; - x = X_OFFSET + 0.005; - y = 0.005; - w = 0.49; - h = 0.05; - style = ST_CENTER; - text = ""; - }; - class slider: Rsc_ACE_Timer_Slider { - idc = 8845; - x = X_OFFSET + 0.005; - 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]];"; - }; - class cancelBtn: RscButton { - idc = 8855; - x = X_OFFSET + 0.005; - w = 0.15; - h = 0.1; - y = 0.09; - style = ST_CENTER; - text = CSTRING(Cancel); - action = "closeDialog 0;"; - }; - class approveBtn: RscButton { - idc = 8860; - x = X_OFFSET + 0.345; - y = 0.09; - h = 0.1; - w = 0.15; - style = ST_CENTER; - text = CSTRING(SetTime); - action = "closeDialog 0;"; - }; - }; -}; - -class Rsc_ACE_NumKeyButton: Rsc_ACE_HiddenButton{}; +class Rsc_ACE_NumKeyButton: Rsc_ACE_HiddenButton {}; class Rsc_ACE_PhoneInterface { idd = 8855; movingEnable = 1; diff --git a/addons/explosives/TimerDialog.hpp b/addons/explosives/TimerDialog.hpp new file mode 100644 index 0000000000..a3ab96af06 --- /dev/null +++ b/addons/explosives/TimerDialog.hpp @@ -0,0 +1,97 @@ +class GVAR(timerUI) { + idd = -1; + movingEnable = 1; + enableSimulation = 1; + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(timerDisplay), _this select 0)]); + class controlsBackground { + class Header: RscText { + idc = -1; + text = CSTRING(ExplosiveTimer); + x = 13.5 * GUI_GRID_W + GUI_GRID_CENTER_X; + y = 5 * GUI_GRID_H + GUI_GRID_CENTER_Y; + w = 13 * GUI_GRID_W; + h = GUI_GRID_H; + colorBackground[] = GUI_BCG_COLOR; + moving = 1; + }; + class Background: RscText { + idd = -1; + x = 13.5 * GUI_GRID_W + GUI_GRID_CENTER_X; + y = 6.1 * GUI_GRID_H + GUI_GRID_CENTER_Y; + w = 13 * GUI_GRID_W; + h = 6.5 * GUI_GRID_H; + colorBackground[] = {0, 0, 0, 0.8}; + }; + }; + class controls { + class DigitBackground_1: RscPicture { + idc = -1; + text = QPATHTOF(UI\seven_segment_8.paa); + x = 14 * GUI_GRID_W + GUI_GRID_CENTER_X; + y = 6.6 * GUI_GRID_H + GUI_GRID_CENTER_Y; + w = 4 * GUI_GRID_W; + h = 4 * GUI_GRID_H; + colorText[] = {0.3, 0.3, 0.3, 0.5}; + }; + class DigitBackground_2: DigitBackground_1 { + x = 16.4 * GUI_GRID_W + GUI_GRID_CENTER_X; + }; + class DigitBackground_3: DigitBackground_1 { + x = 19.7 * GUI_GRID_W + GUI_GRID_CENTER_X; + }; + class DigitBackground_4: DigitBackground_1 { + x = 22.1 * GUI_GRID_W + GUI_GRID_CENTER_X; + }; + class DigitSeparator: DigitBackground_1 { + text = QPATHTOF(UI\seven_segment_separator.paa); + x = 18.025 * GUI_GRID_W + GUI_GRID_CENTER_X; + colorText[] = {1, 0.05, 0.05, 1}; + }; + class Digit_1: DigitBackground_1 { + idc = IDC_TIMER_DIGIT_1; + text = QPATHTOF(UI\seven_segment_0.paa); + colorText[] = {1, 0.05, 0.05, 1}; + }; + class Digit_2: Digit_1 { + idc = IDC_TIMER_DIGIT_2; + x = 16.4 * GUI_GRID_W + GUI_GRID_CENTER_X; + }; + class Digit_3: Digit_1 { + idc = IDC_TIMER_DIGIT_3; + x = 19.7 * GUI_GRID_W + GUI_GRID_CENTER_X; + }; + class Digit_4: Digit_1 { + idc = IDC_TIMER_DIGIT_4; + x = 22.1 * GUI_GRID_W + GUI_GRID_CENTER_X; + }; + class Slider: ctrlXSliderH { + idc = IDC_TIMER_SLIDER; + x = 14 * GUI_GRID_W + GUI_GRID_CENTER_X; + y = 11.1 * GUI_GRID_H + GUI_GRID_CENTER_Y; + w = 12 * GUI_GRID_W; + h = GUI_GRID_H; + color[] = {0.3, 0.3, 0.3, 0.7}; + colorActive[] = {0.3, 0.3, 0.3, 0.7}; + sliderRange[] = {TIMER_VALUE_MIN, TIMER_VALUE_MAX}; + sliderPosition = TIMER_VALUE_DEFAULT; + }; + class CancelButton: RscButton { + idc = -1; + text = CSTRING(Cancel); + onButtonClick = QUOTE(closeDialog 0); + x = 13.5 * GUI_GRID_W + GUI_GRID_CENTER_X; + y = 12.7 * GUI_GRID_H + GUI_GRID_CENTER_Y; + w = 5 * GUI_GRID_W; + h = GUI_GRID_H; + colorActive[] = {0, 0, 0, 1}; + colorBackground[] = {0, 0, 0, 0.8}; + colorFocused[] = {0, 0, 0, 0.8}; + }; + class ConfirmButton: CancelButton { + idc = IDC_TIMER_CONFIRM; + text = CSTRING(SetTime); + onButtonClick = ""; + x = 21.5 * GUI_GRID_W + GUI_GRID_CENTER_X; + }; + }; +}; diff --git a/addons/explosives/UI/seven_segment_0.paa b/addons/explosives/UI/seven_segment_0.paa new file mode 100644 index 0000000000..39c56516b0 Binary files /dev/null and b/addons/explosives/UI/seven_segment_0.paa differ diff --git a/addons/explosives/UI/seven_segment_1.paa b/addons/explosives/UI/seven_segment_1.paa new file mode 100644 index 0000000000..d88e20c28b Binary files /dev/null and b/addons/explosives/UI/seven_segment_1.paa differ diff --git a/addons/explosives/UI/seven_segment_2.paa b/addons/explosives/UI/seven_segment_2.paa new file mode 100644 index 0000000000..dd1e6bd383 Binary files /dev/null and b/addons/explosives/UI/seven_segment_2.paa differ diff --git a/addons/explosives/UI/seven_segment_3.paa b/addons/explosives/UI/seven_segment_3.paa new file mode 100644 index 0000000000..71da8743c0 Binary files /dev/null and b/addons/explosives/UI/seven_segment_3.paa differ diff --git a/addons/explosives/UI/seven_segment_4.paa b/addons/explosives/UI/seven_segment_4.paa new file mode 100644 index 0000000000..3a054e3c48 Binary files /dev/null and b/addons/explosives/UI/seven_segment_4.paa differ diff --git a/addons/explosives/UI/seven_segment_5.paa b/addons/explosives/UI/seven_segment_5.paa new file mode 100644 index 0000000000..7622645c24 Binary files /dev/null and b/addons/explosives/UI/seven_segment_5.paa differ diff --git a/addons/explosives/UI/seven_segment_6.paa b/addons/explosives/UI/seven_segment_6.paa new file mode 100644 index 0000000000..d805a028d5 Binary files /dev/null and b/addons/explosives/UI/seven_segment_6.paa differ diff --git a/addons/explosives/UI/seven_segment_7.paa b/addons/explosives/UI/seven_segment_7.paa new file mode 100644 index 0000000000..f9070da7a7 Binary files /dev/null and b/addons/explosives/UI/seven_segment_7.paa differ diff --git a/addons/explosives/UI/seven_segment_8.paa b/addons/explosives/UI/seven_segment_8.paa new file mode 100644 index 0000000000..f09be85074 Binary files /dev/null and b/addons/explosives/UI/seven_segment_8.paa differ diff --git a/addons/explosives/UI/seven_segment_9.paa b/addons/explosives/UI/seven_segment_9.paa new file mode 100644 index 0000000000..9139d4ea17 Binary files /dev/null and b/addons/explosives/UI/seven_segment_9.paa differ diff --git a/addons/explosives/UI/seven_segment_separator.paa b/addons/explosives/UI/seven_segment_separator.paa new file mode 100644 index 0000000000..aa5bb0a159 Binary files /dev/null and b/addons/explosives/UI/seven_segment_separator.paa differ diff --git a/addons/explosives/XEH_PREP.hpp b/addons/explosives/XEH_PREP.hpp index b43953d8fd..c04e0d3133 100644 --- a/addons/explosives/XEH_PREP.hpp +++ b/addons/explosives/XEH_PREP.hpp @@ -1,7 +1,7 @@ - PREP(addCellphoneIED); PREP(addClacker); PREP(addDetonateActions); +PREP(addDetonateHandler); PREP(addExplosiveActions); PREP(addToSpeedDial); PREP(addTransmitterActions); @@ -15,28 +15,19 @@ PREP(detonateExplosive); PREP(detonateExplosiveAll); PREP(dialPhone); PREP(dialingPhone); - PREP(handleScrollWheel); - PREP(hasExplosives); PREP(hasPlacedExplosives); - PREP(interactEH); - PREP(getDetonators); PREP(getPlacedExplosives); PREP(getSpeedDialExplosive); - PREP(module); - PREP(onIncapacitated); PREP(onInventoryChanged); - -PREP(openTimerSetUI); - +PREP(openTimerUI); PREP(placeExplosive); PREP(removeFromSpeedDial); - PREP(scriptedExplosive); PREP(selectTrigger); PREP(setupExplosive); diff --git a/addons/explosives/XEH_postInit.sqf b/addons/explosives/XEH_postInit.sqf index 1ddd52cc53..76d3e44bd1 100644 --- a/addons/explosives/XEH_postInit.sqf +++ b/addons/explosives/XEH_postInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Initialises the player object for the explosive system. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" //Event for setting explosive placement angle/pitch: [QGVAR(place), {_this call FUNC(setPosition)}] call CBA_fnc_addEventHandler; @@ -22,24 +22,25 @@ //When getting knocked out in medical, trigger deadman explosives: //Event is global, only run on server (ref: ace_medical_fnc_setUnconscious) if (isServer) then { + [QGVAR(detonate), { + params ["_unit", "_explosive", "_delay"]; + TRACE_3("server detonate EH",_unit,_explosive,_delay); + _explosive setShotParents [_unit, _unit]; + [{ + params ["_explosive"]; + TRACE_1("exploding",_explosive); + if (!isNull _explosive) then { + _explosive setDamage 1; + }; + }, _explosive, _delay] call CBA_fnc_waitAndExecute; + }] call CBA_fnc_addEventHandler; + ["ace_unconscious", { params ["_unit", "_isUnconscious"]; if (!_isUnconscious) exitWith {}; 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 {}; @@ -49,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 16a9a4124b..d9a8d39ff4 100644 --- a/addons/explosives/XEH_preInit.sqf +++ b/addons/explosives/XEH_preInit.sqf @@ -1,26 +1,13 @@ -/* - * Author: Garth 'L-H' de Wet - * Initialises the explosives system - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * None - * - * Public: No - */ #include "script_component.hpp" +// Author: Garth 'L-H' de Wet +// Initialises the explosives system ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; -if (isServer) then { - GVAR(explosivesOrientations) = [] -}; +GVAR(detonationHandlers) = []; ADDON = true; diff --git a/addons/explosives/config.cpp b/addons/explosives/config.cpp index 9c323af6c1..3d2077ff1d 100644 --- a/addons/explosives/config.cpp +++ b/addons/explosives/config.cpp @@ -8,16 +8,14 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); - authors[] = {"Garth 'L-H' de Wet"}; + authors[] = {"Garth 'L-H' de Wet", "mharis001"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; }; #include "ACE_Settings.hpp" - #include "CfgEventHandlers.hpp" - #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" @@ -25,11 +23,23 @@ class CfgPatches { #include "CfgCloudlets.hpp" #include "ACE_Triggers.hpp" +#include "ACE_Arsenal_Stats.hpp" + +// UI stuff +class RscText; +class RscEdit; +class RscPicture; +class RscButton; +class ctrlXSliderH; #include "ExplosivesUI.hpp" +#include "TimerDialog.hpp" #include "GUI_VirtualAmmo.hpp" class CfgActions { class None; + class ActivateMine: None { + show = 0; + }; class Deactivate:None { show = 0; }; @@ -45,8 +55,3 @@ class CfgMineTriggers { mineTriggerRange = 1; }; }; - -class ACE_newEvents { - clientRequestsOrientations = QGVAR(sendOrientations); - serverSendsOrientations = QGVAR(orientationsSent); -}; diff --git a/addons/explosives/functions/fnc_addCellphoneIED.sqf b/addons/explosives/functions/fnc_addCellphoneIED.sqf index df198fafb3..d9ae19892c 100644 --- a/addons/explosives/functions/fnc_addCellphoneIED.sqf +++ b/addons/explosives/functions/fnc_addCellphoneIED.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Adds an IED to the cellphone list @@ -16,44 +17,39 @@ * * Public: No */ -#include "script_component.hpp" 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..684161d7ee 100644 --- a/addons/explosives/functions/fnc_addClacker.sqf +++ b/addons/explosives/functions/fnc_addClacker.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Adds an explosive as a clacker item to the passed unit if the unit has the required item. @@ -16,19 +17,16 @@ * * Public: Yes */ -#include "script_component.hpp" 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 f88abc29d3..f1dff4fc9f 100644 --- a/addons/explosives/functions/fnc_addDetonateActions.sqf +++ b/addons/explosives/functions/fnc_addDetonateActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Opens the UI for explosive detonation selection @@ -14,23 +15,20 @@ * * Public: No */ -#include "script_component.hpp" 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; @@ -43,7 +41,7 @@ _explosivesList = []; {(_this select 2) call FUNC(detonateExplosive);}, {true}, {}, - [_unit,_range,_x] + [_unit,_range,_x,_detonator] ] call EFUNC(interact_menu,createAction), [], _unit @@ -62,7 +60,7 @@ if (_detonator != "ACE_DeadManSwitch") then { {(_this select 2) call FUNC(detonateExplosiveAll);}, {true}, {}, - [_unit,_range,_explosivesList] + [_unit,_range,_explosivesList, _detonator] ] call EFUNC(interact_menu,createAction), [], _unit diff --git a/addons/explosives/functions/fnc_addDetonateHandler.sqf b/addons/explosives/functions/fnc_addDetonateHandler.sqf new file mode 100644 index 0000000000..b227b96d07 --- /dev/null +++ b/addons/explosives/functions/fnc_addDetonateHandler.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Add a explosive detonation handler. + * Should be called on all machines. + * Code needs to return BOOL: true(allowed) / false(blocked) + * See https://ace3mod.com/wiki/framework/explosives-framework.html for an example. + * + * Arguments: + * 0: Code + * - Passed [Unit, MaxRange , Explosive , FuzeTime , TriggerItem ] + * + * Return Value: + * None + * + * Example: + * [{false}] call ace_explosives_fnc_addDetonateHandler; + * + * Public: Yes + */ + +params [["_code", {true}, [{}]]]; + +GVAR(detonationHandlers) pushBack _code; diff --git a/addons/explosives/functions/fnc_addExplosiveActions.sqf b/addons/explosives/functions/fnc_addExplosiveActions.sqf index 0ee3ca9f78..281aebf048 100644 --- a/addons/explosives/functions/fnc_addExplosiveActions.sqf +++ b/addons/explosives/functions/fnc_addExplosiveActions.sqf @@ -1,60 +1,42 @@ +#include "script_component.hpp" /* - * Author: Garth 'L-H' de Wet and CAA-Picard - * Adds sub actions for all explosive magazines (from insertChildren) + * Author: Garth 'L-H' de Wet, CAA-Picard, mharis001 + * Returns children actions for explosive magazines in the player's inventory. * * Arguments: - * 0: Unit + * 0: Player * * Return Value: - * Actions + * Actions + * + * Example: + * [_player] call ace_explosives_fnc_addExplosiveActions * * Public: No */ -#include "script_component.hpp" -params ["_unit"]; -TRACE_1("params",_unit); +[_this, { + params ["_player"]; + TRACE_1("Creating explosive actions",_player); -private ["_mags", "_item", "_index", "_children", "_itemCount", "_list"]; + private _cfgMagazines = configFile >> "CfgMagazines"; + private _magazines = magazines _player; + private _totalCount = count _magazines; -_mags = magazines _unit; -_list = []; -_itemCount = []; -{ - _item = ConfigFile >> "CfgMagazines" >> _x; - if (getNumber(_item >> QGVAR(Placeable)) == 1) then { - _index = _list find _item; - if (_index != -1) then { - _itemCount set [_index, (_itemCount select _index) + 1]; - } else { - _list pushBack _item; - _itemCount pushBack 1; + private _actions = []; + { + private _config = _cfgMagazines >> _x; + if (getNumber (_config >> QGVAR(Placeable)) == 1) then { + private _name = getText (_config >> "displayNameShort"); + private _picture = getText (_config >> "picture"); + if (_name isEqualTo "") then { + _name = getText (_config >> "displayName"); + }; + + private _action = [_x, format ["%1 (%2)", _name, _totalCount - count (_magazines - [_x])], _picture, {[{_this call FUNC(setupExplosive)}, _this] call CBA_fnc_execNextFrame}, {true}, {}, _x] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _player]; }; - }; -} forEach _mags; + } forEach (_magazines arrayIntersect _magazines); -_children = []; - -{ - private _name = getText (_x >> "displayNameShort"); - if (_name isEqualTo "") then { - _name = getText (_x >> "displayName"); - }; - - _children pushBack - [ - [ - format ["Explosive_%1", _forEachIndex], - format [_name + " (%1)", _itemCount select _forEachIndex], - getText(_x >> "picture"), - {[{_this call FUNC(setupExplosive)}, _this] call CBA_fnc_execNextFrame}, - {true}, - {}, - (configName _x) - ] call EFUNC(interact_menu,createAction), - [], - _unit - ]; -} forEach _list; - -_children + _actions +}, ACE_player, QGVAR(explosiveActions), 3600, "cba_events_loadoutEvent"] call EFUNC(common,cachedCall); diff --git a/addons/explosives/functions/fnc_addToSpeedDial.sqf b/addons/explosives/functions/fnc_addToSpeedDial.sqf index 7ad0fe76da..5b7d828d53 100644 --- a/addons/explosives/functions/fnc_addToSpeedDial.sqf +++ b/addons/explosives/functions/fnc_addToSpeedDial.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets the speed dial for the UI. @@ -14,15 +15,12 @@ * * Public: Yes */ -#include "script_component.hpp" 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 4397e743a0..d39b9fd731 100644 --- a/addons/explosives/functions/fnc_addTransmitterActions.sqf +++ b/addons/explosives/functions/fnc_addTransmitterActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Opens the UI for selecting the transmitter @@ -6,24 +7,21 @@ * 0: Unit * * Return Value: - * Nothing + * None * * Example: * [player] call ACE_Explosives_fnc_addTransmitterActions; * * Public: No */ -#include "script_component.hpp" 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..6e534a19ae 100644 --- a/addons/explosives/functions/fnc_addTriggerActions.sqf +++ b/addons/explosives/functions/fnc_addTriggerActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Opens the UI for explosive trigger selection @@ -14,21 +15,18 @@ * * Public: No */ -#include "script_component.hpp" 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_canDefuse.sqf b/addons/explosives/functions/fnc_canDefuse.sqf index be114bf072..f42764ee38 100644 --- a/addons/explosives/functions/fnc_canDefuse.sqf +++ b/addons/explosives/functions/fnc_canDefuse.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Whether a unit can perform the defuse action @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_target"]; TRACE_2("params",_unit,_target); @@ -24,7 +24,7 @@ if (isNull _explosive) exitWith { deleteVehicle _target; false }; -if (vehicle _unit != _unit || {!("ACE_DefusalKit" in (items _unit))}) exitWith {false}; +if (vehicle _unit != _unit || {!("ACE_DefusalKit" in (_unit call EFUNC(common,uniqueItems)))}) exitWith {false}; if (GVAR(RequireSpecialist) && {!([_unit] call EFUNC(Common,isEOD))}) exitWith {false}; diff --git a/addons/explosives/functions/fnc_canDetonate.sqf b/addons/explosives/functions/fnc_canDetonate.sqf index 73ca3c4e70..a81103ce13 100644 --- a/addons/explosives/functions/fnc_canDetonate.sqf +++ b/addons/explosives/functions/fnc_canDetonate.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Whether the unit is able to detonate explosives @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/explosives/functions/fnc_cancelPlacement.sqf b/addons/explosives/functions/fnc_cancelPlacement.sqf index e6bd60f637..eaefcfcc07 100644 --- a/addons/explosives/functions/fnc_cancelPlacement.sqf +++ b/addons/explosives/functions/fnc_cancelPlacement.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Cancels explosives placement. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_key"]; diff --git a/addons/explosives/functions/fnc_connectExplosive.sqf b/addons/explosives/functions/fnc_connectExplosive.sqf index aab7ca2c4d..964966f224 100644 --- a/addons/explosives/functions/fnc_connectExplosive.sqf +++ b/addons/explosives/functions/fnc_connectExplosive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: VKing * Add preplaced explosives to a unit's detonator. @@ -15,7 +16,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_object", "_detonator"]; TRACE_3("Params",_unit,_object,_detonator); diff --git a/addons/explosives/functions/fnc_defuseExplosive.sqf b/addons/explosives/functions/fnc_defuseExplosive.sqf index b98b992f8e..24f74a580e 100644 --- a/addons/explosives/functions/fnc_defuseExplosive.sqf +++ b/addons/explosives/functions/fnc_defuseExplosive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Causes the unit to defuse the passed explosive. @@ -14,14 +15,13 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_explosive"]; TRACE_2("params",_unit,_explosive); if (GVAR(ExplodeOnDefuse) && {(random 1.0) < (getNumber (ConfigFile >> "CfgAmmo" >> typeOf _explosive >> QGVAR(explodeOnDefuseChance)))}) exitWith { TRACE_1("exploding on defuse",_explosive); - [_unit, -1, [_explosive, 1], true] call FUNC(detonateExplosive); + [_unit, -1, [_explosive, 1], "#ExplodeOnDefuse"] call FUNC(detonateExplosive); [QGVAR(explodeOnDefuse), [_explosive, _unit]] call CBA_fnc_globalEvent; }; diff --git a/addons/explosives/functions/fnc_detonateExplosive.sqf b/addons/explosives/functions/fnc_detonateExplosive.sqf index b7f4893e52..8edc83f0ff 100644 --- a/addons/explosives/functions/fnc_detonateExplosive.sqf +++ b/addons/explosives/functions/fnc_detonateExplosive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Causes the unit to detonate the passed explosive. @@ -8,47 +9,52 @@ * 2: Explosive * 0: Explosive * 1: Fuse time + * 3: Trigger Item Classname * * Return Value: * None * * Example: - * [player, 100, [Explosive, 1]] call ACE_Explosives_fnc_detonateExplosive; // has to be within range - * [player, -1, [Explosive, 1]] call ACE_Explosives_fnc_detonateExplosive; // range ignored. + * [player, 100, [Explosive, 1], "ACE_Clacker"] call ACE_Explosives_fnc_detonateExplosive; // has to be within range + * [player, -1, [Explosive, 1], "ACE_Cellphone"] call ACE_Explosives_fnc_detonateExplosive; // range ignored. * * Public: Yes */ -#include "script_component.hpp" -params ["_unit", "_range", "_item"]; -TRACE_3("params",_unit,_range,_item); - -private ["_result", "_ignoreRange", "_pos"]; - -_ignoreRange = (_range == -1); -_result = true; +params ["_unit", "_range", "_item", ["_triggerClassname", "#unknown", [""]]]; +TRACE_4("detonateExplosive",_unit,_range,_item,_triggerClassname); +private _ignoreRange = (_range == -1); if (!_ignoreRange && {(_unit distance (_item select 0)) > _range}) exitWith {TRACE_1("out of range",_range); false}; +private _result = true; +{ + // Pass [Unit, MaxRange , Explosive , FuzeTime , TriggerItem ] + private _handlerResult = [_unit, _range, _item select 0, _item select 1, _triggerClassname] call _x; + if (_handlerResult isEqualTo false) then {TRACE_1("Handler Failed",_forEachIndex); _result = false}; +} forEach GVAR(detonationHandlers); +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; }; }; -[{ - params ["_explosive"]; - TRACE_1("exploding",_explosive); - if (!isNull _explosive) then { - _explosive setDamage 1; - }; -}, [_item select 0], (_item select 1)] call CBA_fnc_waitAndExecute; + +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_detonateExplosiveAll.sqf b/addons/explosives/functions/fnc_detonateExplosiveAll.sqf index 377dc0b93a..ec1f1e661a 100644 --- a/addons/explosives/functions/fnc_detonateExplosiveAll.sqf +++ b/addons/explosives/functions/fnc_detonateExplosiveAll.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: VKing * Causes the unit to detonate all passed explosives. @@ -8,20 +9,20 @@ * 2: Explosives to detonate * 0: Explosive * 1: Fuse time + * 3: Trigger Item Classname * * Return Value: * None * * Example: - * [player, -1, [[c4,0.5]]] call ACE_Explosives_fnc_detonateExplosiveAll; + * [player, -1, [[c4,0.5]], "ACE_Clacker"] call ACE_Explosives_fnc_detonateExplosiveAll; * * Public: No */ -#include "script_component.hpp" -params ["_unit", "_range", "_explosivesList"]; -TRACE_3("Params",_unit,_range,_explosivesList); +params ["_unit", "_range", "_explosivesList", "_triggerClassname"]; +TRACE_4("Params",_unit,_range,_explosivesList,_triggerClassname); { - [_unit,_range,_x] call FUNC(detonateExplosive); + [_unit,_range,_x,_triggerClassname] call FUNC(detonateExplosive); } forEach _explosivesList; diff --git a/addons/explosives/functions/fnc_dialPhone.sqf b/addons/explosives/functions/fnc_dialPhone.sqf index e205f9b381..c7b5848e52 100644 --- a/addons/explosives/functions/fnc_dialPhone.sqf +++ b/addons/explosives/functions/fnc_dialPhone.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Dials the number passed and detonates the explosive. @@ -14,33 +15,29 @@ * * Public: Yes */ -#include "script_component.hpp" 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]; (_this select 0) setVariable [QGVAR(Dialing), false, true]; }, [_unit,_explosive select 0], 0.25 * (count _arr - 4)] call CBA_fnc_waitAndExecute; - [_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2)] call FUNC(startTimer); + [_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2), "ACE_Cellphone"] call FUNC(startTimer); }; }; diff --git a/addons/explosives/functions/fnc_dialingPhone.sqf b/addons/explosives/functions/fnc_dialingPhone.sqf index aa20ebf4b0..9fd1184150 100644 --- a/addons/explosives/functions/fnc_dialingPhone.sqf +++ b/addons/explosives/functions/fnc_dialingPhone.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Performs the dial tones and detonation of explosive. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_args", "_pfID"]; _args params ["_unit", "_i", "_arr", "_code"]; @@ -31,7 +31,7 @@ private _explosive = [_code] call FUNC(getSpeedDialExplosive); if (_i >= (count _arr + 2)) then { [_pfID] call CALLSTACK(CBA_fnc_removePerFrameHandler); if ((count _explosive) > 0) then { - [_unit, -1, [_explosive select 0, _explosive select 2]] call FUNC(detonateExplosive); + [_unit, -1, [_explosive select 0, _explosive select 2], "ACE_Cellphone"] call FUNC(detonateExplosive); }; _unit setVariable [QGVAR(Dialing), false, true]; if (_unit == ace_player) then { diff --git a/addons/explosives/functions/fnc_getDetonators.sqf b/addons/explosives/functions/fnc_getDetonators.sqf index d8c095e6f0..3c4d3085ce 100644 --- a/addons/explosives/functions/fnc_getDetonators.sqf +++ b/addons/explosives/functions/fnc_getDetonators.sqf @@ -1,25 +1,22 @@ +#include "script_component.hpp" /* - * Author: Garth 'L-H' de Wet - * Returns all the detonators of the unit + * Author: Garth 'L-H' de Wet, mharis001 + * Returns all detonators the given unit has. * * Arguments: * 0: Unit * * Return Value: - * Configs of all detonators + * Config names of detonators * * Example: - * _detonators = [player] call ACE_Explosives_fnc_getDetonators; + * [_player] call ace_explosives_fnc_getDetonators * * Public: Yes */ -#include "script_component.hpp" -// IGNORE_PRIVATE_WARNING(_detonators); params ["_unit"]; -TRACE_1("params",_unit); +TRACE_1("Getting detonators",_unit); -private _result = (items _unit) select {getNumber (ConfigFile >> "CfgWeapons" >> _x >> QGVAR(Detonator)) == 1}; -_result = _result arrayIntersect _result; - -_result +private _cfgWeapons = configFile >> "CfgWeapons"; +(_unit call EFUNC(common,uniqueItems)) select {getNumber (_cfgWeapons >> _x >> QGVAR(Detonator)) == 1}; diff --git a/addons/explosives/functions/fnc_getPlacedExplosives.sqf b/addons/explosives/functions/fnc_getPlacedExplosives.sqf index e2e56824ec..8b1135717d 100644 --- a/addons/explosives/functions/fnc_getPlacedExplosives.sqf +++ b/addons/explosives/functions/fnc_getPlacedExplosives.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Gets all placed explosives by unit, optionally filtered by specific trigger type. @@ -15,22 +16,19 @@ * * Public: Yes */ -#include "script_component.hpp" // IGNORE_PRIVATE_WARNING(_allExplosives,_deadmanExplosives); 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..84e2ab6ad8 100644 --- a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf +++ b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Gets the explosive from the speed dial entry. @@ -13,15 +14,12 @@ * * Public: Yes */ -#include "script_component.hpp" 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_handleScrollWheel.sqf b/addons/explosives/functions/fnc_handleScrollWheel.sqf index 36530afb08..674769a496 100644 --- a/addons/explosives/functions/fnc_handleScrollWheel.sqf +++ b/addons/explosives/functions/fnc_handleScrollWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Handles rotating of Explosives @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (!GVAR(pfeh_running)) exitWith {false}; diff --git a/addons/explosives/functions/fnc_hasExplosives.sqf b/addons/explosives/functions/fnc_hasExplosives.sqf index c9da5e59d1..0c824a87b2 100644 --- a/addons/explosives/functions/fnc_hasExplosives.sqf +++ b/addons/explosives/functions/fnc_hasExplosives.sqf @@ -1,31 +1,24 @@ +#include "script_component.hpp" /* - * Author: Garth 'L-H' de Wet - * Whether the passed unit has any explosives on them. + * Author: Garth 'L-H' de Wet, mharis001 + * Checks if given unit has any placeable explosives on them. * * Arguments: * 0: Unit * * Return Value: - * The unit has explosives + * Has explosives * * Example: - * hasExplosives = [player] call ACE_Explosives_fnc_hasExplosives; + * [player] call ace_explosives_fnc_hasExplosives * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); -private ["_result", "_magazines"]; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _magazines = magazines _unit; -_result = false; -_magazines = magazines _unit; -{ - if (getNumber (ConfigFile >> "CfgMagazines" >> _x >> QGVAR(Placeable)) == 1) exitWith { - _result = true; - }; -} count _magazines; - -_result +((_magazines arrayIntersect _magazines) findIf {getNumber (_cfgMagazines >> _x >> QGVAR(Placeable)) == 1}) > -1 diff --git a/addons/explosives/functions/fnc_hasPlacedExplosives.sqf b/addons/explosives/functions/fnc_hasPlacedExplosives.sqf index 174bc07fbc..3bb3f03340 100644 --- a/addons/explosives/functions/fnc_hasPlacedExplosives.sqf +++ b/addons/explosives/functions/fnc_hasPlacedExplosives.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Whether the passed unit has placed any explosives or has a clacker that was used when explosives were placed. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" // IGNORE_PRIVATE_WARNING(_hasPlacedExplosives); (count (_this call FUNC(getPlacedExplosives)) > 0) diff --git a/addons/explosives/functions/fnc_interactEH.sqf b/addons/explosives/functions/fnc_interactEH.sqf index c8486adc09..59ddaff432 100644 --- a/addons/explosives/functions/fnc_interactEH.sqf +++ b/addons/explosives/functions/fnc_interactEH.sqf @@ -1,70 +1,73 @@ +#include "script_component.hpp" /* - * Author: PabstMirror - * When interact_menu starts rendering (from "interact_keyDown" event) - * Add defuse helpers to all nearby mines + * Author: PabstMirror, mharis001 + * Dynamically adds "Defuse" actions to nearby mines when interact_menu is opened. + * Called by the "ace_interactMenuOpened" event. * * Arguments: - * Interact Menu Type (0 - world, 1 - self) + * Interact Menu Type (0 - World, 1 - Self) * * Return Value: - * Nothing + * None * * Example: * [0] call ace_explosives_fnc_interactEH * - * Public: Yes + * Public: No */ -#include "script_component.hpp" params ["_interactionType"]; -TRACE_1("params",_interactionType); +TRACE_1("Explosives interactEH",_interactionType); -//Ignore self-interaction menu -if (_interactionType != 0) exitWith {}; -//Ignore while mounted: -if ((vehicle ACE_player) != ACE_player) exitWith {}; -//Ignore if we don't have defuse kit -if (!("ACE_DefusalKit" in (items ACE_player))) exitWith {}; +// Ignore self-interaction menu or mounted vehicle interaction +// For performance reasons only add PFH if player has a defusal kit +// If player somehow gets a defusal kit during keyDown, they will just have to reopen menu +if ( + _interactionType != 0 + || {vehicle ACE_player != ACE_player} + || {!("ACE_DefusalKit" in (ACE_player call EFUNC(common,uniqueItems)))} +) exitWith {}; [{ - params ["_args", "_pfID"]; - _args params ["_setPosition", "_addedDefuseHelpers", "_minesHelped"]; + BEGIN_COUNTER(interactEH); + params ["_args", "_pfhID"]; + _args params ["_setPosition", "_addedHelpers", "_minesHelped"]; if (!EGVAR(interact_menu,keyDown)) then { - TRACE_1("Cleaning Defuse Helpers",(count _addedDefuseHelpers)); - {deleteVehicle _x;} forEach _addedDefuseHelpers; - [_pfID] call CBA_fnc_removePerFrameHandler; + TRACE_1("Cleaning defuse helpers",count _addedHelpers); + {deleteVehicle _x} forEach _addedHelpers; + [_pfhID] call CBA_fnc_removePerFrameHandler; } else { - // Prevent Rare Error when ending mission with interact key down: - if (isNull ace_player) exitWith {}; + // Prevent Rare Error when ending mission with interact key down + private _player = ACE_player; + if (isNull _player) exitWith {}; + private _playerPos = getPosASL _player; - //If player moved >5 meters from last pos, then rescan - if (((getPosASL ace_player) distance _setPosition) > 5) then { + // Rescan if player has moved more than 5 meters from last position + if (_playerPos distanceSqr _setPosition > 25) then { + private _cfgAmmo = configFile >> "CfgAmmo"; { - if (((_x distance ACE_player) < 15) && {!(_x in _minesHelped)}) then { - TRACE_3("Making Defuse Helper",(_x),(typeOf _x),(_x isKindOf "UnderwaterMine_Range_Ammo")); - private _defuseHelper = if (_x isKindOf "UnderwaterMine_Range_Ammo") then { - "ACE_DefuseObject_Large" createVehicleLocal (getPos _x); - } else { - "ACE_DefuseObject" createVehicleLocal (getPos _x); + if (_x distanceSqr _player < 225 && {!(_x in _minesHelped)} && {!(getModelInfo _x select 0 isEqualTo "empty.p3d")}) then { + private _config = _cfgAmmo >> typeOf _x; + private _size = getNumber (_config >> QGVAR(size)); + private _defuseClass = ["ACE_DefuseObject", "ACE_DefuseObject_Large"] select (_size == 1); + private _defusePos = getArray (_config >> QGVAR(defuseObjectPosition)); + if (_defusePos isEqualTo []) then { + _defusePos = [0, 0, 0]; }; - private _config = configFile >> "CfgAmmo" >> typeOf _x; + TRACE_4("Creating defuse helper",_x,typeOf _x,_defuseClass,_defusePos); + private _helper = _defuseClass createVehicleLocal [0, 0, 0]; - private _defuseObjectPosition = getArray (_config >> QGVAR(defuseObjectPosition)); - if (_defuseObjectPosition isEqualTo []) then { - _defuseObjectPosition = [0,0,0]; - }; - - TRACE_1("DefuseObjectPosition",(_defuseObjectPosition)); - - _defuseHelper attachTo [_x, _defuseObjectPosition]; - _defuseHelper setVariable [QGVAR(Explosive),_x]; - _addedDefuseHelpers pushBack _defuseHelper; + _helper attachTo [_x, _defusePos]; + _helper setVariable [QGVAR(Explosive), _x]; + _addedHelpers pushBack _helper; _minesHelped pushBack _x; }; } forEach allMines; - _args set [0, (getPosASL ace_player)]; + + _args set [0, _playerPos]; }; }; -}, 0.5, [((getPosASL ace_player) vectorAdd [-100,0,0]), [], []]] call CBA_fnc_addPerFrameHandler; + END_COUNTER(interactEH); +}, 0.5, [getPosASL ACE_player vectorAdd [-100, 0, 0], [], []]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/explosives/functions/fnc_module.sqf b/addons/explosives/functions/fnc_module.sqf index 6764e9bea4..6fa61b401a 100644 --- a/addons/explosives/functions/fnc_module.sqf +++ b/addons/explosives/functions/fnc_module.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Initialises the explosives module @@ -13,9 +14,6 @@ * * Public: No */ -#include "script_component.hpp" - -if !(isServer) exitWith {}; params ["_logic"]; @@ -23,4 +21,4 @@ params ["_logic"]; [_logic, QGVAR(PunishNonSpecialists),"PunishNonSpecialists"] call EFUNC(Common,readSettingFromModule); [_logic, QGVAR(ExplodeOnDefuse),"ExplodeOnDefuse"] call EFUNC(Common,readSettingFromModule); -ACE_LOGINFO("Explosive Module Initialized."); +INFO("Explosive Module Initialized."); diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index 6bbf6152d3..74d99d2faa 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Detonates all attached deadman's switched triggered explosives. @@ -13,17 +14,24 @@ * * Public: No */ -#include "script_component.hpp" //NOTE: Extended_Killed_EventHandlers runs only where _unit is local params ["_unit"]; TRACE_1("params",_unit); -private ["_deadman"]; +if (_unit == ace_player) then { + // close cellphone if open + findDisplay 8855 closeDisplay 0; +}; -_deadman = [_unit, "DeadManSwitch"] call FUNC(getPlacedExplosives); +// Exit if no item +if !("ACE_DeadManSwitch" in (_unit call EFUNC(common,uniqueItems))) exitWith {}; + +private _range = getNumber (configFile >> "CfgWeapons" >> "ACE_DeadManSwitch" >> QGVAR(range)); +private _deadman = [_unit, "DeadManSwitch"] call FUNC(getPlacedExplosives); +TRACE_2("placed",_deadman,_range); { - [_unit, -1, _x, true] call FUNC(detonateExplosive); + [_unit, _range, _x, "ACE_DeadManSwitch"] call FUNC(detonateExplosive); } forEach _deadman; //Handle deadman connected to explosive in inventory @@ -44,5 +52,5 @@ if (_connectedInventoryExplosive != "") then { private _explosive = createVehicle [_ammo, (getPos _unit), [], 0, "NONE"]; _explosive setPosASL (getPosASL _unit); - [_unit, -1, [_explosive, -1]] call FUNC(detonateExplosive); //Explode, ignoring range, with a random 0-1 second delay + [_unit, -1, [_explosive, 0.5], "ACE_DeadManSwitch"] call FUNC(detonateExplosive); //Explode, ignoring range, with a 0.5 second delay }; diff --git a/addons/explosives/functions/fnc_onInventoryChanged.sqf b/addons/explosives/functions/fnc_onInventoryChanged.sqf index 889e9e2186..874ae3394f 100644 --- a/addons/explosives/functions/fnc_onInventoryChanged.sqf +++ b/addons/explosives/functions/fnc_onInventoryChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * When a take/put event handler fires and a detonator is changed hands. @@ -16,22 +17,18 @@ * * Public: No */ -#include "script_component.hpp" params ["_receiver", "_giver", "_item"]; TRACE_3("params",_receiver,_giver,_item); -private ["_config", "_detonators"]; +if ((_receiver != ace_player) && {_giver != ace_player}) exitWith {}; -if (_receiver != ace_player) exitWith {}; - -_config = ConfigFile >> "CfgWeapons" >> _item; +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]; - _detonators = [_giver] call FUNC(getDetonators); + private _detonators = [_giver] call FUNC(getDetonators); if (count _detonators == 0) then { _giver setVariable [QGVAR(Clackers), nil, true]; }; diff --git a/addons/explosives/functions/fnc_openTimerSetUI.sqf b/addons/explosives/functions/fnc_openTimerSetUI.sqf deleted file mode 100644 index 7175f425d4..0000000000 --- a/addons/explosives/functions/fnc_openTimerSetUI.sqf +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Author: Garth 'L-H' de Wet - * Opens the UI for timer setting of an explosive - * - * Arguments: - * 0: Explosive - * 1: Magazine - * - * Return Value: - * None - * - * Example: - * [_explosive, "SatchelCharge_Remote_Mag"] call ACE_Explosives_fnc_openTimerSetUI; - * - * Public: No - */ -#include "script_component.hpp" - -params ["_explosive", "_mag"]; -TRACE_2("params",_explosive,_mag); - -createDialog "RscACE_SelectTimeUI"; -sliderSetRange [8845, 5, 900]; // 5seconds - 15minutes -sliderSetPosition [8845, 30]; - -GVAR(explosive) = _explosive; - -DFUNC(SetTimer) = { - [ - ACE_player, - getPosATL GVAR(explosive), - GVAR(explosive) getVariable QGVAR(Direction), - GVAR(explosive) getVariable QGVAR(class), - "Timer", - [floor sliderPosition 8845], - GVAR(explosive) - ] call FUNC(placeExplosive); - closeDialog 0; -}; - -buttonSetAction [8860, QUOTE(call DFUNC(SetTimer);)]; -buttonSetAction [8855, QUOTE(closeDialog 0;)]; - -ctrlSetText [8870, format[localize LSTRING(TimerMenu),0, 30]]; diff --git a/addons/explosives/functions/fnc_openTimerUI.sqf b/addons/explosives/functions/fnc_openTimerUI.sqf new file mode 100644 index 0000000000..05d340e8dd --- /dev/null +++ b/addons/explosives/functions/fnc_openTimerUI.sqf @@ -0,0 +1,84 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Opens the Explosive Timer UI for given explosive. + * + * Arguments: + * 0: Explosive + * + * Return Value: + * True + * + * Example: + * [_explosive] call ace_explosives_fnc_openTimerUI + * + * Public: No + */ + +params ["_explosive"]; +TRACE_1("Opening timer UI",_explosive); + +createDialog QGVAR(timerUI); +private _display = uiNamespace getVariable [QGVAR(timerDisplay), displayNull]; + +// Update slider speed to 1s +(_display displayCtrl IDC_TIMER_SLIDER) sliderSetSpeed [1, 1]; + +// Add confirm button action +GVAR(explosive) = _explosive; +(_display displayCtrl IDC_TIMER_CONFIRM) ctrlAddEventHandler ["ButtonClick", { + params ["_button"]; + + private _slider = ctrlParent _button displayCtrl IDC_TIMER_SLIDER; + private _time = floor sliderPosition _slider; + private _explosive = GVAR(explosive); + [ + ACE_player, + getPosATL _explosive, + _explosive getVariable QGVAR(Direction), + _explosive getVariable QGVAR(class), + "Timer", + [_time], + _explosive + ] call FUNC(placeExplosive); + closeDialog 0; +}]; + +// Add EH to allow for changing values by scrolling +_display displayAddEventHandler ["MouseZChanged", { + params ["_display", "_scroll"]; + + private _change = round _scroll; + if (cba_events_control) then {_change = _change * 10}; + + private _slider = _display displayCtrl IDC_TIMER_SLIDER; + private _value = (sliderPosition _slider + _change) max TIMER_VALUE_MIN min TIMER_VALUE_MAX; + _slider sliderSetPosition _value; +}]; + +// Add PFH to update the digit display (delay of 0.1s) +// Done like this to avoid flicker that would happen when rapidly changing values through EH method +[{ + params ["_display", "_pfhID"]; + + // Make sure explosive still exists and is near player + if ((!isNull _display) && {!alive ACE_player} || {!alive GVAR(explosive)} || {(ACE_player distance GVAR(explosive)) > 5}) exitWith { + INFO_2("explosive became invalid",ACE_player,GVAR(explosive)); + closeDialog 0; + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + if (isNull _display) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + private _value = sliderPosition (_display displayCtrl IDC_TIMER_SLIDER); + private _minutes = floor (_value / 60); + private _seconds = floor (_value % 60); + private _digitArray = [floor (_minutes / 10), _minutes mod 10, floor (_seconds / 10), _seconds mod 10]; + { + (_display displayCtrl _x) ctrlSetText format [QPATHTOF(UI\seven_segment_%1.paa), _digitArray select _forEachIndex]; + } forEach TIMER_DIGIT_IDCs; +}, 0.1, _display] call CBA_fnc_addPerFrameHandler; + +true diff --git a/addons/explosives/functions/fnc_placeExplosive.sqf b/addons/explosives/functions/fnc_placeExplosive.sqf index 4a3e06df4b..df8f3ab89c 100644 --- a/addons/explosives/functions/fnc_placeExplosive.sqf +++ b/addons/explosives/functions/fnc_placeExplosive.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet - * Places an explosive at the requested position + * Places an explosive at the requested position. * * Arguments: * 0: Unit @@ -9,46 +10,42 @@ * 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 */ -#include "script_component.hpp" 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; }; if (isNil "_triggerConfig") exitWith { - ACE_LOGERROR_1("Config not passed to PlaceExplosive: %1",_this); + ERROR_1("Config not passed to PlaceExplosive: %1",_this); 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 { - ACE_LOGERROR_1("Config not found in PlaceExplosive: %1",_this); + ERROR_1("Config not found in PlaceExplosive: %1",_this); 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_removeFromSpeedDial.sqf b/addons/explosives/functions/fnc_removeFromSpeedDial.sqf index d15b1b34c7..998bc492d0 100644 --- a/addons/explosives/functions/fnc_removeFromSpeedDial.sqf +++ b/addons/explosives/functions/fnc_removeFromSpeedDial.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes the specified speed dial from unit's speed dial. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" private _speedDial = ace_player getVariable [QGVAR(SpeedDial), []]; if (count _speedDial == 0) exitWith {}; diff --git a/addons/explosives/functions/fnc_scriptedExplosive.sqf b/addons/explosives/functions/fnc_scriptedExplosive.sqf index 6a554ac09c..6b4aedd6a3 100644 --- a/addons/explosives/functions/fnc_scriptedExplosive.sqf +++ b/addons/explosives/functions/fnc_scriptedExplosive.sqf @@ -1,24 +1,24 @@ +#include "script_component.hpp" /* * 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) + * 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 */ -#include "script_component.hpp" -params [["_explosiveArr", [], [[], objNull]], ["_fuzeTime", 0, [0]]]; +params [["_explosiveArr", [], [[], objNull]], ["_fuzeTime", 0, [0]], ["_triggerClassname", "#scripted", [""]]]; if (_explosiveArr isEqualType objNull) then { _explosiveArr = [_explosiveArr]; @@ -26,5 +26,5 @@ if (_explosiveArr isEqualType objNull) then { { private _detTime = if (_fuzeTime < 0) then {random abs _fuzeTime} else {_fuzeTime}; - [objNull, -1, [_x, _detTime]] call FUNC(detonateExplosive); + [objNull, -1, [_x, _detTime], _triggerClassname] call FUNC(detonateExplosive); } forEach _explosiveArr; diff --git a/addons/explosives/functions/fnc_selectTrigger.sqf b/addons/explosives/functions/fnc_selectTrigger.sqf index 77018ea587..549754aab2 100644 --- a/addons/explosives/functions/fnc_selectTrigger.sqf +++ b/addons/explosives/functions/fnc_selectTrigger.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Selects a trigger for an explosive. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_explosive", "_magazine", "_trigger"]; TRACE_3("params",_explosive,_magazine,_trigger); diff --git a/addons/explosives/functions/fnc_setPosition.sqf b/addons/explosives/functions/fnc_setPosition.sqf index 430f926138..7d4235b8d2 100644 --- a/addons/explosives/functions/fnc_setPosition.sqf +++ b/addons/explosives/functions/fnc_setPosition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets the Dir and pitch of passed object @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_explosive", "_direction", "_pitch"]; TRACE_3("params",_explosive,_direction,_pitch); @@ -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_setSpeedDial.sqf b/addons/explosives/functions/fnc_setSpeedDial.sqf index 1876a50103..7d836015a4 100644 --- a/addons/explosives/functions/fnc_setSpeedDial.sqf +++ b/addons/explosives/functions/fnc_setSpeedDial.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets the speed dial for the UI. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" private _speedDial = ace_player getVariable [QGVAR(SpeedDial), []]; if (_speedDial isEqualTo []) exitWith {}; diff --git a/addons/explosives/functions/fnc_setupExplosive.sqf b/addons/explosives/functions/fnc_setupExplosive.sqf index 47608d03e5..8bc4343430 100644 --- a/addons/explosives/functions/fnc_setupExplosive.sqf +++ b/addons/explosives/functions/fnc_setupExplosive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Starts the setup process for the passed explosive. Player only. @@ -15,8 +16,6 @@ * * Public: Yes */ -// #define ENABLE_PERFORMANCE_COUNTERS -#include "script_component.hpp" #define PLACE_RANGE_MAX 1 #define PLACE_RANGE_MIN 0.025 @@ -24,15 +23,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 +42,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 +60,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 +70,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 +85,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 +116,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 +149,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 +157,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 +170,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 +188,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_spawnFlare.sqf b/addons/explosives/functions/fnc_spawnFlare.sqf index acd5dc2a99..5531d11340 100644 --- a/addons/explosives/functions/fnc_spawnFlare.sqf +++ b/addons/explosives/functions/fnc_spawnFlare.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: VKing * Spawns a flare on the ground for tripflare trigger @@ -13,7 +14,6 @@ * * Public: no */ -#include "script_component.hpp" params ["_posX","_posY","_posZ"]; TRACE_3("Params",_posX,_posY,_posZ); @@ -21,3 +21,5 @@ TRACE_3("Params",_posX,_posY,_posZ); private _flare = "ACE_TripFlare_FlareEffect" createVehicle [_posX,_posY,_posZ]; TRACE_1("",_flare); + +nil diff --git a/addons/explosives/functions/fnc_startDefuse.sqf b/addons/explosives/functions/fnc_startDefuse.sqf index 95e258696c..96b3b3eac2 100644 --- a/addons/explosives/functions/fnc_startDefuse.sqf +++ b/addons/explosives/functions/fnc_startDefuse.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Starts defusing an explosive @@ -7,27 +8,23 @@ * 1: Target explosive * * Return Value: - * Nothing + * None * * Example: * [player, ACE_Interaction_Target] call ACE_Explosives_fnc_StartDefuse; * * Public: Yes */ -#include "script_component.hpp" 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 1f529d9765..484171ec6e 100644 --- a/addons/explosives/functions/fnc_startTimer.sqf +++ b/addons/explosives/functions/fnc_startTimer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Starts a timer for an explosive. @@ -5,24 +6,24 @@ * Arguments: * 0: Explosive * 1: Time till detonate + * 2: Trigger classname (default: "#timer") * * Return Value: * None * * Example: - * [_explosive, 10] call ACE_Explosives_fnc_startTimer; + * [_explosive, 10] call ace_explosives_fnc_startTimer * * Public: Yes */ -#include "script_component.hpp" -params ["_explosive", "_delay"]; -TRACE_2("params",_explosive,_delay); +params ["_explosive", "_delay", ["_trigger", "#timer", [""]]]; +TRACE_3("Starting timer",_explosive,_delay,_trigger); [{ - params ["_explosive"]; - TRACE_1("Explosive Going Boom",_explosive); + params ["_explosive", "_trigger"]; + TRACE_1("Explosive detonating from timer",_explosive); if (!isNull _explosive) then { - [_explosive, -1, [_explosive, 0]] call FUNC(detonateExplosive); + [_explosive, -1, [_explosive, 0], _trigger] call FUNC(detonateExplosive); }; -}, [_explosive], _delay] call CBA_fnc_waitAndExecute; +}, [_explosive, _trigger], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/explosives/functions/fnc_triggerType.sqf b/addons/explosives/functions/fnc_triggerType.sqf index 7f763dbdea..6bcbf775d3 100644 --- a/addons/explosives/functions/fnc_triggerType.sqf +++ b/addons/explosives/functions/fnc_triggerType.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Gets the types of triggers associated with the explosive @@ -13,16 +14,13 @@ * * Public: Yes */ -#include "script_component.hpp" 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/script_component.hpp b/addons/explosives/script_component.hpp index 7245801cc9..77ca89d32e 100644 --- a/addons/explosives/script_component.hpp +++ b/addons/explosives/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_EXPLOSIVES @@ -17,6 +16,21 @@ #include "\z\ace\addons\main\script_macros.hpp" +#include "\a3\ui_f\hpp\defineCommonGrids.inc" +#include "\a3\ui_f\hpp\defineCommonColors.inc" + +#define IDC_TIMER_DIGIT_1 8501 +#define IDC_TIMER_DIGIT_2 8502 +#define IDC_TIMER_DIGIT_3 8503 +#define IDC_TIMER_DIGIT_4 8504 +#define IDC_TIMER_SLIDER 8505 +#define IDC_TIMER_CONFIRM 8506 +#define TIMER_DIGIT_IDCs [IDC_TIMER_DIGIT_1, IDC_TIMER_DIGIT_2, IDC_TIMER_DIGIT_3, IDC_TIMER_DIGIT_4] + +#define TIMER_VALUE_MIN 5 +#define TIMER_VALUE_MAX 900 +#define TIMER_VALUE_DEFAULT 30 + #define PLACE_WAITING -1 #define PLACE_CANCEL 0 #define PLACE_APPROVE 1 diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index eab890988c..7c877c7535 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Robbanóanyagok Explosivos Взрывчатка + 爆発物 + 폭발물 + 炸药 + 炸藥 Place @@ -24,6 +28,10 @@ Elhelyezés Colocar Установить + 設置 + 설치 + 放置 + 放置 Detonate @@ -36,6 +44,10 @@ Robbantás Detonar Подрыв + 点火 + 폭파 + 引爆 + 引爆 Detonate All @@ -47,6 +59,10 @@ Detona Tutti Tout détoner Detonar Tudo + すべて点火 + 모두 폭파 + 引爆全部 + 引爆全部 Explosive code: %1 @@ -59,6 +75,10 @@ Código do explosivo: %1 Код подрыва: %1 Codice esplosivo: %1 + 爆破コード: %1 + 폭파 코드: %1 + 炸药代码: %1 + 炸藥代碼: %1 Place @@ -71,6 +91,10 @@ Elhelyezés Colocar Установить + 設置 + 설치 + 放置 + 放置 Attach @@ -83,6 +107,10 @@ Attacca Hozzácsatolás Прикрепить + 取り付け + 부착 + 连接 + 連接 Blocked @@ -94,6 +122,10 @@ Bloccato Blockiert Bloqué + 取り付け不可 + 막힘 + 断开 + 斷開 Cancel @@ -106,6 +138,10 @@ Mégsem Cancelar Отмена + 中止 + 취소 + 取消 + 取消 Rotate @@ -118,6 +154,10 @@ Obrót Rotaciona Bращать + 回転 + 회전 + 旋转 + 旋轉 Turn On Thor III @@ -130,6 +170,10 @@ Thor III bekapcsolása Ativar Thor III Активировать Thor III + Thor III を使う + Thor III 켜기 + 开启索尔三型 + 開啟索爾三型 Turn Off Thor III @@ -142,6 +186,10 @@ Thor III kikapcsolása Desativar Thor III Деактивировать Thor III + Thor III を止める + Thor III 끄기 + 关闭索尔三型 + 關閉索爾三型 Cellphone @@ -154,6 +202,10 @@ Mobiltelefon Celular Сотовый телефон + 携帯電話 + 휴대전화 + 手机 + 手機 Used to remotely trigger explosives @@ -166,6 +218,10 @@ Robbanóanyagok távoli robbantásához való Usado para acionar explosivos remotamente Используется для удаленной детонации СВУ + 爆発物を遠隔で起爆させるのに使います + 원격으로 폭발물을 폭파시킬때 씁니다. + 用于远端引爆炸药 + 用於遠端引爆炸藥 M57 Firing Device @@ -178,6 +234,10 @@ M57 Gyújtóeszköz M57 Dispositivo de Detonação Взрыватель M57 + M57 起爆装置 + M57 격발기 + M57 引爆装置 + M57 引爆裝置 Used to remotely trigger explosives @@ -190,6 +250,10 @@ Robbanóanyagok távoli robbantásához Usado para acionar explosivos remotamente Используется для удаленной детонации зарядов + 爆発物を遠隔で起爆させるのに使います + 원격으로 폭발물을 폭파시킬때 씁니다. + 用于远端引爆炸药 + 用於遠端引爆炸藥 M152 Firing Device @@ -202,6 +266,10 @@ M152 Gyújtóeszköz M152 Dispositivo de Detonação Взрыватель M152 + M152 起爆装置 + M152 격발기 + M152 引爆装置 + M152 引爆裝置 M152 RAMS @@ -214,6 +282,10 @@ M152 RAMS M152 RAMS M152 RAMS + M152 RAMS + M152 RAMS + M152 远端炸药引爆系统 + M152 遠端炸藥引爆系統 Defusal Kit @@ -226,6 +298,10 @@ Hatástalanító felszerelés Kit de desarme Комплект разминирования + 解除キット + 해체 장비 + 拆弹工具 + 拆彈工具 Allows defusing of explosives @@ -238,6 +314,10 @@ Robbanóanyagok hatástalanítását teszi lehetővé Permite o desarme de explosivos Позволяет обезвреживать взрывчатку + 爆発物を無力化できます + 폭발물을 해체할 수 있게 해줍니다 + 可以用来拆除炸弹 + 可以用來拆除炸彈 Add to Speed Dial @@ -250,6 +330,10 @@ Hozzáadás a gyorstárcsázóhoz Adicionar à ligação rápida Добавить в быстрый вызов + 短縮ダイアルに追加 + 단축키에 지정 + 增加到快速拨号 + 增加到快速撥號 Clear @@ -262,6 +346,10 @@ Törlés Limpar Очистить + 消去 + 삭제 + 清除 + 清除 Dial @@ -274,6 +362,10 @@ Tárcsázás Discar Hабрать + ダイアル + 다이얼 + 拨号 + 撥號 Up @@ -286,6 +378,10 @@ Fel Cima Вызов + 上へ + + + Down @@ -298,6 +394,10 @@ Le Baixo Сброс + 下へ + 아래 + + Cancel @@ -310,6 +410,10 @@ Mégsem Cancelar Отмена + 中止 + 취소 + 取消 + 取消 Detonate Menu @@ -322,6 +426,10 @@ Robbantási menü Menu de detonação Меню подрыва + 点火メニュー + 폭파 메뉴 + 引爆选单 + 引爆選單 Place Menu @@ -334,6 +442,10 @@ Elhelyezési menü Menu de posicionamento Меню установки + 設置メニュー + 설치 메뉴 + 放置选单 + 放置選單 Defuse @@ -346,6 +458,10 @@ Hatástalanítás Desarmar Обезвредить + 無力化 + 해체 + 拆除 + 拆除 Defusing Explosive... @@ -358,6 +474,10 @@ Robbanóanyag hatástalanítása... Desarmando Explosivo... Обезвреживание... + 爆発物を無力化しています・・・ + 폭발물 해체중... + 炸弹拆除中... + 炸彈拆除中... Timer @@ -370,6 +490,10 @@ Időzítő Timer Таймер + タイマー + 타이머 + 计时器 + 計時器 Time: %1m %2s @@ -382,6 +506,10 @@ Idő: %1m %2s Tempo: %1m %2s Время: %1m %2c + 設定時間: %1分 %2秒 + 시간: %1분 %2초 + 时间: %1分%2秒 + 時間: %1分%2秒 Set Time @@ -394,6 +522,10 @@ Idő beállítása Configurar Tempo Установить время + 時間を設定 + 시간 설정 + 设定时间 + 設定時間 Select a Trigger @@ -406,6 +538,10 @@ Gyújtóeszköz kiválasztása Selecionar um Gatilho Выберите детонатор + 点火装置を選択 + 작동방식 선택 + 选择一个触发器 + 選擇一個觸發器 Select @@ -418,6 +554,10 @@ Kiválasztás Selecionar Выбрать + 選択 + 선택 + 选择 + 選擇 Pressure Plate @@ -430,6 +570,10 @@ Nyomólap Placa de pressão Нажимная плита + 圧力感知式 + 압력식 + 压力盘 + 壓力盤 Tripwire @@ -442,6 +586,10 @@ Botlódrót Linha de tração Растяжка + 仕掛け線 + 인계철선 + 绊线 + 絆線 IR Sensor @@ -454,6 +602,10 @@ Infravörös szenzor Sensor IV ИК сенсор + 赤外線感知式 + 적외선 센서 + 红外线感应器 + 紅外線感應器 No triggers available for %1 @@ -466,6 +618,10 @@ Nincs elérhető gyújtóeszköz ide: %1 Nenhum gatilho disponível para %1 Нет доступных взрывателей для %1 + %1 につかえる点火装置がありません + %1(을)를 작동할 장치가 없습니다. + 没有适合%1的触发器 + 沒有適合%1的觸發器 IR Sensor (Side Attack) @@ -478,6 +634,10 @@ Infravörös szenzor (Side Attack) Sensor infravermelho (ataque lateral) ИК сенсор (детонация вбок) + 赤外線感知式 (側面攻撃) + 적외선 센서 (측면 공격) + 红外线感应器 (侧边攻击) + 紅外線感應器 (側邊攻擊) Magnetic Influence Sensor (Bottom Attack) @@ -490,6 +650,10 @@ Mágneses mező érzékelő (Bottom Attack) Influência magnética (ataque inferior) Магнитный сенсор (детонация вверх) + 磁気感知式 (底面攻撃) + 자기장 감지센서 (바닥 공격) + 磁性感应器 (底部攻击) + 磁性感應器 (底部攻擊) No explosives on trigger. @@ -502,6 +666,10 @@ Brak ładunków na zapalnik. Nenhum explosivo no gatilho. Взрыватель не подсоединён к взрывчатке + 点火装置に爆発物がありません。 + 격발기에 등록된 폭발물이 없습니다. + 触发器上并没有炸药 + 觸發器上並沒有炸藥 Dead Man's Switch @@ -514,6 +682,10 @@ Detonador do homem morto Кнопка мертвеца Detonatore a rilascio + 自爆装置 + 자폭 장치 + 自杀炸弹客引爆器 + 自殺炸彈客引爆器 Used to remotely trigger explosives when released. @@ -526,6 +698,10 @@ Usado para detonar remotamente o explosivo quando solto. Используется для дистанционного подрыва, после смерти оператора. Usato per attivare a distanza esplosivi al momento del rilascio + 点火装置を遠隔から離すと起爆したいときに使います。 + 압력이 해제될때 원격으로 폭발시킵니다. + 当放开按钮时, 将会引爆炸弹. + 當放開按鈕時, 將會引爆炸彈. Pick up @@ -538,6 +714,10 @@ Поднять Raccogli Pegar + 拾う + 줍기 + 捡起 + 撿起 Explosive System @@ -550,6 +730,10 @@ Robbanóanyag-rendszer Взрывные устройства Sistema Esplosivi + 爆発システム + 폭발물 시스템 + 炸药系统 + 炸藥系統 Require specialists? @@ -562,6 +746,10 @@ Specialisták igénylése? Требуется специалист? Richiedi specialisti? + 特技兵を必要としますか? + 전문가가 필요합니까? + 需要专家? + 需要專家? Require explosive specialists to disable explosives? Default: No @@ -574,6 +762,10 @@ 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 + 爆発物を無効化するには、爆発物の特技兵を必要としますか? 標準: 無効化 + 폭발물을 해제하기 위해서는 전문가가 필요합니까? 기본설정: 아니요 + 需要炸弹专家才能拆除炸弹? 预设: 否 + 需要炸彈專家才能拆除炸彈? 預設: 否 Punish non-specialists? @@ -586,6 +778,10 @@ Nem-specialisták büntetése? Штраф не-специалистам? Punisci non-specialisti? + 非特技兵へ足かせを与えますか? + 비-전문가에 불이익을 줍니까? + 折磨非专业人员? + 折磨非專業人員? Increase the time it takes to complete actions for non-specialists? Default: Yes @@ -598,6 +794,10 @@ 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 + 非特技兵へ動作完了までの時間を増加させますか? 標準: 有効化 + 비-전문가가 폭발물을 해제시 더욱 많은 시간을 소요합니까? 기본설정: 예 + 增加非专业人员相关操作的时间? 预设: 是 + 增加非專業人員相關操作的時間? 預設: 是 Explode on defusal? @@ -610,6 +810,10 @@ Robbanás hatástalanításkor? Взрыв при разминир.? Fai esplodere quando disarmato? + 解除中に爆発させますか? + 해제시 폭발합니까? + 拆除时引爆? + 拆除時引爆? Enable certain explosives to explode on defusal? Default: Yes @@ -622,6 +826,10 @@ Meghatározott robbanóanyagok felrobbanjanak-e hatástalanításkor? Alapértelmezett: Igen Разрешить определенным взрывным устройствам взрываться при разминировании? По-умолчанию: Да Abilita alcuni esplosivi per esplosione al disarmo? Default: Si + 特定の爆発物を解除中に爆発させますか? 標準: 有効化 + 특정 폭발물이 해제시 폭발하게 합니까? 기본설정: 예 + 启用后, 某些炸弹会在拆除时引爆? 预设: 是 + 啟用後, 某些炸彈會在拆除時引爆? 預設: 是 This module adjusts the settings related to explosives. @@ -634,6 +842,10 @@ Этот модуль управляет настройками, связанными со взрывными устройствами Este módulo ajusta las configuraciones relacionadas con explosivos. Questo modulo cambia le impostazioni relative agli esplosivi + モジュールを調節し爆発物に設定を反映させます。 + 이 모듈은 폭발물에 관한 설정을 수정할 수 있게합니다. + 此模块用来调整炸药的相关设定 + 此模塊用來調整炸藥的相關設定 M6 SLAM Mine (Bottom Attack) @@ -652,6 +864,10 @@ M6 SLAM (Útok zespoda) Mina M6 SLAM (Ataque Inferior) Мина M6 SLAM (направлена вверх) + M6 SLAM 地雷 (底面攻撃) + M6 SLAM 지뢰 (바닥 공격) + M6指向性反装甲地雷 (底部攻击) + M6指向性反裝甲地雷 (底部攻擊) M6 SLAM Mine (Side Attack) @@ -670,6 +886,10 @@ M6 SLAM (Útok do strany) Mina M6 SLAM (Ataque Lateral) Мина M6 SLAM (направлена вбок) + M6 SLAM 地雷 (側面攻撃) + M6 SLAM 지뢰 (측면 공격) + M6指向性反装甲地雷 (侧边攻击) + M6指向性反裝甲地雷 (側邊攻擊) Large IED (Urban, Pressure Plate) @@ -688,6 +908,10 @@ IED, Velké (Městské, Nášlapné) IED Grande (Urbano, Placa de pressão) Большое СВУ (городское, нажимного действия) + 大きな IED (市街地用、圧力感知) + 대형 급조폭발물 (시가지, 압력식) + 大型简易爆炸装置 (地表上, 压力盘) + 大型簡易爆炸裝置 (地表上, 壓力盤) Large IED (Dug-in, Pressure Plate) @@ -706,6 +930,10 @@ IED, Velké (Zakopané, Nášlapné) IED Grande (Enterrado, Placa de pressão) Большое СВУ (закопанное, нажимного действия) + 大きな IED (埋め込み型、圧力感知) + 대형 급조폭발물 (묻힘, 압력식) + 大型简易爆炸装置 (地表下, 压力盘) + 大型簡易爆炸裝置 (地表下, 壓力盤) Small IED (Urban, Pressure Plate) @@ -724,6 +952,10 @@ IED, Malé (Městské, Nášlapné) IED Pequeno(Urbano, Placa de pressão) Малое СВУ (городское, нажимного действия) + 小さな IED (市街地用、圧力感知) + 소형 급조폭발물 (시가지, 압력식) + 小型简易爆炸装置 (地表上, 压力盘) + 小型簡易爆炸裝置 (地表上, 壓力盤) Small IED (Dug-in, Pressure Plate) @@ -742,6 +974,10 @@ IED, Malé (Zakopané, Nášlapné) IED Pequeno (Enterrado, Placa de pressão) Малое СВУ (закопанное, нажимного действия) + 小さな IED (埋め込み型、圧力感知) + 소형 급조폭발물 (묻힘, 압력식) + 小型简易爆炸装置 (地表下, 压力盘) + 小型簡易爆炸裝置 (地表下, 壓力盤) Connect to %1 @@ -754,14 +990,46 @@ Csatlakozás %1 Collega a %1 Conectar à %1 + %1 へ接続 + %1에 연결중 + 连接到%1 + 連接到%1 Tripwire Flare Сигнальная растяжка + 仕掛け型照明地雷 + Flara na linkę + Stolperdraht-Leuchtrakete + 조명지뢰 + Fusée éclairante avec fil de détente + Cavo d'innesco + 绊线闪光地雷 + 絆線閃光地雷 Type: Tripwire flare - Ignites a non-lethal flare when triggered.<br />Rounds: 1<br />Used on: Ground Тип: Сигнальная растяжка - При срабатывании выпускает несмертельную сгнальную вспышку.<br />Зарядов: 1<br />Используется на: Земле + 種類: 仕掛け型照明地雷 - 発動したとき、非致死性の照明を発炎します。<br />装填数: 1<br />次で使用: 地表 + Typ: Flara na linkę - Wystrzeliwuje nieszkodliwą flarę przy nadepnięciu linki.<br/>Pociski: 1<br/>Używane na: ziemia + Typ: Stolperdraht-Leuchtrakete - Schießt bei Auslösung eine nicht-tödliche Leuchtrakete ab.<br />Ladungen: 1<br />Benutzt auf: Boden + 종류: 조명지뢰 - 작동시 무해한 조명을 사출합니다.<br />장탄수: 1<br />사용처: 지면 + Type : Fusée éclairante avec fil de détente - Allume une fusée éclairante lorsque déclenché. <br />Coups : 1<br />Utilisé sur : le sol + Tipo: Cavo d'innesco - Sfocio un abbaglio non letale quanto attivato. <br />Rimanenti: 1<br />Usato: A terra + 类型: 绊线闪光地雷 - 触发后产生非致命性的强光.<br />发数: 1<br />使用于: 地面 + 類型: 絆線閃光地雷 - 觸發後產生非致命性的強光.<br />發數: 1<br />使用於: 地面 + + + Explosive range + Portée du détonateur + 爆発範囲 + 爆炸范围 + 爆炸範圍 + Raggio di detonazione + + + Explosive Timer + Timer di detonazione diff --git a/addons/fastroping/CfgVehicles.hpp b/addons/fastroping/CfgVehicles.hpp index 5ade667c12..05ef487325 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"; @@ -43,28 +43,30 @@ class CfgVehicles { condition = QUOTE([vehicle _player] call FUNC(canPrepareFRIES)); statement = QUOTE([vehicle _player] call FUNC(prepareFRIES)); 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; }; class ACE_deployRopes { displayName = CSTRING(Interaction_deployRopes); condition = QUOTE([ARR_2(_player, vehicle _player)] call FUNC(canDeployRopes)); statement = QUOTE([ARR_2(QUOTE(QGVAR(deployRopes)), [vehicle _player])] call CBA_fnc_serverEvent); showDisabled = 0; - priority = 1; }; class ACE_cutRopes { displayName = CSTRING(Interaction_cutRopes); condition = [vehicle _player] call FUNC(canCutRopes); statement = [vehicle _player] call FUNC(cutRopes); showDisabled = 0; - priority = 1; }; class ACE_fastRope { displayName = CSTRING(Interaction_fastRope); condition = [_player, vehicle _player] call FUNC(canFastRope); statement = [_player, vehicle _player] call FUNC(fastRope); showDisabled = 0; - priority = 1; }; }; }; @@ -77,6 +79,10 @@ class CfgVehicles { class ACE_SelfActions {}; EGVAR(cargo,hasCargo) = 0; EGVAR(cargo,space) = 0; + // ACRE 2.6.0 Compatibility + acre_hasInfantryPhone = 0; + class AcreRacks {}; + class AcreIntercoms {}; }; class ACE_friesAnchorBar: ACE_friesBase { author = "jokoho48"; @@ -156,6 +162,12 @@ class CfgVehicles { class ACE_Actions {}; class Turrets {}; class TransportItems {}; + EGVAR(cargo,hasCargo) = 0; + EGVAR(cargo,space) = 0; + // ACRE 2.6.0 Compatibility + acre_hasInfantryPhone = 0; + class AcreRacks {}; + class AcreIntercoms {}; }; class Helicopter_Base_H; @@ -217,7 +229,7 @@ class CfgVehicles { GVAR(enabled) = 2; GVAR(ropeOrigins)[] = {"ropeOriginRight", "ropeOriginLeft"}; GVAR(friesType) = "ACE_friesGantry"; - GVAR(friesAttachmentPoint)[] = {-1.07, 3.26, -0.5}; + GVAR(friesAttachmentPoint)[] = {1.07, 2.5, -0.5}; EQUIP_FRIES_ATTRIBUTE; }; class Heli_Transport_04_base_F: 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 2752e2dcde..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 @@ -16,3 +30,23 @@ false }; }, {false}] call CBA_fnc_addKeybind; + + +#ifdef DRAW_FASTROPE_INFO +addMissionEventHandler ["Draw3D", { + if (!(cursorObject isKindOf "Helicopter")) exitWith {}; + private _config = configFile >> "CfgVehicles" >> (typeOf cursorObject); + private _enabled = getNumber (_config >> QGVAR(enabled)); + drawIcon3D ["", [.5,.5,1,1], (ASLtoAGL getPosASL cursorObject), 0.5, 0.5, 0, format ["%1 = %2", typeOf cursorObject, _enabled], 0.5, 0.025, "TahomaB"]; + if (_enabled > 0) then { + { + private _hookAttachment = cursorObject getVariable [QGVAR(FRIES), cursorObject]; + private _ropeOrigin = if (_x isEqualType []) then {_x} else {_hookAttachment selectionPosition _x}; + drawIcon3D ["", [1,.5,.5,1], (_hookAttachment modelToWorld _ropeOrigin), 0.5, 0.5, 0, format ["Rope: %1", _forEachIndex], 0.5, 0.025, "TahomaB"]; + } forEach (getArray (_config >> QGVAR(ropeOrigins))); + }; + if (_enabled == 2) then { + drawIcon3D ["", [.5,1,.5,1], (cursorObject modelToWorld getArray (_config >> QGVAR(friesAttachmentPoint))), 0.5, 0.5, 0, format ["Fries: %1", getText (_config >> QGVAR(friesType))], 0.5, 0.025, "TahomaB"]; + }; +}]; +#endif diff --git a/addons/fastroping/XEH_preInit.sqf b/addons/fastroping/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/fastroping/XEH_preInit.sqf +++ b/addons/fastroping/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; 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..969d719796 100644 --- a/addons/fastroping/functions/fnc_canCloseRamp.sqf +++ b/addons/fastroping/functions/fnc_canCloseRamp.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the player can close the ramp of the given helo. @@ -11,12 +12,10 @@ * Able to close ramp * * Example: - * [_player, _vehicle] call ace_fastroping_fnc_canCloseRamp + * [_vehicle, _door, _turretPaths] call ace_fastroping_fnc_canCloseRamp * * Public: No */ - -#include "script_component.hpp" params ["_vehicle", "_door", "_turretPaths"]; (_vehicle doorPhase _door > 0.5) && diff --git a/addons/fastroping/functions/fnc_canCutRopes.sqf b/addons/fastroping/functions/fnc_canCutRopes.sqf index 9775b155bb..8107b8066b 100644 --- a/addons/fastroping/functions/fnc_canCutRopes.sqf +++ b/addons/fastroping/functions/fnc_canCutRopes.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can cut deployed ropes. @@ -13,10 +14,9 @@ * * Public: No */ - -#include "script_component.hpp" 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..5bc770c01d 100644 --- a/addons/fastroping/functions/fnc_canDeployRopes.sqf +++ b/addons/fastroping/functions/fnc_canDeployRopes.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can deploy ropes from the helicopter. @@ -14,14 +15,11 @@ * * Public: No */ - -#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..b4f5e20474 100644 --- a/addons/fastroping/functions/fnc_canFastRope.sqf +++ b/addons/fastroping/functions/fnc_canFastRope.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can fast rope from the helicopter. @@ -10,17 +11,15 @@ * Able to fast ropes * * Example: - * [_player, _vehicle] call ace_fastroping_fnc_canDeployRopes + * [_player, _vehicle] call ace_fastroping_fnc_canFastRope * * Public: No */ - -#include "script_component.hpp" params ["_unit", "_vehicle"]; private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; ((driver _vehicle != _unit) && {!(_deployedRopes isEqualTo [])} && -{{!(_x select 5)} count (_deployedRopes) > 0} && +{{!(_x select 5) && !(_x select 6)} count (_deployedRopes) > 0} && {getPos _vehicle select 2 > 2}) diff --git a/addons/fastroping/functions/fnc_canPrepareFRIES.sqf b/addons/fastroping/functions/fnc_canPrepareFRIES.sqf index 67e2165c3f..881996b5a1 100644 --- a/addons/fastroping/functions/fnc_canPrepareFRIES.sqf +++ b/addons/fastroping/functions/fnc_canPrepareFRIES.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit can prepare the helicopters FRIES. @@ -13,8 +14,6 @@ * * Public: No */ - -#include "script_component.hpp" params ["_vehicle"]; private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; diff --git a/addons/fastroping/functions/fnc_canStowFRIES.sqf b/addons/fastroping/functions/fnc_canStowFRIES.sqf new file mode 100644 index 0000000000..6f26fc1ed5 --- /dev/null +++ b/addons/fastroping/functions/fnc_canStowFRIES.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * 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 + */ +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_checkVehicleThread.sqf b/addons/fastroping/functions/fnc_checkVehicleThread.sqf index 38a2cad8c6..7889cdb268 100644 --- a/addons/fastroping/functions/fnc_checkVehicleThread.sqf +++ b/addons/fastroping/functions/fnc_checkVehicleThread.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the given helicopter still exits, and if not, destroys the FRIES. @@ -14,8 +15,6 @@ * * Public: No */ - -#include "script_component.hpp" params ["_vehicle", "_fries"]; if (isNull _vehicle) then { diff --git a/addons/fastroping/functions/fnc_cutRopes.sqf b/addons/fastroping/functions/fnc_cutRopes.sqf index d619a24297..ae1b58638a 100644 --- a/addons/fastroping/functions/fnc_cutRopes.sqf +++ b/addons/fastroping/functions/fnc_cutRopes.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Cut deployed ropes. @@ -13,12 +14,9 @@ * * Public: No */ - -#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 +38,7 @@ _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; +// Set new state (0 if no FRIES, 2 if FRIES for manual stowing) +private _newState = [0, 2] select (isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(onCut))); +_vehicle setVariable [QGVAR(deploymentStage), _newState, true]; diff --git a/addons/fastroping/functions/fnc_deployAI.sqf b/addons/fastroping/functions/fnc_deployAI.sqf index 843f23cdb5..f6f3915181 100644 --- a/addons/fastroping/functions/fnc_deployAI.sqf +++ b/addons/fastroping/functions/fnc_deployAI.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Auomatically deploy a helicopter filled with AI units. @@ -15,36 +16,33 @@ * * Public: Yes */ - -#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 { // Note: BIS_fnc_guiMessage causes a CTD with call, so spawn is used instead. ["deployAI was called with an invalid or non-existant vehicle.", QFUNC(deployAI)] spawn BIS_fnc_guiMessage; }; - ACE_LOGERROR('FUNC(deployAI): deployAI was called with an invalid or non-existant vehicle.'); + 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; }; - ACE_LOGERROR_1('FUNC(deployAI): You cannot fast rope from a "%1" helicopter.',getText (_config >> "DisplayName")); + ERROR_1('FUNC(deployAI): You cannot fast rope from a "%1" helicopter.',getText (_config >> "DisplayName")); }; if (_configEnabled == 2 && {isNull (_vehicle getVariable [QGVAR(FRIES), objNull])}) exitWith { if (hasInterface) then { [format ["""%1"" requires a FRIES for fastroping, but has not been equipped with one.", getText (_config >> "DisplayName")], QFUNC(deployAI)] spawn BIS_fnc_guiMessage; }; - ACE_LOGERROR_1('FUNC(deployAI): "%1" requires a FRIES for fastroping but has not been equipped with one.',getText (_config >> "DisplayName")); + 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 { @@ -52,15 +50,15 @@ if (_deploySpecial) then { }; if (_unitsToDeploy isEqualTo []) exitWith { - ACE_LOGWARNING_1('FUNC(deployAI): Found no units to deploy in "%1".',getText (_config >> "DisplayName")); + WARNING_1('FUNC(deployAI): Found no units to deploy in "%1".',getText (_config >> "DisplayName")); }; 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 9d8f4a03e2..20e3f704f6 100644 --- a/addons/fastroping/functions/fnc_deployAIWaypoint.sqf +++ b/addons/fastroping/functions/fnc_deployAIWaypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Waypoint function for the fast rope waypoint. @@ -7,21 +8,18 @@ * 1: Waypoint position * * Return Value: - * true + * true * * Example: * [_group, [6560, 12390, 0]] call ace_fastroping_fnc_deployAIWayoint * * Public: No */ - -#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_deployRopes.sqf b/addons/fastroping/functions/fnc_deployRopes.sqf index 6e61ed232d..bd286fb08d 100644 --- a/addons/fastroping/functions/fnc_deployRopes.sqf +++ b/addons/fastroping/functions/fnc_deployRopes.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Deploy ropes from the helicopter. @@ -13,8 +14,6 @@ * * Public: No */ - -#include "script_component.hpp" params ["_vehicle"]; private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; @@ -45,8 +44,8 @@ private _hookAttachment = _vehicle getVariable [QGVAR(FRIES), _vehicle]; _ropeTop addEventHandler ["RopeBreak", {[_this, "top"] call FUNC(onRopeBreak)}]; _ropeBottom addEventHandler ["RopeBreak", {[_this, "bottom"] call FUNC(onRopeBreak)}]; - //deployedRopes format: attachment point, top part of the rope, bottom part of the rope, attachTo helper object, occupied - _deployedRopes pushBack [_ropeOrigin, _ropeTop, _ropeBottom, _dummy, _hook, false]; + //deployedRopes format: attachment point, top part of the rope, bottom part of the rope, attachTo helper object, occupied, broken + _deployedRopes pushBack [_ropeOrigin, _ropeTop, _ropeBottom, _dummy, _hook, false, false]; false } count _ropeOrigins; diff --git a/addons/fastroping/functions/fnc_equipFRIES.sqf b/addons/fastroping/functions/fnc_equipFRIES.sqf index 6d714611be..a6dc469749 100644 --- a/addons/fastroping/functions/fnc_equipFRIES.sqf +++ b/addons/fastroping/functions/fnc_equipFRIES.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Equips the given helicopter with a FRIES. @@ -13,17 +14,14 @@ * * Public: No */ - -#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..9deb95b1a6 100644 --- a/addons/fastroping/functions/fnc_fastRope.sqf +++ b/addons/fastroping/functions/fnc_fastRope.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Lets the unit fast rope. @@ -14,17 +15,14 @@ * * Public: No */ - -#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 { + if (!(_x select 5) && !(_x select 6)) exitWith { _usableRope = _x; _usableRopeIndex = _forEachIndex; }; diff --git a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf index 72177bce00..c46e919bc5 100644 --- a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Local PerFrameHandler during fast roping. @@ -14,16 +15,23 @@ * * Public: No */ - -#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 2ebffe680e..ed9cad2255 100644 --- a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Server PerFrameHandler during fast roping. @@ -14,22 +15,25 @@ * * Public: No */ - -#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]; @@ -53,14 +57,19 @@ if (_hasBeenAttached && {isNull attachedTo _unit}) exitWith { _dummy setVelocity [0,0,-6]; //Check if fast rope is finished -if (((getPos _unit select 2) < 0.2) || {ropeLength _ropeTop == 34.5} || {vectorMagnitude (velocity _vehicle) > 5} || {!(alive _unit)} || {captive _unit}) exitWith { +if ( + ((getPos _unit select 2) < 0.2) + || {ropeLength _ropeTop == 34.5} + || {vectorMagnitude (velocity _vehicle) > 5} + || {!([_unit] call EFUNC(common,isAwake))} +) exitWith { detach _unit; //Reset rope 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 @@ -74,8 +83,8 @@ if (((getPos _unit select 2) < 0.2) || {ropeLength _ropeTop == 34.5} || {vectorM _ropeBottom addEventHandler ["RopeBreak", {[_this, "bottom"] call FUNC(onRopeBreak)}]; //Update deployedRopes array - _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; - _deployedRopes set [_ropeIndex, [_attachmentPoint, _ropeTop, _ropeBottom, _dummy, _hook, false]]; + private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; + _deployedRopes set [_ropeIndex, [_attachmentPoint, _ropeTop, _ropeBottom, _dummy, _hook, false, false]]; _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; [_pfhHandle] call CBA_fnc_removePerFrameHandler; diff --git a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf index 9bde56debe..33975168a6 100644 --- a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf +++ b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Equips synched helicopters with a FRIES. @@ -13,8 +14,6 @@ * * Public: No */ - -#include "script_component.hpp" params ["_module"]; private _synchedUnits = synchronizedObjects _module; diff --git a/addons/fastroping/functions/fnc_onCutCommon.sqf b/addons/fastroping/functions/fnc_onCutCommon.sqf index 004c176b65..1a32739eaa 100644 --- a/addons/fastroping/functions/fnc_onCutCommon.sqf +++ b/addons/fastroping/functions/fnc_onCutCommon.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * 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 @@ -13,34 +14,21 @@ * * Public: No */ - -#include "script_component.hpp" 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..76665dea71 100644 --- a/addons/fastroping/functions/fnc_onPrepareCommon.sqf +++ b/addons/fastroping/functions/fnc_onPrepareCommon.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * 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 @@ -13,28 +14,19 @@ * * Public: No */ - -#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 ed5f8bf1c8..023e53f762 100644 --- a/addons/fastroping/functions/fnc_onRopeBreak.sqf +++ b/addons/fastroping/functions/fnc_onRopeBreak.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Handles ropes breaking when deployed. @@ -9,35 +10,35 @@ * Return Value: * None * + * Example: + * [[array]], "top"] call ace_fastroping_fnc_onRopeBreak + * * Public: No */ - -#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; }; } forEach _deployedRopes; -_brokenRope set [5, true]; +_brokenRope set [6, 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..c5bac4deb1 100644 --- a/addons/fastroping/functions/fnc_prepareFRIES.sqf +++ b/addons/fastroping/functions/fnc_prepareFRIES.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Prepares the helicopters FRIES. @@ -13,16 +14,13 @@ * * Public: No */ - -#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..3b18a6dbe1 --- /dev/null +++ b/addons/fastroping/functions/fnc_stowFRIES.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * 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 + */ +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 bb0b891f2b..77c8168f8d 100644 --- a/addons/fastroping/script_component.hpp +++ b/addons/fastroping/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Fastroping #include "\z\ace\addons\main\script_mod.hpp" +// #define DRAW_FASTROPE_INFO // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FASTROPING @@ -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 fe62267b2c..085291ea19 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -7,10 +7,14 @@ Wyposaż FRIES Equiper le FRIES Equipar FRIES - Equipaggia la FRIES + Equipaggia il FRIES Vybavit FRIES Equipar FRIES Десантирование по канатам + FRIES を装備 + FRIES 장착 + 启用快速绳降及撤离系统 + 啟用快速繩降及撤離系統 Equips compatible helicopters with a Fast Rope Insertion Extraction System. @@ -18,14 +22,18 @@ Wyposaża kompatybilne helikoptery w zestaw Fast Rope Insertion Extraction System. Equipe les hélicoptères compatibles avec un Module Fast Rope Insertion Extraction System. Equipar helicoptero compatible con un Sistema de Inserción Extracción Fast Rope. - Equipagga l'elicottero compatibile con il Fast Rope Insertion Exstraction System + Equipagga l'elicottero compatibile con il Fast Rope Insertion Extraction System Vybavit kompatibilní vrtulníky systémem Fast Rope Insertion Extraction (FRIES). Equipa um helicóptero compatível com o Fast Rope Insertion Exctraction System. Снаряжает совместимые вертолеты оборудованием для спуска десанта по канатам. + ヘリコプターで Fast Rope Insertion Extraction System を使えるようにします + 패스트로프 투입 및 탈출 시스템을 호환되는 헬리콥터에 적용합니다. + 使可相容的直升机启用快速绳降及撤离系统 + 使可相容的直升機啟用快速繩降及撤離系統 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 @@ -33,6 +41,19 @@ Připravit systém slaňování Prepara sistema de descida rápida Подготовить канаты + ファスト ロープのシステムを準備 + 패스트로프 준비 + 准备快速绳降系统 + 準備快速繩降系統 + + + Stow fast roping system + Verstaue "Fast Roping"-System + Arrotola le corde + ファスト ロープのシステムを収容 + 收起快速繩降系統 + 收起快速绳降系统 + 패스트 로프 시스템 보관 Deploy ropes @@ -44,6 +65,10 @@ Připravit lana Jogar cordas Зацепить канаты + ロープを展開 + 줄 배치 + 部属绳索 + 部屬繩索 Fast rope @@ -51,10 +76,14 @@ Zjedź na linie Descendre à la corde Descender por la cuerda - Scendi sulla corda + Scendi dalla corda SLANIT Descida rápida Спуститься по канату + ファスト ロープをする + 강하하기 + 快速绳降 + 快速繩降 Cut ropes @@ -66,6 +95,10 @@ Odříznout lano Cortar cordas Обрезать канаты + ロープを切断 + 줄 자르기 + 剪掉绳索 + 剪掉繩索 Equip helicopter with FRIES @@ -73,10 +106,14 @@ Wyposaż helikopter w FRIES Equiper l'hélicoptère avec le FRIES Equipar helicoptero con FRIES - Equipaggia l'elicottero con FRIES + Equipaggia l'elicottero con il FRIES Vybavit vrtulník pomocí FRIES Equipar helicóptero com FRIES Снарядить вертолет канатами для спуска + ヘリコプターへ FRIES を装備 + 헬리콥터에 FRIES 장착 + 启用快速绳降及撤离系统给指定的直升机 + 啟用快速繩降及撤離系統給指定的直升機 Equips the selected helicopter with a Fast Rope Insertion Extraction System @@ -88,6 +125,10 @@ Vybavit vybraný vrtulník systémem Fast Rope Insertion Extraction (FRIES) Equipa um helicóptero selecionado com um sistema de Fast Rope Insertion Extraction System Снаряжает выбранный вертолет оборудованием для спуска десанта по канатам + 選択されたヘリコプターで Fast Rope Insertion Extraction System を使えるようにします。 + 선택된 헬리콥터에 패스트로프 투입 및 탈출 시스템을 장착합니다. + 使指定的直升机启用快速绳降及撤离系统 + 使指定的直升機啟用快速繩降及撤離系統 LET UNITS FAST ROPE @@ -96,6 +137,11 @@ Equipa o helicóptero selecionado com o Fast Rope Insertion Extraction System LAISSER LES UNITES UTILISER LA CORDE ДЕСАНТИРОВАНИЕ ПО КАНАТУ + ユニットへファスト ロープをさせる + ZJAZD NA LINACH + 让单位快速绳降 + 讓單位快速繩降 + 패스트 로프를 놓음 - \ No newline at end of file + diff --git a/addons/fcs/CfgEventHandlers.hpp b/addons/fcs/CfgEventHandlers.hpp index b477f93d6a..9c5c368307 100644 --- a/addons/fcs/CfgEventHandlers.hpp +++ b/addons/fcs/CfgEventHandlers.hpp @@ -17,7 +17,7 @@ class Extended_PostInit_EventHandlers { }; }; -class Extended_Init_EventHandlers { +class Extended_InitPost_EventHandlers { class Tank { class ADDON { serverInit = QUOTE(_this call FUNC(vehicleInit)); diff --git a/addons/fcs/CfgOptics.hpp b/addons/fcs/CfgOptics.hpp index aa68a6f68a..f8770d7327 100644 --- a/addons/fcs/CfgOptics.hpp +++ b/addons/fcs/CfgOptics.hpp @@ -11,110 +11,13 @@ h = 0; \ }; +class RscText; class RscControlsGroup; class RscMapControl; class RscInGameUI { class RscUnitInfo; - class RscUnitInfo_AH64D_gunner { - controls[] = {"CA_Distance","ACE_CA_Distance"}; - MACRO_RANGEFINDER - }; - class RscWeaponRangeFinder { - controls[] = {"CA_Distance","ACE_CA_Distance"}; - MACRO_RANGEFINDER - }; - class RscWeaponRangeFinderPAS13 { - MACRO_RANGEFINDER - }; - class RscOptics_Rangefinder: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscWeaponRangeFinderMAAWS { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscWeaponRangeFinderAbramsCom { - controls[] = {"CA_Distance","ACE_CA_Distance"}; - MACRO_RANGEFINDER - }; - class RscWeaponRangeFinderAbramsGun { - controls[] = {"CA_Distance","ACE_CA_Distance"}; - MACRO_RANGEFINDER - }; - class RscWeaponRangeFinderStrykerMGSGun { - controls[] = {"CA_Distance","ACE_CA_Distance"}; - MACRO_RANGEFINDER - }; - class RscOptics_crows: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_strider_commander { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - - class RscWeaponRangeZeroing: RscUnitInfo { - controls[] = {"CA_Zeroing", "CA_DistanceText", "CA_Distance","ACE_CA_Distance", "ACE_Rangehelper"}; - MACRO_RANGEFINDER - }; - class RscOptics_sos: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_nightstalker: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_tws: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_punisher { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_tws_sniper: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_SDV_periscope { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; class RscOptics_Heli_Attack_02_gunner: RscUnitInfo { class CA_IGUI_elements_group: RscControlsGroup { class controls { @@ -122,7 +25,7 @@ class RscInGameUI { }; }; }; - class Rsc_ACE_Helo_UI_Turret: RscUnitInfo { + class Rsc_ACE_Helo_UI_Turret: RscUnitInfo { // RscOptics_Heli_Attack_01_gunner onLoad = "[""onLoad"",_this,""RscUnitInfo"",'IGUI'] call (uinamespace getvariable 'BIS_fnc_initDisplay'); uiNamespace setVariable ['ACE_dlgRangefinder', _this select 0]; ((_this select 0) displayCtrl 151) ctrlSetTextColor [0, 0, 0, 0];"; class CA_IGUI_elements_group: RscControlsGroup { class controls { @@ -130,103 +33,30 @@ class RscInGameUI { }; }; }; - class RscOptics_Heli_Attack_01_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_UAV_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_UGV_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; + class RscOptics_APC_Tracked_01_gunner: RscUnitInfo { class CA_IGUI_elements_group: RscControlsGroup { class controls { - MACRO_RANGEFINDER + class CA_Distance: RscText {}; }; }; }; - class RscOptics_APC_Tracked_03_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_APC_Wheeled_01_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_APC_Wheeled_03_commander: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_APC_Wheeled_03_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_MBT_01_commander: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_MBT_01_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_MBT_02_commander: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_MBT_02_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - class RscOptics_MBT_03_gunner: RscUnitInfo { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER - }; - }; - }; - - // marksmen - class RscOptics_LaserDesignator_02 { - class CA_IGUI_elements_group: RscControlsGroup { - class controls { - MACRO_RANGEFINDER + class ACE_RscOptics_APC_Tracked_01_gunner: RscOptics_APC_Tracked_01_gunner { + class CA_IGUI_elements_group: CA_IGUI_elements_group { + class controls: controls { + // MACRO_RANGEFINDER + modify IDC of CA_Distance + class CA_Distance: CA_Distance { + idc = 151; + }; + class ACE_CA_Distance: CA_Distance { + idc = 1713151; + text = "----"; + }; + class ACE_Rangehelper: RscMapControl { + onDraw = "((ctrlParent (_this select 0)) displayCtrl 1713151) ctrlShow (cameraView == 'GUNNER');"; + w = 0; + h = 0; + }; }; }; }; diff --git a/addons/fcs/CfgVehicles.hpp b/addons/fcs/CfgVehicles.hpp index 82572f2c68..8461fcc05a 100644 --- a/addons/fcs/CfgVehicles.hpp +++ b/addons/fcs/CfgVehicles.hpp @@ -29,7 +29,6 @@ class CfgVehicles { condition = QUOTE(_player call FUNC(canResetFCS)); statement = QUOTE([ARR_2(vehicle _player,[_player] call DEFUNC(common,getTurretIndex))] call DFUNC(reset);); showDisabled = 0; - priority = 1; icon = ""; }; }; @@ -42,552 +41,57 @@ class CfgVehicles { condition = QUOTE(_player call FUNC(canResetFCS)); statement = QUOTE([ARR_2(vehicle _player,[_player] call DEFUNC(common,getTurretIndex))] call DFUNC(reset);); showDisabled = 0; - priority = 1; icon = ""; }; }; class Turrets { - class MainTurret: NewTurret { - GVAR(Enabled) = 1; // all tracked vehicles get one by default - class Turrets { - class CommanderOptics; - }; - }; + class MainTurret: NewTurret {}; }; }; class Tank_F: Tank { class Turrets { - class MainTurret: NewTurret { - GVAR(Enabled) = 1; // all tracked vehicles get one by default - class Turrets { - class CommanderOptics;//: CommanderOptics {}; - }; - }; + class MainTurret: NewTurret {}; }; }; - class Car_F: Car { - class Turrets { - class MainTurret; - }; - }; - - class Wheeled_APC_F: Car_F { - class Turrets { - class MainTurret: NewTurret { - class Turrets { - class CommanderOptics;//: CommanderOptics {}; - }; - }; - }; - }; - - class MRAP_01_base_F: Car_F {}; - - class MRAP_01_gmg_base_F: MRAP_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - GVAR(MaxDistance) = 2000; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - - class MRAP_01_hmg_base_F: MRAP_01_gmg_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ - }; - - class B_MRAP_01_F: MRAP_01_base_F { - class Turrets; - }; - - class MRAP_02_base_F: Car_F {}; - - class MRAP_02_hmg_base_F: MRAP_02_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - GVAR(MaxDistance) = 2000; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - - class MRAP_02_gmg_base_F: MRAP_02_hmg_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ - }; - - class O_MRAP_02_F: MRAP_02_base_F { - class Turrets; - }; - - class MRAP_03_base_F: Car_F { - class Turrets: Turrets { - class CommanderTurret: MainTurret { - GVAR(Enabled) = 0; - }; - }; - }; - - class MRAP_03_hmg_base_F: MRAP_03_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - GVAR(MaxDistance) = 2000; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - class CommanderTurret: CommanderTurret { - GVAR(Enabled) = 0; - }; - }; - }; - - class MRAP_03_gmg_base_F: MRAP_03_hmg_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - class CommanderTurret: CommanderTurret {}; - };*/ - }; - - class APC_Wheeled_01_base_F: Wheeled_APC_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret { - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; - }; - };*/ - }; - - class B_APC_Wheeled_01_base_F: APC_Wheeled_01_base_F {}; - - class B_APC_Wheeled_01_cannon_F: B_APC_Wheeled_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - - class APC_Wheeled_02_base_F: Wheeled_APC_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - GVAR(MaxDistance) = 2000; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - - // class CommanderOptics: CommanderOptics {}; - }; - }; - - class APC_Wheeled_03_base_F: Wheeled_APC_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - - /*class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - };*/ - }; - }; - }; - - class I_APC_Wheeled_03_base_F: APC_Wheeled_03_base_F {}; - - class I_APC_Wheeled_03_cannon_F: I_APC_Wheeled_03_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ - }; - class APC_Tracked_01_base_F: Tank_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret { - class Turrets; - }; - };*/ - }; - - class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ - }; - - class B_APC_Tracked_01_rcws_F: B_APC_Tracked_01_base_F { class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - GVAR(MaxDistance) = 2000; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - class CommanderOptics: CommanderOptics {}; + class MainTurret: MainTurret {}; }; }; - class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - //GVAR(Enabled) = 0; @todo - }; + class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; class B_APC_Tracked_01_AA_F: B_APC_Tracked_01_base_F { class Turrets: Turrets { class MainTurret: MainTurret { + GVAR(Enabled) = 1; + turretinfotype = "ACE_RscOptics_APC_Tracked_01_gunner"; + GVAR(MaxDistance) = 2000; discreteDistance[] = {}; discreteDistanceInitIndex = 0; magazines[] += {"ACE_120Rnd_35mm_ABM_shells_Tracer_Red"}; - - /*class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - };*/ }; }; }; class APC_Tracked_02_base_F: Tank_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret { - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; - }; - };*/ + class Turrets: Turrets { + class MainTurret: MainTurret {}; + }; }; class O_APC_Tracked_02_base_F: APC_Tracked_02_base_F {}; - - class O_APC_Tracked_02_cannon_F: O_APC_Tracked_02_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ - }; - class O_APC_Tracked_02_AA_F: O_APC_Tracked_02_base_F { class Turrets: Turrets { class MainTurret: MainTurret { + GVAR(Enabled) = 1; + turretinfotype = "ACE_RscOptics_APC_Tracked_01_gunner"; + GVAR(MaxDistance) = 2000; + discreteDistance[] = {}; + discreteDistanceInitIndex = 0; magazines[] += {"ACE_120Rnd_35mm_ABM_shells_Tracer_Green"}; - - /*class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - };*/ - }; - }; - }; - - class APC_Tracked_03_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - - /*class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - };*/ - }; - }; - }; - - class MBT_01_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - - /*class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - };*/ - }; - }; - }; - - class B_MBT_01_base_F: MBT_01_base_F {}; - - class B_MBT_01_cannon_F: B_MBT_01_base_F {}; - - class B_MBT_01_TUSK_F: B_MBT_01_cannon_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - - class Turrets: Turrets { - class CommanderOptics: CommanderOptics { - GVAR(Enabled) = 1; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - }; - }; - - class MBT_01_arty_base_F: MBT_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - - class Turrets: Turrets { - class CommanderOptics: CommanderOptics { - GVAR(Enabled) = 1; - GVAR(MaxDistance) = 2000; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - }; - }; - - class MBT_01_mlrs_base_F: MBT_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - //class Turrets; - }; - }; - }; - - class MBT_02_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - - class Turrets: Turrets { - class CommanderOptics: CommanderOptics { - GVAR(Enabled) = 1; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - }; - }; - - class MBT_02_arty_base_F: MBT_02_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; - - class Turrets: Turrets { - class CommanderOptics: CommanderOptics { - GVAR(Enabled) = 1; - GVAR(MaxDistance) = 2000; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - }; - }; - - class MBT_03_base_F: Tank_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - - class Turrets: Turrets { - class CommanderOptics: CommanderOptics { - GVAR(Enabled) = 1; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - }; - }; - - // SHIPS - class Ship: AllVehicles { - class Turrets { - class MainTurret; - }; - }; - - class Ship_F: Ship {}; - - class Boat_F: Ship_F {}; - - class Boat_Armed_01_base_F: Boat_F { - class Turrets: Turrets { - class FrontTurret: NewTurret { - GVAR(enabled) = 1; - GVAR(minDistance) = 100; - GVAR(maxDistance) = 2000; - GVAR(distanceInterval) = 5; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - class RearTurret: FrontTurret { - discreteDistance[] = {100,200,300,400,600,800,1000,1200}; // Originally inherited from FrontTurret - discreteDistanceInitIndex = 4; - }; - }; - }; - - // AIR VEHICLES - class Air: AllVehicles {}; - - class Helicopter: Air { - class Turrets { - class MainTurret; - }; - }; - - class Plane: Air {}; - - class Helicopter_Base_F: Helicopter { - class Turrets: Turrets { - class CopilotTurret; - }; - }; - - class Helicopter_Base_H: Helicopter_Base_F { - class Turrets: Turrets { - class CopilotTurret; - }; - }; - - class Heli_Light_01_base_F: Helicopter_Base_H { - /*class Turrets: Turrets { - class CopilotTurret: CopilotTurret {}; - };*/ - }; - - class Heli_Light_01_unarmed_base_F: Heli_Light_01_base_F {}; - - class B_Heli_Light_01_F: Heli_Light_01_unarmed_base_F { - /*class Turrets: Turrets { - class CopilotTurret: CopilotTurret {}; - };*/ - }; - - class Heli_Light_01_armed_base_F: Heli_Light_01_base_F { - /*class Turrets: Turrets { - class CopilotTurret: CopilotTurret {}; - };*/ - }; - - class Heli_Light_02_base_F: Helicopter_Base_H { - /*class Turrets: Turrets { - class CopilotTurret: CopilotTurret {}; - };*/ - }; - - class Plane_Base_F: Plane { - class Turrets { - class CopilotTurret; - }; - }; - - class Heli_Attack_01_base_F: Helicopter_Base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - - class Heli_Attack_02_base_F: Helicopter_Base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - - class Heli_Transport_01_base_F: Helicopter_Base_H { - /*class Turrets: Turrets { - class CopilotTurret: CopilotTurret {}; - class MainTurret: MainTurret {}; - class RightDoorGun: MainTurret {}; - };*/ - }; - - class Heli_Transport_02_base_F: Helicopter_Base_H { - /*class Turrets: Turrets { - class CopilotTurret: CopilotTurret {}; - };*/ - }; - - class Heli_light_03_base_F; - class I_Heli_light_03_base_F: Heli_light_03_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ - }; - class I_Heli_light_03_F: Heli_light_03_base_F { - /*class Turrets: Turrets { - class MainTurret: MainTurret {}; - };*/ - }; - - class Plane_CAS_01_base_F: Plane_Base_F { - class Turrets; - }; - - class Plane_CAS_02_base_F: Plane_Base_F { - class Turrets; - }; - - class Plane_Fighter_03_base_F: Plane_Base_F { - class Turrets; - }; - - // static weapons. - class StaticWeapon: LandVehicle { - class Turrets { - class MainTurret; //: NewTurret {}; - }; - }; - - class StaticMGWeapon: StaticWeapon {}; - - class HMG_01_base_F: StaticMGWeapon { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - GVAR(MinDistance) = 200; - GVAR(MaxDistance) = 2000; - GVAR(DistanceInterval) = 5; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; - }; - }; - }; - - class StaticGrenadeLauncher: StaticWeapon {}; - class GMG_TriPod: StaticGrenadeLauncher {}; - - class GMG_01_base_F: GMG_TriPod { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; - GVAR(MinDistance) = 200; - GVAR(MaxDistance) = 2000; - GVAR(DistanceInterval) = 5; - discreteDistance[] = {}; - discreteDistanceInitIndex = 0; }; }; }; diff --git a/addons/fcs/CfgWeapons.hpp b/addons/fcs/CfgWeapons.hpp index 760e39e2de..555060b119 100644 --- a/addons/fcs/CfgWeapons.hpp +++ b/addons/fcs/CfgWeapons.hpp @@ -1,15 +1,6 @@ class CfgWeapons { - // disable locking, so it doesn't interfere with our system class CannonCore; - class cannon_120mm: CannonCore { - canLock = 0; - ballisticsComputer = 0; - }; - class autocannon_Base_F: CannonCore { - canLock = 0; - ballisticsComputer = 0; - }; class autocannon_35mm: CannonCore { canLock = 0; ballisticsComputer = 4; //was "4 + 2", 2 is for manual zeroing, 4 is for the lead indicator - https://community.bistudio.com/wiki/A3_Locking_Review#ballisticsComputer diff --git a/addons/fcs/XEH_postInit.sqf b/addons/fcs/XEH_postInit.sqf index 02c9e72ae5..ef6e89d5cc 100644 --- a/addons/fcs/XEH_postInit.sqf +++ b/addons/fcs/XEH_postInit.sqf @@ -21,3 +21,7 @@ if (!hasInterface) exitWith {}; // Register event for global updates [QGVAR(forceUpdate), {[ACE_player] call FUNC(onForceUpdate)}] call CBA_fnc_addEventHandler; + +#ifdef DEBUG_MODE_FULL +call compile preprocessFileLineNumbers QPATHTOF(functions\dev_debugConfigs.sqf); +#endif diff --git a/addons/fcs/XEH_preInit.sqf b/addons/fcs/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/fcs/XEH_preInit.sqf +++ b/addons/fcs/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; 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/dev/test_debugConfigs.sqf b/addons/fcs/dev/test_debugConfigs.sqf new file mode 100644 index 0000000000..89fa6b0d31 --- /dev/null +++ b/addons/fcs/dev/test_debugConfigs.sqf @@ -0,0 +1,97 @@ +// PabstMirror +// ["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]; +private _problemUIs = []; +{ + private _vehicleType = configName _x; + { + private _turret = _x; + private _config = [_vehicleType, _turret] call CBA_fnc_getTurret; + if (!isNull _config) then { + private _aceFCS = (getNumber (_config >> "ACE_FCS_Enabled")) == 1; + + private _vanillaFCS = false; + private _weapons = getArray (_config >> "weapons"); + { + private _weapon = _x; + private _ballisticComputer = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ballisticsComputer"); + _ballisticComputer = [_ballisticComputer, 5] call ace_common_fnc_toBin; + if ((_ballisticComputer select [(count _ballisticComputer) - 5, 1]) == "1") then { + _vanillaFCS = true; + if (_aceFCS) then { + _testPass = false; + diag_log text format ["%1 -> %2: ACE FCS Enabled CONFLICTS with vanilla FCS [%3]", _vehicleType, _weapon, _ballisticComputer]; + }; + }; + } forEach _weapons; + + if (!(_weapons isEqualTo [])) then { + private _fcsMsg = switch (true) do { + // case ((!_vanillaFCS) && {!_aceFCS}): {"No FCS"}; + // case ((_vanillaFCS) && {_aceFCS}): {"CONFLICT FCS"}; + // case (_vanillaFCS): {"Vanilla FCS"}; + // case (_aceFCS): {"ACE FCS"}; + default {""}; + }; + if (_fcsMsg != "") then {diag_log text format ["%1: %2", _vehicleType, _fcsMsg];}; + }; + + if (_vanillaFCS) then { + private _dd = getArray (_config >> "discreteDistance"); + if (_dd isEqualTo []) exitWith {diag_log format ["%1->%2: discreteDistance with vanillaFCS [%3]", _vehicleType, _turret, _config];}; + }; + + if (true) then { + private _turretInfo = getText (_config >> "turretInfoType"); + private _infoConfig = configFile >> "RscInGameUI" >> _turretInfo; + if (!isNull _infoConfig) then { + private _idcList = []; + + private _fncGetIDCS = { + params ["_subConfig"]; + if (!isClass _subConfig) exitWith {diag_log "err";}; + private _controlsArray = getArray (_subConfig >> "controls"); + { + [_subConfig >> _x] call _fncGetIDCS; + } forEach _controlsArray; + private _controlsConfig = configProperties [(_subConfig >> "controls"), "isClass _x", true]; + { + [_x] call _fncGetIDCS; + } forEach _controlsConfig; + _idcList pushBack getNumber (_subConfig >> "idc"); + }; + [_infoConfig] call _fncGetIDCS; + + if (_aceFCS && {!(1713151 in _idcList)}) then { + _problemUIs pushBackUnique format ["%1: ACE_FCS, but missing ACE_CA_DIST", _turretInfo]; + }; + if (_aceFCS && {(198 in _idcList)}) then { + _problemUIs pushBackUnique format ["%1: ACE_FCS, but NEW Lazr CA_DIST", _turretInfo, _vehicleType]; + }; + if ((!_aceFCS) && {(1713151 in _idcList)}) then { + _problemUIs pushBackUnique format ["%1: Not ACE but has ACE_CA_DIST", _turretInfo, _vehicleType]; + }; + if (_vanillaFCS && {!(198 in _idcList)}) then { + _problemUIs pushBackUnique format ["%1: vanillaFCS but missing NEW Lazr CA_DIST [just a warning]", _turretInfo, _vehicleType]; + }; + }; + }; + }; + // } forEach [[0],[0,0]]; + } forEach [[0],[0,0], [1], [2]]; +} forEach _vehicles; + +_problemUIs sort true; + +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_adjustRange.sqf b/addons/fcs/functions/fnc_adjustRange.sqf index bed9389716..cb0e00c9c1 100644 --- a/addons/fcs/functions/fnc_adjustRange.sqf +++ b/addons/fcs/functions/fnc_adjustRange.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Adjusts the currently zeroed distance. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [bob, [], 5] call ace_fcs_fnc_adjustRange + * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_turret", "_delta"]; diff --git a/addons/fcs/functions/fnc_calculateSolution.sqf b/addons/fcs/functions/fnc_calculateSolution.sqf index 61bfbd8c58..8ceb0c62cf 100644 --- a/addons/fcs/functions/fnc_calculateSolution.sqf +++ b/addons/fcs/functions/fnc_calculateSolution.sqf @@ -1,22 +1,26 @@ +#include "script_component.hpp" /* * Author: VKing * Calculate FCS solution * * Arguments: - * 0: Vehicle - * 1: Turret - * 2: Target distance - * 3: Azimuth offset + * 0: Vehicle + * 1: Turret + * 2: Target distance + * 3: Azimuth offset * * Return Value: * None * + * Example: + * [car, [turret], 5, ?] call ace_fcs_fnc_calculateSolution + * * Public: No */ -#include "script_component.hpp" params ["_vehicle","_turret","_distance","_angleTarget"]; TRACE_4("params",_vehicle,_turret,_distance,_angleTarget); +private _FCSInitSpeed = []; private _FCSMagazines = []; private _FCSElevation = []; private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath); @@ -64,6 +68,7 @@ private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret private _offset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, _angleTarget, _distance]; _offset = parseNumber _offset; + _FCSInitSpeed pushBack _initSpeed; _FCSMagazines pushBack _magazine; _FCSElevation pushBack _offset; }; @@ -71,5 +76,6 @@ private _turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret } count (_vehicle magazinesTurret _turret); [_vehicle, format ["%1_%2", QGVAR(Distance), _turret], _distance] call EFUNC(common,setVariablePublic); +[_vehicle, format ["%1_%2", QGVAR(InitSpeed), _turret], _FCSInitSpeed] call EFUNC(common,setVariablePublic); [_vehicle, format ["%1_%2", QGVAR(Magazines), _turret], _FCSMagazines] call EFUNC(common,setVariablePublic); [_vehicle, format ["%1_%2", QGVAR(Elevation), _turret], _FCSElevation] call EFUNC(common,setVariablePublic); diff --git a/addons/fcs/functions/fnc_canResetFCS.sqf b/addons/fcs/functions/fnc_canResetFCS.sqf index cf0dcf2674..21811d9fd3 100644 --- a/addons/fcs/functions/fnc_canResetFCS.sqf +++ b/addons/fcs/functions/fnc_canResetFCS.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Called from config. Can player reset FCS? * * Arguments: - * Nothing + * None * * Return Value: * Boolean * + * Example: + * call ace_fcs_fnc_canResetFCS + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/fcs/functions/fnc_canUseFCS.sqf b/addons/fcs/functions/fnc_canUseFCS.sqf index de4af99d7a..a246d51f0c 100644 --- a/addons/fcs/functions/fnc_canUseFCS.sqf +++ b/addons/fcs/functions/fnc_canUseFCS.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Called from config. Returns true if the player is a gunner and the players current vehicle has a FCS. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" getNumber ([configFile >> "CfgVehicles" >> typeOf vehicle ACE_player, [ACE_player] call EFUNC(common,getTurretIndex)] call EFUNC(common,getTurretConfigPath) >> QGVAR(Enabled)) == 1 && {cameraView == "GUNNER"} diff --git a/addons/fcs/functions/fnc_canUseRangefinder.sqf b/addons/fcs/functions/fnc_canUseRangefinder.sqf index 7403c74ac1..b558240363 100644 --- a/addons/fcs/functions/fnc_canUseRangefinder.sqf +++ b/addons/fcs/functions/fnc_canUseRangefinder.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns true if the laser distance measurement can be read from the engine. @@ -8,9 +9,11 @@ * Return Value: * Boolean * + * Example: + * call ace_fcs_fnc_canUseRangeFinder + * * Public: No */ -#include "script_component.hpp" !isNull ((uiNamespace getVariable ["ACE_dlgRangefinder", displayNull]) displayCtrl 1713151) && {cameraView == "GUNNER"} // return diff --git a/addons/fcs/functions/fnc_firedEH.sqf b/addons/fcs/functions/fnc_firedEH.sqf index 4c9b7d8b85..0959708bb0 100644 --- a/addons/fcs/functions/fnc_firedEH.sqf +++ b/addons/fcs/functions/fnc_firedEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Adjusts the direction of a shell. Called from the unified fired EH only if the gunner is a player. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * call ace_fcs_fnc_firedEH + * * 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); @@ -19,17 +22,37 @@ private _FCSMagazines = _vehicle getVariable [format ["%1_%2", QGVAR(Magazines), if !(_magazine in _FCSMagazines) exitWith {}; +private _FCSInitSpeed = _vehicle getVariable format ["%1_%2", QGVAR(InitSpeed), _turret]; private _FCSElevation = _vehicle getVariable format ["%1_%2", QGVAR(Elevation), _turret]; -// GET ELEVATION OFFSET OF CURRENT MAGAZINE +// GET ELEVATION OFFSET AND INITSPEED OF CURRENT MAGAZINE private _offset = 0; - +private _initSpeed = 0; { if (_x == _magazine) exitWith { _offset = _FCSElevation select _forEachIndex; + _initSpeed = _FCSInitSpeed select _forEachIndex; }; } forEach _FCSMagazines; +// Calculate the correction due to vanilla zeroing +private _zeroDistance = currentZeroing _gunner; +if (_zeroDistance > 0) then { + private _weaponCombo = [_weapon, _magazine, _ammo, _zeroDistance]; + if !(_weaponCombo isEqualTo (_gunner getVariable [QGVAR(lastWeaponCombo), []])) then { + private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); + private _antiOffset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, 0, _zeroDistance]; + _antiOffset = parseNumber _antiOffset; + + _gunner setVariable [QGVAR(lastWeaponCombo), _weaponCombo]; + _gunner setVariable [QGVAR(lastAntiOffset), _antiOffset]; + }; + private _antiOffset = _gunner getVariable QGVAR(lastAntiOffset); + + _offset = _offset - _antiOffset; + TRACE_4("fired",_gunner, currentZeroing _gunner, _antiOffset, _offset); +}; + [_projectile, (_vehicle getVariable format ["%1_%2", QGVAR(Azimuth), _turret]), _offset, 0] call EFUNC(common,changeProjectileDirection); // Remove the platform velocity @@ -44,7 +67,7 @@ if (vectorMagnitude velocity _vehicle > 2) then { if (!local _gunner) exitWith {}; if (getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(Airburst)) == 1) then { - private _zeroing = _vehicle getVariable [format ["%1_%2", QGVAR(Distance), _turret], currentZeroing _vehicle]; + private _zeroing = _vehicle getVariable [format ["%1_%2", QGVAR(Distance), _turret], currentZeroing _gunner]; if (_zeroing < 50) exitWith {}; if (_zeroing > 1500) exitWith {}; diff --git a/addons/fcs/functions/fnc_getAngle.sqf b/addons/fcs/functions/fnc_getAngle.sqf index d2c51a9542..05add960fb 100644 --- a/addons/fcs/functions/fnc_getAngle.sqf +++ b/addons/fcs/functions/fnc_getAngle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Calculates the angle offset necessary to hit the current target. @@ -14,9 +15,11 @@ * Return Value: * offset from the current angle necessary to hit the target * + * Example: + * [1, 2, 3, 4, 5, 6, 7] call ace_fcs_fnc_getAngle + * * Public: No */ -#include "script_component.hpp" #define PRECISION 0.1 diff --git a/addons/fcs/functions/fnc_getRange.sqf b/addons/fcs/functions/fnc_getRange.sqf index ba49621047..0512359d1e 100644 --- a/addons/fcs/functions/fnc_getRange.sqf +++ b/addons/fcs/functions/fnc_getRange.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Read laser distance measurement from engine. @@ -11,9 +12,11 @@ * Return Value: * Measured distance * + * Example: + * [5, 6, 7, true] call ace_fcs_fnc_getRange + * * Public: No */ -#include "script_component.hpp" params [["_accuracy",1], ["_maxDistance",5000], ["_minDistance",0], ["_blank",false]]; diff --git a/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf b/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf index aa166ece12..a2fe8a2b7f 100644 --- a/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf +++ b/addons/fcs/functions/fnc_handleAirBurstAmmunitionPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle Air burst ammunition. Called from per frame handler. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [[array]] call ace_fcs_fnc_handleAirBurstAummunitionPFH + * * Public: No */ -#include "script_component.hpp" (_this select 0) params ["_vehicle", "_projectile", "_zeroing"]; diff --git a/addons/fcs/functions/fnc_keyDown.sqf b/addons/fcs/functions/fnc_keyDown.sqf index 3c4943badf..0e141c0968 100644 --- a/addons/fcs/functions/fnc_keyDown.sqf +++ b/addons/fcs/functions/fnc_keyDown.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Starts watching the target for sideways correction. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [car, [turret]] call ace_fcs_fnc_keyDown + * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_turret"]; diff --git a/addons/fcs/functions/fnc_keyUp.sqf b/addons/fcs/functions/fnc_keyUp.sqf index a07f5d5d35..fb3ce99974 100644 --- a/addons/fcs/functions/fnc_keyUp.sqf +++ b/addons/fcs/functions/fnc_keyUp.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Calculates the offsets for all weapons needed to hit the current target. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [car, [turret]] call ace_fcs_fnc_keyUp + * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_turret", "_distance", ["_showHint", false], ["_playSound", true]]; TRACE_5("params",_vehicle,_turret,_distance,_showHint,_playSound); diff --git a/addons/fcs/functions/fnc_onForceUpdate.sqf b/addons/fcs/functions/fnc_onForceUpdate.sqf index 2c6d136300..ddf426d293 100644 --- a/addons/fcs/functions/fnc_onForceUpdate.sqf +++ b/addons/fcs/functions/fnc_onForceUpdate.sqf @@ -1,4 +1,19 @@ #include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * Nothing + * + * Return Value: + * None + * + * Example: + * call ace_fcs_fnc_onForceUpdate + * + * Public: No + */ params ["_unit"]; diff --git a/addons/fcs/functions/fnc_reset.sqf b/addons/fcs/functions/fnc_reset.sqf index dcb1718b3f..4cbc4ee7b2 100644 --- a/addons/fcs/functions/fnc_reset.sqf +++ b/addons/fcs/functions/fnc_reset.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Resets the FCS to default. @@ -7,11 +8,13 @@ * 1: Turret * * Return Value: - * none + * None + * + * Example: + * [car, [turret]] call ace_fcs_fnc_reset * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_turret"]; diff --git a/addons/fcs/functions/fnc_updateRangeHUD.sqf b/addons/fcs/functions/fnc_updateRangeHUD.sqf index 0bb15b2507..a00de5fc67 100644 --- a/addons/fcs/functions/fnc_updateRangeHUD.sqf +++ b/addons/fcs/functions/fnc_updateRangeHUD.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Update compatible info elements. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * call ace_fcs_fnc_updateRangeHUD + * * Public: No */ -#include "script_component.hpp" disableSerialization; private _dlgRangefinder = uiNamespace getVariable ["ACE_dlgRangefinder", displayNull]; diff --git a/addons/fcs/functions/fnc_vehicleInit.sqf b/addons/fcs/functions/fnc_vehicleInit.sqf index 901e0477ab..7117a12112 100644 --- a/addons/fcs/functions/fnc_vehicleInit.sqf +++ b/addons/fcs/functions/fnc_vehicleInit.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Checks if a vehicle is equipped with an FCS and if so, adds the fired event handler. Execute on server. * * Arguments: - * 0: Vehicle + * 0: Vehicle * * Return Value: - * none + * None + * + * Example: + * [car] call ace_fcs_fnc_vehicleInit * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; @@ -25,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/script_component.hpp b/addons/fcs/script_component.hpp index 6f5aa2cc86..805d723cd7 100644 --- a/addons/fcs/script_component.hpp +++ b/addons/fcs/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FCS diff --git a/addons/fcs/stringtable.xml b/addons/fcs/stringtable.xml index 2623351972..93d8121058 100644 --- a/addons/fcs/stringtable.xml +++ b/addons/fcs/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,10 +12,14 @@ Célpont lézerezése / Távolság Bemérése Misura la distanza Marcar com laser / Medir Distância + レーザー ターゲット / 計測距離 + 목표까지 거리를 레이저로 취득 + 雷射指示目标 / 测量距离 + 雷射指示目標 / 測量距離 Zeroed To - Haltepunkt + Genullt auf Ajustado a Wyzerowany na Nastaveno na @@ -24,6 +28,10 @@ Nullázási táv Fixado em Azzeramento a + 次にゼロイン + 영점 조절 + 归零到 + 歸零到 Adjust FCS Range (Up) @@ -36,6 +44,10 @@ Ajustar distância do FCS (Acima) Aumentare la distanza dell'FCS Диапазон СУО (Выше) + FCS による距離を調節 (上げ) + 사통장치 거리 조정 (위로) + 调整火控系统距离 (上) + 調整火控系統距離 (上) Adjust FCS Range (Down) @@ -48,6 +60,10 @@ Ajustar distância do FCS (Abaixo) Ridurre la distanza dell'FCS Диапазон СУО (Ниже) + FCS による距離を調節 (下げ) + 사통장치 거리 조정 (아래로) + 调整火控系统距离 (下) + 調整火控系統距離 (下) Reset FCS @@ -60,6 +76,10 @@ Reiniciar FCS Azzeramento dell'FCS Обнулить СУО + FCS を初期化 + 사통장치 초기화 + 重置火控系统 + 重置火控系統 FCS has been reset. @@ -72,6 +92,10 @@ FCS reiniciado. L'FCS è stato azzerato СУО обнулен. + FCS は初期化されました + 사통장치 초기화됨 + 火控系统已被重置 + 火控系統已被重置 - \ No newline at end of file + 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/XEH_preInit.sqf b/addons/finger/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/finger/XEH_preInit.sqf +++ b/addons/finger/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/finger/functions/fnc_incomingFinger.sqf b/addons/finger/functions/fnc_incomingFinger.sqf index 5a970aa372..4706798f40 100644 --- a/addons/finger/functions/fnc_incomingFinger.sqf +++ b/addons/finger/functions/fnc_incomingFinger.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: TheDrill, PabstMirror * Recieve an finger event, adds to the array (or updates if already present) and starts PFEH if not already running @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_sourceUnit", "_fingerPosPrecise", "_distance"]; diff --git a/addons/finger/functions/fnc_keyPress.sqf b/addons/finger/functions/fnc_keyPress.sqf index b9231fb17b..5308c44e6c 100644 --- a/addons/finger/functions/fnc_keyPress.sqf +++ b/addons/finger/functions/fnc_keyPress.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: TheDrill, PabstMirror * On keypress, point and send position to nearby players @@ -13,12 +14,11 @@ * * Public: No */ -#include "script_component.hpp" 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) @@ -48,7 +48,7 @@ private _nearbyMen = (ACE_player nearObjects ["CAManBase", (GVAR(maxRange) + 2)] {alive _x} && {(_x == (vehicle _x)) || {(vehicle _x) isKindOf "StaticWeapon"}} && {GVAR(indicatorForSelf) || {_x != ACE_player}} && - {!(lineIntersects [(eyePos _x), _playerEyePosASL, ACE_player, _x])} && + {!(lineIntersects [(eyePos _x), _playerEyePosASL, vehicle ACE_player, vehicle _x])} && {[_x] call EFUNC(common,isPlayer)}) then { _sendFingerToPlayers pushBack _x; @@ -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 c5189f4562..7dd93ee7ae 100644 --- a/addons/finger/functions/fnc_moduleSettings.sqf +++ b/addons/finger/functions/fnc_moduleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Module for fingering settings @@ -8,13 +9,13 @@ * Return Value: * None * + * Example: + * [logic] call ace_finger_fnc_moduleSettings + * * Public: No */ -#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 94ea4fe067..bfb9995720 100644 --- a/addons/finger/functions/fnc_perFrameEH.sqf +++ b/addons/finger/functions/fnc_perFrameEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: TheDrill, PabstMirror * The perFrameEventHandler to draw the icons @@ -13,17 +14,17 @@ * * Public: No */ -#include "script_component.hpp" 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;}; private _iconSize = BASE_SIZE * 0.10713 * (call EFUNC(common,getZoom)); [+GVAR(fingersHash), { + //IGNORE_PRIVATE_WARNING ["_key", "_value"]; _value params ["_lastTime", "_pos", "_name"]; private _timeLeftToShow = _lastTime + FP_TIMEOUT - diag_tickTime; if (_timeLeftToShow <= 0) then { diff --git a/addons/finger/script_component.hpp b/addons/finger/script_component.hpp index 85abc395f5..690f814b0d 100644 --- a/addons/finger/script_component.hpp +++ b/addons/finger/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FINGER diff --git a/addons/finger/stringtable.xml b/addons/finger/stringtable.xml index 113b3e5c2e..9830c587a5 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,6 +21,10 @@ Mostrar el indicador de señalado a uno mismo Zobrazit ukázání směru pro sebe Mostra puntatore per te stesso + 自分に指差し表記を表示する + 자신이 가리키는곳을 보여줍니다 + 在自己身边显示指向标记 + 顯示指向指示器給自己 Render the indicator for the pointing player. This option doesn't affect whether the other players would see the indicator @@ -24,6 +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 @@ -36,6 +53,10 @@ Indicador de señalado Ukazování směru Indicatore di puntamento + 指差し表記 + 가리키기 표시기 + 指向标记 + 指向指示器 Color of the pointing indicator circle @@ -48,6 +69,10 @@ Color del círculo indicador que señala Barva kruhu pro ukázání směru Colore del cerchio dell'indicatore di puntamento + 指差し表記の円の色 + 가리키기의 원형 색상 + 指向标记颜色 + 指向指示器顏色 Action "point a finger at" @@ -60,6 +85,10 @@ Acción "apuntar con el dedo a" Akce "ukázat prstem na" Azione "punta il dito a" + "指差し"キー + "손가락으로 가리키기"행동 + 使"手指指向在" + 使"手指指向在" Points, and shows a virtual marker of where you are looking to nearby units. Can be held down. @@ -72,6 +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 @@ -84,6 +117,10 @@ Ajustes de señalado Nastavení ukázování směru Impostazioni puntamento + 指差し設定 + 가리키기 설정 + 指向设定 + 指向設定 Pointing Enabled @@ -96,6 +133,10 @@ Señalado habilitado Ukazování povoleno Puntamento abilitato + 指差しを有効 + 가리키기 활성화 + 指向系统启动 + 指向系統啟動 Pointing Max Range @@ -108,10 +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] @@ -120,6 +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公尺] - \ No newline at end of file + diff --git a/addons/flashlights/ACE_Arsenal_Stats.hpp b/addons/flashlights/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..7a5e7ea39a --- /dev/null +++ b/addons/flashlights/ACE_Arsenal_Stats.hpp @@ -0,0 +1,13 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_flashlightColor: statBase { + scope = 2; + priority = 1; + stats[] = {"ACE_Flashlight_Colour"}; + displayName = CSTRING(statMapLightColor); + showText = 1; + textStatement = QUOTE(getText (_this select 1 >> 'itemInfo' >> 'FlashLight' >> (_this select 0) select 0)); + condition = QUOTE(getText (_this select 1 >> 'itemInfo' >> 'FlashLight' >> (_this select 0) select 0) != ''); + tabs[] = {{}, {1,7}}; + }; +}; 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/config.cpp b/addons/flashlights/config.cpp index 734a47db86..eefeb782f1 100644 --- a/addons/flashlights/config.cpp +++ b/addons/flashlights/config.cpp @@ -17,3 +17,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/flashlights/script_component.hpp b/addons/flashlights/script_component.hpp index 3c89c041c5..9b2b9e30be 100644 --- a/addons/flashlights/script_component.hpp +++ b/addons/flashlights/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FLASHLIGHTS diff --git a/addons/flashlights/stringtable.xml b/addons/flashlights/stringtable.xml index d8719d95ae..e4764d097a 100644 --- a/addons/flashlights/stringtable.xml +++ b/addons/flashlights/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ Fulton MX-991 Fulton MX-991 Fulton MX-991 + フルトン MX-991 + Fulton MX-991 + Fulton MX-991手电筒 + Fulton MX-991 Flashlight with red filter. For use on map. @@ -22,6 +26,10 @@ Linterna con filtro rojo. Para su uso en el mapa. Torcia con filtro rosso. Da usare in mappa. Lampe torche avec un filtre rouge. Pour utilisation sur carte. + 赤色フィルタ付きのフラッシュライト。地図上でつかいます。 + 빨간색 필터가 달린 손전등입니다. 지도를 비출때 씁니다. + 拥有红色滤光片的手电筒。用来照亮地图。 + 擁有紅色濾光片的手電筒。用來照亮地圖。 Maglite XL50 @@ -33,6 +41,10 @@ Maglite XL50 Maglite XL50 Maglite XL50 + マグライト XL50 + Maglite XL50 + Maglite XL50手电筒 + Maglite XL50 White mini flashlight. For use on map. @@ -44,6 +56,10 @@ Mini linterna blanca. Para su uso en el mapa. Mini-torcia bianca. Da usare in mappa. Mini lampe torche blanche. Pour utilisation sur carte. + 白色光の小さなフラッシュライト。地図上でつかいます。 + 하얀색 조그마한 손전등. 지도를 비출때 씁니다. + 白色的迷你手电筒。用来照亮地图。 + 白色的迷你手電筒。用來照亮地圖。 KSF-1 @@ -55,10 +71,14 @@ KSF-1 KSF-1 KSF-1 + KSF-1 + KSF-1 + KSF-1手电筒 + KSF-1 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. Фонарь с красным светофильтром. Для использования на карте. @@ -66,6 +86,18 @@ Linterna con filtro rojo. Para su uso en el mapa. Torcia con filtro rosso. Da usare in mappa. Lampe torche avec un filtre rouge. Pour utilisation sur carte. + 赤色フィルタ付きのフラッシュライト。地図上でつかいます。 + 빨간색 필터가 달린 손전등입니다. 지도를 비출때 씁니다. + 拥有红色滤光片的手电筒。用来照亮地图。 + 擁有紅色濾光片的手電筒。用來照亮地圖。 + + + Map light color + Couleur de la lampe sur carte + 光の色 + 地图上手电的颜色 + 地圖上使用手電筒的顏色 + Colore della luce sulla mappa - \ No newline at end of file + diff --git a/addons/flashsuppressors/CfgWeapons.hpp b/addons/flashsuppressors/CfgWeapons.hpp index e807dc2ae9..bf5aee16f1 100644 --- a/addons/flashsuppressors/CfgWeapons.hpp +++ b/addons/flashsuppressors/CfgWeapons.hpp @@ -9,6 +9,12 @@ class asdg_MuzzleSlot_762: asdg_MuzzleSlot { // for 7.62x51 universal mount supp ACE_muzzle_mzls_B = 1; }; }; +class asdg_MuzzleSlot_65: asdg_MuzzleSlot_762 { // for 6.5 weapons, mostly to deal with BIS vanilla compatibility + class compatibleItems: compatibleItems { + ACE_muzzle_mzls_H = 1; + ACE_muzzle_mzls_B = 0; + }; +}; class asdg_MuzzleSlot_93x64: asdg_MuzzleSlot { // for 9.3x64 universal mount suppressors class compatibleItems { ACE_muzzle_mzls_93mmg = 1; @@ -19,6 +25,11 @@ class asdg_MuzzleSlot_9MM_SMG: asdg_MuzzleSlot { // for 9x19mm universal mount S ACE_muzzle_mzls_smg_02 = 1; }; }; +class asdg_MuzzleSlot_9MM: asdg_MuzzleSlot { // for 9x19mm universal mount pistol suppressors + class compatibleItems { + ACE_muzzle_mzls_smg_02 = 1; + }; +}; class asdg_MuzzleSlot_556: asdg_MuzzleSlot { // for 5.56x45 universal mount suppressors class compatibleItems { ACE_muzzle_mzls_L = 1; @@ -29,12 +40,16 @@ class asdg_MuzzleSlot_45ACP_SMG: asdg_MuzzleSlot { // for .45ACP universal mount ACE_muzzle_mzls_smg_01 = 1; }; }; +class asdg_MuzzleSlot_45ACP: asdg_MuzzleSlot { // for .45ACP universal mount pistol suppressors + class compatibleItems { + ACE_muzzle_mzls_smg_01 = 1; + }; +}; class asdg_MuzzleSlot_762MG: asdg_MuzzleSlot { // for 7.62, 6.5 and 5.56 universal mount MG suppressors class compatibleItems { ACE_muzzle_mzls_B = 1; }; }; - class MuzzleSlot; class CfgWeapons { @@ -44,100 +59,6 @@ class CfgWeapons { class WeaponSlotsInfo; }; - /* MX */ - class arifle_MX_Base_F: Rifle_Base_F { - class WeaponSlotsInfo; - }; - - class arifle_MXC_F: arifle_MX_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762 { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - class arifle_MX_F: arifle_MX_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762 { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - class arifle_MX_GL_F: arifle_MX_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762 { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - class arifle_MX_SW_F: arifle_MX_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762MG { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - class arifle_MXM_F: arifle_MX_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762 { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - - - /* Katiba */ - - class arifle_Katiba_Base_F: Rifle_Base_F { - class WeaponSlotsInfo; - }; - class arifle_Katiba_F: arifle_Katiba_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762 { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - class arifle_Katiba_C_F: arifle_Katiba_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762 { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - class arifle_Katiba_GL_F: arifle_Katiba_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: asdg_MuzzleSlot_762 { - class compatibleItems: compatibleItems { - ACE_muzzle_mzls_H = 1; - ACE_muzzle_mzls_B = 0; - }; - }; - }; - }; - - /* Other */ class LMG_Mk200_F: Rifle_Long_Base_F { class WeaponSlotsInfo: WeaponSlotsInfo { @@ -150,56 +71,6 @@ class CfgWeapons { }; }; - /* Pistols */ - - class Pistol; - class Pistol_Base_F: Pistol { - class WeaponSlotsInfo; - }; - - class hgun_P07_F: Pistol_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: MuzzleSlot { - linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE"; - compatibleItems[] += {"ACE_muzzle_mzls_smg_02"}; - }; - }; - }; - - class hgun_Rook40_F: Pistol_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: MuzzleSlot { - linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE"; - compatibleItems[] += {"ACE_muzzle_mzls_smg_02"}; - }; - }; - }; - - class hgun_ACPC2_F: Pistol_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: MuzzleSlot { - compatibleItems[] += {"ACE_muzzle_mzls_smg_01"}; - }; - }; - }; - - class hgun_Pistol_heavy_01_F: Pistol_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot: MuzzleSlot { - compatibleItems[] += {"ACE_muzzle_mzls_smg_01"}; - }; - }; - }; - - /*class hgun_Pistol_heavy_02_F: Pistol_Base_F { - class WeaponSlotsInfo: WeaponSlotsInfo { - class MuzzleSlot { - linkProxy = "\A3\data_f\proxies\weapon_slots\MUZZLE"; - compatibleItems[] += {"ACE_muzzle_mzls_smg_01"}; - }; - }; - };*/ - /* Flashsuppressors */ diff --git a/addons/flashsuppressors/script_component.hpp b/addons/flashsuppressors/script_component.hpp index cfc61f8990..6dcc21780a 100644 --- a/addons/flashsuppressors/script_component.hpp +++ b/addons/flashsuppressors/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FLASHSUPPRESSORS diff --git a/addons/flashsuppressors/stringtable.xml b/addons/flashsuppressors/stringtable.xml index f075f1aa34..52563ea1c4 100644 --- a/addons/flashsuppressors/stringtable.xml +++ b/addons/flashsuppressors/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Cache-flamme (6,5 mm) Пламегаситель (6,5 мм) Bocacha (6,5 mm) + 消炎器 (6.5 mm) + 소염기 (6.5 mm) + 消光器 (6.5 mm) + 消光器 (6.5 mm) Flash Suppressor (7.62 mm) @@ -24,6 +28,10 @@ Cache-flamme (7,62 mm) Пламегаситель (7,62 мм) Bocacha (7,62 mm) + 消炎器 (7.62 mm) + 소염기 (7.62 mm) + 消光器 (7.62 mm) + 消光器 (7.62 mm) Flash Suppressor (5.56 mm) @@ -36,6 +44,10 @@ Cache-flamme (5,56 mm) Пламегаситель (5,56 мм) Bocacha (5,56 mm) + 消炎器 (5.56 mm) + 소염기 (5.56 mm) + 消光器 (5.56 mm) + 消光器 (5.56 mm) Flash Suppressor (.45 ACP) @@ -48,6 +60,10 @@ Cache-flamme (.45 ACP) Пламегаситель (.45 ACP) Bocacha (.45 ACP) + 消炎器 (.45 ACP) + 소염기 (.45 ACP) + 消光器 (.45 ACP) + 消光器 (.45 ACP) Flash Suppressor (9 mm) @@ -60,6 +76,10 @@ Cache-flamme (9 mm) Пламегаситель (9 мм) Bocacha (9 mm) + 消炎器 (9 mm) + 소염기 (9 mm) + 消光器 (9 mm) + 消光器 (9 mm) Flash Suppressor (.338) @@ -72,6 +92,10 @@ Cache-flamme (.338) Пламегаситель (.338) Bocacha (.338) + 消炎器 (.338) + 소염기 (.338) + 消光器 (.338) + 消光器 (.338) Flash Suppressor (9.3 mm) @@ -84,6 +108,10 @@ Cache-flamme (9,3 mm) Пламегаситель (9,3 мм) Bocacha (9,3 mm) + 消炎器 (9.3 mm) + 소염기 (9.3 mm) + 消光器 (9.3 mm) + 消光器 (9.3 mm) - \ No newline at end of file + 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/fonts/script_component.hpp b/addons/fonts/script_component.hpp index 735276e31c..23e7f42f80 100644 --- a/addons/fonts/script_component.hpp +++ b/addons/fonts/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FONTS diff --git a/addons/frag/$PBOPREFIX$ b/addons/frag/$PBOPREFIX$ index ddf45c738b..bc4c9e8dc9 100644 --- a/addons/frag/$PBOPREFIX$ +++ b/addons/frag/$PBOPREFIX$ @@ -1 +1 @@ -z\ace\addons\frag \ No newline at end of file +z\ace\addons\frag diff --git a/addons/frag/ACE_Settings.hpp b/addons/frag/ACE_Settings.hpp index 4dfa172bb3..6d511d3c3d 100644 --- a/addons/frag/ACE_Settings.hpp +++ b/addons/frag/ACE_Settings.hpp @@ -25,21 +25,15 @@ class ACE_Settings { displayName = CSTRING(MaxTrack); description = CSTRING(MaxTrack_Desc); typeName = "SCALAR"; - value = 500; + value = 10; + sliderSettings[] = {0, 50, 10, -1}; }; class GVAR(maxTrackPerFrame) { category = CSTRING(Module_DisplayName); displayName = CSTRING(MaxTrackPerFrame); description = CSTRING(MaxTrackPerFrame_Desc); typeName = "SCALAR"; - value = 50; - }; - - class GVAR(enableDebugTrace) { - category = CSTRING(Module_DisplayName); - displayName = CSTRING(EnableDebugTrace); - description = CSTRING(EnableDebugTrace_Desc); - typeName = "BOOL"; - value = 0; + value = 10; + sliderSettings[] = {0, 50, 10, -1}; }; }; diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 3da01ac29b..00d2d62ad8 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -1,16 +1,31 @@ -#define BASE_DRAG -0.01 -#define HD_MULT 5 -#define BASE_DRAG_HD (BASE_DRAG*HD_MULT) +#define BASE_DRAG -0.01 +#define HD_MULT 5 +#define BASE_DRAG_HD (BASE_DRAG * HD_MULT) class CfgAmmo { - //class ace_arty_105mm_m1_m782_time; - //class ace_arty_105mm_m1_m782_prox: ace_arty_105mm_m1_m782_time {}; - //class ace_arty_105mm_m1_m782_delay: ace_arty_105mm_m1_m782_prox { - // GVAR(skip) = 1; - //}; - class Bo_GBU12_LGB; - class ACE_GBU12 : Bo_GBU12_LGB { + // ~~~~ Bombs: + class ammo_Bomb_LaserGuidedBase; + class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(metal) = 140000; + GVAR(charge) = 87000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = 1/2; + }; + class Bomb_04_F: ammo_Bomb_LaserGuidedBase { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(metal) = 140000; + GVAR(charge) = 87000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = 1/2; + }; + class BombCore; + class Bo_Mk82: BombCore { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; @@ -18,11 +33,9 @@ class CfgAmmo { GVAR(charge) = 87000; GVAR(gurney_c) = 2320; GVAR(gurney_k) = 1/2; - sideAirFriction = 0.04; - airFriction = 0.04; - laserLock = 0; }; + // ~~~~ Grenades: class GrenadeBase; class Grenade; class GrenadeHand: Grenade { @@ -47,41 +60,6 @@ class CfgAmmo { class SmokeShell: GrenadeHand { GVAR(skip) = 1; }; - - class RocketBase; - class R_Hydra_HE: RocketBase { - // Source: http://fas.org/man/dod-101/sys/missile/hydra-70.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 3850; - GVAR(charge) = 1040; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; - }; - //class R_57mm_HE: RocketBase { - // GVAR(skip) = 1; - //}; - - class R_80mm_HE: RocketBase { - GVAR(skip) = 1; - }; - - //class R_S8T_AT: RocketBase { - // GVAR(skip) = 1; - //}; - - class BombCore; - class Bo_Mk82: BombCore { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(metal) = 140000; - GVAR(charge) = 87000; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = 1/2; - }; - class G_40mm_HE: GrenadeBase { // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 GVAR(enabled) = 1; @@ -104,10 +82,8 @@ class CfgAmmo { GVAR(gurney_k) = 1/2; }; - class ACE_G_40mm_HEDP: G_40mm_HEDP { - }; - class ACE_G_40mm_HE: G_40mm_HE { - }; + class ACE_G_40mm_HEDP: G_40mm_HEDP {}; + class ACE_G_40mm_HE: G_40mm_HE {}; class ACE_G_40mm_Practice: ACE_G_40mm_HE { GVAR(skip) = 1; GVAR(force) = 0; @@ -117,6 +93,94 @@ class CfgAmmo { GVAR(force) = 1; }; + + // ~~~~ RPGs: + class MissileBase; + class R_PG32V_F; + class R_TBG32V_F: R_PG32V_F { // HE + GVAR(enabled) = 1; + GVAR(metal) = 400; + GVAR(charge) = 210; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {"ACE_frag_medium_HD"}; + }; + class M_Titan_AA: MissileBase { + GVAR(skip) = 1; + }; + class M_Titan_AT: MissileBase { + GVAR(skip) = 1; + }; + class M_Titan_AP: M_Titan_AT { // "anti personnel" + GVAR(skip) = 0; + GVAR(enabled) = 1; + GVAR(metal) = 400; + GVAR(charge) = 210; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {"ACE_frag_medium_HD"}; + }; + + + // ~~~~ Missiles: + class M_PG_AT; + class M_AT: M_PG_AT { // DAR (Hydra 70) + // Source: http://fas.org/man/dod-101/sys/missile/hydra-70.htm + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 3850; + GVAR(charge) = 1040; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = 1/2; + }; + class RocketBase; + class R_80mm_HE: RocketBase { + GVAR(skip) = 1; + }; + class Missile_AGM_02_F: MissileBase { + // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 56250; + GVAR(charge) = 39000; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = 1/2; + }; + class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) + GVAR(enabled) = 1; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 3850; + GVAR(charge) = 1040; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = 1/2; + }; + class M_Scalpel_AT: MissileBase { // 9K121 Vikhr + GVAR(enabled) = 1; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 10000; + GVAR(charge) = 3000; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = 1/2; + }; + class ACE_Hellfire_AGM114K: M_Scalpel_AT { + // Source: http://www.designation-systems.net/dusrm/m-114.html + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 8000; + GVAR(charge) = 2400; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = 1/2; + }; + class M_Air_AA: MissileBase { + GVAR(skip) = 1; + }; + class Missile_AA_04_F: MissileBase { + GVAR(skip) = 1; + }; + // curator ammo entries class ShellBase; class Sh_125mm_HEAT; @@ -130,7 +194,7 @@ class CfgAmmo { GVAR(gurney_c) = 2440; GVAR(gurney_k) = 1/2; }; - class Sh_82mm_AMOS : Sh_155mm_AMOS { + class Sh_82mm_AMOS: Sh_155mm_AMOS { // Source: http://www.arsenal-bg.com/defense_police/mortar_bombs_82mm.htm GVAR(enabled) = 1; @@ -149,7 +213,7 @@ class CfgAmmo { GVAR(gurney_c) = 2320; GVAR(gurney_k) = 1/2; }; - class Sh_105mm_HEAT_MP : Sh_125mm_HEAT { + class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; @@ -158,7 +222,7 @@ class CfgAmmo { GVAR(gurney_c) = 2800; GVAR(gurney_k) = 1/2; }; - class Sh_120mm_HE : ShellBase { + class Sh_120mm_HE: ShellBase { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; @@ -186,200 +250,6 @@ class CfgAmmo { GVAR(gurney_k) = 1/2; }; - //class R_230mm_HE; - //class ModuleOrdnanceRocket_F_ammo: R_230mm_HE { - //}; - - //class R_230mm_fly; - //class ModuleOrdnanceRocket_F_subammo: R_230mm_fly { - //}; - // end of curator ammo entries - - //class R_SMAW_HEDP; - //class R_MEEWS_HEDP : R_SMAW_HEDP { - // GVAR(force) = 1; - // GVAR(multiplier) = 1.2; - //}; - - class MissileBase; - class Missile_AGM_02_F : MissileBase { - // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 56250; - GVAR(charge) = 39000; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; - }; - class M_Hellfire_AT: MissileBase { - // Source: http://www.designation-systems.net/dusrm/m-114.html - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 8000; - GVAR(charge) = 2400; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = 1/2; - }; - - /* - class B_762x51_Ball; - class GVAR(base): B_762x51_Ball { ////TODO: B_762x45_Ball no longer exists, is this a valid replacement? - model = "\A3\Weapons_f\ammo\shell"; - timeToLive = 12; - typicalSpeed = 800; - // Fix sounds - effectFly = "AmmoClassic"; - soundDefault1[] = {"A3\sounds_f\weapons\hits\concrete_1.wav",0.158114,1,30}; - soundDefault2[] = {"A3\sounds_f\weapons\hits\concrete_2.wav",0.158114,1,30}; - soundDefault3[] = {"A3\sounds_f\weapons\hits\concrete_3.wav",0.158114,1,30}; - soundDefault4[] = {"A3\sounds_f\weapons\hits\concrete_4.wav",0.158114,1,30}; - soundDefault5[] = {"A3\sounds_f\weapons\hits\concrete_5.wav",0.158114,1,30}; - soundDefault6[] = {"A3\sounds_f\weapons\hits\concrete_6.wav",0.158114,1,30}; - soundDefault7[] = {"A3\sounds_f\weapons\hits\concrete_7.wav",0.158114,1,30}; - soundDefault8[] = {"A3\sounds_f\weapons\hits\concrete_8.wav",0.158114,1,30}; - soundGroundSoft1[] = {"A3\sounds_f\weapons\hits\soft_ground_1.wav",0.02811705,1,30}; - soundGroundSoft2[] = {"A3\sounds_f\weapons\hits\soft_ground_2.wav",0.02811705,1,30}; - soundGroundSoft3[] = {"A3\sounds_f\weapons\hits\soft_ground_3.wav",0.02811705,1,30}; - soundGroundSoft4[] = {"A3\sounds_f\weapons\hits\soft_ground_4.wav",0.02811705,1,30}; - soundGroundSoft5[] = {"A3\sounds_f\weapons\hits\soft_ground_5.wav",0.02811705,1,30}; - soundGroundSoft6[] = {"A3\sounds_f\weapons\hits\soft_ground_6.wav",0.02811705,1,30}; - soundGroundSoft7[] = {"A3\sounds_f\weapons\hits\soft_ground_7.wav",0.02811705,1,30}; - soundGroundSoft8[] = {"A3\sounds_f\weapons\hits\soft_ground_8.wav",0.02811705,1,30}; - soundGroundHard1[] = {"A3\sounds_f\weapons\hits\hard_ground_1.wav",0.62946,1,40}; - soundGroundHard2[] = {"A3\sounds_f\weapons\hits\hard_ground_2.wav",0.62946,1,40}; - soundGroundHard3[] = {"A3\sounds_f\weapons\hits\hard_ground_3.wav",0.62946,1,40}; - soundGroundHard4[] = {"A3\sounds_f\weapons\hits\hard_ground_4.wav",0.62946,1,40}; - soundGroundHard5[] = {"A3\sounds_f\weapons\hits\hard_ground_5.wav",0.62946,1,40}; - soundGroundHard6[] = {"A3\sounds_f\weapons\hits\hard_ground_6.wav",0.62946,1,40}; - soundGroundHard7[] = {"A3\sounds_f\weapons\hits\hard_ground_7.wav",0.62946,1,40}; - soundGroundHard8[] = {"A3\sounds_f\weapons\hits\hard_ground_8.wav",0.62946,1,40}; - soundMetal1[] = {"A3\sounds_f\weapons\hits\metal_1.wav",0.158114,1,45}; - soundMetal2[] = {"A3\sounds_f\weapons\hits\metal_2.wav",0.158114,1,45}; - soundMetal3[] = {"A3\sounds_f\weapons\hits\metal_3.wav",0.158114,1,45}; - soundMetal4[] = {"A3\sounds_f\weapons\hits\metal_4.wav",0.158114,1,45}; - soundMetal5[] = {"A3\sounds_f\weapons\hits\metal_5.wav",0.158114,1,45}; - soundMetal6[] = {"A3\sounds_f\weapons\hits\metal_6.wav",0.158114,1,45}; - soundMetal7[] = {"A3\sounds_f\weapons\hits\metal_7.wav",0.158114,1,45}; - soundMetal8[] = {"A3\sounds_f\weapons\hits\metal_8.wav",0.158114,1,45}; - soundGlass1[] = {"A3\sounds_f\weapons\hits\glass_1.wav",0.177828,1,25}; - soundGlass2[] = {"A3\sounds_f\weapons\hits\glass_2.wav",0.177828,1,25}; - soundGlass3[] = {"A3\sounds_f\weapons\hits\glass_3.wav",0.177828,1,25}; - soundGlass4[] = {"A3\sounds_f\weapons\hits\glass_4.wav",0.177828,1,25}; - soundGlass5[] = {"A3\sounds_f\weapons\hits\glass_5.wav",0.177828,1,25}; - soundGlass6[] = {"A3\sounds_f\weapons\hits\glass_6.wav",0.177828,1,25}; - soundGlass7[] = {"A3\sounds_f\weapons\hits\glass_7.wav",0.177828,1,25}; - soundGlass8[] = {"A3\sounds_f\weapons\hits\glass_8.wav",0.177828,1,25}; - soundGlassArmored1[] = {"A3\sounds_f\weapons\hits\glass_arm_1.wav",0.177828,1,30}; - soundGlassArmored2[] = {"A3\sounds_f\weapons\hits\glass_arm_2.wav",0.177828,1,30}; - soundGlassArmored3[] = {"A3\sounds_f\weapons\hits\glass_arm_3.wav",0.177828,1,30}; - soundGlassArmored4[] = {"A3\sounds_f\weapons\hits\glass_arm_4.wav",0.177828,1,30}; - soundGlassArmored5[] = {"A3\sounds_f\weapons\hits\glass_arm_5.wav",0.177828,1,30}; - soundGlassArmored6[] = {"A3\sounds_f\weapons\hits\glass_arm_6.wav",0.177828,1,30}; - soundGlassArmored7[] = {"A3\sounds_f\weapons\hits\glass_arm_7.wav",0.177828,1,30}; - soundGlassArmored8[] = {"A3\sounds_f\weapons\hits\glass_arm_8.wav",0.177828,1,30}; - soundVehiclePlate1[] = {"A3\sounds_f\weapons\hits\metal_plate_1.wav",0.281170,1,40}; - soundVehiclePlate2[] = {"A3\sounds_f\weapons\hits\metal_plate_2.wav",0.281170,1,40}; - soundVehiclePlate3[] = {"A3\sounds_f\weapons\hits\metal_plate_3.wav",0.281170,1,40}; - soundVehiclePlate4[] = {"A3\sounds_f\weapons\hits\metal_plate_4.wav",0.281170,1,40}; - soundVehiclePlate5[] = {"A3\sounds_f\weapons\hits\metal_plate_5.wav",0.281170,1,40}; - soundVehiclePlate6[] = {"A3\sounds_f\weapons\hits\metal_plate_6.wav",0.281170,1,40}; - soundVehiclePlate7[] = {"A3\sounds_f\weapons\hits\metal_plate_7.wav",0.281170,1,40}; - soundVehiclePlate8[] = {"A3\sounds_f\weapons\hits\metal_plate_8.wav",0.281170,1,40}; - soundWood1[] = {"A3\sounds_f\weapons\hits\wood_1.wav",0.158114,1,30}; - soundWood2[] = {"A3\sounds_f\weapons\hits\wood_2.wav",0.158114,1,30}; - soundWood3[] = {"A3\sounds_f\weapons\hits\wood_3.wav",0.158114,1,30}; - soundWood4[] = {"A3\sounds_f\weapons\hits\wood_4.wav",0.158114,1,30}; - soundWood5[] = {"A3\sounds_f\weapons\hits\wood_5.wav",0.158114,1,30}; - soundWood6[] = {"A3\sounds_f\weapons\hits\wood_6.wav",0.158114,1,30}; - soundWood7[] = {"A3\sounds_f\weapons\hits\wood_7.wav",0.158114,1,30}; - soundWood8[] = {"A3\sounds_f\weapons\hits\wood_8.wav",0.158114,1,30}; - soundHitBody1[] = {"A3\sounds_f\weapons\hits\body_1.wav",0.0177828,1,25}; - soundHitBody2[] = {"A3\sounds_f\weapons\hits\body_2.wav",0.0177828,1,25}; - soundHitBody3[] = {"A3\sounds_f\weapons\hits\body_3.wav",0.0177828,1,25}; - soundHitBody4[] = {"A3\sounds_f\weapons\hits\body_4.wav",0.0177828,1,25}; - soundHitBody5[] = {"A3\sounds_f\weapons\hits\body_5.wav",0.0177828,1,25}; - soundHitBody6[] = {"A3\sounds_f\weapons\hits\body_6.wav",0.0177828,1,25}; - soundHitBody7[] = {"A3\sounds_f\weapons\hits\body_7.wav",0.0177828,1,25}; - soundHitBody8[] = {"A3\sounds_f\weapons\hits\body_8.wav",0.0177828,1,25}; - soundHitBuilding1[] = {"A3\sounds_f\weapons\hits\building_1.wav",0.251189,1,30}; - soundHitBuilding2[] = {"A3\sounds_f\weapons\hits\building_2.wav",0.251189,1,30}; - soundHitBuilding3[] = {"A3\sounds_f\weapons\hits\building_3.wav",0.251189,1,30}; - soundHitBuilding4[] = {"A3\sounds_f\weapons\hits\building_4.wav",0.251189,1,30}; - soundHitBuilding5[] = {"A3\sounds_f\weapons\hits\building_5.wav",0.251189,1,30}; - soundHitBuilding6[] = {"A3\sounds_f\weapons\hits\building_6.wav",0.251189,1,30}; - soundHitBuilding7[] = {"A3\sounds_f\weapons\hits\building_7.wav",0.251189,1,30}; - soundHitBuilding8[] = {"A3\sounds_f\weapons\hits\building_8.wav",0.251189,1,30}; - soundHitFoliage1[] = {"A3\sounds_f\weapons\hits\foliage_1.wav",0.177828,1,25}; - soundHitFoliage2[] = {"A3\sounds_f\weapons\hits\foliage_2.wav",0.177828,1,25}; - soundHitFoliage3[] = {"A3\sounds_f\weapons\hits\foliage_3.wav",0.177828,1,25}; - soundHitFoliage4[] = {"A3\sounds_f\weapons\hits\foliage_4.wav",0.177828,1,25}; - soundHitFoliage5[] = {"A3\sounds_f\weapons\hits\foliage_5.wav",0.177828,1,25}; - soundHitFoliage6[] = {"A3\sounds_f\weapons\hits\foliage_6.wav",0.177828,1,25}; - soundHitFoliage7[] = {"A3\sounds_f\weapons\hits\foliage_7.wav",0.177828,1,25}; - soundHitFoliage8[] = {"A3\sounds_f\weapons\hits\foliage_8.wav",0.177828,1,25}; - soundPlastic1[] = {"A3\sounds_f\weapons\hits\plastic_1.wav",0.177828,1,25}; - soundPlastic2[] = {"A3\sounds_f\weapons\hits\plastic_2.wav",0.177828,1,25}; - soundPlastic3[] = {"A3\sounds_f\weapons\hits\plastic_3.wav",0.177828,1,25}; - soundPlastic4[] = {"A3\sounds_f\weapons\hits\plastic_4.wav",0.177828,1,25}; - soundPlastic5[] = {"A3\sounds_f\weapons\hits\plastic_5.wav",0.177828,1,25}; - soundPlastic6[] = {"A3\sounds_f\weapons\hits\plastic_6.wav",0.177828,1,25}; - soundPlastic7[] = {"A3\sounds_f\weapons\hits\plastic_7.wav",0.177828,1,25}; - soundPlastic8[] = {"A3\sounds_f\weapons\hits\plastic_8.wav",0.177828,1,25}; - soundConcrete1[] = {"A3\sounds_f\weapons\hits\concrete_1.wav",0.177828,1,35}; - soundConcrete2[] = {"A3\sounds_f\weapons\hits\concrete_2.wav",0.177828,1,35}; - soundConcrete3[] = {"A3\sounds_f\weapons\hits\concrete_3.wav",0.177828,1,35}; - soundConcrete4[] = {"A3\sounds_f\weapons\hits\concrete_4.wav",0.177828,1,35}; - soundConcrete5[] = {"A3\sounds_f\weapons\hits\concrete_5.wav",0.177828,1,35}; - soundConcrete6[] = {"A3\sounds_f\weapons\hits\concrete_6.wav",0.177828,1,35}; - soundConcrete7[] = {"A3\sounds_f\weapons\hits\concrete_7.wav",0.177828,1,35}; - soundConcrete8[] = {"A3\sounds_f\weapons\hits\concrete_8.wav",0.177828,1,35}; - soundRubber1[] = {"A3\sounds_f\weapons\hits\tyre_1.wav",0.158114,1,25}; - soundRubber2[] = {"A3\sounds_f\weapons\hits\tyre_2.wav",0.158114,1,25}; - soundRubber3[] = {"A3\sounds_f\weapons\hits\tyre_3.wav",0.158114,1,25}; - soundRubber4[] = {"A3\sounds_f\weapons\hits\tyre_4.wav",0.158114,1,25}; - soundRubber5[] = {"A3\sounds_f\weapons\hits\tyre_5.wav",0.158114,1,25}; - soundRubber6[] = {"A3\sounds_f\weapons\hits\tyre_6.wav",0.158114,1,25}; - soundRubber7[] = {"A3\sounds_f\weapons\hits\tyre_7.wav",0.158114,1,25}; - soundRubber8[] = {"A3\sounds_f\weapons\hits\tyre_8.wav",0.158114,1,25}; - soundWater1[] = {"A3\sounds_f\weapons\hits\water_01.wav",0.158114,1,25}; - soundWater2[] = {"A3\sounds_f\weapons\hits\water_02.wav",0.158114,1,25}; - soundWater3[] = {"A3\sounds_f\weapons\hits\water_03.wav",0.158114,1,25}; - soundWater4[] = {"A3\sounds_f\weapons\hits\water_04.wav",0.158114,1,25}; - soundWater5[] = {"A3\sounds_f\weapons\hits\water_05.wav",0.158114,1,25}; - soundWater6[] = {"A3\sounds_f\weapons\hits\water_06.wav",0.158114,1,25}; - soundWater7[] = {"A3\sounds_f\weapons\hits\water_07.wav",0.158114,1,25}; - soundWater8[] = {"A3\sounds_f\weapons\hits\water_08.wav",0.158114,1,25}; - hitGroundSoft[] = {"soundGroundSoft1",0.2,"soundGroundSoft2",0.2,"soundGroundSoft3",0.1,"soundGroundSoft4",0.1,"soundGroundSoft5",0.1,"soundGroundSoft6",0.1,"soundGroundSoft7",0.1,"soundGroundSoft8",0.1}; - hitGroundHard[] = {"soundGroundHard1",0.2,"soundGroundHard2",0.2,"soundGroundHard3",0.1,"soundGroundHard4",0.1,"soundGroundHard5",0.1,"soundGroundHard6",0.1,"soundGroundHard7",0.1,"soundGroundHard8",0.1}; - hitMan[] = {"soundHitBody1",0.125,"soundHitBody2",0.125,"soundHitBody3",0.125,"soundHitBody4",0.125,"soundHitBody5",0.125,"soundHitBody6",0.125,"soundHitBody7",0.125,"soundHitBody8",0.125}; - hitArmor[] = {"soundVehiclePlate1",0.125,"soundVehiclePlate2",0.125,"soundVehiclePlate3",0.125,"soundVehiclePlate4",0.125,"soundVehiclePlate5",0.125,"soundVehiclePlate6",0.125,"soundVehiclePlate7",0.125,"soundVehiclePlate8",0.125}; - hitBuilding[] = {"soundHitBuilding1",0.2,"soundHitBuilding2",0.2,"soundHitBuilding3",0.1,"soundHitBuilding4",0.1,"soundHitBuilding5",0.1,"soundHitBuilding6",0.1,"soundHitBuilding7",0.1,"soundHitBuilding8",0.1}; - hitFoliage[] = {"soundHitFoliage1",0.125,"soundHitFoliage2",0.125,"soundHitFoliage3",0.125,"soundHitFoliage4",0.125,"soundHitFoliage5",0.125,"soundHitFoliage6",0.125,"soundHitFoliage7",0.125,"soundHitFoliage8",0.125}; - hitWood[] = {"soundWood1",0.125,"soundWood2",0.125,"soundWood3",0.125,"soundWood4",0.125,"soundWood5",0.125,"soundWood6",0.125,"soundWood7",0.125,"soundWood8",0.125}; - hitGlass[] = {"soundGlass1",0.125,"soundGlass2",0.125,"soundGlass3",0.125,"soundGlass4",0.125,"soundGlass5",0.125,"soundGlass6",0.125,"soundGlass7",0.125,"soundGlass8",0.125}; - hitGlassArmored[] = {"soundGlassArmored1",0.125,"soundGlassArmored2",0.125,"soundGlassArmored3",0.125,"soundGlassArmored4",0.125,"soundGlassArmored5",0.125,"soundGlassArmored6",0.125,"soundGlassArmored7",0.125,"soundGlassArmored8",0.125}; - hitConcrete[] = {"soundConcrete1",0.125,"soundConcrete2",0.125,"soundConcrete3",0.125,"soundConcrete4",0.125,"soundConcrete5",0.125,"soundConcrete6",0.125,"soundConcrete7",0.125,"soundConcrete8",0.125}; - hitRubber[] = {"soundRubber1",0.125,"soundRubber2",0.125,"soundRubber3",0.125,"soundRubber4",0.125,"soundRubber5",0.125,"soundRubber6",0.125,"soundRubber7",0.125,"soundRubber8",0.125}; - hitPlastic[] = {"soundPlastic1",0.125,"soundPlastic2",0.125,"soundPlastic3",0.125,"soundPlastic4",0.125,"soundPlastic5",0.125,"soundPlastic6",0.125,"soundPlastic7",0.125,"soundPlastic8",0.125}; - hitDefault[] = {"soundDefault1",0.2,"soundDefault2",0.2,"soundDefault3",0.1,"soundDefault4",0.1,"soundDefault5",0.1,"soundDefault6",0.1,"soundDefault7",0.1,"soundDefault8",0.1}; - hitMetal[] = {"soundMetal1",0.125,"soundMetal2",0.125,"soundMetal3",0.125,"soundMetal4",0.125,"soundMetal5",0.125,"soundMetal6",0.125,"soundMetal7",0.125,"soundMetal8",0.125}; - hitMetalplate[] = {"soundVehiclePlate1",0.125,"soundVehiclePlate2",0.125,"soundVehiclePlate3",0.125,"soundVehiclePlate4",0.125,"soundVehiclePlate5",0.125,"soundVehiclePlate6",0.125,"soundVehiclePlate7",0.125,"soundVehiclePlate8",0.125}; - hitWater[] = {"soundWater1",0.125,"soundWater2",0.125,"soundWater3",0.125,"soundWater4",0.125,"soundWater5",0.125,"soundWater6",0.125,"soundWater7",0.125,"soundWater8",0.125}; - bulletFly1[] = {"A3\sounds_f\weapons\hits\bullet_by_1.wav",1,1,35}; - bulletFly2[] = {"A3\sounds_f\weapons\hits\bullet_by_2.wav",1,1,35}; - bulletFly3[] = {"A3\sounds_f\weapons\hits\bullet_by_3.wav",1,1,35}; - bulletFly4[] = {"A3\sounds_f\weapons\hits\bullet_by_4.wav",1,1,35}; - bulletFly5[] = {"A3\sounds_f\weapons\hits\bullet_by_5.wav",1,1,35}; - bulletFly6[] = {"A3\sounds_f\weapons\hits\bullet_by_6.wav",1,1,35}; - bulletFly7[] = {"A3\sounds_f\weapons\hits\bullet_by_7.wav",1,1,35}; - bulletFly8[] = {"A3\sounds_f\weapons\hits\bullet_by_8.wav",1,1,35}; - bulletFly[] = {"bulletFly1",0.166,"bulletFly2",0.166,"bulletFly3",0.166,"bulletFly4",0.166,"bulletFly5",0.166,"bulletFly6",0.167,"bulletFly7",0.166,"bulletFly8",0.167}; - supersonicCrackNear[] = {"A3\sounds_f\weapons\hits\sscrack1.wav",1,1,35}; - supersonicCrackFar[] = {"A3\sounds_f\weapons\hits\sscrack2.wav",1,1,135}; - }; - */ class B_65x39_Caseless; class GVAR(base): B_65x39_Caseless { @@ -438,8 +308,6 @@ class CfgAmmo { indirectHitRange = 0.25; airFriction = BASE_DRAG_HD*0.65; caliber = 2; - - }; class GVAR(huge): GVAR(large) { diff --git a/addons/frag/CfgAmmoReflections.hpp b/addons/frag/CfgAmmoReflections.hpp index fdaac6dd90..513b58d544 100644 --- a/addons/frag/CfgAmmoReflections.hpp +++ b/addons/frag/CfgAmmoReflections.hpp @@ -1,5 +1,3 @@ -//CfgAmmoReflections.hpp - #define ACE_EXPLOSION_REFLECTION(range, hit)\ class ace_explosion_reflection_##range##_##hit : ace_explosion_reflection_base {\ indirectHitRange = range;\ diff --git a/addons/frag/CfgEventhandlers.hpp b/addons/frag/CfgEventhandlers.hpp index becf395052..0d3301d6e0 100644 --- a/addons/frag/CfgEventhandlers.hpp +++ b/addons/frag/CfgEventhandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 2fed1630f2..a7fb8ff8c3 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -7,22 +7,19 @@ PREP(spallTrack); // * Other */ PREP(addBlackList); -PREP(addTrack); -PREP(drawTraces); -PREP(removeTrack); +PREP(dev_addTrack); +PREP(dev_drawTraces); PREP(spallHP); -PREP(startTracing); -PREP(stopTracing); -PREP(trackTrace); +PREP(dev_startTracing); +PREP(dev_stopTracing); +PREP(dev_trackTrace); // New tracking mechanisms PREP(masterPFH); PREP(pfhRound); PREP(addPfhRound); -PREP(removePfhRound); // THIS SHOULD ABE USED SPARINGLY // Explosive Reflection -GVAR(replacedBisArtyWrapper) = true; PREP(findReflections); PREP(doExplosions); PREP(doReflections); diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index feb4be05b6..4126ca328c 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,28 +1,32 @@ #include "script_component.hpp" -if(GVAR(EnableDebugTrace) && !isMultiplayer) then { - GVAR(traceFrags) = true; - GVAR(autoTrace) = true; -}; - -if(isServer) then { - [QGVAR(frag_eh), { _this call FUNC(frago); }] call CBA_fnc_addEventHandler; +if (isServer) then { + GVAR(lastFragTime) = -1; + [QGVAR(frag_eh), {_this call FUNC(frago);}] call CBA_fnc_addEventHandler; }; ["ace_settingsInitialized", { - //If not enabled, exit if (!GVAR(enabled)) exitWith {}; // Register fire event handler - ["ace_firedPlayer", DFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayer", DFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", DFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", DFUNC(fired)] call CBA_fnc_addEventHandler; - - [FUNC(masterPFH), 0, []] call CBA_fnc_addPerFrameHandler; + ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + addMissionEventHandler ["EachFrame", {call FUNC(masterPFH)}]; }] call CBA_fnc_addEventHandler; -//Cache for ammo type configs -GVAR(cacheRoundsTypesToTrack) = createLocation ["ACE_HashLocation", [-10000,-10000,-10000], 0, 0]; -GVAR(cacheRoundsTypesToTrack) setText QGVAR(cacheRoundsTypesToTrack); +// Cache for ammo type configs +GVAR(cacheRoundsTypesToTrack) = [false] call CBA_fnc_createNamespace; + + +// Debug stuff: + +#ifdef DRAW_FRAG_INFO +[] call FUNC(dev_startTracing); +#endif + +#ifdef DEBUG_MODE_FULL +[true, true, 30] call FUNC(dev_debugAmmo); +#endif diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 9c03491a4e..7cbd6092a1 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -2,24 +2,22 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(blackList) = []; GVAR(traceFrags) = false; -GVAR(TOTALFRAGS) = 0; - GVAR(spallHPData) = []; GVAR(spallIsTrackingCount) = 0; -GVAR(autoTrace) = false; GVAR(traceID) = -1; GVAR(traces) = []; GVAR(tracesStarted) = false; GVAR(lastIterationIndex) = 0; GVAR(objects) = []; -GVAR(objectTypes) = []; GVAR(arguments) = []; ADDON = true; diff --git a/addons/frag/config.cpp b/addons/frag/config.cpp index 7ac109d29f..f3b409dbd0 100644 --- a/addons/frag/config.cpp +++ b/addons/frag/config.cpp @@ -1,4 +1,5 @@ #include "script_component.hpp" + class CfgPatches { class ADDON { name = COMPONENT_NAME; diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 1a7d7cb253..71452b9814 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -1,3 +1,21 @@ #include "script_component.hpp" +/* + * Author: Jaynus, NouberNou + * Adds a round to the blacklist (will be ignored). + * + * Arguments: + * 0: Projectile + * + * Return Value: + * None + * + * Example: + * [bullet] call ace_frag_fnc_addBlackList + * + * Public: No + */ + params ["_round"]; -GVAR(blackList) set [(count GVAR(blackList)), _round]; +TRACE_1("addBlackList",_round); + +GVAR(blackList) pushBack _round; diff --git a/addons/frag/functions/fnc_addPfhRound.sqf b/addons/frag/functions/fnc_addPfhRound.sqf index f0047bb24d..35b927e687 100644 --- a/addons/frag/functions/fnc_addPfhRound.sqf +++ b/addons/frag/functions/fnc_addPfhRound.sqf @@ -1,74 +1,77 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: Jaynus, NouberNou + * Starts tracking a round that will frag. + * Should only be called once per round. + * + * Arguments: + * 0: Shooter + * 1: Ammo classname + * 2: Projectile + * + * Return Value: + * None + * + * Example: + * [player, "handGrenade", bullet] call ace_frag_fnc_addPfhRound + * + * Public: No + */ -private ["_enabled", "_doSpall", "_spallTrack", "_spallTrackID"]; -PARAMS_3(_gun,_type,_round); -DEFAULT_PARAM(3,_doFragTrack,false); +params ["_gun", "_type", "_round"]; +TRACE_3("addPfhRound",_gun,_type,_round); -if (!GVAR(enabled)) exitWith {}; +if (!GVAR(enabled)) exitWith {TRACE_1("setting disabled",_this);}; -//_enabled = getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(enabled)); -//if(_enabled < 1) exitWith {}; +if (!alive _round) exitWith {TRACE_1("round dead?",_this);}; -if(_round in GVAR(blackList)) exitWith { - GVAR(blackList) = GVAR(blackList) - [_round]; +if (_round in GVAR(blackList)) exitWith { + TRACE_1("round in blackList",_this); + REM(GVAR(blackList),_round); }; // Exit on max track -if( (count GVAR(objects)) > GVAR(MaxTrack)) exitWith { }; +if ((count GVAR(objects)) >= GVAR(maxTrack)) exitWith {TRACE_1("maxTrack limit",count GVAR(objects));}; -if(_gun == ACE_player) then { - _doFragTrack = true; -} else { - if((gunner _gun) == ACE_player) then { - _doFragTrack = true; - } else { - if(local _gun && {!(isPlayer (gunner _gun))} && {!(isPlayer _gun)}) then { - _doFragTrack = true; - }; - }; -}; - -_doSpall = false; -if(GVAR(SpallEnabled)) then { - if(GVAR(spallIsTrackingCount) <= 0) then { +private _doSpall = false; +if (GVAR(SpallEnabled)) then { + if (GVAR(spallIsTrackingCount) <= 0) then { GVAR(spallHPData) = []; }; - if(GVAR(spallIsTrackingCount) > 5) then { - // ACE_player sideChat "LIMT!"; + if (GVAR(spallIsTrackingCount) > 5) then { + TRACE_1("At Spall Limit",GVAR(spallIsTrackingCount)); } else { _doSpall = true; - GVAR(spallIsTrackingCount) = GVAR(spallIsTrackingCount) + 1; + INC(GVAR(spallIsTrackingCount)); }; + TRACE_2("",_doSpall,GVAR(spallIsTrackingCount)); }; -// ACE_player sideChat format["c: %1", GVAR(spallIsTrackingCount)]; -if(GVAR(autoTrace)) then { - [ACE_player, _round, [1,0,0,1]] call FUNC(addTrack); -}; +#ifdef DRAW_FRAG_INFO +[ACE_player, _round, [0, 1, 0, 1]] call FUNC(dev_addTrack); +#endif // We only do the single track object check here. // We should do an {!(_round in GVAR(objects))} // But we leave that out here for optimization. So this cannot be a framework function // Otherwise, it should only be added once and from the FiredEH -if(_doFragTrack && {alive _round}) then { - _spallTrack = []; - _spallTrackID = []; +if (alive _round) then { + private _spallTrack = []; + private _spallTrackID = []; - private ["_args"]; - _args = [_round, (getPosASL _round), (velocity _round), _type, diag_frameno, _gun, _doSpall, _spallTrack, _spallTrackID, - (getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(skip))), - (getNumber (configFile >> "CfgAmmo" >> _type >> "explosive")), - (getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange")), - (getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force))), - (getNumber(configFile >> "CfgAmmo" >> _type >> "indirecthit")*(sqrt((getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"))))) + private _args = [ + _round, getPosASL _round, velocity _round, _type, diag_frameno, _gun, _doSpall, _spallTrack, _spallTrackID, + getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(skip)), + getNumber (configFile >> "CfgAmmo" >> _type >> "explosive"), + getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"), + getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force)), + getNumber (configFile >> "CfgAmmo" >> _type >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"))) ]; TRACE_1("Initializing track", _round); GVAR(objects) pushBack _round; GVAR(arguments) pushBack _args; - if(_doSpall) then { + if (_doSpall) then { [_round, 1, _spallTrack, _spallTrackID] call FUNC(spallTrack); }; - // ACE_player sideChat "WTF2"; }; diff --git a/addons/frag/functions/fnc_addTrack.sqf b/addons/frag/functions/fnc_addTrack.sqf deleted file mode 100644 index 4270e15996..0000000000 --- a/addons/frag/functions/fnc_addTrack.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "script_component.hpp" - -if (GVAR(autoTrace)) then { - [] call FUNC(startTracing); -}; - -// setAccTime 0.05; -private _index = count GVAR(traces); -params ["_origin", "_obj"]; -private _color = [1,0,0,1]; -if((count _this) > 2) then { - _color = _this select 2; -}; -private _positions = []; -private _objSpd = vectorMagnitude (velocity _obj); -_positions set[(count _positions), [(getPos _obj), _objSpd]]; -private _data = [_origin, typeOf _origin, typeOf _obj, _objSpd, _positions, _color]; - -GVAR(traces) set[_index, _data]; -[DFUNC(trackTrace), 0, [_obj, _index, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_addTrack.sqf b/addons/frag/functions/fnc_dev_addTrack.sqf new file mode 100644 index 0000000000..ce459008f6 --- /dev/null +++ b/addons/frag/functions/fnc_dev_addTrack.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_addTack + * + * Public: No + */ + +params ["_origin", "_obj", ["_color", [1, 0, 0, 1]]]; + +private _positions = []; +private _objSpd = vectorMagnitude (velocity _obj); +_positions pushBack [getPos _obj, _objSpd]; +private _data = [_origin, typeOf _origin, typeOf _obj, _objSpd, _positions, _color]; + +private _index = GVAR(traces) pushBack _data; +[DFUNC(dev_trackTrace), 0, [_obj, _index, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 297113f5af..42debf3d61 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -1,7 +1,26 @@ #define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_debugAmmo + * + * Public: No + */ -params [["_debugMissing", true, [false]], ["_debugForce", false, [false]], ["_debugNonFrag", false, [false]]]; +params [ + ["_debugMissing", true, [false]], + ["_debugForce", false, [false]], + ["_debugSkippedFragPower", 30, [0]] +]; diag_log text format ["~~~~~~~~~~~~~Start [%1]~~~~~~~~~~~~~", _this]; @@ -10,7 +29,7 @@ private _processedCfgAmmos = []; { private _ammo = toLower getText (_x >> "ammo"); - if ((_ammo != "") && {!(_ammo in _processedCfgAmmos)}) then { + if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; //Ignore mines/bombs @@ -23,37 +42,37 @@ private _processedCfgAmmos = []; private _explosive = getNumber (_ammoConfig >> "explosive"); private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); private _force = getNumber (_ammoConfig >> QGVAR(force)); - private _fragPower = getNumber(_ammoConfig >> "indirecthit")*(sqrt((getNumber (_ammoConfig >> "indirectHitRange")))); + private _fragPower = getNumber (_ammoConfig >> "indirecthit") * (sqrt ((getNumber (_ammoConfig >> "indirectHitRange")))); private _shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}}; if (_shouldAdd) then { if (_debugForce && {((getNumber(_ammoConfig >> "hit")) < 5) || {_fragPower < 10}}) then { - diag_log text format ["Ammo [%1] from Mag [%2] - Weak but will still frag!",_ammo,configName _x]; - diag_log text format [" - _force=%1,_fragPower=%2",_force,_fragPower]; + diag_log text format ["Ammo [%1] from Mag [%2] - Weak but will still frag!", _ammo, configName _x]; + diag_log text format [" - _force=%1,_fragPower=%2", _force, _fragPower]; }; - - _warn = false; + + private _warn = false; _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); - if(_fragTypes isEqualTo []) then {_warn = true;}; + if (_fragTypes isEqualTo []) then {_warn = true;}; _c = getNumber(_ammoConfig >> QGVAR(CHARGE)); - if(_c == 0) then {_warn = true;}; + if (_c == 0) then {_warn = true;}; _m = getNumber(_ammoConfig >> QGVAR(METAL)); - if(_m == 0) then {_warn = true;}; + if (_m == 0) then {_warn = true;}; _k = getNumber(_ammoConfig >> QGVAR(GURNEY_K)); - if(_k == 0) then {_warn = true;}; + if (_k == 0) then {_warn = true;}; _gC = getNumber(_ammoConfig >> QGVAR(GURNEY_C)); - if(_gC == 0) then { _warn = true;}; + if (_gC == 0) then {_warn = true;}; - if(_debugMissing && _warn) then { - diag_log text format ["Ammo [%1] from Mag [%2] MISSING frag configs:",_ammo,configName _x]; - diag_log text format [" - _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5",_c,_m,_k,_gC,_fragTypes]; + if (_debugMissing && {_warn}) then { + diag_log text format ["Ammo [%1] from Mag [%2] MISSING frag configs:", _ammo, configName _x]; + diag_log text format [" - _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5", _c, _m, _k, _gC, _fragTypes]; }; } else { - if (_debugNonFrag && {isArray (_ammoConfig >> QGVAR(CLASSES))}) then { - diag_log text format ["Ammo [%1] from Mag [%2] has frag configs but will NOT frag:",_ammo,configName _x]; - diag_log text format ["- skip=%1,explosive=%2,indirectHitRange=%3,force=%4,fragPower=%5",_skip,_explosive,_indirectRange,_force,_fragPower]; + if ((_fragPower > _debugSkippedFragPower) && {isArray (_ammoConfig >> QGVAR(CLASSES))}) then { + diag_log text format ["Ammo [%1] from Mag [%2] has frag configs but will NOT frag:", _ammo, configName _x]; + diag_log text format ["- skip=%1,explosive=%2,indirectHitRange=%3,force=%4,fragPower=%5", _skip, _explosive, _indirectRange, _force, _fragPower]; }; }; }; diff --git a/addons/frag/functions/fnc_dev_drawTraces.sqf b/addons/frag/functions/fnc_dev_drawTraces.sqf new file mode 100644 index 0000000000..76e729ed7f --- /dev/null +++ b/addons/frag/functions/fnc_dev_drawTraces.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_drawTraces + * + * Public: No + */ + +{ + _x params ["", "", "", "", "_positions", "_color"]; + private _index = 0; + private _max = count _positions; + // private _lastSpd = []; + private _lastPos = []; + while {_index < _max} do { + _data1 = _positions select _index; + _data2 = _positions select ([_index + ACE_TRACE_DRAW_INC, _max - 1] select (_index + ACE_TRACE_DRAW_INC >= _max)); + + _pos1 = _data1 select 0; + _pos2 = _data2 select 0; + ADD(_index,ACE_TRACE_DRAW_INC); + + drawLine3D [_pos1, _pos2, _color]; + _lastPos = _pos2; + // _lastSpd = _data1 select 1; + }; + // drawIcon3D ["", [1,0,0,1], _lastPos, 0, 0, 0, format ["%1m/s", _lastSpd], 1, 0.05, "RobotoCondensed"]; +} forEach GVAR(traces); diff --git a/addons/frag/functions/fnc_dev_startTracing.sqf b/addons/frag/functions/fnc_dev_startTracing.sqf new file mode 100644 index 0000000000..d709255a73 --- /dev/null +++ b/addons/frag/functions/fnc_dev_startTracing.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_dev_startTracing + * + * Public: No + */ + +if (GVAR(tracesStarted)) exitWith {}; + +INFO("Starting Trace Drawing"); + +GVAR(tracesStarted) = true; +GVAR(traceID) = [LINKFUNC(dev_drawTraces), 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_stopTracing.sqf b/addons/frag/functions/fnc_dev_stopTracing.sqf new file mode 100644 index 0000000000..75cf38b6d9 --- /dev/null +++ b/addons/frag/functions/fnc_dev_stopTracing.sqf @@ -0,0 +1,22 @@ +#include "script_component.hpp" +/* + * Author: ACE-Team + * Dev things + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * + * Public: No + */ + +if (!GVAR(tracesStarted)) exitWith {}; + +INFO("Ending Trace Drawing"); + +GVAR(tracesStarted) = false; +[GVAR(traceID)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_trackTrace.sqf b/addons/frag/functions/fnc_dev_trackTrace.sqf new file mode 100644 index 0000000000..6481b89310 --- /dev/null +++ b/addons/frag/functions/fnc_dev_trackTrace.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * Author: ACE-Team + * Dev things + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_dev_trackTrace + * + * Public: No + */ + +params ["_args", "_pfhID"]; +_args params ["_tracerObj", "_index"]; + +if (alive _tracerObj && {!(GVAR(traces) isEqualTo [])}) then { + private _data = GVAR(traces) select _index; + private _positions = _data select 4; + _positions pushBack [getPos _tracerObj, vectorMagnitude (velocity _tracerObj)]; +} else { + [_pfhID] call CBA_fnc_removePerFrameHandler; +}; diff --git a/addons/frag/functions/fnc_doExplosions.sqf b/addons/frag/functions/fnc_doExplosions.sqf index 03ad4d1dec..1f5c37597a 100644 --- a/addons/frag/functions/fnc_doExplosions.sqf +++ b/addons/frag/functions/fnc_doExplosions.sqf @@ -1,20 +1,36 @@ -//fnc_doExplosions.sqf #include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_doExplosions + * + * Public: No + */ -params ["_args"]; +params ["_args", "_pfhID"]; _args params ["_explosions", "_index"]; -for "_i" from _index to ((_index+2) min (count _explosions)) do { +for "_i" from _index to ((_index + 2) min (count _explosions)) do { private _exp = _explosions select _i; _exp params ["_refExp", "_bpos", "_hit", "_distance", "_indirectHitRange", "_depth"]; _refExp createVehicle (ASLtoATL _bpos); - // if(_hit >= 150 && _distance > _indirectHitRange) then { + // if (_hit >= 150 && _distance > _indirectHitRange) then { // [_bpos, _refExp, _depth] call FUNC(doReflections); // }; }; -_index = _index + 2; -if(_index >= (count _explosions)) then { - [(_this select 1)] call CBA_fnc_removePerFrameHandler; + +ADD(_index,2); + +if (_index >= count _explosions) then { + [_pfhID] call CBA_fnc_removePerFrameHandler; } else { - _params set[1, _index]; + _args set [1, _index]; }; diff --git a/addons/frag/functions/fnc_doReflections.sqf b/addons/frag/functions/fnc_doReflections.sqf index de5bac1b62..7b16385d75 100644 --- a/addons/frag/functions/fnc_doReflections.sqf +++ b/addons/frag/functions/fnc_doReflections.sqf @@ -1,14 +1,24 @@ -//fnc_doReflections.sqf #include "script_component.hpp" +/* + * Author: ACE-Team + * Dev things + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_doReflections + * + * Public: No + */ -params ["_pos", "_ammo"]; +params ["_pos", "_ammo", ["_depth", 1]]; -private _depth = 1; -if(count _this > 2) then { - _depth = _this select 2; -}; -// TEST_ICONS pushBack [_pos, format["EXP!", _hit, _range, _hitFactor]]; -if(_depth <= 2) then { +// TEST_ICONS pushBack [_pos, format ["EXP!", _hit, _range, _hitFactor]]; +if (_depth <= 2) then { private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); private _indirectHit = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHit"); private _testParams = [_pos, [_indirectHitRange, _indirectHit], [], [], -4, _depth, 0]; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 83f4518a03..eb97875570 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -1,146 +1,139 @@ -//fnc_doSpall.sqf #include "script_component.hpp" -// ACE_player sideChat "WAAAAAAAAAAAAAAAAAAAAA"; +/* + * Author: ACE-Team + * Dev things + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_doSpall + * + * Public: No + */ -params ["_hitData"]; +#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); -private _hpData = (_hitData select 1) select (_this select 1); +_initialData params ["_hpId", "_object", "_roundType", "_round", "_curPos", "_velocity"]; -_hpData params ["_object"]; -_object removeEventHandler ["hitPart", _initialData select 0]; -private _foundObjects = _initialData select 7; -private _index = _foundObjects find _object; -if(_index != -1) then { - _foundObjects set[_index, nil]; -}; +private _hpData = (_hitData select 1) select _hitPartDataIndex; +private _objectHit = _hpData param [0, objNull]; +TRACE_1("",_objectHit); +if ((isNil "_objectHit") || {isNull _objectHit}) exitWith {WARNING_1("Problem with hitPart data - bad object [%1]",_objectHit);}; +_objectHit removeEventHandler ["hitPart", _hpId]; -_initialData params ["", "_object", "_roundType", "_round"]; +private _caliber = getNumber (configFile >> "CfgAmmo" >> _roundType >> "caliber"); +private _explosive = getNumber (configFile >> "CfgAmmo" >> _roundType >> "explosive"); +private _idh = getNumber (configFile >> "CfgAmmo" >> _roundType >> "indirectHitRange"); -private _caliber = getNumber(configFile >> "CfgAmmo" >> _roundType >> "caliber"); -private _explosive = getNumber(configFile >> "CfgAmmo" >> _roundType >> "explosive"); -private _idh = getNumber(configFile >> "CfgAmmo" >> _roundType >> "indirectHitRange"); +if !(_caliber >= 2.5 || {(_explosive > 0 && {_idh >= 1})}) exitWith {}; +// ACE_player sideChat format ["BBBB"]; +private _exit = false; +private _vm = 1; -private _alive = true; -if(!alive _round && (_initialData select 6) isEqualTo 1) then { - _alive = false; -}; +private _oldVelocity = vectorMagnitude _velocity; +private _curVelocity = vectorMagnitude (velocity _round); -if(_alive || {_caliber >= 2.5} || {(_explosive > 0 && {_idh >= 1})}) then { - // ACE_player sideChat format["BBBB"]; - private _exit = false; - private _vm = 1; - private _velocity = _initialData select 5; - - private _oldVelocity = vectorMagnitude _velocity; - private _curVelocity = vectorMagnitude (velocity _round); - - if(alive _round) then { - private _diff = _velocity vectorDiff (velocity _round); - private _polar = _diff call CBA_fnc_vect2polar; - // ACE_player sideChat format["polar: %1", _polar]; - if((abs(_polar select 1) > 45 || abs(_polar select 2) > 45)) then { - if(_caliber < 2.5) then { - // ACE_player sideChat format["exit!"]; - _exit = true; - } else { - _vm = 1-(_curVelocity/_oldVelocity); - }; - }; - }; - if(!_exit) then { - private _unitDir = vectorNormalized _velocity; - private _pos = _hpData select 3; - private _spallPos = nil; - for "_i" from 0 to 100 do { - private _pos1 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * _i)); - private _pos2 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * (_i + 1))); - // _blah = [_object, "FIRE"] intersect [_object worldToModel (ASLtoATL _pos1), _object worldToModel (ASLtoATL _pos2)]; - // diag_log text format["b: %1", _blah]; - - // _data = [nil, nil, nil, 1, [[ASLtoATL _pos1, 1], [ASLtoATL _pos2, 1]]]; - // NOU_TRACES set[(count NOU_TRACES), _data]; - - if(!lineIntersects [_pos1, _pos2]) exitWith { - // ACE_player sideChat format["FOUND!"]; - _spallPos = _pos2; - }; - }; - if(!isNil "_spallPos") then { - private _spallPolar = _velocity call CBA_fnc_vect2polar; - - if(_explosive > 0) then { - // ACE_player sideChat format["EXPLOSIVE!"]; - private _warn = false; - private _c = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(CHARGE)); - if(_c == 0) then { _c = 1; _warn = true;}; - private _m = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(METAL)); - if(_m == 0) then { _m = 2; _warn = true;}; - private _k = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_K)); - if(_k == 0) then { _k = 1/2; _warn = true;}; - private _gC = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_C)); - if(_gC == 0) then { _gC = 2440; _warn = true;}; - - if(_warn) then { - ACE_LOGWARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_roundType); //TODO: turn this off when we get closer to release - }; - - private _fragPower = (((_m/_c)+_k)^-(1/2))*_gC; - _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); - for "_i" from 1 to _spallCount do { - private _elev = ((_spallPolar select 2)-_spread)+(random (_spread*2)); - private _dir = ((_spallPolar select 1)-_spread)+(random (_spread*2)); - if(abs _elev > 90) then { - _dir = _dir + 180; - }; - _dir = _dir % 360; - private _vel = (_spallPolar select 0)*0.33*_vm; - _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]; - _fragment setPosASL _spallPos; - _fragment setVelocity _spallFragVect; - - if(GVAR(traceFrags)) then { - [ACE_player, _fragment, [1,0.5,0,1]] call FUNC(addTrack); - }; - }; - _spread = 5+(random 5); - _spallCount = 3+(random 5); - for "_i" from 1 to _spallCount do { - private _elev = ((_spallPolar select 2)-_spread)+(random (_spread*2)); - private _dir = ((_spallPolar select 1)-_spread)+(random (_spread*2)); - if(abs _elev > 90) then { - _dir = _dir + 180; - }; - _dir = _dir % 360; - private _vel = (_spallPolar select 0)*0.55*_vm; - _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]; - _fragment setPosASL _spallPos; - _fragment setVelocity _spallFragVect; - - if(GVAR(traceFrags)) then { - [ACE_player, _fragment, [1,0,0,1]] call FUNC(addTrack); - }; - }; +if (alive _round) then { + private _diff = _velocity vectorDiff (velocity _round); + private _polar = _diff call CBA_fnc_vect2polar; + // ACE_player sideChat format ["polar: %1", _polar]; + if (abs (_polar select 1) > 45 || {abs (_polar select 2) > 45}) then { + if (_caliber < 2.5) then { + // ACE_player sideChat format ["exit!"]; + _exit = true; + } else { + SUB(_vm,_curVelocity / _oldVelocity); }; }; }; +if (_exit) exitWith {}; + +private _unitDir = vectorNormalized _velocity; +private _pos = _hpData select 3; +private _spallPos = []; +if ((isNil "_pos") || {!(_pos isEqualTypeArray [0,0,0])}) exitWith {WARNING_1("Problem with hitPart data - bad pos [%1]",_pos);}; +for "_i" from 0 to 100 do { + private _pos1 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * _i)); + private _pos2 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * (_i + 1))); + // _data = [nil, nil, nil, 1, [[ASLtoATL _pos1, 1], [ASLtoATL _pos2, 1]]]; + // NOU_TRACES pushBack _data; + + if (!lineIntersects [_pos1, _pos2]) exitWith { + // ACE_player sideChat format ["FOUND!"]; + _spallPos = _pos2; + }; +}; +if (_spallPos isEqualTo []) exitWith {}; +private _spallPolar = _velocity call CBA_fnc_vect2polar; + +if (_explosive > 0) then { + // ACE_player sideChat format ["EXPLOSIVE!"]; + private _warn = false; + private _c = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(CHARGE)); + if (_c == 0) then {_c = 1; _warn = true;}; + private _m = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(METAL)); + if (_m == 0) then {_m = 2; _warn = true;}; + private _k = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_K)); + if (_k == 0) then {_k = 1 / 2; _warn = true;}; + private _gC = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_C)); + if (_gC == 0) then {_gC = 2440; _warn = true;}; + + // if (_warn) then { + // WARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_roundType); //TODO: turn this off when we get closer to release + // }; + + private _fragPower = (((_m / _c) + _k) ^ - (1 / 2)) * _gC; + _spallPolar set [0, _fragPower * 0.66]; +}; + +// diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; +private _spread = 15 + (random 25); +private _spallCount = 5 + (random 10); +TRACE_1("",_spallCount); +for "_i" from 1 to _spallCount do { + private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2)); + private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2)); + if (abs _elev > 90) then { + ADD(_dir,180); + }; + _dir = _dir % 360; + private _vel = (_spallPolar select 0) * 0.33 * _vm; + _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); + + private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; + private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0,0,10000]; + _fragment setPosASL _spallPos; + _fragment setVelocity _spallFragVect; + + #ifdef DRAW_FRAG_INFO + [ACE_player, _fragment, [1, 0.5, 0, 1]] call FUNC(dev_addTrack); + #endif +}; + +_spread = 5 + (random 5); +_spallCount = 3 + (random 5); +for "_i" from 1 to _spallCount do { + private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2)); + private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2)); + if (abs _elev > 90) then { + ADD(_dir,180); + }; + _dir = _dir % 360; + private _vel = (_spallPolar select 0) * 0.55 * _vm; + _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); + + private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; + private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0, 0, 10000]; + _fragment setPosASL _spallPos; + _fragment setVelocity _spallFragVect; + + #ifdef DRAW_FRAG_INFO + [ACE_player, _fragment, [1, 0, 0, 1]] call FUNC(dev_addTrack); + #endif +}; diff --git a/addons/frag/functions/fnc_drawTraces.sqf b/addons/frag/functions/fnc_drawTraces.sqf deleted file mode 100644 index 790d53491f..0000000000 --- a/addons/frag/functions/fnc_drawTraces.sqf +++ /dev/null @@ -1,31 +0,0 @@ -#include "script_component.hpp" - -private ["_color", "_index", "_lastPos", "_lastSpd", "_max", "_positions", "_startSpeed"]; - -{ - _positions = _x select 4; - _color = _x select 5; - _index = 0; - _max = count _positions; - _startSpeed = 0.01 max ((_positions select 0) select 1); - _lastSpd = []; - _lastPos = []; - while {_index < _max} do { - _data1 = _positions select _index; - _data2 = nil; - if(_index + ACE_TRACE_DRAW_INC >= _max) then { - _data2 = _positions select (_max - 1); - } else { - _data2 = _positions select (_index + ACE_TRACE_DRAW_INC); - }; - - _pos1 = _data1 select 0; - _pos2 = _data2 select 0; - _index = _index + ACE_TRACE_DRAW_INC; - - drawLine3D [_pos1, _pos2, _color]; - _lastPos = _pos2; - _lastSpd = _data1 select 1; - }; - // drawIcon3D ["", [1,0,0,1], _lastPos, 0, 0, 0, format["%1m/s", _lastSpd], 1, 0.05, "RobotoCondensed"]; -} forEach GVAR(traces); diff --git a/addons/frag/functions/fnc_findReflections.sqf b/addons/frag/functions/fnc_findReflections.sqf index cc123641d3..8b4a5922a5 100644 --- a/addons/frag/functions/fnc_findReflections.sqf +++ b/addons/frag/functions/fnc_findReflections.sqf @@ -1,61 +1,72 @@ -//fnc_findReflections.sqf #include "script_component.hpp" - -private ["_lastPos", "_test", "_vec", "_testPos", "_buckets", "_excludes", "_bucketIndex", "_bucketPos", "_bucketList", "_c", "_index", "_blist", "_avgX", "_avgY", "_avgZ", "_bpos", "_distance", "_hitFactor", "_hit", "_range", "_refExp", "_i", "_x", "_res", "_forEachIndex", "_explosions", "_can", "_dirvec", "_zAng"]; +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_findReflections + * + * Public: No + */ BEGIN_COUNTER(fnc_findReflections); -params ["_args"]; +params ["_args", "_pfhID"]; _args params ["_pos", "_explosiveInfo", "_los", "_nlos", "_zIndex", "_depth", "_rand"]; private _split = 15; -private _radi = (360/_split*_depth); +private _radi = 360 / _split * _depth; -// player sideChat format["p: %1", _explosiveInfo]; +// player sideChat format ["p: %1", _explosiveInfo]; _explosiveInfo params ["_indirectHitRange", "_indirectHit"]; -private _distanceCount = (floor _indirectHitRange*4) min 100; +private _distanceCount = (floor _indirectHitRange * 4) min 100; -if(_zIndex < 5) then { - _lastPos = _pos; - _zAng = _zIndex*20+2; - if(_zAng > 80) then { +if (_zIndex < 5) then { + private _lastPos = _pos; + private _zAng = _zIndex * 20 + 2; + if (_zAng > 80) then { _radi = 1; _zAng = 90; }; for "_i" from 0 to _radi do { - _test = true; - _vec = [1, ((_i*_split)+_rand) mod 360, _zAng] call CBA_fnc_polar2vect; + private _test = true; + private _vec = [1, ((_i * _split) + _rand) % 360, _zAng] call CBA_fnc_polar2vect; for "_x" from 1 to _distanceCount do { - _testPos = _pos vectorAdd (_vec vectorMultiply _x); + private _testPos = _pos vectorAdd (_vec vectorMultiply _x); // drop ["\a3\data_f\Cl_basic","","Billboard",1,15,ASLtoATL _testPos,[0,0,0],1,1.275,1.0,0.0,[1],[[1,0,0,1]],[0],0.0,2.0,"","",""]; - _res = lineIntersectsWith [_pos, _testPos]; - if(count _res > 0) exitWith { + private _res = lineIntersectsWith [_pos, _testPos]; + if (count _res > 0) exitWith { _test = false; _nlos pushBack _lastPos; // { - // _x addEventHandler ["HandleDamage", { diag_log text format["this: %1", _this]; }]; + // _x addEventHandler ["HandleDamage", { diag_log text format ["this: %1", _this]; }]; // } forEach _res; // drop ["\a3\data_f\Cl_basic","","Billboard",1,15,ASLtoATL _testPos,[0,0,0],1,1.275,1.0,0.0,[1],[[1,0,0,1]],[0],0.0,2.0,"","",""]; // TEST_PAIRS pushBack [_pos, _lastPos, [1,0,0,1]]; }; - // if(terrainIntersectASL [_pos, _testPos]) exitWith {}; + // if (terrainIntersectASL [_pos, _testPos]) exitWith {}; _lastPos = _testPos; }; }; - _params set[4, _zIndex+1]; + _args set [4, _zIndex + 1]; } else { - _depth = _depth + 1; - _buckets = []; - _excludes = []; - _bucketIndex = 0; - _bucketPos = nil; - _bucketList = nil; - _c = 0; - while { count(_nlos) != count(_excludes) && _c < (count _nlos) } do { + INC(_depth); + private _buckets = []; + private _excludes = []; + private _bucketPos = nil; + private _bucketList = nil; + private _c = 0; + while {count _nlos != count _excludes && {_c < (count _nlos)}} do { scopeName "mainSearch"; { - if(!(_forEachIndex in _excludes)) then { - _index = _buckets pushBack [_x, [_x]]; + if (!(_forEachIndex in _excludes)) then { + private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x; _bucketList = (_buckets select _index) select 1; @@ -63,59 +74,53 @@ if(_zIndex < 5) then { }; } forEach _nlos; { - if(!(_forEachIndex in _excludes)) then { + if (!(_forEachIndex in _excludes)) then { _testPos = _x; - if(_testPos vectorDistanceSqr _bucketPos <= 30) then { + if (_testPos vectorDistanceSqr _bucketPos <= 30) then { _bucketList pushBack _x; _excludes pushBack _forEachIndex; }; }; } forEach _nlos; - _c = _c + 1; + INC(_c); }; - // player sideChat format["c: %1", count _buckets]; - _explosions = []; + // player sideChat format ["c: %1", count _buckets]; + private _explosions = []; { - _blist = _x select 1; - _avgX = 0; - _avgY = 0; - _avgZ = 0; + private _blist = _x select 1; + private _avg = [0, 0, 0]; { - _avgX = _avgX + (_x select 0); - _avgY = _avgY + (_x select 1); - _avgZ = _avgZ + (_x select 2); + _avg = _avg vectorAdd _x; } forEach _blist; _c = count _blist; - _bpos = [_avgX/_c, _avgY/_c, _avgZ/_c]; + private _bpos = _avg vectorMultiply (1 / _c); - _distance = _pos vectorDistance _bpos; - _hitFactor = 1-(((_distance/(_indirectHitRange*4)) min 1) max 0); - // _hitFactor = 1/(_distance^2); - _hit = _indirectHit*_hitFactor; - _hit = (floor (_hit/4)) min 500; - _hit = _hit - (_hit%10); - _range = (floor (_indirectHitRange-(_distance/4))) min 100; - _range = _range - (_range%2); + private _distance = _pos vectorDistance _bpos; + private _hitFactor = 1 - (((_distance / (_indirectHitRange * 4)) min 1) max 0); + // _hitFactor = 1 / (_distance ^ 2); + private _hit = (floor (_indirectHit * _hitFactor / 4)) min 500; + SUB(_hit,_hit % 10); + private _range = (floor (_indirectHitRange - (_distance / 4))) min 100; + SUB(_range,_range % 2); - if(_hit >= 10 && _range > 0) then { - // TEST_ICONS pushBack [_bpos, format["h: %1, r: %2, hf: %3 d: %4 ihr: %5", _hit, _range, _hitFactor, _distance, _indirectHitRange*4]]; + if (_hit >= 10 && {_range > 0}) then { + // TEST_ICONS pushBack [_bpos, format ["h: %1, r: %2, hf: %3 d: %4 ihr: %5", _hit, _range, _hitFactor, _distance, _indirectHitRange*4]]; // TEST_PAIRS pushBack [_pos, _bpos, [1,0,0,1]]; - _refExp = format["ace_explosion_reflection_%1_%2", _range, _hit]; + private _refExp = format ["ace_explosion_reflection_%1_%2", _range, _hit]; // _refExp createVehicle (ASLtoATL _bpos); // drop ["\a3\data_f\Cl_basic","","Billboard",1,15,ASLtoATL _bpos,[0,0,0],1,1.275,1.0,0.0,[1],[[1,0,0,1]],[0],0.0,2.0,"","",""]; - _explosions pushBack [_refExp, _bpos, _hit, _distance, _indirectHitRange/4, _depth]; - + _explosions pushBack [_refExp, _bpos, _hit, _distance, _indirectHitRange / 4, _depth]; }; - if(count _explosions > (_radi*2)/_depth) exitWith {}; + if (count _explosions > (_radi * 2) / _depth) exitWith {}; } forEach _buckets; // _can = "Land_Bricks_V4_F" createVehicle (ASLtoATL _pos); // _dirvec = _pos vectorFromTo ((ATLtoASL (player modelToWorldVisual (player selectionPosition "Spine3")))); // _dirvec = _dirvec vectorMultiply 100; // _can setVelocity _dirvec; [DFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; - [(_this select 1)] call CBA_fnc_removePerFrameHandler; + [_pfhID] call CBA_fnc_removePerFrameHandler; }; END_COUNTER(fnc_findReflections); diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index dbe1ab6347..a61a2d14c7 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: nou, jaynus, PabstMirror * Called from the unified fired EH for all. @@ -7,15 +8,13 @@ * None. Parameters inherited from EFUNC(common,firedEH) * * Return Value: - * Nothing + * None * * Example: * [clientFiredBIS-XEH] call ace_frag_fnc_fired * * Public: No */ -// #define DEBUG_ENABLED_FRAG -#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); @@ -24,32 +23,36 @@ private _shouldAdd = GVAR(cacheRoundsTypesToTrack) getVariable _ammo; if (isNil "_shouldAdd") then { TRACE_1("no cache for round",_ammo); - if (!EGVAR(common,settingsInitFinished)) exitWith { - //Just incase fired event happens before settings init, don't want to set cache wrong if spall setting changes - TRACE_1("Settings not init yet - exit without setting cache",_ammo); - _shouldAdd = false; - }; - - if (GVAR(SpallEnabled)) exitWith { - //Always want to run whenever spall is enabled? - _shouldAdd = true; - TRACE_2("SettingCache[spallEnabled]",_ammo,_shouldAdd); - GVAR(cacheRoundsTypesToTrack) setVariable [_ammo, _shouldAdd]; - }; - //Read configs and test if it would actually cause a frag, using same logic as FUNC(pfhRound) private _skip = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(skip)); private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); private _indirectRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); private _force = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(force)); - private _fragPower = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirecthit")*(sqrt((getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange")))); + private _fragPower = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"))); _shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}}; - TRACE_6("SettingCache[willFrag?]",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd); + + if (GVAR(spallEnabled) && {!_shouldAdd}) then { + private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); + if !(_caliber >= 2.5 || {(_explosive > 0 && {_indirectRange >= 1})}) exitWith {}; // from check in doSpall: line 34 + TRACE_1("Won't frag, but will spall",_caliber); + _shouldAdd = true; + }; + + TRACE_6("Setting Cache",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd); GVAR(cacheRoundsTypesToTrack) setVariable [_ammo, _shouldAdd]; }; if (_shouldAdd) then { - TRACE_3("Running Frag Tracking",_unit,_ammo,_projectile); + // firedMan will have nil "_gunner", so just check _unit; for firedVehicle we want to check _gunner + 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 {}; + _unit setVariable [QGVAR(lastTrack), CBA_missionTime]; + [_unit, _ammo, _projectile] call FUNC(addPfhRound); }; diff --git a/addons/frag/functions/fnc_frago.sqf b/addons/frag/functions/fnc_frago.sqf index 2c04528492..8c90445411 100644 --- a/addons/frag/functions/fnc_frago.sqf +++ b/addons/frag/functions/fnc_frago.sqf @@ -1,49 +1,52 @@ -//fnc_frago.sqf -// #define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: Jaynus, NouberNou + * Server func to create the fragmentation for a round. + * + * Arguments: + * 0: Last Position (ASL) + * 1: Velocity + * 2: Ammo Classname + * + * Return Value: + * None + * + * Example: + * [[], [], "handGrenade"] call ace_frag_fnc_frago + * + * Public: No + */ #define FRAG_VEC_VAR 0.004 - #define MAX_FRAG_COUNT 50 -if(!isServer) exitWith { }; - BEGIN_COUNTER(frago); -// _startTime = diag_tickTime; -private ["_fuseDist", "_indirectHitRange", "_fragRange", "_c", "_m", "_k", "_gC", "_fragPower", "_fragPowerRandom", "_manObjects", "_objects", "_crew", "_fragCount", "_fragArcs", "_doRandom", "_boundingBox", "_targetPos", "_distance", "_add", "_bbX", "_bbY", "_bbZ", "_cubic", "_targetVel", "_baseVec", "_dir", "_currentCount", "_count", "_vecVar", "_vec", "_fp", "_vel", "_fragType", "_fragObj", "_randomCount", "_sectorSize", "_sectorOffset", "_i", "_randomDir", "_endTime", "_target"]; +params ["_lastPos", "_lastVel", "_shellType"]; +TRACE_3("frago",_lastPos,_lastVel,_shellType); -params ["_round", "_lastPos", "_lastVel", "_shellType"]; -private _gun = nil; -if((count _this) > 5) then { - _gun = _this select 5; -}; +// Limit max frag count if there was a recent frag +private _maxFrags = round (MAX_FRAG_COUNT * linearConversion [0.1, 1.5, (CBA_missionTime - GVAR(lastFragTime)), 0.1, 1, true]); +TRACE_2("",_maxFrags,CBA_missionTime - GVAR(lastFragTime)); +GVAR(lastFragTime) = CBA_missionTime; private _fragTypes = [ QGVAR(tiny), QGVAR(tiny), QGVAR(tiny), QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(tiny_HD), - QGVAR(small),QGVAR(small),QGVAR(small),QGVAR(small), - QGVAR(small_HD),QGVAR(small_HD),QGVAR(small_HD),QGVAR(small_HD), + QGVAR(small), QGVAR(small), QGVAR(small), QGVAR(small), + QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD) ]; private _warn = false; -if(isArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES))) then { +if (isArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES))) then { _fragTypes = getArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES)); } else { _warn = true; }; -private _atlPos = ASLtoATL _lastPos; - -private _isArmed = true; -if(!isNil "_gun") then { - _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance"); - _isArmed = ((getPosASL _gun) distance _lastPos > _fuseDist); -}; - -_indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _shellType >> "indirecthitrange"); -_fragRange = 20 * _indirectHitRange * 4; +private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _shellType >> "indirecthitrange"); +private _fragRange = 20 * _indirectHitRange * 4; // _c = 185; // grams of comp-b // _m = 210; // grams of fragmentating metal // _k = 3/5; // spherical K factor @@ -54,162 +57,138 @@ _fragRange = 20 * _indirectHitRange * 4; // _k = 1/2; // spherical K factor // _gC = 2320; // Gurney constant of tritonal in /ms +private _c = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CHARGE)); +if (_c == 0) then {_c = 1; _warn = true;}; +private _m = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(METAL)); +if (_m == 0) then {_m = 2; _warn = true;}; +private _k = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_K)); +if (_k == 0) then {_k = 0.5; _warn = true;}; +private _gC = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_C)); +if (_gC == 0) then {_gC = 2440; _warn = true;}; -_c = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(CHARGE)); -if(_c == 0) then { _c = 1; _warn = true;}; -_m = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(METAL)); -if(_m == 0) then { _m = 2; _warn = true;}; -_k = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_K)); -if(_k == 0) then { _k = 1/2; _warn = true;}; -_gC = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_C)); -if(_gC == 0) then { _gC = 2440; _warn = true;}; - -if(_warn) then { - ACE_LOGWARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_shellType); //TODO: turn this off when we get closer to release +if (_warn) then { + INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_shellType); }; -_fragPower = (((_m/_c)+_k)^-(1/2))*_gC; -_fragPower = _fragPower * 0.8; // Gunery equation is for a non-fragmenting metal, imperical value of 80% represents fragmentation +// Gunery equation is for a non-fragmenting metal, imperical value of 80% represents fragmentation +private _fragPower = 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC; -_fragPowerRandom = _fragPower * 0.5; -if((_atlPos select 2) < 0.5) then { - _lastPos set[2, (_lastPos select 2)+0.5]; +private _atlPos = ASLtoATL _lastPos; + +private _fragPowerRandom = _fragPower * 0.5; +if ((_atlPos select 2) < 0.5) then { + _lastPos vectorAdd [0, 0, 0.5]; }; -// _manObjects = _atlPos nearEntities ["CaManBase", _fragRange]; - -// setAccTime 0.01; - -//_objects = nearestObjects [_atlPos, ["AllVehicles"], _fragRange]; // Not sure if tracking "ReammoBox" is required, if so revert this change for _objects -_objects = _atlPos nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; - -// _objects = _manObjects; -// Target also people inside vehicles or manning weapons -_crew = []; +private _objects = _atlPos nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; +// Add unique crews in faster way { { - _crew set [count _crew,_x] + _objects pushBackUnique _x; } forEach (crew _x); } forEach _objects; +TRACE_2("",_fragRange,count _objects); -_objects = _objects - _crew; -_objects = _objects + _crew; +private _fragCount = 0; -_fragCount = 0; +private _fragArcs = []; +_fragArcs set [360, 0]; -_fragArcs = []; -_fragArcs set[360, 0]; - -#ifdef DEBUG_MODE_FULL - ACE_player sideChat format["_fragRange: %1", _fragRange]; - ACE_player sideChat format["_objects: %1", _objects]; -#endif -_doRandom = true; -if(_isArmed && (count _objects) > 0) then { - if (GVAR(ReflectionsEnabled)) then { +private _doRandom = true; +if (!(_objects isEqualTo [])) then { + if (GVAR(reflectionsEnabled)) then { [_lastPos, _shellType] call FUNC(doReflections); }; { - //if(random(1) > 0.5) then { - _target = _x; - if(alive _target) then { - _boundingBox = boundingBox _target; - _targetPos = (getPosASL _target); - _distance = _targetPos distance _lastPos; - _add = (((_boundingBox select 1) select 2)/2)+((((_distance-(_fragpower/8)) max 0)/_fragPower)*10); - _bbX = (abs((_boundingBox select 0) select 0))+((_boundingBox select 1) select 0); - _bbY = (abs((_boundingBox select 0) select 1))+((_boundingBox select 1) select 1); - _bbZ = (abs((_boundingBox select 0) select 2))+((_boundingBox select 1) select 2); - _cubic = _bbX * _bbY * _bbZ; - if(_cubic > 1) then { - _doRandom = true; + private _target = _x; + if (alive _target) then { + (boundingBox _target) params ["_boundingBoxA", "_boundingBoxB"]; - _targetVel = (velocity _target); + private _cubic = ((abs (_boundingBoxA select 0)) + (_boundingBoxB select 0)) * ((abs (_boundingBoxA select 1)) + (_boundingBoxB select 1)) * ((abs (_boundingBoxA select 2)) + (_boundingBoxB select 2)); + if (_cubic <= 1) exitWith {}; + // _doRandom = true; - _targetPos set[0, (_targetPos select 0)+((_targetVel select 0)*(_distance/_fragPower))]; - _targetPos set[1, (_targetPos select 1)+((_targetVel select 1)*(_distance/_fragPower))]; - _targetPos set[2, (_targetPos select 2)+_add]; + private _targetVel = velocity _target; + private _targetPos = getPosASL _target; + private _distance = _targetPos vectorDistance _lastPos; + private _add = ((_boundingBoxB select 2) / 2) + ((((_distance - (_fragpower / 8)) max 0) / _fragPower) * 10); - _baseVec = _lastPos vectorFromTo _targetPos; + _targetPos = _targetPos vectorAdd [ + (_targetVel select 0) * (_distance / _fragPower), + (_targetVel select 1) * (_distance / _fragPower), + _add + ]; - _dir = floor(_baseVec call CBA_fnc_vectDir); - _currentCount = _fragArcs select _dir; - if(isNil "_currentCount") then { - _currentCount = 0; - }; - if(_currentCount < 20) then { - _count = ceil(random(sqrt(_m/1000))); - _vecVar = FRAG_VEC_VAR; - if(!(_target isKindOf "Man")) then { - _vecVar = ((sqrt _cubic)/2000)+FRAG_VEC_VAR; - if((count (crew _target)) == 0 && _count > 0) then { - _count = 0 max (_count/2); - }; - }; - for "_i" from 1 to _count do { - _vec = +_baseVec; + private _baseVec = _lastPos vectorFromTo _targetPos; - _vec set[0, (_vec select 0)-(_vecVar/2)+(random _vecVar)]; - _vec set[1, (_vec select 1)-(_vecVar/2)+(random _vecVar)]; - _vec set[2, (_vec select 2)-(_vecVar/2)+(random _vecVar)]; - - _fp = (_fragPower-(random (_fragPowerRandom))); - _vel = _vec vectorMultiply _fp; - - _fragType = round (random ((count _fragTypes)-1)); - _fragObj = (_fragTypes select _fragType) createVehicleLocal [0,0,10000]; - // diag_log text format["fp: %1 %2", _fp, typeOf _fragObj]; - _fragObj setPosASL _lastPos; - _fragObj setVectorDir _vec; - _fragObj setVelocity _vel; - if(GVAR(traceFrags)) then { - GVAR(TOTALFRAGS) = GVAR(TOTALFRAGS) + 1; - [ACE_player, _fragObj, [1,0,0,1]] call FUNC(addTrack); - }; - _fragCount = _fragCount + 1; - _currentCount = _currentCount + 1; - }; - _fragArcs set[_dir, _currentCount]; + private _dir = floor (_baseVec call CBA_fnc_vectDir); + private _currentCount = RETDEF(_fragArcs select _dir,0); + if (_currentCount < 10) then { + private _count = ceil (random (sqrt (_m / 1000))); + private _vecVar = FRAG_VEC_VAR; + if (!(_target isKindOf "Man")) then { + ADD(_vecVar,(sqrt _cubic) / 2000); + if ((crew _target) isEqualTo [] && {_count > 0}) then { + _count = 0 max (_count / 2); }; }; + for "_i" from 1 to _count do { + private _vec = _baseVec vectorDiff [ + (_vecVar / 2) + (random _vecVar), + (_vecVar / 2) + (random _vecVar), + (_vecVar / 2) + (random _vecVar) + ]; + + private _fp = _fragPower - (random (_fragPowerRandom)); + private _vel = _vec vectorMultiply _fp; + + private _fragObj = (selectRandom _fragTypes) createVehicleLocal [0,0,10000]; + // TRACE_4("targeted",_fp, typeOf _fragObj,_lastPos vectorDistance _targetPos,typeOf _x); + _fragObj setPosASL _lastPos; + _fragObj setVectorDir _vec; + _fragObj setVelocity _vel; + #ifdef DRAW_FRAG_INFO + [ACE_player, _fragObj, [1,0,0,1]] call FUNC(dev_addTrack); + #endif + INC(_fragCount); + INC(_currentCount); + }; + _fragArcs set [_dir, _currentCount]; }; - //}; - if(_fragCount > MAX_FRAG_COUNT) exitWith {}; + }; + if (_fragCount > _maxFrags) exitWith {}; } forEach _objects; - if(_fragCount > MAX_FRAG_COUNT) exitWith {}; - _randomCount = ((ceil((MAX_FRAG_COUNT - _fragCount)*0.1)) max 0)+20; - _sectorSize = 360 / (_randomCount max 1); - // _doRandom = false; - if(_doRandom) then { + TRACE_1("targeted",_fragCount); + if (_fragCount > _maxFrags) exitWith {}; + private _randomCount = ceil ((_maxFrags - _fragCount) * 0.35); + TRACE_1("",_randomCount); + private _sectorSize = 360 / (_randomCount max 1); + + if (_doRandom) then { for "_i" from 1 to _randomCount do { // Distribute evenly - _sectorOffset = 360 * (_i - 1) / (_randomCount max 1); - _randomDir = random(_sectorSize); - _vec = [cos(_sectorOffset + _randomDir), sin(_sectorOffset + _randomDir), sin(30 - (random 45))]; + private _sectorOffset = 360 * (_i - 1) / (_randomCount max 1); + private _randomDir = random (_sectorSize); + _vec = [cos (_sectorOffset + _randomDir), sin (_sectorOffset + _randomDir), sin (30 - (random 45))]; - _fp = (_fragPower-(random (_fragPowerRandom))); + _fp = (_fragPower - (random (_fragPowerRandom))); _vel = _vec vectorMultiply _fp; - _fragType = round (random ((count _fragTypes)-1)); - _fragObj = (_fragTypes select _fragType) createVehicleLocal [0,0,10000]; + _fragObj = (selectRandom _fragTypes) createVehicleLocal [0, 0, 10000]; _fragObj setPosASL _lastPos; _fragObj setVectorDir _vec; _fragObj setVelocity _vel; - if(GVAR(traceFrags)) then { - GVAR(TOTALFRAGS) = GVAR(TOTALFRAGS) + 1; - [ACE_player, _fragObj, [1,0.5,0,1]] call FUNC(addTrack); - }; - _fragCount = _fragCount + 1; + #ifdef DRAW_FRAG_INFO + [ACE_player, _fragObj, [1,0.5,0,1]] call FUNC(dev_addTrack); + #endif + INC(_fragCount); }; }; - }; -// #ifdef DEBUG_MODE_FULL - // ACE_player sideChat format["total frags: %1", GVAR(TOTALFRAGS)]; - // ACE_player sideChat format["tracks: %1", (count GVAR(trackedObjects))]; -// #endif -// _endTime = diag_tickTime; + +TRACE_1("total created",_fragCount); + END_COUNTER(frago); diff --git a/addons/frag/functions/fnc_masterPFH.sqf b/addons/frag/functions/fnc_masterPFH.sqf index 722590a391..06baaad17f 100644 --- a/addons/frag/functions/fnc_masterPFH.sqf +++ b/addons/frag/functions/fnc_masterPFH.sqf @@ -1,50 +1,56 @@ +#include "script_component.hpp" /* * Author: jaynus - * - * Master single PFH abstraction for all rounds being tracked by frag/spall + * Master single PFH abstraction for all rounds being tracked by frag/spall. * * Arguments: - * + * None * * Return Value: * None + * + * Example: + * call ace_frag_fnc_masterPFH + * + * Public: No */ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -//PARAMS_2(_pfhArgs,_handle); -if (!GVAR(enabled)) exitWith {}; +BEGIN_COUNTER(PFH); -private ["_gcIndex", "_iter"]; -_gcIndex = []; +// Fast exit if nothing to do +if (GVAR(objects) isEqualTo []) exitWith {END_COUNTER(PFH);}; -_iter = 0; -while { (count GVAR(objects)) > 0 && { _iter < (GVAR(MaxTrackPerFrame) min (count GVAR(objects))) } } do { - private ["_object", "_args"]; - if(GVAR(lastIterationIndex) >= (count GVAR(objects))) then { +private _gcIndex = []; + +private _iter = 0; +private _objectCount = count GVAR(objects); +while {_objectCount > 0 && {_iter < (GVAR(maxTrackPerFrame) min _objectCount)}} do { + + if (GVAR(lastIterationIndex) >= _objectCount) then { GVAR(lastIterationIndex) = 0; }; - _object = GVAR(objects) select GVAR(lastIterationIndex); + private _object = GVAR(objects) select GVAR(lastIterationIndex); - if(!isNil "_object") then { - _args = GVAR(arguments) select GVAR(lastIterationIndex); + if (!isNil "_object") then { + private _args = GVAR(arguments) select GVAR(lastIterationIndex); - if(!(_args call FUNC(pfhRound))) then { - _gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false + if (!(_args call FUNC(pfhRound))) then { + _gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false }; }; - _iter = _iter + 1; - GVAR(lastIterationIndex) = GVAR(lastIterationIndex) + 1; + INC(_iter); + INC(GVAR(lastIterationIndex)); }; -// clean up dead object references -private ["_deletionCount", "_deleteIndex"]; -_deletionCount = 0; +// Clean up dead object references +private _deletionCount = 0; { TRACE_1("GC Projectile", _x); - _deleteIndex = _x - _deletionCount; + private _deleteIndex = _x - _deletionCount; GVAR(objects) deleteAt _deleteIndex; GVAR(arguments) deleteAt _deleteIndex; - _deletionCount = _deletionCount + 1; + INC(_deletionCount); } forEach _gcIndex; + +END_COUNTER(PFH); diff --git a/addons/frag/functions/fnc_pfhRound.sqf b/addons/frag/functions/fnc_pfhRound.sqf index cbbd75b633..4d5e9b2e99 100644 --- a/addons/frag/functions/fnc_pfhRound.sqf +++ b/addons/frag/functions/fnc_pfhRound.sqf @@ -1,26 +1,49 @@ #include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_pfhRound + * + * Public: No + */ -params ["_round", "_lastPos", "_lastVel", "_type", "_firedFrame", "", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"]; +params ["_round", "_lastPos", "_lastVel", "_shellType", "_firedFrame", "_gun", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"]; -if(_round in GVAR(blackList)) exitWith { +if (_round in GVAR(blackList)) exitWith { false }; if (!alive _round) exitWith { - if((diag_frameno - _firedFrame) > 1) then { //skip if deleted within a single frame - if(_skip == 0) then { - if((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1} ) then { + if ((diag_frameno - _firedFrame) > 1) then { //skip if deleted within a single frame + if (_skip == 0) then { + if ((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1}) then { // shotbullet, shotShell don't seem to explode when touching water, so don't create frags - if (((_lastPos select 2) < 0) && {(toLower getText (configFile >> "CfgAmmo" >> _type >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; - [QGVAR(frag_eh), _this] call CBA_fnc_serverEvent; + if (((_lastPos select 2) < 0) && {(toLower getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; + private _isArmed = true; + if (!isNil "_gun") then { + private _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance"); + _isArmed = ((getPosASL _gun) distance _lastPos > _fuseDist); + TRACE_2("",_fuseDist,_isArmed); + }; + if (!_isArmed) exitWith {TRACE_1("round not armed",_this);}; + TRACE_3("Sending frag event to server",_lastPos,_lastVel,_shellType); + [QGVAR(frag_eh), [_lastPos,_lastVel,_shellType]] call CBA_fnc_serverEvent; }; }; }; - if(_doSpall) then { - GVAR(spallIsTrackingCount) = GVAR(spallIsTrackingCount) - 1; - // diag_log text format["F: %1", _foundObjectHPIds]; + if (_doSpall) then { + DEC(GVAR(spallIsTrackingCount)); + TRACE_1("doSpall",_foundObjectHPIds); { - if(!isNil "_x") then { + if (!isNil "_x") then { _x removeEventHandler ["hitPart", _foundObjectHPIds select _forEachIndex]; }; } forEach _spallTrack; @@ -28,12 +51,11 @@ if (!alive _round) exitWith { false }; -_this set[1, (getPosASL _round)]; -_this set[2, (velocity _round)]; +_this set [1, getPosASL _round]; +_this set [2, velocity _round]; -if(_doSpall) then { - private ["_scale"]; - _scale = ( (count GVAR(objects)) / GVAR(MaxTrackPerFrame) ) max 0.1; +if (_doSpall) then { + private _scale = ((count GVAR(objects)) / GVAR(maxTrackPerFrame)) max 0.1; [_round, _scale, _spallTrack, _foundObjectHPIds] call FUNC(spallTrack); }; diff --git a/addons/frag/functions/fnc_removePfhRound.sqf b/addons/frag/functions/fnc_removePfhRound.sqf deleted file mode 100644 index d186da1e17..0000000000 --- a/addons/frag/functions/fnc_removePfhRound.sqf +++ /dev/null @@ -1,11 +0,0 @@ -#include "script_component.hpp" - -// THIS FUNCTION SHOULD NOT BE USED BECAUSE IT CAUSES AN SEARCH AND REBUILD - -PARAMS_1(_round); - -if(_round in GVAR(blackList)) then { - GVAR(blackList) = GVAR(blackList) - [_round]; -}; - -GVAR(objects) = GVAR(objects) - [_round]; diff --git a/addons/frag/functions/fnc_removeTrack.sqf b/addons/frag/functions/fnc_removeTrack.sqf deleted file mode 100644 index 914a90602c..0000000000 --- a/addons/frag/functions/fnc_removeTrack.sqf +++ /dev/null @@ -1,14 +0,0 @@ -#include "script_component.hpp" - -private ["_ret"]; -_ret = true; -if(IS_ARRAY((_this select 0))) then { - _ret = false; -} else { - if((_this select 0) in GVAR(trackedObjects)) then { - GVAR(trackedObjects) = GVAR(trackedObjects) - [(_this select 0)]; - } else { - _ret = false; - }; -}; -_ret diff --git a/addons/frag/functions/fnc_spallHP.sqf b/addons/frag/functions/fnc_spallHP.sqf index 5bdde6eee9..9a1e144f44 100644 --- a/addons/frag/functions/fnc_spallHP.sqf +++ b/addons/frag/functions/fnc_spallHP.sqf @@ -1,29 +1,42 @@ #include "script_component.hpp" +/* + * Author: ACE-Team + * Handles the HitPart event + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_spallHP + * + * Public: No + */ -private ["_initialData", "_hpData", "_round", "_hpRound", "_hpDirect"]; -//player sideChat format["f: %1 c: %2", (_this select 0), (count GVAR(spallHPData))]; +//player sideChat format ["f: %1 c: %2", (_this select 0), (count GVAR(spallHPData))]; -if ((_this select 0) <= (count GVAR(spallHPData))) then { - _initialData = GVAR(spallHPData) select (_this select 0); - if (!isNil "_initialData") then { - _hpRound = ((_this select 1) select 0) select 2; - _round = _initialData select 3; - _hpDirect = ((_this select 1) select 0) select 10; - if (_hpDirect && {_round == _hpRound}) then { - { - _hpData = _x; - _round = _initialData select 3; - // diag_log text format["HPDUMP-------------------------------------"]; - // { - // _hp = _x; - // diag_log text format["%1 --", _forEachIndex]; - // { - // diag_log text format["%1: %2", _forEachIndex, _x]; - // } forEach _hp; - // } forEach (_this select 1); - [DFUNC(doSpall), [_this, _forEachIndex]] call CBA_fnc_execNextFrame; - // player sideChat "WEEE"; - } forEach (_this select 1); - }; - }; +params ["_index", "_hitPartData"]; + +private _initialData = GVAR(spallHPData) param [_index, []]; +if (_initialData isEqualTo []) exitWith {}; + +private _hpRound = (_hitPartData select 0) select 2; +private _round = _initialData select 3; +private _hpDirect = (_hitPartData select 0) select 10; + +if (_hpDirect && {_round == _hpRound}) then { + { + // diag_log text format ["HPDUMP-------------------------------------"]; + // { + // _hp = _x; + // diag_log text format ["%1 --", _forEachIndex]; + // { + // diag_log text format ["%1: %2", _forEachIndex, _x]; + // } forEach _hp; + // } forEach (_this select 1); + [DFUNC(doSpall), [_this, _forEachIndex]] call CBA_fnc_execNextFrame; + // player sideChat "WEEE"; + } forEach _hitPartData; }; diff --git a/addons/frag/functions/fnc_spallTrack.sqf b/addons/frag/functions/fnc_spallTrack.sqf index 91c7dee511..8e1bf2f804 100644 --- a/addons/frag/functions/fnc_spallTrack.sqf +++ b/addons/frag/functions/fnc_spallTrack.sqf @@ -1,9 +1,23 @@ -//fnc_spallTrack.sqf #include "script_component.hpp" +/* + * Author: ACE-Team + * Add HitPart EventHandler to objects in the projectile's path + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_frag_fnc_spallTrack + * + * Public: No + */ params ["_round", "_multiplier", "_foundObjects", "_foundObjectHPIds"]; -private _delta = (1/diag_fps) * _multiplier; +private _delta = (1 / diag_fps) * _multiplier; private _curPos = getPosASL _round; private _velocity = velocity _round; @@ -12,17 +26,15 @@ private _forwardPos = _curPos vectorAdd _velocityStep; private _intersectsWith = lineIntersectsWith [_curPos, _forwardPos]; -if (count _intersectsWith > 0) then { - // player sideChat format["inter: %1", _intersectsWith]; - { - if(!(_x in _foundObjects)) then { - // diag_log text format["Adding HP: %1", _x]; - private _index = count GVAR(spallHPData); - private _hpId = _x addEventHandler ["hitPart", compile format["[%1, _this] call " + QFUNC(spallHP), _index]]; - _foundObjects set[(count _foundObjects), _x]; - _foundObjectHPIds set[(count _foundObjectHPIds), _hpId]; - private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds]; - GVAR(spallHPData) set[_index, _data]; - }; - } forEach _intersectsWith; -}; +if (_intersectsWith isEqualTo []) exitWith {}; + +// player sideChat format ["inter: %1", _intersectsWith]; +{ + // diag_log text format ["Adding HP: %1", _x]; + private _index = count GVAR(spallHPData); + private _hpId = _x addEventHandler ["hitPart", compile format ["[%1, _this] call " + QFUNC(spallHP), _index]]; + _foundObjects pushBack _x; + _foundObjectHPIds pushBack _hpId; + private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds]; + GVAR(spallHPData) pushBack _data; +} forEach (_intersectsWith select {!(_x in _foundObjects)}); diff --git a/addons/frag/functions/fnc_startTracing.sqf b/addons/frag/functions/fnc_startTracing.sqf deleted file mode 100644 index ca9aa8c84e..0000000000 --- a/addons/frag/functions/fnc_startTracing.sqf +++ /dev/null @@ -1,5 +0,0 @@ -#include "script_component.hpp" -if(!GVAR(tracesStarted)) then { - GVAR(tracesStarted) = true; - GVAR(traceID) = [FUNC(drawTraces), 0, []] call CBA_fnc_addPerFrameHandler; -}; diff --git a/addons/frag/functions/fnc_stopTracing.sqf b/addons/frag/functions/fnc_stopTracing.sqf deleted file mode 100644 index b58352c897..0000000000 --- a/addons/frag/functions/fnc_stopTracing.sqf +++ /dev/null @@ -1,5 +0,0 @@ -#include "script_component.hpp" -if(GVAR(tracesStarted)) then { - GVAR(tracesStarted) = false; - [GVAR(traceID)] call CBA_fnc_removePerFrameHandler; -}; diff --git a/addons/frag/functions/fnc_trackTrace.sqf b/addons/frag/functions/fnc_trackTrace.sqf deleted file mode 100644 index d57eaa8c5c..0000000000 --- a/addons/frag/functions/fnc_trackTrace.sqf +++ /dev/null @@ -1,12 +0,0 @@ -#include "script_component.hpp" - -params ["_args"]; -_args params ["_tracerObj", "_index"]; - -if (alive _tracerObj && (count GVAR(traces)) > 0) then { - private _data = GVAR(traces) select _index; - private _positions = _data select 4; - _positions pushBack [(getPos _tracerObj), vectorMagnitude (velocity _tracerObj)]; -} else { - [(_this select 1)] call CBA_fnc_removePerFrameHandler; -}; diff --git a/addons/frag/functions/script_component.hpp b/addons/frag/functions/script_component.hpp index 8312313751..0903b3ba1e 100644 --- a/addons/frag/functions/script_component.hpp +++ b/addons/frag/functions/script_component.hpp @@ -1 +1 @@ -#include "\z\ace\addons\frag\script_component.hpp" \ No newline at end of file +#include "\z\ace\addons\frag\script_component.hpp" diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 73655e84e5..0215e9f4d7 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -2,10 +2,9 @@ #define COMPONENT_BEAUTIFIED Frag #include "\z\ace\addons\main\script_mod.hpp" -//#define DEBUG_ENABLED_FRAG +// #define DRAW_FRAG_INFO // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FRAG @@ -18,4 +17,4 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ACE_TRACE_DRAW_INC 1 +#define ACE_TRACE_DRAW_INC 1 diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 0385f3d133..d5a3091969 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Repesz-szimuláció Симуляция осколков Simulazione Frammentazione + 破片シミュレーション + 조각 시뮬레이션 + 模拟碎片 + 模擬碎片 Fragmentation Simulation @@ -24,6 +28,10 @@ Repesz-szimuláció Симуляция осколков Simulazione Frammentazione + 破片シミュレーション + 조각 시뮬레이션 + 模拟碎片 + 模擬碎片 Enable the ACE Fragmentation Simulation @@ -36,6 +44,10 @@ Az ACE repesz-szimuláció engedélyezése Включить симуляцию осколков ACE Abilita la Simulazione Frammentazione di ACE + ACE 破片シミュレーションを有効化 + ACE 조각 시뮬레이션을 적용합니다. + 启用ACE模拟碎片 + 啟用ACE模擬碎片 Spalling Simulation @@ -48,6 +60,10 @@ Pattogzás-szimuláció Симуляция обломков Simulazione Spalling + 剥離シミュレーション + 파편 시뮬레이션 + 模拟剥落 + 模擬剝落 Enable the ACE Spalling Simulation @@ -60,6 +76,10 @@ Az ACE pattogzás-szimuláció engedélyezése Включить симуляцию обломков ACE Abilita la Simulazione Spalling di ACE + ACE 剥離シミュレーションを有効化 + ACE 파편 시뮬레이션을 적용합니다. + 启用ACE模拟剥落 + 啟用ACE模擬剝落 Explosion Reflections Simulation @@ -70,6 +90,10 @@ Simulation de la réflection des explosions. Simulação de reflexo de explosão Cимуляция отражения взрывов ACE + 爆発による飛翔シミュレーション + 폭발 반사 시뮬레이션 + 模拟爆炸反射 + 模擬爆炸反射 Enable the ACE Explosion Reflection Simulation @@ -80,6 +104,10 @@ Activer la simulation de la réfléction des explosions ACE. Ativa a simulação de reflexo de explosão do ACE Включить симуляцию отражения взрывов ACE + 爆発による飛翔シミュレーションを有効化 + ACE 폭발 반사 시뮬레이션을 적용합니다. + 启用ACE模拟爆炸反射 + 啟用ACE模擬爆炸反射 Maximum Projectiles Tracked @@ -92,6 +120,10 @@ Maximum követett repeszek Макс. количество отслеживаемых снарядов Numero massimo di Proiettili Tracciati + 最大弾頭追跡数 + 최대 발사체 추적수 + 最大碎片粒子追踪数量 + 最大碎片/剝落粒子追蹤數量 This setting controls the maximum amount of projectiles the fragmentation and spalling system will track at any given time. If more projectiles are fired, they will not be tracked. Lower this setting if you do not want FPS drops at high-count projectile scenarios ( >200 rounds in the air at once) @@ -104,6 +136,10 @@ Ez a beállítás szabályozza a repeszeződés és pattogzás által kilőtt objektumok követett számát. Ha több ez a szám, ezek az objektumok nem lesznek követve. Csökkentsd ezt a beállítást, ha nem akarsz lassulásokat magas-törmelékmennyiségű helyzetekben (200+ repesz a levegőben egyszerre) Эта настройка контролирует максимальное количество снарядов, которок отслеживает система осколков и обломков в каждый момент времени. Снаряды, выстреленные сверх этого числа, отслеживаться не будут. Уменьшите это значение, если вы не хотите падения FPS при большом количестве снарядов в одной перестрелке (> 200 одновременно летящих снарядов) 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顆粒子) Maximum Projectiles Per Frame @@ -116,6 +152,10 @@ Maximum repesz/képkocka Макс. количество снарядов за кадр Numero massimo di proiettili per Frame + フレームごとの最大弾頭数 + 프레임당 최대 발사체 수 + 每一帧数(FPS)最大碎片粒子数量 + 每一幀數(FPS)最大碎片/剝落粒子數量 The number of spall track calculations to perform in any given frame. This helps spread the FPS impact of tracking spall rounds across multiple frames, limiting its impact even further. @@ -128,6 +168,10 @@ A lepattogzási útvonalak számításának darabjai képkockánként. Ez eloszlatja az FPS-megszakadást több képkockára, ezzel csökkentve a súlyosságát. Число обрабатываемых осколков за кадр. Это позволяет распределить нагрузку по отслеживанию осколков между несколькими кадрами, чтобы предотвратить падение FPS. 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 @@ -140,6 +184,10 @@ (Csak SP) Repesz/Pattogzás debug követés (Только для одиночной игры) Отслеживаение/отладка осколков (Solo SP) Debug Tracciamento Frag/Spall + (SP のみ) 破片/剥離のデバッグ用表示 + (싱글플레이 전용) 조각/파편 디버그 추적화 + (仅在单人模式) 追踪显示碎片粒子 + (僅在單人模式) 碎片/剝落除錯追蹤 (SP Only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. @@ -148,10 +196,14 @@ (nur SP) Splitter-/Explosions-Debugging (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. - (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement + (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. + (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の弾頭が見えるようになります。 + (仅在单人模式) 激活后,只有在单人模式下才可观察到碎片粒子的移动轨迹。 + (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 + (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 조각화 및 스 폴링 라운드의 시각적 추적을 가능하게합니다. - \ No newline at end of file + diff --git a/addons/gestures/CfgVehicles.hpp b/addons/gestures/CfgVehicles.hpp index 6eb3990446..bc9c36d6ef 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,107 +6,106 @@ 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); - 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; }; class GVAR(Forward) { displayName = CSTRING(Forward); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(forward)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; - priority = 1.9; }; class GVAR(Regroup) { displayName = CSTRING(Regroup); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(regroup)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; - priority = 1.8; }; class GVAR(Freeze) { displayName = CSTRING(Freeze); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(freeze)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; - priority = 1.7; }; class GVAR(Cover) { displayName = CSTRING(Cover); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(cover)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; - priority = 1.6; }; class GVAR(Point) { displayName = CSTRING(Point); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(point)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; - priority = 1.5; }; class GVAR(Engage) { displayName = CSTRING(Engage); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(engage)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; - priority = 1.4; }; class GVAR(Hold) { displayName = CSTRING(Hold); condition = QUOTE(true); statement = QUOTE(QUOTE(QGVAR(hold)) call FUNC(playSignal)); + exceptions[] = {"isNotSwimming"}; showDisabled = 1; - priority = 1.3; }; class GVAR(Warning) { 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 b68df0a592..935b81aa61 100644 --- a/addons/gestures/XEH_postInit.sqf +++ b/addons/gestures/XEH_postInit.sqf @@ -14,9 +14,14 @@ if (!hasInterface) exitWith {}; }; private _code = compile format [QUOTE('%1' call FUNC(playSignal)), _signalName]; + if (_currentName == "Stop") then { + _code = compile format [QUOTE('%1' call FUNC(playSignal)), "BIgestureFreeze"]; + }; 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/XEH_preInit.sqf b/addons/gestures/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/gestures/XEH_preInit.sqf +++ b/addons/gestures/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; 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 273db82da1..3dcae0d2e3 100644 --- a/addons/gestures/functions/fnc_playSignal.sqf +++ b/addons/gestures/functions/fnc_playSignal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: joko // Jonas, Emperias, Zigomarvin * Detect if the player and play the Gesture Animation @@ -6,19 +7,18 @@ * Animation * * Return Value: - * + * Boolean * * Example: * "GeniusAnimation" call ace_gestures_fnc_playSignal * * Public: No */ -#include "script_component.hpp" 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/script_component.hpp b/addons/gestures/script_component.hpp index ddf7ddb401..f8ddbd1771 100644 --- a/addons/gestures/script_component.hpp +++ b/addons/gestures/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_GESTURES diff --git a/addons/gestures/stringtable.xml b/addons/gestures/stringtable.xml index a0171c7465..6e61d5cac0 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 @@ -12,6 +28,10 @@ ACE Gestos ACE Жесты ACE Gestos + ACE ジェスチャー + ACE 수신호 + ACE 手势 + ACE 手勢 Gestures @@ -24,6 +44,10 @@ Kézjelek Gestos Gesti + ジェスチャー + 수신호 + 手势 + 手勢 Advance @@ -36,6 +60,10 @@ Előre Avançar Avanzare + 警戒 + 전진 + 前进 + 前進 Go @@ -48,6 +76,10 @@ Mozgás Mover-se Muoversi + 進め + 이동 + 出发 + 出發 Follow @@ -60,6 +92,10 @@ Utánam Seguir Seguire + ついて来い + 따라올것 + 跟进 + 跟進 Up @@ -72,6 +108,10 @@ Fel Acima Alzarsi + 立ち上がれ + + 起立 + 起立 Cease Fire @@ -84,6 +124,10 @@ Tüzet szüntess Cessar Fogo Cessare il Fuoco + 撃つな + 사격 중지 + 停火 + 停火 Stop @@ -95,6 +139,10 @@ Stop Stop Detenerse + 止まれ + 멈춰 + 停止 + 停止 Freeze @@ -107,6 +155,10 @@ Állj Alto Fermi + 動くな + 정지 + 不准动 + 不准動 Cover @@ -119,6 +171,10 @@ Fedezékbe Proteger-se Copertura + 隠れろ + 엄폐 + 掩护 + 掩護 Rally up @@ -130,6 +186,10 @@ Přeskupit Raggruppare Reunirse + 集合 + 집결 + 集合 + 集合 Move forward @@ -141,6 +201,10 @@ Kupředu Muovere avanti Avanzar + 前に進め + 앞으로 이동 + 往前走 + 往前走 Engage @@ -152,6 +216,10 @@ Útok Ingaggiare Atacar + 交戦しろ + 교전할것 + 交战 + 交戰 Point @@ -163,6 +231,10 @@ Ukázat Puntare Señalar + 指示 + 가리키기 + 指出 + 指出 Hold @@ -174,6 +246,10 @@ Čekej Mantenere Esperar + そこにいろ + 기다려 + 停住 + 停住 Warning @@ -185,6 +261,10 @@ Pozor Attenzione Atención + 注意 + 주의 + 警告 + 警告 Show Gestures On Interaction Menu @@ -196,39 +276,55 @@ Afficher les gestes dans le menu d'interaction. Mostrar gestos no menu de interação Показать жесты в меню взаимодействия + インタラクション メニュー上でジェスチャー表示 + 수신호를 상호작용 메뉴에서 보여줍니다 + 显示手势互动选单 + 顯示手勢互動選單 Show gestures on the self interaction menu, or just use keybinds, or disable completely Zeige Gesten im Selbst-Interkationsmenü, lege sie auf Schnelltasten, oder deaktiviere sie vollständig. Zobrazit posunky pro vlastní interakční menu, nebo prostě použít klávesové zkratky, nebo to zakázat úplně Pokaż listę gestów w menu własnej interakcji, użyj tylko skrótów na klawiaturze lub wyłącz całkowicie - Mostra Gesti nel Menù Interazione Personale, o usa solamente Hotkey, o disabilita completamente + Mostra Gesti nel Menù Interazione Personale, o usa solamente tasti di scelta rapida, o disabilita completamente Muestror los gestos en el menú de interacción propia, utilizar solo combinación de teclas o desactivarlos completamente Afficher les gestes dans le menu d'interaction personnel, ou seulement utiliser les touches, ou desactiver complètement. Mostra gestos no menu de interação, ou utilize um dos atalhos de teclado ou desative completamente Показать жесты в меню взамиодейтсвия с собой или только использовать горячие клавиши, или полностью отключить + キー操作や同時使用を無効化している場合はセルフ インタラクション メニュ上でジェスチャーを表示します + 수신호를 상호작용 메뉴에서 보여주거나 혹은 단축키를 지정하거나 아니면 아예 사용하지 않습니다. + 显示手势选项在自己的互动选单上,或只利用键盘来使用手势,或完全禁用 + 顯示手勢選項在自己的互動選單上,或只利用鍵盤來使用手勢,或完全禁用 Just Keybinds Nur Schnelltasten Pouze klávesové zkratky Tylko skróty klaw. - Solo Hotkey + Solo tasti di scelta rapida Solo mediante teclas Seulement les touches Somente atalhos de teclado Только горячие клавиши + キー操作のみ + 오직 단축키만 + 只利用键盘 + 只利用鍵盤 Keybinds + Interaction Menu Schnelltasten+ Interaktionsmenü Klávesové zkratky + interakční menu Skróty klaw. + menu interakcji - Hotkey + Menù Interazione + Tasti di scelta rapida + Menù Interazione Teclas y Menú de Interacción Touches + menu d'interaction Atalhos + Menu de Interação Клавиши + Меню взаимодействия + キー操作とインタラクション メニュ + 단축키및 상호작용 메뉴 + 键盘 + 互动选单 + 鍵盤 + 互動選單 - \ No newline at end of file + diff --git a/addons/gforces/ACE_Arsenal_Stats.hpp b/addons/gforces/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..4148ba5fe2 --- /dev/null +++ b/addons/gforces/ACE_Arsenal_Stats.hpp @@ -0,0 +1,13 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_gReduction: statBase { + scope = 2; + priority = 1; + stats[] = {"ACE_GForceCoef"}; + displayName = CSTRING(statGReduction); + showBar = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(1, 0)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default)); + condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0); + tabs[] = {{3}, {}}; + }; +}; diff --git a/addons/gforces/CfgWeapons.hpp b/addons/gforces/CfgWeapons.hpp index 7b69dc24b9..2349ba7b2a 100644 --- a/addons/gforces/CfgWeapons.hpp +++ b/addons/gforces/CfgWeapons.hpp @@ -7,9 +7,15 @@ class CfgWeapons { class U_B_PilotCoveralls: Uniform_Base { ACE_GForceCoef = 0.8; }; + class U_B_HeliPilotCoveralls: Uniform_Base { + ACE_GForceCoef = 0.8; + }; class U_I_pilotCoveralls: Uniform_Base { ACE_GForceCoef = 0.8; }; + class U_I_HeliPilotCoveralls: Uniform_Base { + ACE_GForceCoef = 0.8; + }; class U_O_PilotCoveralls: Uniform_Base { ACE_GForceCoef = 0.8; }; diff --git a/addons/gforces/XEH_postInit.sqf b/addons/gforces/XEH_postInit.sqf index 9eb049c9f5..f7d532c288 100644 --- a/addons/gforces/XEH_postInit.sqf +++ b/addons/gforces/XEH_postInit.sqf @@ -3,22 +3,26 @@ if (!hasInterface) exitWith {}; GVAR(pfID) = -1; +GVAR(playerIsVirtual) = false; ["ace_settingsInitialized", { TRACE_1("SettingsInitialized eh",GVAR(enabledFor)); if (GVAR(enabledFor) == 0) exitWith {}; //Module has no effect if enabledFor is "None" + + ["unit", { // Add unit changed EH to check if player is either virtual (logic) or a UAV AI + params ["_unit"]; + GVAR(playerIsVirtual) = ((getNumber (configFile >> "CfgVehicles" >> (typeOf _unit) >> "isPlayableLogic")) == 1) || + {(getText (configFile >> "CfgVehicles" >> (typeOf _unit) >> "simulation")) == "UAVPilot"}; + TRACE_3("unit changed",_unit,typeOf _unit,GVAR(playerIsVirtual)); + }, true] call CBA_fnc_addPlayerEventHandler; + if (GVAR(enabledFor) == 2) exitWith { //PFEH is always on when enabledFor is "All" [] call FUNC(addPFEH); TRACE_1("adding perm PFEH",GVAR(pfID)); }; //PFEH only runs when player is in a type "Air" vehicle when enabledFor is "Aircraft" - - if ((!isNull (vehicle ACE_player)) && {(vehicle ACE_player) isKindOf "Air"}) then { //"playerVehicleChanged" can happen before "settingInit" - [] call FUNC(addPFEH); - TRACE_1("adding temp PFEH [start in]",GVAR(pfID)); - }; ["vehicle", { params ["", "_vehicle"]; TRACE_2("playerVehicleChanged",_vehicle,typeOf _vehicle); @@ -35,5 +39,5 @@ GVAR(pfID) = -1; GVAR(pfID) = -1; }; }; - }] call CBA_fnc_addPlayerEventHandler; + }, true] call CBA_fnc_addPlayerEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/gforces/XEH_preInit.sqf b/addons/gforces/XEH_preInit.sqf index 99e6461c54..7530cabc45 100644 --- a/addons/gforces/XEH_preInit.sqf +++ b/addons/gforces/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(GForces) = []; GVAR(GForces_Index) = 0; diff --git a/addons/gforces/config.cpp b/addons/gforces/config.cpp index e05f582d08..da9e6a2328 100644 --- a/addons/gforces/config.cpp +++ b/addons/gforces/config.cpp @@ -21,3 +21,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/gforces/functions/fnc_addPFEH.sqf b/addons/gforces/functions/fnc_addPFEH.sqf index 9bd4d7fa1a..55dd8dcd12 100644 --- a/addons/gforces/functions/fnc_addPFEH.sqf +++ b/addons/gforces/functions/fnc_addPFEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi and esteldunedain * Adds the PFEH @@ -8,12 +9,18 @@ * Return Value: * None * + * Example: + * call ace_gforces_fnc_addPFEH + * * Public: No */ -#include "script_component.hpp" //Reset forces array GVAR(GForces) = []; +// init array to full array of neutral g-forces +GVAR(GForces) resize 30; +GVAR(GForces) = GVAR(GForces) apply {1}; + GVAR(GForces_Index) = 0; // Setup ppEffect @@ -26,4 +33,4 @@ GVAR(GForces_CC) ppEffectCommit 0.4; GVAR(lastUpdateTime) = 0; GVAR(oldVel) = [0,0,0]; -GVAR(pfID) = [DFUNC(pfhUpdateGForces), 0, []] call CBA_fnc_addPerFrameHandler; +GVAR(pfID) = [LINKFUNC(pfhUpdateGForces), 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf index 48370c2431..a5aee2d18e 100644 --- a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf +++ b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi and esteldunedain * Calculates average g-forces and triggers g-effects @@ -9,15 +10,17 @@ * Return Value: * None * + * Example: + * [[args], 5] call ace_gforces_fnc_pfhUpdateGForces + * * Public: No */ - #include "script_component.hpp" // Update the g-forces at constant mission time intervals (taking accTime into account) if ((CBA_missionTime - GVAR(lastUpdateTime)) < INTERVAL) exitWith {}; GVAR(lastUpdateTime) = CBA_missionTime; -if (isNull ACE_player || !(alive ACE_player)) exitWith {}; +if (GVAR(playerIsVirtual) || {!alive ACE_player}) exitWith {}; BEGIN_COUNTER(everyInterval); @@ -27,7 +30,7 @@ private _accel = ((_newVel vectorDiff GVAR(oldVel)) vectorMultiply (1 / INTERVAL private _currentGForce = (((_accel vectorDotProduct vectorUp (vehicle ACE_player)) / 9.8) max -10) min 10; GVAR(GForces) set [GVAR(GForces_Index), _currentGForce]; -GVAR(GForces_Index) = (GVAR(GForces_Index) + 1) % round (AVERAGEDURATION / INTERVAL); +GVAR(GForces_Index) = (GVAR(GForces_Index) + 1) % 30; // 30 = round (AVERAGEDURATION / INTERVAL); GVAR(oldVel) = _newVel; /* Source: https://github.com/KoffeinFlummi/AGM/issues/1774#issuecomment-70341573 diff --git a/addons/gforces/script_component.hpp b/addons/gforces/script_component.hpp index 6adfb95cf6..f20c3451bc 100644 --- a/addons/gforces/script_component.hpp +++ b/addons/gforces/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_GFORCES diff --git a/addons/gforces/stringtable.xml b/addons/gforces/stringtable.xml index 7cd33b34d7..6e8b90e230 100644 --- a/addons/gforces/stringtable.xml +++ b/addons/gforces/stringtable.xml @@ -1,14 +1,20 @@ - + Gforces Effects - Gforces Effekte + Effekte der G-Kräfte Efectos Gforces G Force efekty Efeitos de ForçaG Effets de force gravitationnelle Эффекты перегрузок + G による効果 + Efekty przeciążeń + 중력가속도 효과 + Effetti forza G + G力影响 + G力影響 Only Aircraft @@ -18,6 +24,20 @@ Somente Aeronave Avions seulement Только для летательных аппаратов + 航空機のみ + Tylko samoloty + 비행기에만 적용 + Solo Aerei + 只有战斗机 + 只有戰鬥機 + + + G-force reduction + Reduction des Gs + 耐 G 性 + 减少G力 + 減少G力 + Riduzione forza G - \ No newline at end of file + diff --git a/addons/goggles/ACE_Settings.hpp b/addons/goggles/ACE_Settings.hpp index 659a10b4e3..26575ab554 100644 --- a/addons/goggles/ACE_Settings.hpp +++ b/addons/goggles/ACE_Settings.hpp @@ -1,12 +1,15 @@ class ACE_Settings { class GVAR(effects) { + category = CSTRING(DisplayName); displayName = CSTRING(effects_displayName); typeName = "SCALAR"; value = 2; + isClientSettable = 1; 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 b7b5de9e1b..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 }; @@ -20,7 +20,7 @@ if (!hasInterface) exitWith {}; if (GVAR(effects) == 0) exitWith {}; // ---Add the TINT Effect--- - + // make sure to stack effect layers in correct order GVAR(GogglesEffectsLayer) = QGVAR(GogglesEffectsLayer) call BIS_fnc_RSCLayer; GVAR(GogglesLayer) = QGVAR(GogglesLayer) call BIS_fnc_RSCLayer; @@ -29,6 +29,26 @@ if (!hasInterface) exitWith {}; GVAR(UsePP) = true; }; + // init pp effects + GVAR(PostProcess) = ppEffectCreate ["ColorCorrections", 1995]; + GVAR(EffectsActive) = false; + + // add glasses eventhandlers + ["ace_glassesChanged", { + params ["_unit", "_glasses"]; + TRACE_2("ace_glassesChanged eh",_unit,_glasses); + + SETGLASSES(_unit,GLASSESDEFAULT); + + if (call FUNC(ExternalCamera)) exitWith {call FUNC(RemoveGlassesEffect)}; + + if ([_unit] call FUNC(isGogglesVisible)) then { + [_unit, _glasses] call FUNC(applyGlassesEffect); + } else { + call FUNC(removeGlassesEffect); + }; + }] call CBA_fnc_addEventHandler; + // init GlassesChanged eventhandler GVAR(OldGlasses) = ""; ["loadout", { @@ -40,12 +60,9 @@ if (!hasInterface) exitWith {}; ["ace_glassesChanged", [_unit, _currentGlasses]] call CBA_fnc_localEvent; GVAR(OldGlasses) = _currentGlasses; }; - }] call CBA_fnc_addPlayerEventHandler; + }, true] call CBA_fnc_addPlayerEventHandler; - // init pp effects - GVAR(PostProcess) = ppEffectCreate ["ColorCorrections", 1995]; - GVAR(EffectsActive) = false; // check goggles private _fnc_checkGoggles = { @@ -57,7 +74,7 @@ if (!hasInterface) exitWith {}; }; } else { if (!(call FUNC(externalCamera)) && {[_unit] call FUNC(isGogglesVisible)}) then { - [goggles _unit] call FUNC(applyGlassesEffect); + [_unit, goggles _unit] call FUNC(applyGlassesEffect); }; }; }; @@ -66,21 +83,6 @@ if (!hasInterface) exitWith {}; ["ace_activeCameraChanged", _fnc_checkGoggles] call CBA_fnc_addEventHandler; - // add glasses eventhandlers - ["ace_glassesChanged", { - params ["_unit", "_glasses"]; - - SETGLASSES(_unit,GLASSESDEFAULT); - - if (call FUNC(ExternalCamera)) exitWith {call FUNC(RemoveGlassesEffect)}; - - if ([_unit] call FUNC(isGogglesVisible)) then { - _glasses call FUNC(applyGlassesEffect); - } else { - call FUNC(removeGlassesEffect); - }; - }] call CBA_fnc_addEventHandler; - // // ---Add the Dust/Dirt/Rain Effects--- if (GVAR(effects) == 2) then { @@ -96,7 +98,7 @@ if (!hasInterface) exitWith {}; GVAR(PostProcessEyes) ppEffectCommit 0; GVAR(PostProcessEyes) ppEffectEnable false; GVAR(PostProcessEyes_Enabled) = false; - + GVAR(FrameEvent) = [false, [false, 20]]; GVAR(DustHandler) = -1; GVAR(RainDrops) = objNull; diff --git a/addons/goggles/XEH_preInit.sqf b/addons/goggles/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/goggles/XEH_preInit.sqf +++ b/addons/goggles/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/goggles/config.cpp b/addons/goggles/config.cpp index 8341caa9f4..9102b7fbf0 100644 --- a/addons/goggles/config.cpp +++ b/addons/goggles/config.cpp @@ -270,8 +270,3 @@ class CfgCloudlets { destroyOnWaterSurface = 1; }; }; - -class ACE_newEvents { - GlassesChanged = "ace_glassesChanged"; - GlassesCracked = "ace_glassesCracked"; -}; 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..df73bd5bec 100644 --- a/addons/goggles/functions/fnc_applyDirtEffect.sqf +++ b/addons/goggles/functions/fnc_applyDirtEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Adds dirt effect to the glasses. @@ -13,15 +14,12 @@ * * Public: Yes */ -#include "script_component.hpp" 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..d8c6e1c07a 100644 --- a/addons/goggles/functions/fnc_applyDustEffect.sqf +++ b/addons/goggles/functions/fnc_applyDustEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Applies dust to screen. @@ -13,13 +14,10 @@ * * Public: Yes */ -#include "script_component.hpp" 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 71a5b3b84c..096673ea3a 100644 --- a/addons/goggles/functions/fnc_applyGlassesEffect.sqf +++ b/addons/goggles/functions/fnc_applyGlassesEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Sets screen tint for glasses. @@ -5,29 +6,32 @@ * Sets dirt/rain overlay for glasses. * * Arguments: - * 0: Glasses classname to be applied + * 0: Player + * 1: Glasses classname to be applied * * Return Value: * None * * Example: - * [goggles ace_player] call ace_goggles_fnc_applyGlassesEffect + * [ace_player, goggles ace_player] call ace_goggles_fnc_applyGlassesEffect * * Public: No */ -#include "script_component.hpp" -params ["_glasses"]; +params ["_player", "_glasses"]; +TRACE_2("applyGlassesEffect",_player,_glasses); // remove old effect call FUNC(removeGlassesEffect); -private ["_config", "_postProcessColour", "_postProcessTintAmount", "_imagePath"]; +if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _player) >> "isPlayableLogic")) == 1) exitWith { + TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) +}; -_config = configFile >> "CfgGlasses" >> _glasses; +private _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]; @@ -39,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..845490f95f 100644 --- a/addons/goggles/functions/fnc_applyRainEffect.sqf +++ b/addons/goggles/functions/fnc_applyRainEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Handles rain effects being created on glasses. @@ -13,15 +14,12 @@ * * Public: No */ -#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..ab71f01d51 100644 --- a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf +++ b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Handles the rotor wash effects. @@ -13,11 +14,8 @@ * * Public: No */ -#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..5efc547c10 100644 --- a/addons/goggles/functions/fnc_clearGlasses.sqf +++ b/addons/goggles/functions/fnc_clearGlasses.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Clears all dirt, rain, dust from glasses. @@ -14,14 +15,11 @@ * * Public: Yes */ -#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_externalCamera.sqf b/addons/goggles/functions/fnc_externalCamera.sqf index 9e7eed3efe..c251ef1f49 100644 --- a/addons/goggles/functions/fnc_externalCamera.sqf +++ b/addons/goggles/functions/fnc_externalCamera.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Returns if the camera is external or not. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" // Handle the ThreeDen Editor Camera if (is3DEN) exitWith {true}; diff --git a/addons/goggles/functions/fnc_getExplosionIndex.sqf b/addons/goggles/functions/fnc_getExplosionIndex.sqf index 9d7c4004c7..33f0668bef 100644 --- a/addons/goggles/functions/fnc_getExplosionIndex.sqf +++ b/addons/goggles/functions/fnc_getExplosionIndex.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Turns 0-1 damage of explosion Event into a rating system of 0-3 @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_damage"]; diff --git a/addons/goggles/functions/fnc_handleExplosion.sqf b/addons/goggles/functions/fnc_handleExplosion.sqf index 44be6ab6c1..db38e9ab20 100644 --- a/addons/goggles/functions/fnc_handleExplosion.sqf +++ b/addons/goggles/functions/fnc_handleExplosion.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Handles explosions. @@ -8,9 +9,11 @@ * Return Value: * Function is handled? * + * Example: + * [bob] call ace_goggles_fnc_handleExplosion + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; @@ -20,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}; @@ -31,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 066bc040f7..434a61ee5f 100644 --- a/addons/goggles/functions/fnc_handleFired.sqf +++ b/addons/goggles/functions/fnc_handleFired.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Determines whether to place dust on the goggles, based on calibre of weapon fired and other requirements. Called from the unified fired EH only for the local player. @@ -8,9 +9,11 @@ * Return Value: * Function is handled? * + * Example: + * call ace_goggles_fnc_handleFired + * * 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); @@ -21,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"); @@ -47,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; @@ -58,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_handleKilled.sqf b/addons/goggles/functions/fnc_handleKilled.sqf index b9af2e075b..db7364492d 100644 --- a/addons/goggles/functions/fnc_handleKilled.sqf +++ b/addons/goggles/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Handles the player dying. @@ -8,9 +9,11 @@ * Return Value: * Function is handled? * + * Example: + * [bob] call ace_goggles_fnc_handleKilled + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/goggles/functions/fnc_isDivingGoggles.sqf b/addons/goggles/functions/fnc_isDivingGoggles.sqf index ac86a09d2b..cc173f6dc3 100644 --- a/addons/goggles/functions/fnc_isDivingGoggles.sqf +++ b/addons/goggles/functions/fnc_isDivingGoggles.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Determines whether passed goggles is diving goggles or a variant of them. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_glasses"]; diff --git a/addons/goggles/functions/fnc_isGogglesVisible.sqf b/addons/goggles/functions/fnc_isGogglesVisible.sqf index dfa2b97087..3ad5085a57 100644 --- a/addons/goggles/functions/fnc_isGogglesVisible.sqf +++ b/addons/goggles/functions/fnc_isGogglesVisible.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Determines if goggles are visible on passed unit. @@ -13,13 +14,10 @@ * * Public: Yes */ -#include "script_component.hpp" 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/functions/fnc_isInRotorWash.sqf b/addons/goggles/functions/fnc_isInRotorWash.sqf index 319da3a875..d978cde0ce 100644 --- a/addons/goggles/functions/fnc_isInRotorWash.sqf +++ b/addons/goggles/functions/fnc_isInRotorWash.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, commy2 * Checks for nearby running helicopters (within 15m) @@ -7,7 +8,7 @@ * 1: Radius to check for helicopter (default: 15) * * Return Value: - * : + * Array : * 0: In rotorwash * 1: Amount of rotor wash. * @@ -17,7 +18,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", ["_radius", 15]]; diff --git a/addons/goggles/functions/fnc_removeDirtEffect.sqf b/addons/goggles/functions/fnc_removeDirtEffect.sqf index a6d5a232cc..732cbb5c23 100644 --- a/addons/goggles/functions/fnc_removeDirtEffect.sqf +++ b/addons/goggles/functions/fnc_removeDirtEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes dirt from the glasses. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" if (!isNull (GETUVAR(GVAR(DisplayEffects),displayNull))) then { (GETUVAR(GVAR(DisplayEffects),displayNull) displayCtrl 10660) ctrlSetText ""; diff --git a/addons/goggles/functions/fnc_removeDustEffect.sqf b/addons/goggles/functions/fnc_removeDustEffect.sqf index a04121e8ba..00031084b2 100644 --- a/addons/goggles/functions/fnc_removeDustEffect.sqf +++ b/addons/goggles/functions/fnc_removeDustEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes dust from the glasses. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" if (!isNull (GETUVAR(GVAR(DisplayEffects),displayNull))) then { (GETUVAR(GVAR(DisplayEffects),displayNull) displayCtrl 10662) ctrlSetText ""; diff --git a/addons/goggles/functions/fnc_removeGlassesEffect.sqf b/addons/goggles/functions/fnc_removeGlassesEffect.sqf index c27d8684e8..ab19570594 100644 --- a/addons/goggles/functions/fnc_removeGlassesEffect.sqf +++ b/addons/goggles/functions/fnc_removeGlassesEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes the glasses effect from the screen, removes dirt effect, removes rain effect, removes dust effect. Does not reset array (glasses will still be broken, dirty, ect.) @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" GVAR(EffectsActive) = false; GVAR(PostProcess) ppEffectEnable false; diff --git a/addons/goggles/functions/fnc_removeRainEffect.sqf b/addons/goggles/functions/fnc_removeRainEffect.sqf index fb7f3e5e2e..53de0721b1 100644 --- a/addons/goggles/functions/fnc_removeRainEffect.sqf +++ b/addons/goggles/functions/fnc_removeRainEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes rain effects from the screen. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" if (!isNull GVAR(RainDrops)) then { deleteVehicle GVAR(RainDrops); diff --git a/addons/goggles/script_component.hpp b/addons/goggles/script_component.hpp index 3074c10b81..854e27fab3 100644 --- a/addons/goggles/script_component.hpp +++ b/addons/goggles/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_GOGGLES @@ -38,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 5891c98434..86fb2e4558 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 @@ -12,6 +21,10 @@ Włącz efekty gogli w trzeciej osobie Mostrar efeitos de óculos em Terceira Pessoa Attiva l'effetto degli occhiali in terza persona + 三人称視点でもゴーグルによる効果を出す + 3인칭시에도 고글 효과를 보이게 합니다 + 在第三人称视角显示护目镜效果 + 在第三人稱視角顯示護目鏡效果 Wipe Goggles @@ -24,18 +37,46 @@ Wytrzyj gogle Limpar Óculos Pulisci gli occhiali + ゴーグルを拭く + 고글 닦기 + 擦拭护目镜 + 擦拭護目鏡 Goggle Effects Эффект очков + ゴーグルによる効果 + Efekty gogli + Brilleneffekt + 고글 효과 + Effets des lunettes + Effetti Occhiali + 护目镜效果 + 護目鏡效果 Tint Тонировка + 色彩のみ + Winieta + Tönung + 색조 + Teinte + Colore + 染色 + 染色 Tint + Effects Тонировка + эффекты + 色彩 + 効果 + Winieta + Efekty + Tönung + Effekte + 색조+효과 + Teinte + effets + Colore + Effetti + 染色 + 影响 + 染色 + 影響 - \ No newline at end of file + diff --git a/addons/grenades/CfgVehicles.hpp b/addons/grenades/CfgVehicles.hpp index 1315ccf611..f9ac60d9fe 100644 --- a/addons/grenades/CfgVehicles.hpp +++ b/addons/grenades/CfgVehicles.hpp @@ -2,40 +2,40 @@ class CfgVehicles { class NATO_Box_Base; class Box_NATO_Grenades_F: NATO_Box_Base { - class TransportItems { - MACRO_ADDITEM(ACE_HandFlare_White,12); - MACRO_ADDITEM(ACE_HandFlare_Green,12); - MACRO_ADDITEM(ACE_M84,12); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_HandFlare_White,12); + MACRO_ADDMAGAZINE(ACE_HandFlare_Green,12); + MACRO_ADDMAGAZINE(ACE_M84,12); }; }; class EAST_Box_Base; class Box_East_Grenades_F: EAST_Box_Base { - class TransportItems { - MACRO_ADDITEM(ACE_HandFlare_Yellow,12); - MACRO_ADDITEM(ACE_HandFlare_Red,12); - MACRO_ADDITEM(ACE_M84,12); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_HandFlare_Yellow,12); + MACRO_ADDMAGAZINE(ACE_HandFlare_Red,12); + MACRO_ADDMAGAZINE(ACE_M84,12); }; }; class IND_Box_Base; class Box_IND_Grenades_F: IND_Box_Base { - class TransportItems { - MACRO_ADDITEM(ACE_HandFlare_Yellow,12); - MACRO_ADDITEM(ACE_HandFlare_Green,12); - MACRO_ADDITEM(ACE_M84,12); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_HandFlare_Yellow,12); + MACRO_ADDMAGAZINE(ACE_HandFlare_Green,12); + MACRO_ADDMAGAZINE(ACE_M84,12); }; }; class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { - class TransportItems { - MACRO_ADDITEM(ACE_HandFlare_White,12); - MACRO_ADDITEM(ACE_HandFlare_Red,12); - MACRO_ADDITEM(ACE_HandFlare_Green,12); - MACRO_ADDITEM(ACE_HandFlare_Yellow,12); - MACRO_ADDITEM(ACE_M84,12); - MACRO_ADDITEM(ACE_M14,12); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_HandFlare_White,12); + MACRO_ADDMAGAZINE(ACE_HandFlare_Red,12); + MACRO_ADDMAGAZINE(ACE_HandFlare_Green,12); + MACRO_ADDMAGAZINE(ACE_HandFlare_Yellow,12); + MACRO_ADDMAGAZINE(ACE_M84,12); + MACRO_ADDMAGAZINE(ACE_M14,12); }; }; }; diff --git a/addons/grenades/XEH_postInit.sqf b/addons/grenades/XEH_postInit.sqf index 71347d721c..6809321d83 100644 --- a/addons/grenades/XEH_postInit.sqf +++ b/addons/grenades/XEH_postInit.sqf @@ -4,6 +4,11 @@ ["ace_flashbangExploded", {_this call FUNC(flashbangExplosionEH)}] call CBA_fnc_addEventHandler; +// Register fired event handlers +["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayerNonLocal", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedNonPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; + if (!hasInterface) exitWith {}; GVAR(flashbangPPEffectCC) = ppEffectCreate ["ColorCorrections", 4265]; @@ -15,12 +20,9 @@ GVAR(flashbangPPEffectCC) ppEffectForceInNVG true; if !([ACE_player, objNull, ["isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active + if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement [] call FUNC(nextMode); }, {false}, [9, [false, false, false]], false] call CBA_fnc_addKeybind; //8 Key - -// Register fire event handler -["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedPlayerNonLocal", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedNonPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; diff --git a/addons/grenades/XEH_preInit.sqf b/addons/grenades/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/grenades/XEH_preInit.sqf +++ b/addons/grenades/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/grenades/config.cpp b/addons/grenades/config.cpp index a06d5f74d8..c836b613e1 100644 --- a/addons/grenades/config.cpp +++ b/addons/grenades/config.cpp @@ -28,7 +28,3 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "Effects.hpp" - -class ACE_newEvents { - flashbangExplosion = "ace_flashbangExploded"; -}; diff --git a/addons/grenades/functions/fnc_flare.sqf b/addons/grenades/functions/fnc_flare.sqf index a0e8e1ff40..9ad3348f6b 100644 --- a/addons/grenades/functions/fnc_flare.sqf +++ b/addons/grenades/functions/fnc_flare.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Makes flare shine. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_projectile", "_color", "_intensity", "_timeToLive"]; diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index 0d0779ccef..37e9a10845 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Creates the flashbang effect and knock out AI units. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_grenadePosASL"]; TRACE_1("params",_grenadePosASL); diff --git a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf index 5c05abc9a3..46ff41171d 100644 --- a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf +++ b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Waits for the flashbang grenade fuze to trigger and 'explode' @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_projectile"]; TRACE_1("params",_projectile); diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index e9267a155e..b07ed48fb3 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Makes incendiary burn. @@ -14,7 +15,8 @@ * * Public: No */ -#include "script_component.hpp" + +#define ALERT_NEAR_ENEMY_RANGE 60 #define PARTICLE_LIFE_TIME 2 #define PARTICLE_DENSITY 20 @@ -32,10 +34,31 @@ #define ORIENTATION 5.4 #define EXPANSION 1 -params ["_projectile", "_timeToLive"]; +#define DESTRUCTION_RADIUS 1.8 + +params ["_projectile", "_timeToLive", "_center"]; + +if (isNull _projectile) exitWith {TRACE_1("null",_projectile);}; private _position = position _projectile; +// --- AI +private _nearLocalEnemies = []; + +{ + { + if (local _x && {[_center, side _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECTS SIDE HERE! + _nearLocalEnemies pushBackUnique _x; + }; + } forEach crew _x; +} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); + +{ + if (behaviour _x in ["SAFE", "AWARE"]) then { + _x setBehaviour "COMBAT"; + }; +} forEach _nearLocalEnemies; + // --- fire private _fire = "#particlesource" createVehicleLocal _position; @@ -144,9 +167,19 @@ if (isServer) then { //systemChat format ["burn: %1", _x]; // --- destroy nearby static weapons and ammo boxes - if (_x isKindOf "StaticWeapon" || {_x isKindOf "ReammoBox_F"}) then { + if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { _x setDamage 1; }; + if (_x isKindOf "ReammoBox_F") 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; + }; + }; // --- delete nearby ground weapon holders if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { @@ -156,13 +189,41 @@ 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"; + +if (!local _vehicle) exitWith {}; + +private _config = _vehicle call CBA_fnc_getObjectConfig; + +// --- burn tyres +private _fnc_isWheelHitPoint = { + params ["_selectionName"]; + + // wheels must use a selection named "wheel_X_Y_steering" for PhysX to work + _selectionName select [0, 6] == "wheel_" && { + _selectionName select [count _selectionName - 9] == "_steering" + } // return +}; + +{ + private _wheelSelection = getText (_config >> "HitPoints" >> _x >> "name"); + + if (_wheelSelection call _fnc_isWheelHitPoint) then { + private _wheelPosition = _vehicle modelToWorld (_vehicle selectionPosition _wheelSelection); + + if (_position distance _wheelPosition < EFFECT_SIZE * 2) then { + _vehicle setHit [_wheelSelection, 1]; + }; + }; +} forEach (getAllHitPointsDamage _vehicle param [0, []]); // --- burn car engine -private _vehicle = _position nearestObject "Car"; -if (!local _vehicle || {_vehicle isKindOf "Wheeled_APC_F"}) exitWith {}; +if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; -private _engineSelection = getText (_vehicle call CBA_fnc_getObjectConfig >> "HitPoints" >> "HitEngine" >> "name"); +private _engineSelection = getText (_config >> "HitPoints" >> "HitEngine" >> "name"); private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); if (_position distance _enginePosition < EFFECT_SIZE * 2) then { diff --git a/addons/grenades/functions/fnc_nextMode.sqf b/addons/grenades/functions/fnc_nextMode.sqf index 99149f5185..839fbd5786 100644 --- a/addons/grenades/functions/fnc_nextMode.sqf +++ b/addons/grenades/functions/fnc_nextMode.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Select the next throwing mode and display message. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; diff --git a/addons/grenades/functions/fnc_throwGrenade.sqf b/addons/grenades/functions/fnc_throwGrenade.sqf index 5f66dc30bf..0fe0c483d9 100644 --- a/addons/grenades/functions/fnc_throwGrenade.sqf +++ b/addons/grenades/functions/fnc_throwGrenade.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Adjust the grenades throwing direction and speed to the selected throwing mode. Called from the unified fired EH only for CAManBase @@ -13,7 +14,6 @@ * * 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); @@ -56,11 +56,12 @@ if (getNumber (_config >> QGVAR(incendiary)) == 1) then { private _fuzeTime = getNumber (_config >> "explosionTime"); private _timeToLive = getNumber (_config >> "timeToLive"); - [FUNC(incendiary), [_projectile, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; + [FUNC(incendiary), [_projectile, _timeToLive, side _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // WE WANT THE OBJECTS SIDE HERE! }; // handle throw modes if (_unit != ACE_player) exitWith {}; +if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");}; private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; diff --git a/addons/grenades/script_component.hpp b/addons/grenades/script_component.hpp index 299a1cd69a..49dbe92a3f 100644 --- a/addons/grenades/script_component.hpp +++ b/addons/grenades/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_GRENADES diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index 711d12d023..d89ff53044 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Gránátkezelési mód váltása Cambia tipo di granata Alternar Modo de Granada + 投てき方法を切り替え + 투척 종류 전환 + 切换投掷模式 + 切換投擲模式 Normal Throw @@ -24,6 +28,10 @@ Normál dobás Lancio normale Arremesso Normal + 普通に投げる + 일반 던지기 + 普通投掷 + 普通投擲 High Throw @@ -36,6 +44,10 @@ Magas dobás Lancio verso l'alto Arremesso Alto + 高く投げる + 높이 던지기 + 高抛 + 高拋 Precise Throw @@ -48,6 +60,10 @@ Pontos dobás Lancio preciso Arremesso Preciso + 低く投げる + 정확한 던지기 + 精准投掷 + 精準投擲 Roll Grenade @@ -60,6 +76,10 @@ Gránát gurítása Fai rotolare la granata Rolar Granada + 転がす + 굴려넣기 + 地面滚抛 + 地面滾拋 Drop Grenade @@ -72,6 +92,10 @@ Gránát ejtése Lascia la granata Largar Granada + 落とす + 떨어뜨리기 + 下丢投掷 + 下丟投擲 M84 Stun Grenade @@ -84,6 +108,10 @@ M84 Kábítógránát Granata Stordente M84 M84 granada de atordoamento + M84 閃光手榴弾 + M84 섬광 수류탄 + M84 震撼弹 + M84 震撼彈 M84 @@ -96,6 +124,10 @@ M84 M84 M84 + M84 + M84 + M84 + M84 Also known as flashbang. Causes immediate flash blindness, deafness, tinnitus, and inner ear disturbance. @@ -108,6 +140,10 @@ Villanógránát néven is ismert. Azonnali villanási vakságot, süketséget, fülzúgást, és belső füli zavart okoz. Anche conosciuta come flashbang. Causa accecamento immediato, sensazioni di sposatezza, mancanza d'equilibrio e disturbi al timpano. Também conhecida como flashbang. Causa uma clarão imediato, cegueira, surdez, zumbido e distúrbio no tímpano. + フラッシュバンとも知られています。即時に失明と難聴、耳鳴り、内耳障害を引き起こします。 + 플래시뱅이라고도 알려져있습니다. 사용즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. + 也被称为闪光弹,会造成暂时性失明,耳聋,耳鸣等效果。 + 也被稱為閃光彈,會造成暫時性失明,耳聾,耳鳴等效果 M127A1 Hand Held Signal (White) @@ -120,6 +156,10 @@ M127A1 Фальшфейер (Белый) Bengala M127A1 (Blanca) M127A1 Feux à main (Blanc) + M127A1 信号弾 (白) + M127A1 신호탄 (하얀색) + M127A1 手持式信号弹 (白色) + M127A1 手持式信號彈 (白色) M127A1 Hand Held Signal (Red) @@ -132,6 +172,10 @@ M127A1 Фальшфейер (Красный) Bengala M127A1 (Roja) M127A1 Feux à main (Rouge) + M127A1 信号弾 (赤) + M127A1 신호탄 (빨간색) + M127A1 手持式信号弹 (红色) + M127A1 手持式信號彈 (紅色) M127A1 Hand Held Signal (Green) @@ -144,6 +188,10 @@ M127A1 Фальшфейер (Зелёный) Bengala M127A1 (Verde) M127A1 Feux à main (Vert) + M127A1 信号弾 (緑) + M127A1 신호탄 (초록색) + M127A1 手持式信号弹 (绿色) + M127A1 手持式信號彈 (綠色) M127A1 Hand Held Signal (Yellow) @@ -156,6 +204,10 @@ M127A1 Фальшфейер (Жёлтые) Bengala M127A1 (Amarilla) M127A1 Feux à main (Jaune) + M127A1 信号弾 (黄) + M127A1 신호탄 (노란색) + M127A1 手持式信号弹 (黄色) + M127A1 手持式信號彈 (黃色) White Hand Flare @@ -168,6 +220,10 @@ Фальшфейер (Белый) Bengala (Blanca) Feux à main (Blanc) + 白の発炎筒 + 하얀색 불꽃신호기 + 白色手持式信号弹 + 白色手持式信號彈 Red Hand Flare @@ -180,6 +236,10 @@ Фальшфейер (Красный) Bengala (Roja) Feux à main (Rouge) + 赤の発炎筒 + 빨간색 불꽃신호기 + 红色手持式信号弹 + 紅色手持式信號彈 Green Hand Flare @@ -192,6 +252,10 @@ Фальшфейер (Зелёный) Bengala (Verde) Feux à main (Vert) + 緑の発炎筒 + 초록색 불꽃신호기 + 绿色手持式信号弹 + 綠色手持式信號彈 Yellow Hand Flare @@ -204,6 +268,10 @@ Фальшфейер (Жёлтые) Bengala (Amarilla) Feux à main (Jaune) + 黄の発炎筒 + 노란색 불꽃신호기 + 黄色手持式信号弹 + 黃色手持式信號彈 M127A1 (White) @@ -216,6 +284,10 @@ M127A1 (Branco) M127A1 (Белый) M127A1 (Blanca) + M127A1 (白) + M127A1 (하양) + M127A1 (白色) + M127A1 (白色) M127A1 (Red) @@ -228,6 +300,10 @@ M127A1 (Vermelho) M127A1 (Красный) M127A1 (Roja) + M127A1 (赤) + M127A1 (빨강) + M127A1 (红色) + M127A1 (紅色) M127A1 (Green) @@ -240,6 +316,10 @@ M127A1 (Verde) M127A1 (Зелёный) M127A1 (Verde) + M127A1 (緑) + M127A1 (초록) + M127A1 (绿色) + M127A1 (綠色) M127A1 (Yellow) @@ -252,21 +332,46 @@ M127A1 (Amarelo) M127A1 (Жёлтые) M127A1 (Amarilla) + M127A1 (黄) + M127A1 (노랑) + M127A1 (黄色) + M127A1 (黃色) AN-M14 Incendiary Grenade AN-M14 Brandsatz AN-M14 Зажигательная граната + AN-M14 焼夷手榴弾 + Granat zapalający AN-M14 + AN-M14 소이 수류탄 + Grenade incendiaire AN-M14 + AN-M14 Granata Incendiaria + AN-M14 燃烧手榴弹 + AN-M14 燃燒手榴彈 AN-M14 AN-M14 AN-M14 + AN-M14 + AN-M14 + AN-M14 + AN-M14 + AN-M14 + AN-M14 + AN-M14 Incendiary grenade used to destroy weapons, ammunition and other equipment. Brandsatzgranate. Verwendet um Waffen, Munition und andere Ausrüstung zu zerstören. Зажигательная граната используется для уничтожения оружия, боеприпасов и прочего оборудования. + 焼夷手榴弾は武器や弾薬箱などの装備を破壊するために使われます。 + Granat zapalający, używany do niszczenia broni, amunicji i innego sprzętu. + 소이 수류탄은 무기나 탄약 그리고 장비를 파괴할때 쓰입니다. + 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/gunbag/CfgVehicles.hpp b/addons/gunbag/CfgVehicles.hpp index 1377a8f84d..e23966cfa2 100644 --- a/addons/gunbag/CfgVehicles.hpp +++ b/addons/gunbag/CfgVehicles.hpp @@ -8,7 +8,6 @@ class CfgVehicles { condition = QUOTE(([_target] call FUNC(hasGunbag)) && {[ARR_2(_player,_target)] call FUNC(canInteract) == 0}); statement = QUOTE([ARR_2(_player,_target)] call FUNC(toGunbag)); showDisabled = 0; - priority = 1; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; class GVAR(weaponOff) { @@ -16,7 +15,6 @@ class CfgVehicles { condition = QUOTE(([_target] call FUNC(hasGunbag)) && {[ARR_2(_player,_target)] call FUNC(canInteract) == 1}); statement = QUOTE([ARR_2(_player,_target)] call FUNC(offGunbag)); showDisabled = 0; - priority = 1; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; class GVAR(status) { @@ -24,7 +22,6 @@ class CfgVehicles { condition = QUOTE([_target] call FUNC(hasGunbag)); statement = QUOTE([_target] call FUNC(status)); showDisabled = 0; - priority = 2; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; }; @@ -36,15 +33,12 @@ class CfgVehicles { displayName = CSTRING(Displayname); condition = QUOTE([_player] call FUNC(hasGunbag)); showDisabled = 0; - priority = 0.1; icon = QPATHTOF(ui\gunbag_icon_ca.paa); - class GVAR(weaponTo) { displayName = CSTRING(ToGunbag); condition = QUOTE([ARR_2(_player,_player)] call FUNC(canInteract) == 0); statement = QUOTE([ARR_2(_player,_player)] call FUNC(toGunbag)); showDisabled = 0; - priority = 1; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; class GVAR(weaponOff) { @@ -52,7 +46,6 @@ class CfgVehicles { condition = QUOTE([ARR_2(_player,_player)] call FUNC(canInteract) == 1); statement = QUOTE([ARR_2(_player,_player)] call FUNC(offGunbag)); showDisabled = 0; - priority = 1; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; class GVAR(status) { @@ -60,7 +53,6 @@ class CfgVehicles { condition = QUOTE([_player] call FUNC(hasGunbag)); statement = QUOTE([_player] call FUNC(status)); showDisabled = 0; - priority = 2; icon = QPATHTOF(ui\gunbag_icon_ca.paa); }; }; diff --git a/addons/gunbag/XEH_preInit.sqf b/addons/gunbag/XEH_preInit.sqf index 73b1a7ea75..8f313ba472 100644 --- a/addons/gunbag/XEH_preInit.sqf +++ b/addons/gunbag/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; // restore gunbag info after respawn ["CAManBase", "respawn", { @@ -22,4 +24,22 @@ ADDON = false; }, _this] call CBA_fnc_execNextFrame; }] call CBA_fnc_addClassEventHandler; +[QEGVAR(arsenal,displayOpened), { + + private _center = EGVAR(arsenal,center); + + if (_center call FUNC(hasGunBag)) then { + GVAR(arsenalCache) = (backpackContainer _center) getVariable [QGVAR(gunbagWeapon), []]; + }; +}] call CBA_fnc_addEventHandler; + +[QEGVAR(arsenal,displayClosed), { + + if !(isNil QGVAR(arsenalCache)) then { + (backpackContainer EGVAR(arsenal,center)) setVariable [QGVAR(gunbagWeapon),GVAR(arsenalCache), true]; + }; + + GVAR(arsenalCache) = nil; +}] call CBA_fnc_addEventHandler; + ADDON = true; diff --git a/addons/gunbag/data/ace_gunbag.p3d b/addons/gunbag/data/ace_gunbag.p3d index 22658bb93d..64de90bf4e 100644 Binary files a/addons/gunbag/data/ace_gunbag.p3d and b/addons/gunbag/data/ace_gunbag.p3d differ diff --git a/addons/gunbag/functions/fnc_calculateMass.sqf b/addons/gunbag/functions/fnc_calculateMass.sqf index d55ac3a8ee..8f845dc4ee 100644 --- a/addons/gunbag/functions/fnc_calculateMass.sqf +++ b/addons/gunbag/functions/fnc_calculateMass.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Calculate mass of weapon an items. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_weapon", "_items", "_magazines"]; diff --git a/addons/gunbag/functions/fnc_canInteract.sqf b/addons/gunbag/functions/fnc_canInteract.sqf index 1ec9e38583..46451b50d5 100644 --- a/addons/gunbag/functions/fnc_canInteract.sqf +++ b/addons/gunbag/functions/fnc_canInteract.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Check if client able to interact with gunbag. @@ -7,14 +8,13 @@ * 1: Target * * Return Value: - * -1: can't interact 0: empty gunbag 1: full gunbag + * -1: can't interact 0: empty gunbag 1: full gunbag * * Example: * _canInteract = [player, target] call ace_gunbag_fnc_canInteract * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/gunbag/functions/fnc_hasGunbag.sqf b/addons/gunbag/functions/fnc_hasGunbag.sqf index 8c8fdd6147..5fa90c7b9c 100644 --- a/addons/gunbag/functions/fnc_hasGunbag.sqf +++ b/addons/gunbag/functions/fnc_hasGunbag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Switches gunbag full/empty for mass calculation. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/gunbag/functions/fnc_isMachineGun.sqf b/addons/gunbag/functions/fnc_isMachineGun.sqf index a6191c1cca..76cf64d443 100644 --- a/addons/gunbag/functions/fnc_isMachineGun.sqf +++ b/addons/gunbag/functions/fnc_isMachineGun.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Reports true if a weapon is a machine gun. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_weapon"]; diff --git a/addons/gunbag/functions/fnc_offGunbag.sqf b/addons/gunbag/functions/fnc_offGunbag.sqf index a46d49675d..751402fa0f 100644 --- a/addons/gunbag/functions/fnc_offGunbag.sqf +++ b/addons/gunbag/functions/fnc_offGunbag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Get weapon out of gunbag. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/gunbag/functions/fnc_offGunbagCallback.sqf b/addons/gunbag/functions/fnc_offGunbagCallback.sqf index 5d548d0e9c..794ea2e709 100644 --- a/addons/gunbag/functions/fnc_offGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_offGunbagCallback.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Get weapon out of gunbag. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; @@ -29,6 +29,16 @@ if (_state isEqualTo []) exitWith { _state params ["_weapon", "_items", "_magazines"]; _unit addWeapon _weapon; + +// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten +([_unit, _weapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; +{ + if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { + TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); + _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; + }; +} forEach _magazines; + removeAllPrimaryWeaponItems _unit; { diff --git a/addons/gunbag/functions/fnc_status.sqf b/addons/gunbag/functions/fnc_status.sqf index 33c30ec0e1..730e992dcb 100644 --- a/addons/gunbag/functions/fnc_status.sqf +++ b/addons/gunbag/functions/fnc_status.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Check gunbag status full/empty. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/gunbag/functions/fnc_toGunbag.sqf b/addons/gunbag/functions/fnc_toGunbag.sqf index 8851e5610b..1f52eb6baf 100644 --- a/addons/gunbag/functions/fnc_toGunbag.sqf +++ b/addons/gunbag/functions/fnc_toGunbag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Put weapon into gunbag. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/gunbag/functions/fnc_toGunbagCallback.sqf b/addons/gunbag/functions/fnc_toGunbagCallback.sqf index 3587c9e6b8..e47c817979 100644 --- a/addons/gunbag/functions/fnc_toGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_toGunbagCallback.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ir0n1E * Put weapon into gunbag. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/gunbag/script_component.hpp b/addons/gunbag/script_component.hpp index 5627e1048b..c0595c1a46 100644 --- a/addons/gunbag/script_component.hpp +++ b/addons/gunbag/script_component.hpp @@ -2,10 +2,9 @@ #define COMPONENT_BEAUTIFIED Gunbag #include "\z\ace\addons\main\script_mod.hpp" -//#define DEBUG_ENABLED_GUNBAG -//#define DISABLE_COMPILE_CACHE -//#define CBA_DEBUG_SYNCHRONOUS -//#define ENABLE_PERFORMANCE_COUNTERS +// #define DEBUG_ENABLED_GUNBAG +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_GUNBAG #define DEBUG_MODE_FULL diff --git a/addons/gunbag/stringtable.xml b/addons/gunbag/stringtable.xml index 6fca478f6d..ab4fdf5ac7 100644 --- a/addons/gunbag/stringtable.xml +++ b/addons/gunbag/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -7,6 +7,12 @@ Housse d'arme Чехол Pouzdro na zbraň + ガンバッグ + Torba na broń + 총가방 + Borsa per Armi + 枪袋 + 槍袋 Gunbag (Tan) @@ -14,6 +20,12 @@ Housse d'arme (marron clair) Чехол (желтовато-коричневый) Pouzdro na zbraň (Žlutohnědá) + ガンバッグ (タン) + Torba na broń (jasnobrązowa) + 총가방 (황갈색) + Borsa per Armi (Tan) + 枪袋 (黄褐色) + 槍袋 (黃褐色) Put weapon into gunbag @@ -21,6 +33,12 @@ Placer l'arme dans la housse d'arme Зачехлить оружие Vložit zbraň do pouzdra + ガンバッグへ武器を入れる + Włóż broń do torby + 무기를 총가방에 넣기 + Metti l'arma nella borsa per armi + 将武器放置枪袋 + 將武器放置槍袋 Get weapon out of gunbag @@ -28,6 +46,12 @@ Sortir l'arme hors de la housse Расчехлить оружие Vytáhnout zbraň z pouzdra + ガンバッグから武器を出す + Wyciągnij broń z torby + 무기를 총가방에서 꺼내기 + Prendi l'arma dalla borsa per armi + 将武器拿出枪袋 + 將武器拿出槍袋 Status @@ -35,6 +59,12 @@ Status Статус Status + 中身 + Status + 상태 + Stato + 状态 + 狀態 Gunbag Empty @@ -42,6 +72,12 @@ Housse d'arme vide Чехол пуст Prázdné pouzdro na zbraň + ガンバッグは空 + Torba jest pusta + 총가방 비어있음 + Borsa per armi vuota + 枪袋为空 + 槍袋為空 - \ No newline at end of file + diff --git a/addons/hearing/ACE_Arsenal_Stats.hpp b/addons/hearing/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..cc9e048823 --- /dev/null +++ b/addons/hearing/ACE_Arsenal_Stats.hpp @@ -0,0 +1,21 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_hearingProtection: statBase { + scope = 2; + priority = 2; + stats[] = {QGVAR(protection)}; + displayName= CSTRING(statHearingProtection); + showBar = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 1)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default)); + tabs[] = {{6}, {}}; + }; + class ACE_volumeMuffling: statBase { + scope = 2; + priority = 1; + stats[] = {QGVAR(lowerVolume)}; + displayName= CSTRING(statHearingLowerVolume); + showBar = 1; + barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 1)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default)); + tabs[] = {{6}, {}}; + }; +}; diff --git a/addons/hearing/ACE_Settings.hpp b/addons/hearing/ACE_Settings.hpp index 2fb2a46211..a395ddd99f 100644 --- a/addons/hearing/ACE_Settings.hpp +++ b/addons/hearing/ACE_Settings.hpp @@ -8,13 +8,19 @@ class ACE_Settings { }; class GVAR(earplugsVolume) { category = CSTRING(Module_DisplayName); + displayName = CSTRING(earplugsVolume_DisplayName); + description = CSTRING(earplugsVolume_Description); value = 0.5; typeName = "SCALAR"; + sliderSettings[] = {0, 1, 0.5, 1}; }; class GVAR(unconsciousnessVolume) { category = CSTRING(Module_DisplayName); + displayName = CSTRING(unconsciousnessVolume_DisplayName); + description = CSTRING(unconsciousnessVolume_Description); 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 760ed95a03..48fb79277e 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -5,20 +5,18 @@ class CfgVehicles { class ACE_Equipment { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); - condition = QUOTE( !([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player} ); - exceptions[] = {"isNotInside", "isNotSitting"}; + condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}}); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE( [_player] call FUNC(putInEarPlugs) ); showDisabled = 0; - priority = 2.5; icon = QPATHTOF(UI\ACE_earplugs_x_ca.paa); }; class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); - condition = QUOTE( [_player] call FUNC(hasEarPlugsIn) ); - exceptions[] = {"isNotInside", "isNotSitting"}; + condition = QUOTE( GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)}); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE( [_player] call FUNC(removeEarPlugs) ); showDisabled = 0; - priority = 2.5; icon = QPATHTOF(UI\ACE_earplugs_x_ca.paa); }; }; @@ -97,7 +95,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 c063c0e896..5328ff8e9d 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -1,54 +1,91 @@ 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; }; }; + #define HEARING_PROTECTION_VICCREW EGVAR(hearing,protection) = 0.85; EGVAR(hearing,lowerVolume) = 0.6; + #define HEARING_PROTECTION_EARMUFF EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0.5; + #define HEARING_PROTECTION_PELTOR EGVAR(hearing,protection) = 0.75; EGVAR(hearing,lowerVolume) = 0; + class H_HelmetB; class H_HelmetCrew_B: H_HelmetB { - GVAR(protection) = 1; - GVAR(lowerVolume) = 0.80; + HEARING_PROTECTION_VICCREW }; class H_CrewHelmetHeli_B: H_HelmetB { - GVAR(protection) = 0.85; - GVAR(lowerVolume) = 0.75; + HEARING_PROTECTION_VICCREW }; class H_PilotHelmetHeli_B: H_HelmetB { - GVAR(protection) = 0.85; - GVAR(lowerVolume) = 0.75; + HEARING_PROTECTION_VICCREW }; class H_PilotHelmetFighter_B: H_HelmetB { - GVAR(protection) = 1; - GVAR(lowerVolume) = 0.80; + HEARING_PROTECTION_VICCREW }; class HelmetBase; class H_Cap_headphones: HelmetBase { - GVAR(protection) = 0.5; - GVAR(lowerVolume) = 0.60; + 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 { - GVAR(protection) = 0.8; - GVAR(lowerVolume) = 0.20; + HEARING_PROTECTION_PELTOR + }; + class H_HelmetB_camo: H_HelmetB { + HEARING_PROTECTION_PELTOR }; class H_HelmetB_plain_mcamo; class H_HelmetSpecB: H_HelmetB_plain_mcamo { - GVAR(protection) = 0.8; - GVAR(lowerVolume) = 0.20; + HEARING_PROTECTION_PELTOR }; + class H_HelmetB_TI_tna_F: H_HelmetB { + HEARING_PROTECTION_PELTOR + }; + + class H_Tank_base_F; + class H_Tank_black_F: H_Tank_base_F { + HEARING_PROTECTION_VICCREW + }; + + class H_RacingHelmet_1_F: H_HelmetB_camo { + HEARING_PROTECTION_VICCREW + }; + + class H_HelmetO_ocamo: H_HelmetB { + HEARING_PROTECTION_PELTOR + }; // Defender and Assasin Helmet inherit. + + class H_HelmetO_ViperSP_hex_f: H_HelmetB { + HEARING_PROTECTION_PELTOR + }; }; diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index 34664525da..17548a973b 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -11,35 +11,71 @@ GVAR(playerVehAttenuation) = 1; GVAR(time3) = 0; GVAR(damageCoefficent) = 1; GVAR(volumeAttenuation) = 1; +GVAR(lastPlayerVehicle) = objNull; ["ace_settingsInitialized", { TRACE_1("settingInit",GVAR(EnableCombatDeafness)); // Only run PFEH and install event handlers if combat deafness is enabled if (!GVAR(EnableCombatDeafness)) exitWith {}; - //Add XEH: - ["CAManBase", "FiredNear", FUNC(firedNear)] call CBA_fnc_addClassEventHandler; - ["CAManBase", "Explosion", FUNC(explosionNear)] call CBA_fnc_addClassEventHandler; - - // Update hearing protection now: - [] call FUNC(updateHearingProtection); - // Spawn volume updating process - [FUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler; // Update veh attunation when player veh changes - ["vehicle", FUNC(updatePlayerVehAttenuation)] call CBA_fnc_addPlayerEventHandler; - ["turret", FUNC(updatePlayerVehAttenuation)] call CBA_fnc_addPlayerEventHandler; + ["vehicle", { + params ["_player", "_vehicle"]; + TRACE_2("vehicle change",_player,_vehicle); + _this call FUNC(updatePlayerVehAttenuation); + + if (!isNull GVAR(lastPlayerVehicle)) then { + private _firedEH = GVAR(lastPlayerVehicle) getVariable [QGVAR(firedEH), -1]; + GVAR(lastPlayerVehicle) removeEventHandler ["FiredNear", _firedEH]; + GVAR(lastPlayerVehicle) setVariable [QGVAR(firedEH), nil]; + GVAR(lastPlayerVehicle) = objNull; + TRACE_2("removed veh eh",_firedEH,GVAR(lastPlayerVehicle)); + }; + if ((!isNull _vehicle) && {_player != _vehicle}) then { + private _firedEH = _vehicle addEventHandler ["FiredNear", {call FUNC(firedNear)}]; + _vehicle setVariable [QGVAR(firedEH), _firedEH]; + GVAR(lastPlayerVehicle) = _vehicle; + TRACE_2("added veh eh",_firedEH,GVAR(lastPlayerVehicle)); + }; + }, true] call CBA_fnc_addPlayerEventHandler; + ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; + // Reset deafness on respawn (or remote control player switch) ["unit", { + params ["_player", "_oldPlayer"]; + TRACE_2("unit change",_player,_oldPlayer); + + if (!isNull _oldPlayer) then { + private _firedEH = _oldPlayer getVariable [QGVAR(firedEH), -1]; + _oldPlayer removeEventHandler ["FiredNear", _firedEH]; + _oldPlayer setVariable [QGVAR(firedEH), nil]; + private _explosionEH = _oldPlayer getVariable [QGVAR(explosionEH), -1]; + _oldPlayer removeEventHandler ["Explosion", _explosionEH]; + _oldPlayer setVariable [QGVAR(explosionEH), nil]; + TRACE_3("removed unit eh",_oldPlayer,_firedEH,_explosionEH); + }; + // Don't add a new EH if the unit respawned + if ((_player getVariable [QGVAR(firedEH), -1]) == -1) then { + if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _player) >> "isPlayableLogic")) == 1) exitWith { + TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) + }; + private _firedEH = _player addEventHandler ["FiredNear", {call FUNC(firedNear)}]; + _player setVariable [QGVAR(firedEH), _firedEH]; + private _explosionEH = _player addEventHandler ["Explosion", {call FUNC(explosionNear)}]; + _player setVariable [QGVAR(explosionEH), _explosionEH]; + TRACE_3("added unit eh",_player,_firedEH,_explosionEH); + }; + GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; - ACE_player setVariable [QGVAR(deaf), false]; GVAR(time3) = 0; [] call FUNC(updateHearingProtection); - }] call CBA_fnc_addPlayerEventHandler; + }, true] call CBA_fnc_addPlayerEventHandler; // Update protection on possible helmet change - ["loadout", FUNC(updateHearingProtection)] call CBA_fnc_addPlayerEventHandler; + ["loadout", LINKFUNC(updateHearingProtection), false] call CBA_fnc_addPlayerEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/hearing/config.cpp b/addons/hearing/config.cpp index e562227047..a1cc956d89 100644 --- a/addons/hearing/config.cpp +++ b/addons/hearing/config.cpp @@ -20,3 +20,4 @@ class CfgPatches { #include "CfgWeapons.hpp" #include "CfgAmmo.hpp" #include "ACE_Settings.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index 9e6bd0cab2..2fcfdab75d 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Called on unit initialization. Adds earplugs if the unit is equipped with either a really loud primary weapon or a rocket launcher. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); diff --git a/addons/hearing/functions/fnc_earRinging.sqf b/addons/hearing/functions/fnc_earRinging.sqf index 273fad8107..ae830e09a2 100644 --- a/addons/hearing/functions/fnc_earRinging.sqf +++ b/addons/hearing/functions/fnc_earRinging.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2, Rocko, Rommel, Ruthberg * Handle new sound souce near ace_player and apply hearing damage @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_strength"]; if (_strength < 0.05) exitWith {}; diff --git a/addons/hearing/functions/fnc_explosionNear.sqf b/addons/hearing/functions/fnc_explosionNear.sqf index 76c6707de5..799002b3f7 100644 --- a/addons/hearing/functions/fnc_explosionNear.sqf +++ b/addons/hearing/functions/fnc_explosionNear.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2, Ruthberg * Handles deafness due to explosions going off near the player. @@ -14,16 +15,12 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_damage"]; -if (_unit != ACE_player) exitWith {}; - 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_firedNear.sqf b/addons/hearing/functions/fnc_firedNear.sqf index 46bbee4fae..4dd8c759a3 100644 --- a/addons/hearing/functions/fnc_firedNear.sqf +++ b/addons/hearing/functions/fnc_firedNear.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Handles deafness due to large-caliber weapons going off near the player. @@ -20,12 +21,9 @@ * * Public: No */ -#include "script_component.hpp" params ["_object", "_firer", "_distance", "_weapon", "", "", "_ammo"]; -//Only run if firedNear object is player or player's vehicle: -if ((ACE_player != _object) && {(vehicle ACE_player) != _object}) exitWith {}; if (_weapon in ["Throw", "Put"]) exitWith {}; if (_distance > 50) exitWith {}; @@ -55,7 +53,7 @@ if (isNil "_loudness") then { }; } count _muzzles; { - _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo"); + private _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo"); _weaponMagazines set [_forEachIndex, [_x, _ammoType]]; } forEach _weaponMagazines; @@ -74,6 +72,8 @@ if (isNil "_loudness") then { private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); _caliber = call { + // If explicilty defined, use ACE_caliber + if ((count configProperties [(configFile >> "CfgAmmo" >> _ammo), "configName _x == 'ACE_caliber'", false]) == 1) exitWith {_caliber}; if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 }; if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 }; diff --git a/addons/hearing/functions/fnc_handleRespawn.sqf b/addons/hearing/functions/fnc_handleRespawn.sqf index 5bad68761c..74dee65b04 100644 --- a/addons/hearing/functions/fnc_handleRespawn.sqf +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Reset earplugs on respawn, and then re-add if appropriate @@ -6,14 +7,13 @@ * 0: Unit * * Return Value: - * Nothing + * None * * Example: * [player] call ACE_hearing_fnc_handleRespawn; * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); diff --git a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf index 67a76685f4..f24b17737e 100644 --- a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf +++ b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit has earplugs put in. * * Arguments: - * 0:Unit (player) + * 0: Unit (player) * * Return Value: * Have Earplugs in @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; _unit getVariable ["ACE_hasEarPlugsin", false] diff --git a/addons/hearing/functions/fnc_moduleHearing.sqf b/addons/hearing/functions/fnc_moduleHearing.sqf index 053bcb6d7f..d36579c4c0 100644 --- a/addons/hearing/functions/fnc_moduleHearing.sqf +++ b/addons/hearing/functions/fnc_moduleHearing.sqf @@ -1,14 +1,19 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Initializes the Hearing module. * * Arguments: - * Whatever the module provides. (I dunno.) + * Whatever the module provides. (I dunno.) * * Return Value: * None + * + * Example: + * [player] call ACE_hearing_fnc_moduleHearing + * + * Public: No */ -#include "script_component.hpp" params ["_logic"]; @@ -20,4 +25,4 @@ if ((_logic getVariable "DisableEarRinging") != -1) then { }; [_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO("Hearing Module Initialized."); +INFO("Hearing Module Initialized."); diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf index 90fe8d62ac..7292c86f85 100644 --- a/addons/hearing/functions/fnc_putInEarplugs.sqf +++ b/addons/hearing/functions/fnc_putInEarplugs.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: Hope Johnson and commy2 * Puts in earplugs. * * Arguments: - * 0:Unit (player) + * 0: Unit (player) * * Return Value: * None @@ -13,10 +14,11 @@ * * Public: No */ -#include "script_component.hpp" params ["_player"]; +if (!GVAR(EnableCombatDeafness)) exitWith {}; + // Plugs in inventory, putting them in _player removeItem "ACE_EarPlugs"; diff --git a/addons/hearing/functions/fnc_removeEarplugs.sqf b/addons/hearing/functions/fnc_removeEarplugs.sqf index 3154230ecf..9af41f6d8b 100644 --- a/addons/hearing/functions/fnc_removeEarplugs.sqf +++ b/addons/hearing/functions/fnc_removeEarplugs.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: Hope Johnson and commy2 * Takes out earplugs. * * Arguments: - * 0:Unit (player) + * 0: Unit (player) * * Return Value: * None @@ -13,10 +14,11 @@ * * Public: No */ -#include "script_component.hpp" params ["_player"]; +if (!GVAR(EnableCombatDeafness)) exitWith {}; + if !(_player canAdd "ACE_EarPlugs") exitWith { // inventory full [localize LSTRING(Inventory_Full)] call EFUNC(common,displayTextStructured); }; diff --git a/addons/hearing/functions/fnc_updateHearingProtection.sqf b/addons/hearing/functions/fnc_updateHearingProtection.sqf index fe0ca867ff..e010165f8a 100644 --- a/addons/hearing/functions/fnc_updateHearingProtection.sqf +++ b/addons/hearing/functions/fnc_updateHearingProtection.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Updates the hearing protection and volume attenuation for player on earbuds/helmet change @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" TRACE_1("params",_this); diff --git a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf index 7d48ca7b34..8d42ca1c0c 100644 --- a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf +++ b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Gets the sound attenuation of a player to the outside. @@ -13,22 +14,18 @@ * * Public: No */ -#include "script_component.hpp" -private ["_effectType", "_newAttenuation", "_turretConfig", "_turretPath", "_vehicle"]; - -_vehicle = vehicle ACE_player; +private _vehicle = vehicle ACE_player; if (isNull _vehicle) exitWith {}; -_newAttenuation = 1; +private _newAttenuation = 1; if (ACE_player != _vehicle) then { - _effectType = ""; - _turretPath = [ACE_player] call EFUNC(common,getTurretIndex); - _effectType = getText (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "attenuationEffectType"); + private _turretPath = [ACE_player] call EFUNC(common,getTurretIndex); + private _effectType = getText (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "attenuationEffectType"); if (!(_turretPath isEqualTo [])) then { - _turretConfig = [(configFile >> "CfgVehicles" >> (typeOf _vehicle)), _turretPath] call EFUNC(common,getTurretConfigPath); + private _turretConfig = [(configFile >> "CfgVehicles" >> (typeOf _vehicle)), _turretPath] call EFUNC(common,getTurretConfigPath); if ((getNumber (_turretConfig >> "disableSoundAttenuation")) == 1) then { _effectType = ""; @@ -41,8 +38,10 @@ if (ACE_player != _vehicle) then { _newAttenuation = switch (true) do { case (_effectType == ""): {1}; - case (_effectType == "CarAttenuation"): {0.5}; - case (_effectType == "RHS_CarAttenuation"): {0.5}; + case (_effectType == "CarAttenuation"); + case (_effectType == "RHS_CarAttenuation"): { // Increase protection for armored cars + private _armor = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "HitPoints" >> "HitBody" >> "armor"); + linearConversion [2, 8, _armor, 0.5, 0.3, true];}; case (_effectType == "OpenCarAttenuation"): {1}; case (_effectType == "TankAttenuation"): {0.1}; case (_effectType == "HeliAttenuation"): {0.3}; diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index 01ab58ef76..4cf1a6b117 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * 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 @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" if (!alive ACE_player) exitWith { if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; @@ -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/script_component.hpp b/addons/hearing/script_component.hpp index 7c0413898f..7e69c908b5 100644 --- a/addons/hearing/script_component.hpp +++ b/addons/hearing/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_HEARING diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index e58f657417..a30970f77f 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Füldugó Protetor auricular Tappi auricolari + 耳栓 + 귀마개 + 耳塞 + 耳塞 Protective Earplugs allow the wearer to be near loud weaponry without damage to his hearing. @@ -24,6 +28,10 @@ Erősebb hanghatásoktól védő füldugó, megakadályozza a nagy hanggal járó fegyverzettől való halláskárosodást. Protetor para ouvidos permitem que o usuário esteja próximo a ruídos sem danificar sua audição. Proteggono l'apparato uditivo, permettendo a chi li indossa di resistere ai suoni particolarmente forti senza alcun danno. + 着けることにより、近くの大きな銃声から聴覚を保護します。 + 보호용 귀마개는 화기로부터의 큰소리로부터 사용자의 청력을 보호합니다. + 配戴防护耳塞,遇到大声的武器发射时也不会损害听力。 + 配戴防護耳塞,遇到大聲的武器發射時也不會損害聽力 Earplugs in @@ -36,6 +44,10 @@ Füldugó berakva Protetores colocados Indossa i tappi auricolari + 耳栓を着ける + 귀마개 착용 + 塞入耳塞 + 塞入耳塞 Earplugs out @@ -48,6 +60,10 @@ Füldugó kivéve Protetores retirados Levati i tappi auricolari + 耳栓を外す + 귀마개 뺌 + 取出耳塞 + 取出耳塞 Earplugs in @@ -60,6 +76,10 @@ Füldugó berakva Protetores colocados Indossa i tappi auricolari + 耳栓を着けました + 귀마개 착용 + 耳塞已塞入 + 耳塞已塞入 Earplugs out @@ -72,6 +92,10 @@ Füldugó kivéve Protetores retirados Levati i tappi auricolari + 耳栓を外しました + 귀마개 뺌 + 耳塞已取出 + 耳塞已取出 You have no earplugs @@ -84,6 +108,10 @@ Nincsen füldugód Você não possui protetores auriculares Non hai i tappi auricolari + 耳栓を持っていません + 귀마개가 없습니다 + 你没有耳塞 + 你沒有耳塞 No inventory space @@ -96,6 +124,10 @@ Não há espaço no inventário Nincs több hely Нет места в инвентаре + インベントリに空きがありません + 넣을 공간이 없습니다 + 无可用空间 + 無可用空間 Disable ear ringing @@ -108,6 +140,10 @@ Fülcsengés letiltása Disabilita i fischi nelle orecchie Desabilitar zumbido de ouvidos + 耳鳴りを無効化する + 이명현상 끄기 + 关闭耳鸣效果 + 關閉耳鳴效果 Remove tinnitus effect when the player takes hearing damage @@ -118,6 +154,10 @@ Quando il giocatore riceve danni all'udito, non fa sentire i fischi nelle orecchie Remove o efeito de zunido quando o jogador recebe dano na audição Убирает эффект звона в ушах, когда игрок получает повреждение слуха + プレイヤーの聴覚が損傷したら耳鳴りの効果を削除します + 플레이어가 청력손실을 입을때 생기는 이명현상을 제거합니다. + 关闭耳鸣效果时,就算玩家受到相当程度的听力伤害, 也不会造成耳鸣效果 + 關閉耳鳴效果時,就算玩家受到相當程度的聽力傷害, 也不會造成耳鳴效果 Hearing @@ -130,6 +170,10 @@ Hallás Слух Udito + 聴覚 + 청력 + 听力设定 + 聽力設定 Enable Combat Deafness @@ -142,6 +186,10 @@ Harci süketség engedélyezése? Оглушение Sordità da combattimento + 戦闘による難聴を有効化 + 전투 난청 켜기 + 启用战斗性耳聋? + 啟用戰鬥性耳聾? Reduces the hearing ability as the player takes hearing damage @@ -153,6 +201,10 @@ Уменьшает возможность игрока слышать звуки при повреждении органов слуха Riduci l'abilità uditiva quando il giocatore riceve danno uditivo Réduire l'audition lorsque le joueur prend des dommages auditifs. + 音による損傷をうけ、聴覚が減る可能性があります + 청력에 손상을 입으면 듣는 소리가 감소합니다. + 当玩家听力受损时降低听力能力? + 當玩家聽力受損時降低聽力能力? Controls combat deafness and ear ringing. When activated, players can be deafened when a gun is fired in their vicinity or an explosion takes place without hearing protection @@ -165,6 +217,10 @@ Ce module active / désactivé la surdité au combat. Si active, des joueurs peuvent devenir sourds sans protection d'oreille, si une arme est utilisée ou une explosion a lieu à proximité Controles de sordera de combate y zumbido en los oídos. Al activarlo, los jugadores pueden ser ensordecidos cuando un arma se dispara cerca o una explosión tiene lugar sin protección auditiva 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 @@ -176,6 +232,10 @@ Vliv na Zeus RC Effetto Zeus RC Effet sur le CàD du Zeus + Zeus RC への効果 + Zeus RC 효과 + 启用效果在宙斯远程遥控 + 啟用效果在宙斯遠程遙控 Allow zeus remote controlled units to be able to take hearing damage. @@ -187,6 +247,10 @@ Aktivovat efekt ztráty sluchu pro vzdáleně ovládané jednotky. Consenti alle unità controllate in remoto da Zeus di ricevere danni all'udito. Permet aux unités controlées à distance de subir des traumatismes sonores. + Zeus により遠隔操作されたユニットにも、聴覚へ損傷を受けるようにします。 + Zeus가 원격으로 청력손실을 입힐 수 있게 합니다. + 设定宙斯远程遥控的单位也会受到耳鸣的效果。 + 設定宙斯遠程遙控的單位也會受到耳鳴的效果。 Add earplugs to units @@ -198,10 +262,14 @@ Aggiungi Tappi per Orecchie alle unità Agregar tapones de oida a la unidad Ajouter des bouchons anti-bruits aux unités + ユニットへ耳栓を追加 + 해당 인원에게 귀마개 추가 + 增加耳塞给单位 + 增加耳塞給單位 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. @@ -209,6 +277,54 @@ Aggiungi l'oggetto 'ACE_EarPlugs' a tutte le unità che hanno armi rumorose. Può essere disabilitato se vengono usati loadout personalizzati. Agregar el item `ACE_EarPlugs` a todas las unidades equipadas con armas muy ruidosas. Desactivar si quieren utilizarse equipamientos personalizados. 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`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。 + + + Hearing protection + Protection auditive + 聴覚保護 + 听力保护 + 聽力保護 + Protezione auditiva + + + Volume muffling + Étouffement des sons + 音量低下 + 降低音量 + 進低音量 + Volume attenuazione + + + Earplugs Volume + 耳栓時の音量 + 耳塞时音量 + 耳塞時音量 + Volume tappi per le orecchie + + + Volume when using earplugs. + 耳栓使用時の音量を決定します。 + 决定带上耳塞时的音量 + 使用耳塞時音量 + Volume audio quandi si indossano i tappi per le orecchie. + + + Unconscious Volume + 気絶時の音量 + 无意识时音量 + 昏迷時音量 + Volume quando incoscente + + + Volume when unconscious. + 気絶時の音量を決定します。 + 决定处于无意识时的音量 + 昏迷時使用耳塞的音量 + Volume quando incoscente. - \ No newline at end of file + diff --git a/addons/hellfire/$PBOPREFIX$ b/addons/hellfire/$PBOPREFIX$ new file mode 100644 index 0000000000..5bd6c77aff --- /dev/null +++ b/addons/hellfire/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\hellfire diff --git a/addons/hellfire/ACE_GuidanceConfig.hpp b/addons/hellfire/ACE_GuidanceConfig.hpp new file mode 100644 index 0000000000..ad3d8c667d --- /dev/null +++ b/addons/hellfire/ACE_GuidanceConfig.hpp @@ -0,0 +1,18 @@ +class EGVAR(missileguidance,AttackProfiles) { + class hellfire { + name = "LOAL-DIR"; + nameLocked = "LOBL"; + functionName = QFUNC(attackProfile); + GVAR(launchHeightClear) = 0; + }; + 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/CfgAmmo.hpp b/addons/hellfire/CfgAmmo.hpp new file mode 100644 index 0000000000..a5d7214292 --- /dev/null +++ b/addons/hellfire/CfgAmmo.hpp @@ -0,0 +1,68 @@ +class CfgAmmo { + class M_Scalpel_AT; + + class ACE_Hellfire_AGM114K: M_Scalpel_AT { + displayName = "AGM-114K"; + displayNameShort = "AGM-114K"; + description = "AGM-114K"; + descriptionShort = "AGM-114K"; + + model = "\A3\Weapons_F\Ammo\Missile_AT_03_fly_F"; + proxyShape = "\A3\Weapons_F\Ammo\Missile_AT_03_F"; + + effectsMissile = "missile2"; + + irLock = 0; + laserLock = 0; + manualControl = 0; + maxSpeed = 450; + + thrustTime = 2.5; // motor burn 2-3 sec + thrust = 250; + timeToLive = 40; + + EGVAR(rearm,caliber) = 178; + + class ace_missileguidance { + enabled = 1; + + minDeflection = 0.0005; // Minium flap deflection for guidance + maxDeflection = 0.01; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL", "LOBL" }; + + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 70; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 1; + seekerMaxRange = 8000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "hellfire"; + attackProfiles[] = {"hellfire", "hellfire_hi", "hellfire_lo"}; + }; + }; + class ACE_Hellfire_AGM114N: ACE_Hellfire_AGM114K { + displayName = "AGM-114N"; + displayNameShort = "AGM-114N"; + description = "AGM-114N"; + descriptionShort = "AGM-114N"; + hit = 200; + indirectHit = 200; + indirectHitRange = 12; + submunitionAmmo = ""; + explosionEffects = "BombExplosion"; + class ace_missileguidance: ace_missileguidance { + enabled = 1; // Missile Guidance must be explicitly enabled + }; + }; +}; diff --git a/addons/hellfire/CfgEventHandlers.hpp b/addons/hellfire/CfgEventHandlers.hpp new file mode 100644 index 0000000000..77ea0239bd --- /dev/null +++ b/addons/hellfire/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +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_postInit)); + }; +}; diff --git a/addons/hellfire/CfgMagazines.hpp b/addons/hellfire/CfgMagazines.hpp new file mode 100644 index 0000000000..de63540a2a --- /dev/null +++ b/addons/hellfire/CfgMagazines.hpp @@ -0,0 +1,87 @@ +class CfgMagazines { + class 12Rnd_PG_missiles; + + // Kilo - tandem shaped charge HEAT (anti-tank) + class 6Rnd_ACE_Hellfire_AGM114K: 12Rnd_PG_missiles { // Old style vehicle magazine + count = 6; + ammo = "ACE_Hellfire_AGM114K"; + displayName = "AGM-114K [ACE]"; + displayNameShort = "AGM-114K"; + descriptionShort = "AGM-114K"; + }; + + // 1.70 pylon magazines: + class PylonMissile_1Rnd_ACE_Hellfire_AGM114K: 6Rnd_ACE_Hellfire_AGM114K { // Bare missle + displayName = "1x AGM-114K [ACE]"; + count = 1; + mass = 70; + pylonWeapon = QGVAR(launcher); + hardpoints[] = {"SCALPEL_1RND"}; + model = "\A3\Weapons_F\DynamicLoadout\PylonMissile_1x_Bomb_04_F.p3d"; + }; + class PylonRack_1Rnd_ACE_Hellfire_AGM114K: 6Rnd_ACE_Hellfire_AGM114K { // 1x Launcher Support Rack + displayName = "1x AGM-114K [ACE]"; + count = 1; + mass = 85; + pylonWeapon = QGVAR(launcher); + 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 + displayName = "3x AGM-114K [ACE]"; + count = 3; + mass = 250; + pylonWeapon = QGVAR(launcher); + 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}; + }; + class PylonRack_4Rnd_ACE_Hellfire_AGM114K: 6Rnd_ACE_Hellfire_AGM114K { // 4x Launcher Support Rack + displayName = "4x AGM-114K [ACE]"; + count = 4; + mass = 340; + pylonWeapon = QGVAR(launcher); + 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}; + }; + + // November - Metal augmented charge (Thermobaric) (Enclosures, ships, urban targets, air defense units) + class 6Rnd_ACE_Hellfire_AGM114N: 6Rnd_ACE_Hellfire_AGM114K { // Old style vehicle magazine + count = 6; + ammo = "ACE_Hellfire_AGM114N"; + displayName = "AGM-114N [ACE]"; + displayNameShort = "AGM-114N"; + descriptionShort = "AGM-114N"; + }; + + // 1.70 pylon magazines: + class PylonMissile_1Rnd_ACE_Hellfire_AGM114N: PylonMissile_1Rnd_ACE_Hellfire_AGM114K { // Bare missle + displayName = "1x AGM-114N [ACE]"; + displayNameShort = "AGM-114N"; + descriptionShort = "AGM-114N"; + ammo = "ACE_Hellfire_AGM114N"; + pylonWeapon = QGVAR(launcher_N); + }; + class PylonRack_1Rnd_ACE_Hellfire_AGM114N: PylonRack_1Rnd_ACE_Hellfire_AGM114K { // 1x Launcher Support Rack + displayName = "1x AGM-114N [ACE]"; + displayNameShort = "AGM-114N"; + descriptionShort = "AGM-114N"; + ammo = "ACE_Hellfire_AGM114N"; + pylonWeapon = QGVAR(launcher_N); + }; + class PylonRack_3Rnd_ACE_Hellfire_AGM114N: PylonRack_3Rnd_ACE_Hellfire_AGM114K { // 3x Launcher Support Rack + displayName = "3x AGM-114N [ACE]"; + displayNameShort = "AGM-114N"; + descriptionShort = "AGM-114N"; + ammo = "ACE_Hellfire_AGM114N"; + pylonWeapon = QGVAR(launcher_N); + }; + class PylonRack_4Rnd_ACE_Hellfire_AGM114N: PylonRack_4Rnd_ACE_Hellfire_AGM114K { // 4x Launcher Support Rack + displayName = "4x AGM-114N [ACE]"; + displayNameShort = "AGM-114N"; + descriptionShort = "AGM-114N"; + ammo = "ACE_Hellfire_AGM114N"; + pylonWeapon = QGVAR(launcher_N); + }; +}; diff --git a/addons/hellfire/CfgVehicles.hpp b/addons/hellfire/CfgVehicles.hpp new file mode 100644 index 0000000000..89dbf131d7 --- /dev/null +++ b/addons/hellfire/CfgVehicles.hpp @@ -0,0 +1,6 @@ +class CfgVehicles { + class Heli_Attack_01_base_F; + class Heli_Attack_01_dynamicLoadout_base_F: Heli_Attack_01_base_F { + GVAR(addLaserDesignator) = 1; + }; +}; diff --git a/addons/hellfire/CfgWeapons.hpp b/addons/hellfire/CfgWeapons.hpp new file mode 100644 index 0000000000..1d7f167aad --- /dev/null +++ b/addons/hellfire/CfgWeapons.hpp @@ -0,0 +1,31 @@ +class CfgWeapons { + class RocketPods; + class GVAR(launcher): RocketPods { + displayName = "AGM-114K Hellfire II"; + 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 + 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"}; + + autoFire = 0; + canLock = 0; + weaponLockSystem = 0; + lockingTargetSound[] = {"",0,1}; + lockedTargetSound[] = {"",0,1}; + soundFly[] = {"A3\Sounds_F\weapons\Rockets\rocket_fly_1",1,1.1,700}; + nameSound = "MissileLauncher"; + sounds[] = {"StandardSound"}; + class StandardSound { + begin1[] = {"A3\Sounds_F\weapons\Rockets\missile_1",1.12202,1.3,1000}; + soundBegin[] = {"begin1",1}; + soundsetshot[] = {"RocketsMedium_Shot_SoundSet"}; + }; + cursor = "EmptyCursor"; + cursorAim = "missile"; + showAimCursorInternal = 0; + }; + class GVAR(launcher_N): GVAR(launcher) { + displayName = "AGM-114N Hellfire II"; + magazines[] = {"6Rnd_ACE_Hellfire_AGM114N", "PylonMissile_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_3Rnd_ACE_Hellfire_AGM114N", "PylonRack_4Rnd_ACE_Hellfire_AGM114N"}; + }; +}; diff --git a/addons/hellfire/README.md b/addons/hellfire/README.md new file mode 100644 index 0000000000..bb9eef711e --- /dev/null +++ b/addons/hellfire/README.md @@ -0,0 +1,10 @@ +ace_hellfire +========== + +Adds AGM-114K Hellfire missiles. + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/hellfire/XEH_PREP.hpp b/addons/hellfire/XEH_PREP.hpp new file mode 100644 index 0000000000..f30cf0bffd --- /dev/null +++ b/addons/hellfire/XEH_PREP.hpp @@ -0,0 +1,4 @@ +LOG("prep"); +PREP(attackProfile); +PREP(getAttackProfileSettings); +PREP(setupVehicle); diff --git a/addons/hellfire/XEH_postInit.sqf b/addons/hellfire/XEH_postInit.sqf new file mode 100644 index 0000000000..e89bf7a3e3 --- /dev/null +++ b/addons/hellfire/XEH_postInit.sqf @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +["ace_settingsInitialized", { + ["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/XEH_preInit.sqf b/addons/hellfire/XEH_preInit.sqf new file mode 100644 index 0000000000..3464490b65 --- /dev/null +++ b/addons/hellfire/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/hellfire/XEH_preStart.sqf b/addons/hellfire/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/hellfire/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/hellfire/config.cpp b/addons/hellfire/config.cpp new file mode 100644 index 0000000000..8df1594612 --- /dev/null +++ b/addons/hellfire/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction", "ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"PabstMirror"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "ACE_GuidanceConfig.hpp" +#include "CfgAmmo.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/hellfire/functions/fnc_attackProfile.sqf b/addons/hellfire/functions/fnc_attackProfile.sqf new file mode 100644 index 0000000000..8904d57978 --- /dev/null +++ b/addons/hellfire/functions/fnc_attackProfile.sqf @@ -0,0 +1,84 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Hellfire attack profile. Handles all 4 modes LOBL, LOAL-DIR, LOAL-HI, LOAL-LO + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_hellfire_fnc_attackProfile + * + * Public: No + */ + +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH", "_launchParams"]; +_launchParams params ["","_targetLaunchParams"]; +_targetLaunchParams params ["", "", "_launchPos"]; +_firedEH params ["","","","","","","_projectile"]; + +// Get state params: +if (_attackProfileStateParams isEqualTo []) then { + _this call FUNC(getAttackProfileSettings); +}; +_attackProfileStateParams params ["_attackStage", "_configLaunchHeightClear"]; + + +private _projectilePos = getPosASL _projectile; +private _distanceFromLaunch2d = _launchPos distance2d _projectilePos; +private _heightAboveLaunch = (_projectilePos select 2) - (_launchPos select 2); + +// Add height depending on distance for compensate +private _returnTargetPos = nil; + +switch (_attackStage) do { + case STAGE_LAUNCH: { // Gain height quickly to pass terrain mask + _returnTargetPos = _projectilePos getPos [100, getDir _projectile]; + _returnTargetPos set [2, (_projectilePos select 2) + 36.4]; // 100 and 36.4 gives a 20 deg angle + + if (_heightAboveLaunch > _configLaunchHeightClear) then { + _attackProfileStateParams set [0, STAGE_SEEK_CRUISE]; + TRACE_2("New Stage: STAGE_SEEK_CRUISE",_distanceFromLaunch2d,_heightAboveLaunch); + }; + }; + case STAGE_SEEK_CRUISE: { // Slowly gain altitude while searching for target + // Before 4000 cruise at 5.7 degrees up, then level out + private _cruiseHeight = linearConversion [3000, 5000, _distanceFromLaunch2d, 10, 0, true]; + + _returnTargetPos = _projectilePos getPos [100, getDir _projectile]; + _returnTargetPos set [2, (_projectilePos select 2) + _cruiseHeight]; + + if (!(_seekerTargetPos isEqualTo [0,0,0])) then { + _attackProfileStateParams set [0, STAGE_ATTACK_CRUISE]; + TRACE_1("New Stage: STAGE_ATTACK_CRUISE",_distanceFromLaunch2d); + }; + }; + case STAGE_ATTACK_CRUISE: { + private _currentHeightOverTarget = (_projectilePos select 2) - (_seekerTargetPos select 2); + private _distanceToTarget2d = _seekerTargetPos distance2d _projectilePos; + private _distToGoRatio = _distanceToTarget2d / (_launchPos distance2d _seekerTargetPos); + + // arcing up at 7 degrees to start until 50% left, then smooth curve to a downward attack + private _gainSlope = linearConversion [0.5, 0.1, _distToGoRatio, 7, -7, true]; + _returnTargetPos = +_seekerTargetPos; + _returnTargetPos set [2, ((_projectilePos select 2) + (_distanceToTarget2d * sin _gainSlope)) max (_seekerTargetPos select 2)]; + + if ((_distanceToTarget2d < 500) || {(_currentHeightOverTarget atan2 _distanceToTarget2d) > 15}) then { // Wait until we can come down at a sharp angle + _attackProfileStateParams set [0, STAGE_ATTACK_TERMINAL]; + TRACE_2("New Stage: STAGE_ATTACK_TERMINAL",_distanceToTarget2d,_currentHeightOverTarget); + }; + }; + case STAGE_ATTACK_TERMINAL: { + private _distanceToTarget2d = _seekerTargetPos distance2d _projectilePos; + _returnTargetPos = _seekerTargetPos vectorAdd [0, 0, _distanceToTarget2d * 0.02]; + }; +}; + +// TRACE_1("Adjusted target position", _returnTargetPos); +_returnTargetPos; diff --git a/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf new file mode 100644 index 0000000000..066d280d65 --- /dev/null +++ b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets attack profile parameters for first run of hellfire attack profile function + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Nothing + * + * Example: + * [[], [], []] call ace_hellfire_fnc_getAttackProfileSettings; + * + * Public: No + */ + +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH", "_launchParams"]; +_launchParams params ["", "", "", "_attackProfile"]; +_firedEH params ["","","","","","","_projectile"]; + +private _attackConfig = configFile >> QEGVAR(missileguidance,AttackProfiles) >> _attackProfile; + +// Launch (clearing terrain mask for LO/HI): +private _configLaunchHeightClear = getNumber (_attackConfig >> QGVAR(launchHeightClear)); + +// Get starting stage +private _startingStage = if (_configLaunchHeightClear > 0) then { + STAGE_LAUNCH; // LOAL-HI / LO +} else { + if (_seekerTargetPos isEqualTo [0,0,0]) then { + STAGE_SEEK_CRUISE; // LOAL-DIR + } else { + STAGE_ATTACK_CRUISE // LOBL + }; +}; + +// Set data in param array +_attackProfileStateParams set [0, _startingStage]; +_attackProfileStateParams set [1, _configLaunchHeightClear]; + +TRACE_1("new shot settings",_attackProfileStateParams); diff --git a/addons/hellfire/functions/fnc_setupVehicle.sqf b/addons/hellfire/functions/fnc_setupVehicle.sqf new file mode 100644 index 0000000000..e824542021 --- /dev/null +++ b/addons/hellfire/functions/fnc_setupVehicle.sqf @@ -0,0 +1,95 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Adds interaction menu actions to switch the firemode to a vehicle. + * Also adds a Laser Designator if vehicle is configured for one. + * + * Arguments: + * 0: Player + * + * Return Value: + * Nothing + * + * Example: + * [player] call ace_hellfire_fnc_setupVehicle + * + * Public: No + */ + + +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 { + [{ + params ["_vehicle", "_turretPath"]; + TRACE_3("checking for laser",_vehicle,_turretPath,_vehicle turretLocal _turretPath); + if (!alive _vehicle) exitWith {}; + if (!(_vehicle turretLocal _turretPath)) then {WARNING("Turret not local");}; + private _hasLaser = false; + { + // Most addons just use "Laserdesignator_mounted", but this should cover custom ones + if ((getNumber (configFile >> "CfgWeapons" >> _x >> "Laser")) == 1) exitWith { + _hasLaser = true; + }; + } forEach (_vehicle weaponsTurret _turretPath); + if (!_hasLaser) then { + TRACE_1("Adding Laser Designator",typeOf _vehicle); + _vehicle addWeaponTurret ["Laserdesignator_mounted", _turretPath]; + _vehicle addMagazineTurret ["Laserbatteries", _turretPath]; + }; + }, [_vehicle, _turretPath], 1] call CBA_fnc_waitAndExecute; // Need to delay slightly for turret to become local (probably only needs a single frame) +}; + + +// Add interaction menu actions: +if (_vehicle getVariable [QGVAR(actionsAdded), false]) exitWith {}; +_vehicle setVariable [QGVAR(actionsAdded), true]; + +private _action = [QUOTE(ADDON), localize LSTRING(hellfireModeAction), "", {}, {true}] call EFUNC(interact_menu,createAction); +private _basePath = [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + +private _fnc_statement = { + params ["_target", "", "_attackProfile"]; + TRACE_2("statement",_target,_attackProfile); + + _target setVariable [QEGVAR(missileguidance,attackProfile), _attackProfile]; +}; +private _fnc_condition = { + params ["_target", "_player", "_attackProfile"]; + + private _turretPath = if (ACE_player == (driver _target)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + private _hasWeapon = ({(isNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(enabled))) && {getNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(enabled)) > 0}} count (_target weaponsTurret _turretPath)) > 0; + + (_hasWeapon) && + {(_target getVariable [QEGVAR(missileguidance,attackProfile), "hellfire"]) != _attackProfile}; +}; + +{ + private _displayName = getText (configFile >> QEGVAR(missileguidance,AttackProfiles) >> _x >> "name"); + private _action = [format [QGVAR(%1),_x], _displayName, "", _fnc_statement, _fnc_condition, {}, _x] call EFUNC(interact_menu,createAction); + [_vehicle, 1, _basePath, _action] call EFUNC(interact_menu,addActionToObject); +} forEach ["hellfire", "hellfire_hi", "hellfire_lo"]; + +TRACE_2("interactions added",_vehicle,typeOf _vehicle); diff --git a/addons/hellfire/functions/script_component.hpp b/addons/hellfire/functions/script_component.hpp new file mode 100644 index 0000000000..899f29a758 --- /dev/null +++ b/addons/hellfire/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\hellfire\script_component.hpp" diff --git a/addons/hellfire/script_component.hpp b/addons/hellfire/script_component.hpp new file mode 100644 index 0000000000..6d16736a9c --- /dev/null +++ b/addons/hellfire/script_component.hpp @@ -0,0 +1,22 @@ +#define COMPONENT hellfire +#define COMPONENT_BEAUTIFIED Hellfire +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_HELLFIRE + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_HELLFIRE + #define DEBUG_SETTINGS DEBUG_SETTINGS_HELLFIRE +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define STAGE_LAUNCH 1 +#define STAGE_SEEK_CRUISE 2 +#define STAGE_ATTACK_CRUISE 3 +#define STAGE_ATTACK_TERMINAL 4 diff --git a/addons/hellfire/stringtable.xml b/addons/hellfire/stringtable.xml new file mode 100644 index 0000000000..990e5a5b84 --- /dev/null +++ b/addons/hellfire/stringtable.xml @@ -0,0 +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/XEH_preInit.sqf b/addons/hitreactions/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/hitreactions/XEH_preInit.sqf +++ b/addons/hitreactions/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/hitreactions/functions/fnc_fallDown.sqf b/addons/hitreactions/functions/fnc_fallDown.sqf index 03484438eb..08c7282ab7 100644 --- a/addons/hitreactions/functions/fnc_fallDown.sqf +++ b/addons/hitreactions/functions/fnc_fallDown.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Adds reactions to a unit that was hit. EH only runs where to unit is local. Adds screams, falling down, falling from ladders, ejecting from static weapons and camshake for players @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [player, kevin, 5] call ACE_hitreactions_fnc_fallDown + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_firer", "_damage"]; @@ -27,12 +30,15 @@ if (_unit == _firer) exitWith {}; // camshake for player if (_unit == ACE_player) then { + if (visibleMap) then { + openMap false; + }; addCamShake [3, 5, _damage + random 10]; }; // play scream sound if (!isNil QEFUNC(medical,playInjuredSound)) then { - [_unit] call EFUNC(medical,playInjuredSound); + [_unit,_damage] call EFUNC(medical,playInjuredSound); }; private _vehicle = vehicle _unit; diff --git a/addons/hitreactions/functions/fnc_getRandomAnimation.sqf b/addons/hitreactions/functions/fnc_getRandomAnimation.sqf index 996901a31e..bfdfd9646f 100644 --- a/addons/hitreactions/functions/fnc_getRandomAnimation.sqf +++ b/addons/hitreactions/functions/fnc_getRandomAnimation.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Get a random fall animation for the unit. @@ -8,9 +9,11 @@ * Return Value: * Fall animation * + * Example: + * [bob] call ACE_hitreactions_fnc_getRandomAnimation + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/hitreactions/script_component.hpp b/addons/hitreactions/script_component.hpp index 9252f1bca0..dccbef24f7 100644 --- a/addons/hitreactions/script_component.hpp +++ b/addons/hitreactions/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_HITREACTIONS diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml new file mode 100644 index 0000000000..3440ae06bf --- /dev/null +++ b/addons/hitreactions/stringtable.xml @@ -0,0 +1,14 @@ + + + + + Min Damage to trigger falling + Danno Minimo da caduta + 觸發倒下前最低需受到多少傷害 + 触发倒下前最低需受到多少伤害 + 崩れ落ちるまでの最低損傷値 + 방아쇠를 당기는 최소한의 피해 + Mindestschaden, um Sturz auszulösen + + + diff --git a/addons/huntir/CfgVehicles.hpp b/addons/huntir/CfgVehicles.hpp index cd5054a2da..cf6c98904a 100644 --- a/addons/huntir/CfgVehicles.hpp +++ b/addons/huntir/CfgVehicles.hpp @@ -7,9 +7,8 @@ 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); exceptions[] = {}; }; diff --git a/addons/huntir/CfgWeapons.hpp b/addons/huntir/CfgWeapons.hpp index 799cfcb976..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; }; }; @@ -19,11 +20,5 @@ class CfgWeapons { class UGL_F: GrenadeLauncher { magazines[] += {"ACE_HuntIR_M203"}; }; - class Rifle_Base_F; - class arifle_MX_Base_F: Rifle_Base_F { - class GL_3GL_F: UGL_F { - //magazines[] += {"ACE_HuntIR_M203"}; - magazines[] = {"1Rnd_HE_Grenade_shell","UGL_FlareWhite_F","UGL_FlareGreen_F","UGL_FlareRed_F","UGL_FlareYellow_F","UGL_FlareCIR_F","1Rnd_Smoke_Grenade_shell","1Rnd_SmokeRed_Grenade_shell","1Rnd_SmokeGreen_Grenade_shell","1Rnd_SmokeYellow_Grenade_shell","1Rnd_SmokePurple_Grenade_shell","1Rnd_SmokeBlue_Grenade_shell","1Rnd_SmokeOrange_Grenade_shell","3Rnd_HE_Grenade_shell","3Rnd_UGL_FlareWhite_F","3Rnd_UGL_FlareGreen_F","3Rnd_UGL_FlareRed_F","3Rnd_UGL_FlareYellow_F","3Rnd_UGL_FlareCIR_F","3Rnd_Smoke_Grenade_shell","3Rnd_SmokeRed_Grenade_shell","3Rnd_SmokeGreen_Grenade_shell","3Rnd_SmokeYellow_Grenade_shell","3Rnd_SmokePurple_Grenade_shell","3Rnd_SmokeBlue_Grenade_shell","3Rnd_SmokeOrange_Grenade_shell","ACE_HuntIR_M203"}; - }; - }; + // Added to the GL_3GL_F in subconfig }; diff --git a/addons/huntir/XEH_preInit.sqf b/addons/huntir/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/huntir/XEH_preInit.sqf +++ b/addons/huntir/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/huntir/functions/fnc_cam.sqf b/addons/huntir/functions/fnc_cam.sqf index 41a9561e60..ca027b23ab 100644 --- a/addons/huntir/functions/fnc_cam.sqf +++ b/addons/huntir/functions/fnc_cam.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [cam] call ACE_huntir_fnc_cam + * * Public: No */ -#include "script_component.hpp" if (!hasInterface) exitWith {}; params ["_huntIR"]; @@ -52,7 +55,7 @@ GVAR(pphandle) ppEffectAdjust [1, 1, 0, [0.01, 0.02, 0.04, 0.01], [0.87, 1.08, 1 GVAR(pphandle) ppEffectCommit 0; GVAR(pphandle) ppEffectEnable true; -GVAR(stop) = false; +GVAR(stop) = false; // Var also used in ace_common_fnc_isFeatureCameraActive call FUNC(huntirCompass); GVAR(no_cams) = ACE_player nearEntities ["ACE_HuntIR", HUNTIR_MAX_TRANSMISSION_RANGE]; @@ -132,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 b7e8c2a010..42c6bf3c84 100644 --- a/addons/huntir/functions/fnc_handleFired.sqf +++ b/addons/huntir/functions/fnc_handleFired.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * call ACE_huntir_fnc_handleFired + * * 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); @@ -30,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]; [{ @@ -41,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 844ca302e7..221bc5ccec 100644 --- a/addons/huntir/functions/fnc_huntir.sqf +++ b/addons/huntir/functions/fnc_huntir.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * call ACE_huntir_fnc_huntir + * * Public: No */ -#include "script_component.hpp" #define __TYPE_WRITER_DELAY 0.05 @@ -43,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 f383a23a24..9a7882f45c 100644 --- a/addons/huntir/functions/fnc_huntirCompass.sqf +++ b/addons/huntir/functions/fnc_huntirCompass.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Norrin, Rocko, Ruthberg * @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * call ACE_huntir_fnc_huntirCompass + * * Public: No */ -#include "script_component.hpp" disableSerialization; @@ -29,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] @@ -59,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 509dcb9de5..edfa39c534 100644 --- a/addons/huntir/functions/fnc_keyPressed.sqf +++ b/addons/huntir/functions/fnc_keyPressed.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: Norrin, Rocko * Handles the HuntIR monitor key interaction * * Arguments: - * 0: ? + * 0: ? * 1: keycode * * Return Value: @@ -14,10 +15,8 @@ * * Public: No */ -#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/script_component.hpp b/addons/huntir/script_component.hpp index 01b4f92fec..f4fba8ac1a 100644 --- a/addons/huntir/script_component.hpp +++ b/addons/huntir/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_HUNTIR diff --git a/addons/huntir/stringtable.xml b/addons/huntir/stringtable.xml index 8db0e6afd1..b9ec98a378 100644 --- a/addons/huntir/stringtable.xml +++ b/addons/huntir/stringtable.xml @@ -7,11 +7,15 @@ Caja de transporte de HuntIR Transportní bedna HuntIR Ящик с HuntIR - HuntIR Transport Box + Cassa di Trasporto HuntIR Skrzynia HuntIR Boite de transport HuntIR HuntIR Transport Box Caixa de transporte do HuntIR + HuntIR 輸送箱 + HuntIR 수송함 + 高空战术摄像头运输箱 + 高空戰術成像器運輸箱 HuntIR Round @@ -19,11 +23,15 @@ Proyectil HuntIR HuntIR náboj HuntIR снаряд - HuntIR Round + Colpo HuntIR Nabój HuntIR Munition HuntIR HuntIR lövedék Cartucho HuntIR + HuntIR 弾頭 + HuntIR 유탄 + 高空战术摄像头弹药 + 高空戰術成像器彈藥 HuntIR monitor @@ -31,11 +39,15 @@ Monitor HuntIR HuntIR monitor HuntIR монитор - HuntIR monitor + Monitor HuntIR Odbiornik HuntIR Ecran HuntIR HuntIR monitor Monitor HuntIR + HuntIR モニタ + HuntIR 모니터 + 高空战术摄像头显示面板 + 高空戰術成像器顯示面板 Activate HuntIR monitor @@ -43,11 +55,15 @@ Activar monitor HuntIR Zapnout HuntIR monitor Включить HuntIR монитор - Activate HuntIR monitor + Attiva il monitor HuntIR Włącz odbiornik HuntIR Allumer l'écran du HuntIR HuntIR monitor aktiválása Ativar monitor do HuntIR + HuntIR を起動する + HuntIR 모니터 켜기 + 开启高空战术摄像头显示面板 + 開啟高空戰術成像器顯示面板 Camera: @@ -55,11 +71,15 @@ Camara: Kamera: Камера: - Camera: + Telecamera: Kamera: Caméra : Kamera: Câmera: + カメラ: + 카메라: + 摄像头: + 攝影機: Altitude: @@ -67,11 +87,15 @@ Altitud: Výška: Высота: - Altitude: + Altitudine: Wysokość: Altitude : Magasság: Altitude: + 高度: + 고도: + 高度: + 高度: Recording Time: @@ -79,11 +103,15 @@ Tiempo de grabación: Čas nahrávání: Время записи: - Recording Time: + Tempo di Registrazione: Czas nagrywania: Temps d'enregistrement : Felvételi idő: Tempo de gravação: + 録画時間: + 녹화시간: + 记录时间: + 記錄時間: Press ESC to quit camera @@ -91,11 +119,15 @@ Pulsar ESC para salir de la camara Stiskni ESC pro opustění kamery Нажмите ESC чтобы выйти из режима камеры - Press ESC to quit camera + Premi ESC per uscire dalla telecamera Wciśnij ESC by wyjść z widoku kamery Appuyer sur ESC pour quitter la camera Nyomj ESC-ket a kamerából való kilépéshez Pressione ESC para sair da câmera + ESC を押しカメラを抜ける + ESC를 눌러 카메라 나가기 + 按下ESC退出摄像头 + 按下ESC退出攝影機 Help @@ -103,11 +135,15 @@ Ayuda Nápověda Помощь - Help + Aiuto Pomoc Aide Súgó Ajuda + ヘルプ + 도움말 + 帮助 + 幫助 A/D - Cycle zoom @@ -115,11 +151,15 @@ A/D - Cambiar zoom A/D - Změna přiblížení A/D - Приближение - A/D - Cycle zoom + A/D - Cambia zoom A/D - powiększenie Q/D - Changement de zoom A/D - Nagyítás A/D - Troca zoom + A/D - 倍率の変更 + A/D - 줌 전환 + A/D - 切换放大倍率 + A/D - 切換放大倍率 W/S - Select camera @@ -127,11 +167,15 @@ W/S - Seleccionar camara W/S - Výběr kamery W/S - Выбрать камеру - W/S - Select camera + W/S - Seleziona telecamera W/S - wybór kamery Z/S - Sélectionner la caméra W/S - Kamera váltás W/S - Seleciona câmera + W/S - カメラを選択 + W/S - 카메라 선택 + W/S - 切换摄像头 + W/S - 切換攝影機 Left/Right - Rotate camera @@ -139,11 +183,15 @@ Left/Right - Rotar camara Levá/Pravá - Rotace kamery Влево/Вправо - Вращать камеру - Left/Right - Rotate camera + Left/Right - Ruota telecamera Lewo/Prawo - obrót kamery w poziomie Gauche/Droite - Rotation de la caméra Jobb/Bal - Kamera forgatás Esquerda/Direita - Rotaciona câmera + Left/Right - カメラ回転 + 좌/우 - 카메라 돌리기 + 左/右 - 旋转摄像头 + 左/右 - 旋轉攝影機 Up/Down - Elevate/lower camera @@ -151,11 +199,15 @@ Up/Down - Subir/bajar camara Nahoru/Dolu - Zvýšít/snížit úhel pohledu kamery Вверх/Вниз - Поднять/Опустить камеру - Up/Down - Elevate/lower camera + Up/Down - Alza/abbassa telecamera Góra/Dół - obrót kamery w pionie Haut/Bas - Monter/descendre la caméra Fel/Le - Kamera döntése/süllyesztése Acima/Abaixo - Eleva/Abaixa a câmera + Up/Down - カメラ角度を変更 + 상/하 카메라 올리기/내리기 + 上/下 - 上升/下降摄像头 + 上/下 - 上升/下降攝影機 N - Cycle IT modes @@ -163,11 +215,15 @@ N - Cambiar modos de IT N - Změna režimů kamery N - Режимы камеры - N - Cycle IT modes + N - Cambia modalità IT N - wybór trybu IT N - Changement de modes IT N - Hőkép módok N - Troca modo IT + N - IT モードを変更 + N - IT모드 순환 + N - 切换热显模式 + N - 切換熱顯模式 R - Reset camera @@ -175,11 +231,15 @@ R - Reiniciar camara R - Reset kamery R - Сбросить настройки камеры - R - Reset camera + R - Azzera telecamera R - resetuj kamerę R - Reset de la caméra R - Kamera visszaállítása R - Redefine a câmera + R - カメラを初期化 + R - 카메라 초기화 + R - 重置摄像头 + R - 重置攝影機 Esc - Exit help @@ -187,11 +247,15 @@ Esc - Salit de ayuda Esc - Ukončit pomoc Esc - Выйти из помощи - Esc - Exit help + Esc - Chiudi aiuto Esc - wyjście z ekranu Pomocy Esc - Sortir de l'aide Exit - Kilépés a súgóból Esc - Sai do Ajuda + Esc - ヘルプ終了 + Esc - 도움말 나가기 + Esc - 离开帮助 + Esc - 離開幫助 - \ No newline at end of file + diff --git a/addons/huntir/subConfig/config.cpp b/addons/huntir/subConfig/config.cpp new file mode 100644 index 0000000000..29a9f0ca25 --- /dev/null +++ b/addons/huntir/subConfig/config.cpp @@ -0,0 +1,26 @@ +#include "\z\ace\addons\huntir\script_component.hpp" +#undef COMPONENT +#define COMPONENT huntir_sub + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_huntir"}; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +class CfgWeapons { + class UGL_F; + class Rifle_Base_F; + class arifle_MX_Base_F: Rifle_Base_F { + class GL_3GL_F: UGL_F { + magazines[] += {"ACE_HuntIR_M203"}; + }; + }; +}; diff --git a/addons/interact_menu/CfgEventHandlers.hpp b/addons/interact_menu/CfgEventHandlers.hpp index fa53ccf57c..b8bb1264e1 100644 --- a/addons/interact_menu/CfgEventHandlers.hpp +++ b/addons/interact_menu/CfgEventHandlers.hpp @@ -29,4 +29,10 @@ class Extended_DisplayLoad_EventHandlers { class RscDiary { ADDON = QUOTE(call COMPILE_FILE(XEH_displayLoad)); }; + class RscDisplayInterrupt { + ADDON = QUOTE(_this call FUNC(handleEscapeMenu)); + }; + class RscDisplayMPInterrupt { + ADDON = QUOTE(_this call FUNC(handleEscapeMenu)); + }; }; 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 0c1a6842fc..840acbf10d 100644 --- a/addons/interact_menu/XEH_PREP.hpp +++ b/addons/interact_menu/XEH_PREP.hpp @@ -1,14 +1,17 @@ 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); PREP(isSubPath); PREP(keyDown); PREP(keyUp); diff --git a/addons/interact_menu/XEH_clientInit.sqf b/addons/interact_menu/XEH_clientInit.sqf index 0d280506b3..d6d5cd065c 100644 --- a/addons/interact_menu/XEH_clientInit.sqf +++ b/addons/interact_menu/XEH_clientInit.sqf @@ -1,4 +1,3 @@ -//XEH_clientInit.sqf #include "script_component.hpp" if (!hasInterface) exitWith {}; @@ -10,18 +9,18 @@ GVAR(cachedBuildingActionPairs) = []; GVAR(ParsedTextCached) = []; -["ace_settingChanged", { - params ["_name"]; - if (({_x == _name} count [QGVAR(colorTextMax), QGVAR(colorTextMin), QGVAR(colorShadowMax), QGVAR(colorShadowMin), QGVAR(textSize), QGVAR(shadowSetting)]) == 1) then { - [] call FUNC(setupTextColors); - }; -}] call CBA_fnc_addEventHandler; - ["ace_settingsInitialized", { - //Setup text/shadow/size/color settings matrix + // Setup text/shadow/size/color settings matrix [] call FUNC(setupTextColors); + // Setting changed added here so color setup happens once at init + ["ace_settingChanged", { + params ["_name"]; + if (_name in [QGVAR(colorTextMax), QGVAR(colorTextMin), QGVAR(colorShadowMax), QGVAR(colorShadowMin), QGVAR(textSize), QGVAR(shadowSetting)]) then { + [] call FUNC(setupTextColors); + }; + }] call CBA_fnc_addEventHandler; // Install the render EH on the main display - addMissionEventHandler ["Draw3D", DFUNC(render)]; + addMissionEventHandler ["Draw3D", {call FUNC(render)}]; }] call CBA_fnc_addEventHandler; //Add Actions to Houses: @@ -42,6 +41,27 @@ GVAR(ParsedTextCached) = []; [219, [false, true, false]], false] call CBA_fnc_addKeybind; //Left Windows Key + Ctrl/Strg +["ACE3 Common", QGVAR(InteractKey_Toggle), +format ["%1 (%2)", (localize LSTRING(InteractKey)), localize ELSTRING(common,KeybindToggle)], +{ + if (GVAR(openedMenuType) != 0) then { + [0] call FUNC(keyDown) + } else { + [0,false] call FUNC(keyUp) + }; +}, {}, [-1, [false, false, false]], false] call CBA_fnc_addKeybind; // UNBOUND + +["ACE3 Common", QGVAR(SelfInteractKey_Toggle), +format ["%1 (%2)", (localize LSTRING(SelfInteractKey)), localize ELSTRING(common,KeybindToggle)], +{ + if (GVAR(openedMenuType) != 1) then { + [1] call FUNC(keyDown) + } else { + [1, false] call FUNC(keyUp) + }; +}, {}, [-1, [false, false, false]], false] call CBA_fnc_addKeybind; // UNBOUND + + // Listens for the falling unconscious event, just in case the menu needs to be closed ["ace_unconscious", { // If no menu is open just quit diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 8711f8c180..a05eac1bb5 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -2,7 +2,11 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" GVAR(ActNamespace) = [] call CBA_fnc_createNamespace; GVAR(ActSelfNamespace) = [] call CBA_fnc_createNamespace; diff --git a/addons/interact_menu/config.cpp b/addons/interact_menu/config.cpp index 95561f4579..687d644924 100644 --- a/addons/interact_menu/config.cpp +++ b/addons/interact_menu/config.cpp @@ -25,9 +25,3 @@ class CfgPatches { class ACE_Extensions { extensions[] += {"ace_break_line", "ace_parse_imagepath"}; }; - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; - clearConditionCaches = QGVAR(clearConditionCaches); - interactMenuClosed = "ace_interactMenuClosed"; -}; diff --git a/addons/interact_menu/functions/fnc_addActionToClass.sqf b/addons/interact_menu/functions/fnc_addActionToClass.sqf index 1b4ea27b46..558c497667 100644 --- a/addons/interact_menu/functions/fnc_addActionToClass.sqf +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Insert an ACE action to a class, under a certain path @@ -18,10 +19,10 @@ * * Public: Yes */ -#include "script_component.hpp" if (!params [["_objectType", "", [""]], ["_typeNum", 0, [0]], ["_parentPath", [], [[]]], ["_action", [], [[]], 11]]) exitWith { ERROR("Bad Params"); + [] }; TRACE_4("params",_objectType,_typeNum,_parentPath,_action); @@ -38,6 +39,9 @@ if (param [4, false, [false]]) exitwith { ', _index]; TRACE_2("Added inheritable action",_objectType,_index); [_objectType, "init", _initEH, true, [], true] call CBA_fnc_addClassEventHandler; + + // Return the full path + (_parentPath + [_action select 0]) }; // Ensure the config menu was compiled first @@ -60,12 +64,12 @@ if (_parentPath isEqualTo ["ACE_MainActions"]) then { private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); if (isNil {_parentNode}) exitWith { - ERROR("Failed to add action"); - ACE_LOGERROR_4("action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum); + ERROR_4("Failed to add action - action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum); + [] }; // Add action node as children of the correct node of action tree (_parentNode select 1) pushBack [_action,[]]; // Return the full path -(+ _parentPath) pushBack (_action select 0) +(_parentPath + [_action select 0]) diff --git a/addons/interact_menu/functions/fnc_addActionToObject.sqf b/addons/interact_menu/functions/fnc_addActionToObject.sqf index d307f8b9ad..3ee7c5c332 100644 --- a/addons/interact_menu/functions/fnc_addActionToObject.sqf +++ b/addons/interact_menu/functions/fnc_addActionToObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Insert an ACE action to an object, under a certain config path @@ -15,12 +16,12 @@ * Example: * [cursorTarget, 0, ["ACE_TapShoulderRight"],VulcanPinchAction] call ace_interact_menu_fnc_addActionToObject; * - * Public: No + * Public: Yes */ -#include "script_component.hpp" if (!params [["_object", objNull, [objNull]], ["_typeNum", 0, [0]], ["_parentPath", [], [[]]], ["_action", [], [[]], 11]]) exitWith { ERROR("Bad Params"); + [] }; private _varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; @@ -30,6 +31,13 @@ if (_actionList isEqualTo []) then { _object setVariable [_varName, _actionList]; }; +// Ensure the config menu was compiled first +if (_typeNum == 0) then { + [_object] call FUNC(compileMenu); +} else { + [_object] call FUNC(compileMenuSelfAction); +}; + if (_parentPath isEqualTo ["ACE_MainActions"]) then { [(typeOf _object), _typeNum] call FUNC(addMainAction); }; @@ -38,4 +46,4 @@ if (_parentPath isEqualTo ["ACE_MainActions"]) then { _actionList pushBack [_action, +_parentPath]; // Return the full path -(+ _parentPath) pushBack (_action select 0) +(_parentPath + [_action select 0]) diff --git a/addons/interact_menu/functions/fnc_addActionToZeus.sqf b/addons/interact_menu/functions/fnc_addActionToZeus.sqf new file mode 100644 index 0000000000..65ef178fb0 --- /dev/null +++ b/addons/interact_menu/functions/fnc_addActionToZeus.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_addMainAction.sqf b/addons/interact_menu/functions/fnc_addMainAction.sqf index 43273ef967..d00cd2b60e 100644 --- a/addons/interact_menu/functions/fnc_addMainAction.sqf +++ b/addons/interact_menu/functions/fnc_addMainAction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas, PabstMirror * Makes sure there is a ACE_MainActions on the object type @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_objectType", "_typeNum"]; diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index ae066576f7..e7fecfcac8 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Collect a entire tree of active actions @@ -11,9 +12,11 @@ * Return Value: * Active children * + * Example: + * [bob, [array], [array], 5] call ACE_interact_menu_fnc_collectActoveActionTree + * * Public: No */ -#include "script_component.hpp" params ["_object", "_origAction", "_parentPath", "_distanceToBasePoint"]; _origAction params ["_origActionData", "_origActionChildren"]; diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index 4cf657a3bc..94c63795ff 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Compile the action menu from config for an object's class @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ACE_interact_menu_fnc_compileMenu + * * Public: No */ -#include "script_component.hpp"; params ["_target"]; @@ -33,8 +36,12 @@ private _recurseFnc = { private _displayName = getText (_entryCfg >> "displayName"); private _distance = _parentDistance; if (isNumber (_entryCfg >> "distance")) then {_distance = getNumber (_entryCfg >> "distance");}; - // if (_distance < _parentDistance) then {ACE_LOGWARNING_3("[%1] distance %2 less than parent %3", configName _entryCfg, _distance, _parentDistance);}; - private _icon = getText (_entryCfg >> "icon"); + // if (_distance < _parentDistance) then {WARNING_3("[%1] distance %2 less than parent %3", configName _entryCfg, _distance, _parentDistance);}; + private _icon = if (isArray (_entryCfg >> "icon")) then { + getArray (_entryCfg >> "icon"); + } else { + [getText (_entryCfg >> "icon"), "#FFFFFF"]; + }; private _statement = compile (getText (_entryCfg >> "statement")); // If the position entry is present, compile it @@ -99,11 +106,32 @@ private _recurseFnc = { _actions }; +if ((getNumber (configFile >> "CfgVehicles" >> _objectType >> "isPlayableLogic")) == 1) exitWith { + TRACE_1("skipping playable logic",_objectType); + _namespace setVariable [_objectType, []]; +}; + private _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions"; TRACE_1("Building ACE_Actions",_objectType); private _actions = [_actionsCfg, 0] call _recurseFnc; +// ace_interaction_fnc_addPassengerAction expects ACE_MainActions to be first +// Other mods can change the order that configs are added, so we should verify this now and resort if needed +if (_objectType isKindOf "CaManBase") then { + if ((((_actions select 0) select 0) select 0) != "ACE_MainActions") then { + INFO_1("ACE_MainActions not first for man [%1]",_objectType); + private _mainActions = []; + { + if (((_x select 0) select 0) == "ACE_MainActions") then { + _mainActions = _actions deleteAt _forEachIndex; + }; + } forEach _actions; + if (_mainActions isEqualTo []) exitWith {ERROR_1("ACE_MainActions not found on man [%1]",_objectType);}; + _actions = [_mainActions] + _actions; // resort array with ACE_MainActions first + }; +}; + _namespace setVariable [_objectType, _actions]; /* diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index 0c5e236f0b..8a79fe99e1 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Compile the self action menu from config for an object's class @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ACE_interact_menu_fnc_compileMenuSelfAction + * * Public: No */ -#include "script_component.hpp"; params ["_target"]; @@ -34,7 +37,11 @@ private _recurseFnc = { if(isClass _entryCfg) then { private _displayName = getText (_entryCfg >> "displayName"); - private _icon = getText (_entryCfg >> "icon"); + private _icon = if (isArray (_entryCfg >> "icon")) then { + getArray (_entryCfg >> "icon"); + } else { + [getText (_entryCfg >> "icon"), "#FFFFFF"]; + }; private _statement = compile (getText (_entryCfg >> "statement")); private _condition = getText (_entryCfg >> "condition"); @@ -114,7 +121,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_compileMenuZeus.sqf b/addons/interact_menu/functions/fnc_compileMenuZeus.sqf index c0797269e6..af28bf2284 100644 --- a/addons/interact_menu/functions/fnc_compileMenuZeus.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuZeus.sqf @@ -1,16 +1,19 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Compile the zeus action menu (only to be done once) * * Arguments: - * nil + * None * * Return Value: * None * + * Example: + * call ACE_interact_menu_fnc_compileMenuZeus + * * Public: No */ -#include "script_component.hpp"; // Exit if the action menu is already compiled for zeus if !(isNil {missionNamespace getVariable [QGVAR(ZeusActions), nil]}) exitWith {}; @@ -24,7 +27,11 @@ private _recurseFnc = { if(isClass _entryCfg) then { private _displayName = getText (_entryCfg >> "displayName"); - private _icon = getText (_entryCfg >> "icon"); + private _icon = if (isArray (_entryCfg >> "icon")) then { + getArray (_entryCfg >> "icon"); + } else { + [getText (_entryCfg >> "icon"), "#FFFFFF"]; + }; private _statement = compile (getText (_entryCfg >> "statement")); private _condition = getText (_entryCfg >> "condition"); diff --git a/addons/interact_menu/functions/fnc_createAction.sqf b/addons/interact_menu/functions/fnc_createAction.sqf index 27d6d5bc3d..f8c61c3842 100644 --- a/addons/interact_menu/functions/fnc_createAction.sqf +++ b/addons/interact_menu/functions/fnc_createAction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Creates an isolated ACE action @@ -6,7 +7,7 @@ * Arguments: * 0: Action name * 1: Name of the action shown in the menu - * 2: Icon + * 2: Icon file path or Array of icon file path and hex color ("" for default icon) * 3: Statement * 4: Condition * 5: Insert children code (Optional) @@ -24,7 +25,6 @@ * * Public: Yes */ -#include "script_component.hpp" // IGNORE_PRIVATE_WARNING(_actionName,_displayName,_icon,_statement,_condition,_insertChildren,_customParams,_position,_distance,_params,_modifierFunction); diff --git a/addons/interact_menu/functions/fnc_createVehiclesActions.sqf b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf new file mode 100644 index 0000000000..8218242aab --- /dev/null +++ b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_ctrlSetParsedTextCached.sqf b/addons/interact_menu/functions/fnc_ctrlSetParsedTextCached.sqf index 38e5a42460..deed10e293 100644 --- a/addons/interact_menu/functions/fnc_ctrlSetParsedTextCached.sqf +++ b/addons/interact_menu/functions/fnc_ctrlSetParsedTextCached.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Sets the controls structured text if it isn't already set. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [CONTROL, 5, "text"] call ACE_interact_menu_fnc_ctrlSetParsedTextCached + * * Public: No */ -#include "script_component.hpp" params ["_ctrl", "_index", "_text"]; diff --git a/addons/interact_menu/functions/fnc_findActionNode.sqf b/addons/interact_menu/functions/fnc_findActionNode.sqf index c328e03f39..c2807a3e9c 100644 --- a/addons/interact_menu/functions/fnc_findActionNode.sqf +++ b/addons/interact_menu/functions/fnc_findActionNode.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Return action point from path @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_actionTreeList", "_parentPath"]; diff --git a/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf b/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf new file mode 100644 index 0000000000..d915f57999 --- /dev/null +++ b/addons/interact_menu/functions/fnc_handleEscapeMenu.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Handle the escape key being pressed. + * + * Arguments: + * 0: Escape menu display that should be closed (default: displayNull) + * + * Return Value: + * None + * + * Example: + * [display] call ace_interact_menu_fnc_handleEscapeMenu + * + * Public: No + */ + +if (GVAR(openedMenuType) < 0) exitWith {}; + +params [["_display", displayNull, [displayNull]]]; +TRACE_2("handleEscapeMenu",_display,isNull _display); + +if (!isNull _display) then { + _display closeDisplay 0; +}; + +GVAR(actionSelected) = false; +[GVAR(openedMenuType), false] call FUNC(keyUp); diff --git a/addons/interact_menu/functions/fnc_isSubPath.sqf b/addons/interact_menu/functions/fnc_isSubPath.sqf index 5933e2c462..72857f3070 100644 --- a/addons/interact_menu/functions/fnc_isSubPath.sqf +++ b/addons/interact_menu/functions/fnc_isSubPath.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Check if the first path is a subpath of the other @@ -7,14 +8,13 @@ * 1: ShortPath * * Return Value: - * Bool + * Bool * * Example: * [[["ACE_SelfActions", player],["ace_Gestures", player]], [["ACE_SelfActions", player]]] call ace_interact_menu_fnc_isSubPath * * Public: No */ -#include "script_component.hpp" params ["_longPath", "_shortPath"]; @@ -22,6 +22,7 @@ private _isSubPath = true; if (count _shortPath > count _longPath) exitWith {false}; +//IGNORE_PRIVATE_WARNING ["_i"]; for [{private _i = 0},{_i < count _shortPath},{_i = _i + 1}] do { if !((_longPath select _i) isEqualTo (_shortPath select _i)) exitWith { _isSubPath = false; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 58286a65bb..54a9f070ce 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Handle interactions key down @@ -8,9 +9,11 @@ * Return Value: * true * + * Example: + * [0] call ACE_interact_menu_fnc_keyDown + * * Public: No */ -#include "script_component.hpp" params ["_menuType"]; @@ -18,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 { @@ -38,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"}}} || @@ -59,7 +63,13 @@ if (GVAR(useCursorMenu)) then { createDialog QGVAR(cursorMenu); }; (finddisplay 91919) displayAddEventHandler ["KeyUp", {[_this,'keyup'] call CBA_events_fnc_keyHandler}]; - (finddisplay 91919) displayAddEventHandler ["KeyDown", {[_this,'keydown'] call CBA_events_fnc_keyHandler}]; + (finddisplay 91919) displayAddEventHandler ["KeyDown", { + // Handle the escape key being pressed with menu open: + if ((_this select [1,4]) isEqualTo [1,false,false,false]) exitWith { // escape key with no modifiers + [displayNull] call FUNC(handleEscapeMenu); + }; + [_this,'keydown'] call CBA_events_fnc_keyHandler; + }]; // The dialog sets: // uiNamespace getVariable QGVAR(dlgCursorMenu); // uiNamespace getVariable QGVAR(cursorMenuOpened); @@ -73,6 +83,10 @@ if (GVAR(useCursorMenu)) then { ((finddisplay 91919) displayctrl 9922) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; ((finddisplay 91919) displayctrl 9922) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; setMousePosition [0.5, 0.5]; +} else { + if (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]) then { + (findDisplay 91919) closeDisplay 2; + }; }; GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff (AGLtoASL (positionCameraToWorld [0, 0, 0])); @@ -80,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_keyUp.sqf b/addons/interact_menu/functions/fnc_keyUp.sqf index aae9a370c1..be98452177 100644 --- a/addons/interact_menu/functions/fnc_keyUp.sqf +++ b/addons/interact_menu/functions/fnc_keyUp.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Handle interactions key up @@ -8,9 +9,11 @@ * Return Value: * true * + * Example: + * [1] call ACE_interact_menu_fnc_keyUp + * * Public: No */ -#include "script_component.hpp" params ["_menuType", "_calledByClicking"]; diff --git a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf index f3db5fc8c3..92de6b872a 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Removes an action from a class @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_objectType", "_typeNum", "_fullPath"]; diff --git a/addons/interact_menu/functions/fnc_removeActionFromObject.sqf b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf index 3b720d3c71..64c96ec949 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromObject.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, NouberNou and esteldunedain * Removes an action from an object @@ -15,16 +16,14 @@ * * Public: No */ -#include "script_component.hpp" 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_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index 1c3ed50c92..687498e7cd 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Render all available nearby interactions @@ -13,8 +14,6 @@ * * Public: No */ -// #define ENABLE_PERFORMANCE_COUNTERS -#include "script_component.hpp" BEGIN_COUNTER(fnc_render); @@ -28,7 +27,7 @@ if (GVAR(openedMenuType) >= 0) then { // Render all available nearby interactions call FUNC(renderActionPoints); - // Draw the red selector only when there's no cursor + // Draw the selector only when there's no cursor if !(uiNamespace getVariable [QGVAR(cursorMenuOpened),false]) then { [[0.5,0.5], "\a3\ui_f\data\IGUI\Cfg\Cursors\selected_ca.paa"] call FUNC(renderSelector); }; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 017d3e539b..f4aa8927f6 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Render all action points @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * call ACE_interact_menu_fnc_renderActionPoints + * * Public: No */ -#include "script_component.hpp" GVAR(currentOptions) = []; @@ -127,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 363f7100f9..45c30696f3 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Render the interaction menu for a base action @@ -10,9 +11,11 @@ * Return Value: * Was the menu rendered * + * Example: + * [bob, [node], [0, 0, 0]] call ACE_interact_menu_fnc_renderBaseMenu + * * Public: No */ -#include "script_component.hpp" BEGIN_COUNTER(fnc_renderBaseMenu) @@ -34,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; @@ -61,7 +64,7 @@ if ((_sPos select 0) < safeZoneXAbs || {(_sPos select 0) > safeZoneXAbs + safeZo if ((_sPos select 1) < safeZoneY || {(_sPos select 1) > safeZoneY + safeZoneH}) exitWith {false}; -BEGIN_COUNTER(fnc_collectActiveActionTree) +BEGIN_COUNTER(fnc_collectActiveActionTree); // Collect active tree private _uid = format [QGVAR(ATCache_%1), _actionName]; @@ -71,7 +74,7 @@ private _activeActionTree = [ _object, _uid, 1.0, "ace_interactMenuClosed" ] call EFUNC(common,cachedCall); -END_COUNTER(fnc_collectActiveActionTree) +END_COUNTER(fnc_collectActiveActionTree); #ifdef DEBUG_MODE_EXTRA diag_log "Printing: _activeActionTree"; @@ -79,9 +82,6 @@ diag_log "Printing: _activeActionTree"; params ["_level", "_node"]; _node params ["_actionData", "_children", "_object"]; diag_log text format ["Level %1 -> %2 on %3", _level, _actionData select 0, _object]; - { - [_level + 1, _x] call _fnc_print; - } forEach _children; }; #endif @@ -101,6 +101,6 @@ GVAR(collectedActionPoints) pushBack [_sPos select 2, _sPos, _activeActionTree]; END_COUNTER(fnc_renderMenus); -END_COUNTER(fnc_renderBaseMenu) +END_COUNTER(fnc_renderBaseMenu); true diff --git a/addons/interact_menu/functions/fnc_renderIcon.sqf b/addons/interact_menu/functions/fnc_renderIcon.sqf index ec26635f02..21f1962180 100644 --- a/addons/interact_menu/functions/fnc_renderIcon.sqf +++ b/addons/interact_menu/functions/fnc_renderIcon.sqf @@ -1,19 +1,22 @@ +#include "script_component.hpp" /* - * Author: NouberNou and esteldunedain - * Render a single interaction icon + * Author: NouberNou, esteldunedain, mharis001 + * Render a single interaction icon. * * Arguments: * 0: Text - * 1: Icon + * 1: Icon file path or Array of icon file path and hex color * 2: 2d position * 3: Text Settings * * Return Value: * None * + * Example: + * ["text", "icon", [5, 6], "text"] call ace_interact_menu_fnc_renderIcon + * * Public: No */ -#include "script_component.hpp" #define DEFAULT_ICON QUOTE(\z\ace\addons\interaction\ui\dot_ca.paa) params ["_text", "_icon", "_sPos", "_textSettings"]; @@ -30,14 +33,15 @@ if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then { }; private _ctrl = GVAR(iconCtrls) select GVAR(iconCount); -if(_icon == "") then { - _icon = DEFAULT_ICON; +_icon params [["_iconFile", "", [""]], ["_iconColor", "#FFFFFF", [""]]]; +if (_iconFile isEqualTo "") then { + _iconFile = DEFAULT_ICON; }; _text = if (GVAR(UseListMenu)) then { - format ["%3", _icon, _textSettings, _text] + format ["%4", _iconFile, _iconColor, _textSettings, _text] } else { - format ["
%3", _icon, _textSettings, "ace_break_line" callExtension _text]; + format ["
%4", _iconFile, _iconColor, _textSettings, "ace_break_line" callExtension _text]; }; [_ctrl, GVAR(iconCount), _text] call FUNC(ctrlSetParsedTextCached); diff --git a/addons/interact_menu/functions/fnc_renderMenu.sqf b/addons/interact_menu/functions/fnc_renderMenu.sqf index 687c56d2c3..5801f4602f 100644 --- a/addons/interact_menu/functions/fnc_renderMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderMenu.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: NouberNou and esteldunedain * Render an interaction menu and it's children recursively @@ -11,9 +12,11 @@ * Return Value: * None * + * Example: + * [[], [], [5, 2], []] call ACE_interact_menu_fnc_renderMenu + * * Public: No */ -#include "script_component.hpp" params ["_parentPath", "_action", "_sPos", "_angles"]; _action params ["_actionData", "_activeChildren", "_actionObject"]; diff --git a/addons/interact_menu/functions/fnc_renderSelector.sqf b/addons/interact_menu/functions/fnc_renderSelector.sqf index ef10456b5a..0449f9c922 100644 --- a/addons/interact_menu/functions/fnc_renderSelector.sqf +++ b/addons/interact_menu/functions/fnc_renderSelector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Render a single interaction icon @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [[2, 5], "icon"] call ACE_interact_menu_fnc_renderSelector + * * Public: No */ -#include "script_component.hpp" params ["_sPos", "_icon"]; @@ -27,10 +30,10 @@ if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then { private _ctrl = GVAR(iconCtrls) select GVAR(iconCount); private _pos = if (GVAR(UseListMenu)) then { - [_ctrl, GVAR(iconCount), format ["", _icon]] call FUNC(ctrlSetParsedTextCached); + [_ctrl, GVAR(iconCount), format ["", _icon, GVAR(selectorColorHex)]] call FUNC(ctrlSetParsedTextCached); [(_sPos select 0)-(0.014*SafeZoneW), (_sPos select 1)-(0.014*SafeZoneW), 0.05*SafeZoneW, 0.035*SafeZoneW] } else { - [_ctrl, GVAR(iconCount), format ["", _icon]] call FUNC(ctrlSetParsedTextCached); + [_ctrl, GVAR(iconCount), format ["", _icon, GVAR(selectorColorHex)]] call FUNC(ctrlSetParsedTextCached); [(_sPos select 0)-(0.050*SafeZoneW), (_sPos select 1)-(0.014*SafeZoneW), 0.1*SafeZoneW, 0.035*SafeZoneW] }; diff --git a/addons/interact_menu/functions/fnc_setupTextColors.sqf b/addons/interact_menu/functions/fnc_setupTextColors.sqf index 120c5b18e3..3d0a369c60 100644 --- a/addons/interact_menu/functions/fnc_setupTextColors.sqf +++ b/addons/interact_menu/functions/fnc_setupTextColors.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Builds color strings needed for displaying interaction text @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * call ACE_interact_menu_fnc_setupTextColor + * * Public: No */ -#include "script_component.hpp" //Mixes 2 colors (number arrays) and makes a color string "#AARRGGBB" for structured text private _mixColor = { diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf index eba203aa6f..bd59a39d33 100644 --- a/addons/interact_menu/functions/fnc_splitPath.sqf +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Take full path and split it between parent path and action name @@ -9,9 +10,11 @@ * 0: Parent path * 1: Action name * + * Example: + * [[path]] call ACE_interact_menu_fnc_splitPath + * * Public: No */ -#include "script_component.hpp" private _parentPath = []; for [{private _i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do { diff --git a/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf index 2940bc2936..2497021e00 100644 --- a/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_addHouseActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Scans for nearby "Static" objects (buildings) and adds the UserActions to them. @@ -7,14 +8,13 @@ * 0: Interact Menu Type (0 - world, 1 - self) * * Return Value: - * Nothing + * None * * Example: * [0] call ace_interact_menu_fnc_userActions_addHouseActions * * Public: No */ -#include "script_component.hpp" params ["_interactionType"]; diff --git a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf index c513805d10..46667857f5 100644 --- a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Scans the buidling type for UserActions and Ladder mount points. @@ -6,14 +7,13 @@ * 0: Building Classname * * Return Value: - * [[Array of MemPoints], [Array Of Actions]] + * [[Array of MemPoints], [Array Of Actions]] * * Example: * ["Land_i_House_Big_01_V1_F"] call ace_interact_menu_fnc_userActions_getHouseActions * * Public: No */ -#include "script_component.hpp" params ["_typeOfBuilding"]; diff --git a/addons/interact_menu/initSettings.sqf b/addons/interact_menu/initSettings.sqf new file mode 100644 index 0000000000..45c9fdbd3b --- /dev/null +++ b/addons/interact_menu/initSettings.sqf @@ -0,0 +1,9 @@ +[ + QGVAR(selectorColor), + "COLOR", + localize LSTRING(SelectorColor), + format ["ACE %1", localize LSTRING(Category_InteractionMenu)], + [1, 0, 0], + false, + {GVAR(selectorColorHex) = _this call BIS_fnc_colorRGBtoHTML} // Stored in Hex to avoid constant conversion +] call CBA_settings_fnc_init; diff --git a/addons/interact_menu/script_component.hpp b/addons/interact_menu/script_component.hpp index 1d38d205d7..fea92a9417 100644 --- a/addons/interact_menu/script_component.hpp +++ b/addons/interact_menu/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_INTERACT_MENU diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index d44252e8e1..2c56624e36 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Mindig legyen a saját cselekvés kurzorja látható Mostra sempre il cursore delle autointerazioni Sempre mostrar cursor para interação pessoal + セルフ インタラクションへ常にカーソルを表示 + 자기상호작용시 항상 커서를 보이기 + 自我互动时永远显示游标 + 自我互動時永遠顯示游標 Always display cursor for interaction @@ -24,6 +28,10 @@ Immer den Mauszeiger für Fremd-Interaktionen anzeigen Mindig legyen a cselekvés kurzorja látható Sempre mostrar cursor para interação + インタラクションへ常にカーソルを表示 + 상호작용시 항상 커서를 보이기 + 互动时永远显示游标 + 互動時永遠顯示游標 Display interaction menus as lists @@ -36,6 +44,10 @@ Interaktionsmenü in Listen anzeigen Cselekvő menük listaként való megjelenítése Mostrar menu de interação como listas + インタラクション メニューを一覧表示 + 상호작용메뉴를 리스트화 해서 보이기 + 以列表方式显示互动表单 + 以列表方式顯示互動表單 Interact Key @@ -48,6 +60,10 @@ Cselekvő gomb Tasto interazione Tecla de Interação + インタラクション キー + 상호작용 키 + 互动键 + 互動鍵 Self Interaction Key @@ -60,6 +76,10 @@ Saját cselekvő gomb Tasto interazione su se stessi Tecla de Interação Pessoal + セルフ インタラクション キー + 자기상호작용 키 + 自我互动键 + 自我互動鍵 Self Actions @@ -72,6 +92,10 @@ Saját cselekvések Interazioni su se stessi Ações Pessoais + 自分への動作 + 자기 동작 + 自我动作 + 自我動作 Vehicle Actions @@ -84,6 +108,10 @@ Járműves cselekvések Interazioni con veicoli Ações de Veículos + 車両への動作 + 차량 동작 + 载具动作 + 載具動作 Zeus Actions @@ -96,6 +124,10 @@ Ações do Zeus Действия Зевса Azioni Zeus + Zeus への動作 + Zeus 동작 + 宙斯操作 + 宙斯操作 Interaction - Text Max @@ -108,6 +140,10 @@ Interacción - Texto al max. Cselekvés - Szöveg max. Interação - Max. de Texto + インタラクション - 文字の色 + 상호작용 - 문자색깔 + 互动-文字颜色最大值 + 互動 - 文字最大化 Interaction - Text Min @@ -120,6 +156,10 @@ Interacción - Texto al min. Cselekvés - Szöveg min. Interação - Min. de Texto + インタラクション - 文字の背景色 + 상호작용 - 문자배경색 + 互动-文字颜色最小值 + 互動 - 文字最小化 Interaction - Shadow Max @@ -132,6 +172,10 @@ Interacción - Sombras al max. Cselekvés - Árnyék max. Interação - Max. de Sombra + インタラクション - 文字への影の色 + 상호작용 - 문자그림자색 + 互动 - 阴影最大值 + 互動 - 陰影最大化 Interaction - Shadow Min @@ -144,6 +188,10 @@ Interacción - Sombras al min. Cselekvés - Árnyék min. Interação - Min. de Sombra + インタラクション - 文字への影の最低色 + 상호작용 - 문자그림자배경색 + 互动 - 阴影最小值 + 互動 - 陰影最小化 Keep cursor centered @@ -156,6 +204,10 @@ Udržuj kurzor na středu Manter o cursor centralizado Mantieni il cursore centrato + 常にカーソルを中央にする + 커서를 항상 가운데에 둡니다 + 保持游标在中心点 + 保持游標在中心點 Keeps cursor centered and pans the option menu around. Useful if screen size is limited. @@ -168,6 +220,10 @@ Mantiene el cursor centrado y despliega los menús alrededor. Útil si el tamaño de la pantalla es limitado. Manter o cursor centralizado e mover o menu de opções. Útil caso o tamanho da tela seja limitado. Mantieni il cursore centrato e sposta il menù intorno. Utile se lo schermo è piccolo. + 常にカーソルを中央へ表示させ、オプション メニューが移動します。画面の大きさが制限されている時に使いやすくなります。 + 커서를 항상 가운데에 두고 메뉴를 움직입니다. 화면의 크기가 제한되있을때 유용합니다. + 保持游标在中心点并平移周遭的选项选单。这对在荧幕尺寸有限的玩家很有用! + 保持游標在中心點並平移周遭的選項選單。這對在螢幕尺寸有限的玩家很有用! Do action when releasing menu key @@ -180,6 +236,10 @@ Execute a ação quando soltar a tecla de menu Cselekvés végrehajtása a menügomb elengedésekor Esegui l'azione quando rilasci il tasto menu + メニュー キーを離した時に動作を実行 + 메뉴키를 놓을때 행동하기 + 当放开选单键后就执行动作 + 當放開選單鍵後就執行動作 Interaction Text Size @@ -192,6 +252,10 @@ Tamanho do texto de interação Cselekvő szöveg mérete Dimensione del testo d'interazione + インタラクション文字の大きさ + 상호작용 - 문자크기 + 互动选单文字大小 + 互動選單文字大小 Interaction Text Shadow @@ -204,6 +268,10 @@ Sombra do texto de interação Cselekvő szöveg árnyéka Ombra del testo d'interazione + インタラクション文字へ影 + 상호작용 - 문자그림자 + 互动选单文字阴影 + 互動選單文字陰影 Allows controlling the text's shadow. Outline ignores custom shadow colors. @@ -216,6 +284,10 @@ Permite controlar a sombra do texto. Contorno ignora sombras com cores customizadas. Hozzáférést biztosít a szöveg árnyékának kezeléséhez. A körvonal nem veszi figyelembe az egyedi árnyékszíneket. Permette di controllare l'ombra del testo. L'impostazione "Contorno" ignora il colore dell'ombra. + 文字への影を設定します。縁取りは設定された影の色を無視します。 + 문자의 그림자를 조절하는것을 가능케합니다. 외각선은 임의의 그림자색을 무시합니다. + 允许控制文字阴影。轮廓部分则会忽略自定义的阴影颜色。 + 允許控制文字陰影。輪廓部分則會忽略自定義的陰影顏色 Outline @@ -228,6 +300,10 @@ Contorno Körvonal Contorno + 縁取り + 외각선 + 只显示轮廓 + 只顯示輪廓 Interaction menu background @@ -240,6 +316,10 @@ Cselekvő menü háttere Фон меню взаимодействия Sfondo Menù Interazioni + インタラクション メニューの背景 + 상호작용 메뉴 배경 + 互动选单背景 + 互動選單背景 Blur the background while the interaction menu is open. @@ -252,6 +332,10 @@ A háttér elmosása a cselekvő menü használata alatt. Размыть фон, пока открыто меню взаимодействия. Sfoca lo sfondo mentre il Menù Interazioni è aperto. + インタラクション メニューを開いたとき、背景にボケを与えます。 + 상호작용 메뉴가 열릴시 배경을 흐릿하게 처리합니다. + 当互动选单开启时,模糊背景画面。 + 當互動選單開啟時,模糊背景畫面 Blur screen @@ -264,6 +348,10 @@ Kép elmosása Размытый Sfoca schermo + ボケ画面 + 화면 흐리게 + 模糊画面 + 模糊畫面 Black @@ -276,6 +364,10 @@ Fekete Черный Nero + ブラック + 까맣게 + 黑色 + 黑色 Show actions for buildings @@ -288,6 +380,10 @@ Mostrar ações para edifícios Показывать действия для зданий Mostra azioni per edifici + 建物へ動作を表示 + 건물에 행동을 취함 + 显示建筑物可用的动作 + 顯示建築物可用的動作 Adds interaction actions for opening doors and mounting ladders on buildings. (Note: There is a performance cost when opening interaction menu, especially in towns) @@ -300,6 +396,10 @@ Adiciona ações de interações para abrir portas e montar escadas em edifícios. (Nota: Existe um custo de performance quando aberto o menu de interação, especialmente em cidades) Добавляет действия открывания дверей и залезания на лестницы для зданий. (Примечание: возможно падение производительности при открытии меню взаимодействия, особенно в городах) 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 @@ -311,6 +411,10 @@ Menú de interacción Menù Interazioni Menu d'interaction + インタラクション メニュー + 상호작용 메뉴 + 互动选单 + 互動選單 Interaction Animation Speed @@ -322,6 +426,10 @@ Velocità Animazioni Interazioni Velocidad de animación del menú de interacción Vitesse de l'aniamtion d'interaction + インタラクションのアニメーション速度 + 상호작용 움직임 속도 + 互动选单动画速度 + 互動選單動畫速度 Makes menu animations faster and decreases the time needed to hover to show sub actions @@ -333,6 +441,17 @@ Rende le animazioni Menù più veloci e diminuisce il tempo richiesto per mostrare sotto-azioni 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 + ホバーで子アクションを表示した時に出るメニューのアニメーション速度を早くしたり遅くしたりできます + 使选单的动画速度更快,并减少子选项显现出来的时间 + 使選單的動畫速度更快,並減少子選項顯現出來的時間 + 상호 작용을 표시하기 위해 메뉴 애니메이션을 빠르게 만들고 마우스를 가져 오는 데 필요한 시간을 줄입니다. + + + Selector Color + セレクターの色 + 选择器颜色 + 選單的顏色 + Controllo Settore - \ No newline at end of file + 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 af29186895..af6b4504e1 100644 --- a/addons/interaction/ACE_ZeusActions.hpp +++ b/addons/interaction/ACE_ZeusActions.hpp @@ -3,6 +3,7 @@ class ACE_ZeusActions { class ZeusUnits { displayName = "$STR_A3_RscDisplayCurator_ModeUnits_tooltip"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeUnits_ca.paa"; + condition = QUOTE((count (curatorSelected select 0)) > 0); class stance { displayName = "$STR_A3_RscAttributeUnitPos_Title"; @@ -10,62 +11,63 @@ class ACE_ZeusActions { class prone { displayName = "$STR_Pos_Down"; icon = "\A3\UI_F\Data\IGUI\RscIngameUI\RscUnitInfo\SI_prone_ca.paa"; - statement = "{_x setUnitPos 'DOWN';} forEach (curatorSelected select 0);"; + statement = QUOTE([ARR_3(QQGVAR(zeusStance),[ARR_2('DOWN',curatorSelected select 0)],curatorSelected select 0)] call CBA_fnc_targetEvent;); }; class crouch { displayName = "$STR_Pos_Crouch"; icon = "\A3\UI_F\Data\IGUI\RscIngameUI\RscUnitInfo\SI_crouch_ca.paa"; - statement = "{_x setUnitPos 'MIDDLE';} forEach (curatorSelected select 0);"; + statement = QUOTE([ARR_3(QQGVAR(zeusStance),[ARR_2('MIDDLE',curatorSelected select 0)],curatorSelected select 0)] call CBA_fnc_targetEvent;); }; class stand { displayName = "$STR_Pos_Up"; icon = "\A3\UI_F\Data\IGUI\RscIngameUI\RscUnitInfo\SI_stand_ca.paa"; - statement = "{_x setUnitPos 'UP';} forEach (curatorSelected select 0);"; + statement = QUOTE([ARR_3(QQGVAR(zeusStance),[ARR_2('UP',curatorSelected select 0)],curatorSelected select 0)] call CBA_fnc_targetEvent;); }; class auto { displayName = "$STR_Pos_Automatic"; icon = "\A3\UI_F_Curator\Data\default_ca.paa"; - statement = "{_x setUnitPos 'AUTO';} forEach (curatorSelected select 0);"; + statement = QUOTE([ARR_3(QQGVAR(zeusStance),[ARR_2('AUTO',curatorSelected select 0)],curatorSelected select 0)] call CBA_fnc_targetEvent;); }; }; 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'];"; }; }; class ZeusGroups { displayName = "$STR_A3_RscDisplayCurator_ModeGroups_tooltip"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeGroups_ca.paa"; + condition = QUOTE((count (curatorSelected select 1)) > 0); class behaviour { displayName = "$STR_Combat_Mode"; class careless { displayName = "$STR_Combat_Careless"; - statement = "{ _x setBehaviour 'CARELESS'; } forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusBehaviour),[ARR_2('CARELESS',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class safe { displayName = "$STR_Combat_Safe"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\safe_ca.paa"; - statement = "{ _x setBehaviour 'SAFE'; } forEach (curatorSelected select 1);"; + 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"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\aware_ca.paa"; - statement = "{ _x setBehaviour 'AWARE'; } forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusBehaviour),[ARR_2('AWARE',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class combat { displayName = "$STR_Combat_Combat"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\combat_ca.paa"; - statement = "{ _x setBehaviour 'COMBAT'; } forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusBehaviour),[ARR_2('COMBAT',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class stealth { displayName = "$STR_Combat_Stealth"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\stealth_ca.paa"; - statement = "{ _x setBehaviour 'STEALTH'; } forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusBehaviour),[ARR_2('STEALTH',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; }; @@ -75,17 +77,17 @@ class ACE_ZeusActions { class limited { displayName = "$STR_Speed_Limited"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeSpeedMode\limited_ca.paa"; - statement = "{_x setSpeedMode 'LIMITED';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusSpeed),[ARR_2('LIMITED',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class normal { displayName = "$STR_Speed_Normal"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeSpeedMode\normal_ca.paa"; - statement = "{_x setSpeedMode 'NORMAL';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusSpeed),[ARR_2('NORMAL',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class full { displayName = "$STR_Speed_Full"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeSpeedMode\full_ca.paa"; - statement = "{_x setSpeedMode 'FULL';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusSpeed),[ARR_2('FULL',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; }; @@ -95,47 +97,47 @@ class ACE_ZeusActions { class wedge { displayName = "$STR_Wedge"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\wedge_ca.paa"; - statement = "{_x setFormation 'WEDGE';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('WEDGE',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class vee { displayName = "$STR_Vee"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\vee_ca.paa"; - statement = "{_x setFormation 'VEE';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('VEE',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class line { displayName = "$STR_Line"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\line_ca.paa"; - statement = "{_x setFormation 'LINE';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('LINE',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class column { displayName = "$STR_Column"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\column_ca.paa"; - statement = "{_x setFormation 'COLUMN';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('COLUMN',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class file { displayName = "$STR_File"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\file_ca.paa"; - statement = "{_x setFormation 'FILE';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('FILE',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class stag_column { displayName = "$STR_Staggered"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\stag_column_ca.paa"; - statement = "{_x setFormation 'STAG COLUMN';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('STAG COLUMN',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class ech_left { displayName = "$STR_EchL"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\ech_left_ca.paa"; - statement = "{_x setFormation 'ECH LEFT';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('ECH LEFT',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class ech_right { displayName = "$STR_EchR"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\ech_right_ca.paa"; - statement = "{_x setFormation 'ECH RIGHT';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('ECH RIGHT',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; class diamond { displayName = "$STR_Diamond"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\diamond_ca.paa"; - statement = "{_x setFormation 'DIAMOND';} forEach (curatorSelected select 1);"; + statement = QUOTE([ARR_3(QQGVAR(zeusFormation),[ARR_2('DIAMOND',curatorSelected select 1)],curatorSelected select 1)] call CBA_fnc_targetEvent;); }; }; }; @@ -143,33 +145,34 @@ class ACE_ZeusActions { class ZeusWaypoints { displayName = "Waypoints"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeRecent_ca.paa"; + condition = QUOTE((count (curatorSelected select 2)) > 0); class behaviour { displayName = "$STR_Combat_Mode"; class careless { displayName = "$STR_Combat_Careless"; - statement = "{ _x setWaypointBehaviour 'CARELESS'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusBehaviour),[ARR_3('CARELESS',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class safe { displayName = "$STR_Combat_Safe"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\safe_ca.paa"; - statement = "{ _x setWaypointBehaviour 'SAFE'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusBehaviour),[ARR_3('SAFE',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class aware { displayName = "$STR_Combat_Aware"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\aware_ca.paa"; - statement = "{ _x setWaypointBehaviour 'AWARE'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusBehaviour),[ARR_3('AWARE',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class combat { displayName = "$STR_Combat_Combat"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\combat_ca.paa"; - statement = "{ _x setWaypointBehaviour 'COMBAT'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusBehaviour),[ARR_3('COMBAT',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class stealth { displayName = "$STR_Combat_Stealth"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeBehaviour\stealth_ca.paa"; - statement = "{ _x setWaypointBehaviour 'STEALTH'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusBehaviour),[ARR_3('STEALTH',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; }; @@ -179,17 +182,17 @@ class ACE_ZeusActions { class limited { displayName = "$STR_Speed_Limited"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeSpeedMode\limited_ca.paa"; - statement = "{ _x setWaypointSpeed 'LIMITED'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusSpeed),[ARR_3('LIMITED',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class normal { displayName = "$STR_Speed_Normal"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeSpeedMode\normal_ca.paa"; - statement = "{ _x setWaypointSpeed 'NORMAL'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusSpeed),[ARR_3('NORMAL',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class full { displayName = "$STR_Speed_Full"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeSpeedMode\full_ca.paa"; - statement = "{ _x setWaypointSpeed 'FULL'; } forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusSpeed),[ARR_3('FULL',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; }; @@ -199,47 +202,47 @@ class ACE_ZeusActions { class wedge { displayName = "$STR_Wedge"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\wedge_ca.paa"; - statement = "{_x setWaypointFormation 'WEDGE';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('WEDGE',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class vee { displayName = "$STR_Vee"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\vee_ca.paa"; - statement = "{_x setWaypointFormation 'VEE';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('VEE',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class line { displayName = "$STR_Line"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\line_ca.paa"; - statement = "{_x setWaypointFormation 'LINE';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('LINE',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class column { displayName = "$STR_Column"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\column_ca.paa"; - statement = "{_x setWaypointFormation 'COLUMN';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('COLUMN',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class file { displayName = "$STR_File"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\file_ca.paa"; - statement = "{_x setWaypointFormation 'FILE';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('FILE',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class stag_column { displayName = "$STR_Staggered"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\stag_column_ca.paa"; - statement = "{_x setWaypointFormation 'STAG COLUMN';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('COLUMN',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class ech_left { displayName = "$STR_EchL"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\ech_left_ca.paa"; - statement = "{_x setWaypointFormation 'ECH LEFT';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('LEFT',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class ech_right { displayName = "$STR_EchR"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\ech_right_ca.paa"; - statement = "{_x setWaypointFormation 'ECH RIGHT';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('RIGHT',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; class diamond { displayName = "$STR_Diamond"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\diamond_ca.paa"; - statement = "{_x setWaypointFormation 'DIAMOND';} forEach (curatorSelected select 2);"; + statement = QUOTE([ARR_2(QQGVAR(zeusFormation),[ARR_3('DIAMOND',curatorSelected select 2,true)])] call CBA_fnc_serverEvent;); }; }; }; @@ -247,5 +250,6 @@ class ACE_ZeusActions { class ZeusMarkers { displayName = "$STR_A3_RscDisplayCurator_ModeMarkers_tooltip"; icon = "\A3\UI_F_Curator\Data\Displays\RscDisplayCurator\modeMarkers_ca.paa"; + condition = QUOTE((count (curatorSelected select 3)) > 0); }; }; diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index 5ee893e101..ed208b0435 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,24 +46,24 @@ 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"; class ACE_PassMagazinePrimary { 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"; }; class ACE_PassMagazineHandgun { 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,49 +72,49 @@ 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); class ACE_AssignTeamRed { 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; }; class ACE_AssignTeamGreen { 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; }; class ACE_AssignTeamBlue { 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; }; class ACE_AssignTeamYellow { 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; }; class ACE_UnassignTeam { 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; }; }; @@ -116,8 +122,9 @@ class CfgVehicles { displayName = CSTRING(JoinGroup); 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); }; class ACE_GetDown { @@ -125,28 +132,35 @@ class CfgVehicles { condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canInteractWithCivilian)); statement = QUOTE([ARR_2(_player,_target)] call DFUNC(getDown)); showDisabled = 0; - priority = 2.2; }; class ACE_SendAway { 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; }; class ACE_Pardon { 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; }; class ACE_GetOut { 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"; }; }; @@ -156,6 +170,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_Head { displayName = CSTRING(Head); @@ -163,6 +178,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_ArmLeft { displayName = CSTRING(ArmLeft); @@ -170,6 +186,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_ArmRight { displayName = CSTRING(ArmRight); @@ -177,6 +194,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_LegLeft { displayName = CSTRING(LegLeft); @@ -184,6 +202,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_LegRight { displayName = CSTRING(LegRight); @@ -191,6 +210,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_Weapon { displayName = CSTRING(Weapon); @@ -198,6 +218,7 @@ class CfgVehicles { distance = 1.50; condition = ""; statement = ""; + exceptions[] = {"isNotSwimming"}; }; class ACE_TapShoulderRight { displayName = CSTRING(TapShoulder); @@ -205,6 +226,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); @@ -212,6 +234,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"}; }; }; @@ -219,73 +242,65 @@ 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; icon = QPATHTOF(UI\team\team_management_ca.paa); 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; icon = QPATHTOF(UI\team\team_red_ca.paa); }; 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; icon = QPATHTOF(UI\team\team_green_ca.paa); }; 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; icon = QPATHTOF(UI\team\team_blue_ca.paa); }; 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; icon = QPATHTOF(UI\team\team_yellow_ca.paa); }; 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; icon = QPATHTOF(UI\team\team_white_ca.paa); }; 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; icon = QPATHTOF(UI\team\team_white_ca.paa); }; 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; icon = QPATHTOF(UI\team\team_management_ca.paa); }; }; @@ -293,10 +308,9 @@ 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; icon = ""; // @todo }; }; @@ -313,8 +327,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)); }; }; @@ -323,13 +338,47 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; }; + class Car_F: Car{}; + class Quadbike_01_base_F: Car_F { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + class GVAR(flip) { + displayName = CSTRING(Flip); + condition = QUOTE(call DFUNC(canFlip)); + statement = QUOTE([ARR_3(QQGVAR(flip),_target,_target)] call CBA_fnc_targetEvent); + }; + class GVAR(push) { + displayName = CSTRING(Push); + condition = QUOTE(_target call FUNC(canPush)); + statement = QUOTE(call FUNC(push)); + }; + }; + }; + }; + class Kart_01_Base_F: Car_F { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + class GVAR(flip) { + displayName = CSTRING(Flip); + condition = QUOTE(call DFUNC(canFlip)); + statement = QUOTE([ARR_3(QQGVAR(flip),_target,_target)] call CBA_fnc_targetEvent); + }; + class GVAR(push) { + displayName = CSTRING(Push); + condition = QUOTE(_target call FUNC(canPush)); + statement = QUOTE(call FUNC(push)); + }; + }; + }; + }; + class Tank: LandVehicle { class ACE_Actions { class ACE_MainActions { @@ -340,8 +389,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)); }; }; @@ -350,7 +400,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)); }; @@ -366,8 +416,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)); }; }; @@ -376,8 +427,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)); }; }; @@ -395,8 +447,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)); }; }; @@ -405,7 +458,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)); }; @@ -422,8 +475,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)); }; }; @@ -432,7 +486,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)); }; @@ -464,13 +518,14 @@ 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)); }; }; @@ -479,13 +534,18 @@ class CfgVehicles { class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; }; }; + class Boat_F; + class Boat_Transport_02_base_F: Boat_F { + GVAR(canPush) = 1; + }; + class StaticWeapon: LandVehicle { class ACE_Actions { class ACE_MainActions { @@ -495,17 +555,23 @@ 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)); }; + class GVAR(flip) { + displayName = CSTRING(Flip); + condition = QUOTE(call DFUNC(canFlip)); + statement = QUOTE([ARR_3(QQGVAR(flip),_target,_target)] call CBA_fnc_targetEvent); + }; }; }; class ACE_SelfActions { class ACE_Passengers { displayName = CSTRING(Passengers); - condition = "true"; + condition = QUOTE(alive _target); statement = ""; insertChildren = QUOTE(_this call DFUNC(addPassengersActions)); }; @@ -547,20 +613,24 @@ class CfgVehicles { selection = ""; distance = 2; condition = "true"; - class ACE_OpenBox { displayName = CSTRING(OpenBox); - condition = QUOTE(alive _target); + condition = QUOTE((alive _target) && {(getNumber (configFile >> 'CfgVehicles' >> (typeOf _target) >> 'disableInventory')) == 0}); statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)), _target)]); showDisabled = 0; - priority = -1; }; }; }; - class ACE_SelfActions {}; }; class Slingload_base_F: ReammoBox_F {}; + class Slingload_01_Base_F: Slingload_base_F { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + distance = 5; + }; + }; + }; class Pod_Heli_Transport_04_base_F: Slingload_base_F { class ACE_Actions: ACE_Actions { class ACE_MainActions: ACE_MainActions { @@ -587,37 +657,48 @@ class CfgVehicles { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; - - scope = 2; class ACE_Actions { class ACE_MainActions { displayName = CSTRING(MainAction); - selection = ""; distance = 2; - condition = "true"; - class ACE_LampTurnOn { + + class GVAR(TurnOn) { displayName = CSTRING(TurnOn); - condition = QUOTE(alive _target && !(_target getVariable [ARR_2('ACE_lampOn',true)])); - statement = QUOTE(_target call DFUNC(switchLamp)); - selection = ""; - distance = 2; + icon = "\A3\Ui_f\data\IGUI\Cfg\VehicleToggles\LightsIconOn_ca.paa"; + condition = QUOTE(alive _target && !(_target getVariable [ARR_2(QQGVAR(isLightOn),true)])); + statement = QUOTE([ARR_3(QQGVAR(setLight),[ARR_2(_target,true)],_target)] call CBA_fnc_targetEvent); }; - class ACE_LampTurnOff { + class GVAR(TurnOff) { displayName = CSTRING(TurnOff); - condition = QUOTE(alive _target && _target getVariable [ARR_2('ACE_lampOn',true)]); - statement = QUOTE(_target call DFUNC(switchLamp)); - selection = ""; - distance = 2; + icon = "\A3\ui_f\data\igui\cfg\actions\ico_cpt_land_OFF_ca.paa"; + condition = QUOTE(alive _target && _target getVariable [ARR_2(QQGVAR(isLightOn),true)]); + statement = QUOTE([ARR_3(QQGVAR(setLight),[ARR_2(_target,false)],_target)] call CBA_fnc_targetEvent); }; }; }; }; - class Land_PortableLight_single_off_F: Land_PortableLight_single_F { - scope = 1; - }; - class Land_PortableLight_double_F: Land_PortableLight_single_F {}; - class Land_PortableLight_double_off_F: Land_PortableLight_double_F { - scope = 1; + + class FloatingStructure_F; + class Land_Camping_Light_F: FloatingStructure_F { + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(MainAction); + distance = 2; + + class GVAR(TurnOn) { + displayName = CSTRING(TurnOn); + icon = "\A3\Ui_f\data\IGUI\Cfg\VehicleToggles\LightsIconOn_ca.paa"; + condition = QUOTE(alive _target && !isCollisionLightOn _target); + statement = QUOTE([ARR_3(QQGVAR(setCollisionLight),[ARR_2(_target,true)],_target)] call CBA_fnc_targetEvent); + }; + class GVAR(TurnOff) { + displayName = CSTRING(TurnOff); + icon = "\A3\ui_f\data\igui\cfg\actions\ico_cpt_land_OFF_ca.paa"; + condition = QUOTE(alive _target && isCollisionLightOn _target); + statement = QUOTE([ARR_3(QQGVAR(setCollisionLight),[ARR_2(_target,false)],_target)] call CBA_fnc_targetEvent); + }; + }; + }; }; class RoadCone_F: ThingX { 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 c8ceb66e8f..ea6c275f36 100644 --- a/addons/interaction/XEH_PREP.hpp +++ b/addons/interaction/XEH_PREP.hpp @@ -2,6 +2,7 @@ // interaction menu PREP(addPassengerActions); PREP(addPassengersActions); +PREP(getInteractionDistance); PREP(getVehiclePos); PREP(getVehiclePosComplex); PREP(getWeaponPos); @@ -16,6 +17,7 @@ PREP(canInteractWithCivilian); PREP(getDown); PREP(sendAway); PREP(canJoinGroup); +PREP(modifyJoinGroupAction); PREP(canJoinTeam); PREP(joinTeam); PREP(canPassMagazine); @@ -26,9 +28,12 @@ PREP(canTapShoulder); PREP(tapShoulder); PREP(canPardon); PREP(pardon); +PREP(canPullOutBody); +PREP(pullOutBody); // interaction with doors PREP(getDoor); +PREP(getGlassDoor); PREP(getDoorAnimations); PREP(handleScrollWheel); PREP(openDoor); @@ -37,4 +42,4 @@ PREP(openDoor); PREP(canPush); PREP(push); -PREP(switchLamp); +PREP(canFlip); diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index 9aa9cfb157..4b97c408aa 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -18,14 +18,63 @@ ACE_Modifier = 0; _unit doMove _position; }] call CBA_fnc_addEventHandler; -[QGVAR(setLampOn), { - params ["_lamp", "_hitPointsDamage", "_disabledLampDMG"]; - {if((_x select 1) == _disabledLampDMG) then {_lamp setHit [_x select 0, 0];};nil} count _hitPointsDamage; +[QGVAR(flip), { + params ["_vehicle"]; + private _position = getPosATL _vehicle; + _vehicle setVectorUp surfaceNormal _position; + _vehicle setPosATL _position; }] call CBA_fnc_addEventHandler; -[QGVAR(setLampOff), { - params ["_lamp", "_hitPointsDamage", "_disabledLampDMG"]; - {_lamp setHit [_x select 0, (_x select 1) max _disabledLampDMG];nil} count _hitPointsDamage; +[QGVAR(setLight), { + params ["_lamp", "_state"]; + private _hitpoints = _lamp call EFUNC(common,getReflectorsWithSelections) select 1; + { + private _damage = _lamp getHit _x; + if (_state) then { + if (_damage == DISABLED_LAMP_DAMAGE) then { + _lamp setHit [_x, 0]; + }; + } else { + if (_damage < DISABLED_LAMP_DAMAGE) then { + _lamp setHit [_x, DISABLED_LAMP_DAMAGE]; + }; + }; + } forEach _hitpoints; + _lamp setVariable [QGVAR(isLightOn), _state, true]; +}] call CBA_fnc_addEventHandler; + +[QGVAR(setCollisionLight), { + (_this select 0) setCollisionLight (_this select 1); +}] call CBA_fnc_addEventHandler; + +// Zeus action events +[QGVAR(zeusStance),{ + { _x setUnitPos (_this select 0); } forEach (_this select 1); +}] call CBA_fnc_addEventHandler; + +// The following 3 events handle both waypoints and groups +[QGVAR(zeusBehaviour),{ + if (param [2,false]) then { + { _x setWaypointBehaviour (_this select 0); } forEach (_this select 1); + } else { + { _x setBehaviour (_this select 0); } forEach (_this select 1); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(zeusSpeed),{ + if (param [2,false]) then { + { _x setWaypointSpeed (_this select 0); } forEach (_this select 1); + } else { + { _x setSpeedMode (_this select 0); } forEach (_this select 1); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(zeusFormation),{ + if (param [2,false]) then { + { _x setWaypointFormation (_this select 0); } forEach (_this select 1); + } else { + { _x setFormation (_this select 0); } forEach (_this select 1); + }; }] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; @@ -53,14 +102,13 @@ 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 }, [57, [false, true, false]], false] call CBA_fnc_addKeybind; //Key CTRL+Space - ["ACE3 Common", QGVAR(tapShoulder), localize LSTRING(TapShoulder), { // Conditions: canInteract if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false}; @@ -77,5 +125,31 @@ 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; + + +// to make "Camping Lantern (Off)" be turned on we replace it with "Camping Lantern" +private _action = [ + QGVAR(TurnOn), + localize LSTRING(TurnOn), + "\A3\Ui_f\data\IGUI\Cfg\VehicleToggles\LightsIconOn_ca.paa", + { + private _position = getPosATL _target; + private _vectorDirAndUp = [vectorDir _target, vectorUp _target]; + deleteVehicle _target; + private _newLamp = "Land_Camping_Light_F" createVehicle [0,0,0]; + _newLamp setPosATL _position; + _newLamp setVectorDirAndUp _vectorDirAndUp; + }, + {alive _target} +] call EFUNC(interact_menu,createAction); +["Land_Camping_Light_off_F", 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/interaction/config.cpp b/addons/interaction/config.cpp index c6aff730cf..77c2b408af 100644 --- a/addons/interaction/config.cpp +++ b/addons/interaction/config.cpp @@ -19,12 +19,3 @@ class CfgPatches { #include "RscTitles.hpp" #include "ACE_Settings.hpp" #include "ACE_ZeusActions.hpp" - -class ACE_newEvents { - getDown = QGVAR(getDown); - pardon = QGVAR(pardon); - tapShoulder = QGVAR(tapShoulder); - sendAway = QGVAR(sendAway); - lampTurnOff = QGVAR(setLampOff); - lampTurnOn = QGVAR(setLampOn); -}; diff --git a/addons/interaction/functions/fnc_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf index ca87542172..673fb3ad00 100644 --- a/addons/interaction/functions/fnc_addPassengerActions.sqf +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Mount unit actions inside passenger submenu. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["", "", "_parameters"]; _parameters params ["_unit"]; diff --git a/addons/interaction/functions/fnc_addPassengersActions.sqf b/addons/interaction/functions/fnc_addPassengersActions.sqf index 65fecebbdc..05e5ebfd55 100644 --- a/addons/interaction/functions/fnc_addPassengersActions.sqf +++ b/addons/interaction/functions/fnc_addPassengersActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Create one action per passenger. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_player"]; diff --git a/addons/interaction/functions/fnc_canBecomeLeader.sqf b/addons/interaction/functions/fnc_canBecomeLeader.sqf index 3978306fec..af50c081a0 100644 --- a/addons/interaction/functions/fnc_canBecomeLeader.sqf +++ b/addons/interaction/functions/fnc_canBecomeLeader.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Test if can Become Leader of group. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/interaction/functions/fnc_canFlip.sqf b/addons/interaction/functions/fnc_canFlip.sqf new file mode 100644 index 0000000000..b00164415c --- /dev/null +++ b/addons/interaction/functions/fnc_canFlip.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Checks if vehicle can be flipped. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Can Flip + * + * Example: + * [cursorObject] call ace_interaction_fnc_canFlip + * + * Public: No + */ + +params ["_vehicle"]; + +// most suitable mass for all vanilla, CUP and RHS statics ATM (ZU-23 suits, D-30 and M119 don't suit) +#define FLIP_MAX_STATICWEAPON_MASS 2000 + +1 < (vectorUp _vehicle) vectorDistance (surfaceNormal getPosATL _vehicle) +&& {0 == {alive _x} count crew _vehicle || {isAutonomous _vehicle}} +&& {getMass _vehicle <= FLIP_MAX_STATICWEAPON_MASS} diff --git a/addons/interaction/functions/fnc_canInteractWithCivilian.sqf b/addons/interaction/functions/fnc_canInteractWithCivilian.sqf index add66740e5..7b98ba4972 100644 --- a/addons/interaction/functions/fnc_canInteractWithCivilian.sqf +++ b/addons/interaction/functions/fnc_canInteractWithCivilian.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Checks if the unit can interact with civilian @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", ["_isCivilian", true]]; alive _target && [side _target != side _unit, side group _target == civilian] select _isCivilian // return diff --git a/addons/interaction/functions/fnc_canJoinGroup.sqf b/addons/interaction/functions/fnc_canJoinGroup.sqf index 6a3220181d..bc21e9d162 100644 --- a/addons/interaction/functions/fnc_canJoinGroup.sqf +++ b/addons/interaction/functions/fnc_canJoinGroup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Checks if the unit can join a group @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/interaction/functions/fnc_canJoinTeam.sqf b/addons/interaction/functions/fnc_canJoinTeam.sqf index 7732e164e7..424b3be982 100644 --- a/addons/interaction/functions/fnc_canJoinTeam.sqf +++ b/addons/interaction/functions/fnc_canJoinTeam.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Checks if the player can join a team @@ -14,9 +15,8 @@ * * Public: No */ -#include "script_component.hpp" -PARAMS_2(_unit,_target); +params ["_unit", "_target"]; alive _target && {!(_target getVariable ["ACE_isUnconscious", false])} diff --git a/addons/interaction/functions/fnc_canPardon.sqf b/addons/interaction/functions/fnc_canPardon.sqf index a377533018..81319afb3b 100644 --- a/addons/interaction/functions/fnc_canPardon.sqf +++ b/addons/interaction/functions/fnc_canPardon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Checks if the unit can pardon the target. @@ -9,9 +10,11 @@ * Return Value: * Unit can pardon target * + * Example: + * [bob, kevin] call ACE_interaction_fnc_canPardon + * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/interaction/functions/fnc_canPassMagazine.sqf b/addons/interaction/functions/fnc_canPassMagazine.sqf index 66c560c271..f25e5da164 100644 --- a/addons/interaction/functions/fnc_canPassMagazine.sqf +++ b/addons/interaction/functions/fnc_canPassMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if unit has a spare magazine for the specified weapon. @@ -15,8 +16,6 @@ * * Public: No */ - -#include "script_component.hpp" params ["_player", "_target", "_weapon"]; if (!GVAR(enableMagazinePassing)) exitWith {false}; diff --git a/addons/interaction/functions/fnc_canPullOutBody.sqf b/addons/interaction/functions/fnc_canPullOutBody.sqf new file mode 100644 index 0000000000..bb61cb2545 --- /dev/null +++ b/addons/interaction/functions/fnc_canPullOutBody.sqf @@ -0,0 +1,47 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_canPush.sqf b/addons/interaction/functions/fnc_canPush.sqf index 478c89ca45..0032296a50 100644 --- a/addons/interaction/functions/fnc_canPush.sqf +++ b/addons/interaction/functions/fnc_canPush.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Checks if the boat can be pushed. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target"]; diff --git a/addons/interaction/functions/fnc_canTapShoulder.sqf b/addons/interaction/functions/fnc_canTapShoulder.sqf index 514ac0301b..0c3551051d 100644 --- a/addons/interaction/functions/fnc_canTapShoulder.sqf +++ b/addons/interaction/functions/fnc_canTapShoulder.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Checks if the player can tap a shoulder. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target"]; diff --git a/addons/interaction/functions/fnc_doBecomeLeader.sqf b/addons/interaction/functions/fnc_doBecomeLeader.sqf index 8c8663b03b..8bf1b23e30 100644 --- a/addons/interaction/functions/fnc_doBecomeLeader.sqf +++ b/addons/interaction/functions/fnc_doBecomeLeader.sqf @@ -1,4 +1,5 @@ - /* +#include "script_component.hpp" +/* * Author: PabstMirror * Become Leader of group. * @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/interaction/functions/fnc_getDoor.sqf b/addons/interaction/functions/fnc_getDoor.sqf index 8261aa44f0..6503d1e9e9 100644 --- a/addons/interaction/functions/fnc_getDoor.sqf +++ b/addons/interaction/functions/fnc_getDoor.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: commy2 + * Author: commy2, Phyma * Find door. * * Arguments: @@ -15,27 +16,31 @@ * * Public: No */ -#include "script_component.hpp" 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 = _intersections select 0 select 0; +private _door = toLower (_intersections select 0 select 0); + +if (isNil "_door") exitWith {[_house, ""]}; + +//Check if door is glass because then we need to find the proper location of the door so we can use it +if ((_door find "glass") != -1) then { + _door = [_distance, _house, _door] call FUNC(getGlassDoor); +}; if (isNil "_door") exitWith {[_house, ""]}; diff --git a/addons/interaction/functions/fnc_getDoorAnimations.sqf b/addons/interaction/functions/fnc_getDoorAnimations.sqf index fac29c74a8..003cce7664 100644 --- a/addons/interaction/functions/fnc_getDoorAnimations.sqf +++ b/addons/interaction/functions/fnc_getDoorAnimations.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* - * Author: commy2 - * Get door animations. @todo rewrite for better custom building support + * Author: commy2, Phyma + * Get door animations. * * Arguments: * 0: House @@ -16,108 +17,22 @@ * * Public: No */ -#include "script_component.hpp" params ["_house", "_door"]; -private ["_index", "_animations", "_lockedVariable"]; +private _animate = animationNames _house; +private _animations = []; +private _lockedVariable = []; -_index = [ - "door_1", - "door_2", - "door_3", - "door_4", - "door_5", - "door_6", - "door_7", - "door_8", - "door_9", - "door_10", - "door_11", - "door_12", - "door_13", - "Door_14", - "door_15", - "door_16", - "door_17", - "door_18", - "door_19", - "door_20", - "door_21", - "door_22", - - "hatch_1", - "hatch_2", - "hatch_3", - "hatch_4", - "hatch_5", - "hatch_6" -] find toLower _door; - -if (_index == -1) exitWith {[[],""]}; - -_animations = [ - ["Door_1_rot", "Door_Handle_1_rot_1", "Door_Handle_1_rot_2"], - ["Door_2_rot", "Door_Handle_2_rot_1", "Door_Handle_2_rot_2"], - ["Door_3_rot", "Door_Handle_3_rot_1", "Door_Handle_3_rot_2"], - ["Door_4_rot", "Door_Handle_4_rot_1", "Door_Handle_4_rot_2"], - ["Door_5_rot", "Door_Handle_5_rot_1", "Door_Handle_5_rot_2"], - ["Door_6_rot", "Door_Handle_6_rot_1", "Door_Handle_6_rot_2"], - ["Door_7_rot", "Door_Handle_7_rot_1", "Door_Handle_7_rot_2"], - ["Door_8_rot", "Door_Handle_8_rot_1", "Door_Handle_8_rot_2"], - ["Door_9_rot", "Door_Handle_9_rot_1", "Door_Handle_9_rot_2"], - ["Door_10_rot", "Door_Handle_10_rot_1", "Door_Handle_10_rot_2"], - ["Door_11_rot", "Door_Handle_11_rot_1", "Door_Handle_11_rot_2"], - ["Door_12_rot", "Door_Handle_12_rot_1", "Door_Handle_12_rot_2"], - ["Door_13_rot", "Door_Handle_13_rot_1", "Door_Handle_13_rot_2"], - ["Door_14_rot", "Door_Handle_14_rot_1", "Door_Handle_14_rot_2"], - ["Door_15_rot", "Door_Handle_15_rot_1", "Door_Handle_15_rot_2"], - ["Door_16_rot", "Door_Handle_16_rot_1", "Door_Handle_16_rot_2"], - ["Door_17_rot", "Door_Handle_17_rot_1", "Door_Handle_17_rot_2"], - ["Door_18_rot", "Door_Handle_18_rot_1", "Door_Handle_18_rot_2"], - ["Door_19_rot", "Door_Handle_19_rot_1", "Door_Handle_19_rot_2"], - ["Door_20_rot", "Door_Handle_20_rot_1", "Door_Handle_20_rot_2"], - ["Door_21_rot", "Door_Handle_21_rot_1", "Door_Handle_21_rot_2"], - ["Door_22_rot", "Door_Handle_22_rot_1", "Door_Handle_22_rot_2"], - - ["Hatch_1_rot"], - ["Hatch_2_rot"], - ["Hatch_3_rot"], - ["Hatch_4_rot"], - ["Hatch_5_rot"], - ["Hatch_6_rot"] -] select _index; - -_lockedVariable = [ - ["BIS_Disabled_Door_1", "Door_Handle_1_rot_1", "Door_Locked_1_rot"], - ["BIS_Disabled_Door_2", "Door_Handle_2_rot_1", "Door_Locked_2_rot"], - ["BIS_Disabled_Door_3", "Door_Handle_3_rot_1", "Door_Locked_3_rot"], - ["BIS_Disabled_Door_4", "Door_Handle_4_rot_1", "Door_Locked_4_rot"], - ["BIS_Disabled_Door_5", "Door_Handle_5_rot_1", "Door_Locked_5_rot"], - ["BIS_Disabled_Door_6", "Door_Handle_6_rot_1", "Door_Locked_6_rot"], - ["BIS_Disabled_Door_7", "Door_Handle_7_rot_1", "Door_Locked_7_rot"], - ["BIS_Disabled_Door_8", "Door_Handle_8_rot_1", "Door_Locked_8_rot"], - ["BIS_Disabled_Door_9", "Door_Handle_9_rot_1", "Door_Locked_9_rot"], - ["BIS_Disabled_Door_10", "Door_Handle_10_rot_1", "Door_Locked_10_rot"], - ["BIS_Disabled_Door_11", "Door_Handle_11_rot_1", "Door_Locked_11_rot"], - ["BIS_Disabled_Door_12", "Door_Handle_12_rot_1", "Door_Locked_12_rot"], - ["BIS_Disabled_Door_13", "Door_Handle_13_rot_1", "Door_Locked_13_rot"], - ["BIS_Disabled_Door_14", "Door_Handle_14_rot_1", "Door_Locked_14_rot"], - ["BIS_Disabled_Door_15", "Door_Handle_15_rot_1", "Door_Locked_15_rot"], - ["BIS_Disabled_Door_16", "Door_Handle_16_rot_1", "Door_Locked_16_rot"], - ["BIS_Disabled_Door_17", "Door_Handle_17_rot_1", "Door_Locked_17_rot"], - ["BIS_Disabled_Door_18", "Door_Handle_18_rot_1", "Door_Locked_18_rot"], - ["BIS_Disabled_Door_19", "Door_Handle_19_rot_1", "Door_Locked_19_rot"], - ["BIS_Disabled_Door_20", "Door_Handle_20_rot_1", "Door_Locked_20_rot"], - ["BIS_Disabled_Door_21", "Door_Handle_21_rot_1", "Door_Locked_21_rot"], - ["BIS_Disabled_Door_22", "Door_Handle_22_rot_1", "Door_Locked_22_rot"], - - ["", ""], - ["", ""], - ["", ""], - ["", ""], - ["", ""], - ["", ""] -] select _index; +{ + private _animName = toLower _x; + if ((_animName find (toLower _door)) != -1) then { + if (((_animName find "disabled") != -1) || ((_animName find "locked") != -1)) then { + _lockedVariable pushBack _animName; + } else { + _animations pushBack _animName; + }; + }; +} forEach _animate; [_animations, _lockedVariable] diff --git a/addons/interaction/functions/fnc_getDown.sqf b/addons/interaction/functions/fnc_getDown.sqf index 125af18e09..4291a00f0d 100644 --- a/addons/interaction/functions/fnc_getDown.sqf +++ b/addons/interaction/functions/fnc_getDown.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Forces a civilian to the ground with a chance of failure. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" #define SEND_RADIUS 10 diff --git a/addons/interaction/functions/fnc_getGlassDoor.sqf b/addons/interaction/functions/fnc_getGlassDoor.sqf new file mode 100644 index 0000000000..5febe67067 --- /dev/null +++ b/addons/interaction/functions/fnc_getGlassDoor.sqf @@ -0,0 +1,67 @@ +#include "script_component.hpp" +/* + * Author: Phyma + * Find glass door. + * + * Arguments: + * 0: Distance + * 1: House + * 2: Door name + * + * Return Value: + * 0: Door Name + * + * Example: + * [player, target] call ace_interaction_fnc_getGlassDoor + * + * Public: No + */ + +params ["_distance", "_house", "_door"]; + +private _doorParts = []; +private _doorPos = []; +private _animate = animationNames _house; +private _glassDoor = _door splitString "_"; +private _glassPos = (_house selectionPosition [(_glassDoor select 0) + "_" + (_glassDoor select 1) + "_effects", "Memory"]); +// Calculate all animation names so we know what is there +{ + private _animName = toLower _x; + if (((_animName find "door") != -1) && ((_animName find "locked") == -1) && ((_animName find "disabled") == -1) && ((_animName find "handle") == -1)) then { + private _splitStr = _animName splitString "_"; + _doorParts pushBack ((_splitStr select 0) + "_" + (_splitStr select 1) + "_trigger"); + }; +} forEach _animate; + + +// Get the pos of all the door components and save the parts +{ + _doorPos pushBack (_house selectionPosition [_x, "Memory"]); +} forEach _doorParts; + +// Calculate what door that is closest to the glass door +private _lowestDistance = 0; +{ + private _objDist = _glassPos distance _x; + //Make sure we dont take another door by mistake + if (_objDist <= _distance) then { + //Need to set the value in the beginning + if (_lowestDistance == 0) then { + _lowestDistance = _objDist; + private _splitStr = (_doorParts select _forEachIndex) splitString "_"; + _door = (_splitStr select 0) + "_" + (_splitStr select 1); + } else { + if (_objDist < _lowestDistance) then { + _lowestDistance = _objDist; + private _splitStr = (_doorParts select _forEachIndex) splitString "_"; + _door = (_splitStr select 0) + "_" + (_splitStr select 1); + }; + }; + }; +} forEach _doorPos; + +// Check if we have a door or if it is the glass part +if ((isNil "_door") || ((_door find "glass") != -1)) exitWith {}; + +_door + diff --git a/addons/interaction/functions/fnc_getInteractionDistance.sqf b/addons/interaction/functions/fnc_getInteractionDistance.sqf new file mode 100644 index 0000000000..fa15577ed2 --- /dev/null +++ b/addons/interaction/functions/fnc_getInteractionDistance.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Gets effective interaction distance (handles very large vehicles) + * + * Arguments: + * 0: Player + * 0: Target Vehicle + * + * Return Value: + * Distance to interaction point + * + * Example: + * [player, cursorObject] call ace_interaction_fnc_getInteractionDistance + * + * Public: No + */ + +params ["_unit", "_target"]; +TRACE_3("getInteractionDistance",_unit,_target,typeOf _target); + +// Handle Man, Crate +if (!((_target isKindOf "Car") || {_target isKindOf "Tank"} || {_target isKindOf "Helicopter"} || {_target isKindOf "Plane"} || {_target isKindOf "Ship_F"})) exitWith { + _unit distance _target +}; + +private _unitEyeASL = eyePos _unit; +private _targetModelPos = [_target, _unitEyeASL] call FUNC(getVehiclePosComplex); +private _distance = _unitEyeASL distance (AGLtoASL (_target modelToWorld _targetModelPos)); + +TRACE_2("",_targetModelPos,_distance); + +_distance diff --git a/addons/interaction/functions/fnc_getVehiclePos.sqf b/addons/interaction/functions/fnc_getVehiclePos.sqf index 1544aea939..2da5a31820 100644 --- a/addons/interaction/functions/fnc_getVehiclePos.sqf +++ b/addons/interaction/functions/fnc_getVehiclePos.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Return a suitable position for the action point for the given target vehicle @@ -5,7 +6,7 @@ * Arguments: * None (uses local variable _target) * - * Return value: + * Return Value: * Children actions * * Example: @@ -13,23 +14,24 @@ * * Public: No */ -#include "script_component.hpp" // IGNORE_PRIVATE_WARNING(_target); 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 _relPos params ["_dx", "_dy", "_dz"]; -private _ndx = (abs _dx) / ((abs (_bbx)) - 1); -private _ndy = (abs _dy) / ((abs (_bbY)) - 1); -private _ndz = (abs _dz) / ((abs (_bbZ)) - 1); +private _ndx = (abs _dx) / (((abs (_bbX)) - 1) max 1); +private _ndy = (abs _dy) / (((abs (_bbY)) - 1) max 1); +private _ndz = (abs _dz) / (((abs (_bbZ)) - 1) max 1); -private "_pos"; + +private _pos = []; if (_ndx > _ndy) then { if (_ndx > _ndz) then { // _ndx is greater, will colide with x plane first @@ -47,9 +49,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 886f7052c4..186d424956 100644 --- a/addons/interaction/functions/fnc_getVehiclePosComplex.sqf +++ b/addons/interaction/functions/fnc_getVehiclePosComplex.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain, PabstMirror * Return a suitable position for the action point for the given target vehicle @@ -6,7 +7,7 @@ * 0: Target * 1: Player's Position ASL * - * Return value: + * Return Value: * Interaction point in model cords * * Example: @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target", "_cameraPosASL"]; TRACE_2("params",_target,_cameraPosASL); @@ -29,12 +29,12 @@ if (isNumber (_config >> QGVAR(bodyLength))) then {_bbY = getNumber (_config >> private _relPos = _target worldToModelVisual ASLToAGL _cameraPosASL; _relPos params ["_dx", "_dy", "_dz"]; -private _ndx = (abs _dx) / ((abs (_bbx)) - 1); -private _ndy = (abs _dy) / ((abs (_bbY)) - 1); -private _ndz = (abs _dz) / ((abs (_bbZ)) - 1); +private _ndx = (abs _dx) / (((abs (_bbX)) - 1) max 1); +private _ndy = (abs _dy) / (((abs (_bbY)) - 1) max 1); +private _ndz = (abs _dz) / (((abs (_bbZ)) - 1) max 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..9cd526c12c 100644 --- a/addons/interaction/functions/fnc_getWeaponPos.sqf +++ b/addons/interaction/functions/fnc_getWeaponPos.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Return a suitable position for the action point for the current weapon @@ -13,12 +14,9 @@ * * Public: No */ -#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_handleScrollWheel.sqf b/addons/interaction/functions/fnc_handleScrollWheel.sqf index 793e78c1b3..769995d0a6 100644 --- a/addons/interaction/functions/fnc_handleScrollWheel.sqf +++ b/addons/interaction/functions/fnc_handleScrollWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handles incremental door opening @@ -8,9 +9,11 @@ * Return Value: * handled * + * Example: + * [5] call ACE_interaction_fnc_handleScrollWheel + * * Public: No */ -#include "script_component.hpp" params ["_scroll"]; diff --git a/addons/interaction/functions/fnc_hideMouseHint.sqf b/addons/interaction/functions/fnc_hideMouseHint.sqf index 757fe952e5..155f732eab 100644 --- a/addons/interaction/functions/fnc_hideMouseHint.sqf +++ b/addons/interaction/functions/fnc_hideMouseHint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth de Wet (LH) * Hides the interaction helper text with the mouse buttons at the bottom middle of the screen @@ -13,13 +14,12 @@ * * Public: No */ -#include "script_component.hpp" 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..92e06b4217 100644 --- a/addons/interaction/functions/fnc_joinTeam.sqf +++ b/addons/interaction/functions/fnc_joinTeam.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Unit joins a fire team. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_team"]; @@ -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_modifyJoinGroupAction.sqf b/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf new file mode 100644 index 0000000000..480cdaea40 --- /dev/null +++ b/addons/interaction/functions/fnc_modifyJoinGroupAction.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Modifies the ACE_JoinGroup action to show group name. + * + * Arguments: + * 0: Target + * 1: Player + * 2: Args + * 3: Action Data + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, [], []] call ace_interaction_fnc_modifyJoinGroupAction + * + * Public: No + */ + +params ["_target", "_player", "", "_actionData"]; + +private _actionText = format ["%1: %2", localize LSTRING(JoinGroup), groupID group _target]; +TRACE_3("",_target,group _target,_actionText); + +_actionData set [1, _actionText]; diff --git a/addons/interaction/functions/fnc_moduleInteraction.sqf b/addons/interaction/functions/fnc_moduleInteraction.sqf index 425ee9d6e4..7dd5baa464 100644 --- a/addons/interaction/functions/fnc_moduleInteraction.sqf +++ b/addons/interaction/functions/fnc_moduleInteraction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Initializes the Interaction module. @@ -15,12 +16,12 @@ * * Public: No */ -#include "script_component.hpp" params ["_logic", "", "_activated"]; if !(_activated) exitWith {}; [_logic, QGVAR(EnableTeamManagement), "EnableTeamManagement"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(disableNegativeRating), "DisableNegativeRating"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO("Interaction Module Initialized."); +INFO("Interaction Module Initialized."); diff --git a/addons/interaction/functions/fnc_openDoor.sqf b/addons/interaction/functions/fnc_openDoor.sqf index b1c7789ec3..d27ac52f44 100644 --- a/addons/interaction/functions/fnc_openDoor.sqf +++ b/addons/interaction/functions/fnc_openDoor.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Open door. @@ -14,23 +15,37 @@ * * Public: No */ -#include "script_component.hpp" private _info = [MACRO_DOOR_REACH_DISTANCE] call FUNC(getDoor); _info params ["_house", "_door"]; +TRACE_2("openDoor",_house,_door); if (isNull _house) exitWith {}; private _getDoorAnimations = [_house, _door] call FUNC(getDoorAnimations); -_getDoorAnimations params ["_animations", "_lockedVariable"]; +_getDoorAnimations params ["_animations"]; if (_animations isEqualTo []) exitWith {}; -if (_house animationPhase (_animations select 0) <= 0 && {_house getVariable [_lockedVariable select 0, 0] == 1}) exitWith { - _lockedVariable set [0, _house]; - _lockedVariable call BIS_fnc_LockedDoorOpen; +private _lockedVariable = format ["bis_disabled_%1", _door]; + +// 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)); + if (isClass (configfile >> "CfgVehicles" >> (typeOf _house) >> "AnimationSources" >> _lockedAnimation)) then { + // from: a3\structures_f\scripts\fn_door.sqf: - wiggles the door handle (A3 buildings) + _house animateSource [_lockedAnimation, (1 - (_house animationSourcePhase _lockedAnimation))]; + }; +}; + +// 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 @@ -62,7 +77,6 @@ GVAR(usedScrollWheel) = false; if (CBA_missionTime > _time && {diag_frameno > _frame}) then { GVAR(usedScrollWheel) = true; }; - // do incremental door opening {_house animate [_x, GVAR(doorTargetPhase)]; false} count _animations; }, 0.1, [_house, _animations, getPosASL ACE_player, CBA_missionTime + 0.2, diag_frameno + 2]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/interaction/functions/fnc_pardon.sqf b/addons/interaction/functions/fnc_pardon.sqf index e11a92e7db..4a64771e81 100644 --- a/addons/interaction/functions/fnc_pardon.sqf +++ b/addons/interaction/functions/fnc_pardon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Unit pardons target unit. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ACE_interaction_fnc_pardon + * * Public: No */ -#include "script_component.hpp" params ["", "_target"]; diff --git a/addons/interaction/functions/fnc_passMagazine.sqf b/addons/interaction/functions/fnc_passMagazine.sqf index 15a193cd26..c52e40e88f 100644 --- a/addons/interaction/functions/fnc_passMagazine.sqf +++ b/addons/interaction/functions/fnc_passMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Pass spare magazine for the specified weapon. @@ -15,17 +16,14 @@ * * Public: No */ - -#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 +47,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..6f754eae67 --- /dev/null +++ b/addons/interaction/functions/fnc_pullOutBody.sqf @@ -0,0 +1,63 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_push.sqf b/addons/interaction/functions/fnc_push.sqf index 97534e2c68..abed6be396 100644 --- a/addons/interaction/functions/fnc_push.sqf +++ b/addons/interaction/functions/fnc_push.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Pushes a boat away from the player @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_boat", "_unit"]; diff --git a/addons/interaction/functions/fnc_sendAway.sqf b/addons/interaction/functions/fnc_sendAway.sqf index 6bc70b7445..4831fb7e3f 100644 --- a/addons/interaction/functions/fnc_sendAway.sqf +++ b/addons/interaction/functions/fnc_sendAway.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Sends a near civilian crowd away with a chance of failure. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define SEND_DISTANCE 50 #define SEND_RADIUS 10 diff --git a/addons/interaction/functions/fnc_showMouseHint.sqf b/addons/interaction/functions/fnc_showMouseHint.sqf index 9ea1f26cba..7e9cb6110f 100644 --- a/addons/interaction/functions/fnc_showMouseHint.sqf +++ b/addons/interaction/functions/fnc_showMouseHint.sqf @@ -1,11 +1,13 @@ +#include "script_component.hpp" /* * 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 @@ -15,12 +17,11 @@ * * Public: No */ -#include "script_component.hpp" #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/functions/fnc_switchLamp.sqf b/addons/interaction/functions/fnc_switchLamp.sqf deleted file mode 100644 index f1d9509de8..0000000000 --- a/addons/interaction/functions/fnc_switchLamp.sqf +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Author: SzwedzikPL - * Turn on/off lamp - * - * Arguments: - * 0: Lamp - * - * Return Value: - * None - * - * Example: - * lamp call ace_interaction_fnc_switchLamp - * - * Public: No - */ -#include "script_component.hpp" - -#define DISABLED_LAMP_DMG 0.95 - -params ["_lamp"]; - -_isOn = _lamp getVariable ["ACE_lampOn", true]; -private _reflectors = "true" configClasses (configfile >> "CfgVehicles" >> (typeof _lamp) >> "Reflectors"); -private _hitPointsDamage = []; -{ - private _hitPoint = getText (_x >> "hitpoint"); - _hitPointsDamage pushback [_hitPoint, _lamp getHit _hitPoint]; - nil -} count _reflectors; - -//if lamp is on turn it off -private _eventName = [QGVAR(setLampOn), QGVAR(setLampOff)] select _isOn; -[_eventName, [_lamp, _hitPointsDamage, DISABLED_LAMP_DMG], [_lamp]] call CBA_fnc_targetEvent; - -_lamp setVariable ["ACE_lampOn", !_isOn, true]; diff --git a/addons/interaction/functions/fnc_tapShoulder.sqf b/addons/interaction/functions/fnc_tapShoulder.sqf index 3926503746..c55f3b65d4 100644 --- a/addons/interaction/functions/fnc_tapShoulder.sqf +++ b/addons/interaction/functions/fnc_tapShoulder.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Taps a shoulder @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", "_shoulderNum"]; @@ -23,6 +23,6 @@ if (_unit == ACE_player) then { addCamShake [4, 0.5, 5]; }; -[_unit, "PutDown"] call EFUNC(common,doGesture); +[_unit, "gesturePoint"] call EFUNC(common,doGesture); [QGVAR(tapShoulder), [_target, _shoulderNum], [_target]] call CBA_fnc_targetEvent; diff --git a/addons/interaction/script_component.hpp b/addons/interaction/script_component.hpp index 460550300d..e94733c456 100644 --- a/addons/interaction/script_component.hpp +++ b/addons/interaction/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_INTERACTION @@ -18,3 +17,5 @@ #include "\z\ace\addons\main\script_macros.hpp" #define MACRO_DOOR_REACH_DISTANCE (AGLToASL positionCameraToWorld [0,0,0] vectorDistance AGLToASL (ACE_player modelToWorld (ACE_player selectionPosition "Head"))) + 2 + +#define DISABLED_LAMP_DAMAGE 0.95 diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 5d80cc3dc9..041c344571 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -1,6 +1,15 @@ - + + + Interaction + Interaktion + Interazione + 互動 + 互动 + インタラクション + 상호작용 + Interactions Interaktionen @@ -12,6 +21,10 @@ Cselekvések Interazioni Interaçãoes + インタラクション + 상호작용 + 互动 + 互動 Torso @@ -24,6 +37,10 @@ Testtörzs Torso Torso + 胴体 + 몸통 + 身体 + 身體 Head @@ -36,6 +53,10 @@ Fej Testa Cabeça + 頭部 + 머리 + 头部 + 頭部 Left Arm @@ -48,6 +69,10 @@ Bal kar Braccio sinistro Braço Esquerdo + 左腕 + 왼쪽 팔 + 左手 + 左手 Right Arm @@ -60,6 +85,10 @@ Jobb kar Braccio destro Braço Direito + 右腕 + 오른쪽 팔 + 右手 + 右手 Left Leg @@ -72,6 +101,10 @@ Bal láb Gamba sinistra Perna Esquerda + 左足 + 왼쪽 다리 + 左脚 + 左腳 Right Leg @@ -84,6 +117,10 @@ Jobb láb Gamba destra Perna Direita + 右足 + 오른쪽 다리 + 右脚 + 右腳 Weapon @@ -96,6 +133,10 @@ Fegyver Arma Arma + 武器 + 무기 + 武器 + 武器 Interaction Menu @@ -108,6 +149,10 @@ Cselekvő menü Menu de Interação Menù interazione + インタラクション メニュー + 상호작용 메뉴 + 互动选单 + 互動選單 Interaction Menu (Self) @@ -120,6 +165,10 @@ Cselekvő menü (saját) Menu de Interação (Individual) Menù interazione (individuale) + インタラクション メニュー (セルフ) + 상호작용 메뉴(자신) + 互动选单 (自我) + 互動選單 (自我) Open / Close Door @@ -132,6 +181,10 @@ Ajtó nyitása / zárása Abrir / Fechar Porta Apri / Chiudi la porta + ドアの開け閉め + 문 열기 / 닫기 + 打开/关上 门 + 打開/關上 門 Lock Door @@ -144,6 +197,10 @@ Ajtó bezárása Zablokuj drzwi Zamknout dveře + ドアの鍵をしめる + 문 잠그기 + 锁门 + 鎖門 Unlock Door @@ -156,6 +213,10 @@ Zár kinyitása Odblokuj drzwi Odemknout dveře + ドアの鍵をあける + 잠긴문 열기 + 解锁门 + 解鎖門 Locked Door @@ -168,6 +229,10 @@ Zárt ajtó Zablokowano drzwi Zamčené dveře + ドアの鍵をしめました + 잠긴 문 + 门已上锁 + 門已上鎖 Unlocked Door @@ -180,6 +245,10 @@ Nyitott ajtó Odblokowano drzwi Odemčené dveře + ドアの鍵をあけました + 열린 문 + 门未上锁 + 門未上鎖 Join group @@ -192,6 +261,10 @@ Csatlakozás a csoporthoz Unir-se ao grupo Unisciti alla squadra + グループに入る + 그룹 참여 + 加入小队 + 加入小隊 Leave Group @@ -204,6 +277,10 @@ Csoport elhagyása Deixar grupo Lascia la squadra + グループを抜ける + 그룹 나가기 + 离开小队 + 離開小隊 Become Leader @@ -216,6 +293,10 @@ Vezetés átvétele Tornar-se Líder Prendi il comando + リーダーになる + 리더 되기 + 成为队长 + 成為隊長 DANCE! @@ -228,6 +309,10 @@ TÁNC! DANCE! DANZA! + おどれ! + 춤추기! + 跳舞 + 跳舞 Stop Dancing @@ -240,6 +325,10 @@ Tánc abbahagyása Parar de dançar Smetti di ballare + 踊るのをやめる + 춤 멈추기 + 停止跳舞 + 停止跳舞 << Back @@ -252,6 +341,10 @@ << Vissza << Voltar << Indietro + <<もどる + <<뒤로 + <<返回 + <<返回 Put weapon on back @@ -264,6 +357,10 @@ Fegyvert hátra Colocar arma nas costas Metti l'arma in spalla + 武器を背負う + 등에 무기 메기 + 将武器放到背后 + 將武器放到背後 Tap Shoulder @@ -276,6 +373,10 @@ Vállveregetés Tocar ombro Dai un colpetto + 肩を叩く + 어깨 치기 + 轻拍肩膀 + 輕拍肩膀 You were tapped on the RIGHT shoulder @@ -288,6 +389,10 @@ Вас похлопали по ПРАВОМУ плечу Você foi tocado no ombro Ti è stato dato un colpetto sulla spalla destra + 右肩を叩かれました + 누군가 오른쪽 어깨를 쳤다 + 你的右肩膀被轻拍了一下 + 你的右肩膀被輕拍了一下 You were tapped on the LEFT shoulder. @@ -300,6 +405,10 @@ Вас похлопали по ЛЕВОМУ плечу Você foi tocado no ombro. Ti è stato dato un colpetto sulla spalla sinistra + 左肩を叩かれました + 누군가 왼쪽 어깨를 쳤다 + 你的左肩膀被轻拍了一下 + 你的左肩膀被輕拍了一下 Cancel @@ -312,6 +421,10 @@ Отменить Cancelar Mégse + 中止 + 취소 + 取消 + 取消 Select @@ -324,6 +437,10 @@ Выбрать Selecionar Kiválaszt + 選択 + 선택 + 选择 + 選擇 Go Away! @@ -336,6 +453,10 @@ Tűnés! Vá Embora! Via di qui! + 失せろ! + 저리 가! + 走开! + 走開! Get Down! @@ -348,6 +469,10 @@ Ложись! Abaixe-se! A terra! + 伏せろ! + 엎드려! + 趴下! + 趴下! Get Out @@ -358,6 +483,10 @@ Sortez ! Выходи Vystupte + 降りろ + 나가 + 出去 + 出去 Team Management @@ -370,6 +499,10 @@ Gerenciamento de Equipe Organizzazione Squadra Csapat kezelése + チーム管理 + 팀 설정 + 小队管理 + 小隊管理 Red @@ -382,6 +515,10 @@ Vermelha Rosso Piros + レッド + 빨강 + 红色 + 紅色 Green @@ -394,6 +531,10 @@ Verde Verde Zöld + グリーン + 초록 + 绿色 + 綠色 Blue @@ -406,6 +547,10 @@ Azul Blu Kék + ブルー + 파랑 + 蓝色 + 藍色 Yellow @@ -418,6 +563,10 @@ Amarela Giallo Sárga + イエロー + 노랑 + 黄色 + 黃色 Assign Red @@ -430,6 +579,10 @@ Назначить в Красную группу Assigner à rouge Assegna al team rosso + レッドにする + 빨강에 등록 + 指派为红组 + 指派為紅組 Assign Green @@ -442,6 +595,10 @@ Назначить в Зеленую группу Assigner à vert Assegna al team verde + グリーンにする + 초록에 등록 + 指派为绿组 + 指派為綠組 Assign Blue @@ -454,6 +611,10 @@ Назначить в Синюю группу Assigner à bleu Assegna al team blu + ブルーにする + 파랑이 등록 + 指派为蓝组 + 指派為藍組 Assign Yellow @@ -466,6 +627,10 @@ Назначить в Желтую группу Assigner à jaune Assegna al team giallo + イエローにする + 노랑에 등록 + 指派为黄组 + 指派為黃組 Join Red @@ -478,6 +643,10 @@ Присоединиться к Красной группе Rejoindre rouge Unirsi al team rosso + レッドに入る + 빨강에 참여 + 加入红组 + 加入紅組 Join Green @@ -490,6 +659,10 @@ Присоединиться к Зеленой группе Rejoindre vert Unirsi al team verde + グリーンに入る + 초록에 참여 + 加入绿组 + 加入綠組 Join Blue @@ -502,6 +675,10 @@ Присоединиться к Синей группе Rejoindre bleu Unirsi al team blu + ブルーに入る + 파랑에 참여 + 加入蓝组 + 加入藍組 Join Yellow @@ -514,6 +691,10 @@ Присоединиться к Жёлтой группе Rejoindre jaune Unirsi al team giallo + イエローに入る + 노랑에 참여 + 加入黄组 + 加入黃組 You joined Team %1 @@ -526,6 +707,10 @@ Você uniu-se à Equipe %1 Sei entrato nel team %1 Csatlakoztál a %1 csapathoz + チーム %1 に入りました + 당신은 %1팀에 참여했습니다 + 你已加入%1组 + 你已加入%1組 Leave Team @@ -538,6 +723,10 @@ Deixar Equipe Lascia il team Csapat elhagyása + チームを抜ける + 팀 나가기 + 离开小队 + 離開小隊 You left the Team @@ -550,6 +739,10 @@ Você deixou a Equipe Hai lasciato il team Elhagytad a csapatot + チームを抜けました + 팀을 나갔습니다 + 你已离开小队 + 你已離開小隊 Pardon @@ -562,6 +755,10 @@ Perdão Perdona Megbocsátás + 許す + 허용 + 原谅 + 原諒 Scroll @@ -574,6 +771,10 @@ Scorri Görgetés Posunout + スクロール + 스크롤 + 滚动 + 滾動 Modifier Key @@ -586,6 +787,10 @@ Tasto modifica Módosító billentyű Modifikátor + キーを割り当て + 키 할당하기 + 编辑按键 + 編輯按鍵 Not in Range @@ -598,6 +803,10 @@ Poza zasięgiem Mimo dosah Fuori limite + 範囲内にありません + 범위 내에 없습니다 + 不在范围内 + 不在範圍內 Equipment @@ -610,6 +819,10 @@ Снаряжение Equipaggiamento Equipamento + 装備 + 장비 + 装备 + 裝備 Push @@ -619,9 +832,20 @@ Pchnij Tlačit Tolás - Толкать + Толкнуть Empurrar Spingere + 押す + 밀기 + + + + + Flip + Перевернуть + ひっくり返す + + Gira Interact @@ -634,6 +858,10 @@ Cselekvés Interagire Interagir + インタラクト + 상호작용 + 互动 + 互動 Passengers @@ -646,6 +874,10 @@ Utasok Passeggeri Passageiros + 後部座席 + 승객 + 乘客 + 乘客 Open @@ -658,6 +890,10 @@ Открыть Apri Öffnen + 開く + 열기 + 打开 + 打開 Interaction System @@ -670,6 +906,10 @@ Interakciós rendszer Sistema de interação Sistema Interazioni + インタラクション システム + 상호작용 시스템 + 互动系统 + 互動系統 Enable Team Management @@ -682,6 +922,10 @@ Csapatkezelés engedélyezése Habilitar gestão de equipes Abilità Management Squadra + チーム管理を使う + 팀 설정 활성화 + 启用小队管理 + 啟用小隊管理 Should players be allowed to use the Team Management Menu? Default: Yes @@ -694,6 +938,28 @@ 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. @@ -706,6 +972,10 @@ O módulo de gestão de equipe é composto por: a atribuição de cores para os membros da equipe, comando das equipes, juntando-se / deixando equipes. Управление группами позволяет назначать цвета членам групп, брать командование, вступать в группы или покидать их. Management Squadra permette l'assegnazione di colori per membri della squadra, prendere il comando ed entrare/uscire dalle squadre. + チーム管理はチーム メンバーへ色の割り当てや指揮権を取ったり、チームの出入りを許可します。 + 팀 설정은 팀 멤버에게 색을 부여하거나 팀에 참여 혹은 나가게 할 수 있게 합니다. + 队伍管理系统允许将指定颜色分配到队伍成员上,接管队长职位或加入/离开队伍 + 隊伍管理系統允許將指定顏色分配到隊伍成員上,接管隊長職位或加入/離開隊伍 Turn on @@ -717,6 +987,10 @@ Zapnout Ligar Включить + 有効化 + 켜기 + 开启 + 開啟 Turn off @@ -728,6 +1002,10 @@ Vypnout Desligar Выключить + 無効化 + 끄기 + 关闭 + 關閉 Pass magazine @@ -739,6 +1017,10 @@ Passa caricatore Pasar cargador Passer un chargeur + 弾倉をわたす + 탄창 건네기 + 给予弹匣 + 給予彈匣 Primary magazine @@ -750,6 +1032,10 @@ Caricatore Primario Cargador primario Chargeur de l'arme principale + プライマリ用弾倉 + 주무기 탄창 + 给予主武器弹匣 + 給予主武器彈匣 Pistol magazine @@ -761,6 +1047,10 @@ Caricatore Pistola Cargador de pistola Chargeur de pistolet + 拳銃の弾倉 + 부무기 탄창 + 给予手枪弹匣 + 給予手槍彈匣 %1 passed you a %2 magazine. @@ -772,6 +1062,10 @@ %1 ti ha passato un caricatore %2 . %1 te pasó un cargador %2. %1 vous a passé un chargeur de %2. + %1 はあなたに %2 弾倉をわたした + %1에게서 %2탄창을 받았다 + %1给你%2弹匣 + %1給你%2彈匣 Show "pass magazine" interaction @@ -783,6 +1077,19 @@ Mostra interazione "passa caricatore" Mostrar "Pasar cargador" en el menú de interacción Montrer l'interaction "Passer un chargeur" + "弾倉をわたす"をインタラクションに表示する + '탄창 건네기'를 상호작용에서 보여줌 + 显示"给予弹匣"互动动作 + 顯示"給予彈匣"互動動作 + + + Pull out body + Вытащить тело + 身体を引き出す + Estrai il corpo + 시체 끌기 + 拿出屍體 + 拿出尸体 - \ No newline at end of file + diff --git a/addons/inventory/XEH_preInit.sqf b/addons/inventory/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/inventory/XEH_preInit.sqf +++ b/addons/inventory/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/inventory/functions/fnc_addCustomFilter.sqf b/addons/inventory/functions/fnc_addCustomFilter.sqf index 44e43bdbf0..6d7ab4796f 100644 --- a/addons/inventory/functions/fnc_addCustomFilter.sqf +++ b/addons/inventory/functions/fnc_addCustomFilter.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Adds a custom filter list to the inventory display. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * ["displayname", "filter"] call ACE_inventory_fnc_addCustomFilter + * * Public: No */ -#include "script_component.hpp" params [["_filterName", "ERROR: No Name", [""]], ["_fncName", "", [""]]]; diff --git a/addons/inventory/functions/fnc_currentItemListBox.sqf b/addons/inventory/functions/fnc_currentItemListBox.sqf index 1f1b528e93..3a0889865c 100644 --- a/addons/inventory/functions/fnc_currentItemListBox.sqf +++ b/addons/inventory/functions/fnc_currentItemListBox.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns the current item list box of given inventory display. @@ -10,9 +11,11 @@ * Return Value: * Currently selected item list box * + * Example: + * [DISPLAY] call ACE_inventory_fnc_currentItemListBox + * * Public: No */ -#include "script_component.hpp" params ["_display"]; diff --git a/addons/inventory/functions/fnc_filterBackpacks.sqf b/addons/inventory/functions/fnc_filterBackpacks.sqf index 9b629de66f..66f33ec105 100644 --- a/addons/inventory/functions/fnc_filterBackpacks.sqf +++ b/addons/inventory/functions/fnc_filterBackpacks.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Filter condition for the Backpacks filter list @@ -8,9 +9,11 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterBackpacks + * * Public: No */ -#include "script_component.hpp" params ["_config"]; diff --git a/addons/inventory/functions/fnc_filterGrenades.sqf b/addons/inventory/functions/fnc_filterGrenades.sqf index 0acfbcaa2c..777f8c01cb 100644 --- a/addons/inventory/functions/fnc_filterGrenades.sqf +++ b/addons/inventory/functions/fnc_filterGrenades.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Filter condition for the Grenades filter list @@ -8,9 +9,11 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterGrenades + * * Public: No */ -#include "script_component.hpp" params ["_config"]; diff --git a/addons/inventory/functions/fnc_filterHeadgear.sqf b/addons/inventory/functions/fnc_filterHeadgear.sqf index 056406a3d1..e75898849e 100644 --- a/addons/inventory/functions/fnc_filterHeadgear.sqf +++ b/addons/inventory/functions/fnc_filterHeadgear.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Filter condition for the Headgear filter list @@ -8,9 +9,11 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterHeadgear + * * Public: No */ -#include "script_component.hpp" params ["_config"]; diff --git a/addons/inventory/functions/fnc_filterItems.sqf b/addons/inventory/functions/fnc_filterItems.sqf index b9bf9baeea..78343127af 100644 --- a/addons/inventory/functions/fnc_filterItems.sqf +++ b/addons/inventory/functions/fnc_filterItems.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Remove uniforms, vests and backpacks from Items filter. @@ -8,9 +9,11 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterItems + * * Public: No */ -#include "script_component.hpp" params ["_config"]; diff --git a/addons/inventory/functions/fnc_filterMagazines.sqf b/addons/inventory/functions/fnc_filterMagazines.sqf index dfd357f61d..0e23872d73 100644 --- a/addons/inventory/functions/fnc_filterMagazines.sqf +++ b/addons/inventory/functions/fnc_filterMagazines.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Remove backpacks and grenades from Magazines filter. @@ -8,8 +9,10 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterMagazines + * * Public: No */ -#include "script_component.hpp" !(_this call FUNC(filterBackpacks)) && {!(_this call FUNC(filterGrenades))} diff --git a/addons/inventory/functions/fnc_filterMedical.sqf b/addons/inventory/functions/fnc_filterMedical.sqf index 397be50f06..6e04ddc3de 100644 --- a/addons/inventory/functions/fnc_filterMedical.sqf +++ b/addons/inventory/functions/fnc_filterMedical.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Filter condition for the Medical filter list @@ -8,9 +9,11 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterMedical + * * Public: No */ -#include "script_component.hpp" params ["_config"]; diff --git a/addons/inventory/functions/fnc_filterUniforms.sqf b/addons/inventory/functions/fnc_filterUniforms.sqf index 4c135dfa88..39529121a5 100644 --- a/addons/inventory/functions/fnc_filterUniforms.sqf +++ b/addons/inventory/functions/fnc_filterUniforms.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Filter condition for the Uniforms filter list @@ -8,9 +9,11 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterUniforms + * * Public: No */ -#include "script_component.hpp" params ["_config"]; diff --git a/addons/inventory/functions/fnc_filterVests.sqf b/addons/inventory/functions/fnc_filterVests.sqf index 646e23d04d..99115ac84f 100644 --- a/addons/inventory/functions/fnc_filterVests.sqf +++ b/addons/inventory/functions/fnc_filterVests.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Filter condition for the Vests filter list @@ -8,9 +9,11 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterVests + * * Public: No */ -#include "script_component.hpp" params ["_config"]; diff --git a/addons/inventory/functions/fnc_filterWeapons.sqf b/addons/inventory/functions/fnc_filterWeapons.sqf index 94a92814ae..60065069bb 100644 --- a/addons/inventory/functions/fnc_filterWeapons.sqf +++ b/addons/inventory/functions/fnc_filterWeapons.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Remove backpacks from Weapons filter. @@ -8,8 +9,10 @@ * Return Value: * Item should appear in this list? * + * Example: + * [CONFIG] call ACE_inventory_fnc_filterWeapons + * * Public: No */ -#include "script_component.hpp" !(_this call FUNC(filterBackpacks)) diff --git a/addons/inventory/functions/fnc_forceItemListUpdate.sqf b/addons/inventory/functions/fnc_forceItemListUpdate.sqf index e5358212bb..e162aeee6c 100644 --- a/addons/inventory/functions/fnc_forceItemListUpdate.sqf +++ b/addons/inventory/functions/fnc_forceItemListUpdate.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Updates item list and removes every entry that does not fit in the currently selected filter list. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [DISPLAY] call ACE_inventory_fnc_forceitemListUpdate + * * Public: No */ -#include "script_component.hpp" disableSerialization; params ["_display"]; diff --git a/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf b/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf index 0e1daa4a52..8657d212cd 100644 --- a/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf +++ b/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Executed every time an inventory display is opened. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [DISPLAY] call ACE_inventory_fnc_inventoryDisplayLoad + * * Public: No */ -#include "script_component.hpp" disableSerialization; params ["_display"]; diff --git a/addons/inventory/functions/fnc_onLBSelChanged.sqf b/addons/inventory/functions/fnc_onLBSelChanged.sqf index 5ae49049fe..7f20e48fdf 100644 --- a/addons/inventory/functions/fnc_onLBSelChanged.sqf +++ b/addons/inventory/functions/fnc_onLBSelChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Executed when the filter list box is changed. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [CONTROL, 5] call ACE_inventory_fnc_onLBSelChanged + * * Public: No */ -#include "script_component.hpp" disableSerialization; params ["_filter", "_index"]; diff --git a/addons/inventory/script_component.hpp b/addons/inventory/script_component.hpp index defacb991a..5988a1526a 100644 --- a/addons/inventory/script_component.hpp +++ b/addons/inventory/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_INVENTORY diff --git a/addons/inventory/stringtable.xml b/addons/inventory/stringtable.xml index cfff3624bd..ca09417810 100644 --- a/addons/inventory/stringtable.xml +++ b/addons/inventory/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Legyen a felszerelés menüje nagyobb Ingrandisci il menù inventario Aumentar o Tamanho da Tela do Inventário + インベントリ表示を大きくする + 소지품 화면을 더 크게 합니다 + 使物品显示清单更大 + 使物品顯示清單更大 Normally inventory display is scaled by UI size. This allows scaling the Inventory UI size up, but doesn't increase font size allowing more rows displayed. @@ -22,8 +26,12 @@ Ekwipunek skalowany jest poprzez rozmiar UI. Ta opcja pozwala powiększyć rozmiar UI ekwipunku, lecz nie zwiększa rozmiaru fontu pozwalając na wyświetlanie większej ilości wierszy. L'inventaire est normalement affiché en fonction de la taille de l'UI. Cette option permet d'agrandir l'affichage de l'inventaire, mais n'a aucun effet sur la taille des polices permettant d'afficher plus de lignes. 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 il menù inventario è scalato in base alle dimensioni dell'interfaccia. Questa opzione 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 を大きくできますが、文字は大きくできません。 + 보통 소지품 화면은 사용자 인터페이스 크기에 비례합니다. 이 항목은 소지품의 사용자 인터페이스를 확대를 가능케하면서 글씨는 그대로 냅두게 해줍니다. + 一般来说,物品清单尺寸是由使用者介面来决定的。此选项能让你的物品显示清单更大但不会增加字体大小,此举可增加更多能被显示的描述行数! + 一般來說,物品清單尺寸是由使用者介面來決定的。此選項能讓你的物品顯示清單更大但不會增加字體大小,此舉可增加更多能被顯示的描述行數! Backpacks @@ -35,6 +43,10 @@ Sacs à dos Mochilas Рюкзаки + バックパック + 가방 + 背包 + 背包 Headgear @@ -43,9 +55,13 @@ Hełmy Copricapi Cascos - Couvre-chefs + Couvre-chefs Capacetes Головные уборы + ヘッドギア + 헬멧 + 头盔 + 頭盔 Glasses @@ -57,6 +73,10 @@ Lunettes Óculos Очки + メガネ + 안경 + 眼镜 + 眼鏡 Uniforms @@ -68,17 +88,25 @@ Uniformes Uniformes Униформа + 戦闘服 + 복장 + 服装 + 服裝 Vests Westen Vesty Kamizelki - Vests + Giubbotti Chalecos Vestes Coletes Жилеты + ベスト + 조끼 + 背心 + 背心 Grenades @@ -90,6 +118,10 @@ Grenades Granadas Гранаты + 手榴弾 + 수류탄 + 手榴弹 + 手榴彈 Medical @@ -101,6 +133,10 @@ Médical Médico Медицина + 医療 + 의료 + 医疗 + 醫療 - \ No newline at end of file + diff --git a/addons/javelin/CfgEventhandlers.hpp b/addons/javelin/CfgEventhandlers.hpp index 7b76e00d43..789cfeb05c 100644 --- a/addons/javelin/CfgEventhandlers.hpp +++ b/addons/javelin/CfgEventhandlers.hpp @@ -6,20 +6,13 @@ class Extended_PreStart_EventHandlers { }; class Extended_PreInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_pre_init)); + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_post_init)); + class ADDON { clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); }; }; - -class Extended_FiredBIS_EventHandlers { - class All { - ADDON = QUOTE(_this call FUNC(onFired)); - }; -}; diff --git a/addons/javelin/CfgVehicles.hpp b/addons/javelin/CfgVehicles.hpp index a30489ad14..cd9f23607b 100644 --- a/addons/javelin/CfgVehicles.hpp +++ b/addons/javelin/CfgVehicles.hpp @@ -1,19 +1,19 @@ class CfgVehicles { class LandVehicle; - class StaticWeapon : LandVehicle { + class StaticWeapon: LandVehicle { class Turrets; }; - class StaticMGWeapon : StaticWeapon { - class Turrets : Turrets { + class StaticMGWeapon: StaticWeapon { + class Turrets: Turrets { class MainTurret; }; }; class AT_01_base_F: StaticMGWeapon {}; class B_static_AT_F: AT_01_base_F { - class Turrets : Turrets { - class MainTurret : MainTurret { + class Turrets: Turrets { + class MainTurret: MainTurret { weapons[] = { QGVAR(Titan_Static) }; magazines[] = {"1Rnd_GAT_missiles","1Rnd_GAT_missiles","1Rnd_GAT_missiles","1Rnd_GAT_missiles"}; @@ -30,8 +30,8 @@ class CfgVehicles { }; }; class O_static_AT_F: AT_01_base_F { - class Turrets : Turrets { - class MainTurret : MainTurret { + class Turrets: Turrets { + class MainTurret: MainTurret { weapons[] = { QGVAR(Titan_Static) }; magazines[] = {"1Rnd_GAT_missiles","1Rnd_GAT_missiles","1Rnd_GAT_missiles","1Rnd_GAT_missiles"}; @@ -48,8 +48,8 @@ class CfgVehicles { }; }; class I_static_AT_F: AT_01_base_F { - class Turrets : Turrets { - class MainTurret : MainTurret { + class Turrets: Turrets { + class MainTurret: MainTurret { weapons[] = { QGVAR(Titan_Static) }; magazines[] = {"1Rnd_GAT_missiles","1Rnd_GAT_missiles","1Rnd_GAT_missiles","1Rnd_GAT_missiles"}; @@ -65,4 +65,22 @@ class CfgVehicles { }; }; }; + class Car; + class Car_F: Car { + class Turrets { + class MainTurret; + }; + }; + class LSV_01_base_F: Car_F { + class Turrets: Turrets {}; + }; + class LSV_01_AT_base_F: LSV_01_base_F { // Prowler / Polaris DAGOR + class Turrets: Turrets { + class TopTurret: MainTurret { + weapons[] = { QGVAR(Titan_Static) }; + turretInfoType = "ACE_RscOptics_javelin"; + gunnerOpticsModel = QPATHTOF(data\reticle_titan.p3d); + }; + }; + }; }; diff --git a/addons/javelin/CfgWeapons.hpp b/addons/javelin/CfgWeapons.hpp index 45c8c5942c..b277b6364e 100644 --- a/addons/javelin/CfgWeapons.hpp +++ b/addons/javelin/CfgWeapons.hpp @@ -1,18 +1,8 @@ class CfgWeapons { - class Launcher; - class MissileLauncher; - - class Launcher_Base_F : Launcher { - class WeaponSlotsInfo; - }; - - // @TODO: AA by default, motherfuckers - class missiles_titan : MissileLauncher { - - }; - - class missiles_titan_at : missiles_titan { }; - class GVAR(Titan_Static) : missiles_titan_at { + + class missiles_titan_static; + class GVAR(Titan_Static): missiles_titan_static { + modes[] = {"Player"}; GVAR(enabled) = 1; weaponInfoType = "ACE_RscOptics_javelin"; modelOptics = QPATHTOF(data\reticle_titan.p3d); @@ -23,11 +13,7 @@ class CfgWeapons { lockedTargetSound[] = {"",0,1}; }; - // @TODO: AA by default, motherfuckers - class launch_Titan_base : Launcher_Base_F {}; - - class launch_Titan_short_base : launch_Titan_base { }; - + class launch_Titan_short_base; class launch_B_Titan_short_F: launch_Titan_short_base { GVAR(enabled) = 1; weaponInfoType = "ACE_RscOptics_javelin"; @@ -58,7 +44,6 @@ class CfgWeapons { canLock = 0; - lockingTargetSound[] = {"",0,1}; lockedTargetSound[] = {"",0,1}; }; diff --git a/addons/javelin/README.md b/addons/javelin/README.md index 37685d9cce..ecbf3743b4 100644 --- a/addons/javelin/README.md +++ b/addons/javelin/README.md @@ -9,3 +9,4 @@ Adds the Javelin AT launcher. The people responsible for merging changes to this component or answering potential questions. - [jaynus](https://github.com/walterpearce) +- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/javelin/RscInGameUI.hpp b/addons/javelin/RscInGameUI.hpp index 80e1201682..e34630dde3 100644 --- a/addons/javelin/RscInGameUI.hpp +++ b/addons/javelin/RscInGameUI.hpp @@ -1,10 +1,8 @@ class RscOpticsValue; -class RscControlsGroup; +class RscControlsGroupNoScrollbars; class RscPicture; -class RscMapControl; -class VScrollbar; -class HScrollbar; class RscLine; +class RscMapControl; // Taken from AGM for optics management. @@ -12,29 +10,24 @@ class RscLine; class RscInGameUI { class ACE_RscOptics_javelin { idd = 300; - controls[] = { QGVAR(elements_group), "ACE_Targeting" }; //, "ACE_TargetingConstrains", "ACE_TargetingGate", "ACE_TargetingLines"}; - onLoad = QUOTE(_this call FUNC(onOpticLoad)); - onUnload = QUOTE(_this call FUNC(onOpticUnload)); + controls[] = { QGVAR(elements_group), "ACE_Targeting", QGVAR(mapHelper) }; + onLoad = QUOTE(with uiNamespace do {ACE_RscOptics_javelin = _this select 0;};); - class GVAR(elements_group): RscControlsGroup - { - x = "SafezoneX"; - y = "SafezoneY"; - w = "SafezoneW"; - h = "SafezoneH"; + class GVAR(mapHelper): RscMapControl { + onDraw = QUOTE(_this call FUNC(mapHelperDraw);); + x = -10; + y = -10; + w = 0; + h = 0; + }; + + class GVAR(elements_group): RscControlsGroupNoScrollbars { + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; idc = 170; - class VScrollbar { - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - color[] = {1,1,1,0}; - width = 0.001; - }; - class HScrollbar { - color[] = {1,1,1,0}; - height = 0.001; - }; - class Controls { + class Controls { class CA_Distance: RscOpticsValue { idc = 151; sizeEx = "0"; @@ -44,13 +37,12 @@ class RscInGameUI { w = 0; h = 0; }; - class GVAR(Day_mode_off): RscPicture { idc = 1001; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.03/4)*3*SafezoneH - SafezoneX"; - y = "SafezoneY+SafezoneH*0.031 - SafezoneY"; - w = "0.1045752* (((SafezoneW*3)/4)/SafezoneW)/(1/SafezoneH)"; - h = "SafezoneH*0.1045752"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (0.03/4)*3*safeZoneH - safeZoneX"; + y = "safeZoneY+safeZoneH*0.031 - safeZoneY"; + w = "0.1045752* (((safeZoneW*3)/4)/safeZoneW)/(1/safeZoneH)"; + h = "safeZoneH*0.1045752"; colorText[] = {0.2941,0.2941,0.2941,1}; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\day_co.paa"; }; @@ -58,146 +50,135 @@ class RscInGameUI { idc = 160; colorText[] = {0.2941,0.8745,0.2157,1}; }; - class CA_Javelin_WFOV_mode_off : GVAR(Day_mode_off) { + class GVAR(WFOV_mode_off): GVAR(Day_mode_off) { idc = 1004; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.307/4)*3*SafezoneH - SafezoneX"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (0.307/4)*3*safeZoneH - safeZoneX"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\wfov_co.paa"; }; - class GVAR(WFOV_mode_group): RscControlsGroup { - x = "SafezoneX"; - y = "SafezoneY"; - w = "SafezoneW"; - h = "SafezoneH"; + class GVAR(WFOV_mode_group): RscControlsGroupNoScrollbars { + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; idc = 163; - class VScrollbar { - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - color[] = {1,1,1,0}; - width = 0.001; - }; - class HScrollbar { - color[] = {1,1,1,0}; - height = 0.001; - }; class Controls { + class GVAR(WFOV_mode_on): GVAR(WFOV_mode_off) { + idc = -1; + y = "0.031*SafeZoneH - SafezoneY"; + x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.307/4)*3*SafezoneH - SafezoneX"; + colorText[] = {0.2941,0.8745,0.2157,1}; + }; class StadiaL: RscLine { - x = "0.4899*SafezoneW - SafezoneX"; - y = "0.171*SafezoneH - SafezoneY"; + x = "0.4899*safeZoneW - safeZoneX"; + y = "0.171*safeZoneH - safeZoneY"; w = 0; - h = "0.049*SafezoneH"; + h = "0.049*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class StadiaR: RscLine { - x = "0.5109*SafezoneW- SafezoneX"; - y = "0.171*SafezoneH - SafezoneY"; + x = "0.5109*safeZoneW- safeZoneX"; + y = "0.171*safeZoneH - safeZoneY"; w = 0; - h = "0.049*SafezoneH"; + h = "0.049*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class BracketL: RscLine { - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.293/4)*3*SafezoneH - SafezoneX"; - y = "0.4677*SafezoneH - SafezoneY"; + x = "((safeZoneW -safeZoneH*3/4)/2)+ (0.293/4)*3*safeZoneH - safeZoneX"; + y = "0.4677*safeZoneH - safeZoneY"; w = 0; - h = "0.0646*SafezoneH"; + h = "0.0646*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class BracketR: RscLine { - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.70/4)*3*SafezoneH - SafezoneX"; - y = "0.4677*SafezoneH - SafezoneY"; + x = "((safeZoneW -safeZoneH*3/4)/2)+ (0.70/4)*3*safeZoneH - safeZoneX"; + y = "0.4677*safeZoneH - safeZoneY"; w = 0; - h = "0.0646*SafezoneH"; + h = "0.0646*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class BracketT: RscLine { - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.467/4)*3*SafezoneH - SafezoneX"; - y = "0.3535*SafezoneH - SafezoneY"; - w = "0.065* (((SafezoneW*3)/4)/SafezoneW)/(1/SafezoneH)"; + x = "((safeZoneW -safeZoneH*3/4)/2)+ (0.467/4)*3*safeZoneH - safeZoneX"; + y = "0.3535*safeZoneH - safeZoneY"; + w = "0.065* (((safeZoneW*3)/4)/safeZoneW)/(1/safeZoneH)"; h = 0; colorText[] = {0.2941,0.8745,0.2157,1}; }; class BracketB: RscLine { - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.467/4)*3*SafezoneH - SafezoneX"; - y = "0.6465*SafezoneH - SafezoneY"; - w = "0.065* (((SafezoneW*3)/4)/SafezoneW)/(1/SafezoneH)"; + x = "((safeZoneW -safeZoneH*3/4)/2)+ (0.467/4)*3*safeZoneH - safeZoneX"; + y = "0.6465*safeZoneH - safeZoneY"; + w = "0.065* (((safeZoneW*3)/4)/safeZoneW)/(1/safeZoneH)"; h = 0; colorText[] = {0.2941,0.8745,0.2157,1}; }; }; }; - class CA_Javelin_NFOV_mode_off: GVAR(Day_mode_off) { + class GVAR(NFOV_mode_off): GVAR(Day_mode_off) { idc = 1003; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.586/4)*3*SafezoneH - SafezoneX"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (0.586/4)*3*safeZoneH - safeZoneX"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\nfov_co.paa"; }; - class GVAR(NFOV_mode_group): RscControlsGroup { - x = "SafezoneX"; - y = "SafezoneY"; - w = "SafezoneW-SafezoneX"; - h = "SafezoneH-SafezoneY"; + class GVAR(NFOV_mode_group): RscControlsGroupNoScrollbars { + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW-safeZoneX"; + h = "safeZoneH-safeZoneY"; idc = 162; - class VScrollbar { - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - color[] = {1,1,1,0}; - width = 0.001; - }; - class HScrollbar { - color[] = {1,1,1,0}; - height = 0.001; - }; class Controls { + class GVAR(NFOV_mode_on): GVAR(NFOV_mode_off) { + idc = -1; + x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.586/4)*3*SafezoneH - SafezoneX"; + y = "0.031*SafeZoneH - SafezoneY"; + colorText[] = {0.2941,0.8745,0.2157,1}; + }; class StadiaL: RscLine { - x = "0.4788*SafezoneW - SafezoneX"; - y = "0.171*SafezoneH - SafezoneY"; + x = "0.4788*safeZoneW - safeZoneX"; + y = "0.171*safeZoneH - safeZoneY"; w = 0; - h = "0.049*SafezoneH"; + h = "0.049*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class StadiaR: RscLine { - x = "0.5212*SafezoneW - SafezoneX"; - y = "0.171*SafezoneH - SafezoneY"; + x = "0.5212*safeZoneW - safeZoneX"; + y = "0.171*safeZoneH - safeZoneY"; w = 0; - h = "0.049*SafezoneH"; + h = "0.049*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class LineHL: RscLine { - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.01/4)*3*SafezoneH - SafezoneX"; - y = "SafezoneH*0.5 - SafezoneY"; - w = "0.29* (((SafezoneW*3)/4)/SafezoneW)/(1/SafezoneH)"; - h = "SafezoneH*0.0"; + x = "((safeZoneW -safeZoneH*3/4)/2)+ (0.01/4)*3*safeZoneH - safeZoneX"; + y = "safeZoneH*0.5 - safeZoneY"; + w = "0.29* (((safeZoneW*3)/4)/safeZoneW)/(1/safeZoneH)"; + h = "safeZoneH*0.0"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class LineHR: RscLine { - x = "((SafezoneW -SafezoneH*3/4)/2)+ (0.695/4)*3*SafezoneH - SafezoneX"; - y = "SafezoneH*0.5 - SafezoneY"; - w = "0.29* (((SafezoneW*3)/4)/SafezoneW)/(1/SafezoneH)"; - h = "SafezoneH*0.0"; + x = "((safeZoneW -safeZoneH*3/4)/2)+ (0.695/4)*3*safeZoneH - safeZoneX"; + y = "safeZoneH*0.5 - safeZoneY"; + w = "0.29* (((safeZoneW*3)/4)/safeZoneW)/(1/safeZoneH)"; + h = "safeZoneH*0.0"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class LineVT: RscLine { - x = "0.5*SafezoneW - SafezoneX"; - y = "0.171*SafezoneH - SafezoneY"; + x = "0.5*safeZoneW - safeZoneX"; + y = "0.171*safeZoneH - safeZoneY"; w = 0; - h = "0.1825*SafezoneH"; + h = "0.1825*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class LineVB: RscLine { - x = "0.5*SafezoneW - SafezoneX"; - y = "0.6465*SafezoneH - SafezoneY"; + x = "0.5*safeZoneW - safeZoneX"; + y = "0.6465*safeZoneH - safeZoneY"; w = 0; - h = "0.1895*SafezoneH"; + h = "0.1895*safeZoneH"; colorText[] = {0.2941,0.8745,0.2157,1}; }; - }; }; class GVAR(SEEK_off): GVAR(Day_mode_off) { idc = 699000; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.863/4)*3*SafezoneH - SafezoneX"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (0.863/4)*3*safeZoneH - safeZoneX"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\seek_co.paa"; }; class GVAR(SEEK): GVAR(SEEK_off) { @@ -206,8 +187,8 @@ class RscInGameUI { }; class GVAR(Missle_off): GVAR(Day_mode_off) { idc = 1032; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (-0.134/4)*3*SafezoneH - SafezoneX"; - y = "(SafezoneY + 0.208*SafezoneH) - SafezoneY"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (-0.134/4)*3*safeZoneH - safeZoneX"; + y = "(safeZoneY + 0.208*safeZoneH) - safeZoneY"; colorText[] = {0.2941,0.2941,0.2941,1}; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\missle_co.paa"; }; @@ -217,32 +198,32 @@ class RscInGameUI { }; class GVAR(CLU_off): GVAR(Missle_off) { idc = 1027; - y = "(SafezoneY + 0.436*SafezoneH) - SafezoneY"; + y = "(safeZoneY + 0.436*safeZoneH) - safeZoneY"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\clu_co.paa"; }; class GVAR(HangFire_off): GVAR(Missle_off) { idc = 1028; - y = "(SafezoneY + 0.669*SafezoneH) - SafezoneY"; + y = "(safeZoneY + 0.669*safeZoneH) - safeZoneY"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\hangfire_co.paa"; }; class GVAR(TOP_off): GVAR(Day_mode_off) { idc = 699001; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX"; - y = "(SafezoneY + 0.208*SafezoneH) - SafezoneY"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (1.023/4)*3*safeZoneH - safeZoneX"; + y = "(safeZoneY + 0.208*safeZoneH) - safeZoneY"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\top_co.paa"; colorText[] = {0.2941,0.8745,0.2157,1}; }; class GVAR(DIR): GVAR(Day_mode) { idc = 699002; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX"; - y = "(SafezoneY + 0.436*SafezoneH) - SafezoneY"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (1.023/4)*3*safeZoneH - safeZoneX"; + y = "(safeZoneY + 0.436*safeZoneH) - safeZoneY"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\dir_co.paa"; colorText[] = {0.2941,0.2941,0.2941,1}; }; class GVAR(FLTR_mode_off): GVAR(Day_mode_off) { idc = 1002; - x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (1.023/4)*3*SafezoneH - SafezoneX"; - y = "(SafezoneY + 0.669*SafezoneH) - SafezoneY"; + x = "(safeZoneX+(safeZoneW -safeZoneH*3/4)/2)+ (1.023/4)*3*safeZoneH - safeZoneX"; + y = "(safeZoneY + 0.669*safeZoneH) - safeZoneY"; text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\fltr_co.paa"; }; class GVAR(FLTR_mode): GVAR(FLTR_mode_off) { @@ -251,151 +232,139 @@ class RscInGameUI { }; }; }; - class ACE_Targeting : RscControlsGroup { + class ACE_Targeting: RscControlsGroupNoScrollbars { idc = 6999; - - x = "SafezoneX"; - y = "SafezoneY"; - w = "SafezoneW"; - h = "SafezoneH"; - - enabled = 0; + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW"; + h = "safeZoneH"; + enabled = 0; + show = 0; class Controls { - class ACE_TargetingConstrains: RscControlsGroup { - x = "SafezoneX"; - y = "SafezoneY"; - w = "SafezoneW-SafezoneX"; - h = "SafezoneH-SafezoneY"; + class ACE_TargetingConstrains: RscControlsGroupNoScrollbars { + x = "safeZoneX"; + y = "safeZoneY"; + w = "safeZoneW-safeZoneX"; + h = "safeZoneH-safeZoneY"; enabled = 0; - class VScrollbar { - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - color[] = {1,1,1,0}; - width = 0.001; - }; - class HScrollbar { - color[] = {1,1,1,0}; - height = 0.001; - }; class Controls { class Top: RscPicture { idc = 699101; text = "#(argb,8,8,3)color(1,1,1,1)"; colorText[] = {0.2941,0.2941,0.2941,1}; - x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX"; - y = "0.15*SafezoneH-SafezoneY"; - w = "(3/4)*SafezoneH"; - h = "0.21*SafezoneH"; + x = "((safeZoneW -(3/4)*safeZoneH)/2) - safeZoneX"; + y = "0.15*safeZoneH-safeZoneY"; + w = "(3/4)*safeZoneH"; + h = "0.21*safeZoneH"; }; class Bottom: Top { idc = 699102; - y = "0.64*SafezoneH-SafezoneY"; + y = "0.64*safeZoneH-safeZoneY"; }; class Left: Top { idc = 699103; - x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX"; - y = "0.36*SafezoneH-SafezoneY"; - w = "0.31*(3/4)*SafezoneH"; - h = "0.28*SafezoneH"; + x = "((safeZoneW -(3/4)*safeZoneH)/2) - safeZoneX"; + y = "0.36*safeZoneH-safeZoneY"; + w = "0.31*(3/4)*safeZoneH"; + h = "0.28*safeZoneH"; }; class Right: Left { idc = 699104; - x = "((SafezoneW -(3/4)*SafezoneH)/2)+ 0.69*(3/4)*SafezoneH - SafezoneX"; + x = "((safeZoneW -(3/4)*safeZoneH)/2)+ 0.69*(3/4)*safeZoneH - safeZoneX"; }; class OpticsBorders: RscPicture { idc = 699105; text = QPATHTOF(data\javelin_ui_border_ca.paa); colorText[] = {0,0,0,1}; - x = "((SafezoneW -(3.1/4)*SafezoneH)/2) - SafezoneX"; - y = "0.15*SafezoneH-SafezoneY"; - w = "(3.1/4)*SafezoneH"; - h = "0.7*SafezoneH"; + x = "((safeZoneW -(3.1/4)*safeZoneH)/2) - safeZoneX"; + y = "0.15*safeZoneH-safeZoneY"; + w = "(3.1/4)*safeZoneH"; + h = "0.7*safeZoneH"; }; }; }; - class ACE_TargetingGate : ACE_TargetingConstrains { + class ACE_TargetingGate: ACE_TargetingConstrains { idc = 699200; class Controls { class TargetingGateTL: ACE_TargetingConstrains { - x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX"; - y = "0.15*SafezoneH - SafezoneY"; + x = "((safeZoneW -(3/4)*safeZoneH)/2) - safeZoneX"; + y = "0.15*safeZoneH - safeZoneY"; idc = 699201; class Controls { class LineH: RscLine { idc = 699210; x = "0"; y = "0"; - w = "0.025*(3/4)*SafezoneH"; + w = "0.025*(3/4)*safeZoneH"; h = "0"; colorText[] = {0.8745,0.8745,0.8745,1}; }; class LineV: LineH { idc = 699211; w = "0"; - h = "0.025*SafezoneH"; + h = "0.025*safeZoneH"; }; }; }; class TargetingGateTR: TargetingGateTL { - x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX + 0.975*(3/4)*SafezoneH"; - y = "0.15*SafezoneH - SafezoneY"; + x = "((safeZoneW -(3/4)*safeZoneH)/2) - safeZoneX + 0.975*(3/4)*safeZoneH"; + y = "0.15*safeZoneH - safeZoneY"; idc = 699202; class Controls { class LineH: RscLine { idc = 699220; x = "0"; y = "0"; - w = "0.025*(3/4)*SafezoneH"; + w = "0.025*(3/4)*safeZoneH"; h = "0"; colorText[] = {0.8745,0.8745,0.8745,1}; }; class LineV: LineH { idc = 699221; - x = "0.025*(3/4)*SafezoneH"; + x = "0.025*(3/4)*safeZoneH"; w = "0"; - h = "0.025*SafezoneH"; + h = "0.025*safeZoneH"; }; }; }; class TargetingGateBL: TargetingGateTL { - x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX"; - y = "0.825*SafezoneH - SafezoneY"; + x = "((safeZoneW -(3/4)*safeZoneH)/2) - safeZoneX"; + y = "0.825*safeZoneH - safeZoneY"; idc = 699203; class Controls { class LineH: RscLine { x = "0"; - y = "0.025*SafezoneH"; - w = "0.025*(3/4)*SafezoneH"; + y = "0.025*safeZoneH"; + w = "0.025*(3/4)*safeZoneH"; h = "0"; colorText[] = {0.8745,0.8745,0.8745,1}; }; class LineV: LineH { y = "0"; w = "0"; - h = "0.025*SafezoneH"; + h = "0.025*safeZoneH"; }; }; }; class TargetingGateBR: TargetingGateBL { - x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX + 0.975*(3/4)*SafezoneH"; - y = "0.825*SafezoneH - SafezoneY"; + x = "((safeZoneW -(3/4)*safeZoneH)/2) - safeZoneX + 0.975*(3/4)*safeZoneH"; + y = "0.825*safeZoneH - safeZoneY"; idc = 699204; class Controls { class LineH: RscLine { x = "0"; - y = "0.025*SafezoneH"; - w = "0.025*(3/4)*SafezoneH"; + y = "0.025*safeZoneH"; + w = "0.025*(3/4)*safeZoneH"; h = "0"; colorText[] = {0.8745,0.8745,0.8745,1}; }; class LineV: LineH { - x = "0.025*(3/4)*SafezoneH"; + x = "0.025*(3/4)*safeZoneH"; y = "0"; w = "0"; - h = "0.025*SafezoneH"; + h = "0.025*safeZoneH"; }; }; }; @@ -408,18 +377,18 @@ class RscInGameUI { class Controls { class LineH: RscLine { idc = 699301; - x = "((SafezoneW -(3/4)*SafezoneH)/2) - SafezoneX"; - y = "0.5*SafezoneH - SafezoneY"; - w = "(3/4)*SafezoneH"; + x = "((safeZoneW -(3/4)*safeZoneH)/2) - safeZoneX"; + y = "0.5*safeZoneH - safeZoneY"; + w = "(3/4)*safeZoneH"; h = "0"; colorText[] = {0.8745,0.8745,0.8745,1}; }; class LineV: RscLine { idc = 699302; - x = "0.5*SafezoneW - SafezoneX"; - y = "0.15*SafezoneH - SafezoneY"; + x = "0.5*safeZoneW - safeZoneX"; + y = "0.15*safeZoneH - safeZoneY"; w = "0"; - h = "0.7*SafezoneH"; + h = "0.7*safeZoneH"; colorText[] = {0.8745,0.8745,0.8745,1}; }; }; @@ -451,4 +420,4 @@ ACE_Titan_TOP_off: 1006 ACE_Titan_DIR: 1007 ACE_Titan_FLTR_mode_off: 1002 ACE_Titan_FLTR_mode: 161 -*/ + */ diff --git a/addons/javelin/XEH_PREP.hpp b/addons/javelin/XEH_PREP.hpp index fe9bbc553b..76d658d90d 100644 --- a/addons/javelin/XEH_PREP.hpp +++ b/addons/javelin/XEH_PREP.hpp @@ -1,11 +1,5 @@ -PREP(lockKeyDown); -PREP(lockKeyUp); - -PREP(cycleFireMode); -PREP(showFireMode); - -PREP(onFired); -PREP(onOpticLoad); +PREP(getTarget); +PREP(mapHelperDraw); PREP(onOpticDraw); -PREP(onOpticUnload); +PREP(showFireMode); diff --git a/addons/javelin/XEH_clientInit.sqf b/addons/javelin/XEH_clientInit.sqf index 1286be3697..66d645968f 100644 --- a/addons/javelin/XEH_clientInit.sqf +++ b/addons/javelin/XEH_clientInit.sqf @@ -1,5 +1,6 @@ +// #define DEBUG_MODE_FULL #include "script_component.hpp" if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" \ No newline at end of file +#include "initKeybinds.sqf" diff --git a/addons/javelin/XEH_post_init.sqf b/addons/javelin/XEH_post_init.sqf deleted file mode 100644 index 6eccf9d1dd..0000000000 --- a/addons/javelin/XEH_post_init.sqf +++ /dev/null @@ -1,2 +0,0 @@ -#include "script_component.hpp" - diff --git a/addons/javelin/XEH_preInit.sqf b/addons/javelin/XEH_preInit.sqf new file mode 100644 index 0000000000..b404d35889 --- /dev/null +++ b/addons/javelin/XEH_preInit.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +GVAR(isLockKeyDown) = false; +GVAR(pfehID) = -1; + +DFUNC(disableFire) = { + params ["_firedEH"]; + + if (_firedEH < 0 && {difficulty > 0}) then { + _firedEH = [ACE_player, "DefaultAction", {true}, { + private _canFire = (_this select 1) getVariable ["ace_missileguidance_target", nil]; + if (!isNil "_canFire") exitWith { false }; + true + }] call EFUNC(common,addActionEventHandler); + TRACE_1("Locking Fire Button",_firedEH); + + }; + _firedEH +}; +DFUNC(enableFire) = { + params ["_firedEH"]; + + if (_firedEH >= 0 && {difficulty > 0}) then { + TRACE_1("Unlocking Fire Button",_firedEH); + [ACE_player, "DefaultAction", _firedEH] call EFUNC(common,removeActionEventHandler); + }; + -1 +}; + +ADDON = true; diff --git a/addons/javelin/XEH_pre_init.sqf b/addons/javelin/XEH_pre_init.sqf deleted file mode 100644 index 27cbb54cfc..0000000000 --- a/addons/javelin/XEH_pre_init.sqf +++ /dev/null @@ -1,34 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -#include "XEH_PREP.hpp" - -GVAR(isLockKeyDown) = false; -GVAR(pfehID) = -1; - -DFUNC(disableFire) = { - params ["_firedEH"]; - - if(_firedEH < 0 && {difficulty > 0}) then { - _firedEH = [ACE_player, "DefaultAction", {true}, { - _canFire = (_this select 1) getVariable["ace_missileguidance_target", nil]; - if(!isNil "_canFire") exitWith { false }; - true - }] call EFUNC(common,addActionEventHandler); - TRACE_1("added",_firedEH); - - }; - _firedEH -}; -DFUNC(enableFire) = { - params ["_firedEH"]; - - if(_firedEH >= 0 && {difficulty > 0}) then { - TRACE_1("removing",_firedEH); - [ACE_player, "DefaultAction", _firedEH] call EFUNC(common,removeActionEventHandler); - }; - -1 -}; - -ADDON = true; diff --git a/addons/javelin/functions/fnc_cycleFireMode.sqf b/addons/javelin/functions/fnc_cycleFireMode.sqf deleted file mode 100644 index 50609b3468..0000000000 --- a/addons/javelin/functions/fnc_cycleFireMode.sqf +++ /dev/null @@ -1,13 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -TRACE_1("enter", _this); - -private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; -private _currentFireMode = _currentShooter getVariable["ace_missileguidance_attackProfile", "JAV_TOP"]; - -if(_currentFireMode == "JAV_DIR") then { - _currentFireMode = "JAV_TOP"; -} else { - _currentFireMode = "JAV_DIR"; -}; -_currentShooter setVariable["ace_missileguidance_attackProfile", _currentFireMode, false]; diff --git a/addons/javelin/functions/fnc_getTarget.sqf b/addons/javelin/functions/fnc_getTarget.sqf new file mode 100644 index 0000000000..7230aae64a --- /dev/null +++ b/addons/javelin/functions/fnc_getTarget.sqf @@ -0,0 +1,80 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Find a target within the optic range + * + * Arguments: + * 0: Last Target (seeds the scan) + * 1: Max Range (meters) + * + * Return Value: + * Target + * + * Example: + * [bob, 5] call ace_javelin_fnc_getTarget + * + * Public: No + */ + +params ["_lastTarget", "_maxRange"]; + +scopeName "main"; + +private _viewASL = AGLtoASL positionCameraToWorld [0,0,0]; +private _viewDir = _viewASL vectorFromTo (AGLtoASL positionCameraToWorld [0,0,1]); + +// Attempt to lock onto current target if it is still valid +if (!isNull _lastTarget) then { + private _aimASL = aimPos _lastTarget; + + if ((_viewASL vectorDistance _aimASL) > _maxRange) exitWith {}; + if ((acos ((_viewASL vectorFromTo _aimASL) vectorDotProduct _viewDir)) > 0.6) exitWith {}; + + private _relAngle = (_lastTarget getRelDir _viewASL); + + for "_xOffset" from -2.5 to 2.5 step 0.5 do { + for "_yOffset" from -2 to 1 step 0.5 do { + // Find test points in the model based on the angle that we are viewing it from (not true 3d projection, but not bad) + private _testPosASL = AGLtoASL (_lastTarget modelToWorld [_xOffset * - cos _relAngle, _xOffset * sin _relAngle, _yOffset]); + private _intersectionsToCursorTarget = lineIntersectsSurfaces [_viewASL, _testPosASL, ace_player, vehicle ace_player, true, 1]; + // drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [[0,1,1,1], [1,0,1,1]] select (count _intersectionsToCursorTarget), (ASLtoAGL _testPosASL), 0.25, 0.25, 0, "", 0.5, 0.025, "TahomaB"]; + if (!(_intersectionsToCursorTarget isEqualTo [])) then { + (_intersectionsToCursorTarget select 0) params ["", "", "_intersectedObject"]; + if (_intersectedObject isKindOf "AllVehicles") then { + _intersectedObject breakOut "main"; + }; + }; + }; + }; +}; + +// Try cursorObject/Target as they are very fast +if ((cursorObject isKindOf "AllVehicles") && {(cursorObject distance ace_player) < _maxRange}) then { + private _intersectionsToCursorTarget = lineIntersectsSurfaces [_viewASL, aimPos cursorObject, ace_player, cursorObject, true, 1]; + if (_intersectionsToCursorTarget isEqualTo []) then { + cursorObject breakOut "main"; + }; +}; +if ((cursorTarget isKindOf "AllVehicles") && {(cursorObject distance ace_player) < _maxRange}) then { + private _intersectionsToCursorTarget = lineIntersectsSurfaces [_viewASL, aimPos cursorTarget, ace_player, cursorTarget, true, 1]; + if (_intersectionsToCursorTarget isEqualTo []) then { + cursorTarget breakOut "main"; + }; +}; + +// Attempt to scan using multiple rayscasts - This is expensive (n^2) and care should be given to balance accuracy vs speed +for "_xOffset" from -14 to 14 step 2 do { + for "_yOffset" from -12 to 12 step 4 do { + private _testPosASL = AGLtoASL (positionCameraToWorld [_xOffset, _yOffset, _maxRange]); + private _intersectionsToCursorTarget = lineIntersectsSurfaces [_viewASL, _testPosASL, ace_player, vehicle ace_player, true, 1]; + // drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [[0,1,0,1], [1,0,0,1]] select (count _intersectionsToCursorTarget), (ASLtoAGL _testPosASL), 0.25, 0.25, 0, "", 0.5, 0.025, "TahomaB"]; + if (!(_intersectionsToCursorTarget isEqualTo [])) then { + (_intersectionsToCursorTarget select 0) params ["", "", "_intersectedObject"]; + if (_intersectedObject isKindOf "AllVehicles") then { + _intersectedObject breakOut "main"; + }; + }; + }; +}; + +objNull diff --git a/addons/javelin/functions/fnc_lockKeyDown.sqf b/addons/javelin/functions/fnc_lockKeyDown.sqf deleted file mode 100644 index 3eabbd9c28..0000000000 --- a/addons/javelin/functions/fnc_lockKeyDown.sqf +++ /dev/null @@ -1,3 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -TRACE_1("enter", _this); \ No newline at end of file diff --git a/addons/javelin/functions/fnc_lockKeyUp.sqf b/addons/javelin/functions/fnc_lockKeyUp.sqf deleted file mode 100644 index 3eabbd9c28..0000000000 --- a/addons/javelin/functions/fnc_lockKeyUp.sqf +++ /dev/null @@ -1,3 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -TRACE_1("enter", _this); \ No newline at end of file diff --git a/addons/javelin/functions/fnc_mapHelperDraw.sqf b/addons/javelin/functions/fnc_mapHelperDraw.sqf new file mode 100644 index 0000000000..1b81fc7dd5 --- /dev/null +++ b/addons/javelin/functions/fnc_mapHelperDraw.sqf @@ -0,0 +1,51 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Handles the map helper's draw event + * Resets arguments if not run recently + * And starts a watchdog to detect when weapon display unloaded + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_javelin_fnc_mapHelperDraw + * + * Public: No + */ + +if (isNil QGVAR(arguments)) then { + TRACE_1("Starting optic draw", _this); + + // reset shooter var: + private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; + _currentShooter setVariable ["ace_missileguidance_target", nil, false]; + + GVAR(arguments) = [ + diag_frameno, // Last run frame + objNull, // currentTargetObject + 0, // Lock Start Time + 0, // Next Sound timer + -1, // _fireDisabledEH + 0 // _nextTargetScan + ]; + + // Start up a watchdog for when the display is no longer shown (but might not be unloaded or null) + [{ + if (isNull (uiNamespace getVariable ["ACE_RscOptics_javelin", displayNull])) exitWith {true}; + GVAR(arguments) params ["_lastRunFrame"]; + (diag_frameno < _lastRunFrame) || {diag_frameno > (_lastRunFrame + 1)} + }, { + TRACE_1("old/null display - ending optic draw",_this); + private _fireDisabledEH = GVAR(arguments) param [4, -1]; + [_fireDisabledEH] call FUNC(enableFire); + GVAR(arguments) = nil; + }, []] call CBA_fnc_waitUntilAndExecute; +}; + +BEGIN_COUNTER(onOpticDraw); +GVAR(arguments) call FUNC(onOpticDraw); +END_COUNTER(onOpticDraw); diff --git a/addons/javelin/functions/fnc_onFired.sqf b/addons/javelin/functions/fnc_onFired.sqf deleted file mode 100644 index 220ddc37f0..0000000000 --- a/addons/javelin/functions/fnc_onFired.sqf +++ /dev/null @@ -1,15 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" - -PARAMS_2(_shooter,_weapon); - -// Bail on not missile or javelin PFEH not running -if ((_shooter != ACE_player) || {(GVAR(pfehID) == -1)}) exitWith { false }; - -private _configs = configProperties [configFile >> "CfgWeapons" >> _weapon, QUOTE(configName _x == QUOTE(QGVAR(enabled))), false]; -if (((count _configs) < 1) || {(getNumber (_configs select 0)) != 1}) exitWith {}; - -__JavelinIGUITargeting ctrlShow false; -__JavelinIGUITargetingGate ctrlShow false; -__JavelinIGUITargetingLines ctrlShow false; -__JavelinIGUITargetingConstraints ctrlShow false; diff --git a/addons/javelin/functions/fnc_onOpticDraw.sqf b/addons/javelin/functions/fnc_onOpticDraw.sqf index dede3ae69c..ab47556d4c 100644 --- a/addons/javelin/functions/fnc_onOpticDraw.sqf +++ b/addons/javelin/functions/fnc_onOpticDraw.sqf @@ -1,69 +1,66 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" -TRACE_1("enter", _this); +/* + * Author: jaynus, PabstMirror + * Main loop, handles scaning for targets and drawing the javelin optic + * + * Arguments: + * 0: Last run frame + * 0: Current target (what we locked last run) + * 0: Lock start time (cba mission time) + * 0: Next sound play time (ticktime) + * 0: Next target scan (ticktime) + * + * Return Value: + * None + * + * Example: + * [] call ace_javelin_fnc_mapHelperDraw + * + * Public: No + */ -#define __TRACKINTERVAL 0 // how frequent the check should be. -#define __LOCKONTIME 3 // Lock on won't occur sooner +// TRACE_1("onOpticDraw",diag_frameno); -private ["_apos", "_aposX", "_aposY", "_args", "_boundsInput", "_bpos", "_canFire", "_constraintBottom"]; -private ["_constraintLeft", "_constraintRight", "_constraintTop", "_currentTarget", "_fireDisabledEH"]; -private ["_firedEH", "_fov", "_lastTick", "_lockTime", "_maxX", "_maxY", "_minX", "_minY", "_newTarget"]; -private ["_offsetX", "_offsetY", "_pos", "_randomLockInterval", "_randomPosWithinBounds", "_range"]; -private ["_runTime", "_soundTime", "_targetArray", "_zamerny", "_currentShooter"]; - -_currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; - -#define __OffsetX ((ctrlPosition __JavelinIGUITargetingLineV) select 0) - 0.5 -#define __OffsetY ((ctrlPosition __JavelinIGUITargetingLineH) select 1) - 0.5 - -// Reset arguments if we havnt rendered in over a second -_args = uiNamespace getVariable[QGVAR(arguments), [] ]; -if( (count _args) > 0) then { - _lastTick = _args select 0; - if(diag_tickTime - _lastTick > 1) then { - [] call FUNC(onOpticLoad); - }; -}; - -TRACE_1("Running", "Running"); +#define __TRACKINTERVAL 0 // how frequent the ui update should be. +#define __SCANNTERVAL 0.05 // how frequent the target scan check should be. +#define __LOCKONTIME 3 // Lock on won't occur sooner // Pull the arguments -_currentTarget = _args select 1; -_runTime = _args select 2; -_lockTime = _args select 3; -_soundTime = _args select 4; -_randomLockInterval = _args select 5; -_fireDisabledEH = _args select 6; +params ["_lastRunFrame", "_currentTarget", "_lockStartTime", "_soundNextPlayTime", "_fireDisabledEH", "_nextTargetScan"]; -private ["_ammo", "_magazineConfig", "_weaponConfig"]; -_weaponConfig = configProperties [configFile >> "CfgWeapons" >> (currentWeapon _currentShooter), QUOTE(configName _x == QUOTE(QGVAR(enabled))), false]; -_magazineConfig = if ((currentMagazine _currentShooter) != "") then { - _ammo = getText (configFile >> "CfgMagazines" >> (currentMagazine _currentShooter) >> "ammo"); - configProperties [(configFile >> "CfgAmmo" >> _ammo), "(configName _x) == 'ace_missileguidance'", false]; +// Get shooter info +private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; +private _currentWeapon = currentWeapon _currentShooter; +private _currentMagazine = currentMagazine _currentShooter; + +// Get weapon / ammo configs +private _ammoCount = _currentShooter ammo _currentWeapon; +private _weaponConfig = configProperties [configFile >> "CfgWeapons" >> _currentWeapon, QUOTE(configName _x == QUOTE(QGVAR(enabled))), false]; +private _ammoConfig = if (_currentMagazine != "") then { + private _ammoType = getText (configFile >> "CfgMagazines" >> _currentMagazine >> "ammo"); + configProperties [(configFile >> "CfgAmmo" >> _ammoType), "(configName _x) == 'ace_missileguidance'", false]; } else { [] }; -//If weapon does not have "javelin enabled", then exit PFEH -if (((count _weaponConfig) < 1) || {(getNumber (_weaponConfig select 0)) != 1}) exitWith { +// Check if loaded and javelin enabled for wepaon and missile guidance enabled for loaded ammo +if ((_ammoCount == 0) || // No ammo loaded + {(count _weaponConfig) < 1} || {(getNumber (_weaponConfig select 0)) != 1} || // Not enabled for weapon + {(count _ammoConfig) < 1} || {(getNumber ((_ammoConfig select 0) >> "enabled")) != 1} // Not enabled for ammo + ) exitWith { + __JavelinIGUITargeting ctrlShow false; - __JavelinIGUITargetingGate ctrlShow false; - __JavelinIGUITargetingLines ctrlShow false; - __JavelinIGUITargetingConstraints ctrlShow false; + __JavelinIGUISeek ctrlSetTextColor __ColorGray; - if(!isNil "_fireDisabledEH") then { - _fireDisabledEH = [_fireDisabledEH] call FUNC(enableFire); - }; - - [(_this select 1)] call CBA_fnc_removePerFrameHandler; - GVAR(pfehID) = -1; + _fireDisabledEH = [_fireDisabledEH] call FUNC(enableFire); + _this set [0, diag_frameno]; + _this set [4, _fireDisabledEH]; }; -// Find a target within the optic range -_newTarget = objNull; -// Bail on fast movement -if ((velocity ACE_player) distance [0,0,0] > 0.5 && {cameraView == "GUNNER"} && {cameraOn == ACE_player}) exitWith { // keep it steady. +// Bail on fast movement (keep it steady) +if ((velocity ACE_player) distance [0,0,0] > 0.75 && {cameraView == "GUNNER"} && {cameraOn == ACE_player}) exitWith { + TRACE_1("exiting gunner because movement",velocity ACE_player); ACE_player switchCamera "INTERNAL"; if (player != ACE_player) then { TRACE_2("Zeus, manually reseting RC after switchCamera",player,ACE_player); @@ -71,222 +68,122 @@ if ((velocity ACE_player) distance [0,0,0] > 0.5 && {cameraView == "GUNNER"} && }; }; -// Refresh the firemode +// Refresh the firemode (top/dir) [] call FUNC(showFireMode); -_ammo = _currentShooter ammo (currentWeapon _currentShooter); -// not loaded or not "javelin enabled" for magazine, hide targeting and enable firing -if ((_ammo == 0) || {(count _magazineConfig) < 1} || {(getNumber ((_magazineConfig select 0) >> "enabled")) != 1}) exitWith { +// Get UI constants +private _offsetX = 0.5 * safeZoneW - safeZoneX - 0.5; +private _offsetY = 0.5 * safeZoneH - safeZoneY - 0.5; + +private _newTarget = objNull; +if (GVAR(isLockKeyDown) && {cameraView == "GUNNER"} && {(currentVisionMode ACE_player) == 2}) then { + // Attempting to lock; getTarget can be expensive so it's rate is limited + if (diag_tickTime > _nextTargetScan) then { + BEGIN_COUNTER(getTarget); + _newTarget = [_currentTarget, 2500, 0.6] call FUNC(getTarget); + END_COUNTER(getTarget); + _nextTargetScan = diag_tickTime + __SCANNTERVAL; + } else { + _newTarget = _currentTarget; + }; + + // Show gate box + private _boundsInput = if (_currentTarget isKindOf "CAManBase") then { + [_currentTarget,[-0.5,-0.5,-0.25],[0,0,0]]; + } else { + [_currentTarget,[-1,-1,-1],_currentTarget selectionPosition "zamerny"]; + }; + + private _bpos = _boundsInput call EFUNC(common,worldToScreenBounds); + + private _lockTime = if (isNull _currentTarget) then {0} else {CBA_missionTime - _lockStartTime}; + private _minX = ((linearConversion [1, (__LOCKONTIME - 0.5), _lockTime, 0.5 - 0.075*safeZoneW, (_bpos select 0), true]) + _offsetX) max __ConstraintLeft; + private _minY = ((linearConversion [1, (__LOCKONTIME - 0.5), _lockTime, 0.5 - 0.075*safeZoneH, (_bpos select 1), true]) + _offsetY) max __ConstraintTop; + private _maxX = (((linearConversion [1, (__LOCKONTIME - 0.5), _lockTime, 0.5 + 0.075*safeZoneW, (_bpos select 2), true]) + _offsetX) min __ConstraintRight) - (0.025 * (3 / 4) * safeZoneH); + private _maxY = (((linearConversion [1, (__LOCKONTIME - 0.5), _lockTime, 0.5 + 0.075*safeZoneH, (_bpos select 3), true]) + _offsetY) min __ConstraintBottom) - (0.025 * safeZoneH); + + // TRACE_3("",_boundsInput,_bpos,_lockTime); + // TRACE_4("",_minX,_maxX,_minY,_maxY); + + __JavelinIGUITargetingGateTL ctrlSetPosition [_minX, _minY]; + __JavelinIGUITargetingGateTR ctrlSetPosition [_maxX, _minY]; + __JavelinIGUITargetingGateBL ctrlSetPosition [_minX, _maxY]; + __JavelinIGUITargetingGateBR ctrlSetPosition [_maxX, _maxY]; + {_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingGateTL, __JavelinIGUITargetingGateTR, __JavelinIGUITargetingGateBL, __JavelinIGUITargetingGateBR]; + + __JavelinIGUITargeting ctrlShow true; + __JavelinIGUITargetingGate ctrlShow true; +} else { + // Not trying to lock __JavelinIGUITargeting ctrlShow false; __JavelinIGUITargetingGate ctrlShow false; __JavelinIGUITargetingLines ctrlShow false; - __JavelinIGUITargetingConstraints ctrlShow false; - - if(!isNil "_fireDisabledEH") then { - _fireDisabledEH = [_fireDisabledEH] call FUNC(enableFire); - }; -}; - -_range = parseNumber (ctrlText __JavelinIGUIRangefinder); -TRACE_1("Viewing range", _range); -if (_range > 50 && {_range < 2500}) then { - _pos = positionCameraToWorld [0,0,_range]; - _targetArray = _pos nearEntities ["AllVehicles", _range/100]; - TRACE_1("Searching at range", _targetArray); - if (count (_targetArray) > 0) then { - _newTarget = _targetArray select 0; - }; -}; - -if ((isNull _newTarget) && {cursorObject isKindOf "AllVehicles"}) then { - private _intersectionsToCursorTarget = lineIntersectsSurfaces [(AGLtoASL positionCameraToWorld [0,0,0]), aimPos cursorObject, ace_player, cursorObject, true, 1]; - if (_intersectionsToCursorTarget isEqualTo []) then { - _newTarget = cursorObject; - }; -}; -if ((isNull _newTarget) && {cursorTarget isKindOf "AllVehicles"}) then { - private _intersectionsToCursorTarget = lineIntersectsSurfaces [(AGLtoASL positionCameraToWorld [0,0,0]), aimPos cursorTarget, ace_player, cursorTarget, true, 1]; - if (_intersectionsToCursorTarget isEqualTo []) then { - _newTarget = cursorTarget; - }; -}; - -// Create constants -_constraintTop = __ConstraintTop; -_constraintLeft = __ConstraintLeft; -_constraintBottom = __ConstraintBottom; -_constraintRight = __ConstraintRight; - -_offsetX = __OffsetX; -_offsetY = __OffsetY; - -__JavelinIGUITargeting ctrlShow true; -__JavelinIGUITargetingConstrains ctrlShow true; - -_zamerny = _currentTarget selectionPosition (["zamerny", "body"] select (_currentTarget isKindOf "CAManBase")); -_randomPosWithinBounds = [(_zamerny select 0) + 1 - (random 2.0),(_zamerny select 1) + 1 - (random 2.0),(_zamerny select 2) + 0.5 - (random 1.0)]; - -_apos = worldToScreen (_currentTarget modelToWorld _randomPosWithinBounds); - -_aposX = 0; -_aposY = 0; -if (count _apos < 2) then { - _aposX = 1; - _aposY = 0; -} else { - _aposX = (_apos select 0) + _offsetX; - _aposY = (_apos select 1) + _offsetY; -}; - -if((call CBA_fnc_getFoV) select 1 > 9) then { - __JavelinIGUINFOV ctrlSetTextColor __ColorGreen; - __JavelinIGUIWFOV ctrlSetTextColor __ColorGray; -} else { - __JavelinIGUINFOV ctrlSetTextColor __ColorGray; - __JavelinIGUIWFOV ctrlSetTextColor __ColorGreen; }; if (isNull _newTarget) then { - // No targets found + // No target found _currentTarget = objNull; - _lockTime = 0; - + _lockStartTime = 0; __JavelinIGUISeek ctrlSetTextColor __ColorGray; - __JavelinIGUITargeting ctrlShow false; - __JavelinIGUITargetingGate ctrlShow false; + _currentShooter setVariable ["ace_missileguidance_target", nil, false]; + __JavelinIGUITargetingLines ctrlShow false; - __JavelinIGUITargetingConstraints ctrlShow false; - - _currentShooter setVariable ["ace_missileguidance_target",nil, false]; - + // Disallow fire _fireDisabledEH = [_fireDisabledEH] call FUNC(disableFire); } else { - _fov = [] call CBA_fnc_getFoV; - TRACE_1("FOV", _fov); - if (_newTarget distance ACE_player < 2500 - && {(call CBA_fnc_getFoV) select 1 > 9} - && { (currentVisionMode ACE_player == 2)} - && GVAR(isLockKeyDown) - ) then { - // Lock on after 3 seconds - if(_currentTarget != _newTarget) then { - TRACE_1("New Target, reseting locking", _newTarget); - _lockTime = diag_tickTime; - _currentTarget = _newTarget; + if ((!isNull _newTarget) && {_currentTarget != _newTarget}) then { + TRACE_1("New Target, reseting locking", _newTarget); + _lockStartTime = CBA_missionTime; + _currentTarget = _newTarget; + }; - playSound "ACE_Javelin_Locking"; - } else { - if(diag_tickTime - _lockTime > __LOCKONTIME + _randomLockInterval) then { - TRACE_2("LOCKED!", _currentTarget, _lockTime); + if ((CBA_missionTime - _lockStartTime) > __LOCKONTIME) then { // Lock on after 3 seconds + TRACE_2("LOCKED!", _currentTarget, _lockStartTime); + __JavelinIGUISeek ctrlSetTextColor __ColorGreen; + __JavelinIGUITargetingLines ctrlShow true; - __JavelinIGUISeek ctrlSetTextColor __ColorGreen; + // Move target marker (the crosshair) to aimpoint on the target + private _aimPointOnTarget = _currentTarget selectionPosition (["zamerny", "body"] select (_currentTarget isKindOf "CAManBase")); + (worldToScreen (_currentTarget modelToWorld _aimPointOnTarget)) params [["_aposX", 0.5], ["_aposY", 0.5]]; + private _ctrlPos = ctrlPosition __JavelinIGUITargetingLineV; + _ctrlPos set [0, _aposX + _offsetX]; + __JavelinIGUITargetingLineV ctrlSetPosition _ctrlPos; + __JavelinIGUITargetingLineV ctrlCommit __TRACKINTERVAL; + _ctrlPos = ctrlPosition __JavelinIGUITargetingLineH; + _ctrlPos set [1, _aposY + _offsetY]; + __JavelinIGUITargetingLineH ctrlSetPosition _ctrlPos; + __JavelinIGUITargetingLineH ctrlCommit __TRACKINTERVAL; - __JavelinIGUITargeting ctrlShow true; - __JavelinIGUITargetingConstrains ctrlShow false; - __JavelinIGUITargetingGate ctrlShow true; - __JavelinIGUITargetingLines ctrlShow true; + _currentShooter setVariable ["ace_missileguidance_target", _currentTarget, false]; - // Move target marker to coords. - //__JavelinIGUITargetingLineV ctrlSetPosition [_aposX,ctrlPosition __JavelinIGUITargetingLineV select 1]; - //__JavelinIGUITargetingLineH ctrlSetPosition [ctrlPosition __JavelinIGUITargetingLineH select 0,_aposY]; - //{_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingLineH,__JavelinIGUITargetingLineV]; + // Allow fire + _fireDisabledEH = [_fireDisabledEH] call FUNC(enableFire); - _boundsInput = if (_currentTarget isKindOf "CAManBase") then { - [_currentTarget,[-1,-1,-2],_currentTarget selectionPosition "body"]; - } else { - [_currentTarget,[-1,-1,-2],_currentTarget selectionPosition "zamerny"]; - }; - - _bpos = _boundsInput call EFUNC(common,worldToScreenBounds); - - _minX = ((_bpos select 0) + _offsetX) max _constraintLeft; - _minY = ((_bpos select 1) + _offsetY) max _constraintTop; - _maxX = ((_bpos select 2) + _offsetX) min (_constraintRight - 0.025 * (3 / 4) * SafezoneH); - _maxY = ((_bpos select 3) + _offsetY) min (_constraintBottom - 0.025 * SafezoneH); - - TRACE_4("", _boundsInput, _bpos, _minX, _minY); - - __JavelinIGUITargetingGateTL ctrlSetPosition [_minX, _minY]; - __JavelinIGUITargetingGateTR ctrlSetPosition [_maxX, _minY]; - __JavelinIGUITargetingGateBL ctrlSetPosition [_minX, _maxY]; - __JavelinIGUITargetingGateBR ctrlSetPosition [_maxX, _maxY]; - - {_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingGateTL, __JavelinIGUITargetingGateTR, __JavelinIGUITargetingGateBL, __JavelinIGUITargetingGateBR]; - - _currentShooter setVariable["ace_missileguidance_target", _currentTarget, false]; - - // Allow fire - _fireDisabledEH = [_fireDisabledEH] call FUNC(enableFire); - - if(diag_tickTime > _soundTime) then { - playSound "ACE_Javelin_Locked"; - _soundTime = diag_tickTime + 0.25; - }; - } else { - __JavelinIGUITargeting ctrlShow true; - __JavelinIGUITargetingGate ctrlShow true; - __JavelinIGUITargetingConstrains ctrlShow true; - __JavelinIGUITargetingLines ctrlShow false; - - _currentShooter setVariable["ace_missileguidance_target", nil, false]; - - _boundsInput = if (_currentTarget isKindOf "CAManBase") then { - [_newTarget,[-1,-1,-2],_currentTarget selectionPosition "body"]; - } else { - [_newTarget,[-1,-1,-1],_currentTarget selectionPosition "zamerny"]; - }; - - _bpos = _boundsInput call EFUNC(common,worldToScreenBounds); - - _minX = ((_bpos select 0) + _offsetX) max _constraintLeft; - _minY = ((_bpos select 1) + _offsetY) max _constraintTop; - _maxX = ((_bpos select 2) + _offsetX) min (_constraintRight - 0.025 * (3 / 4) * SafezoneH); - _maxY = ((_bpos select 3) + _offsetY) min (_constraintBottom - 0.025 * SafezoneH); - - TRACE_4("", _boundsInput, _bpos, _minX, _minY); - - __JavelinIGUITargetingGateTL ctrlSetPosition [_minX,_minY]; - __JavelinIGUITargetingGateTR ctrlSetPosition [_maxX,_minY]; - __JavelinIGUITargetingGateBL ctrlSetPosition [_minX,_maxY]; - __JavelinIGUITargetingGateBR ctrlSetPosition [_maxX,_maxY]; - - {_x ctrlCommit __TRACKINTERVAL} forEach [__JavelinIGUITargetingGateTL,__JavelinIGUITargetingGateTR,__JavelinIGUITargetingGateBL,__JavelinIGUITargetingGateBR]; - - if(diag_tickTime > _soundTime) then { - playSound "ACE_Javelin_Locking"; - _soundTime = diag_tickTime + 0.25; - }; - // Disallow fire - _fireDisabledEH = [_fireDisabledEH] call FUNC(disableFire); - }; + if (diag_tickTime > _soundNextPlayTime) then { + playSound "ACE_Javelin_Locked"; + _soundNextPlayTime = diag_tickTime + 0.25; }; } else { - // No targets found - _currentTarget = objNull; - _lockTime = 0; - + // Lock in progress __JavelinIGUISeek ctrlSetTextColor __ColorGray; - __JavelinIGUITargeting ctrlShow false; - __JavelinIGUITargetingGate ctrlShow false; __JavelinIGUITargetingLines ctrlShow false; - __JavelinIGUITargetingConstraints ctrlShow false; _currentShooter setVariable ["ace_missileguidance_target", nil, false]; + if (diag_tickTime > _soundNextPlayTime) then { + playSound "ACE_Javelin_Locking"; + _soundNextPlayTime = diag_tickTime + 0.25; + }; // Disallow fire _fireDisabledEH = [_fireDisabledEH] call FUNC(disableFire); }; }; -//TRACE_2("", _newTarget, _currentTarget); - // Save arguments for next run -_args set[0, diag_tickTime]; -_args set[1, _currentTarget]; -_args set[2, _runTime]; -_args set[3, _lockTime]; -_args set[4, _soundTime]; -_args set[6, _fireDisabledEH]; - -uiNamespace setVariable[QGVAR(arguments), _args ]; +_this set [0, diag_frameno]; +_this set [1, _currentTarget]; +_this set [2, _lockStartTime]; +_this set [3, _soundNextPlayTime]; +_this set [4, _fireDisabledEH]; +_this set [5, _nextTargetScan]; diff --git a/addons/javelin/functions/fnc_onOpticLoad.sqf b/addons/javelin/functions/fnc_onOpticLoad.sqf deleted file mode 100644 index 5148ca983f..0000000000 --- a/addons/javelin/functions/fnc_onOpticLoad.sqf +++ /dev/null @@ -1,39 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -TRACE_1("enter", _this); - -#define __LOCKONTIMERANDOM 1 // Deviation in lock on time - -if((count _this) > 0) then { - uiNameSpace setVariable ['ACE_RscOptics_javelin',_this select 0]; -}; - -private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; -TRACE_2("shooter",_currentShooter,typeOf _currentShooter); -_currentShooter setVariable ["ace_missileguidance_target", nil, false]; - -__JavelinIGUISeek ctrlSetTextColor __ColorGray; -__JavelinIGUINFOV ctrlSetTextColor __ColorGray; - -__JavelinIGUITargeting ctrlShow false; -__JavelinIGUITargetingConstrains ctrlShow false; -__JavelinIGUITargetingGate ctrlShow false; -__JavelinIGUITargetingLines ctrlShow false; - -if(GVAR(pfehID) != -1) then { - [] call FUNC(onOpticUnload); // Unload optic if it was already loaded -}; - -uiNameSpace setVariable [QGVAR(arguments), - [ - diag_tickTime, // Last runtime - objNull, // currentTargetObject - 0, // Run Time - 0, // Lock Time - 0, // Sound timer - (random __LOCKONTIMERANDOM), // random lock time addition - -1 - ] -]; - -GVAR(pfehID) = [FUNC(onOpticDraw), 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/javelin/functions/fnc_onOpticUnload.sqf b/addons/javelin/functions/fnc_onOpticUnload.sqf deleted file mode 100644 index 221fe3b5f6..0000000000 --- a/addons/javelin/functions/fnc_onOpticUnload.sqf +++ /dev/null @@ -1,20 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -TRACE_1("enter", _this); -private ["_args", "_disableFireEH"]; - -// uiNameSpace setVariable ['ACE_RscOptics_javelin',nil]; - -if(GVAR(pfehID) != -1) then { - [GVAR(pfehID)] call CBA_fnc_removePerFrameHandler; - GVAR(pfehID) = -1; -}; - -_args = uiNamespace getVariable[QGVAR(arguments), nil ]; -if(!isNil "_args") then { - _disableFireEH = _args select 6; - if(_disableFireEH > 0 && difficulty > 0) then { - [ACE_player, "DefaultAction", _disableFireEH] call EFUNC(common,removeActionEventHandler); - }; - uiNameSpace setVariable [QGVAR(arguments),nil]; -}; diff --git a/addons/javelin/functions/fnc_showFireMode.sqf b/addons/javelin/functions/fnc_showFireMode.sqf index 95dd038b92..e7a8f80ade 100644 --- a/addons/javelin/functions/fnc_showFireMode.sqf +++ b/addons/javelin/functions/fnc_showFireMode.sqf @@ -1,11 +1,26 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" -TRACE_1("enter", _this); +/* + * Author: jaynus + * Updates fire mode on javelin display (top/dir) + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_javelin_fnc_showFireMode + * + * Public: No + */ private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; private _currentFireMode = _currentShooter getVariable ["ace_missileguidance_attackProfile", "JAV_TOP"]; -if(_currentFireMode == "JAV_TOP") then { +TRACE_1("showFireMode", _currentFireMode); + +if (_currentFireMode == "JAV_TOP") then { __JavelinIGUITop ctrlSetTextColor __ColorGreen; __JavelinIGUIDir ctrlSetTextColor __ColorGray; } else { diff --git a/addons/javelin/initKeybinds.sqf b/addons/javelin/initKeybinds.sqf index cbfafa326d..7652f2fd57 100644 --- a/addons/javelin/initKeybinds.sqf +++ b/addons/javelin/initKeybinds.sqf @@ -5,26 +5,16 @@ if (GETGVAR(isLockKeyDown,false)) exitWith {false}; GVAR(isLockKeyDown) = true; + TRACE_1("lock key down",GVAR(isLockKeyDown)); - // Statement - [ACE_player] call FUNC(lockKeyDown); // Return false so it doesn't block the rest weapon action false }, { // prevent holding down GVAR(isLockKeyDown) = false; + TRACE_1("lock key up",GVAR(isLockKeyDown)); - // Statement - [ACE_player] call FUNC(lockKeyUp); false }, [15, [false, false, false]], false] call CBA_fnc_addKeybind; //Tab Key - -["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), -{ false }, -{ - [ACE_player] call FUNC(cycleFireMode); - false -}, -[15, [false, true, false]], false] call CBA_fnc_addKeybind; //Ctrl+Tab Key \ No newline at end of file diff --git a/addons/javelin/script_component.hpp b/addons/javelin/script_component.hpp index 11bb4a5a33..b78032439d 100644 --- a/addons/javelin/script_component.hpp +++ b/addons/javelin/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_JAVELIN @@ -17,9 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ACE_JAV_FIREMODE_DIR 1 -#define ACE_JAV_FIREMODE_TOP 2 - // Javelin IGUI defines #define __JavelinIGUI (uinamespace getVariable "ACE_RscOptics_javelin") @@ -30,8 +26,6 @@ #define __JavelinIGUISeek (__JavelinIGUI displayCtrl 699000) #define __JavelinIGUITop (__JavelinIGUI displayCtrl 699001) #define __JavelinIGUIDir (__JavelinIGUI displayCtrl 699002) -#define __JavelinIGUINFOV (__JavelinIGUI displayCtrl 1003) -#define __JavelinIGUIWFOV (__JavelinIGUI displayCtrl 1004) #define __JavelinIGUIRangefinder (__JavelinIGUI displayCtrl 151) // Constrains diff --git a/addons/javelin/stringtable.xml b/addons/javelin/stringtable.xml index dcc03dca91..96dc8d33ee 100644 --- a/addons/javelin/stringtable.xml +++ b/addons/javelin/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -9,21 +9,13 @@ Namierz cel (przytrzymaj) Verrouiller la cible (maintenir) Célpontra állás (Lenyomva tartott) - Aggangia il bersagio + Aggangia il bersaglio Fijar objetivo (Mantener) Travar Alvo(Segurar) - - - Cycle Fire Mode - Wechsle Feuermodus - Переключение режимов огня - Přepínání režimů palby - Przełącz tryb ognia - Cycle mode de tir - Tüzelési mód váltása - Alterna le modalità di fuoco - Cambiar modo de disparo - Alterar Modo de Disparo + 目標を捕捉 (押しっぱ) + 표적 획득 (누르기) + 锁定目标 (按住) + 鎖定目標 (按住) diff --git a/addons/kestrel4500/CfgVehicles.hpp b/addons/kestrel4500/CfgVehicles.hpp index ccc4fa3bd2..9cdd077066 100644 --- a/addons/kestrel4500/CfgVehicles.hpp +++ b/addons/kestrel4500/CfgVehicles.hpp @@ -8,7 +8,6 @@ class CfgVehicles { condition = QUOTE(call FUNC(canShow) && !GVAR(Kestrel4500)); statement = QUOTE(call FUNC(createKestrelDialog)); showDisabled = 0; - priority = 0.1; icon = QPATHTOF(UI\Kestrel4500_Icon.paa); exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; class GVAR(show) { @@ -16,7 +15,6 @@ class CfgVehicles { condition = QUOTE(call FUNC(canShow) && !GVAR(Overlay)); statement = QUOTE(call FUNC(displayKestrel)); showDisabled = 0; - priority = 0.2; icon = QPATHTOF(UI\Kestrel4500_Icon.paa); exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; }; @@ -25,7 +23,6 @@ class CfgVehicles { condition = QUOTE(GVAR(Overlay)); statement = QUOTE(call FUNC(displayKestrel)); showDisabled = 0; - priority = 0.3; icon = QPATHTOF(UI\Kestrel4500_Icon.paa); exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; }; 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/XEH_preInit.sqf b/addons/kestrel4500/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/kestrel4500/XEH_preInit.sqf +++ b/addons/kestrel4500/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/kestrel4500/functions/fnc_buttonPressed.sqf b/addons/kestrel4500/functions/fnc_buttonPressed.sqf index 788b7d72e0..2edd9d17b8 100644 --- a/addons/kestrel4500/functions/fnc_buttonPressed.sqf +++ b/addons/kestrel4500/functions/fnc_buttonPressed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Handles the Kestrel 4500 dialog button actions @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" switch (_this) do { case 0: { // Enter diff --git a/addons/kestrel4500/functions/fnc_canShow.sqf b/addons/kestrel4500/functions/fnc_canShow.sqf index f563138f5c..d577cfd4d1 100644 --- a/addons/kestrel4500/functions/fnc_canShow.sqf +++ b/addons/kestrel4500/functions/fnc_canShow.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Tests if the Kestrel 4500 can be shown @@ -13,6 +14,5 @@ * * Public: No */ -#include "script_component.hpp" ("ACE_Kestrel4500" in (uniformItems ACE_player)) || ("ACE_Kestrel4500" in (vestItems ACE_player)) diff --git a/addons/kestrel4500/functions/fnc_collectData.sqf b/addons/kestrel4500/functions/fnc_collectData.sqf index 2e25fbcf60..a05aac2667 100644 --- a/addons/kestrel4500/functions/fnc_collectData.sqf +++ b/addons/kestrel4500/functions/fnc_collectData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Gathers the weather data for the Kestrel 4500 @@ -13,21 +14,19 @@ * * Public: No */ -#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_createKestrelDialog.sqf b/addons/kestrel4500/functions/fnc_createKestrelDialog.sqf index a11982968c..445c6cc789 100644 --- a/addons/kestrel4500/functions/fnc_createKestrelDialog.sqf +++ b/addons/kestrel4500/functions/fnc_createKestrelDialog.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Opens the Kestrel 4500 dialog @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (GVAR(Kestrel4500)) exitWith { false }; if (underwater ACE_player) exitWith { false }; diff --git a/addons/kestrel4500/functions/fnc_dayOfWeek.sqf b/addons/kestrel4500/functions/fnc_dayOfWeek.sqf index 356b10da63..932f0a72aa 100644 --- a/addons/kestrel4500/functions/fnc_dayOfWeek.sqf +++ b/addons/kestrel4500/functions/fnc_dayOfWeek.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculate Current Day in the Week @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_year", "_month", "_day"]; private _table = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]; diff --git a/addons/kestrel4500/functions/fnc_displayKestrel.sqf b/addons/kestrel4500/functions/fnc_displayKestrel.sqf index 0cf3234d1e..c93de715ed 100644 --- a/addons/kestrel4500/functions/fnc_displayKestrel.sqf +++ b/addons/kestrel4500/functions/fnc_displayKestrel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows the Kestrel 4500 as rsc title @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define __dsp (uiNamespace getVariable "RscKestrel4500") #define __ctrlKestrel4500 (__dsp displayCtrl 75000) diff --git a/addons/kestrel4500/functions/fnc_generateOutputData.sqf b/addons/kestrel4500/functions/fnc_generateOutputData.sqf index c3bce5efa2..9a9d0551fe 100644 --- a/addons/kestrel4500/functions/fnc_generateOutputData.sqf +++ b/addons/kestrel4500/functions/fnc_generateOutputData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Generates the Kestrel 4500 output text. @@ -29,52 +30,49 @@ * * Public: No */ -#include "script_component.hpp" 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; @@ -107,7 +105,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { }; case 2: { // Wind SPD if (!GVAR(MinAvgMax)) then { - _textCenterBig = Str(round(abs(_windSpeed) * 10) / 10); + _textCenterBig = Str(round(_windSpeed * 10) / 10); } else { _textCenterLine1Left = "Max"; _textCenterLine2Left = "Avg"; @@ -134,16 +132,16 @@ if (GVAR(referenceHeadingMenu) == 0) then { if (!GVAR(MinAvgMax)) then { if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { _textCenterBig = Str(round(abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed) * 10) / 10); - _textInfoLine1 = format["%1 m/s @ %2", round((abs(cos(_playerDir - _windDir)) * _windSpeed) * 10) / 10, round(_playerDir)]; + _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 { _textCenterLine1Left = "Max"; _textCenterLine2Left = "Avg"; - switch (GVAR(MinAvgMax)Mode) do { + switch (GVAR(MinAvgMaxMode)) do { case 0: { _textCenterLine1Right = "--. -"; _textCenterLine2Right = "--. -"; @@ -166,16 +164,16 @@ if (GVAR(referenceHeadingMenu) == 0) then { if (!GVAR(MinAvgMax)) then { if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { _textCenterBig = Str(round(cos(GVAR(RefHeading) - _playerDir) * _windSpeed * 10) / 10); - _textInfoLine1 = format["%1 m/s @ %2", round((abs(cos(_playerDir - _windDir)) * _windSpeed) * 10) / 10, round(_playerDir)]; + _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 { _textCenterLine1Left = "Max"; _textCenterLine2Left = "Avg"; - switch (GVAR(MinAvgMax)Mode) do { + switch (GVAR(MinAvgMaxMode)) do { case 0: { _textCenterLine1Right = "--. -"; _textCenterLine2Right = "--. -"; diff --git a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf index 2a8a4bbbb3..5dcbf681d2 100644 --- a/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf +++ b/addons/kestrel4500/functions/fnc_measureWindSpeed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Measures the wind speed, stores the information in GVAR(MeasuredWindSpeed) and updates GVAR(ImpellerState) @@ -13,13 +14,10 @@ * * Public: No */ -#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/functions/fnc_onCloseDialog.sqf b/addons/kestrel4500/functions/fnc_onCloseDialog.sqf index f8531f0e39..8b8a88f46b 100644 --- a/addons/kestrel4500/functions/fnc_onCloseDialog.sqf +++ b/addons/kestrel4500/functions/fnc_onCloseDialog.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Called if Kestrel Dialog is closed @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" uiNamespace setVariable ['Kestrel4500_Display', nil]; GVAR(Kestrel4500) = false; diff --git a/addons/kestrel4500/functions/fnc_onCloseDisplay.sqf b/addons/kestrel4500/functions/fnc_onCloseDisplay.sqf index 549c22e275..09e5941a77 100644 --- a/addons/kestrel4500/functions/fnc_onCloseDisplay.sqf +++ b/addons/kestrel4500/functions/fnc_onCloseDisplay.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Called if Kestrel Display is closed @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" uiNamespace setVariable ['RscKestrel4500', nil]; GVAR(Overlay) = false; diff --git a/addons/kestrel4500/functions/fnc_restoreUserData.sqf b/addons/kestrel4500/functions/fnc_restoreUserData.sqf index c1d9c0ebb3..ca90f8bbcc 100644 --- a/addons/kestrel4500/functions/fnc_restoreUserData.sqf +++ b/addons/kestrel4500/functions/fnc_restoreUserData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Reads user data from profileNamespace @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" GVAR(Menu) = 0 max (profileNamespace getVariable ["ACE_Kestrel4500_menu", 0]) min ((count GVAR(Menus)) - 1); GVAR(RefHeading) = 0 max (profileNamespace getVariable ["ACE_Kestrel4500_RefHeading", 0]) min 359; diff --git a/addons/kestrel4500/functions/fnc_storeUserData.sqf b/addons/kestrel4500/functions/fnc_storeUserData.sqf index 80fa219a3c..71338984ff 100644 --- a/addons/kestrel4500/functions/fnc_storeUserData.sqf +++ b/addons/kestrel4500/functions/fnc_storeUserData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Saves user data into profileNamespace @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" profileNamespace setVariable ["ACE_Kestrel4500_menu", GVAR(menu)]; profileNamespace setVariable ["ACE_Kestrel4500_RefHeading", GVAR(RefHeading)]; diff --git a/addons/kestrel4500/functions/fnc_updateDisplay.sqf b/addons/kestrel4500/functions/fnc_updateDisplay.sqf index a307e9fcd1..94255115db 100644 --- a/addons/kestrel4500/functions/fnc_updateDisplay.sqf +++ b/addons/kestrel4500/functions/fnc_updateDisplay.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the Kestrel 4500 dialog text boxes. @@ -12,7 +13,6 @@ * * Public: No */ -#include "script_component.hpp" #define __dsp (uiNamespace getVariable "Kestrel4500_Display") #define __ctrlCenterLine3 (__dsp displayCtrl 74602) diff --git a/addons/kestrel4500/functions/fnc_updateImpellerState.sqf b/addons/kestrel4500/functions/fnc_updateImpellerState.sqf index a746a98835..5692f0d276 100644 --- a/addons/kestrel4500/functions/fnc_updateImpellerState.sqf +++ b/addons/kestrel4500/functions/fnc_updateImpellerState.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Updates the Kestrel 4500 Impeller state @@ -12,7 +13,6 @@ * * Public: No */ -#include "script_component.hpp" private _windSpeed = call FUNC(measureWindSpeed); diff --git a/addons/kestrel4500/functions/fnc_updateMemory.sqf b/addons/kestrel4500/functions/fnc_updateMemory.sqf index c393aee14f..2eff1c5a9a 100644 --- a/addons/kestrel4500/functions/fnc_updateMemory.sqf +++ b/addons/kestrel4500/functions/fnc_updateMemory.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Update Memory of Kestrel @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_slot", "_value"]; GVAR(MIN) set [_slot, (GVAR(MIN) select _slot) min _value]; GVAR(MAX) set [_slot, _value max (GVAR(MAX) select _slot)]; 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/script_component.hpp b/addons/kestrel4500/script_component.hpp index f098cd2a57..10a61a4d08 100644 --- a/addons/kestrel4500/script_component.hpp +++ b/addons/kestrel4500/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_KESTREL4500 diff --git a/addons/kestrel4500/stringtable.xml b/addons/kestrel4500/stringtable.xml index 88f0e90363..f83c875d57 100644 --- a/addons/kestrel4500/stringtable.xml +++ b/addons/kestrel4500/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Kestrel 4500NV Kestrel 4500NV Kestrel 4500NV + ケストレル 4500NV + Kestrel 4500NV + 猎隼4500测风仪 + 獵隼4500測風儀 Kestrel 4500 Pocket Weather Tracker @@ -24,6 +28,10 @@ Kestrel 4500 Medidor Balístico Ativo Kestrel 4500 kézi szél-és időjárásmérő Příruční meteostanice Kestrel 4500 + ケストレル 4500 携帯型風速計 + Kestrel 4500 휴대형 기상 관측기 + 猎隼4500掌上型天气追踪仪 + 獵隼4500掌上型天氣追蹤儀 Open Kestrel 4500 @@ -36,6 +44,10 @@ Kestrel 4500 öffnen Abrir Kestrel 4500 Otevřít Kestrel 4500 + Kestrel 4500 を開く + Kestrel 4500 열기 + 开启猎隼4500测风仪 + 開啟獵隼4500測風儀 Show Kestrel 4500 @@ -48,6 +60,10 @@ Kestrel 4500 mutatása Zobrazit Kestrel 4500 Mostrar Kestrel 4500 + ケストレル 4500 を見る + Kestrel 4500 보이기 + 显示猎隼4500测风仪 + 顯示獵隼4500測風儀 Hide Kestrel 4500 @@ -60,6 +76,10 @@ Kestrel 4500 elrejtése Skrýt Kestrel 4500 Ocultar Kestrel 4500 + Kestrel 4500 を隠す + Kestrel 4500 숨기기 + 隐藏猎隼4500测风仪 + 隱藏獵隼4500測風儀 Open Kestrel 4500 @@ -72,6 +92,10 @@ Kestrel 4500 elővétele Otevřít Kestrel 4500 Abrir Kestrel 4500 + ケストレル 4500 を開く + Kestrel 4500 열기 + 开启猎隼4500测风仪 + 開啟獵隼4500測風儀 Show Kestrel 4500 @@ -84,6 +108,10 @@ Kestrel 4500 mutatása Zobrazit Kestrel 4500 Mostrar Kestrel 4500 + ケストレル 4500 を見る + Kestrel 4500 숨기기 + 显示猎隼4500测风仪 + 顯示獵隼4500測風儀 - \ No newline at end of file + diff --git a/addons/laser/ACE_Settings.hpp b/addons/laser/ACE_Settings.hpp new file mode 100644 index 0000000000..3584a2086f --- /dev/null +++ b/addons/laser/ACE_Settings.hpp @@ -0,0 +1,8 @@ +class ACE_Settings { + class GVAR(dispersionCount) { + value = 2; + typeName = "SCALAR"; + displayName = CSTRING(dispersionCount_displayName); + sliderSettings[] = {0, 5, 2, -1}; + }; +}; diff --git a/addons/laser/CfgEventhandlers.hpp b/addons/laser/CfgEventhandlers.hpp index e8fb763b8b..0e652d2459 100644 --- a/addons/laser/CfgEventhandlers.hpp +++ b/addons/laser/CfgEventhandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); @@ -7,20 +6,13 @@ class Extended_PreStart_EventHandlers { class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_pre_init)); + init = QUOTE(call COMPILE_FILE(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_post_init)); + init = QUOTE(call COMPILE_FILE(XEH_postInit)); }; }; -class Extended_Init_EventHandlers { - class LaserTargetBase { - class ADDON { - init = QUOTE(_this call DFUNC(laser_init)); - }; - }; -}; diff --git a/addons/laser/CfgVehicles.hpp b/addons/laser/CfgVehicles.hpp index ed752cee42..4b36a8261d 100644 --- a/addons/laser/CfgVehicles.hpp +++ b/addons/laser/CfgVehicles.hpp @@ -1,44 +1,12 @@ class CfgVehicles { class All; - class LaserTarget: All { // @TODO: Changing the model and simulation hides it, but THEN IT DOESNT SPAWN WTF!? - model = "\A3\Weapons_F\empty.p3d"; - destrType = "DestructNo"; - simulation = "LaserTarget"; + // model = "\A3\Weapons_F\empty.p3d"; class EventHandlers { - init = QUOTE(_this call FUNC(laser_init)); - }; - }; - - // Visual laserTarget override - class ACE_LaserTarget_Visual : LaserTarget { - simulation = "LaserTarget"; - model = "\A3\Weapons_f\laserTgt.p3d"; - }; - - // Vehicle lockable configurations - - class AllVehicles; - class Air: AllVehicles { - class Turrets; - }; - - class Helicopter: Air { - class Turrets { - class MainTurret; - }; - }; - - class Helicopter_Base_F: Helicopter {}; - - class Heli_Attack_01_base_F: Helicopter_Base_F {}; - - class B_Heli_Attack_01_F: Heli_Attack_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(CanLockLaser) = 1; // Enable laser locking selection + class ADDON { + init = QUOTE(_this call FUNC(handleLaserTargetCreation)); }; }; }; diff --git a/addons/laser/README.md b/addons/laser/README.md index 96a2bd7b19..64ea8fe045 100644 --- a/addons/laser/README.md +++ b/addons/laser/README.md @@ -10,3 +10,5 @@ The people responsible for merging changes to this component or answering potent - [walterpearce](https://github.com/walterpearce) - [NouberNou](https://github.com/NouberNou) +- [esteldunedain](https://github.com/esteldunedain) +- [PabstMirror](https://github.com/PabstMirror) 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/laser/RscTitles.hpp b/addons/laser/RscTitles.hpp new file mode 100644 index 0000000000..7421246181 --- /dev/null +++ b/addons/laser/RscTitles.hpp @@ -0,0 +1,53 @@ +class RscTitles { + class GVAR(modeDisplay) { + idd = -1; + onLoad = QUOTE(with uiNameSpace do { GVAR(display) = _this select 0 };); + movingEnable = 0; + duration = 60; + fadeIn = "false"; + fadeOut = "false"; + class controls { + class ModeControlGroup: RscControlsGroupNoScrollbars { + idc = IDC_MODECONTROLGROUP; + x = "3.8 * (((safezoneW / safezoneH) min 1.2) / 40) + (profilenamespace getvariable ['IGUI_GRID_WEAPON_X',((safezoneX + safezoneW) - (10 * (((safezoneW / safezoneH) min 1.2) / 40)) - 4.3 * (((safezoneW / safezoneH) min 1.2) / 40))])"; + y = "2.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (profilenamespace getVariable ['IGUI_GRID_WEAPON_Y', (safezoneY + 0.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))])"; + w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + + class controls { + class AttackMode: RscText { + idc = IDC_ATTACKMODE; + colorText[] = {1, 1, 1, 1}; + colorBackground[] = {0, 0, 0, 0}; + x = "0"; + y = "0"; + w = "(2.6) * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + sizeEx = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + }; + class LaserCode: RscText { + idc = IDC_LASERCODE; + colorText[] = {1, 1, 1, 1}; + colorBackground[] = {0, 0, 0, 0}; + x = "(3.6) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + y = "0"; + w = "(2.5) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + h = "(1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + sizeEx = "0.8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + }; + class LaserIcon: RscPictureKeepAspect { + idc = IDC_LASERICON; + colorText[] = {1, 0, 0, 1}; + colorBackground[] = {0, 0, 0, 0}; + text = "\a3\Ui_F_Curator\Data\CfgCurator\laser_ca.paa"; + x = "(6.1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + y = "0"; + w = "(1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + h = "(1) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + }; + }; + }; + + }; + }; +}; diff --git a/addons/laser/XEH_PREP.hpp b/addons/laser/XEH_PREP.hpp index df185221ff..6af5643e23 100644 --- a/addons/laser/XEH_PREP.hpp +++ b/addons/laser/XEH_PREP.hpp @@ -1,26 +1,16 @@ -PREP(rotateVectLineGetMap); -PREP(rotateVectLine); -PREP(shootRay); -PREP(shootCone); -PREP(checkLos); - -PREP(findStrongestRay); - -PREP(onLaserDesignatorDraw); - -PREP(seekerFindLaserSpot); -PREP(laserOn); +PREP(addLaserTarget); +PREP(dev_drawVisibleLaserTargets); +PREP(findLaserSource); +PREP(handleLaserTargetCreation); +PREP(keyLaserCodeChange); PREP(laserOff); -PREP(handleLaserOn); -PREP(handleLaserOff); - -PREP(drawVisibleLaserTargets); - -PREP(laser_init); -PREP(vanillaLaserSeekerHandler); +PREP(laserOn); PREP(laserTargetPFH); - -PREP(unitTurretCanLockLaser); -PREP(keyLaserCodeUp); -PREP(keyLaserCodeDown); +PREP(onLaserDesignatorDraw); +PREP(rotateVectLine); +PREP(rotateVectLineGetMap); +PREP(seekerFindLaserSpot); +PREP(shootCone); +PREP(shootRay); +PREP(showVehicleHud); diff --git a/addons/laser/XEH_postInit.sqf b/addons/laser/XEH_postInit.sqf new file mode 100644 index 0000000000..709682853b --- /dev/null +++ b/addons/laser/XEH_postInit.sqf @@ -0,0 +1,53 @@ +#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"]; + TRACE_2("ace_laserOn eh",_uuid,_args); + [GVAR(laserEmitters), _uuid, _args] call CBA_fnc_hashSet; +}] call CBA_fnc_addEventHandler; + +["ace_laserOff", { + params ["_uuid"]; + TRACE_1("ace_laserOn eh",_uuid); + if ([GVAR(laserEmitters), _uuid] call CBA_fnc_hashHasKey) then { + [GVAR(laserEmitters), _uuid] call CBA_fnc_hashRem; + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(updateCode), { + params ["_uuid", "_newCode"]; + TRACE_2("ace_laser_updateCode eh",_uuid,_newCode); + if ([GVAR(laserEmitters), _uuid] call CBA_fnc_hashHasKey) then { + private _laserArray = [GVAR(laserEmitters), _uuid] call CBA_fnc_hashGet; + TRACE_2("updating",_newCode,_laserArray select 4); + _laserArray set [4, _newCode]; + }; +}] call CBA_fnc_addEventHandler; + +// Shows detector and mine posistions in 3d when debug is on +#ifdef DRAW_LASER_INFO +addMissionEventHandler ["Draw3D", {_this call FUNC(dev_drawVisibleLaserTargets)}]; +#endif diff --git a/addons/laser/XEH_post_init.sqf b/addons/laser/XEH_post_init.sqf deleted file mode 100644 index 51473ceba6..0000000000 --- a/addons/laser/XEH_post_init.sqf +++ /dev/null @@ -1,7 +0,0 @@ -#include "script_component.hpp" - -#include "initKeybinds.sqf" - -["ace_laserOn", {_this call DFUNC(handleLaserOn)}] call CBA_fnc_addEventHandler; -["ace_laserOff", {_this call DFUNC(handleLaserOff)}] call CBA_fnc_addEventHandler; - diff --git a/addons/laser/XEH_preInit.sqf b/addons/laser/XEH_preInit.sqf new file mode 100644 index 0000000000..2c4e7c7f4f --- /dev/null +++ b/addons/laser/XEH_preInit.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +// Laser default variables +ACE_DEFAULT_LASER_CODE = 1111; +ACE_DEFAULT_LASER_WAVELENGTH = 1550; +ACE_DEFAULT_LASER_BEAMSPREAD = 1; + +GVAR(laserEmitters) = [] call CBA_fnc_hashCreate; +GVAR(trackedLaserTargets) = []; +GVAR(pfehID) = -1; + +ADDON = true; diff --git a/addons/laser/XEH_pre_init.sqf b/addons/laser/XEH_pre_init.sqf deleted file mode 100644 index 410df488f5..0000000000 --- a/addons/laser/XEH_pre_init.sqf +++ /dev/null @@ -1,16 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -#include "XEH_PREP.hpp" - -GVAR(VanillaLasers) = []; - -// Laser default variables -ACE_DEFAULT_LASER_CODE = 1001; -ACE_DEFAULT_LASER_WAVELENGTH = 1550; -ACE_DEFAULT_LASER_BEAMSPREAD = 1; - -GVAR(laserEmitters) = [] call CBA_fnc_hashCreate; - -ADDON = true; diff --git a/addons/laser/config.cpp b/addons/laser/config.cpp index d989c4f85b..fb6ae5e638 100644 --- a/addons/laser/config.cpp +++ b/addons/laser/config.cpp @@ -13,12 +13,19 @@ class CfgPatches { }; }; +#include "ACE_Settings.hpp" #include "CfgEventhandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" -#include "RscInGameUI.hpp" -class ACE_newEvents { - laser_laserOff = "ace_laserOff"; - laser_laserOn = "ace_laserOn"; -}; + +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_addLaserTarget.sqf b/addons/laser/functions/fnc_addLaserTarget.sqf new file mode 100644 index 0000000000..48a98353e9 --- /dev/null +++ b/addons/laser/functions/fnc_addLaserTarget.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +/* + * Author: esteldunedain + * Adds a vanilla laser target to the tracker PFH and globaly turns it on + * + * Argument: + * 0: TargetObject (vanilla laser) + * 1: Vehicle + * + * Return Value: + * None + * + * Example: + * [laserTarget player, player] call ace_laser_fnc_addLaserTarget; + * + * Public: No + */ + +params ["_targetObject", "_vehicle"]; +TRACE_2("params",_targetObject,_vehicle); + +// Get the designator variables, or use defaults +private _waveLength = _vehicle getVariable [QEGVAR(laser,waveLength), ACE_DEFAULT_LASER_WAVELENGTH]; +private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; +private _beamSpread = _vehicle getVariable [QEGVAR(laser,beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD]; +TRACE_3("codes",_waveLength,_laserCode,_beamSpread); + +// Laser method is the method ACE_Laser will use to determine from where to where it should project the designator cone +_vehicle setVariable [QGVAR(targetObject), _targetObject, true]; + +private _laserMethod = QFUNC(findLaserSource); + +private _vehicleSourceSelection = ""; +if (_vehicle isKindOf "CaManBase") then { + _vehicleSourceSelection = "pilot"; +} else { + { // Go through turrets on vehicle and find the laser + private _turretPath = _x; + { + if ((getNumber (configFile >> "CfgWeapons" >> _x >> "laser")) > 0) exitWith { + _vehicleSourceSelection = getText (([_vehicle, _turretPath] call CBA_fnc_getTurret) >> "memoryPointGunnerOptics"); + TRACE_3("",_turretPath,_x,_vehicleSourceSelection); + }; + } forEach (_vehicle weaponsTurret _turretPath); + } forEach (allTurrets [_vehicle, true]); +}; + +private _methodArgs = [_vehicleSourceSelection]; + +TRACE_6("Laser on:",_vehicle,_laserMethod,_waveLength,_laserCode,_beamSpread,_methodArgs); +private _laserUuid = [_vehicle, _vehicle, _laserMethod, _waveLength, _laserCode, _beamSpread, _methodArgs] call FUNC(laserOn); + +GVAR(trackedLaserTargets) pushBack [_targetObject, _vehicle, _laserUuid, _laserCode]; +TRACE_1("",GVAR(trackedLaserTargets)); + +if (GVAR(pfehID) == -1) then { + TRACE_1("starting pfeh",count GVAR(trackedLaserTargets)); + GVAR(pfehID) = [DFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler; +}; diff --git a/addons/laser/functions/fnc_checkLos.sqf b/addons/laser/functions/fnc_checkLos.sqf deleted file mode 100644 index c3dc8cc67f..0000000000 --- a/addons/laser/functions/fnc_checkLos.sqf +++ /dev/null @@ -1,28 +0,0 @@ -#include "script_component.hpp" - -params ["_pos1", "_pos2", "_designator", "_seeker"]; - -private _spacing = 100; -if((count _this) > 4) then { - _spacing = _this select 4; -}; - -private _return = true; -private _vectorTo = [_pos2, _pos1] call BIS_fnc_vectorFromXToY; - -private _x = (_vectorTo select 0)*0.25; -private _y = (_vectorTo select 1)*0.25; -private _z = (_vectorTo select 2)*0.25; - -_pos2 = [(_pos2 select 0) + _x, (_pos2 select 1) + _y, (_pos2 select 2) + _z]; - -// player sideChat format["new los check"]; -if(terrainIntersect [_pos2, _pos1]) then { - _return = false; -} else { - if(lineIntersects [_pos2, _pos1]) then { // should take as arguments and add to this command objects to exclude - target and observer - // player sideChat format["with: %1", lineIntersectsWith [_pos1, _pos2]]; - _return = false; - }; -}; -_return; \ No newline at end of file diff --git a/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf b/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf new file mode 100644 index 0000000000..4613f510ef --- /dev/null +++ b/addons/laser/functions/fnc_dev_drawVisibleLaserTargets.sqf @@ -0,0 +1,79 @@ +#include "script_component.hpp" + +/* + * Author: ACE-Team + * + * + * Argument: + * None + * + * Return Value: + * None + * + * Example: + * call ace_laser_fnc_dev_drawVisibleLaserTargets + * + * Public: No + */ + + +// Dev Debug Function +// Displays lasers and attempts to lock on to codes 1111 and 1112 from a target vehicle's view +// On Screen Debug: +// Red - Vanilla Laser Targets +// Yellow - Array (vehicle pos/weapon) Laser Targets +// Green - Rays +// Blue - Seeker Locks + +// Try searching for lasers from a given vehicle position [BLUE]: +private _seekerVehicle = vehicle ace_player; +private _testSeekerPosASL = AGLtoASL (_seekerVehicle modelToWorldVisual [0,0,1]); +private _testSeekerDir = vectorDirVisual _seekerVehicle; +{ + private _code = _x; + private _results = [_testSeekerPosASL, _testSeekerDir, 45, 10000, [1550,1550], _code, _seekerVehicle] call FUNC(seekerFindLaserSpot); + private _resultPos = _results select 0; + if (!isNil "_resultPos") then { + // Draw lock results + drawLine3D [ASLtoAGL _testSeekerPosASL, ASLtoAGL _resultPos, [0,0,1,1]]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [0,0,1,1], (ASLtoAGL _resultPos), 1.5, 1.5, 45, format ["%1 from %2", _code, _results select 1], 0.5, 0.025, "TahomaB"]; + }; +} forEach [1111, 1112]; // Scan at codes 1111 and 1112 + + +// Draw all lasers +[GVAR(laserEmitters), { + //IGNORE_PRIVATE_WARNING ["_key", "_value"]; + // TRACE_2("",_key,_value); + _value params ["_obj", "_owner", "_laserMethod", "_waveLength", "_laserCode", "_beamSpread"]; + + // Draw vanila lasers [RED] + if (_laserMethod isEqualTo QFUNC(findLaserSource)) then { // Normal vanilla laserTarget func + private _targetObject = _obj getVariable [QGVAR(targetObject), objNull]; + private _targetPosASL = getPosASL _targetObject; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _targetPosASL), 0.5, 0.5, 0, "", 0.5, 0.025, "TahomaB"]; + + (_value call FUNC(findLaserSource)) params ["_laserPosASL", "_laserDir"]; + private _resultsRay = [_laserPosASL, _laserDir, _obj] call FUNC(shootRay); + + private _rayPos = _resultsRay select 0; + if (isNil "_rayPos") then { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _targetPosASL), 2, 2, 0, "Nil Ray", 0.5, 0.025, "TahomaB"]; + } else { + private _diff = _rayPos vectorDistance (getPosASL _targetObject); // Diff from ray position compared to actual + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoAGL _rayPos), 2, 2, 0, format ["Diff %1",_diff], 0.5, 0.025, "TahomaB"]; + }; + }; + // Draw array weapon lasers [YELLOW] + if ((_laserMethod isEqualType []) && {(count _laserMethod) == 2}) then { + _laserMethod params ["_modelPosition", "_weaponName"]; + private _laserPosASL = AGLtoASL (_obj modelToWorldVisual _modelPosition); + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,1,0,1], (ASLtoAGL _laserPosASL), 0.5, 0.5, 0, _weaponName, 0.5, 0.025, "TahomaB"]; + private _laserDir = _obj weaponDirection _weaponName; + private _resultsRay = [_laserPosASL, _laserDir, _obj] call FUNC(shootRay); + private _rayPos = _resultsRay select 0; + if (!isNil "_rayPos") then { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,1,0,1], (ASLtoAGL _rayPos), 2, 2, 0, _weaponName, 0.5, 0.025, "TahomaB"]; + }; + }; +}] call CBA_fnc_hashEachPair; diff --git a/addons/laser/functions/fnc_drawVisibleLaserTargets.sqf b/addons/laser/functions/fnc_drawVisibleLaserTargets.sqf deleted file mode 100644 index 1e03b168fd..0000000000 --- a/addons/laser/functions/fnc_drawVisibleLaserTargets.sqf +++ /dev/null @@ -1,9 +0,0 @@ -// This is a debug function for displaying visible lasers for ourselves -#include "script_component.hpp" - -ACE_LOGINFO("Laser Emitter Dump"); - -{ - ACE_LOGINFO_1(" %1", _x); - ACE_LOGINFO_1(" %1",[ARR_2(GVAR(laserEmitters),_x)] call CBA_fnc_hashGet); -} forEach (GVAR(laserEmitters) select 1); diff --git a/addons/laser/functions/fnc_findLaserSource.sqf b/addons/laser/functions/fnc_findLaserSource.sqf new file mode 100644 index 0000000000..dcb137fb69 --- /dev/null +++ b/addons/laser/functions/fnc_findLaserSource.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * Author: esteldunedain + * Handler function for finding position and direction of a vanilla laser. + * + * Arguments: + * 0: Vehicle (shooter of laser) + * 6: Method Args + * 0: Laser Source selection on Vehicle + * + * Return Value: + * [position, direction] + * + * Example: + * [player, x,x,x,x,x, ["pilot"]] call ace_laser_fnc_findLaserSource; + * + * Public: No + */ + +params ["_vehicle", "", "", "", "", "", "_methodArgs"]; +_methodArgs params ["_ownerSelection"]; + +// Get the laser target object stored in the unit +private _targetObject = _vehicle getVariable [QGVAR(targetObject), objNull]; +private _targetPos = getPosASL _targetObject; +if (surfaceIsWater _targetPos && {(_targetPos select 2) < 0}) then { + // Vanilla lasers seem to give position at ocean floor heigh, even though the x and y are correct?? + _targetPos set [2, 0.25]; +}; + +private _povPos = AGLtoASL (_vehicle modelToWorldVisual (_vehicle selectionPosition _ownerSelection)); +private _povDir = _povPos vectorFromTo _targetPos; + +TRACE_4("",_vehicle,_targetObject,_povPos,_povDir); + +if(isNil "_povPos" || isNil "_povDir") exitWith { + WARNING_2("bad data [%1][%2]",_povPos,_povDir); + [-1,-1] +}; + +[_povPos, _povDir] diff --git a/addons/laser/functions/fnc_findStrongestRay.sqf b/addons/laser/functions/fnc_findStrongestRay.sqf deleted file mode 100644 index e863fb4d11..0000000000 --- a/addons/laser/functions/fnc_findStrongestRay.sqf +++ /dev/null @@ -1,48 +0,0 @@ -#include "script_component.hpp" - -params ["_list", "_checkPos"]; -private _spots = []; -private _outliers = []; -private _spot = []; -(_list select 0) params ["_testPos"]; -{ - _x params ["_samplePos"]; - if(!lineIntersects [_samplePos, _checkPos] && {!terrainIntersectASL [_samplePos, _checkPos]}) then { - if(_samplePos distance _testPos < 2) then { - _spot pushBack _samplePos; - } else { - _outliers pushBack _samplePos; - }; - }; -} forEach _list; -_spots pushBack _spot; - -if(count _outliers > 0) then { - for "_i" from 1 to 3 do { - private _remainingSpots = _outliers; - _outliers = []; - _spot = []; - _testPos = (_remainingSpots select 0); - { - private _samplePos = _x; - if(!lineIntersects [_samplePos, _checkPos] && {!terrainIntersectASL [_samplePos, _checkPos]}) then { - if(_samplePos distance _testPos < 2) then { - _spot pushBack _samplePos; - } else { - _outliers pushBack _samplePos; - }; - }; - } forEach _remainingSpots; - _spots pushBack _spot; - }; -}; -private _largest = 0; -private _largestSpot = []; -{ - if(count _x > _largest) then { - _largest = count _x; - _largestSpot = _x; - }; -} forEach _spots; -// player sideChat format["g: %1", _spots]; -_largestSpot select (random (floor(count _largestSpot))); \ No newline at end of file diff --git a/addons/laser/functions/fnc_handleLaserOff.sqf b/addons/laser/functions/fnc_handleLaserOff.sqf deleted file mode 100644 index 9a83120934..0000000000 --- a/addons/laser/functions/fnc_handleLaserOff.sqf +++ /dev/null @@ -1,7 +0,0 @@ -//fnc_handleLaserOff.sqf -#include "script_component.hpp" - -params ["_uuid"]; -if ([GVAR(laserEmitters), _uuid] call CBA_fnc_hashHasKey) then { - [GVAR(laserEmitters), _uuid] call CBA_fnc_hashRem; -}; diff --git a/addons/laser/functions/fnc_handleLaserOn.sqf b/addons/laser/functions/fnc_handleLaserOn.sqf deleted file mode 100644 index 243023d8aa..0000000000 --- a/addons/laser/functions/fnc_handleLaserOn.sqf +++ /dev/null @@ -1,5 +0,0 @@ -//fnc_handleLaserOn.sqf -#include "script_component.hpp" - -params ["_uuid", "_args"]; -[GVAR(laserEmitters), _uuid, _args] call CBA_fnc_hashSet; diff --git a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf new file mode 100644 index 0000000000..c619024ed4 --- /dev/null +++ b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" +/* + * Author: esteldunedain + * Associates a newly created laser target to it's owner + * + * Argument: + * 0: Vanilla Laser (base type LaserTarget) + * + * Return Value: + * None + * + * Example: + * [laserTarget player] call ace_laser_fnc_handleLaserTargetCreation; + * + * Public: No + */ + +TRACE_1("params",_this); +[{ + params ["_targetObject"]; + + // Only handle locally created lasers + if(!(local _targetObject)) exitWith {TRACE_1("not local",_targetObject);}; + + private _owners = allUnits select {(lasertarget _x) == _targetObject}; + if (count _owners == 1) exitWith { + TRACE_2("Laser target owner [allUnits]", _targetObject, _owners select 0); + [_targetObject, _owners select 0] call FUNC(addLaserTarget); + }; + + _owners = vehicles select {(lasertarget _x) == _targetObject}; + if (count _owners == 1) exitWith { + TRACE_2("Laser target owner [vehicles]", _targetObject, _owners select 0); + [_targetObject, _owners select 0] call FUNC(addLaserTarget); + }; + + // 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 new file mode 100644 index 0000000000..32d9151083 --- /dev/null +++ b/addons/laser/functions/fnc_keyLaserCodeChange.sqf @@ -0,0 +1,66 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Change the laser key code (both seeker and transmitter) + * + * Argument: + * 0: Change in code + * + * Return Value: + * Key Handled + + * Example: + * [1] call ace_laser_fnc_keyLaserCodeChange; + * + * Public: No + */ + +params [["_codeChange", 0, [0]]]; + +TRACE_1("params",_codeChange); + +if ((!alive ACE_player) || {!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))}) exitWith {false}; + +private _currentShooter = objNull; +private _currentWeapon = ""; + +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 = ACE_controlledUAV select 0; + private _turretPath = ACE_controlledUAV select 2; + _currentWeapon = _currentShooter currentWeaponTurret _turretPath; +}; + +TRACE_2("",_currentShooter,_currentWeapon); +if (((getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> "laser")) == 0) && + {(getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> QGVAR(canSelect))) == 0}) exitWith {false}; + +private _oldLaserCode = _currentShooter getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; +private _newLaserCode = _oldLaserCode; + +// "Four-digit code equipment settings range from 1111 to 1788" +// While there is a 0 or 9 in code, keep adding change + +if (((_codeChange < 0) && {_oldLaserCode > ACE_DEFAULT_LASER_CODE}) || {(_codeChange > 0) && {_oldLaserCode < 1788}}) then { + _newLaserCode = _oldLaserCode + _codeChange; + while {(((str _newLaserCode) find "0") >= 0) || {((str _newLaserCode) find "9") >= 0}} do { + _newLaserCode = _newLaserCode + _codeChange; + }; +}; + +TRACE_2("",_oldLaserCode,_newLaserCode); + +if (_oldLaserCode != _newLaserCode) then { + _currentShooter setVariable [QGVAR(code), _newLaserCode, true]; +}; +[format ["%1: %2", localize LSTRING(laserCode), _newLaserCode]] call EFUNC(common,displayTextStructured); + +true diff --git a/addons/laser/functions/fnc_keyLaserCodeDown.sqf b/addons/laser/functions/fnc_keyLaserCodeDown.sqf deleted file mode 100644 index a75487193d..0000000000 --- a/addons/laser/functions/fnc_keyLaserCodeDown.sqf +++ /dev/null @@ -1,12 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -private ["_oldLaserCode", "_laserCode"]; - -_oldLaserCode = ACE_player getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; -if(_oldLaserCode > ACE_DEFAULT_LASER_CODE) then { - _laserCode = _oldLaserCode - 1; - ACE_player setVariable [QGVAR(code), _laserCode, false]; -}; -if(_laserCode != _oldLaserCode) then { - [format ["%1: %2", localize LSTRING(laserCode), _laserCode]] call EFUNC(common,displayTextStructured); -}; \ No newline at end of file diff --git a/addons/laser/functions/fnc_keyLaserCodeUp.sqf b/addons/laser/functions/fnc_keyLaserCodeUp.sqf deleted file mode 100644 index 93001a06fd..0000000000 --- a/addons/laser/functions/fnc_keyLaserCodeUp.sqf +++ /dev/null @@ -1,10 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -private ["_oldLaserCode", "_laserCode"]; - -_oldLaserCode = ACE_player getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; -_laserCode = _oldLaserCode + 1; -ACE_player setVariable [QGVAR(code), _laserCode, false]; -if(_laserCode != _oldLaserCode) then { -[format ["%1: %2", localize LSTRING(laserCode), _laserCode]] call EFUNC(common,displayTextStructured); -}; \ No newline at end of file diff --git a/addons/laser/functions/fnc_laserOff.sqf b/addons/laser/functions/fnc_laserOff.sqf index 8e9792f0d4..bb207f2781 100644 --- a/addons/laser/functions/fnc_laserOff.sqf +++ b/addons/laser/functions/fnc_laserOff.sqf @@ -1,15 +1,22 @@ +#include "script_component.hpp" /* * Author: Nou * Turn a laser designator off. * * Arguments: - * 0: UUID (from laserOn) + * 0: UUID (from laserOn) * * Return Value: * None + * + * Example: + * ["yourLaserUID"] call ace_laser_fnc_laserOff; + * + * Public: No */ -#include "script_component.hpp" - params ["_uuid"]; + +TRACE_1("Sending Global Laser Off Event",_uuid); + ["ace_laserOff", [_uuid]] call CBA_fnc_globalEvent; diff --git a/addons/laser/functions/fnc_laserOn.sqf b/addons/laser/functions/fnc_laserOn.sqf index 644059c406..4038e065ef 100644 --- a/addons/laser/functions/fnc_laserOn.sqf +++ b/addons/laser/functions/fnc_laserOn.sqf @@ -1,22 +1,34 @@ +#include "script_component.hpp" /* * Author: Nou * Turn a laser designator on. * * Arguments: - * 0: Emitter - * 1: Owner - * 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). + * 0: Emitter + * 1: Owner + * 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 (default: nil) * * Return Value: - * String, 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 + * + * Public: No */ -#include "script_component.hpp" +// params [["_emitter", objNull, [objNull]],["_owner", objNull, [objNull]],["_method", "", ["", {}, []]],["_wavelength", 0, [0]],["_code", 0, [0]],["_beamSpread", 0, [0]],"_methodArgs"]; private _uuid = format["%1%2%3", floor diag_tickTime, floor random 1000, floor random 10000]; private _args = [_uuid, _this]; + +TRACE_2("Sending Global Laser On Event",_uuid,_this); + ["ace_laserOn", _args] call CBA_fnc_globalEvent; + _uuid; diff --git a/addons/laser/functions/fnc_laserTargetPFH.sqf b/addons/laser/functions/fnc_laserTargetPFH.sqf index c0805b1e6c..c833aa5254 100644 --- a/addons/laser/functions/fnc_laserTargetPFH.sqf +++ b/addons/laser/functions/fnc_laserTargetPFH.sqf @@ -1,27 +1,46 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" -TRACE_1("enter", _this); +/* + * Author: esteldunedain + * Maintains the tracked lasers, deleting any laser that is turned off + * + * Argument: + * PFEH Args + * + * Return Value: + * None + * + * Example: + * [[], 1]] call ace_laser_fnc_laserTargetPFH; + * + * Public: No + */ -//TRACE_1("enter", _this); -params ["_args"]; -_args params ["_laserTarget", "_shooter", "_uuid"]; +params ["", "_pfhuid"]; -if(isNull _laserTarget || !alive _shooter) exitWith { - [(_this select 1)] call CBA_fnc_removePerFrameHandler; - REM(GVAR(VanillaLasers), _laserTarget); +GVAR(trackedLaserTargets) = GVAR(trackedLaserTargets) select { + _x params ["_targetObject", "_owner", "_laserUuid", "_laserCode"]; + if ((isNull _targetObject) || + {!(alive _targetObject)} || + {isNull _owner} || + {!(alive _owner)}) then { - // Remove laseron - [_uuid] call FUNC(laserOff); + // Turn off the laser in ace_laser + [_laserUuid] call FUNC(laserOff); + TRACE_1("Laser off:", _laserUuid); + false + } else { + private _newCode = _owner getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + if (_laserCode != _newCode) then { + TRACE_2("code change",_newCode,_laserCode); + [QGVAR(updateCode), [_laserUuid, _newCode]] call CBA_fnc_globalEvent; + _x set [3, _newCode]; + }; + true + }; }; -#ifdef DEBUG_MODE_FULL -// Iconize the location of the actual laserTarget -_pos = getPosASL _laserTarget; -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1,0,0,1], (ASLtoATL _pos), 0.75, 0.75, 0, "", 0.5, 0.025, "TahomaB"]; - -{ - drawLine3D [ASLtoATL (_x select 0), ASLtoATL (_x select 1), (_x select 2)]; - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", (_x select 2), ASLtoATL (_x select 1), 0.75, 0.75, 0, "", 0.5, 0.025, "TahomaB"]; -} forEach DRAW_LINES; -DRAW_LINES = []; -#endif +if (GVAR(trackedLaserTargets) isEqualTo []) then { + TRACE_1("ending pfeh",count GVAR(trackedLaserTargets)); + [_pfhuid] call CBA_fnc_removePerFrameHandler; + GVAR(pfehID) = -1; +}; diff --git a/addons/laser/functions/fnc_laser_init.sqf b/addons/laser/functions/fnc_laser_init.sqf deleted file mode 100644 index 23f84c0bf5..0000000000 --- a/addons/laser/functions/fnc_laser_init.sqf +++ /dev/null @@ -1,33 +0,0 @@ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" -TRACE_1("enter", _this); - -PARAMS_1(_laserTarget); -private ["_uuid"]; - -// Add the target to the global targets array -// Everyone tracks them -// Add the laser localized to the laser array, and give it the default localized code -PUSH(GVAR(VanillaLasers), _laserTarget); - -// Check the vehicle, otherwise use the default -_laserTarget setVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE, false]; -_laserTarget setVariable [QGVAR(beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD, false]; -_laserTarget setVariable [QGVAR(waveLength), ACE_DEFAULT_LASER_WAVELENGTH, false]; - -// Clean the lasers of any null objects while we are here -REM(GVAR(VanillaLasers), objNull); - -if(!(local _laserTarget)) exitWith { }; - -// The target is local, so its on this client -if(!isDedicated) then { - // @TODO: Get ownership variables and set them on the vehicle - - _uuid = [(vehicle ACE_player), ACE_player, QFUNC(vanillaLaserSeekerHandler), ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_CODE, ACE_DEFAULT_LASER_BEAMSPREAD] call FUNC(laserOn); - _laserTarget setVariable [QGVAR(uuid), _uuid, false]; - [FUNC(laserTargetPFH), 0, [_laserTarget, ACE_player, _uuid]] call CBA_fnc_addPerFrameHandler; -} else { - // server side ownership of laser - _laserTarget setVariable [QGVAR(owner), nil, true]; -}; diff --git a/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf b/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf index 3161b2a220..e7a4994ce2 100644 --- a/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf +++ b/addons/laser/functions/fnc_onLaserDesignatorDraw.sqf @@ -1,15 +1,28 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" -private ["_laserCode"]; +/* + * Author: Nou + * Update distance when rangefinder laser is on + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_laser_fnc_onLaserDesignatorDraw + * + * Public: No + */ -_laserCode = ACE_player getVariable[QGVAR(code), ACE_DEFAULT_LASER_CODE]; -if(!isNil "_laserCode") then { +private _laserCode = ACE_player getVariable[QGVAR(code), ACE_DEFAULT_LASER_CODE]; +if (!isNil "_laserCode") then { __LaserDesignatorIGUI_LaserCode ctrlSetText format["Code: %1", [_laserCode, 4, 0, false] call CBA_fnc_formatNumber]; }; -if(! (ctrlShown __LaserDesignatorIGUI_LaserOn) ) then { +if (! (ctrlShown __LaserDesignatorIGUI_LaserOn) ) then { // TODO: hide distance __LaserDesignatorIGUI_ACE_Distance ctrlSetText "----"; } else { __LaserDesignatorIGUI_ACE_Distance ctrlSetText (ctrlText __LaserDesignatorIGUI_CA_Distance); -}; \ No newline at end of file +}; diff --git a/addons/laser/functions/fnc_rotateVectLine.sqf b/addons/laser/functions/fnc_rotateVectLine.sqf index 76ff42c66c..990234c62c 100644 --- a/addons/laser/functions/fnc_rotateVectLine.sqf +++ b/addons/laser/functions/fnc_rotateVectLine.sqf @@ -1,16 +1,24 @@ #include "script_component.hpp" -private ["_d", "_map", "_p", "_theta", "_u"]; -_map = _this select 0; -_theta = _this select 1; +/* + * Author: ACE-Team + * + * + * Argument: + * None + * + * Return Value: + * None + * + * Example: + * call ace_laser_fnc_rotateVectline + * + * Public: No + */ -_p = _map select 0; -_p1 = _map select 1; -_p2 = _map select 2; - -_q1 = +(_map select 3); -_q2 = +(_map select 4); -_u = _map select 5; -_d = _map select 6; +params ["_map", "_theta"]; +_map params ["_p", "_p1", "_p2", "_q1", "_q2", "_u", "_d"]; +_q1 = +_q1; +_q2 = +_q2; /* Step 4 */ _q2 set[0, (_q1 select 0) * cos(_theta) - (_q1 select 1) * sin(_theta)]; @@ -33,4 +41,4 @@ if (_d != 0) then { /* Inverse of step 1 */ _q1 = _q2 vectorAdd _p1; -_q1; \ No newline at end of file +_q1; diff --git a/addons/laser/functions/fnc_rotateVectLineGetMap.sqf b/addons/laser/functions/fnc_rotateVectLineGetMap.sqf index 53ee35a288..f87aa21376 100644 --- a/addons/laser/functions/fnc_rotateVectLineGetMap.sqf +++ b/addons/laser/functions/fnc_rotateVectLineGetMap.sqf @@ -1,17 +1,29 @@ #include "script_component.hpp" +/* + * Author: ACE-Team + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_laser_fnc_rotateVectLineGetMap + * + * Public: No + */ -private ["_p", "_theta", "_p1", "_p2", "_q1", "_q2", "_u", "_d"]; -_p = _this select 0; -_p1 = _this select 1; -_p2 = _this select 2; +params ["_p", "_p1", "_p2"]; -_q2 = []; +private _q2 = []; /* Step 1 */ -_q1 = _p vectorDiff _p1; -_u = _p2 vectorDiff _p1; +private _q1 = _p vectorDiff _p1; +private _u = _p2 vectorDiff _p1; _u = vectorNormalized _u; -_d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2)); +private _d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2)); /* Step 2 */ if (_d != 0) then { @@ -27,4 +39,4 @@ _q1 set[0, (_q2 select 0) * _d - (_q2 select 2) * (_u select 0)]; _q1 set[1, (_q2 select 1)]; _q1 set[2, (_q2 select 0) * (_u select 0) + (_q2 select 2) * _d]; -[_p, _p1, _p2, _q1, _q2, _u, _d] \ No newline at end of file +[_p, _p1, _p2, _q1, _q2, _u, _d] diff --git a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf index b6abefa691..7fa64665ab 100644 --- a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf +++ b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf @@ -1,92 +1,118 @@ +#include "script_component.hpp" /* * Author: Nou - * Turn a laser designator on. + * Searches for a laser spot given a seekers params. + * Provides the interface for Missile Guidance * * Arguments: - * 0: Position of seeker (ASL) - * 1: Direction vector (will be normalized) - * 2: Seeker FOV in degrees - * 3: Seeker wavelength sensitivity range, [1550,1550] is common eye safe. - * 4: Seeker laser code. + * 0: Position of seeker (ASL) + * 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 + * 5: Seeker laser code. + * 6: Ignore 1 (e.g. Player's vehicle) (default: objNull) * * Return Value: - * Array, [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 + * + * Public: No */ -#include "script_component.hpp" +BEGIN_COUNTER(seekerFindLaserSpot); -private ["_pos", "_seekerWavelengths", "_seekerCode", "_spots", "_buckets", "_excludes", "_bucketIndex", "_finalPos", "_owner", "_obj", "_x", "_method"]; -private ["_emitterWavelength", "_laserCode", "_divergence", "_laser", "_res", "_bucketPos", "_bucketList", "_c", "_forEachIndex", "_index"]; -private ["_testPos", "_finalBuckets", "_largest", "_largestIndex", "_finalBucket", "_owners", "_avgX", "_avgY", "_avgZ", "_count", "_maxOwner", "_maxOwnerIndex", "_finalOwner"]; -private ["_dir", "_seekerCos", "_seekerFov", "_testDotProduct", "_testPoint", "_testPointVector"]; +params ["_posASL", "_dir", "_seekerFov", "_seekerMaxDistance", "_seekerWavelengths", "_seekerCode", ["_ignoreObj1", objNull]]; -_pos = _this select 0; -_dir = vectorNormalized (_this select 1); -_seekerFov = _this select 2; -_seekerWavelengths = _this select 3; -_seekerCode = _this select 4; +_dir = vectorNormalized _dir; +_seekerWavelengths params ["_seekerWavelengthMin", "_seekerWavelengthMax"]; +private _seekerCos = cos _seekerFov; +private _seekerMaxDistSq = _seekerMaxDistance ^ 2; -_seekerCos = cos _seekerFov; +TRACE_6("",_posASL,_dir,_seekerFov,_seekerMaxDistance,_seekerWavelengths,_seekerCode); -_spots = []; -_buckets = []; -_excludes = []; -_bucketIndex = 0; -_finalPos = nil; -_finalOwner = nil; +private _spots = []; +private _finalPos = nil; +private _finalOwner = objNull; +// Go through all lasers in GVAR(laserEmitters) { - _obj = _x select 0; - _owner = _x select 1; - _method = _x select 2; - _emitterWavelength = _x select 3; - _laserCode = _x select 4; - _divergence = _x select 5; - if(alive _obj && {_emitterWavelength >= (_seekerWavelengths select 0)} && {_emitterWavelength <= (_seekerWavelengths select 1)} && {_laserCode == _seekerCode}) then { - _laser = []; - if(IS_CODE(_method)) then { - _laser = _x call _method; + _x params ["_obj", "_owner", "_laserMethod", "_emitterWavelength", "_laserCode", "_divergence"]; + TRACE_6("laser",_obj,_owner,_laserMethod,_emitterWavelength,_laserCode,_divergence); + + if (alive _obj && {_emitterWavelength >= _seekerWavelengthMin} && {_emitterWavelength <= _seekerWavelengthMax} && {_laserCode == _seekerCode}) then { + + private _laser = []; + // Find laser pos and dir of the laser depending on type + if (IS_STRING(_laserMethod)) then { + _laser = _x call (missionNamespace getVariable [_laserMethod, []]); } else { - if(IS_STRING(_method)) then { - _laser = _x call (missionNamespace getVariable [_method, {}]); + if (IS_CODE(_laserMethod)) then { + _laser = _x call _laserMethod; } else { - if(IS_ARRAY(_method)) then { - if(count _method == 2) then { - _laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), _obj weaponDirection (_method select 1)]; + + if (IS_ARRAY(_laserMethod)) then { + if (count _laserMethod == 2) then { // [modelPosition, weaponName] for _obj + _laser = [AGLtoASL (_obj modelToWorldVisual (_laserMethod select 0)), _obj weaponDirection (_laserMethod select 1)]; } else { - if(count _method == 3) then { - _laser = [ATLtoASL (_obj modelToWorldVisual (_method select 0)), (ATLtoASL (_obj modelToWorldVisual (_method select 1))) vectorFromTo (ATLtoASL (_obj modelToWorldVisual (_method select 2)))]; + if (count _laserMethod == 3) then { + _laser = [AGLtoASL (_obj modelToWorldVisual (_laserMethod select 0)), (AGLtoASL (_obj modelToWorldVisual (_laserMethod select 1))) vectorFromTo (AGLtoASL (_obj modelToWorldVisual (_laserMethod select 2)))]; }; }; }; }; }; - //Handle Weird Data Return - if (_laser params [["_laserPos", [], [[]], 3], ["_laserDir", [], [[]], 3]]) then { - _res = [_laserPos, _laserDir, _divergence] call FUNC(shootCone); + TRACE_1("",_laser); + //Handle Weird Data Return - skips over this laser in the for loop + if ((_laser isEqualTo []) || {_laser isEqualTo [-1, -1]}) exitWith {WARNING_1("Bad Laser Return",_laser);}; + _laser params [["_laserPos", [], [[]], 3], ["_laserDir", [], [[]], 3]]; + + if (GVAR(dispersionCount) > 0) then { + // Shoot a cone with dispersion + ([_laserPos, _laserDir, _divergence, GVAR(dispersionCount), _obj] call FUNC(shootCone)) params ["", "", "_resultPositions"]; { - _testPoint = _x select 0; - _testPointVector = vectorNormalized (_testPoint vectorDiff _pos); - _testDotProduct = _dir vectorDotProduct _testPointVector; - if(_testDotProduct > _seekerCos) then { + private _testPoint = _x select 0; + private _testPointVector = _posASL vectorFromTo _testPoint; + private _testDotProduct = _dir vectorDotProduct _testPointVector; + if ((_testDotProduct > _seekerCos) && {(_testPoint vectorDistanceSqr _posASL) < _seekerMaxDistSq}) then { _spots pushBack [_testPoint, _owner]; }; - } forEach (_res select 2); + } forEach _resultPositions; + } else { + // Shoot a single perfect ray from source to target (note, increased chance to "miss" on weird objects like bushes / rocks) + ([_laserPos, _laserDir, _obj] call FUNC(shootRay)) params ["_resultPos", "_distance"]; + TRACE_2("spot",_resultPos,_distance); + if (_distance > 0) then { + private _testPointVector = _posASL vectorFromTo _resultPos; + private _testDotProduct = _dir vectorDotProduct _testPointVector; + if ((_testDotProduct > _seekerCos) && {(_resultPos vectorDistanceSqr _posASL) < _seekerMaxDistSq}) then { + _spots pushBack [_resultPos, _owner]; + }; + }; }; }; -} forEach (GVAR(laserEmitters) select 2); +} forEach (GVAR(laserEmitters) select 2); // Go through all values in hash -if((count _spots) > 0) then { - _bucketPos = nil; - _bucketList = nil; - _c = 0; +TRACE_2("",count _spots, _spots); + +if ((count _spots) > 0) then { + private _bucketList = nil; + private _bucketPos = nil; + private _c = 0; + private _buckets = []; + private _excludes = []; + private _bucketIndex = 0; + + // Put close points together into buckets while { count(_spots) != count(_excludes) && _c < (count _spots) } do { scopeName "mainSearch"; { - if(!(_forEachIndex in _excludes)) then { - _index = _buckets pushBack [_x, [_x]]; + if (!(_forEachIndex in _excludes)) then { + private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x select 0; _bucketList = (_buckets select _index) select 1; @@ -94,9 +120,9 @@ if((count _spots) > 0) then { }; } forEach _spots; { - if(!(_forEachIndex in _excludes)) then { - _testPos = (_x select 0); - if(_testPos vectorDistanceSqr _bucketPos <= 100) then { + if (!(_forEachIndex in _excludes)) then { + private _testPos = (_x select 0); + if ((_testPos vectorDistanceSqr _bucketPos) <= 100) then { _bucketList pushBack _x; _excludes pushBack _forEachIndex; }; @@ -104,55 +130,72 @@ if((count _spots) > 0) then { } forEach _spots; _c = _c + 1; }; - _finalBuckets = []; - _largest = -1; - _largestIndex = 0; + + TRACE_1("",_buckets); + + private _finalBuckets = []; + private _largest = -1; + private _largestIndex = 0; { - _index = _finalBuckets pushBack []; + // find bucket with largest number of points we can see + private _index = _finalBuckets pushBack []; _bucketList = _finalBuckets select _index; { - _testPos = (_x select 0); - if(!terrainIntersectASL [_pos, _testPos] && {!lineIntersects [_pos, _testPos]}) then { + private _testPos = (_x select 0) vectorAdd [0,0,0.05]; + private _testIntersections = lineIntersectsSurfaces [_posASL, _testPos, _ignoreObj1]; + if ([] isEqualTo _testIntersections) then { _bucketList pushBack _x; }; } forEach (_x select 1); - if((count _bucketList) > _largest) then { + if ((count _bucketList) > _largest) then { _largest = (count _bucketList); _largestIndex = _index; }; } forEach _buckets; - _finalBucket = _finalBuckets select _largestIndex; - _owners = [] call CBA_fnc_hashCreate; + private _finalBucket = _finalBuckets select _largestIndex; + private _ownersHash = [] call CBA_fnc_hashCreate; - if(count _finalBucket > 0) then { - _avgX = 0; - _avgY = 0; - _avgZ = 0; + TRACE_2("",_finalBucket,_finalBuckets); + + if (count _finalBucket > 0) then { + // merge all points in the best bucket into an average point and find effective owner + _finalPos = [0,0,0]; { - //player sideChat format["x: %1", _x]; - _avgX = _avgX + ((_x select 0) select 0); - _avgY = _avgY + ((_x select 0) select 1); - _avgZ = _avgZ + ((_x select 0) select 2); - _owner = _x select 1; - if ([_owners, _owner] call CBA_fnc_hashHasKey) then { - private _count = [_owners, _owner] call CBA_fnc_hashGet; - [_owners, _owner, _count + 1] call CBA_fnc_hashSet; + _x params ["_xPos", "_owner"]; + _finalPos = _finalPos vectorAdd _xPos; + if ([_ownersHash, _owner] call CBA_fnc_hashHasKey) then { + private _count = [_ownersHash, _owner] call CBA_fnc_hashGet; + [_ownersHash, _owner, _count + 1] call CBA_fnc_hashSet; } else { - [_owners, _owner, 1] call CBA_fnc_hashSet; + [_ownersHash, _owner, 1] call CBA_fnc_hashSet; }; } forEach _finalBucket; - _count = count _finalBucket; - _finalPos = [_avgX/_count, _avgY/_count, _avgZ/_count]; - _maxOwner = -1; - _maxOwnerIndex = 0; - { - if((_owners select 1) select _forEachIndex > _maxOwner) then { - _maxOwner = (_owners select 1) select _forEachIndex; - _maxOwnerIndex = _forEachIndex; + + _finalPos = _finalPos vectorMultiply (1 / (count _finalBucket)); + + private _maxOwnerCount = -1; + + [_ownersHash, { + //IGNORE_PRIVATE_WARNING ["_key", "_value"]; + if (_value > _maxOwnerCount) then { + _finalOwner = _key; }; - } forEach (_owners select 0); - _finalOwner = (_owners select 0) select _maxOwnerIndex; + }] call CBA_fnc_hashEachPair; }; }; -[_finalPos, _owner]; + +END_COUNTER(seekerFindLaserSpot); + +#ifdef DRAW_LASER_INFO +if (isNil "_finalPos") then { + drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconMan_ca.paa", [0.9,1,0,1], (ASLtoAGL _posASL), 1, 1, 0, format ["Seeker: %1", _seekerCode], 0.5, 0.025, "TahomaB"]; +} else { + drawIcon3D ["\A3\ui_f\data\map\vehicleicons\iconManAT_ca.paa", [0.5,1,0,1], (ASLtoAGL _posASL), 1, 1, 0, format ["Seeker: %1", _seekerCode], 0.5, 0.025, "TahomaB"]; + drawLine3D [ASLtoAGL _posASL, ASLtoAGL _finalPos, [0.5,1,0,1]]; +}; +#endif + +TRACE_2("return",_finalPos,_finalOwner); +if (isNil "_finalPos") exitWith {[nil, _finalOwner]}; +[_finalPos, _finalOwner]; diff --git a/addons/laser/functions/fnc_shootCone.sqf b/addons/laser/functions/fnc_shootCone.sqf index a9e1f3e50d..b9d64a42fa 100644 --- a/addons/laser/functions/fnc_shootCone.sqf +++ b/addons/laser/functions/fnc_shootCone.sqf @@ -1,68 +1,70 @@ #include "script_component.hpp" -//#define DEBUG_MODE_FULL -private ["_i", "_divergence","_pos","_vec","_longestReturn","_shortestReturn","_resultPositions","_p1","_p2","_p","_v","_cp","_vecRotateMap","_result", "_resultPos","_distance","_count","_pos2","_radOffset","_offset","_offsetPos","_offsetVector"]; -_divergence = 0.3; -_pos = _this select 0; -_vec = _this select 1; -if(count _this > 2) then { - _divergence = _this select 2; -}; -_count = 3; -if(count _this > 3) then { - _count = _this select 3; -}; -_longestReturn = -1000000000; -_shortestReturn = 1000000000; -_resultPositions = []; -_p1 = [0,0,0]; -_p2 = +_vec; -_p = (_vec call CBA_fnc_vect2polar); -_v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect; -_cp = _vec vectorCrossProduct _v; +/* + * Author: Nou + * Shoots multiple rays in a dispersion pattern. + * + * Arguments: + * 0: Origin position ASL + * 1: Direction (normalized) + * 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 + * + * Public: No + */ -_vecRotateMap = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap); +BEGIN_COUNTER(shootCone); -_result = [_pos, _vec] call FUNC(shootRay); -_resultPos = _result select 0; -if(!isNil "_resultPos") then { - _distance = _result select 1; - if(_distance < _shortestReturn) then { - _shortestReturn = _distance; - }; - if(_distance > _longestReturn) then { - _longestReturn = _distance; - }; +params ["_pos", "_vec", ["_divergence", 0.3], ["_count", 3], ["_ignoreObj1", objNull]]; + +private _longestReturn = -1000000000; +private _shortestReturn = 1000000000; +private _resultPositions = []; +private _p1 = [0,0,0]; +private _p2 = +_vec; +private _p = (_vec call CBA_fnc_vect2polar); +private _v = [(_p select 0), (_p select 1), (_p select 2)+90] call CBA_fnc_polar2vect; +private _cp = _vec vectorCrossProduct _v; + +private _vecRotateMap = [_cp, _p1, _p2] call FUNC(rotateVectLineGetMap); + +// Check first with a perfect ray to the center +private _result = [_pos, _vec, _ignoreObj1] call FUNC(shootRay); +private _resultPos = _result select 0; + +if (!isNil "_resultPos") then { + private _distance = _result select 1; + if (_distance < _shortestReturn) then { _shortestReturn = _distance; }; + if (_distance > _longestReturn) then { _longestReturn = _distance; }; _resultPositions pushBack _result; -#ifdef DEBUG_MODE_FULL - // DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]]; - drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]]; -#endif }; - -_pos2 = _pos vectorAdd (_vec vectorMultiply 1000); +private _pos2 = _pos vectorAdd (_vec vectorMultiply 1000); +// Try at 3 radius (full, half, quarter of specified divergence) { - for "_i" from 0 to ceil(_count*_x) do { - _radOffset = random 360; - _offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine); - _offsetPos = _pos2 vectorAdd (_offset vectorMultiply (_divergence*_x)); - _offsetVector = _pos vectorFromTo _offsetPos; - _result = [_pos, _offsetVector] call FUNC(shootRay); + private _radOffset = random 360; + for "_i" from 1 to ceil(_count*_x) do { // Will always do at least 1 + private _offset = [_vecRotateMap, (((360/_count)*_i)+_radOffset) mod 360] call FUNC(rotateVectLine); + private _offsetPos = _pos2 vectorAdd (_offset vectorMultiply (_divergence*_x)); + + private _offsetVector = _pos vectorFromTo _offsetPos; + _result = [_pos, _offsetVector, _ignoreObj1] call FUNC(shootRay); _resultPos = _result select 0; - if(!isNil "_resultPos") then { - _distance = _result select 1; - if(_distance < _shortestReturn) then { - _shortestReturn = _distance; - }; - if(_distance > _longestReturn) then { - _longestReturn = _distance; - }; + if (!isNil "_resultPos") then { + private _distance = _result select 1; + if (_distance < _shortestReturn) then { _shortestReturn = _distance; }; + if (_distance > _longestReturn) then { _longestReturn = _distance; }; _resultPositions pushBack _result; -#ifdef DEBUG_MODE_FULL - // DRAW_LINES set[(count DRAW_LINES), [_pos, _resultPos, [0, 1, 0, 1]]]; - drawLine3D [ASLtoATL _pos, ASLtoATL _resultPos, [1,0,0,1]]; -#endif }; }; } forEach [1,0.5,0.25]; -[_longestReturn, _shortestReturn, _resultPositions]; \ No newline at end of file + +END_COUNTER(shootCone); + +[_longestReturn, _shortestReturn, _resultPositions]; diff --git a/addons/laser/functions/fnc_shootRay.sqf b/addons/laser/functions/fnc_shootRay.sqf index 51b5e55f17..ecd16fc0d4 100644 --- a/addons/laser/functions/fnc_shootRay.sqf +++ b/addons/laser/functions/fnc_shootRay.sqf @@ -1,24 +1,57 @@ #include "script_component.hpp" +/* + * Author: Nou, PabstMirror + * 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) (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 + * + * Public: No + */ -private ["_pos", "_vec", "_distance", "_resultPos", "_fidelity", "_lastPos", "_i", "_nextPos"]; -scopeName "main"; -_pos = _this select 0; -_vec = _this select 1; -_distance = 0; -_resultPos = nil; -_fidelity = [1000,100,10,1,0.1]; -_lastPos = +_pos; -{ - scopeName "mainSearch"; - for "_i" from 1 to 10 do { - _nextPos = _lastPos vectorAdd (_vec vectorMultiply _x); - if(terrainIntersectASL [_lastPos, _nextPos] || {lineIntersects [_lastPos, _nextPos]}) then { - _resultPos = _lastPos; - breakTo "mainSearch"; - } else { - _distance = _distance + _x; - _lastPos = _nextPos; - }; +BEGIN_COUNTER(shootRay); + +params ["_posASL", "_dir", ["_ignoreVehicle1", objNull], ["_ignoreVehicle2", objNull]]; +// TRACE_2("ray origin:", _posASL, _dir); + +private _distance = 0; +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]; }; -} forEach _fidelity; -[_resultPos, _distance]; \ No newline at end of file +}; + +if (!(_intersects isEqualTo [])) then { + (_intersects select 0) params ["_intersectPosASL", "", "_intersectObject"]; + // Move back slightly to prevents issues with it going below terrain + _distance = (_posASL vectorDistance _intersectPosASL) - 0.005; + _resultPos = _posASL vectorAdd (_dir vectorMultiply _distance); +}; + +TRACE_3("", _resultPos, _distance, _intersects); + +#ifdef DRAW_LASER_INFO +if !(isNil "_resultPos") then { + private _text = [_distance, 4, 0] call CBA_fnc_formatNumber; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0, 1, 0, 1], ASLtoAGL _resultPos, 0.5, 0.5, 0, _text, 0.4, 0.025, "TahomaB"]; + drawLine3D [ASLtoAGL _posASL, ASLtoAGL _resultPos, [0,1,0,1]]; +}; +#endif + +END_COUNTER(shootRay); +[_resultPos, _distance]; diff --git a/addons/laser/functions/fnc_showVehicleHud.sqf b/addons/laser/functions/fnc_showVehicleHud.sqf new file mode 100644 index 0000000000..3b9f0adc2f --- /dev/null +++ b/addons/laser/functions/fnc_showVehicleHud.sqf @@ -0,0 +1,114 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Shows the laser hud when vehicle is equiped with the weapon. + * Shows laser code, fire mode and seeker status. + * + * Arguments: + * 0: Player + * + * Return Value: + * Nothing + * + * Example: + * [player] call ace_laser_fnc_showVehicleHud + * + * Public: No + */ + +params ["_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(showHud))) == 1) then { + TRACE_1("showHud",_x); + _enabled = true; + }; + } forEach (_vehicle weaponsTurret _turretPath); +}; + +if ((!_enabled) && (GVAR(pfID) < 0)) exitWith {TRACE_2("Disabled - No Change",_enabled,GVAR(pfID));}; + +TRACE_2("Cleaning up old pfeh and display",_enabled,GVAR(pfID)); +[GVAR(pfID)] call CBA_fnc_removePerFrameHandler; +if (!isNull (uiNamespace getVariable [QGVAR(display), displayNull])) then { + ([QGVAR(modeDisplay)] call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; +}; +GVAR(pfID) = -1; + +if (!_enabled) exitWith {TRACE_2("Disabled - Now Off",_enabled,GVAR(pfID));}; + +TRACE_2("Enabled - Adding PFEH",_enabled,GVAR(pfID)); + +private _adjustDown = false; // Flares display will block ours, if present just move ours down a bit +{ + if ((getText (configFile >> "CfgWeapons" >> _x >> "simulation")) == "cmlauncher") exitWith {_adjustDown = true}; +} forEach (_vehicle weaponsTurret _turretPath); + +private _turretConfig = [_vehicle, _turretPath] call CBA_fnc_getTurret; +private _seekerSource = getText (_turretConfig >> "memoryPointGunnerOptics"); +TRACE_3("",_adjustDown,_seekerSource,_vehicle selectionPosition _seekerSource); + +GVAR(pfID) = [{ + params ["_args", "_pfID"]; + _args params ["_vehicle", "_turretPath", "_seekerSource", "_adjustDown"]; + + // Restart display if null (not just at start, this will happen periodicly) + if (isNull (uiNamespace getVariable [QGVAR(display), displayNull])) then { + TRACE_1("creating display",_this); + ([QGVAR(modeDisplay)] call BIS_fnc_rscLayer) cutRsc [QGVAR(modeDisplay), "PLAIN", 1, false]; + if (_adjustDown) then { + private _ctrl = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_MODECONTROLGROUP; + private _pos = ctrlPosition _ctrl; + _pos set [1, (_pos select 1) + ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)]; + _ctrl ctrlSetPosition _pos; + _ctrl ctrlCommit 0; + }; + }; + + private _currentWeapon = _vehicle currentWeaponTurret _turretPath; + private _showLockMode = (getNumber (configFile >> "CfgWeapons" >> _currentWeapon >> QGVAR(showHud))) == 1; + + private _ctrlGroup = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl 1000; + + if (!_showLockMode) exitWith { + _ctrlGroup ctrlShow false; + }; + _ctrlGroup ctrlShow true; + + private _ctrlText = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_ATTACKMODE; + private _ctrlCode = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_LASERCODE; + 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 _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 _defaultAttackProfile = getText (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "defaultAttackProfile"); + private _vehicleLockMode = _vehicle getVariable [QEGVAR(missileguidance,attackProfile), _defaultAttackProfile]; + + _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); + _ctrlText ctrlSetText _modeShort; + _ctrlCode ctrlSetText format ["CODE: %1", _laserCode]; + +}, 0.1, [_vehicle, _turretPath, _seekerSource, _adjustDown]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/laser/functions/fnc_unitTurretCanLockLaser.sqf b/addons/laser/functions/fnc_unitTurretCanLockLaser.sqf deleted file mode 100644 index 9fe478f623..0000000000 --- a/addons/laser/functions/fnc_unitTurretCanLockLaser.sqf +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Author: jaynus - * Checks if the turret occupied by the given unit can lock a laser designator and select laser code. - * - * Arguments: - * 0: Unit - * - * Return Value: - * Has designator? - */ -#include "script_component.hpp" - -EXPLODE_1_PVT(_this,_unit); - -// Get the player turret path -private ["_turret","_config","_turretConfig"]; -_turret = [_unit] call EFUNC(common,getTurretIndex); -_config = configFile >> "CfgVehicles" >> typeOf vehicle _unit; -_turretConfig = [_config, _turret] call EFUNC(common,getTurretConfigPath); - -getNumber (_turretConfig >> QGVAR(CanLockLaser)) > 0 diff --git a/addons/laser/functions/fnc_vanillaLaserSeekerHandler.sqf b/addons/laser/functions/fnc_vanillaLaserSeekerHandler.sqf deleted file mode 100644 index 7de303dee7..0000000000 --- a/addons/laser/functions/fnc_vanillaLaserSeekerHandler.sqf +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Author: jaynus - * Handler function for laser network code. - * - * Arguments: - * 0: Emitter - * 1: Owner - * - * Return Value: - * [position, direction] - */ -//#define DEBUG_MODE_FULL -#include "script_component.hpp" - -private ["_emmiter", "_owner", "_gunnerInfo", "_turretInfo", "_povPos", "_povDir"]; - -_emmiter = _this select 0; -_owner = _this select 1; - -// Not in a vehicle.... -// @TODO: handle lasering from turrets -if( (vehicle _emmiter) == _emmiter && alive _emmiter && (currentWeapon _emmiter) == "LaserDesignator") exitWith { - [(eyePos _emmiter), (eyeDirection _emmiter)] -}; - -[-1,-1] \ No newline at end of file diff --git a/addons/laser/initKeybinds.sqf b/addons/laser/initKeybinds.sqf index 8ae9d05e9f..418b062fec 100644 --- a/addons/laser/initKeybinds.sqf +++ b/addons/laser/initKeybinds.sqf @@ -1,27 +1,16 @@ + + ["ACE3 Equipment", QGVAR(LaserCodeUp), localize LSTRING(laserCodeUp), { - if( EGVAR(laser_selfdesignate,active) - || - { (currentWeapon ACE_player) == "Laserdesignator" && (call CBA_fnc_getFoV) select 1 > 5 } // If laserdesignator & FOV, we are in scope. - || - { [ACE_player] call FUNC(unitTurretCanLockLaser) } - ) then { - [] call FUNC(keyLaserCodeUp); - }; + [1] call FUNC(keyLaserCodeChange); }, {false}, [16, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+Q) ["ACE3 Equipment", QGVAR(LaserCodeDown), localize LSTRING(laserCodeDown), { - if( EGVAR(laser_selfdesignate,active) - || - { (currentWeapon ACE_player) == "Laserdesignator" && (call CBA_fnc_getFoV) select 1 > 5 } // If laserdesignator & FOV, we are in scope. - || - { [ACE_player] call FUNC(unitTurretCanLockLaser) } - ) then { - [] call FUNC(keyLaserCodeDown); - }; + + [-1] call FUNC(keyLaserCodeChange); }, {false}, [18, [false, true, true]], false, 0] call CBA_fnc_addKeybind; // (ALT+CTRL+E) diff --git a/addons/laser/script_component.hpp b/addons/laser/script_component.hpp index a1c69183df..b0d9951bf3 100644 --- a/addons/laser/script_component.hpp +++ b/addons/laser/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Laser #include "\z\ace\addons\main\script_mod.hpp" +// #define DRAW_LASER_INFO // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_LASER @@ -18,11 +18,13 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define FIREMODE_DIRECT_LOAL 1 - - #define __LaserDesignatorIGUI (uiNamespace getVariable ["ACE_RscOptics_LaserDesignator", nil]) #define __LaserDesignatorIGUI_LaserCode (__LaserDesignatorIGUI displayCtrl 123001) #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/laser/stringtable.xml b/addons/laser/stringtable.xml index 4a478096d0..9d28f10f9e 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -1,6 +1,17 @@  + + Laser Dispersion Simulation Count + レーザーの分散シミュレート数 + Laserstreuung-Simulationszähler + 레이저 분산 시뮬레이션 수 + Wskaźnik poziomu rozproszenia wiązki lasera + Compte de la simulation de la dispersion du laser + Contatore di Simulazione della Dispersione del Laser + 雷射散射模拟计算 + 雷射散射模擬計算 + Laser Code Lasercode @@ -12,6 +23,10 @@ Código del láser Laser kód Codice laser + レーザ コード + 레이저 코드 + 雷射码 + 雷射碼 Laser - Cycle Code Up @@ -23,7 +38,11 @@ Lézer - kódciklus növelése Láser - Aumentar código Laser - Kód + - Codice laser + + Laser - Cambia codice + + レーザ - コードの数値を増やす + 레이저 - 코드 순환 위 + 雷射 - 循环切换雷射码 上 + 雷射 - 循環切換雷射碼 上 Laser - Cycle Code Down @@ -35,7 +54,11 @@ Lézer - kódciklus csökkentése Láser - Reducir código Laser - Kód - - Codice laser - + Laser - Cambia codice - + レーザ - コードの数値を減らす + 레이저 - 코드 순환 아래 + 雷射 - 循环切换雷射码 下 + 雷射 - 循環切換雷射碼 下 diff --git a/addons/laser_selfdesignate/$PBOPREFIX$ b/addons/laser_selfdesignate/$PBOPREFIX$ deleted file mode 100644 index 821ffd07ea..0000000000 --- a/addons/laser_selfdesignate/$PBOPREFIX$ +++ /dev/null @@ -1 +0,0 @@ -z\ace\addons\laser_selfdesignate \ No newline at end of file diff --git a/addons/laser_selfdesignate/CfgEventhandlers.hpp b/addons/laser_selfdesignate/CfgEventhandlers.hpp deleted file mode 100644 index 0458ace904..0000000000 --- a/addons/laser_selfdesignate/CfgEventhandlers.hpp +++ /dev/null @@ -1,26 +0,0 @@ - -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_pre_init)); - }; -}; - -class Extended_PostInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_post_init)); - }; -}; - -class Extended_Init_EventHandlers { - class Helicopter { - class ADDON { - init = QUOTE(_this call DFUNC(initDesignatorActions)); - }; - }; -}; diff --git a/addons/laser_selfdesignate/CfgVehicles.hpp b/addons/laser_selfdesignate/CfgVehicles.hpp deleted file mode 100644 index 8eb84326c5..0000000000 --- a/addons/laser_selfdesignate/CfgVehicles.hpp +++ /dev/null @@ -1,49 +0,0 @@ -class CfgVehicles { - class AllVehicles; - class Air: AllVehicles { - class Turrets; - }; - - class Helicopter: Air { - class Turrets { - class MainTurret; - }; - }; - - class Helicopter_Base_F: Helicopter {}; - - class Heli_Attack_01_base_F: Helicopter_Base_F {}; - - class B_Heli_Attack_01_F: Heli_Attack_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 0; // Enable laser self-designation - }; - }; - }; - - class Plane: Air {}; - class Plane_Base_F: Plane { - class Turrets { - class CopilotTurret; - }; - }; - - /* @TODO: LGB GBU - class Plane_CAS_01_base_F: Plane_Base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; // Enable laser self-designation - }; - }; - }; - - class Plane_CAS_02_base_F: Plane_Base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - GVAR(Enabled) = 1; // Enable laser self-designation - }; - }; - }; - */ -}; diff --git a/addons/laser_selfdesignate/CfgWeapons.hpp b/addons/laser_selfdesignate/CfgWeapons.hpp deleted file mode 100644 index 802e2ba6a5..0000000000 --- a/addons/laser_selfdesignate/CfgWeapons.hpp +++ /dev/null @@ -1,11 +0,0 @@ -class CfgWeapons { - // Disable locking unless newb mode - class LauncherCore; - class RocketPods: LauncherCore { - // canLock = 1; - }; - - class missiles_DAGR: RocketPods { - //canLock = 1; - }; -}; diff --git a/addons/laser_selfdesignate/README.md b/addons/laser_selfdesignate/README.md deleted file mode 100644 index 75b3d2753b..0000000000 --- a/addons/laser_selfdesignate/README.md +++ /dev/null @@ -1,12 +0,0 @@ -ace_laser_selfdesignate -======================= - -Allows gunners to lase their own targets. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [walterpearce](https://github.com/walterpearce) -- [NouberNou](https://github.com/NouberNou) diff --git a/addons/laser_selfdesignate/XEH_PREP.hpp b/addons/laser_selfdesignate/XEH_PREP.hpp deleted file mode 100644 index 6c05680db4..0000000000 --- a/addons/laser_selfdesignate/XEH_PREP.hpp +++ /dev/null @@ -1,7 +0,0 @@ - -PREP(initDesignatorActions); -PREP(laserHudDesignateOn); -PREP(laserHudDesignateOff); -PREP(unitTurretHasDesignator); - -PREP(findLaserSource); diff --git a/addons/laser_selfdesignate/XEH_post_init.sqf b/addons/laser_selfdesignate/XEH_post_init.sqf deleted file mode 100644 index 6eccf9d1dd..0000000000 --- a/addons/laser_selfdesignate/XEH_post_init.sqf +++ /dev/null @@ -1,2 +0,0 @@ -#include "script_component.hpp" - diff --git a/addons/laser_selfdesignate/XEH_pre_init.sqf b/addons/laser_selfdesignate/XEH_pre_init.sqf deleted file mode 100644 index f957638ba2..0000000000 --- a/addons/laser_selfdesignate/XEH_pre_init.sqf +++ /dev/null @@ -1,11 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -#include "XEH_PREP.hpp" - -GVAR(active) = false; - -FUNC(getPosASL) = {visiblePositionASL (_this select 0)}; - -ADDON = true; diff --git a/addons/laser_selfdesignate/config.cpp b/addons/laser_selfdesignate/config.cpp deleted file mode 100644 index e95d754809..0000000000 --- a/addons/laser_selfdesignate/config.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "script_component.hpp" - -class CfgPatches { - class ADDON { - name = COMPONENT_NAME; - units[] = {}; - weapons[] = {}; - requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_laser"}; - author = ECSTRING(common,ACETeam); - url = ECSTRING(main,URL); - VERSION_CONFIG; - }; -}; - -#include "CfgEventhandlers.hpp" -#include "CfgWeapons.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/laser_selfdesignate/functions/fnc_findLaserSource.sqf b/addons/laser_selfdesignate/functions/fnc_findLaserSource.sqf deleted file mode 100644 index ba2e6a4100..0000000000 --- a/addons/laser_selfdesignate/functions/fnc_findLaserSource.sqf +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Author: jaynus - * Handler function for laser network code. - * - * Arguments: - * 0: Emitter - * - * Return Value: - * 0: position - * 1: direction - * - * Public: No - */ -#include "script_component.hpp" - -private ["_gunnerInfo", "_turretInfo"]; -params ["_emmiter"]; - -_gunnerInfo = [_emmiter, (currentWeapon _emmiter)] call CBA_fnc_getFirer; -_turretInfo = [_emmiter, _gunnerInfo select 1] call EFUNC(common,getTurretDirection); -_turretInfo params [["_povPos", -1], ["_povDir", -1]]; - -[_povPos, _povDir] diff --git a/addons/laser_selfdesignate/functions/fnc_initDesignatorActions.sqf b/addons/laser_selfdesignate/functions/fnc_initDesignatorActions.sqf deleted file mode 100644 index 5afc581619..0000000000 --- a/addons/laser_selfdesignate/functions/fnc_initDesignatorActions.sqf +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Author: esteldunedain - * Initializes the actions for turning on/off the laser for vehicles that have them - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Public: No - */ -#include "script_component.hpp" - -params ["_vehicle"]; - -// Add action to class if it is not already done -private ["_type", "_initializedClasses"]; -_type = typeOf _vehicle; -_initializedClasses = GETGVAR(initializedClasses,[]); - -// do nothing if the class is already initialized -if (_type in _initializedClasses) exitWith {}; -_initializedClasses pushBack _type; -GVAR(initializedClasses) = _initializedClasses; - -{ - private ["_turretConfig","_onAction","_offAction"]; - _turretConfig = [configFile >> "CfgVehicles" >> _type, _x] call EFUNC(common,getTurretConfigPath); - - if (getNumber (_turretConfig >> QGVAR(Enabled)) == 1) exitWith { - // @todo: Add the state variables to the vehicle, instead of to the client - // e.g.: _vehicle setVariable [format ["%1_%2", QGVAR(active), _x], false]; - - // Add actions - _onAction = [QGVAR(LaserOn), localize LSTRING(DesignatorOn), "", - { - // Statement - _this call FUNC(laserHudDesignateOn) - }, - { - // Condition - !GVAR(active) && {[ACE_player] call FUNC(unitTurretHasDesignator)} - }] call EFUNC(interact_menu,createAction); - - _offAction = [QGVAR(LaserOff), localize LSTRING(DesignatorOff), "", - { - // Statement - _this call FUNC(laserHudDesignateOff) - }, - { - // Condition - GVAR(active) && {[ACE_player] call FUNC(unitTurretHasDesignator)} - }] call EFUNC(interact_menu,createAction); - - [_type, 1, ["ACE_SelfActions"], _onAction] call EFUNC(interact_menu,addActionToClass); - [_type, 1, ["ACE_SelfActions"], _offAction] call EFUNC(interact_menu,addActionToClass); - }; -} forEach allTurrets _vehicle; diff --git a/addons/laser_selfdesignate/functions/fnc_laserHudDesignateOff.sqf b/addons/laser_selfdesignate/functions/fnc_laserHudDesignateOff.sqf deleted file mode 100644 index be1793668d..0000000000 --- a/addons/laser_selfdesignate/functions/fnc_laserHudDesignateOff.sqf +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Author: jaynus - * Turns off passed laser self designation. - * - * Arguments: - * 0: Shooter, player shooting the laser - * 1: LaserUUID, the UUID of the laser returned by EFUNC(laser,laserOn) - * 2: Local laser target, unused. - * - * Return Value: - * True - */ -#include "script_component.hpp" - -if( (count _this) > 2) then { - params ["", "_laserUuid"]; - [_laserUuid] call EFUNC(laser,laserOff); - // @TODO: Nou gets to field all tickets about missing lasers. - //deleteVehicle _localLaserTarget; -}; - -GVAR(active) = false; - -if(!isNil QGVAR(selfDesignateHandle)) then { - [GVAR(selfDesignateHandle)] call CBA_fnc_removePerFrameHandler; - GVAR(selfDesignateHandle) = nil; -}; - -true diff --git a/addons/laser_selfdesignate/functions/fnc_laserHudDesignateOn.sqf b/addons/laser_selfdesignate/functions/fnc_laserHudDesignateOn.sqf deleted file mode 100644 index d77360ce49..0000000000 --- a/addons/laser_selfdesignate/functions/fnc_laserHudDesignateOn.sqf +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Author: jaynus - * Turns on laser self designation from this vehicle based on the turret. - * There are no arguments, because it is all strictly based on the users vehicle. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Public: No - */ -#include "script_component.hpp" - -TRACE_1("enter", _this); - -#define FCS_UPDATE_DELAY 1 - -FUNC(laserHudDesignatePFH) = { - private ["_strongestResultPos", "_args", "_localLaserTarget", "_laserResultPosition", "_laserResult", "_shooter", "_vehicle", "_weapon", "_gunnerInfo", "_turretInfo", "_pov", "_gunBeg", "_gunEnd", "_povPos", "_povDir", "_result", "_resultPositions", "_firstResult", "_forceUpdateTime"]; - params ["_args"]; - _args params ["_shooter", "_localLaserTarget"]; - _vehicle = vehicle _shooter; - TRACE_1("", _args); - - if((vehicle _shooter) == _shooter || {!alive _shooter} || {isNull _vehicle} || {!GVAR(active)} ) exitWith { - _args call FUNC(laserHudDesignateOff); - }; - if(!([_shooter] call FUNC(unitTurretHasDesignator)) ) exitWith { - _args call FUNC(laserHudDesignateOff); - }; - - if( (count _args) < 4) then { - _args set[3, diag_tickTime + FCS_UPDATE_DELAY]; - }; - _forceUpdateTime = _args select 3; - - // @TODO: We don't have anything here we need to do the calculations for right now - /* - - _gunnerInfo = [_vehicle, (currentWeapon _vehicle)] call CBA_fnc_getFirer; - _turretInfo = [_vehicle, _gunnerInfo select 1] call EFUNC(common,getTurretDirection); - _povPos = _turretInfo select 0; - - _laserCode = (vehicle ACE_player) getVariable["ace_laser_code", ACE_DEFAULT_LASER_CODE]; - _waveLength = (vehicle ACE_player) getVariable["ace_laser_waveLength", ACE_DEFAULT_LASER_WAVELENGTH]; - - - _laserResult = [_povPos, [_waveLength,_waveLength], _laserCode] call EFUNC(laser,seekerFindLaserSpot); - _laserResultPosition = _laserResult select 0; - TRACE_1("Search", _laserResult); - - if((count _laserResult) > 0) then { - // @TODO: Nou gets to field all tickets about missing lasers. - //_localLaserTarget setPosASL _laserResultPosition; - }; - */ - - if(diag_tickTime > _forceUpdateTime) then { - ["ace_fcs_forceUpdate", []] call ace_common_fnc_localEvent; - _args set[3, diag_tickTime + FCS_UPDATE_DELAY]; - }; - - _this set[0, _args]; -}; - -private ["_laserTarget", "_handle", "_vehicle", "_laserUuid", "_waveLength", "_beamSpread", "_laserCode"]; - -if(!GVAR(active)) then { - GVAR(active) = true; - - TRACE_1("Activating laser", ""); - - // Get the self-designation variables, or use defaults - _laserCode = (vehicle ACE_player) getVariable["ace_laser_code", ACE_DEFAULT_LASER_CODE]; - _waveLength = (vehicle ACE_player) getVariable["ace_laser_waveLength", ACE_DEFAULT_LASER_WAVELENGTH]; - _beamSpread = (vehicle ACE_player) getVariable["ace_laser_beamSpread", ACE_DEFAULT_LASER_BEAMSPREAD]; - - _laserUuid = [(vehicle ACE_player), ACE_player, QFUNC(findLaserSource), _waveLength, _laserCode, _beamSpread] call EFUNC(laser,laserOn); - - // @TODO: Create the local target for the players side - // @TODO: Nou gets to field all tickets about missing lasers. - //_localLaserTarget = "LaserTargetW" createVehicleLocal (getpos ACE_player); - - GVAR(selfDesignateHandle) = [FUNC(laserHudDesignatePFH), 0.1, [ACE_player, _laserUuid, nil]] call CBA_fnc_addPerFrameHandler; -} else { - [] call FUNC(laserHudDesignateOff); - [] call FUNC(laserHudDesignateOn); -}; diff --git a/addons/laser_selfdesignate/functions/fnc_unitTurretHasDesignator.sqf b/addons/laser_selfdesignate/functions/fnc_unitTurretHasDesignator.sqf deleted file mode 100644 index 46c3afaaa3..0000000000 --- a/addons/laser_selfdesignate/functions/fnc_unitTurretHasDesignator.sqf +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Author: esteldunedain - * Checks if the turret occupied by the given unit has a laser designator - * - * Arguments: - * 0: Unit - * - * Return Value: - * Has unit designator - * - * Public: No - */ -#include "script_component.hpp" - -params ["_unit"]; - -// Get the player turret path -private ["_turret","_config","_turretConfig"]; -_turret = [_unit] call EFUNC(common,getTurretIndex); -_config = configFile >> "CfgVehicles" >> typeOf vehicle _unit; -_turretConfig = [_config, _turret] call EFUNC(common,getTurretConfigPath); - -getNumber (_turretConfig >> QGVAR(Enabled)) > 0 diff --git a/addons/laser_selfdesignate/functions/script_component.hpp b/addons/laser_selfdesignate/functions/script_component.hpp deleted file mode 100644 index 845a51c186..0000000000 --- a/addons/laser_selfdesignate/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\laser_selfdesignate\script_component.hpp" diff --git a/addons/laser_selfdesignate/script_component.hpp b/addons/laser_selfdesignate/script_component.hpp deleted file mode 100644 index 583aca5e95..0000000000 --- a/addons/laser_selfdesignate/script_component.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#define COMPONENT laser_selfdesignate -#define COMPONENT_BEAUTIFIED Laser Selfdesignate -#include "\z\ace\addons\main\script_mod.hpp" - -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS -// #define ENABLE_PERFORMANCE_COUNTERS - -#ifdef DEBUG_ENABLED_LASER_SELFDESIGNATE - #define DEBUG_MODE_FULL -#endif - -#ifdef DEBUG_SETTINGS_LASER_SELFDESIGNATE - #define DEBUG_SETTINGS DEBUG_SETTINGS_LASER_SELFDESIGNATE -#endif - -#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/laser_selfdesignate/stringtable.xml b/addons/laser_selfdesignate/stringtable.xml deleted file mode 100644 index cdd7439200..0000000000 --- a/addons/laser_selfdesignate/stringtable.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Laser Designator On - Lasermarkierer an - Designador láser encendido - ЛЦУ ВКЛ - Laserový značkovač zapnut - Desygnator laserowy wł. - Désignateur laser allumé - Lézeres Megjelölő Be - Designatore laser acceso - Designador Laser Ligado - - - Laser Designator Off - Lasermarkierer aus - Designador láser apagado - ЛЦУ ВЫКЛ - Laserový značkovat vypnut - Desygnator laserowy wył. - Désignateur laser éteint - Lézeres Megjelölő Ki - Designatore laser spento - Designador Laser Desligado - - - 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/CfgEventHandlers.hpp b/addons/laserpointer/CfgEventHandlers.hpp index becf395052..0d3301d6e0 100644 --- a/addons/laserpointer/CfgEventHandlers.hpp +++ b/addons/laserpointer/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); diff --git a/addons/laserpointer/CfgWeapons.hpp b/addons/laserpointer/CfgWeapons.hpp index 608d025a01..6afa29a344 100644 --- a/addons/laserpointer/CfgWeapons.hpp +++ b/addons/laserpointer/CfgWeapons.hpp @@ -9,16 +9,18 @@ class CfgWeapons { class InventoryFlashLightItem_Base_F; class acc_pointer_IR: ItemCore { - ACE_nextModeClass = "ACE_acc_pointer_red"; - ACE_modeDescription = CSTRING(IRLaser); + MRT_SwitchItemNextClass = "ACE_acc_pointer_red"; + MRT_SwitchItemPrevClass = "ACE_acc_pointer_red"; + MRT_switchItemHintText = CSTRING(IRLaser); displayName = CSTRING(red); descriptionUse = CSTRING(useLaser); }; class ACE_acc_pointer_red: ItemCore { - ACE_nextModeClass = "acc_pointer_IR"; - ACE_modeDescription = CSTRING(Laser); + MRT_SwitchItemNextClass = "acc_pointer_IR"; + MRT_SwitchItemPrevClass = "acc_pointer_IR"; + MRT_switchItemHintText = CSTRING(Laser); ACE_laserpointer = 1; @@ -34,7 +36,11 @@ class CfgWeapons { class ItemInfo: InventoryFlashLightItem_Base_F { mass = 6; - class Pointer {}; + class Pointer { + irLaserPos = "laser pos"; + irLaserEnd = "laser dir"; + irDistance = 5; + }; class FlashLight { color[] = {0,0,0}; @@ -68,8 +74,9 @@ class CfgWeapons { }; class ACE_acc_pointer_green_IR: acc_pointer_IR { - ACE_nextModeClass = "ACE_acc_pointer_green"; - ACE_modeDescription = CSTRING(IRLaser); + MRT_SwitchItemNextClass = "ACE_acc_pointer_green"; + MRT_SwitchItemPrevClass = "ACE_acc_pointer_green"; + MRT_switchItemHintText = CSTRING(IRLaser); author = ECSTRING(common,ACETeam); _generalMacro = "ACE_acc_pointer_green"; @@ -78,8 +85,9 @@ class CfgWeapons { }; class ACE_acc_pointer_green: ACE_acc_pointer_red { - ACE_nextModeClass = "ACE_acc_pointer_green_IR"; - ACE_modeDescription = CSTRING(Laser); + MRT_SwitchItemNextClass = "ACE_acc_pointer_green_IR"; + MRT_SwitchItemPrevClass = "ACE_acc_pointer_green_IR"; + MRT_switchItemHintText = CSTRING(Laser); ACE_laserpointer = 2; diff --git a/addons/laserpointer/XEH_PREP.hpp b/addons/laserpointer/XEH_PREP.hpp index c5dcd74a75..59a28bb4cc 100644 --- a/addons/laserpointer/XEH_PREP.hpp +++ b/addons/laserpointer/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(drawLaserpoint); +PREP(getNearUnits); PREP(onDraw); -PREP(switchLaserLightMode); diff --git a/addons/laserpointer/XEH_postInit.sqf b/addons/laserpointer/XEH_postInit.sqf index 219c70d372..7e90e29259 100644 --- a/addons/laserpointer/XEH_postInit.sqf +++ b/addons/laserpointer/XEH_postInit.sqf @@ -2,33 +2,90 @@ #include "script_component.hpp" // fixes laser when being captured. Needed, because the selectionPosition of the right hand is used -[QEGVAR(captives,setHandcuffed), {if (_this select 1) then {(_this select 0) action ["ace_gunLightOff", _this select 0]};}] call CBA_fnc_addEventHandler; +[QEGVAR(captives,setHandcuffed), {if (_this select 1) then {(_this select 0) action ["GunLightOff", _this select 0]};}] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; GVAR(nearUnits) = []; - -#include "initKeybinds.sqf" +GVAR(index) = -1; +GVAR(laserClassesCache) = [] call CBA_fnc_createNamespace; +GVAR(redLaserUnits) = []; +GVAR(greenLaserUnits) = []; ["ace_settingsInitialized", { - //If not enabled, dont't add draw eventhandler or PFEH (for performance) - if (!GVAR(enabled)) exitWith {}; - - // @todo. Maybe move to common? - [{ - private _nearUnits = []; - { - _nearUnits append crew _x; - if (count _nearUnits > 10) exitWith { - _nearUnits resize 10; + // If not enabled, dont't add draw eventhandler or PFEH (for performance) + if (!GVAR(enabled)) exitWith { + ["CBA_attachmentSwitched", { + params ["_unit", "_prevItem", "_newItem", "_currWeaponType"]; + TRACE_4("CBA_attachmentSwitched eh",_unit,_prevItem,_newItem,_currWeaponType); + if ((getNumber (configFile >> "CfgWeapons" >> _newItem >> "ACE_laserpointer")) > 0) then { + TRACE_1("removing ACE_laserpointer",getNumber (configFile >> "CfgWeapons" >> _newItem >> "ACE_laserpointer")); + [1, "prev"] call CBA_accessory_fnc_switchAttachment; }; - } forEach nearestObjects [positionCameraToWorld [0,0,0], ["AllVehicles"], 50]; // when moving this, search also for units inside vehicles. currently breaks the laser in FFV + }] call CBA_fnc_addEventHandler; + }; - GVAR(nearUnits) = _nearUnits; + [{ + private _oldNearUnits = GVAR(nearUnits); + GVAR(nearUnits) = call FUNC(getNearUnits); - } , 5, []] call CBA_fnc_addPerFrameHandler; + // remove units that moved away + { + GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _x); + GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _x); + } forEach (_oldNearUnits - GVAR(nearUnits)); + }, 5, []] call CBA_fnc_addPerFrameHandler; - addMissionEventHandler ["Draw3D", { - call FUNC(onDraw); - }]; + + private _fnc_processUnit = { + params ["_unit"]; + + private _weapon = currentWeapon _unit; + if (!(_unit isFlashlightOn _weapon)) exitWith { + GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _unit); + GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _unit); + }; + + private _laser = [(_unit weaponAccessories _weapon) select 1] param [0, ""]; + if (_laser isEqualTo "") exitWith { + GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _unit); + GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _unit); + }; + + private _laserID = GVAR(laserClassesCache) getVariable _laser; + + if (isNil "_laserID") then { + _laserID = getNumber (configFile >> "CfgWeapons" >> _laser >> "ACE_laserpointer"); + GVAR(laserClassesCache) setVariable [_laser, _laserID]; + }; + TRACE_3("",_weapon,_laser,_laserID); + + if (_laserID isEqualTo 1) exitWith { + GVAR(redLaserUnits) pushBackUnique _unit; + GVAR(greenLaserUnits) deleteAt (GVAR(greenLaserUnits) find _unit); + }; + + if (_laserID isEqualTo 2) exitWith { + GVAR(greenLaserUnits) pushBackUnique _unit; + GVAR(redLaserUnits) deleteAt (GVAR(redLaserUnits) find _unit); + }; + }; + + // custom scheduler + [{ + params ["_fnc_processUnit"]; + + ACE_player call _fnc_processUnit; + + GVAR(index) = GVAR(index) + 1; + private _unit = GVAR(nearUnits) param [GVAR(index), objNull]; + + if (isNull _unit) exitWith { + GVAR(index) = -1; + }; + + _unit call _fnc_processUnit; + }, 0.1, _fnc_processUnit] call CBA_fnc_addPerFrameHandler; + + addMissionEventHandler ["Draw3D", {call FUNC(onDraw)}]; }] call CBA_fnc_addEventHandler; diff --git a/addons/laserpointer/XEH_preInit.sqf b/addons/laserpointer/XEH_preInit.sqf index a7feade1c3..d2efe43e9c 100644 --- a/addons/laserpointer/XEH_preInit.sqf +++ b/addons/laserpointer/XEH_preInit.sqf @@ -2,6 +2,15 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +["visionMode", { + params ["", "_visionMode"]; + + GVAR(isIR) = _visionMode isEqualTo 1; + GVAR(isTI) = _visionMode isEqualTo 2; +}] call CBA_fnc_addPlayerEventHandler; ADDON = true; diff --git a/addons/laserpointer/config.cpp b/addons/laserpointer/config.cpp index add36aeff5..4058157660 100644 --- a/addons/laserpointer/config.cpp +++ b/addons/laserpointer/config.cpp @@ -19,8 +19,3 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "CfgJointRails.hpp" - -class ACE_newEvents { - GunLightOff = "ace_gunLightOff"; - SetHandcuffed = QEGVAR(captives,setHandcuffed); -}; diff --git a/addons/laserpointer/functions/fnc_drawLaserpoint.sqf b/addons/laserpointer/functions/fnc_drawLaserpoint.sqf index 3ea9ed158b..ab7724fda5 100644 --- a/addons/laserpointer/functions/fnc_drawLaserpoint.sqf +++ b/addons/laserpointer/functions/fnc_drawLaserpoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 and esteldunedain * Draw a Laser Point @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target", "_range", "_isGreen", "_brightness"]; @@ -85,7 +85,7 @@ private _size = 2 * sqrt (1 / _distance) * (call EFUNC(common,getZoom)); drawIcon3D [ format ["\a3\weapons_f\acc\data\collimdot_%1_ca.paa", ["red", "green"] select _isGreen], - [[1,0.25,0.25,0.5*_brightness], [0.25,1,0.25,0.5*_brightness]] select _isGreen, + [[1,0.25,0.25,0.6*_brightness], [0.25,1,0.25,0.5*_brightness]] select _isGreen, _pL, _size, _size, diff --git a/addons/laserpointer/functions/fnc_getNearUnits.sqf b/addons/laserpointer/functions/fnc_getNearUnits.sqf new file mode 100644 index 0000000000..38b1a32ed9 --- /dev/null +++ b/addons/laserpointer/functions/fnc_getNearUnits.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * Author: commy2 + * Reports near units. + * + * Arguments: + * None + * + * Return Value: + * Near Units + * + * Example: + * call ACE_laserpointer_fnc_getNearUnits + * + * Public: No + */ + +private _camPosAGL = positionCameraToWorld [0, 0, 0]; + +// handle RHS / bugged vehicle slots +if !((_camPosAGL select 0) isEqualType 0) exitWith { [] }; + +private _nearUnits = []; + +{ + _nearUnits append crew _x; +} forEach nearestObjects [_camPosAGL, ["AllVehicles"], MAX_LASER_RANGE]; + +_nearUnits diff --git a/addons/laserpointer/functions/fnc_onDraw.sqf b/addons/laserpointer/functions/fnc_onDraw.sqf index 1945dcf2b7..bfee8a7ea6 100644 --- a/addons/laserpointer/functions/fnc_onDraw.sqf +++ b/addons/laserpointer/functions/fnc_onDraw.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Draw the visible laser beams of all cached units. @@ -8,34 +9,22 @@ * Return Value: * None * + * Example: + * call ACE_laserpointer_fnc_onDraw + * * Public: No */ -#include "script_component.hpp" -private _isIR = currentVisionMode ACE_player; +if (count GVAR(redLaserUnits) + count GVAR(greenLaserUnits) > 0 && {!GVAR(isTI)}) then { + private _brightness = 2 - call EFUNC(common,ambientBrightness); -if (_isIR == 2) exitWith {}; + { + // red laser. draw green dot anyway in IR mode + [_x, 100, GVAR(isIR), _brightness] call FUNC(drawLaserpoint); + } count GVAR(redLaserUnits); -_isIR = _isIR == 1; - -private _brightness = 2 - call EFUNC(common,ambientBrightness); - -{ - private _weapon = currentWeapon _x; - private _laser = (_x weaponAccessories _weapon) select 1; - - if (_laser != "") then { - private _cacheName = format [QGVAR(laser_%1), _laser]; - private _laserID = missionNamespace getVariable [_cacheName, -1]; - - if (missionNamespace getVariable [_cacheName, -1] == -1) then { - _laserID = getNumber (configFile >> "CfgWeapons" >> _laser >> "ACE_laserpointer"); - missionNamespace setVariable [_cacheName, _laserID]; - }; - - if (_laserID > 0 && {_x isFlashlightOn _weapon}) then { - [_x, 100, (_laserID == 2 || _isIR), _brightness] call FUNC(drawLaserpoint); - }; - }; - false -} count GVAR(nearUnits); + { + // green laser + [_x, 100, true, _brightness] call FUNC(drawLaserpoint); + } count GVAR(greenLaserUnits); +}; diff --git a/addons/laserpointer/functions/fnc_switchLaserLightMode.sqf b/addons/laserpointer/functions/fnc_switchLaserLightMode.sqf deleted file mode 100644 index e26d5f75c1..0000000000 --- a/addons/laserpointer/functions/fnc_switchLaserLightMode.sqf +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Author: Commy2 - * Switch between laser modes. - * - * Arguments: - * 0: Unit - * 1: Weapon - * - * Return Value: - * None - * - * Public: No - */ -#include "script_component.hpp" - -params ["_unit", "_weapon"]; - -private _pointer = (_unit weaponAccessories _weapon) select 1; - -if (_pointer == "") exitWith {}; - -private _config = configFile >> "CfgWeapons" >> _pointer; - -private _nextPointer = getText (_config >> "ACE_nextModeClass"); - -if (_nextPointer == "") exitWith {}; - -//If system disabled, don't switch to a laser: -private _nextPointerIsLaser = getNumber (configFile >> "CfgWeapons" >> _nextPointer >> "ACE_laserpointer"); -if ((!GVAR(enabled)) && {_nextPointerIsLaser == 1}) exitWith {}; - -// disable inheritance for this entry, because addons claim this as a base class for convenience -if !((_config >> "ACE_nextModeClass") in configProperties [_config, "true", false]) exitWith {}; - -_unit addWeaponItem [_weapon, _nextPointer]; - -private _error = false; - -if ((_unit weaponAccessories _weapon) select 1 != _nextPointer) then { - ERROR("NextPointer not compatible"); - _unit addWeaponItem [_weapon, _pointer]; - _error = true; -}; - -if (!_error) then { - private _description = getText (configFile >> "CfgWeapons" >> _nextPointer >> "ACE_modeDescription"); - private _picture = getText (configFile >> "CfgWeapons" >> _nextPointer >> "picture"); - - [_description, _picture] call EFUNC(common,displayTextPicture); -} else { - ACE_LOGERROR_3("Failed to add %1 to %2 - reverting to %3",_nextPointer,_weapon,_pointer); -}; - -playSound "ACE_Sound_Click"; diff --git a/addons/laserpointer/initKeybinds.sqf b/addons/laserpointer/initKeybinds.sqf deleted file mode 100644 index 2251ddfb71..0000000000 --- a/addons/laserpointer/initKeybinds.sqf +++ /dev/null @@ -1,13 +0,0 @@ -// by commy2 - -["ACE3 Weapons", QGVAR(switchLaserLightMode), localize LSTRING(switchLaserLight), -{ - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; - - [ACE_player, currentWeapon ACE_player] call FUNC(switchLaserLightMode); - true -}, -{false}, [38, [false, true, false]], false] call CBA_fnc_addKeybind; diff --git a/addons/laserpointer/script_component.hpp b/addons/laserpointer/script_component.hpp index 0e450721fd..4b7b2e0d39 100644 --- a/addons/laserpointer/script_component.hpp +++ b/addons/laserpointer/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_LASERPOINTER @@ -16,3 +15,5 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define MAX_LASER_RANGE 50 diff --git a/addons/laserpointer/stringtable.xml b/addons/laserpointer/stringtable.xml index b161b0998c..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) @@ -12,6 +28,10 @@ Puntero láser (rojo) Puntatore laser (rosso) Laser (vermelho) + レーザ ポインタ (赤) + 레이저 지시기 (빨강) + 雷射指示器 (红色) + 雷射指示器 (紅色) Laser Pointer (green) @@ -24,6 +44,10 @@ Puntero láser (verde) Puntatore laser (verde) Laser (verde) + レーザ ポインタ (緑) + 레이저 지시기 (초록) + 雷射指示器 (绿色) + 雷射指示器 (綠色) Emits visible light. @@ -36,6 +60,10 @@ Emite luz visible. Emette luce visibile. Emite luz visível. + 可視光をだします。 + 밝은 곳에서도 보임 + 发射出可见光 + 發射出可見光 <t color='#9cf953'>Use: </t>Turn Laser ON/OFF @@ -48,6 +76,10 @@ <t color='#9cf953'>Использовать: </t>ВКЛ/ВЫКЛ лазер <t color='#9cf953'>Usar: </t>Encender/Apagar láser <t color='#9cf953'>Használat: </t>Lézer BE/KI kapcsolása + <t color='#9cf953'>つかう: </t>レーザの起動/停止 + <t color='#9cf953'>사용키: </t>레이저 켜기/끄기 + <t color='#9cf953'>使用: </t>雷射开启/关闭 + <t color='#9cf953'>使用: </t>雷射開啟/關閉 Laser @@ -60,6 +92,10 @@ Lézer Laser Laser + レーザ + 레이저 + 雷射 + 雷射 IR Laser @@ -72,6 +108,10 @@ Infravörös Lézer IR Laser Laser IV + 赤外線レーザ + 적외선 레이저 + 红外线雷射 + 紅外線雷射 Switch Laser / IR Laser @@ -84,6 +124,10 @@ Lézer / Infravörös Lézer váltása Přepnout Laser / Infračervený Laser Alternar entre Laser / Laser IV + レーザ/赤外線レーザを切り替える + 레이저 / 적외선 레이저 전환 + 切换雷射/红外线雷射 + 切換雷射/紅外線雷射 - \ No newline at end of file + 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/XEH_preInit.sqf b/addons/logistics_uavbattery/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/logistics_uavbattery/XEH_preInit.sqf +++ b/addons/logistics_uavbattery/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf index 451753a9e2..d4e62afa15 100644 --- a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: marc_book * Tests if unit can refuel the target UAV @@ -14,8 +15,7 @@ * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target"]; -("ACE_UAVBattery" in (items _caller)) && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} +("ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))) && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} diff --git a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf index 2bf617478d..c29be7636a 100644 --- a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: marc_book * Starts refueling/recharging the 'Dartar' UAVs @@ -7,14 +8,13 @@ * 1: UAV * * Return Value: - * Nothing + * None * * Example: * [player, theUAV] call ace_logistics_uavbattery_fnc_refuelUAV * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target"]; if (!(_this call FUNC(canRefuelUAV))) exitWith {}; diff --git a/addons/logistics_uavbattery/script_component.hpp b/addons/logistics_uavbattery/script_component.hpp index 464118c01f..6232900558 100644 --- a/addons/logistics_uavbattery/script_component.hpp +++ b/addons/logistics_uavbattery/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_LOGISTICS_UAVBATTERY diff --git a/addons/logistics_uavbattery/stringtable.xml b/addons/logistics_uavbattery/stringtable.xml index ea0cea97eb..412e000d9b 100644 --- a/addons/logistics_uavbattery/stringtable.xml +++ b/addons/logistics_uavbattery/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ O VANT está cheio Il drone è pieno БПЛА полностью заряжен + ドローンは充電完了 + 무인기 충전완료 + 无人载具电池已充满 + 無人載具電池已充滿 You need a UAV Battery @@ -24,6 +28,10 @@ Você precisa de uma bateria para VANTs Hai bisogno di una Batteria UAV Требуется аккумулятор для БПЛА + UAV バッテリが必要です + 무인기 배터리가 필요합니다 + 你需要一个无人载具电池 + 你需要一個無人載具電池 Recharge @@ -36,6 +44,10 @@ Recarregar Ricarica Зарядить + 充電 + 재충전 + 充电 + 充電 UAV Battery @@ -48,6 +60,10 @@ Bateria para VANT Batteria UAV Аккумулятор БПЛА + UAV バッテリ + 무인기 배터리 + 无人载具电池 + 無人載具電池 Used to refuel Carried UAV's @@ -60,6 +76,10 @@ Usada para reabastecer o VANT Usata per ricaricare la Batteria dell'UAV Используется для зарядки переносных БПЛА + 運んでいる UAV を充電に使う + 무인기를 재충전 할때 씁니다. + 对可携式无人载具进行充电 + 對可攜式無人載具進行充電 Recharging... @@ -72,6 +92,10 @@ Recarregando... In ricarica... Заряжается... + 充電しています・・・ + 充电中... + 充電中... + 충전중... - \ No newline at end of file + diff --git a/addons/logistics_wirecutter/CfgEventHandlers.hpp b/addons/logistics_wirecutter/CfgEventHandlers.hpp index 47564cbd2d..36c0fca8a3 100644 --- a/addons/logistics_wirecutter/CfgEventHandlers.hpp +++ b/addons/logistics_wirecutter/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); @@ -13,6 +12,6 @@ class Extended_PreInit_EventHandlers { class Extended_PostInit_EventHandlers { class ADDON { - clientInit = QUOTE( call COMPILE_FILE(XEH_clientInit) ); + clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit)); }; }; diff --git a/addons/logistics_wirecutter/CfgSounds.hpp b/addons/logistics_wirecutter/CfgSounds.hpp deleted file mode 100644 index 598e72255b..0000000000 --- a/addons/logistics_wirecutter/CfgSounds.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class CfgSounds { - class ACE_Wirecutter_sound { - name = "ACE_wirecutter_sound"; - sound[] = {QPATHTOF(sound\wire_cut.ogg), "db-0", 1}; - titles[] = {}; - }; - class ACE_Wirecutter_sound_long { - name = "ACE_wirecutter_sound_long"; - sound[] = {QPATHTOF(sound\wire_cut_long.ogg), "db-0", 1}; - titles[] = {}; - }; -}; diff --git a/addons/logistics_wirecutter/CfgVehicles.hpp b/addons/logistics_wirecutter/CfgVehicles.hpp index d9c2943d45..7dd57f207f 100644 --- a/addons/logistics_wirecutter/CfgVehicles.hpp +++ b/addons/logistics_wirecutter/CfgVehicles.hpp @@ -8,19 +8,76 @@ class CfgVehicles { class Wall_F; class NonStrategic; - - class Land_Net_Fence_4m_F: Wall_F { GVAR(isFence) = 1; }; - class Land_Net_Fence_8m_F: Wall_F { GVAR(isFence) = 1; }; - class Land_New_WiredFence_5m_F: Wall_F { GVAR(isFence) = 1; }; - class Land_New_WiredFence_10m_F: Wall_F { GVAR(isFence) = 1; }; - class Land_SportGround_fence_F: Wall_F { GVAR(isFence) = 1; }; - class Land_Wired_Fence_4m_F: Wall_F { GVAR(isFence) = 1; }; - class Land_Wired_Fence_8m_F: Wall_F { GVAR(isFence) = 1; }; - class Land_SportGround_fence_noLC_F: Wall_F { GVAR(isFence) = 1; }; - class Land_Mil_WiredFence_F: Wall_F { GVAR(isFence) = 1; }; - class Land_IndFnc_Corner_F: Wall_F { GVAR(isFence) = 1; }; - class Land_IndFnc_9_F: Wall_F { GVAR(isFence) = 1; }; - class Land_IndFnc_3_Hole_F: Wall_F { GVAR(isFence) = 1; }; - class Land_IndFnc_3_F: Wall_F { GVAR(isFence) = 1; }; - class Land_Razorwire_F: NonStrategic { GVAR(isFence) = 1; }; + class Land_Net_Fence_4m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_Net_Fence_8m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_New_WiredFence_5m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_New_WiredFence_10m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_SportGround_fence_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_Wired_Fence_4m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_Wired_Fence_8m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_SportGround_fence_noLC_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_Mil_WiredFence_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_IndFnc_Corner_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_IndFnc_9_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_IndFnc_3_Hole_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_IndFnc_3_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_Razorwire_F: NonStrategic { + GVAR(isFence) = 1; + }; + class Land_PlasticNetFence_01_short_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_PlasticNetFence_01_long_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_NetFence_01_m_4m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_NetFence_01_m_8m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_WiredFence_01_4m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_WiredFence_01_8m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_WiredFence_01_16m_F: Wall_F { + GVAR(isFence) = 1; + }; + class Land_Slums01_8m: Wall_F { + GVAR(isFence) = 1; + }; + class Land_Slums02_4m: Wall_F { + GVAR(isFence) = 1; + }; + class Land_BackAlley_01_l_1m_F: Wall_F { + GVAR(isFence) = 1; + }; }; diff --git a/addons/logistics_wirecutter/CfgWeapons.hpp b/addons/logistics_wirecutter/CfgWeapons.hpp index 2cb7e7b7b1..cfaa6c3259 100644 --- a/addons/logistics_wirecutter/CfgWeapons.hpp +++ b/addons/logistics_wirecutter/CfgWeapons.hpp @@ -1,6 +1,6 @@ class CfgWeapons { - class InventoryItem_Base_F; class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; class ACE_wirecutter: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -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/README.md b/addons/logistics_wirecutter/README.md index 89d42c419f..b40242cd86 100644 --- a/addons/logistics_wirecutter/README.md +++ b/addons/logistics_wirecutter/README.md @@ -1,7 +1,7 @@ ace_logistics_wirecutter =========== -Adds an item that allows cutting of fences in Aarma 3 and AiA/CUP maps. +Adds an item that allows cutting of fences in Arma 3 and AiA/CUP maps. #### Items Added: `ACE_wirecutter` diff --git a/addons/logistics_wirecutter/XEH_PREP.hpp b/addons/logistics_wirecutter/XEH_PREP.hpp index d52c83547b..6ab95824ff 100644 --- a/addons/logistics_wirecutter/XEH_PREP.hpp +++ b/addons/logistics_wirecutter/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(cutDownFence); PREP(interactEH); PREP(isFence); diff --git a/addons/logistics_wirecutter/XEH_preInit.sqf b/addons/logistics_wirecutter/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/logistics_wirecutter/XEH_preInit.sqf +++ b/addons/logistics_wirecutter/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/logistics_wirecutter/config.cpp b/addons/logistics_wirecutter/config.cpp index 25c58f1604..c68f362be8 100644 --- a/addons/logistics_wirecutter/config.cpp +++ b/addons/logistics_wirecutter/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interaction"}; author = ECSTRING(common,ACETeam); - authors[] = {"gpgpgpgp", "PabstMirror"}; + authors[] = {"gpgpgpgp", "PabstMirror", "mharis001"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; @@ -17,7 +17,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; -}; \ No newline at end of file diff --git a/addons/logistics_wirecutter/data/ace_wirecutter.rvmat b/addons/logistics_wirecutter/data/ace_wirecutter.rvmat index 1983a2c8f1..2afba8dcbc 100644 --- a/addons/logistics_wirecutter/data/ace_wirecutter.rvmat +++ b/addons/logistics_wirecutter/data/ace_wirecutter.rvmat @@ -1,6 +1,5 @@ -class StageTI -{ - texture = "a3\data_f\default_glass_ti_ca.paa"; +class StageTI { + texture = "a3\data_f\default_glass_ti_ca.paa"; }; ambient[] = {1,1,1,1}; diffuse[] = {1,1,1,1}; @@ -10,81 +9,71 @@ specular[] = {0,0,0,1}; specularPower = 0; PixelShaderID = "Super"; VertexShaderID = "Super"; -class Stage1 -{ - texture = "z\ace\addons\logistics_wirecutter\data\ace_wirecutter_nohq.paa"; - uvSource = "tex"; - class uvTransform - { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,0}; - pos[] = {0,0,0}; - }; +class Stage1 { + texture = "z\ace\addons\logistics_wirecutter\data\ace_wirecutter_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,0.5,DT)"; - 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,0.5,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}; - }; + 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 = "#(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,0}; - pos[] = {0,0,0}; - }; + 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,0}; + pos[] = {0,0,0}; + }; }; class Stage5 { - texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; - uvSource = "tex"; - class uvTransform - { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,0}; - pos[] = {0,0,0}; - }; + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + 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(0.71,0.74)"; - uvSource = "none"; +class Stage6 { + texture = "#(ai,32,128,1)fresnel(0.71,0.74)"; + uvSource = "none"; +}; +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + useWorldEnvMap = "true"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; }; -class Stage7 -{ - texture = "a3\data_f\env_land_co.paa"; - useWorldEnvMap = "true"; - uvSource = "tex"; - class uvTransform - { - aside[] = {1.0,0.0,0.0}; - up[] = {0.0,1.0,0.0}; - dir[] = {0.0,0.0,0.0}; - pos[] = {0.0,0.0,0.0}; - }; -}; \ No newline at end of file diff --git a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf index 2bf807975f..79da93cf79 100644 --- a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf @@ -1,55 +1,68 @@ +#include "script_component.hpp" /* - * Author: gpgpgpgp, edited by commy2, PabstMirror - * Starts cutting down a fence + * Author: gpgpgpgp, commy2, PabstMirror, mharis001 + * Starts cutting down a fence. Triggers global "ace_wireCuttingStarted" event. * * Arguments: * 0: Unit * 1: Fence * * Return Value: - * Nothing + * None * * Example: - * [player, berlinWall] call ace_logistics_wirecutter_fnc_cutDownFence + * [player, cursorObject] call ace_logistics_wirecutter_fnc_cutDownFence * * Public: No */ -#include "script_component.hpp" -params ["_unit", "_fenceObject"]; -TRACE_2("params",_unit,_fenceObject); - -private ["_timeToCut", "_progressCheck", "_onCompletion", "_onFail"]; +params ["_unit", "_fence"]; +TRACE_2("Fence cutting started",_unit,_fence); if (_unit != ACE_player) exitWith {}; -_timeToCut = if ([ACE_player] call EFUNC(common,isEngineer)) then {7.5} else {11}; +// Get cut time based on if unit is a engineer +private _cutTime = if (_unit call EFUNC(common,isEngineer)) then {CUT_TIME_ENGINEER} else {CUT_TIME_DEFAULT}; -[ACE_player, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation); - -_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, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation); }; -_onFail = { - TRACE_1("_onFail", _this); - (_this select 0) params ["", "", "_unit"]; - [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); -}; +[ + _cutTime, + [_unit, _fence, 0], + { + TRACE_1("Fence cutting successful",_this); + (_this select 0) params ["_unit", "_fence"]; -_progressCheck = { - params ["_args", "_passedTime"]; - _args params ["_fenceObject", "_lastSoundEffectTime"]; + _fence setDamage 1; + if !(_unit call EFUNC(common,isSwimming)) then { + [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + }; + }, + { + TRACE_1("Fence cutting failed",_this); + (_this select 0) params ["_unit"]; - if (_passedTime > (_lastSoundEffectTime + SOUND_CLIP_TIME_SPACEING)) then { - playSound3D [QUOTE(PATHTO_R(sound\wirecut.ogg)), objNull, false, (getPosASL ACE_player), 3, 1, 10]; - _args set [1, _passedTime]; - }; + if !(_unit call EFUNC(common,isSwimming)) then { + [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); + }; + }, + localize LSTRING(CuttingFence), + { + params ["_args", "_elapsedTime"]; + _args params ["_unit", "_fence", "_lastSoundTime"]; - ((!isNull _fenceObject) && {(damage _fenceObject) < 1} && {("ACE_wirecutter" in (items ACE_player))}) -}; + if (_elapsedTime > _lastSoundTime + SOUND_CLIP_TIME_SPACING) then { + playSound3D [QPATHTO_R(sound\wirecut.ogg), objNull, false, getPosASL _unit, 3, 1, 10]; + _args set [2, _elapsedTime]; + }; -[_timeToCut, [_fenceObject,0,_unit], _onCompletion, _onFail, localize LSTRING(CuttingFence), _progressCheck] call EFUNC(common,progressBar); + !isNull _fence + && {damage _fence < 1} + && {HAS_WIRECUTTER(_player)} + }, + ["isNotSwimming"] +] call EFUNC(common,progressBar); + +["ace_wireCuttingStarted", [_unit, _fence]] call CBA_fnc_globalEvent; diff --git a/addons/logistics_wirecutter/functions/fnc_interactEH.sqf b/addons/logistics_wirecutter/functions/fnc_interactEH.sqf index bf0f5d3bc9..87b2a84016 100644 --- a/addons/logistics_wirecutter/functions/fnc_interactEH.sqf +++ b/addons/logistics_wirecutter/functions/fnc_interactEH.sqf @@ -1,76 +1,80 @@ +#include "script_component.hpp" /* - * Author: PabstMirror - * When interact_menu starts rendering (from "interact_keyDown" event) + * Author: PabstMirror, mharis001 + * Dynamically adds "Cut Fence" actions to nearby fences when interact_menu is opened. + * Called by the "ace_interactMenuOpened" event. * * Arguments: - * Interact Menu Type (0 - world, 1 - self) + * Interact Menu Type (0 - World, 1 - Self) * * Return Value: - * Nothing + * None * * Example: * [0] call ace_logistics_wirecutter_fnc_interactEH * - * Public: Yes + * Public: No */ -#include "script_component.hpp" params ["_interactionType"]; -//Ignore self-interaction menu or mounted vehicle interaction -if ((_interactionType != 0) || {(vehicle ACE_player) != ACE_player}) exitWith {}; +// Ignore self-interaction menu or mounted vehicle interaction +// For performance reasons only add PFH if player has wirecutter item +// If player somehow gets a wirecutter during keyDown, they will just have to reopen menu +if ( + _interactionType != 0 + || {vehicle ACE_player != ACE_player} + || {!HAS_WIRECUTTER(ACE_player)} +) exitWith {}; -//for performance only do stuff it they have a wirecutter item -//(if they somehow get one durring keydown they'll just have to reopen) -if (!("ACE_wirecutter" in (items ace_player))) exitWith {}; - -TRACE_1("Starting wire-cut action PFEH",_interactionType); +TRACE_1("Starting wirecuter interact PFH",_interactionType); [{ - private ["_fncStatement", "_attachedFence", "_fncCondition", "_helper", "_action"]; - params ["_args", "_pfID"]; + BEGIN_COUNTER(interactEH); + params ["_args", "_pfhID"]; _args params ["_setPosition", "_addedHelpers", "_fencesHelped"]; if (!EGVAR(interact_menu,keyDown)) then { - {deleteVehicle _x; nil} count _addedHelpers; - [_pfID] call CBA_fnc_removePerFrameHandler; + {deleteVehicle _x} forEach _addedHelpers; + [_pfhID] call CBA_fnc_removePerFrameHandler; } else { - // Prevent Rare Error when ending mission with interact key down: - if (isNull ace_player) exitWith {}; + // Prevent rare error when ending mission with interact key down + if (isNull ACE_player) exitWith {}; - //If player moved >5 meters from last pos, then rescan - if (((getPosASL ace_player) distance _setPosition) > 5) then { - - _fncStatement = { + // Rescan if player has moved more than 5 meters from last position + if (getPosASL ACE_player distanceSqr _setPosition > 25) then { + 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}; - ((!isNull _attachedFence) && {(damage _attachedFence) < 1} && {("ACE_wirecutter" in (items _player))} && { - //Custom LOS check for fence - private _headPos = ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot"); - ((!(lineIntersects [AGLtoASL _headPos, AGLtoASL (_helper modelToWorldVisual [0,0,1.25]), _attachedFence, ACE_player])) || - {!(lineIntersects [AGLtoASL _headPos, getPosASL _attachedFence, _attachedFence, ACE_player])}) - }) + + !isNull _attachedFence + && {damage _attachedFence < 1} + && {HAS_WIRECUTTER(_player)} + && {[_player, _attachedFence, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} + && { + // Custom LOS check for fence + private _headPos = AGLtoASL (_player modelToWorldVisual (_player selectionPosition "pilot")); + !lineIntersects [_headPos, AGLtoASL (_helper modelToWorldVisual [0, 0, 1.25]), _attachedFence, _player] + || {!lineIntersects [_headPos, getPosASL _attachedFence, _attachedFence, _player]} + } }; - { - 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); - [_helper, 0, [],_action] call EFUNC(interact_menu,addActionToObject); - _helper setPosASL ((getPosASL _x) vectorAdd [0,0,1.25]); - _addedHelpers pushBack _helper; - }; + if (!(_x in _fencesHelped) && {_x call FUNC(isFence)}) then { + _fencesHelped pushBack _x; + private _helper = "ACE_LogicDummy" createVehicleLocal [0, 0, 0]; + 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; }; - nil - } count nearestObjects [ace_player, [], 15]; + } forEach nearestObjects [ACE_player, [], 15]; - _args set [0, (getPosASL ace_player)]; + _args set [0, getPosASL ACE_player]; }; }; -}, 0.1, [((getPosASL ace_player) vectorAdd [-100,0,0]), [], []]] call CBA_fnc_addPerFrameHandler; + END_COUNTER(interactEH); +}, 0.5, [getPosASL ACE_player vectorAdd [-100, 0, 0], [], []]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/logistics_wirecutter/functions/fnc_isFence.sqf b/addons/logistics_wirecutter/functions/fnc_isFence.sqf index d9122139b7..38610f30fb 100644 --- a/addons/logistics_wirecutter/functions/fnc_isFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_isFence.sqf @@ -1,32 +1,32 @@ +#include "script_component.hpp" /* * Author: PabstMirror - * Checks if object is a fence. Should work on any fence type, even (typeOf == ""). - * Call is fairly expensive because of all of the string checking. + * Checks if object is a fence. Should work on any fence type, even when (typeOf == ""). + * Call is fairly expensive because of string checking. * * Arguments: - * 0: An Object To Test + * 0: Object to test * * Return Value: - * Is it a fence + * Is fence * * Example: - * [aFence] call ace_logistics_wirecutter_fnc_isFence + * [cursorObject] call ace_logistics_wirecutter_fnc_isFence * * Public: No */ -#include "script_component.hpp" params ["_object"]; -TRACE_1("params",_object); +TRACE_1("Checking if fence",_object); private _typeOf = typeOf _object; private _returnValue = if (_typeOf != "") then { - //If the fence has configEntry we can check it directly - (1 == (getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(isFence)))); + // Check for isFence entry since we have valid typeOf + 1 == getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(isFence)); } else { - //Check the p3d name against list (in script_component.hpp) - ((getModelInfo _object) select 0) in FENCE_P3DS; + // Check the p3d name against list (in script_component.hpp) + (getModelInfo _object select 0) in FENCE_P3DS; }; _returnValue diff --git a/addons/logistics_wirecutter/script_component.hpp b/addons/logistics_wirecutter/script_component.hpp index 9e52593ba7..85af4f54c9 100644 --- a/addons/logistics_wirecutter/script_component.hpp +++ b/addons/logistics_wirecutter/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_LOGISTICS_WIRECUTTER @@ -17,8 +16,49 @@ #include "\z\ace\addons\main\script_macros.hpp" +// find is case sensitive, so keep everything lowercase +// also set as isFence, but if the model is reused like for xcam +#define FENCE_P3DS [\ + "net_fence_4m_f.p3d",\ + "net_fence_8m_f.p3d",\ + "netfence_01_m_4m_f.p3d",\ + "netfence_01_m_8m_f.p3d",\ + "wired_fence_4m_f.p3d",\ + "wired_fence_8m_f.p3d",\ + "new_wiredfence_5m_f.p3d",\ + "new_wiredfence_10m_f.p3d",\ + "wiredfence_01_4m_f.p3d",\ + "wiredfence_01_8m_f.p3d",\ + "wiredfence_01_16m_f.p3d",\ + "mil_wiredfence_f.p3d",\ + "sportground_fence_f.p3d",\ + "sportground_fence_nolc_f.p3d",\ + "indfnc_3_f.p3d",\ + "indfnc_3_hole_f.p3d",\ + "indfnc_9_f.p3d",\ + "indfnc_corner_f.p3d",\ + "slums01_8m.p3d",\ + "razorwire_f.p3d",\ + "slums02_4m.p3d",\ + "backalley_01_l_1m_f.p3d",\ + "plasticnetfence_01_short_f.p3d",\ + "plasticnetfence_01_long_f.p3d",\ + "wall_indfnc_3.p3d",\ + "wall_indfnc_9.p3d",\ + "wall_indfnc_corner.p3d",\ + "pletivo_wired.p3d",\ + "wall_fen1_5.p3d",\ + "plot_provizorni.p3d",\ + "plp_ctm_partitioningfencegrey.p3d",\ + "fence.p3d"\ +] -//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 SOUND_CLIP_TIME_SPACING 1.5 +#define CUT_TIME_DEFAULT 11 +#define CUT_TIME_ENGINEER 7.5 -#define SOUND_CLIP_TIME_SPACEING 1.5 +#define HAS_WIRECUTTER(unit) (\ + "ACE_wirecutter" in (unit call EFUNC(common,uniqueItems)) \ + || {1 == getNumber (configFile >> "CfgVehicles" >> (backpack unit) >> QGVAR(hasWirecutter))} \ + || {1 == getNumber (configFile >> "CfgWeapons" >> (vest unit) >> QGVAR(hasWirecutter))} \ +) diff --git a/addons/logistics_wirecutter/sound/wire_cut.ogg b/addons/logistics_wirecutter/sound/wire_cut.ogg deleted file mode 100644 index 246b15432c..0000000000 Binary files a/addons/logistics_wirecutter/sound/wire_cut.ogg and /dev/null differ diff --git a/addons/logistics_wirecutter/sound/wire_cut_long.ogg b/addons/logistics_wirecutter/sound/wire_cut_long.ogg deleted file mode 100644 index 36d25c9c73..0000000000 Binary files a/addons/logistics_wirecutter/sound/wire_cut_long.ogg and /dev/null differ diff --git a/addons/logistics_wirecutter/stringtable.xml b/addons/logistics_wirecutter/stringtable.xml index 6790d67ec6..dd4ce0dd2e 100644 --- a/addons/logistics_wirecutter/stringtable.xml +++ b/addons/logistics_wirecutter/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Drótvágó Trancia Cortador de Arame + ワイヤーカッター + 절단기 + 剪铁丝网钳 + 剪鐵絲網鉗 Wirecutter @@ -22,8 +26,12 @@ Służą do cięcia drutu i płotów Pince coupante Drótok, huzalok, és kábelek vágására alkalmas olló. - Trancia da ferro + Tronchese Cortador de Arame + ワイヤーカッター + 절단기 + 剪铁丝网钳 + 剪鐵絲網鉗 Cut Fence @@ -36,6 +44,10 @@ Taglia Drótkerítés átvágása Разрезать забор + フェンスを切断する + 철조망 자르기 + 剪断护栏 + 剪斷護欄 Cutting Fences / Wires... @@ -48,6 +60,10 @@ Sto tagliando... Drótok elvágása... Разрезаем забор / провода... + フェンス/ワイヤを切断しています・・・ + 철망/철조망 자르는중... + 剪断护栏/刺网中... + 剪斷護欄/刺網中... Fence cut @@ -60,6 +76,10 @@ Fatto! Drótkerítés átvágva Забор разрезан + フェンスを切断しました + 절단됨 + 护栏已被剪断 + 護欄已被剪斷 - \ No newline at end of file + 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..7d1d328647 100644 --- a/addons/magazinerepack/CfgVehicles.hpp +++ b/addons/magazinerepack/CfgVehicles.hpp @@ -5,10 +5,9 @@ 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/XEH_preInit.sqf b/addons/magazinerepack/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/magazinerepack/XEH_preInit.sqf +++ b/addons/magazinerepack/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf index f8403d81e5..b1cdef9829 100644 --- a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf +++ b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror, commy2, esteldunedain, Ruthberg * Gets magazine children for interaciton menu. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target", "_player"]; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf index 36544b0084..d70899ba56 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror (based on repack from commy2, esteldunedain, Ruthberg) * Simulates repacking a set of magazines. @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_args", "_elapsedTime", "_totalTime", "_errorCode"]; _args params ["_magazineClassname", "_lastAmmoCount"]; @@ -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_magazineRepackProgress.sqf b/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf index 3808df4cdc..f48d0029fa 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror (based on repack from commy2, esteldunedain, Ruthberg) * Handles each frame durring the repack progressBar. @@ -16,9 +17,8 @@ * * Public: No */ -#include "script_component.hpp" -params ["_ars", "_elapsedTime", "_totalTime"]; +params ["_args", "_elapsedTime", "_totalTime"]; _args params ["_magazineClassname", "_lastAmmoCount", "_simEvents"]; if !((_simEvents select 0) params ["_nextEventTime", "_nextEventIsBullet", "_nextEventMags"]) exitWith { ERROR("No Event"); false }; diff --git a/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf b/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf index 09c04de26e..bd7d4dae2a 100644 --- a/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf +++ b/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Simulates repacking a set of magazines. @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_fullMagazineCount", "_arrayOfAmmoCounts", "_isBelt"]; @@ -26,6 +26,7 @@ _arrayOfAmmoCounts = +_arrayOfAmmoCounts; _arrayOfAmmoCounts sort true; private _fnc_newMag = { + //IGNORE_PRIVATE_WARNING ["_time", "_events"]; _time = _time + GVAR(TimePerMagazine); _events pushBack [_time, false, +_arrayOfAmmoCounts]; }; diff --git a/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf index 32ce65d188..cd9df9b2a9 100644 --- a/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf +++ b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror (based on repack from commy2, esteldunedain, Ruthberg) * Starts repacking a specific magazine classname. @@ -10,14 +11,13 @@ * 2: Magazine Classname * * Return Value: - * Nothing + * None * * Example: * [player, player, "30Rnd_65x39_caseless_mag"] call ace_magazinerepack_fnc_startRepackingMagazine * * Public: No */ -#include "script_component.hpp" params ["_target", "_player", "_magazineClassname"]; @@ -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/script_component.hpp b/addons/magazinerepack/script_component.hpp index 79c1a20652..0b81c73d98 100644 --- a/addons/magazinerepack/script_component.hpp +++ b/addons/magazinerepack/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MAGAZINEREPACK diff --git a/addons/magazinerepack/stringtable.xml b/addons/magazinerepack/stringtable.xml index 75cd177ed9..ac4334f5b5 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,34 +43,14 @@ Réorganiser les chargeurs Przepakuj magazynki Přepáskovat zásobníky - Riempi i caricatori + Riempi Caricatori Reorganizar Carregadores Újratárazás Перепаковать магазины - - - 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... @@ -44,22 +59,14 @@ 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... Перепаковка магазинов... - - - 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) @@ -72,6 +79,10 @@ %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發額外子彈 Repacking Finished @@ -82,8 +93,12 @@ Páskování dokončeno Przepakowywanie zakończone Újratárazás befejezve - Caricatori riempiti + Caricatori Riempiti Reorganização Terminada + 詰め替えが完了しました + 탄창 채우기 끝남 + 重整完成 + 重整完成 Repacking Interrupted @@ -94,20 +109,28 @@ Páskování přerušeno Przepakowywanie przerwane Újratárazás megszakítva - Riempimento interrotto + Riempimento Interrotto Reorganização Interrompida + 詰め替えを中断しました + 탄창 채우기 방해받음 + 重整被中断 + 重整被中斷 %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個部分的 - \ No newline at end of file + 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/CfgSettings.hpp b/addons/main/CfgSettings.hpp index 58cb824a6f..dcb78ffb60 100644 --- a/addons/main/CfgSettings.hpp +++ b/addons/main/CfgSettings.hpp @@ -10,6 +10,7 @@ class CfgSettings { //Warnings for missing RHS compat pbos compat_rhs_afrf3[] = {"ace_compat_rhs_afrf3", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'rhs_main')"}; compat_rhs_usf3[] = {"ace_compat_rhs_usf3", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'rhsusf_main')"}; + compat_rhs_gref3[] = {"ace_compat_rhs_gref3", {VERSION_AR}, "isClass (configFile >> 'CfgPatches' >> 'rhsgref_main')"}; }; }; }; diff --git a/addons/main/config.cpp b/addons/main/config.cpp index 5d485b6fd9..1d02625747 100644 --- a/addons/main/config.cpp +++ b/addons/main/config.cpp @@ -7,864 +7,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = { - // Vanilla - "a3_3den", - "a3_3den_language", - "a3_air_f", - "a3_air_f_beta", - "a3_air_f_beta_heli_attack_01", - "a3_air_f_beta_heli_attack_02", - "a3_air_f_beta_heli_transport_01", - "a3_air_f_beta_heli_transport_02", - "a3_air_f_beta_parachute_01", - "a3_air_f_beta_parachute_02", - "a3_air_f_epb", - "a3_air_f_epb_heli_light_03", - "a3_air_f_epc", - "a3_air_f_epc_plane_cas_01", - "a3_air_f_epc_plane_cas_02", - "a3_air_f_epc_plane_fighter_03", - "a3_air_f_exp", - "a3_air_f_exp_heli_light_01", - "a3_air_f_exp_heli_transport_01", - "a3_air_f_exp_plane_civil_01", - "a3_air_f_exp_uav_03", - "a3_air_f_exp_uav_04", - "a3_air_f_exp_vtol_01", - "a3_air_f_exp_vtol_02", - "a3_air_f_gamma", - "a3_air_f_gamma_plane_fighter_03", - "a3_air_f_gamma_uav_01", - "a3_air_f_gamma_uav_02", - "a3_air_f_heli", - "a3_air_f_heli_heli_attack_01", - "a3_air_f_heli_heli_attack_02", - "a3_air_f_heli_heli_light_01", - "a3_air_f_heli_heli_light_02", - "a3_air_f_heli_heli_light_03", - "a3_air_f_heli_heli_transport_01", - "a3_air_f_heli_heli_transport_02", - "a3_air_f_heli_heli_transport_03", - "a3_air_f_heli_heli_transport_04", - "a3_air_f_heli_light_01", - "a3_air_f_heli_light_02", - "a3_animals_f", - "a3_animals_f_animconfig", - "a3_animals_f_beta", - "a3_animals_f_beta_chicken", - "a3_animals_f_beta_dog", - "a3_animals_f_beta_goat", - "a3_animals_f_beta_sheep", - "a3_animals_f_chicken", - "a3_animals_f_dog", - "a3_animals_f_fishes", - "a3_animals_f_goat", - "a3_animals_f_kestrel", - "a3_animals_f_rabbit", - "a3_animals_f_seagull", - "a3_animals_f_sheep", - "a3_animals_f_snakes", - "a3_animals_f_turtle", - "a3_anims_f", - "a3_anims_f_bootcamp", - "a3_anims_f_config_sdr", - "a3_anims_f_config_sdr_weaponswitching", - "a3_anims_f_data", - "a3_anims_f_epa", - "a3_anims_f_epc", - "a3_anims_f_exp", - "a3_anims_f_exp_a", - "a3_anims_f_exp_revive", - "a3_anims_f_heli", - "a3_anims_f_kart", - "a3_anims_f_mark", - "a3_anims_f_mark_deployment", - "a3_armor_f", - "a3_armor_f_amv", - "a3_armor_f_apc_wheeled_03", - "a3_armor_f_beta", - "a3_armor_f_beta_apc_tracked_01", - "a3_armor_f_beta_apc_tracked_02", - "a3_armor_f_beta_apc_wheeled_01", - "a3_armor_f_beta_apc_wheeled_02", - "a3_armor_f_epb", - "a3_armor_f_epb_apc_tracked_03", - "a3_armor_f_epb_mbt_03", - "a3_armor_f_epc", - "a3_armor_f_epc_mbt_01", - "a3_armor_f_exp", - "a3_armor_f_exp_apc_tracked_02", - "a3_armor_f_exp_apc_wheeled_02", - "a3_armor_f_exp_mbt_02", - "a3_armor_f_gamma", - "a3_armor_f_gamma_apc_wheeled_03", - "a3_armor_f_gamma_mbt_01", - "a3_armor_f_gamma_mbt_02", - "a3_armor_f_marid", - "a3_armor_f_panther", - "a3_armor_f_slammer", - "a3_armor_f_t100k", - "a3_baseconfig_f", - "a3_boat_f", - "a3_boat_f_beta", - "a3_boat_f_beta_boat_armed_01", - "a3_boat_f_beta_boat_transport_01", - "a3_boat_f_beta_sdv_01", - "a3_boat_f_boat_armed_01", - "a3_boat_f_boat_transport_01", - "a3_boat_f_civilian_boat", - "a3_boat_f_epc", - "a3_boat_f_epc_submarine_01", - "a3_boat_f_epc_submarine_01_f", - "a3_boat_f_exp", - "a3_boat_f_exp_boat_transport_01", - "a3_boat_f_exp_boat_transport_02", - "a3_boat_f_exp_scooter_transport_01", - "a3_boat_f_gamma", - "a3_boat_f_gamma_boat_civil_01", - "a3_boat_f_gamma_boat_civil_04", - "a3_boat_f_gamma_boat_transport_01", - "a3_boat_f_heli", - "a3_boat_f_heli_boat_armed_01", - "a3_boat_f_heli_sdv_01", - "a3_boat_f_sdv_01", - "a3_boat_f_trawler", - "a3_cargoposes_f", - "a3_cargoposes_f_exp", - "a3_cargoposes_f_heli", - "a3_characters_f", - "a3_characters_f_beta", - "a3_characters_f_beta_indep", - "a3_characters_f_blufor", - "a3_characters_f_bootcamp", - "a3_characters_f_bootcamp_common", - "a3_characters_f_civil", - "a3_characters_f_common", - "a3_characters_f_epa", - "a3_characters_f_epb", - "a3_characters_f_epb_heads", - "a3_characters_f_epc", - "a3_characters_f_exp", - "a3_characters_f_exp_civil", - "a3_characters_f_exp_headgear", - "a3_characters_f_exp_vests", - "a3_characters_f_gamma", - "a3_characters_f_heads", - "a3_characters_f_indep", - "a3_characters_f_kart", - "a3_characters_f_mark", - "a3_characters_f_opfor", - "a3_characters_f_proxies", - "a3_data_f", - "a3_data_f_bootcamp", - "a3_data_f_curator", - "a3_data_f_curator_characters", - "a3_data_f_curator_eagle", - "a3_data_f_curator_intel", - "a3_data_f_curator_misc", - "a3_data_f_curator_respawn", - "a3_data_f_curator_virtual", - "a3_data_f_exp", - "a3_data_f_exp_a", - "a3_data_f_exp_a_virtual", - "a3_data_f_exp_b", - "a3_data_f_exp_particleeffects", - "a3_data_f_heli", - "a3_data_f_hook", - "a3_data_f_kart", - "a3_data_f_kart_particleeffects", - "a3_data_f_mark", - "a3_data_f_particleeffects", - "a3_drones_f", - "a3_drones_f_air_f_gamma_uav_01", - "a3_drones_f_air_f_gamma_uav_02", - "a3_drones_f_characters_f_gamma", - "a3_drones_f_soft_f_gamma_ugv_01", - "a3_drones_f_weapons_f_gamma_ammoboxes", - "a3_drones_f_weapons_f_gamma_items", - "a3_dubbing_f", - "a3_dubbing_f_beta", - "a3_dubbing_f_bootcamp", - "a3_dubbing_f_epa", - "a3_dubbing_f_epb", - "a3_dubbing_f_epc", - "a3_dubbing_f_exp", - "a3_dubbing_f_gamma", - "a3_dubbing_f_heli", - "a3_dubbing_f_mark", - "a3_dubbing_f_mp_mark", - "a3_dubbing_radio_f", - "a3_dubbing_radio_f_data_eng", - "a3_dubbing_radio_f_data_engb", - "a3_dubbing_radio_f_data_gre", - "a3_dubbing_radio_f_data_per", - "a3_dubbing_radio_f_data_vr", - "a3_dubbing_radio_f_exp", - "a3_dubbing_radio_f_exp_data_chi", - "a3_dubbing_radio_f_exp_data_engfre", - "a3_dubbing_radio_f_exp_data_fre", - "a3_editor_f", - "a3_editorpreviews_f", - "a3_editorpreviews_f_exp", - "a3_functions_f", - "a3_functions_f_bootcamp", - "a3_functions_f_curator", - "a3_functions_f_epa", - "a3_functions_f_epc", - "a3_functions_f_exp", - "a3_functions_f_exp_a", - "a3_functions_f_heli", - "a3_functions_f_mark", - "a3_functions_f_mp_mark", - "a3_language_f", - "a3_language_f_beta", - "a3_language_f_bootcamp", - "a3_language_f_curator", - "a3_language_f_epa", - "a3_language_f_epb", - "a3_language_f_epc", - "a3_language_f_exp", - "a3_language_f_exp_a", - "a3_language_f_exp_b", - "a3_language_f_gamma", - "a3_language_f_heli", - "a3_language_f_kart", - "a3_language_f_mark", - "a3_language_f_mp_mark", - "a3_languagemissions_f", - "a3_languagemissions_f_beta", - "a3_languagemissions_f_bootcamp", - "a3_languagemissions_f_epa", - "a3_languagemissions_f_epb", - "a3_languagemissions_f_epc", - "a3_languagemissions_f_exp", - "a3_languagemissions_f_exp_a", - "a3_languagemissions_f_gamma", - "a3_languagemissions_f_heli", - "a3_languagemissions_f_kart", - "a3_languagemissions_f_mark", - "a3_languagemissions_f_mp_mark", - "a3_map_altis", - "a3_map_altis_data", - "a3_map_altis_data_layers", - "a3_map_altis_scenes", - "a3_map_altis_scenes_f", - "a3_map_data", - "a3_map_stratis", - "a3_map_stratis_data", - "a3_map_stratis_data_layers", - "a3_map_stratis_scenes", - "a3_map_stratis_scenes_f", - "a3_map_vr", - "a3_map_vr_scenes", - "a3_map_vr_scenes_f", - "a3_misc_f", - "a3_misc_f_helpers", - "a3_missions_f", - "a3_missions_f_beta", - "a3_missions_f_beta_data", - "a3_missions_f_beta_video", - "a3_missions_f_bootcamp", - "a3_missions_f_bootcamp_data", - "a3_missions_f_bootcamp_video", - "a3_missions_f_curator", - "a3_missions_f_data", - "a3_missions_f_epa", - "a3_missions_f_epa_data", - "a3_missions_f_epa_video", - "a3_missions_f_epb", - "a3_missions_f_epc", - "a3_missions_f_exp", - "a3_missions_f_exp_a", - "a3_missions_f_exp_a_data", - "a3_missions_f_exp_data", - "a3_missions_f_exp_video", - "a3_missions_f_gamma", - "a3_missions_f_gamma_data", - "a3_missions_f_gamma_video", - "a3_missions_f_heli", - "a3_missions_f_heli_data", - "a3_missions_f_heli_video", - "a3_missions_f_kart", - "a3_missions_f_kart_data", - "a3_missions_f_mark", - "a3_missions_f_mark_data", - "a3_missions_f_mark_video", - "a3_missions_f_mp_mark", - "a3_missions_f_mp_mark_data", - "a3_missions_f_video", - "a3_modules_f", - "a3_modules_f_beta", - "a3_modules_f_beta_data", - "a3_modules_f_beta_firingdrills", - "a3_modules_f_bootcamp", - "a3_modules_f_bootcamp_misc", - "a3_modules_f_curator", - "a3_modules_f_curator_animals", - "a3_modules_f_curator_cas", - "a3_modules_f_curator_chemlights", - "a3_modules_f_curator_curator", - "a3_modules_f_curator_effects", - "a3_modules_f_curator_environment", - "a3_modules_f_curator_flares", - "a3_modules_f_curator_intel", - "a3_modules_f_curator_lightning", - "a3_modules_f_curator_mines", - "a3_modules_f_curator_misc", - "a3_modules_f_curator_multiplayer", - "a3_modules_f_curator_objectives", - "a3_modules_f_curator_ordnance", - "a3_modules_f_curator_respawn", - "a3_modules_f_curator_smokeshells", - "a3_modules_f_data", - "a3_modules_f_dyno", - "a3_modules_f_effects", - "a3_modules_f_epb", - "a3_modules_f_epb_misc", - "a3_modules_f_events", - "a3_modules_f_exp", - "a3_modules_f_exp_a", - "a3_modules_f_groupmodifiers", - "a3_modules_f_hc", - "a3_modules_f_heli", - "a3_modules_f_heli_misc", - "a3_modules_f_heli_spawnai", - "a3_modules_f_intel", - "a3_modules_f_kart", - "a3_modules_f_kart_data", - "a3_modules_f_kart_timetrials", - "a3_modules_f_livefeed", - "a3_modules_f_mark", - "a3_modules_f_mark_firingdrills", - "a3_modules_f_mark_objectives", - "a3_modules_f_marta", - "a3_modules_f_misc", - "a3_modules_f_mp_mark", - "a3_modules_f_mp_mark_objectives", - "a3_modules_f_multiplayer", - "a3_modules_f_objectmodifiers", - "a3_modules_f_sites", - "a3_modules_f_skirmish", - "a3_modules_f_strategicmap", - "a3_modules_f_supports", - "a3_modules_f_uav", - "a3_music_f", - "a3_music_f_bootcamp", - "a3_music_f_bootcamp_music", - "a3_music_f_epa", - "a3_music_f_epa_music", - "a3_music_f_epb", - "a3_music_f_epb_music", - "a3_music_f_epc", - "a3_music_f_epc_music", - "a3_music_f_exp", - "a3_music_f_exp_music", - "a3_music_f_heli", - "a3_music_f_heli_music", - "a3_music_f_mark", - "a3_music_f_mark_music", - "a3_music_f_music", - "a3_plants_f", - "a3_plants_f_bush", - "a3_props_f_exp", - "a3_props_f_exp_a", - "a3_props_f_exp_a_military", - "a3_props_f_exp_a_military_equipment", - "a3_props_f_exp_civilian", - "a3_props_f_exp_civilian_garbage", - "a3_props_f_exp_commercial", - "a3_props_f_exp_commercial_market", - "a3_props_f_exp_industrial", - "a3_props_f_exp_industrial_heavyequipment", - "a3_props_f_exp_infrastructure", - "a3_props_f_exp_infrastructure_railways", - "a3_props_f_exp_infrastructure_traffic", - "a3_props_f_exp_military", - "a3_props_f_exp_military_camps", - "a3_props_f_exp_military_oldplanewrecks", - "a3_props_f_exp_naval", - "a3_props_f_exp_naval_boats", - "a3_roads_f", - "a3_rocks_f", - "a3_rocks_f_blunt", - "a3_rocks_f_sharp", - "a3_rocks_f_water", - "a3_signs_f", - "a3_signs_f_ad", - "a3_signs_f_signs_ad", - "a3_soft_f", - "a3_soft_f_beta", - "a3_soft_f_beta_mrap_03", - "a3_soft_f_beta_quadbike", - "a3_soft_f_beta_quadbike_01", - "a3_soft_f_beta_truck_01", - "a3_soft_f_beta_truck_02", - "a3_soft_f_bootcamp", - "a3_soft_f_bootcamp_offroad_01", - "a3_soft_f_bootcamp_quadbike", - "a3_soft_f_bootcamp_quadbike_01", - "a3_soft_f_bootcamp_truck", - "a3_soft_f_bootcamp_van_01", - "a3_soft_f_car", - "a3_soft_f_crusher_ugv", - "a3_soft_f_epc", - "a3_soft_f_epc_truck_03", - "a3_soft_f_exp", - "a3_soft_f_exp_lsv_01", - "a3_soft_f_exp_lsv_02", - "a3_soft_f_exp_mrap_02", - "a3_soft_f_exp_offroad_01", - "a3_soft_f_exp_offroad_02", - "a3_soft_f_exp_quadbike_01", - "a3_soft_f_exp_truck_03", - "a3_soft_f_exp_ugv_01", - "a3_soft_f_exp_van_01", - "a3_soft_f_gamma", - "a3_soft_f_gamma_hatchback_01", - "a3_soft_f_gamma_hemtt", - "a3_soft_f_gamma_offroad", - "a3_soft_f_gamma_offroad_01", - "a3_soft_f_gamma_quadbike", - "a3_soft_f_gamma_quadbike_01", - "a3_soft_f_gamma_suv_01", - "a3_soft_f_gamma_truck_01", - "a3_soft_f_gamma_truck_02", - "a3_soft_f_gamma_truckheavy", - "a3_soft_f_gamma_van_01", - "a3_soft_f_heli", - "a3_soft_f_heli_car", - "a3_soft_f_heli_crusher_ugv", - "a3_soft_f_heli_hatchback_01", - "a3_soft_f_heli_mrap_01", - "a3_soft_f_heli_mrap_02", - "a3_soft_f_heli_mrap_03", - "a3_soft_f_heli_quadbike", - "a3_soft_f_heli_quadbike_01", - "a3_soft_f_heli_suv", - "a3_soft_f_heli_suv_01", - "a3_soft_f_heli_truck", - "a3_soft_f_heli_ugv_01", - "a3_soft_f_heli_van_01", - "a3_soft_f_hemtt", - "a3_soft_f_kart", - "a3_soft_f_kart_kart_01", - "a3_soft_f_mrap_01", - "a3_soft_f_mrap_02", - "a3_soft_f_mrap_03", - "a3_soft_f_offroad_01", - "a3_soft_f_quadbike", - "a3_soft_f_quadbike_01", - "a3_soft_f_suv", - "a3_soft_f_truck", - "a3_soft_f_truckheavy", - "a3_sounds_f", - "a3_sounds_f_arsenal", - "a3_sounds_f_bootcamp", - "a3_sounds_f_characters", - "a3_sounds_f_environment", - "a3_sounds_f_epb", - "a3_sounds_f_epc", - "a3_sounds_f_exp", - "a3_sounds_f_exp_a", - "a3_sounds_f_heli", - "a3_sounds_f_kart", - "a3_sounds_f_mark", - "a3_sounds_f_sfx", - "a3_sounds_f_vehicles", - "a3_static_f", - "a3_static_f_aa_01", - "a3_static_f_at_01", - "a3_static_f_beta", - "a3_static_f_beta_mortar_01", - "a3_static_f_exp", - "a3_static_f_gamma", - "a3_static_f_gamma_aa", - "a3_static_f_gamma_at", - "a3_static_f_gamma_mortar_01", - "a3_static_f_mark", - "a3_static_f_mark_designator_01", - "a3_static_f_mark_designator_02", - "a3_static_f_mortar_01", - "a3_structures_f", - "a3_structures_f_bootcamp", - "a3_structures_f_bootcamp_civ_camping", - "a3_structures_f_bootcamp_civ_sportsgrounds", - "a3_structures_f_bootcamp_ind_cargo", - "a3_structures_f_bootcamp_items_electronics", - "a3_structures_f_bootcamp_items_food", - "a3_structures_f_bootcamp_items_sport", - "a3_structures_f_bootcamp_system", - "a3_structures_f_bootcamp_training", - "a3_structures_f_bootcamp_vr_blocks", - "a3_structures_f_bootcamp_vr_coverobjects", - "a3_structures_f_bootcamp_vr_helpers", - "a3_structures_f_bridges", - "a3_structures_f_civ", - "a3_structures_f_civ_accessories", - "a3_structures_f_civ_ancient", - "a3_structures_f_civ_belltowers", - "a3_structures_f_civ_calvaries", - "a3_structures_f_civ_camping", - "a3_structures_f_civ_chapels", - "a3_structures_f_civ_constructions", - "a3_structures_f_civ_dead", - "a3_structures_f_civ_garbage", - "a3_structures_f_civ_graffiti", - "a3_structures_f_civ_infoboards", - "a3_structures_f_civ_kiosks", - "a3_structures_f_civ_lamps", - "a3_structures_f_civ_market", - "a3_structures_f_civ_offices", - "a3_structures_f_civ_pavements", - "a3_structures_f_civ_playground", - "a3_structures_f_civ_sportsgrounds", - "a3_structures_f_civ_statues", - "a3_structures_f_civ_tourism", - "a3_structures_f_data", - "a3_structures_f_dominants", - "a3_structures_f_dominants_amphitheater", - "a3_structures_f_dominants_castle", - "a3_structures_f_dominants_church", - "a3_structures_f_dominants_hospital", - "a3_structures_f_dominants_lighthouse", - "a3_structures_f_dominants_wip", - "a3_structures_f_epa", - "a3_structures_f_epa_civ_camping", - "a3_structures_f_epa_civ_constructions", - "a3_structures_f_epa_items_electronics", - "a3_structures_f_epa_items_food", - "a3_structures_f_epa_items_medical", - "a3_structures_f_epa_items_tools", - "a3_structures_f_epa_items_vessels", - "a3_structures_f_epa_mil_scrapyard", - "a3_structures_f_epa_walls", - "a3_structures_f_epb", - "a3_structures_f_epb_civ_accessories", - "a3_structures_f_epb_civ_camping", - "a3_structures_f_epb_civ_dead", - "a3_structures_f_epb_civ_garbage", - "a3_structures_f_epb_civ_graffiti", - "a3_structures_f_epb_civ_playground", - "a3_structures_f_epb_furniture", - "a3_structures_f_epb_items_documents", - "a3_structures_f_epb_items_luggage", - "a3_structures_f_epb_items_military", - "a3_structures_f_epb_items_vessels", - "a3_structures_f_epb_naval_fishing", - "a3_structures_f_epc", - "a3_structures_f_epc_civ_accessories", - "a3_structures_f_epc_civ_camping", - "a3_structures_f_epc_civ_garbage", - "a3_structures_f_epc_civ_infoboards", - "a3_structures_f_epc_civ_kiosks", - "a3_structures_f_epc_civ_playground", - "a3_structures_f_epc_civ_tourism", - "a3_structures_f_epc_dominants_ghosthotel", - "a3_structures_f_epc_dominants_stadium", - "a3_structures_f_epc_furniture", - "a3_structures_f_epc_items_documents", - "a3_structures_f_epc_items_electronics", - "a3_structures_f_epc_walls", - "a3_structures_f_exp_a", - "a3_structures_f_exp_a_vr_blocks", - "a3_structures_f_exp_a_vr_helpers", - "a3_structures_f_furniture", - "a3_structures_f_heli", - "a3_structures_f_heli_civ_accessories", - "a3_structures_f_heli_civ_constructions", - "a3_structures_f_heli_civ_garbage", - "a3_structures_f_heli_civ_market", - "a3_structures_f_heli_furniture", - "a3_structures_f_heli_ind_airport", - "a3_structures_f_heli_ind_cargo", - "a3_structures_f_heli_ind_machines", - "a3_structures_f_heli_items_airport", - "a3_structures_f_heli_items_electronics", - "a3_structures_f_heli_items_food", - "a3_structures_f_heli_items_luggage", - "a3_structures_f_heli_items_sport", - "a3_structures_f_heli_items_tools", - "a3_structures_f_heli_vr_helpers", - "a3_structures_f_households", - "a3_structures_f_households_addons", - "a3_structures_f_households_house_big01", - "a3_structures_f_households_house_big02", - "a3_structures_f_households_house_shop01", - "a3_structures_f_households_house_shop02", - "a3_structures_f_households_house_small01", - "a3_structures_f_households_house_small02", - "a3_structures_f_households_house_small03", - "a3_structures_f_households_slum", - "a3_structures_f_households_stone_big", - "a3_structures_f_households_stone_shed", - "a3_structures_f_households_stone_small", - "a3_structures_f_households_wip", - "a3_structures_f_ind", - "a3_structures_f_ind_airport", - "a3_structures_f_ind_cargo", - "a3_structures_f_ind_carservice", - "a3_structures_f_ind_concretemixingplant", - "a3_structures_f_ind_crane", - "a3_structures_f_ind_dieselpowerplant", - "a3_structures_f_ind_factory", - "a3_structures_f_ind_fuelstation", - "a3_structures_f_ind_fuelstation_small", - "a3_structures_f_ind_pipes", - "a3_structures_f_ind_powerlines", - "a3_structures_f_ind_reservoirtank", - "a3_structures_f_ind_shed", - "a3_structures_f_ind_solarpowerplant", - "a3_structures_f_ind_tank", - "a3_structures_f_ind_transmitter_tower", - "a3_structures_f_ind_wavepowerplant", - "a3_structures_f_ind_windmill", - "a3_structures_f_ind_windpowerplant", - "a3_structures_f_items", - "a3_structures_f_items_cans", - "a3_structures_f_items_documents", - "a3_structures_f_items_electronics", - "a3_structures_f_items_food", - "a3_structures_f_items_gadgets", - "a3_structures_f_items_luggage", - "a3_structures_f_items_medical", - "a3_structures_f_items_military", - "a3_structures_f_items_stationery", - "a3_structures_f_items_tools", - "a3_structures_f_items_valuables", - "a3_structures_f_items_vessels", - "a3_structures_f_kart", - "a3_structures_f_kart_civ_sportsgrounds", - "a3_structures_f_kart_mil_flags", - "a3_structures_f_kart_signs_companies", - "a3_structures_f_mark", - "a3_structures_f_mark_items_military", - "a3_structures_f_mark_items_sport", - "a3_structures_f_mark_mil_flags", - "a3_structures_f_mark_training", - "a3_structures_f_mark_vr_helpers", - "a3_structures_f_mark_vr_shapes", - "a3_structures_f_mark_vr_targets", - "a3_structures_f_mil", - "a3_structures_f_mil_bagbunker", - "a3_structures_f_mil_bagfence", - "a3_structures_f_mil_barracks", - "a3_structures_f_mil_bunker", - "a3_structures_f_mil_cargo", - "a3_structures_f_mil_flags", - "a3_structures_f_mil_fortification", - "a3_structures_f_mil_helipads", - "a3_structures_f_mil_offices", - "a3_structures_f_mil_radar", - "a3_structures_f_mil_scrapyard", - "a3_structures_f_mil_shelters", - "a3_structures_f_mil_tenthangar", - "a3_structures_f_naval", - "a3_structures_f_naval_buoys", - "a3_structures_f_naval_fishing", - "a3_structures_f_naval_piers", - "a3_structures_f_naval_rowboats", - "a3_structures_f_research", - "a3_structures_f_signs_companies", - "a3_structures_f_system", - "a3_structures_f_training", - "a3_structures_f_training_invisibletarget", - "a3_structures_f_walls", - "a3_structures_f_wrecks", - "a3_supplies_f_exp", - "a3_supplies_f_exp_ammoboxes", - "a3_supplies_f_heli", - "a3_supplies_f_heli_bladders", - "a3_supplies_f_heli_cargonets", - "a3_supplies_f_heli_fuel", - "a3_supplies_f_heli_slingload", - "a3_supplies_f_mark", - "a3_uav_f_characters_f_gamma", - "a3_uav_f_weapons_f_gamma_ammoboxes", - "a3_ui_f", - "a3_ui_f_bootcamp", - "a3_ui_f_curator", - "a3_ui_f_data", - "a3_ui_f_exp", - "a3_ui_f_exp_a", - "a3_ui_f_heli", - "a3_ui_f_kart", - "a3_ui_f_mark", - "a3_ui_f_mp_mark", - "a3_uifonts_f", - "a3_weapons_f", - "a3_weapons_f_aaf", - "a3_weapons_f_acc", - "a3_weapons_f_ammoboxes", - "a3_weapons_f_beta", - "a3_weapons_f_beta_acc", - "a3_weapons_f_beta_ammoboxes", - "a3_weapons_f_beta_ebr", - "a3_weapons_f_beta_longrangerifles_ebr", - "a3_weapons_f_beta_longrangerifles_gm6", - "a3_weapons_f_beta_longrangerifles_m320", - "a3_weapons_f_beta_rifles_khaybar", - "a3_weapons_f_beta_rifles_mx", - "a3_weapons_f_beta_rifles_trg20", - "a3_weapons_f_bootcamp", - "a3_weapons_f_bootcamp_ammoboxes", - "a3_weapons_f_bootcamp_longrangerifles_gm6", - "a3_weapons_f_bootcamp_longrangerifles_gm6_camo", - "a3_weapons_f_bootcamp_longrangerifles_m320", - "a3_weapons_f_bootcamp_longrangerifles_m320_camo", - "a3_weapons_f_csat", - "a3_weapons_f_dummyweapons", - "a3_weapons_f_ebr", - "a3_weapons_f_epa", - "a3_weapons_f_epa_acc", - "a3_weapons_f_epa_ammoboxes", - "a3_weapons_f_epa_ebr", - "a3_weapons_f_epa_longrangerifles_dmr_01", - "a3_weapons_f_epa_longrangerifles_gm6", - "a3_weapons_f_epa_rifles_mx", - "a3_weapons_f_epb", - "a3_weapons_f_epb_acc", - "a3_weapons_f_epb_ammoboxes", - "a3_weapons_f_epb_longrangerifles_gm3", - "a3_weapons_f_epb_longrangerifles_gm6", - "a3_weapons_f_epb_longrangerifles_m320", - "a3_weapons_f_epb_rifles_mx_black", - "a3_weapons_f_epc", - "a3_weapons_f_exp", - "a3_weapons_f_exp_launchers_rpg32", - "a3_weapons_f_exp_launchers_rpg7", - "a3_weapons_f_exp_launchers_titan", - "a3_weapons_f_exp_longrangerifles_dmr_07", - "a3_weapons_f_exp_machineguns_lmg_03", - "a3_weapons_f_exp_pistols_pistol_01", - "a3_weapons_f_exp_rifles_ak12", - "a3_weapons_f_exp_rifles_akm", - "a3_weapons_f_exp_rifles_aks", - "a3_weapons_f_exp_rifles_arx", - "a3_weapons_f_exp_rifles_ctar", - "a3_weapons_f_exp_rifles_ctars", - "a3_weapons_f_exp_rifles_spar_01", - "a3_weapons_f_exp_rifles_spar_02", - "a3_weapons_f_exp_rifles_spar_03", - "a3_weapons_f_exp_smgs_smg_05", - "a3_weapons_f_explosives", - "a3_weapons_f_fia", - "a3_weapons_f_gamma", - "a3_weapons_f_gamma_acc", - "a3_weapons_f_gamma_ammoboxes", - "a3_weapons_f_gamma_items", - "a3_weapons_f_gamma_longrangerifles_ebr", - "a3_weapons_f_gamma_rifles_mx", - "a3_weapons_f_headgear", - "a3_weapons_f_itemholders", - "a3_weapons_f_items", - "a3_weapons_f_kart", - "a3_weapons_f_kart_pistols_pistol_signal_f", - "a3_weapons_f_launchers_law", - "a3_weapons_f_launchers_nlaw", - "a3_weapons_f_launchers_rpg32", - "a3_weapons_f_launchers_titan", - "a3_weapons_f_longrangerifles_dmr_01", - "a3_weapons_f_longrangerifles_ebr", - "a3_weapons_f_longrangerifles_gm6", - "a3_weapons_f_longrangerifles_m320", - "a3_weapons_f_machineguns_m200", - "a3_weapons_f_machineguns_zafir", - "a3_weapons_f_mark", - "a3_weapons_f_mark_acc", - "a3_weapons_f_mark_ebr", - "a3_weapons_f_mark_longrangerifles_dmr_01", - "a3_weapons_f_mark_longrangerifles_dmr_02", - "a3_weapons_f_mark_longrangerifles_dmr_03", - "a3_weapons_f_mark_longrangerifles_dmr_04", - "a3_weapons_f_mark_longrangerifles_dmr_05", - "a3_weapons_f_mark_longrangerifles_dmr_06", - "a3_weapons_f_mark_longrangerifles_ebr", - "a3_weapons_f_mark_longrangerifles_gm6", - "a3_weapons_f_mark_longrangerifles_gm6_camo", - "a3_weapons_f_mark_longrangerifles_m320", - "a3_weapons_f_mark_longrangerifles_m320_camo", - "a3_weapons_f_mark_machineguns_m200", - "a3_weapons_f_mark_machineguns_mmg_01", - "a3_weapons_f_mark_machineguns_mmg_02", - "a3_weapons_f_mark_machineguns_zafir", - "a3_weapons_f_mark_rifles_khaybar", - "a3_weapons_f_mark_rifles_mk20", - "a3_weapons_f_mark_rifles_mx", - "a3_weapons_f_mark_rifles_sdar", - "a3_weapons_f_mark_rifles_trg20", - "a3_weapons_f_nato", - "a3_weapons_f_pistols_acpc2", - "a3_weapons_f_pistols_p07", - "a3_weapons_f_pistols_pdw2000", - "a3_weapons_f_pistols_pistol_heavy_01", - "a3_weapons_f_pistols_pistol_heavy_02", - "a3_weapons_f_pistols_rook40", - "a3_weapons_f_rifles_khaybar", - "a3_weapons_f_rifles_mk20", - "a3_weapons_f_rifles_mx", - "a3_weapons_f_rifles_mx_black", - "a3_weapons_f_rifles_sdar", - "a3_weapons_f_rifles_smg_02", - "a3_weapons_f_rifles_trg20", - "a3_weapons_f_rifles_vector", - "a3_weapons_f_smgs_pdw2000", - "a3_weapons_f_smgs_smg_01", - "a3_weapons_f_smgs_smg_02", - "a3_weapons_f_uniforms", - "a3_weapons_f_vests", - "curatoronly_air_f_beta_heli_attack_01", - "curatoronly_air_f_beta_heli_attack_02", - "curatoronly_air_f_gamma_uav_01", - "curatoronly_armor_f_amv", - "curatoronly_armor_f_beta_apc_tracked_02", - "curatoronly_armor_f_marid", - "curatoronly_armor_f_panther", - "curatoronly_armor_f_slammer", - "curatoronly_armor_f_t100k", - "curatoronly_boat_f_boat_armed_01", - "curatoronly_characters_f_blufor", - "curatoronly_characters_f_common", - "curatoronly_characters_f_opfor", - "curatoronly_modules_f_curator_animals", - "curatoronly_modules_f_curator_chemlights", - "curatoronly_modules_f_curator_effects", - "curatoronly_modules_f_curator_environment", - "curatoronly_modules_f_curator_flares", - "curatoronly_modules_f_curator_lightning", - "curatoronly_modules_f_curator_mines", - "curatoronly_modules_f_curator_objectives", - "curatoronly_modules_f_curator_ordnance", - "curatoronly_modules_f_curator_smokeshells", - "curatoronly_signs_f", - "curatoronly_soft_f_crusher_ugv", - "curatoronly_soft_f_mrap_01", - "curatoronly_soft_f_mrap_02", - "curatoronly_soft_f_quadbike", - "curatoronly_static_f_gamma", - "curatoronly_static_f_mortar_01", - "curatoronly_structures_f_civ_ancient", - "curatoronly_structures_f_civ_camping", - "curatoronly_structures_f_civ_garbage", - "curatoronly_structures_f_epa_civ_constructions", - "curatoronly_structures_f_epb_civ_dead", - "curatoronly_structures_f_ind_cargo", - "curatoronly_structures_f_ind_crane", - "curatoronly_structures_f_ind_reservoirtank", - "curatoronly_structures_f_ind_transmitter_tower", - "curatoronly_structures_f_items_vessels", - "curatoronly_structures_f_mil_bagbunker", - "curatoronly_structures_f_mil_bagfence", - "curatoronly_structures_f_mil_cargo", - "curatoronly_structures_f_mil_fortification", - "curatoronly_structures_f_mil_radar", - "curatoronly_structures_f_mil_shelters", - "curatoronly_structures_f_research", - "curatoronly_structures_f_walls", - "curatoronly_structures_f_wrecks", - "a3data", - "3den", - "map_vr", - + "A3_Data_F_Tank_Loadorder", // CBA "cba_ui", "cba_xeh", @@ -892,3 +35,4 @@ class CfgMods { #include "CfgSettings.hpp" #include "CfgModuleCategories.hpp" #include "CfgVehicleClasses.hpp" +#include "CfgEditorSubcategories.hpp" diff --git a/addons/main/script_component.hpp b/addons/main/script_component.hpp index 2f40ce8e8d..c88928f0cd 100644 --- a/addons/main/script_component.hpp +++ b/addons/main/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MAIN diff --git a/addons/main/script_debug.hpp b/addons/main/script_debug.hpp index 92f58e1f96..bb08e34e09 100644 --- a/addons/main/script_debug.hpp +++ b/addons/main/script_debug.hpp @@ -1,3 +1,20 @@ +/** +Fast Recompiling via function +**/ +// #define DISABLE_COMPILE_CACHE +// To Use: [] call ACE_PREP_RECOMPILE; + +#ifdef DISABLE_COMPILE_CACHE + #define LINKFUNC(x) {_this call FUNC(x)} + #define PREP_RECOMPILE_START if (isNil "ACE_PREP_RECOMPILE") then {ACE_RECOMPILES = []; ACE_PREP_RECOMPILE = {{call _x} forEach ACE_RECOMPILES;}}; private _recomp = { + #define PREP_RECOMPILE_END }; call _recomp; ACE_RECOMPILES pushBack _recomp; +#else + #define LINKFUNC(x) FUNC(x) + #define PREP_RECOMPILE_START /* */ + #define PREP_RECOMPILE_END /* */ +#endif + + /** STACK TRACING **/ @@ -6,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 @@ -23,6 +40,7 @@ STACK TRACING PERFORMANCE COUNTERS SECTION **/ //#define ENABLE_PERFORMANCE_COUNTERS +// 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 5b92c93ade..fc96567785 100644 --- a/addons/main/script_macros.hpp +++ b/addons/main/script_macros.hpp @@ -1,11 +1,4 @@ -// BWC for CBA's DEBUG_SYNCHRONOUS - https://github.com/CBATeam/CBA_A3/pull/466/ -#ifdef CBA_DEBUG_SYNCHRONOUS - // For New CBA: - #define DEBUG_SYNCHRONOUS - // For Old CBA: - #define CBA_fnc_log { params ["_file","_lineNum","_message"]; diag_log [diag_frameNo, diag_tickTime, time, _file + ":"+str(_lineNum + 1), _message]; } -#endif - +#define DEBUG_SYNCHRONOUS #include "\x\cba\addons\main\script_macros_common.hpp" #include "\x\cba\addons\xeh\script_xeh.hpp" @@ -27,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) @@ -44,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 { \ @@ -67,6 +60,18 @@ count = COUNT; \ } +// weapon types +#define TYPE_WEAPON_PRIMARY 1 +#define TYPE_WEAPON_HANDGUN 2 +#define TYPE_WEAPON_SECONDARY 4 +// magazine types +#define TYPE_MAGAZINE_HANDGUN_AND_GL 16 // mainly +#define TYPE_MAGAZINE_PRIMARY_AND_THROW 256 +#define TYPE_MAGAZINE_SECONDARY_AND_PUT 512 // mainly +// more types +#define TYPE_BINOCULAR_AND_NVG 4096 +#define TYPE_WEAPON_VEHICLE 65536 +#define TYPE_ITEM 131072 // item types #define TYPE_DEFAULT 0 #define TYPE_MUZZLE 101 @@ -105,93 +110,7 @@ #define IDC_STAMINA_BAR 193 -#define ACE_LOG(module,level,message) diag_log text ACE_LOGFORMAT(module,level,message) -#define ACE_LOGFORMAT(module,level,message) FORMAT_2(QUOTE([ACE] (module) %1: %2),level,message) - -#define ACE_LOG_FILELINENUMBERS(module,level,message) diag_log text ACE_LOGFORMAT_FILELINENUMBERS(module,level,message) -#define ACE_LOGFORMAT_FILELINENUMBERS(module,level,message) FORMAT_4(QUOTE([ACE] (module) %1: %2 File: %3 Line: %4),level,message,__FILE__,__LINE__) - -#define ACE_LOGERROR(message) ACE_LOG_FILELINENUMBERS(COMPONENT,"ERROR",message) -#define ACE_LOGERROR_1(message,arg1) ACE_LOGERROR(FORMAT_1(message,arg1)) -#define ACE_LOGERROR_2(message,arg1,arg2) ACE_LOGERROR(FORMAT_2(message,arg1,arg2)) -#define ACE_LOGERROR_3(message,arg1,arg2,arg3) ACE_LOGERROR(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_LOGERROR_4(message,arg1,arg2,arg3,arg4) ACE_LOGERROR(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_LOGERROR_5(message,arg1,arg2,arg3,arg4,arg5) ACE_LOGERROR(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_LOGERROR_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_LOGERROR(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_LOGERROR_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_LOGERROR(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_LOGERROR_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_LOGERROR(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_ERRORFORMAT(message) ACE_LOGFORMAT_FILELINENUMBERS(COMPONENT,"ERROR",message) -#define ACE_ERRORFORMAT_1(message,arg1) ACE_ERRORFORMAT(FORMAT_1(message,arg1)) -#define ACE_ERRORFORMAT_2(message,arg1,arg2) ACE_ERRORFORMAT(FORMAT_2(message,arg1,arg2)) -#define ACE_ERRORFORMAT_3(message,arg1,arg2,arg3) ACE_ERRORFORMAT(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_ERRORFORMAT_4(message,arg1,arg2,arg3,arg4) ACE_ERRORFORMAT(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_ERRORFORMAT_5(message,arg1,arg2,arg3,arg4,arg5) ACE_ERRORFORMAT(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_ERRORFORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_ERRORFORMAT(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_ERRORFORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_ERRORFORMAT(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_ERRORFORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_ERRORFORMAT(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_LOGWARNING(message) ACE_LOG_FILELINENUMBERS(COMPONENT,"WARNING",message) -#define ACE_LOGWARNING_1(message,arg1) ACE_LOGWARNING(FORMAT_1(message,arg1)) -#define ACE_LOGWARNING_2(message,arg1,arg2) ACE_LOGWARNING(FORMAT_2(message,arg1,arg2)) -#define ACE_LOGWARNING_3(message,arg1,arg2,arg3) ACE_LOGWARNING(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_LOGWARNING_4(message,arg1,arg2,arg3,arg4) ACE_LOGWARNING(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_LOGWARNING_5(message,arg1,arg2,arg3,arg4,arg5) ACE_LOGWARNING(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_LOGWARNING_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_LOGWARNING(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_LOGWARNING_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_LOGWARNING(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_LOGWARNING_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_LOGWARNING(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_WARNINGFORMAT(message) ACE_LOGFORMAT_FILELINENUMBERS(COMPONENT,"WARNING",message) -#define ACE_WARNINGFORMAT_1(message,arg1) ACE_WARNINGFORMAT(FORMAT_1(message,arg1)) -#define ACE_WARNINGFORMAT_2(message,arg1,arg2) ACE_WARNINGFORMAT(FORMAT_2(message,arg1,arg2)) -#define ACE_WARNINGFORMAT_3(message,arg1,arg2,arg3) ACE_WARNINGFORMAT(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_WARNINGFORMAT_4(message,arg1,arg2,arg3,arg4) ACE_WARNINGFORMAT(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_WARNINGFORMAT_5(message,arg1,arg2,arg3,arg4,arg5) ACE_WARNINGFORMAT(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_WARNINGFORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_WARNINGFORMAT(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_WARNINGFORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_WARNINGFORMAT(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_WARNINGFORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_WARNINGFORMAT(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_LOGINFO(message) ACE_LOG(COMPONENT,"INFO",message) -#define ACE_LOGINFO_1(message,arg1) ACE_LOGINFO(FORMAT_1(message,arg1)) -#define ACE_LOGINFO_2(message,arg1,arg2) ACE_LOGINFO(FORMAT_2(message,arg1,arg2)) -#define ACE_LOGINFO_3(message,arg1,arg2,arg3) ACE_LOGINFO(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_LOGINFO_4(message,arg1,arg2,arg3,arg4) ACE_LOGINFO(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_LOGINFO_5(message,arg1,arg2,arg3,arg4,arg5) ACE_LOGINFO(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_LOGINFO_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_LOGINFO(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_LOGINFO_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_LOGINFO(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_LOGINFO_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_LOGINFO(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_INFOFORMAT(message) ACE_LOGFORMAT(COMPONENT,"INFO",message) -#define ACE_INFOFORMAT_1(message,arg1) ACE_INFOFORMAT(FORMAT_1(message,arg1)) -#define ACE_INFOFORMAT_2(message,arg1,arg2) ACE_INFOFORMAT(FORMAT_2(message,arg1,arg2)) -#define ACE_INFOFORMAT_3(message,arg1,arg2,arg3) ACE_INFOFORMAT(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_INFOFORMAT_4(message,arg1,arg2,arg3,arg4) ACE_INFOFORMAT(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_INFOFORMAT_5(message,arg1,arg2,arg3,arg4,arg5) ACE_INFOFORMAT(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_INFOFORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_INFOFORMAT(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_INFOFORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_INFOFORMAT(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_INFOFORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_INFOFORMAT(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_LOGDEBUG(message) ACE_LOG_FILELINENUMBERS(COMPONENT,"DEBUG",message) -#define ACE_LOGDEBUG_1(message,arg1) ACE_LOGDEBUG(FORMAT_1(message,arg1)) -#define ACE_LOGDEBUG_2(message,arg1,arg2) ACE_LOGDEBUG(FORMAT_2(message,arg1,arg2)) -#define ACE_LOGDEBUG_3(message,arg1,arg2,arg3) ACE_LOGDEBUG(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_LOGDEBUG_4(message,arg1,arg2,arg3,arg4) ACE_LOGDEBUG(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_LOGDEBUG_5(message,arg1,arg2,arg3,arg4,arg5) ACE_LOGDEBUG(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_LOGDEBUG_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_LOGDEBUG(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_LOGDEBUG_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_LOGDEBUG(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_LOGDEBUG_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_LOGDEBUG(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_DEBUGFORMAT(message) ACE_LOGFORMAT_FILELINENUMBERS(COMPONENT,"DEBUG",message) -#define ACE_DEBUGFORMAT_1(message,arg1) ACE_DEBUGFORMAT(FORMAT_1(message,arg1)) -#define ACE_DEBUGFORMAT_2(message,arg1,arg2) ACE_DEBUGFORMAT(FORMAT_2(message,arg1,arg2)) -#define ACE_DEBUGFORMAT_3(message,arg1,arg2,arg3) ACE_DEBUGFORMAT(FORMAT_3(message,arg1,arg2,arg3)) -#define ACE_DEBUGFORMAT_4(message,arg1,arg2,arg3,arg4) ACE_DEBUGFORMAT(FORMAT_4(message,arg1,arg2,arg3,arg4)) -#define ACE_DEBUGFORMAT_5(message,arg1,arg2,arg3,arg4,arg5) ACE_DEBUGFORMAT(FORMAT_5(message,arg1,arg2,arg3,arg4,arg5)) -#define ACE_DEBUGFORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6) ACE_DEBUGFORMAT(FORMAT_6(message,arg1,arg2,arg3,arg4,arg5,arg6)) -#define ACE_DEBUGFORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7) ACE_DEBUGFORMAT(FORMAT_7(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7)) -#define ACE_DEBUGFORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ACE_DEBUGFORMAT(FORMAT_8(message,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)) - -#define ACE_DEPRECATED(arg1,arg2,arg3) ACE_LOGWARNING_3("%1 is deprecated. Support will be dropped in version %2. Replaced by: %3",arg1,arg2,arg3) +#define ACE_DEPRECATED(arg1,arg2,arg3) WARNING_3("%1 is deprecated. Support will be dropped in version %2. Replaced by: %3",arg1,arg2,arg3) #define PFORMAT_10(MESSAGE,A,B,C,D,E,F,G,H,I,J) \ format ['%1: A=%2, B=%3, C=%4, D=%5, E=%6, F=%7, G=%8, H=%9, I=%10 J=%11', MESSAGE, RETNIL(A), RETNIL(B), RETNIL(C), RETNIL(D), RETNIL(E), RETNIL(F), RETNIL(G), RETNIL(H), RETNIL(I), RETNIL(J)] @@ -202,4 +121,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 56add6aead..65aa94f8fa 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -3,17 +3,14 @@ #define MAINPREFIX z #define PREFIX ace -#define MAJOR 3 -#define MINOR 6 -#define PATCHLVL 2 -#define BUILD 0 +#include "script_version.hpp" #define VERSION MAJOR.MINOR.PATCHLVL.BUILD #define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD // MINIMAL required version for the Mod. Components can specify others.. -#define REQUIRED_VERSION 1.62 -#define REQUIRED_CBA_VERSION {2,4,1} +#define REQUIRED_VERSION 1.84 +#define REQUIRED_CBA_VERSION {3,8,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 new file mode 100644 index 0000000000..54f90d76f7 --- /dev/null +++ b/addons/main/script_version.hpp @@ -0,0 +1,4 @@ +#define MAJOR 3 +#define MINOR 12 +#define PATCHLVL 3 +#define BUILD 36 diff --git a/addons/main/stringtable.xml b/addons/main/stringtable.xml index 225d61a51d..9f1a9d6b8d 100644 --- a/addons/main/stringtable.xml +++ b/addons/main/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ ACE Logística Logistica ACE ACE Logistique + ACE ロジスティクス + ACE 后勤 + ACE 後勤 + ACE 논리 http://ace3mod.com/ @@ -24,6 +28,8 @@ http://ace3mod.com/ http://ace3mod.com/ http://ace3mod.com/ + http://ace3mod.com/ + 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/Cfg3DEN.hpp b/addons/map/Cfg3DEN.hpp new file mode 100644 index 0000000000..bf230829f4 --- /dev/null +++ b/addons/map/Cfg3DEN.hpp @@ -0,0 +1,21 @@ + +class Cfg3DEN { + class Group { + class AttributeCategories { + class ace_attributes { + class Attributes { + class GVAR(hideBlueForceMarker) { + property = QGVAR(hideBlueForceMarker); + control = "Checkbox"; + displayName = CSTRING(disableBFT); + tooltip = CSTRING(disableBFT_description); + // groups are kaputt. have to delay setVariable public for it to work. + expression = QUOTE(if (_value) then {[ARR_2({(_this select 0) setVariable [ARR_3('%s',_this select 1,true)];},[ARR_2(_this,_value)])] call CBA_fnc_execNextFrame};); + typeName = "BOOL"; + defaultValue = "(false)"; // fix pbo project preprocessing bug + }; + }; + }; + }; + }; +}; diff --git a/addons/map/CfgLights.hpp b/addons/map/CfgLights.hpp index bd69f9acbf..c5ebc8e054 100644 --- a/addons/map/CfgLights.hpp +++ b/addons/map/CfgLights.hpp @@ -1,7 +1,7 @@ class CfgLights { - + class Chemlight_Blue; - + class ACE_FlashlightLight_White: Chemlight_Blue { brightness = 100; color[] = {1,1,1,1}; @@ -16,20 +16,24 @@ class CfgLights { start = 0.075; }; }; - + class ACE_FlashlightLight_Red: ACE_FlashlightLight_White { diffuse[] = {1,0,0}; }; - + class ACE_FlashlightLight_Blue: ACE_FlashlightLight_White { diffuse[] = {0.25,0.25,1}; }; - + class ACE_FlashlightLight_Green: ACE_FlashlightLight_White { diffuse[] = {0,1,0}; }; - + class ACE_FlashlightLight_Yellow: ACE_FlashlightLight_White { diffuse[] = {1,1,0.4}; }; -}; \ No newline at end of file + + class ACE_FlashlightLight_Orange: ACE_FlashlightLight_White { + diffuse[] = {1,0.65,0}; + }; +}; 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..16c03bd225 100644 --- a/addons/map/CfgVehicles.hpp +++ b/addons/map/CfgVehicles.hpp @@ -10,7 +10,6 @@ class CfgVehicles { exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; insertChildren = QUOTE(_this call DFUNC(compileFlashlightMenu)); showDisabled = 0; - priority = 99; }; }; }; @@ -21,7 +20,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 +80,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 683b7b1eda..6f2f60fc0c 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -63,9 +63,9 @@ call FUNC(determineZoom); setCurrentChannel GVAR(DefaultChannel); if (currentChannel == GVAR(DefaultChannel)) then { - // ACE_LOGINFO_1("Channel Set - %1", currentChannel); + // INFO_1("Channel Set - %1", currentChannel); } else { - ACE_LOGERROR_2("Failed To Set Channel %1 (is %2)", GVAR(DefaultChannel), currentChannel); + ERROR_2("Failed To Set Channel %1 (is %2)", GVAR(DefaultChannel), currentChannel); }; }, 0, []] call CBA_fnc_addPerFrameHandler; }; @@ -116,12 +116,53 @@ call FUNC(determineZoom); GVAR(hasWatch) = true; ["loadout", { - if (isNull (_this select 0)) exitWith { + params ["_unit"]; + if (isNull _unit) exitWith { GVAR(hasWatch) = true; }; GVAR(hasWatch) = false; { if (_x isKindOf ["ItemWatch", configFile >> "CfgWeapons"]) exitWith {GVAR(hasWatch) = true;}; false - } count (assignedItems ACE_player); -}] call CBA_fnc_addPlayerEventHandler; + } 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 7d00e938cf..92a7e896f3 100644 --- a/addons/map/XEH_preInit.sqf +++ b/addons/map/XEH_preInit.sqf @@ -3,6 +3,10 @@ ADDON = false; LOG(MSG_INIT); +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" ADDON = true; diff --git a/addons/map/config.cpp b/addons/map/config.cpp index b619d96d10..aab52c3536 100644 --- a/addons/map/config.cpp +++ b/addons/map/config.cpp @@ -26,6 +26,7 @@ class RscButtonMenu; class RscEdit; #include "ACE_Settings.hpp" +#include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" #include "CfgMarkers.hpp" #include "CfgVehicles.hpp" diff --git a/addons/map/functions/fnc_blueForceTrackingModule.sqf b/addons/map/functions/fnc_blueForceTrackingModule.sqf index fd839cbb38..6569fabc35 100644 --- a/addons/map/functions/fnc_blueForceTrackingModule.sqf +++ b/addons/map/functions/fnc_blueForceTrackingModule.sqf @@ -1,17 +1,19 @@ -/* -* Author: KoffeinFlummi -* Initializes the blue force tracking module. -* -* Arguments: -* Whatever the module provides. (I dunno.) -* -* Return Value: -* None -*/ - #include "script_component.hpp" - -if (!isServer) exitWith {}; +/* + * Author: KoffeinFlummi + * Initializes the blue force tracking module. + * + * Arguments: + * Whatever the module provides. (I dunno.) + * + * Return Value: + * None + * + * Example: + * call ACE_map_fnc_blueForceTrackingModule + * + * Public: No + */ params ["_logic"]; @@ -20,4 +22,4 @@ params ["_logic"]; [_logic, QGVAR(BFT_HideAiGroups), "HideAiGroups"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(BFT_ShowPlayerNames), "ShowPlayerNames"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO_3("Blue Force Tracking Module Initialized:", GVAR(BFT_Enabled), GVAR(BFT_Interval), GVAR(BFT_HideAiGroups)); +INFO_3("Blue Force Tracking Module Initialized:", GVAR(BFT_Enabled), GVAR(BFT_Interval), GVAR(BFT_HideAiGroups)); diff --git a/addons/map/functions/fnc_blueForceTrackingUpdate.sqf b/addons/map/functions/fnc_blueForceTrackingUpdate.sqf index 9f37252331..9b8e288ac4 100644 --- a/addons/map/functions/fnc_blueForceTrackingUpdate.sqf +++ b/addons/map/functions/fnc_blueForceTrackingUpdate.sqf @@ -1,5 +1,20 @@ -// #define ENABLE_PERFORMANCE_COUNTERS #include "script_component.hpp" +/* + * Author: ACE-Team + * Update the blue force tracking. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ACE_map_fnc_blueForceTrackingUpdate + * + * Public: No + */ + // BEGIN_COUNTER(blueForceTrackingUpdate); // Delete last set of markers (always) diff --git a/addons/map/functions/fnc_compileFlashlightMenu.sqf b/addons/map/functions/fnc_compileFlashlightMenu.sqf index fb33b59682..c6af389a0a 100644 --- a/addons/map/functions/fnc_compileFlashlightMenu.sqf +++ b/addons/map/functions/fnc_compileFlashlightMenu.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Compile list of flashlight classnames and add to the "Flashlight" parent menu. @@ -16,8 +17,6 @@ * Public: No */ -#include "script_component.hpp" - params ["", "_player"]; private _actions = []; @@ -39,7 +38,7 @@ _unitLight params ["_flashlight", ""]; {[_player, _this select 2] call FUNC(switchFlashlight)} }; - _action = [_x, _displayName, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); + private _action = [_x, _displayName, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _player]; } forEach _flashlightItems; diff --git a/addons/map/functions/fnc_determineMapLight.sqf b/addons/map/functions/fnc_determineMapLight.sqf index 3269c5a056..d6a0f09a08 100644 --- a/addons/map/functions/fnc_determineMapLight.sqf +++ b/addons/map/functions/fnc_determineMapLight.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko and esteldunedain * Calculates the current map illumination for a given unit @@ -9,11 +10,12 @@ * 0: Does the map needs shading? * 1: Color of the overlay * + * Example: + * [player] call ACE_map_fnc_determineMapLight + * * Public: No */ -#include "script_component.hpp" - params ["_unit"]; // Blend two colors @@ -44,9 +46,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_determineZoom.sqf b/addons/map/functions/fnc_determineZoom.sqf index efe20a0e52..45a6faeaf2 100644 --- a/addons/map/functions/fnc_determineZoom.sqf +++ b/addons/map/functions/fnc_determineZoom.sqf @@ -1,16 +1,19 @@ -/* -* Author: Rocko -* Calculate the maximum zoom level allowed for the current map -* -* Arguments: -* None -* -* Return Value: -* None -* -* Public: No -*/ #include "script_component.hpp" +/* + * Author: Rocko + * Calculate the maximum zoom level allowed for the current map + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ACE_map_fnc_determineZoom + * + * Public: No + */ private _grids = (configFile >> "CfgWorlds" >> worldName >> "Grid"); private _fourSize = -1; diff --git a/addons/map/functions/fnc_flashlightGlow.sqf b/addons/map/functions/fnc_flashlightGlow.sqf index 5d743193df..32615d014b 100644 --- a/addons/map/functions/fnc_flashlightGlow.sqf +++ b/addons/map/functions/fnc_flashlightGlow.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Add or remove global flashlight glow for when player is looking at map. @@ -16,8 +17,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_flashlightType", ["_set", true]]; private _unitLight = _unit getVariable [QGVAR(flashlight), ["", objNull]]; diff --git a/addons/map/functions/fnc_getUnitFlashlights.sqf b/addons/map/functions/fnc_getUnitFlashlights.sqf index 86eeed006d..0bbd8b7af9 100644 --- a/addons/map/functions/fnc_getUnitFlashlights.sqf +++ b/addons/map/functions/fnc_getUnitFlashlights.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Check a unit for any flashlights that can be used on map. @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit"]; private _flashlights = []; @@ -24,6 +23,6 @@ private _flashlights = []; if (isText (configFile >> "CfgWeapons" >> _x >> "ItemInfo" >> "FlashLight" >> "ACE_Flashlight_Colour")) then { _flashlights pushBackUnique _x; }; -} forEach (items _unit); +} forEach (_unit call EFUNC(common,uniqueItems)); _flashlights diff --git a/addons/map/functions/fnc_moduleMap.sqf b/addons/map/functions/fnc_moduleMap.sqf index 605c15127e..e5747d5955 100644 --- a/addons/map/functions/fnc_moduleMap.sqf +++ b/addons/map/functions/fnc_moduleMap.sqf @@ -1,18 +1,20 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Initializes the Map module. * * Arguments: - * Whatever the module provides. (I dunno.) + * Whatever the module provides. (I dunno.) * * Return Value: * None + * + * Example: + * call ACE_map_fnc_moduleMap + * + * Public: No */ -#include "script_component.hpp" - -if !(isServer) exitWith {}; - params ["_logic", "", "_activated"]; if !(_activated) exitWith {}; @@ -24,4 +26,4 @@ if !(_activated) exitWith {}; [_logic, QGVAR(mapShowCursorCoordinates), "MapShowCursorCoordinates"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(DefaultChannel), "DefaultChannel" ] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO("Map Module Initialized."); +INFO("Map Module Initialized."); diff --git a/addons/map/functions/fnc_onDrawMap.sqf b/addons/map/functions/fnc_onDrawMap.sqf index 37ec5a7000..5ad3d42fe0 100644 --- a/addons/map/functions/fnc_onDrawMap.sqf +++ b/addons/map/functions/fnc_onDrawMap.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * Something + * + * Return Value: + * None + * + * Example: + * call ACE_map_fnc_onDrawMap + * + * Public: No + */ ((_this select 0) displayCtrl 1016) ctrlShow GVAR(mapShowCursorCoordinates); diff --git a/addons/map/functions/fnc_simulateMapLight.sqf b/addons/map/functions/fnc_simulateMapLight.sqf index ba03c421a7..236914820f 100644 --- a/addons/map/functions/fnc_simulateMapLight.sqf +++ b/addons/map/functions/fnc_simulateMapLight.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voiper * Draw nearby lighting and sexy flashlight beams on main map. @@ -11,11 +12,12 @@ * Return Value: * None * + * Example: + * [CONTROL, 5, [5, 4, 6], []] call ace_map_fnc_simulateMapLight + * * Public: No */ -#include "script_component.hpp" - params ["_mapCtrl", "_mapScale", "_mapCentre", "_lightLevel"]; private _unitLight = ACE_player getVariable [QGVAR(flashlight), ["", objNull]]; @@ -44,7 +46,7 @@ _colourList sort false; private _maxColour = _colourList select 0; //ambient colour fill -_mapCtrl drawIcon [format["#(rgb,8,8,3)color(%1,%2,%3,1)", _r / _maxColour, _g / _maxColour, _b / _maxColour], [1,1,1,_colourAlpha], _mapCentre, _screenSize, _screenSize, 0, "", 0]; +_mapCtrl drawIcon ["#(rgb,8,8,3)color(1,1,1,1)", [_r / _maxColour, _g / _maxColour, _b / _maxColour, _colourAlpha], _mapCentre, _screenSize, _screenSize, 0, "", 0]; if (_flashlight == "") then { //ambient shade fill diff --git a/addons/map/functions/fnc_switchFlashlight.sqf b/addons/map/functions/fnc_switchFlashlight.sqf index cda4380d08..4fc1c75356 100644 --- a/addons/map/functions/fnc_switchFlashlight.sqf +++ b/addons/map/functions/fnc_switchFlashlight.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: voioper * Switch flashlight on/off. @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_newFlashlight"]; private _unitLight = _unit getVariable [QGVAR(flashlight), ["", objNull]]; diff --git a/addons/map/functions/fnc_updateMapEffects.sqf b/addons/map/functions/fnc_updateMapEffects.sqf index 23e97114a8..4e8d65bee2 100644 --- a/addons/map/functions/fnc_updateMapEffects.sqf +++ b/addons/map/functions/fnc_updateMapEffects.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko and esteldunedain * On map draw, updates the effects @@ -8,11 +9,12 @@ * Return Value: * None * + * Example: + * call ACE_map_fnc_updateMapEffects + * * Public: No */ -#include "script_component.hpp" - params ["_mapCtrl"]; private _mapScale = ctrlMapScale _mapCtrl; private _mapCentre = _mapCtrl ctrlMapScreenToWorld [0.5, 0.5]; @@ -32,7 +34,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..ae0e31b0ae --- /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(Module_DisplayName)], 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(Module_DisplayName)], 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(Module_DisplayName)], 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(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], + false, + true +] call CBA_settings_fnc_init; diff --git a/addons/map/script_component.hpp b/addons/map/script_component.hpp index 414d4d17c9..172a0fe838 100644 --- a/addons/map/script_component.hpp +++ b/addons/map/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MAP diff --git a/addons/map/stringtable.xml b/addons/map/stringtable.xml index 364f595637..d2cc5e90d0 100644 --- a/addons/map/stringtable.xml +++ b/addons/map/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,18 +12,26 @@ Térkép Карта Mappa + 地図 + 지도 + 地图 + 地圖 - 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? @@ -35,17 +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? @@ -57,18 +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? @@ -81,18 +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? @@ -105,18 +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? @@ -129,6 +169,10 @@ Mutatva legyen-e a kurzornál található rész rácskoordinátája? Показывать координаты около курсора мыши? Mostra la griglia coordinate sul cursore mouse? + カーソルに合わせた先を地図座標で表示しますか? + 지도에서 커서 옆에 좌표가 뜨게 합니까? + 显示滑鼠游标所在的网格座标? + 顯示滑鼠游標所在的網格座標? This module allows you to customize the map screen. @@ -141,6 +185,10 @@ Этот модуль позволяет настроить отображение карты. Este módulo permite personalizar la pantalla del mapa. Questo modulo ti permette di customizzare lo schermo della mappa. + このモジュールは地図画面を変更できます。 + 이 모듈은 지도 화면을 임의로 설정할 수 있게 해줍니다. + 此模块允许自定地图的相关效果. + 此模塊允許自定地圖的相關效果. Blue Force Tracking @@ -153,6 +201,10 @@ Blue Force követés Система слежения Blue Force Tracking Blue Force Tracking + ブルー フォース トラッキング + GPS피아식별기 + 显示蓝方踪迹 + 顯示藍方蹤跡 BFT Enable @@ -165,6 +217,10 @@ BFT engedélyezése Включить BFT Abilita BFT + BFT を有効化 + GPS피아식별기 켜기 + 蓝方踪迹启用 + 藍方蹤跡啟用 Enable Blue Force Tracking. Default: No @@ -177,6 +233,10 @@ Blue Force követés engedélyezése. Alapértelmezett: Nem Включает систему служения BFT. По-умолчанию: Нет Abilita Blue Force Tracking. Default: No + ブルー フォース トラッキングを有効化します。標準: 無効 + GPS피아식별기 켭니다. 기본설정: 아니요 + 启用显示蓝方踪迹. 预设: 否 + 啟用顯示藍方蹤跡. 預設: 否 Interval @@ -189,6 +249,10 @@ Intervallum Интервал Intervallo + 間隔 + 간격 + 间隔 + 間隔 How often the markers should be refreshed (in seconds) @@ -201,18 +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? + ¿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? @@ -225,30 +297,42 @@ Jelölők elrejtése "csak AI" csoportoknál? Скрыть маркеры групп, которые состоят полностью из ботов? Nascondi markers per gruppi di sole IA? + '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? + プレイヤの名前を表示しますか? + 각 플레이어의 이름을 표시합니까? + 显示玩家的个别名称? + 顯示玩家的個別名稱? This module allows the tracking of allied units with BFT map markers. @@ -261,6 +345,10 @@ Этот модуль позволяет отслеживать перемещение союзных войск по карте при помощи маркеров BFT. Este módulo permite el seguimiento de las unidades aliadas con marcadores de mapa BFT. Questo modulo permette il tracciamento di unità alleate con i marker BFT in mappa + モジュールは BFT マップ マーカとともに、同勢力ユニットの追跡を許可します。 + 이 모듈은 아군을 지도상에서 추적할 수 있게 해줍니다. + 此模块将使你能在地图上看见友方单位的踪迹 + 此模塊將使你能在地圖上看見友方單位的蹤跡 Flashlights @@ -272,6 +360,10 @@ Svítilny Linternas Torcia + フラッシュライト + 손전등 + 手电筒 + 手電筒 NVG @@ -283,6 +375,10 @@ NVG NVG NVG + 夜間暗視装置 + 야투경 + 夜视镜 + 夜視鏡 On @@ -294,6 +390,10 @@ Zapnout Encendido Acceso + 起動 + 켜기 + 开启 + 開啟 Off @@ -305,6 +405,10 @@ Vypnout Apagado Spento + 停止 + 끄기 + 关闭 + 關閉 Increase Brightness @@ -316,6 +420,10 @@ Zvýšit jas Aumentar brillo Aumenta Luminosità + 明度を上げる + 밝기 올리기 + 增加亮度 + 增加亮度 Decrease Brightness @@ -327,6 +435,10 @@ Snížit jas Reducir brillo Diminuisci Luminosità + 明度を下げる + 밝기 내리기 + 降低亮度 + 降低亮度 Turn On %1 @@ -339,6 +451,10 @@ %1 Bekapcsolása Ativar %1 Активировать %1 + %1 を点ける + %1 켜기 + 开启%1 + 開啟%1 Turn Off %1 @@ -351,6 +467,10 @@ %1 Kikapcsolása Desativar %1 Деактивировать %1 + %1 を消す + %1 끄기 + 关闭%1 + 關閉%1 Set Channel At Start @@ -362,6 +482,10 @@ Imposta Canale all'Avvio Setear canal al comenzar Mettre un canal par défaut + 開始時のチャンネルを決定 + 시작시 채널 + 设定游戏开始时的聊天频道 + 設定遊戲開始時的聊天頻道 Change the starting marker channel at mission start @@ -373,6 +497,32 @@ Cambia il canale marker iniziale all'avvio di missione Cambiar el canal de marcadores inicial al comenzar la misión Change le canal de communication par défaut au début de la mission. + ミッション開始時にあらかじめ設定されているマーカ チャンネルを変更します + 미션시작시 마커채널을 변경합니다 + 更改任务启动时的聊天频道 + 更改任務啟動時的聊天頻道 + + + Disable BFT + BFT deaktivieren + BFTを無効化 + GPS피아식별기 끄기 + Wyłącz BFT + Désactive le BFT + Disablita BFT + 关闭友军踪迹 + 關閉友軍蹤跡 + + + Always disable Blue Force Tracking for this group. + Blue Force Tracking für diese Gruppe immer deaktivieren. + このグループへのブルー フォース トラッキングを常に無効化します。 + 이 그룹에 한해 GPS피아식별기를 항상 끕니다. + 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. + 对此小队永远关闭友军踪迹显示 + 對此小隊永遠關閉友軍蹤跡顯示 - \ No newline at end of file + diff --git a/addons/map_gestures/ACE_Settings.hpp b/addons/map_gestures/ACE_Settings.hpp index 3730c08c58..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); @@ -44,18 +46,4 @@ class ACE_Settings { typeName = "COLOR"; value[] = {1, 0.88, 0, 0.7}; }; - class GVAR(groupColorConfigurations) { - displayName = CSTRING(groupColorConfigurations_displayName); - description = CSTRING(groupColorConfigurations_description); - category = CSTRING(mapGestures_category); - typeName = "ARRAY"; - value[] = {}; - }; - class GVAR(groupColorConfigurationMapping) { - displayName = CSTRING(groupColorConfigurationMapping_displayName); - description = CSTRING(groupColorConfigurationMapping_description); - category = CSTRING(mapGestures_category); - typeName = "ARRAY"; - value[] = {{}, {}}; - }; }; diff --git a/addons/map_gestures/CfgEventHandlers.hpp b/addons/map_gestures/CfgEventHandlers.hpp index b0848d0248..becf395052 100644 --- a/addons/map_gestures/CfgEventHandlers.hpp +++ b/addons/map_gestures/CfgEventHandlers.hpp @@ -14,6 +14,5 @@ class Extended_PreInit_EventHandlers { class Extended_PostInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_postInit)); - serverInit = QUOTE(call COMPILE_FILE(XEH_serverPostInit)); }; }; diff --git a/addons/map_gestures/CfgVehicles.hpp b/addons/map_gestures/CfgVehicles.hpp index 5593d66181..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); @@ -47,7 +47,7 @@ class CfgVehicles { category = "ACE"; displayName = CSTRING(moduleGroupSettings_displayName); function = QFUNC(moduleGroupSettings); - isGlobal = 0; + isGlobal = 2; author = ECSTRING(common,ACETeam); icon = QPATHTOF(ui\icon_module_map_gestures_ca.paa); class Arguments { diff --git a/addons/map_gestures/XEH_PREP.hpp b/addons/map_gestures/XEH_PREP.hpp index eba9f5bfe8..8d457bd7e0 100644 --- a/addons/map_gestures/XEH_PREP.hpp +++ b/addons/map_gestures/XEH_PREP.hpp @@ -1,5 +1,5 @@ -PREP(assignClientIDOnServer); +PREP(addGroupColorMapping); PREP(drawMapGestures); PREP(endTransmit); PREP(getProximityPlayers); diff --git a/addons/map_gestures/XEH_postInit.sqf b/addons/map_gestures/XEH_postInit.sqf index 185eaf97f0..cc3daf6a06 100644 --- a/addons/map_gestures/XEH_postInit.sqf +++ b/addons/map_gestures/XEH_postInit.sqf @@ -1,13 +1,24 @@ #include "script_component.hpp" if (["STMapGestures"] call EFUNC(common,isModLoaded)) exitWith { - ACE_LOGWARNING("st_map_gestures is installed - exiting [remove st_map_gestures.pbo to allow ace version]"); + WARNING("st_map_gestures is installed - exiting [remove st_map_gestures.pbo to allow ace version]"); }; if (!hasInterface) exitWith {}; ["ace_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; + + // This will set QEGVAR(common,playerOwner) var on player objects + [] call EFUNC(common,setPlayerOwner); + + GVAR(pointPosition) = [0,0,0]; + + [QGVAR(syncPos), { + params ["_unit", "_pointPos"]; + _unit setVariable [QGVAR(pointPosition), _pointPos]; + }] call CBA_fnc_addEventHandler; + [{ if (isNull (findDisplay 12)) exitWith {}; diff --git a/addons/map_gestures/XEH_preInit.sqf b/addons/map_gestures/XEH_preInit.sqf index a7feade1c3..92387036e4 100644 --- a/addons/map_gestures/XEH_preInit.sqf +++ b/addons/map_gestures/XEH_preInit.sqf @@ -2,6 +2,10 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +GVAR(GroupColorCfgMappingNew) = call CBA_fnc_createNamespace; ADDON = true; diff --git a/addons/map_gestures/XEH_serverPostInit.sqf b/addons/map_gestures/XEH_serverPostInit.sqf deleted file mode 100644 index 1b70e24149..0000000000 --- a/addons/map_gestures/XEH_serverPostInit.sqf +++ /dev/null @@ -1,3 +0,0 @@ -#include "script_component.hpp" - -[QGVAR(noOwnerID), FUNC(assignClientIDOnServer)] call CBA_fnc_addEventHandler; diff --git a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf new file mode 100644 index 0000000000..eaf319bc90 --- /dev/null +++ b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Dslyecxi, MikeMatrix, PabstMirror + * Adds a group id color mapping. + * + * Arguments: + * 0: Group ID or group + * 1: Leader color array (4 numbers including alpha) + * 2: Unit (non-leader) color array (4 numbers including alpha) + * + * Return Value: + * None + * + * Example: + * ["Alpha 1-1", [1,0,0,1], [0,1,0,1]] call ace_map_gestures_fnc_addGroupColorMapping + * + * Public: Yes + */ + +if (!params [["_group", "", [grpNull, ""]], ["_leadColor", [1,1,1,1], [[]], 4], ["_unitColor", [1,1,1,1], [[]], 4]]) exitWith { + ERROR_1("Bad Params: %1",_this); +}; +TRACE_3("params",_group,_leadColor,_unitColor); + +if (_group isEqualType grpNull) then {_group = groupID _group}; + +if (_group == "") exitWith {ERROR("Group ID is blank, which is not valid.")}; +if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; +if (!([_unitColor] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; + +GVAR(GroupColorCfgMappingNew) setVariable [_group, [_leadColor, _unitColor]]; diff --git a/addons/map_gestures/functions/fnc_assignClientIDOnServer.sqf b/addons/map_gestures/functions/fnc_assignClientIDOnServer.sqf deleted file mode 100644 index 92b1e95ab5..0000000000 --- a/addons/map_gestures/functions/fnc_assignClientIDOnServer.sqf +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Author: Dslyecxi, MikeMatrix - * Assign readable client ID to unit on the server. - * - * Arguments: - * 0: Unit name - * - * Return Value: - * None - * - * Example: - * ["MikeMatrix"] call ace_map_gestures_fnc_assignClientIDOnServer - * - * Public: No - */ -#include "script_component.hpp" - -params ["_unitName"]; - -{ - if (name _x == _unitName) exitWith { - _x setVariable [QGVAR(owner_id), owner _x, true]; - }; -} count playableUnits; diff --git a/addons/map_gestures/functions/fnc_drawMapGestures.sqf b/addons/map_gestures/functions/fnc_drawMapGestures.sqf index 728126531e..2aecd2388f 100644 --- a/addons/map_gestures/functions/fnc_drawMapGestures.sqf +++ b/addons/map_gestures/functions/fnc_drawMapGestures.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Receives and draws map gestures from nearby players. @@ -13,7 +14,8 @@ * * Public: No */ -#include "script_component.hpp" + +BEGIN_COUNTER(draw); #define ICON_RENDER_SIZE 55 #define ICON_TEXT_ALIGN "left" @@ -26,36 +28,34 @@ if (!GVAR(enabled) || !visibleMap) exitWith {}; -private ["_color", "_drawPosVariableName", "_group", "_grpName", "_pos", "_unitUID"]; - params ["_mapHandle"]; // Iterate over all nearby players and render their pointer if player is transmitting. { - // Data variable name for unit - _unitUID = getPlayerUID _x; - _drawPosVariableName = if (!isNil "_unitUID" && _unitUID != "") then {format [QGVAR(%1_DrawPos), _unitUID]} else {nil}; - if (!isNil "_drawPosVariableName") then { - if (isNil {missionNamespace getVariable _drawPosVariableName}) then {missionNamespace setVariable [_drawPosVariableName, [1, 1, 1]];}; - _pos = missionNamespace getVariable _drawPosVariableName; + // Only render if the unit is alive and transmitting + if (alive _x && {_x getVariable [QGVAR(Transmit), false]}) then { - // Only render if the unit is alive and transmitting - if (alive _x && {_x getVariable QGVAR(Transmit)}) then { - _group = group _x; - _grpName = groupID _group; + private _pos = _x getVariable [QGVAR(pointPosition), [0,0,0]]; - // If color settings for the group exist, then use those, otherwise fall back to the default colors - _color = if ([GVAR(GroupColorConfigurationMapping), _grpName] call CBA_fnc_hashHasKey) then { - (GVAR(GroupColorConfigurations) select ([GVAR(GroupColorConfigurationMapping), _grpName] call CBA_fnc_hashGet)) select (_x != leader _group) - } else { - if (_x == leader _group) then {GVAR(defaultLeadColor)} else {GVAR(defaultColor)}; - }; + private _group = group _x; + private _grpName = groupID _group; - // Render icon and player name - _mapHandle drawIcon ["\a3\ui_f\data\gui\cfg\Hints\icon_text\group_1_ca.paa", _color, _pos, ICON_RENDER_SIZE, ICON_RENDER_SIZE, ICON_ANGLE, "", ICON_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN]; - _mapHandle drawIcon ["#(argb,8,8,3)color(0,0,0,0)", GVAR(nameTextColor), _pos, TEXT_ICON_RENDER_SIZE, TEXT_ICON_RENDER_SIZE, ICON_ANGLE, name _x, TEXT_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN]; + // If color settings for the group exist, then use those, otherwise fall back to the default colors + private _colorMap = GVAR(GroupColorCfgMappingNew) getVariable _grpName; + private _color = if (isNil "_colorMap") then { + [GVAR(defaultLeadColor), GVAR(defaultColor)] select (_x != leader _group); + } else { + _colorMap select (_x != leader _group); }; + + TRACE_2("",_colorMap,_color); + + // Render icon and player name + _mapHandle drawIcon ["\a3\ui_f\data\gui\cfg\Hints\icon_text\group_1_ca.paa", _color, _pos, ICON_RENDER_SIZE, ICON_RENDER_SIZE, ICON_ANGLE, "", ICON_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN]; + _mapHandle drawIcon ["#(argb,8,8,3)color(0,0,0,0)", GVAR(nameTextColor), _pos, TEXT_ICON_RENDER_SIZE, TEXT_ICON_RENDER_SIZE, ICON_ANGLE, name _x, TEXT_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN]; }; nil } count ([ACE_player, GVAR(maxRange)] call FUNC(getProximityPlayers)); + +END_COUNTER(draw); diff --git a/addons/map_gestures/functions/fnc_endTransmit.sqf b/addons/map_gestures/functions/fnc_endTransmit.sqf index fc3e0e81e1..e591cd39ba 100644 --- a/addons/map_gestures/functions/fnc_endTransmit.sqf +++ b/addons/map_gestures/functions/fnc_endTransmit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Ensure that all variables used to indicate transmission are disabled. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (!GVAR(enabled)) exitWith {}; diff --git a/addons/map_gestures/functions/fnc_getProximityPlayers.sqf b/addons/map_gestures/functions/fnc_getProximityPlayers.sqf index e4ec44837b..9718095b01 100644 --- a/addons/map_gestures/functions/fnc_getProximityPlayers.sqf +++ b/addons/map_gestures/functions/fnc_getProximityPlayers.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Returns all players in a given range and in the units vehicle. @@ -10,15 +11,15 @@ * All units in proximity * * Example: - * ["example value"] call ace_module_fnc_functionName + * [player, 7] call ace_map_gestures_fnc_getProximityPlayers * * Public: No */ -#include "script_component.hpp" params ["_unit", "_range"]; private _proximityPlayers = (getPos _unit) nearEntities [["CAMAnBase"], _range]; _proximityPlayers deleteAt (_proximityPlayers find _unit); _proximityPlayers append (crew vehicle _unit); -_proximityPlayers + +_proximityPlayers select {[_x, false] call EFUNC(common,isPlayer);} diff --git a/addons/map_gestures/functions/fnc_initTransmit.sqf b/addons/map_gestures/functions/fnc_initTransmit.sqf index 604bf9e233..782b4c9666 100644 --- a/addons/map_gestures/functions/fnc_initTransmit.sqf +++ b/addons/map_gestures/functions/fnc_initTransmit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Initializes transmitting map gestures. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (!GVAR(enabled)) exitWith {}; diff --git a/addons/map_gestures/functions/fnc_isValidColorArray.sqf b/addons/map_gestures/functions/fnc_isValidColorArray.sqf index fdf89a46d6..8abaf4f375 100644 --- a/addons/map_gestures/functions/fnc_isValidColorArray.sqf +++ b/addons/map_gestures/functions/fnc_isValidColorArray.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: MikeMatrix * Validate if an array is in the propper color format. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" scopeName "main"; diff --git a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf index 52ae6d0a49..fb87822a30 100644 --- a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Initializes Settings for the groups modules and transcodes settings to a useable format. @@ -15,31 +16,19 @@ * * Public: No */ -#include "script_component.hpp" - -private ["_color", "_configurationGroupMappings", "_configurationIndex", "_configurations", "_leadColor"]; params ["_logic", "_units", "_activated"]; +TRACE_3("params",_logic,_units,_activated); -if (!_activated || !isServer) exitWith {}; +if (!_activated) exitWith {}; // Transcode string setting into usable array. Example: "1,1,1,1" -> [1, 1, 1, 1] -_leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]"); +private _leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]"); if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; -_color = call compile ("[" + (_logic getVariable ["color", ""]) + "]"); +private _color = call compile ("[" + (_logic getVariable ["color", ""]) + "]"); if (!([_color] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; -// If we already have color configurations from another source, use those, otherwise use default. -_configurations = if (isNil QGVAR(GroupColorConfigurations)) then { [] } else { +GVAR(GroupColorConfigurations) }; -_configurationGroupMappings = if(isNil QGVAR(GroupColorConfigurationMapping)) then { [] call CBA_fnc_hashCreate } else { +GVAR(GroupColorConfigurationMapping) }; - -// Save custom color configuration and keep the index of the entry. -_configurationIndex = _configurations pushBack [_leadColor, _color]; - // Add all synchronized groups and reference custom configuration for them { - [_configurationGroupMappings, groupID group _x, _configurationIndex] call CBA_fnc_hashSet; + [group _x, _leadColor, _color] call FUNC(addGroupColorMapping); } forEach _units; - -[QGVAR(GroupColorConfigurations), _configurations, false, true] call EFUNC(common,setSetting); -[QGVAR(GroupColorConfigurationMapping), _configurationGroupMappings, false, true] call EFUNC(common,setSetting); diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index 56d3235d03..93525226ea 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Initializes Settings for the module and transcodes settings to a useable format. @@ -15,11 +16,10 @@ * * Public: No */ -#include "script_component.hpp" 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; }; -ACE_LOGINFO("Map Gestures Module Initialized."); +INFO("Map Gestures Module Initialized."); diff --git a/addons/map_gestures/functions/fnc_receiverInit.sqf b/addons/map_gestures/functions/fnc_receiverInit.sqf index b132dad1d7..0effb9a7d5 100644 --- a/addons/map_gestures/functions/fnc_receiverInit.sqf +++ b/addons/map_gestures/functions/fnc_receiverInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Initializes the receiver and hooks it to the Draw event of the map. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" ACE_player setVariable [QGVAR(Transmit), false, true]; GVAR(EnableTransmit) = false; @@ -22,4 +22,4 @@ if (!isNil QGVAR(DrawMapHandlerID)) then { (findDisplay 12 displayCtrl 51) ctrlRemoveEventHandler ["Draw", GVAR(DrawMapHandlerID)]; GVAR(DrawMapHandlerID) = nil; }; -GVAR(DrawMapHandlerID) = findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw", FUNC(drawMapGestures)]; +GVAR(DrawMapHandlerID) = findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw", {call FUNC(drawMapGestures)}]; diff --git a/addons/map_gestures/functions/fnc_transmit.sqf b/addons/map_gestures/functions/fnc_transmit.sqf index aacff9e679..1b1f462f01 100644 --- a/addons/map_gestures/functions/fnc_transmit.sqf +++ b/addons/map_gestures/functions/fnc_transmit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Transmit PFH @@ -14,9 +15,8 @@ * * Public: No */ -#include "script_component.hpp" -private ["_ownerID", "_unitUID", "_drawPosVariableName", "_playerOwnerID"]; +BEGIN_COUNTER(transmit); params ["", "_pfhId"]; @@ -29,17 +29,14 @@ if (!GVAR(EnableTransmit) || !visibleMap) exitWith { }; { - _ownerID = _x getVariable QGVAR(owner_id); - if (isNil "_ownerID") then { - [QGVAR(noOwnerID), [name _x]] call CBA_fnc_serverEvent; - } else { - _playerOwnerID = ACE_player getVariable QGVAR(owner_id); - if (!isNil "_playerOwnerID" && _ownerID != _playerOwnerID) then { - _unitUID = getPlayerUID ACE_Player; - _drawPosVariableName = if (!isNil "_unitUID" && _unitUID != "") then {format [QGVAR(%1_DrawPos), _unitUID]} else {nil}; - if (!isNil "_drawPosVariableName") then { - _ownerID publicVariableClient _drawPosVariableName; - }; + private _owner = _x getVariable [QEGVAR(common,playerOwner), -1]; + if (_owner > -1) then { + private _remotePos = _x getVariable [QGVAR(remotePos), [0,0,0]]; + if ((_remotePos distance2d GVAR(pointPosition)) > 1) then { // Only transmit when actually moving + [QGVAR(syncPos), [ACE_Player, GVAR(pointPosition)], _owner] call CBA_fnc_ownerEvent; + _x setVariable [QGVAR(remotePos), GVAR(pointPosition)]; }; }; } count ([ACE_player, GVAR(maxRange)] call FUNC(getProximityPlayers)); + +END_COUNTER(transmit); diff --git a/addons/map_gestures/functions/fnc_transmitterInit.sqf b/addons/map_gestures/functions/fnc_transmitterInit.sqf index d115fb22c5..a081ef5b14 100644 --- a/addons/map_gestures/functions/fnc_transmitterInit.sqf +++ b/addons/map_gestures/functions/fnc_transmitterInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Dslyecxi, MikeMatrix * Initializes the transmitting event handlers. @@ -13,13 +14,10 @@ * * Public: No */ -#include "script_component.hpp" - -private ["_mapCtrl", "_unitUID", "_drawPosVariableName"]; disableSerialization; -_mapCtrl = findDisplay 12 displayCtrl 51; +private _mapCtrl = findDisplay 12 displayCtrl 51; // MouseMoving EH. if (!isNil QGVAR(MouseMoveHandlerID)) then { @@ -28,7 +26,7 @@ if (!isNil QGVAR(MouseMoveHandlerID)) then { }; GVAR(MouseMoveHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseMoving", { // Don't transmit any data if we're using the map tools - if (!GVAR(EnableTransmit) || EGVAR(maptools,mapTool_isDragging) || EGVAR(maptools,mapTool_isRotating)) exitWith {}; + if (!GVAR(EnableTransmit) || {(["ace_maptools"] call EFUNC(common,isModLoaded)) && {EGVAR(maptools,mapTool_isDragging) || EGVAR(maptools,mapTool_isRotating)}}) exitWith {}; params ["_control", "_posX", "_posY"]; @@ -36,11 +34,7 @@ GVAR(MouseMoveHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseMoving", { ACE_player setVariable [QGVAR(Transmit), true, true]; }; - _unitUID = getPlayerUID ACE_player; - _drawPosVariableName = if (!isNil "_unitUID" && _unitUID != "") then {format [QGVAR(%1_DrawPos), _unitUID]} else {nil}; - if (!isNil "_drawPosVariableName") then { - missionNamespace setVariable [_drawPosVariableName, _control ctrlMapScreenToWorld [_posX, _posY]]; - }; + GVAR(pointPosition) = _control ctrlMapScreenToWorld [_posX, _posY]; }]; // MouseDown EH @@ -51,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 @@ -66,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/script_component.hpp b/addons/map_gestures/script_component.hpp index 96189555f9..ca428f8725 100644 --- a/addons/map_gestures/script_component.hpp +++ b/addons/map_gestures/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MAP_GESTURES diff --git a/addons/map_gestures/stringtable.xml b/addons/map_gestures/stringtable.xml index e89d6c07a3..feb98f2091 100644 --- a/addons/map_gestures/stringtable.xml +++ b/addons/map_gestures/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ Kartenzeichen Gestos en mapa Gestes de carte + マップ ジェスチャ + 지도 신호 + 地图标识器 + 地圖指示器 Enabled @@ -22,6 +26,10 @@ Aktiviert Activado Activer + 有効化 + 켜기 + 启用 + 啟用 Map Gesture Max Range @@ -33,6 +41,10 @@ Maximale Reichweite der Kartenzeichen Máx. dist. para gestos en mapa Distance max. des gestes de carte + マップ ジェスチャの最大範囲 + 지도 신호 최대 거리 + 地图标识器最大范围 + 地圖指示器最大範圍 Max range between players to show the map gesture indicator [default: 7 meters] @@ -44,6 +56,10 @@ Maximale Reichweite zwischen Spielern um Kartenzeichen anzuzeigen (Standard: 7 Meter) Máxima distancia a la cual pueden verse el indicador de gestos [defecto: 7 m] Distance max. entre les joueurs pour montrer le pointage sur carte. (Défaut : 7m) + プレイヤのマップ ジェスチャによる表示範囲を設定します [標準:7 メートル] + 플레이어간에 지도 신호 표시거리를 설정합니다. [기본: 7 미터] + 设定地图标识器显示的最大范围距离 [预设: 7公尺] + 設定地圖指示器顯示的最大範圍距離 [預設: 7公尺] Lead Default Color @@ -55,6 +71,10 @@ Gruppenführer-Standardfarbe Color por defecto para el lider Couleur principale de commandement. + リーダー用標準の色 + 리더 기본 색상 + 队长预设颜色 + 隊長預設顏色 Fallback Color value for group leaders when there is no group setting. [Module: leave blank to not force on clients] @@ -65,6 +85,10 @@ Ersatz-Farbwert für Gruppenführer wenn keine Gruppeneinstellung vorhanden ist. [Modul: leer lassen um Anwendung bei Clients nicht zu erzwingen] Color por defecto para líderes cuando no está configurado [Módulo: dejar en blanco para no forzar] 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 @@ -76,6 +100,10 @@ Standardfarbe Color por defecto Couleur par défaut + 標準色 + 기본 색상 + 预设颜色 + 預設顏色 Fallback Color value when there is no group setting. [Module: leave blank to not force on clients] @@ -86,6 +114,10 @@ Ersatz-Farbwert wenn keine Gruppeneinstellung vorhanden ist. [Modul: leer lassen um Anwendung bei Clients nicht zu erzwingen] Color por defecto cuando no está configurado [Módulo: dejar en blanco para no forzar] 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 @@ -97,6 +129,10 @@ Gruppenführer-Farbe Color para el líder Couleur de commandement + リーダー用の色 + 리더 색상 + 队长颜色 + 隊長顏色 Color value for group leaders of groups synced with this module. @@ -107,6 +143,10 @@ Farbwert für Gruppenführer, die mit diesem Modul synchronisiert werden. Color para los líderes de los grupos sincronizados al módulo. Couleur pour les chefs de groupe des groupes synchronisés avec le module. + モジュールで同期されたグループのリーダー用に色の値を決定します。 + 그룹이 이 모듈에 동기화 됐을때의 리더 색상입니다. + 改变与此同步小队队长的标识器颜色。 + 改變與此同步小隊隊長的指示器顏色 Color @@ -118,6 +158,10 @@ Farbe Color Couleur + + 색상 + 颜色 + 顏色 Color value for group members of groups synced with this module. @@ -128,6 +172,10 @@ Farbwert für Gruppenmitglieder, die mit diesem Modul synchronisiert werden. Color para los miembros de los grupos sincronizados al módulo. Couleur pour les membres du groupe synchronisé avec ce module. + モジュールで同期されたグループのメンバ用に色の値を決定します。 + 그룹이 이 모듈에 동기화 됐을때의 멤버 색상입니다. + 改变与此同步小队队员的标识器颜色 + 改變與此同步小隊隊員的指示器顏色 Map Gestures - Group Settings @@ -139,6 +187,10 @@ Kartenzeichen - Gruppeneinstellungen Gestos en mapas - Configuración de grupos Gestes de carte - réglages de groupe + マップ ジェスチャ - グループ設定 + 지도 신호 - 그룹 설정 + 地图标识器 - 队伍设定 + 地圖指示器 - 隊伍設定 Update Interval @@ -150,6 +202,10 @@ Update-Intervall Período de actualización Intervalle de mise à jour + 更新間隔 + 갱신 간격 + 更新间隔 + 更新間隔 Time between data updates. @@ -161,47 +217,10 @@ Zeit zwischen Datenupdates. Tiempo entre actualizaciones sucesivas. Temps entre les actualisations de données - - - Group color configurations - Configurações de cores de grupo - Konf. koloru grup - Конфигурация цвета групп - Konfigurace barvy pro skupinu - Configurazioni colori dei gruppi - Konfiguration der Gruppenfarbe - Configuración de color de grupo - Configuration des couleurs de groupe - - - Group color configuration containing arrays of color pairs ([leadColor, color]). - Configuração de cores de grupo contendo arrays com pares de cores ([leadColor, color]). - Konfiguracja kolorów grup zawierająca tablice par kolorów ([kolorLidera, kolor]). - Конфигурация цвета групп содержит массив цветовых пар ([лид. цвет, цвет]). - Configurazioni colori gruppi contenenti array di coppie di colori ([leadColor, color]). - Konfiguration der Gruppenfarbe mit zugeordneten Farbpaaren der Aufstellung ([leadColor, color]). - Configuración de color de grupo conteniendo una lista de pares de colores ([colorLider, colo]). - Configuration des couleurs de groupe contenant des tableaux de paires de couleurs ([couleurDeCommandement, couleur]). - - - Hash of Group ID mapped to the Group color configuration index. - Hashes de ID de grupos mapeados para o índice de configuração de cor de grupos. - Hasz ID grup zmapowanych w indeksie konfiguracji koloru grup. - Хеш ID групп, соответствующих индексам конфигурации цвета групп. - Hash degli ID Gruppi mappati nell'indice configurazioni colori gruppi. - Hashwert der Gruppen-ID, die dem Konfigurations-Index der Gruppenfarbe zugeordnet werden. - ID de Grupo mapeado al índice de la configuración de color de grupo. - Hash de l'identifiant du groupe mappé à l'index de la configuration de la couleur du groupe. - - - GroupID Color configuration mapping - Mapeamento de configuração para cores de GroupID - Mapowanie kolorów poprzez GroupID - Соответствие ID групп конфигурации цвета групп - Mappatura configurazioni colori GroupID - Gruppen-ID-Farbe Konfigurationszuordnung - Mapeado de ID de Grupo - Configuration du mappage de l'identifiant de la couleur du groupe. + データの更新間隔 + 데이터 갱신 간격 + 定义每次更新数据的时间. + 定義每次更新數據的時間 Enables the Map Gestures. @@ -213,6 +232,10 @@ Aktiviert die Kartenzeichen. Activar Gestos en Mapa Activer les gestes de carte + マップ ジェスチャを有効化 + 지도 신호 활성화 + 启用地图标识器 + 啟用地圖指示器 Name Text Color @@ -224,6 +247,10 @@ Farbe der Namenstexte. Color de los nombres Couleur du texte du nom + 名前への色 + 글 색상 명칭 + 名称文字颜色 + 名稱文字顏色 Color of the name tag text besides the map gestures mark. @@ -234,6 +261,10 @@ Farbe der Namenstexte neben der Kartenzeichen-Markierung. Color de los nombres dibujados al lado del marcados de gestos. Couleur des tags de nom à côté de marqueur de pointage sur carte. + マップ ジェスチャに表示される、名前の色を決定します。 + 지도 색상에 표시되는 이름의 색상을 결정합니다. + 定义名称文字颜色。使其与地图标识器颜色有所区别。 + 定義名稱文字顏色。使其與地圖指示器顏色有所區別 Map Gestures @@ -245,6 +276,10 @@ Kartenzeichen Gestos en mapa Gestes de carte + マップ ジェスチャ + 지도 신호 + 地图标识器 + 地圖指示器 diff --git a/addons/maptools/ACE_Settings.hpp b/addons/maptools/ACE_Settings.hpp index 0da43b64ca..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,4 +8,12 @@ class ACE_Settings { description = CSTRING(rotateModifierKey_description); values[] = {"$STR_A3_OPTIONS_DISABLED", "ALT", "CTRL", "SHIFT"}; }; + class GVAR(drawStraightLines) { + category = CSTRING(Name); + value = 1; + typeName = "BOOL"; + isClientSettable = 1; + displayName = CSTRING(drawStraightLines_displayName); + description = CSTRING(drawStraightLines_description); + }; }; diff --git a/addons/maptools/CfgVehicles.hpp b/addons/maptools/CfgVehicles.hpp index 6c9bdc74d9..2e5663e251 100644 --- a/addons/maptools/CfgVehicles.hpp +++ b/addons/maptools/CfgVehicles.hpp @@ -2,14 +2,12 @@ class CfgVehicles { class Man; class CAManBase: Man { class ACE_SelfActions { - class ACE_MapGpsShow { displayName = CSTRING(MapGpsShow); condition = QUOTE((!GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)}); statement = QUOTE(GVAR(mapGpsShow) = true; [GVAR(mapGpsShow)] call FUNC(openMapGps)); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 0; - priority = 0; }; class ACE_MapGpsHide { displayName = CSTRING(MapGpsHide); @@ -17,24 +15,19 @@ class CfgVehicles { statement = QUOTE(GVAR(mapGpsShow) = false; [GVAR(mapGpsShow)] call FUNC(openMapGps)); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 0; - priority = 0; }; - class ACE_MapTools { displayName = CSTRING(MapTools_Menu); condition = QUOTE(call FUNC(canUseMapTools)); statement = ""; exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 0; - priority = 100; - class ACE_MapToolsHide { displayName = CSTRING(MapToolsHide); condition = QUOTE(GVAR(mapTool_Shown) != 0); statement = QUOTE(GVAR(mapTool_Shown) = 0;); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 1; - priority = 5; }; class ACE_MapToolsShowNormal { displayName = CSTRING(MapToolsShowNormal); @@ -42,7 +35,6 @@ class CfgVehicles { statement = QUOTE(GVAR(mapTool_Shown) = 1;); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 1; - priority = 4; }; class ACE_MapToolsShowSmall { displayName = CSTRING(MapToolsShowSmall); @@ -50,7 +42,6 @@ class CfgVehicles { statement = QUOTE(GVAR(mapTool_Shown) = 2;); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 1; - priority = 3; }; class ACE_MapToolsAlignNorth { displayName = CSTRING(MapToolsAlignNorth); @@ -58,7 +49,6 @@ class CfgVehicles { statement = QUOTE(GVAR(mapTool_angle) = 0;); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 1; - priority = 2; }; class ACE_MapToolsAlignCompass { displayName = CSTRING(MapToolsAlignCompass); @@ -66,7 +56,6 @@ class CfgVehicles { statement = QUOTE(GVAR(mapTool_angle) = getDir ACE_player;); exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; showDisabled = 1; - priority = 1; }; }; }; 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/MapGpsUI.hpp b/addons/maptools/MapGpsUI.hpp index c5b230f163..cd0a418465 100644 --- a/addons/maptools/MapGpsUI.hpp +++ b/addons/maptools/MapGpsUI.hpp @@ -40,7 +40,8 @@ class RscTitles { colorBackground[] = {0,0,0,0}; colorText[] = {0.247,0.251,0.157,1}; shadowColo[] = {0,0,0,0}; - font = "EtelkaNarrowMediumPro"; + // EtelkaNarrowMediumPro broke with 1.72 hotfix, can revert back to that font if fixed (following 3 uses of PuristaSemibold) + font = "PuristaSemibold"; shadow = 0; sizeEx = 0.042; }; @@ -55,7 +56,7 @@ class RscTitles { colorBackground[] = {0,0,0,0}; colorText[] = {0.247,0.251,0.157,1}; shadowColo[] = {0,0,0,0}; - font = "EtelkaNarrowMediumPro"; + font = "PuristaSemibold"; shadow = 0; sizeEx = 0.042; }; @@ -70,7 +71,7 @@ class RscTitles { colorBackground[] = {0,0,0,0}; colorText[] = {0.247,0.251,0.157,1}; shadowColo[] = {0,0,0,0}; - font = "EtelkaNarrowMediumPro"; + font = "PuristaSemibold"; shadow = 0; sizeEx = 0.1; }; diff --git a/addons/maptools/XEH_PREP.hpp b/addons/maptools/XEH_PREP.hpp index 1670c59593..eac6947431 100644 --- a/addons/maptools/XEH_PREP.hpp +++ b/addons/maptools/XEH_PREP.hpp @@ -1,6 +1,7 @@ PREP(calculateMapScale); PREP(canUseMapGPS); PREP(canUseMapTools); +PREP(drawLinesOnRoamer); PREP(handleMouseButton); PREP(handleMouseMove); PREP(isInsideMapTool); diff --git a/addons/maptools/XEH_postInitClient.sqf b/addons/maptools/XEH_postInitClient.sqf index 8569f0eb9f..ddde7063cc 100644 --- a/addons/maptools/XEH_postInitClient.sqf +++ b/addons/maptools/XEH_postInitClient.sqf @@ -30,5 +30,13 @@ GVAR(mapTool_isRotating) = false; } else { // Hide GPS [false] call FUNC(openMapGps); + + // Handle closing map in middle of line drawing (it's never created) + GVAR(freedrawing) = false; }; }] call CBA_fnc_addPlayerEventHandler; + + +GVAR(freeDrawingData) = []; +GVAR(freedrawing) = false; + diff --git a/addons/maptools/XEH_preInit.sqf b/addons/maptools/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/maptools/XEH_preInit.sqf +++ b/addons/maptools/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/maptools/functions/fnc_calculateMapScale.sqf b/addons/maptools/functions/fnc_calculateMapScale.sqf index 926ed558fe..035946aea5 100644 --- a/addons/maptools/functions/fnc_calculateMapScale.sqf +++ b/addons/maptools/functions/fnc_calculateMapScale.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Returns the equivalent of 100m in screen coordinates @@ -6,11 +7,13 @@ * None * * Return Value: - * No + * None + * + * Example: + * call ACE_maptools_fnc_calculateMapScale * * Public: No */ -#include "script_component.hpp" private _pos = ((findDisplay 12) displayCtrl 51) ctrlMapScreenToWorld [0.5, 0.5]; private _screenOffset = ((findDisplay 12) displayCtrl 51) posWorldToScreen [(_pos select 0) + 100, (_pos select 1)]; diff --git a/addons/maptools/functions/fnc_canUseMapGPS.sqf b/addons/maptools/functions/fnc_canUseMapGPS.sqf index a327c2bc8d..80f2541cab 100644 --- a/addons/maptools/functions/fnc_canUseMapGPS.sqf +++ b/addons/maptools/functions/fnc_canUseMapGPS.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * canUseMapGPS @@ -6,11 +7,13 @@ * None * * Return Value: - * + * Boolean + * + * Example: + * call ACE_map_fnc_canUseMapGPS * * Public: No */ -#include "script_component.hpp" visibleMap && {alive ACE_player} && diff --git a/addons/maptools/functions/fnc_canUseMapTools.sqf b/addons/maptools/functions/fnc_canUseMapTools.sqf index 8c16425082..e09a450031 100644 --- a/addons/maptools/functions/fnc_canUseMapTools.sqf +++ b/addons/maptools/functions/fnc_canUseMapTools.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * canUseMapTools @@ -6,11 +7,13 @@ * None * * Return Value: - * + * Boolean + * + * Example: + * call ACE_maptools_fnc_canUseMapTools * * Public: No */ -#include "script_component.hpp" visibleMap && {alive ACE_player} && @@ -21,6 +24,6 @@ visibleMap && } forEach (assignedItems ACE_player); false } && -{"ACE_MapTools" in (items ACE_player)} && +{"ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems))} && {!GVAR(mapTool_isDragging)} && {!GVAR(mapTool_isRotating)} diff --git a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf new file mode 100644 index 0000000000..a2ec5bfe78 --- /dev/null +++ b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf @@ -0,0 +1,144 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Prevents the cursor from entering the roamer when drawing lines and records the positions + * + * Arguments: + * 0: The Map + * 1: Roamer Width + * + * Return Value: + * None + * + * Example: + * [map, 300] call ace_maptools_fnc_drawLinesOnRoamer + * + * Public: No + */ + +if (!GVAR(drawStraightLines)) exitWith {}; + +params ["_theMap", "_roamerWidth"]; +GVAR(mapTool_pos) params ["_roamerPosX", "_roamerPosY"]; + +private _posCenter = [_roamerPosX, _roamerPosY, 0]; + +private _posTopRight = [ +_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, +_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, +0]; + +private _posTopLeft = [ +_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, +_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, +0]; + +private _posBottomLeft = [ +_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, +_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, +0]; + +private _posBottomRight = [ +_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, +_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, +0]; + +private _fnc_Distance = { // Get distance point _p is from a line made from _a to _b (uses 3d array commands, but z should be 0) + // Ref: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation + params ["_a", "_b", "_p"]; + private _n = _b vectorDiff _a; + private _pa = _a vectorDiff _p; + private _c = _n vectorMultiply ((_pa vectorDotProduct _n) / (_n vectorDotProduct _n)); + private _d = _pa vectorDiff _c; + sqrt (_d vectorDotProduct _d); +}; + +private _currentMousePos = _theMap ctrlMapScreenToWorld getMousePosition; +_currentMousePos set [2, 0]; + +// Break the roamer rectangle into 4 triangle, one for each side +switch (true) do { + case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posBottomLeft]): { // Left + private _distanceToRoamerLine = ([_posTopLeft, _posBottomLeft, _currentMousePos] call _fnc_Distance); + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) - 90) ,0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line + GVAR(freeDrawingData) = ["left", _currentMousePos, _currentMousePos]; + } else { + if ((GVAR(freeDrawingData) select 0) == "left") then { // We are already drawing on this line, find best spot + if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { + GVAR(freeDrawingData) set [1, _currentMousePos]; + }; + if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomLeft)) then { + GVAR(freeDrawingData) set [2, _currentMousePos]; + }; + }; + }; + private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + setMousePosition _screenPosOfCorrectedPos; + }; + case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posTopRight]): { // Top + private _distanceToRoamerLine = ([_posTopLeft, _posTopRight, _currentMousePos] call _fnc_Distance); + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 0) ,0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line + GVAR(freeDrawingData) = ["top", _currentMousePos, _currentMousePos]; + } else { + if ((GVAR(freeDrawingData) select 0) == "top") then { // We are already drawing on this line, find best spot + if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { + GVAR(freeDrawingData) set [1, _currentMousePos]; + }; + if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 2) distance2d _posTopRight)) then { + GVAR(freeDrawingData) set [2, _currentMousePos]; + }; + }; + }; + private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + setMousePosition _screenPosOfCorrectedPos; + }; + case (_currentMousePos inPolygon [_posCenter, _posTopRight, _posBottomRight]): { // Right + private _distanceToRoamerLine = ([_posTopRight, _posBottomRight, _currentMousePos] call _fnc_Distance); + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 90) ,0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line + GVAR(freeDrawingData) = ["right", _currentMousePos, _currentMousePos]; + } else { + if ((GVAR(freeDrawingData) select 0) == "right") then { // We are already drawing on this line, find best spot + if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 1) distance2d _posTopRight)) then { + GVAR(freeDrawingData) set [1, _currentMousePos]; + }; + if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then { + GVAR(freeDrawingData) set [2, _currentMousePos]; + }; + }; + }; + private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + setMousePosition _screenPosOfCorrectedPos; + }; + case (_currentMousePos inPolygon [_posCenter, _posBottomLeft, _posBottomRight]): { // Bottom + private _distanceToRoamerLine = ([_posBottomLeft, _posBottomRight, _currentMousePos] call _fnc_Distance); + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 180) ,0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line + GVAR(freeDrawingData) = ["bottom", _currentMousePos, _currentMousePos]; + } else { + if ((GVAR(freeDrawingData) select 0) == "bottom") then { // We are already drawing on this line, find best spot + if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posBottomLeft)) then { + GVAR(freeDrawingData) set [1, _currentMousePos]; + }; + if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then { + GVAR(freeDrawingData) set [2, _currentMousePos]; + }; + }; + }; + private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + setMousePosition _screenPosOfCorrectedPos; + }; +}; + +#ifdef DEBUG_MODE_FULL +_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopRight,24,24,getDir player,'1,1',1,0.03,'TahomaB','right']; +_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopLeft,24,24,getDir player,'-1,1',1,0.03,'TahomaB','right']; +_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomLeft,24,24,getDir player,'-1,-1',1,0.03,'TahomaB','right']; +_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomRight,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; +if !(GVAR(freeDrawingData) isEqualTo []) then { + _theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 1,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; + _theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 2,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; +}; +#endif diff --git a/addons/maptools/functions/fnc_handleMouseButton.sqf b/addons/maptools/functions/fnc_handleMouseButton.sqf index bf30a32ce1..36639a02d7 100644 --- a/addons/maptools/functions/fnc_handleMouseButton.sqf +++ b/addons/maptools/functions/fnc_handleMouseButton.sqf @@ -1,20 +1,70 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Handle mouse buttons. * * Arguments: - * 0: 1 if mouse down down, 0 if mouse button up (Number) - * 1: Parameters of the mouse button event + * 0: 1 if mouse down down, 0 if mouse button up + * 1: Parameters of the mouse button event * * Return Value: - * Boolean, true if event was handled + * true if event was handled + * + * Example: + * [0, [array]] call ACE_maptools_fnc_handleMouseButton + * + * Public: No */ -#include "script_component.hpp" params ["_dir", "_params"]; _params params ["_control", "_button", "_screenPosX", "_screenPosY", "_shiftKey", "_ctrlKey", "_altKey"]; TRACE_2("params",_dir,_params); +// Using line drawing +if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith { + if (GVAR(freedrawing) && {_dir == 0}) then { + GVAR(freedrawing) = false; + GVAR(drawPosEnd) = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; + TRACE_1("Ending Line",GVAR(freedrawing),GVAR(drawPosEnd)); + [{ + if (allMapMarkers isEqualTo []) exitWith {}; + private _markerName = allMapMarkers select (count allMapMarkers - 1); + private _markerPos = getMarkerPos _markerName; + private _distanceCheck = _markerPos distance2d GVAR(drawPosStart); + + TRACE_3("Line Drawn",_markerName,_markerPos,_distanceCheck); + + if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!");}; + if ((count GVAR(freeDrawingData)) != 3) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData));}; + + GVAR(freeDrawingData) params ["", "_startStraightPos", "_endStraightPos"]; + _startStraightPos set [2, 0]; + _endStraightPos set [2, 0]; + + // Convert marker to rectangle and change it's pos/size/dir + _markerName setMarkerShape "RECTANGLE"; + + private _difPos = _endStraightPos vectorDiff _startStraightPos; + private _mag = vectorMagnitude _difPos; + _markerName setMarkerPos (_startStraightPos vectorAdd (_difPos vectorMultiply 0.5)); + _markerName setMarkerSize [10, _mag / 2]; + _markerName setMarkerDir (_difPos call CBA_fnc_vectDir); + + }, []] call CBA_fnc_execNextFrame; + } else { + if (_ctrlKey && {_dir == 1}) then { + GVAR(freeDrawingData) = []; + GVAR(freedrawing) = true; + GVAR(drawPosStart) = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; + TRACE_2("Starting Line",GVAR(freedrawing),GVAR(drawPosStart)); + } else { + GVAR(freedrawing) = false; + TRACE_1("weird - reseting",GVAR(freedrawing)); + }; + }; + false +}; + private _handled = false; // If it's not a left button event, exit diff --git a/addons/maptools/functions/fnc_handleMouseMove.sqf b/addons/maptools/functions/fnc_handleMouseMove.sqf index a52163ba32..6ba8e1938c 100644 --- a/addons/maptools/functions/fnc_handleMouseMove.sqf +++ b/addons/maptools/functions/fnc_handleMouseMove.sqf @@ -1,22 +1,26 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Handle mouse movement over the map tool. * * Arguments: - * 0: Map Control - * 1: Mouse position on screen coordinates + * 0: Map Control + * 1: Mouse position on screen coordinates * * Return Value: - * Boolean, true if event was handled + * true if event was handled + * + * Example: + * [CONTROL, [0, 5, 1]] call ACE_maptools_fnc_handleMouseMove + * + * Public: No */ -#include "script_component.hpp" - params ["_control", "_mousePosX", "_mousePosY"]; TRACE_3("params",_control,_mousePosX,_mousePosY); // If have no map tools, then exit -if (((isNull ACE_player) || {!("ACE_MapTools" in items ACE_player)})) exitWith { +if (((isNull ACE_player) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))})) exitWith { false }; diff --git a/addons/maptools/functions/fnc_isInsideMapTool.sqf b/addons/maptools/functions/fnc_isInsideMapTool.sqf index 1bcb35f86a..97eedf85f3 100644 --- a/addons/maptools/functions/fnc_isInsideMapTool.sqf +++ b/addons/maptools/functions/fnc_isInsideMapTool.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Return true if the position is inside the map marker (to allow dragging). @@ -7,14 +8,13 @@ * 1: y Position (in meters) * * Return Value: - * Boolean + * Boolean + * + * Example: + * [0, 5] call ACE_maptools_fnc_isInsideMapTool + * + * Public: No */ -#include "script_component.hpp" - -#define TEXTURE_WIDTH_IN_M 6205 -#define DIST_BOTTOM_TO_CENTER_PERC -0.33 -#define DIST_TOP_TO_CENTER_PERC 0.65 -#define DIST_LEFT_TO_CENTER_PERC 0.30 if (GVAR(mapTool_Shown) == 0) exitWith {false}; private _textureWidth = [TEXTURE_WIDTH_IN_M, TEXTURE_WIDTH_IN_M / 2] select (GVAR(mapTool_Shown) - 1); diff --git a/addons/maptools/functions/fnc_openMapGps.sqf b/addons/maptools/functions/fnc_openMapGps.sqf index c3e2a8bfee..96be3f6bd2 100644 --- a/addons/maptools/functions/fnc_openMapGps.sqf +++ b/addons/maptools/functions/fnc_openMapGps.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Opens or closes the gps on the map screen, showing coordinates @@ -6,11 +7,13 @@ * 0: Open GPS? * * Return Value: - * Nothing + * None + * + * Example: + * [true] call ACE_maptools_fnc_openMapGps * * Public: No */ -#include "script_component.hpp" params ["_shouldOpenGps"]; diff --git a/addons/maptools/functions/fnc_openMapGpsUpdate.sqf b/addons/maptools/functions/fnc_openMapGpsUpdate.sqf index 719bf37763..84cb3f17a4 100644 --- a/addons/maptools/functions/fnc_openMapGpsUpdate.sqf +++ b/addons/maptools/functions/fnc_openMapGpsUpdate.sqf @@ -1,7 +1,19 @@ -//esteldunedain -//update gps display - #include "script_component.hpp" +/* + * Author: esteldunedain + * update gps display + * + * Arguments: + * Something + * + * Return Value: + * None + * + * Example: + * call ACE_maptools_fnc_openMapGpsUpdate + * + * Public: No + */ if ((!("ItemGPS" in assigneditems ACE_player)) || {isNull (uiNamespace getVariable [QGVAR(ui_mapGpsDisplay), displayNull])}) exitWith { ("RscACE_MapGps" call BIS_fnc_rscLayer) cutText ["","PLAIN"]; // Close GPS RSC diff --git a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf index 47688cdb91..e9cb14d7ed 100644 --- a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf +++ b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Update the map tool markers, position, size, rotation and visibility. @@ -6,19 +7,17 @@ * 0: The Map * * Return Value: - * Nothing + * None + * + * Example: + * [CONTROL] call ACE_maptools_fnc_updateMapToolMarkers * * Public: No */ -#include "script_component.hpp" - -#define TEXTURE_WIDTH_IN_M 6205 -#define CENTER_OFFSET_Y_PERC 0.1606 -#define CONSTANT_SCALE 0.2 params ["_theMap"]; -if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in items ACE_player)}) exitWith {}; +if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))}) exitWith {}; private _rotatingTexture = ""; private _textureWidth = 0; @@ -30,6 +29,8 @@ if (GVAR(mapTool_Shown) == 1) then { _textureWidth = TEXTURE_WIDTH_IN_M / 2; }; +if (GVAR(freedrawing)) then {[_theMap, _textureWidth] call FUNC(drawLinesOnRoamer);}; + // Update scale of both parts getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"]; private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale)); diff --git a/addons/maptools/script_component.hpp b/addons/maptools/script_component.hpp index d5f5b0f2d7..4710caa7a3 100644 --- a/addons/maptools/script_component.hpp +++ b/addons/maptools/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MAPTOOLS @@ -16,3 +15,10 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define TEXTURE_WIDTH_IN_M 6205 +#define CENTER_OFFSET_Y_PERC 0.1606 +#define CONSTANT_SCALE 0.2 +#define DIST_BOTTOM_TO_CENTER_PERC -0.33 +#define DIST_TOP_TO_CENTER_PERC 0.65 +#define DIST_LEFT_TO_CENTER_PERC 0.30 diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index e15135dcfd..f0fdd8f186 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Ferramentas de Mapa Térképészeti eszközök Инструменты карты + マップ ツール + 독도용 도구 + 地图工具 + 地圖工具 The Map Tools allow you to measure distances and angles on the map. @@ -24,6 +28,10 @@ As Ferramentas de Mapa permitem que você meça distâncias e ângulos no mapa. A térképészeti eszközökkel távolságokat és szögeket tudsz mérni a térképen. Картографические инструменты позволяют измерять расстояния и углы на карте. + マップ ツールは地図上で距離や角度を測れます。 + 독도용 도구는 지도상에서 거리나 각도를 잴 수 있게 해줍니다. + 地图工具能够让你在地图上测量距离与角度 + 地圖工具能夠讓你在地圖上測量距離與角度 Map Tools @@ -36,6 +44,10 @@ Ferramentas de Mapa Térképészeti eszközök Инструменты карты + マップ ツール + 독도용 도구 + 地图工具 + 地圖工具 Hide Map Tool @@ -48,6 +60,10 @@ Ukryj narzędzia nawigacyjne Schovat pomůcky k mapě Скрыть инструменты + マップ ツールを隠す + 독도용 도구 숨기기 + 隐藏地图工具 + 隱藏地圖工具 Show Normal Map Tool @@ -60,6 +76,10 @@ Pokaż normalne narzędzia nawigacyjne Zobrazit pomůcku k mapě (Velkou) Показать инструменты (средн. размер) + マップ ツールを表示する + 보통 독도용 도구로 보기 + 显示地图工具 + 顯示地圖工具 Show Small Map Tool @@ -72,6 +92,10 @@ Pokaż pomniejszone narzędzia nawigacyjne Zobrazit pomůcku k mapě (Malou) Показать инструменты (малый размер) + 小さいマップ ツールを表示する + 작은 독도용 도구로 보기 + 显示小的地图工具 + 顯示小的地圖工具 Align Map Tool to North @@ -84,6 +108,10 @@ Wyrównaj linijkę do północy Srovnat pomůcku k mapě na sever Выровнять инструменты на север + マップ ツールを北に合わせる + 독도용 도구를 북쪽으로 정렬 + 地图工具对准北方 + 地圖工具對準北方 Align Map Tool to Compass @@ -96,6 +124,10 @@ Wyrównaj linijkę do kompasu Srovnat pomůcku k mapě ke kompasu Выровнять инструменты по компасу + マップ ツールを方位磁石に合わせる + 독도용 도구를 나침반에 정렬 + 地图工具对准指北针 + 地圖工具對準指北針 Show GPS on Map @@ -108,6 +140,10 @@ Pokaż GPS na mapie Zobrazit GPS na mapě Показать GPS на карте + 地図上に GPS を表示する + GPS를 지도상에 꺼내기 + 在地图上显示GPS + 在地圖上顯示GPS Hide GPS on Map @@ -120,6 +156,10 @@ Ukryj GPS na mapie Schovat GPS na mapě Скрыть GPS на карте + 地図上から GPS を隠す + GPS를 지도상에서 숨기기 + 在地图上隐藏GPS + 在地圖上隱藏GPS Direction: %1° @@ -132,16 +172,56 @@ Направление: %1° Direzione: %1° Direção: %1 + 方位:%1° + 방위: %1° + 方位: %1° + 方位: %1° Rotate Map Tools Key Touche de rotation des outils de naviguation Клавиша поворота инструментов карты + マップ ツールの回転キー + Klawisz obrotu narzędzi nawigacyjnych + Taste zum Drehen des Kartenwerkzeugs + 독도용 도구 돌리기 키 + Ruota Strumenti di Mappatura + 选转地图工具的按键 + 選轉地圖工具的按鍵 Modifier key to allow rotating map tools Touche modificatrice permettant la rotation des outils de naviguation Клавиша-модификатор, позволяющая поворачивать инструменты карты + マップ ツールを回転させるキーを編集できます。 + Modyfikator pozwalający na obracanie narzędzi nawigacyjnych + Steuerungstaste, um Drehung des Kartenwerkzeugs zu ermöglichen. + 독도용 도구를 돌리기 위한 키를 변경할 수 있습니다. + Tasto modifica per consentire strumenti di mappatura rotanti + 修改旋转地图工具的按键 + 修改旋轉地圖工具的按鍵 + + + Draw straight lines with maptools + マップ ツールを使って直線を書く + Zeichne gerade Linien mit dem Kartenwerkzeug + 독도용 도구로 직선 그리기 + Rysuj proste linie przy użyciu narzędzi nawigacyjnych + Tracer des lignes droites + Disegna linee dritte con gli strumenti di mappatura + 使用地图工具来绘制直线 + 使用地圖工具來繪製直線 + + + 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 + 독도용 도구 가장자리에 직선을 그립니다. 주의: 삭제하기 위해선 선의 중앙에 가져다 대십시요 + 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. + 使用地图工具的边缘来绘制直线。备注: 要删除直线时,请把滑鼠移动到该线条的中央即可删除该线。 + 使用地圖工具的邊緣來繪製直線。備註: 要刪除直線時,請把滑鼠移動到該線條的中央即可刪除該線 - \ No newline at end of file + 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 da62205b51..885a0a3068 100644 --- a/addons/markers/XEH_preInit.sqf +++ b/addons/markers/XEH_preInit.sqf @@ -2,7 +2,11 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" // init marker types if (isNil QGVAR(MarkersCache)) then { @@ -13,11 +17,12 @@ if (isNil QGVAR(MarkersCache)) then { for "_a" from 0 to (count _config - 1) do { private _marker = _config select _a; - if (getNumber (_marker >> "scope") == 2) then { + if (getNumber (_marker >> "scope") isEqualTo 2) then { + private _class = configName _marker; private _name = getText (_marker >> "name"); private _icon = getText (_marker >> "icon"); - GVAR(MarkersCache) pushBack [_name, _a, _icon]; + GVAR(MarkersCache) pushBack [_name, _a, _icon, _class]; }; }; }; @@ -31,7 +36,8 @@ if (isNil QGVAR(MarkerColorsCache)) then { for "_a" from 0 to (count _config - 1) do { private _marker = _config select _a; - if (getNumber (_marker >> "scope") == 2) then { + if (getNumber (_marker >> "scope") isEqualTo 2) then { + private _class = configName _marker; private _name = getText (_marker >> "name"); private _rgba = getArray (_marker >> "color"); @@ -44,7 +50,7 @@ if (isNil QGVAR(MarkerColorsCache)) then { _rgba params ["_red", "_green", "_blue", "_alpha"]; private _icon = format ["#(argb,8,8,3)color(%1,%2,%3,%4)", _red, _green, _blue, _alpha]; - GVAR(MarkerColorsCache) pushBack [_name, _a, _icon]; + GVAR(MarkerColorsCache) pushBack [_name, _a, _icon, _class]; }; }; }; 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..7b19385d26 --- /dev/null +++ b/addons/markers/functions/fnc_canMove.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_getEnabledChannels.sqf b/addons/markers/functions/fnc_getEnabledChannels.sqf index 9a64ff06d4..bc665cf69c 100644 --- a/addons/markers/functions/fnc_getEnabledChannels.sqf +++ b/addons/markers/functions/fnc_getEnabledChannels.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: commy2 + * Author: commy2, Timi007 * Return enabled channels. * * Arguments: @@ -8,9 +9,11 @@ * Return Value: * Enabled Channels * + * Example: + * [false] call ACE_markers_fnc_getEnabledChannels + * * Public: No */ -#include "script_component.hpp" params [["_localize", false, [false]]]; @@ -37,12 +40,8 @@ if (_localize) then { if (setCurrentChannel 4) then { _enabledChannels pushBack localize "str_channel_vehicle"; }; - - if (setCurrentChannel 5) then { - _enabledChannels pushBack localize "str_channel_direct"; - }; } else { - for "_i" from 0 to 5 do { + for "_i" from 0 to 4 do { if (setCurrentChannel _i) then { _enabledChannels pushBack _i; }; diff --git a/addons/markers/functions/fnc_initInsertMarker.sqf b/addons/markers/functions/fnc_initInsertMarker.sqf index 549a89730d..fa7cec19ee 100644 --- a/addons/markers/functions/fnc_initInsertMarker.sqf +++ b/addons/markers/functions/fnc_initInsertMarker.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: BIS, commy2 + * Author: BIS, commy2, Timi007 * Sets up the marker placement * Run instead of \a3\ui_f\scripts\GUI\RscDisplayInsertMarker.sqf * @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" #define BORDER 0.005 @@ -46,32 +46,39 @@ private _aceAngleSlider = _display displayctrl 1220; private _aceAngleSliderText = _display displayctrl 1221; - //////////////////// - // Install MapDrawEH on current map - private _mapIDD = -1; + private _mapDisplay = displayParent _display; + if (isNull _mapDisplay) exitWith {ERROR("No Map");}; + private _mapCtrl = _mapDisplay displayCtrl 51; - { - if (!isNull (findDisplay _x)) exitWith { - _mapIDD = _x; + GVAR(editingMarker) = ""; + (ctrlMapMouseOver _mapCtrl) params ["_mouseOverType", "_marker"]; + + //check if entity under mouse is a user marker + if (_mouseOverType isEqualTo "marker") then { + if !((_marker find "_USER_DEFINED") isEqualTo -1) then { + GVAR(editingMarker) = _marker; + //hide marker which is being edited because if the user cancels editing, it will still exist unchanged + GVAR(editingMarker) setMarkerAlphaLocal 0; }; - false - } count [12, 37, 52, 53, 160]; - - if (_mapIDD == -1) exitWith { - ERROR("No Map?"); }; - if !(_mapIDD in GVAR(mapDisplaysWithDrawEHs)) then { - GVAR(mapDisplaysWithDrawEHs) pushBack _mapIDD; - ((finddisplay _mapIDD) displayctrl 51) ctrlAddEventHandler ["Draw", {_this call FUNC(mapDrawEH)}]; // @todo check if persistent + //////////////////// + // Install MapDrawEH on current map + if !((ctrlIDD _mapDisplay) in GVAR(mapDisplaysWithDrawEHs)) then { + GVAR(mapDisplaysWithDrawEHs) pushBack (ctrlIDD _mapDisplay); + _mapCtrl ctrlAddEventHandler ["Draw", {_this call FUNC(mapDrawEH)}]; // @todo check if persistent }; //////////////////// // Calculate center position of the marker placement ctrl - private _pos = ctrlPosition _picture; - _pos = [(_pos select 0) + (_pos select 2) / 2, (_pos select 1) + (_pos select 3) / 2]; - - GVAR(currentMarkerPosition) = ((findDisplay _mapIDD) displayCtrl 51) ctrlMapScreenToWorld _pos; + if !(GVAR(editingMarker) isEqualTo "") then { + //prevent changing the original marker position + GVAR(currentMarkerPosition) = markerPos GVAR(editingMarker); + } else { + private _pos = ctrlPosition _picture; + _pos = [(_pos select 0) + (_pos select 2) / 2, (_pos select 1) + (_pos select 3) / 2]; + GVAR(currentMarkerPosition) = _mapCtrl ctrlMapScreenToWorld _pos; + }; //Hide the bis picture: _picture ctrlShow false; @@ -79,12 +86,16 @@ // prevent vanilla key input _display displayAddEventHandler ["KeyDown", {(_this select 1) in [200, 208]}]; + if !((markerText GVAR(editingMarker)) isEqualTo "") then { + //fill text input with text from marker which is being edited + _text ctrlSetText (markerText GVAR(editingMarker)); + }; //Focus on the text input ctrlSetFocus _text; //--- Background - _pos = ctrlposition _text; + private _pos = ctrlposition _text; _pos params ["_posX", "_posY", "_posW", "_posH"]; _posX = _posX + 0.01; _posY = _posY min ((safeZoneH + safeZoneY) - (8 * _posH + 8 * BORDER)); //prevent buttons being placed below bottom edge of screen @@ -161,12 +172,20 @@ }; }; - private _currentChannelName = CHANNEL_NAMES param [currentChannel, localize "str_channel_group"]; + private _selectChannel = if !(GVAR(editingMarker) isEqualTo "") then { + //get the channel where the marker was placed in + parseNumber ((GVAR(editingMarker) splitString "/") param [2, "3"]) + } else { + currentChannel + }; + + private _currentChannelName = CHANNEL_NAMES param [_selectChannel, localize "str_channel_group"]; // select current channel in list box, must be done after lbDelete for "_j" from 0 to (lbSize _channel - 1) do { if (_channel lbText _j == _currentChannelName) then { _channel lbSetCurSel _j; + setCurrentChannel (CHANNEL_NAMES find _currentChannelName); }; }; @@ -198,10 +217,15 @@ // init marker shape lb lbClear _aceShapeLB; { - _x params ["_add", "_set", "_pic"]; + _x params ["_add", "_set", "_pic", "_classname"]; _aceShapeLB lbAdd _add; _aceShapeLB lbSetValue [_forEachIndex, _set]; _aceShapeLB lbSetPicture [_forEachIndex, _pic]; + + if ((markerType GVAR(editingMarker)) isEqualTo _classname) then { + //if the marker is being edited then get the original shape + GVAR(curSelMarkerShape) = _forEachIndex; + }; } forEach GVAR(MarkersCache); private _curSelShape = GETGVAR(curSelMarkerShape,0); @@ -215,10 +239,15 @@ // init marker color lb lbClear _aceColorLB; { - _x params ["_add", "_set", "_pic"]; + _x params ["_add", "_set", "_pic", "_classname"]; _aceColorLB lbAdd _add; _aceColorLB lbSetValue [_forEachIndex, _set]; _aceColorLB lbSetPicture [_forEachIndex, _pic]; + + if ((markerColor GVAR(editingMarker)) isEqualTo _classname) then { + //if the marker is being edited then get the original color + GVAR(curSelMarkerColor) = _forEachIndex; + }; } forEach GVAR(MarkerColorsCache); private _curSelColor = GETGVAR(curSelMarkerColor,0); @@ -232,6 +261,11 @@ // init marker angle slider _aceAngleSlider sliderSetRange [-180, 180]; + if !(GVAR(editingMarker) isEqualTo "") then { + //get the original direction + GVAR(currentMarkerAngle) = markerDir GVAR(editingMarker); + }; + private _curSelAngle = GETGVAR(currentMarkerAngle,0); _aceAngleSlider sliderSetPosition _curSelAngle; diff --git a/addons/markers/functions/fnc_mapDisplayInitEH.sqf b/addons/markers/functions/fnc_mapDisplayInitEH.sqf index 662f6f80c0..3ab874c445 100644 --- a/addons/markers/functions/fnc_mapDisplayInitEH.sqf +++ b/addons/markers/functions/fnc_mapDisplayInitEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles XEH DisplayLoad for the various map displays (RscDiary) @@ -13,9 +14,6 @@ * * Public: No */ -#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_mapDrawEH.sqf b/addons/markers/functions/fnc_mapDrawEH.sqf index 7197c90cc7..5f3c6aed15 100644 --- a/addons/markers/functions/fnc_mapDrawEH.sqf +++ b/addons/markers/functions/fnc_mapDrawEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Draws the current temp marker. Allows rotation. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_theMap"]; // TRACE_1("params",_theMap); diff --git a/addons/markers/functions/fnc_movePFH.sqf b/addons/markers/functions/fnc_movePFH.sqf new file mode 100644 index 0000000000..144fce6ff0 --- /dev/null +++ b/addons/markers/functions/fnc_movePFH.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" +/* + * 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 + */ + +(_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_onLBSelChangedChannel.sqf b/addons/markers/functions/fnc_onLBSelChangedChannel.sqf index f63c4e5cf4..954e90470c 100644 --- a/addons/markers/functions/fnc_onLBSelChangedChannel.sqf +++ b/addons/markers/functions/fnc_onLBSelChangedChannel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * When the channel list box is changed. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [CONTROL, 5] call ACE_markers_fnc_onLBSelChangedChannel + * * Public: No */ -#include "script_component.hpp" params ["_ctrl", "_index"]; TRACE_2("params",_ctrl,_index); diff --git a/addons/markers/functions/fnc_onLBSelChangedColor.sqf b/addons/markers/functions/fnc_onLBSelChangedColor.sqf index dc186a6c61..a141f7e72d 100644 --- a/addons/markers/functions/fnc_onLBSelChangedColor.sqf +++ b/addons/markers/functions/fnc_onLBSelChangedColor.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * When the color list box is changed. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_ctrl", "_index"]; TRACE_2("params",_ctrl,_index); diff --git a/addons/markers/functions/fnc_onLBSelChangedShape.sqf b/addons/markers/functions/fnc_onLBSelChangedShape.sqf index 6fd9aabd89..52a85e5c8d 100644 --- a/addons/markers/functions/fnc_onLBSelChangedShape.sqf +++ b/addons/markers/functions/fnc_onLBSelChangedShape.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * When the shape list box is changed. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_ctrl", "_index"]; TRACE_2("params",_ctrl,_index); diff --git a/addons/markers/functions/fnc_onMouseButtonDown.sqf b/addons/markers/functions/fnc_onMouseButtonDown.sqf new file mode 100644 index 0000000000..afdacfb521 --- /dev/null +++ b/addons/markers/functions/fnc_onMouseButtonDown.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..ffe0ed000f --- /dev/null +++ b/addons/markers/functions/fnc_onMouseButtonUp.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * 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 + */ + +params ["_ctrlMap", "_button", "_x", "_y", "_shift", "_ctrl", "_alt"]; + +GVAR(moving) = false; diff --git a/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf b/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf index 030e2314ab..c334d0a8f0 100644 --- a/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf +++ b/addons/markers/functions/fnc_onSliderPosChangedAngle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Angle Slider Pos changed @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_ctrl", "_data"]; TRACE_2("params",_ctrl,_data); diff --git a/addons/markers/functions/fnc_placeMarker.sqf b/addons/markers/functions/fnc_placeMarker.sqf index 281953e104..af905d71f1 100644 --- a/addons/markers/functions/fnc_placeMarker.sqf +++ b/addons/markers/functions/fnc_placeMarker.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: commy2 + * Author: commy2, Timi007 * MarkerPlacement closed * * Arguments: @@ -14,13 +15,16 @@ * * Public: No */ -#include "script_component.hpp" disableserialization; params ["_display", "_closeNum"]; TRACE_2("params",_display,_closeNum); -if (_closeNum == 1) then { +if (_closeNum isEqualTo 1) then { + if !(GVAR(editingMarker) isEqualTo "") then { + //delete "old" marker + deleteMarker GVAR(editingMarker); + }; // set and send marker data the next frame. the actual marker isn't created yet [{ [QGVAR(setMarkerNetwork), [ @@ -33,4 +37,11 @@ if (_closeNum == 1) then { ]] call CBA_fnc_globalEvent; }, []] call CBA_fnc_execNextFrame; +} else { + if !(GVAR(editingMarker) isEqualTo "") then { + //editing was canceled show the original marker again + GVAR(editingMarker) setMarkerAlphaLocal 1; + }; }; + +GVAR(editingMarker) = ""; diff --git a/addons/markers/functions/fnc_sendMarkersJIP.sqf b/addons/markers/functions/fnc_sendMarkersJIP.sqf index e63a32b843..08b36181b1 100644 --- a/addons/markers/functions/fnc_sendMarkersJIP.sqf +++ b/addons/markers/functions/fnc_sendMarkersJIP.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Server: Recives a dummy logic, sends marker data back to the owner. @@ -13,13 +14,12 @@ * * Public: No */ -#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..ba7dc68a5b 100644 --- a/addons/markers/functions/fnc_setMarkerJIP.sqf +++ b/addons/markers/functions/fnc_setMarkerJIP.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Client: Recives a marker data from server. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_allMapMarkers", "_allMapMarkersProperties"]; TRACE_3("params",_allMapMarkers,_allMapMarkersProperties); @@ -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/functions/fnc_setMarkerNetwork.sqf b/addons/markers/functions/fnc_setMarkerNetwork.sqf index 9d6d2d8ecf..b59338e7d2 100644 --- a/addons/markers/functions/fnc_setMarkerNetwork.sqf +++ b/addons/markers/functions/fnc_setMarkerNetwork.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Sets newly placed marker @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_marker", "_data"]; TRACE_2("params",_marker,_data); 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 458f5cfabf..fdb5f1614e 100644 --- a/addons/markers/script_component.hpp +++ b/addons/markers/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MARKERS @@ -22,6 +21,11 @@ localize "str_channel_side", \ localize "str_channel_command", \ localize "str_channel_group", \ - localize "str_channel_vehicle", \ - localize "str_channel_direct" \ + localize "str_channel_vehicle" \ ] + +#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 44d64eb1e0..9eb3925c73 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -1,10 +1,10 @@ - + Direction: %1° Drehung: %1° - Direction: %1° + Direction : %1° Směr: %1° Kierunek: %1° Dirección: %1° @@ -12,6 +12,82 @@ Irány: %1° Direzione: %1° Direção %1 + 方位: %1° + 방위: %1° + 方位: %1° + 方位: %1° + + + Markers + Markierungen + マーカー + Marcatori + 標誌 + 标志 + 맵마커 + + + Allow moving markers for + Erlaube Marker zu bewegen für + 次ユーザーにマーカー移動を許可 + 마커 이동 허가 + 誰可以移動標誌 + 谁可以移动标志 + Permetti di spostare i marcatori a: + + + 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 키를 누른 상태에서 마커를 움직일 수있는 플레이어를 제한합니다. + 設定誰可以透過按住Alt鍵來移動標誌 + 设定谁可以透过按住Alt键来移动标志。 + Limita quali giocatori possono spostare i marcatori mentre premono il tasto Alt. + + + Nobody + Niemand + 不許可 + 비활성 + 沒有人 + 没有人 + Nessuno + + + 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..2b48618e82 --- /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; + maxDeflection = 0.002; + incDeflection = 0.001; + + 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; + maxDeflection = 0.002; + incDeflection = 0.001; + + 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..57c7f85101 --- /dev/null +++ b/addons/maverick/stringtable.xml @@ -0,0 +1,92 @@ + + + + + + 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, 레이저 유도 대공 미사일 + Kh-25ML,雷射導引對地導彈 + Kh-25ML,镭射导引空地导弹 + Kh-25ML、レーザー誘導対地ミサイル + Kh-25ML, a Guida Laser Missile Aria-Terra + + + 1x Kh-25ML [ACE] + 1x Ch-25ML [ACE] + 1x Х-25МЛ [ACE] + 1x Kh-25ML [ACE] + 1x Kh-25ML [ACE] + 1x Kh-25ML镭射空地导弹 [ACE] + 1x Kh-25ML [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 + Kh-25ML + Kh-25ML镭射空地导弹 + Kh-25ML + Kh-25ML + + + + diff --git a/addons/medical/ACE_Medical_Actions.hpp b/addons/medical/ACE_Medical_Actions.hpp index 900e6cb26c..64fc82dbec 100644 --- a/addons/medical/ACE_Medical_Actions.hpp +++ b/addons/medical/ACE_Medical_Actions.hpp @@ -15,7 +15,6 @@ class ACE_Head { statement = QUOTE([ARR_4(_player, _target, 'head', 'Bandage')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 1; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; // Advanced medical @@ -26,7 +25,6 @@ class ACE_Head { statement = QUOTE([ARR_4(_player, _target, 'head', 'FieldDressing')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; class PackingBandage: fieldDressing { @@ -92,7 +90,6 @@ class ACE_Torso { statement = QUOTE([ARR_4(_player, _target, 'body', 'Bandage')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 1; - priority = 2; enableInside = 1; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -103,7 +100,6 @@ class ACE_Torso { statement = QUOTE([ARR_4(_player, _target, 'body', 'BodyBag')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 1; - priority = 2; enableInside = 1; }; class TriageCard { @@ -113,7 +109,6 @@ class ACE_Torso { statement = QUOTE([ARR_2(_target, true)] call DFUNC(displayTriageCard)); EXCEPTIONS showDisabled = 1; - priority = 2; enableInside = 1; icon = QPATHTOF(UI\icons\triageCard.paa); }; @@ -124,7 +119,6 @@ class ACE_Torso { statement = QUOTE([ARR_4(_player, _target, 'body', 'Diagnose')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 0; - priority = 2; icon = ""; }; @@ -136,7 +130,6 @@ class ACE_Torso { statement = QUOTE([ARR_4(_player, _target, 'body', 'FieldDressing')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 0; - priority = 2; enableInside = 1; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -200,7 +193,6 @@ class ACE_ArmLeft { statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'Bandage')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 1; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -212,7 +204,6 @@ class ACE_ArmLeft { statement = QUOTE([ARR_4(_player, _target, 'hand_l', 'FieldDressing')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; class PackingBandage: fieldDressing { @@ -363,7 +354,6 @@ class ACE_ArmRight { statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'Bandage')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 1; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -375,7 +365,6 @@ class ACE_ArmRight { statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'FieldDressing')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; class PackingBandage: fieldDressing { @@ -524,7 +513,6 @@ class ACE_LegLeft { statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Bandage')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 1; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -537,7 +525,6 @@ class ACE_LegLeft { statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'FieldDressing')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; class PackingBandage: fieldDressing { @@ -574,7 +561,7 @@ class ACE_LegLeft { icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Adenosine: Morphine { - displayName = CSTRING(Inject_Atropine); + displayName = CSTRING(Inject_Adenosine); condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'Adenosine')] call DFUNC(canTreatCached)); statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'Adenosine')] call DFUNC(treatment)); EXCEPTIONS @@ -672,7 +659,6 @@ class ACE_LegRight { statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Bandage')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 1; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -685,7 +671,6 @@ class ACE_LegRight { statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'FieldDressing')] call DFUNC(treatment)); EXCEPTIONS showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\icons\bandage.paa); }; class PackingBandage: fieldDressing { @@ -722,7 +707,7 @@ class ACE_LegRight { icon = QPATHTOF(UI\icons\autoInjector.paa); }; class Adenosine: Morphine { - displayName = CSTRING(Inject_Atropine); + displayName = CSTRING(Inject_Adenosine); condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'Adenosine')] call DFUNC(canTreatCached)); statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'Adenosine')] call DFUNC(treatment)); EXCEPTIONS diff --git a/addons/medical/ACE_Medical_SelfActions.hpp b/addons/medical/ACE_Medical_SelfActions.hpp index fca025adcb..9f01f08908 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,10 +19,9 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; // Advanced medical @@ -30,44 +29,43 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; 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,21 +74,19 @@ 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; - priority = 2; icon = QPATHTOF(UI\icons\medical_cross.paa); class Bandage { 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; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -98,10 +94,9 @@ 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; icon = QPATHTOF(UI\icons\triageCard.paa); }; @@ -110,30 +105,29 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; 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 +135,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,10 +145,9 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -163,92 +156,91 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; 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); + displayName = CSTRING(Inject_Adenosine); 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,10 +250,9 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -270,88 +261,87 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; 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,10 +351,9 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -374,76 +363,75 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; 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); + displayName = CSTRING(Inject_Adenosine); 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,10 +441,9 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; @@ -466,68 +453,67 @@ 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; icon = QPATHTOF(UI\icons\bandage.paa); }; 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); + displayName = CSTRING(Inject_Adenosine); 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..ee393c37e7 100644 --- a/addons/medical/ACE_Settings.hpp +++ b/addons/medical/ACE_Settings.hpp @@ -32,6 +32,8 @@ class ACE_Settings { }; class GVAR(enableOverdosing) { category = CSTRING(Category_Medical); + displayName = CSTRING(MedicalSettings_enableOverdosing_DisplayName); + description = CSTRING(MedicalSettings_enableOverdosing_Description); typeName = "BOOL"; value = 1; }; @@ -41,6 +43,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 +51,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 +80,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 +88,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 +126,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,12 +134,17 @@ class ACE_Settings { description = CSTRING(ReviveSettings_amountOfReviveLives_Description); typeName = "SCALAR"; value = -1; + sliderSettings[] = {-1, 25, -1, -1}; }; + + /* class GVAR(allowDeadBodyMovement) { category = CSTRING(Category_Medical); typeName = "BOOL"; value = 0; }; + */ + class GVAR(allowLitterCreation) { category = CSTRING(Category_Medical); displayName = CSTRING(MedicalSettings_allowLitterCreation_DisplayName); @@ -166,6 +168,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); @@ -278,11 +281,15 @@ class ACE_Settings { }; class GVAR(allowUnconsciousAnimationOnTreatment) { category = CSTRING(Category_Medical); + displayName = CSTRING(MedicalSettings_allowUnconsciousAnimationOnTreatment_DisplayName); + description = CSTRING(MedicalSettings_allowUnconsciousAnimationOnTreatment_Description); typeName = "BOOL"; value = 0; }; class GVAR(moveUnitsFromGroupOnUnconscious) { category = CSTRING(Category_Medical); + displayName = CSTRING(MedicalSettings_moveUnitsFromGroupOnUnconscious_DisplayName); + description = CSTRING(MedicalSettings_moveUnitsFromGroupOnUnconscious_Description); typeName = "BOOL"; value = 0; }; @@ -301,5 +308,6 @@ class ACE_Settings { description = CSTRING(MedicalSettings_delayUnconCaptive_Description); typeName = "SCALAR"; value = 3; + sliderSettings[] = {0, 30, 3, 0}; }; }; diff --git a/addons/medical/CfgEden.hpp b/addons/medical/CfgEden.hpp index e4d034a413..bebfdb9549 100644 --- a/addons/medical/CfgEden.hpp +++ b/addons/medical/CfgEden.hpp @@ -9,8 +9,8 @@ class Cfg3DEN { }; }; class GVAR(isMedicControl): Title { - attributeLoad = "(_this controlsGroupCtrl 100) lbsetcursel (((_value + 1) min 3) max 0);"; - attributeSave = "(missionnamespace getvariable ['ace_isMeidc_temp',0]) - 1;"; + attributeLoad = "(_this controlsGroupCtrl 100) lbSetCurSel (((_value + 1) min 3) max 0);"; + attributeSave = "(lbCurSel (_this controlsGroupCtrl 100)) - 1"; class Controls: Controls { class Title: Title{}; class Value: ctrlToolbox { @@ -22,7 +22,6 @@ class Cfg3DEN { rows = 1; columns = 4; strings[] = {"$STR_3DEN_Attributes_Lock_Default_text", CSTRING(AssignMedicRoles_role_none), CSTRING(AssignMedicRoles_role_medic), CSTRING(AssignMedicRoles_role_doctorShort)}; - onToolboxSelChanged = "missionnamespace setvariable ['ace_isMeidc_temp',_this select 1];"; }; }; }; @@ -36,7 +35,7 @@ class Cfg3DEN { control = QGVAR(isMedicControl); displayName = CSTRING(AssignMedicRoles_role_DisplayName); tooltip = CSTRING(Attributes_isMedic_Description); - expression = QUOTE(if (_value != -1) then {_this setVariable [ARR_3(QUOTE(QGVAR(medicClass)),_value, true)];};); + expression = QUOTE(if (_value > -1) then {_this setVariable [ARR_3(QUOTE(QGVAR(medicClass)),_value, true)];};); typeName = "NUMBER"; condition = "objectBrain"; defaultValue = "-1"; 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..5db82ce1e5 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,28 @@ 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 +875,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 +900,32 @@ 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; + }; + 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; + }; + }; + }; }; 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_init.sqf b/addons/medical/XEH_init.sqf deleted file mode 100644 index acdd50ce82..0000000000 --- a/addons/medical/XEH_init.sqf +++ /dev/null @@ -1,12 +0,0 @@ -#include "script_component.hpp" - -params ["_unit"]; - -_unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}]; - -if (local _unit) then { - if (!EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(init), [_unit]]; - }; - [_unit] call FUNC(init); -}; diff --git a/addons/medical/XEH_postInit.sqf b/addons/medical/XEH_postInit.sqf index bf2030e6e7..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 { @@ -289,7 +301,13 @@ GVAR(lastHeartBeatSound) = CBA_missionTime; if (hasInterface) then { ["ace_playerJIP", { - ACE_LOGINFO("JIP Medical init for player."); + INFO("JIP Medical init for player."); [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 17e570ae92..51c2c16688 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -2,16 +2,16 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(injuredUnitCollection) = []; private _versionEx = "ace_medical" callExtension "version"; DFUNC(handleDamage_assignWounds) = if (_versionEx == "") then { - ACE_LOGINFO_1("Extension %1.dll not installed.","ace_medical"); DFUNC(handleDamage_woundsOld) } else { - ACE_LOGINFO_2("Extension version: %1: %2","ace_medical",_versionEx); DFUNC(handleDamage_wounds) }; @@ -39,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); @@ -48,6 +53,9 @@ addMissionEventHandler ["Loaded",{ TRACE_1("preload done",_this); }, [_x]] call CBA_fnc_waitUntilAndExecute; } forEach GVAR(fixedStatics); + + // Reload configs into extension (handle full game restart) + call FUNC(parseConfigForInjuries); }]; diff --git a/addons/medical/XEH_respawn.sqf b/addons/medical/XEH_respawn.sqf deleted file mode 100644 index 1d1c34d6c7..0000000000 --- a/addons/medical/XEH_respawn.sqf +++ /dev/null @@ -1,17 +0,0 @@ -#include "script_component.hpp" - -params ["_unit"]; - -// reset all variables. @todo GROUP respawn? -[_unit] call FUNC(init); - -// Reset captive status for respawning unit -if (!(_unit getVariable ["ACE_isUnconscious", false])) then { - [_unit, "setCaptive", "ace_unconscious", false] call EFUNC(common,statusEffect_set); -}; - -// Remove maximum unconsciousness time handler -_maxUnconHandle = _unit getVariable [QGVAR(maxUnconTimeHandle), -1]; -if (_maxUnconHandle > 0) then { - [_maxUnconHandle] call CBA_fnc_removePerFrameHandler; -}; diff --git a/addons/medical/config.cpp b/addons/medical/config.cpp index ed490b6e20..c2010177de 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_actionCheckBloodPressure.sqf b/addons/medical/functions/fnc_actionCheckBloodPressure.sqf index 9e66eda263..dfd930451f 100644 --- a/addons/medical/functions/fnc_actionCheckBloodPressure.sqf +++ b/addons/medical/functions/fnc_actionCheckBloodPressure.sqf @@ -1,18 +1,20 @@ -/* -* Author: Glowbal -* Action for checking the blood pressure of the patient -* -* Arguments: -* 0: The medic -* 1: The patient -* -* Return Value: -* None -* -* Public: No -*/ - #include "script_component.hpp" +/* + * Author: Glowbal + * Action for checking the blood pressure of the patient + * + * Arguments: + * 0: The medic + * 1: The patient + * + * Return Value: + * None + * + * Example: + * [bob, kevin] call ACE_medical_fnc_actionCheckBloodPressure + * + * Public: No + */ params ["_caller", "_target", "_selectionName"]; if (local _target) then { diff --git a/addons/medical/functions/fnc_actionCheckBloodPressureLocal.sqf b/addons/medical/functions/fnc_actionCheckBloodPressureLocal.sqf index 184110265a..aa87f4889d 100644 --- a/addons/medical/functions/fnc_actionCheckBloodPressureLocal.sqf +++ b/addons/medical/functions/fnc_actionCheckBloodPressureLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Local callback for checking the blood pressure of a patient @@ -9,11 +10,12 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ACE_medical_fnc_actionCheckBloodPressureLocal + * * Public: No */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName"]; private _bloodPressure = if (!alive _target) then { diff --git a/addons/medical/functions/fnc_actionCheckPulse.sqf b/addons/medical/functions/fnc_actionCheckPulse.sqf index 39f196a0a5..da0711d280 100644 --- a/addons/medical/functions/fnc_actionCheckPulse.sqf +++ b/addons/medical/functions/fnc_actionCheckPulse.sqf @@ -1,18 +1,20 @@ -/* -* Author: Glowbal -* Action for checking the pulse or heart rate of the patient -* -* Arguments: -* 0: The medic -* 1: The patient -* -* Return Value: -* None -* -* Public: No -*/ - #include "script_component.hpp" +/* + * Author: Glowbal + * Action for checking the pulse or heart rate of the patient + * + * Arguments: + * 0: The medic + * 1: The patient + * + * Return Value: + * None + * + * Example: + * [bob, kevin] call ACE_medical_fnc_actionCheckPulse + * + * Public: No + */ params ["_caller","_target", "_selectionName"]; if (local _target) then { diff --git a/addons/medical/functions/fnc_actionCheckPulseLocal.sqf b/addons/medical/functions/fnc_actionCheckPulseLocal.sqf index cf84df075e..6e8989acc3 100644 --- a/addons/medical/functions/fnc_actionCheckPulseLocal.sqf +++ b/addons/medical/functions/fnc_actionCheckPulseLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Local callback for checking the pulse of a patient @@ -9,11 +10,12 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ACE_medical_fnc_actionCheckPulseLocal + * * Public: No */ -#include "script_component.hpp" - params ["_caller", "_unit", "_selectionName"]; private _heartRate = _unit getVariable [QGVAR(heartRate), 80]; diff --git a/addons/medical/functions/fnc_actionCheckResponse.sqf b/addons/medical/functions/fnc_actionCheckResponse.sqf index c47dc5dd64..58e8219be9 100644 --- a/addons/medical/functions/fnc_actionCheckResponse.sqf +++ b/addons/medical/functions/fnc_actionCheckResponse.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Action for checking the response status of the patient @@ -9,11 +10,12 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ACE_medical_fnc_actionCheckResponse + * * Public: No */ -#include "script_component.hpp" - params ["_caller", "_target"]; private _output = [LSTRING(Check_Response_Unresponsive), LSTRING(Check_Response_Responsive)] select ([_target] call EFUNC(common,isAwake)); diff --git a/addons/medical/functions/fnc_actionDiagnose.sqf b/addons/medical/functions/fnc_actionDiagnose.sqf index d86d90db7d..bd51233ddd 100644 --- a/addons/medical/functions/fnc_actionDiagnose.sqf +++ b/addons/medical/functions/fnc_actionDiagnose.sqf @@ -1,18 +1,20 @@ -/* -* Author: Glowbal -* Action for diagnosing in basic medical -* -* Arguments: -* 0: The medic -* 1: The patient -* -* Return Value: -* None -* -* Public: No -*/ - #include "script_component.hpp" +/* + * Author: Glowbal + * Action for diagnosing in basic medical + * + * Arguments: + * 0: The medic + * 1: The patient + * + * Return Value: + * None + * + * Example: + * [bob, kevin] call ACE_medical_fnc_actionDiagnose + * + * Public: No + */ params ["_caller", "_target"]; diff --git a/addons/medical/functions/fnc_actionLoadUnit.sqf b/addons/medical/functions/fnc_actionLoadUnit.sqf index 55a7a9ba51..95b7cbf8a3 100644 --- a/addons/medical/functions/fnc_actionLoadUnit.sqf +++ b/addons/medical/functions/fnc_actionLoadUnit.sqf @@ -1,20 +1,23 @@ +#include "script_component.hpp" /* * 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 * + * Example: + * [bob, kevin] call ACE_medical_fnc_actionLoadUnit + * * Public: No */ -#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; @@ -26,4 +29,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..b4f53370aa 100644 --- a/addons/medical/functions/fnc_actionPlaceInBodyBag.sqf +++ b/addons/medical/functions/fnc_actionPlaceInBodyBag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Replace a (dead) body by a body bag @@ -15,8 +16,6 @@ * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target"]; TRACE_2("params",_caller,_target); @@ -41,7 +40,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_actionRemoveTourniquet.sqf b/addons/medical/functions/fnc_actionRemoveTourniquet.sqf index bf0a3e5ae4..0e7d668b3a 100644 --- a/addons/medical/functions/fnc_actionRemoveTourniquet.sqf +++ b/addons/medical/functions/fnc_actionRemoveTourniquet.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Action for removing the tourniquet on specified selection @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [bob, kevin, "selection"] call ace_medical_fnc_actionRemoveTourniquet + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName"]; TRACE_3("params",_caller,_target,_selectionName); diff --git a/addons/medical/functions/fnc_actionUnloadUnit.sqf b/addons/medical/functions/fnc_actionUnloadUnit.sqf index 75fe76bce9..e98c01fd2b 100644 --- a/addons/medical/functions/fnc_actionUnloadUnit.sqf +++ b/addons/medical/functions/fnc_actionUnloadUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Action for unloading an unconscious or dead unit from a vechile @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [bob, kevin, false] call ACE_medical_fnc_actionUnloadUnit + * * Public: No */ -#include "script_component.hpp" - params ["_caller", "_target", ["_drag", false]]; // cannot unload a unit not in a vehicle. diff --git a/addons/medical/functions/fnc_addDamageToUnit.sqf b/addons/medical/functions/fnc_addDamageToUnit.sqf index 1969e3ff74..609c636bfa 100644 --- a/addons/medical/functions/fnc_addDamageToUnit.sqf +++ b/addons/medical/functions/fnc_addDamageToUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Manually Apply Damage to a unit (can cause lethal damage) @@ -18,17 +19,15 @@ * * Public: Yes */ -// #define DEBUG_MODE_FULL // #define DEBUG_TESTRESULTS -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_damageToAdd", -1, [0]], ["_selection", "", [""]], ["_typeOfDamage", "", [""]]]; TRACE_4("params",_unit,_damageToAdd,_selection,_typeOfDamage); _selection = toLower _selection; -if ((isNull _unit) || {!local _unit} || {!alive _unit}) exitWith {ACE_LOGERROR_1("addDamageToUnit - badUnit %1", _this); -1}; -if (_damageToAdd < 0) exitWith {ACE_LOGERROR_1("addDamageToUnit - bad damage %1", _this); -1}; -if (!(_selection in GVAR(SELECTIONS))) exitWith {ACE_LOGERROR_1("addDamageToUnit - bad selection %1", _this); -1}; +if ((isNull _unit) || {!local _unit} || {!alive _unit}) exitWith {ERROR_1("addDamageToUnit - badUnit %1", _this); -1}; +if (_damageToAdd < 0) exitWith {ERROR_1("addDamageToUnit - bad damage %1", _this); -1}; +if (!(_selection in GVAR(SELECTIONS))) exitWith {ERROR_1("addDamageToUnit - bad selection %1", _this); -1}; //Get the hitpoint and the index private _hitpoint = [_unit, _selection, true] call ace_medical_fnc_translateSelections; @@ -37,7 +36,7 @@ private _hitpointIndex = -1; { //case insensitive find if (_x == _hitpoint) exitWith {_hitpointIndex = _forEachIndex;}; } forEach _allHitPoints; -if (_hitpointIndex < 0) exitWith {ACE_LOGERROR_1("addDamageToUnit - bad hitpointIndex %1", _this); -1}; +if (_hitpointIndex < 0) exitWith {ERROR_1("addDamageToUnit - bad hitpointIndex %1", _this); -1}; private _currentDamage = _unit getHitIndex _hitpointIndex; @@ -49,15 +48,15 @@ private _debugCode = { params ["", "_unit", "_startDmg", "_damageToAdd", "_partNumber"]; private _endDmg = (_unit getVariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0]]) select _partNumber; if ((!alive _unit) || {_endDmg > _startDmg}) then { - ACE_LOGINFO_6("addDamageToUnit - PASSED - [unit:%1, partNo:%2, addDmg:%3] results:[alive:%4 old:%5 new:%6]", _unit, _partNumber, _damageToAdd, alive _unit, _startDmg, _endDmg); + INFO_6("addDamageToUnit - PASSED - [unit:%1, partNo:%2, addDmg:%3] results:[alive:%4 old:%5 new:%6]", _unit, _partNumber, _damageToAdd, alive _unit, _startDmg, _endDmg); } else { - ACE_LOGERROR_6("addDamageToUnit - FAILED - [unit:%1, partNo:%2, addDmg:%3] results:[alive:%4 old:%5 new:%6]", _unit, _partNumber, _damageToAdd, alive _unit, _startDmg, _endDmg); + ERROR_6("addDamageToUnit - FAILED - [unit:%1, partNo:%2, addDmg:%3] results:[alive:%4 old:%5 new:%6]", _unit, _partNumber, _damageToAdd, alive _unit, _startDmg, _endDmg); }; }; [{diag_frameno > (_this select 0)}, _debugCode, [_checkAtFrame, _unit, _startDmg, _damageToAdd, _partNumber]] call CBA_fnc_waitUntilAndExecute; #endif -private _return = [_unit, _selection, (_currentDamage + _damageToAdd), _unit, _typeOfDamage, _hitpointIndex] call FUNC(handleDamage); +private _return = [_unit, _selection, (_currentDamage + _damageToAdd), _unit, _typeOfDamage, _hitpointIndex, objNull] call FUNC(handleDamage); TRACE_1("handleDamage called",_return); _return diff --git a/addons/medical/functions/fnc_addHeartRateAdjustment.sqf b/addons/medical/functions/fnc_addHeartRateAdjustment.sqf index a23ea45023..6c932bb2ef 100644 --- a/addons/medical/functions/fnc_addHeartRateAdjustment.sqf +++ b/addons/medical/functions/fnc_addHeartRateAdjustment.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Increase the Heart Rate of a local unit by given number within given amount of seconds. @@ -11,11 +12,12 @@ * Return Value: * None * + * Example: + * [bob, 1, 5, {callback}] call ace_medical_fnc_addHeartRateAdjustment + * * Public: Yes */ -#include "script_component.hpp" - params [["_unit", objNull, [objNull]], ["_value", 0, [0]], ["_time", 1, [0]], ["_callBack", {}, [{}]]]; private _adjustment = _unit getVariable [QGVAR(heartRateAdjustments), []]; diff --git a/addons/medical/functions/fnc_addLoadPatientActions.sqf b/addons/medical/functions/fnc_addLoadPatientActions.sqf new file mode 100644 index 0000000000..0b0b64fb69 --- /dev/null +++ b/addons/medical/functions/fnc_addLoadPatientActions.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 77d2378d0d..0000000000 --- a/addons/medical/functions/fnc_addToInjuredCollection.sqf +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Author: Glowbal - * Enabled the vitals loop for a unit. - * - * Arguments: - * 0: The Unit - * - * ReturnValue: - * None - * - * Deprecated - */ -#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_addToLog.sqf b/addons/medical/functions/fnc_addToLog.sqf index f0c6b9c622..dadab94a2a 100644 --- a/addons/medical/functions/fnc_addToLog.sqf +++ b/addons/medical/functions/fnc_addToLog.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Add an entry to the specified log @@ -11,11 +12,12 @@ * Return Value: * None * + * Example: + * [bob, "type", "message", [_args]] call ace_medical_fnc_addToLog + * * Public: Yes */ -#include "script_component.hpp" - params ["_unit", "_type", "_message", "_arguments"]; if (!local _unit) exitWith { diff --git a/addons/medical/functions/fnc_addToTriageCard.sqf b/addons/medical/functions/fnc_addToTriageCard.sqf index 0e11f38f77..9b240846bc 100644 --- a/addons/medical/functions/fnc_addToTriageCard.sqf +++ b/addons/medical/functions/fnc_addToTriageCard.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Add an entry to the triage card @@ -9,11 +10,12 @@ * Return Value: * None * + * Example: + * [bob, "bandage"] call ace_medical_fnc_addToTriageCard + * * Public: Yes */ -#include "script_component.hpp" - params ["_unit", "_newItem"]; if (!local _unit) exitWith { diff --git a/addons/medical/functions/fnc_addUnconsciousCondition.sqf b/addons/medical/functions/fnc_addUnconsciousCondition.sqf index 195cd557d7..f31e5045fd 100644 --- a/addons/medical/functions/fnc_addUnconsciousCondition.sqf +++ b/addons/medical/functions/fnc_addUnconsciousCondition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Adds new condition for the unconscious state. Conditions are not actively checked for units unless unit is in unconscious state. @@ -5,12 +6,14 @@ * Arguments: * 0-N: Code, should return a boolean * - * ReturnValue: + * Return Value: * None * + * Example: + * [[{bob}]] call ace_medical_fnc_addUnconsciousCondition + * * Public: Yes */ -#include "script_component.hpp" if (isnil QGVAR(unconsciousConditions)) then { GVAR(unconsciousConditions) = []; diff --git a/addons/medical/functions/fnc_addUnloadPatientActions.sqf b/addons/medical/functions/fnc_addUnloadPatientActions.sqf index 596a536de6..bb73dab4e8 100644 --- a/addons/medical/functions/fnc_addUnloadPatientActions.sqf +++ b/addons/medical/functions/fnc_addUnloadPatientActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Create one unload action per unconscious passenger @@ -10,9 +11,11 @@ * Return Value: * Children actions * + * Example: + * [car, kevin, [params]] call ACE_medical_fnc_addUnloadPatientActions + * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_player", "_parameters"]; private _actions = []; diff --git a/addons/medical/functions/fnc_addVitalLoop.sqf b/addons/medical/functions/fnc_addVitalLoop.sqf index aa3d6608d0..a1a01a5a61 100644 --- a/addons/medical/functions/fnc_addVitalLoop.sqf +++ b/addons/medical/functions/fnc_addVitalLoop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Enabled the vitals loop for a unit. @@ -5,14 +6,15 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob] call ace_medical_fnc_addVitalLoop + * * Public: Yes */ -#include "script_component.hpp" - params ["_unit", ["_force", false]]; if !([_unit] call FUNC(hasMedicalEnabled) || _force) exitWith {}; diff --git a/addons/medical/functions/fnc_adjustPainLevel.sqf b/addons/medical/functions/fnc_adjustPainLevel.sqf index e37972d0ef..97bc9389a0 100644 --- a/addons/medical/functions/fnc_adjustPainLevel.sqf +++ b/addons/medical/functions/fnc_adjustPainLevel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Interface to allow external modules to safely adjust pain levels. @@ -14,9 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" - -private ["_pain"]; params ["_unit", "_addedPain"]; //Only run on local units: diff --git a/addons/medical/functions/fnc_bodyCleanupLoop.sqf b/addons/medical/functions/fnc_bodyCleanupLoop.sqf index af17ffcd34..31d1ef8b92 100644 --- a/addons/medical/functions/fnc_bodyCleanupLoop.sqf +++ b/addons/medical/functions/fnc_bodyCleanupLoop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, esteldunedain * Loop that cleans up litter @@ -5,14 +6,15 @@ * Arguments: * None * - * ReturnValue: + * Return Value: * None * + * Example: + * call ACE_medical_fnc_bodyCleanupLoop + * * Public: No */ -#include "script_component.hpp" - { TRACE_2("body",_x,isPlayer _x); if ((!isNull _x) && {!isPlayer _x}) then {deleteVehicle _x}; diff --git a/addons/medical/functions/fnc_canAccessMedicalEquipment.sqf b/addons/medical/functions/fnc_canAccessMedicalEquipment.sqf index 53707ae65c..d73a70f657 100644 --- a/addons/medical/functions/fnc_canAccessMedicalEquipment.sqf +++ b/addons/medical/functions/fnc_canAccessMedicalEquipment.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if caller can access targets medical equipment, based upon accessLevel. @@ -6,14 +7,15 @@ * 0: The caller * 1: The target * - * ReturnValue: + * Return Value: * Can Treat * + * Example: + * [bob, target] call ace_medical_fnc_canAccessMedicalEquipment + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target"]; private _accessLevel = _target getVariable [QGVAR(allowSharedEquipmentAccess), -1]; diff --git a/addons/medical/functions/fnc_canTreat.sqf b/addons/medical/functions/fnc_canTreat.sqf index 1c78eb1e43..913cc4c30e 100644 --- a/addons/medical/functions/fnc_canTreat.sqf +++ b/addons/medical/functions/fnc_canTreat.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if the treatment action can be performed. @@ -8,7 +9,7 @@ * 2: Selection name * 3: ACE_Medical_Treatments Classname * - * ReturnValue: + * Return Value: * Can Treat * * Example: @@ -17,8 +18,6 @@ * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName", "_className"]; if !(_target isKindOf "CAManBase") exitWith { false }; diff --git a/addons/medical/functions/fnc_canTreatCached.sqf b/addons/medical/functions/fnc_canTreatCached.sqf index 76d4897b74..35fc3ada22 100644 --- a/addons/medical/functions/fnc_canTreatCached.sqf +++ b/addons/medical/functions/fnc_canTreatCached.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Cached Check if the treatment action can be performed. @@ -8,14 +9,15 @@ * 2: Selection name * 3: ACE_Medical_Treatments Classname * - * ReturnValue: + * Return Value: * Can Treat * + * Example: + * [bob, kevin, "selection", "classname"] call ACE_medical_fnc_canTreatCached + * * Public: No */ -#include "script_component.hpp" - #define MAX_DURATION_CACHE 2 params ["", "_target", "_selection", "_classname"]; diff --git a/addons/medical/functions/fnc_copyDeadBody.sqf b/addons/medical/functions/fnc_copyDeadBody.sqf index af601d9f33..56687988e4 100644 --- a/addons/medical/functions/fnc_copyDeadBody.sqf +++ b/addons/medical/functions/fnc_copyDeadBody.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Makes a copy of a dead body. For handling dead bodies for actions such as load and carry. @@ -9,23 +10,23 @@ * Return Value: * Returns the copy of the unit. If no copy could be made, returns the oldBody * + * Example: + * [bob, kevin] call ACE_medical_fnc_copyDeadBody + * * Public: No */ -#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_createLitter.sqf b/addons/medical/functions/fnc_createLitter.sqf index 2780642056..349f6252d9 100644 --- a/addons/medical/functions/fnc_createLitter.sqf +++ b/addons/medical/functions/fnc_createLitter.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Spawns litter for the treatment action on the ground around the target @@ -7,18 +8,19 @@ * 1: The target * 2: The treatment Selection Name * 3: The treatment classname - * 4: ? - * 5: Users of Items + * 4: ? + * 5: Users of Items * 6: Blood Loss on selection (previously called _previousDamage) * * Return Value: * None * + * Example: + * [bob, kevin, "selection", "classname", , , 5] call ACE_medical_fnc_createLitter + * * Public: No */ -#include "script_component.hpp" - #define MIN_ENTRIES_LITTER_CONFIG 3 params ["_caller", "_target", "_selectionName", "_className", "", "_usersOfItems", "_bloodLossOnSelection"]; diff --git a/addons/medical/functions/fnc_determineIfFatal.sqf b/addons/medical/functions/fnc_determineIfFatal.sqf index 9dbbcce9a6..1cf30acc75 100644 --- a/addons/medical/functions/fnc_determineIfFatal.sqf +++ b/addons/medical/functions/fnc_determineIfFatal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Determine If Fatal @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [bob, 2, 5] call ACE_medical_fnc_determineIfFatal + * * Public: No */ -#include "script_component.hpp" #define INCREASE_CHANCE_HEAD 0.05 #define INCREASE_CHANCE_TORSO 0.03 @@ -30,7 +33,7 @@ if (_part < 0 || _part > 5) exitWith {false}; // Find the correct Damage threshold for unit. private _damageThreshold = [1,1,1]; -if ([_unit] call EFUNC(common,IsPlayer)) then { +if ([_unit, GVAR(remoteControlledAI)] call EFUNC(common,isPlayer)) then { _damageThreshold =_unit getVariable[QGVAR(unitDamageThreshold), [GVAR(playerDamageThreshold), GVAR(playerDamageThreshold), GVAR(playerDamageThreshold) * 1.7]]; } else { _damageThreshold =_unit getVariable[QGVAR(unitDamageThreshold), [GVAR(AIDamageThreshold), GVAR(AIDamageThreshold), GVAR(AIDamageThreshold) * 1.7]]; diff --git a/addons/medical/functions/fnc_displayPatientInformation.sqf b/addons/medical/functions/fnc_displayPatientInformation.sqf index 1489e27288..3058dd82bf 100644 --- a/addons/medical/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical/functions/fnc_displayPatientInformation.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Displays the patient information for given unit. @@ -7,13 +8,14 @@ * 1: Show (default: true) * 2: Selection (default: 0) * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, true, 2] call ACE_medical_fnc_displayPatientInformation + * * Public: No */ - -#include "script_component.hpp" #define MAX_DISTANCE 10 // Exit for basic medical @@ -28,7 +30,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"]; @@ -68,7 +69,7 @@ if (_show) then { }; private _totalIvVolume = 0; - private _bloodBags = _unit getVariable [QGVAR(ivBags), []]; + private _bloodBags = _target getVariable [QGVAR(ivBags), []]; { _x params ["_bagVolumeRemaining"]; _totalIvVolume = _totalIvVolume + _bagVolumeRemaining; diff --git a/addons/medical/functions/fnc_displayTriageCard.sqf b/addons/medical/functions/fnc_displayTriageCard.sqf index 1633853214..1a84b98e87 100644 --- a/addons/medical/functions/fnc_displayTriageCard.sqf +++ b/addons/medical/functions/fnc_displayTriageCard.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Display triage card for a unit @@ -9,11 +10,12 @@ * Return Value: * None * + * Example: + * [bob, true] call ace_medical_fnc_displayTriageCard + * * Public: Yes */ -#include "script_component.hpp" - params ["_target", ["_show", true]]; GVAR(TriageCardTarget) = if (_show) then {_target} else {ObjNull}; diff --git a/addons/medical/functions/fnc_dropDownTriageCard.sqf b/addons/medical/functions/fnc_dropDownTriageCard.sqf index c499283446..c409e39ac0 100644 --- a/addons/medical/functions/fnc_dropDownTriageCard.sqf +++ b/addons/medical/functions/fnc_dropDownTriageCard.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Display triage card for a unit @@ -8,11 +9,12 @@ * Return Value: * None * + * Example: + * [true] call ace_medical_fnc_dropDownTriageCard + * * Public: Yes */ -#include "script_component.hpp" - params ["_show"]; disableSerialization; diff --git a/addons/medical/functions/fnc_getBloodLoss.sqf b/addons/medical/functions/fnc_getBloodLoss.sqf index 8f2f968e99..1caff24527 100644 --- a/addons/medical/functions/fnc_getBloodLoss.sqf +++ b/addons/medical/functions/fnc_getBloodLoss.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Calculate the total blood loss of a unit. @@ -5,14 +6,15 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * Total blood loss of unit * + * Example: + * [bob] call ACE_medical_fnc_getBloodLoss + * * Public: No */ -#include "script_component.hpp" - #define BLOODLOSSRATE_BASIC 0.2 // TODO Only use this calculation if medium or higher, otherwise use vanilla calculations (for basic medical). diff --git a/addons/medical/functions/fnc_getBloodPressure.sqf b/addons/medical/functions/fnc_getBloodPressure.sqf index 63908eecc7..7a582df5e1 100644 --- a/addons/medical/functions/fnc_getBloodPressure.sqf +++ b/addons/medical/functions/fnc_getBloodPressure.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Calculates the blood volume change and decreases the IVs given to the unit. @@ -5,15 +6,16 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * 0: BloodPressure Low * 1: BloodPressure High * + * Example: + * [bob, kevin] call ACE_medical_fnc_getBloodPressure + * * Public: No */ -#include "script_component.hpp" - // Value is taken because with cardic output and resistance at default values, it will put blood pressure High at 120. #define MODIFIER_BP_HIGH 0.229 diff --git a/addons/medical/functions/fnc_getBloodVolumeChange.sqf b/addons/medical/functions/fnc_getBloodVolumeChange.sqf index 396d058140..32bcfb23ed 100644 --- a/addons/medical/functions/fnc_getBloodVolumeChange.sqf +++ b/addons/medical/functions/fnc_getBloodVolumeChange.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Calculates the blood volume change and decreases the IVs given to the unit. @@ -6,14 +7,15 @@ * 0: The Unit * 1: Global Sync Values (bloodbags) * - * ReturnValue: + * Return Value: * Blood volume change (in % total) * + * Example: + * [bob, true] call ACE_medical_fnc_getBloodVolumeChange + * * Public: No */ -#include "script_component.hpp" - /* IV Change per second calculation: 250ml should take 60 seconds to fill. 250/60 = 4.166. diff --git a/addons/medical/functions/fnc_getCardiacOutput.sqf b/addons/medical/functions/fnc_getCardiacOutput.sqf index 74da98012b..9fcaad8731 100644 --- a/addons/medical/functions/fnc_getCardiacOutput.sqf +++ b/addons/medical/functions/fnc_getCardiacOutput.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the cardiac output from the Heart, based on current Heart Rate and Blood Volume. @@ -5,14 +6,15 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * Current cardiac output * + * Example: + * [bob] call ACE_medical_fnc_getCardiacOutput + * * Public: No */ -#include "script_component.hpp" - /* Cardiac output (Q or or CO ) is the volume of blood being pumped by the heart, in particular by a left or right ventricle in the CBA_missionTime interval of one minute. CO may be measured in many ways, for example dm3/min (1 dm3 equals 1 litre). diff --git a/addons/medical/functions/fnc_getHeartRateChange.sqf b/addons/medical/functions/fnc_getHeartRateChange.sqf index 4f0b19f80c..dcd35ed476 100644 --- a/addons/medical/functions/fnc_getHeartRateChange.sqf +++ b/addons/medical/functions/fnc_getHeartRateChange.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the change in the heart rate. Used for the vitals calculations. Calculated in one seconds. @@ -5,14 +6,15 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * Change in heart Rate * + * Example: + * [bob] call ACE_medical_fnc_getHeartRateChange + * * Public: No */ -#include "script_component.hpp" - #define HEART_RATE_MODIFIER 0.02 params ["_unit"]; diff --git a/addons/medical/functions/fnc_getTriageStatus.sqf b/addons/medical/functions/fnc_getTriageStatus.sqf index 79af660407..2b502b563b 100644 --- a/addons/medical/functions/fnc_getTriageStatus.sqf +++ b/addons/medical/functions/fnc_getTriageStatus.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the triage status and information from a unit @@ -10,15 +11,16 @@ * 1: Status ID * 2: Color > * + * Example: + * [bob] call ace_medical_fnc_getTriageStatus + * * Public: Yes */ -#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_getTypeOfDamage.sqf b/addons/medical/functions/fnc_getTypeOfDamage.sqf index 56cb8f75ef..c65f5d78e7 100644 --- a/addons/medical/functions/fnc_getTypeOfDamage.sqf +++ b/addons/medical/functions/fnc_getTypeOfDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the type of damage based upon the projectile. @@ -5,14 +6,15 @@ * Arguments: * 0: The projectile classname or object * - * ReturnValue: + * Return Value: * Type of damage * + * Example: + * ["bullet"] call ACE_medical_fnc_getTypeOfDamage + * * Public: No */ -#include "script_component.hpp" - params ["_typeOfProjectile"]; diff --git a/addons/medical/functions/fnc_getUnconsciousCondition.sqf b/addons/medical/functions/fnc_getUnconsciousCondition.sqf index ad366b5ab2..436365cc91 100644 --- a/addons/medical/functions/fnc_getUnconsciousCondition.sqf +++ b/addons/medical/functions/fnc_getUnconsciousCondition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get whatever or not a unit should be or stay unconscious. @@ -5,14 +6,15 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * Should the unit stay unconscious? * + * Example: + * [bob] call ace_medical_fnc_getUnconsciousCondition + * * Public: Yes */ -#include "script_component.hpp" - params ["_unit"]; if (isnil QGVAR(unconsciousConditions)) then { diff --git a/addons/medical/functions/fnc_handleBandageOpening.sqf b/addons/medical/functions/fnc_handleBandageOpening.sqf index f2a5a45af2..1e80a727df 100644 --- a/addons/medical/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical/functions/fnc_handleBandageOpening.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handles the bandage of a patient. @@ -13,12 +14,12 @@ * Return Value: * None * + * Example: + * [bob, 5, 5, 1, [injury], "bandage"] call ACE_medical_fnc_handleBandageOpening + * * Public: No */ -#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; @@ -37,7 +38,7 @@ if (isClass (_config >> _bandage)) then { _reopeningMinDelay = getNumber (_config >> "reopeningMinDelay"); _reopeningMaxDelay = getNumber (_config >> "reopeningMaxDelay") max _reopeningMinDelay; } else { - ACE_LOGWARNING_2("No config for bandage [%1] config base [%2]", _bandage, _config); + WARNING_2("No config for bandage [%1] config base [%2]", _bandage, _config); }; if (isClass (_config >> _className)) then { @@ -52,7 +53,7 @@ if (isClass (_config >> _className)) then { _reopeningMaxDelay = getNumber (_woundTreatmentConfig >> "reopeningMaxDelay") max _reopeningMinDelay; }; } else { - ACE_LOGWARNING_2("No config for wound type [%1] config base [%2]", _className, _config); + WARNING_2("No config for wound type [%1] config base [%2]", _className, _config); }; TRACE_5("configs",_bandage,_className,_reopeningChance,_reopeningMinDelay,_reopeningMaxDelay); @@ -63,7 +64,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]; @@ -82,7 +83,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"]; @@ -100,7 +101,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 191a91cb6a..aaaa3f894b 100644 --- a/addons/medical/functions/fnc_handleCollisionDamage.sqf +++ b/addons/medical/functions/fnc_handleCollisionDamage.sqf @@ -1,13 +1,26 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * 0: Unit + * 1: New Damage + * + * Return Value: + * None + * + * Example: + * [bob, 2] call ACE_medical_fnc_handleCollisionDamage + * + * Public: No + */ 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_handleCreateLitter.sqf b/addons/medical/functions/fnc_handleCreateLitter.sqf index 2c701a2917..7a39fe767a 100644 --- a/addons/medical/functions/fnc_handleCreateLitter.sqf +++ b/addons/medical/functions/fnc_handleCreateLitter.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * handle Litter Create @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * ["litter", [2, 5, 6], bob] call ACE_medical_fnc_handleCreateLitter + * * Public: No */ -#include "script_component.hpp" params ["_litterClass", "_position", "_direction"]; TRACE_3("params",_litterClass,_position,_direction); diff --git a/addons/medical/functions/fnc_handleDamage.sqf b/addons/medical/functions/fnc_handleDamage.sqf index abb91ff1c3..ea4c5d9611 100644 --- a/addons/medical/functions/fnc_handleDamage.sqf +++ b/addons/medical/functions/fnc_handleDamage.sqf @@ -1,4 +1,5 @@ - /* +#include "script_component.hpp" +/* * Author: KoffeinFlummi, Glowbal, commy2 * Main HandleDamage EH function. * @@ -7,16 +8,20 @@ * 1: Name Of Hit Selection * 2: Amount Of Damage * 3: Shooter - * 4: Projectile + * 4: Projectile * 5: HitPointIndex (-1 for structural) + * 6: Shooter * * Return Value: * Damage To Be Inflicted * + * Example: + * [bob, "leg", 2, kevin, "bullet", -1, kevin] call ACE_medical_fnc_handleDamage + * * Public: No */ -#include "script_component.hpp" +_this = _this select [0, 7]; params ["_unit", "_selection", "_damage", "_shooter", "_projectile", "_hitPointIndex"]; TRACE_5("ACE_DEBUG: HandleDamage Called",_unit, _selection, _damage, _shooter, _projectile); diff --git a/addons/medical/functions/fnc_handleDamage_advanced.sqf b/addons/medical/functions/fnc_handleDamage_advanced.sqf index 724958dfbc..049b6a004c 100644 --- a/addons/medical/functions/fnc_handleDamage_advanced.sqf +++ b/addons/medical/functions/fnc_handleDamage_advanced.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Advanced HandleDamage EH function. @@ -15,11 +16,12 @@ * Return Value: * None * + * Example: + * [bob, "leg", 2, kevin, "bullet", 2, kevin, 2] call ACE_medical_fnc_handleDamage_advanced + * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_selectionName", "_amountOfDamage", "_sourceOfDamage", "_typeOfProjectile", "_hitPointNumber", "", "_newDamage"]; // For burning damage we will get a ton of very small hits of damage; they are too small to create any wounds @@ -27,10 +29,10 @@ params ["_unit", "_selectionName", "_amountOfDamage", "_sourceOfDamage", "_typeO if ((_typeOfProjectile == "") && {_newDamage < 0.15} && { _newDamage = _newDamage + (_unit getVariable [QGVAR(trivialDamage), 0]); - if (_newDamage > 0.15) then { + if (_newDamage > 0.15) then { // if the new sum is large enough, reset variable and continue with it added in _unit setVariable [QGVAR(trivialDamage), 0]; - false + false } else { // otherwise just save the new sum into the variable and exit _unit setVariable [QGVAR(trivialDamage), _newDamage]; diff --git a/addons/medical/functions/fnc_handleDamage_advancedSetDamage.sqf b/addons/medical/functions/fnc_handleDamage_advancedSetDamage.sqf index b18604f133..8bf6d8f8e0 100644 --- a/addons/medical/functions/fnc_handleDamage_advancedSetDamage.sqf +++ b/addons/medical/functions/fnc_handleDamage_advancedSetDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Sets the hitpoint damage for au nit to the correct values @@ -8,11 +9,12 @@ * Return Value: * None * + * Example: + * [bob] call ACE_medical_fnc_handleDamage_advancedSetDamage + * * Public: No */ -#include "script_component.hpp" - params ["_unit"]; if (!local _unit) exitWith {}; diff --git a/addons/medical/functions/fnc_handleDamage_airway.sqf b/addons/medical/functions/fnc_handleDamage_airway.sqf index fb4c9fe83c..6b033dee36 100644 --- a/addons/medical/functions/fnc_handleDamage_airway.sqf +++ b/addons/medical/functions/fnc_handleDamage_airway.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handling of the airway injuries upon the handleDamage eventhandler. @@ -12,11 +13,12 @@ * Return Value: * None * + * Example: + * [bob, "leg", 2, kevin, "shot"] call ACE_medical_fnc_airway + * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_selectionName", "_amountOfDamage", "_sourceOfDamage", "_typeOfDamage"]; private _bodyPartn = [_selectionName] call FUNC(selectionNameToNumber); diff --git a/addons/medical/functions/fnc_handleDamage_caching.sqf b/addons/medical/functions/fnc_handleDamage_caching.sqf index 792f09e75d..6d17077a38 100644 --- a/addons/medical/functions/fnc_handleDamage_caching.sqf +++ b/addons/medical/functions/fnc_handleDamage_caching.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Cache a handleDamage call to execute it 3 frames later @@ -11,11 +12,13 @@ * 5: HitPointIndex (-1 for structural) * * Return Value: - * + * None + * + * Example: + * [bob, "leg", 2, kevin, "bullet", -1] call ACE_medical_fnc_handleDamage_caching * * Public: No */ -#include "script_component.hpp" params ["_unit", "_selectionName", "_damage", "_source", "_projectile", "_hitPointIndex"]; diff --git a/addons/medical/functions/fnc_handleDamage_fractures.sqf b/addons/medical/functions/fnc_handleDamage_fractures.sqf index 5292781420..cc36b698c2 100644 --- a/addons/medical/functions/fnc_handleDamage_fractures.sqf +++ b/addons/medical/functions/fnc_handleDamage_fractures.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handling of the fracture injuries upon the handleDamage eventhandler. @@ -12,16 +13,16 @@ * Return Value: * None * + * Example: + * [bob, "leg", 2, kevin, "shot"] call ACE_medical_fnc_handleDamage_fractures + * * Public: No */ -#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. @@ -58,10 +59,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_internalInjuries.sqf b/addons/medical/functions/fnc_handleDamage_internalInjuries.sqf index 8e249eee8f..6f96b138c2 100644 --- a/addons/medical/functions/fnc_handleDamage_internalInjuries.sqf +++ b/addons/medical/functions/fnc_handleDamage_internalInjuries.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handling of the internal injuries upon the handleDamage eventhandler. @@ -12,11 +13,12 @@ * Return Value: * None * + * Example: + * [bob, "leg", 2, kevin, "shot"] call ACE_medical_fnc_handleDamage_internalInjuries + * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_selectionName", "_amountOfDamage", "_sourceOfDamage", "_typeOfDamage"]; private _bodyPartn = [_selectionName] call FUNC(selectionNameToNumber); diff --git a/addons/medical/functions/fnc_handleDamage_wounds.sqf b/addons/medical/functions/fnc_handleDamage_wounds.sqf index 170880ce34..fdc06621c5 100644 --- a/addons/medical/functions/fnc_handleDamage_wounds.sqf +++ b/addons/medical/functions/fnc_handleDamage_wounds.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handling of the open wounds & injuries upon the handleDamage eventhandler. @@ -12,11 +13,12 @@ * Return Value: * None * + * Example: + * [bob, "leg", 2, kevin, "shot"] call ACE_medical_fnc_handleDamage_wounds + * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_selectionName", "_damage", "_typeOfProjectile", "_typeOfDamage"]; TRACE_6("ACE_DEBUG: HandleDamage Called",_unit, _selectionName, _damage, _shooter, _typeOfProjectile,_typeOfDamage); @@ -38,7 +40,7 @@ call compile _extensionOutput; { _x params ["", "_compareId", "_comparyBodyPartN"]; // Check if we have an id of the given class on the given bodypart already - if (_compareId == _toAddClassID && {_comparyBodyPartN2 == _bodyPartNToAdd}) exitWith { + if (_compareId == _toAddClassID && {_comparyBodyPartN == _bodyPartNToAdd}) exitWith { _foundIndex = _forEachIndex; }; } forEach _openWounds; diff --git a/addons/medical/functions/fnc_handleDamage_woundsOld.sqf b/addons/medical/functions/fnc_handleDamage_woundsOld.sqf index c6ccd1c2b5..4cc51ce38f 100644 --- a/addons/medical/functions/fnc_handleDamage_woundsOld.sqf +++ b/addons/medical/functions/fnc_handleDamage_woundsOld.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handling of the open wounds & injuries upon the handleDamage eventhandler. @@ -12,24 +13,24 @@ * Return Value: * None * + * Example: + * [bob, "leg", 1, kevin, "shot"] call ACE_medical_fnc_handleDamage_woundsOld + * * Public: No */ -#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 { @@ -39,20 +40,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 { @@ -73,21 +73,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 { { @@ -98,7 +98,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]; @@ -129,6 +129,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/functions/fnc_handleInit.sqf b/addons/medical/functions/fnc_handleInit.sqf new file mode 100644 index 0000000000..3431713d5d --- /dev/null +++ b/addons/medical/functions/fnc_handleInit.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * 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 + */ + +params ["_unit"]; + +_unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}]; + +if (local _unit) then { + if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(init), [_unit]]; + }; + [_unit] call FUNC(init); +}; diff --git a/addons/medical/functions/fnc_handleKilled.sqf b/addons/medical/functions/fnc_handleKilled.sqf index 6ca05a4228..9a2e8d2f63 100644 --- a/addons/medical/functions/fnc_handleKilled.sqf +++ b/addons/medical/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Called when a unit is killed @@ -5,14 +6,15 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob] call ACE_medical_fnc_handleKilled + * * Public: No */ -#include "script_component.hpp" - params ["_unit"]; if (!local _unit) exitWith {}; diff --git a/addons/medical/functions/fnc_handleLocal.sqf b/addons/medical/functions/fnc_handleLocal.sqf index 8bf3cd5e69..06047f5545 100644 --- a/addons/medical/functions/fnc_handleLocal.sqf +++ b/addons/medical/functions/fnc_handleLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Called when a unit switched locality @@ -6,15 +7,15 @@ * 0: The Unit * 1: Is local * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, true] call ACE_medical_fnc_handleLocal + * * Public: No */ - -#include "script_component.hpp" - params ["_unit", "_local"]; if (_local) then { // If the unit had a loop tracking its vitals, restart it locally diff --git a/addons/medical/functions/fnc_handleRespawn.sqf b/addons/medical/functions/fnc_handleRespawn.sqf new file mode 100644 index 0000000000..be8f5f4f29 --- /dev/null +++ b/addons/medical/functions/fnc_handleRespawn.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +/* + * Author: KoffeinFlummi + * Called when a unit is Respawned + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [bob] call ACE_medical_fnc_handleRespawn + * + * Public: No + */ + +params ["_unit"]; + +// reset all variables. @todo GROUP respawn? +[_unit] call FUNC(init); + +// Reset captive status for respawning unit +if (!(_unit getVariable ["ACE_isUnconscious", false])) then { + [_unit, "setHidden", "ace_unconscious", false] call EFUNC(common,statusEffect_set); +}; + +// Remove maximum unconsciousness time handler +_maxUnconHandle = _unit getVariable [QGVAR(maxUnconTimeHandle), -1]; +if (_maxUnconHandle > 0) then { + [_maxUnconHandle] call CBA_fnc_removePerFrameHandler; +}; diff --git a/addons/medical/functions/fnc_handleUnitVitals.sqf b/addons/medical/functions/fnc_handleUnitVitals.sqf index 78c1cc9dfe..a593c8e579 100644 --- a/addons/medical/functions/fnc_handleUnitVitals.sqf +++ b/addons/medical/functions/fnc_handleUnitVitals.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Updates the vitals. Is expected to be called every second. @@ -5,14 +6,15 @@ * Arguments: * 0: The Unit * - * ReturnValue: - * + * Return Value: + * None + * + * Example: + * [bob] call ACE_medical_fnc_handleUnitVitals * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_interval"]; TRACE_3("ACE_DEBUG",_unit,_interval,_unit); if (_interval == 0) exitWith {}; diff --git a/addons/medical/functions/fnc_hasItem.sqf b/addons/medical/functions/fnc_hasItem.sqf index cebe02e6c6..1174563dfc 100644 --- a/addons/medical/functions/fnc_hasItem.sqf +++ b/addons/medical/functions/fnc_hasItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if the item is present between the patient and the medic @@ -7,14 +8,15 @@ * 1: Patient * 2: Item * - * ReturnValue: - * + * Return Value: + * None + * + * Example: + * [bob, patient, "bandage"] call ace_medical_fnc_hasItem * * Public: Yes */ -#include "script_component.hpp" - params ["_medic", "_patient", "_item"]; if (isNil QGVAR(setting_allowSharedEquipment)) then { diff --git a/addons/medical/functions/fnc_hasItems.sqf b/addons/medical/functions/fnc_hasItems.sqf index d3e79c0a54..1ea0f15b65 100644 --- a/addons/medical/functions/fnc_hasItems.sqf +++ b/addons/medical/functions/fnc_hasItems.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if all items are present between the patient and the medic. @@ -7,14 +8,15 @@ * 1: Patient * 2: Items > * - * ReturnValue: + * Return Value: * Has the items * + * Example: + * [bob, patient, ["bandage", "morphine"]] call ace_medical_fnc_hasItems + * * Public: Yes */ -#include "script_component.hpp" - params ["_medic", "_patient", "_items"]; private _return = true; diff --git a/addons/medical/functions/fnc_hasMedicalEnabled.sqf b/addons/medical/functions/fnc_hasMedicalEnabled.sqf index 5cc5b60aa3..c034648c33 100644 --- a/addons/medical/functions/fnc_hasMedicalEnabled.sqf +++ b/addons/medical/functions/fnc_hasMedicalEnabled.sqf @@ -1,4 +1,4 @@ - +#include "script_component.hpp" /* * Author: Glowbal * Check if unit has CMS enabled @@ -14,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/medical/functions/fnc_hasTourniquetAppliedTo.sqf b/addons/medical/functions/fnc_hasTourniquetAppliedTo.sqf index abbe512d74..852bddfa12 100644 --- a/addons/medical/functions/fnc_hasTourniquetAppliedTo.sqf +++ b/addons/medical/functions/fnc_hasTourniquetAppliedTo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if unit has a tourniquet applied to the specified bodypart @@ -6,14 +7,15 @@ * 0: The Unit * 1: SelectionName * - * ReturnValue: + * Return Value: * Has tourniquet applied * + * Example: + * [bob, "leg"] call ace_medical_fnc_hasTourniquetAppliedTo + * * Public: Yes */ -#include "script_component.hpp" - params ["_target", "_selectionName"]; (((_target getVariable [QGVAR(tourniquets), [0,0,0,0,0,0]]) select ([_selectionName] call FUNC(selectionNameToNumber))) > 0); diff --git a/addons/medical/functions/fnc_init.sqf b/addons/medical/functions/fnc_init.sqf index d6db3db392..a9f164eb0f 100644 --- a/addons/medical/functions/fnc_init.sqf +++ b/addons/medical/functions/fnc_init.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, commy2 * Initializes unit variables. @@ -5,12 +6,14 @@ * Arguments: * 0: The Unit * - * ReturnValue: - * nil + * Return Value: + * None + * + * Example: + * [bob] call ACE_medical_fnc_init * * Public: No */ -#include "script_component.hpp" params ["_unit"]; @@ -66,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_isBeingCarried.sqf b/addons/medical/functions/fnc_isBeingCarried.sqf index 26ce932901..79a0f4ce9d 100644 --- a/addons/medical/functions/fnc_isBeingCarried.sqf +++ b/addons/medical/functions/fnc_isBeingCarried.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Returns if a target is being carried. (from ace_dragging) @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target"]; diff --git a/addons/medical/functions/fnc_isBeingDragged.sqf b/addons/medical/functions/fnc_isBeingDragged.sqf index b0297c0049..e10ba60b8f 100644 --- a/addons/medical/functions/fnc_isBeingDragged.sqf +++ b/addons/medical/functions/fnc_isBeingDragged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Returns if a target is being dragged. (from ace_dragging) @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_target"]; diff --git a/addons/medical/functions/fnc_isInMedicalFacility.sqf b/addons/medical/functions/fnc_isInMedicalFacility.sqf index 313ee8eca4..9d12bd9640 100644 --- a/addons/medical/functions/fnc_isInMedicalFacility.sqf +++ b/addons/medical/functions/fnc_isInMedicalFacility.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Checks if a unit is in a designated medical facility @@ -5,7 +6,7 @@ * Arguments: * 0: The Unit * - * ReturnValue: + * Return Value: * Is in medical facility * * Example: @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/medical/functions/fnc_isInMedicalVehicle.sqf b/addons/medical/functions/fnc_isInMedicalVehicle.sqf index 4182003bad..77b36caa25 100644 --- a/addons/medical/functions/fnc_isInMedicalVehicle.sqf +++ b/addons/medical/functions/fnc_isInMedicalVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Checks if a unit is in a medical vehicle. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; private _vehicle = vehicle _unit; diff --git a/addons/medical/functions/fnc_isInStableCondition.sqf b/addons/medical/functions/fnc_isInStableCondition.sqf index a11e40dd31..da56ea402e 100644 --- a/addons/medical/functions/fnc_isInStableCondition.sqf +++ b/addons/medical/functions/fnc_isInStableCondition.sqf @@ -1,17 +1,19 @@ -/* -* Author: Glowbal -* Check if a unit is in a stable condition -* -* Arguments: -* 0: The patient -* -* Return Value: -* Is in stable condition -* -* Public: No -*/ - #include "script_component.hpp" +/* + * Author: Glowbal + * Check if a unit is in a stable condition + * + * Arguments: + * 0: The patient + * + * Return Value: + * Is in stable condition + * + * Example: + * [bob] call ACE_medical_fnc_isInStableCondition + * + * Public: No + */ params ["_unit"]; diff --git a/addons/medical/functions/fnc_isMedic.sqf b/addons/medical/functions/fnc_isMedic.sqf index ff5a1b24a9..580733b4d5 100644 --- a/addons/medical/functions/fnc_isMedic.sqf +++ b/addons/medical/functions/fnc_isMedic.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Check if a unit is any medical class @@ -6,7 +7,7 @@ * 0: The Unit * 1: Class (default: 1) * - * ReturnValue: + * Return Value: * Is in of medic class * * Example: @@ -15,11 +16,9 @@ * Public: Yes */ -#include "script_component.hpp" - params ["_unit", ["_medicN", 1]]; -private _class = _unit getVariable [QGVAR(medicClass), getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "attendant")]; +private _class = _unit getVariable [QGVAR(medicClass), [0, 1] select (_unit getUnitTrait "medic")]; if (_class >= _medicN min GVAR(medicSetting)) exitWith {true}; if (!GVAR(increaseTrainingInLocations)) exitWith {false}; diff --git a/addons/medical/functions/fnc_isMedicalVehicle.sqf b/addons/medical/functions/fnc_isMedicalVehicle.sqf index 14499cb241..26f2bd6850 100644 --- a/addons/medical/functions/fnc_isMedicalVehicle.sqf +++ b/addons/medical/functions/fnc_isMedicalVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if vehicle is a medical vehicle @@ -5,12 +6,14 @@ * Arguments: * 0: The Vehicle * - * ReturnValue: + * Return Value: * Is in of medic class * + * Example: + * [car] call ace_medical_fnc_isMedicalVehicle + * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/medical/functions/fnc_itemCheck.sqf b/addons/medical/functions/fnc_itemCheck.sqf index d49e04e774..0290deeea8 100644 --- a/addons/medical/functions/fnc_itemCheck.sqf +++ b/addons/medical/functions/fnc_itemCheck.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Replaces vanilla items with ACE ones. @@ -5,14 +6,15 @@ * Arguments: * 0: The unit * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob] call ace_medical_fnc_itemCheck + * * Public: Yes */ -#include "script_component.hpp" - params ["_unit"]; while {({_x == "FirstAidKit"} count items _unit) > 0} do { diff --git a/addons/medical/functions/fnc_litterCleanupLoop.sqf b/addons/medical/functions/fnc_litterCleanupLoop.sqf index 417144dd64..539ca74e26 100644 --- a/addons/medical/functions/fnc_litterCleanupLoop.sqf +++ b/addons/medical/functions/fnc_litterCleanupLoop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, esteldunedain * Loop that cleans up litter @@ -5,14 +6,15 @@ * Arguments: * None * - * ReturnValue: + * Return Value: * None * + * Example: + * call ACE_medical_fnc_litterCleanupLoop + * * Public: No */ -#include "script_component.hpp" - { _x params ["_time", "_objects"]; //Older elements are always at the begining of the array: diff --git a/addons/medical/functions/fnc_medicationEffectLoop.sqf b/addons/medical/functions/fnc_medicationEffectLoop.sqf index 00ef00a82c..efef65ece9 100644 --- a/addons/medical/functions/fnc_medicationEffectLoop.sqf +++ b/addons/medical/functions/fnc_medicationEffectLoop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, esteldunedain * Medication effect loop for an injection. @@ -10,14 +11,15 @@ * 4: Viscosity adjustment rate * 5: Pain reduction rate * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, "leg", 1, 2, 3, 4] call ACE_medical_fnc_medicationEffectLoop + * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_variableName", "_amountDecreased","_decreaseRate", "_viscosityAdjustmentRate", "_painReduceRate"]; // If the unit died the loop is finished diff --git a/addons/medical/functions/fnc_modifyMedicalAction.sqf b/addons/medical/functions/fnc_modifyMedicalAction.sqf index 4d0db7af34..16ea718d72 100644 --- a/addons/medical/functions/fnc_modifyMedicalAction.sqf +++ b/addons/medical/functions/fnc_modifyMedicalAction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Modify the visuals of a medical action point. @@ -9,14 +10,15 @@ * 2: Selection Number * 3: The action to modify * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, kevin, 2, "action"] call ACE_medical_fnc_modifyMedicalAction + * * Public: No */ -#include "script_component.hpp" - params ["_target", "_player", "_partNumber", "_actionData"]; private _bloodLossOnSelection = 0; diff --git a/addons/medical/functions/fnc_moduleAdvancedMedicalSettings.sqf b/addons/medical/functions/fnc_moduleAdvancedMedicalSettings.sqf index b54196d75f..e19f670b3a 100644 --- a/addons/medical/functions/fnc_moduleAdvancedMedicalSettings.sqf +++ b/addons/medical/functions/fnc_moduleAdvancedMedicalSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Module for adjusting the medical treatment settings @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ACE_medical_fnc_moduleAdvancedMedicalSettings + * * Public: No */ -#include "script_component.hpp" - params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/medical/functions/fnc_moduleAssignMedicRoles.sqf b/addons/medical/functions/fnc_moduleAssignMedicRoles.sqf index 5bdaccff93..d65afdf7cb 100644 --- a/addons/medical/functions/fnc_moduleAssignMedicRoles.sqf +++ b/addons/medical/functions/fnc_moduleAssignMedicRoles.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Assign a medical role to a unit. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ACE_medical_fnc_moduleAssignMedicRoles + * * Public: No */ -#include "script_component.hpp" params ["_logic"]; diff --git a/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf b/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf index 368b065908..a1b6303b45 100644 --- a/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf +++ b/addons/medical/functions/fnc_moduleAssignMedicalFacility.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Register synchronized objects from passed object as a medical facility @@ -10,16 +11,16 @@ * Return Value: * None * + * Example: + * [LOGIC, [kevin, bob], true] call ACE_medical_fnc_moduleAssignMedicalFacility + * * Public: No */ -#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_moduleAssignMedicalVehicle.sqf b/addons/medical/functions/fnc_moduleAssignMedicalVehicle.sqf index 60a46f8420..3eda8f0106 100644 --- a/addons/medical/functions/fnc_moduleAssignMedicalVehicle.sqf +++ b/addons/medical/functions/fnc_moduleAssignMedicalVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Assign vehicle as a medical vehicle. @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ACE_medical_fnc_moduleAssignMedicalVehicle + * * Public: No */ -#include "script_component.hpp" params ["_logic"]; diff --git a/addons/medical/functions/fnc_moduleBasicMedicalSettings.sqf b/addons/medical/functions/fnc_moduleBasicMedicalSettings.sqf index 08076878f2..6d27cfe803 100644 --- a/addons/medical/functions/fnc_moduleBasicMedicalSettings.sqf +++ b/addons/medical/functions/fnc_moduleBasicMedicalSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Module for adjusting the medical treatment settings @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [Logic, [bob, kevin], true] call ACE_medical_fnc_moduleBasicMedicalSettings + * * Public: No */ -#include "script_component.hpp" - params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/medical/functions/fnc_moduleMedicalSettings.sqf b/addons/medical/functions/fnc_moduleMedicalSettings.sqf index 29398bbc35..a843d8c1c1 100644 --- a/addons/medical/functions/fnc_moduleMedicalSettings.sqf +++ b/addons/medical/functions/fnc_moduleMedicalSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Module for adjusting the medical damage settings @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ACE_medical_fnc_moduleMedicalSettings + * * Public: No */ -#include "script_component.hpp" - params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/medical/functions/fnc_moduleReviveSettings.sqf b/addons/medical/functions/fnc_moduleReviveSettings.sqf index 19aa9579dd..d7f54583cf 100644 --- a/addons/medical/functions/fnc_moduleReviveSettings.sqf +++ b/addons/medical/functions/fnc_moduleReviveSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Module for adjusting the medical revive settings @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ACE_medical_fnc_moduleReviveSettings + * * Public: No */ -#include "script_component.hpp" - params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/medical/functions/fnc_onMedicationUsage.sqf b/addons/medical/functions/fnc_onMedicationUsage.sqf index 019abd094c..ee45d60a39 100644 --- a/addons/medical/functions/fnc_onMedicationUsage.sqf +++ b/addons/medical/functions/fnc_onMedicationUsage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handles the medication given to a patient. @@ -13,11 +14,12 @@ * Return Value: * None * + * Example: + * [bob, "classname", "varname", 5, 6, ["stuff"]] call ACE_medical_fnc_onMedicationUsage + * * Public: No */ -#include "script_component.hpp" - params ["_target", "_className", "_variable", "_maxDosage", "_timeInSystem", "_incompatabileMeds", "_viscosityChange", "_painReduce"]; TRACE_8("params",_target,_className,_variable,_maxDosage,_timeInSystem,_incompatabileMeds,_viscosityChange,_painReduce); diff --git a/addons/medical/functions/fnc_parseConfigForInjuries.sqf b/addons/medical/functions/fnc_parseConfigForInjuries.sqf index 42dd98dc1f..c94a4f898f 100644 --- a/addons/medical/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical/functions/fnc_parseConfigForInjuries.sqf @@ -1,24 +1,26 @@ +#include "script_component.hpp" /* * Author: Glowbal * Parse the ACE_Medical_Advanced config for all injury types. * * Arguments: * None - * ReturnValue: + * + * Return Value: * None * + * Example: + * call ACE_medical_fnc_parseConfigForInjuries + * * Public: No */ -#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 @@ -26,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 @@ -41,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]; @@ -64,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 @@ -97,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); @@ -139,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; @@ -153,7 +153,7 @@ _selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific"); }; } forEach _selections; - _causes = ""; + private _causes = ""; { _causes = _causes + _x; diff --git a/addons/medical/functions/fnc_playInjuredSound.sqf b/addons/medical/functions/fnc_playInjuredSound.sqf index 2e5ec2ab5f..6955886659 100644 --- a/addons/medical/functions/fnc_playInjuredSound.sqf +++ b/addons/medical/functions/fnc_playInjuredSound.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Play the injured sound for a unit if the unit is damaged. The sound broadcasted across MP. @@ -8,14 +9,15 @@ * 0: The Unit * 1: Amount of Pain * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, 5] call ACE_medical_fnc_playInjuredSound + * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_pain"]; if (!local _unit || !GVAR(enableScreams)) exitWith{}; diff --git a/addons/medical/functions/fnc_reviveStateLoop.sqf b/addons/medical/functions/fnc_reviveStateLoop.sqf index 5dcaad09c4..7e662bdbb1 100644 --- a/addons/medical/functions/fnc_reviveStateLoop.sqf +++ b/addons/medical/functions/fnc_reviveStateLoop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, esteldunedain * Loop that handles a unit in the revive state. @@ -5,14 +6,15 @@ * Arguments: * 0: Unit * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob] call ACE_medical_fnc_reviveStateLoop + * * Public: No */ -#include "script_component.hpp" - params ["_unit"]; // If locality changed finish the local loop diff --git a/addons/medical/functions/fnc_selectionNameToNumber.sqf b/addons/medical/functions/fnc_selectionNameToNumber.sqf index 1e8d79183f..c5c0ceb2ed 100644 --- a/addons/medical/functions/fnc_selectionNameToNumber.sqf +++ b/addons/medical/functions/fnc_selectionNameToNumber.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the number representation of a selection name. @@ -5,12 +6,13 @@ * Arguments: * 0: The selection name of a unit * - * ReturnValue: + * Return Value: * Number representation. -1 if invalid. * + * Example: + * ["head"] call ace_medical_fnc_selectionNameToNumber + * * Public: yes */ -#include "script_component.hpp" - (["head","body","hand_l","hand_r","leg_l","leg_r"] find (_this select 0)); diff --git a/addons/medical/functions/fnc_serverRemoveBody.sqf b/addons/medical/functions/fnc_serverRemoveBody.sqf index f68ffd95cd..3b85fb06a3 100644 --- a/addons/medical/functions/fnc_serverRemoveBody.sqf +++ b/addons/medical/functions/fnc_serverRemoveBody.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Removes corpse. Idealy it is just deleted the next frame, @@ -7,7 +8,7 @@ * 0: Mr Body * * Return Value: - * Nothing + * None * * Example: * [cursorTarget] call ace_medical_fnc_serverRemoveBody @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_target"]; TRACE_2("",_target,isPlayer _target); diff --git a/addons/medical/functions/fnc_setCardiacArrest.sqf b/addons/medical/functions/fnc_setCardiacArrest.sqf index 69bda192dd..a8676c7342 100644 --- a/addons/medical/functions/fnc_setCardiacArrest.sqf +++ b/addons/medical/functions/fnc_setCardiacArrest.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Triggers a unit into the Cardiac Arrest state from CMS. Will put the unit in an unconscious state and run a countdown timer until unit dies. @@ -6,14 +7,15 @@ * Arguments: * 0: The unit that will be put in cardiac arrest state * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob] call ace_medical_fnc_setCardiacArrest + * * Public: yes */ -#include "script_component.hpp" - params ["_unit"]; if (_unit getVariable [QGVAR(inCardiacArrest),false]) exitWith {}; diff --git a/addons/medical/functions/fnc_setDead.sqf b/addons/medical/functions/fnc_setDead.sqf index 0e5fd884f4..ce15a0b548 100644 --- a/addons/medical/functions/fnc_setDead.sqf +++ b/addons/medical/functions/fnc_setDead.sqf @@ -1,21 +1,22 @@ +#include "script_component.hpp" /* * Author: Glowbal * Either kills a unit or puts the unit in a revivable state, depending on the settings. * * Arguments: * 0: The unit that will be killed - * 1: Force Dead (ignore revive setting) - * 1: Delay setDamage for a frame + * 1: Force Dead (ignore revive setting) (default: false) + * 1: Delay setDamage for a frame (default: false) * - * ReturnValue: + * Return Value: * Did he died? * + * Example: + * [bob, false, false] call ace_medical_fnc_setDead + * * Public: yes */ -#include "script_component.hpp" - -private ["_reviveVal", "_lifesLeft"]; params ["_unit", ["_force", false], ["_delaySetDamage", false]]; if ((!alive _unit) || {_unit getVariable ["ACE_isDead", false]}) exitWith {true}; @@ -24,12 +25,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 b1dfe59d29..c68feb83c8 100644 --- a/addons/medical/functions/fnc_setHitPointDamage.sqf +++ b/addons/medical/functions/fnc_setHitPointDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * My very own setHitPointDamage since BIS' one is buggy when affecting a remote unit. @@ -12,16 +13,16 @@ * Return Value: * None * + * Example: + * [medic, "Leg", 2, false] call ace_medical_fnc_setHitPointDamage + * * Public: Yes */ - -#include "script_component.hpp" #define LEGDAMAGETRESHOLD1 1 #define LEGDAMAGETRESHOLD2 1.7 #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. @@ -34,7 +35,7 @@ if (_disabled) exitWith { _unit setHitPointDamage [_selection, _damage]; }; -_selections = [ +private _selections = [ "HitHead", "HitBody", "HitLeftArm", @@ -47,10 +48,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; @@ -58,12 +59,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); }; @@ -77,12 +78,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 { @@ -92,7 +93,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_setStructuralDamage.sqf b/addons/medical/functions/fnc_setStructuralDamage.sqf index ba30b08153..4f8c6e2613 100644 --- a/addons/medical/functions/fnc_setStructuralDamage.sqf +++ b/addons/medical/functions/fnc_setStructuralDamage.sqf @@ -5,8 +5,11 @@ * Arguments: * 0: The unit * - * ReturnValue: - * + * Return Value: + * None + * + * Example: + * [bob] call ACE_medical_fnc_setStructuralDamage * * Public: no? */ diff --git a/addons/medical/functions/fnc_setUnconscious.sqf b/addons/medical/functions/fnc_setUnconscious.sqf index 5bee0967ba..c2e43e702d 100644 --- a/addons/medical/functions/fnc_setUnconscious.sqf +++ b/addons/medical/functions/fnc_setUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Sets a unit in the unconscious state. @@ -8,8 +9,8 @@ * 2: Minimum unconscious time (default: (round(random(10)+5))) * 3: Force AI Unconscious (skip random death chance) (default: false) * - * ReturnValue: - * nil + * Return Value: + * None * * Example: * [bob, true] call ace_medical_fnc_setUnconscious; @@ -17,8 +18,6 @@ * Public: yes */ -#include "script_component.hpp" - #define DEFAULT_DELAY (round(random(10)+5)) // only run this after the settings are initialized @@ -26,7 +25,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 +53,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; @@ -77,7 +75,10 @@ if (vehicle _unit == _unit) then { if (primaryWeapon _unit == "") then { _unit addWeapon "ACE_FakePrimaryWeapon"; }; - _unit selectWeapon (primaryWeapon _unit); + + if (currentWeapon _unit != primaryWeapon _unit) then { + _unit selectWeapon primaryWeapon _unit; + }; }; // We are storing the current animation, so we can use it later on when waking the unit up inside a vehicle @@ -86,7 +87,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 +99,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 +122,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 8ed77714cb..47abf0536c 100644 --- a/addons/medical/functions/fnc_showBloodEffect.sqf +++ b/addons/medical/functions/fnc_showBloodEffect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Does the blood screen effect, just like BIS_fnc_bloodeffect, but in non-sheduled environment. @@ -8,19 +9,23 @@ * Return Value: * None * + * Example: + * [2] call ace_medical_fnc_showBloodEffect + * * Public: Yes */ -#include "script_component.hpp" 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_translateSelections.sqf b/addons/medical/functions/fnc_translateSelections.sqf index e6624507d1..3990429e91 100644 --- a/addons/medical/functions/fnc_translateSelections.sqf +++ b/addons/medical/functions/fnc_translateSelections.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Translate selection names into medical usable hit selection names. @@ -20,7 +21,6 @@ * * Public: No */ -#include "script_component.hpp" #define HEAD_SELECTIONS ["face_hub", "neck", "head"] #define HEAD_HITPOINTS ["hitface", "hitneck", "hithead"] diff --git a/addons/medical/functions/fnc_treatment.sqf b/addons/medical/functions/fnc_treatment.sqf index 453d074f98..0ed4694c2f 100644 --- a/addons/medical/functions/fnc_treatment.sqf +++ b/addons/medical/functions/fnc_treatment.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Starts the treatment process @@ -11,11 +12,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [medic, patient, "SelectionName","bandage"] call ace_medical_fnc_treatment + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName", "_className"]; // If the cursorMenu is open, the loading bar will fail. If we execute the function one frame later, it will work fine @@ -173,21 +175,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 @@ -217,7 +222,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_treatmentAdvanced_CPR.sqf b/addons/medical/functions/fnc_treatmentAdvanced_CPR.sqf index 0ce1f7d4d9..5c673c080a 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_CPR.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_CPR.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Callback for the CPR treatment action on success. @@ -11,11 +12,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [medic, patient, "selectionName", "bandage"] call ace_medical_fnc_treatmentAdvanced_CPR + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName", "_className", "_items"]; if (alive _target && {(_target getVariable [QGVAR(inCardiacArrest), false] || _target getVariable [QGVAR(inReviveState), false])}) then { diff --git a/addons/medical/functions/fnc_treatmentAdvanced_CPRLocal.sqf b/addons/medical/functions/fnc_treatmentAdvanced_CPRLocal.sqf index fbc7aac601..9659ee7481 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_CPRLocal.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_CPRLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * local Callback for the CPR treatment action on success. @@ -9,11 +10,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [medic, patient] call ace_medical_fnc_treatmentAdvanced_CPRLocal + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller","_target"]; if (_target getVariable [QGVAR(inReviveState), false]) then { diff --git a/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf b/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf index 0db3e641b3..9cb4ac423b 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * IV Treatment callback @@ -13,11 +14,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [medic, patient, "Selectionname", "bandage", "bandage", -1] call ace_medical_fnc_treatmentAdvanced_bandage + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName", "_className", "_items", "", ["_specificSpot", -1]]; [_target, "activity", LSTRING(Activity_bandagedPatient), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); diff --git a/addons/medical/functions/fnc_treatmentAdvanced_bandageLocal.sqf b/addons/medical/functions/fnc_treatmentAdvanced_bandageLocal.sqf index d7d19d6e53..ba94eb2d01 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_bandageLocal.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_bandageLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handles the bandage of a patient. @@ -10,11 +11,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [bob, "classname"] call ACE_medical_fnc_treatmentAdvanced_bandageLocal + * * Public: No */ -#include "script_component.hpp" - params ["_target", "_bandage", "_selectionName", ["_specificClass", -1]]; // Ensure it is a valid bodypart @@ -59,7 +61,7 @@ private _exit = false; } else { //Basic medical bandage just has a base level config (same effectivenes for all wound types) if (_bandage != "Bandage") then { - ACE_LOGWARNING_2("No config for wound type [%1] config base [%2]", _className, _config); + WARNING_2("No config for wound type [%1] config base [%2]", _className, _config); }; }; diff --git a/addons/medical/functions/fnc_treatmentAdvanced_fullHeal.sqf b/addons/medical/functions/fnc_treatmentAdvanced_fullHeal.sqf index 18bd0468d2..d5c6427aa8 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_fullHeal.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_fullHeal.sqf @@ -1,14 +1,23 @@ -/** - * fn_heal.sqf - * @Descr: N/A - * @Author: Glowbal - * - * @Arguments: [] - * @Return: - * @PublicAPI: false - */ - #include "script_component.hpp" +/* + * Author: Glowbal + * + * + * Arguments: + * 0: Caller + * 1: Target + * 2: SelectionName + * 3: ClassName + * 4: Item + * + * Return Value: + * Boolean + * + * Example: + * [bob, kevin, "selection", "classname", ] call ACE_medical_fnc_treatmentAdvanced_fullHeal + * + * Public: No + */ params ["_caller", "_target", "_selectionName", "_className", "_items"]; diff --git a/addons/medical/functions/fnc_treatmentAdvanced_fullHealLocal.sqf b/addons/medical/functions/fnc_treatmentAdvanced_fullHealLocal.sqf index 7517f235e7..d2435e0ee0 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_fullHealLocal.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_fullHealLocal.sqf @@ -1,14 +1,20 @@ -/** - * fn_healLocal.sqf - * @Descr: N/A - * @Author: Glowbal - * - * @Arguments: [] - * @Return: - * @PublicAPI: false - */ - #include "script_component.hpp" +/* + * Author: Glowbal + * + * + * Arguments: + * 0: Caller + * 1: Target + * + * Return Value: + * Boolean + * + * Example: + * [bob, kevin] call ACE_medical_fnc_treatmentAdvanced_fullHealLocal + * + * Public: No + */ params ["_caller", "_target"]; @@ -47,7 +53,6 @@ if (alive _target) exitWith { _target setVariable [QGVAR(airwayCollapsed), false, true]; // generic medical admin - _target setVariable [QGVAR(addedToUnitLoop), false, true]; _target setVariable [QGVAR(inCardiacArrest), false, true]; _target setVariable [QGVAR(inReviveState), false, true]; _target setVariable ["ACE_isUnconscious", false, true]; diff --git a/addons/medical/functions/fnc_treatmentAdvanced_fullHealTreatmentTime.sqf b/addons/medical/functions/fnc_treatmentAdvanced_fullHealTreatmentTime.sqf index b2b222e601..35c9c5133f 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_fullHealTreatmentTime.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_fullHealTreatmentTime.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the personal aid kit treatment time based on amount of damage to heal @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" private _totalDamage = 0; diff --git a/addons/medical/functions/fnc_treatmentAdvanced_medication.sqf b/addons/medical/functions/fnc_treatmentAdvanced_medication.sqf index ceb788f571..b48e2bb2da 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_medication.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_medication.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * IV Treatment callback @@ -12,11 +13,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [medic, patient, "selectionName", "bandage", 2] call ace_medical_fnc_treatmentAdvanced_medication + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName", "_className", "_items"]; TRACE_5("params",_caller,_target,_selectionName,_className,_items); diff --git a/addons/medical/functions/fnc_treatmentAdvanced_medicationLocal.sqf b/addons/medical/functions/fnc_treatmentAdvanced_medicationLocal.sqf index 46a8b9c2a8..4435ae4f48 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_medicationLocal.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_medicationLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handles the medication given to a patient. @@ -10,11 +11,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [medic, "bandage", 2] call ace_medical_fnc_treatmentAdvanced_medicationLocal + * * Public: Yes */ -#include "script_component.hpp" - params ["_target", "_className", "_partNumber"]; TRACE_3("params",_target,_className,_partNumber); diff --git a/addons/medical/functions/fnc_treatmentAdvanced_surgicalKit_onProgress.sqf b/addons/medical/functions/fnc_treatmentAdvanced_surgicalKit_onProgress.sqf index 0a1e48288f..7f7cb481aa 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_surgicalKit_onProgress.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_surgicalKit_onProgress.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Handles treatment via surgical kit per frame @@ -12,9 +13,11 @@ * Return Value: * Succesful treatment started * + * Example: + * [[bob, kevin], 5, 5] call ACE_medical_fnc_treatmentAdvanced_surgicalKit_onProgress + * * Public: No */ -#include "script_component.hpp" params ["_args", "_elapsedTime", "_totalTime"]; _args params ["_caller", "_target"]; diff --git a/addons/medical/functions/fnc_treatmentBasic_bloodbag.sqf b/addons/medical/functions/fnc_treatmentBasic_bloodbag.sqf index 6989ac14b8..297e5a5e43 100644 --- a/addons/medical/functions/fnc_treatmentBasic_bloodbag.sqf +++ b/addons/medical/functions/fnc_treatmentBasic_bloodbag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Callback when the bloodbag treatment is complete @@ -11,11 +12,12 @@ * Return Value: * None * + * Example: + * [bob, kevin, "selection", "classname"] call ACE_medical_fnc_treatmentBasic_bloodbag + * * Public: No */ -#include "script_component.hpp" - params ["_caller", "_target", "_treatmentClassname"]; if (local _target) then { diff --git a/addons/medical/functions/fnc_treatmentBasic_bloodbagLocal.sqf b/addons/medical/functions/fnc_treatmentBasic_bloodbagLocal.sqf index cb4dcf032c..91626095b5 100644 --- a/addons/medical/functions/fnc_treatmentBasic_bloodbagLocal.sqf +++ b/addons/medical/functions/fnc_treatmentBasic_bloodbagLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Local callback when the bloodbag treatment is complete @@ -7,12 +8,13 @@ * 1: Treatment Classname * * Return Value: - * nil + * None + * + * Example: + * [bob, "classname"] call ACE_medical_fnc_treatmentBasic_bloodbagLocal * * Public: No */ - -#include "script_component.hpp" #define BLOODBAGHEAL 70 params ["_target", "_treatmentClassname"]; diff --git a/addons/medical/functions/fnc_treatmentBasic_epipen.sqf b/addons/medical/functions/fnc_treatmentBasic_epipen.sqf index 1abee1cd58..4e67cfe697 100644 --- a/addons/medical/functions/fnc_treatmentBasic_epipen.sqf +++ b/addons/medical/functions/fnc_treatmentBasic_epipen.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Callback when the epipen treatment is complete @@ -11,9 +12,11 @@ * Return Value: * None * + * Example: + * [bob, kevin, "selection", "classname"] call ACE_medical_fnc_treatmentBasic_epipen + * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target","_className"]; diff --git a/addons/medical/functions/fnc_treatmentBasic_morphine.sqf b/addons/medical/functions/fnc_treatmentBasic_morphine.sqf index f704a67042..dbfbecab7f 100644 --- a/addons/medical/functions/fnc_treatmentBasic_morphine.sqf +++ b/addons/medical/functions/fnc_treatmentBasic_morphine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Callback when the morphine treatment is complete @@ -11,10 +12,11 @@ * Return Value: * None * + * Example: + * [bob, kevin, "selection", "classname"] call ACE_medical_fnc_treatmentBasic_morphine + * * Public: No */ - -#include "script_component.hpp" #define MORPHINEHEAL 0.4 params ["_caller", "_target"]; diff --git a/addons/medical/functions/fnc_treatmentBasic_morphineLocal.sqf b/addons/medical/functions/fnc_treatmentBasic_morphineLocal.sqf index bb670c75bd..2a2c4358d5 100644 --- a/addons/medical/functions/fnc_treatmentBasic_morphineLocal.sqf +++ b/addons/medical/functions/fnc_treatmentBasic_morphineLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Local callback when the morphine treatment is complete @@ -9,10 +10,11 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ACE_medical_fnc_treatmentBasic_morphineLocal + * * Public: No */ - -#include "script_component.hpp" #define MORPHINEHEAL 0.4 params ["_target"]; diff --git a/addons/medical/functions/fnc_treatmentIV.sqf b/addons/medical/functions/fnc_treatmentIV.sqf index 7b16fad650..8da7a3bcf6 100644 --- a/addons/medical/functions/fnc_treatmentIV.sqf +++ b/addons/medical/functions/fnc_treatmentIV.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Patient IV Treatment callback @@ -11,11 +12,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [medic, patient, "SelectionName", "bandage"] call ace_medical_fnc_treatmentIV + * * Public: Yes */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName", "_className", "_items"]; if (_items isEqualTo []) exitWith {false}; diff --git a/addons/medical/functions/fnc_treatmentIVLocal.sqf b/addons/medical/functions/fnc_treatmentIVLocal.sqf index 1324d5aac2..1f59edbc35 100644 --- a/addons/medical/functions/fnc_treatmentIVLocal.sqf +++ b/addons/medical/functions/fnc_treatmentIVLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * IV Treatment local callback @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [medic, "Classname"] call ace_medical_fnc_treatmentIVLocal + * * Public: Yes */ -#include "script_component.hpp" - params ["_target", "_treatmentClassname"]; private _bloodVolume = _target getVariable [QGVAR(bloodVolume), 100]; diff --git a/addons/medical/functions/fnc_treatmentTourniquet.sqf b/addons/medical/functions/fnc_treatmentTourniquet.sqf index 3fa34a58aa..23de5f177a 100644 --- a/addons/medical/functions/fnc_treatmentTourniquet.sqf +++ b/addons/medical/functions/fnc_treatmentTourniquet.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Apply a tourniquet to the patient @@ -12,11 +13,12 @@ * Return Value: * Succesful treatment started * + * Example: + * [bob, kevin, "selection", "classname"] call ACE_medical_fnc_treatmentTourniquet + * * Public: No */ -#include "script_component.hpp" - params ["_caller", "_target", "_selectionName", "_className", "_items"]; if (count _items == 0) exitWith {false}; diff --git a/addons/medical/functions/fnc_treatmentTourniquetLocal.sqf b/addons/medical/functions/fnc_treatmentTourniquetLocal.sqf index ab24a94a23..dc05d6ce5f 100644 --- a/addons/medical/functions/fnc_treatmentTourniquetLocal.sqf +++ b/addons/medical/functions/fnc_treatmentTourniquetLocal.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Apply a tourniquet to the patient, local callback. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, "classname"] call ACE_medical_fnc_treatmentTourniquetLocal + * * Public: No */ -#include "script_component.hpp" params ["_target", "_tourniquetItem", "_selectionName"]; diff --git a/addons/medical/functions/fnc_treatment_failure.sqf b/addons/medical/functions/fnc_treatment_failure.sqf index d81c576feb..02d3153271 100644 --- a/addons/medical/functions/fnc_treatment_failure.sqf +++ b/addons/medical/functions/fnc_treatment_failure.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Callback when the treatment fails @@ -12,18 +13,19 @@ * Return Value: * None * + * Example: + * [bob, kevin, "selectionname", "classname", ["bandage"]] call ACE_medical_fnc_treatment_failure + * * Public: No */ -#include "script_component.hpp" - params ["_args"]; _args params ["_caller", "_target", "_selectionName", "_className", "_items", "_usersOfItems"]; 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); @@ -34,21 +36,20 @@ 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]; private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnTreatment), []]); if ((_weaponSelect params [["_previousWeapon", ""]]) && {(_previousWeapon != "") && {_previousWeapon in (weapons _caller)}}) then { - for "_index" from 0 to 99 do { + for "_index" from 0 to 299 do { _caller action ["SwitchWeapon", _caller, _caller, _index]; //Just check weapon, muzzle and mode (ignore ammo in case they were reloading) if (((weaponState _caller) select [0,3]) isEqualTo (_weaponSelect select [0,3])) exitWith {TRACE_1("Restoring", (weaponState _caller));}; if ((weaponState _caller) isEqualTo ["","","","",0]) exitWith {ERROR("weaponState not found");}; }; } else { - _caller action ["SwitchWeapon", _caller, _caller, 99]; + _caller action ["SwitchWeapon", _caller, _caller, 299]; }; { diff --git a/addons/medical/functions/fnc_treatment_success.sqf b/addons/medical/functions/fnc_treatment_success.sqf index eb52d20e3c..17c9de62ba 100644 --- a/addons/medical/functions/fnc_treatment_success.sqf +++ b/addons/medical/functions/fnc_treatment_success.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Callback when the treatment is completed @@ -12,18 +13,19 @@ * Return Value: * None * + * Example: + * [bob, kevin, "selectionname", "classname", ["bandage"]] call ACE_medical_fnc_treatment_success + * * Public: No */ -#include "script_component.hpp" - params ["_args"]; _args params ["_caller", "_target", "_selectionName", "_className", "_items", "_usersOfItems"]; 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); @@ -34,21 +36,20 @@ 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]; private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnTreatment), []]); if ((_weaponSelect params [["_previousWeapon", ""]]) && {(_previousWeapon != "") && {_previousWeapon in (weapons _caller)}}) then { - for "_index" from 0 to 99 do { + for "_index" from 0 to 299 do { _caller action ["SwitchWeapon", _caller, _caller, _index]; //Just check weapon, muzzle and mode (ignore ammo in case they were reloading) if (((weaponState _caller) select [0,3]) isEqualTo (_weaponSelect select [0,3])) exitWith {TRACE_1("Restoring", (weaponState _caller));}; if ((weaponState _caller) isEqualTo ["","","","",0]) exitWith {ERROR("weaponState not found");}; }; } else { - _caller action ["SwitchWeapon", _caller, _caller, 99]; + _caller action ["SwitchWeapon", _caller, _caller, 299]; }; // Record specific callback diff --git a/addons/medical/functions/fnc_unconsciousPFH.sqf b/addons/medical/functions/fnc_unconsciousPFH.sqf index 37d54a2ad6..31f4d60d4b 100644 --- a/addons/medical/functions/fnc_unconsciousPFH.sqf +++ b/addons/medical/functions/fnc_unconsciousPFH.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: Glowbal * PFH logic for unconscious state * * Arguments: - * 0: PFEH - Args + * 0: PFEH - * 0: The unit that will be put in an unconscious state * 1: unitPos (stance) * 2: Starting Time @@ -12,14 +13,15 @@ * 5: Parachute Check * 1: PFEH ID * - * ReturnValue: + * Return Value: * None * + * Example: + * [[unit,"pos", 5, 5, true, false], 5], "classname"] call ace_medical_fnc_unconsciousPFH + * * Public: yes */ -#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"]; @@ -33,7 +35,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; @@ -48,6 +50,12 @@ if (!alive _unit) exitWith { // In case the unit is no longer in an unconscious state, we are going to check if we can already reset the animation if !(_unit getVariable ["ACE_isUnconscious",false]) exitWith { TRACE_7("ACE_DEBUG_Unconscious_PFH",_unit, _args, [_unit] call FUNC(isBeingCarried), [_unit] call FUNC(isBeingDragged), _idPFH, _unit getVariable QGVAR(unconsciousArguments),animationState _unit); + + //Unmute the unit before the carry check + _unit setVariable ["tf_voiceVolume", 1, true]; + _unit setVariable ["tf_unable_to_use_radio", false, true]; + _unit setVariable ["acre_sys_core_isDisabled", false, true]; + // TODO, handle this with carry instead, so we can remove the PFH here. // Wait until the unit isn't being carried anymore, so we won't end up with wierd animations if !(([_unit] call FUNC(isBeingCarried)) || ([_unit] call FUNC(isBeingDragged))) then { @@ -64,9 +72,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; }; @@ -76,7 +84,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: @@ -101,7 +109,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/functions/fnc_useItem.sqf b/addons/medical/functions/fnc_useItem.sqf index 63b3f2a696..49efceac05 100644 --- a/addons/medical/functions/fnc_useItem.sqf +++ b/addons/medical/functions/fnc_useItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Use Equipment if any is available. Priority: 1) Medic, 2) Patient. If in vehicle: 3) Crew @@ -7,15 +8,16 @@ * 1: Patient * 2: Item * - * ReturnValue: + * Return Value: * 0: success * 1: Unit * + * Example: + * [unit, patient, "bandage"] call ace_repair_fnc_useItem + * * Public: Yes */ -#include "script_component.hpp" - params ["_medic", "_patient", "_item"]; if (isNil QGVAR(setting_allowSharedEquipment)) then { diff --git a/addons/medical/functions/fnc_useItems.sqf b/addons/medical/functions/fnc_useItems.sqf index aac7b0623a..ef3dc78ab3 100644 --- a/addons/medical/functions/fnc_useItems.sqf +++ b/addons/medical/functions/fnc_useItems.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Use Equipment items if any is available. Priority: 1) Medic, 2) Patient. If in vehicle: 3) Crew @@ -7,14 +8,15 @@ * 1: Patient * 2: Items > * - * ReturnValue: + * Return Value: * None * + * Example: + * [unit, patient, ["bandage"]] call ace_medical_fnc_useItems + * * Public: Yes */ -#include "script_component.hpp" - params ["_medic", "_patient", "_items"]; private _itemsUsedBy = []; diff --git a/addons/medical/functions/fnc_vitalLoop.sqf b/addons/medical/functions/fnc_vitalLoop.sqf index 6e5bb7fb2b..44cd1e4d17 100644 --- a/addons/medical/functions/fnc_vitalLoop.sqf +++ b/addons/medical/functions/fnc_vitalLoop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, esteldunedain * Vital loop for a unit. @@ -6,14 +7,15 @@ * 0: The Unit * 1: Time of last computation * - * ReturnValue: + * Return Value: * None * + * Example: + * [bob, 5] call ACE_medical_fnc_vitalLoop + * * Public: No */ -#include "script_component.hpp" - params ["_unit", "_lastTime"]; // If the unit died the loop is finished diff --git a/addons/medical/script_component.hpp b/addons/medical/script_component.hpp index bb0db0cd74..5735f940f4 100644 --- a/addons/medical/script_component.hpp +++ b/addons/medical/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MEDICAL diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index 8c639ccd86..afbdc7ebdc 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -1,10 +1,10 @@ - + INJURIES VERLETZUNGEN - LESIONI + FERITE ТРАВМЫ BLESSURES OBRAŻENIA @@ -12,18 +12,26 @@ SÉRÜLÉSEK ZRANĚNÍ FERIMENTOS + 負傷 + 부상 + 受伤 + 受傷 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 blessures sur cette partie du corps... + Aucune blessure ici... Brak obrażeń na tej części ciała... Sin heridas en esta parte del cuerpo... Ezen a testrészen nincs sérülés... Žádné zranění na této části těla... Nenhum ferimento nesta parte do corpo... + この身体は怪我をしていません・・・ + 이 부위에는 부상이 없습니다... + 此身体部位没有受伤 + 此身體部位沒有受傷 Litter Simulation Detail @@ -36,6 +44,10 @@ 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 + 医療廃棄物シミュレーション詳細度 + 의료폐기물 재현 상세도 + 模拟医疗废弃物细节 + 醫療廢棄物模擬細節 Litter simulation detail level sets the number of litter items which will be locally spawned in the client. Excessive amounts in local areas could cause FPS lag, so this is a client only setting. @@ -48,17 +60,25 @@ 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 Adenosin injizieren Inyectar Adenosina Wstrzyknij adenozynę - Injecter de l'adénosine + Adénosine Inietta andenosina Aplikovat adenosine - Injetar Adenosina + Injetar adenosina Ввести аденозин + アデノシンを投与 + 아데노신 주사 + 注射腺苷 + 注射腺苷 Inject Atropine @@ -66,11 +86,15 @@ Inyectar Atropina Aplikovat atropin Wstrzyknij atropinę - Injecter de l'atropine + Atropine Ввести атропин Atropin beadása Inietta atropina - Injetar Atropina + Injetar atropina + アトロピンを投与 + 아트로핀 주사 + 注射阿托品 + 注射阿托品 Inject Epinephrine @@ -78,11 +102,15 @@ Inyectar Epinefrina Wstrzyknij adrenalinę Aplikovat adrenalin - Injecter épinéphrine + Épinéphrine Ввести адреналин Epinefrin beadása - Injetar Epinefrina + Injetar epinefrina Inietta adrenalina + アドレナリンを投与 + 에피네프린 주사 + 注射肾上腺素 + 注射腎上腺素 Inject Morphine @@ -91,10 +119,14 @@ Wstrzyknij morfinę Aplikovat morfin Ввести морфин - Injecter morphine + Morphine Morfium beadása - Injetar Morfina + Injetar morfina Inietta morfina + モルヒネを投与 + 모르핀 주사 + 注射吗啡 + 注射嗎啡 Transfuse Blood @@ -103,10 +135,14 @@ Przetocz krew Transfúze krve Перелить кровь - Transfuser du sang + Transfuser (sang) Infúzió (vér) - Transfundir Sangue + Transfundir sangue Trasfusione di sangue + 輸血する + 혈액 수혈 + 输血液 + 輸血液 Transfuse Plasma @@ -114,11 +150,15 @@ Transfundir plasma Transfúze plazmy Przetocz osocze - Transfuser du Plasma + Transfuser (plasma) Перелить плазму Infúzió (vérplazma) Trasfusione di plasma - Transfundir Plasma + Transfundir plasma + 血しょうを投与 + 혈장 수혈 + 输血浆 + 輸血漿 Transfuse Saline @@ -126,11 +166,15 @@ Transfundir salino Transfúze fyziologického roztoku Przetocz sól fizjologiczną - Transfuser de la solution saline + Transfuser (saline) Перелить физраствор Infúzió (sós víz) Trasfusione di soluzione salina - Transfundir Soro + Transfundir soro + 生理食塩水を投与 + 생리식염수 수혈 + 注射生理食盐水 + 注射生理食鹽水 Apply Tourniquet @@ -138,11 +182,15 @@ Aplicar torniquete Aplikovat škrtidlo Załóż stazę - Appliquer un garrot + Poser garrot Наложить жгут Applica laccio emostatico - Aplicar Torniquete + Aplicar torniquete Érszorító alkalmazása + 止血帯を巻く + 지혈대 적용 + 使用军用止血带 + 使用軍用止血帶 Bandage @@ -155,6 +203,10 @@ Kötözés Atadura Перевязать + 包帯 + 붕대 + 绷带 + 繃帶 Bandage Head @@ -165,8 +217,12 @@ Перевязать голову Panser Tête Fej kötözése - Atar Cabeça + Atar cabeça Benda la testa + 包帯を頭へ + 머리에 붕대감기 + 绷带包扎 头部 + 繃帶包紮 頭部 Bandage Torso @@ -177,8 +233,12 @@ Перевязать торс Panser Torse Testtörzs kötözése - Atar Tronco + Atar tronco Benda il torso + 包帯を胴体へ + 몸통에 붕대감기 + 绷带包扎 身体 + 繃帶包紮 身體 Bandage Left Arm @@ -189,8 +249,12 @@ Перевязать левую руку Panser Bras Gauche Bal kar kötözése - Atar Braço Esquerdo + Atar braço esquerdo Benda il braccio sinistro + 包帯を左腕に + 왼팔에 붕대감기 + 绷带包扎 左手 + 繃帶包紮 左手 Bandage Right Arm @@ -201,8 +265,12 @@ Перевязать правую руку Panser Bras Droit Jobb kar kötözése - Atar Braço Direito + Atar braço direito Benda il braccio destro + 包帯を右腕に + 오른팔에 붕대감기 + 绷带包扎 右手 + 繃帶包紮 右手 Bandage Left Leg @@ -213,8 +281,12 @@ Перевязать левую ногу Panser Jambe Gauche Bal láb kötözése - Atar Perna Esquerda + Atar perna esquerda Benda la gamba sinistra + 包帯を左足へ + 왼쪽 다리에 붕대감기 + 绷带包扎 左脚 + 繃帶包紮 左腳 Bandage Right Leg @@ -225,8 +297,12 @@ Перевязать правую ногу Panser Jambe Droite Jobb láb kötözése - Atar Perna Direita + Atar perna direita Benda la gamba destra + 包帯を右足へ + 오른쪽 다리에 붕대감기 + 绷带包扎 右脚 + 繃帶包紮 右腳 Injecting Morphine... @@ -235,10 +311,14 @@ Wstrzykiwanie morfiny... Aplikuji morfin... Введение морфина... - Injection de Morphine... + Injection (morphine)... Morfium beadása... - Injetando Morfina... + Injetando morfina... Inietto la morfina... + モルヒネを投与しています・・・ + 모르핀 주사중... + 吗啡注射中... + 嗎啡注射中... Injecting Epinephrine... @@ -247,21 +327,29 @@ Wstrzykiwanie adrenaliny... Aplikuji adrenalin... Введение адреналина... - Injection d'Adrénaline... + Injection (épinéphrine)... Epinefrin beadása... - Injetando Epinefrina... + Injetando epinefrina... Inietto l'adrenalina... + アドレナリンを投与しています・・・ + 에피네프린 주사중... + 肾上腺素注射中... + 腎上腺素注射中... Injecting Adenosine... Adenosin injizieren... Inyectando Adenosina... Wstrzykiwanie adenozyny... - Injection d'adénosine... + Injection (adénosine)... Inietto l'andenosina Aplikuji adenosine... - Injetando Adenosina... + Injetando adenosina... Введение аденозина... + アドネシンを投与しています・・・ + 아데노신 주사중... + 腺苷注射中... + 腺苷注射中... Injecting Atropine... @@ -269,11 +357,15 @@ Inyectando Atropina... Aplikuji atropin... Wstrzykiwanie atropiny... - Injection d'Atropine... + Injection (atropine)... Введение атропина... Atropin beadása... Inietto l'atropina... - Injetando Atropina + Injetando atropina + アトロピンを投与しています・・・ + 아트리핀 주사중... + 阿托品注射中 ... + 阿托品注射中 ... Transfusing Blood... @@ -282,10 +374,14 @@ Przetaczanie krwi... Probíhá transfúze krve... Переливание крови... - Transfusion Sanguine... + Transfusion (sang)... Infúzió vérrel... - Transfundindo Sangue... + Transfundindo sangue... Effettuo la trasfusione di sangue... + 輸血しています・・・ + 혈액 수혈중... + 输血液中 ... + 輸血液中 ... Transfusing Saline... @@ -293,11 +389,15 @@ Transfusión de salino... Probíha transfúze fyziologického roztoku... Przetaczanie soli fizjologicznej... - Transfusion de saline... + Transfusion (solution saline)... Переливание физраствора... Infúzió sós vizzel... Effettuo la rasfusione di soluzione salina - Transfundindo Soro... + Transfundindo soro... + 生理食塩水を投与しています・・・ + 생리식염수 수혈중... + 施打生理食盐水中 ... + 施打生理食鹽水中 ... Transfusing Plasma... @@ -305,11 +405,15 @@ Transfusión de plasma... Probíha transfúze plazmy... Przetaczanie osocza... - Transfusion de Plasma... + Transfusion (plasma)... Переливание плазмы... Infúzió vérplazmával... - Effettu la trasfusione di plasma... - Transfundindo Plasma... + Effettuo la trasfusione di plasma... + Transfundindo plasma... + 血しょうを投与しています・・・ + 혈장 수혈중... + 输血浆中 ... + 輸血漿中 ... Bandaging... @@ -322,6 +426,10 @@ Bekötözés... Atando... Перевязывание... + 包帯を巻いています・・・ + 붕대감는중... + 绷带包扎中 ... + 繃帶包紮中 ... Applying Tourniquet... @@ -329,11 +437,15 @@ Aplicando torniquete... Aplikuji škrtidlo... Zakładanie stazy... - Mise en place du Garrot... + Pose du garrot... Наложение жгута... Érszorító felhelyezése... Sto applicando il laccio emostatico... - Applicando Torniquete + Applicando torniquete + 止血帯を巻いています・・・ + 지혈대 적용중... + 使用军用止血带中 ... + 使用軍用止血帶中 ... Medical @@ -346,6 +458,10 @@ Медик Médico Orvosi + 治療 + 치료 + 医疗 + 醫療 Field Dressing @@ -354,10 +470,14 @@ Бинтовая повязка Obinadlo Bandaż jałowy - Bandage rapide + Pansement individuel Zárókötszer Bendaggio rapido - Curativo de Campo + Curativo de campo + 緊急圧迫包帯 + 필드 드레싱 + 基础绷带 + 基礎繃帶 Packing Bandage @@ -367,9 +487,13 @@ Bandaż uciskowy Nyomókötszer Bendaggio compressivo - Bandage gauze - Bandagem de Compressão + Bande extensible + Atadura de compressão Obvaz Tlakový + 弾性包帯 + 거즈 붕대 + 包扎绷带 + 包紮繃帶 Elastic Bandage @@ -378,10 +502,14 @@ Давящая повязка Obavaz Elastický Bandaż elastyczny - Pansement élastique + Bande compressive Rögzitő kötszer Bendaggio elastico - Bandagem Elástica + Atadura elástica + 伸縮包帯 + 압박 붕대 + 弹性绷带 + 彈性繃帶 QuikClot @@ -390,10 +518,14 @@ QuikClot Opatrunek QuikClot QuikClot - Hémostatique + Bandage hémostatique QuikClot QuikClot (polvere emostatica) - QuikClot + QuikClot (Agente homeostático) + クイッククロット + 퀵 클롯 + 止血粉 + 止血粉 Check Pulse @@ -402,10 +534,14 @@ Проверить пульс Zkontrolovat puls Sprawdź tętno - Vérifier le pouls + Prendre le pouls Pulzus ellenőrzése Controlla il polso - Checar Pulso + Checar pulso + 心拍数をはかる + 맥박 확인 + 检查脉搏 + 檢查脈搏 Check Blood Pressure @@ -414,10 +550,14 @@ Проверить давление Zkontrolovat krevní tlak Sprawdź ciśnienie krwi - Vérification de la tension + Prendre la tension Vérnyomás megmérése Controlla pressionsa sanguigna - Chegar Pressão Sanguínea + Chegar pressão sanguínea + 血圧をはかる + 혈압 확인 + 检查血压 + 檢查血壓 Triage Card @@ -426,22 +566,30 @@ Медкарта Karta segregacyjna Štítek - Carte de triage + Fiche de triage Orvosi lap Triage Card - Cartão de Triagem + Cartão de triagem + トリアージ カード + 부상자 분류 카드 + 检伤分类卡 + 檢傷分類卡 No entries on this triage card. Keine Einträge auf der Triagekarte Nessuna voce sulla Triage Card Нет записей. - Aucune entrée sur cette carte de triage + Fiche vide Brak wpisów w tej karcie segregacyjnej. Sin entradas en esta tarjeta de clasificación. Ez az orvosi lap nem tartalmaz bejegyzést. Žádné záznamy na tomto štítku - Nenhuma entrada neste cartão de triagem + Nenhuma entrada neste cartão de triagem. + トリアージ カードには何もありません。 + 부상자 분류 카드에 쓰여있는것이 없습니다. + 此检伤分类卡上没有任何资料 + 此檢傷分類卡上沒有任何資料 Tourniquet @@ -454,6 +602,10 @@ Érszorító Laccio emostatico Torniquete + 止血帯 + 지혈대 + 军用止血带 + 軍用止血帶 Remove Tourniquet @@ -462,10 +614,14 @@ Снять жгут Sundat škrtidlo Zdejmij stazę - Enlever le garrot + Enlever garrot Érszorító leszedése Rimuovi laccio emostatico - Remover Torniquete + Remover torniquete + 止血帯をはずす + 지혈대 제거 + 移除军用止血带 + 移除軍用止血帶 Diagnose @@ -478,6 +634,10 @@ Diagnosztizálás Diagnóza Diagnosticar + 診断する + 진단 + 诊断 + 診斷 Diagnosing... @@ -490,30 +650,42 @@ Diagnózis folyamatban... Diagnostika... Diagnosticando... + 診断しています・・・ + 진단중... + 诊断中... + 診斷中... CPR HLW RCP Сердечно-лёгочная реанимация - RPC + RCP RKO RCP Újraélesztés CPR SBV + 心肺蘇生 + 심폐소생술 + 心肺复苏术 + 心肺復甦術 Performing CPR... HLW durchführen... Eseguendo RCP... Сердечно-лёгочная реанимация... - RPC en cours + RCP en cours Przeprowadzanie RKO... Realizando RCP... Újraélesztés folyamatban... Provádím CPR... Realizando o SBV... + 心肺蘇生をしています・・・ + 심폐소생중... + 进行心肺复苏术中... + 進行心肺復甦術中... Give Blood IV (1000ml) @@ -521,11 +693,15 @@ Dar Sangre IV (1000ml) Перелить пакет крови (1000 мл) Podaj krew IV (1000ml) - Administrer du sang en IV (1000ml) + Sang en IV (1000ml) Podat krev. transfúzi (1000ml) Vér adása intravénásan (1000ml) Effettua trasfusione sangue EV (1˙000ml) - Administrar Sangue IV (1000ml) + Administrar sangue IV (1000ml) + 血液 IV (1000ml) をあたえる + IV 혈액 수혈 (1000ml) + 输血液 (1000ml) + 輸血液 (1000ml) Give Blood IV (500ml) @@ -533,11 +709,15 @@ Dar Sangre IV (500ml) Перелить пакет крови (500 мл) Podaj krew IV (500ml) - Administrer du sang en IV (500ml) - Podat krev. transfúzi (500ml) + Sang en IV (500ml) + Podat krev. transfúzi (500ml) Vér adása intravénásan (500ml) Effettua trasfusione sangue EV (500ml) - Administrar Sangue IV (500ml) + Administrar sangue IV (500ml) + 血液 IV (500ml) をあたえる + IV 혈액 수혈 (500ml) + 输血液 (500ml) + 輸血液 (500ml) Give Blood IV (250ml) @@ -545,11 +725,15 @@ Dar Sangre IV (250ml) Перелить пакет крови (250 мл) Podaj krew IV (250ml) - Administrer du sang en IV (250ml) + Sang en IV (250ml) Podat krev. transfúzi (250ml) Vér adása intravénásan (250ml) Effettua trasfusione sangue EV (250ml) - Administrar Sangue IV (250ml) + Administrar sangue IV (250ml) + 血液 IV (250ml) をあたえる + IV 혈액 수혈 (250ml) + 输血液 (250ml) + 輸血液 (250ml) Give Plasma IV (1000ml) @@ -557,11 +741,15 @@ Dar Plasma IV (1000ml) Перелить пакет плазмы (1000 мл) Podaj osocze IV (1000ml) - Administrer du plasma en IV (1000ml) + Plasma en IV (1000ml) Podat plazmu (1000ml) Vérplazma adása intravénásan (1000ml) Effettua trasfusione plasma EV (1˙000ml) - Administrar Plasma IV (1000ml) + Administrar plasma IV (1000ml) + 血しょう IV (1000ml) をあたえる + IV 혈장 수혈 (1000ml) + 输血浆 (1000ml) + 輸血漿 (1000ml) Give Plasma IV (500ml) @@ -569,11 +757,15 @@ Dar Plasma IV (500ml) Перелить пакет плазмы (500 мл) Podaj osocze IV (500ml) - Administrer du plasma en IV (500ml) + Plasma en IV (500ml) Podat plazmu (500ml) Vérplazma adása intravénásan (500ml) Effettua trasfusione plasma EV (500ml) - Administrar Plasma IV (500ml) + Administrar plasma IV (500ml) + 血しょう IV (500ml) をあたえる + IV 혈장 수혈 (500ml) + 输血浆 (500ml) + 輸血漿 (500ml) Give Plasma IV (250ml) @@ -581,11 +773,15 @@ Dar Plasma IV (250ml) Перелить пакет плазмы (250 мл) Podaj osocze IV (250ml) - Administrer du plasma en IV (250ml) + Plasma en IV (250ml) Podat plazmu (250ml) Vérplazma adása intravénásan (250ml) Effettua trasfusione plasma EV (250ml) - Administrar Plasma IV (250ml) + Administrar plasma IV (250ml) + 血しょう IV (250ml) をあたえる + IV 혈장 수혈 (250ml) + 输血浆 (250ml) + 輸血漿 (250ml) Give Saline IV (1000ml) @@ -593,11 +789,15 @@ Dar Salino IV (1000ml) Перелить пакет физраствора (1000 мл) Podaj sól fizjologiczną IV (1000ml) - Administrer de la solution saline en IV (1000ml) + Solution saline en IV (1000ml) Podaz fyz. roztok (1000ml) Sós víz adása intravénásan (1000ml) Effettua trasfusione salina EV (1˙000ml) - Administrar Soro IV (1000ml) + Administrar soro IV (1000ml) + 生理食塩水 IV (1000ml) をあたえる + IV 생리식염수 수혈 (1000ml) + 注射生理食盐水 (1000ml) + 注射生理食鹽水 (1000ml) Give Saline IV (500ml) @@ -605,11 +805,15 @@ Dar Salino IV (500ml) Перелить пакет физраствора (500 мл) Podaj sól fizjologiczną IV (500ml) - Administrer de la solution saline en IV (500ml) + Solution saline en IV (500ml) Podaz fyz. roztok (500ml) Sós víz adása intravénásan (500ml) Effettua trasfusione salina EV (500ml) - Administrar Soro IV (500ml) + Administrar soro IV (500ml) + 生理食塩水 IV (500ml) をあたえる + IV 생리식염수 수혈 (500ml) + 注射生理食盐水 (500ml) + 注射生理食鹽水 (500ml) Give Saline IV (250ml) @@ -617,11 +821,15 @@ Dar Salino IV (250ml) Перелить пакет физраствора (250 мл) Podaj sól fizjologiczną IV (250ml) - Administrer de la solution saline en IV (250ml) + Solution saline en IV (250ml) Podaz fyz. roztok (250ml) Sós víz adása intravénásan (250ml) Effettua trasfusione salina EV (250ml) - Administrar Soro IV (250ml) + Administrar soro IV (250ml) + 生理食塩水 IV (250ml) をあたえる + IV 생리식염수 수혈 (250ml) + 注射生理食盐水 (250ml) + 注射生理食鹽水 (250ml) Minor @@ -629,35 +837,47 @@ Menor Несрочная помощь Normalny - Mineur + Traitement en attente Minimální Enyhe Minore Leve + 保留群 + 경미 + 轻微 + 輕微 Delayed Retrasado Срочная помощь Opóźniony - Différé + Traitement urgent Verzögert Odložitelný Késleltetett Differito Atrasado + 待機的治療群 + 늦어짐 + 延后 + 延後 Immediate Inmediato Неотложная помощь Natychmiastowy - Urgence Immédiate + Traitement immédiat Sofort Okamžitý Azonnali Immediata Imediato + 再優先治療群 + 긴급 + 紧急 + 緊急 Deceased @@ -670,18 +890,26 @@ Elhalálozott Deceduto Falecido + 死亡群 + 사망 + 死亡 + 死亡 None Ninguno Отсутствует Brak - Aucun + Pas de fiche Keine Nic Semmi Nessuna Nenhum + なし + 없음 + 未分类 + 未分類 Normal breathing @@ -694,30 +922,42 @@ Normális légzés Respiro normale Respiração normal + 通常の呼吸 + 정상 호흡 + 呼吸正常 + 呼吸正常 No breathing Keine Atmung Дыхание отсутствует No respira - Aucune respiration + Pas de respiration Brak oddechu Nedýchá Nincs légzés Mancanza di respiro Não respira + 息をしていません + 호흡 불가 + 没有呼吸 + 沒有呼吸 Difficult breathing Дыхание затруднено Dificultad para respirar - Difficultée respiratoire + Difficulté respiratoire Trudności z oddychaniem Schwere Atmung Dýchá s obtížemi Nehéz légzés Difficoltà a respirare Dificuldade para respirar + 呼吸が苦しそうです + 호흡 곤란 + 呼吸困难 + 呼吸困難 Almost no breathing @@ -730,6 +970,10 @@ Alig van légzés Respira a fatica Quase não respira + ほとんど呼吸をしていません + 호흡이 없음 + 快要没呼吸 + 快要沒呼吸 Bleeding @@ -742,18 +986,26 @@ Vérzik Sanguinando Sangrando + 出血しています + 출혈 + 流血中 + 流血中 - In Pain + In pain Hat Schmerzen Испытывает боль Con dolor - Ressent de la douleur + Douleur moyenne W bólu V bolestech Fájdalom alatt Con dolore Com dor + 痛みがあります + 고통 + 疼痛中 + 疼痛中 Lost a lot of Blood @@ -766,6 +1018,10 @@ Sok vért vesztett Ha perso parecchio sangue Perdeu muito sangue + 大量失血しています + 大量失血中 + 大量失血中 + 혈액 부족 Tourniquet [CAT] @@ -778,6 +1034,10 @@ Érszorító [CAT] Laccio emostatico [CAT] Torniquete [CAT] + 止血帯 [CAT] + 지혈대 [CAT] + 军用止血带 + 軍用止血帶 Receiving IV [%1ml] @@ -785,23 +1045,31 @@ Recibiendo IV [%1ml] Принимается переливание [%1 мл] Otrzymywanie IV [pozostało %1ml] - Transfusion en IV [%1ml] + Transfusion : [%1ml] Přijímání transfúze [%1ml] Infúzióra kötve [%1ml] Ricevendo EV [%1ml] Recebendo IV [%1ml] + IV で [%1ml] 投与されています + 接收静脉注射液中 [%1ml] + 接收靜脈注射液中 [%1ml] + IV처리 [%1ml] 수혈중 Bandage (Basic) Bandage (Einfach) Повязка (обычная) Vendaje (Básico) - Bandage (Standard) + Pansement adhésif Bandaż (jałowy) Obvaz (Standartní) Kötszer (Általános) Bendaggio (base) - Bandagem(Básico) + Atadura (Básica) + 包帯 (緊急圧迫) + 붕대 (기본) + 基础绷带 + 基礎繃帶 Used to cover a wound @@ -814,42 +1082,58 @@ Usato per coprire una ferita Usado para cobrir um ferimento Slouží k překrytí poranění + 傷口をおおう + 상처를 덮을때 씁니다 + 用于覆盖伤口 + 用於覆蓋傷口 A dressing, that is a particular material used to cover a wound, which is applied over the wound once bleeding has been stemmed. Ein Verband, der aus einem besonderen Material besteht um die Wunde zu schützen, nachdem die Blutung gestoppt wurde. Повязка, накладываемая поверх раны после остановки кровотечения. Un apósito, material específico utilizado para cubrir una herida, se aplica sobre la herida una vez ha dejado de sangrar. - Bandage fait d'un matériel spécial utilisé pour couvrir une blessure, qui peut etre appliqué dès que le saignement a été stoppé. + Pansement utilisé pour couvrir une blessure lorsque le saignement a été stoppé. Opatrunek materiałowy, używany do przykrywania ran, zakładany na ranę po zatamowaniu krwawienia. Egy különleges anyagú kötszer sebek betakarására, amelyet a vérzés elállítása után helyeznek fel. 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. + Um curativo, material específico usado para cobrir um ferimento 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 Mullbinde Тампонирующая повязка Vendaje compresivo - Bandage gauze + Bande extensible Bandaż (uciskowy) Nyomókötszer Bendaggio compressivo - Bandagem de Compressão + Atadura de compressão Obvaz (Tlakový) + 弾性包帯 + 거즈 붕대 + 包扎绷带 + 包紮繃帶 Used to pack medium to large wounds and stem the bleeding Wird verwendet, um mittlere bis große Wunden abzudecken und Blutungen zu stoppen Для тампонирования ран среднего и большого размера и остановки кровотечения. Se utiliza para vendar heridas medianas o grandes y detener el sangrado - Utilisé pour couvrir des blessures de taille moyenne à grande. Arrête l'hémorragie. + Utilisé pour couvrir des blessures moyennes et grandes, ralentit le saignement. Używany w celu opatrywania średnich i dużych ran oraz tamowania krwawienia. Dobrze radzi sobie z tamowaniem ran płatowych oraz postrzałowych. Közepestől nagyig terjedő sebek betakarására és vérzés elállítására használt kötszer Usato su ferite medie o larghe per fermare emorragie. - Usado para o preenchimento de cavidades geradas por ferimentos médios e grandes e estancar o sangramento. + Usado para atar ferimentos médios ou grandes e estancar sangramentos. 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. @@ -860,32 +1144,44 @@ Egy kötszerfajta, melyet a sebek nyomására használnak a vérzés elállítása és sebgyógyulás érdekében. A nyomókötés egy lehetőség nagyobb polytraumatikus sérülések esetén. Un bendaggio usato per coprire la ferita, fermare il sanguinamento e facilitarne la guarigione. Questa tecnica è opzionale su ferite multiple. 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. + Atadura usada para atar o ferimento, estancando o sangramento e facilitando a cicatrização. Atar 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) Bandage (Elastisch) Повязка (давящая) Vendaje (Elástico) - Bandage (Élastique) + Bande compressive Bandaż (elastyczny) Obvaz (Elastický) Rögzító kötszer Benda (elastica) - Bandagem (Elástica) + Atadura (Elástica) + 包帯 (伸縮) + 붕대 (압박) + 弹性绷带 + 彈性繃帶 Bandage kit, Elastic Elastische Binde (Kompressionsbinde) Давящая повязка Kit de vendaje (Elástico) - Bandage compressif élastique + Bande compressive Bandaż elastyczny służy do opatrywania ran ciętych oraz kłutych. Dobrze radzi sobie również ze zgniecieniami tkanek miękkich oraz rozerwaniami powierzchni skóry. Rugalmas kötszercsomag, "rögzítő" Kit di bendaggio, elastico - Kit de Bandagem, Elástica + Kit de ataduras elásticas Sada obvazů, Elastická + 包帯キット (伸縮) + 붕대, 압박 + 弹性绷带 + 彈性繃帶 Allows an even compression and extra support to the injured area. @@ -896,8 +1192,12 @@ Brinda una compresión uniforme y ofrece soporte extra a una zona lesionada Egyenletes nyomást és támogatást biztosít a sebesült felületnek. Permette di comprimere e aiutare la zone ferita. - Esta bandagem pode ser utilizada para comprimir o ferimento e diminuir o sangramento e garantir que o ferimento não abra em movimento. + Esta atadura pode ser utilizada para comprimir o ferimento e diminuir o sangramento e garantir que não se abra em movimento. Hodí se k fixačním účelům a to i v oblastech kloubů. + 負傷部分へ最大の対応と止血を続けられます。 + 부상 부위를 골고루 압박해주면서 동시에 고정시켜 줍니다. + 可对伤口持续压迫并固定以防止伤口情况变严重 + 可對傷口持續壓迫並固定以防止傷口情況變嚴重 Tourniquet (CAT) @@ -910,42 +1210,58 @@ Érszorító (CAT) Laccio emostatico (CAT) Torniquete (CAT) + 止血帯 (CAT) + 지혈대 [CAT] + 军用止血带 + 軍用止血帶 Slows down blood loss when bleeding Замедляет кровопотерю при кровотечении Reduce la velocidad de pérdida de sangre - Ralentit le saignement + Ralentit l'hémorragie Zmniejsza ubytek krwi z kończyn w przypadku krwawienia. Nie może być noszony zbyt długo ze względu na narastający ból z kończyny. Verringert den Blutverlust Lelassítja a vérvesztést vérzés esetén Rallenta la perdita di sangue in caso di sanguinamento Reduz a velocidade da perda de sangue Zpomaluje ztráty krve při krvácení + 出血しているときに、失血量をおさえます。 + 출혈 시 혈액손실을 늦춰줍니다 + 减缓失血的速度 + 減緩失血的速度 A constricting device used to compress venous and arterial circulation in effect inhibiting or slowing blood flow and therefore decreasing loss of blood. Жгут используется для прижатия сосудов к костным выступам, которое приводит к остановке или значительному уменьшению кровотечения Dispositivo utilizado para eliminar el pulso distal y de ese modo controlar la pérdida de sangre - Un dispositif permettant de compresser les artères et veines afin de réduire la perte de sang. + Un dispositif permettant de compresser les artères et veines afin de ralentir l'hémorragie. Opaska uciskowa CAT służy do tamowanie krwotoków w sytuacji zranienia kończyn z masywnym krwawieniem tętniczym lub żylnym. Ein Hilfsmittel, das Druck auf Venen und Arterien ausübt und so den Blutfluss verringert. Egy szűkítőeszköz, mely a vénás és artériás nyomás keringés helyi összenyomására szolgál, ezzel lelassítva vagy megállítva az adott területen a vérkeringést. Ez csökkenti a vérvesztés mértékét. Un laccio emostatico usato per comprimere le vene e arterie per bloccare o rallentare la circolazione del sangue e quindi rallentare dissanguamenti. - A aparelho que comprime as artérias e veias para diminuir a perda de sangue. + Aparelho que comprime as artérias e veias para diminuir a perda de sangue. 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 Morphium-Autoinjektor Морфин в пневмошприце Morfina auto-inyectable - Auto-injecteur de Morphine + Auto-injecteur de morphine Autostrzykawka z morfiną Auto-morfin Morfium autoinjektor Autoiniettore di morfina Auto-injetor de morfina + モルヒネ注射器 + 모르핀 자동주사기 + 吗啡自动注射器 + 嗎啡自動注射器 Used to combat moderate to severe pain experiences @@ -958,6 +1274,10 @@ Usato per combattere il dolore. Usado para combater dores moderadas e severas Slouží k tlumení středně těžkých a těžkých bolestí + 戦闘が収まったとき、痛みにたいしてつかいます。 + 심한 통증을 완화하는데 쓰입니다 + 减低中度至重度的疼痛感 + 減低中度至重度的疼痛感 An analgesic used to combat moderate to severe pain experiences. @@ -970,51 +1290,71 @@ Un analgesico usato per combattere il dolore. Um analgésico usado para combater dores moderadas e fortes. Analgetikum slouží k tlumení středně těžkých a těžkých bolestí + 戦闘が収まったとき、モルヒネを痛みにたいしてつかいます。 + 심한 통증을 완화하기 위해 쓰이는 진통제입니다. + 止痛药的一种,用于减低中度至重度的疼痛感。 + 止痛藥的一種,用於減低中度至重度的疼痛感 Adenosine autoinjector Adenosin-Autoinjektor Asenosina auto-inyectable Autostrzykawka z adenozyną - Auto-injécteur d'adénosine + Auto-injecteur d'adénosine Autoiniettore di adenosina Auto-adenosine - Auto-injetor de Adenosina + Auto-injetor de adenosina Аденозин в пневмошприце + アデノシン注射器 + 아데노신 자동주사기 + 腺苷自动注射器 + 腺苷自動注射器 Used to counter effects of Epinephrine Wird verwendet um die Symptome von Epiniphrin zu lindern Utilizada para contrarrestar los effectos de la Epinefrina Adenozyna. Stosowana do zwalczania efektów działania adrenaliny. - Utilisé pour contrer les effets de l'adrénaline + Utilisé pour contrer les effets de l'épinéphrine Usato per contrastare l'effetto dell'epinefrina Slouží jako protiváha Adrenalinu - Usado para combater os efeitos da Epinefrina + Usado para combater os efeitos da epinefrina Используется для купирования эффектов адреналина + アドレナリンの反対の効果としてつかいます。 + 에피네프린 대응책으로 쓰입니다 + 用来对付肾上腺素的影响 + 用來對付腎上腺素的影響 A drug used to counter the effects of Epinephrine Ein Medikament, das die Symptome von Epiniphrin bekämpft. Medicamento usado para contrarrestar los efectos de la Epinefrina. Organiczny związek chemiczny z grupy nukleozydów. Skuteczna w leczeniu częstoskurczu komorowego. Działa rozszerzająco na naczynia krwionośne. - Un composé utilisé pour contrer les effets de l'adrénaline + Un composé utilisé pour contrer les effets de l'épinéphrine Medicamento usato per contrastare l'effetto dell'epinefrina Droga používaná k tlumení efektu Adrenalinu - Uma droga usada para combater os efeitos da Epinefrina + Uma droga usada para combater os efeitos da epinefrina Препарат используется для купирования эффектов адреналина + つかうと、アドレナリンと反対の効果がでます。 + 에피네프린에 대응용으로 쓰이는 약품 + 一种药物用于减低肾上腺素的效果 + 一種藥物用於減低腎上腺素的效果 Atropine autoinjector Атропин в пневмошприце Atropina auto-inyectable - Auto-injecteur d'Atropine + Auto-injecteur d'atropine Autostrzykawka AtroPen Atropin-Autoinjektor Auto-atropine Atropin autoinjektor Autoiniettore di atropina - Auto-injetor de Atropina + Auto-injetor de atropina + アトロピン注射器 + 아트로핀 자동주사기 + 阿托品自动注射器 + 阿托品自動注射器 Used in NBC scenarios @@ -1027,6 +1367,10 @@ Usato in situazioni con gas nervino. Usado em casos de ataque QBRN Používá se v přítomnosti nervových plynů + 核・生物・化学兵器によ汚染環境下にてつかいます。 + 핵,생물,화학 상황에 쓰입니다 + 使用于核生化污染的情况 + 使用於核生化汙染的情況 A drug used by the Military in NBC scenarios. @@ -1039,6 +1383,10 @@ E' un farmaco usato in ambito militare in scenari con presenza di gas nervino. Uma droga usada por militares em casos de ataque QBRN. Atropin slouží jako protijed na otravu organofosfátovými insekticidy (diazinon) a nervovými plyny. + 核・生物・化学兵器がつかわれている条件下にてつかいます。 + 핵,생물,화학 상황에 쓰이는 군용 약품 + 军用神经解毒针,用来应付核生化污染的情况。 + 軍用神經解毒針,用來應付核生化汙染的情況 Epinephrine autoinjector @@ -1051,6 +1399,10 @@ Epinefrin autoinjektor Autoiniettore di adrenalina Auto-injetor de epinefrina + アドレナリン注射器 + 에피네프린 자동주사기 + 肾上腺素自动注射器 + 腎上腺素自動注射器 Increase heart rate and counter effects given by allergic reactions @@ -1063,6 +1415,10 @@ Aumenta il battito cardiaco e combatte gli effetti di reazioni allergiche. Aumenta a frequência cardíaca e combate efeitos causados por reações alérgicas Zvyšuje srdeční frekvenci a chrání před alergickými reakcemi + 心拍数を増加させたり、アレルギー反応を収める効果もあります。 + 심박수를 높이며 알러지반응의 대응책입니다 + 增加心跳速率的一种药物 + 增加心跳速率的一種藥物 A drug that works on a sympathetic response to dilate the bronchi, increase heart rate and counter such effects given by allergic reactions (anaphylaxis). Used in sudden cardiac arrest scenarios with decreasing positive outcomes. @@ -1072,93 +1428,125 @@ EpiPen z adrenaliną ma działanie sympatykomimetyczne, tj. pobudza receptory alfa- i beta-adrenergiczne. Pobudzenie układu współczulnego prowadzi do zwiększenia częstotliwości pracy serca, zwiększenia pojemności wyrzutowej serca i przyśpieszenia krążenia wieńcowego. Pobudzenie oskrzelowych receptorów beta-adrenergicznych wywołuje rozkurcz mięśni gładkich oskrzeli, co w efekcie zmniejsza towarzyszące oddychaniu świsty i duszności. Una sostanza che permette di dilatare i bronchi, aumentare il battito cardiaco e combattere effetti di reazioni allergiche. Usato anche in casi di arresto cardiaco. Ein Medikament, das die Bronchien erweitert, die Herzfrequenz erhöht und Symptome von allergischen Reaktionen (Anaphylaxie) bekämpft. Wird bei plötzlichem Herzstillstand verabreicht. - Uma droga trabalha dilatando os bronquios, aumentando a frequência cardíaca e combate efeitos de reações alérgicas(anáfilaticas). Usado em casos de parada cardiaca com poucas changes de recuperação. + Uma droga que trabalha dilatando os brônquios, aumentando a frequência cardíaca e combate efeitos de reações alérgicas (anáfilaticas). Usado em casos de parada cardíaca com poucas chances de recuperação. Egy hormon, mely a szimpatikus idegrendszer által kitágítja a hörgőket, valamint megnöveli a szívverést, ezzel ellensúlyozva ilyen jellegű allergiás reakciókat (anafilaxiás sokk). Hirtelen szívmegállás esetén is használt, idő alatt csökkenő hatásfokkal. 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) Плазма для в/в вливания (1000 мл) Plasma IV (1000ml) - Plasma Sanguin IV (1000ml) + Plasma IV (1000ml) Osocze IV (1000ml) Plasma IV (1000ml) Vérplazma-infúzió (1000ml) Plasma EV (1000ml) Plasma IV (1000ml) Krevní plazma (1000ml) + 血しょう IV (1000ml) + 혈장 IV (250ml) + 血浆 (1000ml) + 血漿 (1000ml) A volume-expanding blood supplement. Дополнительный препарат, применяемый при возмещении объема крови. Suplemento para expandir el volumen sanguíneo. - Supplément visant à remplacer les volumes sanguin + Supplément sanguin visant à remplacer les volumes perdus. Składnik krwi, używany do zwiększenia jej objętości. Egy térfogatnövelő vérkiegészítmény. Aiuta ad aumentare il volume sanguigno. Volumenerweiterungsmittel (künstliches Blutvolumen) Suplemento para expandir o volume sanguíneo. - Intravenózně podávaný doplněk k zvětšení objemu krve + Intravenózně podávaný doplněk k zvětšení objemu krve + 血液量を増加させる補助です。 + 혈액량을 늘리기위한 보조수단 입니다. + 可快速得到血液补充 + 可快速得到血液補充 A volume-expanding blood supplement. Дополнительный препарат, применяемый при возмещении объема крови. Suplemento para expandir el volumen sanguíneo. - Supplément visant à remplacer le volume sanguin et remplace les plaquettes. + Supplément visant à remplacer le volume sanguin perdu et remplace les plaquettes. Składnik krwi, używany do zwiększenia jej objętości. Egy térfogatnövelő vérkiegészítmény. Aiuta ad aumentare il volume sanguigno. Volumenerweiterungsmittel (künstliches Blutvolumen) Suplemento para expandir o volume sanguíneo. - Intravenózně podávaný doplněk k zvětšení objemu krve + Intravenózně podávaný doplněk k zvětšení objemu krve + 血液量を増加させる補助です。 + 혈액량을 늘리기위한 보조수단 입니다. + 可快速得到血液补充 + 可快速得到血液補充 Plasma IV (500ml) Плазма для в/в вливания (500 мл) Plasma IV (500ml) - Plasma sanguin IV (500ml) + Plasma IV (500ml) Osocze IV (500ml) Plasma IV (500ml) Vérplazma-infúzió (500ml) Plasma EV (500ml) Plasma IV (500ml) Krevní plazma (500ml) + 血しょう IV (500ml) + 혈장 IV (500ml) + 血浆 (500ml) + 血漿 (500ml) Plasma IV (250ml) Плазма для в/в вливания (250 мл) Plasma IV (250ml) - Plasma sanguin (250ml) + Plasma (250ml) Osocze IV (250ml) Plasma IV (250ml) Vérplazma-infúzió (250ml) Plasma EV (250ml) Plasma IV (250ml) Krevní plazma (250ml) + 血しょう IV (250ml) + 혈장 IV (250ml) + 血浆 (250ml) + 血漿 (250ml) Blood IV (1000ml) Кровь для переливания (1000 мл) Sangre IV (1000ml) - Cullot sanguin IV (1000ml) + Culot sanguin IV (1000ml) Krew IV (1000ml) Blut IV (1000ml) Vér-infúzió (1000ml) Sangue EV (1000ml) Sangue IV (1000ml) Krevní transfúze (1000ml) + 血液 IV (1000ml) + 혈액 IV (1000ml) + 血液 (1000ml) + 血液 (1000ml) Blood IV, for restoring a patients blood (keep cold) Пакет крови для возмещения объёма потерянной крови (хранить в холодильнике) Sangre intravenosa, para restarurar el volumen sanguíneo (mantener frío) - Cullot sanguin O-, utilisé seulement lors de perte sanguine majeure afin de remplacer le volume sanguin perdu. Habituelment utilisé lors du transport ou dans un etablisement de soins. + Culot sanguin O-, utilisé seulement lors de perte sanguine majeure afin de remplacer le volume sanguin perdu. Habituellement utilisé lors du transport ou dans un établissement de soins. Krew IV, używana do uzupełnienia krwi u pacjenta, trzymać w warunkach chłodniczych. Vér-infúzió, intravénás bejuttatásra egy páciensnek (hidegen tárolandó) Sangue usato per ripristinare pazienti in cui si è verificata una perdita di sangue (conservare al fresco) Blut IV, Bluthaushalt des Patienten wiederherstellen. (Kühl halten) - Sangue intravenoso, para restaurar o volume sanguinio do paciente.(Manter frio) + Sangue intravenoso, para restaurar o volume sanguíneo do paciente.(Manter frio) Krevní transfuze pro doplnění pacientovi krve (skladujte v chladu) + 血液 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. @@ -1166,59 +1554,79 @@ Krew 0 Rh-, używana w rzadkich i szczególnych przypadkach do uzupełnienia krwi u pacjenta, zazwyczaj w trakcie fazie transportu rannej osoby do szpitala. Utilice sólo durante gran pérdida de sangre para reemplazar el volumen de sangre perdida. Uso habitual durante el transporte de heridos. Sangue 0 negativo usato per ripristinare sangue in pazienti in cui si è verificata una perdita di sangue. - Cullot sanguin O- utilisé dans de rares et stricts cas pour compléter une perte de sang importante. Administré normalement lors d'un MEDEVAC. + Culot sanguin O- utilisé dans de rares et stricts cas pour compléter une perte de sang importante. Administré normalement lors d'un MEDEVAC. O Negative Blutinfusion wird nur in seltenen Fällen verwendet, um den Bluthaushalt des Patienten zu ergänzen. Wird in der Regel wärend der Transportphase durchgeführt. - Sangue O- , utilizado em casos raros para rapidamente repor o sangue. Uso habitual ocorre durante o transporte ou em estações de tratamento. + Sangue "O" de fator Rh negativo, utilizado em casos raros para rapidamente repor o sangue. Uso habitual ocorre durante o transporte ou em estações de tratamento. Nullás vércsoportú, Rh-negatív vér-infúzió, melyet kritikus és ritka helyzetekben vérutánpótlásra használnak, jellemzően az orvosi ellátás szállítási fázisa közben. 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型負值注射用血液,在緊急情況時使用,用於補充傷者流失的血液。 Blood IV (500ml) Кровь для переливания (500 мл) Sangre IV (500ml) - Cullot sanguin IV (500ml) + Culot sanguin IV (500ml) Krew IV (500ml) Blut IV (500ml) Vér-infúzió (500ml) Sangue EV (500ml) Sangue IV (500ml) Krevní transfúze (500ml) + 血液 IV (500ml) + 혈액 IV (500ml) + 血液 (500ml) + 血液 (500ml) Blood IV (250ml) Кровь для переливания (250 мл) Sangre IV (250ml) - Cullot sanguin IV (250ml) + Culot sanguin IV (250ml) Krew IV (250ml) Blut IV (250ml) Vér-infúzió (250ml) Sangue EV (250ml) Sangue IV (250ml) Krevní transfúze (250ml) + 血液 IV (250ml) + 혈액 IV (250ml) + 血液 (250ml) + 血液 (250ml) Saline IV (1000ml) Физраствор для в/в вливания (1000 мл) Salino IV (1000ml) - Solution saline 0.9% IV (1000ml) + Solution saline IV (1000ml) Sól fizjologiczna IV (1000ml) Kochsalzlösung (1000ml) 0,9%-os sósvíz-infúzió (1000ml) Soluzione salina EV (1˙000ml) Soro IV (1000ml) Fyziologický roztok (1000ml) + 生理食塩水 IV (1000ml) + 생리식염수 IV (1000ml) + 生理食盐水 (1000ml) + 生理食鹽水 (1000ml) Saline IV, for restoring a patients blood Пакет физраствора для возмещения объёма потерянной крови Solución salina intravenosa, para restaurar el volumen sanguíneo - Solution saline 0.9% IV, pour rétablir temporairement la tension artérielle + Solution saline, pour rétablir temporairement la tension artérielle Używany w medycynie w formie płynu infuzyjnego jako środek nawadniający i uzupełniający niedobór elektrolitów, podawany dożylnie (IV). 0,9%-os sósvíz-infúzió, a páciens vérmennyiségének helyreállítására Soluzione salina, usata per ripristinare sangue nei pazienti. Kochsalzlösung, ein medizinisches Volumenersatzmittel - Solução Salina Intravenosa 0.9%, para restaurar o volume de sangue temporariamente. + Solução salina intravenosa, para restaurar o volume de sangue. 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. @@ -1228,33 +1636,45 @@ Używany w medycynie w formie płynu infuzyjnego jako środek nawadniający i uzupełniający niedobór elektrolitów, podawany dożylnie (IV). Egy orvosi térfogat-helyreállító készítmény, melyet intravénás módon lehet a szervezetbe juttatni. Una soluzione medica per ripristinare il volume del sangue introdotta tramite trasfusione EV. - Ein medizinisches Volumenersatzmittel, dass durch einen intravenösen Zugang in den Blutkreislauf verabreicht wird. - Uma reposição temporaria para restaurar a pressão arterial perdida por perda de sangue. + Ein medizinisches Volumenersatzmittel, dass durch einen intravenösen Zugang in den Blutkreislauf verabreicht wird. + Uma reposição temporária para restaurar a pressão arterial perdida por perda de sangue. Fyziologický roztok se využívá nejčastěji jako infuze při dehydrataci organismu. + 生理食塩水 IV を静脈へ投与し、血液量を増加させることができます。 + 혈류에 IV로 투여되는 의료 용적 대체 요법 + 利用静脉注射进入人体血液系统,帮助伤者血液恢复。 + 利用靜脈注射進入人體血液系統,幫助傷者血液恢復。 Saline IV (500ml) Физраствор для в/в вливания (500 мл) Salino IV (500ml) - Solution saline 0.9% IV (500ml) + Solution saline IV (500ml) Sól fizjologiczna IV (500ml) Kochsalzlösung (500ml) 0,9%-os sósvíz-infúzió (500ml) Soluzione salina EV (500ml) Soro IV (1000ml) Fyziologický roztok (500ml) + 生理食塩水 IV (500ml) + 생리식염수 IV (500ml) + 生理食盐水 (500ml) + 生理食鹽水 (500ml) Saline IV (250ml) Физраствор для в/в вливания (250 мл) Salino IV (250ml) - Solution saline 0.9% IV (250ml) + Solution saline IV (250ml) Sól fizjologiczna IV (250ml) Kochsalzlösung (250ml) 0,9%-os sósvíz-infúzió (250ml) Soluzione salina EV (250ml) Soro IV (1000ml) Fyziologický roztok (250ml) + 生理食塩水 IV (250ml) + 생리식염수 IV (250ml) + 生理食盐水 (250ml) + 生理食鹽水 (250ml) Basic Field Dressing (QuikClot) @@ -1265,8 +1685,12 @@ Verbandpäckchen (QuikClot) Általános zárókötszer (QuikClot) Bendaggio emostatico (QuikClot) - Bandagem básica (Coagulante) + Atadura básica (Coagulante) Hemostatický obvaz (QuikClot) + 緊急圧迫止血包帯 (クイッククロット) + 필드 드레싱 (퀵 클롯) + 基本战地包扎 (止血粉) + 基本戰地包紮 (止血粉) QuikClot bandage @@ -1277,8 +1701,12 @@ Bandage mit Gerinnungsmittel QuikClot kötszer Bendaggio emostatico (QuikClot) - Bandagem com agente coagulante + Atadura com agente coagulante Hemostatický obvaz (QuikClot) + クイッククロット包帯 + 퀵 클롯 붕대 + 止血粉绷带 + 止血粉繃帶 Hemostatic bandage with coagulant that stops bleeding. @@ -1289,56 +1717,76 @@ Verband mit Gerinnungsmittel, um starke Blutung zu behandeln. Hemostatikus kötszer egy vérzésgátló anyaggal. Bendaggio emostatico con coagulante che permette di arrestare perdite di sangue - Bandagem Hemostática com coagulante que controla hemorragia médias e grandes com risco de vida. + Atadura homeostática com coagulante que controla hemorragias médias e grandes. Hemostatický obvaz určený k zástavě krvácení + 血液凝固剤をふくむ包帯により、止血できます。 + 지혈시 사용하는 붕대로 혈액 응고제를 포함하고있습니다. + 包含止血粉成分的止血绷带,可用于止血。 + 包含止血粉成分的止血繃帶,可用於止血。 Personal Aid Kit Аптечка - Trousse de premiers soins + Trousse sanitaire Equipo de primeros auxilios Apteczka osobista Persönliches Erste-Hilfe-Set Elsősegélycsomag Pronto soccorso personale - Kit De Primeiros Socorros Pessoal + Kit de Primeiros Socorros Pessoal Osobní lékárnička (PAK) + 応急処置キット + 개인응급키트 + 个人急救包 + 個人急救包 Includes various treatment kit needed for stitching or advanced treatment Содержит различные материалы и инструменты для зашивания ран и оказания специальной медпомощи. Incluye material médico para tratamientos avanzados - Inclue du matériel medical pour les traitements avancés, tel les points de suture. + Inclut du matériel medical pour les traitements délicats, tel les points de suture. Zestaw środków medycznych do opatrywania ran i dodatkowego leczenia po-urazowego. Beinhaltet medizinisches Material für fortgeschrittene Behandlung und zum Nähen. Változatos segédfelszereléseket tartalmaz sebvarráshoz és haladó elsősegélynyújtáshoz Include vario materiale medico per trattamenti avanzati. - Inclui vários tratamentos materiais para custura e tratamento avançado - Osobní lékárnička obsahuje zdravotnický materiál umožňující šití a pokročilejší ošetřování raněných + Inclui vários tratamentos materiais para costura e tratamento avançado + 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 W znacznym stopniu poprawia stan pacjenta Полевая аптчека для продвинутого лечения и зашивания ран Persönliches Erste-Hilfe-Set zum ambulanten Nähen und fortgeschrittener Behandlung. - Trousse de premiers soins pour coudre sur le terrain et traitements avancés. + Inclut du matériel medical pour les traitements délicats, tel les points de suture. Equipo de primeros auxilios para sutura de campaña o tratamientos avanzados Elsősegélycsomag, terepen való sebvarráshoz és haladó ellátáshoz Kit de primeiros socorros para sutura ou tratamentos avançados - Osobní lékárnička obsahuje zdravotnický materiál umožňující šití a pokročilejší ošetřování raněných v poli + Osobní lékárnička obsahuje zdravotnický materiál umožňující šití a pokročilejší ošetřování raněných v poli Pronto soccorso personale da campo per mettersi i punti o per trattamenti avanzati. + 戦場で縫合や高度な処置に必要とされる、さまざまな治療器具が含まれています。 + 야전에서 봉합및 고급 조치를 위한 개인응급키트 + 个人急救包可用于战地缝合手术或进阶伤口系统使用 + 個人急救包可用於戰地縫合手術或進階傷口系統使用 Use Personal Aid Kit Erste-Hilfe-Set benutzen Использовать аптечку - Utiliser la Trousse de premier soins + Utiliser la trousse sanitaire Użyj apteczki osobistej Usar equipo de primeros auxilios Elsősegélycsomag használata Usar o kit de primeiros socorros Použít osobní lékárničku (PAK) Usa il pronto soccorso personale + 応急処置キットをつかう + 개인 응급 키트사용하기 + 使用个人急救包 + 使用個人急救包 Surgical Kit @@ -1349,8 +1797,12 @@ Operationsset Sebészeti készlet Kit chirurgico - Kit Cirurgico + Kit Cirúrgico Chirurgická sada + 縫合キット + 봉합 키트 + 手术包 + 手術包 Surgical Kit for in field advanced medical treatment @@ -1363,6 +1815,10 @@ Kit chirurgico per trattamenti avanzati sul campo. Kit Cirurgico para uso de tratamento médico avançado em campo Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli + 縫合キットは戦場で高度な処置をするためにつかわれます。 + 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 + 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) + 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) Surgical Kit for in field advanced medical treatment @@ -1373,8 +1829,12 @@ Trousse chirurgicale pour le traitement sur le terrain Sebészeti készlet komplex orvosi feladatok terepen való ellátására Kit chirurgico per trattamenti avanzati sul campo. - Kit Cirurgico para uso de tratamento médico avançado em campo. + Kit Cirúrgico para tratamento médico avançado em campo. Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli + 縫合キットは戦場で高度な処置をするためにつかわれます。 + 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 + 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) + 用於在戰場上為傷口進行縫合(需要開啟進階傷口系統) Use Surgical Kit @@ -1387,6 +1847,10 @@ Sebészeti készlet használata Použít chirurgickou sadu Usar kit cirúrgico + 縫合キットをつかう + 봉합키트 사용하기 + 使用手术包 + 使用手術包 Bodybag @@ -1397,8 +1861,12 @@ Leichensack Hullazsák Sacca per corpi - Saco para cadáver + Saco mortuário Pytel na mrtvoly + 死体袋 + 尸袋 + 屍袋 + 시체 운반 가방 A bodybag for dead bodies @@ -1411,6 +1879,10 @@ Una sacca nera per trasportare cadaveri. Um saco para corpos mortos Pytel na mrtvoly + 死体袋は死体を入れるためにつかいます + 시체를 운반할때 쓰는 가방입니다 + 用来装尸体用 + 用來裝屍體用 A bodybag for dead bodies @@ -1423,6 +1895,10 @@ Una sacca nera per trasportare cadaveri. Um saco para corpos mortos. Pytel na mrtvoly + 死体袋は死体を入れるためにつかいます + 시체를 운반할때 쓰는 가방입니다 + 用来装尸体用 + 用來裝屍體用 Blood Pressure @@ -1433,36 +1909,48 @@ Blutdruck Vérnyomás Pressione sanguigna - Pressão Arterial + Pressão arterial Krevní tlak + 血圧を測る + 혈압 + 血压 + 血壓 Checking Blood Pressure.. - Mesure de la tension... + Prise de la tension... Проверка артериального давления... Comprobando presión arterial... Sprawdzanie ciśnienia krwi... Blutdruck kontrollieren... Vérnyomás megmérése... Controllando la pressione sanguigna.. - Aferindo Pressão Arterial... + Aferindo pressão arterial... Měřím krevní tlak... + 血圧を測定しています・・・ + 혈압 측정증... + 检查血压中... + 檢查血壓中... %1 checked Blood Pressure: %2 %1 kontrollierte Blutdruck: %2 %1 controllata pressione sanguigna: %2 %1 проверил артериальное давление: %2 - %1 à vérifié la tension: %2 + %1 a mesuré la tension: %2 %1 sprawdził ciśnienie krwi: %2 %1 verificada la presión arterial: %2 %1 ellenőrizte a vérnyomást: %2 %1 zkontroloval krevní tlak: %2 %1 verificou pressão arterial: %2 + %1 が測った血圧は: %2 + %1 (이)가 혈압을 측정했습니다: %2 + 已由%1确认血压: %2 + 已由%1確認血壓: %2 You checked %1 - Vous diagnostiquez %1 + Vous examinez %1 Вы осмотрели раненого %1 Examinando a %1 Zbadałeś %1 @@ -1471,18 +1959,26 @@ Hai diagnosticato %1 Você verificou o paciente %1 Zkontroloval jsi %1 + 自分の血圧は %1 + 나의 혈압은 %1 이다 + 你已经检查 %1 + 你已經檢查 %1 You find a blood pressure of %2/%3 - Vous avez trouvé une tension de %2/%3 + Vous avez mesuré une tension de %2/%3 Артериальное давление %2/%3 La Presión Arterial es %2/%3 A vérnyomás %2/%3 Hai riscontrato una pressione di %2/%3 Wyczuwasz ciśnienie krwi o wartości %2/%3 Der Blutdruck liegt bei %2/%3 - A Pressão Arterial é de %2/%3 + A pressão arterial é de %2/%3 Naměřil si krevní tlak u %2/%3 + 血圧は %2/%3 + 혈압이 %2/%3 이다 + 血压为%2/%3 + 血壓為%2/%3 You find a low blood pressure @@ -1493,8 +1989,12 @@ Blutdruck ist niedrig A vérnyomás alacsony La pressione sanguigna è bassa - Pressão Arterial baixa + Pressão arterial baixa Naměřil si nízký krevní tlak + 血圧はかなり低い + 发现到低血压 + 發現到低血壓 + 혈압이 낮음 You find a normal blood pressure @@ -1505,20 +2005,28 @@ Blutdruck ist normal A vérnyomás normális La pressione sanguigna è normale - Pressão Arterial normal + Pressão arterial normal Naměřil si normální krevní tlak + 血圧は通常 + 发现到正常血压 + 發現到正常血壓 + 혈압이 정상 You find a high blood pressure - Tension haute + Tension élevée Давление высокое La presión arterial es alta Wyczuwasz wysokie ciśnienie krwi Blutdruck ist hoch A vérnyomás magas La pressione sanguigna è alta - Pressão Arterial Alta + Pressão arterial alta Naměřil si vysoký krevní tlak + 血圧はかなり高い + 发现到高血压 + 發現到高血壓 + 혈압이 높음 You find no blood pressure @@ -1529,8 +2037,12 @@ Patient hat keinen Blutdruck Nem észlelhető vérnyomás La pressione sanguigna è assente - Sem Pressão Arterial + Sem pressão arterial Nenaměřil si žádný krevní tlak + 血圧を測れませんでした + 혈압이 잡히지 않는다 + 量不到血压 + 量不到血壓 You fail to find a blood pressure @@ -1541,56 +2053,76 @@ Du konntest keinen Blutdruck feststellen Nem sikerült a vérnyomás megmérése Manca strumento per misurare pressione sanguigna - Você falhou em aferir a Pressão Arterial + Você falhou em aferir a pressão arterial Nedokázal si změřit krevní tlak + 血圧を測るのに失敗しました + 혈압을 잡을 수 없었다 + 检查血压的动作失败 + 檢查血壓的動作失敗 Low Niedrig Bassa Низкое - Faible + basse Niskie Baja Alacsony Nízký Baixa + 低い + 낮음 + + Normal Normal Normale Нормальное - Normale + normale Normalne Normal Normális Normální Normal + 通常 + 보통 + 正常 + 正常 High Hoch Alta Высокое - Haute + élevée Wysokie Alta Magas Vysoký Alta + 高い + 높음 + + No Blood Pressure Kein Blutdruck Nessuna Pressione Sanguigna Артериальное давление отсутствует - Aucune tension + pas de tension Brak ciśnienia krwi Sin presión arterial Nincs vérnyomás Žádný krevní tlak Sem pressão arterial + 血圧なし + 혈압 없음 + 无血压 + 無血壓 Pulse @@ -1603,18 +2135,26 @@ Polso Pulso Puls + 心拍数 + 맥박 + 脉搏 + 脈搏 Checking Heart Rate... - Vérification du rythme cardiaque... + Vérification du pouls... Проверка пульса... Comprobando ritmo cardíaco... Sprawdzanie tętna... Kontrolliere Herzfrequenz... Szívverés-szám mérése... Controllando il battito cardiaco... - Aferindo Pulso... + Aferindo pulso... Kontroluji srdeční tep... + 心拍数を測定しています・・・ + 맥박 확인중... + 检查心跳中... + 檢查心跳中... You checked %1 @@ -1627,18 +2167,26 @@ Hai diagnosticato %1 Você aferiu o paciente %1 Zkontroloval si %1 + 心拍数は %1 + 나의 맥박은 %1 이다 + 你已经检查 %1 + 你已經檢查 %1 %1 checked Heart Rate: %2 %1 kontrollierte Herzfrequenz: %2 %1 Controllata Frequenza Cardiaca: %2 %1 проверил пульс: %2 - %1 à vérifié le rythme cardiaque: %2 + %1 a vérifié le pouls de : %2 %1 sprawdził tętno: %2 %1 verificado el ritmo cardíaco: %2 %1 ellenőrizte a szívverés-számot: %2 %1 zkontroloval srdeční tep: %2 %1 verificou a frequência cardíaca: %2 + %1 が測った心拍数は: %2 + %1 (이)가 맥박을 측정했습니다: %2 + 已由%1确认心跳: %2 + 已由%1確認心跳: %2 None @@ -1648,109 +2196,145 @@ Keine Žádný Nada - Aucun + aucun Nincs Niente + なし + 없음 + + Weak Schwach Lento Слабый - Faible + lent Słabe Débil Gyenge Slabý Fraca + 弱い + 약함 + 微弱 + 微弱 Normal Normal Normale Нормальный - Normal + normal Normalne Normal Normális Normální Normal + 通常 + 보통 + 正常 + 正常 Strong Stark Veloce Сильный - Fort + rapide Silne Fuerte Erős Silný Forte + 強い + 강함 + 过快 + 過快 You find a Heart Rate of %2 - Rythme cardiaque de %2 + %2 battements par minute Пульс %2 уд./мин. El ritmo cardíaco es de %2 Wyczuwasz tętno o wartości %2 Herzfrequenz ist %2 A szívverés-szám %2 Il battito cardiaco è %2 - A Freqüência Cardíaca é de %2 + A freqüência cardíaca é de %2 Nahmatal jsi srdeční tep u %2 + 心拍数は %2 + 心跳为%2 + 心跳為%2 + 맥박 %2 You find a weak Heart Rate - Rythme cardiaque faible + Poulslent Пульс слабый El ritmo cardíaco es débil Wyczuwasz słabe tętno Schwacher Puls A szívverés-szám alacsony Hai riscontrato un debole battito cardiaco - Freqüência Cardíaca baixa + Freqüência cardíaca baixa Nahmatal si slabý srdeční puls + 自分の心拍数は低い + 心跳微弱 + 心跳微弱 + 약한 맥박 You find a strong Heart Rate - Rythme cardiaque élevé + pouls rapide Пульс учащенный El ritmo cardíaco está acelerado Wyczuwasz silne tętno Starker Puls A szívverés-szám magas Hai riscontrato un forte battito cardiaco - Freqüência Cardíaca normal + Freqüência cardíaca normal Nahmatal si silný srdeční puls + 自分の心拍数は強い + 心跳过快 + 心跳過快 + 강한 맥박 You find a normal Heart Rate - Rythme cardiaque normal + pouls normal Пульс в норме El ritmo cardíaco es bueno Wyczuwasz normalne tętno Normaler Puls A szívverés-szám normális Hai riscontrato un normale battito cardiaco - Freqüência Cardíaca alta + Freqüência cardíaca alta Nahmatal si normální srdeční puls + 自分の心拍数は通常 + 心跳正常 + 心跳正常 + 보통 맥박 You find no Heart Rate - Pas de rythme cardiaque + pas de pouls Пульс не прощупывается No tiene ritmo cardíaco Wyczuwasz brak tętna Kein Puls gefunden Nem észlelhető szívverés Hai riscontrato una assenza di battito cardiaco - Sem Freqüência Cardíaca + Sem freqüência cardíaca Žádný puls + 心拍数を測れませんでした + 量不到心跳 + 量不到心跳 + 맥박 없음 Response - Etat de Conscience + Conscience Реакция Respuesta Przytomność @@ -1759,10 +2343,14 @@ Risposta Reação Odezva + 反応を見る + 반응 + 反应 + 反應 You check response of patient - Vous vérifiez la réponse du patient + Vous évaluez l'état de conscience Вы проверяете реакцию раненого Compruebas si el paciente reacciona Sprawdzasz przytomność pacjenta @@ -1771,6 +2359,10 @@ Controlli la risposta del paziente Aferindo se o paciente tem reação Zkontroloval jsi reakci pacienta + 患者からの反応を見る + 대상의 반응 확인중 + 检查伤者的反应 + 檢查傷者的反應 %1 is responsive @@ -1778,11 +2370,15 @@ %1 est conscient %1 ha reaccionado %1 jest przytomny - %1 ist anprechbar + %1 ist ansprechbar %1 reakcióképes %1 e' cosciente %1 está respondendo %1 odpovídá + %1 は反応あり + %1 有反应 + %1 有反應 + %1 은 반응이 있다 %1 is not responsive @@ -1795,6 +2391,10 @@ %1 e' incosciente %1 não está respondendo %1 neodpovídá + %1 の反応なし + %1 没有反应 + %1 沒有反應 + %1 은 반응이 없다 You checked %1 @@ -1807,6 +2407,10 @@ Hai controllato %1 Você aferiu o paciente %1 Zkontroloval jsi %1 + %1 を見ました + %1 을 확인함 + 你已经检查 %1 + 你已經檢查 %1 Patient %1<br/>is %2.<br/>%3.<br/>%4 @@ -1819,6 +2423,10 @@ 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/>is %2.<br/>%3.<br/>%4 + 傷者 %1<br/>is %2.<br/>%3.<br/>%4 alive @@ -1831,6 +2439,10 @@ élő naživu vivo + 生存 + 생존 + 活着 + 活著 dead @@ -1838,11 +2450,15 @@ мёртв muerto tot - mort + décédé martwy halott mrtev morto + 死亡 + 사망 + 死亡 + 死亡 He's lost some blood @@ -1855,6 +2471,10 @@ Valamennyi vért vesztett Ztratil trochu krve Ele perdeu um pouco de sangue + 出血しています + 적은 양의 피를 잃었다 + 他流失一些血液 + 他流失一些血液 He's lost a lot of blood @@ -1867,6 +2487,10 @@ Ztratil hodně krve Ele perdeu muito sangue Ha perso molto sangue + 大量失血しています + 많은 양의 피를 잃었다 + 他流失大量血液 + 他流失大量血液 He hasn't lost blood @@ -1879,6 +2503,10 @@ Nem vesztett vért Neztratil žádnou krev Ele não perdeu sangue + 失血していません + 피를 잃지 않았다 + 他并没有失血 + 他並沒有失血 He is in pain @@ -1891,6 +2519,10 @@ Fájdalmai vannak Je v bolestech Ele está com dor + 痛いようです + 통증이 있다 + 他感到疼痛 + 他感到疼痛 He is not in pain @@ -1903,10 +2535,14 @@ Nincsenek fájdalmai Nemá žádné bolesti Ele não está com dor + 痛くないようです + 통증이 없다 + 他不会疼痛 + 他不會疼痛 Bandaged - Bandé + Pansé Повязка наложена Vendado Zabandażowano @@ -1915,22 +2551,30 @@ verbunden Enfaixado Obvázaný + 包帯 + 붕대 감음 + 绷带 + 繃帶 You bandage %1 (%2) - Vous bandez %1 (%2) + Vous pansez %1 (%2) Вы перевязали раненого %1 (%2) Aplicas vendaje a %1 en %2 Bandażujesz %1 (%2) Bekötözöd %1-t (%2) Stai bendando %1 (%2) Du verbindest %1 (%2) - Você aplica bandagem no paciente %1 (%2) + Você aplica atadura no paciente %1 (%2) Obvazuješ %1 (%2) + %1 (%2) 包帯をつかいました + %1 (%2) 붕대를 감았다 + 你正在对 %1 (%2) 包扎绷带中 + 你正在對 %1 (%2) 包紮繃帶中 %1 is bandaging you - %1 vous bande + %1 vous panse %1 перевязывает вас %1 te está vendando %1 bandażuje Ciebie @@ -1939,6 +2583,10 @@ %1 verbindet dich %1 está aplicando uma bandagem em você %1 tě obvazuje + %1 はあなたに包帯を巻いています + %1 (이)가 나에게 붕대를 감고있다 + %1 正在对你包扎绷带中 + %1 正在對你包紮繃帶中 You start stitching injuries from %1 (%2) @@ -1951,6 +2599,10 @@ Stai suturando le ferite di %1 (%2) Você começa a suturar os ferimentos do %1 (%2) Zašíváš rány %1 (%2) + %1 (%2) の外傷へ縫合を始めました + 나는 %1(%2) 상처로부터 봉합을 시작했다 + 你正开始对 %1 (%2) 缝合伤口中 + 你正開始對 %1 (%2) 縫合傷口中 Stitching @@ -1963,6 +2615,10 @@ Suturando Suturando Šití + 縫合中 + 붕합중 + 缝合中 + 縫合中 You treat the airway of %1 @@ -1975,6 +2631,10 @@ Controlli le vie respiratorie di %1 Você entuba o %1 Ošetřuješ dýchací cesty %1 + %1 の気道を診断する + %1의 기도를 확보했다 + 你治疗 %1 的呼吸道 + 你治療 %1 的呼吸道 Airway @@ -1987,6 +2647,10 @@ Vie respiratorie Vias Aéreas Dýchací cesty + 気道 + 기도 + 呼吸道 + 呼吸道 %1 is treating your airway @@ -1999,6 +2663,10 @@ %1 ti sta trattando le vie respiratorie %1 está te entubando %1 ošetřuje tvoje dýchací cesty + %1 はあなたの気道を見ています + %1 (이)가 나의 기도를 확보중이다 + %1 正在治疗你的呼吸道 + %1 正在治療你的呼吸道 Drag @@ -2007,10 +2675,14 @@ Ciągnij Táhnout Тащить - Trainer + Traîner Húzás Arrastar Trascina + 引きずる + 끌다 + 拖拉 + 拖拉 Carry @@ -2023,6 +2695,10 @@ Cipelés Carregar Trasporta + 運ぶ + 업다 + 背起 + 背起 Release @@ -2035,6 +2711,10 @@ Elengedés Soltar Rrilascia + 離す + 내려놓기 + 放下 + 放下 Load Patient Into @@ -2045,8 +2725,12 @@ Погрузить пациента в Embarquer le patient Sebesült berakása - Carregar Paciente Em + Carregar paciente em Carica paziente nel + 患者を載せる + 환자 싣기 + 将伤者放入 + 將傷者放入 Unload Patient @@ -2057,8 +2741,12 @@ Выгрузить пациента Débarquer le patient Sebesült kihúzása - Descarregar Paciente + Descarregar paciente Scarica il paziente + 患者を降ろす + 환자 내리기 + 将伤者背出 + 將傷者背出 Unload patient @@ -2066,11 +2754,15 @@ Выгрузить пациента Patient ausladen Wyładuj pacjenta - Débarquer le patient + Le patient débarque Sebesült kihúzása Scarica il paziente - Descarregar Paciente + Descarregar paciente Vyložit pacienta + 患者を降ろす + 환자 내리기 + 将伤者背出 + 將傷者背出 Load patient @@ -2081,8 +2773,12 @@ Embarquer le patient Sebesült berakása Carica il paziente - Carregar Paciente Em + Carregar paciente em Naložit pacienta + 患者を載せる + 환자 싣기 + 将伤者放入 + 將傷者放入 Place body in bodybag @@ -2093,8 +2789,12 @@ Mettre le corps dans la housse mortuaire Test hullazsákba helyezése Metti il corpo nella sacca per cadaveri - Colocar corpo dentro do saco para cadáver + Colocar corpo dentro do saco mortuário Umístni tělo do pytle na mrtvoly + 死体袋に入れる + 시체 가방에 담기 + 将尸体放入尸袋 + 將屍體放入屍袋 Placing body in bodybag... @@ -2105,8 +2805,12 @@ Placement du corps dans la housse... Test hullazsákba helyezése... Stai mettendo il corpo nella sacca... - Colocando corpo dentro do saco para cadáver... + Colocando corpo dentro do saco mortuário... Umístňuji tělo do pytle na mrtvoly... + 死体袋へ入れています・・・ + 시체 가방에 담는중... + 将尸体放入尸袋中... + 將屍體放入屍袋中... %1 has bandaged patient @@ -2117,8 +2821,12 @@ %1 a pansé le patient %1 bekötözte a pácienst %1 ha bendato il paziente - %1 aplicou bandagem no paciente + %1 aplicou atadura no paciente %1 již obvázal pacienta + %1 は包帯を巻きました + %1 已包扎伤者 + %1 已包紮傷者 + %1 (이)가 붕대를 감음 %1 performed CPR @@ -2129,7 +2837,11 @@ %1 realizou RCP %1 провел сердечно-легочную реанимацию %1 realicó RCP - %1 à fait une RPC + %1 à fait une RCP + %1 は心肺蘇生をしました + %1 已执行心肺复苏术 + %1 已執行心肺復甦術 + %1 (이)가 심폐소생술을 실시함 %1 used %2 @@ -2142,6 +2854,10 @@ %1 ha usato %2 %1 usou %2 %1 použil %2 + %1 は %2 をつかいました + %1 已使用 %2 + %1 已使用 %2 + %1 (이)가 %2 을 사용함 %1 has given an IV @@ -2149,11 +2865,15 @@ %1 ha puesto una IV %1 hat eine Infusion verabreicht %1 podał IV - %1 a administré une IV + %1 a plaçé une IV %1 infúziót adott %1 ha somministrato una EV %1 aplicou um intravenoso %1 již aplikoval IV + %1 は IV をしました + %1 已经给予静脉注射液 + %1 已經給予靜脈注射液 + %1 (이)가 IV를 실시함 %1 applied a tourniquet @@ -2161,11 +2881,15 @@ %1 наложил жгут %1 hat ein Tourniquet angelegt %1 założył stazę - %1 a appliqué un garrot + %1 a plaçé un garrot %1 felhelyezett egy érszorítót %1 ha applicato un laccio emostatico %1 aplicou um torniquete %1 použil škrtidlo + %1 は止血帯を巻きました + %1 已经绑上止血带 + %1 已經綁上止血帶 + %1 (이)가 지혈대를 적용함 %1 used Personal Aid Kit @@ -2176,7 +2900,11 @@ %1 использовал аптечку %1 ha usato Kit Pronto Soccorso Personale %1 usó Kit de Primeros Auxilios - %1 à utilisé un PAK + %1 a utilisé une trousse + %1 は応急処置キットをつかいました + %1 已使用了个人急救包 + %1 已使用了個人急救包 + %1 (이)가 개인응급키트를 사용함 Heavily wounded @@ -2185,10 +2913,14 @@ Тяжелые ранения Gravemente ferito Gravemente herido - Lourdement blessé + Gravement blessé Erősen sérült Těžce raněn Gravemente ferido + 重傷 + 중상 + 重伤 + 重傷 Lightly wounded @@ -2201,6 +2933,10 @@ Enyhén sérült Lehce raněn Levemente ferido + 軽傷 + 경상 + 轻伤 + 輕傷 Very lightly wounded @@ -2212,7 +2948,11 @@ Très légèrement blessé Nagyon enyhén sérült Velmi lehce raněn - Muito levemente ferido + Ferido muito levemente + かなり浅い傷 + 매우 가벼운 부상 + 小伤 + 小傷 Head @@ -2225,6 +2965,10 @@ Fej Hlava Cabeça + 頭部 + 머리 + 头部 + 頭部 Torso @@ -2237,6 +2981,10 @@ Testtörzs Trup Torso + 胴体 + 몸통 + 身体 + 身體 Left Arm @@ -2245,10 +2993,14 @@ Левой руки Braccio sinistro Brazo izquierdo - Bras gouche + Bras gauche Bal kar Levá ruka - Braço Esquerdo + Braço esquerdo + 左腕 + 왼쪽 팔 + 左手 + 左手 Right Arm @@ -2260,7 +3012,11 @@ Bras droit Jobb kar Pravá ruka - Braço Direito + Braço direito + 右腕 + 오른쪽 팔 + 右手 + 右手 Left Leg @@ -2272,7 +3028,11 @@ Jambe gauche Bal láb Levá noha - Perna Esquerda + Perna esquerda + 左足 + 왼쪽 다리 + 左脚 + 左腳 Right Leg @@ -2284,18 +3044,26 @@ Jambe droite Jobb láb Pravá noha - Perna Direita + Perna direita + 右足 + 오른쪽 다리 + 右脚 + 右腳 Heal fully bandaged hitpoints Lecz w pełni zabandażowane hitpointy Curar miembros totalmente vendados Исцелять полностью перебинтованные части тела - Curar hitpoints totalmente enfaixados + Curar pontos de vida totalmente enfaixados Heal fully bandaged hitpoints Cura hitpoints completamente bendati - Soigner les plaies entièrement bandées. + Soigner les plaies entièrement bandées Heilt vollständig bandagierte Trefferpunkte + 包帯は体力を完全に回復する + 붕대를 감은후 체력을 회복함 + 完全医疗包扎的部位至痊愈 + 完全醫療包紮的部位至痊癒 Pain is only temporarily suppressed @@ -2303,11 +3071,15 @@ Ból jest tymczasowo zwalczany Bolest je potlačena pouze dočasně El dolor se suprime solo temporalmente - Dor é suprimida somente temporáriamente - La douleur est seulement supprimée temporairement + Dor é suprimida somente temporariamente + La douleur est temporairement calmée A fájdalom csak ideiglenesen csökken Боль приглушается только временно Dolore è soppresso solo temporaneamente + 痛みは一時的な影響 + 疼痛只会暂时性压制 + 疼痛只會暫時性壓制 + 고통은 일시적으로만 회복 Pain Effect Type @@ -2318,8 +3090,12 @@ Tipo de efecto de dolor Type d'effet de douleur Fájdalom-effekt típusa - Tipo do efeito de dor + Tipo do efeito da dor Typ bolesti - efekt + 痛みの種類 + 고통 효과 종류 + 疼痛效果类型 + 疼痛效果類型 Colour Flashing @@ -2332,6 +3108,10 @@ Színvillódzás Flash de cor Blikající barva + 色の点滅 + 색 반짝임 + 闪烁颜色 + 閃爍顏色 Chromatic Aberration @@ -2343,12 +3123,16 @@ Aberration chromatique Kromatikus aberráció Chromatická aberace - Aberração Cromática + Aberração cromática + 色の収差 + 색수차 + 色差 + 色差 Style of menu (Medical) Styl menu medycznego - Style de menu (Médical) + Style de menu (médical) Menüstil (Medizin) Вид меню (медицина) Tipo de menú (Medico) @@ -2356,23 +3140,31 @@ Estilo do menu (Médico) Menü stílusa (Orvosi) Stile del menù (medico) + メニューの表示形式 (治療) + 메뉴의 스타일 (의료) + 选单样式 (医疗) + 選單樣式 (醫療) Select the type of menu you prefer; default 3d selections or radial. Wybierz rodzaj menu, który preferujesz: domyślne pozycje 3D lub radialne - Selctionne le type de menu préféré; par défaut la sélection 3D ou radiale + Sélectionne le type de menu préféré; par défaut la sélection 3D ou radiale Wähle den Menüstil: Standard 3D-Auswahl oder kreisförmig. Выберите тип меню: стандартный вариант (3D) или радиальный Selecciona el tipo de menú que prefieres: selecciones 3d por defecto o radial. - Selecione o tipo de menu que você prefere; padrão seleções 3d ou radial. + Selecione o tipo de menu que você prefere; seleções 3d padrão ou radial. Válaszd ki a neked megfelelő menüt: Alapértelmezett 3D válogatás, vagy kerek. Zvolte typ menu: základní 3D výběr nebo kruhový Seleziona il tipo di menù che preferisci: selezione (3D), radiale o disabilitata. + メニューの表示形式を選んでください。標準では 3D 選択か円状です。 + 선호하는 종류의 메뉴를 고르세요; 기본 3d 선택형 혹은 다이얼형 + 选择你喜欢的选单样式; 预设为3D选项或放射状 + 選擇你喜歡的選單樣式; 預設為3D選項或放射狀 Selections (3d) Pozycje (3D) - sélections (3D) + Sélection (3D) 3D-Auswahl Стандартный (3D) Selecciones (3d) @@ -2380,11 +3172,15 @@ Választékok (3D) 3D výběr Selezione (3D) + 選択 (3D) + 선택 (3d) + 选择 (3D) + 選擇 (3D) Radial Radialne - Radiale + Radial Kreisförmig Радиальный Radial @@ -2392,54 +3188,74 @@ Kerek Kruhový Radiale + 円状 + 다이얼형 + 放射状 + 放射狀 Scrape Kratzer Scorticatura Ссадина - Eraflure + Abrasion Draśnięcie Arañazo Horzsolás - Raspão + Escoriação Odřenina + 擦り傷 + 찰과상 + 擦伤 + 擦傷 Minor Scrape Kleiner Kratzer Minima Scorticatura Малая ссадина - Petite éraflure + Petite abrasion Pomniejsze draśnięcie Arañazo menor Kis horzsolás - Raspão leve + Escoriação leve Malá odřenina + 小さな擦り傷 + 소형 찰과상 + 小擦伤 + 小擦傷 Medium Scrape Mittlerer Kratzer Media Scorticatura Средняя ссадина - Moyenne éraflure + Moyenne abrasion Średnie draśnięcie Arañazo medio Közepes horzsolás - Raspão médio + Escoriação média Středně velká odřenina + 中くらいの擦り傷 + 중형 찰과상 + 中擦伤 + 中擦傷 Large Scrape Großer Kratzer Alta Scorticatura Большая ссадина - Grande éraflure + Grande abrasion Duże draśnięcie Arañazo severo Nagy horzsolás - Raspão grave + Escoriação grave Velká odřenina + 大きな擦り傷 + 대형 찰과상 + 大擦伤 + 大擦傷 Avulsion @@ -2452,6 +3268,10 @@ Leszakadás Avulsão Avulze + 剥離傷 + 적출상 + 撕脱伤 + 撕脫傷 Minor Avulsion @@ -2464,6 +3284,10 @@ Kis leszakadás Avulsão leve Malá avulze + 小さな剥離傷 + 소형 적출상 + 小撕脱伤 + 小撕脫傷 Medium Avulsion @@ -2476,6 +3300,10 @@ Közepes leszakadás Avulsão média Střední avulze + 中くらいの剥離傷 + 중형 적출상 + 中撕脱伤 + 中撕脫傷 Large Avulsion @@ -2488,102 +3316,138 @@ Nagy leszakadás Avulsão grave Velká avulze + 大きな剥離傷 + 대형 적출상 + 大撕脱伤 + 大撕脫傷 Bruise Prellung Contusione Ушиб - Hématome + Contusion Stłuczenie Contusión Zúzódás Contusão Modřina + 打ち傷 + 타박상 + 挫伤 + 挫傷 Minor Bruise Kleine Prellung Minima Contusione Малый ушиб - Petit hématome + Petite contusion Pomniejsze stłuczenie Contusión menor Kis zúzódás - Contusão leve + Hematoma leve Malá modřina + 小さな打ち傷 + 소형 타박상 + 小挫伤 + 小挫傷 Medium Bruise Mittlere Prellung Media Contusione Средний ушиб - Hématome moyen + Moyenne contusion Średnie stłuczenie Contusión media Közepes zúzódás - Contusão média + Hematoma médio Středně velká modřina + 中くらいの打ち傷 + 중형 타박상 + 中挫伤 + 中挫傷 Large Bruise Große Prellung Alta Contusione Большой ушиб - Hématome important + Grande contusion Duże stłuczenie Contusión severa Nagy zúzódás - Contusão grave + Hematoma grande Velká modřina + 大きな打撲傷 + 대형 타박상 + 大挫伤 + 大挫傷 Crushed tissue Quetschverletzung Tessuto Schiacciato Компресионная травма - Tissu écrasé + Écrasement Zgniecienie tkanek miękkich Tejido triturado Zúzott szövet - Tecido esmagado + Contusão Zhmoždění měkkých tkání + 圧挫傷 + 압궤상 + 撞伤 + 撞傷 Minor crushed tissue Kleine Quetschverletzung Minimo Tessuto Schiacciato Малая компрессионная травма - Tissu écrasé léger + Petit écrasement Pomniejsze zgniecienie tkanek miękkich Tejido triturado menor Kis zúzott szövet - Tecido esmagado leve + Contusão leve Malé zhmoždění měkkých tkání + 小さな圧挫傷 + 소형 압궤상 + 小撞伤 + 小撞傷 Medium crushed tissue Mittlere Quetschverletzung Medio Tessuto Schiacciato Средняя компрессионная травма - Tissu écrasé moyen + Moyen écrasement Średnie zgniecienie tkanek miękkich Tejido triturado medio Közepes zúzott szövet - Tecido esmagado médio + Contusão média Střední zhmoždění měkkých tkání + 中くらいの圧挫傷 + 중형 압궤상 + 中撞伤 + 中撞傷 Large crushed tissue Große Quetschverletzung Alto Tessuto Schiacciato Большая компрессионная травма - Tissu écrasé large + Grand écrasement Duże zgniecienie tkanek miękkich Tejido triturado severo Nagy zúzött szövet - Tecido esmagado grave + Contusão grande Velké zhmoždění měkkých tkání + 大きな圧挫傷 + 대형 압궤상 + 大撞伤 + 大撞傷 Cut @@ -2596,6 +3460,10 @@ Vágás Corte Řezná rána + 切り傷 + 절상 + 割伤 + 割傷 Small Cut @@ -2608,6 +3476,10 @@ Petite coupure Corte leve Malá řezná rána + 小さな切り傷 + 소형 절상 + 小割伤 + 小割傷 Medium Cut @@ -2620,6 +3492,10 @@ Moyenne coupure Corte médio Střední řezná rána + 中くらいの切り傷 + 중형 절상 + 中割伤 + 中割傷 Large Cut @@ -2629,9 +3505,13 @@ Duża rana cięta Corte severo Nagy vágás - Large coupure + Grande coupure Corte grave Velká řezná rána + 大きな切り傷 + 대형 절상 + 大割伤 + 大割傷 Tear @@ -2639,11 +3519,15 @@ Strappo Рваная рана Rozerwanie skóry - Déchirure + Lacération Desgarro Szakadás Ruptura Tržná rána + 裂傷 + 열상 + 撕裂伤 + 撕裂傷 Small Tear @@ -2651,11 +3535,15 @@ Piccolo Strappo Малая рваная рана Pomniejsze rozerwanie skóry - Petite Déchirure + Petite lacération Desgarro menor Kis szakadás Ruptura leve Malá tržná rána + 小さな裂傷 + 소형 열상 + 小撕裂伤 + 小撕裂傷 Medium Tear @@ -2665,9 +3553,13 @@ Średnie rozerwanie skóry Desgarro medio Közepes szakadás - Moyenne déchirure + Moyenne lacération Ruptura média Střední tržná rána + 中くらいの裂傷 + 중형 열상 + 中撕裂伤 + 中撕裂傷 Large Tear @@ -2677,9 +3569,13 @@ Duże rozerwanie skóry Desgarro severo Nagy szakadás - Large déchirure + Grande lacération Ruptura grave Velká tržná rána + 大きな裂傷 + 대형 열상 + 大撕裂伤 + 大撕裂傷 Velocity Wound @@ -2687,11 +3583,15 @@ Velocità Ferita Огнестрельная рана Rana postrzałowa - Blessure de vélocité + Plaie pénétrante Herida de bala Lőtt seb - Ferimento por projétil de arma de fogo + Trauma balístico Střelné poranění + 銃創 + 총상 + 穿透伤 + 穿透傷 Small Velocity Wound @@ -2701,9 +3601,13 @@ Pomniejsza rana postrzałowa Herida de bala menor Kis lőtt seb - Petite blessure de vélocité - Ferimento leve por projétil de arma de fogo + Petite plaie pénétrante + Trauma balístico pequeno Malé střelné poranění + 小さな銃創 + 소형 총상 + 小穿透伤 + 小穿透傷 Medium Velocity Wound @@ -2713,9 +3617,13 @@ Średnia rana postrzałowa Herida de bala media Közepes lőtt seb - Moyenne blessure de vélocité - Ferimento médio por projétil de arma de fogo + Moyenne plaie pénétrante + Trauma balístico médio Střední střelné poranění + 中くらいの銃創 + 중형 총상 + 中穿透伤 + 中穿透傷 Large Velocity Wound @@ -2725,9 +3633,13 @@ Duża rana postrzałowa Herida de bala severa Nagy lőtt seb - Large blessure de vélocité - Ferimento grave por projétil de arma de fogo + Grande plaie pénétrante + Trauma balístico grande Velké střelné poranění + 大きな銃創 + 대형 총상 + 大穿透伤 + 大穿透傷 Puncture Wound @@ -2735,11 +3647,15 @@ Puntura Ferita Колотая рана Rana kłuta - Blessure de perforation + Perforation Herida punzante Szúrt seb - Ferimento por perfuração + Ferimento perfurante Bodná rána + 刺し傷 + 자상 + 穿刺伤 + 穿刺傷 Minor Puncture Wound @@ -2749,9 +3665,13 @@ Pomniejsza rana kłuta Herida punzante menor Kis szúrt seb - Légère blessure de perforation - Ferimento leve por perfuração + Petite perforation + Ferimento perfurante leve Malá bodná rána + 小さな刺し傷 + 소형 자상 + 小穿刺伤 + 小穿刺傷 Medium Puncture Wound @@ -2761,9 +3681,13 @@ Średnia rana kłuta Herida punzante media Közepes szúrt seb - Moyenne blessure de perforation - Ferimento médio por perfuração + Moyenne perforation + Ferimento perfurante médio Střední bodná rána + 中くらいの刺し傷 + 중형 자상 + 中穿刺伤 + 中穿刺傷 Large Puncture Wound @@ -2773,9 +3697,13 @@ Duża rana kłuta Herida punzante severa Nagy szúrt seb - Large blessure de perforation - Ferimento grave por perfuração + Grande perforation + Ferimento perfurante grave Velká bodná rána + 大きな刺し傷 + 대형 자상 + 大穿刺伤 + 大穿刺傷 Broken Femur @@ -2788,6 +3716,10 @@ Törött combcsont Fêmur quebrado Zlomená stehenní kost + 大腿骨の骨折 + 대퇴골 골절 + 大腿骨骨折 + 大腿骨骨折 Treating... @@ -2800,6 +3732,10 @@ Tratando... Ošetřuji... Curando... + 治療しています・・・ + 치료중... + 治疗中... + 治療中... Removing Tourniquet... @@ -2812,6 +3748,10 @@ Sundavám škrtidlo... Снятие жгута... Togliendo il laccio emostatico... + 止血帯を外しています・・・ + 지혈대 제거중... + 移除军用止血带中... + 移除軍用止血帶中... ACE Medical @@ -2824,6 +3764,10 @@ ACE Médical ACE Orvosi Rendszer ACE Medical + ACE 医療 + ACE 의료 + ACE 医疗系统 + ACE 醫療系統 Medical Settings [ACE] @@ -2833,9 +3777,13 @@ Sanitätseinstellungen [ACE] Lékařské nastavení [ACE] Ajustes médicos [ACE] - Option médicale [ACE] + Options médicales [ACE] Orvosi beállítások [ACE] Impostazioni Mediche [ACE] + 医療設定 [ACE] + 의료 설정 [ACE] + 医疗设定 [ACE] + 醫療設定 [ACE] Medical Level @@ -2848,6 +3796,10 @@ Niveau de simulation médicale Orvosi szint Livello Medico + 医療レベル + 의료 수준 + 医疗等级 + 醫療等級 What is the medical simulation level? @@ -2857,9 +3809,13 @@ Wie hoch soll das medizinische Simulationslevel sein? Jaká je úroveň lékařské simulace? Qual o nível de simulação médica? - Quel niveau de simulation médicale choisissez vous? + Quel niveau de simulation médicale choisissez-vous? Milyen komplex legyen az orvosi szimuláció? Qual'è il livello di simulazione medica? + 治療の再現度 + 의료 시뮬레이션의 수준 + 选择需要的医疗模拟等级 + 選擇需要的醫療模擬等級 Basic @@ -2872,6 +3828,10 @@ Basique Alap Basico + ベーシック + 기본 + 基本 + 基本 Advanced @@ -2881,9 +3841,13 @@ Erweitert Pokročilé Avançada - Avancée + Avancé Fejlett Avanzato + アドバンスド + 고급 + 进阶 + 進階 Medics setting @@ -2893,9 +3857,13 @@ Sanitätseinstellungen Úroveň zdravotníků Configuração médica - Paramètre des infirmiers + Règlage des infirmiers Orvosok beállítása Parametri Medici + 治療の設定 + 의료 설정 + 医护兵等级 + 醫護兵等級 What is the level of detail prefered for medics? @@ -2905,9 +3873,13 @@ ¿Cuál es el nivel de detalle preferido para los médicos? Jaká úroveň detailů je preferována pro zdravotníky? Qual o nível de detalhe preferido para os médicos? - Quel niveau de détail voullez vous pour les infirmier? + 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 @@ -2917,19 +3889,27 @@ Ubicación mejora entrenamiento. Miejsca zwiększają wyszkolenie Localização melhora treinamento - Locations boost l'entraînement de médecin + Le lieu améliore l'efficacité Места ускоренного обучения + 衛生兵としての能力を与える場所 + 受所在位置影响提升医疗能力 + 受所在位置影響提升醫療能力 + 의료 효과 증가 지역 Boost medic rating in medical vehicles or near medical facilities [untrained becomes medic, medic becomes doctor] - Zlepšit zkušenosti zdravotníka v medickém vozidle nebo poblíž zdravotního zařízení [nezkušení se stane zdravotníkem, zdravotník se stane doktorem] + Zlepšit zkušenosti zdravotníka v medickém vozidle nebo poblíž zdravotního zařízení [nezkušení se stane zdravotníkem, zdravotník se stane doktorem] Aumenta il rating medico in veicoli medici o vicino strutture mediche [non addestrato diventa medico, medico diventa dottore] Steigert die medizinische Einstufung eines Soldaten in Sanitätsfarhzeugen oder in der Nähe von Sanitätseinrichtungen [untrainiert wird zu Sanitäter, Sanitäter zu Doktor] Mejora el entrenamiento médico dentro de vehículos médicos o cerca de instalaciones médicas (no entrenados se convierten en médicos, médicos se convierten en doctores) Zwiększa poziom wyszkolenia medyków wewnątrz pojazdów medycznych lub w pobliżu budynków medycznych [niedoświadczony zostaje medykiem, medyk zostaje doktorem] 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] - Boost le rang médical dans les véhicules ou bâtiments médicaux [non entraînés deviennent médecins, médecins deviennent docteurs] + 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 @@ -2942,6 +3922,10 @@ Désactiver les infirmiers Orvosok letiltása Disabilita medici + 衛生兵を無効化 + 의무병 비활성화 + 关闭医护兵 + 關閉醫護兵 Enable Litter @@ -2954,6 +3938,10 @@ Activer les détritus Szemét engedélyezése Abilita Barella + 医療廃棄物の表示を有効化 + 의료폐기물 활성화 + 启用医疗废弃物 + 啟用醫療廢棄物 Enable litter being created upon treatment @@ -2962,10 +3950,14 @@ Activar los restos médicos que se crean en el tratamiento Aktiviere Abfälle, wenn eine Behandlung durchgeführt wurde Vytváří odpad zdravotnického materiálu pří léčení - Ativar lixo ser criado após tratamento + Ativar lixo a ser criado após tratamento Activer la création de détrimus au début des traitements Engedélyezi a szemét keletkezését ellátáskor Abilita la creazione della barella dopo trattamento + 治療を始めると、医療廃棄物の作成を有効化する + 의료폐기물이 치료중 주변에 생성되는것을 활성화 합니다 + 本功能启用后,当每次医疗动作结束时,地上会产生相应的医疗废弃物 + 本功能啟用後,當每次醫療動作結束時,地上會產生相應的醫療廢棄物 Life time of litter objects @@ -2974,10 +3966,14 @@ Tiempo de vida de los restos médicos Dauer des angezeigten Abfalls Životnost pro odpadky - Tempo de vida dos objetos do lixo + Tempo de vida do lixo médico Durée d'affichage des détritus Szemétobjektumok élettartama Tempo di vita delle barelle + 医療廃棄物の作成限界数を設定 + 의료폐기물 시간제한 + 医疗废弃物存在时间 + 醫療廢棄物存在時間 How long should litter objects stay? In seconds. -1 is forever. @@ -2986,10 +3982,14 @@ ¿Por cuánto tiempo deben permanecer los restos médicos? En segundos. -1 es para siempre. Wie lange sollen Abfälle am Boden liegen (in Sekunden)? -1 ist für immer. Za jak dlouho začnou odpadky mizet? V sekundách. -1 navždy. - Quanto tempo os objetos do lixo devem ficar? Em segundos. -1 é para sempre. + Quanto tempo o lixo médico deve permanecer? Em segundos. -1 é para sempre. 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為永遠存在。 Enable Screams @@ -3002,9 +4002,13 @@ Activer les hurlements Kiáltások engedélyezése Abilita Grida + 叫びを有効化 + 비명 활성화 + 启用尖叫 + 啟用尖叫 - Enable screaming by injuried units + Enable screaming by injured units Включить крики раненных бойцов Aktywuj wrzeszczenie z bólu przez ranne jednostki Activar gritos para unidades heridas @@ -3014,6 +4018,10 @@ Active les hurlements d'unités blessées Engedélyezi a sérült egységek kiáltásait Abilita Grida da parte delle unità ferite + 負傷したユニットが叫ぶように + 부상당한 인원이 소리지르는것을 활성화합니다 + 启用伤者的尖叫声 + 啟用傷者的尖叫聲 Player Damage @@ -3023,9 +4031,13 @@ Spielerschaden Poškození hráče Dano do jogador - Dégats des joueurs + Dégats du joueur Játékos sérülés Danno Giocatore + プレイヤーへの損傷 + 플레이어 부상 + 玩家伤害 + 玩家傷害 What is the damage a player can take before being killed? @@ -3034,10 +4046,14 @@ ¿Cuál es el daño que un jugador puede sufrir antes de morir? Wie viel Schaden kann ein Spieler erleiden, bevor er getötet wird? Jaké poškození může hráč dostat než bude zabit? - Qal é o dano que um jogador pode sofrer antes de morrer? - Quels dégats peut subir un joueur avant d'être tué + Qual é o dano que um jogador pode sofrer antes de morrer? + 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? + プレイヤーが死に始める前に損傷を受けるようにしますか? + 얼마정도의 부상을 플레이어가 죽기 전까지 버틸 수 있습니까? + 玩家死亡前所能承受的伤害程度 + 玩家死亡前所能承受的傷害程度 AI Damage @@ -3047,9 +4063,13 @@ KI-Schaden Poškození AI Dano da IA - Dégats des IA + Dégâts des IA AI sérülés Danno AI + AI への損傷 + 인공지능 부상 + AI伤害 + AI傷害 What is the damage an AI can take before being killed? @@ -3059,9 +4079,13 @@ Wie viel Schaden kann eine KI erleiden, bis sie getötet wird? Jaké poškození může AI dostat než bude zabito? Qual é o dano que uma IA pode sofrer antes de morrer? - Quels dégats peut subir une IA avant d'être tuée + 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 Unconsciousness @@ -3074,6 +4098,10 @@ Inconscience des IA AI eszméletlenség Incoscienza IA + AI の気絶 + 인공지능 기절 + AI无意识 + AI無意識 Allow AI to go unconscious @@ -3086,6 +4114,10 @@ Autoriser les IA à tomber inconscients Engedélyezi az AI eszméletének elvesztését Permetti alle IA di diventare incoscienti + AI が気絶をするように + 인공지능도 기절에 빠지게 합니다 + 允许AI进入无意识状态 + 允許AI進入無意識狀態 Remote Controlled AI @@ -3098,6 +4130,10 @@ Távvezérelt AI Зевса считать ботом IA Controllate in Remoto + 遠隔操作された AI + 인공지능 원격조종 + 遥控AI + 遙控AI Treat remote controlled units as AI not players? @@ -3110,6 +4146,10 @@ 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的方式醫療被遙控的單位 Prevent instant death @@ -3122,6 +4162,10 @@ Empêcher la mort instantanée Azonnali halál kiiktatása Previeni morte istantanea + 即死の防止 + 즉사 방지 + 防止当场死亡 + 防止當場死亡 Have a unit move to unconscious instead of death @@ -3130,10 +4174,14 @@ Mover una unidad a inconsciente en vez de a muerta Lässt eine Einheit bewusstlos werden anstatt zu sterben Jednotka upadne do bezvědomí namísto smrti - Fazer a unidade ficar inconsciente invés de morrer + Fazer a unidade ficar inconsciente ao invés de morrer Forcer l'inconscience au lieu de la mort instantanée Egy egység kerüljön eszméletlen állapotba a halott helyett Imposta un'unità come incosciente invece di morta + ユニットの即死を防止するために、気絶へ移行させます + 인원의 즉사를 방지코자 즉사 대신 기절시킵니다 + 伤者最严重只会立即进入昏迷,而非立即死亡 + 傷者最嚴重只會立即進入昏迷,而非立即死亡 Bleeding coefficient @@ -3143,9 +4191,13 @@ Verblutungsmultiplikator Koeficient krvácení Coeficiente de sangramento - Coefficient de saignement + Coéfficient de saignement Vérzési koefficiens Coefficiente sanguinamento + 出血の係数 + 출혈 계수 + 流血系数 + 流血係數 Coefficient to modify the bleeding speed @@ -3155,9 +4207,13 @@ Multiplikator um die Verblutungsgeschwindigkeit zu verändern Koeficient rychlosti krvácení Coeficiente para modificar a velocidade do sangramento - Coefficient modifiant la vitesse de saignement + Modifie le débit des saignements Egy szorzó a vérzés sebességének szabályozására Coefficiente che modifica la velocità di sanguinamento + この係数では出血速度を変更できます + 출혈의 속도를 계수만큼 변경합니다 + 修改流血速度 + 修改流血速度 Pain coefficient @@ -3167,9 +4223,13 @@ Schmerzmultiplikator Koeficient bolesti Coeficiente de dor - Coefficient de douleur + Coéfficient de douleur Fájdalmi koefficiens Coefficiente dolore + 痛みの係数 + 고통 계수 + 疼痛系数 + 疼痛係數 Coefficient to modify the pain intensity @@ -3179,9 +4239,13 @@ Multiplikator um die Schmerzintensität zu verändern Koeficient intenzity bolesti Coeficiente para modificar a instensidade de dor - Coefficient modifiant l'intensité de la douleur + Modifie l'intensité de la douleur Egy szorzó a fájdalom erősségének szabályozására Coefficiente che modifica l'intensità del dolore + この係数では痛みの強さを変更できます + 고통의 정도를 계수만큼 변경합니다 + 修改疼痛强度的系数 + 修改疼痛強度的係數 Sync status @@ -3191,9 +4255,13 @@ Status synchronisieren Synchronizovat status Sincronizar estado - Status de la synchronisation + Synchronisation du status Szinkronizációs állapot Sincronizza stato + 同期状態 + 상태 동기화 + 同步状态 + 同步狀態 Keep unit status synced. Recommended on. @@ -3203,9 +4271,13 @@ Status der Einheit synchron halten. Sollte aktiviert bleiben. Udržuje status jednotky synchronizovaný. Doporučeno zapnout. Mater o estado da unidade sincronizado. Recomendado ativado. - Garder l'unité synchronisée, Recommandé sur oui. + Garder l'unité synchronisée. Activation recommandée. Egységállapotok szinkronizálása. Javasolt a bekapcsolása. Mantieni lo stato delle unità sincronizzato. Consigliato attivo. + ユニット状態の同期を続けます。有効化を推奨。 + 인원의 상태를 동기화합니다. 켜기를 권장합니다. + 保持单位状态同步,建议启用! + 保持單位狀態同步,建議啟用! Provides a medical system for both players and AI. @@ -3215,20 +4287,28 @@ Aktiviert ein Sanitätssystem für Spieler und KI. Poskytuje zdravotní systém pro hráče a AI. Proporciona o sistema médico para os jogadores e a IA. - Fourni un système médical pour les joueurs tout comme pour les IA. + Fourni un système médical pour les joueurs et les IA. Egy orvosi rendszert ad játékosok és AI-k számára. Fornisce un sistema medico sia per giocatori che IA. + プレイヤーと AI の両方へ医療システムを提供します。 + 의료 시스템을 플레이어 및 인공지능에게 제공합니다. + 医疗系统将同时对玩家与AI发生作用。 + 醫療系統將同時對玩家與AI發生作用。 Basic Medical Settings [ACE] Standard Sanitätseinstellungen [ACE] Podstawowe ustawienia medyczne Ajustes médicos básicos [ACE] - Réglages du système médical basic [ACE] + Paramètres des soins basiques [ACE] Impostazioni Mediche Di Base [ACE] Základní zdravotnické nastavení [ACE] Ajustes médicos básicos [ACE] Настройки базовой медицины [ACE] + ベーシック医療設定 [ACE] + 기본 의료 설정 [ACE] + 基本医疗设定 [ACE] + 基本醫療設定 [ACE] Advanced Medical Settings [ACE] @@ -3241,6 +4321,10 @@ Paramètres des soins avancés Fejlett orvosi beállítások [ACE] Impostazioni Mediche Avanzate [ACE] + アドバンスド医療設定 [ACE] + 고급 의료 설정 [ACE] + 进阶医疗设定 [ACE] + 進階醫療設定 [ACE] Enabled for @@ -3253,6 +4337,10 @@ Activer pour Engedélyezve Abilitato per + 次を有効化 + 활성 + 被启用给 + 被啟用給 Select what units the advanced medical system will be enabled for @@ -3262,9 +4350,13 @@ Wähle aus, welche Einheiten unter das erweiterte Sanitätssystem fallen Vyberte, pro jaké jednotky bude pokročilý zdravotní systém povolen Selecione quais unidades o sistema médico avançado será habilitado - Sélectionne pour quelle unité le système de soin avancé est activé + Sélectionne pour quelles unités les soins avancés seront activés Kiválasztható, mely egységek számára legyen engedélyezve a fejlett orvosi rendszer Seleziona per quali unità verrà abilitato i sistema medico avanzato + 選択されたユニットが、アドバンスド医療が使えるようになります + 어느 인원에게 고급 의료 시스템을 적용시킬지 선택하십시요. + 选择进阶医疗系统影响的对象 + 選擇進階醫療系統影響的對象 Players only @@ -3274,9 +4366,13 @@ Nur Spieler Pouze hráči Somente jogadores - Joueur uniquement + Joueurs uniquement Csak játékosok Solo giocatori + プレイヤーのみ + 플레이어만 + 只限玩家 + 只限玩家 Players and AI @@ -3286,9 +4382,13 @@ Spieler und KI Hráči a AI Jogadores e IA - Joueur et IA + Joueurs et IA Játékosok és AI Giocatori ed IA + プレイヤーと AI + 플레이어 및 인공지능 + 玩家与AI + 玩家與AI Enable Advanced wounds @@ -3298,9 +4398,13 @@ Aktiviere erweiterte Wunden Povolit pokročilé zranění Ativar ferimentos avançados - Activer les blessures avancées + Activer les plaies compliquées Komplex sebek engedélyezése Abilita ferite Avanzate + アドバンスドな傷を有効化 + 고급 부상 활성화 + 启用进阶伤口系统 + 啟用進階傷口系統 Allow reopening of bandaged wounds? @@ -3310,9 +4414,13 @@ Erlaube das Öffnen von bandagierten Wunden? Umožnit znovuotevření zavázané rány? Permitr reabertura de ferimentos enfaixados? - Permettre la réouverture des bandages + Les plaies peuvent se rouvrir Visszanyílhatnak a bekötözött sebek? Permetti la riapertura di ferite bendate? + 包帯で巻かれた傷を再び開くようにしますか? + 붕대가 풀리는것을 활성화합니까? + 启用进阶伤口系统会使已被包扎的伤口有机率裂开 + 啟用進階傷口系統會使已被包紮的傷口有機率裂開 Vehicle Crashes @@ -3321,10 +4429,14 @@ Accidentes de vehículos Fahrzeugunfälle Poškození z kolize - Batidas de veículos + Colisão de veículos Accident en véhicule Járműbalesetek Schianto Veicoli + 車両の衝突 + 차량 사고 + 载具碰撞 + 載具碰撞 Do units take damage from a vehicle crash? @@ -3333,21 +4445,29 @@ ¿Las unidades reciben daño de un accidente de tráfico? Verursacht ein Fahrzeugunfall Verletzungen Dostane jednotka poškození při autonehodě? - As unidades recebem dano de uma batida de veículo? + As unidades recebem dano de uma colisão de veículo? 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? + ユニットは車両の衝突による損傷を受けるようにしますか? + 차량 사고시 인원들이 부상을 입습니까? + 设定人员是否会因为载具冲撞别的物件而产生伤害? + 設定人員是否會因為載具衝撞別的物件而產生傷害? Allow Epinephrine Erlaube Epiniphrin Permitir Epinefrina Ograniczenia adrenaliny - Autoriser l'adrénaline + Activer l'épinéphrine Permette epinefrina Povolit adrenalin - Permitir Epinefrina + Permitir epinefrina Разрешить Адреналин + アドレナリンの許可 + 에피네프린 활성화 + 允许使用肾上腺素 + 允許使用腎上腺素 Who can use Epinephrine for full heal? (Basic medical only) @@ -3357,8 +4477,12 @@ Qui peut utiliser l'adrénaline pour les soins complets ? (Médical basique seulement) Chi può usare l'epinefrina per la cura completa? (solo per sistema medico di base) 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) + Quem pode usar epinefrina para cura completa? (Somente sistema médico básico) Кому разрешено использовать адреналин для полного излечения? (Только для базовой медицины) + 完全に回復できるよう誰しもがアドレナリンを使えるようにしますか? (ベーシック医療のみ) + 완전한 체력회복을 위해 어느 인원이 에피네프린을 쓸 수 있습니까? (기본 의료 전용) + 谁可以使用肾上腺素完整医治? (仅适用于基本医疗) + 誰可以使用腎上腺素完整醫治? (僅適用於基本醫療) Allow PAK @@ -3368,9 +4492,13 @@ Erlaube Erste-Hilfe-Set Povolit osobní lékárničky (PAK) Permitir Kit de Primeiros Socorros - Permettre le kit de premier secours + Activer la trousse sanitaire Elsősegélycsomag engedélyezése Consenti Kit di Pronto Soccorso + 応急処置キットの許可 + 개인응급키트 활성화 + 允许使用个人急救包 + 允許使用個人急救包 Who can use the PAK for full heal? @@ -3380,9 +4508,13 @@ Wer kann das Erste-Hilfe-Set für eine Endheilung verwenden? Kdo může použít osobní lékárničku pro plné vyléčení? Quem pode usar o KPS para cura completa? - Qui peut utilier les kit de premier secours pour soigner + 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? + 完全に回復できるよう誰しもが応急処置キットを使えるようにしますか? + 완전한 체력회복을 위해 어느 인원이 개인응급키트을 쓸 수 있습니까? (기본 의료 전용) + 谁能够使用个人急救包来达到完整医疗? + 誰能夠使用個人急救包來達到完整醫療? Anyone @@ -3392,9 +4524,13 @@ Jeder Kdokoliv Qualquer um - Tout le monde + Tous Akárki Chiunque + だれでも + 모두 + 任何人 + 任何人 Medics only @@ -3404,9 +4540,13 @@ Nur Sanitäter Pouze zdravotník Somente médicos - Infirmier uniquement + Infirmiers uniquement Csak orvosok Solo medici + 衛生兵のみ + 의무병만 + 只限医疗兵 + 只限醫療兵 Doctors only @@ -3416,9 +4556,13 @@ Nur Ärzte Pouze doktor Somente doutores - Médecin uniquement + Médecins uniquement Csak doktorok Solo dottori + 医師のみ + 의사만 + 只限军医 + 只限軍醫 Remove PAK on use @@ -3427,10 +4571,14 @@ Eliminar EPA después del uso Entf. Erste-Hilfe-Set bei Verwendung Odebrat osobní lékárničku po použití - Remover o KPS depois do uso - Enlever le KPS à l'utilisation + Remover o KPS após uso + Utilisation unique de la trousse sanitaire Elsősegélycsomag eltávolítása használatkor Rimuovi Kit Pronto Soccorso dopo l'uso + 応急処置キットの削除 + 개인응급키트 사용후 사라짐 + 在使用后删除个人急救包 + 在使用後刪除個人急救包 Should PAK be removed on usage? @@ -3439,32 +4587,44 @@ El EPA será eliminado después de usarlo Sollen Erste-Hilfe-Sets bei Verwendung entfernt werden? Má se osobní lékárnička odstranit po použití? - Deve o KPS ser removido depois do uso? - Le Kit de Premier Secours doit il être enlevé à l'utilisation? + Deve o KPS ser removido após seu uso? + 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? + 応急処置キットを使うと削除しますか? + 개인응급키트를 사용하고 나서 제거합니까? + 要在使用后删除个人急救包吗? + 要在使用後刪除個人急救包嗎? Locations Epinephrine Orte für Epiniphrin Ubicaciones epinefrina Ograniczenia adrenaliny - Position des adrénalines + Utilisation de l'épinéphrine Ubicazione epinefrina Oblast k použití adrenalinu - Localizações de Epinefrina + Localizações de epinefrina Место использования адреналина + アドレナリンをつかう場所 + 에피네프린 사용 장소 + 肾上腺素使用地点 + 腎上腺素使用地點 Where can the Epinephrine be used? (Basic Medical) Wo kann Epiniphrin verwendet werden? (Standard Sanitätseinstellungen) Configura donde puede usarse Epinefrina (Solo sistema médico básico) Gdzie można korzystać z adrenaliny? (Podstawowy system medyczny) - Où peuvent être utilisées les adrénalines ? (Médical basique) + Où peut être utilisé l'épinéphrine ? (Médical basique) Dove si può usare l'epinefrina? (Sistema medico di base) 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) + Onde pode-se usar a epinefrina? (Somente sistema médico básico) Где может использоваться адреналин? (Базовая медицина) + どこでもアドレナリンをつかえるようにしますか? (ベーシック医療のみ) + 어디에서 에피네프린을 사용할 수 있습니까? (기본 의료) + 在哪里可以使用肾上腺素? (基本医疗) + 在哪裡可以使用腎上腺素? (基本醫療) Locations PAK @@ -3474,9 +4634,13 @@ Orte für Erste-Hilfe-Set Oblast k použití PAK Localizações do KPS - Lieu d'utilisation du KPS + Lieu d'utilisation da trousse sanitaire Elsősegélycsomag helyek Locazioni Kit Pronto Soccorso + 応急処置キットをつかう場所 + 개인응급키트 사용 장소 + 个人急救包使用地点 + 個人急救包使用地點 Where can the PAK be used? @@ -3486,33 +4650,45 @@ Wo kann das Erste-Hilfe-Set verwendet werden? Kde může být použita osobní lékárnička (PAK)? Onde o kit de primeiros socorros pode ser utilizado? - Où le Kit de Premier Secour peut être utilisé + Où la trousse sanitaire peut être utilisée ? Hol lehet az elsősegélycsomagot használni? Dove può essere usato il Kit Pronto Soccorso? + どこでも応急処置キットをつかえるようにしますか? + 어디에서 개인응급키트를 사용할 수 있습니까? + 在哪里可以使用个人急救包? + 在哪裡可以使用個人急救包? Condition PAK Bedingungen für d. Erste-Hilfe-Set Podmínky pro použití osobní lékárničky Condición EPA - Condition d'utilisation du KPS + Condition d'utilisation de la trousse sanitaire Warunek apteczek Elsősegélycsomag állapot Condição do KPS Условие использования аптечки Condizioni Kit Pronto Soccorso + 応急処置キットの状態 + 개인응급키트 상태 + 个人急救包使用条件 + 個人急救包使用條件 When can the PAK be used? Wann kann das Erste-Hilfe-Set verwendet werden? Kdy může být použita osobní lékárnička? ¿Cuando se puede utilizar el Equipo de primeros auxilios? - Quand peut être utilisé le Kit de Premier Secours + Quand peut être utilisé la trousse sanitaire? Po spełnieniu jakich warunków apteczka osobista może zostać zastosowana na pacjencie? Mikor lehet az elsősegélycsomagot használni? Onde o kit de primeiros socorros pode ser utilizado? Когда может использоваться аптечка? Quando può essere usato il Kit Pronto Soccorso? + どこでも応急処置キットをつかえるようにしますか? + 언제 개인응급키트를 사용할 수 있습니까? + 何时可以使用个人急救包? + 何時可以使用個人急救包? Anywhere @@ -3522,9 +4698,13 @@ Überall Kdekoliv Qualquer lugar - PArtout + Partout Akárhol Ovunque + どこでも + 어디서나 + 任何地方 + 任何地方 Medical vehicles @@ -3533,10 +4713,14 @@ Vehiculos médicos Sanitätsfahrzeuge Zdravotnická vozidla - Veículos médcos - Dans les véhicules médicals + Veículos médicos + Dans les véhicules sanitaires Orvosi járművek Veicoli medici + 医療車両のみ + 의료차량 + 医疗载具 + 醫療載具 Medical facility @@ -3546,9 +4730,13 @@ Medizinische Einrichtungen Zdravotnické zařízení Instalação médica - Dans les installations médicales + Dans les structures sanitaires Orvosi létesítmény Strutture mediche + 医療施設でのみ + 의료시설 + 医疗设施 + 醫療設施 Vehicles & facility @@ -3558,9 +4746,13 @@ Fahrzeuge & Einrichtungen Vozidla a zařízení Veículos e instalações - Dans les véhicules et les installations médicals + Dans les véhicules et les structures sanitaires Járművek & létesítmény Veicoli e Strutture + 車両 & 施設 + 차량 및 시설 + 医疗载具 & 医疗设施 + 醫療載具 & 醫療設施 Allow Surgical Kit (Adv) @@ -3570,9 +4762,13 @@ Erlaube Operationskasten Povolit chirurgickou soupravu (Pokr.) Permite kit cirúrgico (avançado) - Permettre les kit de chirurgie (Avancé) + Permettre les trousses chirurgicales (Avancé) Sebészkészlet (Fejlett) engedélyezése Permetti Kit Chirurgico (Avanzato) + 縫合キットの許可 (アド) + 봉합키트 활성화 (고급) + 允许使用手术包 (进阶伤口) + 允許使用手術包 (進階傷口) Who can use the Surgical Kit? @@ -3582,9 +4778,13 @@ Wer kann den Operationskasten verwenden? Kdo může použít chirurgickou soupravu? Quem pode usar o kit cirúrgico? - Qui peut utiliser les kit de chirurgie + Qui peut utiliser les trousses chirurgicales? Ki használhatja a sebészkészletet? Chi può usare il Kit Chirurgico? + だれでも縫合キットをつかえるようにしますか? + 어느 인원이 봉합키트를 사용할 수 있습니까? + 谁能够使用手术包? + 誰能夠使用手術包? Remove Surgical Kit (Adv) @@ -3594,9 +4794,13 @@ Entferne Operationskasten (erweitert) Odebrat chirurgickou soupravu (Pokr.) Remover kit cirúrgico (avançado) - Supprimer les kit de chirurgie (Avancé) + Consommer les trousses chirurgicales (Av.) Sebészkészlet (Fejlett) eltávolítása Rimuovi Kit Chirurgico (Avanzato) + 縫合キットを削除 (アド) + 봉합키트 제거 (고급) + 在使用后删除手术包 (进阶伤口) + 在使用後刪除手術包 (進階傷口) Should Surgical kit be removed on usage? @@ -3605,10 +4809,14 @@ Eliminar el equipo quirúrgico después del uso Entferne Operationskästen bei Verwendung? Odebrat chirurgickou soupravu po použití? - Deve o kit cirúrgico ser removido após o uso? - Le kit de chirurgie doit il être supprimé à l'utilisation + Deve o kit cirúrgico ser removido após seu uso? + 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? + 縫合キットをつかった後に削除しますか? + 봉합키트를 사용하고 나서 제거합니까? + 手术包会在使用后被删除吗? + 手術包會在使用後被刪除嗎? Locations Surgical Kit (Adv) @@ -3618,9 +4826,13 @@ Orte für Operationskästen (erweitert) Lokace chirurgické soupravy (Pokr.) Localizações do kit cirúrgico (avançado) - Lieu d'utilisation du kit de chirurgie + Lieu d'utilisation des trousses chirurgicales Sebészkészlet (Fejlett) helyei Località Kit Chirurgico (Avanzato) + 縫合キットをつかう場所 (アド) + 봉합키트 사용 장소 (고급) + 手术包使用地点 (进阶伤口) + 手術包使用地點 (進階傷口) Where can the Surgical Kit be used? @@ -3630,33 +4842,45 @@ Wo kann der Operationskasten verwendet werden? Kde může být použita chirurgická souprava? Onde o kit cirúrgico pode ser utilizado? - Où peut être utilisé les kit de chirurgie + Où peut être utilisé les trousses chirurgicales? Hol lehet a sebészkészletet használni? Dove può essere usato il Kit Chirurgico? + どこでも縫合キットをつかえるようにしますか? + 어디에서 봉합키트를 사용할 수 있게 합니까? + 定义手术包可被使用的地方? + 定義手術包可被使用的地方? Condition Surgical Kit (Adv) Beding. für d. Operationskasten (erw.) Podmínka chirurgické soupravy (Pokr.) Condición de equipo quirúrgico (Av) - Conditions d'utilisation du kit de chirurgie + Conditions d'utilisation de la trousse chirurgicale (Av.) Warunek zestawu chirurgicznego Sebészkészlet állapot Condição do Kit Cirúrgico (Avançado) Условие использования хирургического набора (усл.) Condizioni Kit Chirurgico (Avanzato) + 縫合キットの状態 (アド) + 봉합키트 상태 (고급) + 使用手术包的条件 (进阶伤口) + 使用手術包的條件 (進階傷口) When can the Surgical Kit be used? Wann kann der Operationskasten verwendet werden? Kde může být použita chirurgická souprava? ¿Cuando se puede utilizar el equipo quirúrgico? - Quand peut être utilisé les kit de chirurgie + Quand peut être utilisé la trousse chirurgicale Po spełnieniu jakich warunków zestaw chirurgiczny może zostać zastosowany na pacjencie? Mikor lehet a sebészkészletet használni? Onde o kit cirúrgico pode ser utilizado? Когда может использоваться хирургический набор? Quando può essere usato il Kit Chirurgico? + いつでも縫合キットをつかえるようにしますか? + 언제 봉합키트를 사용할 수 있습니까? + 何时可以使用手术工具包? + 何時可以使用手術工具包? Heal hitpoints @@ -3664,10 +4888,14 @@ Lecz hitpointy Curar puntos de vida Исцелять части тела - Curar hitpoints + Curar pontos de vida Léčit hitponty Cura Hitpoints - Soigner les dommages + Soigner les blessures + ヒットポイントの回復 + 체력 회복 + 完整治疗 + 完整治療 Heal fully bandaged hitpoints @@ -3675,10 +4903,14 @@ Po bandażowaniu ulecz hitpointy, usuwając z nich ślady krwi i przywracając im pełną sprawność. Curar miembros totalmente vendados Исцелять полностью перебинтованные части тела - Curar totalmente hitpoints enfaixados + Curar totalmente pontos de vida enfaixados Heal fully bandaged hitpoints Cura Hitpoints completamente bendati Soigner les plaies entièrement bandées. + 包帯によりヒットポイントを完全に回復する + 붕대를 감아서 체력을 회복 + 完全医疗包扎的部位至痊愈 + 完全醫療包紮的部位至痊癒 Pain suppression @@ -3687,10 +4919,14 @@ Potlačení bolesti Supresión del dolor Supressão de dor - Suppression de la douleur + Traitement de la douleur Fájdalomcsillapítás Приглушение боли Soppressione dolore + 痛みの継続 + 고통 억제 + 疼痛抑制 + 疼痛抑制 Pain is only temporarily suppressed, not removed @@ -3698,11 +4934,15 @@ Ból jest tylko tymczasowo zwalczany, nie jest usuwany trwale Bolest je potlačena, ale jen dočastně El dolor se suprime solo temporalmente, no se elimina. - Dor é somente temporáriamente suprimida, não removida - La douleur est temporairement supprimée, pas enlevée + Dor é somente temporariamente suprimida, não removida + La douleur est seulement temporairement calmée A fájdalom csak ideiglenesen csökken, nem távolítódik el Боль приглушается только временно Dolore è solo temporaneamente soppresso, non rimosso + 痛みを一時的に継続させ、取り除かない + 고통은 제거가 아닌 일시적으로 억제만 가능합니다. + 疼痛只会被暂时抑制,而不能完全消除 + 疼痛只會被暫時抑制,而不能完全消除 Configure the treatment settings from ACE Basic Medical @@ -3713,6 +4953,10 @@ Configura le impostazioni trattamenti per ACE Medical di base Configura as opções de tratamento do sistema médico básico do ACE Настройка лечения в базовой медицинской системе ACE + ACE ベーシック医療による設定で、治療を設定する + ACE 기본 의료에 대한 치료 설정 수정 + 设定ACE基本医疗的规则 + 設定ACE基本醫療的規則 Configure the treatment settings from ACE Advanced Medical @@ -3722,9 +4966,13 @@ Behandlungseinstellungen vom ACE-Medizin konfigurieren Konfigurace nastavení léčby ze zdravotnické systému ACE Configure as opções de tratamento do ACE Médico - Configure les paramètres de traitement du système de soin ACE + Configure les réglages de traitement dans dans ACE médical avancé Kezelési lehetőségek konfigurálása az ACE Orvosi rendszerből Configura le impostazioni trattamenti per ACE Medical + ACE アドバンスド医療による設定で、治療を設定する + ACE 고급 의료에 대한 치료 설정 수정 + 设定ACE进阶医疗的规则 + 設定ACE進階醫療的規則 Revive Settings [ACE] @@ -3737,6 +4985,10 @@ Paramètre du revive [ACE] Újraélesztés beállításai [ACE] Impostazioni Revive [ACE] + リバイブ設定 [ACE] + 소생 설정 [ACE] + 复苏设定 [ACE] + 復甦設定 [ACE] Enable Revive @@ -3749,6 +5001,10 @@ Activer le revive Újraélesztés engedélyezése Abilita Revive + リバイブを有効化 + 소생 활성화 + 启用复苏 + 啟用復甦 Enable a basic revive system @@ -3758,9 +5014,13 @@ Aktiviere Standard-Wiederbelebungssystem Povolit základní systém oživení Habilitar um sistema básico de reavivamento - Active un sytème de revive basique + Active un système de revive basique Egy alap újraélesztési rendszer engedélyezése Abilita un sistema revive basico + ベーシックなリバイブを有効化 + 기본 소생 시스템 활성화 + 启用基本复苏系统 + 啟用基本復甦系統 Max Revive time @@ -3770,9 +5030,13 @@ Maximale Wiederbelebungszeit Maximální čas pro oživení Tempo máximo de reavivamento - Temps maximum pour le revive + Délai maximum pour le revive Maximum újraélesztési idő Tempo massimo Revive + 最大リバイブ時間 + 최대 소생 시간 + 最大复苏时间 + 最大復甦時間 Max amount of seconds a unit can spend in revive state @@ -3782,9 +5046,13 @@ Maximale Zeitspanne in Sekunden die eine Einheit im Wiederbelebungszustand verbringen kann Maximální doba v agónii v sekundách Quantidade máxima de segundos que uma unidade pode gastar em um estado de reavivamento - Nombre de seconde maximum qu'une unité peut être en attente d'un revive + Délai d'attente maximum pour un revive Maximum másodperc, amit egy egység újraélesztési állapotban tölthet Numero massimo di secondi che un'unità può spendere in stato revive + ユニットがリバイブ状態になっている最大時間を設定できます + 소생상태에서 인원이 버틸 수 있는 최대 시간을 초 단위로 정합니다 + 人员在等待复苏状态下能够等待的最大时间(秒) + 人員在等待復甦狀態下能夠等待的最大時間(秒) Max Revive lives @@ -3797,6 +5065,10 @@ Nombre maximum de revive Maximum újraélesztési lehetőségek Numero massimo Revives + 最大リバイブ数 + 최대 소생 횟수 + 最大被救活次数 + 最大被救活次數 Max amount of lives a unit. 0 or -1 is disabled. @@ -3806,9 +5078,13 @@ Anzahl der Leben einer Einheit. 0 oder -1 bedeutet deaktiviert. Maximální počet životu pro jednotku. 0 nebo -1 je zakázáno. Quantidade máxima de vidas por unidade. 0 ou -1 é desativado. - Nombre de vie maximale d'une unité. 0 ou -1 désactive + Nombre de vie maximum d'une unité. 0 ou -1 désactive Egy egység maximum "életei". 0 vagy -1 letiltja. Numero massimo di vite di un'unità. 0 o -1 per disabilitare. + ユニットの最大リバイブ数を設定できます。0 または -1 は無効化になります + 소생 가능한 횟수입니다. 0 혹은 -1 로 비활성화 합니다 + 一个人员最大可被救活次数,0或-1为关闭 (无限救活) + 一個人員最大可被救活次數,0或-1為關閉 (無限救活) Provides a medical system for both players and AI. @@ -3818,9 +5094,13 @@ Aktiviert das Sanitätssystem für Spieler und KI. Poskytuje zdravotní systém pro hráče a AI. Proporciona um sistema médico para jogadores e IA. - Fourni un sytème médical pour les joueurs et les IAs + Fourni un sytème médical pour les joueurs et les IA. Egy orvosi rendszert ad játékosok és AI-k számára. Fornisce un sistema medico sia per giocatori che IA + プレイヤーと AI の両方へ医療システムを提供します。 + 플레이어와 인공지능 모두에게 의료 시스템을 지원합니다. + 医疗系统将同时作用在玩家与AI + 醫療系統將同時作用在玩家與AI Set Medic Class [ACE] @@ -3830,9 +5110,13 @@ Setze Sanitäterklassen [ACE] Určit třídu medika [ACE] Definir classe médica [ACE] - Définir comme unité médicale [ACE] + Définir classe médicale [ACE] Orvos beállítása [ACE] Imposta Classe Medico [ACE] + 衛生兵クラスとして設定 [ACE] + 의무병 보직 설정 [ACE] + 设定医疗兵单位 [ACE] + 設定醫療兵單位 [ACE] List @@ -3845,6 +5129,10 @@ Liste Lista Lista + 一覧 + 목록 + 列表 + 列表 List of unit names that will be classified as medic, separated by commas. @@ -3854,9 +5142,13 @@ Aufzählung von Einheiten, die als Sanitäter gelten. Werden durch Kommata getrennt. Seznam osob které budou klasifikovány jako zdravotník, oddělené čárkami. Lista dos nomes das unidades que se classificam como médicos, separados por vírgulas. - Liste d'unité qui seront listées comme infirmier, séparation par virgule + Liste d'unité qui seront qualifiés comme infirmier, séparation par virgule. Azon egységek nevei, melyek orvosként vannak meghatározva, vesszővel elválasztva. Lista di nomi unità che verranno classificati come medici, separati da virgole. + 衛生兵として設定されるユニット名を一覧で指定でき、コンマで区切りを付けられます。 + 보직 이름 목록으로 의무병이 구분됩니다, 쉼표로 구분. + 列出的单位名字将被指派为医疗兵,记得用逗号隔开! + 列出的單位名字將被指派為醫療兵,記得用逗號隔開! Is Medic @@ -3869,6 +5161,10 @@ Est infirmier Orvos-e E' Medico + 衛生兵として + 의무병 + 是医疗兵 + 是醫療兵 This module allows you to assign the medic class to selected units. @@ -3881,6 +5177,10 @@ Этот модуль позволяет назначить класс медика выбранным юнитам. Este módulo permite asignar la clase médico a las unidades seleccionadas. Questo modulo ti permette di assegnare la classe Medico alle unità selezionate. + 選択されたユニットを衛生兵として指定します。 + 이 모듈은 선택한 보직이 의무병을 할 수 있게 해줍니다. + 本模块可让被同步的单位成为医疗兵 + 本模塊可讓被同步的單位成為醫療兵 None @@ -3893,6 +5193,10 @@ Aucun Nincs Nessuno + なし + 없음 + + Regular medic @@ -3902,9 +5206,13 @@ Normaler Sanitäter Řadový zdravotník Médico regular - Infirmier standard + Infirmier Hagyományos orvos Medico Regolare + 通常の衛生兵 + 일반 의무병 + 普通医疗兵 + 普通醫療兵 Doctor (Only Advanced Medics) @@ -3917,6 +5225,10 @@ Médecin (traitements avancés uniquement) Doktor (csak fejlett orvosok) Dottore (Solo Medici Avanzati) + 医師 (アドバンスド医療のみ) + 의사 (오직 고급 의료에서만) + 军医 (只限进阶医疗系统) + 軍醫 (只限進階醫療系統) Doctor @@ -3929,6 +5241,10 @@ Médecin Doktor Dottore + 医師 + 의사 + 军医 + 軍醫 Assigns the ACE medic class to a unit @@ -3941,6 +5257,10 @@ Assigner la classe médicale à une unité Az ACE orvosi jelző hozzárendelése egy egységhez Assegna la classe medico ACE ad un'unità + ユニットを ACE の衛生兵として割り当てる + 인원에게 ACE 의무병 보직 선정 + 指派ACE医疗职位给该单位 + 指派ACE醫療職位給該單位 Set Medical Vehicle [ACE] @@ -3953,6 +5273,10 @@ Définir comme véhicule médical [ACE] Orvosi jármű beállítása [ACE] Imposta Veicolo Medico [ACE] + 医療車両を設定 [ACE] + 의료 차랑 선정 [ACE] + 设定医疗载具 [ACE] + 設定醫療載具 [ACE] List @@ -3965,6 +5289,10 @@ Liste Lista Lista + 一覧 + 목록 + 列表 + 列表 List of vehicles that will be classified as medical vehicle, separated by commas. @@ -3977,6 +5305,10 @@ Liste de véhicule classé comme véhicule médical, séparation par virgule. Orvosi járműveknek tekintett járművek listája, vesszővel elválasztva. Lista di veicoli che verranno classificati come veicoli medici, separati da virgole. + 医療車両として設定されるクラス名を一覧で指定でき、コンマで区切りを付けられます + 차량 명칭 목록으로 의료차량이 구분됩니다, 쉼표로 구분. + 列出的载具将被指定为医疗载具,记得用逗号隔开! + 列出的載具將被指定為醫療載具,記得用逗號隔開! Is Medical Vehicle @@ -3989,6 +5321,10 @@ Véhicule médical Orvosi jármű-e E' Veicolo Medico + 医療車両として + 의료 차량 + 是医疗载具 + 是醫療載具 Whatever or not the objects in the list will be a medical vehicle. @@ -4001,6 +5337,10 @@ Quoi qu'il arrive les objets de la liste seront des véhicules médical A listában lévő objektumok orvosi járművek-e, vagy sem. Gli oggetti nella lista verranno considerati veicoli medici o meno. + どれでも、またはこの一覧にないオブジェクトを医療車両として割り当てる。 + 무엇이 되었던간에 이 목록에 있는 물체는 의료 차량이 됩니다. + 列表中的载具将会变成医疗载具 + 列表中的載具將會變成醫療載具 Assigns the ACE medic class to a unit @@ -4013,6 +5353,10 @@ Assigne la classe médicale à une unité Hozzárendeli az ACE orvosi jelzőt egy egységhez Assegna la classe medico ACE ad un'unità + ユニットを ACE の衛生兵として割り当てる + 指派ACE医疗职位给该单位 + 指派ACE醫療職位給該單位 + 병력에 ACE 의무병 보직 선정 Set Medical Facility [ACE] @@ -4022,9 +5366,13 @@ Setze medizinische Einrichtung [ACE] Určit zdravotnické zařízení [ACE] Definir instalação médica [ACE] - Définir comme équipement médical [ACE] + Définir comme installation médical [ACE] Orvosi létesítmény beállítása [ACE] Imposta Struttura Medica [ACE] + 医療施設を設定 [ACE] + 의료시설 선정 [ACE] + 设定医疗设施 [ACE] + 設定醫療設施 [ACE] Is Medical Facility @@ -4034,9 +5382,13 @@ Ist eine medizinische Einrichtung Zdravotnické zařízení É uma instalação médica - Est un équipement médical + Est une installation médical Orvosi létesítmény-e E' Struttura Medica + 医療施設として + 의료시설 + 是医疗设施 + 是醫療設施 Registers an object as a medical facility @@ -4046,9 +5398,13 @@ Definiert ein Objekt als medizinische Einrichtung Registruje objekt jako zdravotnické zařízení Registra um objeto como instalacão médica - Enregistrer un objet comme un équipement médical + Enregistrer un objet comme une installation médical Egy objektum orvosi létesítményként való regisztrálása Registra un oggetto come struttura medica + オブジェクトを医療施設として割り当てる + 물체를 의료시설로 등록합니다 + 指定一个物件作为医疗设施 + 指定一個物件作為醫療設施 Defines an object as a medical facility. This allows for more advanced treatments. Can be used on buildings and vehicles. @@ -4058,9 +5414,13 @@ Definiert ein Objekt als medizinische Einrichtung. Hier werden weitere, tiefgreifende Behandlungen ermöglicht. Kann Fahrzeugen oder Gebäuden zugewiesen werden. Definuje objekt jako zdravotnické zařízení. To umožňuje více pokročilé léčení. Může být použito na budovy nebo na vozidla. Define um objeto como instalação médica. Isso permite tratamentos mais avançados. Pode ser utilizado em edifícios e veículos. - Définir un objet comme équipement médical. Cela permet les traitements avancés. Peut être utilisé sur les batiments et les véhicules + Définir un objet comme installation médical. Cela permet les traitements avancés. Peut être utilisé sur les batiments et les véhicules Egy objektumot orvosi létesítményként határoz meg. Ez fejlett ellátási lehetőségeket engedélyez. Használható járműveken és épületeken. Definisce un oggetto come struttura medica. Questo permette cure più avanzate. Può essere usato su edifici e veicoli. + オブジェクトを医療施設として割り当てます。建物と車両へ割り当てられた場合、より高度な治療が可能になります。 + 물체를 의료시설로 정의합니다. 건물 혹은 차량이 될 수 있습니다. 이는 고급 의료 조치를 할 수 있게해줍니다. + 定义一个物件作为医疗设施,此医疗设施将被允许使用更进阶的医疗方法。此功能可用于建筑物或是载具上! + 定義一個物件作為醫療設施,此醫療設施將被允許使用更進階的醫療方法。此功能可用於建築物或是載具上! [ACE] Medical Supply Crate (Basic) @@ -4073,6 +5433,10 @@ [ACE] Caisse médicale (basique) [ACE] Orvosi láda (Alap) [ACE] Cassa Rifornimenti Medici (Basico) + [ACE] 医療物資箱 (ベーシック) + [ACE] 의료 물자 (기본) + [ACE] 医疗补给箱(基本) + [ACE] 醫療補給箱(基本) [ACE] Medical Supply Crate (Advanced) @@ -4085,6 +5449,10 @@ [ACE] Caisse médicale (avancée) [ACE] Orvosi láda (Fejlett) [ACE] Cassa Rifornimenti Medici (Avanzato) + [ACE] 医療物資箱 (アドバンスド) + [ACE] 의료 물자 (고급) + [ACE] 医疗补给箱(进阶) + [ACE] 醫療補給箱(進階) Anytime @@ -4097,6 +5465,10 @@ Sempre В любое время Sempre + いつでも + 언제나 + 任何时间 + 任何時間 Stable @@ -4109,6 +5481,10 @@ Estável После стабилизации Stabile + 安静下 + 안정된 + 稳定状态下 + 穩定狀態下 Medical @@ -4121,6 +5497,10 @@ Медик Médico Orvosi + 治療 + 의료 + 医疗设定 + 醫療設定 Distance to %1 has become to far for treatment @@ -4132,6 +5512,10 @@ %1 je příliš daleko, léčba není možná Distanza da %1 è diventata troppo alta per permettere trattamento %1 est trop loin pour être soigné + %1 は治療をできない所まで離れました + %1 부터의 거리가 너무 멀어 치료할 수 없습니다 + 设定当距离超过%1将不能使用治疗动作 + 設定當距離超過%1將不能使用治療動作 This person (%1) is awake and cannot be loaded @@ -4142,7 +5526,11 @@ Esta pessoa (%1) está acordada e não pode ser carregada Tato osoba (%1) je vzhůru a nemůže být naložena Questa persona (%1) è sveglia e non può essere caricata. - Cette personne (%1) est consciente et ne peut être chargées. + %1 est conscient et ne peut être embarqué. + 患者 (%1) は意識があり、積み込めません + 이 사람 (%1) 은(는) 의식이 있어 태우지 못합니다 + 此人(%1)是清醒且不能被装载 + 此人(%1)是清醒且不能被裝載 There is no tourniquet on this body part! @@ -4154,6 +5542,10 @@ Žá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 ! + 身体には止血帯が無い! + 이 부위에는 지혈대가 없습니다! + 这部位没有止血带! + 這部位沒有止血帶! Medical training @@ -4165,16 +5557,24 @@ Lékařský výcvik Treino médico Медицинская подготовка + 治療の訓練 + 의료 훈련 + 医疗训练 + 醫療訓練 Whether or not the object will be a medical vehicle. - Czy pojazdy ma być pojazdem medycznym? + Czy pojazd ma być pojazdem medycznym? L'oggetto in questione sarà un veicolo medico o meno. Legt fest, ob das Objekt ein Sanitätsfahrzeug ist. Es un vehículo médico? - Définit si le véhicule est un véhicule médical ou non. + Détermine si c'est un véhicule sanitaire. Se o objeto será ou não um veículo médico Будет ли объект считаться медицинским транспортом. + どれでも、またはオブジェクトを医療車両として割り当てます。 + 무엇이 되었던간에 이 목록에 있는 물체는 의료 차량이 됩니다. + 是否使该载具为医疗载具? + 是否使該載具為醫療載具? Delay cease fire of AI while player is unconscious for medical reasons. @@ -4182,19 +5582,88 @@ Ritarda il cessate il fuoco dell'IA quando il giocatore è svenuto per motivi medici. Prodleva zastavení palby pro AI, pokud je hráč v bezvědomí ze zdravotních důvodů. Atraso durante cessar fogo da AI durante inconsciência médica - Délai de cessez le feu pour l'IA pendant que le joueur est inconscient pour des raisons médicales + Délai de cessez le feu pour l'IA pendant que le joueur est inconscient pour des raisons médicales. Задержка прекращения огня ботами, когда игрок теряет сознание по медицинским причинам. + AI はプレイヤーが医療的な理由で気絶している場合にかぎり、撃つのをためらいます。 + Opóźnij stan wstrzymania ognia u AI kiedy gracz jest nieprzytomny z powodów medycznych. + 의료상의 이유로 플레이어가 기절할 경우 인공지능이 발사를 지연합니다. + 当玩家为无意识的状态时, 延长AI的开火时间 + 當玩家為無意識的狀態時, 延長AI的停火時間 Delay cease fire of AI for unconsciousness Verzögert Ende des KI-Beschusses bei medizinischer Bewustlosigkeit Demora antes de volverse neutral al caer inconsciente - Opóźnij status captive u nieprzytomnych osób + Opóźnij wstrzymanie ognia AI dla nieprzytomnych osób Ritarda il cessate il fuoco dell'IA quando si è svenuti Prodleva zastavení palby AI na bezvědomé Atraso durante cessar fogo da AI durante inconsciência Délai de cessez le feu de l'IA pour la perte de conscience Задержка прекращения огня ботами при потере сознания + AI が気絶者へためらってから射撃 + 기절할 경우 인공지능이 발사를 지연합니다 + 延长AI对已无意识玩家的开火时间 + 延長AI對已無意識玩家的停火時間 + + + Open lid + Deckel aufklappen + フタをあける + Apri lid + 打開蓋子 + 打开盖子 + 뚜껑 열기 + + + Close lid + Deckel zuklappen + フタをしめる + Chiudi lid + 關閉蓋子 + 关闭盖子 + 뚜껑 닫기 + + + Unconscious animation during treatment + 処置中に気絶アニメーション + 治疗时死亡动画 + 醫療時加入的昏迷動作 + Animazione da svenuto durante la cura + + + Allow animation of unconscious patients during treatment. + 患者の処置中に気絶アニメーションを許可します。 + 在无意识患者治疗时死亡,会播放死亡动画? + 允許醫療時加入昏迷的動作 + Permette l'animazione da svenuto dei pazioenti durante loro la cura. + + + Move unconscious units from group + グループから気絶ユニットを移動 + 从小队中移除无意识伤者 + 從小隊中移動昏迷的單位 + Toglie le unità svenute dal grouppo + + + When a group member goes unconscious, removes them from their group. + グループのメンバーが気絶すると、グループから退出させます。 + 当一个队员失去意识时,他将被移除出小队 + 當隊員昏迷時,將被他的小組中刪除 + Quando un membro del gruppo sviene, viene tolto dal gruppo. + + + Overdosing + 過剰投与 + 过量 + 過量 + Overdose + + + Makes patient vulnerable to Morphine/Epinephrine/Atropine overdosing. + モルヒネ/アドレナリン/アトロピンの過剰投与により患者を脆弱にします。 + 当队员处于吗啡/肾上腺素/阿托品过量时再次受伤,他的伤害会更重 + 當隊員對嗎啡/腎上腺素/阿托品過量時,會使他的傷害更重 + Rende il paziente suscettibile di overdose da morfina, epinefrina o atropina. - \ No newline at end of file + diff --git a/addons/medical_ai/ACE_Settings.hpp b/addons/medical_ai/ACE_Settings.hpp index a4962dfbc8..fc24f6dc2f 100644 --- a/addons/medical_ai/ACE_Settings.hpp +++ b/addons/medical_ai/ACE_Settings.hpp @@ -1,5 +1,8 @@ class ACE_Settings { class GVAR(enabledFor) { + category = ECSTRING(medical,Category_Medical); + displayName = CSTRING(enabledFor_DisplayName); + description = CSTRING(enabledFor_Description); value = 2; typeName = "SCALAR"; values[] = {ECSTRING(Common,Disabled), CSTRING(enabledFor_OnlyServerAndHC), ECSTRING(Common,Enabled)}; 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/XEH_preInit.sqf b/addons/medical_ai/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/medical_ai/XEH_preInit.sqf +++ b/addons/medical_ai/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/medical_ai/functions/fnc_canRequestMedic.sqf b/addons/medical_ai/functions/fnc_canRequestMedic.sqf index a73b7a7822..ab03042899 100644 --- a/addons/medical_ai/functions/fnc_canRequestMedic.sqf +++ b/addons/medical_ai/functions/fnc_canRequestMedic.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if there is a medic available in the unit's group. @@ -8,9 +9,11 @@ * Return Value: * Can request medic * + * Example: + * call ACE_medical_ai_fnc_canRequestMedic + * * Public: No */ -#include "script_component.hpp" // Note: Although an unconscious unit cannot call for a medic itself, // we ignore this here. We need to "notice" the medic that he should @@ -19,7 +22,7 @@ if ([_this] call EFUNC(medical,isMedic) || {vehicle _this != _this}) exitWith {false}; { - if ([_x] call EFUNC(medical,isMedic)) exitWith { + if ([_x] call EFUNC(medical,isMedic) && {!([_x] call EFUNC(common,isPlayer))}) exitWith { _this setVariable [QGVAR(assignedMedic), _x]; true }; diff --git a/addons/medical_ai/functions/fnc_healSelf.sqf b/addons/medical_ai/functions/fnc_healSelf.sqf index 7a1091b315..6cb0c3257f 100644 --- a/addons/medical_ai/functions/fnc_healSelf.sqf +++ b/addons/medical_ai/functions/fnc_healSelf.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Makes the unit heal itself. @@ -6,14 +7,16 @@ * None * * Return Value: - * Nothing + * None + * + * Example: + * call ACE_medical_ai_fnc_healSelf * * Public: No */ -#include "script_component.hpp" // Player will have to do this manually of course -if (isPlayer _this) exitWith {}; +if ([_this] call EFUNC(common,isPlayer)) exitWith {}; // Can't heal self when unconscious if (_this getVariable ["ACE_isUnconscious", false]) exitWith {}; // Check if we're still treating diff --git a/addons/medical_ai/functions/fnc_healUnit.sqf b/addons/medical_ai/functions/fnc_healUnit.sqf index 52b0c51e6e..2d9116be4f 100644 --- a/addons/medical_ai/functions/fnc_healUnit.sqf +++ b/addons/medical_ai/functions/fnc_healUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Makes a medic heal the next unit that needs treatment. @@ -6,11 +7,13 @@ * None * * Return Value: - * Nothing + * None + * + * Example: + * call ACE_medical_ai_fnc_healUnit * * Public: No */ -#include "script_component.hpp" // Can't heal other units when unconscious if (_this getVariable ["ACE_isUnconscious", false]) exitWith {}; @@ -29,6 +32,7 @@ if (isNull _target || {!alive _target} || {!(_target call FUNC(isInjured))}) exi _this forceSpeed -1; // return to formation instead of going where the injured unit was if it healed itself in the mean time _this doFollow leader _this; + _this setVariable [QGVAR(movingToInjured), false]; #ifdef DEBUG_MODE_FULL systemChat format ["%1 finished healing %2", _this, _target]; @@ -50,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: { @@ -62,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]; @@ -73,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]; @@ -81,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 6852fc1c58..8cbe280914 100644 --- a/addons/medical_ai/functions/fnc_isInjured.sqf +++ b/addons/medical_ai/functions/fnc_isInjured.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if a unit needs treatment. @@ -8,15 +9,12 @@ * Return Value: * Does unit need treatment * + * Example: + * call ACE_medical_ai_fnc_isInjured + * * Public: No */ -#include "script_component.hpp" 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/functions/fnc_isSafe.sqf b/addons/medical_ai/functions/fnc_isSafe.sqf index 92bbc60587..b18adbdc1c 100644 --- a/addons/medical_ai/functions/fnc_isSafe.sqf +++ b/addons/medical_ai/functions/fnc_isSafe.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if a unit is currently considered safe enough to treat itself. @@ -8,8 +9,10 @@ * Return Value: * Is unit safe enough * + * Example: + * call ACE_medical_ai_fnc_isSafe + * * Public: No */ -#include "script_component.hpp" (getSuppression _this == 0) && {CBA_missionTime - (_this getVariable [QGVAR(lastFired), -30]) > 30} diff --git a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf index 93a784922d..92d5460daf 100644 --- a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf +++ b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Plays the corresponding treatment animation. @@ -8,11 +9,13 @@ * 2: Is self treatment * * Return Value: - * Nothing + * None + * + * Example: + * [bob, true, true] call ACE_medical_ai_fnc_playTreatmentAnim * * Public: No */ -#include "script_component.hpp" params ["_unit", "_isBandage", "_isSelfTreatment"]; if (vehicle _unit != _unit) exitWith {}; @@ -32,7 +35,12 @@ if (stance _unit == "PRONE") then { }; private _anim = getText (_animConfig >> _configProperty); -private _wpn = ["non", "rfl", "pst"] select (1 + ([primaryWeapon _unit, handgunWeapon _unit] find (currentWeapon _unit))); +private _wpn = switch (true) do { + case ((currentWeapon _unit) == ""): {"non"}; + case ((currentWeapon _unit) == (primaryWeapon _unit)): {"rfl"}; + case ((currentWeapon _unit) == (handgunWeapon _unit)): {"pst"}; + default {"non"}; +}; _anim = [_anim, "[wpn]", _wpn] call CBA_fnc_replace; [_unit, _anim] call EFUNC(common,doAnimation); diff --git a/addons/medical_ai/functions/fnc_requestMedic.sqf b/addons/medical_ai/functions/fnc_requestMedic.sqf index f669b06975..450911c801 100644 --- a/addons/medical_ai/functions/fnc_requestMedic.sqf +++ b/addons/medical_ai/functions/fnc_requestMedic.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Sends a request to the units assigned medic to heal it. @@ -6,11 +7,13 @@ * None * * Return Value: - * Nothing + * None + * + * Example: + * call ACE_medical_ai_fnc_requestMedic * * Public: No */ -#include "script_component.hpp" private _assignedMedic = _this getVariable QGVAR(assignedMedic); private _healQueue = _assignedMedic getVariable [QGVAR(healQueue), []]; diff --git a/addons/medical_ai/functions/fnc_wasRequested.sqf b/addons/medical_ai/functions/fnc_wasRequested.sqf index 2b86423be8..479dc0c880 100644 --- a/addons/medical_ai/functions/fnc_wasRequested.sqf +++ b/addons/medical_ai/functions/fnc_wasRequested.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Checks if the unit was requested to treat another unit. @@ -8,9 +9,11 @@ * Return Value: * Was requested * + * Example: + * call ACE_medical_ai_fnc_wasRequested + * * Public: No */ -#include "script_component.hpp" private _healQueue = _this getVariable [QGVAR(healQueue), []]; !(_healQueue isEqualTo []) diff --git a/addons/medical_ai/script_component.hpp b/addons/medical_ai/script_component.hpp index f50197ee67..cd0c047751 100644 --- a/addons/medical_ai/script_component.hpp +++ b/addons/medical_ai/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_ENABLED_MEDICAL_AI // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MEDICAL_AI diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 3bec1c3824..9519a273c2 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -1,11 +1,32 @@ - + + + Medical AI enabled for + 次に AI 治療を有効 + AI医疗启用 + AI醫療啟用 + AI medica abilitata per: + + + Enable AI units to heal themselves and each other. + AI ユニットの自己や相互治療を有効化します。 + 使AI单位能够彼此治疗自己 + 啟用AI能夠彼此醫療自己 + Permette alle unità AI di curare se stesse e fra di loro. + Only Server and HC Nur Server und HC Sólo Server y HC Нур сервера унд HC + サーバーと HC のみ + Tylko serwer i HC + Seulement sur le server ou le HC + Solo Server e HC + 只在伺服器或无头客户端 + 只在伺服器或無頭客戶端 + 서버와 헤드리스만 diff --git a/addons/medical_blood/$PBOPREFIX$ b/addons/medical_blood/$PBOPREFIX$ new file mode 100644 index 0000000000..352725c3fd --- /dev/null +++ b/addons/medical_blood/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\medical_blood diff --git a/addons/medical_blood/ACE_Settings.hpp b/addons/medical_blood/ACE_Settings.hpp new file mode 100644 index 0000000000..b5e1f0db21 --- /dev/null +++ b/addons/medical_blood/ACE_Settings.hpp @@ -0,0 +1,10 @@ +class ACE_Settings { + class GVAR(enabledFor) { + category = ECSTRING(medical,Category_Medical); + displayName = CSTRING(MedicalBloodSettings_enabledFor_DisplayName); + description = CSTRING(MedicalBloodSettings_enabledFor_Description); + value = 2; + typeName = "SCALAR"; + values[] = {ECSTRING(Common,Disabled), CSTRING(enabledFor_OnlyPlayers), ECSTRING(Common,Enabled)}; + }; +}; diff --git a/addons/medical_blood/CfgEventHandlers.hpp b/addons/medical_blood/CfgEventHandlers.hpp new file mode 100644 index 0000000000..becf395052 --- /dev/null +++ b/addons/medical_blood/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/medical_blood/README.md b/addons/medical_blood/README.md new file mode 100644 index 0000000000..29632ffd29 --- /dev/null +++ b/addons/medical_blood/README.md @@ -0,0 +1,11 @@ +ace_medical_blood +=============== + +Adds blood visual effect on the ground near a bleeding player. + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [Glowbal](https://github.com/Glowbal) +- [commy2](https://github.com/commy2) diff --git a/addons/medical_blood/XEH_PREP.hpp b/addons/medical_blood/XEH_PREP.hpp new file mode 100644 index 0000000000..64ebbae911 --- /dev/null +++ b/addons/medical_blood/XEH_PREP.hpp @@ -0,0 +1,6 @@ + +PREP(hit); +PREP(isBleeding); +PREP(onBleeding); +PREP(createBlood); +PREP(spurt); diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf new file mode 100644 index 0000000000..ceff7f074c --- /dev/null +++ b/addons/medical_blood/XEH_postInit.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" + +GVAR(useAceMedical) = ["ace_medical"] call EFUNC(common,isModLoaded); + +// To support public API regardless of component settings +[QGVAR(spurt), { + _this call FUNC(spurt); +}] call CBA_fnc_addEventHandler; + +if (isServer) then { + GVAR(bloodDrops) = []; + + [QGVAR(bloodDropCreated), { + params ["_bloodDrop"]; + GVAR(bloodDrops) pushBack _bloodDrop; + if (count GVAR(bloodDrops) >= MAX_BLOOD_OBJECTS) then { + private _deletedBloodDrop = GVAR(bloodDrops) deleteAt 0; + deleteVehicle _deletedBloodDrop; + }; + + [{deleteVehicle _this}, _bloodDrop, BLOOD_OBJECT_LIFETIME] call CBA_fnc_waitAndExecute; + }] call CBA_fnc_addEventHandler; +}; + +["ace_settingsInitialized", { + TRACE_1("settingsInitialized", GVAR(enabledFor)); + if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled + if ((GVAR(enabledFor) == 1) && {!hasInterface}) exitWith {}; // 1: enabledFor_OnlyPlayers + + private _listcode = if (GVAR(enabledFor) == 1) then { + {[ACE_player] select {[_x] call FUNC(isBleeding)}} // ace_player is only possible local player + } else { + {allUnits select {(local _x) && {[_x] call FUNC(isBleeding)}}}; // filter all local bleeding units + }; + + private _stateMachine = [_listcode, true] call CBA_statemachine_fnc_create; + [_stateMachine, {call FUNC(onBleeding)}, {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState; + + + ["CAManBase", "hit", { + params ["_unit"]; + if (GVAR(enabledFor) == 1 && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; + _this call FUNC(hit); + }] call CBA_fnc_addClassEventHandler; + +}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_blood/XEH_preInit.sqf b/addons/medical_blood/XEH_preInit.sqf new file mode 100644 index 0000000000..9cf50a1b60 --- /dev/null +++ b/addons/medical_blood/XEH_preInit.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +// blood object model namespace +GVAR(models) = [] call CBA_fnc_createNamespace; + +{ + _x params ["_name", "_model"]; + + // createSimpleObject expects a path without the leading slash + if ((_model select [0,1]) isEqualTo "\") then { + _model = _model select [1]; + }; + + GVAR(models) setVariable [_name, _model]; +} forEach [ + // higher number means bigger model + ["blooddrop_1", QPATHTOF(data\ace_drop_1.p3d)], + ["blooddrop_2", QPATHTOF(data\ace_drop_2.p3d)], + ["blooddrop_3", QPATHTOF(data\ace_drop_3.p3d)], + ["blooddrop_4", QPATHTOF(data\ace_drop_4.p3d)] +]; + +ADDON = true; diff --git a/addons/medical_blood/XEH_preStart.sqf b/addons/medical_blood/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/medical_blood/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/medical_blood/config.cpp b/addons/medical_blood/config.cpp new file mode 100644 index 0000000000..65b2a69809 --- /dev/null +++ b/addons/medical_blood/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_main"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Glowbal","Sickboy","commy2"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "ACE_Settings.hpp" +#include "CfgEventHandlers.hpp" diff --git a/addons/medical_blood/data/ace_drop_1.p3d b/addons/medical_blood/data/ace_drop_1.p3d new file mode 100644 index 0000000000..b72f206a6f Binary files /dev/null and b/addons/medical_blood/data/ace_drop_1.p3d differ diff --git a/addons/medical_blood/data/ace_drop_2.p3d b/addons/medical_blood/data/ace_drop_2.p3d new file mode 100644 index 0000000000..bb155f3e65 Binary files /dev/null and b/addons/medical_blood/data/ace_drop_2.p3d differ diff --git a/addons/medical_blood/data/ace_drop_3.p3d b/addons/medical_blood/data/ace_drop_3.p3d new file mode 100644 index 0000000000..de564cfd0b Binary files /dev/null and b/addons/medical_blood/data/ace_drop_3.p3d differ diff --git a/addons/medical_blood/data/ace_drop_4.p3d b/addons/medical_blood/data/ace_drop_4.p3d new file mode 100644 index 0000000000..fd9e0de0a0 Binary files /dev/null and b/addons/medical_blood/data/ace_drop_4.p3d differ diff --git a/addons/medical_blood/data/blood.rvmat b/addons/medical_blood/data/blood.rvmat new file mode 100644 index 0000000000..691515d6b4 --- /dev/null +++ b/addons/medical_blood/data/blood.rvmat @@ -0,0 +1,91 @@ +class StageTI { + texture = "z\ace\addons\medical_blood\data\blood_ti_ca.paa"; +}; + +ambient[] = {1.0,1.0,1.0,1.0}; +diffuse[] = {1.0,1.0,1.0,1.0}; +forcedDiffuse[] = {0.0,0.0,0.0,0.0}; +emmisive[] = {0.0,0.0,0.0,1.0}; +specular[] = {0.0,0.0,0.0,1.0}; +specularPower = 1.0; +PixelShaderID = "Super"; +VertexShaderID = "Super"; +renderFlags[] = {"NoZWrite"}; + +class Stage1 { + texture = "z\ace\addons\medical_blood\data\blood_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; + +class Stage2 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,0.5,DT)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; + +class Stage3 { + texture = "#(argb,8,8,3)color(0.0,0.0,0.0,0.0,MC)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; + +class Stage4 { + texture = "#(argb,8,8,3)color(1.0,1.0,1.0,1.0,AS)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; + +class Stage5 { + texture = "z\ace\addons\medical_blood\data\blood_smdi.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnel(0.7,0.001)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; + +class Stage7 { + texture = "a3\data_f\env_land_co.paa"; + useWorldEnvMap = "false"; + uvSource = "tex"; + class uvTransform { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; diff --git a/addons/medical_blood/data/blood_ca.paa b/addons/medical_blood/data/blood_ca.paa new file mode 100644 index 0000000000..9ae34f8eb0 Binary files /dev/null and b/addons/medical_blood/data/blood_ca.paa differ diff --git a/addons/medical_blood/data/blood_nohq.paa b/addons/medical_blood/data/blood_nohq.paa new file mode 100644 index 0000000000..bae0ed1075 Binary files /dev/null and b/addons/medical_blood/data/blood_nohq.paa differ diff --git a/addons/medical_blood/data/blood_smdi.paa b/addons/medical_blood/data/blood_smdi.paa new file mode 100644 index 0000000000..36e4728b16 Binary files /dev/null and b/addons/medical_blood/data/blood_smdi.paa differ diff --git a/addons/medical_blood/data/blood_ti_ca.paa b/addons/medical_blood/data/blood_ti_ca.paa new file mode 100644 index 0000000000..9172b23d5f Binary files /dev/null and b/addons/medical_blood/data/blood_ti_ca.paa differ diff --git a/addons/medical_blood/data/model.cfg b/addons/medical_blood/data/model.cfg new file mode 100644 index 0000000000..9f1696ab51 --- /dev/null +++ b/addons/medical_blood/data/model.cfg @@ -0,0 +1,19 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; +}; + +class CfgModels { + class Default { + sectionsInherit = ""; + sections[] = {""}; + skeletonName = "Default"; + }; + class ace_drop_1: Default {}; + class ace_drop_2: Default {}; + class ace_drop_3: Default {}; + class ace_drop_4: Default {}; +}; diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf new file mode 100644 index 0000000000..8d3fbc8776 --- /dev/null +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Spawn a blood drop. + * Available blood drop classes are blooddrop_1 through blooddrop_4. + * + * Arguments: + * 0: classname of blood drop + * 1: Position + * + * Return Value: + * Created blood drop + * + * Example: + * ["blooddrop_2", getPos player] call ace_medical_blood_fnc_createBlood + * + * Public: No + */ + +params ["_type", "_pos"]; +TRACE_2("creating blood",_type,_pos); + +private _model = GVAR(models) getVariable _type; + +private _object = createSimpleObject [_model, [0,0,0]]; +_object setDir random 360; +_object setPos _pos; + +[QGVAR(bloodDropCreated), [_object]] call CBA_fnc_serverEvent; + +_object diff --git a/addons/medical_blood/functions/fnc_hit.sqf b/addons/medical_blood/functions/fnc_hit.sqf new file mode 100644 index 0000000000..17df627f1f --- /dev/null +++ b/addons/medical_blood/functions/fnc_hit.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Handle unit hit eventhandler + * + * Arguments: + * 0: unit + * 1: caused by + * 2: damage + * + * Return Value: + * None + * + * Example: + * [bob, kevin, 5] call ACE_medical_blood_fnc_hit + * + * Public: No + */ + +params ["_unit", "_causedBy", "_damage"]; + +if (((vehicle _unit) != _unit) && {!((vehicle _unit) isKindOf "StaticWeapon")}) exitWith {}; // Don't bleed on ground if mounted + +if (isNull _causedBy) exitWith { // won't be able to calculate the direction properly, so instead we pick something at random + [QGVAR(spurt), [_unit, random 360, _damage]] call CBA_fnc_serverEvent; +}; + +// Calculate bulletDirection +private _bulletDir = _unit getDir _causedBy; + +[QGVAR(spurt), [_unit, _bulletDir, _damage]] call CBA_fnc_serverEvent; diff --git a/addons/medical_blood/functions/fnc_isBleeding.sqf b/addons/medical_blood/functions/fnc_isBleeding.sqf new file mode 100644 index 0000000000..73e5c10e6f --- /dev/null +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * Check if is bleeding + * + * Arguments: + * 0: unit + * + * Return Value: + * is Bleeding + * + * Example: + * [UNIT] call ace_medical_blood_fnc_isBleeding + * + * Public: No + */ + +params ["_unit"]; + +if (GVAR(useAceMedical)) exitWith { + _unit getVariable [QEGVAR(medical,isBleeding), false]; +}; +alive _unit && {getDammage _unit > 0.3}; diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf new file mode 100644 index 0000000000..e21f68f02f --- /dev/null +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: Glowbal + * handle bleeding state (state machine) + * + * Arguments: + * 0: unit + * + * Return Value: + * is Bleeding + * + * Example: + * [UNIT] call ace_medical_blood_fnc_onBleeding + * + * Public: No + */ + +params ["_unit"]; + +if (((vehicle _unit) != _unit) && {!((vehicle _unit) isKindOf "StaticWeapon")}) exitWith {}; // Don't bleed on ground if mounted + +private _lastTime = _unit getVariable [QGVAR(lastTime), -10]; +private _bloodLoss = (if (GVAR(useAceMedical)) then {([_unit] call EFUNC(medical,getBloodLoss)) * 2.5} else {getDammage _unit * 2}) min 6; + +if ((CBA_missionTime - _lastTime) + _bloodLoss >= 8 + random 2) then { + _unit setVariable [QGVAR(lastTime), CBA_missionTime]; + + private _position = getPosASL _unit; + _position = _position vectorAdd [ + random 0.4 - 0.2, + random 0.4 - 0.2, + 0 + ]; + _position set [2, 0]; + + private _bloodDrop = ["blooddrop_1", "blooddrop_2", "blooddrop_3", "blooddrop_4"] select floor (_bloodLoss min 3); + [_bloodDrop, _position, getDir _unit] call FUNC(createBlood); +}; diff --git a/addons/medical_blood/functions/fnc_spurt.sqf b/addons/medical_blood/functions/fnc_spurt.sqf new file mode 100644 index 0000000000..6f1dbaaa1d --- /dev/null +++ b/addons/medical_blood/functions/fnc_spurt.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: Sickboy + * Spurt blood on the ground + * + * Arguments: + * 0: unit + * 1: direction + * 2: damage + * + * Return Value: + * None + * + * Example: + * [UNIT, random 360, 1] call ace_medical_blood_fnc_spurt + * + * Public: No + */ + +#define MAXIMUM_DROPS 4 +#define DISTANCE_BETWEEN_DROPS 0.20 +#define OFFSET 0.25 + +params ["_unit", "_dir", "_damage"]; +_damage = _damage min 1; + +private _distanceBetweenDrops = DISTANCE_BETWEEN_DROPS * _damage; +private _offset = OFFSET + _distanceBetweenDrops; +private _pos = _unit getPos [_offset, _dir]; +["blooddrop_2", _pos, _dir] call FUNC(createBlood); + +private _dropAmount = ceil (MAXIMUM_DROPS * _damage); +if (_dropAmount > 1) then { + for "_i" from 2 to _dropAmount do { + _pos = _pos getPos [_distanceBetweenDrops, _dir]; + ["blooddrop_1", _pos, _dir] call FUNC(createBlood); + }; +}; diff --git a/addons/medical_blood/functions/script_component.hpp b/addons/medical_blood/functions/script_component.hpp new file mode 100644 index 0000000000..8f2dd066de --- /dev/null +++ b/addons/medical_blood/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\medical_blood\script_component.hpp" diff --git a/addons/medical_blood/script_component.hpp b/addons/medical_blood/script_component.hpp new file mode 100644 index 0000000000..335cdc44c5 --- /dev/null +++ b/addons/medical_blood/script_component.hpp @@ -0,0 +1,20 @@ +#define COMPONENT medical_blood +#define COMPONENT_BEAUTIFIED Medical Blood +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_ENABLED_MEDICAL_BLOOD +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_MEDICAL_BLOOD + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_MEDICAL_BLOOD + #define DEBUG_SETTINGS DEBUG_SETTINGS_MEDICAL_BLOOD +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define MAX_BLOOD_OBJECTS 500 +#define BLOOD_OBJECT_LIFETIME 900 diff --git a/addons/medical_blood/stringtable.xml b/addons/medical_blood/stringtable.xml new file mode 100644 index 0000000000..d58f41bfc4 --- /dev/null +++ b/addons/medical_blood/stringtable.xml @@ -0,0 +1,38 @@ + + + + + Only Players + プレイヤーのみ + Nur Spieler + 오직 플레이어만 + Tylko gracze + Joueurs seulement + Solo Giocatori + 只有玩家 + 只有玩家 + + + Enable Blood Drops + 血痕を有効化 + Aktiviere Blutspritzer + 피흘리기 활성화 + Włącz ślady krwi na ziemi + Active les gouttes de sang + Abilita Perdite di Sangue + 开启血液滴落效果 + 開啟血液滴落效果 + + + Enable or disable Blood Drops created on bleeding and taking damage + ダメージを受けたり、出血していると出る血痕の有効か無効化 + Aktiviere oder deaktiviere Blutspritzer, die durch Blutungen oder bei Schadensnahme entstehen. + 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..b180157b3a 100644 --- a/addons/medical_menu/ACE_Settings.hpp +++ b/addons/medical_menu/ACE_Settings.hpp @@ -25,9 +25,12 @@ class ACE_Settings { category = ECSTRING(medical,Category_Medical); }; class GVAR(maxRange) { + displayName = CSTRING(maxRange); + description = CSTRING(maxRange_Descr); //for ref: 3d interaction (MEDICAL_ACTION_DISTANCE) is 1.75 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..fcf2dbfd66 100644 --- a/addons/medical_menu/XEH_postInit.sqf +++ b/addons/medical_menu/XEH_postInit.sqf @@ -17,11 +17,15 @@ GVAR(pendingReopen) = false; ["ACE3 Common", QGVAR(displayMenuKeyPressed), localize LSTRING(DisplayMenuKey), { + TRACE_3("keyDown",cursorTarget,cursorObject,ACE_player); private _target = cursorTarget; - if (!((_target isKindOf "CAManBase") && {[ACE_player, _target] call FUNC(canOpenMenu)})) then {_target = ACE_player}; + if (!((_target isKindOf "CAManBase") && {[ACE_player, _target] call FUNC(canOpenMenu)})) then { + _target = cursorObject; + 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/XEH_preInit.sqf b/addons/medical_menu/XEH_preInit.sqf index 009a9ed1a6..16e448fc38 100644 --- a/addons/medical_menu/XEH_preInit.sqf +++ b/addons/medical_menu/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(INTERACTION_TARGET) = objNull; GVAR(actionsOther) = []; diff --git a/addons/medical_menu/functions/fnc_canOpenMenu.sqf b/addons/medical_menu/functions/fnc_canOpenMenu.sqf index 1ef7dccf5b..f69cf80d12 100644 --- a/addons/medical_menu/functions/fnc_canOpenMenu.sqf +++ b/addons/medical_menu/functions/fnc_canOpenMenu.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if ACE_player can Open the medical menu @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_caller", "_target"]; diff --git a/addons/medical_menu/functions/fnc_collectActions.sqf b/addons/medical_menu/functions/fnc_collectActions.sqf index af6742188e..5353582fb2 100644 --- a/addons/medical_menu/functions/fnc_collectActions.sqf +++ b/addons/medical_menu/functions/fnc_collectActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Collect treatment actions from medical config @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" private _configBasic = (configFile >> "ACE_Medical_Actions" >> "Basic"); private _configAdvanced = (configFile >> "ACE_Medical_Actions" >> "Advanced"); diff --git a/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf b/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf index 6fed994671..eac639c4d5 100644 --- a/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf +++ b/addons/medical_menu/functions/fnc_getTreatmentOptions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Grab available treatment options for given category @@ -10,16 +11,15 @@ * Return Value: * Available actions * - * Exmaple: + * Example: * [ACE_player, poor_dude, "some category"] call ace_medical_menu_fnc_getTreatmentOptions * * Public: No */ -#include "script_component.hpp" 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..55de1339d0 100644 --- a/addons/medical_menu/functions/fnc_handleUI_DisplayOptions.sqf +++ b/addons/medical_menu/functions/fnc_handleUI_DisplayOptions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Display the available treatment options in category @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define START_IDC 20 #define END_IDC 27 @@ -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_handleUI_dropDownTriageCard.sqf b/addons/medical_menu/functions/fnc_handleUI_dropDownTriageCard.sqf index 946ee2d0ef..988022d7a6 100644 --- a/addons/medical_menu/functions/fnc_handleUI_dropDownTriageCard.sqf +++ b/addons/medical_menu/functions/fnc_handleUI_dropDownTriageCard.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handle the triage card display @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; diff --git a/addons/medical_menu/functions/fnc_module.sqf b/addons/medical_menu/functions/fnc_module.sqf index 666440e208..bdb6f33086 100644 --- a/addons/medical_menu/functions/fnc_module.sqf +++ b/addons/medical_menu/functions/fnc_module.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Module for adjusting the medical menu settings @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ACE_medical_menu_fnc_module + * * Public: No */ -#include "script_component.hpp" - params ["_logic", "", "_activated"]; if !(_activated) exitWith {}; diff --git a/addons/medical_menu/functions/fnc_onMenuClose.sqf b/addons/medical_menu/functions/fnc_onMenuClose.sqf index 656336eb4e..f6318263dd 100644 --- a/addons/medical_menu/functions/fnc_onMenuClose.sqf +++ b/addons/medical_menu/functions/fnc_onMenuClose.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: joko // Jonas * Handle medical menu closed @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (EGVAR(interact_menu,menuBackground)==1) then {[QGVAR(id), false] call EFUNC(common,blurScreen);}; if (EGVAR(interact_menu,menuBackground)==2) then {(uiNamespace getVariable [QEGVAR(interact_menu,menuBackground), displayNull]) closeDisplay 0;}; diff --git a/addons/medical_menu/functions/fnc_onMenuOpen.sqf b/addons/medical_menu/functions/fnc_onMenuOpen.sqf index 58cb9ff74e..991529712a 100644 --- a/addons/medical_menu/functions/fnc_onMenuOpen.sqf +++ b/addons/medical_menu/functions/fnc_onMenuOpen.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handle medical menu opened @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define MAX_DISTANCE 10 params ["_display"]; @@ -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_openMenu.sqf b/addons/medical_menu/functions/fnc_openMenu.sqf index e0de46dba8..a492da8c43 100644 --- a/addons/medical_menu/functions/fnc_openMenu.sqf +++ b/addons/medical_menu/functions/fnc_openMenu.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Open the medical menu for target @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_interactionTarget"]; diff --git a/addons/medical_menu/functions/fnc_setTriageStatus.sqf b/addons/medical_menu/functions/fnc_setTriageStatus.sqf index 8a85eeb950..9580a051e8 100644 --- a/addons/medical_menu/functions/fnc_setTriageStatus.sqf +++ b/addons/medical_menu/functions/fnc_setTriageStatus.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Set the triage status of object @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, 2] call ACE_medical_menu_fnc_setTriageStatus + * * Public: No */ -#include "script_component.hpp" params ["_target", "_status"]; diff --git a/addons/medical_menu/functions/fnc_updateActivityLog.sqf b/addons/medical_menu/functions/fnc_updateActivityLog.sqf index 7406e25f33..c99bc1ef4f 100644 --- a/addons/medical_menu/functions/fnc_updateActivityLog.sqf +++ b/addons/medical_menu/functions/fnc_updateActivityLog.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Update the activity log @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_display", "_logs"]; diff --git a/addons/medical_menu/functions/fnc_updateBodyImage.sqf b/addons/medical_menu/functions/fnc_updateBodyImage.sqf index 1d83b54372..234556a969 100644 --- a/addons/medical_menu/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_menu/functions/fnc_updateBodyImage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Update the body image on the menu @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_selectionBloodLoss", "_damaged", "_display"]; diff --git a/addons/medical_menu/functions/fnc_updateIcons.sqf b/addons/medical_menu/functions/fnc_updateIcons.sqf index 37508bd2b0..2d437612d7 100644 --- a/addons/medical_menu/functions/fnc_updateIcons.sqf +++ b/addons/medical_menu/functions/fnc_updateIcons.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Update the category icons @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define START_IDC 111 #define END_IDC 118 diff --git a/addons/medical_menu/functions/fnc_updateInformationLists.sqf b/addons/medical_menu/functions/fnc_updateInformationLists.sqf index 28818465bc..25f457503c 100644 --- a/addons/medical_menu/functions/fnc_updateInformationLists.sqf +++ b/addons/medical_menu/functions/fnc_updateInformationLists.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Update the treatment information list @@ -10,9 +11,11 @@ * Return Value: * None * + * Example: + * [DISPLAY, [messagecollection], [injurycollection]] call ACE_medical_menu_fnc_updateInformationLists + * * Public: No */ -#include "script_component.hpp" params ["_display", "_genericMessages", "_allInjuryTexts"]; diff --git a/addons/medical_menu/functions/fnc_updateQuickViewLog.sqf b/addons/medical_menu/functions/fnc_updateQuickViewLog.sqf index 836ebafca2..c398faaf14 100644 --- a/addons/medical_menu/functions/fnc_updateQuickViewLog.sqf +++ b/addons/medical_menu/functions/fnc_updateQuickViewLog.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Update the quick view log @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_display", "_logs"]; diff --git a/addons/medical_menu/functions/fnc_updateUIInfo.sqf b/addons/medical_menu/functions/fnc_updateUIInfo.sqf index 130f76af2f..3c54cd71f0 100644 --- a/addons/medical_menu/functions/fnc_updateUIInfo.sqf +++ b/addons/medical_menu/functions/fnc_updateUIInfo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Update all UI information in the medical menu @@ -14,19 +15,16 @@ * * Public: No */ -#include "script_component.hpp" 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,27 +43,25 @@ 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), []]; { - private _value = _target getVariable _x; - if (!isNil "_value") then { - _totalIvVolume = _totalIvVolume + (_target getVariable [_x, 0]); - }; -} count EGVAR(medical,IVBags); + _x params ["_bagVolumeRemaining"]; + _totalIvVolume = _totalIvVolume + _bagVolumeRemaining; +} foreach _bloodBags; 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]; @@ -84,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))]; @@ -107,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]; @@ -118,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/script_component.hpp b/addons/medical_menu/script_component.hpp index cb437060a3..28ab0311b3 100644 --- a/addons/medical_menu/script_component.hpp +++ b/addons/medical_menu/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MEDICAL_MENU diff --git a/addons/medical_menu/stringtable.xml b/addons/medical_menu/stringtable.xml index a5b75c00e2..a935197300 100644 --- a/addons/medical_menu/stringtable.xml +++ b/addons/medical_menu/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ Zdravotnikcá nabídka Menù Medico Menu médical + 治療メニュー + 의료 메뉴 + 医疗选单 + 醫療選單 Allow Medical Menu @@ -22,6 +26,10 @@ Povolit zdravotnickou nabídku Consenti Menù Medico Autoriser le menu médical + 治療メニューを有効化 + 의료 메뉴 활성화 + 允许医疗选单 + 允許醫療選單 Allow clients to use the medical menu @@ -33,6 +41,10 @@ Povolit klientům používat zdravotnickou nabídku Consenti ai clients di usare il Menù Medico Autoriser les clients à utiliser le menu médical + 全クライアントが治療メニューを使えるようにします + 클라이언트가 의료 메뉴를 쓰는것을 허락합니다 + 允许客户端使用医疗选单 + 允許客戶端使用醫療選單 Use Medical menu @@ -44,6 +56,10 @@ Použít zdravotnickou nabídku Usa Menù Medico Utiliser le menu médical + 治療メニューを使う + 의료 메뉴 사용 + 使用医疗选单 + 使用醫療選單 If allowed by server, enable the option to use the Medical Menu through keybinding and interaction menu @@ -55,6 +71,10 @@ Pokud je povoleno serverem, umožní použít zdravotnickou nabídku skrze kláv. zkratku a interakční menu Se consentito dal server, abilita l'opzione di usare il Menù Medico attraverso hotkeys e menù interazione 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 @@ -66,6 +86,10 @@ Znovu otevřít zdravotnickou nabídku Ri-apri Menù Medico Ré-ouvrir le menu médical + 治療メニューを再び開く + 의료 메뉴 다시 열기 + 重新开启医疗选单 + 重新開啟醫療選單 Re-open the medical menu after succesful treatment @@ -77,6 +101,10 @@ Znovu otevřít zdravotnickou nabídku po úspěšné léčbě Ri-Apri il Menù Medico dopo un trattamento riuscito Ré-ouvrir le menu médical après un traitement réussi + 治療が終わった後、再び治療メニューを開きます + 성공적으로 치료한후에 의료 메뉴를 다시 엽니다 + 当治疗成功后重新打开医疗选单 + 當治療成功後重新打開醫療選單 Open Medical Menu @@ -88,6 +116,10 @@ Otevřít zdravotnickou nabídku Apri Menù Medico Ouvir le menu médical + 治療メニューを開く + 의료 메뉴 열기 + 开起医疗选单 + 開起醫療選單 Medical Menu Settings @@ -99,6 +131,10 @@ Nastavení zdravotnické nabídky Impostazioni Menù Medico Réglages du menu médical + 治療メニューの設定 + 의료 메뉴 설정 + 医疗选单设定 + 醫療選單設定 Configure the usage of the Medical Menu @@ -110,6 +146,10 @@ Konfigurace využití zdravotnické nabídky Configura l'uso del Menù Medico Configurer l'utilisation du menu médical + 治療メニュー用の設定 + 의료 메뉴 사용의 설정 + 设置医疗选单的使用 + 設置醫療選單的使用 EXAMINE & TREATMENT @@ -121,6 +161,10 @@ EXAMINAR & TRATAMENTO VYŠETŘENÍ & LÉČBA ESAMINA & TRATTA + 診断 & 治療 + 검사 / 치료 + 检查 & 治疗 + 檢查 & 治療 STATUS @@ -132,6 +176,10 @@ ESTADO STAV STATO + 状態 + 상태 + 状态 + 狀態 OVERVIEW @@ -143,6 +191,10 @@ VISÃO GERAL PŘEHLED PANORAMICA + オーバービュー + 개요 + 概述 + 概述 ACTIVITY LOG @@ -154,6 +206,10 @@ REGISTRO DE ATIVIDADE PROTOKOL LOG ATTIVITA' + 治療履歴 + 활동 로그 + 医疗纪录 + 醫療紀錄 QUICK VIEW @@ -165,6 +221,10 @@ VISÃO RÁPIDA RYCHLÝ NÁHLED VISTA RAPIDA + クイック ビュー + 퀵 뷰 + 快速检查 + 快速檢查 View triage Card @@ -176,6 +236,10 @@ Ver cartão de triagem Zkontrolovat štítek Guarda Triage Card + トリアージ カードを見る + 부상자 카드 보기 + 查看诊断卡 + 查看診斷卡 Examine Patient @@ -187,6 +251,10 @@ Examinar paciente Zkontrolovat pacienta Esamina Paziente + 患者を調べる + 환자 검사하기 + 检查伤者 + 檢查傷者 Bandage / Fractures @@ -198,6 +266,10 @@ Bandagens / Fraturas Bandáž / Zlomeniny Bendaggi/Fratture + 包帯 / 骨折 + 붕대 / 골절 + 绷带 / 骨折 + 繃帶 / 骨折 Medication @@ -209,6 +281,10 @@ Medicação Léky Medicazione + 薬物による治療 + 약물 치료 + 药物 + 藥物 Airway Management @@ -220,6 +296,10 @@ Dýchací systém Gestione Vie Respiratorie Atemwegssicherung + 気道を確保 + 기도 관리 + 呼吸道管理 + 呼吸道管理 Advanced Treatments @@ -231,6 +311,10 @@ Tratamentos avançados Pokročilé ošetření Trattamenti Avanzati + 高度な治療 + 고급 치료 + 进阶治疗 + 進階治療 Drag/Carry @@ -242,6 +326,10 @@ Arrastar/Carregar Táhnout/Nést Trascina/Trasporta + 引きずる / 運ぶ + 끌기 / 들기 + 拖 / 背 + 拖 / 背 Toggle (Self) @@ -253,83 +341,115 @@ Alternar (Si mesmo) Přepnout (na sebe) Attiva (Te Stesso) + 切り替え (自分) + 토글 (자신) + 切换 (自己) + 切換 (自己) Select triage status Setze Status auf der Triagekarte Сортировка Seleccionar estado de Triage - Selectioner l'état de triage + Sélectionner l'état de triage Wybierz priorytet Selecionar estado de triagem Vybrat prioritu Seleziona stato Triage + トリアージによる状態を選択 + 부상 상태 고르기 + 选择分诊状态 + 選擇分診狀態 Select Head Wähle Kopf Выбрать голову Seleccionar Cabeza - Selectioner Tête + Sélectionner la tête Wybierz głowę Selecionar Cabeça Vybrat Hlavu Seleziona Testa + 頭部を選ぶ + 머리 선택 + 选择头部 + 選擇頭部 Select Torso Wähle Torso Выбрать торс Seleccionar Torso - Selectioner Torse + Sélectionner le torse Wybierz tors Selecionar Torso Vybrat Trup Seleziona Torso + 胴体を選ぶ + 몸통 선택 + 选择身体 + 選擇身體 Select Left Arm Wähle linken Arm Выбрать левую руку Seleccionar Brazo Izquierdo - Selectioner Bras Gauche + Sélectionner le bras gauche Wybierz lewą rękę Selecionar Braço Esquerdo Vybrat Levou ruku Seleziona Braccio Sinistro + 左腕を選ぶ + 왼쪽 팔 선택 + 选择左手 + 選擇左手 Select Right Arm Wähle rechten Arm Выбрать правую руку Seleccionar Brazo Derecho - Selectioner Bras Droit + Sélectionner le bras droit Wybierz prawą rękę Selecionar Braço Direito Vybrat Pravou ruku Seleziona Braccio Destro + 右腕を選ぶ + 오른쪽 팔 선택 + 选择右手 + 選擇右手 Select Left Leg Wähle linkes Bein Выбрать левую ногу Seleccionar Pierna Izquierda - Selectioner Jambe Gauche + Sélectionner la jambe gauche Wybierz lewą nogę Selecionar Perna Esquerda Vybrat Levou nohu Seleziona Gamba Sinistra + 左足を選ぶ + 왼쪽 다리 선택 + 选择左脚 + 選擇左腳 Select Right Leg Wähle rechtes Bein Выбрать правую ногу Seleccionar Pierna Derecha - Selectioner Jambe Droite + Sélectionner la jambe droite Wybierz prawą nogę Selecionar Perna Direita Vybrat Pravou nohu Seleziona Gamba Destra + 右足を選ぶ + 오른쪽 다리 선택 + 选择右脚 + 選擇右腳 Head @@ -341,6 +461,10 @@ Caebça Hlava Testa + 頭部 + 머리 + 头部 + 頭部 Torso @@ -352,61 +476,85 @@ Trup Torso Torso + 胴体 + 몸통 + 身体 + 身體 Left Arm Linker Arm Левая рука Brazo Izquierdo - Bras Gauche + Bras gauche Lewa ręka Braço Esquerdo Levá Ruka Braccio Sinistro + 左腕 + 왼쪽 팔 + 左手 + 左手 Right Arm Rechter Arm Правая рука Brazo Derecho - Bras Droit + Bras droit Prawa ręka Braço Direito Pravá Ruka Braccio Destro + 右腕 + 오른쪽 팔 + 右手 + 右手 Left Leg Linkes Bein Левая нога Pierna Izquierda - Jambe Gauche + Jambe gauche Lewa noga Perna Esquerda Levá Noha Gamba Sinistra + 左足 + 왼쪽 다리 + 左脚 + 左腳 Right Leg Rechtes Bein Правая нога Pierna Derecha - Jambe Droite + Jambe droite Prawa noga Perna Direita Pravá Noha Gamba Destra + 右足 + 오른쪽 다리 + 右脚 + 右腳 Body Part: %1 Körperteil: %1 Часть тела: %1 Parte del cuerpo: %1 - Partie du corps: %1 + Partie du corps : %1 Część ciała: %1 Parte do corpo: %1 Část těla: %1 Parte del Corpo: %1 + 身体の一部: %1 + 신체 부위: %1 + 身体部位: %1 + 身體部位: %1 Small @@ -418,6 +566,10 @@ Pequeno Malý Piccolo + 小さい + + + Medium @@ -429,6 +581,10 @@ Médio Střední Medio + 中くらい + + + Large @@ -440,17 +596,25 @@ Grande Velký Grande + 大きい + + + There are %2 %1 Open Wounds Er hat %2 offene Wunden (%1) %2 открытые раны %1 Hay %2 Heridas Abiertas %1 - Il y a %2 %1 Blessure(s) Ouverte(s) + Il y a %2 %1 blessure(s) ouverte(s) Widzisz otwarte rany w ilości %2 o %1 rozmiarze Existem %2 ferimentos abertos %1 Jsou zde %2 %1 otevřené rány Ci sono %2 %1 Ferite Aperte + 開いている傷口が %2 %1 ほどあります + 여기 %2 %1 크기의 열린 상처가 있다 + 有 %2 %1 开放性伤口 + 有 %2 %1 開放性傷口 There is 1 %1 Open Wound @@ -462,50 +626,70 @@ Existe 1 %1 ferimento aberto Je zde 1 %1 otevřená rána C'è 1 %1 Ferita Aperta + 1 つの空いている %1 傷口 + 여기 %1 크기의 열린 상처가 있다 + 有 1 %1 开放性伤口 + 有 1 %1 開放性傷口 There is a partial %1 Open wound Er hat eine zum Teil offene Wunde (%1) Частично открытая рана %1 Hay una herida parcial abierta %1 - Il y a une Blessure Patiellement Ouverte %1 + Il y a une blessure partiellement ouverte %1 Widzisz częściowo otwartą ranę o %1 rozmiarze Existe um ferimento parcial aberto %1 Je zde částečně %1 otevřená rána C'è 1 parziale %1 Ferita Aperta + 部分的に開いている %1 の傷口があります + 여기 부분적으로 %1 크기의 상처가 있다 + 有部分 %1 开放性伤口 + 有部分 %1 開放性傷口 There are %2 %1 Bandaged Wounds Er hat %2 verbundene Wunden (%1) %2 перевязанные раны %1 Hay %2 Heridas %1 Vendadas - Il y a %2 %1 Blessure(s) Bandée(s) + Il y a %2 %1 blessure(s) bandée(s) Widzisz %2 zabandażowanych ran o %1 rozmiarze Existem %2 ferimentos %1 tratados Jsou zde %2 %1 ovázané rány Ci sono %2 %1 Ferite Bendate + ここには %2 %1 の処置された傷があります + 여기에 붕대를 감은 %2 %1 크기의 상처가 있다 + 有 %2 %1 包扎过伤口 + 有 %2 %1 包紮過傷口 There is 1 %1 Bandaged Wound Er hat 1 verbundene Wunde (%1) 1 перевязанная рана %1 Hay 1 Herida Vendada %1 - Il y a 1 %1 Blessure Bandée + Il y a 1 %1 blessure bandée Widzisz 1 zabandażowaną ranę o %1 rozmiarze Existe 1 ferimento %1 tratado Je zde 1 %1 ovázaná rána C'è 1 %1 Ferita Bendata + 1 つの包帯で巻かれている %1 傷 + 여기에 붕대를 감은 %1 크기의 상처가 있다 + 有 1 %1 包扎过伤口 + 有 1 %1 包紮過傷口 There is a partial %1 Bandaged wound Er hat eine zum Teil verbundene Wunde (%1) Частично перевязанная рана %1 Hay una Herida parcial %1 Vendada - Il y a %1 Blessure Partielment Bandée + Il y a %1 blessure partiellement bandée Widzisz 1 częściowo zabandażowaną ranę o %1 rozmiarze Existe um ferimento parcial tratado %1 Je zde částěčně %1 ovázaná rána C'è 1 parziale %1 Ferita Bendata + 患者には %1 の包帯で処置された傷があります + 여기 부분적으로 붕대질한 %1 크기의 상처가 있다 + 有部分 %1 包扎过伤口 + 有部分 %1 包紮過傷口 Normal breathing @@ -517,6 +701,10 @@ Respiração normal Normální dýchání Respirazione Normale + 通常の呼吸 + 정상 호흡 + 正常呼吸 + 正常呼吸 No breathing @@ -528,6 +716,10 @@ Sem respiração Nedýchá Nessuna Respirazione + 息をしていません + 호흡이 없음 + 没有呼吸 + 沒有呼吸 Difficult breathing @@ -539,6 +731,10 @@ Dificuldade para respirar Potíže s dýcháním Difficoltà Respiratorie + 呼吸が難しそうです + 호흡 곤란 + 呼吸困难 + 呼吸困難 Almost no breathing @@ -550,6 +746,10 @@ Quase sem respiração Téměř nedýchá Quasi nessuna Respirazione + ほとんど呼吸していません + 호흡이 거의 없음 + 几乎没有呼吸 + 幾乎沒有呼吸 Bleeding @@ -561,6 +761,10 @@ Sangrando Krvácí Sanguinamento + 出血中 + 출혈 + 出血中 + 出血中 in Pain @@ -572,17 +776,25 @@ Com dor v bolestech in Dolore + 痛みがある + 고통 + 疼痛中 + 疼痛中 Lost a lot of Blood hat sehr viel Blut verloren Большая кровопотеря Mucha Sangre perdida - A Perdu Bcp de Sang + A perdu beaucoup de sang Stracił dużo krwi Perdeu muito sangue Ztratil hodně krve Perso molto Sangue + 大量失血しています + 많은 피를 흘림 + 大量失血 + 大量失血 Tourniquet [CAT] @@ -594,6 +806,10 @@ Torniquete [CAT] Škrtidlo [CAT] Laccio Emostatico [CAT] + 止血帯 [CAT] + 지혈대 [CAT] + 军用止血带 + 軍用止血帶 Nasopharyngeal Tube [NPA] @@ -605,6 +821,24 @@ Tubo nasofaríngeo [NPA] Nasofaryngeální trubice [NPA] Tubo Nasofaringeo [NPA] + 鼻咽頭チューブ [NPA] + 비-인두 기도기 [NPA] + 鼻咽管 + 鼻咽管 + + + Medical Menu maximum range + 治療メニューの最大範囲 + 医疗菜单最大范围 + 醫療選單最大範圍 + Dirstanza menù medico + + + Maximum distance from where the Medical Menu can be opened. + 你可以打开医疗菜单的最大范围 + 醫療選單可以開啟的最大距離 + 医疗选单可以开启的最大距离 + Massima distanza dalla quale si può aprire il menù medico. - \ No newline at end of file + diff --git a/addons/microdagr/ACE_Settings.hpp b/addons/microdagr/ACE_Settings.hpp index f1e7595b74..fa51a6535d 100644 --- a/addons/microdagr/ACE_Settings.hpp +++ b/addons/microdagr/ACE_Settings.hpp @@ -1,10 +1,5 @@ class ACE_Settings { class GVAR(mapDataAvailable) { - displayName = CSTRING(MapDataAvailable_DisplayName); - description = CSTRING(MapDataAvailable_Description); - value = 2; - typeName = "SCALAR"; - isClientSettable = 0; - values[] = {CSTRING(MapFill_None), CSTRING(MapFill_OnlyRoads), CSTRING(MapFill_Full)}; + movedToSQF = 1; }; }; diff --git a/addons/microdagr/CfgUIGrids.hpp b/addons/microdagr/CfgUIGrids.hpp new file mode 100644 index 0000000000..5d7b921800 --- /dev/null +++ b/addons/microdagr/CfgUIGrids.hpp @@ -0,0 +1,21 @@ +class CfgUIGrids { + class IGUI { + class Presets { + class Arma3 { + class Variables { + grid_ACE_microDagr[] = {{"(safezoneX + safezoneW - 11 * (((safezoneW / safezoneH) min 1.2) / 40))","(safezoneY + safezoneH - 15 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))","(10 * (((safezoneW / safezoneH) min 1.2) / 40))","(10 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25))"},"(((safezoneW / safezoneH) min 1.2) / 40)","((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"}; + }; + }; + }; + + class Variables { + class grid_ACE_microDagr { + displayName = COMPONENT_NAME; + description = "ACE MicroDagr"; + preview = QPATHTOF(ui\IGUI_preview_ca.paa); + saveToProfile[] = {0,1,2,3}; + canResize = 1; + }; + }; + }; +}; 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/UI/IGUI_preview_ca.paa b/addons/microdagr/UI/IGUI_preview_ca.paa new file mode 100644 index 0000000000..12cbdb5f9b Binary files /dev/null and b/addons/microdagr/UI/IGUI_preview_ca.paa differ diff --git a/addons/microdagr/XEH_clientInit.sqf b/addons/microdagr/XEH_clientInit.sqf index 46003b9cb1..7a8d775a05 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 = { - ("ACE_microDAGR" in (items ACE_player)) +private _conditonCode = { + "ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems)) }; -_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/XEH_preInit.sqf b/addons/microdagr/XEH_preInit.sqf index ba262ec8c5..b46948b0bb 100644 --- a/addons/microdagr/XEH_preInit.sqf +++ b/addons/microdagr/XEH_preInit.sqf @@ -2,9 +2,13 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; //Functions that are called for each draw of the map: GVAR(miniMapDrawHandlers) = []; +#include "initSettings.sqf" + ADDON = true; diff --git a/addons/microdagr/config.cpp b/addons/microdagr/config.cpp index 5d33c073e1..a138a194d5 100644 --- a/addons/microdagr/config.cpp +++ b/addons/microdagr/config.cpp @@ -18,8 +18,5 @@ class CfgPatches { #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" #include "gui.hpp" +#include "CfgUIGrids.hpp" #include "ACE_Settings.hpp" - -class ACE_newEvents { - RangerfinderData = QEGVAR(vector,rangefinderData); -}; diff --git a/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf b/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf index 86ace87b3e..ece62c22e9 100644 --- a/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf +++ b/addons/microdagr/functions/fnc_appMarkKeypadEntry.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles the keypad entries from the "Mark" Application @@ -13,25 +14,22 @@ * * Public: No */ -#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_appMenuButtonConnectRangefinder.sqf b/addons/microdagr/functions/fnc_appMenuButtonConnectRangefinder.sqf index 589ec096fb..4aa01155ca 100644 --- a/addons/microdagr/functions/fnc_appMenuButtonConnectRangefinder.sqf +++ b/addons/microdagr/functions/fnc_appMenuButtonConnectRangefinder.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles the "Connect To" button from the menu application @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" GVAR(currentWaypoint) = [-2, -1] select (GVAR(currentWaypoint) == -2); GVAR(rangeFinderPositionASL) = []; diff --git a/addons/microdagr/functions/fnc_appSettingsLBClick.sqf b/addons/microdagr/functions/fnc_appSettingsLBClick.sqf index 9e808559b2..5c5c511ca6 100644 --- a/addons/microdagr/functions/fnc_appSettingsLBClick.sqf +++ b/addons/microdagr/functions/fnc_appSettingsLBClick.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles double clicking on the setting listbox @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; params ["", "_itemClicked"]; diff --git a/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf b/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf index d1fe1e8bdd..61508a1553 100644 --- a/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf +++ b/addons/microdagr/functions/fnc_appWaypointsButtonDeleteWP.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles clicking the delete button from the waypoint application @@ -13,16 +14,13 @@ * * Public: No */ -#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..80d5cfaef6 100644 --- a/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf +++ b/addons/microdagr/functions/fnc_appWaypointsButtonSetWP.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles clicking the setWP button from the waypoint application @@ -13,16 +14,13 @@ * * Public: No */ -#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_canShow.sqf b/addons/microdagr/functions/fnc_canShow.sqf index cb652b9214..0c80896661 100644 --- a/addons/microdagr/functions/fnc_canShow.sqf +++ b/addons/microdagr/functions/fnc_canShow.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Tests if the dagr can be shown in a mode @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_showType"]; private _returnValue = false; @@ -22,12 +22,12 @@ _returnValue = switch (_showType) do { case (DISPLAY_MODE_CLOSED): { true }; //Can always close case (DISPLAY_MODE_HIDDEN): { true }; //Can always hide case (DISPLAY_MODE_DIALOG): { - ("ACE_microDAGR" in (items ACE_player)) && {[ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)} + ("ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems))) && {[ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)} }; case (DISPLAY_MODE_DISPLAY): { //Can't have minimap up while zoomed in on foot, but allow drivers to use while in "Gunner" to handle non-3d vehicles like most tanks ((cameraView != "GUNNER") || {(vehicle ACE_player != ACE_player) && {driver vehicle ACE_player == ACE_player}}) && - {"ACE_microDAGR" in (items ACE_player)} && + {"ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems))} && {[ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)} }; default { false }; diff --git a/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf b/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf index ded268299c..443ab193e4 100644 --- a/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf +++ b/addons/microdagr/functions/fnc_deviceAddWaypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Adds a waypoint to the "device" @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_waypointName","_waypointPosASL"]; diff --git a/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf b/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf index b2e4f13d06..895b64bb38 100644 --- a/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf +++ b/addons/microdagr/functions/fnc_deviceDeleteWaypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Deletes a waypoint from the "device" @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_wpIndex"]; diff --git a/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf b/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf index da3484ceb0..c231b583b4 100644 --- a/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf +++ b/addons/microdagr/functions/fnc_deviceGetWaypoints.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Gets all waypoints from the "device" @@ -14,6 +15,5 @@ * * Public: No */ -#include "script_component.hpp" (ACE_player getVariable [QGVAR(waypoints), []]) diff --git a/addons/microdagr/functions/fnc_dialogClosedEH.sqf b/addons/microdagr/functions/fnc_dialogClosedEH.sqf index 5180734644..fc94b101f5 100644 --- a/addons/microdagr/functions/fnc_dialogClosedEH.sqf +++ b/addons/microdagr/functions/fnc_dialogClosedEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles the dialog closeing, switches back to display mode @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (GVAR(currentShowMode) == DISPLAY_MODE_DIALOG) then { [-1] call FUNC(saveCurrentAndSetNewMode); diff --git a/addons/microdagr/functions/fnc_mapButtonDownEH.sqf b/addons/microdagr/functions/fnc_mapButtonDownEH.sqf index 566f08dc66..9ca55bc5ab 100644 --- a/addons/microdagr/functions/fnc_mapButtonDownEH.sqf +++ b/addons/microdagr/functions/fnc_mapButtonDownEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles right clicking on the map ('dragging' the map) @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" params ["", "_mouseButton"]; diff --git a/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf b/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf index 02e111929d..aeb73414f5 100644 --- a/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf +++ b/addons/microdagr/functions/fnc_mapDoubleTapEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles the double tapping either of the 2 mini-maps @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_theMap", "_mouseButton", "_xPos", "_yPos"]; diff --git a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf index 92d647f348..15c1b0a59c 100644 --- a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf +++ b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles the draw event from all 3 maps (compass + 2 minimaps) @@ -13,25 +14,22 @@ * * Public: No */ -#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, _targetPos] call BIS_fnc_relativeDirTo; + 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_modeMapButtons.sqf b/addons/microdagr/functions/fnc_modeMapButtons.sqf index a0d74bec49..8ed8171535 100644 --- a/addons/microdagr/functions/fnc_modeMapButtons.sqf +++ b/addons/microdagr/functions/fnc_modeMapButtons.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Takes some arguments and returns something or other. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_mode"]; diff --git a/addons/microdagr/functions/fnc_moduleMapFill.sqf b/addons/microdagr/functions/fnc_moduleMapFill.sqf index 03089a4ff4..01e6af799f 100644 --- a/addons/microdagr/functions/fnc_moduleMapFill.sqf +++ b/addons/microdagr/functions/fnc_moduleMapFill.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Function for the module (handles the map fill level) @@ -13,9 +14,7 @@ * * Public: No */ -#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..775378a533 100644 --- a/addons/microdagr/functions/fnc_openDisplay.sqf +++ b/addons/microdagr/functions/fnc_openDisplay.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * 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 @@ -13,12 +14,9 @@ * * Public: No */ -#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: @@ -75,7 +73,7 @@ if ((_oldShowMode == DISPLAY_MODE_CLOSED) && {GVAR(currentShowMode) != DISPLAY_M [{ params ["_args", "_idPFH"]; _args params ["_player"]; - if ((isNull ACE_player) || {!alive ACE_player} || {ACE_player != _player} || {!("ACE_microDAGR" in (items ACE_player))} || {GVAR(currentShowMode) == DISPLAY_MODE_CLOSED}) then { + if ((isNull ACE_player) || {!alive ACE_player} || {ACE_player != _player} || {!("ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems)))} || {GVAR(currentShowMode) == DISPLAY_MODE_CLOSED}) then { //Close Display if still open: if (GVAR(currentShowMode) != DISPLAY_MODE_CLOSED) then { [DISPLAY_MODE_CLOSED] call FUNC(openDisplay); diff --git a/addons/microdagr/functions/fnc_recieveRangefinderData.sqf b/addons/microdagr/functions/fnc_recieveRangefinderData.sqf index 8b2c6672a8..640c42cfe4 100644 --- a/addons/microdagr/functions/fnc_recieveRangefinderData.sqf +++ b/addons/microdagr/functions/fnc_recieveRangefinderData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Recieves the data packet from the vector rangefinder @@ -15,20 +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..973e0ac7fb 100644 --- a/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf +++ b/addons/microdagr/functions/fnc_saveCurrentAndSetNewMode.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Saves the current mode and sets a new mode @@ -14,23 +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..1ba8a36d45 100644 --- a/addons/microdagr/functions/fnc_showApplicationPage.sqf +++ b/addons/microdagr/functions/fnc_showApplicationPage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Changes the "application page" shown on the microDAGR @@ -13,13 +14,10 @@ * * Public: No */ -#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..a78f369d56 100644 --- a/addons/microdagr/functions/fnc_updateDisplay.sqf +++ b/addons/microdagr/functions/fnc_updateDisplay.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Updates the display (several times a second) called from the pfeh @@ -13,35 +14,32 @@ * * Public: No */ -#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 GVAR(waypointPrecision)]; + 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 GVAR(waypointPrecision)]; }; (_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 GVAR(waypointPrecision)])]; } 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/gui.hpp b/addons/microdagr/gui.hpp index fe15bb7bb2..1404f6b81d 100644 --- a/addons/microdagr/gui.hpp +++ b/addons/microdagr/gui.hpp @@ -59,10 +59,10 @@ class GVAR(TheDialog) { //Redfine Scaling for the RscTitle -#define PROFILE_X (profilenamespace getVariable ['IGUI_GRID_GPS_X', 0]) -#define PROFILE_Y (profilenamespace getVariable ['IGUI_GRID_GPS_Y', 0]) -#define PROFILE_W (profilenamespace getVariable ['IGUI_GRID_GPS_W', 1]) -#define PROFILE_H ((16/9) * (profilenamespace getVariable ['IGUI_GRID_GPS_W', 1])) +#define PROFILE_X (profilenamespace getVariable ['IGUI_grid_ACE_microDagr_X', 0]) +#define PROFILE_Y (profilenamespace getVariable ['IGUI_grid_ACE_microDagr_Y', 0]) +#define PROFILE_W (profilenamespace getVariable ['IGUI_grid_ACE_microDagr_W', 1]) +#define PROFILE_H ((16/9) * (profilenamespace getVariable ['IGUI_grid_ACE_microDagr_W', 1])) //Need undef's for pboProject #undef X_PART diff --git a/addons/microdagr/initSettings.sqf b/addons/microdagr/initSettings.sqf new file mode 100644 index 0000000000..5138637645 --- /dev/null +++ b/addons/microdagr/initSettings.sqf @@ -0,0 +1,21 @@ +// CBA Settings [ADDON: ace_microdagr]: + +[ + QGVAR(mapDataAvailable), "LIST", + [LSTRING(MapDataAvailable_DisplayName), LSTRING(MapDataAvailable_Description)], + ["ACE Uncategorized", "MicroDAGR"], + [[0,1,2],[LSTRING(MapFill_None), LSTRING(MapFill_OnlyRoads), LSTRING(MapFill_Full)],2], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(mapDataAvailable), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // require mission restart +] call CBA_settings_fnc_init; + +[ + QGVAR(waypointPrecision), "LIST", + [LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)], + ["ACE Uncategorized", "MicroDAGR"], + [[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(waypointPrecision), _this] call EFUNC(common,cbaSettings_settingChanged)}, + false // require mission restart +] call cba_settings_fnc_init; diff --git a/addons/microdagr/script_component.hpp b/addons/microdagr/script_component.hpp index 60d7caaa80..56966b345d 100644 --- a/addons/microdagr/script_component.hpp +++ b/addons/microdagr/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MICRODAGR diff --git a/addons/microdagr/stringtable.xml b/addons/microdagr/stringtable.xml index c20ea7aede..dc0f506cc9 100644 --- a/addons/microdagr/stringtable.xml +++ b/addons/microdagr/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ MicroDAGR GPS GPS MicroDAGR GPS MicroDAGR + MicroDAGR GPS + MicroDAGR GPS + 微型军用GPS接收器 + 微型軍用GPS接收器 MicroDAGR advanced GPS receiver @@ -24,6 +28,10 @@ MicroDAGR fejlett GPS vevőegység Ricevitore GPS avanzato MicroDAGR Recepitor GPS avançado MicroDAGR + MicroDAGR は改良された GPS 受信機です + MicroDAGR 고급 위성항법 수신기 + 微型军用高级防御GPS接收器 + 微型軍用高級防禦GPS接收器 Angular Unit: @@ -36,6 +44,10 @@ Szögmértékegység: Unità angolare: Unidade Angular: + 角度の種類: + 각도의 단위: + 角密位: + 角密位: Mils @@ -48,6 +60,10 @@ Mil Mils Mils: + ミル + + 密位 + 密位 Show Waypoints On Map: @@ -60,6 +76,10 @@ Útvonalpontok mutatása a térképen: Mostra waypoint sulla mappa: Mostrar Waypoints no mapa: + 地図へウェイポイントを表示: + 웨이포인트를 지도에 보이기: + 显示路径点在地图上: + 顯示路徑點在地圖上: Degrees @@ -72,6 +92,10 @@ Fok Gradi Graus + 角度 + 각도 + + On @@ -84,6 +108,10 @@ Вкл. Encendido Be + 有効 + 켜기 + 开启 + 開啟 Off @@ -96,6 +124,10 @@ Выкл. Apagado Ki + 無効 + 끄기 + 关闭 + 關閉 Enter Grid Cords: @@ -108,6 +140,10 @@ Add meg a rácskoordinátákat: Introduci griglia coordinate: Digite as Ccords. do Grid + 座標を入力: + 输入网格座标: + 輸入網格座標: + 좌표 입력: Name of [%1] @@ -120,6 +156,10 @@ [%1] neve Nome di [%1] Nome do [%1] + [%1] の名前 + [%1] 의 이름 + 名称 [%1] + 名稱 [%1] MGRS-New @@ -132,6 +172,10 @@ MGRS-új Nuovo MGRS MGRS-Novo + MGRS-New + 军事网格座标系统-新型 + 軍事網格座標系統-新型 + MGRS-New WGD @@ -144,6 +188,10 @@ WGD WGD WGD + WGD + WGD + 世界座标 + 世界座標 Range: @@ -156,6 +204,10 @@ Távolság: Distanza: Distância: + 距離: + 거리: + 范围: + 範圍: Compass Direction @@ -168,6 +220,10 @@ Irányszög Azimut Direção na bússula + 方位磁石での方位 + 방위 + 指北针方位 + 指北針方位 Mark @@ -180,6 +236,10 @@ Jelölés Marca Marca + マーク + 표시 + 标记 + 標記 Waypoints @@ -192,6 +252,10 @@ Útvonalpontok waypoints Waypoints + ウェイポイント + 웨이포인트 + 路径点 + 路徑點 Connect To @@ -204,6 +268,10 @@ Csatlakozás Collega a Conectar à + 次に接続 + 연결 + 连接到 + 連接到 Settings @@ -216,6 +284,10 @@ Beállítások Impostaizoni Opções + 設定 + 설정 + 设定 + 設定 SetWP @@ -228,6 +300,10 @@ UP Beállítása Definisci WayPoints Definir WP + ウェイポイント設定 + 웨이포인트 설정 + 设置路径点 + 設置路徑點 Add @@ -240,6 +316,10 @@ Hozzáadás Aggiungi Adicionar + 追加 + 더하기 + 新增 + 新增 Delete @@ -252,6 +332,10 @@ Удалить Borrar Törlés + 削除 + 지우기 + 删除 + 刪除 Toggle MicroDAGR Display Mode @@ -264,6 +348,10 @@ MicroDAGR kijelzési mód váltása Alterna modalità display MicroDAGR Alternar Modo de Display do MicroDAGR + MicroDAGR の表示モード + MicroDAGR 화면 모드 토글 + 切换微型军用GPS接收器显示模式 + 切換微型軍用GPS接收器顯示模式 Show MicoDAGR @@ -276,6 +364,10 @@ MicroDAGR mutatása Mostra MicroDAGR Mostrar MicroDAGR + MicoDAGR を表示 + MicroDAGR 꺼내기 + 显示微型军用GPS接收器 + 顯示微型軍用GPS接收器 Configure MicroDAGR @@ -288,6 +380,10 @@ MicroDAGR konfigurálása ConfiguraMicroDAGR Configurar MicroDAGR + MicroDAGR を設定 + MicroDAGR 설정하기 + 设定微型军用GPS接收器 + 設定微型軍用GPS接收器 Close MicroDAGR @@ -300,6 +396,10 @@ MicroDAGR elrejtése Chiudi MicroDAGR Fechar MicroDAGR + MicroDAGR を閉じる + MicroDAGR 집어넣기 + 关闭微型军用GPS接收器 + 關閉微型軍用GPS接收器 MicroDAGR Map Fill @@ -312,6 +412,10 @@ MicroDAGR térképkitöltés Заполнение карты MicroDAGR Riempimento Mappa MicroDAGR + MicroDAGR での地図情報 + MicroDAGR - 지도채우기 + 微型军用GPS接收器地图资料 + 微型軍用GPS接收器地圖資料 MicroDAGR Map Fill @@ -324,6 +428,10 @@ MicroDAGR térképkitöltés Заполнение карты MicroDAGR Riempimento Mappa MicroDAGR + MicroDAGR での地図情報 + MicroDAGR - 지도채우기 + 微型军用GPS接收器地图资料 + 微型軍用GPS接收器地圖資料 How much map data is filled on MicroDAGR's @@ -336,6 +444,10 @@ Mennyi térképadatot tartalmaz a MicroDAGR Сколько данных должно отображаться на карте MicroDAGR Quanti dati sono trasferiti nella mappa del MicroDAGR + MicroDAGR で表示する地図情報を決定します + 얼마나 많은 데이터가 MicroDAGR에 있는지에 대한 정보 + 有多少地图数据会显示在微型军用GPS接收器 + 有多少地圖數據會顯示在微型軍用GPS接收器 Full Satellite + Buildings @@ -348,6 +460,10 @@ Teljes műholdas + épületek Спутник + Здания Satellite Completo + Edifici + 完全な衛星画像と建物 + 위성 사진 + 건물 + 完整卫星画面 + 建筑物位置 + 完整衛星畫面 + 建築物位置 Topographical + Roads @@ -360,6 +476,10 @@ Topográfia + utak Топография + Дороги Topografico + Strade + 地形と道路 + 지형학 도표 + 도로 + 地形 + 道路 + 地形 + 道路 None (Cannot use map view) @@ -372,6 +492,35 @@ Semmi (nem használható a térképnézet) Не показывать (запрещает использовать режим карты) Nessuno (Non puoi usare la vista mappa) + なし(地図表示を使えません) + 없음 (지도를 볼 수 없음) + 无 (无法检视地图) + 無 (無法檢視地圖) + + + MicroDAGR - Waypoint Precision + MicroDAGR - Wegpunkt Genauigkeit + MicroDAGR - Precisione del Waypoint + + + Controls how precise the waypointdistance can be displayed + Legt die Genauigkeit der Entfernung von Wegpunkten fest + Controlla quanto precisamente può essere visualizzato il waypoint a distanza + + + 100m + 100m + 100m + + + 10m + 10m + 10m + + + 1m + 1m + 1m Controls how much data is filled on the microDAGR items. Less data restricts the map view to show less on the minimap. @@ -384,6 +533,10 @@ Meghatárroza a MicroDAGR objektumok térképének tartalmát. A kevesebb adat korlátozza a térképnézeti módot az eszközön. Контролирует, сколько данных должно отображаться на карте устройств MicroDAGR. Ограничивает объем отображаемых данных на миникарте. Controlla quanti dati sono presenti negli oggetti MicroDAGR. Meno dati costringono la vista mappa a mostrare meno informazioni nella minimappa. + アイテム上で表示されるデータ量を決定します。設定を減らすと地図上での情報が少なくなります。 + MicroDAGR에 얼마나 많은 데이터가 들어있는지 정합니다. 적을 수록 지도상에도 비춰지는게 적어집니다. + 设定有多少数据会显示在微型军用GPS接收器上。这些资料的多寡会反映在迷你地图的显示上。 + 設定有多少數據會顯示在微型軍用GPS接收器上。這些資料的多寡會反映在迷你地圖的顯示上。 - \ No newline at end of file + diff --git a/addons/minedetector/CfgVehicles.hpp b/addons/minedetector/CfgVehicles.hpp index 14273b108c..ab6c06b4cb 100644 --- a/addons/minedetector/CfgVehicles.hpp +++ b/addons/minedetector/CfgVehicles.hpp @@ -1,9 +1,9 @@ class CfgVehicles { class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { - class TransportItems { - MACRO_ADDITEM(ACE_VMM3,4); - MACRO_ADDITEM(ACE_VMH3,4); + class TransportWeapons { + MACRO_ADDWEAPON(ACE_VMM3,4); + MACRO_ADDWEAPON(ACE_VMH3,4); }; }; diff --git a/addons/minedetector/XEH_postInit.sqf b/addons/minedetector/XEH_postInit.sqf index 4b842e3488..7ea04b5a5d 100644 --- a/addons/minedetector/XEH_postInit.sqf +++ b/addons/minedetector/XEH_postInit.sqf @@ -27,7 +27,7 @@ addMissionEventHandler ["Draw3D", { GVAR(debugDetector) params ["_detectorPointAGL", "_mines"]; drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [0,0,1,1], _detectorPointAGL, 1, 1, 0, "detector", 1, 0.02, "PuristaMedium"]; { - _name = format ["%1@%2", typeOf _x, (floor ((_x distance _detectorPointAGL) * 10)) / 10]; + private _name = format ["%1@%2", typeOf _x, (floor ((_x distance _detectorPointAGL) * 10)) / 10]; if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _x) >> QGVAR(detectable))) == 1) then { drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [1,0,0,1], (ASLtoAGL (getPosASL _x)), 1, 1, 0, _name, 1, 0.02, "PuristaMedium"]; } else { diff --git a/addons/minedetector/XEH_preInit.sqf b/addons/minedetector/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/minedetector/XEH_preInit.sqf +++ b/addons/minedetector/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/minedetector/functions/fnc_activateDetector.sqf b/addons/minedetector/functions/fnc_activateDetector.sqf index f22dae1ee9..5ce236250b 100644 --- a/addons/minedetector/functions/fnc_activateDetector.sqf +++ b/addons/minedetector/functions/fnc_activateDetector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Activate the mine detector @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - if (call FUNC(canActivateDetector)) then { [ACE_player, currentWeapon ACE_player] call FUNC(enableDetector); }; diff --git a/addons/minedetector/functions/fnc_canActivateDetector.sqf b/addons/minedetector/functions/fnc_canActivateDetector.sqf index 93089df063..8a5d795b49 100644 --- a/addons/minedetector/functions/fnc_canActivateDetector.sqf +++ b/addons/minedetector/functions/fnc_canActivateDetector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if the mine detector can be activated @@ -14,7 +15,5 @@ * Public: No */ -#include "script_component.hpp" - ([ACE_player] call FUNC(hasDetector)) && !([ACE_player, currentWeapon ACE_player] call FUNC(isDetectorEnabled)); diff --git a/addons/minedetector/functions/fnc_canConnectHeadphones.sqf b/addons/minedetector/functions/fnc_canConnectHeadphones.sqf index dfaf9699d8..4266f6e065 100644 --- a/addons/minedetector/functions/fnc_canConnectHeadphones.sqf +++ b/addons/minedetector/functions/fnc_canConnectHeadphones.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Check if headphones can be connected to the mine detector @@ -14,7 +15,5 @@ * Public: No */ -#include "script_component.hpp" - !(ACE_player getVariable [QGVAR(isUsingHeadphones), false]) && {[ACE_player] call FUNC(hasDetector)}; diff --git a/addons/minedetector/functions/fnc_canDeactivateDetector.sqf b/addons/minedetector/functions/fnc_canDeactivateDetector.sqf index e308ba3789..8c38363288 100644 --- a/addons/minedetector/functions/fnc_canDeactivateDetector.sqf +++ b/addons/minedetector/functions/fnc_canDeactivateDetector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if the mine detector can be deactivated @@ -14,7 +15,5 @@ * Public: No */ -#include "script_component.hpp" - ([ACE_player] call FUNC(hasDetector)) && {[ACE_player, currentWeapon ACE_player] call FUNC(isDetectorEnabled)}; diff --git a/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf b/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf index f58fe6617d..b55338b641 100644 --- a/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf +++ b/addons/minedetector/functions/fnc_canDisconnectHeadphones.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Check if headphones can be disconnected from the mine detector @@ -14,7 +15,5 @@ * Public: No */ -#include "script_component.hpp" - (ACE_player getVariable [QGVAR(isUsingHeadphones), false]) && {[ACE_player] call FUNC(hasDetector)}; diff --git a/addons/minedetector/functions/fnc_connectHeadphones.sqf b/addons/minedetector/functions/fnc_connectHeadphones.sqf index 2a715a66a0..3bf76a4d23 100644 --- a/addons/minedetector/functions/fnc_connectHeadphones.sqf +++ b/addons/minedetector/functions/fnc_connectHeadphones.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Connect/disconnect headphones to the mine detector @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_state"]; _unit setVariable [QGVAR(isUsingHeadphones), _state]; diff --git a/addons/minedetector/functions/fnc_deactivateDetector.sqf b/addons/minedetector/functions/fnc_deactivateDetector.sqf index 05ce00d978..7ed0713846 100644 --- a/addons/minedetector/functions/fnc_deactivateDetector.sqf +++ b/addons/minedetector/functions/fnc_deactivateDetector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Deactivate the mine detector @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - if (call FUNC(canDeactivateDetector)) then { [ACE_player, currentWeapon ACE_player] call FUNC(disableDetector); }; diff --git a/addons/minedetector/functions/fnc_detectorLoop.sqf b/addons/minedetector/functions/fnc_detectorLoop.sqf index e5fd4d5bd3..3895ab8193 100644 --- a/addons/minedetector/functions/fnc_detectorLoop.sqf +++ b/addons/minedetector/functions/fnc_detectorLoop.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Handle mine detection in a PFH loop @@ -9,11 +10,12 @@ * Return Value: * None * + * Example: + * [[args], 2] call ACE_minedetector_fnc_detectorLoop + * * Public: No */ -#include "script_component.hpp" - params ["_args", "_idPFH"]; _args params ["_unit", "_type", "_detectorConfig", "_lastPlayed"]; diff --git a/addons/minedetector/functions/fnc_disableDetector.sqf b/addons/minedetector/functions/fnc_disableDetector.sqf index e2fbb55798..be0c57117d 100644 --- a/addons/minedetector/functions/fnc_disableDetector.sqf +++ b/addons/minedetector/functions/fnc_disableDetector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Disables the mine detector @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_detectorType"]; if !(local _unit) then { diff --git a/addons/minedetector/functions/fnc_enableDetector.sqf b/addons/minedetector/functions/fnc_enableDetector.sqf index 8ed31433d1..2bb663d977 100644 --- a/addons/minedetector/functions/fnc_enableDetector.sqf +++ b/addons/minedetector/functions/fnc_enableDetector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Enables the mine detector @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_detectorType"]; if !(local _unit) then { diff --git a/addons/minedetector/functions/fnc_getDetectedObject.sqf b/addons/minedetector/functions/fnc_getDetectedObject.sqf index 0b6faa6168..9bcfcf2cc7 100644 --- a/addons/minedetector/functions/fnc_getDetectedObject.sqf +++ b/addons/minedetector/functions/fnc_getDetectedObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the distance to the nearest detectable object @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_detectorConfig"]; _detectorConfig params ["", "_radius"]; @@ -42,7 +41,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/minedetector/functions/fnc_getDetectorConfig.sqf b/addons/minedetector/functions/fnc_getDetectorConfig.sqf index ccafa83edd..313cc30142 100644 --- a/addons/minedetector/functions/fnc_getDetectorConfig.sqf +++ b/addons/minedetector/functions/fnc_getDetectorConfig.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Get the mine detector configuration from the cache or config file @@ -14,10 +15,10 @@ * Public: No */ -#include "script_component.hpp" - params ["_detectorType"]; +if (_detectorType isEqualTo "") exitWith {[]}; + private _detectorConfig = GVAR(detectorConfigs) getVariable _detectorType; if (isNil "_detectorConfig") then { private _cfgEntry = (configFile >> "ACE_detector" >> "detectors" >> _detectorType); diff --git a/addons/minedetector/functions/fnc_hasDetector.sqf b/addons/minedetector/functions/fnc_hasDetector.sqf index fcd6eb1c19..4752284196 100644 --- a/addons/minedetector/functions/fnc_hasDetector.sqf +++ b/addons/minedetector/functions/fnc_hasDetector.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if unit has a mine detector in hands @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit"]; !(([currentWeapon _unit] call FUNC(getDetectorConfig)) isEqualTo []); diff --git a/addons/minedetector/functions/fnc_isDetectorEnabled.sqf b/addons/minedetector/functions/fnc_isDetectorEnabled.sqf index 9e75788794..95ff89fa65 100644 --- a/addons/minedetector/functions/fnc_isDetectorEnabled.sqf +++ b/addons/minedetector/functions/fnc_isDetectorEnabled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if the mine detector is enabled @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_detectorType"]; alive _unit && {(_unit getVariable [format[QGVAR(enable_%1), _detectorType], false])}; diff --git a/addons/minedetector/functions/fnc_playDetectorSound.sqf b/addons/minedetector/functions/fnc_playDetectorSound.sqf index dc57532b8c..8e47508209 100644 --- a/addons/minedetector/functions/fnc_playDetectorSound.sqf +++ b/addons/minedetector/functions/fnc_playDetectorSound.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Play the detector sound @@ -15,15 +16,13 @@ * Public: No */ -#include "script_component.hpp" - params ["_unit", "_soundClass"]; if (isNull _unit) exitWith { - ACE_LOGERROR_1("unit does not exist [%1]",_unit); + ERROR_1("unit does not exist [%1]",_unit); }; if (!alive _unit) exitWith { - ACE_LOGERROR_1("unit is not alive [%1]",_unit); + ERROR_1("unit is not alive [%1]",_unit); }; if (_unit getVariable [QGVAR(isUsingHeadphones), false] && {_unit == ACE_player}) then { diff --git a/addons/minedetector/script_component.hpp b/addons/minedetector/script_component.hpp index f6a1d05dfc..154f1a05e2 100644 --- a/addons/minedetector/script_component.hpp +++ b/addons/minedetector/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MINEDETECTOR diff --git a/addons/minedetector/stringtable.xml b/addons/minedetector/stringtable.xml index 46c0d8c3b9..72f389813f 100644 --- a/addons/minedetector/stringtable.xml +++ b/addons/minedetector/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -6,44 +6,104 @@ Détecteur de métaux Детектор металла Detektor kovů + 地雷探知機 + Wykrywacz metali + Metalldetektor + 지뢰탐지기 + Metal detector + 金属探测器 + 金屬探測器 Metal detector Détecteur de métaux Детектор металла Detektor kovů + 地雷探知機 + Wykrywacz metali + Metalldetektor + 지뢰탐지기 + Metal detector + 金属探测器 + 金屬探測器 Activate Activer Включить Aktivovat + 起動 + Aktywuj + Aktivieren + 작동 + Attiva + 启用探测器 + 啟用探測器 Deactivate Désactiver Выключить Deaktivovat + 停止 + Deaktywuj + Deaktivieren + 끄기 + Disattiva + 停用探测器 + 停用探測器 Connect Headphones Подключить наушники Připojit sluchátka + ヘッドホンへつなぐ + Podłącz słuchawki + Kopfhörer verbinden + 헤드폰에 연결 + Connecter les écouteurs + Connetti Auricolari + 连接耳机 + 連接耳機 Disconnect Headphones Отключить наушники Odpojit sluchátka + ヘッドホンからはずす + Odłącz słuchawki + Kopfhörer trennen + 헤드폰 연결끊기 + Déconnecter les écouteurs + Disconnetti Auricolari + 断开耳机 + 斷開耳機 Headphones Connected Наушники подключены Sluchátka připojena + ヘッドホンに接続しました + Słuchawki podpięte + Kopfhörer verbunden + 헤드폰 연결됨 + Écouteurs connectés + Auricolari Connessi + 已连接耳机 + 已連接耳機 Headphones Disconnected Наушники отключены Sluchátka odpojena + ヘッドホンから外しました + Słuchawki odpięte + Kopfhörer getrennt + 헤드폰 연결끊김 + Écouteurs déconnectés + Auricolari Disconnessi + 已断开耳机 + 已斷開耳機 - \ No newline at end of file + diff --git a/addons/missileguidance/ACE_Settings.hpp b/addons/missileguidance/ACE_Settings.hpp deleted file mode 100644 index e73d533c08..0000000000 --- a/addons/missileguidance/ACE_Settings.hpp +++ /dev/null @@ -1,10 +0,0 @@ -class ACE_Settings { - class GVAR(enabled) { - value = 2; - typeName = "SCALAR"; - isClientSettable = 1; - displayName = CSTRING(Title); - description = CSTRING(Desc); - values[] = {CSTRING(Off), CSTRING(PlayerOnly), CSTRING(PlayerAndAi)}; - }; -}; \ No newline at end of file diff --git a/addons/missileguidance/CfgAmmo.hpp b/addons/missileguidance/CfgAmmo.hpp index 592cf6d996..7c2fb90d22 100644 --- a/addons/missileguidance/CfgAmmo.hpp +++ b/addons/missileguidance/CfgAmmo.hpp @@ -1,44 +1,7 @@ -enum { - ACE_LOBL = 1, - ACE_LOAL = 2 -}; - class CfgAmmo { class MissileBase; - class M_PG_AT: MissileBase { - model = "\A3\Weapons_F\Ammo\Rocket_01_fly_F"; - proxyShape = "\A3\Weapons_F\Ammo\Rocket_01_F"; - - // Reenable this settings when ACE laser targeting and missile guidance is reenabled - //laserLock = 1; - //airLock = 0; - //irLock = 0; - //weaponLockSystem = "4 + 16"; - //fuseDistance = 2; - //timeToLive = 60; - // Turn off arma crosshair-guidance - //manualControl = 0; - // ACE uses these values - //trackOversteer = 1; - //trackLead = 0; - - maxSpeed = 720; - maxControlRange = 5000; - maneuvrability = 8; - - simulationStep = 0.01; - airFriction = 0.1; - sideAirFriction = 0.16; - initTime = 0.002; - thrustTime = 1.07; - thrust = 530; - - effectsMissileInit = "MissileDAR1"; - effectsMissile = "missile2"; - whistleDist = 4; - muzzleEffect = ""; - }; + class M_PG_AT: MissileBase {}; class ACE_Hydra70_DAGR: M_PG_AT { displayName = CSTRING(Hydra70_DAGR); @@ -47,13 +10,18 @@ class CfgAmmo { description = CSTRING(Hydra70_DAGR_Desc); descriptionShort = CSTRING(Hydra70_DAGR_Desc); + irLock = 0; + laserLock = 0; + manualControl = 0; + maxSpeed = 300; + EGVAR(rearm,caliber) = 70; class ADDON { enabled = 1; - minDeflection = 0.00025; // Minium flap deflection for guidance - maxDeflection = 0.001; // Maximum flap deflection for guidance + minDeflection = 0.0005; // Minium flap deflection for guidance + maxDeflection = 0.0025; // Maximum flap deflection for guidance incDeflection = 0.0005; // The incrmeent in which deflection adjusts. canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode @@ -77,31 +45,11 @@ class CfgAmmo { }; }; - class ACE_Hellfire_AGM114K: ACE_Hydra70_DAGR { - displayName = CSTRING(Hellfire_AGM114K); - displayNameShort = CSTRING(Hellfire_AGM114K_Short); - - description = CSTRING(Hellfire_AGM114K_desc); - descriptionShort = CSTRING(Hellfire_AGM114K_desc); - - // @TODO: placeholder model to at least make it look different - model = "\A3\Weapons_F\Ammo\Missile_AT_03_fly_F"; - proxyShape = "\A3\Weapons_F\Ammo\Missile_AT_03_F"; - - hit = 1400; - indirectHit = 71; - indirectHitRange = 4.5; - effectsMissile = "missile2"; - - //Explicity add guidance config - class ADDON: ADDON {}; - }; - // Titan class M_Titan_AT: MissileBase {}; class ACE_Javelin_FGM148: M_Titan_AT { - irLock = 0; + irLock = 1; laserLock = 0; airLock = 0; @@ -140,6 +88,8 @@ class CfgAmmo { seekerMinRange = 0; seekerMaxRange = 2500; // Range from the missile which the seeker can visually search + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + // Attack profile type selection defaultAttackProfile = "JAV_TOP"; attackProfiles[] = { "JAV_TOP", "JAV_DIR" }; diff --git a/addons/missileguidance/CfgMagazines.hpp b/addons/missileguidance/CfgMagazines.hpp index e4a84862ae..7cc33b17a3 100644 --- a/addons/missileguidance/CfgMagazines.hpp +++ b/addons/missileguidance/CfgMagazines.hpp @@ -24,30 +24,4 @@ class CfgMagazines { descriptionShort = "24 Round DAGR"; weight = 72; }; - - // Hellfires - class 6Rnd_ACE_Hellfire_AGM114K : 12Rnd_PG_missiles { - count = 12; - ammo = "ACE_Hellfire_AGM114K"; - displayName = "6Rnd_ACE_Hellfire_AGM114K"; - displayNameShort = "6Rnd_ACE_Hellfire_AGM114K"; - descriptionShort = "6Rnd_ACE_Hellfire_AGM114K"; - weight = 36; - - }; - class 12Rnd_ACE_Hellfire_AGM114K : 6Rnd_ACE_Hydra70_DAGR { - count = 12; - displayName = "12Rnd_ACE_Hellfire_AGM114K"; - displayNameShort = "12Rnd_ACE_Hellfire_AGM114K"; - descriptionShort = "12Rnd_ACE_Hellfire_AGM114K"; - weight = 72; - }; - class 24Rnd_ACE_Hellfire_AGM114K : 6Rnd_ACE_Hydra70_DAGR { - count = 24; - displayName = "24Rnd_ACE_Hellfire_AGM114K"; - displayNameShort = "24Rnd_ACE_Hellfire_AGM114K"; - descriptionShort = "24Rnd_ACE_Hellfire_AGM114K"; - weight = 72; - }; - }; diff --git a/addons/missileguidance/CfgVehicles.hpp b/addons/missileguidance/CfgVehicles.hpp deleted file mode 100644 index be5c31a3f6..0000000000 --- a/addons/missileguidance/CfgVehicles.hpp +++ /dev/null @@ -1,36 +0,0 @@ -class CfgVehicles { - - class AllVehicles; - class Air: AllVehicles { - class Turrets; - }; - - class Helicopter: Air { - class Turrets { - class MainTurret; - }; - }; - class Helicopter_Base_F: Helicopter {}; - class Heli_Attack_01_base_F: Helicopter_Base_F {}; - class B_Heli_Attack_01_F : Heli_Attack_01_base_F { - class Turrets: Turrets { - class MainTurret; - }; - }; - - class ACE_Comanche_Test : B_Heli_Attack_01_F { - scope = 1; - scopeCurator = 0; - displayName = "ACE_Comanche_Test"; - author = "ACE Team"; - class Library { - libTextDesc = "ACE_Comanche_Test"; - }; - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "24Rnd_ACE_Hellfire_AGM114K"}; - }; - }; - }; - -}; diff --git a/addons/missileguidance/CfgWeapons.hpp b/addons/missileguidance/CfgWeapons.hpp index f57e3ab0df..b03628e777 100644 --- a/addons/missileguidance/CfgWeapons.hpp +++ b/addons/missileguidance/CfgWeapons.hpp @@ -1,12 +1,10 @@ -class Mode_SemiAuto; class CfgWeapons { - class CannonCore; - class LauncherCore; + class missiles_DAGR; - class RocketPods: LauncherCore { - // canLock = 1; - }; - class missiles_DAGR : RocketPods { - canLock = 2; + class GVAR(dagr): missiles_DAGR { + canLock = 0; + magazines[] = {"6Rnd_ACE_Hydra70_DAGR","12Rnd_ACE_Hydra70_DAGR","24Rnd_ACE_Hydra70_DAGR"}; + lockingTargetSound[] = {"",0,1}; + lockedTargetSound[] = {"",0,1}; }; }; diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 55948e7171..ee2b7328cb 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -1,6 +1,6 @@ +LOG("prep"); +PREP(cycleAttackProfileKeyDown); -PREP(rotateVectLineGetMap); -PREP(rotateVectLine); PREP(changeMissileDirection); PREP(checkSeekerAngle); @@ -17,11 +17,11 @@ PREP(doHandoff); PREP(handleHandoff); // Attack Profiles -PREP(attackProfile_LIN); -PREP(attackProfile_DIR); -PREP(attackProfile_MID); -PREP(attackProfile_HI); PREP(attackProfile_AIR); +PREP(attackProfile_DIR); +PREP(attackProfile_HI); +PREP(attackProfile_LIN); +PREP(attackProfile_MID); // Javelin profiles PREP(attackProfile_JAV_DIR); diff --git a/addons/missileguidance/XEH_post_init.sqf b/addons/missileguidance/XEH_post_init.sqf index 282aac5503..cc09b1f0ac 100644 --- a/addons/missileguidance/XEH_post_init.sqf +++ b/addons/missileguidance/XEH_post_init.sqf @@ -1,3 +1,13 @@ #include "script_component.hpp" [QGVAR(handoff), {_this call FUNC(handleHandoff)}] call CBA_fnc_addEventHandler; + +["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), +{ + [] call FUNC(cycleAttackProfileKeyDown); + false +}, +{ + false +}, +[15, [false, true, false]], false] call CBA_fnc_addKeybind; //Ctrl+Tab Key diff --git a/addons/missileguidance/XEH_pre_init.sqf b/addons/missileguidance/XEH_pre_init.sqf index a7feade1c3..f377efddb6 100644 --- a/addons/missileguidance/XEH_pre_init.sqf +++ b/addons/missileguidance/XEH_pre_init.sqf @@ -2,6 +2,13 @@ ADDON = false; +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 c97a542a7f..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,10 +14,8 @@ class CfgPatches { }; #include "ACE_GuidanceConfig.hpp" -#include "ACE_Settings.hpp" #include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf index 9909124e2f..823e85efaa 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_AIR.sqf @@ -1,4 +1,21 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: AIR + * TODO: falls back to Linear + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_AIR; + * + * Public: No + */ -_this call FUNC(attackProfile_LIN); \ No newline at end of file +_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf index 9909124e2f..cddd70807e 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf @@ -1,4 +1,21 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: DIR + * TODO: falls back to Linear + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_DIR; + * + * Public: No + */ -_this call FUNC(attackProfile_LIN); \ No newline at end of file +_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf b/addons/missileguidance/functions/fnc_attackProfile_HI.sqf index 9909124e2f..6f1fbe67d3 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_HI.sqf @@ -1,4 +1,21 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: HI + * TODO: falls back to Linear + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_HI; + * + * Public: No + */ -_this call FUNC(attackProfile_LIN); \ No newline at end of file +_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf index 1fec6b1ee0..f277c1bc68 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf @@ -1,55 +1,66 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: Javelin Dir + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_JAV_DIR; + * + * Public: No + */ #define STAGE_LAUNCH 1 #define STAGE_CLIMB 2 #define STAGE_COAST 3 #define STAGE_TERMINAL 4 -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private ["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"]; -private ["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"]; -private ["_cruisAlt", "_distanceShooterToTarget", "_shooterPos"]; -_seekerTargetPos = _this select 0; -_launchParams = _this select 1; +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH"]; +_firedEH params ["_shooter","","","","","","_projectile"]; -_target = _launchParams select 0; -_targetLaunchParams = _launchParams select 1; +if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; -_state = _this select 2; -if( (count _state) < 1) then { - _state set[0, STAGE_LAUNCH]; +if (_attackProfileStateParams isEqualTo []) then { + _attackProfileStateParams set [0, STAGE_LAUNCH]; }; -_shooterPos = getPosASL _shooter; -_projectilePos = getPosASL _projectile; +private _shooterPos = getPosASL _shooter; +private _projectilePos = getPosASL _projectile; -_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; -_distanceToShooter = _projectilePos vectorDistance _shooterPos; -_distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; +private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; +private _distanceToShooter = _projectilePos vectorDistance _shooterPos; +private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; TRACE_2("", _distanceToTarget, _distanceToShooter); // Add height depending on distance for compensate -_returnTargetPos = _seekerTargetPos; +private _returnTargetPos = _seekerTargetPos; -switch( (_state select 0) ) do { +switch (_attackProfileStateParams select 0) do { case STAGE_LAUNCH: { TRACE_1("STAGE_LAUNCH",""); - if(_distanceToShooter < 10) then { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 2]; + if (_distanceToShooter < 10) then { + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; } else { - _state set [0, STAGE_CLIMB]; + _attackProfileStateParams set [0, STAGE_CLIMB]; }; }; case STAGE_CLIMB: { TRACE_1("STAGE_CLIMB",""); - _cruisAlt = 60 * (_distanceShooterToTarget/2000); + private _cruisAlt = 60 * (_distanceShooterToTarget/2000); - if( ((ASLToATL _projectilePos) select 2) - ((ASLToATL _seekerTargetPos) select 2) >= _cruisAlt) then { - _state set [0, STAGE_TERMINAL]; + if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { + _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 1.5]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5]; }; }; case STAGE_TERMINAL: { @@ -58,9 +69,5 @@ switch( (_state select 0) ) do { }; }; -#ifdef DEBUG_MODE_FULL -drawLine3D [(ASLtoATL _returnTargetPos), (ASLtoATL _seekerTargetPos), [0, 1, 0, 1]]; -#endif - TRACE_1("Adjusted target position", _returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf index 9a5a64f255..08219ea24a 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf @@ -1,84 +1,90 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: Javelin Top + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_JAV_TOP; + * + * Public: No + */ #define STAGE_LAUNCH 1 #define STAGE_CLIMB 2 #define STAGE_COAST 3 #define STAGE_TERMINAL 4 -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private ["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"]; -private ["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_state"]; -private ["_cruisAlt", "_distanceShooterToTarget", "_shooterPos"]; +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH"]; +_firedEH params ["_shooter","","","","","","_projectile"]; -_seekerTargetPos = _this select 0; -_launchParams = _this select 1; +if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; -_target = _launchParams select 0; -_targetLaunchParams = _launchParams select 1; - -_state = _this select 2; -if( (count _state) < 1) then { - _state set[0, STAGE_LAUNCH]; +if (_attackProfileStateParams isEqualTo []) then { + _attackProfileStateParams set [0, STAGE_LAUNCH]; }; -_shooterPos = getPosASL _shooter; -_projectilePos = getPosASL _projectile; +private _shooterPos = getPosASL _shooter; +private _projectilePos = getPosASL _projectile; -_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; -_distanceToShooter = _projectilePos vectorDistance _shooterPos; -_distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; +private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; +private _distanceToShooter = _projectilePos vectorDistance _shooterPos; +private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; TRACE_2("", _distanceToTarget, _distanceToShooter); // Add height depending on distance for compensate -_returnTargetPos = _seekerTargetPos; +private _returnTargetPos = _seekerTargetPos; -switch( (_state select 0) ) do { +switch( (_attackProfileStateParams select 0) ) do { case STAGE_LAUNCH: { TRACE_1("STAGE_LAUNCH",""); - if(_distanceToShooter < 10) then { - _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 2]; + if (_distanceToShooter < 10) then { + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*2]; } else { - _state set[0, STAGE_CLIMB]; + _attackProfileStateParams set [0, STAGE_CLIMB]; }; }; case STAGE_CLIMB: { TRACE_1("STAGE_CLIMB",""); - _cruisAlt = 140; - if(_distanceShooterToTarget < 1250) then { + private _cruisAlt = 140; + if (_distanceShooterToTarget < 1250) then { _cruisAlt = 140 * (_distanceShooterToTarget/1250); TRACE_1("_cruisAlt", _cruisAlt); }; - if(((ASLToATL _projectilePos) select 2) - ((ASLToATL _seekerTargetPos) select 2) >= _cruisAlt) then { - if(_cruisAlt < 140) then { - _state set[0, STAGE_TERMINAL]; + if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { + if (_cruisAlt < 140) then { + _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { - _state set[0, STAGE_COAST]; + _attackProfileStateParams set [0, STAGE_COAST]; }; } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0, 0, _distanceToTarget * 1.5]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget*1.5]; }; }; case STAGE_COAST: { TRACE_1("STAGE_COAST",""); - TRACE_1("", ((ASLToATL _projectilePos) select 2) - (( ASLToATL _seekerTargetPos) select 2) ); - if(_distanceToTarget < (((ASLToATL _projectilePos) select 2) - (( ASLToATL _seekerTargetPos) select 2)) * 1.5) then { - _state set[0, STAGE_TERMINAL]; + TRACE_1("", ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ); + if (_distanceToTarget < ( ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ) * 2) then { + _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { - _returnTargetPos = _seekerTargetPos vectorAdd [0, 0, (_projectilePos select 2)]; + _returnTargetPos = _seekerTargetPos vectorAdd [0,0,(_projectilePos select 2)]; }; }; case STAGE_TERMINAL: { TRACE_1("STAGE_TERMINAL",""); - //_returnTargetPos = _seekerTargetPos vectorAdd [0, 0, _distanceToTarget * 0.02]; + //_returnTargetPos = _seekerTargetPos vectorAdd [0,0,_distanceToTarget * 0.02]; _returnTargetPos = _seekerTargetPos; }; }; -#ifdef DEBUG_MODE_FULL -drawLine3D [(ASLtoATL _returnTargetPos), (ASLtoATL _seekerTargetPos), [0, 1, 0, 1]]; -#endif - TRACE_1("Adjusted target position", _returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf index f85643a8e2..464ee9e36b 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -1,50 +1,59 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: Linear (used by DAGR) + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_LIN; + * + * Public: No + */ -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private ["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"]; -private ["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos", "_shooterPos"]; -_seekerTargetPos = _this select 0; -_launchParams = _this select 1; +params ["_seekerTargetPos", "_args"]; +_args params ["_firedEH"]; +_firedEH params ["_shooter","","","","","","_projectile"]; -_target = _launchParams select 0; -_targetLaunchParams = _launchParams select 1; +if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; -_shooterPos = getPosASL _shooter; -_projectilePos = getPosASL _projectile; +private _shooterPos = getPosASL _shooter; +private _projectilePos = getPosASL _projectile; -_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; -_distanceToShooter = _projectilePos vectorDistance _shooterPos; +private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; +private _distanceToShooter = _projectilePos vectorDistance _shooterPos; +private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; -TRACE_3("", _distanceToTarget, _distanceToShooter, _seekerTargetPos); +TRACE_2("", _distanceToTarget, _distanceToShooter); // Add height depending on distance for compensate -_addHeight = [0,0,0]; +private _addHeight = [0,0,0]; // Always climb an arc on initial launch if we are close to the round -if( ((ASLtoATL _projectilePos) select 2) < 5 && _distanceToShooter < 15) then { - _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; +if ((((ASLtoAGL _projectilePos) select 2) < 5) && {_distanceToShooter < 15}) then { + _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; + TRACE_1("climb - near shooter",_addHeight); } else { // If we are below the target, increase the climbing arc - if((_projectilePos select 2) < (_seekerTargetPos select 2) && _distanceToTarget > 100) then { + if (((_projectilePos select 2) < (_seekerTargetPos select 2)) && {_distanceToTarget > 100}) then { _addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))]; + TRACE_1("climb - below target and far",_addHeight); }; }; -// Handle arcing terminal low for high decent -if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget < 100) then { - _addHeight = _addHeight vectorDiff [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2)) * 0.5]; -} else { - if((_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget > 100) then { - _addHeight = _addHeight vectorAdd [0,0, _distanceToTarget*0.02]; - }; +// Projectile above target +if ((_projectilePos select 2) > (_seekerTargetPos select 2)) then { + TRACE_1("above - far",_addHeight); + _addHeight = _addHeight vectorAdd [0,0, _distanceToTarget / 50]; }; -_returnTargetPos = _seekerTargetPos vectorAdd _addHeight; +private _returnTargetPos = _seekerTargetPos vectorAdd _addHeight; -#ifdef DEBUG_MODE_FULL -drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]]; -#endif - -TRACE_1("Adjusted target position", _returnTargetPos); -_returnTargetPos; \ No newline at end of file +TRACE_2("Adjusted target position",_returnTargetPos,_addHeight); +_returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf b/addons/missileguidance/functions/fnc_attackProfile_MID.sqf index 9909124e2f..f66088844c 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_MID.sqf @@ -1,4 +1,21 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: MID + * TODO: falls back to Linear + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_MID; + * + * Public: No + */ -_this call FUNC(attackProfile_LIN); \ No newline at end of file +_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf index f5fdee95a0..d560f05e2a 100644 --- a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf +++ b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf @@ -1,11 +1,25 @@ #include "script_component.hpp" -private ["_projectile", "_v", "_l", "_r"]; +/* + * Author: jaynus / nou + * Change a projectile's direction, maintaing speed + * + * Arguments: + * 0: Projectile + * 1: Direction (unit vector) + * + * Return Value: + * None + * + * Example: + * [missile, [0,1,0]] call ace_missileguidance_fnc_changeMissileDirection; + * + * Public: No + */ -_projectile = _this select 0; -_v = _this select 1; +params ["_projectile", "_v"]; -_l = sqrt ((_v select 0) ^ 2 + (_v select 1) ^ 2); -_r = -(_v select 2) / _l; +private _l = sqrt ((_v select 0) ^ 2 + (_v select 1) ^ 2); +private _r = -(_v select 2) / _l; _projectile setVectorDirAndUp [ _v, [(_v select 0) * _r,(_v select 1) * _r, _l] ]; -_projectile setVelocity (_v vectorMultiply (vectorMagnitude (velocity _projectile))); \ No newline at end of file +_projectile setVelocity (_v vectorMultiply (vectorMagnitude (velocity _projectile))); diff --git a/addons/missileguidance/functions/fnc_checkLos.sqf b/addons/missileguidance/functions/fnc_checkLos.sqf index d41554dc65..205ff3d4ef 100644 --- a/addons/missileguidance/functions/fnc_checkLos.sqf +++ b/addons/missileguidance/functions/fnc_checkLos.sqf @@ -1,19 +1,27 @@ +#include "script_component.hpp" /* * Author: jaynus * Returns whether the seeker object can see the target position with lineIntersect * * Arguments: - * 0: Seeker [Object] - * 1: Target [Object] + * 0: Seeker + * 1: Target * * Return Value: - * Boolean + * Has LOS + * + * Example: + * [player, cursorTarget] call ace_missileguidance_fnc_checkLOS; + * + * Public: No */ -#include "script_component.hpp" params ["_seeker", "_target"]; -if ((isNil "_seeker") || {isNil "_target"}) exitWith {false}; +if ((isNil "_seeker") || {isNil "_target"}) exitWith { + ERROR_2("nil",_seeker,_target); + false +}; private _targetPos = getPosASL _target; private _targetAimPos = aimPos _target; @@ -21,11 +29,11 @@ private _seekerPos = getPosASL _seeker; private _return = true; if (!((terrainIntersectASL [_seekerPos, _targetPos]) && {terrainIntersectASL [_seekerPos, _targetAimPos]})) then { - if(lineIntersects [_seekerPos, _targetPos, _seeker, _target]) then { + if (lineIntersects [_seekerPos, _targetPos, _seeker, _target]) then { _return = false; }; } else { _return = false; }; -_return; \ No newline at end of file +_return; diff --git a/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf b/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf index 9415f347b6..d8b3b858b3 100644 --- a/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf +++ b/addons/missileguidance/functions/fnc_checkSeekerAngle.sqf @@ -1,31 +1,34 @@ +#include "script_component.hpp" /* * Author: jaynus - * Returns whether the target position is within the maximum angle FOV of the provided seeker + * Returns whether the target position is within the maximum angle FOV of the provided seeker * objects current direction. * * Arguments: - * 0: Seeker [Object] - * 1: Target [Position] - * 2: Max Angle [Degrees] - * + * 0: Seeker + * 1: Target PosASL + * 2: Max Angle (degrees) + * * Return Value: - * Boolean + * Can See + * + * Example: + * [player, cursorTarget, 45] call ace_missileguidance_fnc_checkSeekerAngle; + * + * Public: No */ -#include "script_component.hpp" -private ["_seeker", "_targetPos", "_seekerMaxAngle", "_sensorPos", "_testPointVector", "_testDotProduct"]; +params ["_seeker", "_targetPos", "_seekerMaxAngle"]; -_seeker = _this select 0; -_targetPos = _this select 1; -_seekerMaxAngle = _this select 2; +private _sensorPos = getPosASL _seeker; -_sensorPos = getPosASL _seeker; +private _testPointVector = vectorNormalized (_targetPos vectorDiff _sensorPos); +private _testDotProduct = (vectorNormalized (velocity _seeker)) vectorDotProduct _testPointVector; -_testPointVector = vectorNormalized (_targetPos vectorDiff _sensorPos); -_testDotProduct = (vectorNormalized (velocity _seeker)) vectorDotProduct _testPointVector; +TRACE_2("fov",acos _testDotProduct,_seekerMaxAngle); -if(_testDotProduct < (cos _seekerMaxAngle)) exitWith { - false +if (_testDotProduct < (cos _seekerMaxAngle)) exitWith { + false }; -true \ No newline at end of file +true diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf new file mode 100644 index 0000000000..45e2c4f900 --- /dev/null +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -0,0 +1,75 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Cycles fire mode for any missileGuidance enabled ammo that has multiple attack profiles + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_cycleAttackProfileKeyDown + * + * Public: No + */ + +TRACE_1("cycle fire mode",_this); + +if (!alive ACE_player) exitWith {}; +if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; + + +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 = 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"); + +TRACE_3("",_currentShooter,_currentMagazine,_ammo); + +// Bail if guidance is disabled for this ammo +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {TRACE_1("not enabled",_ammo)}; + +// Verify ammo has explicity added guidance config (ignore inheritances) +private _configs = configProperties [(configFile >> "CfgAmmo" >> _ammo), QUOTE(configName _x == QUOTE(QUOTE(ADDON))), false]; +if ((count _configs) < 1) exitWith {TRACE_2("not explicity enabled",_ammo,_configs)}; + +private _attackProfiles = getArray (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "attackProfiles"); +if ((count _attackProfiles) <= 1) exitWith {TRACE_1("no choices for attack profile",_attackProfiles)}; + +private _currentFireMode = _currentShooter getVariable [QGVAR(attackProfile), "#undefined"]; + +// Just like onFired, this is case sensitive! +private _index = _attackProfiles find _currentFireMode; +if (_index == -1) then { + _index = _attackProfiles find (getText (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "defaultAttackProfile")); +}; +_index = (_index + 1) % (count _attackProfiles); +private _nextFireMode = _attackProfiles select _index; +TRACE_4("",_currentFireMode,_nextFireMode,_index,_attackProfiles); + +_currentShooter setVariable [QGVAR(attackProfile), _nextFireMode, false]; + +playSound "ACE_Sound_Click"; + +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "showHintOnCycle")) == 1) then { + private _localizedName = getText (configFile >> QGVAR(AttackProfiles) >> _nextFireMode >> "name"); + [_localizedName] call EFUNC(common,displayTextStructured); +}; diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index 1c589838f5..53d43883d3 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -1,29 +1,39 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou, PabstMirror + * Do attack profile with a valid seeker target location + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_doAttackProfile; + * + * Public: No + */ -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private ["_testName", "_attackProfilePos", "_attackProfile", "_attackProfileName", "_attackProfilesCfg", "_i", "_launchParams", "_testame", "_testProfile"]; -_launchParams = ((_this select 1) select 1); -_attackProfileName = _launchParams select 3; +params ["_seekerTargetPos", "_args"]; +_args params ["", "_launchParams"]; +_launchParams params ["", "", "", "_attackProfileName"]; -TRACE_1("Attacking profile", _attackProfileName); +private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfileName >> "functionName"); -_attackProfilesCfg = ( configFile >> QGVAR(AttackProfiles) ); +private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); -_attackProfile = nil; -for [{_i=0}, {_i< (count _attackProfilesCfg) }, {_i=_i+1}] do { - _testProfile = _attackProfilesCfg select _i; - _testName = configName _testProfile; - TRACE_3("", _testName, _testProfile, _attackProfilesCfg); - - if( _testName == _attackProfileName) exitWith { - _attackProfile = _attackProfilesCfg select _i; - }; +if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { + ERROR_1("attack profile returned bad pos",_attackProfilePos); + [0,0,0] }; -_attackProfilePos = [0,0,0]; -if(!isNil "_attackProfile") then { - _attackProfilePos = _this call (missionNamespace getVariable (getText (_attackProfile >> "functionName"))); -}; +#ifdef DRAW_GUIDANCE_INFO +drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _attackProfilePos, 0.5, 0.5, 0, _attackProfileName, 1, 0.025, "TahomaB"]; +#endif +TRACE_2("return",_attackProfilePos,_attackProfileName); _attackProfilePos; diff --git a/addons/missileguidance/functions/fnc_doHandoff.sqf b/addons/missileguidance/functions/fnc_doHandoff.sqf index 011c3d52d1..569a827173 100644 --- a/addons/missileguidance/functions/fnc_doHandoff.sqf +++ b/addons/missileguidance/functions/fnc_doHandoff.sqf @@ -1,4 +1,20 @@ #include "script_component.hpp" -PARAMS_2(_target,_args); +/* + * Author: ACE + * Not currently used + * + * Arguments: + * 0: Target + * 1: Args + * + * Return Value: + * None + * + * Example: + * [target, [args]] call ace_missileguidance_fnc_doHandoff + * + * Public: No + */ +params ["_target", "_args"]; -[QGVAR(handoff), [_target, _args]] call CBA_fnc_globalEvent; \ No newline at end of file +[QGVAR(handoff), [_target, _args]] call CBA_fnc_globalEvent; diff --git a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf index 4eaefb6656..feb13481a5 100644 --- a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf +++ b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf @@ -1,30 +1,52 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou, PabstMirror + * Do seeker search + * Handles a nil/bad return and will attempt to use last known position if enabled on ammo + * + * Arguments: + * 1: Guidance Arg Array + * 3: Last known pos state array + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[], [], []] call ace_missileguidance_fnc_seekerType_Optic; + * + * Public: No + */ -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private ["_seekerProfilePos", "_i", "_launchParams", "_seekerType", "_seekerTypeName", "_seekerTypesCfg", "_testName", "_testProfile"]; +params ["", "_args", "", "_lastKnownPosState"]; +_args params ["", "_launchParams"]; +_launchParams params ["", "", "_seekerTypeName"]; +_lastKnownPosState params ["_seekLastTargetPos", "_lastKnownPos"]; -_launchParams = ((_this select 1) select 1); -_seekerTypeName = _launchParams select 2; +private _seekerFunction = getText (configFile >> QGVAR(SeekerTypes) >> _seekerTypeName >> "functionName"); -TRACE_1("Seeker type", _seekerTypeName); +private _seekerTargetPos = _this call (missionNamespace getVariable _seekerFunction); -_seekerTypesCfg = ( configFile >> QGVAR(SeekerTypes) ); - -_seekerType = nil; -for [{_i = 0}, {_i< (count _seekerTypesCfg) }, {_i=_i + 1}] do { - _testProfile = _seekerTypesCfg select _i; - _testName = configName _testProfile; - TRACE_3("", _testName, _testProfile, _seekerTypesCfg); - - if( _testName == _seekerTypeName) exitWith { - _seekerType = _seekerTypesCfg select _i; +if ((isNil "_seekerTargetPos") || {_seekerTargetPos isEqualTo [0,0,0]}) then { // A return of nil or [0,0,0] indicates the seeker has no target + if (_seekLastTargetPos && {!(_lastKnownPos isEqualTo [0,0,0])}) then { // if enabled for the ammo, use last known position if we have one stored + TRACE_2("seeker returned bad pos - using last known",_seekLastTargetPos,_lastKnownPos); + _seekerTargetPos = _lastKnownPos; + #ifdef DRAW_GUIDANCE_INFO + drawIcon3D ["\A3\ui_f\data\map\markers\military\unknown_CA.paa", [1,1,0,1], ASLtoAGL _lastKnownPos, 0.25, 0.25, 0, "LastKnownPos", 1, 0.02, "TahomaB"]; + #endif + } else { + TRACE_1("seeker returned no pos",_seekerTargetPos); + _seekerTargetPos = [0,0,0]; + }; +} else { + if (_seekLastTargetPos) then { // if enabled for the ammo, store last known position + TRACE_1("saving current pos",_seekLastTargetPos); + _lastKnownPosState set [1, _seekerTargetPos]; }; }; -_seekerProfilePos = [0, 0, 0]; -if(!isNil "_seekerType") then { - _seekerProfilePos = _this call (missionNamespace getVariable (getText (_seekerType >> "functionName"))); -}; +#ifdef DRAW_GUIDANCE_INFO +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLtoAGL _seekerTargetPos, 0.5, 0.5, 0, _seekerTypeName, 1, 0.025, "TahomaB"]; +#endif -_seekerProfilePos; +TRACE_2("return",_seekerTargetPos,_seekerTypeName); +_seekerTargetPos; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index a007d333f1..8196de8057 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -1,33 +1,40 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Guidance Per Frame Handler + * + * Arguments: + * 0: Guidance Arg Array + * 1: PFID + * + * Return Value: + * None + * + * Example: + * [[], 0] call ace_missileguidance_fnc_guidancePFH; + * + * Public: No + */ + +BEGIN_COUNTER(guidancePFH); #define TIMESTEP_FACTOR 0.01 -private ["_launchParams", "_targetLaunchParams", "_flightParams", "_seekerParams", "_stateParams"]; -private ["_lastRunTime", "_runtimeDelta", "_adjustTime", "_args", "_seekerTargetPos", "_projectilePos"]; -private ["_profileAdjustedTargetPos", "_incDeflection", "_minDeflection", "_maxDeflection"]; -private ["_targetVector", "_adjustVector", "_finalAdjustVector", "_changeVector", "_pitch", "_yaw", "_roll"]; -private ["_PS", "_distanceToTarget", "_targetRelativeVector", "_vectorTo"]; +params ["_args", "_pfID"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["","_targetLaunchParams"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; -_args = _this select 0; -EXPLODE_7_PVT((_args select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); - -if(!alive _projectile || isNull _projectile || isNull _shooter) exitWith { - [(_this select 1)] call CBA_fnc_removePerFrameHandler; +if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { + [_pfID] call CBA_fnc_removePerFrameHandler; + END_COUNTER(guidancePFH); }; -_launchParams = _args select 1; -_targetLaunchParams = _launchParams select 1; -_flightParams = _args select 2; -_seekerParams = _args select 3; +private _runtimeDelta = diag_tickTime - _lastRunTime; +private _adjustTime = 1; -_stateParams = _args select 4; - -_lastRunTime = _stateParams select 0; -_runtimeDelta = diag_tickTime - _lastRunTime; -_adjustTime = 1; - -if(accTime > 0) then { +if (accTime > 0) then { _adjustTime = 1/accTime; _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) ); @@ -35,72 +42,72 @@ if(accTime > 0) then { _adjustTime = 0; }; -_minDeflection = ((_flightParams select 0) - ((_flightParams select 0) * _adjustTime)) max 0; -_maxDeflection = (_flightParams select 1) * _adjustTime; -_incDeflection = _flightParams select 2; +private _minDeflection = ((_flightParams select 0) - ((_flightParams select 0) * _adjustTime)) max 0; +private _maxDeflection = (_flightParams select 1) * _adjustTime; +// private _incDeflection = _flightParams select 2; // todo -_projectilePos = getPosASL _projectile; +private _projectilePos = getPosASL _projectile; -// @TODO: placeholder for "last seek target position" -// Last target pos should be optional based on the seeker unit -_seekerTargetPos = [ [0,0,0], _args, (_stateParams select 1)] call FUNC(doSeekerSearch); -if(isNil "_seekerTargetPos") then { - _seekerTargetPos = _seekerTargetPos vectorAdd ((velocity _projectile) vectorMultiply 5); -} else { - if( (vectorMagnitude _seekerTargetPos) == 0) then { - _seekerTargetPos = _seekerTargetPos vectorAdd ((velocity _projectile) vectorMultiply 5); +// Run seeker function: +private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosState] call FUNC(doSeekerSearch); + +// Run attack profile function: +private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams] call FUNC(doAttackProfile); + +// If we have no seeker target, then do not change anything +if (!(_profileAdjustedTargetPos isEqualTo [0,0,0])) then { + + private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; + private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); + _adjustVector params ["_adjustVectorX", "_adjustVectorY", "_adjustVectorZ"]; + + private _yaw = 0; + private _pitch = 0; + private _roll = 0; + + if (_adjustVectorX < 0) then { + _yaw = - ( (_minDeflection max ((abs _adjustVectorX) min _maxDeflection) ) ); + } else { + if (_adjustVectorX > 0) then { + _yaw = ( (_minDeflection max (_adjustVectorX min _maxDeflection) ) ); + }; + }; + if (_adjustVectorY < 0) then { + _roll = - ( (_minDeflection max ((abs _adjustVectorY) min _maxDeflection) ) ); + } else { + if (_adjustVectorY > 0) then { + _roll = ( (_minDeflection max (_adjustVectorY min _maxDeflection) ) ); + }; + }; + if (_adjustVectorZ < 0) then { + _pitch = - ( (_minDeflection max ((abs _adjustVectorZ) min _maxDeflection) ) ); + } else { + if (_adjustVectorZ > 0) then { + _pitch = ( (_minDeflection max (_adjustVectorZ min _maxDeflection) ) ); + }; + }; + private _finalAdjustVector = [_yaw, _roll, _pitch]; + + TRACE_3("", _pitch, _yaw, _roll); + TRACE_3("", _targetVector, _adjustVector, _finalAdjustVector); + + if (accTime > 0) then { + private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; + TRACE_2("",_projectile,_changeVector); + [_projectile, _changeVector] call FUNC(changeMissileDirection); }; }; -_profileAdjustedTargetPos = [_seekerTargetPos,_args, (_stateParams select 2)] call FUNC(doAttackProfile); -_targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; -_adjustVector = _targetVector vectorDiff (vectorDir _projectile); +#ifdef DRAW_GUIDANCE_INFO +TRACE_3("",_projectilePos,_seekerTargetPos,_profileAdjustedTargetPos); +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; -_yaw = 0; -_pitch = 0; -_roll = 0; -if((_adjustVector select 0) < 0) then { - _yaw = - ( (_minDeflection max (abs(_adjustVector select 0) min _maxDeflection) ) ); -} else { - if((_adjustVector select 0) > 0) then { - _yaw = ( (_minDeflection max ((_adjustVector select 0) min _maxDeflection) ) ); - }; -}; -if((_adjustVector select 1) < 0) then { - _roll = - ( (_minDeflection max (abs(_adjustVector select 1) min _maxDeflection) ) ); -} else { - if((_adjustVector select 1) > 0) then { - _roll = ( (_minDeflection max ((_adjustVector select 1) min _maxDeflection) ) ); - }; -}; -if((_adjustVector select 2) < 0) then { - _pitch = - ( (_minDeflection max (abs(_adjustVector select 2) min _maxDeflection) ) ); -} else { - if((_adjustVector select 2) > 0) then { - _pitch = ( (_minDeflection max ((_adjustVector select 2) min _maxDeflection) ) ); - }; -}; -_finalAdjustVector = [_yaw, _roll, _pitch]; -TRACE_2("", _pitch, _yaw); -TRACE_4("", _targetVector, _targetRelativeVector, _adjustVector, _finalAdjustVector); - -if(accTime > 0) then { - _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; - [_projectile, _changeVector] call FUNC(changeMissileDirection); -}; - -#ifdef DEBUG_MODE_FULL -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _projectilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"]; -drawLine3D [ASLtoATL _projectilePos, ASLtoATL _profileAdjustedTargetPos, [1,0,0,1]]; - -_ps = "#particlesource" createVehicleLocal (ASLtoATL _projectilePos); +private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); _PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; _PS setDropInterval 3.0; - -hintSilent format["d: %1", _distanceToTarget]; #endif -_stateParams set[0, diag_tickTime]; +_stateParams set [0, diag_tickTime]; + +END_COUNTER(guidancePFH); -_args set[4, _stateParams]; -_this set[0, _args]; \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_handleHandoff.sqf b/addons/missileguidance/functions/fnc_handleHandoff.sqf index af23ed84d8..b4bb0052ae 100644 --- a/addons/missileguidance/functions/fnc_handleHandoff.sqf +++ b/addons/missileguidance/functions/fnc_handleHandoff.sqf @@ -1,6 +1,22 @@ #include "script_component.hpp" -PARAMS_2(_target,_args); +/* + * Author: ACE-Team + * Not currently used + * + * Arguments: + * 0: TARGET + * 1: ARGS + * + * Return Value: + * Boolean + * + * Example: + * [bob, kevin] call ACE_missileguidance_fnc_handleHandoff + * + * Public: No + */ +params ["_target", "_args"]; -if(isNil "_target" || {isNull _target} || {!local _target} ) exitWith { false }; +if (isNil "_target" || {isNull _target} || {!local _target} ) exitWith { false }; -[FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; \ No newline at end of file +[FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 2269810b94..eb4d2051cf 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -1,44 +1,57 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Fired event handler, starts guidance if enabled for ammo + * + * Arguments: + * 0: Shooter (Man/Vehicle) + * 4: Ammo + * 6: Projectile + * + * Return Value: + * None + * + * Example: + * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFired; + * + * Public: No + */ -PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); - -// Bail if guidance is disabled -// Bail on locality of the projectile, it should be local to us -if(GVAR(enabled) < 1 || {!local _projectile} ) exitWith { false }; - -//Bail if shooter isn't player AND system not enabled for AI: -if( !isPlayer _shooter && { GVAR(enabled) < 2 } ) exitWith { false }; +params ["_shooter","","","","_ammo","","_projectile"]; // Bail on not missile -if(! (_ammo isKindOf "MissileBase") ) exitWith { false }; +if (!(_ammo isKindOf "MissileBase")) exitWith {}; -private ["_config", "_configs", "_enabled", "_target", "_seekerType", "_attackProfile"]; -private ["_args", "_canUseLock", "_guidingUnit", "_launchPos", "_lockMode", "_targetPos", "_vanillaTarget"]; +// Bail if guidance is disabled for this ammo +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; -//Verify ammo has explicity added guidance config (ignore inheritances) -_configs = configProperties [(configFile >> "CfgAmmo" >> _ammo), QUOTE(configName _x == QUOTE(QUOTE(ADDON))), false]; -if( (count _configs) < 1) exitWith {}; +// Bail on locality of the projectile, it should be local to us +if (GVAR(enabled) < 1 || {!local _projectile} ) exitWith {}; -_config = (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON)); -_enabled = getNumber ( _config >> "enabled"); +// Bail if shooter isn't player AND system not enabled for AI: +if ( !isPlayer _shooter && { GVAR(enabled) < 2 } ) exitWith {}; -// Bail if guidance is not enabled -if(isNil "_enabled" || {_enabled != 1}) exitWith { false }; +// Verify ammo has explicity added guidance config (ignore inheritances) +private _configs = configProperties [(configFile >> "CfgAmmo" >> _ammo), QUOTE(configName _x == QUOTE(QUOTE(ADDON))), false]; +if ((count _configs) < 1) exitWith {}; -_target = (vehicle _shooter) getVariable [QGVAR(target), nil]; -_targetPos = (vehicle _shooter) getVariable [QGVAR(targetPosition), nil]; -_seekerType = (vehicle _shooter) getVariable [QGVAR(seekerType), nil]; -_attackProfile = (vehicle _shooter) getVariable [QGVAR(attackProfile), nil]; -_lockMode = (vehicle _shooter) getVariable [QGVAR(lockMode), nil]; +// MissileGuidance is enabled for this shot +TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); -// @TODO: make this vehicle shooter, but we need to differentiate where its set in ace_laser -_laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; -_laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; +private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); -_launchPos = getPosASL (vehicle _shooter); +private _target = _shooter getVariable [QGVAR(target), nil]; +private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; +private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; +private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; +private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; -TRACE_3("Begin guidance", _target, _seekerType, _attackProfile); +private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; +private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; + +TRACE_6("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode); + +private _launchPos = getPosASL (vehicle _shooter); if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { _seekerType = getText (_config >> "defaultSeekerType"); @@ -51,28 +64,37 @@ if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes" }; // If we didn't get a target, try to fall back on tab locking -if(isNil "_target") then { - if(!isPlayer _shooter) then { +if (isNil "_target") then { + if (!isPlayer _shooter) then { // This was an AI shot, lets still guide it on the AI target - _target = _shooter getVariable[QGVAR(vanilla_target), nil]; + _target = _shooter getVariable [QGVAR(vanilla_target), nil]; TRACE_1("Detected AI Shooter!", _target); } else { - _canUseLock = getNumber (_config >> "canVanillaLock"); + private _canUseLock = getNumber (_config >> "canVanillaLock"); // @TODO: Get vanilla target - if(_canUseLock > 0 || difficulty < 1) then { - _vanillaTarget = cursorTarget; + if (_canUseLock > 0 || difficulty < 1) then { + private _vanillaTarget = cursorTarget; TRACE_1("Using Vanilla Locking", _vanillaTarget); - if(!isNil "_vanillaTarget") then { + if (!isNil "_vanillaTarget") then { _target = _vanillaTarget; }; }; }; }; +// Array for seek last target position +private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; +private _lastKnownPosState = [_seekLastTargetPos]; +if (_seekLastTargetPos && {!isNil "_target"}) then { + _lastKnownPosState set [1, (getPosASL _target)]; +} else { + _lastKnownPosState set [1, [0,0,0]]; +}; + TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile); -_args = [_this, - [_shooter, +private _args = [_this, + [ _shooter, [_target, _targetPos, _launchPos], _seekerType, _attackProfile, @@ -89,30 +111,50 @@ _args = [_this, getNumber ( _config >> "seekerAccuracy" ), getNumber ( _config >> "seekerMaxRange" ) ], - [ diag_tickTime, [], [] ] + [ diag_tickTime, [], [], _lastKnownPosState] ]; + +// Run the "onFired" function passing the full guidance args array +private _onFiredFunc = getText (_config >> "onFired"); +TRACE_1("",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + + +// Reverse: +// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; +// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; +// _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange"]; + + // Hand off to the guiding unit. We just use local player so local PFH fires for now // Laser code needs to give us a shooter for LOBL, or the seeker unit needs to be able to shift locality // Based on its homing laser // Lasers need to be handled in a special LOAL/LOBL case -//if(isPlayer _shooter) then { -// _guidingUnit = ACE_player; +//if (isPlayer _shooter) then { +// private _guidingUnit = ACE_player; // -// if(local _guidingUnit) then { +// if (local _guidingUnit) then { // [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; // } else { // [QGVAR(handoff), [_guidingUnit, _args] ] call FUNC(doHandoff); // }; //} else { - [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; + // [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; //}; +[FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; + /* Clears locking settings (vehicle _shooter) setVariable [QGVAR(target), nil]; (vehicle _shooter) setVariable [QGVAR(seekerType), nil]; (vehicle _shooter) setVariable [QGVAR(attackProfile), nil]; (vehicle _shooter) setVariable [QGVAR(lockMode), nil]; -*/ + */ diff --git a/addons/missileguidance/functions/fnc_onIncomingMissile.sqf b/addons/missileguidance/functions/fnc_onIncomingMissile.sqf index 14902c32a5..04ad0c79b7 100644 --- a/addons/missileguidance/functions/fnc_onIncomingMissile.sqf +++ b/addons/missileguidance/functions/fnc_onIncomingMissile.sqf @@ -1,8 +1,26 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" -PARAMS_3(_target,_ammo,_shooter); +/* + * Author: jaynus / nou + * Handles AI shooting a locking missile + * + * Arguments: + * 0: Target + * 1: Ammo + * 2: Shooter + * + * Return Value: + * None + * + * Example: + * [cursorTarget, "x", player] call ace_missileguidance_fnc_changeMissileDirection; + * + * Public: No + */ -if(GVAR(enabled) < 1) exitWith {}; // bail if enabled +params ["_target", "_ammo", "_shooter"]; + +if (GVAR(enabled) < 1) exitWith {}; // bail if enabled if !(local (gunner _shooter) || {local _shooter}) exitWith {}; // bail if not shooter -_shooter setVariable [QGVAR(vanilla_target),_target, false]; \ No newline at end of file +_shooter setVariable [QGVAR(vanilla_target),_target, false]; +TRACE_2("setting vanilla target",_shooter,_target); diff --git a/addons/missileguidance/functions/fnc_rotateVectLine.sqf b/addons/missileguidance/functions/fnc_rotateVectLine.sqf deleted file mode 100644 index 9adb283cae..0000000000 --- a/addons/missileguidance/functions/fnc_rotateVectLine.sqf +++ /dev/null @@ -1,39 +0,0 @@ -#include "script_component.hpp" -private ["_d", "_map", "_p", "_theta", "_u"]; - -_map = _this select 0; -_theta = _this select 1; - -_p = _map select 0; -_p1 = _map select 1; -_p2 = _map select 2; - -_q1 = +(_map select 3); -_q2 = +(_map select 4); -_u = _map select 5; -_d = _map select 6; - -/* Step 4 */ -_q2 set[0, (_q1 select 0) * cos(_theta) - (_q1 select 1) * sin(_theta)]; -_q2 set[1, (_q1 select 0) * sin(_theta) + (_q1 select 1) * cos(_theta)]; -_q2 set[2, (_q1 select 2)]; - -/* Inverse of step 3 */ -_q1 set[0, (_q2 select 0) * _d + (_q2 select 2) * (_u select 0)]; -_q1 set[1, (_q2 select 1)]; -_q1 set[2, - (_q2 select 0) * (_u select 0) + (_q2 select 2) * _d]; - -/* Inverse of step 2 */ -if (_d != 0) then { - _q2 set[0, (_q1 select 0)]; - _q2 set[1, (_q1 select 1) * (_u select 2) / _d + (_q1 select 2) * (_u select 1) / _d]; - _q2 set[2, - (_q1 select 1) * (_u select 1) / _d + (_q1 select 2) * (_u select 2) / _d]; -} else { - _q2 = _q1; -}; - -/* Inverse of step 1 */ -_q1 set[0, (_q2 select 0) + (_p1 select 0)]; -_q1 set[1, (_q2 select 1) + (_p1 select 1)]; -_q1 set[2, (_q2 select 2) + (_p1 select 2)]; -_q1; \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_rotateVectLineGetMap.sqf b/addons/missileguidance/functions/fnc_rotateVectLineGetMap.sqf deleted file mode 100644 index 258cc93ae2..0000000000 --- a/addons/missileguidance/functions/fnc_rotateVectLineGetMap.sqf +++ /dev/null @@ -1,37 +0,0 @@ -#include "script_component.hpp" - -private ["_p", "_theta", "_p1", "_p2", "_q1", "_q2", "_u", "_d"]; -_p = _this select 0; -_p1 = _this select 1; -_p2 = _this select 2; - -_q1 = []; -_q2 = []; -_u = []; - -/* Step 1 */ -_q1 set[0, (_p select 0) - (_p1 select 0)]; -_q1 set[1, (_p select 1) - (_p1 select 1)]; -_q1 set[2, (_p select 2) - (_p1 select 2)]; - -_u set[0, (_p2 select 0) - (_p1 select 0)]; -_u set[1, (_p2 select 1) - (_p1 select 1)]; -_u set[2, (_p2 select 2) - (_p1 select 2)]; -_u = _u call BIS_fnc_unitVector; -_d = sqrt((_u select 1)*(_u select 1) + (_u select 2)*(_u select 2)); - -/* Step 2 */ -if (_d != 0) then { - _q2 set[0, (_q1 select 0)]; - _q2 set[1, (_q1 select 1) * (_u select 2) / _d - (_q1 select 2) * (_u select 1) / _d]; - _q2 set[2, (_q1 select 1) * (_u select 1) / _d + (_q1 select 2) * (_u select 2) / _d]; -} else { - _q2 = _q1; -}; - -/* Step 3 */ -_q1 set[0, (_q2 select 0) * _d - (_q2 select 2) * (_u select 0)]; -_q1 set[1, (_q2 select 1)]; -_q1 set[2, (_q2 select 0) * (_u select 0) + (_q2 select 2) * _d]; - -[_p, _p1, _p2, _q1, _q2, _u, _d] \ No newline at end of file diff --git a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf index b491110ac6..356ad5c2f1 100644 --- a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf @@ -1,52 +1,53 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Seeker Type: Optic + * + * Arguments: + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[], [], []] call ace_missileguidance_fnc_seekerType_Optic; + * + * Public: No + */ -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private ["_targets", "_foundTargetPos", "_launchParams", "_seekerParams", "_targetLaunchParams"]; -private ["_angleFov", "_angleOkay", "_losOkay", "_seekerTargetPos", "_sensorPos", "_target"]; +params ["", "_args"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; +_firedEH params ["","","","","","","_projectile"]; +_launchParams params ["", "_targetParams"]; +_targetParams params ["_target"]; +_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; -_seekerTargetPos = _this select 0; +if (isNil "_target") exitWith {[0,0,0]}; -_launchParams = _this select 1; -_target = (((_launchParams select 1) select 1) select 0); -_seekerParams = _launchParams select 3; - -TRACE_1("", _this); -TRACE_1("", _launchParams); - -// TODO:: Make sure the missile maintains LOS -_foundTargetPos = [0,0,0]; -if(!isNil "_target") then { - _foundTargetPos = aimPos _target ; - //_foundTargetPos = (_target modelToWorldVisual (getCenterOfMass _target)); -}; +private _foundTargetPos = aimPos _target; // @TODO: This is seeker LOS and angle checks for LOAL only; LOBL does not need visual -_angleFov = _seekerParams select 0; -_angleOkay = [_projectile, _foundTargetPos, _angleFov] call FUNC(checkSeekerAngle); +private _angleOkay = [_projectile, _foundTargetPos, _seekerAngle] call FUNC(checkSeekerAngle); -_losOkay = false; -if(_angleOkay) then { +private _losOkay = false; +if (_angleOkay) then { _losOkay = [_projectile, _target] call FUNC(checkLos); }; TRACE_2("", _angleOkay, _losOkay); -// If we got here, it was an invalid target, just return a spot 5m in front of the missile -if(!_angleOkay || !_losOkay) then { - _foundTargetPos = _sensorPos vectorAdd ((velocity _projectile) vectorMultiply 5); -} else { - TRACE_2("", _target, _foundTargetPos); - private ["_projectileSpeed", "_distanceToTarget", "_eta", "_adjustDistance"]; - // @TODO: Configurable lead for seekers - _projectileSpeed = (vectorMagnitude velocity _projectile); - _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos; +// Can't see target, return [0,0,0] and let doSeekerSearch handle it +if (!_angleOkay || !_losOkay) exitWith {[0,0,0]}; - _eta = _distanceToTarget / _projectileSpeed; +TRACE_2("", _target, _foundTargetPos); +// @TODO: Configurable lead for seekers +private _projectileSpeed = (vectorMagnitude velocity _projectile); +private _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos; +private _eta = _distanceToTarget / _projectileSpeed; - _adjustDistance = (velocity _target) vectorMultiply _eta; - TRACE_3("leading target",_distanceToTarget,_eta,_adjustDistance); - _foundTargetPos = _foundTargetPos vectorAdd _adjustDistance; -}; +private _adjustDistance = (velocity _target) vectorMultiply _eta; +TRACE_3("leading target",_distanceToTarget,_eta,_adjustDistance); +_foundTargetPos = _foundTargetPos vectorAdd _adjustDistance; TRACE_2("return",_foundTargetPos,(aimPos _target) distance _foundTargetPos); _foundTargetPos; diff --git a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf index 034fc03e45..09e20e7887 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf @@ -1,32 +1,32 @@ -//#define DEBUG_MODE_FULL #include "script_component.hpp" +/* + * Author: jaynus / nou + * Seeker Type: SALH (Laser) + * Wrapper for ace_laser_fnc_seekerFindLaserSpot + * + * Arguments: + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[], [], []] call ace_missileguidance_fnc_seekerType_SALH; + * + * Public: No + */ -EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); -private ["_angleFov", "_canSeeTarget", "_foundTargetPos", "_laserResult", "_launchParams", "_seekerParams", "_laserCode", "_laserParams", "_seekerTargetPos", "_sensorPos", "_target"]; -_seekerTargetPos = _this select 0; -_launchParams = _this select 1; -_seekerParams = _launchParams select 3; -_angleFov = _seekerParams select 0; +params ["", "_args"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams"]; +_firedEH params ["","","","","","","_projectile"]; +_launchParams params ["","","","","","_laserParams"]; +_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; +_laserParams params ["_code", "_wavelengthMin", "_wavelengthMax"]; -_laserParams = (_launchParams select 1) select 5; -TRACE_2("", _launchParams, _laserParams); -if(!isNil "_target") then { - // Handle AI or moving vanilla lasers - _foundTargetPos = getPosASL _target; -} else { - _laserResult = [(getPosASL _projectile), (velocity _projectile), _angleFov, [(_laserParams select 1),(_laserParams select 2)], (_laserParams select 0)] call EFUNC(laser,seekerFindLaserSpot); - _foundTargetPos = _laserResult select 0; - TRACE_1("Search", _laserResult); -}; -if(!isNil "_foundTargetPos") then { - //_canSeeTarget = [_projectile, _foundTargetPos, _angleFov] call FUNC(checkSeekerAngle); +private _laserResult = [(getPosASL _projectile), (velocity _projectile), _seekerAngle, _seekerMaxRange, [_wavelengthMin, _wavelengthMax], _code, _projectile] call EFUNC(laser,seekerFindLaserSpot); +private _foundTargetPos = _laserResult select 0; +TRACE_1("Search", _laserResult); - // If we got here, it was an invalid target, just return a spot 5m in front of the missile - if(!_canSeeTarget) then { - _foundTargetPos = _sensorPos vectorAdd ((velocity _projectile) vectorMultiply 5); - }; - -}; - -_foundTargetPos; \ No newline at end of file +_foundTargetPos; diff --git a/addons/missileguidance/script_component.hpp b/addons/missileguidance/script_component.hpp index beac3e318d..298de3a051 100644 --- a/addons/missileguidance/script_component.hpp +++ b/addons/missileguidance/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Missile Guidance #include "\z\ace\addons\main\script_mod.hpp" +// #define DRAW_GUIDANCE_INFO // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MISSILEGUIDANCE @@ -16,5 +16,3 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" - -#define FIREMODE_DIRECT_LOAL 1 diff --git a/addons/missileguidance/stringtable.xml b/addons/missileguidance/stringtable.xml index 35b947ce97..1758dea3e3 100644 --- a/addons/missileguidance/stringtable.xml +++ b/addons/missileguidance/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Avançado Missile Guidance Fejlett rakétairányító Продвинутое наведение ракет + 高度なミサイルの誘導 + 고급 미사일 유도 + 进阶飞弹制导 + 進階飛彈制導 Advanced missile guidance, or AMG, provides multiple enhancements to missile locking and firing. It is also a framework required for missile weapon types. @@ -24,6 +28,10 @@ A fejlett rakétairányító (vagy AMG) többféle módosítást tartalmaz a rakéták célkövetéséhez és tüzeléséhez. Ez egy szükséges keresztrendszer a rakéta-alapú fegyverekhez. Orientação avançada de mísseis ou OAM, fornece vários aprimoramentos para travamento de mísseis e disparos. Também é um sistema requerido para disparar armas que utilizem mísseis. 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 @@ -36,6 +44,10 @@ Míssil Hydra-70 DAGR Hydra-70 DAGR rakéta Hydra-70 DAGR + ハイドラ-70 DAGR ミサイル + Hydra-70 DAGR 미사일 + 九头蛇-70 直接攻击导引飞弹 + 九頭蛇-70 直接攻擊導引飛彈 DAGR @@ -48,6 +60,10 @@ DAGR DAGR DAGR + DAGR + DAGR + 直接攻击制导火箭弹 + 直接攻擊導引飛彈 Hydra-70 DAGR Laser Guided Missile @@ -56,10 +72,14 @@ Laserowo naprowadzana rakieta Hydra-70 DAGR Hydra-70 DAGR lasergelenkte Rakete Hydra-70 DAGR laserem naváděná střela - Hydra-70 DAGR missile guida laser + Hydra-70 DAGR Missile a Guida Laser Míssil guiado a laser Hydra-70 DAGR Hydra-70 DAGR lézer-irányított rakéta Управляемая ракета лазерного наведения Hydra-70 DAGR + ハイドラ-70 DAGR レーザ誘導ミサイル + Hydra-70 DAGR 레이저 유도 미사일 + 九头蛇-70mm 制导航空火箭弹 + 九頭蛇-70 直接攻擊雷射導引飛彈 Hellfire II AGM-114K Missile @@ -72,6 +92,10 @@ Míssil Hellfire II AGM-114K Hellfire II AGM-114K rakéta Hellfire II AGM-114K + ヘルファイア II AGM-114K ミサイル + Hellfire II AGM-114K 미사일 + 地狱火II型AGM-114K空地制导破甲弹 + 地獄火II型 AGM-114K 導彈 AGM-114K @@ -84,6 +108,10 @@ AGM-114K AGM-114K AGM-114K + AGM-114K + AGM-114K + AGM-114K制导破甲弹 + AGM-114K Hellfire II AGM-114K Laser Guided Missile @@ -92,10 +120,14 @@ Laserowo naprowadzana rakieta Hellfire II AGM-114K Hellfire II AGM-114K Lasergelenkte Rakete Hellfire II AGM-114K laserem naváděná střela - Missile guida laser Hellfire II AGM-114K + Missile a Guida Laser Hellfire II AGM-114K Míssil guiado a laser Hellfire II AGM-114K Hellfire II AGM-114K lézer-irányított rakéta Управляемая ракета лазерного наведения Hellfire II AGM-114K + ヘルファイア II AGM-114K レーザ誘導ミサイル + Hellfire II AGM-114K 레이저 유도 미사일 + 地狱火II型AGM-114K空地制导破甲弹 + 地獄火II型 AGM-114K 雷射導引飛彈 Off @@ -108,6 +140,10 @@ Ki Выкл. Spento + 無効 + 끄기 + 关闭 + 關閉 Player Only @@ -120,6 +156,10 @@ Csak játékosok Только игрок Solo Giocatore + プレイヤーのみ + 오직 플레이어만 + 只有玩家 + 只有玩家 Player and AI @@ -132,6 +172,26 @@ Játékosok és AI Игрок и боты Giocatore ed IA + プレイヤーと AI + 玩家和AI + 玩家和AI + 플레이어와 AI + + + Cycle Fire Mode + Wechsle Feuermodus + Переключение режимов огня + Přepínání režimů palby + Przełącz tryb ognia + Cycle mode de tir + Tüzelési mód váltása + Alterna le modalità di fuoco + Cambiar modo de disparo + Alterar Modo de Disparo + 発射モード切り替え + 발사 방식 순환 + 循环切换开火模式 + 循環切換開火模式 - \ No newline at end of file + diff --git a/addons/missionmodules/XEH_preInit.sqf b/addons/missionmodules/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/missionmodules/XEH_preInit.sqf +++ b/addons/missionmodules/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf index eb44a68f15..ba20ac0b8d 100644 --- a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf +++ b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Plays synchronized ambiance sounds while the module is alive. @@ -8,112 +9,101 @@ * 2: Activated * * Return Value: - * Nothing + * None * * Example: - * N/A + * [LOGIC, [bob, kevin], true] call ace_missionmodules_fnc_moduleAmbianceSound * * Public: No */ -#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 EFUNC(common,stringRemoveWhiteSpace); +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 { - _ambianceSounds pushBack ((getArray(configFile >> "CfgSounds" >> _x >> "sound") select 0)); - } else { - ACE_LOGERROR_1("Ambient Sounds: Sound ""%1"" not found.",_x); - }; + _ambianceSounds pushBack (_missionRoot + _soundPath); }; - - false - } count _splittedList; - - if (count _ambianceSounds == 0) exitWith {}; - { - if ((_x find ".") == -1) then { - _ambianceSounds set [_forEachIndex, _x + ".wss"]; + } 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); }; - } forEach _ambianceSounds; + }; - [{ - private ["_newPos", "_allUnits", "_targetUnit"]; - params ["_args", "_pfhHandle"]; - _args params ["_logic", "_ambianceSounds", "_minimalDistance", "_maximalDistance", "_minDelayBetweensounds", "_maxDelayBetweenSounds", "_volume", "_followPlayers", "_lastTimePlayed"]; + false +} count _splittedList; - if (!alive _logic) exitWith { - [_pfhHandle] call CBA_fnc_removePerFrameHandler; - }; +if (count _ambianceSounds == 0) exitWith {}; +{ + if ((_x find ".") == -1) then { + _ambianceSounds set [_forEachIndex, _x + ".wss"]; + }; +} forEach _ambianceSounds; - if (CBA_missionTime - _lastTimePlayed >= ((_minDelayBetweensounds + random(_maxDelayBetweenSounds)) min _maxDelayBetweenSounds)) then { +TRACE_1("",_ambianceSounds); - // Find all players in session. - _allUnits = if (isMultiplayer) then {playableUnits} else {[ACE_player]}; +[{ + params ["_args", "_pfhHandle"]; + _args params ["_logic", "_ambianceSounds", "_minimalDistance", "_maximalDistance", "_minDelayBetweensounds", "_maxDelayBetweenSounds", "_volume", "_followPlayers", "_lastTimePlayed"]; - // Check if there are enough players to even start playing this sound. - if (count _allUnits > 0) then { + 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. - _targetUnit = _allUnits call BIS_fnc_selectRandom; + private _targetUnit = selectRandom _allUnits; + AGLtoASL (_targetUnit getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); + } else { + AGLtoASL (_logic getPos [_minimalDistance + random (_maximalDistance - _minimalDistance), random 360]); + }; - // find the position from which we are going to play this sound from. - _newPos = (getPos _targetUnit); - if (!_followPlayers) then { - _newPos = getPos _logic; - }; - - // Randomize this position. - if (random(1) >= 0.5) then { - if (random(1) >= 0.5) then { - _newPos set [0, (_newPos select 0) + (_minimalDistance + random(_maximalDistance))]; - } else { - _newPos set [0, (_newPos select 0) - (_minimalDistance + random(_maximalDistance))]; - }; - } else { - if (random(1) >= 0.5) then { - _newPos set [1, (_newPos select 1) + (_minimalDistance + random(_maximalDistance))]; - } else { - _newPos set [1, (_newPos select 1) - (_minimalDistance + random(_maximalDistance))]; - }; - }; - - // If no unit is to close to this position, we will play the sound. - if ({(_newPos distance _x < (_minimalDistance / 2))}count _allUnits == 0) then { - playSound3D [selectRandom _ambianceSounds, objNull, false, _newPos, _volume, 1, 1000]; - _args set [8, CBA_missionTime]; - }; + 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/script_component.hpp b/addons/missionmodules/script_component.hpp index d1fdd10580..0d447899f7 100644 --- a/addons/missionmodules/script_component.hpp +++ b/addons/missionmodules/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MISSIONMODULES diff --git a/addons/missionmodules/stringtable.xml b/addons/missionmodules/stringtable.xml index 1043d99f64..cb28cb3d7e 100644 --- a/addons/missionmodules/stringtable.xml +++ b/addons/missionmodules/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,18 +12,26 @@ ACE küldetési modulok Модули миссий ACE Moduli Missione ACE + ACE ミッション モジュール + ACE 미션 모듈 + ACE 任务模块 + ACE 任務模塊 - Ambiance Sounds [ACE] - Dźwięki [ACE] - [ACE] Sonidos ambiente - Umgebungsgeräusche [ACE] - Zvuky prostředí [ACE] - [ACE] Sons ambientes - Sons d'ambiance [ACE] - Ambiens hangok [ACE] - Звук окружения [ACE] - Souni Ambientali [ACE] + Ambiance Sounds + Dźwięki + Sonidos ambiente + Umgebungsgeräusche + Zvuky prostředí + Sons ambientes + Sons d'ambiance + Ambiens hangok + Звук окружения + Souni Ambientali + 環境音 + 환경 효과음 + 环境声音 + 環境聲音 Sounds @@ -36,6 +44,10 @@ Hangok Звуки Suoni + 効果音 + 효과음 + 声音 + 聲音 Class names of the ambiance sounds to be played. Seperated by ',' @@ -47,6 +59,10 @@ Имена классов звуков окружения, которые должны проигрываться. Разделенные ',' ClassNames des sons d'ambiances. Séparation par "," Nomi classi dei suoni ambientali da eseguire. Separati da ',' + 再生する環境音のクラスネームを記載。','で複数指定できます。 + 재생되는 환경 효과음의 단위와 이름입니다. ','로 구분됩니다. + 输入想使用的环境声音classname。每个classname用','做区隔 + 輸入想使用的環境聲音classname。每個classname用','做區隔 Minimal Distance @@ -59,6 +75,10 @@ Minimális távolság Минимальная дистанция Distanza Minimale + 最低距離 + 최소 거리 + 最小距离 + 最小距離 Used for calculating a random position and sets the minimal distance between the players and the played sound file(s) @@ -71,6 +91,10 @@ Egy véletlenszerű pozíció számításához használt érték, amihez megadja a minimum távolságot a játékosok és a lejátszott hangfájl(ok) között Используется для расчета случайной позиции и указывает минимальное расстояние между игроками и источниками звука Usati per calcolare una posizione casuale ed impostare la distanza minima tra i giocatori ed il file suono eseguito + 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最低距離を設定します + 무작위 위치 계산에 사용되며 플레이어와 재생 된 사운드 파일 간의 최소 거리를 설정합니다. + 声音将随机产生在玩家附近,此选项定义该声音最近会距离玩家多少公尺 + 聲音將隨機產生在玩家附近,此選項定義該聲音最近會距離玩家多少公尺 Maximum Distance @@ -83,6 +107,10 @@ Maximális távolság Максимальная дистанция Distanza Massima + 最大距離 + 최대 거리 + 最大距离 + 最大距離 Used for calculating a random position and sets the maximum distance between the players and the played sound file(s) @@ -95,6 +123,10 @@ Egy véletlenszerű pozíció számításához használt érték, amihez megadja a maximum távolságot a játékosok és a lejátszott hangfájl(ok) között Используется для расчета случайной позиции и указывает максимальное расстояние между игроками и источниками звука Usato per calcolare una posizione casuale ed impostare la distanza massima tra giocatori e il file suono eseguito + 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最大距離を設定します + 무작위 위치 계산에 사용되며 플레이어와 재생 된 사운드 파일 간의 최대 거리를 설정합니다. + 声音将随机产生在玩家附近,此选项定义该声音最远会距离玩家多少公尺 + 聲音將隨機產生在玩家附近,此選項定義該聲音最遠會距離玩家多少公尺 Minimal Delay @@ -107,6 +139,10 @@ Minimum késleltetés Минимальная задержка Pausa Minima + 最低遅延 + 최소 지연 + 最小延迟 + 最小延遲 Minimal delay between sounds played @@ -119,6 +155,10 @@ Minimum késleltetés a lejátszott hangok között Минимальная задержка между воспроизведением звуков Pausa Minima tra suoni eseguiti + 再生されるまでの最低遅延 + 재생된 소리간 최소 지연시간 + 设定每个声音档案中间最少间隔多久再进行播放 + 設定每個聲音檔案中間最少間隔多久再進行播放 Maximum Delay @@ -131,6 +171,10 @@ Maximum késleltetés Максимальная задержка Pausa Massima + 最大遅延 + 최대 지연 + 最大延迟 + 最大延遲 Maximum delay between sounds played @@ -143,6 +187,10 @@ Maximum késleltetés a lejátszott hangok között Максимальная задержка между воспроизведением звуков Pausa Massima tra suoni eseguiti + 再生されるまでの最大遅延 + 재생된 소리간 최대 지연시간 + 设定每个声音档案中间最多间隔多久再进行播放 + 設定每個聲音檔案中間最多間隔多久再進行播放 Follow Players @@ -155,6 +203,10 @@ Játékosok követése Следовать за игроками Segui Giocatori + プレイヤーを追随 + 플레이어 따라가기 + 跟随玩家 + 跟隨玩家 Follow players. If set to false, loop will play sounds only nearby logic position. @@ -167,6 +219,10 @@ Játékosok követése. Ha le van tiltva, az ismétlés csak a legközelebbi logikai ponton játszik le hangokat. Следовать за игроками. Если установить в Ложь, звуки будут циклически проигрываться только около позиции Логики. Segui Giocatori. Se impostato su falso, il ciclo eseguirà i suoni solo vicino ad una posizione logica. + プレイヤーを追随します。False に設定するとロジックの近くで延々と再生します。 + 플레이어를 따라갑니다. 거짓으로 설정될경우 오직 한 자리에서만 반복해서 소리를 재생합니다. + 设定声音是否会在玩家的附近产生。假如关闭此功能,声音只会在模块的位置产生。 + 設定聲音是否會在玩家的附近產生。假如關閉此功能,聲音只會在模塊的位置產生。 Volume @@ -179,6 +235,10 @@ Hangerő Громкость Volume + 音量 + 볼륨 + 音量 + 音量 The volume of the sounds played @@ -191,6 +251,10 @@ A lejátszott hangok hangereje Громкость воспроизводимых звуков Il volume dei suoni eseguiti + 再生される音の大きさ + 재생되는 소리의 볼륨 + 调整声音的音量 + 調整聲音的音量 Ambiance sounds loop (synced across MP) @@ -203,6 +267,10 @@ Ambiens hangok folyamatossága (MP alatt szinkronizálva) Циклически воспроизводимые звуки окружения (синх. между игроками) Ciclo Suoni Ambientali (sincronizzato in MP) + 環境音の繰り返し (MP 間で同期させます) + 환경 효과음 반복 (멀티플레이 전반적으로 동기화됨) + 循环的环境声音 (在多人游戏中会同步所有玩家的播放状态) + 循環的環境聲音 (在多人遊戲中會同步所有玩家的播放狀態) - \ No newline at end of file + 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..4a5d420f5c 100644 --- a/addons/mk6mortar/CfgVehicles.hpp +++ b/addons/mk6mortar/CfgVehicles.hpp @@ -7,7 +7,6 @@ class CfgVehicles { displayName = CSTRING(rangetable_action); condition = QUOTE(_this call FUNC(rangeTableCanUse)); statement = QUOTE(_this call FUNC(rangeTableOpen)); - priority = 0; icon = QPATHTOF(UI\icon_rangeTable.paa); exceptions[] = {"notOnMap", "isNotInside", "isNotSitting"}; }; @@ -99,8 +98,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/XEH_postInit.sqf b/addons/mk6mortar/XEH_postInit.sqf index aceb721d70..e3169b6dba 100644 --- a/addons/mk6mortar/XEH_postInit.sqf +++ b/addons/mk6mortar/XEH_postInit.sqf @@ -17,7 +17,25 @@ ["ace_initMortar", {_this call FUNC(mortarInit);}] call CBA_fnc_addEventHandler; -if (!hasInterface) exitWith {}; +if (hasInterface) then { + ["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; +}; -["vehicle", FUNC(handlePlayerVehicleChanged)] call CBA_fnc_addPlayerEventHandler; -["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; +["ace_settingsInitialized", { + TRACE_1("ace_settingsInitialized",GVAR(useAmmoHandling)); + + ["vehicle", FUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; + + if (GVAR(useAmmoHandling)) then { + ["Mortar_01_base_F", "init", { + TRACE_2("mortar init",_this,(_this select 0) turretLocal [0]); + + //wait for proper turret locality change + [{ + TRACE_2("after delay",_this,(_this select 0) turretLocal [0]); + ["ace_initMortar", _this] call CBA_fnc_localEvent; + }, _this, 0.5] call CBA_fnc_waitAndExecute; + + }, true, [], true] call CBA_fnc_addClassEventHandler; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/mk6mortar/XEH_preInit.sqf b/addons/mk6mortar/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/mk6mortar/XEH_preInit.sqf +++ b/addons/mk6mortar/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/mk6mortar/config.cpp b/addons/mk6mortar/config.cpp index a63f7086f9..f387632446 100644 --- a/addons/mk6mortar/config.cpp +++ b/addons/mk6mortar/config.cpp @@ -34,7 +34,3 @@ class RscStructuredText; #include "RscInGameUI.hpp" #include "RscRangeTable.hpp" - -class ACE_newEvents { - initMortar = "ace_initMortar"; -}; diff --git a/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf b/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf index c0858a328a..67bcf4d522 100644 --- a/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_canLoadMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Grey * Checks whether magazine can be loaded into static weapon @@ -15,22 +16,20 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_static","_unit",["_magazineClassOptional","",[""]]]; -private ["_canLoadMagazine","_currentMagazine","_weapon","_listOfMagNames", - "_hasCompatibleMagazine","_count"]; if !(alive _static && GVAR(useAmmoHandling)) exitWith {false}; +if (_static getVariable [QGVAR(inUse), false]) 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 { @@ -47,7 +46,7 @@ if (count (_static magazinesTurret [0]) > 0) then { _count = _currentMagazine select 2; }; //If the static weapon doesn't have a magzine or a magazine with no bullets, the player has a compatible magazine and the static weapon has a barrel then you can load a magazine -if ((count (_static magazinesTurret [0]) == 0 || _count == 0 ) && _hasCompatibleMagazine) then { +if ((count (_static magazinesTurret [0]) == 0 || _count == 0) && _hasCompatibleMagazine) then { _canLoadMagazine = true; }; _canLoadMagazine diff --git a/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf b/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf index b1d6593574..a296d56c32 100644 --- a/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_canUnloadMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Grey * Checks whether magazine can be unloaded from static weapon @@ -14,15 +15,15 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_static","_unit"]; -private ["_canUnloadMagazine","_ammoCount"]; if !(alive _static && GVAR(useAmmoHandling) && _static getVariable [QGVAR(initialized),false]) exitWith {false}; -_canUnloadMagazine = false; +if (_static getVariable [QGVAR(inUse), false]) exitWith {false}; -_ammoCount = ((magazinesAllTurrets _static) select 1) select 2; +private _canUnloadMagazine = false; + +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 84184fcb51..6141314eea 100644 --- a/addons/mk6mortar/functions/fnc_dev_buildTable.sqf +++ b/addons/mk6mortar/functions/fnc_dev_buildTable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * DEV function to build mortar tables, very cpu intensive (never used durring normal gameplay) @@ -7,7 +8,7 @@ * 1: Air Friction * * Return Value: - * + * None * * Example: * [100, -0.0001] spawn ace_mk6mortar_fnc_dev_buildTable; //spawn (scheduled) is slower @@ -15,23 +16,19 @@ * * Public: No */ -#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]; @@ -84,4 +81,4 @@ _outputString = format ["case ((abs(_muzzleVelocity - %1) < 0.00001) && {(abs(_a copyToClipboard _outputString; rangeTableOutput = _outputString; -hint "done"; \ No newline at end of file +hint "done"; diff --git a/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf b/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf index f89c3a1b8f..a24f456037 100644 --- a/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf +++ b/addons/mk6mortar/functions/fnc_dev_formatNumber.sqf @@ -1,30 +1,26 @@ -/* -Author: Pabst Mirror - -Description: -Converts numbers into nicely formated strings. - -Parameters: -0: NUMBER - Input number -1: STRING - Output type (see case statement) -2: BOOL - If output type is mil, convert input type from deg->mil - -Returns: -STRING - Formatted number - -Example: -[45, "mil4", true] call ace_mk6mortar_fnc_dev_formatNumber = "0800" - */ #include "script_component.hpp" +/* + * Author: Pabst Mirror + * Converts numbers into nicely formated strings. + * + * Arguments: + * 0: Input number + * 1: Output type (see case statement) + * 2: If output type is mil, convert input type from deg->mil + * + * Return Value: + * Formatted number + * + * Example: + * [45, "mil4", true] call ace_mk6mortar_fnc_dev_formatNumber = "0800" + * + * Public: No + */ -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 d1e0a8dd05..2bdfe56c22 100644 --- a/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf +++ b/addons/mk6mortar/functions/fnc_dev_simulateCalcRangeTableLine.sqf @@ -1,62 +1,60 @@ -/* -Author: Pabst Mirror - -Description: -Builds a rangeTable line for a certian range, given muzzle velocity and air friction, returns [] if out of range. - -Parameters: -0: NUMBER - Muzzle Velocity -1: NUMBER - Air Friction -2: NUMBER - Range To Hit - -Returns: -ARRAY - Range Table Line Data (see return line) - -Example: -[300, -0.0001, 3000] call ace_mk6mortar_fnc_simulateCalcRangeTableLine - */ #include "script_component.hpp" +/* + * Author: Pabst Mirror + * Builds a rangeTable line for a certian range, given muzzle velocity and air friction, returns [] if out of range. + * + * Arguments: + * 0: Muzzle Velocity + * 1: Air Friction + * 2: Range To Hit + * + * Return Value: + * Range Table Line Data (see return line) + * + * Example: + * [300, -0.0001, 3000] call ace_mk6mortar_fnc_simulateCalcRangeTableLine + * + * Public: No + */ #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 d302a40f40..3c509d5a19 100644 --- a/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf +++ b/addons/mk6mortar/functions/fnc_dev_simulateFindSolution.sqf @@ -1,41 +1,34 @@ +#include "script_component.hpp" /* * Author: PabstMirror * DEV to find a firing solution for a given range * * Arguments: - * 0: Range to Hit (Meters) - * 1: Height To Hit (Meters) - * 2: Muzzle Velocity (M/S) + * 0: Range to Hit (Meters) + * 1: Height To Hit (Meters) + * 2: Muzzle Velocity (M/S) * 3: Air Friction * 4: Time Step (seconds) (eg 1/50 will simulate 50 cycles per second) * * Return Value: - * ARRAY - [NUMBER - Elevation In Degrees, NUMBER - Shot Durration] + * [NUMBER - Elevation In Degrees, NUMBER - Shot Durration] * * Example: * [_rangeToHit, _heightToHit, _muzzleVelocity, _airFriction, TIME_STEP] call ace_mk6mortar_fnc_dev_simulateFindSolution; * * Public: No */ -#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..7974526ff6 100644 --- a/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf +++ b/addons/mk6mortar/functions/fnc_dev_simulateShot.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * DEV function to build mortar tables, very cpu intensive (never used durring normal gameplay) @@ -21,37 +22,26 @@ * * Public: No */ -#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 483a69d42b..02a8e51ce0 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Called when the mortar is fired. @@ -12,16 +13,15 @@ * 6: projectile - Object of the projectile that was shot * * Return Value: - * Nothing + * None * * Example: * [clientFiredBIS-XEH] call ace_mk6mortar_fnc_handleFired * * Public: No */ -#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 5c74927e46..fd53bcf3d4 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. @@ -7,14 +8,13 @@ * 1: New Vehicle * * Return Value: - * No + * None * * Example: * [bob, mortar] call ace_mk6mortar_fnc_handlePlayerVehicleChanged; * * Public: No */ -#include "script_component.hpp" params ["_player", "_newVehicle"]; @@ -45,19 +45,18 @@ if (_lastFireMode != -1) then { }; [{ - private ["_chargeText", "_currentChargeMode", "_currentFireMode", "_display", "_elevDeg", "_elevationDiff", "_lookVector", "_notGunnerView", "_realAzimuth", "_realElevation", "_upVectorDir", "_useMils", "_weaponDir"]; - PARAMS_2(_args,_pfID); - EXPLODE_2_PVT(_args,_mortarVeh,_fireModes); + params ["_args", "_pfID"]; + _args params ["_mortarVeh", "_fireModes"]; if ((vehicle ACE_player) != _mortarVeh) 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,29 +67,41 @@ 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; - if ((ctrlText (_display displayCtrl 173)) == "--") then { + private _realAzimuth = -1; + private _realElevation = -1; + + private _useRealWeaponDir = (ctrlText (_display displayCtrl 173)) == "--"; + if (_useRealWeaponDir && {(_mortarVeh ammo (currentWeapon _mortarVeh)) == 0}) then { + // With no ammo, distance display will be empty, but gun will still fire at wonky angle if aimed at ground + private _testSeekerPosASL = AGLtoASL (positionCameraToWorld [0,0,0]); + private _testSeekerDir = _testSeekerPosASL vectorFromTo (AGLtoASL (positionCameraToWorld [0,0,1])); + private _testPoint = _testSeekerPosASL vectorAdd (_testSeekerDir vectorMultiply viewDistance); + if ((terrainIntersectASL [_testSeekerPosASL, _testPoint]) || {lineIntersects [_testSeekerPosASL, _testPoint]}) then { + _useRealWeaponDir = false; // If we are not looking at infinity (based on viewDistance) + }; + }; + + 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; }; @@ -123,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..297fb2a969 100644 --- a/addons/mk6mortar/functions/fnc_loadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_loadMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Grey * Loads Magazine into static weapon @@ -15,11 +16,8 @@ * * Public: Yes */ -#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..cfc6adff08 100644 --- a/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf +++ b/addons/mk6mortar/functions/fnc_loadMagazineTimer.sqf @@ -1,12 +1,13 @@ +#include "script_component.hpp" /* * 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 @@ -16,13 +17,14 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_static","_unit","_timeToLoad",["_magazineClassOptional","",[""]]]; -//Move player into animation if player is standing +_static setVariable [QGVAR(inUse), true, true]; + +// 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); }; -[_timeToLoad, [_static,_unit,_magazineClassOptional], {(_this select 0) call FUNC(loadMagazine)}, {}, localize LSTRING(loadingMortar)] call EFUNC(common,progressBar); +[_timeToLoad, [_static,_unit,_magazineClassOptional], {(_this select 0) call FUNC(loadMagazine); ((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, {((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, localize LSTRING(loadingMortar)] call EFUNC(common,progressBar); diff --git a/addons/mk6mortar/functions/fnc_moduleInit.sqf b/addons/mk6mortar/functions/fnc_moduleInit.sqf index 3dedbb2c9e..3158236859 100644 --- a/addons/mk6mortar/functions/fnc_moduleInit.sqf +++ b/addons/mk6mortar/functions/fnc_moduleInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Loads settings from the module. @@ -15,12 +16,10 @@ * * Public: No */ -#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_mortarInit.sqf b/addons/mk6mortar/functions/fnc_mortarInit.sqf index 65d0ff74db..46c16738bf 100644 --- a/addons/mk6mortar/functions/fnc_mortarInit.sqf +++ b/addons/mk6mortar/functions/fnc_mortarInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: VKing * Initializes mortar for use with ammunition handling magazines. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_mortar"]; diff --git a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf index 1a3301d779..1a5d5bf9a6 100644 --- a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Can player open 82mm rangetable. @@ -14,8 +15,7 @@ * * Public: No */ -#include "script_component.hpp" -PARAMS_2(_vehicle,_player); +params ["_vehicle", "_player"]; -"ACE_RangeTable_82mm" in (items _player); +"ACE_RangeTable_82mm" in (_player call EFUNC(common,uniqueItems)); diff --git a/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf b/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf index 07e0536d24..f55e2bcd99 100644 --- a/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTableOpen.sqf @@ -1,44 +1,42 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Opens the rangetable and fills the charge listbox. * * Arguments: - * No + * None * * Return Value: - * No + * None * * Example: * [] call ace_mk6mortar_fnc_rangeTableOpen * * Public: No */ -#include "script_component.hpp" #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 c0cc40ccdc..84bb2fba05 100644 --- a/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTablePageChange.sqf @@ -1,32 +1,30 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Called when listbox selection changes. Updates the rangetable with new values. * * Arguments: - * No + * None * * Return Value: - * No + * None * * Example: * [] call ace_mk6mortar_fnc_rangeTablePageChange * * Public: No */ -#include "script_component.hpp" #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 db87cb6000..7a219e5535 100644 --- a/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTablePreCalculatedValues.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Simple Lookup Table for various muzzle velocities and air frictions. @@ -8,16 +9,15 @@ * 1: Air Friction * * Return Value: - * + * Array * * Example: * [200, 0] call ace_mk6mortar_fnc_rangeTablePreCalculatedValues * * Public: No */ -#include "script_component.hpp" -PARAMS_2(_muzzleVelocity,_airFriction); +params ["_muzzleVelocity", "_airFriction"]; switch (true) do { @@ -268,4 +268,4 @@ case ((abs(_muzzleVelocity - 200) < 0.00001) && {(abs(_airFriction - 0) < 0.0000 ERROR("MuzzleVelocity not found in LUT"); [] }; -}; \ No newline at end of file +}; diff --git a/addons/mk6mortar/functions/fnc_toggleMils.sqf b/addons/mk6mortar/functions/fnc_toggleMils.sqf index 5c27bf64e4..a2c2a29789 100644 --- a/addons/mk6mortar/functions/fnc_toggleMils.sqf +++ b/addons/mk6mortar/functions/fnc_toggleMils.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Toggles the mortart to show mils or degrees @@ -7,16 +8,15 @@ * 1: Player * * Return Value: - * No + * None * * Example: * [mortar,bob] call ace_mk6mortar_fnc_toggleMils; * * Public: No */ -#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..aa2e9f2823 100644 --- a/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf +++ b/addons/mk6mortar/functions/fnc_turretDisplayLoaded.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Called when the mk6's in game UI is loaded. Hides rangefinder data if it is disabled. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; @@ -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..4da21b3e8f 100644 --- a/addons/mk6mortar/functions/fnc_unloadMagazine.sqf +++ b/addons/mk6mortar/functions/fnc_unloadMagazine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Grey * @@ -15,15 +16,13 @@ * * Public: Yes */ -#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/functions/fnc_unloadMagazineTimer.sqf b/addons/mk6mortar/functions/fnc_unloadMagazineTimer.sqf index 151f35492a..4c152bc7d1 100644 --- a/addons/mk6mortar/functions/fnc_unloadMagazineTimer.sqf +++ b/addons/mk6mortar/functions/fnc_unloadMagazineTimer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Grey * @@ -16,13 +17,14 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_static","_unit","_timeToUnload"]; +_static setVariable [QGVAR(inUse), true, true]; + //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); }; -[_timeToUnload, [_static,_unit], {(_this select 0) call FUNC(unloadMagazine)}, {}, localize LSTRING(unloadingMortar)] call EFUNC(common,progressBar); +[_timeToUnload, [_static,_unit], {(_this select 0) call FUNC(unloadMagazine); ((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, {((_this select 0) select 0) setVariable [QGVAR(inUse), nil, true]}, localize LSTRING(unloadingMortar)] call EFUNC(common,progressBar); diff --git a/addons/mk6mortar/script_component.hpp b/addons/mk6mortar/script_component.hpp index d7f0b92cee..b892893850 100644 --- a/addons/mk6mortar/script_component.hpp +++ b/addons/mk6mortar/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MK6MORTAR diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index 29db72fa65..9fb6f218d5 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Tabela de distâncias de para 82mm 82mm Rangetable Tavola di tiro 82mm + 82mm 射表 + 82mm 사거리표 + 82mm迫击炮射表 + 82mm迫擊炮射表 Range Table for the Mk6 82mm Mortar @@ -24,6 +28,10 @@ Tabela de distâncias para morteiro Mk6 82mm Rangetable pro Mk6 82mm minomet Tavola di tiro per il mortaio calibro 82mm Mk6 + Mk6 82mm 迫撃砲の射表 + Mk6 82mm 박격포 사격을 위한 사거리표 + MK6 82mm迫击炮射表 + MK6 82mm迫擊炮射表 Open 82mm Rangetable @@ -36,6 +44,10 @@ Abrir tabela de distâncias para 82mm Otevřít 82mm Rangetable Apri la tavola di tiro 82mm + 82mm 射表を開く + 82mm 사거리표 열기 + 开启82mm迫击炮射表 + 開啟82mm迫擊炮射表 Charge @@ -48,6 +60,18 @@ Carregar Charge Carica + 装薬 + 장약 + 装药 + 裝藥 + + + Mk6 Mortar + Mk6 Mörser + Mortaio Mk6 + MK6迫擊炮 + MK6迫击炮 + Mk6 迫撃砲 Mk6 Settings @@ -60,6 +84,10 @@ Mk6 beállítások Настройки Mk6 Impostazioni Mk6 + Mk6 設定 + Mk6 설정 + MK6设定 + MK6設定 Air Resistance @@ -72,6 +100,10 @@ Légellenállás Сопротивление воздуха Resistenza dell'Aria + 空気抵抗 + 공기저항 + 空气阻力 + 空氣阻力 For Player Shots, Model Air Resistance and Wind Effects @@ -84,6 +116,10 @@ Játékos általi lövésekhez, legyen-e számított légellenállás és szélhatás Для выстрелов игрока. Моделирует сопротивление воздуха и эффект ветра Per Proiettili dei Giocatori, simula la Resistenza dell'Aria e gli Effetti del Vento + プレイヤが射撃すると、空気抵抗モデルと風による影響をあたえます。 + 플레이어 사격시 공기저항과 바람에 영향을 받습니다 + 设定由玩家射击的迫击炮,将会受到空气阻力与风力的影响 + 設定由玩家射擊的迫擊砲,將會受到空氣阻力與風力的影響 Allow Mk6 Computer @@ -96,6 +132,10 @@ Mk6 számítógép engedélyezése Разрешить компьютер Mk6 Consenti Computer Mk6 + Mk6 コンピュータを許可 + Mk6 탄도계산컴퓨터 허가 + 允许使用MK6射控电脑 + 允許使用MK6射控電腦 Show the Computer and Rangefinder (these NEED to be removed if you enable air resistance) @@ -108,6 +148,10 @@ A távmérő és számítógép megjelenítése (ezeket el KELL távolítani ha a légellenállás engedélyezve van) Показывает компьютер и дальномер (это НУЖНО отключить, если вы включаете сопротивление воздуха) Mostra il Computer e Distaziometro (questi DEVONO essere rimossi se vuoi abilitare la resistenza dell'aria) + コンピュータと距離を表示します (空気抵抗を有効化している場合は必ず削除してください) + 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을경우 이 항목은 비활성화 되어야만 합니다) + 显示射控电脑和测距仪 (如果有启用空气阻力功能时,须停用此项功能) + 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時,須停用此項功能) Allow Mk6 Compass @@ -120,6 +164,10 @@ Mk6 iránytű engedélyezése Разрешить компас Mk6 Consenti Bussola Mk6 + Mk6 への方位磁石を有効化 + Mk6 나침반 허용 + 允许使用MK6指北针 + 允許使用MK6指北針 Show the Mk6 Digital Compass @@ -132,6 +180,10 @@ Az Mk6 digitális iránytű megjelenítése Показывает цифровой компас Mk6 Mostra la Bussola Digitale Mk6 + Mk6 のデジタル方位磁石を表示 + Mk6 에서 전자 나침반을 보여줍니다 + 显示MK6的数位指北针 + 顯示MK6的數位指北針 This module allows you to setup Mk6 mortar settings. @@ -143,6 +195,10 @@ Ce module permet de régler les options du mortier Mk6 Questo modulo ti consente di impostare i parametri del mortaio Mk6. Este módulo permite configurar los parámetros del mortero Mk6. + Mk6 迫撃砲への設定をできます。 + 이 모듈은 Mk6 설치 설정을 가능케 합니다. + 这个模块允许你设定MK6迫击炮的相关功能 + 這個模塊允許你設定MK6迫擊砲的相關功能 Use Ammunition handling @@ -153,6 +209,10 @@ Utilizza la gestione delle munizioni Usar manejo de munição Использовать манипуляции с боеприпасами + 弾薬の取り扱い + 탄약 관리 활성화 + 使用手动弹药装卸 + 使用手動彈藥裝卸 Removes mortar magazines, requiring individual rounds to be loaded by the gunner or loader. Does not affect AI mortars. @@ -163,6 +223,10 @@ Toglie i proiettili dal mortaio. I colpi singoli devono essere caricati dall'operatore. Non cambia quado l'IA spara. Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. Não afeta os morteiros controlados pela IA. Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжащим. Не влияет на артиллерию ИИ. + 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI 迫撃砲へ影響を与えません。 + 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야만 합니다. 인공지능은 영향을 받지 않습니다. + 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由AI射击的迫击炮 + 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 Remove Round @@ -174,6 +238,10 @@ Odstranit náboj Remover munição Извлечь снаряд + 弾薬を除去 + 탄약 제거 + 卸除弹头 + 卸除彈頭 Load Mortar @@ -185,6 +253,10 @@ Nabít minomet Carregar morteiro Зарядить миномет + 弾薬を装填 + 탄약 장전 + 装载弹头 + 裝載彈頭 Unloading Round @@ -195,6 +267,10 @@ Scarica proiettile Descarregar munição Извлечение снаряда + 弾薬を除去しています + 탄약 제거중 + 卸除弹头中 + 卸除彈頭中 Preparing Round @@ -206,6 +282,10 @@ Připavuji náboj Preparar munição Подготовка снаряда + 事前に装填 + 탄약 준비중 + 准备弹头中 + 準備彈頭中 Load HE @@ -217,6 +297,10 @@ Nabít HE Carregar HE Зарядить фугасный + りゅう弾を装填 + 고폭탄 장전 + 装载高爆弹 + 裝載高爆彈 Load Smoke @@ -228,6 +312,10 @@ Nabít Dýmovnici Carregar Fumaça Зарядить дымовой + 煙幕弾を装填 + 연막탄 장전 + 装载烟雾弹 + 裝載煙霧彈 Load Illumination @@ -239,6 +327,10 @@ Nabít Světlici Carregar Iluminação Зарядить осветительный + 照明弾を装填 + 조명탄 장전 + 装载照明弹 + 裝載照明彈 Load Guided HE @@ -250,6 +342,10 @@ Nabít HE (Naváděné) Carregar HE Guiada Зарядить фугасный управляемый + 誘導りゅう弾を装填 + 유도 고폭탄 장전 + 装载导引高爆弹 + 裝載導引高爆彈 Load Laser Guided HE @@ -261,6 +357,10 @@ Nabít HE (Naváděné laserem) Carregar HE Guiada por Laser Зарядить фугасный управляемый по ЛЦУ + レーザ誘導りゅう弾を装填 + 레이저 유도 고폭탄 장전 + 装载雷射导引高爆弹 + 裝載雷射導引高爆彈 82mm HE Round @@ -272,6 +372,10 @@ 82mm HE náboj Munição 82mm HE Фугасный снаряд 82мм + 82mm りゅう弾 + 82mm 고폭탄 + 82mm高爆弹 + 82mm高爆彈 82mm Smoke Round @@ -283,6 +387,10 @@ 82mm Kouřový náboj Munição 82mm Fumaça Дымовой снаряд 82мм + 82mm 煙幕弾 + 82mm 연막탄 + 82mm烟雾弹 + 82mm煙霧彈 82mm Illumination Round @@ -294,6 +402,10 @@ 82mm Osvětlovací náboj Munição 82mm Iluminação Осветительный снаряд 82мм + 82mm 照明弾 + 82mm 조명탄 + 82mm照明弹 + 82mm照明彈 82mm Guided HE Round @@ -305,6 +417,10 @@ 82mm HE náboj (naváděný) Munição 82mm HE Guiada Фугасный снаряд управляемый 82мм + 82mm 誘導りゅう弾 + 82mm 유도 고폭탄 + 82mm导引高爆弹 + 82mm導引高爆彈 82mm Laser Guided HE Round @@ -316,6 +432,10 @@ 82mm HE náboj (naváděný laserem) Munição 82mm HE Guiada por Laser Фугасный снаряд управляемый по ЛЦУ 82мм + 82mm レーザ誘導りゅう弾 + 82mm 레이저 유도 고폭탄 + 82mm雷射导引高爆弹 + 82mm雷射導引高爆彈 Used in Mk6 mortar @@ -327,6 +447,10 @@ Používá se u minometu Mk6 Usada no Morteiro MK6 Использовался в миномете Mk6 + Mk6 mortar で使います + Mk6 박격포에 사용됨 + 用于Mk6迫击炮 + 用於Mk6迫擊砲 [ACE] 82mm HE Rounds Box @@ -338,6 +462,10 @@ [ACE] Bedna s municí (82mm HE) [ACE] Caixa de Munição 82mm HE [ACE] Ящик фугасных снарядов 82мм + [ACE] 82mm りゅう弾入り弾薬箱 + [ACE] 82mm 고폭탄 상자 + [ACE] 82mm高爆弹药箱 + [ACE] 82mm高爆彈藥箱 [ACE] 82mm Smoke Rounds Box @@ -349,6 +477,10 @@ [ACE] Bedna s municí (82mm Dýmovnice) [ACE] Caixa de Munição 82mm Fumaça [ACE] Ящик дымовых снарядов 82мм + [ACE] 82mm 煙幕弾入り弾薬箱 + [ACE] 82mm 연막탄 상자 + [ACE] 82mm烟雾弹药箱 + [ACE] 82mm煙霧彈藥箱 [ACE] 82mm Illumination Rounds Box @@ -360,6 +492,10 @@ [ACE] Bedna s municí (82mm Světlice) [ACE] Caixa de Munição 82mm Iluminação [ACE] Ящик осветительных снарядов 82мм + [ACE] 82mm 照明弾入り弾薬箱 + [ACE] 82mm 조명탄 상자 + [ACE] 82mm照明弹药箱 + [ACE] 82mm照明彈藥箱 [ACE] 82mm Default Loadout Box @@ -371,6 +507,10 @@ [ACE] Bedna se standardní 82mm municí [ACE] Caixa de Munição 82mm Padrão [ACE] Ящик снарядов 82мм (стандартный) + [ACE] 82mm 梱包箱 + [ACE] 82mm 기본 장비 상자 + [ACE] 82mm预设弹药箱 + [ACE] 82mm預設彈藥箱 - \ No newline at end of file + diff --git a/addons/modules/CfgEventHandlers.hpp b/addons/modules/CfgEventHandlers.hpp index cd12d1938e..dc1da95f37 100644 --- a/addons/modules/CfgEventHandlers.hpp +++ b/addons/modules/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); @@ -11,7 +10,6 @@ class Extended_PreInit_EventHandlers { }; }; - class Extended_PostInit_EventHandlers { class _ACE_modules { // using a _ so it is the first postInit to be executed init = QUOTE(call COMPILE_FILE(XEH_postInit)); diff --git a/addons/modules/XEH_PREP.hpp b/addons/modules/XEH_PREP.hpp index 66edc4e817..ab0c69eab9 100644 --- a/addons/modules/XEH_PREP.hpp +++ b/addons/modules/XEH_PREP.hpp @@ -1,2 +1 @@ - PREP(moduleInit); diff --git a/addons/modules/XEH_postInit.sqf b/addons/modules/XEH_postInit.sqf index 293b946897..c6892046fe 100644 --- a/addons/modules/XEH_postInit.sqf +++ b/addons/modules/XEH_postInit.sqf @@ -1,4 +1,3 @@ - #include "script_component.hpp" [QEGVAR(common,initSettingsFromModules), { @@ -10,7 +9,7 @@ [_x] call { params ["_logic"]; private _logicType = typeOf _logic; - _logic hideobject true; + _logic hideObject true; if (_logic getVariable [QGVAR(initalized), false]) exitWith {}; private _config = (configFile >> "CfgVehicles" >> _logicType); @@ -18,7 +17,7 @@ private _isGlobal = getNumber (_config >> "isGlobal") > 0; private _isDisposable = getNumber (_config >> "isDisposable") > 0; - private _isPersistent = getNumber (_config >> "isPersistent") > 0 || getnumber (_config >> "isGlobal") > 1; + private _isPersistent = getNumber (_config >> "isPersistent") > 0 || getNumber (_config >> "isGlobal") > 1; private _isSingular = getNumber (_config >> "isSingular") > 0; private _function = getText (_config >> "function"); if (isNil _function) then { @@ -27,7 +26,7 @@ _function = missionNamespace getVariable _function; }; if (_isSingular && {_logicType in _uniqueModulesHandled}) then { //ToDo: should this be an exit? - ACE_LOGWARNING_1("Module [%1] - More than 1 singular module placed", _logicType); + WARNING_1("Module [%1] - More than 1 singular module placed", _logicType); }; if (_isSingular) then {_uniqueModulesHandled pushBack _logicType;}; @@ -40,6 +39,7 @@ }; if (_isDisposable) then { + if (_isGlobal) then {WARNING_1("Deleting Global Module??? [%1]",_logicType);}; deleteVehicle _logic; }; }; diff --git a/addons/modules/XEH_preInit.sqf b/addons/modules/XEH_preInit.sqf index 419cd902b5..cb884af1f5 100644 --- a/addons/modules/XEH_preInit.sqf +++ b/addons/modules/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(moduleInitCollection) = []; diff --git a/addons/modules/config.cpp b/addons/modules/config.cpp index 662b1cb349..6475b90cf4 100644 --- a/addons/modules/config.cpp +++ b/addons/modules/config.cpp @@ -14,6 +14,7 @@ class CfgPatches { }; }; +class CBA_Extended_EventHandlers; class CfgVehicles { class Logic; class Module_F: Logic { @@ -23,6 +24,7 @@ class CfgVehicles { class ACE_Module: Module_F { class EventHandlers { init = QUOTE(_this call DFUNC(moduleInit)); + class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; }; }; diff --git a/addons/modules/functions/fnc_moduleInit.sqf b/addons/modules/functions/fnc_moduleInit.sqf index 5d42b4fa87..5e03aad13c 100644 --- a/addons/modules/functions/fnc_moduleInit.sqf +++ b/addons/modules/functions/fnc_moduleInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * IV Treatment local callback @@ -7,13 +8,14 @@ * * * Return Value: - * nil + * None + * + * Example: + * [LOGIC] call ace_modules_fnc_moduleInit * * Public: No */ -#include "script_component.hpp" - if ((_this select 0) isKindOf "Module_F") then { GVAR(moduleInitCollection) pushBack (_this select 0); }; diff --git a/addons/modules/script_component.hpp b/addons/modules/script_component.hpp index 0ba8e441e8..9c15587f72 100644 --- a/addons/modules/script_component.hpp +++ b/addons/modules/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MODULES 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/XEH_preInit.sqf b/addons/movement/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/movement/XEH_preInit.sqf +++ b/addons/movement/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; 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_addLoadToUnitContainer.sqf b/addons/movement/functions/fnc_addLoadToUnitContainer.sqf index a79b2ab917..5910f6c186 100644 --- a/addons/movement/functions/fnc_addLoadToUnitContainer.sqf +++ b/addons/movement/functions/fnc_addLoadToUnitContainer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Add (negative numbers to subtract) a virtual mass to a units container. @@ -10,9 +11,11 @@ * Return Value: * Success? * + * Example: + * [bob, box, 5] call ace_movement_fnc_addLoadToUnitContainer + * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_container", objNull, [objNull]], ["_virtualLoadToAdd", 0, [0]]]; diff --git a/addons/movement/functions/fnc_canClimb.sqf b/addons/movement/functions/fnc_canClimb.sqf index 260f76105b..808a81d582 100644 --- a/addons/movement/functions/fnc_canClimb.sqf +++ b/addons/movement/functions/fnc_canClimb.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Tests the the player can climb. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/movement/functions/fnc_climb.sqf b/addons/movement/functions/fnc_climb.sqf index 57df4e5991..2d5eb88786 100644 --- a/addons/movement/functions/fnc_climb.sqf +++ b/addons/movement/functions/fnc_climb.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Make the player climb over short walls. @@ -6,14 +7,13 @@ * 0: The Unit (usually the player) * * Return Value: - * Nothing + * None * * Example: * [player] call ace_movement_fnc_climb * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/movement/functions/fnc_getWeight.sqf b/addons/movement/functions/fnc_getWeight.sqf deleted file mode 100644 index b64abc3623..0000000000 --- a/addons/movement/functions/fnc_getWeight.sqf +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Author: commy2 - * Returns the weight (from the loadAbs command) in lbs/kg (based on user option) - * - * Arguments: - * 0: The Unit (usually the player) - * - * Return Value: - * The return value - * - * Example: - * [player] call ace_movement_fnc_getWeight - * - * Public: No - */ -#include "script_component.hpp" - -params ["_unit"]; - -private _virtualLoad = 0; - -{ - _virtualLoad = _virtualLoad + (_x getVariable [QGVAR(vLoad), 0]); -} forEach [ - _unit, - uniformContainer _unit, - vestContainer _unit, - backpackContainer _unit -]; - -private _weight = (loadAbs _unit + _virtualLoad) * 0.1; - -if (GVAR(useImperial)) then { - _weight = format ["%1lb", (round (_weight * 100)) / 100]; -} else { - _weight = format ["%1kg", (round (_weight * FACTOR_POUND_TO_KILOGRAMM * 100)) / 100]; -}; - -_weight diff --git a/addons/movement/functions/fnc_handleClimb.sqf b/addons/movement/functions/fnc_handleClimb.sqf index e6d8fed12c..6f6c7b536b 100644 --- a/addons/movement/functions/fnc_handleClimb.sqf +++ b/addons/movement/functions/fnc_handleClimb.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handles the climb animation finishing. Called from "AnimDone" event handler. @@ -7,14 +8,13 @@ * 1: The finisehd animation * * Return Value: - * Nothing + * None * * Example: * [player, "ACE_climb"] call ace_movement_fnc_handleClimb * * Public: No */ -#include "script_component.hpp" params ["_unit", "_anim"]; @@ -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_handleVirtualMass.sqf b/addons/movement/functions/fnc_handleVirtualMass.sqf index 8e33197089..8f035cc5ad 100644 --- a/addons/movement/functions/fnc_handleVirtualMass.sqf +++ b/addons/movement/functions/fnc_handleVirtualMass.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Recalculate the units loadCoef to emulate a mass added to uniform, vest or backpack. @@ -6,11 +7,13 @@ * 0: The Unit (usually the player) * * Return Value: - * Nothing + * None + * + * Example: + * [bob] call ace_movement_fnc_handleVirtualMass * * Public: No */ -#include "script_component.hpp" params ["_unit"]; @@ -28,6 +31,8 @@ private _virtualLoad = 0; backpackContainer _unit ]; +_unit setVariable [QGVAR(totalLoad), (loadAbs _unit + _virtualLoad)]; + // get absolute vanilla load private _absLoad = getNumber (configFile >> "CfgInventoryGlobalVariable" >> "maxSoldierLoad"); diff --git a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf b/addons/movement/functions/fnc_inventoryDisplayLoad.sqf new file mode 100644 index 0000000000..d107bd70b1 --- /dev/null +++ b/addons/movement/functions/fnc_inventoryDisplayLoad.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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/script_component.hpp b/addons/movement/script_component.hpp index f64f10fdd4..5876fa7e8f 100644 --- a/addons/movement/script_component.hpp +++ b/addons/movement/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MOVEMENT diff --git a/addons/movement/stringtable.xml b/addons/movement/stringtable.xml index af5ce71af4..45a3bf65c3 100644 --- a/addons/movement/stringtable.xml +++ b/addons/movement/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,18 +12,10 @@ Mostrar peso em libras Súly megjelenítése fontban. Показывать вес в фунтах - - - Weight: - Gewicht: - Peso: - Poids: - Waga: - Váha: - Peso: - Peso: - Súly: - Вес: + ポンドで重量を表示する + 무게를 파운드(lb)로 보여줍니다 + 使用磅来显示重量 + 使用磅來顯示重量 Climb @@ -36,6 +28,10 @@ Mászás Arrampicati Subir + 登る + 오르기 + 攀爬 + 攀爬 Can't climb here @@ -48,6 +44,10 @@ Itt nem tudsz mászni Non puoi arrampicarti qui Não se pode subir aqui + ここは登れません + 这里无法攀爬 + 這裡無法攀爬 + 여기는 올라갈 수 없다 diff --git a/addons/mx2a/CfgVehicles.hpp b/addons/mx2a/CfgVehicles.hpp index c450133ba7..51038b9625 100644 --- a/addons/mx2a/CfgVehicles.hpp +++ b/addons/mx2a/CfgVehicles.hpp @@ -6,15 +6,15 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(DisplayName); vehicleClass = "Items"; - class TransportWeapons { - MACRO_ADDWEAPON(ACE_MX2A,1); + class TransportItems { + MACRO_ADDITEM(ACE_MX2A,1); }; }; class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { - class TransportWeapons { - MACRO_ADDWEAPON(ACE_MX2A,6); + class TransportItems { + MACRO_ADDITEM(ACE_MX2A,6); }; }; }; diff --git a/addons/mx2a/script_component.hpp b/addons/mx2a/script_component.hpp index c2fc0e12e6..95ddda7f1c 100644 --- a/addons/mx2a/script_component.hpp +++ b/addons/mx2a/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MX2A diff --git a/addons/mx2a/stringtable.xml b/addons/mx2a/stringtable.xml index e2c7ed2dc7..099a8e7703 100644 --- a/addons/mx2a/stringtable.xml +++ b/addons/mx2a/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ MX-2A MX-2A MX-2A + MX-2A + MX-2A + MX-2A(热成像) + MX-2A Thermal imaging device @@ -24,6 +28,10 @@ Hőleképező készülék Тепловизионный прибор Dispositivo di visione termica + サーマル画像表示双眼鏡 + 열영상 장치 + 热成像装置 + 熱成像裝置 - \ No newline at end of file + diff --git a/addons/nametags/ACE_Settings.hpp b/addons/nametags/ACE_Settings.hpp index ab6220f131..702cba07cd 100644 --- a/addons/nametags/ACE_Settings.hpp +++ b/addons/nametags/ACE_Settings.hpp @@ -37,6 +37,7 @@ class ACE_Settings { category = CSTRING(Module_DisplayName); }; class GVAR(showCursorTagForVehicles) { + displayName = CSTRING(showCursorTagForVehicles_DisplayName); value = 0; typeName = "BOOL"; isClientSettable = 0; @@ -52,16 +53,20 @@ class ACE_Settings { category = CSTRING(Module_DisplayName); }; class GVAR(playerNamesViewDistance) { + displayName = CSTRING(playerNamesViewDistance_DisplayName); value = 5; typeName = "SCALAR"; isClientSettable = 0; category = CSTRING(Module_DisplayName); + sliderSettings[] = {0, 50, 5, 1}; }; class GVAR(playerNamesMaxAlpha) { + displayName = CSTRING(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/XEH_PREP.hpp b/addons/nametags/XEH_PREP.hpp index 5d99258d27..a27102a4e5 100644 --- a/addons/nametags/XEH_PREP.hpp +++ b/addons/nametags/XEH_PREP.hpp @@ -2,6 +2,7 @@ PREP(canShow); PREP(doShow); PREP(drawNameTagIcon); +PREP(getCachedFlags); PREP(getVehicleData); PREP(initIsSpeaking); PREP(moduleNameTags); diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index bebe840b47..2df7565cd6 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -15,7 +15,7 @@ GVAR(showNamesTime) = -10; // Statement GVAR(showNamesTime) = CBA_missionTime; - if (call FUNC(canShow)) then{ call FUNC(doShow); }; + // if (call FUNC(canShow)) then{ call FUNC(doShow); }; // This code doesn't work (canShow has a nil / has never worked??) // Return false so it doesn't block other actions false }, @@ -34,4 +34,14 @@ GVAR(showNamesTime) = -10; if (_name == QGVAR(showPlayerNames)) then { call FUNC(updateSettings); }; + // Reset nametag flag cache on setting change: + ACE_player setVariable [QGVAR(flagsCache), nil]; }] call CBA_fnc_addEventHandler; + +["cba_events_visionModeEvent", { + // Reset nametag flag cache on vision mode change: + ACE_player setVariable [QGVAR(flagsCache), nil]; +}] call CBA_fnc_addEventHandler; + +// civilians don't use military ranks +["CIV_F", ["","","","","","",""]] call FUNC(setFactionRankIcons); diff --git a/addons/nametags/XEH_preInit.sqf b/addons/nametags/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/nametags/XEH_preInit.sqf +++ b/addons/nametags/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/nametags/functions/fnc_canShow.sqf b/addons/nametags/functions/fnc_canShow.sqf index 5bccc8f91d..9cc83cfd91 100644 --- a/addons/nametags/functions/fnc_canShow.sqf +++ b/addons/nametags/functions/fnc_canShow.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: aeroson * Checks if crew info can be shown. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" ((vehicle ACE_player) != ACE_player) && {GVAR(ShowCrewInfo)} && diff --git a/addons/nametags/functions/fnc_doShow.sqf b/addons/nametags/functions/fnc_doShow.sqf index 1f689704b9..12ac1a04cb 100644 --- a/addons/nametags/functions/fnc_doShow.sqf +++ b/addons/nametags/functions/fnc_doShow.sqf @@ -1,3 +1,5 @@ +#include "script_component.hpp" +#include "common.hpp" /* * Author: aeroson * Shows the actual text and sets text the crew info. @@ -13,27 +15,23 @@ * * Public: No */ -#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_drawNameTagIcon.sqf b/addons/nametags/functions/fnc_drawNameTagIcon.sqf index bfe065cf30..093496cfb8 100644 --- a/addons/nametags/functions/fnc_drawNameTagIcon.sqf +++ b/addons/nametags/functions/fnc_drawNameTagIcon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, esteldunedain * Draw the nametag and rank icon. @@ -20,8 +21,6 @@ * Public: No */ -#include "script_component.hpp" - TRACE_1("drawName:", _this); params ["", "_target", "", "_heightOffset"]; diff --git a/addons/nametags/functions/fnc_getCachedFlags.sqf b/addons/nametags/functions/fnc_getCachedFlags.sqf new file mode 100644 index 0000000000..3fc13256e0 --- /dev/null +++ b/addons/nametags/functions/fnc_getCachedFlags.sqf @@ -0,0 +1,56 @@ +#include "script_component.hpp" +/* + * Author: + * Get's flags used for onDraw3D that can be cached + * + * Arguments: + * None + * + * Return Value: + * [_drawName,_drawRank,_enabledTagsNearby,_enabledTagsCursor,_maxDistance] + * + * Example: + * call ace_nametags_fnc_getCachedFlags + * + * Public: No + */ + +// Determine flags from current settings +private _drawName = true; +private _enabledTagsNearby = false; +private _enabledTagsCursor = false; + +switch (GVAR(showPlayerNames)) do { + case 0: { + // Player names Disabled [Note: this should be unreachable as the drawEH will be removed] + _drawName = false; + _enabledTagsNearby = (GVAR(showSoundWaves) == 2); + }; + case 1: { + // Player names Enabled + _enabledTagsNearby = true; + }; + case 2: { + // Player names Only cursor + _enabledTagsNearby = (GVAR(showSoundWaves) == 2); + _enabledTagsCursor = true; + }; + case 3: { + // Player names Only Keypress + _enabledTagsNearby = GVAR(showSoundWaves) == 2; // non-cached: || _onKeyPressAlphaMax) > 0 + }; + case 4: { + // Player names Only Cursor and Keypress + _enabledTagsNearby = (GVAR(showSoundWaves) == 2); + // non-cached: _enabledTagsCursor = _onKeyPressAlphaMax > 0; + }; + case 5: { + // Fade on border + _enabledTagsNearby = true; + }; +}; + +private _ambientBrightness = ((([] call EFUNC(common,ambientBrightness)) + ([0, 0.4] select ((currentVisionMode ace_player) != 0))) min 1) max 0; +private _maxDistance = _ambientBrightness * GVAR(PlayerNamesViewDistance); + +[_drawName, GVAR(showPlayerRanks),_enabledTagsNearby,_enabledTagsCursor,_maxDistance] diff --git a/addons/nametags/functions/fnc_getVehicleData.sqf b/addons/nametags/functions/fnc_getVehicleData.sqf index 1c916f81aa..55dc758081 100644 --- a/addons/nametags/functions/fnc_getVehicleData.sqf +++ b/addons/nametags/functions/fnc_getVehicleData.sqf @@ -1,3 +1,5 @@ +#include "script_component.hpp" +#include "common.hpp" /* * Author: aeroson * Gathers and caches data needed by ace_nametags_fnc_doShow. @@ -17,8 +19,6 @@ * * Public: No */ -#include "script_component.hpp" -#include "common.hpp"; params ["_type"]; diff --git a/addons/nametags/functions/fnc_initIsSpeaking.sqf b/addons/nametags/functions/fnc_initIsSpeaking.sqf index 08a72e57b3..62a96bf5d9 100644 --- a/addons/nametags/functions/fnc_initIsSpeaking.sqf +++ b/addons/nametags/functions/fnc_initIsSpeaking.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, PabstMirror * Starts up a PFEH to monitor the when players are talking. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" if (isServer) then { //If someone disconnects while speaking, reset their variable @@ -37,14 +37,14 @@ if (!hasInterface) exitWith {}; }] call CBA_fnc_addPlayerEventHandler; if (isClass (configFile >> "CfgPatches" >> "acre_api")) then { - ACE_LOGINFO("ACRE Detected."); + INFO("ACRE Detected."); DFUNC(isSpeaking) = { params ["_unit"]; ([_unit] call acre_api_fnc_isSpeaking) && {!(_unit getVariable ["ACE_isUnconscious", false])} }; } else { if (isClass (configFile >> "CfgPatches" >> "task_force_radio")) then { - ACE_LOGINFO("TFR Detected."); + INFO("TFR Detected."); DFUNC(isSpeaking) = { params ["_unit"]; (_unit getVariable ["tf_isSpeaking", false]) && {!(_unit getVariable ["ACE_isUnconscious", false])} @@ -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 079e4aa704..03ced478be 100644 --- a/addons/nametags/functions/fnc_moduleNameTags.sqf +++ b/addons/nametags/functions/fnc_moduleNameTags.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Initializes the name tags module. @@ -7,12 +8,13 @@ * * Return Value: * None + * + * Example: + * [] call ace_nametags_fnc_moduleNameTags + * + * Public: No */ -#include "script_component.hpp" - -if !(isServer) exitWith {}; - params ["_logic", "", "_activated"]; if !(_activated) exitWith {}; @@ -33,4 +35,4 @@ if ((_logic getVariable "showVehicleCrewInfo") != -1) then { [_logic, QGVAR(showVehicleCrewInfo), "showVehicleCrewInfo" ] call EFUNC(common,readSettingFromModule); }; -ACE_LOGINFO("Nametags Module Initialized."); +INFO("Nametags Module Initialized."); diff --git a/addons/nametags/functions/fnc_onDraw3d.sqf b/addons/nametags/functions/fnc_onDraw3d.sqf index 7f3f04a0c4..fb5d29807a 100644 --- a/addons/nametags/functions/fnc_onDraw3d.sqf +++ b/addons/nametags/functions/fnc_onDraw3d.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: * Draws names and icons. @@ -13,67 +14,34 @@ * * Public: No */ -#include "script_component.hpp" - -private ["_defaultIcon", "_distance", "_alpha", "_icon", "_targets", "_relPos", "_projDist", "_target"]; BEGIN_COUNTER(GVAR(onDraw3d)); // Don't show nametags in spectator or if RscDisplayMPInterrupt is open if ((isNull ACE_player) || {!alive ACE_player} || {!isNull (findDisplay 49)}) exitWith {}; -// Determine flags from current settings -private _drawName = true; -private _drawRank = GVAR(showPlayerRanks); -private _enabledTagsNearby = false; -private _enabledTagsCursor = false; +private _flags = [[], DFUNC(getCachedFlags), ACE_player, QGVAR(flagsCache), 2] call EFUNC(common,cachedCall); + +_flags params ["_drawName", "_drawRank", "_enabledTagsNearby", "_enabledTagsCursor", "_maxDistance"]; + private _onKeyPressAlphaMax = 1; -switch (GVAR(showPlayerNames)) do { - case 0: { - // Player names Disabled - _drawName = false; - _enabledTagsNearby = (GVAR(showSoundWaves) == 2); - _enabledTagsCursor = false; - }; - case 1: { - // Player names Enabled - _enabledTagsNearby = true; - _enabledTagsCursor = false; - }; - case 2: { - // Player names Only cursor - _enabledTagsNearby = (GVAR(showSoundWaves) == 2); - _enabledTagsCursor = true; - }; - case 3: { - // Player names Only Keypress - _onKeyPressAlphaMax = 2 + (GVAR(showNamesTime) - CBA_missionTime); - _enabledTagsNearby = (_onKeyPressAlphaMax) > 0 || (GVAR(showSoundWaves) == 2); - _enabledTagsCursor = false; - }; - case 4: { - // Player names Only Cursor and Keypress - _onKeyPressAlphaMax = 2 + (GVAR(showNamesTime) - CBA_missionTime); - _enabledTagsNearby = (GVAR(showSoundWaves) == 2); - _enabledTagsCursor = _onKeyPressAlphaMax > 0; - }; - case 5: { - // Fade on border - _enabledTagsNearby = true; - _enabledTagsCursor = false; - }; +if (GVAR(showPlayerNames) == 3) then { + _onKeyPressAlphaMax = 2 + (GVAR(showNamesTime) - CBA_missionTime); + _enabledTagsNearby = _enabledTagsNearby || {_onKeyPressAlphaMax > 0} +}; +if (GVAR(showPlayerNames) == 4) then { + _onKeyPressAlphaMax = 2 + (GVAR(showNamesTime) - CBA_missionTime); + _enabledTagsCursor = _onKeyPressAlphaMax > 0; }; -private _ambientBrightness = ((([] call EFUNC(common,ambientBrightness)) + ([0, 0.4] select ((currentVisionMode ace_player) != 0))) min 1) max 0; -private _maxDistance = _ambientBrightness * GVAR(PlayerNamesViewDistance); - private _camPosAGL = positionCameraToWorld [0, 0, 0]; +if !((_camPosAGL select 0) isEqualType 0) exitWith {}; // handle RHS / bugged vehicle slots + private _camPosASL = AGLtoASL _camPosAGL; -private _vecy = (AGLtoASL positionCameraToWorld [0, 0, 1]) vectorDiff _camPosASL; // Show nametag for the unit behind the cursor or its commander if (_enabledTagsCursor) then { - _target = cursorTarget; + private _target = cursorTarget; if !(_target isKindOf "CAManBase") then { // When cursorTarget is on a vehicle show the nametag for the commander. if !(_target in allUnitsUAV) then { @@ -90,7 +58,7 @@ if (_enabledTagsCursor) then { {lineIntersectsSurfaces [_camPosASL, eyePos _target, ACE_player, _target] isEqualTo []} && {!isObjectHidden _target}) then { - _distance = ACE_player distance _target; + private _distance = ACE_player distance _target; private _drawSoundwave = (GVAR(showSoundWaves) > 0) && {[_target] call FUNC(isSpeaking)}; // Alpha: @@ -135,6 +103,9 @@ if (_enabledTagsNearby) then { private _target = _x; if !(isNull _target) then { + private _drawSoundwave = (GVAR(showSoundWaves) > 0) && {[_target] call FUNC(isSpeaking)}; + if (_enabledTagsCursor && {!_drawSoundwave}) exitWith {}; // (Cursor Only && showSoundWaves==2) - quick exit + private _relPos = (visiblePositionASL _target) vectorDiff _camPosASL; private _distance = vectorMagnitude _relPos; @@ -150,7 +121,6 @@ if (_enabledTagsNearby) then { }; }; - private _drawSoundwave = (GVAR(showSoundWaves) > 0) && {[_target] call FUNC(isSpeaking)}; private _alphaMax = _onKeyPressAlphaMax; if ((GVAR(showSoundWaves) == 2) && _drawSoundwave) then { _drawName = _drawSoundwave; diff --git a/addons/nametags/functions/fnc_setFactionRankIcons.sqf b/addons/nametags/functions/fnc_setFactionRankIcons.sqf index c0a315636b..fa7975d5e5 100644 --- a/addons/nametags/functions/fnc_setFactionRankIcons.sqf +++ b/addons/nametags/functions/fnc_setFactionRankIcons.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Sets a custom set of icons for a specified faction. @@ -22,7 +23,6 @@ * * Public: Yes */ -#include "script_component.hpp" if (isNil QGVAR(factionRanks)) then { GVAR(factionRanks) = [] call CBA_fnc_createNamespace; diff --git a/addons/nametags/functions/fnc_setText.sqf b/addons/nametags/functions/fnc_setText.sqf index 9bc084cfd4..543b4fc913 100644 --- a/addons/nametags/functions/fnc_setText.sqf +++ b/addons/nametags/functions/fnc_setText.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: aeroson * Sets the text on the dialog. @@ -13,16 +14,13 @@ * * Public: No */ -#include "script_component.hpp" #define TextIDC 11123 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/functions/fnc_updateSettings.sqf b/addons/nametags/functions/fnc_updateSettings.sqf index 76110b4f79..56ba016064 100644 --- a/addons/nametags/functions/fnc_updateSettings.sqf +++ b/addons/nametags/functions/fnc_updateSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Dynamically adds and removes Draw3D based on settings on run-time. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (isNil QGVAR(drawHandler) && {GVAR(showPlayerNames) != 0}) then { GVAR(drawHandler) = addMissionEventHandler ["Draw3D", {_this call FUNC(onDraw3d);}]; diff --git a/addons/nametags/script_component.hpp b/addons/nametags/script_component.hpp index fff9a31de3..29dce66096 100644 --- a/addons/nametags/script_component.hpp +++ b/addons/nametags/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_NAMETAGS diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index c248dba636..aa0cca2b18 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Показать имена Mostra i nomi Mostrar nomes + 名前の表示 + 이름 표시 + 显示名字 + 顯示名稱 Show player names @@ -24,6 +28,10 @@ Mostrar nomes de jogadores Mostra i nomi dei giocatori Показывать имена игроков (включить имена) + プレイヤ名を表示 + 플레이어 이름 표시 + 显示玩家名字 + 顯示玩家名稱 Show player name only on cursor (requires player names) @@ -36,6 +44,10 @@ 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) Показать имена игроков только под курсором (при включенных именах) + カーソルを合わせた時だけプレイヤ名を表示 (プレイヤ名が必要) + 커서로 지시할때만 플레이어 이름 표시(플레이어 이름 필요) + 仅在准心指到后显示玩家名字 (玩家必须有设定名字) + 僅在準心指到後顯示玩家名稱 (玩家必須有設定名稱) Show player name only on keypress (requires player names) @@ -48,6 +60,10 @@ Показать имена игроков только по нажатию клавиши (при включенных именах) Mostra i nomi solo se si preme il tasto (insieme ai nomi) Mostrar nomes somente ao pressionar teclar (requer nome de jogadores) + キーを押した時だけプレイヤ名を表示 (プレイヤ名が必要) + 키를 누를때만 플레이어 이름 표시(플레이어 이름 필요) + 仅在按按键后显示玩家名字 (玩家必须有设定名字) + 僅在按按鍵後顯示玩家名稱 (玩家必須有設定名稱) Show player ranks (requires player names) @@ -60,6 +76,10 @@ Mostrar patente de jogadores (requer nome de jogadores) Játékosok rendfokozatának mutatása (a nevek mutatása szükséges) Показывать звания игроков (при вкл. именах) + プレイヤの階級を表示 (プレイヤ名が必要) + 플레이어 계급 표시 (플레이어 이름 필요) + 显示玩家军阶 (玩家必须有设定名字) + 顯示玩家軍階 (玩家必須有設定名稱) Show vehicle crew info @@ -72,6 +92,10 @@ Jármű-legénység adatainak mutatása Mostrar tripulantes Mostra l'elenco del personale a bordo + 車両の乗員を表示 + 차량 승무원 정보 표시 + 显示载具成员信息 + 顯示載具成員信息 Show name tags for AI units @@ -84,6 +108,10 @@ Névcímkék mutatása MI-egységeknél Mostra i nomi delle le unità AI Mostrar nomes para unidades de IA + AI ユニットの名札を表示 + 인공지능 인원 이름 표시 + 显示AI单位名字 + 顯示AI單位名稱 Show SoundWaves (requires player names) @@ -96,6 +124,10 @@ "Hanghullámok" mutatása (a nevek mutatása szükséges) Mostra movimento audio (insieme ai nomi) Mostrar onda sonora (requer nome de jogadores) + 音波形を表示 (プレイヤ名が必要) + 음파 표시 (플레이어 이름 필요) + 当玩家讲话时,显示声波图案 (玩家必须有设定名字) + 當玩家講話時,顯示聲波圖案 (玩家必須有設定名稱) Default Nametag Color (Non Group Members) @@ -108,6 +140,10 @@ Alap névcímke-szín (csoporton kívüli személyek) Colore dei nomi non appartenenti al gruppo Cor padrão do nome (unidades fora do grupo) + 標準の名札の色(グループ メンバ以外) + 기본 이름표 색상 (비-그룹 멤버) + 预设名字颜色 (非同小队队友) + 預設名稱顏色 (非同小隊隊友) Name Tags @@ -120,6 +156,10 @@ Névcímkék Имена игроков Etichette Nomi + 名札 + 이름표 + 玩家名字 + 玩家名稱 Player Names View Dist. @@ -132,6 +172,10 @@ Játékosok nevének látótávja Дистанция отображения имен Distanza Visiva Etichette Nomi + プレイヤ名が見える範囲 + 플레이어 이름 표시 거리 + 玩家名字显示距离 + 玩家名稱顯示距離 Distance in meters at which player names are shown. Default: 5 @@ -144,6 +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公尺 Show name tags for AI? @@ -156,6 +204,10 @@ Névcímkék megjelenítése AI-nál? Показывать имена ботов? Mostra etichette nomi per IA? + AI の名札も表示しますか? + 인공지능의 이름도 표시합니까? + 显示AI名字? + 顯示AI名稱? Show the name and rank tags for friendly AI units? Default: Do not force @@ -168,6 +220,10 @@ 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的名稱和軍階? 預設: 不顯示 Force Hide @@ -180,6 +236,10 @@ Erőltetett rejtett Обязательно: Скрывать Forza Nascosto + 強制で非表示 + 강제로 숨기기 + 强制隐藏 + 強迫隱藏 Force Show @@ -192,6 +252,10 @@ Erőltetett látható Обязательно: Показывать Forza Mostra + 強制で表示 + 강제로 표시 + 强制显示 + 強迫顯示 Show crew info? @@ -204,6 +268,10 @@ Legénységi adatok megjelenítése? Показывать экипаж? Mostra informazioni equipaggio? + 乗員の情報を表示 + 승무원 정보 표시? + 显示载具成员讯息? + 顯示載具成員訊息? Show vehicle crew info, or by default allows players to choose it on their own. Default: Do Not Force @@ -216,6 +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 @@ -228,6 +300,10 @@ Mutatás járműveknél Показывать для техники Mostra per Veicoli + 車両への表示 + 차량 표시 + 显示给载具指挥官 + 顯示給載具指揮官 Show cursor NameTag for vehicle commander (only if client has name tags enabled) Default: No @@ -239,6 +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. @@ -251,6 +331,10 @@ Ez a modul lehetővé teszi a névcímkék beállításainak testreszabását. Этот модуль позволяет настроить опции и дистанцию отображения имен игроков. Questo modulo ti consente di personalizzare le impostazioni ed il raggio delle Etichette Nomi + これは名札の表示範囲と設定を変更できます。 + 이 모듈은 당신이 이름표의 범위를 임의로 수정할 수 있게 해줍니다. + 这个模块允许您设定名字和显示范围等设定 + 這個模塊允許您設定名稱和顯示範圍等設定 Only on Cursor @@ -263,6 +347,10 @@ Csak kurzorra Только под курсором Solo su Cursore + カーソルでのみ + 커서만 해당 + 只有准心指到时 + 只有準心指到時 Only on Keypress @@ -275,6 +363,10 @@ Csak gombnyomásra Только по нажатию клавиши Solo quando Premi Tasto + キー押下のみ + 키를 누를경우만 + 只有按按键时 + 只有按按鍵時 Only on Cursor and Keypress @@ -287,6 +379,10 @@ Csak kurzorra és gombnyomásra Под курсором или по нажатию клавиши Solo su Cursore e quando Premi Tasto + カーソルとキー押下のみ + 커서와 키를 누를경우만 + 只有在准心指到和按按键时 + 只有在準心指到和按按鍵時 Force Show Only on Cursor @@ -299,6 +395,10 @@ Erőltetett látható, csak kurzorra Обязательно: Только под курсором Forza Mostra solo su Cursore + カーソルでのみに強制する + 커서만 강제로 해당 + 强制仅显示在准心指到时 + 強制僅顯示在準心指到時 Force Show Only on Keypress @@ -311,6 +411,10 @@ Erőltetett látható, csak gombnyomásra Обязательно: Только по нажатию клавиши Forza Mostra solo quando Premi Tasto + キー押下のみに強制する + 키를 누를경우만 강제로 해당 + 强制仅显示在按按键时 + 強制僅顯示在按按鍵時 Force Show Only on Cursor and Keypress @@ -323,6 +427,10 @@ Erőltetett látható, csak kurzorra és gombnyomásra Обязательно: Под курсором или по нажатию клавиши Forza Mostra solo su Cursore e quando Premi Tasto + カーソルとキー押下のみに強制する + 커서와 키를 누를경우만 강제로 해당 + 强制显示在准心指到和按按键时 + 強制顯示在準心指到和按按鍵時 Use Nametag settings @@ -335,6 +443,10 @@ Névcímkék beállításának használata Так же, как имена Usa impostazioni Etichette Nomi + 名札の設定 + 이름표 설정 사용 + 玩家名字设定 + 玩家名稱設定 Always Show All @@ -347,6 +459,10 @@ Mindig minden mutatása Всегда показывать Mostra Sempre Tutto + 常に表示する + 항상 모두 표시 + 永远显示全部 + 永遠顯示全部 Show player names and set their activation. Default: Enabled @@ -359,6 +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. @@ -371,6 +491,10 @@ Hanghullám-effekt a beszélő játékosok feje felett a PTT-gomb lenyomásakor. Ez a beállítás TFAR és ACRE2 alatt működik. Эффект звуковой волны над головами говорящих игроков при удерживании кнопки push-to-talk. Эта опация работает также с рациями TFAR и ACRE2. 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等模組使用。 Nametags Size @@ -383,6 +507,10 @@ Névcímkék mérete Размер имен игроков Dimensione Etichette Nome + 名札の大きさ + 이름표 크기 + 玩家名字标记大小 + 玩家名稱標記大小 Text and Icon Size Scaling @@ -395,10 +523,28 @@ Szöveg és ikon méretének skálázása Масштабирование размера текста и иконок Proporzione Dimensioni Testo ed Icone + 文字とアイコンの大きさ + 글자와 아이콘 크기 비례 + 文字和图示大小设定 + 文字和圖示大小設定 Fade on screen border Am Bildschirmrand ausblenden + 画面端では非表示 + Ukryj na brzegach ekranu + 화면 가장자리에서 사라짐 + Estomper sur les bords de l'écran + Sfocatura nei bordi dello schermo + 在荧幕边框旁淡出 + 在螢幕邊框旁淡出 + + + Player tags transparency + プレイヤー名札の透明度 + 玩家名字标签透明度 + 玩家名稱透明度 + Trasparenza Etichette Nome diff --git a/addons/nightvision/ACE_Settings.hpp b/addons/nightvision/ACE_Settings.hpp index 32dbab7fff..1b9b0e164a 100644 --- a/addons/nightvision/ACE_Settings.hpp +++ b/addons/nightvision/ACE_Settings.hpp @@ -1,8 +1,17 @@ class ACE_Settings { class GVAR(disableNVGsWithSights) { - displayName = CSTRING(DisableNVGsWithSights_DisplayName); - description = CSTRING(DisableNVGsWithSights_description); - typeName = "BOOL"; - value = 0; + movedToSQF = 1; + }; + class GVAR(fogScaling) { + movedToSQF = 1; + }; + class GVAR(noiseScaling) { + movedToSQF = 1; + }; + class GVAR(effectScaling) { + movedToSQF = 1; + }; + class GVAR(aimDownSightsBlur) { + movedToSQF = 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..a81835996f 100644 --- a/addons/nightvision/CfgWeapons.hpp +++ b/addons/nightvision/CfgWeapons.hpp @@ -2,55 +2,88 @@ 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_exp\reticle\ENVG.p3d"; // use vanilla modelOptics so it will show in IR mode + }; + class NVGogglesB_gry_F: NVGoggles { + modelOptics = "\A3\weapons_f_exp\reticle\ENVG.p3d"; }; 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..44926ae7ac --- /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_4("settingsInitialized",GVAR(disableNVGsWithSights),GVAR(fogScaling),GVAR(noiseScaling),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/XEH_preInit.sqf b/addons/nightvision/XEH_preInit.sqf index a7feade1c3..d021ef1f57 100644 --- a/addons/nightvision/XEH_preInit.sqf +++ b/addons/nightvision/XEH_preInit.sqf @@ -2,6 +2,10 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf"; ADDON = true; 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 2616cb83f5..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: - * Nothing - * - * 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 04cea0f214..ffbdc45dea 100644 --- a/addons/nightvision/functions/fnc_changeNVGBrightness.sqf +++ b/addons/nightvision/functions/fnc_changeNVGBrightness.sqf @@ -1,34 +1,41 @@ +#include "script_component.hpp" /* * Author: commy2 - * Change the brightness of the unit's NVG + * Change the brightness of the unit's NVG. * * Arguments: * 0: The Unit * 1: Change in brightness (1 or -1) * * Return Value: - * Nothing + * None * * Example: * [player, 1] call ace_nightvision_fnc_changeNVGBrightness * * Public: No */ -#include "script_component.hpp" params ["_player", "_changeInBrightness"]; -TRACE_2("params",_player,_changeInBrightness); +TRACE_2("changeNVGBrightness",_player,_changeInBrightness); -if (!hasInterface) exitWith {}; - -private _brightness = _player getVariable [QGVAR(NVGBrightness), 0]; - -_brightness = ((round (10 * _brightness + _changeInBrightness) / 10) min 0.5) max -0.5; +private _effectsEnabled = GVAR(effectScaling) != 0; +private _defaultBrightness = [-3, 0] select _effectsEnabled; +private _brightness = _player getVariable [QGVAR(NVGBrightness), _defaultBrightness]; +_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); +// Display default setting as 0 +[format [LLSTRING(NVGBrightness), _brightness - _defaultBrightness]] call EFUNC(common,displayTextStructured); playSound "ACE_Sound_Click"; + +// Handle brightness only if effects are disabled +if (!_effectsEnabled) exitWith { + _brightness = linearConversion [-6, 0, _brightness, 0.4, 1.6, true]; + GVAR(ppEffectNVGBrightness) ppEffectAdjust [1, _brightness, 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..4118360ccc 100644 --- a/addons/nightvision/functions/fnc_initModule.sqf +++ b/addons/nightvision/functions/fnc_initModule.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Initializes the settings for the disable NVGs in sight module. @@ -14,8 +15,7 @@ * Public: No */ -#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..578099846d --- /dev/null +++ b/addons/nightvision/functions/fnc_nonDedicatedFix.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..09eb8e247f 100644 --- a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf +++ b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut * Disables/re-enables NVGs when the player starts/stops aiming down his sight. @@ -15,9 +16,11 @@ * 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..19750891c9 --- /dev/null +++ b/addons/nightvision/functions/fnc_onFiredPlayer.sqf @@ -0,0 +1,61 @@ +#include "script_component.hpp" +/* + * 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 + */ + +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; +TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); + +if ((!GVAR(running)) || {!GVAR(shutterEffects)} || {_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..59be659f53 --- /dev/null +++ b/addons/nightvision/functions/fnc_onLoadoutChanged.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..b4bdc7f4f9 100644 --- a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf +++ b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, Dslyecxi, PabstMirror * Disables turning on NVGs while the player aims down his sight. * * Arguments: @@ -15,16 +16,34 @@ * 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..c889b59a47 --- /dev/null +++ b/addons/nightvision/functions/fnc_pfeh.sqf @@ -0,0 +1,172 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 _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 general effects based on ace_nightvision_effectScaling setting + private _radialBlurPower = 0.0025 * GVAR(effectScaling); + _brightFinal = linearConversion [0, 1, GVAR(effectScaling), 1, _brightFinal]; + _contrastFinal = linearConversion [0, 1, GVAR(effectScaling), 1, _contrastFinal]; + + // Add adjusted NVG brightness + private _playerBrightSetting = ACE_player getVariable [QGVAR(NVGBrightness), 0]; + _brightFinal = _brightFinal + (_playerBrightSetting / 20); + + // Scale grain effects based on ace_nightvision_noiseScaling setting + _grainIntensityFinal = _grainIntensityFinal * GVAR(noiseScaling); + _noiseSharpnessFinal = linearConversion [0, 1, GVAR(noiseScaling), 2.5, _noiseSharpnessFinal]; + + // 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), GVAR(noiseScaling)] + ]; + #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..8943784646 --- /dev/null +++ b/addons/nightvision/functions/fnc_refreshGoggleType.sqf @@ -0,0 +1,129 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..e01a798580 --- /dev/null +++ b/addons/nightvision/functions/fnc_scaleCtrl.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..9137419202 --- /dev/null +++ b/addons/nightvision/functions/fnc_setupDisplayEffects.sqf @@ -0,0 +1,73 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 9bf8321353..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: - * Nothing - * - * Return Value: - * Nothing - * - * 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/initSettings.sqf b/addons/nightvision/initSettings.sqf new file mode 100644 index 0000000000..884c53055a --- /dev/null +++ b/addons/nightvision/initSettings.sqf @@ -0,0 +1,54 @@ +// CBA Settings [ADDON: ace_nightVision]: + +[ + QGVAR(effectScaling), "SLIDER", + [LSTRING(effectScaling_DisplayName), LSTRING(effectScaling_Description)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(effectScaling), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; +[ + QGVAR(fogScaling), "SLIDER", + [LSTRING(fogScaling_DisplayName), LSTRING(fogScaling_Description)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(fogScaling), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(noiseScaling), "SLIDER", + [LSTRING(noiseScaling_DisplayName), LSTRING(noiseScaling_Description)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(noiseScaling), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(aimDownSightsBlur), "SLIDER", + [LSTRING(aimDownSightsBlur_DisplayName)], + localize LSTRING(Category), + [0,2,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(aimDownSightsBlur), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(disableNVGsWithSights), "CHECKBOX", + [LSTRING(DisableNVGsWithSights_DisplayName), LSTRING(DisableNVGsWithSights_description)], + localize LSTRING(Category), + false, // default value + true, // isGlobal + {[QGVAR(disableNVGsWithSights), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(shutterEffects), "CHECKBOX", + [LSTRING(shutterEffects_DisplayName), LSTRING(shutterEffects_description)], + localize LSTRING(Category), + true, // default value + false, // isGlobal + {[QGVAR(shutterEffects), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; diff --git a/addons/nightvision/script_component.hpp b/addons/nightvision/script_component.hpp index 32ded9ac5a..2f431c5407 100644 --- a/addons/nightvision/script_component.hpp +++ b/addons/nightvision/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_NIGHTVISION @@ -16,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 708860d134..d0d1ebbbbb 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -1,6 +1,14 @@ - + + + ACE Nightvision + ACE 暗視装置 + ACE Visione notturna + ACE-Nachtsicht + ACE夜視鏡 + ACE夜视镜 + NV Goggles (Gen1) Noktovizor (Gen1) @@ -12,6 +20,10 @@ ПНВ (Gen1) Gafas de visión nocturna (Gen1) Éjjellátó szemüveg (1. Gen.) + 暗視装置 (第1世代) + 야투경 (1세대) + 夜视镜 (初代) + 夜視鏡 (初代) NV Goggles (Gen2) @@ -24,6 +36,10 @@ ПНВ (Gen2) Gafas de visión nocturna (Gen2) Éjjellátó szemüveg (2. Gen.) + 暗視装置 (第2世代) + 야투경 (2세대) + 夜视镜 (二代) + 夜視鏡 (二代) NV Goggles (Gen3) @@ -36,42 +52,58 @@ ПНВ (Gen3) Gafas de visión nocturna (Gen3) Éjjellátó szemüveg (3. Gen.) + 暗視装置 (第3世代) + 야투경 (3세대) + 夜视镜 (三代) + 夜視鏡 (三代) NV Goggles (Gen3, Brown) 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세대, 갈색) + 夜视镜 (三代, 棕色) + 夜視鏡 (三代, 棕色) NV Goggles (Gen3, Green) 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세대, 녹색) + 夜视镜 (三代, 绿色) + 夜視鏡 (三代, 綠色) NV Goggles (Gen3, Black) 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세대, 검정색) + 夜视镜 (三代, 黑色) + 夜視鏡 (三代, 黑色) NV Goggles (Gen4) @@ -84,6 +116,10 @@ ПНВ (Gen4) Gafas de visión nocturna (Gen4) Éjjellátó szemüveg (4. Gen.) + 暗視装置 (第4世代) + 야투경 (4세대) + 夜视镜 (四代) + 夜視鏡 (四代) NV Goggles (Wide) @@ -96,6 +132,10 @@ Éjjellátó szemüveg (széles látószögű) Óculos de visão noturna (Panorâmico) Occhiali notturni (Larghi) + 暗視装置 (ワイド) + 야투경 (넓음) + 夜视镜 (宽版) + 夜視鏡 (寬版) Brightness: %1 @@ -108,6 +148,10 @@ Fényerő: %1 Luminosidade: %1 Luminosità: %1 + 明度: %1 + 밝기: %1 + 亮度: %1 + 亮度: %1 Increase NVG Brightness @@ -120,6 +164,10 @@ Éjjellátó fényerejének növelése Aumentar Luminosidade do EVN Aumenta la luminosità dell'NVG + 暗視装置の明度を上げる + 야투경 밝기 높이기 + 增加夜视镜亮度 + 增加夜視鏡亮度 Decrease NVG Brightness @@ -132,6 +180,10 @@ Éjjellátó fényerejének csökkentése Diminuir Luminosidade do EVN Riduci la luminosità dell'NVG + 暗視装置の明度を下げる + 야투경 밝기 줄이기 + 减少夜视镜亮度 + 減少夜視鏡亮度 Nightvision @@ -143,6 +195,10 @@ Visione Notturna Visión Nocturna Vision nocturne + 暗視装置 + 야간투시경 + 夜视 + 夜視 Settings for night vision. @@ -154,6 +210,10 @@ Impostazioni per visione notturna. Parámetros para visión nocturna Réglage pour la vision nocturne + 暗視装置の設定をします。 + 야간투시경 설정 + 设定夜视选项. + 設定夜視選項 Disable NVGs in scope @@ -165,6 +225,10 @@ Disabilita NVG nei mirini Desactivar NVG en miras Desactiver les JVN dans les viseurs. + スコープでは暗視装置を無効化 + 조준경 사용시 야투경 비활성화 + 使用瞄准镜时关闭夜视镜 + 使用瞄準鏡時關閉夜視鏡 Blocks the usage of night vision goggles whilst aiming down the sight. @@ -176,6 +240,80 @@ 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 and brightness effects [Setting to 0 will disable ALL nightvision effects] + ぼかしと粒子、明度効果 [0 に設定で全効果を無効化します] + Effetti di sfocatura e luminosità [Importare a 0 disabiliterà TUTTI gli effetti della visione notturna] + Unschärfe und Helligkeitseffekte [Dies auf 0 zu setzen deaktiviert SÄMTLICHE Nachtsichteffekte] + 調整模糊與亮度的效果。[設值為0會關閉所有夜視鏡的特殊效果] + 调整模糊与亮度的效果。[设值为0会关闭所有夜视镜的特殊效果] + + + Aim Down Sights Blur + 照準器を覗く時にぼかし + Visierunschärfe + 瞄準具模糊程度 + 瞄准具模糊程度 + Blur durante la mira + + + NVG Noise Scale + Intensität des Bildrauschens + 夜視鏡雜訊程度 + 夜视镜杂讯程度 + 暗視装置のノイズ度 + Fattore di Disturbo del NVG + + + Image noise intensity when wearing NVGs + Intensität des Bildrauschens im Nachtsichtgerät + 調整配戴夜視鏡時畫面雜訊的多寡。 + 调整配戴夜视镜时画面杂讯的多寡。 + 暗視装置を使用時に起きる画像ノイズの強度です + Intensità del disturbo dell'immagine quando i NVG sono equipaggiati + + + Shutter Effects + シャッター効果 + 快门效果 + 快門效果 + Effetti lampeggianti + + + Rolling shutter effect from muzzle flashes + 発射炎が作るローリング シャッター効果です + 枪械开火时产生瞬间快门效果 + 槍開火時瞬間產生快門效果 + Effetto lampeggiante dato dal lampo dello sparo - \ No newline at end of file + diff --git a/addons/nlaw/$PBOPREFIX$ b/addons/nlaw/$PBOPREFIX$ new file mode 100644 index 0000000000..cbcdbb46de --- /dev/null +++ b/addons/nlaw/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\nlaw diff --git a/addons/nlaw/ACE_GuidanceConfig.hpp b/addons/nlaw/ACE_GuidanceConfig.hpp new file mode 100644 index 0000000000..e04753d681 --- /dev/null +++ b/addons/nlaw/ACE_GuidanceConfig.hpp @@ -0,0 +1,14 @@ +class EGVAR(missileguidance,AttackProfiles) { + class GVAR(directAttack) { + name = CSTRING(directAttack); + functionName = QFUNC(attackProfile); + }; + class GVAR(overflyTopAttack): GVAR(directAttack) { + name = CSTRING(overflyTopAttack); + }; +}; +class EGVAR(missileguidance,SeekerTypes) { + class GVAR(seeker) { + functionName = QFUNC(seeker); + }; +}; diff --git a/addons/nlaw/CfgAmmo.hpp b/addons/nlaw/CfgAmmo.hpp new file mode 100644 index 0000000000..f51816d692 --- /dev/null +++ b/addons/nlaw/CfgAmmo.hpp @@ -0,0 +1,55 @@ +class CfgAmmo { + class M_NLAW_AT_F; + class ACE_NLAW: M_NLAW_AT_F { + hit = 400; // Default was 500 + indirectHit = 20; // Default was 15 + class ace_missileguidance { + enabled = 1; + + minDeflection = 0.0005; // Minium flap deflection for guidance + maxDeflection = 0.01; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = QGVAR(seeker); + seekerTypes[] = {QGVAR(seeker)}; + + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = {"LOBL"}; + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 45; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 10; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = QGVAR(directAttack); + attackProfiles[] = {QGVAR(directAttack), QGVAR(overflyTopAttack)}; + showHintOnCycle = 1; + + // Run once at fired event + onFired = QFUNC(onFired); + }; + }; + + // Sub ammos used in OTA mode (see fnc_seeker.sqf) + class ACE_NLAW_Explosion: ACE_NLAW { // Based on FCS-Airburst, will explode right away + timeToLive = 0; + model = "\A3\weapons_f\empty"; + }; + class ACE_NLAW_ShapedCharge: ACE_NLAW { // Shaped charge from rocket explosion, no effects + timeToLive = 1; + model = "\A3\weapons_f\empty"; + hit = 750; + indirectHit = 0; + indirectHitRange = 0; + explosionSoundEffect = ""; + explosionEffects = ""; + CraterEffects = ""; + muzzleEffect = ""; + }; +}; diff --git a/addons/nlaw/CfgEventhandlers.hpp b/addons/nlaw/CfgEventhandlers.hpp new file mode 100644 index 0000000000..0d3301d6e0 --- /dev/null +++ b/addons/nlaw/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/nlaw/CfgMagazines.hpp b/addons/nlaw/CfgMagazines.hpp new file mode 100644 index 0000000000..fe2e2ecf8d --- /dev/null +++ b/addons/nlaw/CfgMagazines.hpp @@ -0,0 +1,6 @@ +class CfgMagazines { + class CA_LauncherMagazine; + class NLAW_F: CA_LauncherMagazine { + ammo = "ACE_NLAW"; + }; +}; diff --git a/addons/nlaw/CfgWeapons.hpp b/addons/nlaw/CfgWeapons.hpp new file mode 100644 index 0000000000..35f5b17122 --- /dev/null +++ b/addons/nlaw/CfgWeapons.hpp @@ -0,0 +1,13 @@ +class CfgWeapons { + class Launcher_Base_F; + class launch_NLAW_F: Launcher_Base_F { + GVAR(enabled) = 1; + canLock = 1; + class OpticsModes { + class optic { + distanceZoomMin = 0; + distanceZoomMax = 0; + }; + }; + }; +}; diff --git a/addons/nlaw/README.md b/addons/nlaw/README.md new file mode 100644 index 0000000000..dd62b36014 --- /dev/null +++ b/addons/nlaw/README.md @@ -0,0 +1,10 @@ +ace_nlaw +=============== + +Adds Predicted Line Of Sight guidance to the NLAW. + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/nlaw/XEH_PREP.hpp b/addons/nlaw/XEH_PREP.hpp new file mode 100644 index 0000000000..aad1e57efb --- /dev/null +++ b/addons/nlaw/XEH_PREP.hpp @@ -0,0 +1,6 @@ +LOG("prep"); + +PREP(attackProfile); +PREP(keyDown); +PREP(onFired); +PREP(seeker); diff --git a/addons/nlaw/XEH_postInit.sqf b/addons/nlaw/XEH_postInit.sqf new file mode 100644 index 0000000000..885e2d5e2f --- /dev/null +++ b/addons/nlaw/XEH_postInit.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +GVAR(isLockKeyDown) = false; + +// Degrees per second +GVAR(yawChange) = 0; +GVAR(pitchChange) = 0; + +// Add keybind +["ACE3 Weapons", QGVAR(trackTarget), localize LSTRING(trackTarget), { + call FUNC(keyDown); + false // Return false so it doesn't block the rest weapon action +}, { + TRACE_1("lock key up",GVAR(isLockKeyDown)); + GVAR(isLockKeyDown) = false; + false +}, [15, [false, false, false]], false] call CBA_fnc_addKeybind; //Tab Key + + + +// Visual debuging, idealy used with a moving vehicle called "testTarget" +#ifdef DRAW_NLAW_INFO +addMissionEventHandler ["Draw3d", { + // GREEN - Draw an object called "testTarget"'s aim pos and 1 sec aimpos predicted by velocity + if ((!isNil "testTarget") && {!isNull testTarget}) then { + { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLtoAGL ((aimPos testTarget) vectorAdd ((velocity testTarget) vectorMultiply _x)), 0.75, 0.75, 0, format ["%1", _x], 1, 0.025, "TahomaB"]; + } forEach [0, 1, 2, 3]; + }; + + // RED - If lock key is down, draw weapon dir and predicted path at various times + if (GVAR(yawChange) != 0) then { + { + private _viewASL = AGLtoASL positionCameraToWorld [0,0,0]; + private _viewDir = ACE_player weaponDirection (currentWeapon ACE_player); + (_viewDir call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; + private _realYaw = _yaw + GVAR(yawChange) * _x; + private _realPitch = _pitch + GVAR(pitchChange) * _x; + private _returnTargetPos = _viewASL vectorAdd ([1000, _realYaw, _realPitch] call CBA_fnc_polar2vect); + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _returnTargetPos, 0.75, 0.75, 0, format ["%1", _x], 1, 0.025, "TahomaB"]; + } forEach [0, 1, 2, 3]; + }; +}]; +#endif diff --git a/addons/nlaw/XEH_preInit.sqf b/addons/nlaw/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/nlaw/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/nlaw/XEH_preStart.sqf b/addons/nlaw/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/nlaw/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/nlaw/config.cpp b/addons/nlaw/config.cpp new file mode 100644 index 0000000000..7109459066 --- /dev/null +++ b/addons/nlaw/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventhandlers.hpp" + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" + +#include "ACE_GuidanceConfig.hpp" diff --git a/addons/nlaw/functions/fnc_attackProfile.sqf b/addons/nlaw/functions/fnc_attackProfile.sqf new file mode 100644 index 0000000000..acc4330083 --- /dev/null +++ b/addons/nlaw/functions/fnc_attackProfile.sqf @@ -0,0 +1,60 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * NLAW missile guidance attack profile. + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_nlaw_fnc_attackProfile + * + * Public: No + */ + +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH", "_launchParams"]; +_launchParams params ["","_targetLaunchParams", "", "_attackProfile"]; +_targetLaunchParams params ["", "", "_launchPos"]; +_firedEH params ["","","","","","","_projectile"]; + +// Use seeker (if terminal) +if (!(_seekerTargetPos isEqualTo [0,0,0])) exitWith {_seekerTargetPos}; + +_attackProfileStateParams params ["_startTime", "_startLOS", "_yawChange", "_pitchChange"]; +(_startLOS call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; + +private _projectilePos = getPosASL _projectile; +private _distanceFromLaunch = (_launchPos distance _projectilePos) + 10; +private _flightTime = CBA_missionTime - _startTime; + +private _realYaw = _yaw + _yawChange * _flightTime; +private _realPitch = _pitch + _pitchChange * _flightTime; + +private _returnTargetPos = _launchPos vectorAdd ([_distanceFromLaunch, _realYaw, _realPitch] call CBA_fnc_polar2vect); + +if (_attackProfile == QGVAR(overflyTopAttack)) then { // Add 2m height in OTA attack mode + _returnTargetPos = _returnTargetPos vectorAdd [0,0,2]; +}; + + +#ifdef DRAW_NLAW_INFO +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], ASLtoAGL _launchPos, 0.75, 0.75, 0, "LAUNCH", 1, 0.025, "TahomaB"]; +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,1,1], ASLtoAGL (_launchPos vectorAdd (_startLOS vectorMultiply (_distanceFromLaunch + 50))), 0.75, 0.75, 0, "Original LOS", 1, 0.025, "TahomaB"]; +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,0,1], ASLtoAGL (_launchPos vectorAdd ([_distanceFromLaunch + 50, _realYaw, _realPitch] call CBA_fnc_polar2vect)), 0.75, 0.75, 0, format ["Predicted @%1sec",(floor(_flightTime * 10)/10)], 1, 0.025, "TahomaB"]; +drawLine3D [ASLtoAGL _launchPos, ASLtoAGL (_launchPos vectorAdd (_startLOS vectorMultiply (_distanceFromLaunch + 50))), [1,0,0,1]]; +drawLine3D [ASLtoAGL _launchPos, ASLtoAGL (_launchPos vectorAdd ([_distanceFromLaunch + 50, _realYaw, _realPitch] call CBA_fnc_polar2vect)), [1,1,0,1]]; +private _test = lineIntersectsSurfaces [_launchPos, _launchPos vectorAdd (_startLOS vectorMultiply 3000), player, _projectile]; +if ((count _test) > 0) then { + private _posAGL = ASLtoAGL ((_test select 0) select 0); + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], _posAGL, 0.75, 0.75, 0, "Original Impact", 1, 0.025, "TahomaB"]; +}; +#endif + +// TRACE_1("Adjusted target position", _returnTargetPos); +_returnTargetPos; diff --git a/addons/nlaw/functions/fnc_keyDown.sqf b/addons/nlaw/functions/fnc_keyDown.sqf new file mode 100644 index 0000000000..fcc320360c --- /dev/null +++ b/addons/nlaw/functions/fnc_keyDown.sqf @@ -0,0 +1,80 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Handles the track key being held down. + * Tracks change in direction of weapon and computes angle change per second. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_nlaw_fnc_keyDown + * + * Public: No + */ + +TRACE_1("lock key down",GVAR(isLockKeyDown)); + +if (!alive ACE_player) exitWith {}; +if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; +if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith {}; +if ((getNumber (configFile >> "CfgWeapons" >> (currentWeapon ACE_player) >> QGVAR(enabled))) == 0) exitWith {}; +if (GVAR(isLockKeyDown)) exitWith {ERROR("already running?");}; + +GVAR(isLockKeyDown) = true; +playSound "ACE_Sound_Click"; + +// Get starting weapon dir +((ACE_player weaponDirection (currentWeapon ACE_player)) call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; + +[{ + params ["_args", "_pfID"]; + _args params ["_lastTime", "_lastYaw", "_lastPitch", "_initPhase"]; + + if ((!alive ACE_player) || + {!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))} || + {!GVAR(isLockKeyDown)} || + {!(ACE_player call CBA_fnc_canUseWeapon)} || + {(getNumber (configFile >> "CfgWeapons" >> (currentWeapon ACE_player) >> QGVAR(enabled))) == 0}) + exitWith { + TRACE_1("ending track",_pfID); + [_pfID] call CBA_fnc_removePerFrameHandler; + playSound "ACE_Sound_Click"; + + [{ // reset gvars after a short delay + TRACE_1("reset vars",_this); + GVAR(yawChange) = 0; + GVAR(pitchChange) = 0; + }, [], 0.5] call CBA_fnc_waitAndExecute; + }; + + private _deltaT = CBA_missionTime - _lastTime; + if (_deltaT == 0) exitWith {}; + if (_initPhase && {_deltaT < 0.75}) exitWith {}; + + ((ACE_player weaponDirection (currentWeapon ACE_player)) call CBA_fnc_vect2Polar) params ["", "_yaw", "_pitch"]; + private _yawChange = ([_yaw - _lastYaw] call CBA_fnc_simplifyAngle180) / _deltaT; + private _pitchChange = ([_pitch - _lastPitch] call CBA_fnc_simplifyAngle180) / _deltaT; + + if (_initPhase) then { // initial value will use first 0.75 seconds of input + GVAR(yawChange) = _yawChange; + GVAR(pitchChange) = _pitchChange; + _args set [3, false]; + } else { + // smoothing factor alpha - higher values will be more responsive to change, but also spike higher on jerky mouse movmeent + private _alpha = _deltaT / 3; + GVAR(yawChange) = (_yawChange * _alpha) + GVAR(yawChange) * (1 - _alpha); + GVAR(pitchChange) = (_pitchChange * _alpha) + GVAR(pitchChange) * (1 - _alpha); + }; + + _args set [0, CBA_missionTime]; + _args set [1, _yaw]; + _args set [2, _pitch]; + + #ifdef DEBUG_MODE_FULL + hintSilent format ["Instantaneous\nYaw: %1\n Pitch: %2\nGVAR\nYaw: %3\nPitch: %4", _yawChange, _pitchChange, GVAR(yawChange), GVAR(pitchChange)]; + #endif +}, .25, [CBA_missionTime, _yaw, _pitch, true]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/nlaw/functions/fnc_onFired.sqf b/addons/nlaw/functions/fnc_onFired.sqf new file mode 100644 index 0000000000..0552afcd86 --- /dev/null +++ b/addons/nlaw/functions/fnc_onFired.sqf @@ -0,0 +1,62 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Sets up missile guidance state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_nlaw_fnc_onFired + * + * Public: No + */ + +params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_launchParams params ["","_targetLaunchParams","","_attackProfile"]; +_targetLaunchParams params ["_target"]; +_stateParams params ["", "", "_attackProfileStateParams"]; + +// Reset _launchPos origin as projectile's height instead of player's foot +_targetLaunchParams set [2, getPosASL _projectile]; + +// Get state params: +TRACE_3("start of attack profile",_attackProfile,_shooter,vectorDir _projectile); + +private _firedLOS = _shooter weaponDirection (currentWeapon _shooter); +private _yawChange = 0; +private _pitchChange = 0; + +if (_shooter == ACE_player) then { + TRACE_2("isPlayer",GVAR(yawChange),GVAR(pitchChange)); + _yawChange = GVAR(yawChange); + _pitchChange = GVAR(pitchChange); + TRACE_1("los check",_firedLOS call CBA_fnc_vect2Polar); +} else { + if ((!isNil "_target") && {!isNull _target}) then { + _firedLOS = (getPosASL _projectile) vectorFromTo (aimPos _target); + (((eyePos _shooter) vectorFromTo (aimPos _target)) call CBA_fnc_vect2Polar) params ["", "_startYaw", "_startPitch"]; + // Add some random error to AI's velocity prediction: + private _random = random [(_shooter skillFinal "aimingAccuracy") min 0.9, 1, 2-((_shooter skillFinal "aimingAccuracy") min 0.9)]; + (((eyePos _shooter) vectorFromTo ((aimPos _target) vectorAdd ((velocity _target) vectorMultiply (_random)))) call CBA_fnc_vect2Polar) params ["", "_predictedYaw", "_predictedPitch"]; + _yawChange = ([_predictedYaw - _startYaw] call CBA_fnc_simplifyAngle180); + _pitchChange = ([_predictedPitch - _startPitch] call CBA_fnc_simplifyAngle180); + TRACE_1("AI",_target); + } else { + TRACE_1("AI - no target",_target); + }; +}; + +// Limit Max Deflection +_yawChange = -10 max _yawChange min 10; +_pitchChange = -10 max _pitchChange min 10; + +TRACE_3("attackProfileStateParams",_firedLOS,_yawChange,_pitchChange); +_attackProfileStateParams set [0, CBA_missionTime]; +_attackProfileStateParams set [1, _firedLOS]; +_attackProfileStateParams set [2, _yawChange]; +_attackProfileStateParams set [3, _pitchChange]; diff --git a/addons/nlaw/functions/fnc_seeker.sqf b/addons/nlaw/functions/fnc_seeker.sqf new file mode 100644 index 0000000000..eeb2e0794c --- /dev/null +++ b/addons/nlaw/functions/fnc_seeker.sqf @@ -0,0 +1,93 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Handles the top down attack seeker for missile guidance. + * Has a very short range (IR/Magnetic?) seeker that will trigger the shaped charge midair above the target. + * + * Arguments: + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Seeker Pos + * + * Example: + * [] call ace_nlaw_fnc_seeker + * + * Public: No + */ + +params ["", "_args", "_seekerStateParams"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; +_firedEH params ["","","","","","","_projectile"]; +_launchParams params ["", "_targetLaunchParams", "", "_attackProfile"]; +_targetLaunchParams params ["", "", "_launchPos"]; + +if (_attackProfile == QGVAR(directAttack)) exitWith {[0,0,0]}; + +private _projPos = getPosASL _projectile; + +// Arm seeker after 20 meters +if ((_projPos distance _launchPos) >= 20) then { + scopeName "targetScan"; + BEGIN_COUNTER(targetScan); + + if (_seekerStateParams isEqualTo []) then { + TRACE_2("Seeker Armed",_projPos distance _launchPos,diag_fps); + _seekerStateParams set [0, _projPos]; // Set _lastPos to current position + }; + + _seekerStateParams params ["_lastPos", "_terminal"]; + if (_terminal) exitWith {}; + + private _vectorDir = _lastPos vectorFromTo _projPos; + private _frameDistance = _lastPos vectorDistance _projPos; + + // Distance traveled depends on velocity and FPS - at 60fps it will be ~4m + // Step size will effect accuracy and performance costs + for "_stepSize" from 0 to _frameDistance step 0.5 do { + // This represents a position that the missile was at between the last frame and now + private _virtualPos = _lastPos vectorAdd (_vectorDir vectorMultiply _stepSize); + #ifdef DRAW_NLAW_INFO + drawLine3D [ASLtoAGL _virtualPos, ASLtoAGL (_virtualPos vectorAdd [0,0,-5]), [1,0,_stepSize/(_frameDistance max 0.1),1]]; + #endif + + // Limit scan to 5 meters directly down (shaped charge jet has a very limited range) + private _res = lineIntersectsSurfaces [_virtualPos, (_virtualPos vectorAdd [0,0,-5]), _projectile]; + if (!(_res isEqualTo [])) then { + (_res select 0) params ["_targetPos", "", "_target"]; + if ((_target isKindOf "Tank") || {_target isKindOf "Car"} || {_target isKindOf "Air"}) exitWith { + TRACE_3("Firing shaped charge down",_target,_targetPos distance _virtualPos,_frameDistance); + TRACE_2("",_target worldToModel (ASLtoAGL _virtualPos),boundingBoxReal _target); + _virtualPos = _virtualPos vectorAdd (_vectorDir vectorMultiply 1.25); + + deleteVehicle _projectile; + + // Damage and effects of missile exploding (timeToLive is 0 so should happen next frame) + private _explosion = "ACE_NLAW_Explosion" createVehicle _virtualPos; + _explosion setPosASL _virtualPos; + + // Just damage from shaped charge + private _shapedCharage = "ACE_NLAW_ShapedCharge" createVehicle _virtualPos; + _shapedCharage setPosASL _virtualPos; + _shapedCharage setVectorDirAndUp [[0,0,-1], [1,0,0]]; + _shapedCharage setVelocity [0,0,-300]; + + _seekerStateParams set [1, true]; + + END_COUNTER(targetScan); + breakOut "targetScan"; + }; + }; + }; + _seekerStateParams set [0, _projPos]; + END_COUNTER(targetScan); +}; + +// Exploded, return dummy value +if (_seekerStateParams param [1, false]) exitWith { + [0,0,1] +}; + +// return: +[0,0,0] diff --git a/addons/nlaw/functions/script_component.hpp b/addons/nlaw/functions/script_component.hpp new file mode 100644 index 0000000000..50d8cac4c1 --- /dev/null +++ b/addons/nlaw/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\nlaw\script_component.hpp" diff --git a/addons/nlaw/script_component.hpp b/addons/nlaw/script_component.hpp new file mode 100644 index 0000000000..2cabaf7e47 --- /dev/null +++ b/addons/nlaw/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT nlaw +#define COMPONENT_BEAUTIFIED NLAW +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DRAW_NLAW_INFO +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_NLAW + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_NLAW + #define DEBUG_SETTINGS DEBUG_SETTINGS_NLAW +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/nlaw/stringtable.xml b/addons/nlaw/stringtable.xml new file mode 100644 index 0000000000..c986467887 --- /dev/null +++ b/addons/nlaw/stringtable.xml @@ -0,0 +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/noidle/script_component.hpp b/addons/noidle/script_component.hpp index 4931efb771..cdc905afac 100644 --- a/addons/noidle/script_component.hpp +++ b/addons/noidle/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_NOIDLE 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/script_component.hpp b/addons/noradio/script_component.hpp index d55efd222b..0cf8f1f1d4 100644 --- a/addons/noradio/script_component.hpp +++ b/addons/noradio/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_NORADIO diff --git a/addons/noradio/stringtable.xml b/addons/noradio/stringtable.xml new file mode 100644 index 0000000000..4e55b58236 --- /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/norearm/script_component.hpp b/addons/norearm/script_component.hpp index f5b481fe0d..e73a77236e 100644 --- a/addons/norearm/script_component.hpp +++ b/addons/norearm/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_NOREARM 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/XEH_preInit.sqf b/addons/optics/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/optics/XEH_preInit.sqf +++ b/addons/optics/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/optics/functions/fnc_handleFired.sqf b/addons/optics/functions/fnc_handleFired.sqf index f1216fb15d..fbcb177f2e 100644 --- a/addons/optics/functions/fnc_handleFired.sqf +++ b/addons/optics/functions/fnc_handleFired.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Original Author: Taosenai + * Author: Taosenai * Adapted By: KoffeinFlummi, commy2 * * Animates the scope when firing. Called from the unified fired EH only for the local player. @@ -9,15 +10,19 @@ * * Return Value: * None + * + * Example: + * call ace_optics_fnc_handleFired + * + * Public: No */ -#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 {}; @@ -30,25 +35,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 ]; @@ -57,8 +60,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 ]; @@ -72,8 +75,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 fd899b5a02..22b9ddc2b2 100644 --- a/addons/optics/functions/fnc_onDrawScope.sqf +++ b/addons/optics/functions/fnc_onDrawScope.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * 0: Display + * + * Return Value: + * None + * + * Example: + * [DISPLAY] call ace_optics_fnc_onDrawScope + * + * Public: No + */ disableSerialization; @@ -11,12 +25,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 e8b26dca65..9031ca8ba7 100644 --- a/addons/optics/functions/fnc_onDrawScope2D.sqf +++ b/addons/optics/functions/fnc_onDrawScope2D.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Helper function for updating the 2d and 3d scope controls @@ -7,14 +8,13 @@ * 0: Display (RscInGameUI for a weapon) * * Return Value: - * Nothing + * None * * Example: * [ACE_RscWeapon_Arco's Display] call ace_optics_fnc_onDrawScope2D * * Public: No */ -#include "script_component.hpp" disableSerialization; @@ -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/optics/script_component.hpp b/addons/optics/script_component.hpp index 428017bda8..6cc168aea0 100644 --- a/addons/optics/script_component.hpp +++ b/addons/optics/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_OPTICS diff --git a/addons/optics/stringtable.xml b/addons/optics/stringtable.xml index a6818a90d3..377cca28bc 100644 --- a/addons/optics/stringtable.xml +++ b/addons/optics/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ RCO (2D) RCO (2D) RCO (2D) + RCO (2D) + RCO (2D) + 步枪战斗光学瞄准镜(2D) + 步槍戰鬥光學瞄準鏡(2D) RCO (PIP) @@ -24,6 +28,10 @@ RCO (PIP) RCO (PIP) RCO (PIP) + RCO (PIP) + RCO (PIP) + 步枪战斗光学瞄准镜(拟真版) + 步槍戰鬥光學瞄準鏡(擬真版) ARCO (2D) @@ -36,6 +44,10 @@ ARCO (2D) ARCO (2D) ARCO (2D) + ARCO (2D) + ARCO (2D) + 先进步枪战斗光学瞄准镜(2D) + 先進步槍戰鬥光學瞄準鏡(2D) ARCO (PIP) @@ -48,6 +60,10 @@ ARCO (PIP) ARCO (PIP) ARCO (PIP) + ARCO (PIP) + ARCO (PIP) + 先进步枪战斗光学瞄准镜(拟真版) + 先進步槍戰鬥光學瞄準鏡(擬真版) MRCO (2D) @@ -60,6 +76,10 @@ MRCO (2D) MRCO (2D) MRCO (2D) + MRCO (2D) + MRCO (2D) + 多距离战斗瞄准镜(2D) + 多距離戰鬥瞄準鏡(2D) MRCO (PIP) @@ -72,6 +92,10 @@ MRCO (PIP) MRCO (PIP) MRCO (PIP) + MRCO (PIP) + MRCO (PIP) + 多距离战斗瞄准镜(拟真版) + 多距離戰鬥瞄準鏡(擬真版) MOS (2D) @@ -84,6 +108,10 @@ MOS (2D) MOS (2D) MOS (2D) + MOS (2D) + MOS (2D) + 精准光学瞄准镜(2D) + 精準光學瞄準鏡(2D) MOS (PIP) @@ -96,6 +124,10 @@ MOS (PIP) MOS (PIP) MOS (PIP) + MOS (PIP) + MOS (PIP) + 精准光学瞄准镜(拟真版) + 精準光學瞄準鏡(擬真版) LRPS (2D) @@ -108,6 +140,10 @@ LRPS (2D) MPLD (2D) LRPS (2D) + LRPS (2D) + LRPS (2D) + 长距离精确瞄准镜(2D) + 長距離精確瞄準鏡(2D) LRPS (PIP) @@ -120,6 +156,10 @@ LRPS (PIP) MPLD (PIP) LRPS (PIP) + LRPS (PIP) + LRPS (PIP) + 长距离精确瞄准镜(拟真版) + 長距離精確瞄準鏡(擬真版) - \ No newline at end of file + 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 d6451e638d..4f50c9613f 100644 --- a/addons/optionsmenu/CfgEventHandlers.hpp +++ b/addons/optionsmenu/CfgEventHandlers.hpp @@ -11,17 +11,8 @@ 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)); - - //Hide the button if there is no world (-world=empty) - GVAR(hideButtonEmptyWorld) = "((_this select 0) displayCtrl 80085) ctrlShow (missionName != '');"; }; }; 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 8b6f55a0ca..46d58b5a8a 100644 --- a/addons/optionsmenu/XEH_preInit.sqf +++ b/addons/optionsmenu/XEH_preInit.sqf @@ -2,17 +2,13 @@ ADDON = false; +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 a239e55498..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"}; @@ -22,22 +22,19 @@ 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"}; }; - class CfgCommands { allowedHTMLLoadURIs[] += { - "http://ace3mod.com/version.html" + "https://ace3mod.com/version.html" }; }; diff --git a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf index dd2c187bf7..3b662eb121 100644 --- a/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf +++ b/addons/optionsmenu/functions/fnc_debugDumpToClipboard.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Dumps debug info to clipboard. @@ -13,19 +14,16 @@ * * Public: No */ -#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 633a9aa162..0000000000 --- a/addons/optionsmenu/functions/fnc_moduleAllowConfigExport.sqf +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Author: Glowbal - * - * - * Arguments: - * none - * - * Return Value: - * None - * - * 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 4ab0bf83fa..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 { - ACE_LOGERROR_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 8fd52d8d72..0000000000 --- a/addons/optionsmenu/functions/fnc_toggleIncludeClientSettings.sqf +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Author: Glowbal - * - * - * Arguments: - * none - * - * Return Value: - * None - * - * 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 75177fa3b6..f48cecfd0f 100644 --- a/addons/optionsmenu/gui/pauseMenu.hpp +++ b/addons/optionsmenu/gui/pauseMenu.hpp @@ -1,200 +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 ACE_Open_settingsMenu_Btn : ACE_Open_SettingsMenu_BtnBase { - action = "if (missionName != '') then {createDialog 'ACE_settingsMenu';};"; - x = "safezoneX"; - y = "safezoneY"; - idc = 80085; - }; - - - class ACE_news_apex: RscControlsGroupNoHScrollbars { - idc = 80090; - x = "safezoneX + safezoneW - 10 * (pixelW * pixelGrid * 2) - (4 * pixelH)"; - y = "safezoneY + safezoneH - (3 * 2 + 1) * (pixelH * pixelGrid * 2) - 3 * (4 * pixelH)"; - w = "10 * (pixelW * pixelGrid * 2)"; - h = "2 * (pixelH * pixelGrid * 2)"; - class Controls { - class Background: RscPicture { - idc = 80091; - text = "\a3\Ui_f\data\GUI\Rsc\RscDisplayMain\gradientMods_ca.paa"; - colorText[] = {0,0,0,0.75}; - x = "(10 - 4 * 2) * (pixelW * pixelGrid * 2)"; - y = 0; - w = "4 * 2 * (pixelW * pixelGrid * 2)"; - h = "2 * (pixelH * pixelGrid * 2)"; - angle = 180; - }; - class BackgroundIcon: RscPicture { - idc = 80092; - text = "\a3\Ui_f\data\GUI\Rsc\RscDisplayMain\backgroundModsIcon_ca.paa"; - colorText[] = {0,0,0,0.75}; - x = "(10 - 2 * 2) * (pixelW * pixelGrid * 2)"; - y = 0; - w = "2 * 2 * (pixelW * pixelGrid * 2)"; - h = "2 * (pixelH * pixelGrid * 2)"; - angle = 180; - }; - class Icon: RscPicture { - idc = 80093; - text = QPATHTOF(gui\aceMenuIcon_ca.paa); - colorText[] = {1,1,1,0.5}; - x = "(10 - 2) * (pixelW * pixelGrid * 2)"; - y = 0; - w = "2 * (pixelW * pixelGrid * 2)"; - h = "2 * (pixelH * pixelGrid * 2)"; - }; - class CurrentVersionInfo: RscText { - idc = 80094; - 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 = "2 * (pixelH * pixelGrid * 1)"; - onLoad = "(_this select 0) ctrlenable false;"; - }; - class HTTPVersionInfo: RscHTML { - idc = 80095; - 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 = "2 * (pixelH * pixelGrid * 1)"; - w = "(10 - 1.25 * 2) * (pixelW * pixelGrid * 2)"; - h = "2 * (pixelH * pixelGrid * 1)"; - onLoad = "(_this select 0) ctrlenable false;"; - }; - class Button: RscButtonMenu { - idc = 80096; - colorBackground[] = {0,0,0,0}; - colorBackgroundFocused[] = {0,0,0,0}; - colorBackground2[] = {0,0,0,0}; - x = 0; - y = 0; - w = "10 * (pixelW * pixelGrid * 2)"; - h = "2 * (pixelH * pixelGrid * 2)"; - - tooltip = "Download latest and report issues:"; - url = "https://github.com/acemod/ACE3"; - }; - }; - }; - }; +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/init_loadMainMenuBox.sqf b/addons/optionsmenu/init_loadMainMenuBox.sqf index a9b8f5a02a..5b21d7aabb 100644 --- a/addons/optionsmenu/init_loadMainMenuBox.sqf +++ b/addons/optionsmenu/init_loadMainMenuBox.sqf @@ -1,3 +1,5 @@ +#include "\a3\ui_f\hpp\defineResinclDesign.inc" +#include "script_component.hpp" /* * Author: PabstMirror * Loads the version info HTML box from main menu @@ -13,17 +15,45 @@ * * Public: No */ -#include "script_component.hpp" + +params ["_display"]; +private _controlsGroup = _display displayCtrl IDC_MAIN_INFO; //Need to load from profileNamespace because ace_settings might not be init if world = empty if (profileNamespace getVariable [QGVAR(showNewsOnMainMenu), true]) then { - ((_this select 0) displayCtrl 80090) ctrlShow true; + _controlsGroup ctrlShow true; - private _ace3VersionStr = (getText (configFile >> "CfgPatches" >> "ace_main" >> "versionStr")) select [0,5]; - ((_this select 0) displayCtrl 80094) ctrlSetText format ["Version: %1", _ace3VersionStr]; - ((_this select 0) displayCtrl 80095) htmlLoad "http://ace3mod.com/version.html"; + private _fnc_onSetFocus = { + params ["_control"]; + private _controlsGroup = ctrlParentControlsGroup _control; + + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BACKGROUND) ctrlSetTextColor [1,1,1,1]; + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BACKGROUND_ICON) ctrlSetTextColor [1,1,1,1]; + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_ICON) ctrlSetTextColor [0,0,0,1]; + }; + + private _fnc_onKillFocus = { + params ["_control"]; + private _controlsGroup = ctrlParentControlsGroup _control; + + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BACKGROUND) ctrlSetTextColor [0,0,0,0.75]; + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BACKGROUND_ICON) ctrlSetTextColor [0,0,0,0.75]; + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_ICON) ctrlSetTextColor [1,1,1,0.5]; + }; + + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BUTTON) ctrlAddEventHandler ["MouseEnter", _fnc_onSetFocus]; + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BUTTON) ctrlAddEventHandler ["SetFocus", _fnc_onSetFocus]; + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BUTTON) ctrlAddEventHandler ["MouseExit", _fnc_onKillFocus]; + (_controlsGroup controlsGroupCtrl IDC_MAIN_INFO_BUTTON) ctrlAddEventHandler ["KillFocus", _fnc_onKillFocus]; + + private _versionStr = getText (configFile >> "CfgPatches" >> "ace_main" >> "versionStr") splitString "."; + _versionStr resize 3; // MAJOR, MINOR, PATCH + _versionStr = _versionStr joinString "."; + + (_display displayCtrl IDC_MAIN_INFO_CURRENT_VERSION_INFO) ctrlSetText format ["Version: %1", _versionStr]; + (_display displayCtrl IDC_MAIN_INFO_NEWEST_VERSION_INFO) htmlLoad "https://ace3mod.com/version.html"; } else { - ((_this select 0) displayCtrl 80090) ctrlShow false; + _controlsGroup ctrlShow false; }; /* diff --git a/addons/optionsmenu/script_component.hpp b/addons/optionsmenu/script_component.hpp index 2bb7482252..7ae6409e6c 100644 --- a/addons/optionsmenu/script_component.hpp +++ b/addons/optionsmenu/script_component.hpp @@ -3,7 +3,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #include "\z\ace\addons\main\script_mod.hpp" @@ -18,9 +17,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#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 +#define IDC_MAIN_INFO 80090 +#define IDC_MAIN_INFO_CURRENT_VERSION_INFO 80091 +#define IDC_MAIN_INFO_NEWEST_VERSION_INFO 80092 diff --git a/addons/optionsmenu/stringtable.xml b/addons/optionsmenu/stringtable.xml index b051e3f219..4d5846dced 100644 --- a/addons/optionsmenu/stringtable.xml +++ b/addons/optionsmenu/stringtable.xml @@ -1,354 +1,6 @@ - + - - ACE Options - ACE-Optionen - Opciones ACE - Ustawienia ACE - ACE Nastavení - Options ACE - ACE Настройки - Opções do ACE - ACE Beállítások - Opzioni ACE - - - Fix Animation - Behebe Animation - Arreglar animación - Фикс анимации - Opravit animace - Napraw animację - Corriger animation - Animációk kijavítása - Fixa l'animazione - Arrumar Animação - - - Reset All - Alles zurücksetzen - Reiniciar todo - Полный сброс - Vyresetovat vše - Resetuj wszystko - Défaut - Minden visszaállítása - Resetta tutto - Resetar Tudo - - - Colors - Couleurs - Farben - Colores - Цвета - Barvy - Kolory - Színek - Colori - Cores - - - Options - Optionen - Opciones - Opcje - Nastavení - Options - Настройки - Opções - Beállítások - Opzioni - - - 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. - Array. 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 - - - 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] - - - 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. - - - Hide - Ukryj - Ocultar - Verstecken - Skrýt - Ocultar - Cacher - Elrejtés - Скрыть - Nascondi - - - Top right, downwards - Po prawej u góry, w dół - Arriba a la derecha, hacia abajo - Oben rechts, nach unten - Vpravo nahoře, dolů - Superior direito, para baixo - Haut droit, vers le bas - Jobb felül, lefele - Справа — сверху вниз - In Alto a Destra, verso il Basso - - - Top right, to the left - Po prawej u góry, do lewej - Arriba a la derecha, hacia la izquierda - Von rechts nach links - Vpravo nahoře, do leva - Superior direito, à esquerda - Haut droit, vers la gauche - Jobb felül, balra - Сверху — справа налево - In Alto a Destra, verso Sinistra - - - Top left, downwards - Po lewej u góry, w dół - Arriba a la izquierda, hacia abajo - Von links, nach unten - Vlevo nahoře, dolů - Superior esquerdo, para baixo - Haut gauche, vers le bas - Bal felül, lefele - Слева - сверху вниз - In Alto a Sinistra, verso il Basso - - - Top left, to the right - Po lewej u góry, do prawej - Arriba a la izquierda, hacia la derecha - Oben links nach rechts - Vlevo nahoře, do prava - Superior esquerdo, para a direita - Haut gauche, vers la droite - Bal felül, jobbra - Сверху — слева направо - In Alto a Sinistra, verso Destra - - - Top - Góra - Arriba - Oben - Nahoře - Acima - Haut - Fent - Сверху - Alto - - - Bottom - Dół - Abajo - Unten - Dole - Abaixo - Bas - Alul - Снизу - Basso - Debug To Clipboard Debug do schowka @@ -360,6 +12,10 @@ Debug a vágólapra Отладка в буфер обмена Debug su Blocco Note + クリップボードにデバッグ + 디버그를 클립보드로 + 复制除错讯息至剪贴簿 + 複製除錯訊息至剪貼簿 Sends debug information to RPT and clipboard. @@ -372,6 +28,10 @@ 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 @@ -383,7 +43,11 @@ Fix Headbug Fix Headbug Corregir error de cabeza (headbug) - Sistema Headbug + Sistema Bug della Testa + ヘッドバグ修正 + 헤드버그 수정 + 修复动作BUG + 修復動作BUG Resets your animation state. @@ -396,6 +60,10 @@ Resetovat aktuální animaci. Restablece tu estado de animación. Resetta il tuo stato animazione + 現在のアニメーションの状況を初期化します。 + 자신의 동작 상태 초기화 + 当ACE发生动作BUG时,点此修复。 + 當ACE發生動作BUG時,點此修復 ACE News @@ -407,7 +75,11 @@ Nouveautés ACE ACE hírek Новости ACE - News ACE + Novità ACE + ACE ニュース + ACE 새소식 + ACE新闻 + ACE新聞 Show News on Main Menu @@ -420,28 +92,137 @@ Показывать новости в Главном Меню 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 + ACE Logistics + ACE Logistik + ACE Logistyka + ACE Logística + ACE Логистика + ACE Logistika + ACE Logística + ACE Logistica + ACE Logistique + ACE ロジスティクス + ACE 보급 + ACE 后勤设定 + ACE 後勤設定 + + + Hide + Ukryj + Ocultar + Verstecken + Skrýt + Ocultar + Cacher + Elrejtés + Скрыть + Nascondi + 非表示 + 숨기기 + 隐藏 + 隱藏 + + + Top right, downwards + Po prawej u góry, w dół + Arriba a la derecha, hacia abajo + Oben rechts, nach unten + Vpravo nahoře, dolů + Superior direito, para baixo + Haut droit, vers le bas + Jobb felül, lefele + Справа — сверху вниз + In Alto a Destra, verso il Basso + 右上、下側 + 오른쪽 위에서 아래로 + 右上角,向下 + 右上角,向下 + + + Top right, to the left + Po prawej u góry, do lewej + Arriba a la derecha, hacia la izquierda + Von rechts nach links + Vpravo nahoře, do leva + Superior direito, à esquerda + Haut droit, vers la gauche + Jobb felül, balra + Сверху — справа налево + In Alto a Destra, verso Sinistra + 右上、左詰 + 오른쪽 위에서 왼쪽으로 + 右上角,向左 + 右上角,向左 + + + Top left, downwards + Po lewej u góry, w dół + Arriba a la izquierda, hacia abajo + Von links, nach unten + Vlevo nahoře, dolů + Superior esquerdo, para baixo + Haut gauche, vers le bas + Bal felül, lefele + Слева - сверху вниз + In Alto a Sinistra, verso il Basso + 左上、下側 + 왼쪽 위에서 아래로 + 左上角,向下 + 左上角,向下 + + + Top left, to the right + Po lewej u góry, do prawej + Arriba a la izquierda, hacia la derecha + Oben links nach rechts + Vlevo nahoře, do prava + Superior esquerdo, para a direita + Haut gauche, vers la droite + Bal felül, jobbra + Сверху — слева направо + In Alto a Sinistra, verso Destra + 右上、右詰 + 왼쪽 위에서 오른쪽으로 + 左上角,向右 + 左上角,向右 + + + Top + Góra + Arriba + Oben + Nahoře + Acima + Haut + Fent + Сверху + Alto + 上側 + 상단 + 上方 + 上方 + + + Bottom + Dół + Abajo + Unten + Dole + Abaixo + Bas + Alul + Снизу + Basso + 下側 + 하단 + 下方 + 下方 - \ No newline at end of file + 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 a096754ce3..e142b71a89 100644 --- a/addons/overheating/CfgVehicles.hpp +++ b/addons/overheating/CfgVehicles.hpp @@ -7,36 +7,33 @@ 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; icon = QPATHTOF(UI\spare_barrel_ca.paa); }; 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; icon = QPATHTOF(UI\temp_ca.paa); }; 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; icon = QUOTE(PATHTOF(UI\temp_ca.paa)); }; }; @@ -48,12 +45,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)); }; @@ -68,62 +66,62 @@ class CfgVehicles { class FIA_Box_Base_F; class Box_NATO_Support_F: NATO_Box_Base { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class B_supplyCrate_F: ReammoBox_F { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class Box_East_Support_F: EAST_Box_Base { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class O_supplyCrate_F: B_supplyCrate_F { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class Box_IND_Support_F: IND_Box_Base { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class Box_FIA_Support_F: FIA_Box_Base_F { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class I_supplyCrate_F: B_supplyCrate_F { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class IG_supplyCrate_F: ReammoBox_F { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class C_supplyCrate_F: ReammoBox_F { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,2); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,2); }; }; class ACE_Box_Misc: Box_NATO_Support_F { - class TransportItems { - MACRO_ADDITEM(ACE_SpareBarrel,6); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_SpareBarrel,6); }; }; }; 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/XEH_preInit.sqf b/addons/overheating/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/overheating/XEH_preInit.sqf +++ b/addons/overheating/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/overheating/config.cpp b/addons/overheating/config.cpp index 8ef1ac2d51..bedd96fa30 100644 --- a/addons/overheating/config.cpp +++ b/addons/overheating/config.cpp @@ -52,10 +52,3 @@ class CfgGesturesMale { }; }; }; -class ACE_newEvents { - initiateSwapBarrelAssisted = QGVAR(initiateSwapBarrelAssisted); - showWeaponTemperature = QGVAR(showWeaponTemperature); - loadCoolestSpareBarrel = QGVAR(loadCoolestSpareBarrel); - sendSpareBarrelTemperatureHint = QGVAR(sendSpareBarrelTemperatureHint); - weaponJammed = "ace_weaponJammed"; -}; diff --git a/addons/overheating/functions/fnc_calculateCooling.sqf b/addons/overheating/functions/fnc_calculateCooling.sqf index ced682d6d7..01983814f5 100644 --- a/addons/overheating/functions/fnc_calculateCooling.sqf +++ b/addons/overheating/functions/fnc_calculateCooling.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Calculate the cooling down of a weapon over a time interval. @@ -15,10 +16,10 @@ * * Public: No */ -#include "script_component.hpp" 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_canCheckSpareBarrelsTemperatures.sqf b/addons/overheating/functions/fnc_canCheckSpareBarrelsTemperatures.sqf index 29c08275ef..ca4d76e77b 100644 --- a/addons/overheating/functions/fnc_canCheckSpareBarrelsTemperatures.sqf +++ b/addons/overheating/functions/fnc_canCheckSpareBarrelsTemperatures.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Grey-Soldierman * Return true if player can check temperatures of spare barrels @@ -6,12 +7,15 @@ * 0: Player * * Return Value: - * Bool + * Bool + * + * Example: + * [bob] call ace_overheating_fnc_canCheckSpareBarrelsTemperatures * * Public: No */ -#include "script_component.hpp" -params ["_unit"]; + +params ["_player"]; //Get the classname of the spare barrel for the weapon private _weaponBarrelClass = getText (configFile >> 'CfgWeapons' >> currentWeapon _player >> QGVAR(barrelClassname)); @@ -22,4 +26,4 @@ if(_weaponBarrelClass == "") then { //Check if the player has the barrel and the weapon can have its barrel swapped private _canCheckTemperature = GVAR(enabled) && {_weaponBarrelClass in magazines _player}; -_canCheckTemperature; \ No newline at end of file +_canCheckTemperature; diff --git a/addons/overheating/functions/fnc_canSwapBarrel.sqf b/addons/overheating/functions/fnc_canSwapBarrel.sqf index e183490439..53104e19d5 100644 --- a/addons/overheating/functions/fnc_canSwapBarrel.sqf +++ b/addons/overheating/functions/fnc_canSwapBarrel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Grey-Soldierman * Return true if player can swap barrel @@ -5,16 +6,19 @@ * Arguments: * 0: Player * 1: Weapon + * * Return Value: - * Bool + * Bool + * + * Example: + * [bob, "weapon"] call ace_overheating_fnc_canSwapBarrel * * Public: No */ -#include "script_component.hpp" params ["_unit","_weapon"]; //Check if weapon can have its barrel swapped. If not exit out of function -if( !GVAR(enabled) && (getNumber (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(allowSwapBarrel))) != 1) exitWith{false}; +if( !GVAR(enabled) || {getNumber (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(allowSwapBarrel)) != 1}) exitWith{false}; //Get the classname of the spare barrel for the weapon private _weaponBarrelClass = getText (configFile >> 'CfgWeapons' >> _weapon >> QGVAR(barrelClassname)); @@ -23,4 +27,4 @@ if(_weaponBarrelClass == "") then { _weaponBarrelClass = "ACE_SpareBarrel"; }; //If the player has the spare barrel then it can be swapped -(_weaponBarrelClass in magazines _unit) \ No newline at end of file +(_weaponBarrelClass in magazines _unit) diff --git a/addons/overheating/functions/fnc_canUnjam.sqf b/addons/overheating/functions/fnc_canUnjam.sqf index 610fa9ca22..06511f79cd 100644 --- a/addons/overheating/functions/fnc_canUnjam.sqf +++ b/addons/overheating/functions/fnc_canUnjam.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 and esteldunedain * Return true if the unit can unjam it's current weapon @@ -6,11 +7,13 @@ * 0: Player * * Return Value: - * Bool + * Bool + * + * Example: + * [bob] call ace_overheating_fnc_canUnjam * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("_unit",_unit); diff --git a/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf b/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf index 8a634409ee..4c7eba2919 100644 --- a/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf +++ b/addons/overheating/functions/fnc_checkSpareBarrelsTemperatures.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Make the player check the temperature of his spare barrels @@ -8,16 +9,15 @@ * Return Value: * None * + * Example: + * [bob] call ace_overheating_fnc_checkSpareBarrelsTemperature + * * * Public: No */ -#include "script_component.hpp" params ["_player"]; -// Check canInteractWith: -if (!([_player, objNull, ["isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith))) exitWith {}; - // Make the unit go kneeling [_player] call EFUNC(common,goKneeling); @@ -34,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_checkTemperature.sqf b/addons/overheating/functions/fnc_checkTemperature.sqf index c58d14a29d..b7be4f4c13 100644 --- a/addons/overheating/functions/fnc_checkTemperature.sqf +++ b/addons/overheating/functions/fnc_checkTemperature.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 and esteldunedain * Make the player check the temperature of his weapon @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_assistant", "_gunner", "_weapon"]; TRACE_3("params",_assistant,_gunner,_weapon); diff --git a/addons/overheating/functions/fnc_clearJam.sqf b/addons/overheating/functions/fnc_clearJam.sqf index 4dcdaa0caf..44b219fda2 100644 --- a/addons/overheating/functions/fnc_clearJam.sqf +++ b/addons/overheating/functions/fnc_clearJam.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 * Make the unit clear the jam from a weapon @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon", ["_skipAnim", false]]; TRACE_3("params",_unit,_weapon,_skipAnim); diff --git a/addons/overheating/functions/fnc_displayTemperature.sqf b/addons/overheating/functions/fnc_displayTemperature.sqf index e829b61f57..006d81f8f5 100644 --- a/addons/overheating/functions/fnc_displayTemperature.sqf +++ b/addons/overheating/functions/fnc_displayTemperature.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 and esteldunedain * Displays the weapon temperature @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon"]; TRACE_2("params",_unit,_weapon); @@ -45,7 +45,7 @@ for "_a" from (_count + 1) to 12 do { TRACE_3("",_temperature,_color,_string); -_text = composeText [_text, [_string, [0.5, 0.5, 0.5]] call EFUNC(common,stringToColoredText)]; +_text = composeText [_text, [_string, "#808080"] call EFUNC(common,stringToColoredText)]; private _picture = getText (configFile >> "CfgWeapons" >> _weapon >> "picture"); diff --git a/addons/overheating/functions/fnc_firedEH.sqf b/addons/overheating/functions/fnc_firedEH.sqf index b7409355a2..dd6b408a21 100644 --- a/addons/overheating/functions/fnc_firedEH.sqf +++ b/addons/overheating/functions/fnc_firedEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 and esteldunedain * Handle weapon fire. Called from the unified fired EH 1- always for the local player 2- and for non local players if dispersion is simulated. @@ -8,85 +9,79 @@ * Return Value: * None * + * Example: + * call ace_overheating_fnc_firedEH + * * 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); 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 {ACE_LOGERROR("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, "", "", ""]; + }; }; }; @@ -94,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.5, 15, 150], 3 * _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_getWeaponData.sqf b/addons/overheating/functions/fnc_getWeaponData.sqf index b1525f0f41..a055f65b1e 100644 --- a/addons/overheating/functions/fnc_getWeaponData.sqf +++ b/addons/overheating/functions/fnc_getWeaponData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror and esteldunedain * Get weapon data with caching @@ -10,9 +11,13 @@ * 1: slowdownFactor * 2: jamChance * + * Example: + * ["gun"] call ace_overheating_fnc_getWeaponData + * * Public: No */ -#include "script_component.hpp" + +params ["_weapon"]; // Look in the cache first private _weaponData = GVAR(cacheWeaponData) getVariable _weapon; diff --git a/addons/overheating/functions/fnc_handleTakeEH.sqf b/addons/overheating/functions/fnc_handleTakeEH.sqf index b4eecbf236..d347e5f071 100644 --- a/addons/overheating/functions/fnc_handleTakeEH.sqf +++ b/addons/overheating/functions/fnc_handleTakeEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 * Handle "take" event @@ -11,9 +12,11 @@ * Return Value: * None * + * Example: + * [bob, thing, "thing"] call ace_overheating_fnc_handleTakeEH + * * Public: No */ -#include "script_component.hpp" if !(GVAR(unJamOnreload)) exitWith {}; diff --git a/addons/overheating/functions/fnc_jamWeapon.sqf b/addons/overheating/functions/fnc_jamWeapon.sqf index 02966d0067..f8518add8e 100644 --- a/addons/overheating/functions/fnc_jamWeapon.sqf +++ b/addons/overheating/functions/fnc_jamWeapon.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2, based on KK_fnc_playerWeaponMulfunction from KillzoneKid * Jam the weapon @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon"]; TRACE_2("params",_unit,_weapon); diff --git a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf index fa5cdd1c43..5b7ce31571 100644 --- a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf +++ b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Collect the temperature of all the spare barrels a unit has and load the @@ -13,10 +14,12 @@ * Return Value: * None * + * Example: + * [bob, bob, "weapon",5, 2] call ace_overheating_fnc_loadCoolestSpareBarrel + * * * Public: No */ -#include "script_component.hpp" params ["_assistant", "_gunner", "_weapon", "_weaponTemp", "_barrelMass"]; TRACE_5("loadCoolestSpareBarrel1",_assistant,_gunner,_weapon,_weaponTemp,_barrelMass); diff --git a/addons/overheating/functions/fnc_overheat.sqf b/addons/overheating/functions/fnc_overheat.sqf index 84ab7e152f..cff8807003 100644 --- a/addons/overheating/functions/fnc_overheat.sqf +++ b/addons/overheating/functions/fnc_overheat.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 and esteldunedain * Handle weapon fire, heat up the weapon @@ -13,34 +14,34 @@ * Return Value: * None * + * Example: + * [bob, "weapon", "muzzle", "ammo", "magazine", bullet] call ace_overheating_fnc_overheat + * * Public: No */ -#include "script_component.hpp" 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, @@ -61,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_sendSpareBarrelsTemperaturesHint.sqf b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf index 3855f96d3f..ff71814ea8 100644 --- a/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf +++ b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Collect the temperature of all the spare barrels a unit has and send a hint @@ -10,10 +11,12 @@ * Return Value: * None * + * Example: + * [bob, "bob"] call ace_overheating_fnc_sendSpareBarrelsIsTemperaturesHint + * * * Public: No */ -#include "script_component.hpp" params ["_player","_unit"]; diff --git a/addons/overheating/functions/fnc_swapBarrel.sqf b/addons/overheating/functions/fnc_swapBarrel.sqf index 3ad49df7d7..b24ac39f3c 100644 --- a/addons/overheating/functions/fnc_swapBarrel.sqf +++ b/addons/overheating/functions/fnc_swapBarrel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2 * Make a unit start swapping it's barrel @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_assistant", "_gunner", "_weapon"]; TRACE_3("params",_assistant,_gunner,_weapon); @@ -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..c8fbba6e3c 100644 --- a/addons/overheating/functions/fnc_swapBarrelAssistant.sqf +++ b/addons/overheating/functions/fnc_swapBarrelAssistant.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain, Commy2 * Make a unit start swapping the barrel of another unit @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_assistant", "_gunner", "_weapon"]; TRACE_3("params",_assistant,_gunner,_weapon); @@ -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/functions/fnc_swapBarrelCallback.sqf b/addons/overheating/functions/fnc_swapBarrelCallback.sqf index 0e4326cfea..0b0dec4916 100644 --- a/addons/overheating/functions/fnc_swapBarrelCallback.sqf +++ b/addons/overheating/functions/fnc_swapBarrelCallback.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Commy2, esteldunedain * Swap barrel callback @@ -15,8 +16,6 @@ * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" params ["_assistant", "_gunner", "_weapon"]; TRACE_3("params",_assistant,_gunner,_weapon); @@ -31,7 +30,7 @@ if (_assistant isEqualTo _gunner) then { [localize LSTRING(SwappedBarrel), QPATHTOF(UI\spare_barrel_ca.paa)] call EFUNC(common,displayTextPicture); private _temp = _gunner getVariable [format [QGVAR(%1_temp), _weapon], 0]; -private _barrelMass = 0.50 * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; +private _barrelMass = METAL_MASS_RATIO * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; // Instruct the server to load the coolest spare barrel into the weapon and // store the removed barrel with the former weapon temperature. The server diff --git a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf index 0bb240533c..d2a499fb94 100644 --- a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf +++ b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Calculate cooldown of all the stored spare barrels. @@ -13,12 +14,13 @@ * * Public: No */ -// #define DEBUG_MODE_FULL -#include "script_component.hpp" private _pairs = []; TRACE_1("updateSpareBarrelsTemperaturesThread1",GVAR(storedSpareBarrels)); -[GVAR(storedSpareBarrels), {_pairs pushBack [_key, _value];}] call CBA_fnc_hashEachPair; +[GVAR(storedSpareBarrels), { + //IGNORE_PRIVATE_WARNING ["_key", "_value"]; + _pairs pushBack [_key, _value]; +}] call CBA_fnc_hashEachPair; TRACE_1("updateSpareBarrelsTemperaturesThread2",_pairs); { _x params ["_barrelMagazineID","_value"]; diff --git a/addons/overheating/functions/fnc_updateTemperature.sqf b/addons/overheating/functions/fnc_updateTemperature.sqf index 51b4b13ae3..475f0454f9 100644 --- a/addons/overheating/functions/fnc_updateTemperature.sqf +++ b/addons/overheating/functions/fnc_updateTemperature.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Update temperature of a weapon. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon", "_heatIncrement"]; TRACE_3("params",_unit,_weapon,_heatIncrement); @@ -27,7 +27,7 @@ private _timeVarName = format [QGVAR(%1_time), _weapon]; private _temperature = _unit getVariable [_tempVarName, 0]; private _lastTime = _unit getVariable [_timeVarName, 0]; -private _barrelMass = 0.50 * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; +private _barrelMass = METAL_MASS_RATIO * (getNumber (configFile >> "CfgWeapons" >> _weapon >> "WeaponSlotsInfo" >> "mass") / 22.0) max 1.0; // Calculate cooling _temperature = [_temperature, _barrelMass, CBA_missionTime - _lastTime] call FUNC(calculateCooling); diff --git a/addons/overheating/functions/fnc_updateTemperatureThread.sqf b/addons/overheating/functions/fnc_updateTemperatureThread.sqf index 1d1574b1ed..03f2bee53f 100644 --- a/addons/overheating/functions/fnc_updateTemperatureThread.sqf +++ b/addons/overheating/functions/fnc_updateTemperatureThread.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Update cooldown calculation of all player weapons at regular intervals. @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - private _currentWeapon = currentWeapon ACE_player; if ((_currentWeapon != "") && {_currentWeapon == primaryWeapon ACE_player || {_currentWeapon == handgunWeapon ACE_player}}) then { [ACE_player, _currentWeapon, 0] call FUNC(updateTemperature); diff --git a/addons/overheating/script_component.hpp b/addons/overheating/script_component.hpp index 6d2db895aa..d7dde59da2 100644 --- a/addons/overheating/script_component.hpp +++ b/addons/overheating/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_OVERHEATING @@ -18,6 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" #define TEMP_TOLERANCE 50 +#define METAL_MASS_RATIO 0.55 #ifdef DEBUG_MODE_FULL #define TRACE_PROJECTILE_INFO(BULLET) _vdir = vectorNormalized velocity BULLET; _dir = (_vdir select 0) atan2 (_vdir select 1); _up = asin (_vdir select 2); _mv = vectorMagnitude velocity BULLET; TRACE_3("adjusted projectile",_dir,_up,_mv); diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index 822e84f044..d54a9250d5 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 @@ -12,6 +20,10 @@ Szöveges értesítés kijelzése a fegyver elakadásakor Mostrar texto quando trava acontecer Visualizza testo in caso di inceppamento + 弾詰りを文章で表示 + 탄걸림의 경우 화면에 표시 + 在卡弹时显示提示讯息 + 在卡彈時顯示提示訊息 Display a notification whenever your weapon gets jammed @@ -24,6 +36,10 @@ Egy szöveges értesítés jelenik meg, amikor a fegyver megakad Mostra uma notificação quando sua arma sofre um travamento. Visualizza una notifica in caso la tua arma si inceppasse + 持っている武器が弾詰りをすると、通知を表示します + 총알이 무기에 걸릴경우 화면에 알림을 띄웁니다 + 当武器卡弹时显示提示讯息 + 當武器卡彈時顯示提示訊息 Overheating Particle Effects @@ -35,6 +51,10 @@ Částicové efekty přehřívání Efeito de parícula de superaquecimento Эффект частиц при перегреве + 過熱の視覚効果 + 과열 입자 효과 + 枪管过热特效 + 槍管過熱特效 Show particle effects when weapon overheats @@ -46,6 +66,10 @@ Mostra efeitos de párticula quando a arma superaquece Показывать эффект частиц, когда оружие перегревается Zobrazit částicové efekty když se zbraň přehřije + 武器を過熱すると視覚表現を表示します + 무기가 과열되면 입자 효과를 보여줍니다 + 显示枪管过热特效 + 顯示槍管過熱特效 Overheating Particle Effects for everyone @@ -57,6 +81,10 @@ Částicové efekty přehřívání pro všechny Efeito de partícula de superaquecimento para todos Эффект частиц при перегреве для всех + 過熱の視覚表現を全員に与えます + 모두에게 과열 입자 효과 적용 + 显示其他玩家的枪管过热特效 + 顯示其他玩家的槍管過熱特效 Show particle effects when other players weapon overheats @@ -68,6 +96,10 @@ Mostra efeito de partículas quando a arma de outros jogadores superaquece Показывать эффект частиц, когда оружие других игроков перегревается Zobrazit částicové efekty když se zbraň přehřije jinému hráči + 他のプレイヤの過熱の視覚表現を表示します + 모든 인원이 무기가 과열될시 입자 효과가 나타납니다. + 当其他玩家的武器过热时显示特效 + 當其他玩家的武器過熱時顯示特效 Overheating Dispersion @@ -79,6 +111,10 @@ Disperção de superaquecimento Разброс при перегреве Důsledky přehřátí zbraně + 過熱による精度の低下 + 과열 명중률 저하 + 过热散射 + 過熱散射 Overheated weapons will be less accurate and have decreased muzzle velocity. Applys for all players. @@ -90,6 +126,10 @@ Armas superaquecidas irão ser menos precisas e ter velocidade de disparo reduzidas. Aplica a todos os jogadores. Перегретое оружие будет менее точным, а дульная скорость будет снижена. Применяется ко всем игрокам. 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 @@ -101,6 +141,10 @@ Uvolnit zbraň při přebití Desemperrar arma no recarregamento Исправлять клин при перезарядке + 再装填による弾詰りの解消 + 재장전시 탄걸림 해결 + 重装弹匣以解决卡弹 + 重裝彈匣以解決卡彈 Reloading clears a weapon jam. @@ -112,6 +156,10 @@ Přebití uvolní zaseknutou zbraň. Recarregar desemperra arma. Перезарядка устраняет заклинивание оружия. + 再装填により、弾詰りを除去します。 + 탄걸림이 재장전시 해결됩니다. + 利用重装弹匣来解决卡弹 + 利用重裝彈匣來解決卡彈 Chance of unjam failing @@ -123,6 +171,10 @@ Šance, že uvolnění zbraně selže Chance de falha de desemperramento Шанс неудачи при устранении клина + 弾詰りの除去を失敗する可能性 + 탄걸림 해결 시도 실패확률 + 解决卡弹失败机率 + 解決卡彈失敗機率 Probability that an unjam action might fail, requiring to be repeated. @@ -134,6 +186,10 @@ Probabilidade que uma ação de desemperramento falhe, tendo que ser repetida Вертоятность того, что устранение заклинивания не сработает, и его придется повторить. Pravděpodobnost, že uvolnění zbraně selže, je proto nutné tuto akci opakovat. + 弾詰りの除去を失敗する可能性が生まれ、もう一度動作を行う必要があります。 + 탄걸림 해결 시도시 실패할 확률이 있습니다. 이는 다시 탄걸림 해결을 시도해야함을 의미합니다. + 清除卡弹时有可能会失败,需要反覆进行清枪。 + 清除卡彈時有可能會失敗,需要反覆進行清槍。 Spare barrel @@ -146,6 +202,10 @@ Tartalék cső Cano Reserva Canna di ricambio + 予備銃身 + 예비 총열 + 备用枪管 + 備用槍管 Use to swap barrel. @@ -158,6 +218,10 @@ Használd a cső kicseréléséhez. Use para trocar o cano/estriamento. Usata per cambiare la canna. + 予身の交換に使用します。 + 총열을 바꿀때 사용합니다. + 用来更换枪管 + 用來更換槍管 Weapon jammed! @@ -170,6 +234,10 @@ Megakadt a fegyver! Arma travada! Arma inceppata! + 武器が詰まった! + 탄걸림! + 武器卡弹! + 武器卡彈! Clear jam @@ -182,6 +250,10 @@ Akadás elhárítása Destravar arma Ripulisci l'arma + 弾詰りを除去する + 탄걸림 해결 + 清除卡弹 + 清除卡彈 Jam cleared @@ -194,6 +266,10 @@ Akadás elhárítva Arma destravada Arma pronta al fuoco + 弾詰りが除去されました + 탄걸림 해결됨 + 卡弹已清除 + 卡彈已清除 Jam failed to clear @@ -205,6 +281,10 @@ Zbrań se nepodařilo uvolnit Falha no desemperramento Не удалось исправить клин + 弾詰りの除去に失敗しました + 탄걸림 해결 실패 + 卡弹未能清除 + 卡彈未能清除 Swap barrel @@ -217,10 +297,14 @@ Cső cserélése Substituir cano Sostiuisci la canna + 銃身を交換 + 총열 교체 + 换枪管 + 換槍管 Swapping barrel... - Lauf wird gewechselt... + Lauf wird gewechselt ... Cambiando el cañón... Wymienianie lufy... Měním hlaveň... @@ -228,7 +312,11 @@ Смена ствола... Cső kicserélése folyamatban... Substituindo cano... - Sto sostituendo la canna... + Sostituendo la canna... + 銃身を交換しています・・・ + 총열 교체중... + 换枪管中... + 換槍管中... Swapped barrel @@ -241,6 +329,10 @@ Cső kicserélve Cano substituído Canna sostituita + 銃身を交換しました + 교체된 총열 + 完成换枪管 + 完成換槍管 Check weapon temperature @@ -253,6 +345,10 @@ Conferir temperatura da arma Controlla la temperatura della canna Проверить температуру оружия + 武器の温度を測る + 무기 온도 확인 + 检查枪管温度 + 檢查槍管溫度 Check weapon temperature @@ -265,18 +361,26 @@ Проверить температуру оружия Conferir temperatura Controlla la temperatura della canna + 武器の温度を測る + 무기 온도 확인 + 检查枪管温度 + 檢查槍管溫度 Checking temperature... - Prüfe Temperatur... + Prüfe Temperatur ... Verificando temperatura... Sprawdzanie temperatury... Vérification de la température... Hőmérséklet ellenőrzése... Zjišťuju teplotu... Conferindo temperatura... - Sto controllando la temperatura... + Controllando la temperatura... Проверка температуры... + 温度を測っています・・・ + 무기 온도 확인중... + 检查枪管温度中... + 檢查槍管溫度中... Check spare barrels temperatures @@ -284,6 +388,13 @@ Vérifier la température des canons de rechange Проверить температуру запасных стволов Zkontrolovat teplotu náhradní hlavně + 予備銃身の温度を測る + Sprawdź temperaturę zapasowych luf + Temperatur der Wechselläufe prüfen + 총열 온도 확인 + Controlla la temperatura della canna di ricambio + 检查备用枪管温度 + 檢查備用槍管溫度 Checking spare barrels temperatures... @@ -291,6 +402,13 @@ 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 ... + 총열 온도 확인중... + Controllando la temperatura della canna di ricambio... + 检查枪管温度中... + 檢查槍管溫度中... Temperature @@ -303,6 +421,10 @@ Temperatura Temperatura Температура + 温度 + 온도 + 温度 + 溫度 Cool Spare Barrel/s @@ -310,6 +432,13 @@ Canon(s) de rechange froid Прохладные Studená náhrandí hlaveň + 予備銃身は冷たい + Zimne zapasowe lufy + Kalte Wechselläufe + 차가운 예비 총열 + Canna/e di Ricambio Fredda + 备用枪管温度正常 + 備用槍管溫度正常 Warm Spare Barrel/s @@ -317,6 +446,13 @@ Canon(s) de rechange tiède Теплые Teplá náhrandí hlaveň + 予備銃身は温かい + Ciepłe zapasowe lufy + Warme Wechselläufe + 따뜻한 예비 총열 + Canna/e di Ricambio Calda + 备用枪管温度偏温 + 備用槍管溫度偏溫 Hot Spare Barrel/s @@ -324,6 +460,13 @@ Canon(s) de rechange chaud Горячие Horká náhrandí hlaveň + 予備銃身は熱い + Gorące zapasowe lufy + Heiße Wechselläufe + 뜨거운 예비 총열 + Canna/e di Ricambio Molto Calda + 备用枪管温度偏热 + 備用槍管溫度偏熱 Very Hot Spare Barrel/s @@ -331,6 +474,13 @@ Canon(s) de rechange très chaud Очень горячие Velmi horká náhrandí hlaveň + 予備銃身はとても熱い + Bardzo gorące zapasowe lufy + Sehr heiße Wechselläufe + 매우 뜨거운 예비 총열 + Canna/e di Ricambio Estremamente Calda + 备用枪管温度过热 + 備用槍管溫度過熱 Extremely Hot Spare Barrel/s @@ -338,21 +488,41 @@ Canon(s) de rechange extrêmement chaud Запредельно горячие Extrémně horká náhrandí hlaveň + 予備銃身は極めて熱い + Ekstremalnie gorące zapasowe lufy + Extrem heiße Wechselläufe + 엄청나게 뜨거운 예비 총열 + Canna/e di Ricambio Rovente + 备用枪管温度超级热 + 備用槍管溫度超級熱 Overheating Enabled - Überhitzen Aktiviert + Überhitzung aktiviert Activada Sobrecalentamiento Superaquecimento ativado Surchauffe activée Перегрев включен Přehřívání povoleno + 過熱を有効化 + Przegrzewanie włączone + 과열 활성화 + Surriscaldamento Abilitato + 启用过热 + 啟用過熱 Master enable for the overheating/jamming module Chave mestra para o módulo de superaquecimento/emperramento Activateur maître pour le module de surchauffe / enrayement Главный включатель для модуля перегрева/заклинивания + 過熱と弾詰まりモジュールを全て有効化します + Główny włącznik modułu przegrzewania/zacinania się broni + Hauptschalter, um die Überhitzung-/Ladehemmung-Module zu aktivieren + 과열/탄걸림 최종 활성화 + Abilitazione master per il modulo di surriscaldamento / inceppamento + 启用枪管过热/干扰模块 + 啟用槍管過熱/干擾模塊 - \ No newline at end of file + diff --git a/addons/overpressure/ACE_Arsenal_Stats.hpp b/addons/overpressure/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..906c50e8fb --- /dev/null +++ b/addons/overpressure/ACE_Arsenal_Stats.hpp @@ -0,0 +1,21 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_backblastAngle: statBase { + scope = 2; + priority = 2; + stats[] = {QGVAR(angle)}; + displayName = CSTRING(statBackblastAngle); + showText = 1; + textStatement = QUOTE(params [ARR_2('_stat', '_config')]; format [ARR_2('%1°', getNumber (_config >> _stat select 0))]); + tabs[] = {{2}, {}}; + }; + class ACE_backblastRange: statBase { + scope = 2; + priority = 1; + stats[] = {QGVAR(range)}; + displayName = CSTRING(statBackblastRange); + showText = 1; + textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _blastRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)', _blastRangeStat, (_blastRangeStat / 0.3048) toFixed 1)]); + tabs[] = {{2}, {}}; + }; +}; diff --git a/addons/overpressure/ACE_Settings.hpp b/addons/overpressure/ACE_Settings.hpp new file mode 100644 index 0000000000..58e0d3d8ac --- /dev/null +++ b/addons/overpressure/ACE_Settings.hpp @@ -0,0 +1,9 @@ +class ACE_Settings { + class GVAR(distanceCoefficient) { + displayName = CSTRING(distanceCoefficient_displayName); + description = CSTRING(distanceCoefficient_toolTip); + typeName = "SCALAR"; + value = 1; + sliderSettings[] = {-1, 10, 5, 1}; + }; +}; diff --git a/addons/overpressure/XEH_postInit.sqf b/addons/overpressure/XEH_postInit.sqf index dd74ec5c3a..02b0e71bb6 100644 --- a/addons/overpressure/XEH_postInit.sqf +++ b/addons/overpressure/XEH_postInit.sqf @@ -1,7 +1,12 @@ #include "script_component.hpp" -["ace_overpressure", FUNC(overpressureDamage)] call CBA_fnc_addEventHandler; +["ace_settingsInitialized", { + TRACE_1("settingsInit eh",GVAR(distanceCoefficient)); + if (GVAR(distanceCoefficient) <= 0) exitWith {}; -// Register fire event handler -["ace_firedPlayer", DFUNC(firedEHBB)] call CBA_fnc_addEventHandler; -["ace_firedPlayerVehicle", DFUNC(firedEHOP)] call CBA_fnc_addEventHandler; + ["ace_overpressure", LINKFUNC(overpressureDamage)] call CBA_fnc_addEventHandler; + + // Register fire event handler + ["ace_firedPlayer", LINKFUNC(firedEHBB)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(firedEHOP)] call CBA_fnc_addEventHandler; +}] call CBA_fnc_addEventHandler; diff --git a/addons/overpressure/XEH_preInit.sqf b/addons/overpressure/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/overpressure/XEH_preInit.sqf +++ b/addons/overpressure/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/overpressure/config.cpp b/addons/overpressure/config.cpp index 0aa455de7d..3815cc831f 100644 --- a/addons/overpressure/config.cpp +++ b/addons/overpressure/config.cpp @@ -14,9 +14,7 @@ class CfgPatches { }; }; +#include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" - -class ACE_newEvents { - overpressure = "ace_overpressure"; -}; +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf b/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf index 4b447b5012..7e984f993c 100644 --- a/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf +++ b/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: joko // Jonas * Cache the shot data for a given weapon/mag/ammo combination. @@ -19,7 +20,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_weapon", "_ammo", "_magazine"]; TRACE_3("Parameter",_weapon,_magazine,_ammo); @@ -46,7 +46,7 @@ TRACE_1("ConfigPath",_config); // get the Variables out of the Configes and create a array with then private _return = [ (getNumber (_config >> QGVAR(angle))), - (getNumber (_config >> QGVAR(range))), + (getNumber (_config >> QGVAR(range))) * GVAR(distanceCoefficient), (getNumber (_config >> QGVAR(damage))) ]; diff --git a/addons/overpressure/functions/fnc_firedEHBB.sqf b/addons/overpressure/functions/fnc_firedEHBB.sqf index a9a37a0560..3c65ca813c 100644 --- a/addons/overpressure/functions/fnc_firedEHBB.sqf +++ b/addons/overpressure/functions/fnc_firedEHBB.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: joko // Jonas * Handle fire of local launchers. Called from the unified fired EH only for the local player. @@ -13,7 +14,6 @@ * * 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); @@ -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_firedEHOP.sqf b/addons/overpressure/functions/fnc_firedEHOP.sqf index 0c02526928..5871fae9b8 100644 --- a/addons/overpressure/functions/fnc_firedEHOP.sqf +++ b/addons/overpressure/functions/fnc_firedEHOP.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: joko // Jonas * Handle fire of Vehicle Weapons. Called from the unified fired EH only for the local player vehicle. @@ -13,7 +14,6 @@ * * 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); diff --git a/addons/overpressure/functions/fnc_getDistance.sqf b/addons/overpressure/functions/fnc_getDistance.sqf index febb4ea747..3e36a3ea78 100644 --- a/addons/overpressure/functions/fnc_getDistance.sqf +++ b/addons/overpressure/functions/fnc_getDistance.sqf @@ -1,11 +1,12 @@ +#include "script_component.hpp" /* * Author: commy2 and esteldunedain * Calculate the distance to the first intersection of a line * * Arguments: - * 0: Pos ASL of origin (ARRAY> + * 0: Pos ASL of origin * 1: Direction - * 2: Max distance to search + * 2: Max distance to search * 3: Shooter * * Return Value: @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_posASL", "_direction", "_maxDistance", "_shooter"]; TRACE_4("params",_posASL,_direction,_maxDistance, _shooter); @@ -38,7 +38,7 @@ private _distance = 999; if (isNull _intersectObject) then { //Terrain: // Calculate the angle between the terrain and the back blast direction - _angle = 90 - acos (- (_surfaceNormal vectorDotProduct _direction)); + private _angle = 90 - acos (- (_surfaceNormal vectorDotProduct _direction)); TRACE_3("Terrain Intersect",_surfaceNormal,_direction,_angle); // Angles is below 25deg, no backblast at all if (_angle < 25) exitWith {_distance = 999}; diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index 75286a968b..53b02fe10d 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 and esteldunedain * Calculate and apply backblast damage to potentially affected local units @@ -19,7 +20,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_firer", "_posASL", "_direction", "_weapon", "_magazine", "_ammo"]; @@ -51,6 +51,7 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); private _beta = sqrt (1 - _angle / _overpressureAngle); private _damage = _alpha * _beta * _overpressureDamage; + TRACE_1("",_damage); // If the target is the ACE_player if (_x == ACE_player) then {[_damage * 100] call BIS_fnc_bloodEffect}; @@ -58,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/script_component.hpp b/addons/overpressure/script_component.hpp index c9e5ff587d..c0fcb82dd2 100644 --- a/addons/overpressure/script_component.hpp +++ b/addons/overpressure/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_OVERPRESSURE diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml new file mode 100644 index 0000000000..1d64ebc0d3 --- /dev/null +++ b/addons/overpressure/stringtable.xml @@ -0,0 +1,41 @@ + + + + + Overpressure Distance Coefficient + Überdruckentfernungskoeffizient + 過圧の距離係数 + 초과압력 거리 계수 + Mnożnik dystansu nadciśnienia + Coéfficient de distance pour la surpression + Coefficente Distanza Sovrapressione + 高压影响距离系数 + 高壓影響距離係數 + + + 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] + Échelonne les effets de la surpression [Par défaut : 1] + Scala l'effetto di sovrapressione [Predefinito: 1] + 高压影响的范围 [预设: 1] + 高壓影響的範圍 [預設: 1] + + + Backblast range + 後方噴射の範囲 + 向后喷射的范围 + 後方尾焰的範圍 + Raggio della fiammata [lanciarazzi] + + + Backblast angle + 後方噴射の角度 + 向后喷射的角度 + 後方尾焰的角度 + Angolo della fiammata [lanciarazzi] + + + 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..5f1b750377 100644 --- a/addons/parachute/CfgVehicles.hpp +++ b/addons/parachute/CfgVehicles.hpp @@ -9,23 +9,17 @@ 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; + icon = QPATHTOF(UI\cut_ca.paa); + }; + }; MACRO_HASRESERVE }; class ParachuteWest: ParachuteBase { @@ -43,13 +37,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 +92,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..06e02f0757 100644 --- a/addons/parachute/XEH_postInit.sqf +++ b/addons/parachute/XEH_postInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Initialises the parachute system. @@ -13,31 +14,27 @@ * * Public: No */ -#include "script_component.hpp" 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 bffa5623b8..5a10c0bd83 100644 --- a/addons/parachute/XEH_preInit.sqf +++ b/addons/parachute/XEH_preInit.sqf @@ -1,22 +1,21 @@ -/* - * Author: Garth 'L-H' de Wet - * Initialises the parachute system. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * None - * - * Public: No - */ #include "script_component.hpp" +// Author: Garth 'L-H' de Wet +// Initialises the parachute system. ADDON = false; +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 94137ed67c..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])) \ No newline at end of file diff --git a/addons/parachute/functions/fnc_cutParachute.sqf b/addons/parachute/functions/fnc_cutParachute.sqf index f7aa86991b..286673af41 100644 --- a/addons/parachute/functions/fnc_cutParachute.sqf +++ b/addons/parachute/functions/fnc_cutParachute.sqf @@ -1,21 +1,19 @@ +#include "script_component.hpp" /* - * 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 + * 0: Object * * Return Value: - * Nothing + * 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 b27849a0c8..280765d8a2 100644 --- a/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf +++ b/addons/parachute/functions/fnc_handleInfoDisplayChanged.sqf @@ -1,21 +1,24 @@ +#include "script_component.hpp" /* * Author: commy2 * Hides the height and velocity display while freefalling or parachuting on higher difficulties. * * Arguments: - * Stuff from infoDisplayChanged eventhandler. + * Stuff from infoDisplayChanged eventhandler. * * Return Value: * None * + * Example: + * [?] call ACE_parachute_fnc_handleInfoDisplayChanged + * * Public: No */ -#include "script_component.hpp" 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..3df8d6607e --- /dev/null +++ b/addons/parachute/functions/fnc_handleReserve.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..280ee286b4 100644 --- a/addons/parachute/functions/fnc_hideAltimeter.sqf +++ b/addons/parachute/functions/fnc_hideAltimeter.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Removes the altimeter from the screen. @@ -13,6 +14,5 @@ * * Public: No */ -#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..d4aa11f883 100644 --- a/addons/parachute/functions/fnc_showAltimeter.sqf +++ b/addons/parachute/functions/fnc_showAltimeter.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet * Displays the altimeter on screen. @@ -13,38 +14,36 @@ * * Public: Yes */ -#include "script_component.hpp" 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 8980a8ff82..0000000000 --- a/addons/parachute/functions/fnc_storeParachute.sqf +++ /dev/null @@ -1,30 +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: - * None - * - * 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/script_component.hpp b/addons/parachute/script_component.hpp index cb341ba5ce..e43f330e49 100644 --- a/addons/parachute/script_component.hpp +++ b/addons/parachute/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_PARACHUTE diff --git a/addons/parachute/stringtable.xml b/addons/parachute/stringtable.xml index 880cc55e5f..293506b4d5 100644 --- a/addons/parachute/stringtable.xml +++ b/addons/parachute/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Высотомер Altimetro Altímetro + 高度計 + 고도계 + 高度计 + 高度計 Altimeter Watch @@ -24,6 +28,10 @@ Часы с высотомером Controlla l'altimetro Relógio Altímetro + 時計型高度計 + 고도계 시계 + 高度计手表 + 高度計手錶 Used to show height, descent rate and the time. @@ -36,6 +44,10 @@ Используется для определения высоты, скорости снижения и времени. Usato per mostrare l'altitudine, la velocità di discesa e l'ora. Usado para mostrar altura, taxa de descida e o tempo. + 高度や降下率、時間を見るのに使います。 + 높이와, 하강속도 그리고 시간을 보여줍니다. + 用于显示高度,下降率和时间。 + 用於顯示高度,下降率和時間 Non-Steerable Parachute @@ -48,6 +60,10 @@ Неуправляемый парашют Paracadute non manovrabile Para-querdas não controlável + 非操作型パラシュート + 비-조종 낙하산 + 非可操控降落伞 + 非可操控降落傘 Cut Parachute @@ -60,6 +76,10 @@ Odžíznout padák Cortar paracaídas Taglia Paracadute + パラシュートを切断 + 낙하산 자르기 + 剪断降落伞 + 剪斷降落傘 Reserve Parachute @@ -72,6 +92,26 @@ Záložní padák Paracaídas de reserva Paracadute di Riserva + 予備パラシュート + 예비 낙하산 + 备用降落伞 + 備用降落傘 + + + 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. + 在自由落體時或開傘下隱藏自由落體高度計 + 在自由落体时或开伞下隐藏自由落体高度计。 - \ No newline at end of file + diff --git a/addons/particles/CfgAmmo.hpp b/addons/particles/CfgAmmo.hpp deleted file mode 100644 index 6065a0b818..0000000000 --- a/addons/particles/CfgAmmo.hpp +++ /dev/null @@ -1,75 +0,0 @@ -class CfgAmmo { - class GrenadeHand; - - // - Smoke hand grenades -------------------------------------------------- - class SmokeShell: GrenadeHand { - smokeColor[] = {1, 1, 1, 1}; - timeToLive = 90; - }; - class SmokeShellRed: SmokeShell { - smokeColor[] = SMOKE_COLOR_RED; - timeToLive = 60; - }; - class SmokeShellGreen: SmokeShell { - smokeColor[] = SMOKE_COLOR_GREEN; - timeToLive = 60; - }; - class SmokeShellYellow: SmokeShell { - smokeColor[] = SMOKE_COLOR_YELLOW; - timeToLive = 60; - }; - class SmokeShellPurple: SmokeShell { - smokeColor[] = SMOKE_COLOR_PURPLE; - timeToLive = 60; - }; - class SmokeShellBlue: SmokeShell { - smokeColor[] = SMOKE_COLOR_BLUE; - timeToLive = 60; - }; - class SmokeShellOrange: SmokeShell { - smokeColor[] = SMOKE_COLOR_ORANGE; - timeToLive = 60; - }; - - // - 40mm smoke grenades -------------------------------------------------- - class G_40mm_Smoke: SmokeShell { - smokeColor[] = {1, 1, 1, 1}; - timeToLive = 40; - }; - class G_40mm_SmokeRed: G_40mm_Smoke { - smokeColor[] = SMOKE_COLOR_RED; - timeToLive = 40; - }; - class G_40mm_SmokeGreen: G_40mm_Smoke { - smokeColor[] = SMOKE_COLOR_GREEN; - timeToLive = 40; - }; - class G_40mm_SmokeYellow: G_40mm_Smoke { - smokeColor[] = SMOKE_COLOR_YELLOW; - timeToLive = 40; - }; - class G_40mm_SmokePurple: G_40mm_Smoke { - smokeColor[] = SMOKE_COLOR_PURPLE; - timeToLive = 40; - }; - class G_40mm_SmokeBlue: G_40mm_Smoke { - smokeColor[] = SMOKE_COLOR_BLUE; - timeToLive = 40; - }; - class G_40mm_SmokeOrange: G_40mm_Smoke { - smokeColor[] = SMOKE_COLOR_ORANGE; - timeToLive = 40; - }; - - // - Artillery smoke submunition ------------------------------------------ - class SmokeShellArty: SmokeShell { - explosionTime = 0; - effectsSmoke = "ACE_ArtillerySmoke"; - }; - - // - 120mm/155mm artillery smoke ------------------------------------------ - class SubmunitionBase; - class Smoke_120mm_AMOS_White: SubmunitionBase { - submunitionConeAngle = 10; - }; -}; diff --git a/addons/particles/script_component.hpp b/addons/particles/script_component.hpp deleted file mode 100644 index 6d7065a31d..0000000000 --- a/addons/particles/script_component.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#define COMPONENT particles -#include "\z\ace\addons\main\script_mod.hpp" - -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS -// #define ENABLE_PERFORMANCE_COUNTERS - -#ifdef DEBUG_ENABLED_PARTICLES - #define DEBUG_MODE_FULL -#endif - -#ifdef DEBUG_SETTINGS_PARTICLES - #define DEBUG_SETTINGS DEBUG_SETTINGS_PARTICLES -#endif - -#include "\z\ace\addons\main\script_macros.hpp" - -#define SMOKE_COLOR_RED {0.9528, 0.0438, 0.0410, 0.8} -#define SMOKE_COLOR_GREEN {0.0328, 0.1626, 0.1023, 0.8} -#define SMOKE_COLOR_YELLOW {0.9610, 0.4505, 0.0109, 0.8} -#define SMOKE_COLOR_PURPLE {0.4622, 0.0578, 0.3154, 0.8} -#define SMOKE_COLOR_BLUE {0.0355, 0.1863, 1.0000, 0.8} -#define SMOKE_COLOR_ORANGE {0.9132, 0.1763, 0.0070, 0.8} - -#define EFFECT_HANDGRENADE(color) class SmokeShell##color##Effect: SmokeShellWhiteEffect { \ - class SmokeShell: SmokeShell { \ - type = "ACE_SmokeBaseMedium"; \ - }; \ -} -#define EFFECT_40MM(color) class ACE_40mmSmokeShell##color##Effect: ACE_40mmSmokeShellWhiteEffect { \ - class SmokeShellUW { \ - simulation = "particles"; \ - type = QUOTE(SmokeShell##color##UW); \ - position[] = {0, 0, 0}; \ - intensity = 1; \ - interval = 1; \ - }; \ - class SmokeShell2UW { \ - simulation = "particles"; \ - type = QUOTE(SmokeShell##color##2UW); \ - position[] = {0, 0, 0}; \ - intensity = 1; \ - interval = 1; \ - }; \ -} -#define MERGE(var1,var2) ##var1####var2 -#define EFFECT_AFTER_WATER(color) class ACE_SmokeAfterWater##color##: ACE_SmokeAfterWaterWhite { \ - class SmokeAfterWater: SmokeAfterWater { \ - type = QUOTE(MERGE(ACE_SmokeAfterWater,color)); \ - }; \ -} - -#define CLOUDLET_UNDERWATER(color) class SmokeShell##color##UW; \ -class SmokeShell##color##2UW: SmokeShell##color##UW { \ - postEffects = QUOTE(MERGE(ACE_SmokeAfterWater,color)); \ -} 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..e2d4c40d5c --- /dev/null +++ b/addons/pylons/ACE_Settings.hpp @@ -0,0 +1,17 @@ +class ACE_Settings { + class GVAR(rearmNewPylons) { + movedToSQF = 1; + }; + class GVAR(searchDistance) { + movedToSQF = 1; + }; + class GVAR(timePerPylon) { + movedToSQF = 1; + }; + class GVAR(requireEngineer) { + movedToSQF = 1; + }; + class GVAR(requireToolkit) { + movedToSQF = 1; + }; +}; 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..6a8f781469 --- /dev/null +++ b/addons/pylons/XEH_postInit.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" + +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)}, + { + if (!GVAR(enabledFromAmmoTrucks)) exitWith {false}; + + 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", "_weaponToRemove"]; + TRACE_5("setPylonLoadOutEvent",_aircraft,_pylonIndex,_pylon,_turret,_weaponToRemove); + _aircraft setPylonLoadOut [_pylonIndex, _pylon, false, _turret]; + if (_weaponToRemove != "") then { + { + if (_aircraft turretLocal _x) then { + TRACE_3("removing",_aircraft,_x,_weaponToRemove); + _aircraft removeWeaponTurret [_weaponToRemove, _x]; + }; + } forEach [[-1], [0]]; + }; +}] 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", {call FUNC(handleDisconnect)}]; +}; diff --git a/addons/pylons/XEH_preInit.sqf b/addons/pylons/XEH_preInit.sqf new file mode 100644 index 0000000000..9361d05015 --- /dev/null +++ b/addons/pylons/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" + +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/addons/pylons/config.cpp b/addons/pylons/config.cpp new file mode 100644 index 0000000000..011167fd22 --- /dev/null +++ b/addons/pylons/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interact_menu", "ace_zeus"}; + author = ECSTRING(common,ACETeam); + authors[] = {"654wak654"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#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..546d3e6766 --- /dev/null +++ b/addons/pylons/functions/fnc_canConfigurePylons.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..81313ce61e --- /dev/null +++ b/addons/pylons/functions/fnc_configurePylons.sqf @@ -0,0 +1,77 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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; + TRACE_2("",_currentPylon,_pylonIndex); + + // Remove the weapon of current pylon from aircraft IF weapon is only on this pylon + private _weaponToRemove = ""; + 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 { + TRACE_2("Removing unused weapon",_pylonWeapon,_allPylonWeapons); + _weaponToRemove = _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, _weaponToRemove] + ] 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..9ad646eb31 --- /dev/null +++ b/addons/pylons/functions/fnc_handleDisconnect.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Cleans up pylons on client disconnect. + * + * Arguments: + * 0: Player + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_handleDisconnect + * + * Public: No + */ + +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..5603ed8d94 --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonApply.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Starts the pylon configuration. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonApply + * + * Public: No + */ + +// 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..c0f51e634a --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonClose.sqf @@ -0,0 +1,20 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Handles the closing of the dialog. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonClose + * + * Public: No + */ + +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..eaf16cd99a --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonDelete.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Deletes the selected pylon configuration from profileNamespace. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonDelete + * + * Public: No + */ + +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..af3183073a --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonLoad.sqf @@ -0,0 +1,58 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Loads selected pylon configuration from either config or profileNamespace. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonLoad + * + * Public: No + */ + +[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..8f30ad1a58 --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonSave.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Saves the selected pylon configuration to profileNamespace. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_pylons_fnc_onButtonSave + * + * Public: No + */ + +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..e6828bab99 --- /dev/null +++ b/addons/pylons/functions/fnc_onButtonTurret.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..aa71c65099 --- /dev/null +++ b/addons/pylons/functions/fnc_onComboSelChange.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..70344baa80 --- /dev/null +++ b/addons/pylons/functions/fnc_onNameChange.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..949668ceb8 --- /dev/null +++ b/addons/pylons/functions/fnc_onPylonMirror.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..2ce438e0ab --- /dev/null +++ b/addons/pylons/functions/fnc_showDialog.sqf @@ -0,0 +1,166 @@ +#include "script_component.hpp" +/* +* 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 +*/ + +params ["_aircraft", ["_isCurator", false]]; + +if !(typeOf _aircraft in GVAR(aircraftWithPylons)) exitWith { + if (_isCurator) then { + [LSTRING(AircraftDoesntHavePylons)] call EFUNC(zeus,showMessage); + }; +}; + +if (_isCurator && {!GVAR(enabledForZeus)}) exitWith { + [LSTRING(ConfigurePylonsDisabledForZeus)] call EFUNC(zeus,showMessage); +}; + +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)} + }, { + TRACE_3("disconnect/far",GVAR(currentAircraft),ace_player distance GVAR(currentAircraft),GVAR(currentAircraft) getVariable QGVAR(currentUser)); + if ((ace_player distanceSqr GVAR(currentAircraft)) > GVAR(searchDistanceSqr)) then { + [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/initSettings.sqf b/addons/pylons/initSettings.sqf new file mode 100644 index 0000000000..57a2a79efb --- /dev/null +++ b/addons/pylons/initSettings.sqf @@ -0,0 +1,66 @@ +[ + QGVAR(enabledFromAmmoTrucks), + "CHECKBOX", + [LSTRING(EnabledFromAmmoTrucks), LSTRING(EnabledFromAmmoTrucks_description)], + LSTRING(Category_Pylons), + [true], + true +] call CBA_Settings_fnc_init; + +[ + QGVAR(enabledForZeus), + "CHECKBOX", + [LSTRING(EnabledForZeus), LSTRING(EnabledForZeus_description)], + LSTRING(Category_Pylons), + [true], + true +] call CBA_Settings_fnc_init; + +[ + QGVAR(rearmNewPylons), + "CHECKBOX", + [LSTRING(RearmNewPylons), LSTRING(RearmNewPylons_description)], + LSTRING(Category_Pylons), + [false], + true +] call CBA_Settings_fnc_init; + +[ + QGVAR(requireEngineer), + "CHECKBOX", + [LSTRING(RequireEngineer), LSTRING(RequireEngineer_description)], + LSTRING(Category_Pylons), + [false], + true +] call CBA_Settings_fnc_init; + +[ + QGVAR(requireToolkit), + "CHECKBOX", + [LSTRING(RequireToolkit), LSTRING(RequireToolkit_description)], + LSTRING(Category_Pylons), + [true], + true +] call CBA_Settings_fnc_init; + +[ + QGVAR(searchDistance), + "SLIDER", + [LSTRING(SearchDistance), LSTRING(SearchDistance_description)], + LSTRING(Category_Pylons), + [5, 50, 15, 0], + true, + { + params ["_searchDistance"]; + GVAR(searchDistanceSqr) = _searchDistance ^ 2; + } +] call CBA_Settings_fnc_init; + +[ + QGVAR(timePerPylon), + "SLIDER", + [LSTRING(TimePerPylon), LSTRING(TimePerPylon_description)], + LSTRING(Category_Pylons), + [1, 10, 5, 0], + true +] call CBA_Settings_fnc_init; 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..1d7f6335d8 --- /dev/null +++ b/addons/pylons/stringtable.xml @@ -0,0 +1,227 @@ + + + + + AIRCRAFT LOADOUT + 航空機の兵装 + ARMAMENTO DELL'AEREO + 飛機武裝配置 + 飞机武器配置 + 항공기 무장 + AUSRÜSTUNG DES FLUGGERÄTS + + + Loadouts for %1 + %1の兵装 + Armamenti per %1 + %1用的武裝配置 + %1用的武器配置 + %1 무장 + Ausrüstung für %1 + + + Configure Pylons + パイロン設定 + Configura Piloni + 定義派龍架 + 设定导弹挂架 + 파일런 설정 + Konfiguriere Außenlaststationen + + + ACE Pylons + ACE パイロン + ACE Piloni + ACE 派龍架 + ACE 导弹挂架 + ACE 파일런 + ACE 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 for Zeus + 启用宙斯导弹挂架菜单 + 啟用派龍架選單給宙斯 + Abilita Menù Piloni da Zeus + Zeus でパイロン メニューを有効化 + + + Enables use of the zeus module. + 允许启用宙斯模组 + 允啟使用宙斯模塊 + Abilita l'uso dal modulo di Zeus + Zeus モジュールでパイロン メニューを利用できます。 + + + Enable Pylons Menu from Ammo Trucks + 启用弹药车导弹挂架菜单 + 啟用從彈藥卡車使用派龍架選單 + Abilita Menù Piloni da mezzi rifornimento munizioni + 弾薬トラックからパイロン メニューを有効化 + + + Enables use of pylons menu from ammo trucks. + 允许在弹药车上启用导弹挂架菜单 + 允許從彈藥卡車使用派龍架選單 + Abilita l'uso del Menù Piloni da mezzi rifornimento munizioni + 弾薬給弾トラックからパイロン メニューを利用できます。 + + + This aircraft doesn't have pylons + 这架飞机没有导弹挂架 + 這架飛機沒有派龍架 + Questo aereo non ha piloni + 航空機にパイロンがありません + + + Configure pylons module is disabled for zeus + 宙斯模组的导弹挂架已禁用 + 宙斯模塊的派龍架設定已被禁用 + Il modulo per configurare i piloni da Zeus è disabilitato + Zeus のパイロン モジュールを無効化 + + + 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/$PBOPREFIX$ b/addons/quickmount/$PBOPREFIX$ new file mode 100644 index 0000000000..2251bc0b6e --- /dev/null +++ b/addons/quickmount/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\quickmount diff --git a/addons/quickmount/ACE_Settings.hpp b/addons/quickmount/ACE_Settings.hpp new file mode 100644 index 0000000000..b4e07be4b4 --- /dev/null +++ b/addons/quickmount/ACE_Settings.hpp @@ -0,0 +1,41 @@ +class ACE_Settings { + class GVAR(enabled) { + value = 0; + typeName = "BOOL"; + category = CSTRING(Category); + displayName = ECSTRING(common,Enabled); + description = CSTRING(KeybindDescription); + isClientSettable = 1; + force = 0; + }; + class GVAR(distance) { + value = DEFAULT_DISTANCE; + typeName = "SCALAR"; + category = CSTRING(Category); + displayName = CSTRING(Distance); + description = CSTRING(DistanceDescription); + isClientSettable = 0; + force = 0; + values[] = {"0m", "1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m", "10m"}; + }; + class GVAR(speed) { + value = DEFAULT_SPEED; + typeName = "SCALAR"; + category = CSTRING(Category); + displayName = CSTRING(Speed); + description = CSTRING(SpeedDescription); + isClientSettable = 0; + force = 0; + values[] = {"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30"}; + }; + class GVAR(priority) { + value = DEFAULT_PRIORITY; + typeName = "SCALAR"; + category = CSTRING(Category); + displayName = CSTRING(Priority); + description = CSTRING(PriorityDescription); + isClientSettable = 1; + force = 0; + values[] = {"$str_getin_pos_driver", "$str_getin_pos_gunn", "$str_getin_pos_comm", "$STR_GETIN_POS_PASSENGER"}; + }; +}; diff --git a/addons/quickmount/CfgEventHandlers.hpp b/addons/quickmount/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9426fa861e --- /dev/null +++ b/addons/quickmount/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/quickmount/CfgVehicles.hpp b/addons/quickmount/CfgVehicles.hpp new file mode 100644 index 0000000000..702f7cab4e --- /dev/null +++ b/addons/quickmount/CfgVehicles.hpp @@ -0,0 +1,37 @@ +class CfgVehicles { + class ACE_Module; + class GVAR(module): ACE_Module { + author = ECSTRING(common,ACETeam); + category = "ACE"; + displayName = CSTRING(Category); + function = QFUNC(moduleInit); + scope = 1; + isGlobal = 1; + isTriggerActivated = 0; + isDisposable = 0; + icon = "a3\ui_f\data\IGUI\Cfg\Actions\Obsolete\ui_action_getin_ca.paa"; + class Arguments { + class enabled { + displayName = ECSTRING(common,Enabled); + description = CSTRING(KeybindDescription); + typeName = "BOOL"; + defaultValue = 1; + }; + class distance { + displayName = CSTRING(Distance); + description = CSTRING(DistanceDescription); + typeName = "NUMBER"; + defaultValue = DEFAULT_DISTANCE; + }; + class speed { + displayName = CSTRING(Speed); + description = CSTRING(SpeedDescription); + typeName = "NUMBER"; + defaultValue = DEFAULT_SPEED; + }; + }; + class ModuleDescription { + description = CSTRING(KeybindDescription); + }; + }; +}; diff --git a/addons/quickmount/README.md b/addons/quickmount/README.md new file mode 100644 index 0000000000..6e11fc8ae4 --- /dev/null +++ b/addons/quickmount/README.md @@ -0,0 +1,9 @@ +ace_quickmount +============ +Adds a keybind to quickly enter the vehicle you are directly looking at. + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [Kingsley](https://github.com/jameslkingsley) diff --git a/addons/quickmount/XEH_PREP.hpp b/addons/quickmount/XEH_PREP.hpp new file mode 100644 index 0000000000..eba2f68296 --- /dev/null +++ b/addons/quickmount/XEH_PREP.hpp @@ -0,0 +1,2 @@ +PREP(getInNearest); +PREP(moduleInit); diff --git a/addons/quickmount/XEH_postInitClient.sqf b/addons/quickmount/XEH_postInitClient.sqf new file mode 100644 index 0000000000..718c08b843 --- /dev/null +++ b/addons/quickmount/XEH_postInitClient.sqf @@ -0,0 +1,10 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +["ACE3 Movement", QGVAR(mount), [localize LSTRING(KeybindName), localize LSTRING(KeybindDescription)], "", { + if (!dialog) then { + call FUNC(getInNearest); + }; + false +}] call CBA_fnc_addKeybind; diff --git a/addons/quickmount/XEH_preInit.sqf b/addons/quickmount/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/quickmount/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/quickmount/XEH_preStart.sqf b/addons/quickmount/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/quickmount/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/quickmount/config.cpp b/addons/quickmount/config.cpp new file mode 100644 index 0000000000..063897aebc --- /dev/null +++ b/addons/quickmount/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + authors[] = {"Kingsley"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "ACE_Settings.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf new file mode 100644 index 0000000000..e068d2c0e6 --- /dev/null +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -0,0 +1,117 @@ +#include "script_component.hpp" +/* + * Author: Kingsley + * Mount the player in the vehicle they are directly looking at based on their distance. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_quickmount_fnc_getInNearest; + * + * Public: No + */ + +if (!GVAR(enabled) || + {isNull ACE_player} || + {vehicle ACE_player != ACE_player} || + {!alive ACE_player} || + {ACE_player getVariable ["ace_unconscious", false]} +) exitWith {}; + +private _start = AGLtoASL (ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot")); +private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); +private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; +private _target = (_objects param [0, []]) param [2, objNull]; + +if (locked _target in [2,3]) exitWith { + [localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); + true +}; + +TRACE_1("",_target); + +if (!isNull _target && + {alive _target} && + {{_target isKindOf _x} count ["Air","LandVehicle","Ship","StaticMortar"] > 0} && + {([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} && + {speed _target <= GVAR(speed)} + ) then { + + + if (GVAR(priority) > 3 || GVAR(priority) < 0) then { + GVAR(priority) = 0; + }; + + private _seats = ["Driver", "Gunner", "Commander", "Cargo"]; + private _sortedSeats = [_seats select GVAR(priority)]; + _seats deleteAt GVAR(priority); + _sortedSeats append _seats; + + + private _hasAction = false; + scopeName "SearchForSeat"; + { + private _desiredRole = _x; + { + _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; + if ((isNull _unit) || {!alive _unit}) then { + private _effectiveRole = toLower _role; + + 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"; + }; + if (_cargoIndex < 0) exitWith { + _effectiveRole = "gunner"; // door gunners / 2nd turret + }; + _effectiveRole = "cargo"; // probably a FFV + }; + TRACE_2("",_effectiveRole,_x); + if (_effectiveRole != _desiredRole) exitWith {}; + + 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 { + 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; + breakTo "SearchForSeat"; + }; + } forEach (fullCrew [_target, "", true]); + } forEach _sortedSeats; + + if (!_hasAction) then { + TRACE_1("no empty seats",_hasAction); + [localize LSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); + }; +}; + +true diff --git a/addons/quickmount/functions/fnc_moduleInit.sqf b/addons/quickmount/functions/fnc_moduleInit.sqf new file mode 100644 index 0000000000..216cda90c0 --- /dev/null +++ b/addons/quickmount/functions/fnc_moduleInit.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Kingsley + * Initializes the quick-mount module. + * + * Arguments: + * 0: The module logic + * 1: Units (Unused) + * 2: Activated + * + * Return Value: + * None + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_logic", "", "_activated"]; + +if (!_activated) exitWith {}; + +[_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(distance), "distance"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(speed), "speed"] call EFUNC(common,readSettingFromModule); diff --git a/addons/quickmount/functions/script_component.hpp b/addons/quickmount/functions/script_component.hpp new file mode 100644 index 0000000000..a91c3e1665 --- /dev/null +++ b/addons/quickmount/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\quickmount\script_component.hpp" diff --git a/addons/quickmount/script_component.hpp b/addons/quickmount/script_component.hpp new file mode 100644 index 0000000000..a0ec1debd0 --- /dev/null +++ b/addons/quickmount/script_component.hpp @@ -0,0 +1,21 @@ +#define COMPONENT quickmount +#define COMPONENT_BEAUTIFIED Quick Mount +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_QUICKMOUNT + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_QUICKMOUNT + #define DEBUG_SETTINGS DEBUG_SETTINGS_QUICKMOUNT +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define DEFAULT_DISTANCE 3 +#define DEFAULT_SPEED 18 +#define DEFAULT_PRIORITY 0 diff --git a/addons/quickmount/stringtable.xml b/addons/quickmount/stringtable.xml new file mode 100644 index 0000000000..2e1a6b9743 --- /dev/null +++ b/addons/quickmount/stringtable.xml @@ -0,0 +1,115 @@ + + + + + Quick Mount + Schnellzugang + Entrata Rapida + クイック マウント + 快速搭乘 + 快速搭乘 + Szybkie wsiadanie + 빠른 탑승 + + + Vehicle quick mount + 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/CfgVehicles.hpp b/addons/rangecard/CfgVehicles.hpp index e7df701409..5974e62e69 100644 --- a/addons/rangecard/CfgVehicles.hpp +++ b/addons/rangecard/CfgVehicles.hpp @@ -19,7 +19,6 @@ class CfgVehicles { condition = QUOTE(call FUNC(canShow) && !GVAR(RangeCardOpened)); statement = QUOTE(false call FUNC(openRangeCard)); showDisabled = 0; - priority = 0.1; icon = QPATHTOF(UI\RangeCard_Icon.paa); exceptions[] = {"notOnMap"}; class GVAR(openCopy) { @@ -27,16 +26,14 @@ class CfgVehicles { condition = QUOTE(call FUNC(canShowCopy) && !GVAR(RangeCardOpened)); statement = QUOTE(true call FUNC(openRangeCard)); showDisabled = 0; - priority = 0.1; icon = QPATHTOF(UI\RangeCard_Icon.paa); exceptions[] = {"notOnMap"}; }; class GVAR(makeCopy) { displayName = CSTRING(CopyRangeCard); condition = QUOTE(call FUNC(canShow) && !GVAR(RangeCardOpened)); - statement = QUOTE(GVAR(ammoClassCopy) = GVAR(ammoClass); GVAR(magazineClassCopy) = GVAR(magazineClass); GVAR(weaponClassCopy) = GVAR(ammoClass);); + statement = QUOTE(GVAR(zeroRangeCopy)=GVAR(zeroRange); GVAR(boreHeightCopy)=GVAR(boreHeight); GVAR(ammoClassCopy)=GVAR(ammoClass); GVAR(magazineClassCopy)=GVAR(magazineClass); GVAR(weaponClassCopy)=GVAR(weaponClass);); showDisabled = 0; - priority = 0.1; icon = QPATHTOF(UI\RangeCard_Icon.paa); exceptions[] = {"notOnMap"}; }; 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/XEH_PREP.hpp b/addons/rangecard/XEH_PREP.hpp index 6b13dcc45a..abbeaa2803 100644 --- a/addons/rangecard/XEH_PREP.hpp +++ b/addons/rangecard/XEH_PREP.hpp @@ -1,5 +1,5 @@ -PREP(calculateSolution); +PREP(calculateRangeCard); PREP(canCopy); PREP(canShow); PREP(canShowCopy); diff --git a/addons/rangecard/XEH_postInit.sqf b/addons/rangecard/XEH_postInit.sqf index 8396d76b39..9e60821fc1 100644 --- a/addons/rangecard/XEH_postInit.sqf +++ b/addons/rangecard/XEH_postInit.sqf @@ -6,10 +6,14 @@ GVAR(RangeCardOpened) = false; GVAR(controls) = []; +GVAR(zeroRange) = 100; +GVAR(boreHeight) = 3.81; GVAR(ammoClass) = "B_65x39_Caseless"; GVAR(magazineClass) = "30Rnd_65x39_caseless_mag"; GVAR(weaponClass) = "arifle_MXM_F"; +GVAR(zeroRangeCopy) = 100; +GVAR(boreHeightCopy) = 3.81; GVAR(ammoClassCopy) = "";//"ACE_762x51_Ball_M118LR"; GVAR(magazineClassCopy) = "";//"ACE_20Rnd_762x51_M118LR_Mag"; GVAR(weaponClassCopy) = "";//srifle_DMR_06_olive_F"; diff --git a/addons/rangecard/XEH_preInit.sqf b/addons/rangecard/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/rangecard/XEH_preInit.sqf +++ b/addons/rangecard/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/rangecard/config.cpp b/addons/rangecard/config.cpp index 9017583606..f300fb1a30 100644 --- a/addons/rangecard/config.cpp +++ b/addons/rangecard/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {"ACE_Item_RangeCard"}; weapons[] = {"ACE_RangeCard"}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ACE_Advanced_Ballistics"}; + requiredAddons[] = {"ACE_Advanced_Ballistics","ace_scopes"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg"}; url = ECSTRING(main,URL); diff --git a/addons/rangecard/functions/fnc_calculateRangeCard.sqf b/addons/rangecard/functions/fnc_calculateRangeCard.sqf new file mode 100644 index 0000000000..ebeadf6b7e --- /dev/null +++ b/addons/rangecard/functions/fnc_calculateRangeCard.sqf @@ -0,0 +1,148 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Calculates the range card data + * + * Arguments: + * 0: Scope base angle + * 1: Bore height + * 2: air friction + * 3: muzzle velocity + * 4: temperature + * 5: barometric pressure + * 6: relative humidity + * 7: simulation steps + * 8: wind speed + * 9: target speed + * 10: target range + * 11: ballistic coefficient + * 12: drag model + * 13: atmosphere model + * 14: transonicStabilityCoef + * 15: Range Card Slot + * 16: Use advanced ballistics config? + * + * Return Value: + * None + * + * Example: + * [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ,14, 15, 16, true] call ace_rangecard_fnc_calculateRangeCard + * + * Public: No + */ +params [ + "_scopeBaseAngle", "_boreHeight", "_airFriction", "_muzzleVelocity", + "_temperature", "_barometricPressure", "_relativeHumidity", "_simSteps", + "_windSpeed", "_targetSpeed", "_targetRange", "_bc", "_dragModel", "_atmosphereModel", + "_transonicStabilityCoef", "_rangeCardSlot", "_useABConfig" +]; + +GVAR(rangeCardDataMVs) set [_rangeCardSlot, format[" %1", round(_muzzleVelocity)]]; + +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 = 0; +private _windage = 0; +private _lead = 0; +private _TOF = 0; +private _trueVelocity = [0, 0, 0]; +private _trueSpeed = 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 = 1; +if (!_useABConfig && (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { + private _airDensity = [_temperature, _barometricPressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); + _airFrictionCoef = _airDensity / 1.22498; +}; + +private _speedTotal = 0; +private _stepsTotal = 0; +private _speedAverage = 0; + +_bulletPos set [0, 0]; +_bulletPos set [1, 0]; +_bulletPos set [2, -(_boreHeight / 100)]; + +_bulletVelocity set [0, 0]; +_bulletVelocity set [1, Cos(_scopeBaseAngle) * _muzzleVelocity]; +_bulletVelocity set [2, Sin(_scopeBaseAngle) * _muzzleVelocity]; + +while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do { + _bulletSpeed = vectorMagnitude _bulletVelocity; + + _speedTotal = _speedTotal + _bulletSpeed; + _stepsTotal = _stepsTotal + 1; + _speedAverage = (_speedTotal / _stepsTotal); + + if (_transonicStabilityCoef < 1.0 && _speedAverage > 450 && _bulletSpeed < _speedOfSound) exitWith {}; + + _trueVelocity = _bulletVelocity vectorDiff [-_windSpeed, 0, 0]; + _trueSpeed = vectorMagnitude _trueVelocity; + + if (_useABConfig) then { + 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); + }; + + _bulletAccel = _bulletAccel vectorAdd _gravity; + + _lastBulletPos = _bulletPos; + _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply (_deltaT * 0.5)); + _bulletVelocity = _bulletVelocity vectorAdd (_bulletAccel vectorMultiply _deltaT); + _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply (_deltaT * 0.5)); + + if (atan((_bulletPos select 2) / (abs(_bulletPos select 1) + 1)) < -2.254) exitWith {}; + + _TOF = _TOF + _deltaT; + + _range = GVAR(rangeCardStartRange) + _n * GVAR(rangeCardIncrement); + if ((_bulletPos select 1) >= _range && _range <= GVAR(rangeCardEndRange)) then { + if (_range != 0) then { + _tx = (_lastBulletPos select 0) + (_range - (_lastBulletPos select 1)) * ((_bulletPos select 0) - (_lastBulletPos select 0)) / ((_bulletPos select 1) - (_lastBulletPos select 1)); + _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(MRAD_TO_DEG(1)) * _range); + }; + + 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"; + }; + private _windageString = Str(round(DEG_TO_MRAD(_windage) * 10) / 10); + if (_windageString find "." == -1) then { + _windageString = _windageString + ".0"; + }; + private _leadString = Str(round(_lead * 10) / 10); + if (_leadString find "." == -1) then { + _leadString = _leadString + ".0"; + }; + (GVAR(rangeCardDataElevation) select _rangeCardSlot) set [_n, _elevationString]; + (GVAR(rangeCardDataWindage) select _rangeCardSlot) set [_n, _windageString]; + (GVAR(rangeCardDataLead) select _rangeCardSlot) set [_n, _leadString]; + _n = _n + 1; + }; +}; diff --git a/addons/rangecard/functions/fnc_calculateSolution.sqf b/addons/rangecard/functions/fnc_calculateSolution.sqf deleted file mode 100644 index 945c2aa512..0000000000 --- a/addons/rangecard/functions/fnc_calculateSolution.sqf +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Author: Ruthberg - * Calculates the range card data - * - * Arguments: - * 0: Scope base angle - * 1: Bullet mass - * 2: Bore height - * 3: air friction - * 4: muzzle velocity - * 5: temperature - * 6: barometric pressure - * 7: relative humidity - * 8: simulation steps - * 9: wind speed - * 10: wind direction - * 11: inclination angle - * 12: target speed - * 13: target range - * 14: ballistic coefficient - * 15: drag model - * 16: atmosphere model - * 17: Store range card data? - * 18: Stability factor - * 19: Twist Direction - * 20: Latitude - * 21: Direction of Fire - * 22: Range Card Slot - * 23: Use advanced ballistics config? - * - * Return Value: - * 0: Elevation (MOA) - * 1: Windage (MOA) - * 2: Lead (MOA) - * 3: Time of fligth (SECONDS) - * 4: Remaining velocity (m/s) - * 5: Remaining kinetic energy (ft·lb) - * 6: Vertical coriolis drift (MOA) - * 7: Horizontal coriolis drift (MOA) - * 8: Spin drift (MOA) - * - * Example: - * call ace_rangecard_fnc_calculateSolution - * - * Public: No - */ -#include "script_component.hpp" -params [ - "_scopeBaseAngle", "_bulletMass", "_boreHeight", "_airFriction", "_muzzleVelocity", - "_temperature", "_barometricPressure", "_relativeHumidity", "_simSteps", "_windSpeed", - "_windDirection", "_inclinationAngle", "_targetSpeed", "_targetRange", "_bc", "_dragModel", - "_atmosphereModel", "_storeRangeCardData", "_stabilityFactor", "_twistDirection", "_latitude", - "_directionOfFire", "_rangeCardSlot", "_useABConfig" -]; -_windSpeed params ["_windSpeed1", "_windSpeed2"]; - -if (_storeRangeCardData) then { - GVAR(rangeCardDataMVs) set [_rangeCardSlot, format[" %1", round(_muzzleVelocity)]]; -}; - -private ["_bulletPos", "_bulletVelocity", "_bulletAccel", "_bulletSpeed", "_gravity", "_deltaT", "_speedOfSound"]; -_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; -_speedOfSound = 0; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - _speedOfSound = _temperature call EFUNC(weather,calculateSpeedOfSound); -}; - -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 ["_n", "_range"]; -_n = 0; -_range = 0; - -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; -if (_useABConfig) then { - _bc = [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel] call EFUNC(advanced_ballistics,calculateAtmosphericCorrection); -}; - -private ["_airFrictionCoef", "_airDensity"]; -_airFrictionCoef = 1; -if (!_useABConfig && (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { - _airDensity = [_temperature, _barometricPressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); - _airFrictionCoef = _airDensity / 1.22498; -}; - -private ["_speedTotal", "_stepsTotal", "_speedAverage"]; -_speedTotal = 0; -_stepsTotal = 0; -_speedAverage = 0; - -_bulletPos set [0, 0]; -_bulletPos set [1, 0]; -_bulletPos set [2, -(_boreHeight / 100)]; - -_bulletVelocity set [0, 0]; -_bulletVelocity set [1, Cos(_scopeBaseAngle) * _muzzleVelocity]; -_bulletVelocity set [2, Sin(_scopeBaseAngle) * _muzzleVelocity]; - -while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do { - _bulletSpeed = vectorMagnitude _bulletVelocity; - - _speedTotal = _speedTotal + _bulletSpeed; - _stepsTotal = _stepsTotal + 1; - _speedAverage = (_speedTotal / _stepsTotal); - - if (_speedAverage > 450 && _bulletSpeed < _speedOfSound) exitWith {}; - if (atan((_bulletPos select 2) / (abs(_bulletPos select 1) + 1)) < -2.254) exitWith {}; - - _trueVelocity = _bulletVelocity vectorDiff _wind1; - _trueSpeed = vectorMagnitude _trueVelocity; - - if (_useABConfig) then { - private _drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then { - parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed])) - } else { - ([_dragModel, _bc, _trueSpeed] call EFUNC(advanced_ballistics,calculateRetardation)) - }; - _bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag); - } else { - _bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction * _airFrictionCoef); - }; - - _bulletAccel = _bulletAccel vectorAdd _gravity; - - _bulletVelocity = _bulletVelocity vectorAdd (_bulletAccel vectorMultiply _deltaT); - _bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply _deltaT); - - _TOF = _TOF + _deltaT; - - if (_storeRangeCardData) then { - _range = GVAR(rangeCardStartRange) + _n * GVAR(rangeCardIncrement); - if ((_bulletPos select 1) >= _range && _range <= GVAR(rangeCardEndRange)) then { - if ((_bulletPos select 1) > 0) then { - _elevation = - atan((_bulletPos select 2) / (_bulletPos select 1)); - _windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1)); - }; - if (_range != 0) then { - _lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _range); - }; - private ["_elevationString", "_windageString", "_leadString"]; - _elevationString = Str(round(-_elevation * 60 / 3.38 * 10) / 10); - if (_elevationString == "0") then { - _elevationString = "-0.0"; - }; - if (_elevationString find "." == -1) then { - _elevationString = _elevationString + ".0"; - }; - _windageString = Str(round(_windage1 * 60 / 3.38 * 10) / 10); - if (_windageString find "." == -1) then { - _windageString = _windageString + ".0"; - }; - _leadString = Str(round(_lead * 10) / 10); - if (_leadString find "." == -1) then { - _leadString = _leadString + ".0"; - }; - (GVAR(rangeCardDataElevation) select _rangeCardSlot) set [_n, _elevationString]; - (GVAR(rangeCardDataWindage) select _rangeCardSlot) set [_n, _windageString]; - (GVAR(rangeCardDataLead) select _rangeCardSlot) set [_n, _leadString]; - _n = _n + 1; - }; - }; -}; - -if ((_bulletPos select 1) > 0) then { - _elevation = - atan((_bulletPos select 2) / (_bulletPos select 1)); - _windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1)); - _windDrift = (_wind2 select 0) * (_TOF - _targetRange / _muzzleVelocity); - _windage2 = - atan(_windDrift / (_bulletPos select 1)); -}; - -if (_targetRange != 0) then { - _lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _targetRange); -}; - -_kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2)); -_kineticEnergy = _kineticEnergy * 0.737562149; - -[_elevation * 60, [_windage1 * 60, _windage2 * 60], _lead, _TOF, _bulletSpeed, _kineticEnergy, _verticalCoriolis * 60, _horizontalCoriolis * 60, _spinDrift * 60] diff --git a/addons/rangecard/functions/fnc_canCopy.sqf b/addons/rangecard/functions/fnc_canCopy.sqf index c9e0a05d0e..ee85bcf096 100644 --- a/addons/rangecard/functions/fnc_canCopy.sqf +++ b/addons/rangecard/functions/fnc_canCopy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Checks if the target has a copyable range card @@ -6,13 +7,12 @@ * unit * * Return Value: - * canShow (bool) + * canShow * * Example: - * [] call ace_rangecard_fnc_canCopy + * [bob] call ace_rangecard_fnc_canCopy * * Public: No */ -#include "script_component.hpp" ((primaryWeapon _this) != "" && [_this] call EFUNC(common,isPlayer) && [_this, "ACE_RangeCard"] call EFUNC(common,hasItem)) diff --git a/addons/rangecard/functions/fnc_canShow.sqf b/addons/rangecard/functions/fnc_canShow.sqf index 330788ee7c..6b3cf6997a 100644 --- a/addons/rangecard/functions/fnc_canShow.sqf +++ b/addons/rangecard/functions/fnc_canShow.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Tests if the Range Card can be shown @@ -6,13 +7,12 @@ * Nothing * * Return Value: - * canShow (bool) + * canShow * * Example: * [] call ace_rangecard_fnc_canShow * * Public: No */ -#include "script_component.hpp" (GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "" && !GVAR(RangeCardOpened) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player))) diff --git a/addons/rangecard/functions/fnc_canShowCopy.sqf b/addons/rangecard/functions/fnc_canShowCopy.sqf index e78c64cc89..e4eb28b60b 100644 --- a/addons/rangecard/functions/fnc_canShowCopy.sqf +++ b/addons/rangecard/functions/fnc_canShowCopy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Tests if the Range Card copy can be shown @@ -6,13 +7,12 @@ * Nothing * * Return Value: - * canShow (bool) + * canShow * * Example: * [] call ace_rangecard_fnc_canShowCopy * * Public: No */ -#include "script_component.hpp" (GVAR(ammoClassCopy) != "" && GVAR(magazineClassCopy) != "" && GVAR(weaponClassCopy) != "" && !GVAR(RangeCardOpened) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player))) diff --git a/addons/rangecard/functions/fnc_onCloseDialog.sqf b/addons/rangecard/functions/fnc_onCloseDialog.sqf index f5d971f22f..0a93eb897c 100644 --- a/addons/rangecard/functions/fnc_onCloseDialog.sqf +++ b/addons/rangecard/functions/fnc_onCloseDialog.sqf @@ -1,4 +1,19 @@ #include "script_component.hpp" +/* + * Author: joko // Jonas + * Add the Reserve Parachute to Units or Save Backpack if is a Parachute in Unit + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * None + * + * Public: No + */ uiNamespace setVariable ['RangleCard_Display', nil]; GVAR(RangeCardOpened) = false; diff --git a/addons/rangecard/functions/fnc_openRangeCard.sqf b/addons/rangecard/functions/fnc_openRangeCard.sqf index ea085ed5b1..ed2bb9e241 100644 --- a/addons/rangecard/functions/fnc_openRangeCard.sqf +++ b/addons/rangecard/functions/fnc_openRangeCard.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Opens the range card dialog @@ -6,14 +7,13 @@ * Open copy? * * Return Value: - * Nothing + * None * * Example: - * call ace_rangecard_fnc_openRangeCard + * [true] call ace_rangecard_fnc_openRangeCard * * Public: No */ -#include "script_component.hpp" if (GVAR(RangeCardOpened)) exitWith {}; @@ -23,7 +23,7 @@ if (_this) then { createDialog "ACE_RangeCard_Dialog"; - [GVAR(ammoClassCopy), GVAR(magazineClassCopy), GVAR(weaponClassCopy)] call FUNC(updateRangeCard); + [GVAR(zeroRangeCopy), GVAR(boreHeightCopy), GVAR(ammoClassCopy), GVAR(magazineClassCopy), GVAR(weaponClassCopy)] call FUNC(updateRangeCard); }; } else { if (ACE_player call FUNC(updateClassNames)) then { @@ -31,6 +31,6 @@ if (_this) then { createDialog "ACE_RangeCard_Dialog"; - [GVAR(ammoClass), GVAR(magazineClass), GVAR(weaponClass)] call FUNC(updateRangeCard); + [GVAR(zeroRange), GVAR(boreHeight), GVAR(ammoClass), GVAR(magazineClass), GVAR(weaponClass)] call FUNC(updateRangeCard); }; }; diff --git a/addons/rangecard/functions/fnc_updateClassNames.sqf b/addons/rangecard/functions/fnc_updateClassNames.sqf index 70cf25825e..e13198bcfc 100644 --- a/addons/rangecard/functions/fnc_updateClassNames.sqf +++ b/addons/rangecard/functions/fnc_updateClassNames.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Updates the ammo and weapon class names @@ -13,21 +14,19 @@ * * Public: No */ -#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; @@ -37,10 +36,14 @@ if (_weaponClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(magazineClass) if (_ammoClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(magazineClass) != "" && GVAR(weaponClass) != "") }; if (_unit == ACE_player) then { + GVAR(zeroRange) = [_unit] call EFUNC(scopes,getCurrentZeroRange); + GVAR(boreHeight) = [_unit, 0] call EFUNC(scopes,getBoreHeight); GVAR(ammoClass) = _ammoClass; GVAR(magazineClass) = _magazineClass; GVAR(weaponClass) = _weaponClass; } else { + GVAR(zeroRangeCopy) = [_unit] call EFUNC(scopes,getCurrentZeroRange); + GVAR(boreHeightCopy) = [_unit, 0] call EFUNC(scopes,getBoreHeight); GVAR(ammoClassCopy) = _ammoClass; GVAR(magazineClassCopy) = _magazineClass; GVAR(weaponClassCopy) = _weaponClass; diff --git a/addons/rangecard/functions/fnc_updateRangeCard.sqf b/addons/rangecard/functions/fnc_updateRangeCard.sqf index a7b0b996e2..9fc2c9ebab 100644 --- a/addons/rangecard/functions/fnc_updateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_updateRangeCard.sqf @@ -1,29 +1,29 @@ +#include "script_component.hpp" /* * Authors: Ruthberg * Updates the range card data * * Arguments: - * 0: ammo class - * 1: magazine class - * 2: weapon class + * 0: zero range + * 1: bore height + * 2: ammo class + * 3: magazine class + * 4: weapon class * * Return Value: - * Nothing + * None * * Example: - * [mode] call ace_rangecard_fnc_openRangeCard + * [1, 2, "ammo", "magazine", "weapon"] call ace_rangecard_fnc_openRangeCard * * Public: No */ -#include "script_component.hpp" disableSerialization; #define __dsp (uiNamespace getVariable "RangleCard_Display") -private ["_airFriction", "_ammoConfig", "_atmosphereModel", "_barometricPressure", "_barrelLength", "_barrelTwist", "_bc", "_bulletMass", "_boreHeight", "_cacheEntry", "_column", "_control", "_dragModel", "_i", "_muzzleVelocity", "_mv", "_mvShift", "_offset", "_relativeHumidity", "_result", "_row", "_scopeBaseAngle", "_weaponConfig", "_zeroRange", "_initSpeed", "_initSpeedCoef", "_useABConfig"]; -_useABConfig = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]); -PARAMS_3(_ammoClass,_magazineClass,_weaponClass); +params ["_zeroRange", "_boreHeight", "_ammoClass", "_magazineClass", "_weaponClass"]; if (_ammoClass == "" || _magazineClass == "" || _weaponClass == "") exitWith {}; @@ -33,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]; @@ -47,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"; @@ -57,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"; @@ -67,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"; @@ -92,23 +92,22 @@ 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; }; -_dragModel = _ammoConfig select 5; -_atmosphereModel = _ammoConfig select 8; -_bulletMass = 5; -_boreHeight = 3.81; -_zeroRange = 100; +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 { _useABConfig = false; }; @@ -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)"]]; @@ -147,33 +143,34 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t lnbAddRow [770300, ["-15°C", " 10°C", " 35°C", "-15°C", " 10°C", " 35°C"]]; }; -_barometricPressure = 1013.25; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - _barometricPressure = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; -}; -_relativeHumidity = 0.5; +ctrlSetText [77003, format["%1m ZERO", round(_zeroRange)]]; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { - ctrlSetText [770001, format["Drop Tables for B.P.: %1mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C", round(_barometricPressure * 100) / 100]]; - ctrlSetText [77004 , format["B.P.: %1mb", round(_barometricPressure * 100) / 100]]; + ctrlSetText [770001, format["Drop Tables for B.P.: %1mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]]; + ctrlSetText [77004 , format["B.P.: %1mb", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]]; } else { ctrlSetText [770001, ""]; ctrlSetText [77004 , ""]; }; -_cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3), _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 { - _result = [0, 0, _boreHeight, _airFriction, _muzzleVelocity, 15, 1013.25, 0.5, 1000, [0, 0], 0, 0, 0, _zeroRange, _bc, _dragModel, _atmosphereModel, false, 1.5, 0, 0, 0, 0, _useABConfig] call FUNC(calculateSolution); - _scopeBaseAngle = (_result select 0) / 60; - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + private _scopeBaseAngle = if (!_useABConfig) then { + 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 ["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 { { - _mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift); - _mv = _muzzleVelocity + _mvShift; + private _mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift); + private _mv = _muzzleVelocity + _mvShift; - [_scopeBaseAngle,_bulletMass,_boreHeight,_airFriction,_mv,_x,_barometricPressure,_relativeHumidity,1000,[4,0],3,0,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,true,1.5,1,46,23,_forEachIndex,_useABConfig] call FUNC(calculateSolution); + [_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,_bulletMass,_boreHeight,_airFriction,_muzzleVelocity,15,_barometricPressure,_relativeHumidity,1000,[4,0],3,0,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,true,1.5,1,46,23,3,_useABConfig] call FUNC(calculateSolution); + [_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 { @@ -191,7 +188,7 @@ if (isNil {_cacheEntry}) then { }; }; - missionNamespace setVariable [format[QGVAR(%1_%2_%3), _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]]; + missionNamespace setVariable [format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]]; } else { GVAR(rangeCardDataElevation) = _cacheEntry select 0; GVAR(rangeCardDataWindage) = _cacheEntry select 1; @@ -204,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]; @@ -216,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]; @@ -229,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]; @@ -240,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, "and load with optic mounted 1.5'' above line of bore."]; -} 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/rangecard/script_component.hpp b/addons/rangecard/script_component.hpp index 95344973fe..a83f40931f 100644 --- a/addons/rangecard/script_component.hpp +++ b/addons/rangecard/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_RANGECARD diff --git a/addons/rangecard/stringtable.xml b/addons/rangecard/stringtable.xml index e97a31195e..5862981e16 100644 --- a/addons/rangecard/stringtable.xml +++ b/addons/rangecard/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Távolsági kártya Таблица поправок Tavola Balistica + 射表 + 사거리표 + 弹道射表 + 彈道射表 50 METER increments -- MRAD/MRAD (reticle/turrets) @@ -24,6 +28,10 @@ 50 MÉTERES lépések - MRAD/MRAD (célzó/lövegek) Шаг 50 МЕТРОВ - MRAD/MRAD (сетка/маховички) Incrementi per 50 METRI - MRAD/MRAD (reticolo/torrette) + 50 メートル増やす -- MRAD/MRAD (照準線/砲塔) + 50 미터 늘리기 -- MRAD/MRAD (조준선/포탑) + 50公尺增量 -- 毫弧度/毫弧度 (瞄镜分划线/调整纽) + 50公尺增量 -- 毫弧度/毫弧度 (瞄鏡分劃線/調整紐) Open Range Card @@ -36,6 +44,10 @@ Távolsági kártya kinyitása Открыть таблицу поправок Apri Tavola Balistica + 射表を開く + 사거리표 열기 + 开启弹道射表 + 開啟彈道射表 Open Range Card Copy @@ -48,6 +60,10 @@ Távolsági kártya-másolat kinyitása Открыть копию таблицы поправок Apri Copia Tavola Balistica + 複製された射表を開く + 복제 사거리표 열기 + 开启弹道射表副本 + 開啟彈道射表副本 Open Range Card @@ -60,6 +76,10 @@ Távolsági kártya kinyitása Открыть таблицу поправок Apri Tavola Balistica + 射表を開く + 사거리표 열기 + 开启弹道射表 + 開啟彈道射表 Open Range Card Copy @@ -72,6 +92,10 @@ Távolsági kártya-másolat kinyitása Открыть копию таблицы поправок Apri Copia Tavola Balistica + 複製された射表を開く + 복제 사거리표 열기 + 开启弹道射表副本 + 開啟彈道射表副本 Copy Range Card @@ -84,6 +108,10 @@ Távolsági kártya másolása Скопировать таблицу поправок Copia Tavola Balistica + 射表を複製する + 사거리표 복제 + 复制弹道射表 + 複製彈道射表 - \ No newline at end of file + diff --git a/addons/realisticnames/CfgMagazines.hpp b/addons/realisticnames/CfgMagazines.hpp index a6a64a4a15..bc84947798 100644 --- a/addons/realisticnames/CfgMagazines.hpp +++ b/addons/realisticnames/CfgMagazines.hpp @@ -246,23 +246,23 @@ class CfgMagazines { displayNameShort = "125mm MP-T"; }; - class 32Rnd_120mm_APFSDS_shells; - class 24Rnd_125mm_APFSDS: 32Rnd_120mm_APFSDS_shells { + class 20Rnd_125mm_APFSDS; + class 24Rnd_125mm_APFSDS: 20Rnd_125mm_APFSDS { displayNameShort = "125mm AP"; }; - class 32Rnd_120mm_APFSDS_shells_Tracer_Red; - class 24Rnd_125mm_APFSDS_T_Red: 32Rnd_120mm_APFSDS_shells_Tracer_Red { + class 20Rnd_125mm_APFSDS_T_Red; + class 24Rnd_125mm_APFSDS_T_Red: 20Rnd_125mm_APFSDS_T_Red { displayNameShort = "125mm AP-T"; }; - class 32Rnd_120mm_APFSDS_shells_Tracer_Green; - class 24Rnd_125mm_APFSDS_T_Green: 32Rnd_120mm_APFSDS_shells_Tracer_Green { + class 20Rnd_125mm_APFSDS_T_Green; + class 24Rnd_125mm_APFSDS_T_Green: 20Rnd_125mm_APFSDS_T_Green { displayNameShort = "125mm AP-T"; }; - class 32Rnd_120mm_APFSDS_shells_Tracer_Yellow; - class 24Rnd_125mm_APFSDS_T_Yellow: 32Rnd_120mm_APFSDS_shells_Tracer_Yellow { + class 20Rnd_125mm_APFSDS_T_Yellow; + class 24Rnd_125mm_APFSDS_T_Yellow: 20Rnd_125mm_APFSDS_T_Yellow { displayNameShort = "125mm AP-T"; }; @@ -396,6 +396,10 @@ class CfgMagazines { displayName = CSTRING(HandGrenade_Name); displayNameShort = "M67"; }; + class MiniGrenade: CA_Magazine { + displayName = CSTRING(MiniGrenade_Name); + displayNameShort = "V40"; + }; class SmokeShell: HandGrenade { displayName = CSTRING(SmokeShell_Name); }; @@ -417,4 +421,80 @@ class CfgMagazines { class SmokeShellYellow: SmokeShell { displayName = CSTRING(SmokeShellYellow_Name); }; + + + // 1.70 Pylon Magazines (Should Match Weapon Name) + class 2Rnd_Missile_AA_04_F; + class PylonRack_1Rnd_Missile_AA_04_F: 2Rnd_Missile_AA_04_F { + displayName = "AIM-9 Sidewinder"; // [vanilla: Falchion-22 - Missile_AA_04_Plane_CAS_01_F] + }; + class 4Rnd_AAA_missiles; + class PylonRack_1Rnd_AAA_missiles: 4Rnd_AAA_missiles { + displayName = "AIM-132 ASRAAM"; // [vanilla: ASRAAM - missiles_ASRAAM] + }; + class 4Rnd_GAA_missiles; + class PylonRack_1Rnd_GAA_missiles: 4Rnd_GAA_missiles { + displayName = "AIM-120A AMRAAM"; // [vanilla: Zephyr - missiles_Zephyr] + }; + class 6Rnd_Missile_AGM_02_F; + class PylonRack_1Rnd_Missile_AGM_02_F: 6Rnd_Missile_AGM_02_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 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 { + displayName = "9K121 Vikhr"; // [vanilla: Scalpel - missiles_SCALPEL] + }; + class PylonRack_3Rnd_LG_scalpel: PylonRack_1Rnd_LG_scalpel { + displayName = "9K121 Vikhr 3x"; // [vanilla: Scalpel 3x - missiles_SCALPEL] + }; + class PylonRack_4Rnd_LG_scalpel: PylonRack_1Rnd_LG_scalpel { + displayName = "9K121 Vikhr 4x"; // [vanilla: Scalpel 4x - missiles_SCALPEL] + }; + class PylonRack_7Rnd_Rocket_04_HE_F: 7Rnd_Rocket_04_HE_F { + displayName = "Hydra 70 7x HE"; // [vanilla: Shrieker 7x HE - Rocket_04_HE_Plane_CAS_01_F] + }; + class PylonRack_7Rnd_Rocket_04_AP_F: 7Rnd_Rocket_04_AP_F { + displayName = "Hydra 70 7x AP"; // [vanilla: Shrieker 7x AP - Rocket_04_AP_Plane_CAS_01_F] + }; + class 12Rnd_missiles; + class PylonRack_12Rnd_missiles: 12Rnd_missiles { + 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] + }; + class PylonRack_20Rnd_Rocket_03_AP_F: 20Rnd_Rocket_03_AP_F { + displayName = "S-8 20x AP"; // [vanilla: Tratnyr 20x AP - Rocket_03_AP_Plane_CAS_02_F] + }; + class 2Rnd_Missile_AA_03_F; + class PylonRack_1Rnd_Missile_AA_03_F: 2Rnd_Missile_AA_03_F { + displayName = "Wympel R-73"; // [vanilla: Sahr-3 - Missile_AA_03_Plane_CAS_02_F] + }; + class 4Rnd_Missile_AGM_01_F; + class PylonRack_1Rnd_Missile_AGM_01_F: 4Rnd_Missile_AGM_01_F { + displayName = "Kh-25MTP"; // [vanilla: Sharur - Missile_AGM_01_Plane_CAS_02_F] + }; + class 2Rnd_Bomb_03_F; + class PylonMissile_1Rnd_Bomb_03_F: 2Rnd_Bomb_03_F { + displayName = "FAB-250M-54"; // [vanilla: LOM-250G - Bomb_03_Plane_CAS_02_F] + }; + }; diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index f53465b08f..9b0ab1b95a 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,15 @@ 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); + }; + class APC_Wheeled_02_base_v2_F; + class O_APC_Wheeled_02_rcws_v2_F : APC_Wheeled_02_base_v2_F { + displayName = CSTRING(APC_Wheeled_02_rcws_Name); + }; + class O_T_APC_Wheeled_02_rcws_v2_ghex_F : APC_Wheeled_02_base_v2_F { displayName = CSTRING(APC_Wheeled_02_rcws_Name); }; @@ -248,9 +264,25 @@ class CfgVehicles { class I_Truck_02_box_F: Truck_02_box_base_F { displayName = CSTRING(Truck_02_box_Name); }; + class Truck_02_MRL_base_F; + class I_Truck_02_MRL_F: Truck_02_MRL_base_F { + displayName = CSTRING(Truck_02_MRL_Name); + }; class I_Truck_02_medical_F: Truck_02_medical_base_F { displayName = CSTRING(Truck_02_medical_Name); }; + class C_Truck_02_transport_F: Truck_02_transport_base_F { + displayName = CSTRING(Truck_02_transport_Name); + }; + class C_Truck_02_covered_F: Truck_02_base_F { + displayName = CSTRING(Truck_02_covered_Name); + }; + class C_Truck_02_fuel_F: Truck_02_fuel_base_F { + displayName = CSTRING(Truck_02_fuel_Name); + }; + class C_Truck_02_box_F: Truck_02_box_base_F { + displayName = CSTRING(Truck_02_box_Name); + }; class Truck_03_base_F; class O_Truck_03_transport_F: Truck_03_base_F { @@ -281,18 +313,30 @@ class CfgVehicles { displayName = CSTRING(Heli_Attack_01_Name); }; + class Heli_Attack_01_dynamicLoadout_base_F; + class B_Heli_Attack_01_dynamicLoadout_F: Heli_Attack_01_dynamicLoadout_base_F { + displayName = CSTRING(Heli_Attack_01_Name); + }; + class Heli_Light_01_unarmed_base_F; class B_Heli_Light_01_F: Heli_Light_01_unarmed_base_F { displayName = CSTRING(Heli_Light_01_Name); }; + 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 { displayName = CSTRING(Heli_Light_01_armed_Name); }; - class Heli_Light_01_civil_base_F: Heli_Light_01_unarmed_base_F { - displayName = CSTRING(Heli_Light_01_civil_Name); + class Heli_Light_01_dynamicLoadout_base_F; + class B_Heli_Light_01_dynamicLoadout_F: Heli_Light_01_dynamicLoadout_base_F { + displayName = CSTRING(Heli_Light_01_armed_Name); }; class Heli_Transport_03_base_F; @@ -316,6 +360,11 @@ class CfgVehicles { displayName = CSTRING(Heli_Light_02_unarmed_Name); }; + class Heli_Light_02_dynamicLoadout_base_F; + class O_Heli_Light_02_dynamicLoadout_F: Heli_Light_02_dynamicLoadout_base_F { + displayName = CSTRING(Heli_Light_02_Name); + }; + class Heli_light_03_base_F; class I_Heli_light_03_F: Heli_light_03_base_F { displayName = CSTRING(Heli_light_03_Name); @@ -326,6 +375,11 @@ class CfgVehicles { displayName = CSTRING(Heli_light_03_unarmed_Name); }; + class Heli_light_03_dynamicLoadout_base_F; + class I_Heli_light_03_dynamicLoadout_F: Heli_light_03_dynamicLoadout_base_F { + displayName = CSTRING(Heli_light_03_Name); + }; + class Heli_Transport_02_base_F; class I_Heli_Transport_02_F: Heli_Transport_02_base_F { displayName = CSTRING(Heli_Transport_02_Name); @@ -337,11 +391,21 @@ class CfgVehicles { displayName = CSTRING(Plane_CAS_01_Name); }; + class Plane_CAS_01_dynamicLoadout_base_F; + class B_Plane_CAS_01_dynamicLoadout_F: Plane_CAS_01_dynamicLoadout_base_F { + displayName = CSTRING(Plane_CAS_01_Name); + }; + class Plane_CAS_02_base_F; class O_Plane_CAS_02_F: Plane_CAS_02_base_F { displayName = CSTRING(Plane_CAS_02_Name); }; + class Plane_CAS_02_dynamicLoadout_base_F; + class O_Plane_CAS_02_dynamicLoadout_F: Plane_CAS_02_dynamicLoadout_base_F { + displayName = CSTRING(Plane_CAS_02_Name); + }; + class Plane_Fighter_03_base_F; class I_Plane_Fighter_03_CAS_F: Plane_Fighter_03_base_F { displayName = CSTRING(Plane_Fighter_03_CAS_Name); @@ -351,6 +415,16 @@ class CfgVehicles { displayName = CSTRING(Plane_Fighter_03_AA_Name); }; + class Plane_Fighter_03_dynamicLoadout_base_F; + class I_Plane_Fighter_03_dynamicLoadout_F: Plane_Fighter_03_dynamicLoadout_base_F { + 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 { @@ -363,7 +437,7 @@ class CfgVehicles { displayName = CSTRING(UAV_02_Name); }; - class UAV_02_CAS_base_F: UAV_02_base_F {}; + class UAV_02_CAS_base_F; class B_UAV_02_CAS_F: UAV_02_CAS_base_F { displayName = CSTRING(UAV_02_CAS_Name); }; @@ -374,6 +448,17 @@ class CfgVehicles { displayName = CSTRING(UAV_02_CAS_Name); }; + class UAV_02_dynamicLoadout_base_F; + class B_UAV_02_dynamicLoadout_F: UAV_02_dynamicLoadout_base_F { + displayName = CSTRING(UAV_02_Name); + }; + class O_UAV_02_dynamicLoadout_F: UAV_02_dynamicLoadout_base_F { + displayName = CSTRING(UAV_02_Name); + }; + class I_UAV_02_dynamicLoadout_F: UAV_02_dynamicLoadout_base_F { + displayName = CSTRING(UAV_02_Name); + }; + // pistols class Pistol_Base_F; class Weapon_hgun_P07_F: Pistol_Base_F { @@ -513,11 +598,11 @@ class CfgVehicles { class Weapon_SMG_02_F: Weapon_Base_F { displayName = CSTRING(SMG_02_Name); }; - + class Weapon_SMG_05_F: Weapon_Base_F { displayName = CSTRING(SMG_05); }; - + class Weapon_hgun_PDW2000_F: Weapon_Base_F { displayName = CSTRING(hgun_PDW2000_Name); }; @@ -652,21 +737,25 @@ class CfgVehicles { // APEX/Tanoa // Jeep Wrangler - class Offroad_02_unarmed_base_F; + class Offroad_02_base_F; + class Offroad_02_unarmed_base_F : Offroad_02_base_F {}; class 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); + class I_C_Offroad_02_unarmed_F: Offroad_02_unarmed_base_F { + displayName = CSTRING(C_Offroad_02_unarmed); }; - class C_Offroad_02_unarmed_F_blue: C_Offroad_02_unarmed_F { - displayName = CSTRING(C_Offroad_02_unarmed_blue); + class Offroad_02_at_base_F: Offroad_02_base_F { + displayName = CSTRING(C_Offroad_02_at); }; - class C_Offroad_02_unarmed_F_green: C_Offroad_02_unarmed_F { - displayName = CSTRING(C_Offroad_02_unarmed_green); + class I_C_Offroad_02_at_F: Offroad_02_at_base_F { + displayName = CSTRING(C_Offroad_02_at); }; - class C_Offroad_02_unarmed_F_orange: C_Offroad_02_unarmed_F { - displayName = CSTRING(C_Offroad_02_unarmed_orange); + class Offroad_02_lmg_base_F: Offroad_02_base_F { + displayName = CSTRING(C_Offroad_02_lmg); + }; + class I_C_Offroad_02_lmg_F: Offroad_02_lmg_base_F { + displayName = CSTRING(C_Offroad_02_lmg); }; // Cessna @@ -677,10 +766,91 @@ 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); + }; + class LSV_01_AT_base_F : LSV_01_base_F { + displayName = CSTRING(lsv_01_at); + }; + + // 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); + }; + class LSV_02_AT_base_F : LSV_02_base_F { + displayName = CSTRING(lsv_02_at); + }; + + // Rooikat 120 (Rhino MGS) + class AFV_Wheeled_01_base_F; + class B_AFV_Wheeled_01_cannon_F : AFV_Wheeled_01_base_F { + displayName = CSTRING(afv_wheeled_01); + }; + class B_T_AFV_Wheeled_01_cannon_F : AFV_Wheeled_01_base_F { + displayName = CSTRING(afv_wheeled_01); + }; + class AFV_Wheeled_01_up_base_F; + class B_AFV_Wheeled_01_up_cannon_F : AFV_Wheeled_01_up_base_F { + displayName = CSTRING(afv_wheeled_01_up); + }; + class B_T_AFV_Wheeled_01_up_cannon_F : AFV_Wheeled_01_up_base_F { + displayName = CSTRING(afv_wheeled_01_up); + }; + + // T-14 Armata (T-140 Angara) + class MBT_04_cannon_base_F; + class O_MBT_04_cannon_F : MBT_04_cannon_base_F { + displayName = CSTRING(MBT_04_cannon); + }; + class O_T_MBT_04_cannon_F : MBT_04_cannon_base_F { + displayName = CSTRING(MBT_04_cannon); + }; + class MBT_04_command_base_F; // Keep "K" designation for command variant. + class O_MBT_04_command_F : MBT_04_command_base_F { + displayName = CSTRING(MBT_04_command); + }; + class O_T_MBT_04_command_F : MBT_04_command_base_F { + displayName = CSTRING(MBT_04_command); + }; + + // Wiesel 2 (AWC 302 Nyx) + class LT_01_AA_base_F; + class I_LT_01_AA_F : LT_01_AA_base_F { + displayName = CSTRING(LT_01_AA); + }; + class LT_01_AT_base_F; + class I_LT_01_AT_F : LT_01_AT_base_F { + displayName = CSTRING(LT_01_AT); + }; + class LT_01_cannon_base_F; + class I_LT_01_cannon_F : LT_01_cannon_base_F { + displayName = CSTRING(LT_01_cannon); + }; + class LT_01_scout_base_F; + class I_LT_01_scout_F : LT_01_scout_base_F { + displayName = CSTRING(LT_01_scout); + }; + }; diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index 2654dc0df7..6959334fb6 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -192,6 +192,14 @@ class CfgWeapons { displayName = CSTRING(launch_NLAW_Name); }; + class launch_Vorona_base_F; + class launch_O_Vorona_brown_F : launch_Vorona_base_F { + displayName = CSTRING(launch_Vorona_brown); + }; + class launch_O_Vorona_green_F : launch_Vorona_base_F { + displayName = CSTRING(launch_Vorona_green); + }; + // marksmen marksman class DMR_02_base_F: Rifle_Long_Base_F { displayName = CSTRING(DMR_02); //MAR-10 .338; @@ -232,9 +240,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; }; @@ -319,7 +324,7 @@ class CfgWeapons { }; }; - class gatling_30mm: CannonCore { // This is a fictional veresion of the GSh-6-30, with 3 barrels + class gatling_30mm_base: CannonCore { // This is a fictional version of the GSh-6-30, with 3 barrels displayName = "GSh-3-30"; class LowROF: Mode_FullAuto { displayName = "GSh-3-30"; @@ -351,11 +356,17 @@ class CfgWeapons { class MissileLauncher; class Missile_AGM_02_Plane_CAS_01_F: MissileLauncher { - displayName = "AGM-65 Maverick"; + displayName = "AGM-65 Maverick G"; }; + class weapon_AGM_65Launcher: RocketPods { + displayName = "AGM-65 Maverick G"; + }; class Missile_AGM_01_Plane_CAS_02_F: Missile_AGM_02_Plane_CAS_01_F { displayName = "Kh-25MTP"; }; + class missiles_Vorona : MissileLauncher { + displayName = CSTRING(missiles_vorona); + }; // rockets class Rocket_04_HE_Plane_CAS_01_F: RocketPods { @@ -416,9 +427,7 @@ class CfgWeapons { }; // bomb - class Bomb_04_Plane_CAS_01_F: RocketPods { - //displayName = ""; - }; + class Bomb_04_Plane_CAS_01_F; class Bomb_03_Plane_CAS_02_F: Bomb_04_Plane_CAS_01_F { displayName = "FAB-250M-54"; }; @@ -446,6 +455,11 @@ class CfgWeapons { }; }; + class HMG_127_APC : HMG_127 {}; + class ACE_HMG_127_KORD : HMG_127_APC { + displayName = "6P49 Kord"; + }; + class HMG_01: HMG_127 { displayName = "XM312"; }; @@ -489,6 +503,10 @@ class CfgWeapons { displayName = "Mini-Spike"; }; + class missiles_SAAMI : MissileLauncher { + displayName = "FIM-92F"; + }; + // mortar class mortar_155mm_AMOS: CannonCore { displayName = "L/52"; @@ -510,6 +528,10 @@ class CfgWeapons { class player: player {}; }; + class ACE_cannon_120mm_GT12: cannon_120mm { + displayName = "GT12"; + }; + class cannon_105mm: CannonCore { displayName = "M68"; class player: Mode_SemiAuto { @@ -520,13 +542,17 @@ class CfgWeapons { class cannon_125mm: CannonCore { displayName = "2A46"; }; + + class cannon_125mm_advanced : cannon_125mm { + displayName = "2A82-1M"; + }; // coax machine guns class LMG_coax: LMG_RCWS { displayName = "PKT"; }; - // class ACE_LMG_coax_PKT_mem2: LMG_coax {}; - class ACE_LMG_coax_MAG58_mem2: LMG_coax { + class LMG_coax_ext: LMG_coax {}; + class ACE_LMG_coax_ext_MAG58: LMG_coax_ext { displayName = "MAG 58M"; }; class ACE_LMG_coax_MAG58_mem3: LMG_coax { @@ -535,6 +561,12 @@ class CfgWeapons { class ACE_LMG_coax_L94A1_mem3: LMG_coax { displayName = "L94A1"; }; + class ACE_LMG_coax_ext_MG3: LMG_coax_ext { + displayName = "H&K MG3"; + }; + class ACE_LMG_coax_DenelMG4 : LMG_coax { + displayName = "Denel MG4"; + }; // more autocannons class autocannon_Base_F; @@ -549,6 +581,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 { @@ -570,6 +612,24 @@ class CfgWeapons { displayName = "L21A1 RARDEN"; }; }; + + class autocannon_30mm_RCWS : autocannon_Base_F { + displayName = "2A42"; + }; + + class cannon_20mm : autocannon_Base_F { + class AP : autocannon_Base_F {}; + class HE : autocannon_Base_F {}; + }; + class ACE_cannon_20mm_Rh202 : cannon_20mm { + displayName = "MK20 Rh 202"; + class AP: AP { + displayName = "MK20 Rh 202"; + }; + class HE: HE { + displayName = "MK20 Rh 202"; + }; + }; //attachments @@ -579,6 +639,90 @@ class CfgWeapons { displayName = "UTG Defender 126"; }; + class optic_hamr : ItemCore { + displayName = CSTRING(optic_hamr); + }; + class optic_Hamr_khk_F : optic_hamr { + displayName = CSTRING(optic_hamr_khk); + }; + + class optic_Arco : ItemCore { + displayName = CSTRING(optic_arco); + }; + class optic_Arco_blk_F : optic_Arco { + displayName = CSTRING(optic_arco_blk); + }; + class optic_Arco_ghex_F : optic_Arco { + displayName = CSTRING(optic_arco_ghex); + }; + + class optic_ERCO_blk_f : optic_Arco { + displayName = CSTRING(optic_erco_blk); + }; + class optic_ERCO_khk_f : optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_khk); + }; + class optic_ERCO_snd_f : optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_snd); + }; + + class optic_LRPS : ItemCore { + displayName = CSTRING(optic_lrps); + }; + class optic_LRPS_ghex_F : optic_LRPS { + displayName = CSTRING(optic_lrps_ghex); + }; + class optic_LRPS_tna_F : optic_LRPS { + displayName = CSTRING(optic_lrps_tna); + }; + + class optic_DMS : ItemCore { + displayName = CSTRING(optic_dms); + }; + class optic_DMS_ghex_F : optic_DMS { + displayName = CSTRING(optic_dms_ghex); + }; + + class optic_holosight : ItemCore { + displayName = CSTRING(optic_holosight); + }; + class optic_Holosight_blk_F : optic_holosight { + displayName = CSTRING(optic_holosight_blk); + }; + class optic_Holosight_khk_F : optic_holosight { + displayName = CSTRING(optic_holosight_khk); + }; + class optic_Holosight_smg : ItemCore { + displayName = CSTRING(optic_holosight_smg); + }; + class optic_Holosight_smg_blk_F : optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_blk); + }; + class optic_Holosight_smg_khk_F : optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_khk); + }; + + class optic_MRCO : ItemCore { + displayName = CSTRING(optic_MRCO); + }; + + class optic_Yorris : ItemCore { + displayName = CSTRING(optic_Yorris); + }; + + class optic_ACO : ItemCore { + displayName = CSTRING(optic_ACO); + }; + class optic_ACO_grn : ItemCore { + displayName = CSTRING(optic_ACO_grn); + }; + class optic_ACO_smg : ItemCore { + displayName = CSTRING(optic_ACO_smg); + }; + class optic_ACO_grn_smg : ItemCore { + displayName = CSTRING(optic_ACO_grn_smg); + }; + // APEX/Tanoa // QBZ-95 and variants @@ -586,14 +730,33 @@ class CfgWeapons { class arifle_CTAR_blk_F: arifle_CTAR_base_F { displayName = CSTRING(arifle_CTAR_blk); }; + class arifle_CTAR_ghex_F: arifle_CTAR_base_F { + displayName = CSTRING(arifle_CTAR_ghex); + }; + class arifle_CTAR_hex_F: arifle_CTAR_base_F { + displayName = CSTRING(arifle_CTAR_hex); + }; class arifle_CTAR_GL_base_F; class arifle_CTAR_GL_blk_F: arifle_CTAR_GL_base_F { displayName = CSTRING(arifle_CTAR_GL_blk); }; + class arifle_CTAR_GL_ghex_F: arifle_CTAR_GL_base_F { + displayName = CSTRING(arifle_CTAR_GL_ghex); + }; + class arifle_CTAR_GL_hex_F: arifle_CTAR_GL_base_F { + displayName = CSTRING(arifle_CTAR_GL_hex); + }; + class arifle_CTARS_base_F; class arifle_CTARS_blk_F: arifle_CTARS_base_F { displayName = CSTRING(arifle_CTARS_blk); }; + class arifle_CTARS_ghex_F: arifle_CTARS_base_F { + displayName = CSTRING(arifle_CTARS_ghex); + }; + class arifle_CTARS_hex_F: arifle_CTARS_base_F { + displayName = CSTRING(arifle_CTARS_hex); + }; // QBU-88 class DMR_07_base_F; diff --git a/addons/realisticnames/dev_dumpPylon.sqf b/addons/realisticnames/dev_dumpPylon.sqf new file mode 100644 index 0000000000..df0d7ea4a5 --- /dev/null +++ b/addons/realisticnames/dev_dumpPylon.sqf @@ -0,0 +1,29 @@ +// [] execVM "z\ace\addons\realisticnames\dev_dumpPylon.sqf"; + +private _justLog = true; + +diag_log text format ["[Dumping Pylons] --------------------"]; +private _magazines = configProperties [configFile >> "CfgMagazines", "isClass _x", true]; +{ + private _pylonWeapon = getText (_x >> "pylonWeapon"); + if (_pylonWeapon != "") then { + private _weaponConfig = configFile >> "CfgWeapons" >> _pylonWeapon; + private _weaponName = getText (_weaponConfig >> "displayName"); + private _inherit = (configProperties [_x, "configName _x == 'displayName'", false]) isEqualTo []; + private _pylonMagName = getText (_x >> "displayName"); + if (_justLog) then { + if (!_inherit) then { + diag_log text format ["%1: [%2 vs %3]", configName _x, _pylonMagName, _weaponName]; + } else { + diag_log text format [" - %1: [%2 vs %3]", configName _x, _pylonMagName, _weaponName]; + }; + } else { + if (!_inherit) then { + diag_log text format ['class %1;', configName inheritsFrom _x]; + diag_log text format ['class %1: %2 {', configName _x, configName inheritsFrom _x]; + diag_log text format ['displayName = "%1"; [vanilla: %2 - %3]', _weaponName, _pylonMagName, _pylonWeapon]; + diag_log text format ['};', configName _x, configName inheritsFrom _x, _weaponName, _pylonMagName]; + }; + }; + }; +} forEach _magazines; diff --git a/addons/realisticnames/script_component.hpp b/addons/realisticnames/script_component.hpp index dda1fc93c5..e873ddee0c 100644 --- a/addons/realisticnames/script_component.hpp +++ b/addons/realisticnames/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_REALISTICNAMES diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 8f8134e5a5..3218ca27d5 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ XM312 XM312 XM312A + XM312 + XM312 + XM312重機槍 + XM312重机枪 XM312A @@ -24,6 +28,10 @@ XM312A XM312A XM312A + XM312A + XM312A + XM312A重機槍 + XM312A重机枪 XM312 (High) @@ -36,6 +44,10 @@ XM312 (Alta) XM312 (Magasított) XM312 (Alta) + XM312 (高) + XM312 (높음) + XM312重機槍 (高射腳架) + XM312重机枪 (高射脚架) XM307 @@ -48,6 +60,10 @@ XM307 XM307 XM307 + XM307 + XM307 + XM307榴彈機槍 + XM307榴弹机枪 XM307A @@ -60,6 +76,10 @@ XM307A XM307A XM307A + XM307A + XM307A + XM307A榴彈機槍 + XM307A榴弹机枪 XM307 (High) @@ -72,6 +92,10 @@ XM307 (Alta) XM307 (Magasított) XM307 (Alta) + XM307 (高) + XM307 (높음) + XM307榴彈機槍 (高射腳架) + XM307榴弹机枪 (高射脚架) Mini-Spike Launcher (AT) @@ -84,6 +108,10 @@ Lança-mísseis Mini-Spike (AC) Mini-Spike rakétarendszer (Tankelhárító) Lanciatore Mini-Spike (AC) + ミニスパイク ランチャー (対戦) + Mini-Spike Launcher (대전차) + "迷你長釘"導彈發射器 (反坦克) + "迷你长钉"导弹发射器 (反坦克) Mini-Spike Launcher (AA) @@ -96,6 +124,10 @@ Lança-mísseis Mini-Spike (AA) Mini-Spike rakétarendszer (Repülő-elhárító) Lanciatore Mini-Spike (AA) + ミニスパイク ランチャー (対空) + Mini-Spike Launcher (대공) + "迷你長釘"導彈發射器 (防空) + "迷你长钉"导弹发射器 (防空) YABHON-R3 @@ -108,6 +140,10 @@ YABHON-R3 YABHON-R3 YABHON-R3 + YABHON-R3 + YABHON-R3 + "亞伯罕-R3型"空中無人載具 + "亚伯罕-R3型"空中无人载具 YABHON-R3 (CAS) @@ -120,6 +156,10 @@ YABHON-R3 (Légitámogató) YABHON-R3 (CAS) YABHON-R3 (CAS) + YABHON-R3 (対地) + YABHON-R3 (근접지원) + "亞伯罕-R3型"空中無人載具 (近空支援) + "亚伯罕-R3型"空中无人载具 (近空支援) M-ATV @@ -132,10 +172,14 @@ M-ATV M-ATV M-ATV + M-ATV + M-ATV + 防地雷反伏擊全地形車 + 防地雷反伏击全地形车 M-ATV (HMG) - M-ATV (SMG) + M-ATV (sMG) M-ATV (HMG) M-ATV (CKM) M-ATV (HMG) @@ -144,6 +188,10 @@ M-ATV (HMG) M-ATV (nehézgéppuska) M-ATV (HMG) + M-ATV (HMG) + M-ATV (HMG) + 防地雷反伏擊全地形車 (重機槍) + 防地雷反伏击全地形车 (重机枪) M-ATV (GMG) @@ -156,6 +204,10 @@ M-ATV (GMG) M-ATV (gránátgéppuska) M-ATV (GMG) + M-ATV (GMG) + M-ATV (GMG) + 防地雷反伏擊全地形車 (榴彈機槍) + 防地雷反伏击全地形车 (榴弹机枪) Merkava Mk IV M @@ -168,6 +220,10 @@ Merkava Mk IV M Merkava Mk IV M Merkava Mk IV M + メルカバ Mk IV M + Merkava Mk IV M + "梅卡瓦4代"主戰坦克 + "梅卡瓦4代"主战坦克 Merkava Mk IV LIC @@ -180,6 +236,10 @@ Merkava Mk IV LIC Merkava Mk IV LIC Merkava Mk IV LIC + メルカバ Mk IV LIC + Merkava Mk IV LIC + "梅卡瓦4代"主戰坦克 城市版 + "梅卡瓦4代"主战坦克 城市版 Sholef @@ -192,6 +252,10 @@ Sholef Sholef Sholef + ショルフ + Sholef + "神槍"自走炮 + "神枪"自走炮 Seara @@ -204,6 +268,10 @@ Seara Seara Seara + シアラ + Seara + "希拉"多管火箭車 + "希拉"多管火箭车 Namer @@ -216,6 +284,10 @@ Namer Namer Namer + ネイマー + Namer + "花豹"裝甲運兵車 + "花豹"装甲运兵车 Bardelas @@ -228,6 +300,10 @@ Bardelas Bardelas Bardelas + バーラデラス + Bardelas + "布萊德斯"防空車 + "布莱德斯"防空车 Badger IFV @@ -240,6 +316,10 @@ Badger IFV Badger IFV Badger IFV + バッジ IFV + Badger IFV + "蜜獾"步兵戰車 + "蜜獾"步兵战车 Nemmera @@ -252,6 +332,10 @@ Nemmera Nemmera Nemmera + ネマラ + Nemmera + "雌豹"戰鬥工程車 + "雌豹"战斗工程车 HEMTT Transport @@ -264,6 +348,10 @@ HEMTT Transporte HEMTT szállítójármű HEMTT da trasporto + HEMTT 輸送型 + HEMTT 수송 + 重型增程機動戰術卡車 (運輸) + 重型增程机动战术卡车 (运输) HEMTT Transport (covered) @@ -276,6 +364,10 @@ HEMTT Transporte (coberto) HEMTT szállítójármű (ponyvás) HEMTT da trasporto (coperto) + HEMTT 輸送型 (幌) + HEMTT 수송 (덮개) + 重型增程機動戰術卡車 (運輸, 棚布) + 重型增程机动战术卡车 (运输, 棚布) HEMTT @@ -288,6 +380,10 @@ HEMTT HEMTT HEMTT + HEMTT + HEMTT + 重型增程機動戰術卡車 + 重型增程机动战术卡车 HEMTT Container @@ -299,7 +395,11 @@ HEMTT Контейнер HEMTT Contêiner HEMTT (konténer) - HEMTT portacontainer + HEMTT portacontainer + HEMTT コンテナ型 + HEMTT 컨테이너 + 重型增程機動戰術卡車 (貨櫃) + 重型增程机动战术卡车 (货柜) HEMTT Medical @@ -312,6 +412,10 @@ HEMTT Médico HEMTT (egészségügyi) HEMTT Medico + HEMTT 救急車 + HEMTT 의료 + 重型增程機動戰術卡車 (醫療) + 重型增程机动战术卡车 (医疗) HEMTT Ammo @@ -324,6 +428,10 @@ HEMTT Munições HEMTT (lőszerszállító) HEMTT di rifornimento munizioni + HEMTT 弾薬給弾型 + HEMTT 탄약 + 重型增程機動戰術卡車 (彈藥) + 重型增程机动战术卡车 (弹药) HEMTT Fuel @@ -336,6 +444,10 @@ HEMTT Combustível HEMTT (üzemanyag-szállító) HEMTT di rifornimento carburante + HEMTT 燃料給油車 + HEMTT 연료 + 重型增程機動戰術卡車 (燃油) + 重型增程机动战术卡车 (燃油) HEMTT Repair @@ -348,6 +460,10 @@ HEMTT Reparador HEMTT (szerelő-jármű) HEMTT Riparatore + HEMTT 修理型 + HEMTT 수리 + 重型增程機動戰術卡車 (維修) + 重型增程机动战术卡车 (维修) Fennek @@ -360,10 +476,14 @@ Fennek Fennek Fennek + フェネック + Fennek + "非洲小狐"防地雷反伏擊車 + "非洲小狐"防地雷反伏击车 Fennek (HMG) - Fennek (SMG) + Fennek (sMG) Fennek (HMG) Fennek (CKM) Fennek (HMG) @@ -372,6 +492,10 @@ Fennek (HMG) Fennek (nehézgéppuska) Fennek (HMG) + フェネック (HMG) + Fennek (HMG) + "非洲小狐"防地雷反伏擊車 (重機槍) + "非洲小狐"防地雷反伏击车 (重机枪) Fennek (GMG) @@ -384,6 +508,10 @@ Fennek (GMG) Fennek (gránátgéppuska) Fennek (GMG) + フェネック (GMG) + Fennek (GMG) + "非洲小狐"防地雷反伏擊車 (榴彈機槍) + "非洲小狐"防地雷反伏击车 (榴弹机枪) Leopard 2SG @@ -396,6 +524,10 @@ Leopard 2SG Leopard 2SG Leopard 2SG + レオパルド 2SG + Leopard 2SG + "豹2型新加坡版"主戰坦克 + "豹2型新加坡版"主战坦克 FV510 Warrior @@ -408,6 +540,10 @@ FV510 Warrior FV510 Warrior FV510 Warrior + FV510 ウォーリアー + FV510 Warrior + FV510"戰士"步兵戰車 + FV510"战士"步兵战车 Pandur II @@ -420,10 +556,14 @@ Pandur II Pandur II Pandur II + パンデュール II + Pandur II + "潘德2型"裝甲運兵車 + "潘德2型"装甲运兵车 KamAZ Transport - KamAZ Transport + KamAS Transport KamAZ de transporte KamAZ transportowy KamAZ (valník) @@ -432,10 +572,14 @@ KamAZ Transporte KamAZ szállítójármű KamAZ da trasporto + KamAZ 輸送型 + KamAZ 수송 + "卡瑪斯"卡車 (運輸) + "卡玛斯"卡车 (运输) KamAZ Transport (covered) - KamAZ Transport (bedeckt) + KamAS Transport (bedeckt) KamAZ de transporte (cubierto) KamAZ Transportowy (zakryty) KamAZ (valník-krytý) @@ -444,10 +588,14 @@ KamAZ Transporte (coberto) KamAZ szállítójármű (ponyvás) KamAZ da trasporto (coperto) + KamAZ 輸送型 (幌) + KamAZ 수송 (덮개) + "卡瑪斯"卡車 (運輸, 棚布) + "卡玛斯"卡车 (运输, 棚布) KamAZ Ammo - KamAZ Munition + KamAS Munition KamAZ de munición KamAZ Amunicyjny KamAZ (muniční) @@ -456,10 +604,14 @@ KamAZ Munições KamAZ (lőszerszállító) KamAZ di rifornimento munizioni + KamAZ 弾薬給弾型 + KamAZ 탄약 + "卡瑪斯"卡車 (彈藥) + "卡玛斯"卡车 (弹药) KamAZ Fuel - KamAZ Treibstoff + KamAS Treibstoff KamAZ de combustible KamAZ cysterna KamAZ (cisterna) @@ -468,10 +620,14 @@ KamAZ Combustível KamAZ (üzemanyag-szállító) KamAZ di rifornimento carburante + KamzAZ 燃料給油車 + KamAZ 연료 + "卡瑪斯"卡車 (燃油) + "卡玛斯"卡车 (燃油) KamAZ Repair - KamAZ Instandsetzung + KamAS Instandsetzung KamAZ de reparación KamAZ Naprawczy KamAZ (opravárenský) @@ -480,10 +636,14 @@ KamAZ Reparador KamAZ (szerelő-jármű) KamAZ riparatore + KamzAZ 修理型 + KamAZ 수리 + "卡瑪斯"卡車 (維修) + "卡玛斯"卡车 (维修) KamAZ Medical - KamAZ Sanitäter + KamAS Sanitäter KamAZ médico KamAZ Medyczny KamAZ (zdravotnický) @@ -492,42 +652,65 @@ KamAZ Médico KamAZ (egészségügyi) KamAZ Medico + KamAZ 救急車 + KamAZ 의료 + "卡瑪斯"卡車 (醫療) + "卡玛斯"卡车 (医疗) + + + KamAZ MRL + KamAS MRL + "卡瑪斯"卡車 (多管火箭) + "卡玛斯"卡车 (多管火箭) + KamAZ MRL - Punisher - Punisher - Punisher - Punisher - Punisher - Punisher + Karatel + Karatel + Karatel + Karatel + Karatel + Karatel Kаратель - 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) + 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) + Karatel (GMG) + Karatel (gránátgéppuska) + Karatel (GMG) + カラテル (GMG) + Karatel (GMG) + "懲罰者"防地雷反伏擊車 (榴彈機槍) + "惩罚者"防地雷反伏击车 (榴弹机枪) T100 Black Eagle @@ -540,6 +723,10 @@ T100 Black Eagle T100 Fekete Sas T100 Black Eagle + T100 ブラック イーグル + T100 Black Eagle + T100"黑鷹"主戰坦克 + T100"黑鹰"主战坦克 2S9 Sochor @@ -552,6 +739,10 @@ 2S9 Sochor 2S9 Sochor 2S9 Sochor + 2S9 ソーカー + 2S9 Sochor + 2S9"薩克爾"自走砲 + 2S9"萨克尔"自走炮 BM-2T Stalker @@ -564,6 +755,10 @@ BM-2T Stalker BM-2T Stalker BM-2T Stalker + BM-2T ストーカー + BM-2T Stalker + BM-2T"潛行者"步兵戰車 + BM-2T"潜行者"步兵战车 ZSU-35 Tigris @@ -576,6 +771,10 @@ ZSU-35 Tigris ZSU-35 Tigris ZSU-35 Tigris + ZSU-35 ティグリス + ZSU-35 Tigris + ZSU-35"虎式"防空車 + ZSU-35"虎式"防空车 Otokar ARMA @@ -588,6 +787,10 @@ Otokar ARMA Otokar ARMA Otokar ARMA + オトカ アルマ + Otokar ARMA + "奧托卡-阿爾默"裝甲運兵車 + "奥托卡-阿尔默"装甲运兵车 Typhoon Transport @@ -600,6 +803,10 @@ Typhoon Transporte Typhoon szállítójármű Typhoon da trasporto + タイフーン 輸送型 + Typhoon 수송 + "颱風"卡車 (運輸) + "台风"卡车 (运输) Typhoon Transport (covered) @@ -612,6 +819,10 @@ Typhoon Transporte (coberto) Typhoon szállítójármű (ponyvás) Typhoon da trasporto (coperto) + タイフーン 輸送型 (幌) + Typhoon 수송 (덮개) + "颱風"卡車 (運輸, 棚布) + "台风"卡车 (运输, 棚布) Typhoon Device @@ -624,6 +835,10 @@ Typhoon Dispositivo Typhoon (eszköz) Typhoon per dispositivo + タイフーン デバイス型 + Typhoon 장치 + "颱風"卡車 (精密設備) + "台风"卡车 (精密设备) Typhoon Ammo @@ -636,6 +851,10 @@ Typhoon Munições Typhoon (lőszerszállító) Typhoon di rifornimento munizioni + タイフーン 弾薬給弾型 + Typhoon 탄약 + "颱風"卡車 (彈藥) + "台风"卡车 (弹药) Typhoon Fuel @@ -648,6 +867,10 @@ Typhoon Combustível Typhoon (üzemanyag-szállító) Typhoon di rifornimento carburante + タイフーン 燃料給油車 + Typhoon 연료 + "颱風"卡車 (燃油) + "台风"卡车 (燃油) Typhoon Repair @@ -660,6 +883,10 @@ Typhoon Reparador Typhoon (szerelő-jármű) Typhoon riparatore + タイフーン 修理型 + Typhoon 수리 + "颱風"卡車 (維修) + "台风"卡车 (维修) Typhoon Medical @@ -672,6 +899,10 @@ Typhoon Médico Typhoon (egészségügyi) Typhoon medico + タイフーン 救急車 + Typhoon 의료 + "颱風"卡車 (醫療) + "台风"卡车 (医疗) RAH-66 Comanche @@ -684,6 +915,10 @@ RAH-66 Comanche RAH-66 Comanche RAH-66 Comanche + RAH-66 コマンチ + RAH-66 Comanche + RAH-66"卡曼契"攻擊直升機 + RAH-66"卡曼契"攻击直升机 MH-6 Little Bird @@ -696,6 +931,10 @@ MH-6 Little Bird MH-6 Little Bird MH-6 Little Bird + MH-6 リトル バード + MH-6 Little Bird + MH-6"小鳥"運輸直升機 + MH-6"小鸟"运输直升机 AH-6 Little Bird @@ -708,6 +947,10 @@ AH-6 Little Bird AH-6 Little Bird AH-6 Little Bird + AH-6 リトル バード + AH-6 Little Bird + AH-6"小鳥"武裝直升機 + AH-6"小鸟"武装直升机 CH-47I Chinook @@ -720,6 +963,10 @@ CH-47I Chinook CH-47I Chinook CH-47I Chinook + CH-47I チヌーク + CH-47I Chinook + CH-47I"契努克"運輸直升機 + CH-47I"契努克"运输直升机 CH-47I Chinook (unarmed) @@ -732,6 +979,10 @@ CH-47I Chinook (fegyvertelen) CH-47I Chinook (disarmato) CH-47I Chinook (desarmado) + CH-47I チヌーク (非武装) + CH-47I Chinook (비무장) + CH-47I"契努克"運輸直升機 (無武裝) + CH-47I"契努克"运输直升机 (无武装) A-10D Thunderbolt II @@ -744,6 +995,10 @@ A-10D Thunderbolt II A-10D Thunderbolt II A-10D Thunderbolt II + A-10D サンダーボルト II + A-10D Thunderbolt II + A-10D"雷霆二式"攻擊機 + A-10D"雷霆二式"攻击机 AW159 Wildcat @@ -756,6 +1011,10 @@ AW159 Wildcat AW159 Wildcat AW159 Wildcat + AW159 ワイルドキャット + AW159 Wildcat + AW159"野貓"直升機 + AW159"野猫"直升机 AW159 Wildcat (unarmed) @@ -768,6 +1027,10 @@ AW159 Wildcat (desarmado) AW159 Wildcat (fegyvertelen) AW159 Wildcat (disarmato) + AW159 ワイルドキャット (非武装) + AW159 Wildcat (비무장) + AW159"野貓"直升機 (無武裝) + AW159"野猫"直升机 (无武装) AW101 Merlin @@ -780,6 +1043,26 @@ AW101 Merlin AW101 Merlin AW101 Merlin + AW101 マーリン + AW101 Merlin + AW101"灰背隼"運輸直升機 + AW101"灰背隼"运输直升机 + + + L-159 ALCA + L-159 ALCA + L-159 ALCA + L-159 ALCA + L-159 ALCA + L-159 ALCA + L-159 Альбатрос + L-159 ALCA + L-159 ALCA + L-159 ALCA + L-159 アルカ + L-159 ALCA + L-159先進輕型戰鬥機 + L-159先进轻型战斗机 L-159 ALCA (CAS) @@ -792,6 +1075,10 @@ L-159 ALCA (CAS) L-159 ALCA (Légitámogató) L-159 ALCA (CAS) + L-159 アルカ (対地) + L-159 ALCA (근접지원) + L-159先進輕型戰鬥機 (近空支援) + L-159先进轻型战斗机 (近空支援) L-159 ALCA (AA) @@ -804,6 +1091,25 @@ L-159 ALCA (ВВ) L-159 ALCA (Repülő-elhárító) L-159 ALCA (AA) + L-159 アルカ (対空) + L-159 ALCA (대공) + 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 獅鷲戰鬥機 + JAS 39 狮鹫战斗机 Ka-60 Kasatka @@ -816,6 +1122,10 @@ Ka-60 Kasatka Ka-60 Kasatka Ka-60 Kasatka + Ka-60 カサートカ + Ka-60 Kasatka + Ka-60"逆戟鯨"直升機 + Ka-60"逆戟鲸"直升机 Ka-60 Kasatka (Black & White) @@ -827,6 +1137,10 @@ Ka-60 Kasatka (preto e branco) Ka-60 Касатка (белый и черный) Ka-60 Kasatka (blanco y negro) + Ka-60 カサートカ (黒 & 白) + Ka-60 Kasatka (검정 및 하양) + Ka-60"逆戟鯨"直升機 (黑&白) + Ka-60"逆戟鲸"直升机 (黑&白) Ka-60 Kasatka (unarmed) @@ -839,6 +1153,10 @@ Ka-60 Kasatka (desarmado) Ka-60 Kasatka (fegyvertelen) Ka-60 Kasatka (disarmato) + Ka-60 カサートカ (非武装) + Ka-60 Kasatka (비무장) + Ka-60"逆戟鯨"直升機 (無武裝) + Ka-60"逆戟鲸"直升机 (无武装) Yak-130 @@ -851,6 +1169,10 @@ Yak-130 Jak-130 Yak-130 + Yak-130 + Yak-130 + Yak-130"手套"攻擊機 + Yak-130"手套"攻击机 MD 500 @@ -863,6 +1185,10 @@ MD 500 MD 500 MD 500 + MD 500 + MD 500 + MD 500"防衛者"直升機 + MD 500"防卫者"直升机 M4A1 SLAM @@ -875,6 +1201,10 @@ M4A1 SLAM M4A1 SLAM M4A1 SLAM + M4A1 SLAM + M4A1 SLAM + M4A1指向性反裝甲地雷 + M4A1指向性反装甲地雷 M18A1 Claymore @@ -887,6 +1217,10 @@ M18A1 Claymore M18A1 Claymore akna M18A1 Claymore Mina antiuomo + M18A1 クレイモア + M18A1 클레이모어 + M18A1"闊刀"地雷 + M18A1"阔刀"地雷 M183 Demolition Charge Assembly @@ -899,34 +1233,51 @@ M183 Sacola de Demolição M183 romboló töltet M183 Demolition Charge Assembly + M183 梱包爆薬 + M183 폭파 장약 조립 + M183炸藥包 + M183炸药包 M112 Demolition Block M112 Sprengladung Bloque de demolición M112 Ładunek burzący M112 - Výbušná nálož M112 + Výbušná nálož M112 M112 Block de Démolition M112 подрывной заряд M112 Carga de Demolição M112 romboló tömb - M112 Demolition Block + M112 da Demolizione + M112 爆薬ブロック + M112 폭파 블럭 + M112塑性炸藥 + M112塑性炸药 M67 Fragmentation Grenade M67 Splittergranate Granada de fragmentación M67 Granat obronny M67 - Granát M67 + Granát M67 M67 Grenade à fragmentation M67 ручная осколочная граната M67 Granada de fragmentação M67 repeszgránát M67 Granata a frammentazione + M67 破片手榴弾 + M67 세열 수류탄 + M67破片手榴彈 + M67破片手榴弹 + + + V40 Mini-Grenade + V40 Minigranate + Mini Granata V40 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ý) @@ -935,6 +1286,10 @@ M83 Granada de fumaça (Branca) M83 füstgránát (Fehér) M83 Granata fumogena (Bianco) + M18 煙幕手榴弾 (白) + M83 연막탄 (하양) + M83煙霧彈 (白色) + M83烟雾弹 (白色) M18 Smoke Grenade (Blue) @@ -947,6 +1302,10 @@ M18 Granada de fumaça (Azul) M18 füstgránát (Kék) M18 Granata fumogena (Blu) + M18 煙幕手榴弾 (青) + M18 연막탄 (파랑) + M18煙霧彈 (藍色) + M18烟雾弹 (蓝色) M18 Smoke Grenade (Green) @@ -959,6 +1318,10 @@ M18 Granada de fumaça (Verde) M18 füstgránát (Zöld) M18 Granata fumogena (Verde) + M18 煙幕手榴弾 (緑) + M18 연막탄 (초록) + M18煙霧彈 (綠色) + M18烟雾弹 (绿色) M18 Smoke Grenade (Orange) @@ -971,6 +1334,10 @@ M18 Granada de fumaça (Laranja) M18 füstgránát (Narancssárga) M18 Granata fumogena (Arancione) + M18 煙幕手榴弾 (橙) + M18 연막탄 (주황) + M18煙霧彈 (橘色) + M18烟雾弹 (橘色) M18 Smoke Grenade (Purple) @@ -983,6 +1350,10 @@ M18 Granada de fumaça (Roxa) M18 füstgránát (Lila) M18 Granata fumogena (Viola) + M18 煙幕手榴弾 (紫) + M18 연막탄 (보라) + M18煙霧彈 (紫色) + M18烟雾弹 (紫色) M18 Smoke Grenade (Red) @@ -995,6 +1366,10 @@ M18 Granada de fumaça (Vermelha) M18 füstgránát (Piros) M18 Granata fumogena (Rosso) + M18 煙幕手榴弾 (赤) + M18 연막탄 (빨강) + M18煙霧彈 (紅色) + M18烟雾弹 (红色) M18 Smoke Grenade (Yellow) @@ -1007,18 +1382,26 @@ M18 Granada de fumaça (Amarela) M18 füstgránát (Sárga) M18 Granata fumogena (Giallo) + M18 煙幕手榴弾 (黄) + M18 연막탄 (노랑) + M18煙霧彈 (黃色) + M18烟雾弹 (黄色) M15 Anti-Tank Mine M15 Panzerabwehrmine Mina antitanque M15 Mina przeciwpancerna M15 - M15 Protitanková mina + M15 Protitanková mina M15 Mine antichar M15 противотанковая мина M15 Mina anticarro M15 harckocsiakna M15 Mine anticarro + M15 対戦車地雷 + M15 대전차지뢰 + M15反坦克地雷 + M15反坦克地雷 VS-50 Anti-Personnel Mine @@ -1031,6 +1414,10 @@ VS-50 Mina antipessoal VS-50 gyalogsági taposóakna VS-50 Mine antiuomo + VS-50 対人地雷 + VS-50 대인지뢰 + VS-50反人員地雷 + VS-50反人员地雷 M26 Anti-Personnel Bounding Mine @@ -1043,6 +1430,10 @@ M26 Mina saltadora antipessoal M26 gyalogsági ugróakna M26 Mine saltanti antiuomo + M26 対人跳躍地雷 + M26 대인도약지뢰 + M26反人員彈跳雷 + M26反人员弹跳雷 PMR-3 Anti-Personnel Tripwire Mine @@ -1055,6 +1446,10 @@ PMR-3 Mina antipessoal (armadilha) PMR-3 botlódrótos gyalogsági akna PMR-3 Mine antiuomo + PMR-3 仕掛け型対人地雷 + PMR-3 대인인계철선지뢰 + PMR-3反人員絆線雷 + PMR-3反人员绊线雷 P99 @@ -1067,6 +1462,10 @@ P99 P99 P99 + P99 + P99 + P99手槍 + P99手枪 MP-443 Grach @@ -1079,6 +1478,10 @@ МР-443 "Грач" MP-443 Grach MP-443 Grach + MP-433 グラッチ + MP-443 Grach + MP-443"烏鴉"手槍 + MP-443"乌鸦"手枪 Custom Covert II @@ -1091,6 +1494,10 @@ Custom Covert II Custom Covert II ACP-C2 + カスタム コンバート II + Custom Covert II + 特裝隱蔽Ⅱ型手槍 + 特装隐蔽Ⅱ型手枪 FNX-45 Tactical @@ -1103,6 +1510,10 @@ FNX-45 Tactical FNX-45 Tactical FNX-45 Tactical + FNX-45 タクティカル + FNX-45 Tactical + FNX-45戰術型手槍 + FNX-45战术型手枪 Chiappa Rhino 60DS @@ -1115,6 +1526,10 @@ Chiappa Rhino 60DS Chiappa Rhino 60DS Chiappa Rhino 6DS + チアッパ ライノ 60DS + Chiappa Rhino 60DS + 齊亞帕"犀牛"60DS左輪手槍 + 齐亚帕"犀牛"60DS左轮手枪 Taurus Judge @@ -1127,6 +1542,10 @@ Taurus Judge Taurus Judge Taurus Judge + タウルス ジャッジ + Taurus Judge + 金牛座"法官"信號槍 + 金牛座"法官"信号枪 NLAW @@ -1139,6 +1558,10 @@ NLAW NLAW NLAW + NLAW + NLAW + 次世代輕型反坦克導彈發射器 + 次世代轻型反坦克导弹发射器 RPG-32 @@ -1151,6 +1574,10 @@ РПГ-32 RPG-32 RPG-32 + RPG-32 + RPG-32 + RPG-32"哈希姆"火箭發射器 + RPG-32"哈希姆"火箭发射器 Mini-Spike (AA) @@ -1163,6 +1590,10 @@ Mini-Spike (AA) Mini-Spike (AA) Mini-Spike (AA) + ミニスパイク (対空) + Mini-Spike (대공) + "迷你長釘"導彈發射器 (防空) + "迷你长钉"导弹发射器 (防空) Mini-Spike (AT) @@ -1175,6 +1606,37 @@ Mini-Spike (AT) Mini-Spike (AT) Mini-Spike (AT) + ミニスパイク (対地) + Mini-Spike (대전차) + "迷你長釘"導彈發射器 (反坦克) + "迷你长钉"导弹发射器 (反坦克) + + + Metis-M + Metis-M + Metis-M + Метис-М + "麥士蒂索人"-M型反坦克導彈 + "麦士蒂索人"-M型反坦克导弹 + Metis-M + + + Metis-M (Brown) + Metis-M (Braun) + Metis-M (Brun) + Метис-М (Кори́чневый) + "麥士蒂索人"-M型反坦克導彈(棕色) + "麦士蒂索人"-M型反坦克导弹(棕色) + Metis-M (Marrone) + + + Metis-M (Green) + Metis-M (Grün) + Metis-M (Verde) + Метис-М (Зелёный) + "麥士蒂索人"-M型反坦克導彈(綠色) + "麦士蒂索人"-M型反坦克导弹(绿色) + Metis-M (Verde) MX @@ -1187,6 +1649,10 @@ MX MX MX + MX + MX + MX突擊步槍 + MX突击步枪 MX (Black) @@ -1199,6 +1665,10 @@ MX (Чёрный) MX (Preto) MX (Nero) + MX (黒) + MX (검정) + MX突擊步槍 (黑色) + MX突击步枪 (黑色) MXC @@ -1211,6 +1681,10 @@ MXC MXC MXC + MXC + MXC + MXC卡賓步槍 + MXC卡宾步枪 MXC (Black) @@ -1223,6 +1697,10 @@ MXC (Чёрный) MXC (Preto) MXC (Nero) + MXC (黒) + MXC (검정) + MXC卡賓步槍 (黑色) + MXC卡宾步枪 (黑色) MX 3GL @@ -1235,6 +1713,10 @@ MX 3GL MX 3GL MX 3GL + MX 3GL + MX 3GL + MX突擊步槍 (3連裝榴彈) + MX突击步枪 (3连装榴弹) MX 3GL (Black) @@ -1247,6 +1729,10 @@ MX 3GL (Чёрный) MX 3GL (Preto) MX 3GL (Nero) + MX 3GL (黒) + MX 3GL (검정) + MX突擊步槍 (3連裝榴彈-黑色) + MX突击步枪 (3连装榴弹-黑色) MX LSW @@ -1259,6 +1745,10 @@ MX LSW MX LSW MX LSW + MX LSW + MX LSW + MX輕型機槍 + MX轻型机枪 MX LSW (Black) @@ -1271,6 +1761,10 @@ MX LSW (Чёрный) MX LSW (Preto) MX LSW (Nero) + MX LSW (黒) + MX LSW (검정) + MX輕型機槍 (黑色) + MX轻型机枪 (黑色) MXM @@ -1283,6 +1777,10 @@ MXM MXM MXM + MXM + MXM + MXM精準步槍 + MXM精准步枪 MXM (Black) @@ -1295,6 +1793,10 @@ MXM (Чёрный) MXM (Preto) MXM (Nero) + MXM (黒) + MXM (검정) + MXM精準步槍 (黑色) + MXM精准步枪 (黑色) KH2002 Sama @@ -1307,6 +1809,10 @@ KH2002 Сама KT2002 Sama KT2002 Katiba + KH2002 サマ + KH2002 Sama + KH2002"海白爾"突擊步槍 + KH2002"海白尔"突击步枪 KH2002C Sama @@ -1319,6 +1825,10 @@ KH2002C Сама KT2002C Sama KT2002C Katiba + KH2002C サマ + KH2002C Sama + KH2002C"海白爾"卡賓步槍 + KH2002C"海白尔"卡宾步枪 KH2002 Sama KGL @@ -1331,6 +1841,10 @@ KH2002 Сама KGL KT2002 Sama KGL KT2002 Katiba KGL + KH2002 サマ KGL + KH2002 Sama KGL + KH2002"海白爾"突擊步槍 (榴彈) + KH2002"海白尔"突击步枪 (榴弹) F2000 (Camo) @@ -1343,6 +1857,10 @@ F2000 (Камо) F2000 (Camo) F2000 (Camo) + F2000 (迷彩) + F2000 (위장) + F2000突擊步槍 (迷彩) + F2000突击步枪 (迷彩) F2000 @@ -1355,6 +1873,10 @@ F2000 F2000 F2000 + F2000 + F2000 + F2000突擊步槍 + F2000突击步枪 F2000 Tactical (Camo) @@ -1367,6 +1889,10 @@ F2000 Tactical (Камо) F2000 Tactical (Camo) F2000 Tactical (Camo) + F2000 タクティカル (迷彩) + F2000 Tactical (위장) + F2000戰術型突擊步槍 (迷彩) + F2000战术型突击步枪 (迷彩) F2000 Tactical @@ -1379,6 +1905,10 @@ F2000 Tactical F2000 Tactical F2000 Tactical + F2000 タクティカル + F2000 Tactical + F2000戰術型突擊步槍 + F2000战术型突击步枪 F2000 EGLM (Camo) @@ -1391,6 +1921,10 @@ F2000 EGLM (Камо) F2000 EGLM (Camo) F2000 EGLM (Camo) + F2000 EGLM (迷彩) + F2000 EGLM (위장) + F2000突擊步槍 (榴彈-迷彩) + F2000突击步枪 (榴弹-迷彩) F2000 EGLM @@ -1403,6 +1937,10 @@ F2000 EGLM F2000 EGLM F2000 EGLM + F2000 EGLM + F2000 EGLM + F2000突擊步槍 (榴彈) + F2000突击步枪 (榴弹) TAR-21 @@ -1415,6 +1953,10 @@ TAR-21 TAR-21 TAR-21 + TAR-21 + TAR-21 + TAR-21突擊步槍 + TAR-21突击步枪 CTAR-21 @@ -1427,18 +1969,26 @@ CTAR-21 CTAR-21 CTAR-21 + CTAR-21 + CTAR-21 + CTAR-21卡賓步槍 + 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 + 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 @@ -1451,6 +2001,10 @@ Vector SMG Vector SMG Vector SMG + ベクター SMG + Vector SMG + "維克特"衝鋒槍 + "维克特"冲锋枪 Scorpion Evo 3 A1 @@ -1463,6 +2017,10 @@ Scorpion Evo 3 A1 Scorpion Evo 3 A1 Scorpion Evo 3 A1 + スコーピオン エボ 3 A1 + Scorpion Evo 3 A1 + "蠍式"Evo 3 A1衝鋒槍 + "蝎式"Evo 3 A1冲锋枪 CPW @@ -1475,6 +2033,10 @@ CPW CPW CPW + CPW + CPW + 緊湊型個人衝鋒槍 + 紧凑型个人冲锋枪 RFB SDAR @@ -1487,6 +2049,10 @@ RFB SDAR RFB SDAR RFB SDAR + RFB SDAR + RFB SDAR + 犢牛式水陸兩用步槍 + 犊牛式水陆两用步枪 Stoner 99 LMG @@ -1499,6 +2065,10 @@ Stoner 99 LMG Stoner 99 LMG Stoner 99 LMG + ストーナー 99 LMG + Stoner 99 LMG + 斯通納99輕機槍 + 斯通纳99轻机枪 Negev NG7 @@ -1511,6 +2081,10 @@ Negev NG7 Negev NG7 Negev NG7 + ネゲフ NG7 + Negev NG7 + 內蓋夫NG7機槍 + 内盖夫NG7机枪 Mk14 Mod 1 EBR @@ -1523,6 +2097,10 @@ Mk14 Mod 1 EBR Mk14 Mod 1 EBR Mk14 Mod 1 EBR + Mk14 Mod 1 EBR + Mk14 Mod 1 EBR + Mk14一型增強型戰鬥步槍 + Mk14一型增强型战斗步枪 GM6 Lynx @@ -1535,6 +2113,10 @@ GM6 Lynx GM6 Lynx GM6 Lynx + GM6 リンクス + GM6 Lynx + GM6"天貓"反器材狙擊步槍 + GM6"天猫"反器材狙击步枪 GM6 Lynx (Camo) @@ -1547,6 +2129,10 @@ GM6 Lynx (Камо) GM6 Lynx (Camo) GM6 Lynx (Camo) + GM6 リンクス (迷彩) + GM6 Lynx (위장) + GM6"天貓"反器材狙擊步槍 (迷彩) + GM6"天猫"反器材狙击步枪 (迷彩) M200 Intervention @@ -1559,6 +2145,10 @@ M200 Intervention M200 Intervention M200 Intervention + M200 インターベンション + M200 Intervention + M200干預型狙擊步槍 + M200干预型狙击步枪 M200 Intervention (Camo) @@ -1571,6 +2161,10 @@ M200 Intervention (Камо) M200 Intervention (Camo) M200 Intervention (Camo) + M200 インターベンション (迷彩) + M200 Intervention (위장) + M200干預型狙擊步槍 (迷彩) + M200干预型狙击步枪 (迷彩) VS-121 @@ -1583,6 +2177,10 @@ VS-121 VS-121 VS-121 + VS-121 + VS-121 + VS-121狙擊步槍 + VS-121狙击步枪 Noreen "Bad News" ULR @@ -1595,6 +2193,10 @@ Noreen "Bad News" ULR Noreen "Bad News"ULR Noreen "Bad News" ULR + ノレーン "バッド ニュース" ULR + Noreen "Bad News" ULR + 諾琳"壞消息"極距狙擊步槍 + 诺琳"坏消息"极距狙击步枪 Noreen "Bad News" ULR (Black) @@ -1607,6 +2209,10 @@ Noreen "Bad News" ULR (Nero) Noreen "Bad News"ULR (Fekete) Noreen "Bad News" ULR (Preto) + ノレーン "バッド ニュース" ULR (黒) + Noreen "Bad News" ULR (검정) + 諾琳"壞消息"極距狙擊步槍 (黑色) + 诺琳"坏消息"极距狙击步枪 (黑色) Noreen "Bad News" ULR (Camo) @@ -1614,11 +2220,15 @@ 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) Noreen "Bad News" ULR (Camuflagem) + ノレーン "バッド ニュース" ULR (迷彩) + Noreen "Bad News" ULR (위장) + 諾琳"壞消息"極距狙擊步槍 (迷彩) + 诺琳"坏消息"极距狙击步枪 (迷彩) Noreen "Bad News" ULR (Sand) @@ -1626,11 +2236,15 @@ 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) Noreen "Bad News" ULR (Deserto) + ノレーン "バッド ニュース" ULR (砂地) + Noreen "Bad News" ULR (모래) + 諾琳"壞消息"極距狙擊步槍 (沙色) + 诺琳"坏消息"极距狙击步枪 (沙色) SIG 556 @@ -1643,6 +2257,10 @@ SIG 556 SIG 556 SIG 556 + SIG 556 + SIG 556 + SIG 556精準步槍 + SIG 556精准步枪 SIG 556 (Black) @@ -1655,6 +2273,10 @@ SIG 556 (Nero) SIG 556 (Fekete) SIG 556 (Preto) + SIG 556 (黒) + SIG 556 (검정) + SIG 556精準步槍 (黑色) + SIG 556精准步枪 (黑色) SIG 556 (Khaki) @@ -1667,6 +2289,10 @@ SIG 556 (Khaki) SIG 556 (Khaki) SIG 556 (Caqui) + SIG 556 (土埃) + SIG 556 (카키) + SIG 556精準步槍 (卡其色) + SIG 556精准步枪 (卡其色) SIG 556 (Sand) @@ -1675,10 +2301,14 @@ SIG 556 (Arena) SIG 556 (Песочный) SIG 556 (piaskowy) - SIG 556 (Sand) + SIG 556 (sandfarben) SIG 556 (Sabbia) SIG 556 (Homok) SIG 556 (Deserto) + SIG 556 (砂地) + SIG 556 (모래) + SIG 556精準步槍 (沙色) + SIG 556精准步枪 (沙色) SIG 556 (Camo) @@ -1687,10 +2317,14 @@ SIG 556 (Camuflaje) SIG 556 (Камо) SIG 556 (kamuflaż) - SIG 556 (Camo) + SIG 556 (Tarnmuster) SIG 556 (Camo) SIG 556 (Terepmintás) SIG 556 (Camuflagem) + SIG 556 (迷彩) + SIG 556 (위장) + SIG 556精準步槍 (迷彩) + SIG 556精准步枪 (迷彩) SIG 556 (Woodland) @@ -1699,22 +2333,14 @@ 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) - - - 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 (우드랜드) + SIG 556精準步槍 (森林迷彩) + SIG 556精准步枪 (森林迷彩) ASP-1 Kir @@ -1727,6 +2353,10 @@ ASP-1 Kir ASP-1 Kir ASP-1 Kir + ASP-1 Kir + ASP-1 キール + ASP-1"基爾"消音狙擊步槍 + ASP-1"基尔"消音狙击步枪 ASP-1 Kir (Black) @@ -1739,6 +2369,10 @@ ASP-1 Kir (Nero) ASP-1 Kir (Fekete) ASP-1 Kir (Preto) + ASP-1 キール (黒) + ASP-1 Kir (검정) + ASP-1"基爾"消音狙擊步槍 (黑色) + ASP-1"基尔"消音狙击步枪 (黑色) ASP-1 Kir (Tan) @@ -1751,6 +2385,10 @@ ASP-1 Kir (Tan) ASP-1 Kir (Cserszín) ASP-1 Kir (Deserto) + ASP-1 キール (黄褐) + ASP-1 Kir (황갈) + ASP-1"基爾"消音狙擊步槍 (黃褐色) + ASP-1"基尔"消音狙击步枪 (黄褐色) Cyrus @@ -1763,6 +2401,10 @@ Cyrus Cyrus Cyrus + サイラス + Cyrus + "居鲁士"狙擊步槍 + "居鲁士"狙击步枪 Cyrus (Black) @@ -1775,6 +2417,10 @@ Cyrus (Nero) Cyrus (Fekete) Cyrus (Preto) + サイラス (黒) + Cyrus (검정) + "居鲁士"狙擊步槍 (黑色) + "居鲁士"狙击步枪 (黑色) Cyrus (Hex) @@ -1787,6 +2433,10 @@ Cyrus (Hex) Cyrus (Hex) Cyrus (Hex) + サイラス (蜂巣) + Cyrus (육각) + "居鲁士"狙擊步槍 (數位蜂巢迷彩) + "居鲁士"狙击步枪 (数位蜂巢迷彩) Cyrus (Tan) @@ -1799,6 +2449,10 @@ Cyrus (Tan) Cyrus (Cserszín) Cyrus (Deserto) + サイラス (黄褐) + Cyrus (황갈) + "居鲁士"狙擊步槍 (黃褐色) + "居鲁士"狙击步枪 (黄褐色) M14 @@ -1811,6 +2465,10 @@ M14 M14 M14 + M14 + M14 + M14精準步槍 + M14精准步枪 M14 (Camo) @@ -1819,10 +2477,14 @@ M14 (Camuflaje) M14 (Камо) M14 (kamuflaż) - M14 (Camo) + M14 (Tarnmuster) M14 (Camo) M14 (Terepmintás) M14 (Camuflagem) + M14 (迷彩) + M14 (위장) + M14精準步槍 (迷彩) + M14精准步枪 (迷彩) M14 (Olive) @@ -1831,10 +2493,14 @@ M14 (Oliva) M14 (Олива) M14 (oliwkowy) - M14 (Olive) + M14 (Olivgrün) M14 (Olive) M14 (Olíva) M14 (Oliva) + M14 (オリーブド ラブ) + M14 (올리브) + M14精準步槍 (橄欖色) + M14精准步枪 (橄榄色) HK121 @@ -1847,6 +2513,10 @@ HK121 HK121 HK121 + HK 121 + HK121 + HK121中型機槍 + HK121中型机枪 HK121 (Hex) @@ -1859,6 +2529,10 @@ HK121 (Hex) HK121 (Hex) HK121 (Hex) + HK 121 (蜂巣) + HK121 (육각) + HK121中型機槍 (數位蜂巢迷彩) + HK121中型机枪 (数位蜂巢迷彩) HK121 (Tan) @@ -1871,6 +2545,10 @@ HK121 (Tan) HK121 (Cserszín) HK121 (Deserto) + HK 121 (黄褐) + HK121 (황갈) + HK121機槍 (黃褐色) + HK121机枪 (黄褐色) LWMMG @@ -1883,6 +2561,10 @@ LWMMG LWMMG LWMMG + LWMMG + LWMMG + 輕量化中型機槍 + 轻量化中型机枪 LWMMG (MTP) @@ -1895,6 +2577,10 @@ LWMMG (MTP) LWMMG (MTP) LWMMG (MTP) + LWMMG (マルチカモ) + LWMMG (MTP) + 輕量化中型機槍 (多地形迷彩) + 轻量化中型机枪 (多地形迷彩) LWMMG (Black) @@ -1907,6 +2593,10 @@ LWMMG (Nero) LWMMG (Fekete) LWMMG (Preto) + LWMMG (黒) + LWMMG (검정) + 輕量化中型機槍 (黑色) + 轻量化中型机枪 (黑色) LWMMG (Sand) @@ -1915,10 +2605,14 @@ LWMMG (Arena) LWMMG (Песочный) LWMMG (piaskowy) - LWMMG (Sand) + LWMMG (sandfarben) LWMMG (Sabbia) LWMMG (Homok) LWMMG (Deserto) + LWMMG (砂地) + LWMMG (모래) + 輕量化中型機槍 (沙色) + 轻量化中型机枪 (沙色) Jeep Wrangler @@ -1931,78 +2625,26 @@ Jeep Wrangler Jeep Wrangler Jeep Wrangler + ジープ ラングラー + Jeep Wrangler + "牧馬人"吉普車 + "牧马人"吉普车 - - Jeep Wrangler (Black) - Jeep Wrangler (Černý) - Jeep Wrangler (Noir) - Jeep Wrangler (Negro) - Jeep Wrangler (Чёрный) - Jeep Wrangler (czarny) - Jeep Wrangler (Schwarz) - Jeep Wrangler (Nero) - Jeep Wrangler (Fekete) - Jeep Wrangler (Preto) + + Jeep Wrangler (SPG-9) + Jeep Wrangler (SPG-9) + "牧马人"吉普车(SPG-9火箭筒) + "牧馬人"吉普車 (SPG-9火箭筒) + ジープ ラングラー (SPG-9) + Jeep Wrangler (SPG-9) - - Jeep Wrangler (Blue) - Jeep Wrangler (Blau) - Jeep Wrangler (Azul) - Jeep Wrangler (niebieski) - Jeep Wrangler (Modrý) - Jeep Wrangler (Bleue) - Jeep Wrangler (Синий) - Jeep Wrangler (Azul) - Jeep Wrangler (Kék) - Jeep Wrangler (Blu) - - - Jeep Wrangler (Green) - Jeep Wrangler (Grün) - Jeep Wrangler (Verde) - Jeep Wrangler (zielony) - Jeep Wrangler (Zelený) - Jeep Wrangler (Verte) - Jeep Wrangler (Зелёный) - Jeep Wrangler (Verde) - Jeep Wrangler (Zöld) - Jeep Wrangler (Verde) - - - Jeep Wrangler (Orange) - Jeep Wrangler (Orange) - Jeep Wrangler (Naranja) - Jeep Wrangler (pomarańczowy) - Jeep Wrangler (Oranžový) - Jeep Wrangler (Orange) - Jeep Wrangler (Оранжевый) - Jeep Wrangler (Laranja) - Jeep Wrangler (Narancssárga) - Jeep Wrangler (Arancione) - - - Jeep Wrangler (Red) - Jeep Wrangler (Rot) - Jeep Wrangler (Rojo) - Jeep Wrangler (czerwony) - Jeep Wrangler (Červený) - Jeep Wrangler (Rouge) - Jeep Wrangler (Красный) - Jeep Wrangler (Vermelha) - Jeep Wrangler (Piros) - Jeep Wrangler (Rosso) - - - Jeep Wrangler (White) - Jeep Wrangler (Weiß) - Jeep Wrangler (Blanco) - Jeep Wrangler (biały) - Jeep Wrangler (Bílý) - Jeep Wrangler (Blanche) - Jeep Wrangler (Белый) - Jeep Wrangler (Branca) - Jeep Wrangler (Fehér) - Jeep Wrangler (Bianco) + + Jeep Wrangler (LMG) + Jeep Wrangler (LMG) + "牧马人"吉普车(轻机枪) + "牧馬人"吉普車 (輕機槍) + ジープ ラングラー (LMG) + Jeep Wrangler (LMG) Cessna TTx @@ -2015,6 +2657,10 @@ Cessna TTx Cessna TTx Cessna TTx + セスナ TTx + Cessna TTx + "賽斯納"TTx單引擎飛機 + "赛斯纳"TTx单引擎飞机 Cessna TTx (Racing) @@ -2027,6 +2673,10 @@ Cessna TTx (Racing) Cessna TTx (Racing) Cessna TTx (Racing) + セスナ TTx (レース仕様) + Cessna TTx (경주용) + "賽斯納"TTx單引擎飛機 (競速) + "赛斯纳"TTx单引擎飞机 (竞速) Burraq UCAV @@ -2039,6 +2689,10 @@ Burraq UCAV Burraq UCAV Burraq UCAV + ブラーク UCAV + Burraq UCAV + "柏拉格"空中無人戰鬥載具 + "柏拉格"空中无人战斗载具 QBZ-95-1 (Black) @@ -2051,6 +2705,42 @@ QBZ-95-1 (Nero) QBZ-95-1 (Fekete) QBZ-95-1 (Preto) + QBZ-95-1 (黒) + QBZ-95-1 (검정) + QBZ-95-1式自動步槍 (黑色) + QBZ-95-1式自动步枪 (黑色) + + + QBZ-95-1 (Green Hex) + QBZ-95-1 (Hex Grün) + QBZ-95-1 (Hex Verde) + QBZ-95-1 (zielony hex) + QBZ-95-1 (Zelený Hex) + QBZ-95-1 (Hex Verte) + QBZ-95-1 (Зелёный Hex) + QBZ-95-1 (Verde Hex) + QBZ-95-1 (Zöld Hex) + QBZ-95-1 (Hex Verde) + QBZ-95-1 (緑蜂巣) + QBZ-95-1 (초록육각) + QBZ-95-1式自動步槍 (綠色數位蜂巢迷彩) + QBZ-95-1式自动步枪 (绿色数位蜂巢迷彩) + + + QBZ-95-1 (Hex) + QBZ-95-1 (Hex) + QBZ-95-1 (Hex) + QBZ-95-1 (hex) + QBZ-95-1 (Hex) + QBZ-95-1 (Hex) + QBZ-95-1 (Hex) + QBZ-95-1 (Hex) + QBZ-95-1 (Hex) + QBZ-95-1 (Hex) + QBZ-95-1 (蜂巣) + QBZ-95-1 (육각) + QBZ-95-1式自動步槍 (數位蜂巢迷彩) + QBZ-95-1式自动步枪 (数位蜂巢迷彩) QBZ-95-1 GL (Black) @@ -2063,6 +2753,42 @@ QBZ-95-1 GL (Nero) QBZ-95-1 GL (Fekete) QBZ-95-1 GL (Preto) + QBZ-95-1 GL (黒) + QBZ-95-1 GL (검정) + QBZ-95-1式自動步槍 (榴彈-黑色) + QBZ-95-1式自动步枪 (榴弹-黑色) + + + QBZ-95-1 GL (Green Hex) + QBZ-95-1 GL (Hex Grün) + QBZ-95-1 GL (Hex Verde) + QBZ-95-1 GL (zielony hex) + QBZ-95-1 GL (Zelený Hex) + QBZ-95-1 GL (Hex Verte) + QBZ-95-1 GL (Зелёный Hex) + QBZ-95-1 GL (Verde Hex) + QBZ-95-1 GL (Zöld Hex) + QBZ-95-1 GL (Hex Verde) + QBZ-95-1 GL (緑蜂巣) + QBZ-95-1 GL (초록육각) + QBZ-95-1式自動步槍 (榴彈-綠色數位蜂巢迷彩) + QBZ-95-1式自动步枪 (榴弹-绿色数位蜂巢迷彩) + + + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (Hex) + QBZ-95-1 GL (蜂巣) + QBZ-95-1 GL (육각) + QBZ-95-1式自動步槍 (榴彈-數位蜂巢迷彩) + QBZ-95-1式自动步枪 (榴弹-数位蜂巢迷彩) QBZ-95-1 LSW (Black) @@ -2075,6 +2801,42 @@ QBZ-95-1 LSW (Nero) QBZ-95-1 LSW (Fekete) QBZ-95-1 LSW (Preto) + QBZ-95-1 LSW (黒) + QBZ-95-1 LSW (검정) + QBZ-95-1式輕機槍 (黑色) + QBZ-95-1式轻机枪 (黑色) + + + QBZ-95-1 LSW (Green Hex) + QBZ-95-1 LSW (Hex Grün) + QBZ-95-1 LSW (Hex Verde) + QBZ-95-1 LSW (zielony hex) + QBZ-95-1 LSW (Zelený Hex) + QBZ-95-1 LSW (Hex Verte) + QBZ-95-1 LSW (Зелёный Hex) + QBZ-95-1 LSW (Verde Hex) + QBZ-95-1 LSW (Zöld Hex) + QBZ-95-1 LSW (Hex Verde) + QBZ-95-1 LSW (緑蜂巣) + QBZ-95-1 LSW (초록육각) + QBZ-95-1式輕機槍 (綠色數位蜂巢迷彩) + QBZ-95-1式轻机枪 (绿色数位蜂巢迷彩) + + + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (Hex) + QBZ-95-1 LSW (蜂巣) + QBZ-95-1 LSW (육각) + QBZ-95-1式輕機槍 (數位蜂巢迷彩) + QBZ-95-1式轻机枪 (数位蜂巢迷彩) QBU-88 (Black) @@ -2087,6 +2849,10 @@ QBU-88 (Nero) QBU-88 (Fekete) QBU-88 (Preto) + QBU-88 (黒) + QBU-88 (검정) + QBU-88式狙擊步槍 (黑色) + QBU-88式狙击步枪 (黑色) QBU-88 (Green Hex) @@ -2099,6 +2865,10 @@ QBU-88 (Verde Hex) QBU-88 (Zöld Hex) QBU-88 (Hex Verde) + QBU-88 (緑蜂巣) + QBU-88 (초록육각) + QBU-88式狙擊步槍 (綠色數位蜂巢迷彩) + QBU-88式狙击步枪 (绿色数位蜂巢迷彩) QBU-88 (Hex) @@ -2111,6 +2881,10 @@ QBU-88 (Hex) QBU-88 (Hex) QBU-88 (Hex) + QBU-88 (蜂巣) + QBU-88 (육각) + QBU-88式狙擊步槍 (數位蜂巢迷彩) + QBU-88式狙击步枪 (数位蜂巢迷彩) GM6 Lynx (Green Hex) @@ -2123,18 +2897,26 @@ GM6 Lynx (Verde Hex) GM6 Lynx (Zöld Hex) GM6 Lynx (Hex Verde) + GM6 リンクス (緑蜂巣) + GM6 Lynx (초록육각) + GM6"天貓"反器材狙擊步槍 (綠色數位蜂巢迷彩) + GM6"天猫"反器材狙击步枪 (绿色数位蜂巢迷彩) - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 SPW - M249 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 Minimi SPW + FN ミニミ SPW + FN Minimi SPW + FN Minimi班用自動機槍 + FN Minimi班用自动机枪 M200 Intervention (Tropic) @@ -2147,6 +2929,10 @@ M200 Intervention (тропик) M200 Intervention (Trópico) M200 Intervention (Tropico) + M200 インターベンション (熱帯) + M200 Intervention (열대) + M200干預型狙擊步槍 (熱帶迷彩) + M200干预型狙击步枪 (热带迷彩) MP5K @@ -2159,78 +2945,106 @@ MP5K MP5K MP5K + MP5K + MP5K + MP5K衝鋒槍 + MP5K冲锋枪 - HK416A5 10" (Black) - HK416A5 10" (Černá) - HK416A5 10" (Noir) - HK416A5 10" (Negro) - HK416A5 10" (Чёрный) - HK416A5 10" (czarny) - HK416A5 10" (Schwarz) - HK416A5 10" (Nero) - HK416A5 10" (Fekete) - HK416A5 10" (Preto) + HK416A5 11" (Black) + HK416A5 11" (Černá) + HK416A5 11" (Noir) + HK416A5 11" (Negro) + HK416A5 11" (Чёрный) + HK416A5 11" (czarny) + HK416A5 11" (Schwarz) + HK416A5 11" (Nero) + HK416A5 11" (Fekete) + HK416A5 11" (Preto) + HK416A5 11" (黒) + HK416A5 11" (검정) + HK416A5 11"突擊步槍 (黑色) + HK416A5 11"突击步枪 (黑色) - HK416A5 10" (Khaki) - HK416A5 10" (Khaki) - HK416A5 10" (Kaki) - HK416A5 10" (Caqui) - HK416A5 10" (Хаки) - HK416A5 10" (khaki) - HK416A5 10" (Khaki) - HK416A5 10" (Khaki) - HK416A5 10" (Khaki) - HK416A5 10" (Caqui) + HK416A5 11" (Khaki) + HK416A5 11" (Khaki) + HK416A5 11" (Kaki) + HK416A5 11" (Caqui) + HK416A5 11" (Хаки) + HK416A5 11" (khaki) + HK416A5 11" (Khaki) + HK416A5 11" (Khaki) + HK416A5 11" (Khaki) + HK416A5 11" (Caqui) + HK416A5 11" (土埃) + HK416A5 11" (카키) + HK416A5 11"突擊步槍 (卡其色) + HK416A5 11"突击步枪 (卡其色) - HK416A5 10" (Sand) - HK416A5 10" (Písková) - HK416A5 10" (Beige) - HK416A5 10" (Arena) - HK416A5 10" (Песочный) - HK416A5 10" (Sand) - HK416A5 10" (piaskowy) - HK416A5 10" (Sabbia) - HK416A5 10" (Homok) - HK416A5 10" (Deserto) + HK416A5 11" (Sand) + HK416A5 11" (Písková) + HK416A5 11" (Beige) + HK416A5 11" (Arena) + HK416A5 11" (Песочный) + HK416A5 11" (sandfarben) + HK416A5 11" (piaskowy) + HK416A5 11" (Sabbia) + HK416A5 11" (Homok) + HK416A5 11" (Deserto) + HK416A5 11" (砂地) + HK416A5 11" (모래) + HK416A5 11"突擊步槍 (沙色) + HK416A5 11"突击步枪 (沙色) - HK416A5 10" GL (Black) - HK416A5 10" GL (Černá) - HK416A5 10" GL (Noir) - HK416A5 10" GL (Negro) - HK416A5 10" GL (Чёрный) - HK416A5 10" GL (czarny) - HK416A5 10" GL (Schwarz) - HK416A5 10" GL (Nero) - HK416A5 10" GL (Fekete) - HK416A5 10" GL (Preto) + HK416A5 11" GL (Black) + HK416A5 11" GL (Černá) + HK416A5 11" GL (Noir) + HK416A5 11" GL (Negro) + HK416A5 11" GL (Чёрный) + HK416A5 11" GL (czarny) + HK416A5 11" GL (Schwarz) + HK416A5 11" GL (Nero) + HK416A5 11" GL (Fekete) + HK416A5 11" GL (Preto) + HK416A5 11" GL (黒) + HK416A5 11" GL (검정) + HK416A5 11"突擊步槍 (榴彈-黑色) + HK416A5 11"突击步枪 (榴弹-黑色) - HK416A5 10" GL (Khaki) - HK416A5 10" GL (Khaki) - HK416A5 10" GL (Kaki) - HK416A5 10" GL (Caqui) - HK416A5 10" GL (Хаки) - HK416A5 10" GL (khaki) - HK416A5 10" GL (Khaki) - HK416A5 10" GL (Khaki) - HK416A5 10" GL (Khaki) - HK416A5 10" GL (Caqui) + HK416A5 11" GL (Khaki) + HK416A5 11" GL (Khaki) + HK416A5 11" GL (Kaki) + HK416A5 11" GL (Caqui) + HK416A5 11" GL (Хаки) + HK416A5 11" GL (khaki) + HK416A5 11" GL (Khaki) + HK416A5 11" GL (Khaki) + HK416A5 11" GL (Khaki) + HK416A5 11" GL (Caqui) + HK416A5 11" GL (土埃) + HK416A5 11" GL (카키) + HK416A5 11"突擊步槍 (榴彈-卡其色) + HK416A5 11"突击步枪 (榴弹-卡其色) - HK416A5 10" GL (Sand) - HK416A5 10" GL (Písková) - HK416A5 10" GL (Beige) - HK416A5 10" GL (Arena) - HK416A5 10" GL (Песочный) - HK416A5 10" GL (Sand) - HK416A5 10" GL (piaskowy) - HK416A5 10" GL (Sabbia) - HK416A5 10" GL (Homok) - HK416A5 10" GL (Deserto) + HK416A5 11" GL (Sand) + HK416A5 11" GL (Písková) + HK416A5 11" GL (Beige) + HK416A5 11" GL (Arena) + HK416A5 11" GL (Песочный) + HK416A5 11" GL (sandfarben) + HK416A5 11" GL (piaskowy) + HK416A5 11" GL (Sabbia) + HK416A5 11" GL (Homok) + HK416A5 11" GL (Deserto) + HK416A5 11" GL (砂地) + HK416A5 11" GL (모래) + HK416A5 11"突擊步槍 (榴彈-沙色) + HK416A5 11"突击步枪 (榴弹-沙色) HK416A5 14.5" (Black) @@ -2243,6 +3057,10 @@ HK416A5 14.5" (Nero) HK416A5 14.5" (Fekete) HK416A5 14.5" (Preto) + HK416A5 14.5" (黒) + HK416A5 14.5" (검정) + HK416A5 14.5"突擊步槍 (黑色) + HK416A5 14.5"突击步枪 (黑色) HK416A5 14.5" (Khaki) @@ -2255,6 +3073,10 @@ HK416A5 14.5" (Khaki) HK416A5 14.5" (Khaki) HK416A5 14.5" (Caqui) + HK416A5 14.5" (土埃) + HK416A5 14.5" (카키) + HK416A5 14.5"突擊步槍 (卡其色) + HK416A5 14.5"突击步枪 (卡其色) HK416A5 14.5" (Sand) @@ -2262,11 +3084,15 @@ 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) HK416A5 14.5" (Deserto) + HK416A5 14.5" (砂地) + HK416A5 14.5" (모래) + HK416A5 14.5"突擊步槍 (沙色) + HK416A5 14.5"突击步枪 (沙色) HK417A2 20" (Black) @@ -2279,6 +3105,10 @@ HK417A2 20" (Nero) HK417A2 20" (Fekete) HK417A2 20" (Preto) + HK417A2 20" (黒) + HK417A2 20" (검정) + HK417A2 20"突擊步槍 (黑色) + HK417A2 20"突击步枪 (黑色) HK417A2 20" (Khaki) @@ -2291,6 +3121,10 @@ HK417A2 20" (Khaki) HK417A2 20" (Khaki) HK417A2 20" (Caqui) + HK417A2 20" (土埃) + HK417A2 20" (카키) + HK417A2 20"突擊步槍 (卡其色) + HK417A2 20"突击步枪 (卡其色) HK417A2 20" (Sand) @@ -2298,11 +3132,15 @@ HK417A2 20" (Beige) HK417A2 20" (Arena) HK417A2 20" (Песочный) - HK417A2 20" (Sand) + HK417A2 20" (sandfarben) HK417A2 20" (piaskowy) HK417A2 20" (Sabbia) HK417A2 20" (Homok) HK417A2 20" (Deserto) + HK417A2 20" (砂地) + HK417A2 20" (모래) + HK417A2 20"突擊步槍 (沙色) + HK417A2 20"突击步枪 (沙色) RPG-32 (Green Hex) @@ -2315,6 +3153,10 @@ RPG-32 (Verde Hex) RPG-32 (Zöld Hex) RPG-32 (Hex Verde) + RPG-32 (緑蜂巣) + RPG-32 (초록육각) + RPG-32火箭發射器 (綠色數位蜂巢迷彩) + RPG-32火箭发射器 (绿色数位蜂巢迷彩) P99 (Khaki) @@ -2327,6 +3169,10 @@ P99 (Khaki) P99 (Khaki) P99 (Caqui) + P99 (土埃) + P99 (카키) + P99半自動手槍 (卡其色) + P99半自动手枪 (卡其色) Makarov PM @@ -2339,6 +3185,324 @@ Makarov PM Makarov PM Makarov PM + マカロフ PM + Makarov PM + "馬卡洛夫"手槍 + "马卡洛夫"手枪 + + + Polaris DAGOR (XM312) + Polaris DAGOR (XM312) + ポラリス DAGOR (XM312) + "北極星"先進佈署越野車 (XM312重機槍) + "北极星"先进布署越野车 (XM312重机枪) + Polaris DAGOR (XM312) + + + Polaris DAGOR (Mini-Spike AT) + Polaris DAGOR (Mini-Spike PzAbw) + "北极星"先进布署越野车("迷你长钉"反坦克导弹发射器) + "北極星"先進佈署越野車("迷你長釘"反坦克導彈發射器) + Polaris DAGOR (Mini-Spike AT) + + + Polaris DAGOR + Polaris DAGOR + ポラリス DAGOR + "北極星"先進佈署越野車 + "北极星"先进布署越野车 + Polaris DAGOR + + + Polaris DAGOR (light) + Polaris DAGOR (leicht) + ポラリス DAGOR (軽) + "北極星"先進佈署越野車 (輕型) + "北极星"先进布署越野车 (轻型) + Polaris DAGOR (leggero) + + + LSV Mk. II (M134) + LSV Mk. II (M134) + 輕型突擊車2式 (M134迷你機炮) + 轻型突击车2式 (M134迷你机炮) + LSV Mk. II (M134) + LSV Mk. II (M134) + + + LSV Mk. II (Metis-M) + LSV Mk. II (Metis-M) + 轻型突击车2式 ("麦士蒂索人"-M型反坦克导弹) + 輕型突擊車2式 ("麥士蒂索人"-M型反坦克導彈) + LSV Mk. II (メチス-M) + LSV Mk. II (Metis-M) + + + LSV Mk. II + LSV Mk. II + 輕型突擊車2式 + 轻型突击车2式 + LSV Mk. II + LSV Mk. II + + + Rooikat 120 + Rooikat 120 + "狞猫"120主炮轮式装甲车 + "獰貓"120主炮輪式裝甲車 + ルーイカット 120 + Rooikat 120 + + + Rooikat 120 UP + Rooikat 120 UP + "狞猫"120主炮轮式装甲车 (城市版) + "獰貓"120主炮輪式裝甲車 (城市版) + ルーイカット 120 UP + Rooikat 120 UP + + + T-14 Armata + T-14 Armata + Т-14 Армата + T-14"阿玛塔"主战坦克 + T-14"阿瑪塔"主戰坦克 + T-14 アルマータ + T-14 Armata + + + T-14K Armata + T-14K Armata + Т-14К Армата + T-14K"阿玛塔"主战坦克 + T-14K"阿瑪塔"主戰坦克 + T-14K アルマータ + T-14K Armata + + + Wiesel 2 Ozelot (AA) + Wiesel 2 Ozelot (FlaRaWaTrg) + "鼬鼠"2装甲车 (防空) + "鼬鼠"2裝甲車 (防空) + ウィーゼル 2 オゼロット (対空) + Wiesel 2 Ozelot (AA) + + + Wiesel 2 (ATGM) + Wiesel 2 (PzAbw) + "鼬鼠"2装甲车 (反坦导弹) + "鼬鼠"2裝甲車 (反坦導彈) + ウィーゼル 2 (ATGM) + Wiesel 2 (ATGM) + + + Wiesel 2 (MK20) + Wiesel 2 (MK20) + "鼬鼠"2装甲车 (MK20机炮) + "鼬鼠"2裝甲車 (MK20機炮) + ウィーゼル 2 (MK20) + Wiesel 2 (MK20) + + + Wiesel 2 RFCV (Radar) + Wiesel 2 AFF (Radar) + "鼬鼠"2装甲车 (雷达) + "鼬鼠"2裝甲車 (雷達) + ウィーゼル 2 (レーダー) + Wiesel 2 RFCV (Radar) + + + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + Leupold Mark 4 HAMR + + + Leupold Mark 4 HAMR (Khaki) + Leupold Mark 4 HAMR (Khaki) + Leupold Mark 4 HAMR (卡其色) + Leupold Mark 4 HAMR (卡其色) + Leupold Mark 4 HAMR (土埃) + Leupold Mark 4 HAMR (Khaki) + + + ELCAN SpecterOS (Tan) + ELCAN SpecterOS (Beige) + ELCAN SpecterOS (黃褐色) + ELCAN SpecterOS (黄褐色) + ELCAN SpecterOS (黄褐) + ELCAN SpecterOS (Tan) + + + ELCAN SpecterOS (Black) + ELCAN SpecterOS (Schwarz) + ELCAN SpecterOS (黑色) + ELCAN SpecterOS (黑色) + ELCAN SpecterOS (黒) + ELCAN SpecterOS (Nero) + + + ELCAN SpecterOS (Green Hex) + ELCAN SpecterOS (綠色數位蜂巢迷彩) + ELCAN SpecterOS (绿色数位蜂巢迷彩) + ELCAN SpecterOS (緑蜂巣) + ELCAN SpecterOS (Verde Hex) + + + SIG BRAVO4 / ROMEO3 (Black) + SIG BRAVO4 / ROMEO3 (Schwarz) + SIG BRAVO4 / ROMEO3 (黑色) + SIG BRAVO4 / ROMEO3 (黑色) + SIG BRAVO4 / ROMEO3 (黒) + SIG BRAVO4 / ROMEO3 (Nero) + + + SIG BRAVO4 / ROMEO3 (Khaki) + SIG BRAVO4 / ROMEO3 (Khaki) + SIG BRAVO4 / ROMEO3 (卡其色) + SIG BRAVO4 / ROMEO3 (卡其色) + SIG BRAVO4 / ROMEO3 (土埃) + SIG BRAVO4 / ROMEO3 (Khaki) + + + SIG BRAVO4 / ROMEO3 (Sand) + SIG BRAVO4 / ROMEO3 (Beige) + SIG BRAVO4 / ROMEO3 (沙色) + SIG BRAVO4 / ROMEO3 (沙色) + SIG BRAVO4 / ROMEO3 (砂地) + SIG BRAVO4 / ROMEO3 (Sabbia) + + + Nightforce NXS + Nightforce NXS + Nightforce NXS + Nightforce NXS + Nightforce NXS + + + Nightforce NXS (Green Hex) + Nightforce NXS (綠色數位蜂巢迷彩) + Nightforce NXS (绿色数位蜂巢迷彩) + Nightforce NXS (緑蜂巣) + Nightforce NXS (Verde Hex) + + + Nightforce NXS (Jungle) + Nightforce NXS (Dschungel) + Nightforce NXS (叢林色) + Nightforce NXS (丛林色) + Nightforce NXS (熱帯) + Nightforce NXS (Giungla) + + + Burris XTR II + Burris XTR II + Burris XTR II + Burris XTR II + Burris XTR II + + + Burris XTR II (Green Hex) + Burris XTR II (綠色數位蜂巢迷彩) + Burris XTR II (绿色数位蜂巢迷彩) + Burris XTR II (緑蜂巣) + Burris XTR II (Green Hex) + + + EOTech XPS3 (Tan) + EOTech XPS3 (Beige) + EOTech XPS3 (黃褐色) + EOTech XPS3 (黄褐色) + EOTech XPS3 (黄褐) + EOTech XPS3 (Tan) + + + EOTech XPS3 (Black) + EOTech XPS3 (Schwarz) + EOTech XPS3 (黑色) + EOTech XPS3 (黑色) + EOTech XPS3 (黒) + EOTech XPS3 (Black) + + + EOTech XPS3 (Khaki) + EOTech XPS3 (Khaki) + EOTech XPS3 (卡其色) + EOTech XPS3 (卡其色) + EOTech XPS3 (土埃) + EOTech XPS3 (Khaki) + + + EOTech XPS3 SMG (Tan) + EOTech XPS3 SMG (Beige) + EOTech XPS3 SMG (黃褐色) + EOTech XPS3 SMG (黄褐色) + EOTech XPS3 SMG (黄褐) + EOTech XPS3 SMG (Tan) + + + EOTech XPS3 SMG (Black) + EOTech XPS3 SMG (Schwarz) + EOTech XPS3 SMG (黑色) + EOTech XPS3 SMG (黑色) + EOTech XPS3 SMG (黒) + EOTech XPS3 SMG (Nero) + + + EOTech XPS3 SMG (Khaki) + EOTech XPS3 SMG (Khaki) + EOTech XPS3 SMG (卡其色) + EOTech XPS3 SMG (卡其色) + EOTech XPS3 SMG (土埃) + EOTech XPS3 SMG (Khaki) + + + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada Pitbull 2 + IOR-Valdada ピットブル 2 + IOR-Valdada Pitbull 2 + + + Burris FastFire 2 + Burris FastFire 2 + Burris FastFire 2 + Burris ファストファイア 2 + Burris FastFire 2 + + + C-More Railway (Red) + C-More Railway (Rot) + C-More Railway (紅色) + C-More Railway (红色) + C-More レイルウェイ (赤) + C-More Railway (Rosso) + + + C-More Railway (Green) + C-More Railway (Grün) + C-More Railway (綠色) + C-More Railway (绿色) + C-More レイルウェイ (緑) + C-More Railway (Verde) + + + C-More Railway SMG (Red) + C-More Railway SMG (Rot) + C-More Railway SMG (紅色) + C-More Railway SMG (红色) + C-More レイルウェイ SMG (赤) + C-More Railway SMG (Rosso) + + + C-More Railway SMG (Green) + C-More Railway SMG (Grün) + C-More Railway SMG (綠色) + C-More Railway SMG (绿色) + C-More レイルウェイ SMG (緑) + C-More Railway SMG (Verde) - \ No newline at end of file + diff --git a/addons/realisticweights/CfgWeapons.hpp b/addons/realisticweights/CfgWeapons.hpp index 5c60f8d464..25b83815b4 100644 --- a/addons/realisticweights/CfgWeapons.hpp +++ b/addons/realisticweights/CfgWeapons.hpp @@ -3,6 +3,9 @@ class CfgWeapons { class Rifle_Long_Base_F: Rifle_Base_F { class WeaponSlotsInfo; }; + class Rifle_Short_Base_F: Rifle_Base_F { + class WeaponSlotsInfo; + }; class Launcher; class Launcher_Base_F: Launcher { class WeaponSlotsInfo; @@ -176,7 +179,7 @@ class CfgWeapons { // - SMGs --------------------------------------------------------------------- // - CPW ------------------------------------------------------------------ - class pdw2000_base_F: Rifle_Base_F { + class pdw2000_base_F: Rifle_Short_Base_F { class WeaponSlotsInfo; }; class hgun_PDW2000_F: pdw2000_base_F { @@ -186,7 +189,7 @@ class CfgWeapons { }; // - KRISS Vector --------------------------------------------------------- - class SMG_01_Base: Rifle_Base_F { + class SMG_01_Base: Rifle_Short_Base_F { class WeaponSlotsInfo; }; class SMG_01_F: SMG_01_Base { @@ -196,7 +199,7 @@ class CfgWeapons { }; // - CZ Scorpion ---------------------------------------------------------- - class SMG_02_base_F: Rifle_Base_F { + class SMG_02_base_F: Rifle_Short_Base_F { class WeaponSlotsInfo; }; class SMG_02_F: SMG_02_base_F { @@ -286,6 +289,16 @@ class CfgWeapons { }; }; + // - Cyrus ------------------------------------------------------ + class DMR_05_base_F: Rifle_Long_Base_F { + class WeaponSlotsInfo; + }; + class srifle_DMR_05_blk_F: DMR_05_base_F { + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 140; + }; + }; + // - SIG 556 -------------------------------------------------------------- class DMR_03_base_F: Rifle_Long_Base_F { class WeaponSlotsInfo; diff --git a/addons/realisticweights/script_component.hpp b/addons/realisticweights/script_component.hpp index e933b6220c..fcdb345068 100644 --- a/addons/realisticweights/script_component.hpp +++ b/addons/realisticweights/script_component.hpp @@ -3,7 +3,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_REALISTICWEIGHTS diff --git a/addons/rearm/ACE_Settings.hpp b/addons/rearm/ACE_Settings.hpp index 798bbd7650..e592466c40 100644 --- a/addons/rearm/ACE_Settings.hpp +++ b/addons/rearm/ACE_Settings.hpp @@ -1,10 +1,8 @@ class ACE_Settings { class GVAR(level) { - category = ECSTRING(OptionsMenu,CategoryLogistics); - displayName = CSTRING(RearmSettings_level_DisplayName); - description = CSTRING(RearmSettings_level_Description); - value = 0; - typeName = "SCALAR"; - values[] = {CSTRING(RearmSettings_vehicle), CSTRING(RearmSettings_magazine), CSTRING(RearmSettings_caliber)}; + movedToSQF = 1; + }; + class GVAR(supply) { + movedToSQF = 1; }; }; diff --git a/addons/rearm/CfgAmmo.hpp b/addons/rearm/CfgAmmo.hpp index 2443ab91a5..54ff37e279 100644 --- a/addons/rearm/CfgAmmo.hpp +++ b/addons/rearm/CfgAmmo.hpp @@ -1,9 +1,6 @@ class CfgAmmo { class BombCore; - class BombBase : BombCore { - GVAR(caliber) = 250; // Default caliber for bombs - }; class LaserBombCore : BombCore { GVAR(caliber) = 250; // Default caliber for bombs }; @@ -54,9 +51,6 @@ class CfgAmmo { GVAR(caliber) = 60; GVAR(dummy) = QGVAR(R_60mm_HE); }; - class R_Hydra_HE : RocketBase { - GVAR(dummy) = QGVAR(R_Hydra_HE); - }; class BulletBase; class B_19mm_HE : BulletBase { @@ -184,17 +178,18 @@ class CfgAmmo { GVAR(dummy) = QGVAR(Bo_Mk82); }; - class Bo_GBU12_LGB : LaserBombCore { + class ammo_Bomb_LaserGuidedBase: LaserBombCore {}; + class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { GVAR(caliber) = 250; // Default caliber for bombs GVAR(dummy) = QGVAR(Bo_GBU12_LGB); }; - class Bomb_04_F : LaserBombCore { + class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(caliber) = 250; // Default caliber for bombs GVAR(dummy) = QGVAR(Bomb_04_F); }; - class Bomb_03_F : Bomb_04_F { + class Bomb_03_F: ammo_Bomb_LaserGuidedBase { GVAR(dummy) = QGVAR(Bomb_03_F); }; }; 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 44b7fe38af..c12ee16066 100644 --- a/addons/rearm/CfgVehicles.hpp +++ b/addons/rearm/CfgVehicles.hpp @@ -1,54 +1,29 @@ - #define MACRO_REARM_ACTIONS \ - class ACE_Actions { \ - class ACE_MainActions { \ - class GVAR(Rearm) { \ - displayName = CSTRING(Rearm); \ - distance = REARM_ACTION_DISTANCE; \ - condition = QUOTE(_this call FUNC(canRearm)); \ - statement = QUOTE(_player call FUNC(rearm)); \ - exceptions[] = {"isNotInside"}; \ - icon = QPATHTOF(ui\icon_rearm_interact.paa); \ - }; \ + class ACE_Actions { \ + class ACE_MainActions { \ + class GVAR(Rearm) { \ + displayName = CSTRING(Rearm); \ + distance = REARM_ACTION_DISTANCE; \ + condition = QUOTE(_this call FUNC(canRearm)); \ + statement = QUOTE(_this call FUNC(rearm)); \ + exceptions[] = {"isNotInside"}; \ + icon = QPATHTOF(ui\icon_rearm_interact.paa); \ }; \ - }; - -#define MACRO_REARM_TRUCK_ACTIONS \ - class ACE_Actions: ACE_Actions { \ - class ACE_MainActions: ACE_MainActions { \ - class GVAR(TakeAmmo) { \ - displayName = CSTRING(TakeAmmo); \ - distance = REARM_ACTION_DISTANCE; \ - condition = QUOTE(_this call FUNC(canTakeAmmo)); \ - insertChildren = QUOTE(_target call FUNC(addRearmActions)); \ - exceptions[] = {"isNotInside"}; \ - showDisabled = 0; \ - priority = 2; \ - icon = QPATHTOF(ui\icon_rearm_interact.paa); \ - }; \ - class GVAR(StoreAmmo) { \ - displayName = CSTRING(StoreAmmo); \ - distance = REARM_ACTION_DISTANCE; \ - condition = QUOTE(_this call FUNC(canStoreAmmo)); \ - statement = QUOTE(_this call FUNC(storeAmmo)); \ - exceptions[] = {"isNotInside"}; \ - icon = QPATHTOF(ui\icon_rearm_interact.paa); \ - }; \ - }; \ - }; + }; \ + }; 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 { @@ -72,6 +47,26 @@ class CfgVehicles { }; }; }; + class supply { + displayName = CSTRING(RearmSettings_supply_DisplayName); + description = CSTRING(RearmSettings_supply_Description); + typeName = "NUMBER"; + class values { + class unlimited { + name = CSTRING(RearmSettings_unlimited); + value = 0; + default = 1; + }; + class magazine { + name = CSTRING(RearmSettings_limited); + value = 1; + }; + class caliber { + name = CSTRING(RearmSettings_magazineSupply); + value = 2; + }; + }; + }; }; class ModuleDescription { description = CSTRING(RearmSettings_Module_Description); @@ -105,66 +100,67 @@ class CfgVehicles { MACRO_REARM_ACTIONS }; - - // Ammo Vehicles (with full inheritance for granted ACE_Actions) - class Car_F: Car {}; - class Truck_F: Car_F {}; - - class Truck_03_base_F: Truck_F {}; + class Truck_03_base_F; class O_Truck_03_ammo_F: Truck_03_base_F { transportAmmo = 0; - MACRO_REARM_TRUCK_ACTIONS + GVAR(defaultSupply) = 1200; }; - class Truck_02_base_F: Truck_F {}; - class Truck_02_Ammo_base_F: Truck_02_base_F {}; - class I_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; - MACRO_REARM_TRUCK_ACTIONS - }; - class O_Truck_02_Ammo_F: Truck_02_Ammo_base_F { - transportAmmo = 0; - MACRO_REARM_TRUCK_ACTIONS + GVAR(defaultSupply) = 1200; }; - class Truck_01_base_F: Truck_F {}; - class B_Truck_01_transport_F: Truck_01_base_F {}; - class B_Truck_01_mover_F: B_Truck_01_transport_F {}; + class B_Truck_01_mover_F; class B_Truck_01_ammo_F: B_Truck_01_mover_F { transportAmmo = 0; - MACRO_REARM_TRUCK_ACTIONS + GVAR(defaultSupply) = 1200; }; - class Helicopter_Base_F: Helicopter {}; - class Helicopter_Base_H: Helicopter_Base_F {}; - class Heli_Transport_04_base_F: Helicopter_Base_H {}; + class B_APC_Tracked_01_base_F; + class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { + transportAmmo = 0; + GVAR(defaultSupply) = 1200; + }; + + class Heli_Transport_04_base_F; class O_Heli_Transport_04_ammo_F: Heli_Transport_04_base_F { transportAmmo = 0; - MACRO_REARM_TRUCK_ACTIONS + GVAR(defaultSupply) = 1200; }; - class ThingX; - class ReammoBox_F: ThingX { - class ACE_Actions { - class ACE_MainActions {}; - }; - }; - class Slingload_base_F: ReammoBox_F {}; - class Slingload_01_Base_F: Slingload_base_F {}; - - class Pod_Heli_Transport_04_base_F: Slingload_base_F {}; + class Pod_Heli_Transport_04_base_F; class Land_Pod_Heli_Transport_04_ammo_F: Pod_Heli_Transport_04_base_F { transportAmmo = 0; - MACRO_REARM_TRUCK_ACTIONS + GVAR(defaultSupply) = 1200; }; + class Slingload_01_Base_F; class B_Slingload_01_Ammo_F: Slingload_01_Base_F { transportAmmo = 0; - MACRO_REARM_TRUCK_ACTIONS + GVAR(defaultSupply) = 1200; }; + class ReammoBox_F; + class NATO_Box_Base: ReammoBox_F{}; + class Box_NATO_AmmoVeh_F: NATO_Box_Base { + transportAmmo = 0; + GVAR(defaultSupply) = 1200; + }; + class EAST_Box_Base: ReammoBox_F{}; + class Box_East_AmmoVeh_F: EAST_Box_Base { + transportAmmo = 0; + GVAR(defaultSupply) = 1200; + }; + class IND_Box_Base: ReammoBox_F{}; + class Box_IND_AmmoVeh_F: IND_Box_Base { + transportAmmo = 0; + GVAR(defaultSupply) = 1200; + }; // Dummy Vehicles + class ThingX; class GVAR(defaultCarriedObject): ThingX { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; @@ -183,7 +179,6 @@ class CfgVehicles { statement = QUOTE(_this call FUNC(grabAmmo)); exceptions[] = {"isNotInside"}; showDisabled = 0; - priority = 2; icon = QPATHTOF(ui\icon_rearm_interact.paa); }; }; @@ -240,7 +235,4 @@ class CfgVehicles { class GVAR(R_60mm_HE): GVAR(defaultCarriedObject) { model = "\A3\Weapons_F_EPC\Ammo\Rocket_03_HE_F.p3d"; }; - class GVAR(R_Hydra_HE): GVAR(defaultCarriedObject) { - model = "\A3\Weapons_F_EPC\Ammo\Rocket_03_HE_F.p3d"; - }; }; diff --git a/addons/rearm/XEH_PREP.hpp b/addons/rearm/XEH_PREP.hpp index 8e3c10cd2c..dc34fbd9e9 100644 --- a/addons/rearm/XEH_PREP.hpp +++ b/addons/rearm/XEH_PREP.hpp @@ -1,26 +1,39 @@ - +PREP(addMagazineToSupply); PREP(addRearmActions); +PREP(addVehicleMagazinesToSupply); +PREP(canReadSupplyCounter); PREP(canRearm); PREP(canStoreAmmo); PREP(canTakeAmmo); PREP(createDummy); PREP(disable); PREP(dropAmmo); -PREP(getConfigMagazines); +PREP(getAllRearmTurrets); +PREP(getCaliber); PREP(getMaxMagazines); PREP(getNeedRearmMagazines); +PREP(getSupplyCount); +PREP(getTurretConfigMagazines); +PREP(getTurretMagazineAmmo); PREP(grabAmmo); PREP(handleKilled); +PREP(handleRespawn); PREP(handleUnconscious); +PREP(hasEnoughSupply); +PREP(initSupplyVehicle); PREP(makeDummy); PREP(moduleRearmSettings); PREP(pickUpAmmo); +PREP(readSupplyCounter); PREP(rearm); PREP(rearmEntireVehicle); PREP(rearmEntireVehicleSuccess); PREP(rearmEntireVehicleSuccessLocal); 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 cfbbdf9d4d..1fd9462df8 100644 --- a/addons/rearm/XEH_postInit.sqf +++ b/addons/rearm/XEH_postInit.sqf @@ -1,6 +1,14 @@ #include "script_component.hpp" -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace; +GVAR(configTypesAdded) = []; +["ace_settingsInitialized", { + TRACE_2("settingsInit",GVAR(level),GVAR(supply)); + ["LandVehicle", "Init", {_this call FUNC(initSupplyVehicle)}, true, ["StaticWeapon"], true] call CBA_fnc_addClassEventHandler; + ["ReammoBox_F", "Init", {_this call FUNC(initSupplyVehicle)}, true, [], true] call CBA_fnc_addClassEventHandler; +}] call CBA_fnc_addEventHandler; + +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; ["vehicle", { params ["_unit"]; [_unit] call FUNC(dropAmmo); @@ -10,6 +18,9 @@ if (isServer) then { addMissionEventHandler ["HandleDisconnect", {params ["_unit"]; [_unit] call FUNC(dropAmmo)}]; }; -[QGVAR(makeDummyEH), FUNC(makeDummy)] call CBA_fnc_addEventHandler; -[QGVAR(rearmEntireVehicleSuccessLocalEH), FUNC(rearmEntireVehicleSuccessLocal)] call CBA_fnc_addEventHandler; -[QGVAR(rearmSuccessLocalEH), FUNC(rearmSuccessLocal)] call CBA_fnc_addEventHandler; +[QGVAR(makeDummyEH), LINKFUNC(makeDummy)] call CBA_fnc_addEventHandler; +[QGVAR(rearmEntireVehicleSuccessEH), LINKFUNC(rearmEntireVehicleSuccess)] call CBA_fnc_addEventHandler; +[QGVAR(rearmEntireVehicleSuccessLocalEH), LINKFUNC(rearmEntireVehicleSuccessLocal)] call CBA_fnc_addEventHandler; +[QGVAR(rearmSuccessEH), LINKFUNC(rearmSuccess)] call CBA_fnc_addEventHandler; +[QGVAR(rearmSuccessLocalEH), LINKFUNC(rearmSuccessLocal)] call CBA_fnc_addEventHandler; + diff --git a/addons/rearm/XEH_preInit.sqf b/addons/rearm/XEH_preInit.sqf index a7feade1c3..9361d05015 100644 --- a/addons/rearm/XEH_preInit.sqf +++ b/addons/rearm/XEH_preInit.sqf @@ -2,6 +2,10 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" ADDON = true; diff --git a/addons/rearm/XEH_respawn.sqf b/addons/rearm/XEH_respawn.sqf deleted file mode 100644 index 33ac042e7c..0000000000 --- a/addons/rearm/XEH_respawn.sqf +++ /dev/null @@ -1,13 +0,0 @@ -#include "script_component.hpp" - -params ["_unit"]; -if !(local _unit) exitWith {}; - -_unit setVariable [QGVAR(selectedWeaponOnRearm), nil]; -_unit setVariable [QGVAR(carriedMagazine), nil]; -private _dummy = _unit getVariable [QGVAR(dummy), objNull]; -if !(isNull _dummy) then { - detach _dummy; - deleteVehicle _dummy; -}; -_unit setVariable [QGVAR(dummy), nil]; \ No newline at end of file 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_addMagazineToSupply.sqf b/addons/rearm/functions/fnc_addMagazineToSupply.sqf new file mode 100644 index 0000000000..1f646e3598 --- /dev/null +++ b/addons/rearm/functions/fnc_addMagazineToSupply.sqf @@ -0,0 +1,72 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Adds magazines to the supply. [Global Effects] + * + * Arguments: + * 0: Ammo Truck + * 1: Magazine Classname + * 2: Only partial (default: false) + * + * Return Value: + * None + * + * Example: + * [ammo_truck, "32Rnd_155mm_Mo_shells"] call ace_rearm_fnc_addMagazineToSupply + * + * Public: Yes + */ + +if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the settings are initialized + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addMagazineToSupply), _this]; +}; + +params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]], ["_partial", false, [false]]]; +TRACE_3("addMagazineToSupply",_truck,_magazineClass,_partial); + +if (GVAR(supply) == 0) exitWith {WARNING("supply setting is set to unlimited");}; + +if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {}; + +([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; + +// With limited supply, we add the caliber to the supply count +if (GVAR(supply) == 1) then { + private _supply = [_truck] call FUNC(getSupplyCount); + private _amountToAdd = if (!_partial || {GVAR(level) == 1}) then { + _cal + } else { + private _magazinePart = ((REARM_COUNT select _idx) / (getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"))) min 1; + _cal * _magazinePart + }; + TRACE_1("Adding",_amountToAdd); + [_truck, (_supply + _amountToAdd)] call FUNC(setSupplyCount); +}; + +// With magazine specific supply, we add or update the magazineSupply array +if (GVAR(supply) == 2) then { + private _magazineSupply = _truck getVariable [QGVAR(magazineSupply), []]; + private _magazineIdx = -1; + { + _x params ["_magazine", "_rounds"]; + if ((_magazine isEqualTo _magazineClass)) exitWith { + _magazineIdx = _forEachIndex; + }; + } forEach _magazineSupply; + + private _roundsPerTransaction = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); + if (_partial) then { + _roundsPerTransaction = _roundsPerTransaction min (REARM_COUNT select _idx); + }; + if (_magazineIdx == -1) then { + if (_magazineSupply isEqualTo []) then { + _magazineSupply = [[_magazineClass, _roundsPerTransaction]]; + } else { + _magazineSupply append [[_magazineClass, _roundsPerTransaction]]; + } + } else { + (_magazineSupply select _magazineIdx) params ["", "_rounds"]; + _magazineSupply set [_magazineIdx, [_magazineClass, (_rounds + _roundsPerTransaction)]]; + }; + _truck setVariable [QGVAR(magazineSupply), _magazineSupply, true]; +}; diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf index db92df470d..a714a1987a 100644 --- a/addons/rearm/functions/fnc_addRearmActions.sqf +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: GitHawk * Show the resupplyable ammunition of all surrounding vehicles. * * Arguments: - * 0: Target + * 0: Ammo Truck * * Return Value: * ChildActions @@ -13,79 +14,70 @@ * * Public: No */ -#include "script_component.hpp" -private ["_vehicleActions", "_actions", "_action", "_vehicles", "_vehicle", "_needToAdd", "_magazineHelper", "_turretPath", "_magazines", "_magazine", "_icon", "_cnt"]; -params [["_target", objNull, [objNull]]]; +params ["_truck"]; -_vehicles = nearestObjects [_target, ["AllVehicles"], 20]; -if (count _vehicles < 2) exitWith {false}; // Rearming needs at least 2 vehicles +private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20]; +_vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}}; -_vehicleActions = []; +private _vehicleActions = []; { - _actions = []; - _vehicle = _x; - _needToAdd = false; - _action = []; - if !((_vehicle == _target) || (_vehicle isKindOf "CAManBase")) then { - _magazineHelper = []; - { - _turretPath = _x; - _magazines = [_vehicle, _turretPath] call FUNC(getConfigMagazines); - { - _magazine = _x; - _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); - if ((_currentMagazines < ([_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines))) && !(_magazine in _magazineHelper)) then { - _action = [_magazine, - getText(configFile >> "CfgMagazines" >> _magazine >> "displayName"), - getText(configFile >> "CfgMagazines" >> _magazine >> "picture"), - {_this call FUNC(takeAmmo)}, - {true}, - {}, - [_magazine, _vehicle]] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _target]; - _magazineHelper pushBack _magazine; - _needToAdd = true; - } else { - if (((_vehicle magazineTurretAmmo [_magazine, _turretPath]) < getNumber (configFile >> "CfgMagazines" >> _magazine >> "count")) && !(_magazine in _magazineHelper)) then { - _action = [_magazine, - getText(configFile >> "CfgMagazines" >> _magazine >> "displayName"), - getText(configFile >> "CfgMagazines" >> _magazine >> "picture"), - {_this call FUNC(takeAmmo)}, - {true}, - {}, - [_magazine, _vehicle]] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _target]; - _magazineHelper pushBack _magazine; - _needToAdd = true; - }; - }; - } forEach _magazines; - } forEach REARM_TURRET_PATHS; - }; - if (_needToAdd && !(_vehicle getVariable [QGVAR(disabled), false])) then { - _icon = getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Icon"); + private _vehicle = _x; + + // 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); + + if (!(_magazineHelper isEqualTo [])) then { + private _icon = getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Icon"); if !((_icon select [0, 1]) == "\") then { _icon = ""; }; if (GVAR(level) == 0) then { - _action = [_vehicle, + // [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); - _vehicleActions pushBack [_action, [], _target]; + _vehicle + ] call EFUNC(interact_menu,createAction); + _vehicleActions pushBack [_action, [], _truck]; } else { - _action = [_vehicle, + // [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); + + _actions pushBack [_action, [], _truck]; + } forEach _magazineHelper; + + private _action = [ + _vehicle, getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), _icon, {}, {true}, {}, - []] call EFUNC(interact_menu,createAction); - _vehicleActions pushBack [_action, _actions, _target]; + [] + ] call EFUNC(interact_menu,createAction); + + _vehicleActions pushBack [_action, _actions, _truck]; }; }; } forEach _vehicles; diff --git a/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf new file mode 100644 index 0000000000..1ab5377aad --- /dev/null +++ b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Adds all magazines of a vehicle to the supply. + * + * Arguments: + * 0: Ammo Truck + * 1: Vehicle object or Vehicle class + * + * Return Value: + * None + * + * Example: + * [ammo_truck, tank] call ace_rearm_fnc_addVehicleMagazinesToSupply + * [ammo_truck, "B_MBT_01_arty_F"] call ace_rearm_fnc_addVehicleMagazinesToSupply + * + * Public: Yes + */ + +if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the settings are initialized + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addVehicleMagazinesToSupply), _this]; +}; + +params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull, ""]]]; +TRACE_2("addVehicleMagazinesToSupply",_truck,_vehicle); + +if (isNull _truck) exitWith {}; +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(getTurretConfigMagazines); + TRACE_2("",_turretPath,_magazines); + { + [_truck, _x] call FUNC(addMagazineToSupply); + false + } count _magazines; + false +} count _turrets; + +// 1.70 pylons +private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; +{ + private _defaultMag = getText (_x >> "attachment"); + TRACE_3("",_defaultMag,configName _x,_forEachIndex); + [_truck, _defaultMag] call FUNC(addMagazineToSupply); +} forEach _pylonConfigs; diff --git a/addons/rearm/functions/fnc_canReadSupplyCounter.sqf b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf new file mode 100644 index 0000000000..66ab8534bd --- /dev/null +++ b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Checks if unit can read supply counter. [Only for GVAR(supply) > 0] + * + * Arguments: + * 0: Ammo Truck + * 1: Unit + * + * Return Value: + * Can read supply counter + * + * Example: + * [ammo_truck, player] call ace_rearm_fnc_canReadSupplyCounter + * + * Public: No + */ + +params ["_truck", "_unit"]; + +(alive _unit) +&& {_unit isKindOf "CAManBase"} +&& {local _unit} +&& {alive _truck} +&& {(_truck distance _unit) < REARM_ACTION_DISTANCE} +&& {GVAR(supply) > 0} +&& {[_unit, _truck, ["IsNotInside"]] call EFUNC(common,canInteractWith)} // manually added actions need this + diff --git a/addons/rearm/functions/fnc_canRearm.sqf b/addons/rearm/functions/fnc_canRearm.sqf index 202524dd10..bda5d8088c 100644 --- a/addons/rearm/functions/fnc_canRearm.sqf +++ b/addons/rearm/functions/fnc_canRearm.sqf @@ -1,29 +1,34 @@ +#include "script_component.hpp" /* * Author: GitHawk, Jonpas * Check if a unit can rearm. * * Arguments: - * 0: Target + * 0: Vehicle * 1: Unit * * Return Value: * Can Rearm * * Example: - * [player, tank] call ace_rearm_fnc_canRearm + * [tank, player] call ace_rearm_fnc_canRearm * * Public: No */ -#include "script_component.hpp" -private ["_dummy","_magazineClass"]; -params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]]; +params ["_vehicle", "_unit"]; -if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {_target distance _unit > REARM_ACTION_DISTANCE} || {_target getVariable [QGVAR(disabled), false]}) exitWith {false}; +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}; -_dummy = _unit getVariable [QGVAR(dummy), objNull]; +private _dummy = _unit getVariable [QGVAR(dummy), objNull]; if (isNull _dummy) exitwith {false}; -_magazineClass = _dummy getVariable QGVAR(magazineClass); +private _magazineClass = _dummy getVariable QGVAR(magazineClass); if (isNil "_magazineClass") exitWith {false}; -([_target, _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 a3139d6f11..24d1901690 100644 --- a/addons/rearm/functions/fnc_canStoreAmmo.sqf +++ b/addons/rearm/functions/fnc_canStoreAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Check if a unit can store ammo in an ammo truck. @@ -10,16 +11,17 @@ * Can Store Ammo * * Example: - * [player, tank] call ace_rearm_fnc_canStoreAmmo + * [ammo_truck, player] call ace_rearm_fnc_canStoreAmmo * * Public: No */ -#include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]]; - -!(isNull _unit || - {!(_unit isKindOf "CAManBase")} || - {!local _unit} || - {(_target distance _unit) > REARM_ACTION_DISTANCE} || - {isNull (_unit getVariable [QGVAR(dummy), objNull])}) +params ["_truck", "_unit"]; + +(alive _unit) +&& {_unit isKindOf "CAManBase"} +&& {local _unit} +&& {!isNull (_unit getVariable [QGVAR(dummy), objNull])} +&& {alive _truck} +&& {(_truck distance _unit) < REARM_ACTION_DISTANCE} +&& {[_unit, _truck, ["IsNotInside"]] call EFUNC(common,canInteractWith)} // manually added actions need this diff --git a/addons/rearm/functions/fnc_canTakeAmmo.sqf b/addons/rearm/functions/fnc_canTakeAmmo.sqf index 496e7a12a4..911ffc8834 100644 --- a/addons/rearm/functions/fnc_canTakeAmmo.sqf +++ b/addons/rearm/functions/fnc_canTakeAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Check if a unit can pick up ammo. @@ -10,16 +11,17 @@ * Can Pick Up Ammo * * Example: - * [player, tank] call ace_rearm_fnc_canTakeAmmo + * [ammo_truck, player] call ace_rearm_fnc_canTakeAmmo * * Public: No */ -#include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]]; +params ["_truck", "_unit"]; -!(isNull _unit || - {!(_unit isKindOf "CAManBase")} || - {!local _unit} || - {(_target distance _unit) > REARM_ACTION_DISTANCE} || - {!isNull (_unit getVariable [QGVAR(dummy), objNull])}) +(alive _unit) +&& {_unit isKindOf "CAManBase"} +&& {local _unit} +&& {alive _truck} +&& {(_truck distance _unit) < REARM_ACTION_DISTANCE} +&& {isNull (_unit getVariable [QGVAR(dummy), objNull])} +&& {[_unit, _truck, ["IsNotInside"]] call EFUNC(common,canInteractWith)} // manually added actions need this diff --git a/addons/rearm/functions/fnc_createDummy.sqf b/addons/rearm/functions/fnc_createDummy.sqf index 38955fb806..05f6f3505b 100644 --- a/addons/rearm/functions/fnc_createDummy.sqf +++ b/addons/rearm/functions/fnc_createDummy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Creates a carryable ammunition dummy object. @@ -10,18 +11,16 @@ * Created Dummy * * Example: - * ["500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_createDummy + * [player, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_createDummy * * Public: No */ -#include "script_component.hpp" -private ["_ammo", "_dummyName", "_dummy"]; -params [["_unit", objNull, [objNull]], ["_magazineClass", "", [""]]]; +params ["_unit", "_magazineClass"]; -_ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); -_dummyName = getText (configFile >> "CfgAmmo" >> _ammo >> QGVAR(dummy)); -_dummy = objNull; +private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); +private _dummyName = getText (configFile >> "CfgAmmo" >> _ammo >> QGVAR(dummy)); +private _dummy = objNull; if !(_dummyName == "") then { _dummy = _dummyName createVehicle (position _unit); } else { @@ -30,4 +29,6 @@ if !(_dummyName == "") then { _dummy allowDamage false; _dummy setVariable [QGVAR(magazineClass), _magazineClass, true]; +TRACE_4("createdDummy",_unit,_magazineClass,_dummyName,_dummy); + _dummy diff --git a/addons/rearm/functions/fnc_disable.sqf b/addons/rearm/functions/fnc_disable.sqf index b5e8b77d04..4812c34cfb 100644 --- a/addons/rearm/functions/fnc_disable.sqf +++ b/addons/rearm/functions/fnc_disable.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: GitHawk - * Disables rearm for a vehicle. + * Disables being able to rearm a vehicle's turrets. [Global Effects] * * Arguments: - * 0: Target - * 1: Disable + * 0: Vehicle + * 1: Disable (optional) * * Return Value: * None @@ -15,7 +16,10 @@ * * Public: Yes */ -#include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_disable", true, [true]]]; -_target setVariable [QGVAR(disabled), _disable, true]; +params [ + ["_vehicle", objNull, [objNull]], + ["_disable", true, [true]] +]; + +_vehicle setVariable [QGVAR(disabled), _disable, true]; diff --git a/addons/rearm/functions/fnc_dropAmmo.sqf b/addons/rearm/functions/fnc_dropAmmo.sqf index eafc8bee50..d4c68ea34b 100644 --- a/addons/rearm/functions/fnc_dropAmmo.sqf +++ b/addons/rearm/functions/fnc_dropAmmo.sqf @@ -1,11 +1,12 @@ +#include "script_component.hpp" /* * Author: GitHawk * Drops a magazine, optionally deletes it and optionally unholsters the wepaon. * * Arguments: * 0: Unit - * 1: Delete dummy object (optional) - * 2: Unholster Weapon (optional) + * 1: Delete dummy object (optional) + * 2: Unholster Weapon (optional) * * Return Value: * None @@ -15,14 +16,14 @@ * * Public: No */ -#include "script_component.hpp" -private ["_dummy", "_actionID"]; -params [["_unit", objNull, [objNull]], ["_delete", false, [false]], ["_unholster", true, [true]]]; +params [ + "_unit", + ["_delete", false], + ["_unholster", true] +]; -if (isNull _unit) exitWith {}; - -_dummy = _unit getVariable [QGVAR(dummy), objNull]; +private _dummy = _unit getVariable [QGVAR(dummy), objNull]; if !(isNull _dummy) then { detach _dummy; if (_delete) then { @@ -31,14 +32,14 @@ if !(isNull _dummy) then { _dummy setVelocity [0,0,-0.1]; }; _unit setVariable [QGVAR(dummy), objNull]; - //_unit setVariable [QEGVAR(dragging,isCarrying), false, true]; // breaks things, since it hides interact menu on _target }; -_actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; +private _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; 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..95f773e1bb --- /dev/null +++ b/addons/rearm/functions/fnc_getAllRearmTurrets.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +/* + * 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 + */ + +params ["_vehicle"]; + +private _turrets = if (_vehicle isEqualType objNull) then { + allTurrets _vehicle; +} else { + [_vehicle] call BIS_fnc_allTurrets; // "Does what allTurrets command does, except the param is vehicle's config class name" +}; + +// 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 new file mode 100644 index 0000000000..6c37deb938 --- /dev/null +++ b/addons/rearm/functions/fnc_getCaliber.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Get the caliber of the ammo in a magazine and return its parameters. + * + * Arguments: + * 0: Magazine Classname + * + * Return Value: + * 0: Caliber information + * 0: Rounded caliber + * 1: Caliber index + * + * Example: + * ["500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getCaliber + * + * Public: No + */ + +params [ + ["_magazineClass", ""] +]; + +if (_magazineClass isEqualTo "") exitWith {[8, 2]}; + +private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); +private _tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_caliber"); +private _cal = 8; +if (_tmpCal > 0) then { + _cal = _tmpCal; +} else { + _tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(caliber)); + if (_tmpCal > 0) then { + _cal = _tmpCal; + } else { + diag_log format ["[ACE] ERROR: Undefined Ammo [%1 : %2]", _ammo, inheritsFrom (configFile >> "CfgAmmo" >> _ammo)]; + if (_ammo isKindOf "BulletBase") then { + _cal = 8; + } else { + _cal = 100; + }; + }; +}; +_cal = round _cal; +private _idx = REARM_CALIBERS find _cal; +if (_idx == -1 ) then { + _idx = 2; +}; + +[_cal, _idx] diff --git a/addons/rearm/functions/fnc_getConfigMagazines.sqf b/addons/rearm/functions/fnc_getConfigMagazines.sqf deleted file mode 100644 index dce6c5da64..0000000000 --- a/addons/rearm/functions/fnc_getConfigMagazines.sqf +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Author: GitHawk, Jonpas - * Returns all magazines a turret can hold according to config. - * - * Arguments: - * 0: Target - * 1: Turret Path - * - * Return Value: - * Magazine classes in TurretPath - * - * Example: - * [vehicle, [0]] call ace_rearm_fnc_getConfigMagazines - * - * Public: No - */ -#include "script_component.hpp" - -params [["_target", objNull, [objNull]], ["_turretPath", [], [[]]]]; - -if (isNull _target) exitWith {[]}; - -_cfg = configFile >> "CfgVehicles" >> (typeOf _target) >> "Turrets"; - -if (count _turretPath == 1) then { - _turretPath params ["_subPath"]; - - if (_subPath == -1) exitWith { - _cfg = configFile >> "CfgVehicles" >> (typeOf _target); - }; - - if (count _cfg > _subPath) then { - _cfg = _cfg select _subPath; - } else { - _cfg = nil; - }; -} else { - _turretPath params ["", "_subPath"]; - if (count _cfg > 0) then { - _cfg = (_cfg select 0) >> "Turrets"; - if (count _cfg > _subPath) then { - _cfg = _cfg select _subPath; - } else { - _cfg = nil; - }; - } else { - _cfg = nil; - }; -}; - -if !(isClass _cfg) exitWith {[]}; - -getArray (_cfg >> "magazines") diff --git a/addons/rearm/functions/fnc_getMaxMagazines.sqf b/addons/rearm/functions/fnc_getMaxMagazines.sqf index 4b92431ed9..45f90d6579 100644 --- a/addons/rearm/functions/fnc_getMaxMagazines.sqf +++ b/addons/rearm/functions/fnc_getMaxMagazines.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: GitHawk, Jonpas * Calculates the maximum number of magazines a turret can hold according to config. * * Arguments: - * 0: Target + * 0: Vehicle * 1: Turret Path * 2: Magazine Classname * @@ -15,11 +16,8 @@ * * Public: No */ -#include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_turretPath", [], [[]]], ["_magazineClass", "", [""]]]; +params ["_vehicle", "_turretPath", "_magazineClass"]; -if (isNull _target) exitWith {0}; - -private _count = {_x == _magazineClass} count ([_target, _turretPath] call FUNC(getConfigMagazines)); +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 f56b437708..e2a06075d5 100644 --- a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf +++ b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf @@ -1,44 +1,87 @@ +#include "script_component.hpp" /* - * 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: Target - * 1: Magazine Classname + * 0: Vehicle * * Return Value: - * Return Value - * 0: Can Rearm - * 1: TurretPath - * 2: Number of current magazines in turret path + * 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, "mag"] call ace_rearm_fnc_getNeedRearmMagazines + * [tank] call ace_rearm_fnc_getNeedRearmMagazines * * Public: No */ -#include "script_component.hpp" -private ["_return", "_magazines", "_currentMagazines"]; -params ["_target", "_magazineClass"]; +params ["_vehicle"]; -_return = [false, [], 0]; +private _magazineInfo = []; + +// 1.70 pylons +private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; { - _magazines = [_target, _x] call FUNC(getConfigMagazines); + 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 { - _currentMagazines = {_x == _magazineClass} count (_target magazinesTurret _x); - - if ((_target magazineTurretAmmo [_magazineClass, _x]) < getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count")) exitWith { - _return = [true, _x, _currentMagazines]; - }; - - if (_currentMagazines < ([_target, _x, _magazineClass] call FUNC(getMaxMagazines))) exitWith { - _return = [true, _x, _currentMagazines]; + _magazineInfo pushBack [_pylonMagazine, _pylonTurret, true, _pylonIndex, 1, 1, _maxRounds, [_currentRounds]]; }; }; +} forEach _pylonConfigs; - if (_return select 0) exitWith {}; -} forEach REARM_TURRET_PATHS; +private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); +{ + private _turretPath = _x; + private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines); -_return + // _magazines without duplicates + private _magazineClasses = _magazines arrayIntersect _magazines; + + { + 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 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]; + }; + + } forEach _magazineClasses; +} forEach _turrets; + +TRACE_2("getNeedRearmMagazines",_vehicle,_magazineInfo); +_magazineInfo diff --git a/addons/rearm/functions/fnc_getSupplyCount.sqf b/addons/rearm/functions/fnc_getSupplyCount.sqf new file mode 100644 index 0000000000..892764b76f --- /dev/null +++ b/addons/rearm/functions/fnc_getSupplyCount.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Get the supply count. + * + * Arguments: + * 0: Ammo Truck + * + * Return Value: + * Supply count + * + * Example: + * [ammo_truck] call ace_rearm_fnc_getSupplyCount + * + * Public: Yes + */ + +params [["_truck", objNull, [objNull]]]; + +if (GVAR(supply) != 1) exitWith { + WARNING("supply setting is not set to limited"); // func shouldn't have been called + -1 +}; + +private _supply = _truck getVariable QGVAR(currentSupply); + +if (isNil "_supply") then { + if (isNumber (configFile >> "CfgVehicles" >> typeOf _truck >> QGVAR(defaultSupply))) then { + _supply = getNumber (configFile >> "CfgVehicles" >> typeOf _truck >> QGVAR(defaultSupply)); + } else { + _supply = 1200; + }; + if (_supply > 0) then { + _truck setVariable [QGVAR(currentSupply), _supply, true]; + }; +}; + +_supply diff --git a/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf new file mode 100644 index 0000000000..56a2fbdf05 --- /dev/null +++ b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf @@ -0,0 +1,19 @@ +#include "script_component.hpp" +/* + * Author: GitHawk, Jonpas + * Returns all magazines a turret of a vehicle object can hold according to config. + * + * Arguments: + * 0: Vehicle object or typeOf + * 1: Turret Path + * + * Return Value: + * Magazine classes in TurretPath + * + * Example: + * [vehicle, [0]] call ace_rearm_fnc_getTurretConfigMagazines + * + * Public: No + */ + +getArray ((_this call CBA_fnc_getTurret) >> "magazines") diff --git a/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf new file mode 100644 index 0000000000..2e914f3e7a --- /dev/null +++ b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 9573ac85a5..8a72ec2cf1 100644 --- a/addons/rearm/functions/fnc_grabAmmo.sqf +++ b/addons/rearm/functions/fnc_grabAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Grabs an dummy ammo. @@ -14,15 +15,15 @@ * * Public: No */ -#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); +REARM_HOLSTER_WEAPON; +[_unit, "forceWalk", "ACE_rearm", true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", "ACE_rearm", true] call EFUNC(common,statusEffect_set); [ - 5, + TIME_PROGRESSBAR(5), [_dummy, _unit], { params ["_args"]; diff --git a/addons/rearm/functions/fnc_handleKilled.sqf b/addons/rearm/functions/fnc_handleKilled.sqf index 5f80246f52..6ba6e4f4ee 100644 --- a/addons/rearm/functions/fnc_handleKilled.sqf +++ b/addons/rearm/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk, Jonpas * Handles medical on set dead event. @@ -13,9 +14,8 @@ * * Public: No */ -#include "script_component.hpp" -params [["_unit", objNull, [objNull]]]; +params ["_unit"]; if (!local _unit) exitWith {}; diff --git a/addons/rearm/functions/fnc_handleRespawn.sqf b/addons/rearm/functions/fnc_handleRespawn.sqf new file mode 100644 index 0000000000..a1ddd97301 --- /dev/null +++ b/addons/rearm/functions/fnc_handleRespawn.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: unknown + * Called when a unit is Respawned + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [bob] call ACE_rearm_fnc_handleRespawn + * + * Public: No + */ + +params ["_unit"]; +if !(local _unit) exitWith {}; + +_unit setVariable [QGVAR(selectedWeaponOnRearm), nil]; +_unit setVariable [QGVAR(carriedMagazine), nil]; +private _dummy = _unit getVariable [QGVAR(dummy), objNull]; +if !(isNull _dummy) then { + detach _dummy; + deleteVehicle _dummy; +}; +_unit setVariable [QGVAR(dummy), nil]; diff --git a/addons/rearm/functions/fnc_handleUnconscious.sqf b/addons/rearm/functions/fnc_handleUnconscious.sqf index eab25fcf64..18a8af4b56 100644 --- a/addons/rearm/functions/fnc_handleUnconscious.sqf +++ b/addons/rearm/functions/fnc_handleUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk, Jonpas * Handles medical on unconscious event. @@ -14,9 +15,8 @@ * * Public: No */ -#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 new file mode 100644 index 0000000000..232d6776ad --- /dev/null +++ b/addons/rearm/functions/fnc_hasEnoughSupply.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* +* Author: GitHawk +* Check whether enough supply is left to take the magazine. +* +* Arguments: +* 0: Ammo Truck +* 1: Magazine Classname +* +* Return Value: +* Enough supply +* +* Example: +* [ammo_truck, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_hasEnoughSupply +* +* Public: No +*/ + +params ["_truck", "_magazineClass"]; + +// With infinite supply, there is always enough +if (GVAR(supply) == 0) exitWith {true}; + + +// With limited supply, we need to check supply +if (GVAR(supply) == 1) exitWith { + private _supply = [_truck] call FUNC(getSupplyCount); + ([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; + + // With caliber based rearming, we only need partial supply + if (GVAR(level) == 2) exitWith { + // If REARM_COUNT is bigger than the magazine size, we might get a bigger number than 1 + private _magazinePart = ((REARM_COUNT select _idx) / (getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"))) min 1; + (_cal * _magazinePart <= _supply) + }; + (_cal <= _supply) +}; + + +// With magazine specific supply, we need to check stored magazines +if (GVAR(supply) == 2) exitWith { + private _magazineSupply = _truck getVariable [QGVAR(magazineSupply), []]; + private _magazinePresent = false; + { + _x params ["_magazine", "_rounds"]; + if ((_magazine isEqualTo _magazineClass) && (_rounds > 0)) exitWith {_magazinePresent = true; }; + false + } count _magazineSupply; + _magazinePresent +}; diff --git a/addons/rearm/functions/fnc_initSupplyVehicle.sqf b/addons/rearm/functions/fnc_initSupplyVehicle.sqf new file mode 100644 index 0000000000..9ca8728833 --- /dev/null +++ b/addons/rearm/functions/fnc_initSupplyVehicle.sqf @@ -0,0 +1,76 @@ +#include "script_component.hpp" +/* + * Author: Githawk, PabstMirror + * Adds rearm supply actions to a vehicle or ammo container. + * + * Arguments: + * 0: Object + * + * Return Value: + * None + * + * Example: + * [ammoTruck] call ace_rearm_fnc_initSupplyVehicle; + * + * Public: No + */ + +if (!hasInterface) exitWith {}; // For now we just add actions, so no need non-clients + +params ["_vehicle"]; +private _typeOf = typeOf _vehicle; +TRACE_2("initSupplyVehicle",_vehicle,_typeOf); + +if (!alive _vehicle) exitWith {}; + +private _configSupply = getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(defaultSupply)); +private _isSupplyVehicle = _vehicle getVariable [QGVAR(isSupplyVehicle), false]; +private _oldRearmConfig = isClass (configFile >> "CfgVehicles" >> _typeOf >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(takeAmmo)); +TRACE_3("",_configSupply,_isSupplyVehicle,_oldRearmConfig); + +if ((_configSupply <= 0) && {!_isSupplyVehicle} && {!_oldRearmConfig}) exitWith {}; // Ignore if not enabled +if ((_oldRearmConfig || {_configSupply > 0}) && {_typeOf in GVAR(configTypesAdded)}) exitWith {}; // Only add class actions once +if (_oldRearmConfig || {_configSupply > 0}) then {GVAR(configTypesAdded) pushBack _typeOf}; + + +private _actionReadSupplyCounter = [ // GVAR(supply) > 0 + QGVAR(ReadSupplyCounter), + localize LSTRING(ReadSupplyCounter), // Check remaining ammunition + QPATHTOF(ui\icon_rearm_interact.paa), + {_this call FUNC(readSupplyCounter)}, + {_this call FUNC(canReadSupplyCounter)} +] call EFUNC(interact_menu,createAction); + +private _actionTakeAmmo = [ + QGVAR(takeAmmo), + localize ([LSTRING(Rearm), LSTRING(TakeAmmo)] select (GVAR(level) > 0)), + QPATHTOF(ui\icon_rearm_interact.paa), + {}, + {_this call FUNC(canTakeAmmo)}, + {_this call FUNC(addRearmActions)} +] call EFUNC(interact_menu,createAction); + +private _actionStoreAmmo = [ + QGVAR(StoreAmmo), + localize LSTRING(StoreAmmo), // "Store ammo" + QPATHTOF(ui\icon_rearm_interact.paa), + {_this call FUNC(storeAmmo)}, + {_this call FUNC(canStoreAmmo)} +] call EFUNC(interact_menu,createAction); + +if (_oldRearmConfig || {_configSupply > 0}) then { + TRACE_1("Adding Class Actions",_typeOf); + [_typeOf, 0, ["ACE_MainActions"], _actionReadSupplyCounter] call EFUNC(interact_menu,addActionToClass); + if (!_oldRearmConfig) then { + [_typeOf, 0, ["ACE_MainActions"], _actionTakeAmmo] call EFUNC(interact_menu,addActionToClass); + [_typeOf, 0, ["ACE_MainActions"], _actionStoreAmmo] call EFUNC(interact_menu,addActionToClass); + } else { + WARNING_1("Actions already present on [%1]. Old Compat PBO?",_typeOf); + }; +} else { + TRACE_1("Adding Object Actions",_typeOf); + [_vehicle, 0, ["ACE_MainActions"], _actionReadSupplyCounter] call EFUNC(interact_menu,addActionToObject); + [_vehicle, 0, ["ACE_MainActions"], _actionTakeAmmo] call EFUNC(interact_menu,addActionToObject); + [_vehicle, 0, ["ACE_MainActions"], _actionStoreAmmo] call EFUNC(interact_menu,addActionToObject); +}; + diff --git a/addons/rearm/functions/fnc_makeDummy.sqf b/addons/rearm/functions/fnc_makeDummy.sqf index 5c19f8f12d..d319d3587e 100644 --- a/addons/rearm/functions/fnc_makeDummy.sqf +++ b/addons/rearm/functions/fnc_makeDummy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Make a dummy object by disabling collision and turning it. @@ -14,9 +15,8 @@ * * Public: No */ -#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 af627862da..4b61cfa2ee 100644 --- a/addons/rearm/functions/fnc_moduleRearmSettings.sqf +++ b/addons/rearm/functions/fnc_moduleRearmSettings.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * Author: GitHawk - * Module for adjusting the refuel settings. + * Module for adjusting the rearm settings. * * Arguments: * 0: The module logic @@ -10,17 +11,21 @@ * Return Value: * None * - * Example; + * Example: * function = "ace_rearm_fnc_moduleRearmSettings" * * Public: No */ -#include "script_component.hpp" -params ["_logic", "", ["_activated", false, [false]]]; +params [ + "_logic", + "", + ["_activated", false, [false]] +]; if (!_activated) exitWith {}; [_logic, QGVAR(level), "level"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(supply), "supply"] call EFUNC(common,readSettingFromModule); -diag_log text format ["[ACE]: Rearm Module Initialized on level: %1", GVAR(level)]; +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 653c131586..a47885e716 100644 --- a/addons/rearm/functions/fnc_pickUpAmmo.sqf +++ b/addons/rearm/functions/fnc_pickUpAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Starts progress bar for picking up a specific kind of magazine from the ground. @@ -14,17 +15,16 @@ * * Public: No */ -#include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]]; +params ["_dummy", "_unit"]; -_dummy = _unit getVariable [QGVAR(dummy), objNull]; -if !(isNull _dummy) exitWith {}; +private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; +if !(isNull _attachedDummy) exitWith {}; -//_target attachTo [_unit, [0,0.7,0], "pelvis"]; -_target attachTo [_unit, [0,1,0], "pelvis"]; -{ - [QGVAR(makeDummyEH), [_dummy, [[-1,0,0],[0,0,1]]], _x] call CBA_fnc_targetEvent; -} count (position _unit nearObjects ["CAManBase", 100]); -_unit setVariable [QGVAR(dummy), _target]; -//_unit setVariable [QEGVAR(dragging,isCarrying), true, true]; // breaks things, since it hides interact menu on _target +_dummy attachTo [_unit, [0,1,0], "pelvis"]; + +private _nearUnits = _unit nearObjects ["CAManBase", 100]; +// disableCollisionWith damage with the nearby units: +[QGVAR(makeDummyEH), [_dummy, [[-1,0,0],[0,0,1]]], _nearUnits] call CBA_fnc_targetEvent; + +_unit setVariable [QGVAR(dummy), _dummy]; diff --git a/addons/rearm/functions/fnc_readSupplyCounter.sqf b/addons/rearm/functions/fnc_readSupplyCounter.sqf new file mode 100644 index 0000000000..31edaa2684 --- /dev/null +++ b/addons/rearm/functions/fnc_readSupplyCounter.sqf @@ -0,0 +1,76 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Get the remaining ammunition amount. + * + * Arguments: + * 0: Ammo Truck + * 1: Unit + * + * Return Value: + * None + * + * Example: + * [ammo_truck, player] call ace_rearm_fnc_readSupplyCounter + * + * Public: No + */ + +params ["_truck", "_unit"]; +TRACE_2("readSupplyCounter",_truck,_unit); + +if (GVAR(supply) == 0) exitWith {WARNING("Supply is unlimited");}; + +if (GVAR(supply) == 1) then { + [ + TIME_PROGRESSBAR(5), + [_unit, _truck, [_truck] call FUNC(getSupplyCount)], + { + params ["_args"]; + _args params [["_unit", objNull, [objNull]], ["_truck", objNull, [objNull]], ["_supplyCount", 0, [0]]]; + if (_supplyCount > 0 ) then { + [[LSTRING(Hint_RemainingSupplyPoints), _supplyCount], 2, _unit] call EFUNC(common,displayTextStructured); + } else { + [LSTRING(Hint_Empty), 2, _unit] call EFUNC(common,displayTextStructured); + }; + true + }, + {true}, + localize LSTRING(ReadSupplyCounterAction), + {true}, + ["isnotinside"] + ] call EFUNC(common,progressBar); +} else { + [ + TIME_PROGRESSBAR(5), + [_unit, _truck], + { + params ["_args"]; + _args params [["_unit", objNull, [objNull]], ["_truck", objNull, [objNull]]]; + private _supply = 1.5; + private _numChars = count (localize LSTRING(Hint_RemainingAmmo)); + private _text = ""; + private _magazines = _truck getVariable QGVAR(magazineSupply); + if !(isNil "_magazines") then { + { + _x params ["_magazineClass", "_rounds"]; + private _line = format ["%1: %2", getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), _rounds]; + _numChars = _numChars max (count _line); + _text = format ["%1
%2", _text, _line]; + _supply = _supply + 0.5; + false + } count _magazines; + }; + if (_supply > 1.5) then { + [[LSTRING(Hint_RemainingAmmo), _text], _supply, _unit, (_numChars/2.9)] call EFUNC(common,displayTextStructured); + } else { + [LSTRING(Hint_Empty), 2, _unit] call EFUNC(common,displayTextStructured); + }; + true + }, + {true}, + localize LSTRING(ReadSupplyCounterAction), + {true}, + ["isnotinside"] + ] call EFUNC(common,progressBar); +}; diff --git a/addons/rearm/functions/fnc_rearm.sqf b/addons/rearm/functions/fnc_rearm.sqf index 61009b085d..bf703e9b6b 100644 --- a/addons/rearm/functions/fnc_rearm.sqf +++ b/addons/rearm/functions/fnc_rearm.sqf @@ -1,75 +1,56 @@ +#include "script_component.hpp" /* * Author: GitHawk * Starts progress bar for rearming a vehicle. * * Arguments: - * 0: Unit + * 0: Target Vehicle + * 1: Unit * * Return Value: * None * * Example: - * [player] call ace_rearm_fnc_rearm + * [tank, player] call ace_rearm_fnc_rearm * * Public: No */ -#include "script_component.hpp" -private ["_magazineClass", "_ammo", "_tmpCal", "_cal", "_idx", "_needRearmMags", "_magazineDisplayName"]; -params [["_unit", objNull, [objNull]]]; +params ["_target", "_unit"]; +TRACE_2("rearm",_target,_unit); -_dummy = _unit getVariable [QGVAR(dummy), objNull]; -if (isNull _dummy) exitwith {false}; -_magazineClass = _dummy getVariable QGVAR(magazineClass); -if (isNil "_magazineClass") exitWith {false}; +private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; +if (isNull _attachedDummy) exitwith {ERROR_1("attachedDummy null",_attachedDummy);}; +private _magazineClass = _attachedDummy getVariable QGVAR(magazineClass); +if (isNil "_magazineClass") exitWith {ERROR_1("magazineClass nil",_attachedDummy);}; -_ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); -_tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_caliber"); -_cal = 8; -if (_tmpCal > 0) then { - _cal = _tmpCal; -} else { - _tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(caliber)); - if (_tmpCal > 0) then { - _cal = _tmpCal; - } else { - diag_log format ["[ACE] ERROR: Undefined Ammo [%1 : %2]", _ammo, inheritsFrom (configFile >> "CfgAmmo" >> _ammo)]; - if (_ammo isKindOf "BulletBase") then { - _cal = 8; - } else { - _cal = 100; - }; - }; -}; -_cal = round _cal; -_idx = REARM_CALIBERS find _cal; -if (_idx == -1) then { - _idx = 2; -}; +([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; // Get magazines that can be rearmed -_needRearmMags = [_target, _magazineClass] call FUNC(getNeedRearmMagazines); -_needRearmMags params ["_needRearm", "_turretPath", "_cnt"]; +private _needRearmMags = [_target] call FUNC(getNeedRearmMagazines); +private _needRearmMagsOfClass = _needRearmMags select {(_x select 0) isEqualTo _magazineClass}; // Exit if no magazines need rearming -if (!_needRearm) exitWith { - diag_log format ["[ACE] ERROR: 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);}; -//hint format ["Magazine: %1\nAmmo: %2\nCaliber: %3\nIndex: %4\nTurretPath: %5\nREARM_DURATION_REARM: %6\nCount: %7", _magazine, _ammo, _cal, _idx, _turretPath, (REARM_DURATION_REARM select _idx), (REARM_COUNT select _idx)]; +private _currentRearmableMag = _needRearmMagsOfClass select 0; +_currentRearmableMag params ["", "_turretPath", "", "_pylon", "", "_magazineCount"]; -_magazineDisplayName = getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"); +private _magazineDisplayName = getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"); if (_magazineDisplayName == "") then { _magazineDisplayName = _magazineClass; - diag_log format ["[ACE] ERROR: Magazine is missing display name [%1]", _magazineClass]; + ERROR_1("Magazine is missing display name [%1]",_magazineClass); }; [ - (REARM_DURATION_REARM select _idx), - [_target, _unit, _turretPath, _cnt, _magazineClass, (REARM_COUNT select _idx)], - FUNC(rearmSuccess), + TIME_PROGRESSBAR(REARM_DURATION_REARM select _idx), + [_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 27fd20c528..b136c5d267 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Starts progress bar for rearming an entire vehicle. @@ -15,15 +16,19 @@ * * Public: No */ -#include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]], ["_vehicle", objNull, [objNull]]]; // _target is for future possible finite ammo, _unit placeholder + +params ["_truck", "_player", "_vehicle"]; +TRACE_3("rearmEntireVehicle",_truck,_player,_vehicle); [ - 10, - _vehicle, + TIME_PROGRESSBAR(10), + [_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 2eb0b408f9..f3eecbb245 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf @@ -1,43 +1,37 @@ +#include "script_component.hpp" /* * Author: GitHawk * Rearm an entire vehicle. * * Arguments: - * 0: Vehicle + * 0: Rearm information + * 0: Ammo Truck + * 1: Vehicle * * Return Value: * None * * Example: - * [tank] call ace_rearm_fnc_rearmEntireVehicleSuccess + * [[ammo_truck, tank]] call ace_rearm_fnc_rearmEntireVehicleSuccess * * Public: No */ -#include "script_component.hpp" -private ["_turretPath", "_magazines", "_magazine", "_currentMagazines", "_maxMagazines", "_maxRounds", "_currentRounds"]; -params [["_vehicle", objNull, [objNull]]]; -TRACE_1("params",_vehicle); +params ["_args"]; +_args params ["_truck", "_vehicle"]; +TRACE_2("rearmEntireVehicleSuccess",_truck,_vehicle); - -//ToDo: Cleanup with CBA_fnc_ownerEvent in CBA 2.4.2 -{ - [QGVAR(rearmEntireVehicleSuccessLocalEH), [_vehicle, _x]] call CBA_fnc_globalEvent; -} forEach REARM_TURRET_PATHS; - - -/* if (isServer) then { + private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); { - _turretOwnerID = _vehicle turretOwner _x; + private _turretOwnerID = _vehicle turretOwner _x; if (_turretOwnerID == 0) then { - //wtf is _truck from??? - [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _truck] call CBA_fnc_targetEvent; + [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], [_vehicle]] call CBA_fnc_targetEvent; } else { - [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_targetEvent; + [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent; }; - } count REARM_TURRET_PATHS; + false + } count _turrets; } else { - [QGVAR(rearmEntireVehicleSuccessLocalEH), _this] call CBA_fnc_serverEvent; + [QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent; }; -*/ diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf index 7d81aa6345..90845648ba 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf @@ -1,48 +1,58 @@ +#include "script_component.hpp" /* - * Author: GitHawk + * Author: Tuupertunut * Rearm an entire turret locally. * * Arguments: - * 0: Vehicle - * 1: TurretPath + * 0: Ammo Truck + * 1: Vehicle + * 2: TurretPath * * Return Value: * None * * Example: - * [tank, [0]] call ace_rearm_fnc_rearmEntireVehicleSuccessLocal + * [ammo_truck, tank, [0]] call ace_rearm_fnc_rearmEntireVehicleSuccessLocal * * Public: No */ -#include "script_component.hpp" -private ["_magazines", "_magazine", "_currentMagazines", "_maxMagazines", "_maxRounds", "_currentRounds"]; -params [["_vehicle", objNull, [objNull]], ["_turretPath", [], [[]]]]; -TRACE_2("params",_vehicle,_turretPath); +params ["_truck", "_vehicle", "_turretPath"]; +TRACE_3("rearmEntireVehicleSuccessLocal",_truck,_vehicle,_turretPath); -//ToDo: Cleanup with CBA_fnc_ownerEvent in CBA 2.4.2 -if (!(_vehicle turretLocal _turretPath)) exitWith {TRACE_1("not local turret",_turretPath);}; - -_magazines = [_vehicle, _turretPath] call FUNC(getConfigMagazines); +// Fetching all rearmable magazines in this turret +private _magazines = ([_vehicle] call FUNC(getNeedRearmMagazines)) select {(_x select 1) isEqualTo _turretPath}; { - _magazine = _x; - _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); - _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines); - _maxRounds = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); - _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; - }; - if (_currentMagazines < _maxMagazines) then { - _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; - for "_idx" from 1 to (_maxMagazines - _currentMagazines) do { - _vehicle addMagazineTurret [_magazine, _turretPath]; + _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 _currentRounds; + + // Trying to add new full magazines, if there is space left. + if (_currentMagazines < _maxMagazines) then { + for "_idx" from 1 to (_maxMagazines - _currentMagazines) do { + if ((GVAR(supply) == 0) || {[_truck, _magazineClass, _maxRoundsPerMag] call FUNC(removeMagazineFromSupply)}) then { + _plannedRounds pushBack _maxRoundsPerMag; + }; }; - } else { - _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; }; -} foreach _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 4a8e4972ed..d0610dbb5a 100644 --- a/addons/rearm/functions/fnc_rearmSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmSuccess.sqf @@ -1,49 +1,42 @@ +#include "script_component.hpp" /* * Author: GitHawk - * Rearms a vehicle. + * Rearms a vehicle, after progress bar finishes, pass args to machine where turret is local. * * Arguments: - * 0: Params - * 0: Target - * 1: Unit - * 2: Turret Path - * 3: Number of magazines - * 4: Magazine Classname - * 5: Number of rounds + * 0: Vehicle + * 1: Unit + * 2: Turret Path + * 3: Number of magazines + * 4: Magazine Classname + * 5: Number of rounds + * 6: Pylon Index * * Return Value: * None * * Example: - * [[vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500]] call ace_rearm_fnc_rearmSuccess + * [vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500, -1] call ace_rearm_fnc_rearmSuccess * * Public: No */ -#include "script_component.hpp" -private ["_dummy", "_weaponSelect", "_turretOwnerID"]; -params [["_args", [objNull, objNull, [], 0, "", 0], [[]], [6]]]; -_args params ["_target", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds"]; -TRACE_6("params",_target,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds); - -//hint format ["Target: %1\nTurretPath: %2\nNumMagazines: %3\nMagazine: %4\nNumRounds: %5", _target, _turretPath, _numMagazines, _magazineClass, _numRounds]; +params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"]; +TRACE_7("rearmSuccess",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon); if (local _unit) then { [_unit, true, true] call FUNC(dropAmmo); }; -//ToDo: Cleanup with CBA_fnc_ownerEvent in CBA 2.4.2 -[QGVAR(rearmSuccessLocalEH), _this] call CBA_fnc_globalEvent; +if (!alive _vehicle) exitWith {WARNING("vehicle dead/null");}; -/* if (isServer) then { - _turretOwnerID = _target turretOwner _turretPath; + private _turretOwnerID = _vehicle turretOwner _turretPath; if (_turretOwnerID == 0) then { - [QGVAR(rearmSuccessLocalEH), _this, _vehicle] call CBA_fnc_targetEvent; + [QGVAR(rearmSuccessLocalEH), _this, [_vehicle]] call CBA_fnc_targetEvent; } else { - [QGVAR(rearmSuccessLocalEH), _this, _turretOwnerID] call CBA_fnc_targetEvent; + [QGVAR(rearmSuccessLocalEH), _this, _turretOwnerID] call CBA_fnc_ownerEvent; }; } else { - [QGVAR(rearmSuccessLocalEH), _this] call CBA_fnc_serverEvent; + [QGVAR(rearmSuccessEH), _this] call CBA_fnc_serverEvent; }; - */ \ No newline at end of file diff --git a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf index dc4afbc886..d141ca4a64 100644 --- a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf @@ -1,110 +1,112 @@ +#include "script_component.hpp" /* * Author: GitHawk * Rearms a vehicle on the turret owner. * * Arguments: - * 0: Params - * 0: Target - * 1: Unit - * 2: Turret Path - * 3: Number of magazines - * 4: Magazine Classname - * 5: Number of rounds + * 0: Vehicle + * 1: Unit + * 2: Turret Path + * 3: Number of magazines + * 4: Magazine Classname + * 5: Number of rounds + * 6: Pylon Index * * Return Value: * None * * Example: - * [[vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500]] call ace_rearm_fnc_rearmSuccess + * [vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500, ""] call ace_rearm_fnc_rearmSuccessLocal * * Public: No */ -#include "script_component.hpp" -private ["_rounds", "_currentRounds", "_maxMagazines", "_currentMagazines", "_dummy", "_weaponSelect"]; -params [["_args", [objNull, objNull, [], 0, "", 0], [[]], [6]]]; -_args params ["_target", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds"]; -TRACE_6("params",_target,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds); +params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"]; +TRACE_7("rearmSuccessLocal",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon); -//ToDo: Cleanup with CBA_fnc_ownerEvent in CBA 2.4.2 -if (!(_target turretLocal _turretPath)) exitWith {TRACE_1("not local turret",_turretPath);}; +private _rounds = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); -//hint format ["Target: %1\nTurretPath: %2\nNumMagazines: %3\nMagazine: %4\nNumRounds: %5\nUnit: %6", _target, _turretPath, _numMagazines, _magazineClass, _numRounds, _unit]; +if (_pylon > 0) exitWith { + if (GVAR(level) == 1) then { + // Fill magazine completely + if (_turretPath isEqualTo [-1]) then {_turretPath = [];}; // Convert back to pylon turret format + TRACE_2("",_pylon,_magazineClass,_rounds); + _vehicle setPylonLoadOut [_pylon, _magazineClass, true, _turretPath]; + [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _rounds, + getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; + } else { + // Fill only at most _numRounds + if (_turretPath isEqualTo [-1]) then {_turretPath = [];}; // Convert back to pylon turret format + private _currentCount = _vehicle ammoOnPylon _pylon; + private _newCount = ((_currentCount max 0) + _numRounds) min _rounds; + TRACE_2("",_pylon,_magazineClass,_newCount); + _vehicle setPylonLoadOut [_pylon, _magazineClass, true, _turretPath]; + _vehicle setAmmoOnPylon [_pylon, _newCount]; + [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _numRounds, + getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; + }; +}; -_rounds = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); -_currentRounds = 0; +private _currentRounds = 0; +private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMaxMagazines); -_maxMagazines = [_target, _turretPath, _magazineClass] call FUNC(getMaxMagazines); if (_maxMagazines == 1) then { - _currentMagazines = { _x == _magazineClass } count (_target magazinesTurret _turretPath); + private _currentMagazines = { _x == _magazineClass } count (_vehicle magazinesTurret _turretPath); if (_currentMagazines == 0 && {!(_turretPath isEqualTo [-1])}) then { // Driver gun will always retain it's magazines - _target addMagazineTurret [_magazineClass, _turretPath]; + _vehicle addMagazineTurret [_magazineClass, _turretPath]; + _vehicle setMagazineTurretAmmo [_magazineClass, 0, _turretPath]; }; if (GVAR(level) == 1) then { // Fill magazine completely - _target setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; - [QEGVAR(common,displayTextStructured), - [ - [LSTRING(Hint_RearmedTriple), _rounds, + _vehicle setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; + [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _rounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), - getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit - ], - [_unit]] call CBA_fnc_targetEvent; + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; } else { // Fill only at most _numRounds - _target setMagazineTurretAmmo [_magazineClass, ((_target magazineTurretAmmo [_magazineClass, _turretPath]) + _numRounds) min _rounds, _turretPath]; - [QEGVAR(common,displayTextStructured), - [ - [LSTRING(Hint_RearmedTriple), _numRounds, + _vehicle setMagazineTurretAmmo [_magazineClass, ((_vehicle magazineTurretAmmo [_magazineClass, _turretPath]) + _numRounds) min _rounds, _turretPath]; + [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _numRounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), - getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit - ], - [_unit]] call CBA_fnc_targetEvent; + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; }; } else { for "_idx" from 1 to (_maxMagazines+1) do { - _currentRounds = _target magazineTurretAmmo [_magazineClass, _turretPath]; + _currentRounds = _vehicle magazineTurretAmmo [_magazineClass, _turretPath]; if (_currentRounds > 0 || {_idx == (_maxMagazines+1)}) exitWith { if (_idx == (_maxMagazines+1) && {!(_turretPath isEqualTo [-1])}) then { - _target addMagazineTurret [_magazineClass, _turretPath]; + _vehicle addMagazineTurret [_magazineClass, _turretPath]; }; if (GVAR(level) == 2) then { - //hint format ["Target: %1\nTurretPath: %2\nNumMagazines: %3\nMaxMagazines %4\nMagazine: %5\nNumRounds: %6\nMagazine: %7", _target, _turretPath, _numMagazines, _maxMagazines, _currentRounds, _numRounds, _magazineClass]; + //hint format ["Target: %1\nTurretPath: %2\nNumMagazines: %3\nMaxMagazines %4\nMagazine: %5\nNumRounds: %6\nMagazine: %7", _vehicle, _turretPath, _numMagazines, _maxMagazines, _currentRounds, _numRounds, _magazineClass]; // Fill only at most _numRounds if ((_currentRounds + _numRounds) > _rounds) then { - _target setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; + _vehicle setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; if (_numMagazines < _maxMagazines) then { - _target addMagazineTurret [_magazineClass, _turretPath]; - _target setMagazineTurretAmmo [_magazineClass, _currentRounds + _numRounds - _rounds, _turretPath]; + _vehicle addMagazineTurret [_magazineClass, _turretPath]; + _vehicle setMagazineTurretAmmo [_magazineClass, _currentRounds + _numRounds - _rounds, _turretPath]; }; } else { - _target setMagazineTurretAmmo [_magazineClass, _currentRounds + _numRounds, _turretPath]; + _vehicle setMagazineTurretAmmo [_magazineClass, _currentRounds + _numRounds, _turretPath]; }; - [QEGVAR(common,displayTextStructured), - [ - [LSTRING(Hint_RearmedTriple), _numRounds, + [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _numRounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), - getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit - ], - [_unit]] call CBA_fnc_targetEvent; + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; } else { // Fill current magazine completely and fill next magazine partially - _target setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; + _vehicle setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; if (_numMagazines < _maxMagazines) then { - _target addMagazineTurret [_magazineClass, _turretPath]; - _target setMagazineTurretAmmo [_magazineClass, _currentRounds, _turretPath]; + _vehicle addMagazineTurret [_magazineClass, _turretPath]; + _vehicle setMagazineTurretAmmo [_magazineClass, _currentRounds, _turretPath]; }; - [QEGVAR(common,displayTextStructured), - [ - [LSTRING(Hint_RearmedTriple), _rounds, + [QEGVAR(common,displayTextStructured), [[LSTRING(Hint_RearmedTriple), _rounds, getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), - getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit - ], - [_unit]] call CBA_fnc_targetEvent; + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], 3, _unit], [_unit]] call CBA_fnc_targetEvent; }; }; - _target removeMagazineTurret [_magazineClass, _turretPath]; + _vehicle removeMagazineTurret [_magazineClass, _turretPath]; _numMagazines = _numMagazines - 1; }; }; diff --git a/addons/rearm/functions/fnc_removeMagazineFromSupply.sqf b/addons/rearm/functions/fnc_removeMagazineFromSupply.sqf new file mode 100644 index 0000000000..b6e6c4d0d2 --- /dev/null +++ b/addons/rearm/functions/fnc_removeMagazineFromSupply.sqf @@ -0,0 +1,92 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Removes a magazine from the supply. + * + * Arguments: + * 0: Ammo Truck + * 1: Magazine Classname + * 2: Number of Rounds to withdraw (default: -1) + * + * Return Value: + * Magazine was removed + * + * Example: + * [ammo_truck, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_removeMagazineFromSupply + * + * Public: Yes + */ + +params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]], ["_numRounds", -1, [0]]]; +TRACE_3("removeMagazineFromSupply",_truck,_magazineClass,_numRounds); + +if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {false}; + +private _return = false; +([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; + +if (GVAR(supply) == 0) then { + WARNING("supply setting is set to unlimited"); // func shouldn't have been called + _return = true; +}; + +if (GVAR(supply) == 1) then { + private _supply = [_truck] call FUNC(getSupplyCount); + if (GVAR(level) == 2) then { + // Remove partial magazine supply count + private _rearmAmount = (REARM_COUNT select _idx); + if (_numRounds > 0) then { + _rearmAmount = _numRounds; + }; + private _magazinePart = (_rearmAmount / (getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"))) min 1; + if (_supply >= (_cal * _magazinePart)) then { + [_truck, (_supply - (_cal * _magazinePart))] call FUNC(setSupplyCount); + _return = true; + }; + } else { + // Remove entire magazine supply count + if (_supply >= _cal) then { + [_truck, (_supply - _cal)] call FUNC(setSupplyCount); + _return = true; + }; + }; +}; + +if (GVAR(supply) == 2) then { + private _magazineSupply = _truck getVariable [QGVAR(magazineSupply), []]; + private _magazineIdx = -1; + { + _x params ["_magazine"]; + if ((_magazine isEqualTo _magazineClass)) exitWith { + _magazineIdx = _forEachIndex; + }; + } forEach _magazineSupply; + if (_magazineIdx == -1) exitWith {false}; + + (_magazineSupply select _magazineIdx) params ["", "_rounds"]; + + private _configRounds = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); + if (GVAR(level) == 2) then { + // With caliber based rearming, we need to remove the correct amount + private _rearmAmount = (REARM_COUNT select _idx); + if (_numRounds > 0) then { + if (_numRounds > _rearmAmount) then { + _rearmAmount = ceil (_numRounds / _rearmAmount); + }; + }; + private _roundsPerTransaction = _rearmAmount min _configRounds; + if (_rounds >= _roundsPerTransaction) then { + _magazineSupply set [_magazineIdx, [_magazineClass, (_rounds - _roundsPerTransaction)]]; + _truck setVariable [QGVAR(magazineSupply), _magazineSupply, true]; + _return = true; + }; + } else { + // Remove entire magazine + if (_rounds >= _configRounds) then { + _magazineSupply set [_magazineIdx, [_magazineClass, (_rounds - _configRounds)]]; + _truck setVariable [QGVAR(magazineSupply), _magazineSupply, true]; + _return = true; + }; + }; +}; +_return diff --git a/addons/rearm/functions/fnc_setSupplyCount.sqf b/addons/rearm/functions/fnc_setSupplyCount.sqf new file mode 100644 index 0000000000..41b3016dba --- /dev/null +++ b/addons/rearm/functions/fnc_setSupplyCount.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: GitHawk + * Sets the supply count. [Global Effects] + * + * Arguments: + * 0: Ammo Truck + * 1: Supply Count + * + * Return Value: + * None + * + * Example: + * [ammo_truck, 1000] call ace_rearm_fnc_setSupplyCount + * + * Public: Yes + */ + +if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the settings are initialized + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSupplyCount), _this]; +}; + +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);}; + +_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..984d382e08 --- /dev/null +++ b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf @@ -0,0 +1,89 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 b94616652e..7d4427e1a2 100644 --- a/addons/rearm/functions/fnc_storeAmmo.sqf +++ b/addons/rearm/functions/fnc_storeAmmo.sqf @@ -1,32 +1,37 @@ +#include "script_component.hpp" /* * Author: GitHawk * Stores ammo in an ammo truck. * * Arguments: - * 0: Target + * 0: Ammo Truck * 1: Unit * * Return Value: * None * * Example: - * [player, dummy] call ace_rearm_fnc_storeAmmo + * [ammo_truck, player] call ace_rearm_fnc_storeAmmo * * Public: No */ -#include "script_component.hpp" -params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]]; +params ["_truck", "_unit"]; -private _dummy = _unit getVariable [QGVAR(dummy), objNull]; -if (isNull _dummy) exitwith {}; +private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; +if (isNull _attachedDummy) exitwith {}; [ - 5, - _unit, - {params ["_unit"]; [_unit, true, true] call FUNC(dropAmmo)}, + TIME_PROGRESSBAR(5), + [_unit, _truck, _attachedDummy], + { + params ["_args"]; + _args params ["_unit", "_truck", "_attachedDummy"]; + [_truck, (_attachedDummy getVariable [QGVAR(magazineClass), ""]), true] call FUNC(addMagazineToSupply); + [_unit, true, true] call FUNC(dropAmmo); + }, "", - format [localize LSTRING(StoreAmmoAction), getText(configFile >> "CfgMagazines" >> (_dummy getVariable QGVAR(magazineClass)) >> "displayName"), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], + format [localize LSTRING(StoreAmmoAction), getText(configFile >> "CfgMagazines" >> (_attachedDummy getVariable QGVAR(magazineClass)) >> "displayName"), getText(configFile >> "CfgVehicles" >> (typeOf _truck) >> "displayName")], {true}, ["isnotinside"] ] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_takeAmmo.sqf b/addons/rearm/functions/fnc_takeAmmo.sqf index d2de1e1b59..1576044eb1 100644 --- a/addons/rearm/functions/fnc_takeAmmo.sqf +++ b/addons/rearm/functions/fnc_takeAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Starts progress bar for picking up a specific kind of magazine from an ammo truck. @@ -17,42 +18,18 @@ * * Public: No */ -#include "script_component.hpp" -private ["_ammo", "_tmpCal", "_cal", "_idx"]; - -params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]], ["_args", ["", objNull], [[]]]]; +params ["_truck", "_unit", "_args"]; _args params ["_magazineClass", "_vehicle"]; +TRACE_5("takeAmmo",_truck,_unit,_args,_magazineClass,_vehicle); -_ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); -_tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_caliber"); -_cal = 8; -if (_tmpCal > 0) then { - _cal = _tmpCal; -} else { - _tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(caliber)); - if (_tmpCal > 0) then { - _cal = _tmpCal; - } else { - diag_log format ["[ACE] ERROR: Undefined Ammo [%1 : %2]", _ammo, inheritsFrom (configFile >> "CfgAmmo" >> _ammo)]; - if (_ammo isKindOf "BulletBase") then { - _cal = 8; - } else { - _cal = 100; - }; - }; -}; -_cal = round _cal; -_idx = REARM_CALIBERS find _cal; -if (_idx == -1 ) then { - _idx = 2; -}; +([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; -REARM_HOLSTER_WEAPON +REARM_HOLSTER_WEAPON; [ - (REARM_DURATION_TAKE select _idx), - [_unit, _magazineClass, _target], + TIME_PROGRESSBAR(REARM_DURATION_TAKE select _idx), + [_unit, _magazineClass, _truck], FUNC(takeSuccess), "", format [localize LSTRING(TakeAction), getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], diff --git a/addons/rearm/functions/fnc_takeSuccess.sqf b/addons/rearm/functions/fnc_takeSuccess.sqf index 6d5966c9f9..3986b21484 100644 --- a/addons/rearm/functions/fnc_takeSuccess.sqf +++ b/addons/rearm/functions/fnc_takeSuccess.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Takes a magazine from an ammo truck. @@ -16,17 +17,23 @@ * * Public: No */ -#include "script_component.hpp" -private ["_ammo", "_dummyName", "_dummy", "_actionID"]; -params [["_args", [objNull, "", objNull], [[]]]]; -_args params ["_unit", "_magazineClass", "_target"]; // _target is for future possible finite ammo +params ["_args"]; +_args params ["_unit", "_magazineClass", "_truck"]; +TRACE_3("takeSuccess",_unit,_magazineClass,_truck); -[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set); -_dummy = [_unit, _magazineClass] call FUNC(createDummy); +private _success = true; +if (GVAR(supply) > 0) then { + _success = [_truck, _magazineClass] call FUNC(removeMagazineFromSupply); +}; +if !(_success) exitWith {WARNING_2("takeSuccess failed to take [%1] from [%2]",_magazineClass,_truck);}; + +[_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); -_actionID = _unit addAction [ +private _actionID = _unit addAction [ format ["%1", localize ELSTRING(dragging,Drop)], '(_this select 0) call FUNC(dropAmmo)', nil, diff --git a/addons/rearm/initSettings.sqf b/addons/rearm/initSettings.sqf new file mode 100644 index 0000000000..0e5e421747 --- /dev/null +++ b/addons/rearm/initSettings.sqf @@ -0,0 +1,19 @@ +// CBA Settings [ADDON: ace_rearm]: + +[ + QGVAR(level), "LIST", + [LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize LSTRING(DisplayName)], + [[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(level), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(supply), "LIST", + [LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize LSTRING(DisplayName)], + [[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; diff --git a/addons/rearm/script_component.hpp b/addons/rearm/script_component.hpp index 43b9a8bb5f..83d495bc38 100644 --- a/addons/rearm/script_component.hpp +++ b/addons/rearm/script_component.hpp @@ -4,8 +4,8 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS +// #define FAST_PROGRESSBARS #ifdef DEBUG_ENABLED_REARM #define DEBUG_MODE_FULL @@ -18,8 +18,8 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define REARM_ACTION_DISTANCE 7 -#define REARM_TURRET_PATHS [[-1], [0], [0,0], [0,1], [1], [2], [0,2]] +#define REARM_ACTION_DISTANCE 9 +#define REARM_ACTION_DISTANCE_SQR 81 #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] @@ -29,12 +29,19 @@ #define REARM_HOLSTER_WEAPON \ _unit setVariable [QGVAR(selectedWeaponOnRearm), currentWeapon _unit]; \ - _unit action ["SwitchWeapon", _unit, _unit, 99]; + TRACE_2("REARM_HOLSTER_WEAPON",_unit,currentWeapon _unit); \ + _unit action ["SwitchWeapon", _unit, _unit, 299]; #define REARM_UNHOLSTER_WEAPON \ _weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRearm); \ - TRACE_2("REARM_UNHOLSTER_WEAPON",_unit,_weaponSelect); \ if (!isNil "_weaponSelect") then { \ + TRACE_2("REARM_UNHOLSTER_WEAPON",_unit,_weaponSelect); \ _unit selectWeapon _weaponSelect; \ _unit setVariable [QGVAR(selectedWeaponOnRearm), nil]; \ }; + +#ifdef FAST_PROGRESSBARS + #define TIME_PROGRESSBAR(X) ((X) * 0.075) +#else + #define TIME_PROGRESSBAR(X) (X) +#endif diff --git a/addons/rearm/stringtable.xml b/addons/rearm/stringtable.xml index 7806735c57..3726b7606a 100644 --- a/addons/rearm/stringtable.xml +++ b/addons/rearm/stringtable.xml @@ -1,6 +1,14 @@ - + + + Rearm + Aufmunitionierung + Riarmo + 整裝 + 整装 + 再武装 + Rearm Settings Aufmunitioniereinstellungen @@ -11,6 +19,10 @@ Impostazioni Riarmo Parámetros de rearme Options de réarmement + 재보급 설정 + 整装设定 + 整裝設定 + 再武装設定 This module allows you to tweak rearm system settings. @@ -22,6 +34,10 @@ Questo modulo ti consente di cambiare le impostazioni del sistema Riarmo. Este módulo permite cambiar los parámetros de rearme. Ce module autorise l'amélioration du système de réarmement. + 再武装システムの設定を微調整します。 + 이 모듈은 재보급시의 설정을 바꿀수 있게해줍니다. + 此模块允许你调整整装系统设定 + 此模塊允許你調整整裝系統設定 Rearm Amount @@ -33,6 +49,10 @@ Ammontare Riarmo Velocidad de rearme Quantité à réarmer + 再武装できる量 + 재보급 양 + 整装所需时间 + 整裝所需時間 How fast should a vehicle be rearmed? @@ -44,6 +64,10 @@ Quanto velocemente dovrebbe essere riarmato un veicolo? Cuán rápido es el proceso de rearme? A quelle vitesse devrait être réarmé un véhicule ? + 車両を再武装する早さを設定します。 + 차량을 얼마나 빨리 재보급 시킵니까? + 载具多快会整装完毕? + 載具多快會整裝完畢? Entire Vehicle @@ -55,6 +79,10 @@ Tutto il Veicolo Vehículo completo Véhicule entier + 車両全体 + 모든 차량 + 整个载具 + 整個載具 Entire Magazine @@ -66,6 +94,10 @@ Tutto il Caricatore Cargador completo Chargeur entier + マガジン全体 + 모든 탄창 + 整个弹匣 + 整個彈匣 Amount based on caliber @@ -77,6 +109,110 @@ Ammontare basato sul calibro Cantidad basada en el calibre Quantité basée sur le calibre + 口径に基づいた量 + 구경에 따라 수량 설정 + 基于口径决定所耗时间 + 基於口徑決定所耗時間 + + + Ammunition supply + Munitionsvorrat + Scorta munizioni + 弾薬の供給 + 弹药补给 + 彈藥補給 + Zapas amunicji + 탄약 보급 + + + How much ammunition does an ammo truck carry? + Wie viel Munition transportiert ein Munitionslaster? + Quante munizioni può trasportare un camion? + 弾薬トラックの運搬量を設定します。 + 弹药卡车会携带多少的弹药? + 彈藥卡車會攜帶多少的彈藥? + Ile amunicji przewozi ciężarówka? + 탄약 차량은 얼마나 많은 양의 탄약을 가질 수 있음? + + + Unlimited ammo supply + Unbegrenzter Munitionsvorrat + Scorta munizioni infinita + 無制限供給 + 无限弹药 + 無限彈藥 + Nielimitowany zapas amunicji + 무한의 탄약 + + + Limited ammo supply based on caliber + Begrenzter, kaliberabhängiger Munitionsvorrat + Scorta munizioni limitata in base al calibro + 口径に基づいた限定的供給 + 基于口径限制弹药数量 + 基於口徑限制彈藥數量 + Zapas amunicji zależny od kalibru + 구경에 따라 제한된 탄약 + + + Only specific Magazines + Nur bestimmte Magazine + Solo specifici caricatori + 特定の弾薬のみ + 只有指定的弹药 + 只有指定的彈藥 + Tylko konkretne magazynki + 특정 탄약만 + + + Check remaining ammunition + Verbleibende Munition prüfen + Controlla munizioni rimanenti + 残弾薬を確認する + 检查剩余的弹药 + 檢查剩餘的彈藥 + Sprawdź ilość amunicji + 남은 탄약 확인 + + + Checking remaining ammunition... + Überprüfe verbleibende Munition... + Controllando le munizioni rimanenti + 残弾薬を確認中… + 正在检查剩余的弹药中... + 正在檢查剩餘的彈藥中... + Sprawdzanie ilości amunicji... + 남은 탄약 확인중... + + + There is ammunition worth %1 points left. + Es ist noch Munition für %1 Punkte übrig. + E' presente una penalità delle munizioni %1 punti rimanenti. + 弾薬は%1残っている + 还剩下%1多的弹药. + 還剩下%1多的彈藥. + Pozostało %1 punktów amunicji. + 여기에는 최소 %1 포인트의 탄약이 남았습니다. + + + The following ammunition is left:%1 + Folgende Munition ist übrig:%1 + Mancano le seguenti:%1 + この弾薬の残りは:%1 + 以下剩余的弹药:%1 + 以下剩餘的彈藥:%1 + Pozostała amunicja: %1 + 다음의 탄약이 남음 : %1 + + + There is no ammunition left. + Es ist keine Munition übrig. + Non ci sono munizioni rimanenti. + 弾薬は残っていない + 已经没有剩余的弹药了. + 已經沒有剩餘的彈藥了. + Brak amunicji w zapasie. + 여기에는 탄약이 남지 않았습니다. Rearm @@ -88,6 +224,10 @@ Riarma Rearmar Réarmer + 再武装 + 재보급 + 整装 + 整裝 Rearming %1 with %2... @@ -96,9 +236,13 @@ Перевооружается %1 снарядами %2... Rearmando %1 com %2... Přezbrojuji %1 za pomoci %2... - Sto Riarmando %1 con %2... + Riarmando %1 con %2... Rearmando %1 con %2... Réarmement de %1 avec %2... + %1に%2を再武装中… + %2을 %1에 재보급중... + %2正整装到%1中... + %2正整裝到%1中... Rearming %1... @@ -110,6 +254,10 @@ Riarmando %1... Rearmando %1... Réarmement de %1... + %1を再武装中… + %1 재보급중... + 整装%1中... + 整裝%1中... Taking %1 for %2... @@ -121,6 +269,10 @@ Sto prendendo %1 per %2... Tomando %1 para %2... Prend %1 pour %2... + %1から%2を取得中… + %2를 위해 %1 가져오는중... + 拿取%1给%2中... + 拿取%1給%2中... Take ammo @@ -132,6 +284,10 @@ Prendi munizioni Tomar munición Prendre la munition + 弾薬を取る + 탄약 가지기 + 取得弹药 + 取得彈藥 Pick up ammo @@ -143,6 +299,10 @@ Raccogli munizioni Levantar munición Ramasser la munition + 弾薬を拾得する + 탄약 줍기 + 捡起弹药 + 撿起彈藥 Store ammo @@ -154,6 +314,10 @@ Riponi munizioni Guardar munición Stocker la munition + 弾薬を格納する + 탄약 보관하기 + 储存弹药 + 儲存彈藥 Storing %1 in %2... @@ -165,6 +329,10 @@ Sto riponendo %1 in %2... Guardando %1 en %2... Stocke %1 dans %2... + %1を%2へ格納中… + %2에 %1 보관중... + 储存%1到%2中... + 儲存%1到%2中... Picking up ammo... @@ -175,6 +343,10 @@ Sto raccogliendo le munizioni... Levantando munición... Ramassage des munitions... + 弾薬を拾得中… + 탄약 줍는중... + 捡起弹药中... + 撿起彈藥中... Rearmed %1 rounds of %2 on %3 @@ -186,6 +358,10 @@ Riarmati %1 colpi di %2 su %3 Rearmadas %1 rondas de %2 en %3 %1 balles réarmées de %2 dans %3 + %1発の%2を%3から装填しました + %3에 2%의 %1 탄약 재보급 + 整装了%1发%2到%3上 + 整裝了%1發%2到%3上 Smoke Screen @@ -197,6 +373,10 @@ Cortina de fumaça Дым. завеса Pantalla de humo + 煙幕弾 + 연막 차장 + 烟幕弹 + 煙幕彈 Flares @@ -208,6 +388,10 @@ Sinalizadores ЛТЦ Bengalas + フレア + 기만체 + 热焰弹 + 熱焰彈 30mm HEI @@ -219,6 +403,10 @@ 30mm HEI 30mm HEI 30mm HEI + 30mm 焼夷りゅう弾 + 30mm 고폭소이탄 + 30mm 高爆燃烧弹 + 30mm 高爆燃燒彈 30mm HEI-T @@ -230,6 +418,10 @@ 30mm HEI-T 30mm HEI-T 30mm HEI-T + 30mm 焼夷曳光りゅう弾 + 30mm 고폭소이예광탄 + 30mm 高爆燃烧曳光弹 + 30mm 高爆燃燒曳光彈 AIM-9 Sidewinder @@ -241,6 +433,10 @@ AIM-9 Sidewinder AIM-9 Sidewinder AIM-9 Sidewinder + AIM-9 サイドワインダー + AIM-9 Sidewinder + AIM-9 响尾蛇 + AIM-9 響尾蛇 Wympel R-73 @@ -252,6 +448,10 @@ Wympel R-73 Wympel R-73 Wympel R-73 + ヴィンペル R-73 + Vympel R-73 + Wympel R-73 + Wympel R-73 AGM-65 Maverick @@ -263,6 +463,10 @@ AGM-65 Maverick AGM-65 Maverick AGM-65 Maverick + AGM-65 マーベリック + AGM-65 Maverick + AGM-65 小牛 + AGM-65 小牛 Kh-25MTP @@ -274,6 +478,10 @@ Kh-25MTP Kh-25MTP Kh-25MTP + Kh-25MTP + Kh-25MTP + Kh-25MTP + Kh-25MTP Hydra 70 HE @@ -285,6 +493,10 @@ Hydra 70 HE Hydra 70 HE Hydra 70 HE + ハイドラ 70 りゅう弾 + Hydra 70 고폭탄 + 九头蛇 70 高爆弹 + 九頭蛇 70 高爆彈 S-8 HE @@ -296,6 +508,10 @@ S-8 HE S-8 HE S-8 HE + S-8 りゅう弾 + S-8 고폭탄 + S-8 高爆弹 + S-8 高爆彈 Hydra 70 AP @@ -306,7 +522,11 @@ Hydra 70 AP Hydra 70 AP Hydra 70 AP - Hydra 70 AP + Hydra 70 徹甲弾 + ハイドラ 70 AP + Hydra 70 철갑탄 + 九头蛇 70 反人员弹 + 九頭蛇 70 反人員彈 S-8 AP @@ -318,6 +538,10 @@ S-8 AP S-8 AP S-8 AP + S-8 徹甲弾 + S-8 철갑탄 + S-8 反人员弹 + S-8 反人員彈 GBU-12 @@ -329,6 +553,10 @@ GBU-12 GBU-12 GBU-12 + GBU-12 + GBU-12 + GBU-12 + GBU-12 FAB-250M-54 @@ -340,6 +568,10 @@ FAB-250M-54 FAB-250M-54 FAB-250M-54 + FAB-250M-54 + FAB-250M-54 + FAB-250M-54 + FAB-250M-54 - \ No newline at end of file + diff --git a/addons/recoil/XEH_preInit.sqf b/addons/recoil/XEH_preInit.sqf index c503c2edbc..ffd1bfc414 100644 --- a/addons/recoil/XEH_preInit.sqf +++ b/addons/recoil/XEH_preInit.sqf @@ -3,6 +3,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/recoil/functions/fnc_camshake.sqf b/addons/recoil/functions/fnc_camshake.sqf index deb454df71..fff9fecd6c 100644 --- a/addons/recoil/functions/fnc_camshake.sqf +++ b/addons/recoil/functions/fnc_camshake.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Orginal by Ryan Schultz, edited by KoffeinFlummi, commy2 * Adds camera shake when firing. Called from the unified fired EH only for the local player. @@ -7,14 +8,13 @@ * None. Parameters inherited from EFUNC(common,firedEH) * * Return Value: - * Nothing + * None * * Example: * [player, (currentWeapon player), (currentMuzzle player)] call ace_recoil_fnc_camShake; * * 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); diff --git a/addons/recoil/script_component.hpp b/addons/recoil/script_component.hpp index d3147f056b..99fdf02a94 100644 --- a/addons/recoil/script_component.hpp +++ b/addons/recoil/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_RECOIL diff --git a/addons/refuel/ACE_Settings.hpp b/addons/refuel/ACE_Settings.hpp index b38a880641..e545a7fed5 100644 --- a/addons/refuel/ACE_Settings.hpp +++ b/addons/refuel/ACE_Settings.hpp @@ -1,9 +1,8 @@ class ACE_Settings { class GVAR(rate) { - category = ECSTRING(OptionsMenu,CategoryLogistics); - displayName = CSTRING(RefuelSettings_speed_DisplayName); - description = CSTRING(RefuelSettings_speed_Description); - value = 1; - typeName = "SCALAR"; + movedToSQF = 1; + }; + class GVAR(hoseLength) { + movedToSQF = 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 c6f26efe1a..c8d6e21596 100644 --- a/addons/refuel/CfgEventHandlers.hpp +++ b/addons/refuel/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); @@ -20,15 +19,15 @@ class Extended_PostInit_EventHandlers { class Extended_Respawn_EventHandlers { class CAManBase { class ADDON { - respawn = QUOTE(call COMPILE_FILE(XEH_respawn)); + respawn = QUOTE(call DFUNC(handleRespawn)); }; }; }; -class Extended_Killed_EventHandlers { - class CAManBase { +class Extended_InitPost_EventHandlers { + class Land_CanisterFuel_F { class ADDON { - killed = QUOTE(_this call FUNC(handleKilled)); + init = QUOTE(call DFUNC(makeJerryCan)); }; }; -}; \ No newline at end of file +}; diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index 1fd63bb461..efcd1aa3a2 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -1,68 +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 = "true"; \ - 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(Connect) { \ - displayName = CSTRING(Connect); \ - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canConnectNozzle)); \ - statement = QUOTE([ARR_2(_player,_target)] call DFUNC(connectNozzle)); \ - 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 { \ @@ -71,35 +6,35 @@ 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); \ }; \ }; \ @@ -110,13 +45,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 { @@ -126,6 +61,11 @@ class CfgVehicles { typeName = "NUMBER"; defaultValue = 10; }; + class hoseLength { + displayName = CSTRING(RefuelSettings_hoseLength_DisplayName); + typeName = "NUMBER"; + defaultValue = 12; + }; }; }; @@ -148,20 +88,17 @@ class CfgVehicles { class NonStrategic: Building {}; class HouseBase: NonStrategic {}; class House: HouseBase {}; - class House_F: House {}; - - class House_Small_F: House_F { - class EventHandlers; - + class House_F: House { class ACE_Actions { class ACE_MainActions { displayName = ECSTRING(interaction,MainAction); selection = ""; - distance = 10; + distance = 5; condition = "true"; }; }; }; + class House_Small_F: House_F {}; class AllVehicles: All { GVAR(flowRate) = 1; @@ -169,36 +106,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(fuelCapacity) = 1500; + GVAR(canReceive) = 1; }; class Helicopter_Base_F: Helicopter {}; - - class Helicopter_Base_H: Helicopter_Base_F { - GVAR(fuelCapacity) = 3000; - }; + class Helicopter_Base_H: Helicopter_Base_F {}; class Plane: Air { - MACRO_CONNECT_ACTIONS - GVAR(fuelCapacity) = 2000; + GVAR(canReceive) = 1; GVAR(flowRate) = 16; }; @@ -207,8 +135,7 @@ class CfgVehicles { class Ship: AllVehicles {}; class Ship_F: Ship { - MACRO_CONNECT_ACTIONS - GVAR(fuelCapacity) = 2000; + GVAR(canReceive) = 1; GVAR(flowRate) = 4; }; @@ -226,11 +153,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; @@ -312,7 +242,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; }; @@ -322,7 +251,7 @@ class CfgVehicles { class I_G_Van_01_fuel_F: Van_01_fuel_base_F { transportFuel = 0; //1k }; - + class Tank_F: Tank { GVAR(fuelCapacity) = 1200; }; @@ -337,7 +266,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; }; @@ -380,19 +308,6 @@ class CfgVehicles { GVAR(fuelCapacity) = 830; }; - class Heli_Attack_01_base_F: Helicopter_Base_F { - // Commanche - }; - - class Heli_Attack_02_base_F: Helicopter_Base_F { - // Mi-48 Kajman - }; - - class Heli_Light_01_base_F: Helicopter_Base_H { - // MH-6 - GVAR(fuelCapacity) = 242; - }; - class Heli_Light_02_base_F: Helicopter_Base_H { // Ka-60 Kasatka GVAR(fuelCapacity) = 1450; @@ -436,7 +351,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 {}; @@ -446,11 +365,6 @@ class CfgVehicles { GVAR(fuelCapacity) = 270; }; - class UGV_01_base_F: Car_F { - // Stomper - GVAR(fuelCapacity) = 100; - }; - class Plane_Fighter_03_base_F: Plane_Base_F { // L-159 ALCA GVAR(fuelCapacity) = 1914; @@ -459,21 +373,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; }; @@ -488,7 +402,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; }; @@ -496,19 +409,17 @@ 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; }; - + // Vanilla fuel objects class StorageBladder_base_F: NonStrategic { class ACE_Actions { class ACE_MainActions { @@ -524,35 +435,67 @@ class CfgVehicles { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; - MACRO_REFUEL_ACTIONS transportFuel = 0; //60k GVAR(hooks)[] = {{-3.35,2.45,0.17}}; GVAR(fuelCargo) = 60000; }; + class FlexibleTank_base_F: ThingX { + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + position = "[0, 0, 0.5]"; + distance = 4; + condition = "true"; + }; + }; + }; + class Land_FlexibleTank_01_F: FlexibleTank_base_F { + transportFuel = 0; //300 + GVAR(hooks)[] = {{0, 0, 0.5}}; + GVAR(fuelCargo) = 300; + }; + // Vanilla buildings class Land_Fuelstation_Feed_F: House_Small_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - 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 { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - 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 + 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 + GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; + GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; + }; + + // Helper object for non-AllVehicles objects + class GVAR(helper): Helicopter_Base_F { + scope = 1; + displayName = "Refuel Helper"; + model = "\A3\Weapons_f\empty"; + class ACE_Actions {}; + class ACE_SelfActions {}; + EGVAR(cargo,hasCargo) = 0; + EGVAR(cargo,space) = 0; + damageEffect = ""; + destrType = ""; + class HitPoints {}; + class Turrets {}; + class TransportItems {}; + }; + /* // Barrels found in config \ BarrelHelper: Misc_thing 100 BarrelBase: BarrelHelper 100 diff --git a/addons/refuel/XEH_PREP.hpp b/addons/refuel/XEH_PREP.hpp index dac451da17..e4c5298036 100644 --- a/addons/refuel/XEH_PREP.hpp +++ b/addons/refuel/XEH_PREP.hpp @@ -1,28 +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(handleUnconscious); +PREP(handleRespawn); +PREP(initSource); PREP(makeJerryCan); +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 89a1f3dc45..43933f2cf5 100644 --- a/addons/refuel/XEH_postInit.sqf +++ b/addons/refuel/XEH_postInit.sqf @@ -1,24 +1,105 @@ #include "script_component.hpp" -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; - if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {_this call FUNC(handleDisconnect)}]; + addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; }; -[QGVAR(resetLocal), { - _this call FUNC(resetLocal); -}] call CBA_fnc_addEventHandler; +[QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; +if (!hasInterface) exitWith {}; -#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]; +["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), + {}, + { + 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) +]; + +// 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; + // 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; +} forEach ('true' configClasses (configFile >> "CfgVehicles")); + + +#ifdef DRAW_HOOKS_POS +addMissionEventHandler ["Draw3D", { + 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], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; + } forEach ([_dynPos, _cfgPos] select (_dynPos isEqualTo [])); +}]; #endif diff --git a/addons/refuel/XEH_preInit.sqf b/addons/refuel/XEH_preInit.sqf index a7feade1c3..9361d05015 100644 --- a/addons/refuel/XEH_preInit.sqf +++ b/addons/refuel/XEH_preInit.sqf @@ -2,6 +2,10 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" ADDON = true; 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 e0046dea3d..f7bb8a4aa8 100644 --- a/addons/refuel/functions/fnc_canCheckFuel.sqf +++ b/addons/refuel/functions/fnc_canCheckFuel.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: Jonpas, GitHawk * Checks if unit can check fuel. * * Arguments: * 0: Unit - * 1: Fuel Truck/Station + * 1: Fuel Source * * Return Value: * Can Check Fuel @@ -14,13 +15,12 @@ * * Public: No */ -#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} || - {(_target distance _unit) > 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 396931d9ba..0000000000 --- a/addons/refuel/functions/fnc_canConnectNozzle.sqf +++ /dev/null @@ -1,31 +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 || - {_engine} || - {(_target distance _unit) > REFUEL_ACTION_DISTANCE} || - {!isNull (_target getVariable [QGVAR(nozzle), objNull])}) // TODO verify cant connect multiple fuel lines diff --git a/addons/refuel/functions/fnc_canDisconnect.sqf b/addons/refuel/functions/fnc_canDisconnect.sqf index 8bb24a8df2..1288d9f103 100644 --- a/addons/refuel/functions/fnc_canDisconnect.sqf +++ b/addons/refuel/functions/fnc_canDisconnect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Check if a unit can disconnect a fuel nozzle @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; @@ -22,6 +22,7 @@ if (isNull _unit || {isNull _nozzle} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || + {!isNull (_unit getVariable [QGVAR(nozzle), objNull])} || {(_nozzle distance _unit) > REFUEL_ACTION_DISTANCE}) exitWith {false}; private _sink = _nozzle getVariable [QGVAR(sink), objNull]; diff --git a/addons/refuel/functions/fnc_canReturnNozzle.sqf b/addons/refuel/functions/fnc_canReturnNozzle.sqf index 4f3abe1d30..aef2e96fa0 100644 --- a/addons/refuel/functions/fnc_canReturnNozzle.sqf +++ b/addons/refuel/functions/fnc_canReturnNozzle.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: GitHawk * Check if a unit can return a fuel nozzle * * Arguments: * 0: Unit - * 1: Fuel truck + * 1: Fuel Source * * Return Value: * Can Return Nozzle @@ -14,10 +15,11 @@ * * Public: No */ -#include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; -private _nozzle = _unit getVariable QGVAR(nozzle); +private _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; -(_this call FUNC(canConnectNozzle)) && {_target == (_nozzle getVariable [QGVAR(source), objNull])} +(!isNull _nozzle) && +{([_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 0ed998993b..82ca8452bc 100644 --- a/addons/refuel/functions/fnc_canTakeNozzle.sqf +++ b/addons/refuel/functions/fnc_canTakeNozzle.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: GitHawk * Check if a unit can take a fuel nozzle * * Arguments: * 0: Unit - * 1: Fuel Station or Nozzle + * 1: Fuel Source or Nozzle * * Return Value: * Can connect @@ -14,14 +15,15 @@ * * Public: No */ -#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} || - {(_target distance _unit) > REFUEL_ACTION_DISTANCE}) exitWith {false}; + {!alive _object} || + {!isNull (_unit getVariable [QGVAR(nozzle), objNull])} || + {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_canTurnOff.sqf b/addons/refuel/functions/fnc_canTurnOff.sqf index e44e1fc669..624cfde552 100644 --- a/addons/refuel/functions/fnc_canTurnOff.sqf +++ b/addons/refuel/functions/fnc_canTurnOff.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Check if a unit can turn off a fuel nozzle @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; diff --git a/addons/refuel/functions/fnc_canTurnOn.sqf b/addons/refuel/functions/fnc_canTurnOn.sqf index e9de5c205c..855837d97c 100644 --- a/addons/refuel/functions/fnc_canTurnOn.sqf +++ b/addons/refuel/functions/fnc_canTurnOn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Check if a unit can turn on a fuel nozzle @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; @@ -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 49d62b1e44..275ad7999b 100644 --- a/addons/refuel/functions/fnc_checkFuel.sqf +++ b/addons/refuel/functions/fnc_checkFuel.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: GitHawk * Get the remaining fuel amount * * Arguments: * 0: Unit - * 1: Fuel Truck + * 1: Fuel Source * * Return Value: * None @@ -14,18 +15,17 @@ * * Public: No */ -#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); [ - 5, - [_unit, _target, _fuel], + TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION * 2), + [_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 a124a331d5..0000000000 --- a/addons/refuel/functions/fnc_connectNozzle.sqf +++ /dev/null @@ -1,63 +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 _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, _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, _virtualPos, _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 250da51e21..7c626c2359 100644 --- a/addons/refuel/functions/fnc_connectNozzleAction.sqf +++ b/addons/refuel/functions/fnc_connectNozzleAction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk et.al. * Calculates a connection for refueling. @@ -5,8 +6,8 @@ * * Arguments: * 0: Unit - * 1: Target - * 2: Visual Position + * 1: Vehicle + * 2: Visual Position ASL * 3: Nozzle * * Return Value: @@ -17,80 +18,65 @@ * * Public: No */ -#include "script_component.hpp" -private ["_closeInDistance", "_endPosTestOffset"]; -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]], ["_startingPosition", [0,0,0], [[]], 3], ["_nozzle", objNull, [objNull]]]; -private _startingOffset = _target worldToModel _startingPosition; +params [["_unit", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_startingPosASL", [0,0,0], [[]], 3], ["_nozzle", objNull, [objNull]]]; -private _startDistanceFromCenter = vectorMagnitude _startingOffset; -private _closeInUnitVector = vectorNormalized (_startingOffset vectorFromTo [0,0,0]); -private _closeInMax = _startDistanceFromCenter; -private _closeInMin = 0; +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 (_sink modelToWorld [0,0,0])); +private _modelVectorLow = _startingPosASL vectorFromTo (AGLtoASL (_sink modelToWorld [0,0,-1])); -while {(_closeInMax - _closeInMin) > 0.01} do { - _closeInDistance = (_closeInMax + _closeInMin) / 2; - _endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); - _endPosTestOffset set [2, (_startingOffset select 2)]; - private _endPosTest = _target modelToWorldVisual _endPosTestOffset; - - private _doesIntersect = false; +{ + private _endPosASL = _x; + // [_startingPosASL, _endPosASL, [1,0,0,1]] call EFUNC(common,addLineToDebugDraw); // Debug scan lines + private _intersections = lineIntersectsSurfaces [_startingPosASL, _endPosASL, _unit]; { - if (_doesIntersect) exitWith {}; - private _startingPosShifted = _startingPosition vectorAdd _x; - _startASL = if (surfaceIsWater _startingPosShifted) then {_startingPosShifted} else {ATLtoASL _startingPosShifted}; - { - _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 (_target in lineIntersectsWith [_startASL, _endASL, _unit]) 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]]; - - if (_doesIntersect) then { - _closeInMax = _closeInDistance; - } else { - _closeInMin = _closeInDistance; - }; -}; - -_closeInDistance = (_closeInMax + _closeInMin) / 2; + _x params ["_intersectPosASL", "", "_intersectObject"]; + if (_intersectObject == _sink) then { + private _distance = _startingPosASL distance _intersectPosASL; + if (_distance < _bestPosDistance) then { + _bestPosDistance = _distance; + _bestPosASL = _intersectPosASL; + }; + }; + } forEach _intersections; +} forEach [ + // Shoot rays towards player's view angle and see which spot is closest + _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0,0,1])) vectorMultiply 3), + _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [-0.25,0,1])) vectorMultiply 3), + _startingPosASL vectorAdd (((positionCameraToWorld [0,0,0]) vectorFromTo (positionCameraToWorld [0.25,0,1])) vectorMultiply 3), + _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 (_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 ((_startDistanceFromCenter - _closeInDistance) < 0.1) exitWith { - TRACE_2("no valid spot found",_closeInDistance,_startDistanceFromCenter); +if (_bestPosASL isEqualTo []) exitWith { [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) -_closeInDistance = (_closeInDistance - 0.05); +_bestPosASL = _bestPosASL vectorAdd ((_bestPosASL vectorFromTo _startingPosASL) vectorMultiply 0.05); -_endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); -_endPosTestOffset set [2, (_startingOffset select 2)]; +private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); [ - 2, - [_unit, _nozzle, _target, _endPosTestOffset], + TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), + [_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]; @@ -120,9 +106,10 @@ _endPosTestOffset set [2, (_startingOffset select 2)]; }; }; [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); @@ -132,10 +119,17 @@ _endPosTestOffset set [2, (_startingOffset select 2)]; _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 { + [localize 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..b227b9fcc9 100644 --- a/addons/refuel/functions/fnc_disconnect.sqf +++ b/addons/refuel/functions/fnc_disconnect.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Disconnect a fuel nozzle. @@ -14,16 +15,16 @@ * * Public: No */ -#include "script_component.hpp" 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 575d318068..e49872a279 100644 --- a/addons/refuel/functions/fnc_dropNozzle.sqf +++ b/addons/refuel/functions/fnc_dropNozzle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Detaches the fuel nozzle, drops it and removes player variables. @@ -16,17 +17,29 @@ * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_disconnectOnly", false, [false]]]; +TRACE_3("dropNozzle",_unit,_nozzle,_disconnectOnly); detach _nozzle; _nozzle setVariable [QGVAR(isRefueling), false, true]; if (_disconnectOnly) exitWith {}; _nozzle setVelocity [0, 0, 0]; -_nozzle setPosATL [(getPosATL _nozzle) select 0, (getPosATL _nozzle) select 1, 0.05]; + +private _groundPosition = getPosASL _nozzle; +private _posA = (getPosASL _nozzle) vectorAdd [0,0,0.05]; +private _posB = (getPosASL _nozzle) vectorAdd [0,0,-1000]; +private _intersections = lineIntersectsSurfaces [_posA, _posB, _unit, _nozzle, true, 1, "GEOM"]; +TRACE_1("",_intersections); +if (_intersections isEqualTo []) then { + _groundPosition set [2, (getTerrainHeightASL _groundPosition) + 0.005]; +} else { + _groundPosition = ((_intersections select 0) select 0) vectorAdd [0,0,0.005]; +}; +_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..ecba330363 100644 --- a/addons/refuel/functions/fnc_getFuel.sqf +++ b/addons/refuel/functions/fnc_getFuel.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: GitHawk, Jonpas * Get the remaining fuel amount. * * Arguments: - * 0: Target + * 0: Fuel Source * * Return Value: * Fuel left (in liters) @@ -13,17 +14,16 @@ * * Public: Yes */ -#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..ebf0d729ea 100644 --- a/addons/refuel/functions/fnc_handleDisconnect.sqf +++ b/addons/refuel/functions/fnc_handleDisconnect.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * Author: GitHawk - * Cleans up refuel + * Cleans up refuel on client disconnect. * * Arguments: * 0: Player @@ -13,14 +14,14 @@ * * Public: No */ -#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_handleRespawn.sqf b/addons/refuel/functions/fnc_handleRespawn.sqf new file mode 100644 index 0000000000..893f893724 --- /dev/null +++ b/addons/refuel/functions/fnc_handleRespawn.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Clean variables on unit respawn. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_refuel_fnc_handleRespawn + * + * Public: No + */ + +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..c484c151f4 --- /dev/null +++ b/addons/refuel/functions/fnc_initSource.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Adds refuel menu to object. + * + * Arguments: + * 0: Source + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_refuel_fnc_initSource + * + * Public: No + */ + +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 c826948fa2..4c4cd22aa1 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Makes an object into a jerry can. @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params [["_target", objNull, [objNull]], ["_fuelAmount", 20, [0]]]; @@ -22,9 +22,11 @@ if (isNull _target || {_target isKindOf "AllVehicles"} || {_target getVariable [QGVAR(jerryCan), false]}) exitWith {}; -[_target, _fuelAmount] call FUNC(setFuel); -_target setVariable [QGVAR(jerryCan), true, true]; -_target setVariable [QGVAR(source), _target, true]; +if (isServer) then { + [_target, _fuelAmount] call FUNC(setFuel); // has global effects +}; +_target setVariable [QGVAR(jerryCan), true]; +_target setVariable [QGVAR(source), _target]; // Main Action private _action = [QGVAR(Refuel), @@ -36,19 +38,19 @@ private _action = [QGVAR(Refuel), [], [0, 0, 0], REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); -[_target, 0, [], _action] call EFUNC(interact_menu,addActionToObject); +[_target, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); // Add pickup _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)}, {}, [], [0, 0, 0], REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); -[_target, 0, [QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); +[_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add turnOn _action = [QGVAR(TurnOn), @@ -60,7 +62,7 @@ _action = [QGVAR(TurnOn), [], [0, 0, 0], REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); -[_target, 0, [QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); +[_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add turnOff _action = [QGVAR(TurnOff), @@ -72,7 +74,7 @@ _action = [QGVAR(TurnOff), [], [0, 0, 0], REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); -[_target, 0, [QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); +[_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add disconnect _action = [QGVAR(Disconnect), @@ -84,4 +86,4 @@ _action = [QGVAR(Disconnect), [], [0, 0, 0], REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); -[_target, 0, [QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); +[_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); diff --git a/addons/refuel/functions/fnc_makeSource.sqf b/addons/refuel/functions/fnc_makeSource.sqf new file mode 100644 index 0000000000..7b2179adab --- /dev/null +++ b/addons/refuel/functions/fnc_makeSource.sqf @@ -0,0 +1,60 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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_moduleRefuelSettings.sqf b/addons/refuel/functions/fnc_moduleRefuelSettings.sqf index 4d8f89425e..fabdad1706 100644 --- a/addons/refuel/functions/fnc_moduleRefuelSettings.sqf +++ b/addons/refuel/functions/fnc_moduleRefuelSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Module for adjusting the refuel settings. @@ -10,15 +11,17 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_refuel_fnc_moduleRefuelSettings + * * Public: No */ -#include "script_component.hpp" - params ["_logic", "", ["_activated", false, [false]]]; if !(_activated) exitWith {}; [_logic, QGVAR(rate), "rate"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(hoseLength), "hoseLength"] call EFUNC(common,readSettingFromModule); -diag_log text format ["[ACE]: Refuel Module Initialized with flow rate: %1", GVAR(rate)]; +INFO_2("Refuel Module Initialized with flow rate: %1 - hoseLength: %2",GVAR(rate), GVAR(hoseLength)) diff --git a/addons/refuel/functions/fnc_onMouseButtonDown.sqf b/addons/refuel/functions/fnc_onMouseButtonDown.sqf new file mode 100644 index 0000000000..2111be99e8 --- /dev/null +++ b/addons/refuel/functions/fnc_onMouseButtonDown.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Mouse button down event. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_refuel_fnc_onMouseButtonDown + * + * Public: No + */ + +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 519b07897d..cc851a549f 100644 --- a/addons/refuel/functions/fnc_readFuelCounter.sqf +++ b/addons/refuel/functions/fnc_readFuelCounter.sqf @@ -1,10 +1,11 @@ +#include "script_component.hpp" /* * Author: GitHawk * Reads the fuel counter. * * Arguments: * 0: Unit - * 1: Fuel Truck + * 1: Fuel Source * * Return Value: * None @@ -14,28 +15,15 @@ * * Public: No */ -#include "script_component.hpp" -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]]]; +params [["_unit", objNull, [objNull]], ["_source", objNull, [objNull]]]; -[ - 2, - [_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 ae17ce8d02..4717f1206c 100644 --- a/addons/refuel/functions/fnc_refuel.sqf +++ b/addons/refuel/functions/fnc_refuel.sqf @@ -1,25 +1,35 @@ +#include "script_component.hpp" /* * Author: GitHawk * Refuels the vehicle. * * Arguments: * 0: Unit - * 1: Target + * 1: Vehicle * 2: Nozzle * 3: Connection Point * * Return Value: * None * + * Example: + * [bob, kevin, nozzle, [2, 1, 5]] call ace_refuel_fnc_refuel + * * Public: No */ -#include "script_component.hpp" +params [["_unit", objNull, [objNull]], ["_sink", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_connectToPoint", [0,0,0], [[]], 3]]; -params [["_unit", objNull, [objNull]], ["_target", objNull, [objNull]], ["_nozzle", objNull, [objNull]], ["_connectToPoint", [0,0,0], [[]], 3]]; +private _config = configFile >> "CfgVehicles" >> typeOf _sink; -private _rate = getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(flowRate)) * GVAR(rate); -private _maxFuel = getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(fuelCapacity)); +private _rate = getNumber (_config >> QGVAR(flowRate)) * GVAR(rate); +private _maxFuel = getNumber (_config >> QGVAR(fuelCapacity)); + +// Fall back to vanilla fuelCapacity value (only air and sea vehicles don't have this defined by default by us) +// Air and sea vehicles have that value properly defined in liters, unlike ground vehicles which is is formula of (range * tested factor) - different fuel consumption system than ground vehicles +if (_maxFuel == 0) then { + _maxFuel = getNumber (_config >> "fuelCapacity"); +}; [{ params ["_args", "_pfID"]; @@ -32,28 +42,27 @@ private _maxFuel = getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> 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 _tooFar = ((_sink modelToWorld _connectToPoint) distance (_source modelToWorld _connectFromPoint)) > (REFUEL_HOSE_LENGTH - 2); + private _hoseLength = _source getVariable [QGVAR(hoseLength), GVAR(hoseLength)]; + private _tooFar = ((_sink modelToWorld _connectToPoint) distance (_source modelToWorld _connectFromPoint)) > (_hoseLength - 2); if (_tooFar && {!(_nozzle getVariable [QGVAR(jerryCan), false])}) exitWith { [LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured); [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); @@ -96,11 +105,11 @@ private _maxFuel = getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> }; }, 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 d58f0a48ad..0000000000 --- a/addons/refuel/functions/fnc_reset.sqf +++ /dev/null @@ -1,40 +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; - }; - - { - [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 1bd364eafb..3cc2f773f0 100644 --- a/addons/refuel/functions/fnc_returnNozzle.sqf +++ b/addons/refuel/functions/fnc_returnNozzle.sqf @@ -1,59 +1,53 @@ +#include "script_component.hpp" /* * Author: GitHawk, Jonpas * Returns the nozzle back to source vehicle. * * Arguments: * 0: Unit - * 1: Fuel Truck + * 1: Fuel Source * * Return Value: - * Returned Nozzle + * None * * Example: * [player, fuelTruck] call ace_refuel_fnc_returnNozzle * * Public: No */ -#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 {}; [ - 2, - [_unit, _nozzle, _target], + TIME_PROGRESSBAR(REFUEL_PROGRESS_DURATION), + [_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; }; + private _helper = _nozzle getVariable [QGVAR(helper), objNull]; + if !(isNull _helper) then { + deleteVehicle _helper; + }; 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..f95596f4f1 100644 --- a/addons/refuel/functions/fnc_setFuel.sqf +++ b/addons/refuel/functions/fnc_setFuel.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: GitHawk * Set the remaining fuel amount. * * Arguments: - * 0: Fuel Truck + * 0: Fuel Source * 1: Amount (in liters) * * Return Value: @@ -14,11 +15,10 @@ * * Public: Yes */ -#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..7f4d936ed3 --- /dev/null +++ b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf @@ -0,0 +1,114 @@ +#include "script_component.hpp" +/* + * 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 + */ + +#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 9548b2ed2f..83e38c1be6 100644 --- a/addons/refuel/functions/fnc_takeNozzle.sqf +++ b/addons/refuel/functions/fnc_takeNozzle.sqf @@ -1,165 +1,99 @@ +#include "script_component.hpp" /* * Author: GitHawk * Take a fuel nozzle either from a fuel truck/station or from the ground. * * 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 */ -#include "script_component.hpp" 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; - }; - [ - 2, - [_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]; - - if (_target isKindOf "AllVehicles") then { - // Currently ropeCreate requires its first parameter to be a real vehicle - private _rope = ropeCreate [_target, _endPosOffset, _newNozzle, [0, -0.20, 0.12], REFUEL_HOSE_LENGTH]; - _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]; - }, - "", - localize LSTRING(TakeNozzleAction), - {true}, - ["isnotinside"] - ] call EFUNC(common,progressBar); -} else { // func is called on muzzle either connected or on ground - [ - 2, - [_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; - }; - _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]; - }, - "", - localize LSTRING(TakeNozzleAction), - {true}, - ["isnotinside"] - ] call EFUNC(common,progressBar); - - _target = _nozzle getVariable QGVAR(source); - _endPosOffset = _nozzle getVariable QGVAR(attachPos); -}; -if !(_nozzle getVariable [QGVAR(jerryCan), false]) then { - [{ - params ["_args", "_pfID"]; - _args params [ - ["_unit", player, [objNull]], - ["_source", objNull, [objNull]], - ["_endPosOffset", [0, 0, 0], [[]], 3], - ["_nozzle", _unit getVariable [QGVAR(nozzle), objNull], [objNull]] - ]; - - if (isNull _source || {_unit distance (_source modelToWorld _endPosOffset) > (REFUEL_HOSE_LENGTH - 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; - }; - deleteVehicle _nozzle; + 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 { - [LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured); + _helper setPosWorld (getPosWorld _source); + _helper setDir (getDir _source); + _helper setVectorUp (vectorUp _source); }; + _nozzle setVariable [QGVAR(helper), _helper, true]; + _ropeTarget = _helper; }; - [_pfID] call cba_fnc_removePerFrameHandler; + 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]; + + [_source, "blockEngine", "ACE_Refuel", true] call EFUNC(common,statusEffect_set); + _source setVariable [QGVAR(isConnected), true, true]; + _source setVariable [QGVAR(ownedNozzle), _nozzle, true]; }; - }, 0, [_unit, _target, _endPosOffset]] call cba_fnc_addPerFrameHandler; -}; + + _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 7ce3d9c874..1448a0d145 100644 --- a/addons/refuel/functions/fnc_turnOff.sqf +++ b/addons/refuel/functions/fnc_turnOff.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Turn off a fuel nozzle. @@ -14,22 +15,9 @@ * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; -[ - 2, - [_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 7a69de9b6f..4cbbc0033d 100644 --- a/addons/refuel/functions/fnc_turnOn.sqf +++ b/addons/refuel/functions/fnc_turnOn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: GitHawk * Turn on a fuel nozzle. @@ -14,22 +15,9 @@ * * Public: No */ -#include "script_component.hpp" params [["_unit", objNull, [objNull]], ["_nozzle", objNull, [objNull]]]; -[ - 2, - [_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/initSettings.sqf b/addons/refuel/initSettings.sqf new file mode 100644 index 0000000000..b16cff3230 --- /dev/null +++ b/addons/refuel/initSettings.sqf @@ -0,0 +1,19 @@ +// CBA Settings [ADDON: ace_refuel]: + +[ + QGVAR(rate), "SLIDER", + [LSTRING(RefuelSettings_speed_DisplayName), LSTRING(RefuelSettings_speed_Description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], + [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(rate), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(hoseLength), "SLIDER", + [LSTRING(RefuelSettings_hoseLength_DisplayName)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], + [0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(hoseLength), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; diff --git a/addons/refuel/script_component.hpp b/addons/refuel/script_component.hpp index 124b5acd64..be346e0cca 100644 --- a/addons/refuel/script_component.hpp +++ b/addons/refuel/script_component.hpp @@ -2,9 +2,10 @@ #define COMPONENT_BEAUTIFIED Refuel #include "\z\ace\addons\main\script_mod.hpp" +// #define FAST_PROGRESSBARS +// #define DRAW_HOOKS_POS // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_REFUEL @@ -18,15 +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_HOSE_LENGTH 12 +#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, 99]; +#ifdef FAST_PROGRESSBARS + #define TIME_PROGRESSBAR(X) ((X) * 0.075) +#else + #define TIME_PROGRESSBAR(X) (X) +#endif -#define REFUEL_UNHOLSTER_WEAPON \ - _weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRefuel); \ - _unit selectWeapon _weaponSelect; \ - _unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; +#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 2df51ea540..9ca639d076 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ Impostazioni Rifornimento Parámetros de reabastecimiento Réglages de ravitaillement + 給油設定 + 재급유 설정 + 加油设定 + 加油設定 Flow Rate @@ -19,9 +23,13 @@ Скорость заправки Velocidade da vazão Rychlost tankování - Rateo Flusso + Portata Flusso Caudal de llenado Vitesse du ravitaillement + 流量 + 주유량 + 油料流量 + 油料流量 How fast should a vehicle be refueled? @@ -33,6 +41,10 @@ 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 ? + どのくらいの速さで車両へ給油しますか? + 차량이 얼마나 빨리 재급유될 수 있습니까? + 载具多快会加油完毕? + 載具多快會加油完畢? Refuel @@ -44,6 +56,10 @@ Rifornisci Reabastecer Ravitaillement + 給油 + 재급유 + 加油 + 加油 Take fuel nozzle @@ -52,9 +68,13 @@ Взять топливный шланг Pegar o bocal de combustível Vzít výdejní pistoli - Prenti manica benzina + Prendi manica benzina Tomar surtidor Prendre la pompe + 給油ノズルを取る + 주유기 획득 + 拿取燃料喷嘴 + 拿取燃料噴嘴 Taking fuel nozzle... @@ -63,9 +83,13 @@ Берем топливный шланг... Pegando o bocal de combustível... Beru výdejní pistoli... - Sto prendendo manica benzina... + Prendendo manicotto benzina... Tomando surtidor... Prise de la pompe... + 給油ノズルを取っています・・・ + 주유기 획득중... + 拿取燃料喷嘴中... + 拿取燃料噴嘴中... Connect fuel nozzle @@ -77,6 +101,10 @@ Collega manica benzina Conectar surtidor Connecter la pompe + 給油ノズルを接続する + 주유기 꼽기 + 连接燃料喷嘴 + 連接燃料噴嘴 Connecting fuel nozzle... @@ -85,9 +113,13 @@ Присоединяем топливный шланг... Conectando o bocal de combustível... Připojuji výdejní pistoli... - Sto collegando la manica benzina... + Collegando manicotto benzina... Conectando surtidor... Connection de la pompe... + 給油ノズルを接続しています・・・ + 주유기 꼽는중... + 连结燃料喷嘴中... + 連結燃料噴嘴中... Disconnect fuel nozzle @@ -96,9 +128,13 @@ Отсоединить топливный шланг Desconectar o bocal de combustível Odpojit výdejní pistoli - Scollega manica benzina + Scollega manicotto benzina Desconectar surtidor Déconnecter la pompe + 給油ノズルを外しました + 주유기 뽑기 + 断开燃料喷嘴 + 斷開燃料噴嘴 Connect @@ -110,6 +146,10 @@ Collega Conectar Connecter + 接続 + 꼽기 + 连结 + 連結 Check remaining fuel @@ -121,6 +161,10 @@ Controlla benzina rimanente Verificar combustible remanente Vérifier le carburant restant + 残燃料を見る + 남은 연료 확인 + 检查剩余燃料 + 檢查剩餘燃料 Checking remaining fuel... @@ -129,9 +173,13 @@ Проверяем остаток топлива... Verificando combustível restante... Kontroluji zůstatek paliva... - Sto controllando la benzina rimanente... + Controllando la benzina rimanente... Verificando combustible remanente,,, Vérifie le carburant restant... + 残燃料を見ています・・・ + 남은 연료 확인중... + 检查剩余燃料中... + 檢查剩餘燃料中... There are %1 liters left. @@ -143,6 +191,10 @@ Sono rimasti %1 litri. Quedan %1 litros. Il reste %1 litres. + 後 %1 リットル残っています。 + %1 리터 남음 + 剩下%1公升的燃料。 + 剩下%1公升的燃料。 There is no fuel left. @@ -154,6 +206,10 @@ Non è rimasta più benzina. No queda combustible. Il n'y a plus de carburant. + もう燃料は残っていません。 + 연료 없음. + 没有剩余的燃料 + 沒有剩餘的燃料 Cancel @@ -165,6 +221,10 @@ Cancella Cancelar Annuler + 中止 + 취소 + 取消 + 取消 Failed @@ -176,6 +236,10 @@ Fallito Falló Echoué + 失敗 + 실패 + 失败 + 失敗 Stop fueling @@ -187,17 +251,10 @@ Ferma rifornimento Detener reabastecimiento Arrêter le ravitaillement - - - Stopping fueling... - Stoppe Betankung... - Zatrzymywanie tankowania... - Останавливаем заправку... - Parando reabastecimento... - Zastavuji tankování... - Sto fermando il rifornimento... - Deteniendo reabastecimiento... - Arrête le ravitaillement... + 給油を止める + 그만 재급유하기 + 停止加油 + 停止加油 Start fueling @@ -209,17 +266,19 @@ Inizia rifornimento Comenzar reabastecimiento Débute le ravitaillement + 給油を始める + 재급유 시작 + 开始加油 + 開始加油 - - Starting fueling... - Beginne Betankung... - Rozpoczynanie tankowania... - Начинаем заправку... - Começando reabastecimento... - Spouštím tankování... - Sto 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 @@ -231,6 +290,10 @@ %1 litri riforniti %1 lt reabastecido %1 litres ravitaillés + %1 リッターを給油しました + %1 리터 재급유됨 + 已加入%1公升的燃料 + 已加入%1公升的燃料 The fuel source is empty. @@ -239,9 +302,13 @@ Источник топлива пустой. A fonte de combustível está vazia. Zdroj paliva je prázdný. - La fonte di benzina èvuota. + La fonte di benzina è vuota. La fuente de combustible está vacía. La source de carburant est vide. + 給油元は空です。 + 燃料来源已空. + 燃料來源已空. + 연료공급처가 비었음. Maximum fuel hose length reached. @@ -250,9 +317,13 @@ Достигнута максимальная длина шланга. Distância máxima da mangueira de combustível alcançada. Dosažena maximální délka hadice - Distanza massima della manica raggiunta. + Distanza massima della pompa raggiunta. Máxima longitud de manguera alcanzada. Tuyau tendu au maximum + 給油ホースはもうこれ以上届きません。 + 주유기 호스 최대 거리에 도달함. + 已加满至最大油量。 + 已加滿至最大油量。 Fueling completed @@ -264,6 +335,10 @@ Rifornimento completato Reabastecimiento completado Ravitaillement terminé + 給油を完了しました + 재급유 완료함 + 加油完毕 + 加油完畢 Fueling stopped @@ -275,6 +350,10 @@ Rifornimento fermato Reabastecimiento detenido Ravitaillement stoppé + 給油を止めました + 재급유 멈춤 + 已停止加油 + 已停止加油 Fueling started @@ -286,6 +365,10 @@ Rifornimento iniziato Comenzó el reabastecimiento Ravitaillement débuté + 給油を始めました + 재급유 시작함 + 已开始加油 + 已開始加油 Return fuel nozzle @@ -294,9 +377,13 @@ Вернуть топливный шланг Retornar bocal de combustível Vrátit výdejní pistoli - Riponi manica benzina + Riponi manicotto benzina Devolver surtidor Retourner la pompe + 給油ノズルを戻す + 주유기 반환 + 放回燃料喷嘴 + 放回燃料噴嘴 Returning fuel nozzle... @@ -305,9 +392,13 @@ Возвращаем топливный шланг... Retornando bocal de combustível... Vracím výdejní pistoli... - Sto riponendo la manica della benzina... + Riponendo la manica della benzina... Devolviendo el surtidor... Retourne la pompe + 給油ノズルを戻しています・・・ + 주유기 반환중 + 放回燃料喷嘴中... + 放回燃料噴嘴中... Check fuel counter @@ -319,17 +410,10 @@ Controlla indicatore livello benzina Verificar el contador de combustible Vérifier le compteur - - - Checking fuel counter... - Betrachte Tankuhr... - Sprawdzanie wskaźnika paliwa... - Проверяем счетчик топлива... - Verificando contador de combustível... - Konroluji palivoměr... - Sto controllando l'indicatore del livello benzina... - Verificando el contador de combustible - Vérification du compteur... + 燃料計を見る + 연로카운터 확인 + 检查燃料表 + 檢查燃料表 %1 liters have been fueled. @@ -341,6 +425,62 @@ %1 litri sono stati riforniti. Se reabastecieron %1 lt %1 litres ont été écoulés. + %1 リッターが給油されました。 + %1 리터가 재급유되었습니다. + 已加入%1公升 + 已加入%1公升 + + + Refuel hose length + Betankung Schlauchlänge + Reabastecer longitud de manguera + Rifiuta lungezza tubo + 給油ホースの長さ + 加油软管长度 + 加油軟管長度 + 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/ACE_UI.hpp b/addons/reload/ACE_UI.hpp index 8164d04b17..cfc2a26f9c 100644 --- a/addons/reload/ACE_UI.hpp +++ b/addons/reload/ACE_UI.hpp @@ -1,7 +1,7 @@ class ACE_UI { class ammoCount { class conditions { - ADDON = "(false)"; + ADDON = "cameraOn == (getConnectedUAV ACE_player)"; }; }; }; diff --git a/addons/reload/CfgEventHandlers.hpp b/addons/reload/CfgEventHandlers.hpp index a3dd6de29b..6016e7712a 100644 --- a/addons/reload/CfgEventHandlers.hpp +++ b/addons/reload/CfgEventHandlers.hpp @@ -20,7 +20,7 @@ class Extended_PostInit_EventHandlers { class Extended_Take_EventHandlers { class CAManBase { class ACE_AmmoIndicatorReload { - clientTake = QUOTE(if (_this select 0 == ACE_player && {GVAR(DisplayText)} && {(_this select 1) in [ARR_3(uniformContainer (_this select 0), vestContainer (_this select 0), backpackContainer (_this select 0))]} && {_this select 2 == currentMagazine (_this select 0)}) then {[ARR_2(_this select 0, vehicle (_this select 0))] call FUNC(displayAmmo)};); + clientTake = QUOTE(params ['_unit']; if (_unit == ACE_player && {GVAR(DisplayText)} && {(_this select 1) in [ARR_3(uniformContainer _unit, vestContainer _unit, backpackContainer _unit)]} && {_this select 2 == currentMagazine _unit}) then {[ARR_2(_unit, vehicle _unit)] call FUNC(displayAmmo)};); }; }; }; diff --git a/addons/reload/CfgVehicles.hpp b/addons/reload/CfgVehicles.hpp index a9fa4deadd..7a1d483bd9 100644 --- a/addons/reload/CfgVehicles.hpp +++ b/addons/reload/CfgVehicles.hpp @@ -6,14 +6,16 @@ class CfgVehicles { class GVAR(LinkBelt) { displayName = CSTRING(LinkBelt); distance = 2.0; - condition = QUOTE([ARR_2(_player, _target)] call FUNC(canLinkBelt)); + 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_PREP.hpp b/addons/reload/XEH_PREP.hpp index bfd89b098e..f2b386ac37 100644 --- a/addons/reload/XEH_PREP.hpp +++ b/addons/reload/XEH_PREP.hpp @@ -1,6 +1,6 @@ PREP(canCheckAmmo); -PREP(canLinkBelt); +PREP(getAmmoToLinkBelt); PREP(checkAmmo); PREP(displayAmmo); PREP(startLinkingBelt); diff --git a/addons/reload/XEH_postInit.sqf b/addons/reload/XEH_postInit.sqf index 7a5e17464c..eda5c61faa 100644 --- a/addons/reload/XEH_postInit.sqf +++ b/addons/reload/XEH_postInit.sqf @@ -6,9 +6,11 @@ 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}; + // Ignore if controlling UAV (blocks radar keybind) + if (!isNull (ACE_controlledUAV param [0, objNull])) exitWith {false}; // Statement [ACE_player] call FUNC(checkAmmo); diff --git a/addons/reload/XEH_preInit.sqf b/addons/reload/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/reload/XEH_preInit.sqf +++ b/addons/reload/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/reload/config.cpp b/addons/reload/config.cpp index 9c66dd4828..21e28d35f5 100644 --- a/addons/reload/config.cpp +++ b/addons/reload/config.cpp @@ -20,9 +20,3 @@ class CfgPatches { #include "CfgActions.hpp" #include "ACE_Settings.hpp" #include "ACE_UI.hpp" - -class ACE_newEvents { - setAmmoSync = QGVAR(syncAmmo); - returnedAmmo = QGVAR(ammoReturned); - linkedAmmo = QGVAR(ammoLinked); -}; diff --git a/addons/reload/functions/fnc_canCheckAmmo.sqf b/addons/reload/functions/fnc_canCheckAmmo.sqf index 7f38e3fbfa..a0aa0c5c70 100644 --- a/addons/reload/functions/fnc_canCheckAmmo.sqf +++ b/addons/reload/functions/fnc_canCheckAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: CAA-Picard * Check if the player can check the ammo of the target. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["", "_target"]; diff --git a/addons/reload/functions/fnc_canLinkBelt.sqf b/addons/reload/functions/fnc_canLinkBelt.sqf deleted file mode 100644 index d29dc6efd6..0000000000 --- a/addons/reload/functions/fnc_canLinkBelt.sqf +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Author: esteldunedain - * Check if the target has an MG equiped with belt system that the player can link - * - * Arguments: - * 0: Player - * 1: Target - * - * Return Value: - * Can link belt - * - * Example: - * [player, cursorObject] call ace_reload_fnc_canLinkBelt; - * - * Public: No - */ -#include "script_component.hpp" - -params ["_player", "_target"]; - -if (vehicle _target != _target) exitWith {false}; - -private _magazineType = currentMagazine _target; -private _magazineCfg = configFile >> "CfgMagazines" >> _magazineType; - -if (getNumber (_magazineCfg >> "ACE_isBelt") == 0) exitWith {false}; - -// Check if the ammo is not empty or full -private _ammoCount = _target ammo currentWeapon _target; - -// Exit if the belt is full or empty -if (_ammoCount == 0 || getNumber (_magazineCfg >> "count") - _ammoCount == 0) exitWith {false}; - -// Check if the player has any of the same magazines -// Calculate max ammo -private _maxAmmo = 0; - -{ - _maxAmmo = _maxAmmo max (_x select 1); -} forEach (magazinesAmmo _player select {_x select 0 == _magazineType}); - -_maxAmmo > 0 diff --git a/addons/reload/functions/fnc_checkAmmo.sqf b/addons/reload/functions/fnc_checkAmmo.sqf index baa0754f80..156ca30a32 100644 --- a/addons/reload/functions/fnc_checkAmmo.sqf +++ b/addons/reload/functions/fnc_checkAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 and esteldunedain * Count the ammo of the currently loaded magazine or count rifle grenades. Play animation and display message. @@ -7,9 +8,13 @@ * 1: Target. Optional, if not suplied the player counts his personal or static weapon ammo * * Return Value: - * Nothing + * None + * + * Example: + * [bob, kevin] call ace_reload_fnc_checkAmmo + * + * Public: No */ -#include "script_component.hpp" #define COUNT_BARS 12 diff --git a/addons/reload/functions/fnc_displayAmmo.sqf b/addons/reload/functions/fnc_displayAmmo.sqf index 6aa8f013d9..9b018131d4 100644 --- a/addons/reload/functions/fnc_displayAmmo.sqf +++ b/addons/reload/functions/fnc_displayAmmo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 and esteldunedain * Display the ammo of the currently loaded magazine of the target or count rifle grenades. @@ -6,9 +7,13 @@ * 0: Target * * Return Value: - * Nothing + * None + * + * Example: + * [bob] call ace_reload_fnc_displayAmmo + * + * Public: No */ -#include "script_component.hpp" #define COUNT_BARS 12 @@ -89,7 +94,7 @@ private _ammoBarsStructuredText = if (_showNumber) then { _string = _string + "|"; }; - composeText [_text, [_string, [0.5, 0.5, 0.5]] call EFUNC(common,stringToColoredText)]; + composeText [_text, [_string, "#808080"] call EFUNC(common,stringToColoredText)]; }; diff --git a/addons/reload/functions/fnc_getAmmoToLinkBelt.sqf b/addons/reload/functions/fnc_getAmmoToLinkBelt.sqf new file mode 100644 index 0000000000..3701b32d8b --- /dev/null +++ b/addons/reload/functions/fnc_getAmmoToLinkBelt.sqf @@ -0,0 +1,42 @@ +#include "script_component.hpp" +/* + * Author: esteldunedain, phyma + * Check if the target has an MG equiped with belt system that the player can link + * + * Arguments: + * 0: Player + * 1: Target + * + * Return Value: + * Maximum ammo of magazine (-1 on error) + * + * Example: + * [player, cursorObject] call ace_reload_fnc_getAmmoToLinkBelt; + * + * Public: No + */ + +params ["_player", "_target"]; + +if (vehicle _target != _target) exitWith {-1}; + +private _magazineType = currentMagazine _target; +private _magazineCfg = configFile >> "CfgMagazines" >> _magazineType; + +if (getNumber (_magazineCfg >> "ACE_isBelt") == 0) exitWith {-1}; + +// Check if the ammo is not empty or full +private _ammoCount = _target ammo currentWeapon _target; + +// Exit if the belt is full or empty +if (_ammoCount == 0 || getNumber (_magazineCfg >> "count") - _ammoCount == 0) exitWith {-1}; + +// Check if the player has any of the same magazines +// Calculate max ammo +private _maxAmmo = 0; + +{ + _maxAmmo = _maxAmmo max (_x select 1); +} forEach (magazinesAmmo _player select {_x select 0 == _magazineType}); + +_maxAmmo diff --git a/addons/reload/functions/fnc_startLinkingBelt.sqf b/addons/reload/functions/fnc_startLinkingBelt.sqf index a1cc73635d..54fc1921d7 100644 --- a/addons/reload/functions/fnc_startLinkingBelt.sqf +++ b/addons/reload/functions/fnc_startLinkingBelt.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Start linking the belt @@ -8,33 +9,24 @@ * * Return Value: * None + * + * Example: + * [bob, kevin] call ace_reload_fnc_startLinkingBelt + * + * Public: No */ -#include "script_component.hpp" params ["_player", "_target"]; if (vehicle _target != _target) exitWith {false}; private _magazineType = currentMagazine _target; -private _magazineCfg = configFile >> "CfgMagazines" >> _magazineType; -if (getNumber (_magazineCfg >> "ACE_isBelt") == 0) exitWith {false}; -// Check if the ammo is not empty or full -private _ammoCount = _target ammo currentWeapon _target; +private _maxAmmo = [_player, _target] call FUNC(getAmmoToLinkBelt); -// Exit if the belt is full or empty -if ((_ammoCount == 0) || (getNumber (_magazineCfg >> "count") - _ammoCount) == 0) exitWith {false}; - -// Check if the player has any of the same same magazines -// Calculate max ammo it can link -private _maxAmmo = 0; - -{ - _maxAmmo = _maxAmmo max (_x select 1); -} forEach (magazinesAmmo _player select {_x select 0 == _magazineType}); - -if (_maxAmmo == 0) exitWith {}; +//if _maxAmmo is below 0 we quit +if (_maxAmmo <= 0) exitWith {}; // Condition to call each frame private _condition = { @@ -50,7 +42,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 @@ -63,4 +55,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/script_component.hpp b/addons/reload/script_component.hpp index c2dc3b55a1..4cce82a013 100644 --- a/addons/reload/script_component.hpp +++ b/addons/reload/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_RELOAD diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index 647322e8e6..2a7764dc04 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -10,8 +10,12 @@ Sprawdź stan amunicji przy przeładowaniu broni Vérification des munitions au rechargement Lőszer ellenőrzése a fegyver újratöltésekor - Controlla le munizioni ricaricando + Controlla le munizioni durante il ricaricamento Conferir munição ao recarregar a arma + 再装填された武器の弾薬を確認 + 재장전시 장탄수 확인 + 在重新装填时检查弹药 + 在重新裝填時檢查彈藥 Check the ammo in your new magazine on magazine reload. @@ -24,6 +28,10 @@ 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 + 新しく装填された弾倉の弾薬を確認します。 + 재장전시 새탄창에 있는 탄약을 확인합니다. + 在重新装填时检查新弹匣上的弹药. + 在重新裝填時檢查新彈匣上的彈藥. Check Ammo @@ -36,6 +44,10 @@ Controlla le munizioni Conferir munições Проверить боеприпасы + 弾薬を確認 + 장탄수 확인 + 检查弹药 + 檢查彈藥 Ammo @@ -48,6 +60,10 @@ Munizioni Munições Боеприпасы + 弾薬 + 장탄수 + 弹药 + 彈藥 Link belt @@ -60,6 +76,10 @@ Töltényheveder összekötése Attacca la tracolla Ligar cintos de munição + ベルトをつなげる + 벨트 연결 + 连接弹链 + 連接彈鏈 Linking belt... @@ -70,8 +90,12 @@ Podłączanie taśmy... Gurt anhängen... Töltényheveder összekötése folyamatban... - Attacco la tracolla... + 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/XEH_preInit.sqf b/addons/reloadlaunchers/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/reloadlaunchers/XEH_preInit.sqf +++ b/addons/reloadlaunchers/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/reloadlaunchers/config.cpp b/addons/reloadlaunchers/config.cpp index 16ae8cb867..09f01e0594 100644 --- a/addons/reloadlaunchers/config.cpp +++ b/addons/reloadlaunchers/config.cpp @@ -18,7 +18,3 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" - -class ACE_newEvents { - reloadLauncher = QGVAR(reloadLauncher); -}; diff --git a/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf index 6a9d779d02..42af3e5027 100644 --- a/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf +++ b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf @@ -1,18 +1,21 @@ +#include "script_component.hpp" /* * Author: commy2 * Create one action per reloadable missile * * Arguments: - * 1: Target (Object) - * 0: Player (Object) + * 1: Target + * 0: Player * * Return Value: - * Children actions (Array) + * Children actions + * + * Example: + * [bob, kevin] call ace_reloadlaunchers_fnc_addMissileReloadActions * * Public: No * */ -#include "script_component.hpp" params ["_target", "_unit"]; TRACE_2("params",_target,_unit); @@ -30,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 5072d44a48..af08ed8013 100644 --- a/addons/reloadlaunchers/functions/fnc_canLoad.sqf +++ b/addons/reloadlaunchers/functions/fnc_canLoad.sqf @@ -1,26 +1,29 @@ +#include "script_component.hpp" /* * Author: commy2 * Check of the unit can reload the launcher of target unit. * * Arguments: - * 0: Unit to do the reloading (Object) - * 1: Unit eqipped with launcher (Object) - * 2: weapon name (String) - * 3: missile name (String) + * 0: Unit to do the reloading + * 1: Unit eqipped with launcher + * 2: weapon name + * 3: missile name * * Return Value: - * NONE + * None + * + * Example: + * [bob, kevin, "weapon", "missile"] call ace_reloadlaunchers_fnc_canLoad * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", "_weapon", "_magazine"]; 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_getLoadableMissiles.sqf b/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf index 40766a5905..6bded89110 100644 --- a/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf +++ b/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf @@ -1,17 +1,20 @@ +#include "script_component.hpp" /* * Author: commy2 * Return all magazine types from reloaders inventory that are compatible with given weapon. * * Arguments: - * 0: Unit to to the reload (Object) - * 1: A launcher (String) + * 0: Unit to to the reload + * 1: A launcher * * Return Value: - * Reloable magazines (Array) + * Reloable magazines + * + * Example: + * [bob, launcher] call ace_reloadlaunchers_fnc_getLoadableMissiles * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon"]; TRACE_2("params",_unit,_weapon); diff --git a/addons/reloadlaunchers/functions/fnc_load.sqf b/addons/reloadlaunchers/functions/fnc_load.sqf index 2f822bb6d7..27d4cafbf2 100644 --- a/addons/reloadlaunchers/functions/fnc_load.sqf +++ b/addons/reloadlaunchers/functions/fnc_load.sqf @@ -1,19 +1,22 @@ +#include "script_component.hpp" /* * Author: commy2 * Reload a launcher * * Arguments: - * 0: Unit with magazine (Object) - * 1: Unit with launcher (Object) - * 2: weapon name (String) - * 3: missile name (String) + * 0: Unit with magazine + * 1: Unit with launcher + * 2: weapon name + * 3: missile name * * Return Value: - * NONE + * None + * + * Example: + * [bob, kevin, "weapon", "missile"] call ace_reloadlaunchers_fnc_load * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", "_weapon", "_magazine"]; TRACE_4("params",_unit,_target,_weapon,_magazine); @@ -28,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/functions/fnc_reloadLauncher.sqf b/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf index 96db7cdca5..58f6b6556a 100644 --- a/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf +++ b/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf @@ -1,19 +1,22 @@ +#include "script_component.hpp" /* * Author: commy2 * Reload a launcher * * Arguments: - * 0: Unit to do the reloading (Object) - * 1: Target to rload (Object) - * 2: weapon name (String) - * 3: missile name (String) + * 0: Unit to do the reloading + * 1: Target to rload + * 2: weapon name + * 3: missile name * * Return Value: - * NONE + * None + * + * Example: + * [bob, kevin, "weapon", "missile"] call ace_reloadlaunchers_fnc_realoadLauncher * * Public: No */ -#include "script_component.hpp" params ["_unit","_target","_weapon","_magazine"]; TRACE_4("params",_unit,_target,_weapon,_magazine); @@ -24,4 +27,4 @@ if (currentWeapon _target != _weapon) exitWith {}; if (currentMagazine _target != "") exitWith {}; // command is wip, reload time for launchers is not intended. -_target addWeaponItem [_weapon, _magazine]; +_target addWeaponItem [_weapon, _magazine]; diff --git a/addons/reloadlaunchers/script_component.hpp b/addons/reloadlaunchers/script_component.hpp index 9051d0c36f..30901ec53b 100644 --- a/addons/reloadlaunchers/script_component.hpp +++ b/addons/reloadlaunchers/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_RELOADLAUNCHERS diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index 72193d48e2..eef4c9e50a 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Kilövö betöltése Carica lanciamissili Recarregar lançador + ランチャーに装填 + 무기 재장전 + 装载发射器 + 裝載發射器 Loading launcher... @@ -22,8 +26,12 @@ Nabíjím odpalovač... Ładowanie wyrzutni... Kilövő betöltés alatt... - Carico il lanciamissili... + Caricando il lanciamissili... Recarregando lançador... + ランチャーに装填中・・・ + 무기 재장전중... + 装载发射器中... + 裝載發射器中... Launcher loaded @@ -36,6 +44,10 @@ Kilövő betöltve Lanciamissili caricato Lançador Carregado + ランチャーに装填完了 + 무기 재장전됨 + 发射器装载完毕 + 發射器裝載完畢 Load %1 @@ -48,6 +60,10 @@ %1 betöltése Caricato %1 Recarregar %1 + %1 を装填 + %1 장전 + 装载%1 + 裝載%1 diff --git a/addons/repair/ACE_Repair.hpp b/addons/repair/ACE_Repair.hpp index 6e5eac4fa8..ec0624e2dc 100644 --- a/addons/repair/ACE_Repair.hpp +++ b/addons/repair/ACE_Repair.hpp @@ -72,7 +72,7 @@ class ACE_Repair { requiredEngineer = QGVAR(engineerSetting_fullRepair); repairLocations[] = {QGVAR(fullRepairLocation)}; repairingTime = 30; - condition = "damage _target > 0"; + condition = "-1 != ((getAllHitPointsDamage _target param [2,[]]) findIf {_x > 0})"; callbackSuccess = QUOTE(call FUNC(doFullRepair)); itemConsumed = QGVAR(consumeItem_ToolKit); }; diff --git a/addons/repair/ACE_Settings.hpp b/addons/repair/ACE_Settings.hpp index 46228e2e44..82217bc5ad 100644 --- a/addons/repair/ACE_Settings.hpp +++ b/addons/repair/ACE_Settings.hpp @@ -1,85 +1,37 @@ +// Warning: do not remove without handling wheelRepairRequiredItems's _values config on line 32 [used in repair/canRepair] class ACE_Settings { class GVAR(displayTextOnRepair) { - displayName = CSTRING(SettingDisplayTextName); - description = CSTRING(SettingDisplayTextDesc); - typeName = "BOOL"; - isClientSettable = 1; - value = 1; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(engineerSetting_repair) { - displayName = CSTRING(enginerSetting_Repair_name); - description = CSTRING(enginerSetting_Repair_description); - typeName = "SCALAR"; - value = 1; - values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_RepairSpecialistOnly)}; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(engineerSetting_wheel) { - displayName = CSTRING(enginerSetting_Wheel_name); - description = CSTRING(enginerSetting_Wheel_description); - typeName = "SCALAR"; - value = 0; - values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_RepairSpecialistOnly)}; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(repairDamageThreshold) { - displayName = CSTRING(repairDamageThreshold_name); - description = CSTRING(repairDamageThreshold_description); - typeName = "SCALAR"; - value = 0.6; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(repairDamageThreshold_engineer) { - displayName = CSTRING(repairDamageThreshold_Engineer_name); - description = CSTRING(repairDamageThreshold_Engineer_description); - typeName = "SCALAR"; - value = 0.4; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(consumeItem_toolKit) { - displayName = CSTRING(consumeItem_ToolKit_name); - description = CSTRING(consumeItem_ToolKit_description); - typeName = "SCALAR"; - value = 0; - values[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(fullRepairLocation) { - displayName = CSTRING(fullRepairLocation); - description = CSTRING(fullRepairLocation_description); - typeName = "SCALAR"; - value = 2; - values[] = {CSTRING(useAnywhere), CSTRING(repairVehicleOnly), CSTRING(repairFacilityOnly), CSTRING(vehicleAndFacility), ECSTRING(common,Disabled)}; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(engineerSetting_fullRepair) { - displayName = CSTRING(engineerSetting_fullRepair_name); - description = CSTRING(engineerSetting_fullRepair_description); - typeName = "SCALAR"; - value = 2; - values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_RepairSpecialistOnly)}; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(addSpareParts) { - displayName = CSTRING(addSpareParts_name); - description = CSTRING(addSpareParts_description); - typeName = "BOOL"; - value = 1; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; class GVAR(wheelRepairRequiredItems) { - displayName = CSTRING(wheelRepairRequiredItems_name); - description = CSTRING(wheelRepairRequiredItems_description); - category = ECSTRING(OptionsMenu,CategoryLogistics); - typeName = "SCALAR"; - value = 0; - values[] = {"None", "ToolKit"}; + movedToSQF = 1; _values[] = {{}, {"ToolKit"}}; }; class GVAR(autoShutOffEngineWhenStartingRepair) { - typeName = "BOOL"; - value = 0; - category = ECSTRING(OptionsMenu,CategoryLogistics); + movedToSQF = 1; }; }; diff --git a/addons/repair/CfgEden.hpp b/addons/repair/CfgEden.hpp index eb7933fee4..be92ec6689 100644 --- a/addons/repair/CfgEden.hpp +++ b/addons/repair/CfgEden.hpp @@ -9,8 +9,8 @@ class Cfg3DEN { }; }; class GVAR(isEngineerControl): Title { - attributeLoad = "(_this controlsGroupCtrl 100) lbsetcursel (((_value + 1) min 3) max 0);"; - attributeSave = "(missionnamespace getvariable ['ace_isEng_temp',0]) - 1;"; + attributeLoad = "(_this controlsGroupCtrl 100) lbSetCurSel (((_value + 1) min 3) max 0);"; + attributeSave = "(lbCurSel (_this controlsGroupCtrl 100)) - 1"; class Controls: Controls { class Title: Title{}; class Value: ctrlToolbox { @@ -21,8 +21,7 @@ class Cfg3DEN { h = "5 * (pixelH * pixelGrid * 0.50)"; rows = 1; columns = 4; - strings[] = {"$STR_3DEN_Attributes_Lock_Default_text", CSTRING(AssignEngineerRole_role_none), CSTRING(AssignEngineerRole_role_engineer), CSTRING(AssignEngineerRole_role_specialist)}; - onToolboxSelChanged = "missionnamespace setvariable ['ace_isEng_temp',_this select 1];"; + strings[] = {"$STR_3DEN_Attributes_Lock_Default_text", CSTRING(AssignEngineerRole_role_none), CSTRING(AssignEngineerRole_role_engineer), CSTRING(AssignEngineerRole_role_advanced)}; }; }; }; @@ -64,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/CfgEventHandlers.hpp b/addons/repair/CfgEventHandlers.hpp index 559d2d4d7e..3e47f9f96f 100644 --- a/addons/repair/CfgEventHandlers.hpp +++ b/addons/repair/CfgEventHandlers.hpp @@ -37,7 +37,7 @@ class Extended_InitPost_EventHandlers { class Helicopter { class ADDON { init = QUOTE(_this call DFUNC(addRepairActions)); - exclude[] = {QEGVAR(fastroping,helper), "ACE_friesBase"}; + exclude[] = {QEGVAR(fastroping,helper), "ACE_friesBase", QEGVAR(refuel,helper)}; }; }; class Plane { 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 c2f2bfacc7..7f0255d2a5 100644 --- a/addons/repair/CfgVehicles.hpp +++ b/addons/repair/CfgVehicles.hpp @@ -7,20 +7,19 @@ statement = ""; \ runOnHover = 1; \ showDisabled = 0; \ - priority = 2; \ icon = "\A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; \ distance = 4; \ - exceptions[] = {"isNotOnLadder"}; \ + exceptions[] = {"isNotSwimming", "isNotOnLadder"}; \ }; \ }; \ }; -class CBA_Extended_EventHandlers; +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,23 +31,23 @@ 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; }; class Engineer { name = CSTRING(engineerSetting_EngineerOnly); value = 1; default = 1; }; - class Special { name = CSTRING(engineerSetting_RepairSpecialistOnly); value = 2; }; + class Advanced { name = CSTRING(engineerSetting_AdvancedOnly); value = 2; }; }; }; 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; }; class Engineer { name = CSTRING(engineerSetting_EngineerOnly); value = 1; }; - class Special { name = CSTRING(engineerSetting_RepairSpecialistOnly); value = 2; }; + class Advanced { name = CSTRING(engineerSetting_AdvancedOnly); value = 2; }; }; }; class repairDamageThreshold { @@ -91,7 +90,7 @@ class CfgVehicles { class values { class anyone { name = CSTRING(engineerSetting_anyone); value = 0; }; class Engineer { name = CSTRING(engineerSetting_EngineerOnly); value = 1; }; - class Special { name = CSTRING(engineerSetting_RepairSpecialistOnly); value = 2; default = 1;}; + class Advanced { name = CSTRING(engineerSetting_AdvancedOnly); value = 2; default = 1;}; }; }; class addSpareParts { @@ -118,7 +117,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"; @@ -150,7 +149,7 @@ class CfgVehicles { default = 1; }; class doctor { - name = CSTRING(AssignEngineerRole_role_specialist); + name = CSTRING(AssignEngineerRole_role_advanced); value = 2; }; }; @@ -162,7 +161,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 +233,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"; @@ -311,14 +310,18 @@ class CfgVehicles { class ThingX; class ACE_RepairItem_Base: ThingX { class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; + class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers_base {}; + }; + class ACE_Actions { + class ACE_MainActions { + modifierFunction = QUOTE(_this call FUNC(modifyInteraction)); + }; }; - icon = "iconObject_circle"; - mapSize = 0.7; accuracy = 0.2; vehicleClass = "ACE_Logistics_Items"; - destrType = "DesturctNo"; + editorCategory = "EdCat_Supplies"; + editorSubcategory = QEGVAR(main,subcategory); }; class ACE_Track: ACE_RepairItem_Base { @@ -328,6 +331,27 @@ class CfgVehicles { scope = 2; model = QPATHTOF(data\ace_track.p3d); displayName = CSTRING(SpareTrack); + icon = "iconObject_2x1"; + mapSize = 0.5; + + // damage handling + armor = 1000; + armorStructural = 1; + minTotalDamageThreshold = 0.01; + explosionShielding = 1; + replaceDamagedLimit = 0.9; + selectionDamage = "mat_track"; + + class Damage { + tex[] = {}; + mat[] = { + QPATHTO_R(data\trailObjects_steel.rvmat), + QPATHTO_R(data\trailObjects_steel_damage.rvmat), + QPATHTO_R(data\trailObjects_steel_destruct.rvmat) + }; + }; + + editorPreview = QPATHTOF(data\preview_track.jpg); }; class ACE_Wheel: ACE_RepairItem_Base { @@ -338,10 +362,58 @@ class CfgVehicles { model = QPATHTOF(data\ace_wheel.p3d); displayName = CSTRING(SpareWheel); picture = QPATHTOF(ui\tire_ca.paa); + icon = "iconObject_circle"; + mapSize = 0.7; + + // damage handling + armor = 120; + armorStructural = 1; + minTotalDamageThreshold = 0.01; + explosionShielding = 1; + replaceDamagedLimit = 0.9; + selectionDamage = "mat_tyre"; //"mat_rim" + + // necessary because only one "selectionDamage" (== "visual") is allowed for simple damage objects + // can not take damage individually though, because of limitations of the thingX simulation type + class HitPoints { + class HitBody { + armor = 0.6; + material = -1; + name = "mat_rim"; + visual = "mat_rim"; + passThrough = 1; + radius = 0.1; + explosionShielding = 1; + }; + }; + + class Damage { + tex[] = {}; + mat[] = { + QPATHTO_R(data\trailObjects_tyre.rvmat), + QPATHTO_R(data\trailObjects_tyre_damage.rvmat), + QPATHTO_R(data\trailObjects_tyre_damage.rvmat), + QPATHTO_R(data\trailObjects_steel.rvmat), + QPATHTO_R(data\trailObjects_steel_damage.rvmat), + QPATHTO_R(data\trailObjects_steel_destruct.rvmat) + }; + }; + + editorPreview = QPATHTOF(data\preview_wheel.jpg); }; // disable vanilla repair // "getNumber (_x >> ""transportRepair"") > 0" configClasses (configFile >> "CfgVehicles") + class ReammoBox_F; + class Land_RepairDepot_01_base_F: ReammoBox_F { // TanksDLC - Repair Depo Thing + GVAR(canRepair) = 1; + transportRepair = 0; + }; + class Van_02_base_F; + class Van_02_service_base_F: Van_02_base_F { // OrangeDLC + GVAR(canRepair) = 1; + transportRepair = 0; + }; class Slingload_01_Base_F; class B_Slingload_01_Repair_F: Slingload_01_Base_F { @@ -351,7 +423,7 @@ class CfgVehicles { class Helicopter_Base_H; class Heli_Transport_04_base_F: Helicopter_Base_H { - GVAR(hitpointGroups)[] = { {"HitEngine", {"HitEngine1", "HitEngine2"}}, {"Glass_1_hitpoint", {"Glass_2_hitpoint", "Glass_3_hitpoint", "Glass_4_hitpoint", "Glass_5_hitpoint", "Glass_6_hitpoint", "Glass_7_hitpoint", "Glass_8_hitpoint", "Glass_9_hitpoint", "Glass_10_hitpoint", "Glass_11_hitpoint", "Glass_12_hitpoint", "Glass_13_hitpoint", "Glass_14_hitpoint", "Glass_15_hitpoint", "Glass_16_hitpoint", "Glass_17_hitpoint", "Glass_18_hitpoint", "Glass_19_hitpoint", "Glass_20_hitpoint"}} }; + GVAR(hitpointGroups)[] = { {"HitEngine", {"HitEngine1", "HitEngine2"}} }; }; class O_Heli_Transport_04_repair_F: Heli_Transport_04_base_F { GVAR(canRepair) = 1; @@ -385,18 +457,12 @@ class CfgVehicles { }; class Car_F; - class Offroad_01_base_F: Car_F { - GVAR(hitpointGroups)[] = { {"HitGlass1", {"HitGlass2"}} }; - }; + class Offroad_01_base_F: Car_F {}; class Offroad_01_repair_base_F: Offroad_01_base_F { GVAR(canRepair) = 1; transportRepair = 0; }; - class MRAP_01_base_F: Car_F { - GVAR(hitpointGroups)[] = { {"HitGlass1", {"HitGlass2", "HitGlass3", "HitGlass4", "HitGlass5", "HitGlass6"}} }; - }; - class B_Truck_01_mover_F; class B_Truck_01_Repair_F: B_Truck_01_mover_F { GVAR(canRepair) = 1; @@ -413,7 +479,7 @@ class CfgVehicles { transportRepair = 0; }; - class Truck_02_engineeral_base_F: Truck_02_box_base_F { + class Truck_02_medical_base_F: Truck_02_box_base_F { GVAR(canRepair) = 0; }; @@ -423,8 +489,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 e3604c95a7..7c2e5a1f15 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -23,6 +23,8 @@ PREP(isEngineer); 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 a7feade1c3..216a16fcf7 100644 --- a/addons/repair/XEH_preInit.sqf +++ b/addons/repair/XEH_preInit.sqf @@ -2,6 +2,43 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" + +["ACE_RepairItem_Base", "killed", { + params ["_object"]; + + [{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 + }; + if (_spareTracks > 0) then { + [_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 + }; + if (_spareWheels > 0) then { + [_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 71a990ea73..1dbe9b46b1 100644 --- a/addons/repair/config.cpp +++ b/addons/repair/config.cpp @@ -16,14 +16,8 @@ class CfgPatches { #include "ACE_Repair.hpp" #include "ACE_Settings.hpp" -#include "CfgEventHandlers.hpp" #include "CfgActions.hpp" -#include "CfgVehicles.hpp" #include "CfgEden.hpp" - -class ACE_newEvents { - setWheelHitPointDamage = QGVAR(setWheelHitPointDamage); - setVehicleHitPointDamage = QGVAR(setVehicleHitPointDamage); - setVehicleDamage = QGVAR(setVehicleDamage); - AddCargoByClass = "ace_addCargo"; -}; +#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 988499c32b..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/ace_wheel.p3d b/addons/repair/data/ace_wheel.p3d index c24f804b4f..aedbf291ce 100644 Binary files a/addons/repair/data/ace_wheel.p3d and b/addons/repair/data/ace_wheel.p3d differ diff --git a/addons/repair/data/material_dummy.p3d b/addons/repair/data/material_dummy.p3d new file mode 100644 index 0000000000..0926cc0f73 Binary files /dev/null and b/addons/repair/data/material_dummy.p3d differ diff --git a/addons/repair/data/model.cfg b/addons/repair/data/model.cfg new file mode 100644 index 0000000000..5be2ddde24 --- /dev/null +++ b/addons/repair/data/model.cfg @@ -0,0 +1,40 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; + + class ace_wheel: Default { + skeletonBones[] = {}; + }; + + class ace_track: Default { + skeletonBones[] = {}; + }; +}; + +class CfgModels { + class Default { + skeletonName = ""; + sectionsInherit = ""; + sections[] = {}; + }; + + class ace_wheel: Default { + skeletonName = "ace_wheel"; + sectionsInherit = ""; + sections[] = { + "mat_tyre", + "mat_rim" + }; + }; + + class ace_track: Default { + skeletonName = "ace_track"; + sectionsInherit = ""; + sections[] = { + "mat_track" + }; + }; +}; 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.rvmat b/addons/repair/data/trailObjects.rvmat deleted file mode 100644 index 8692493699..0000000000 --- a/addons/repair/data/trailObjects.rvmat +++ /dev/null @@ -1,100 +0,0 @@ -#define _ARMA_ - -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,0}; -specular[] = {0.0099999998,0.0099999998,0.0099999998,0.0099999998}; -specularPower = 500; -surfaceInfo="a3\data_f\penetration\metal.bisurf"; -PixelShaderID = "Super"; -VertexShaderID = "Super"; -class Stage1 -{ - texture = "z\ace\addons\repair\data\trailObjects_nohq.paa"; - uvSource = "tex"; - class uvTransform - { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - 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,1}; - 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,1}; - pos[] = {0,0,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,0}; - }; -}; -class Stage5 -{ - texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; - uvSource = "tex"; - class uvTransform - { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; -class Stage6 -{ - texture = "#(ai,64,64,1)fresnelGlass(2)"; - uvSource = "tex"; - class uvTransform - { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; -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/repair/data/trailObjects_steel.rvmat b/addons/repair/data/trailObjects_steel.rvmat new file mode 100644 index 0000000000..f92ea9113f --- /dev/null +++ b/addons/repair/data/trailObjects_steel.rvmat @@ -0,0 +1,91 @@ +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,0}; +specular[] = {0.01,0.01,0.01,0.01}; +specularPower = 500; +surfaceInfo = "a3\data_f\penetration\metal.bisurf"; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\repair\data\trailObjects_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + 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,1}; + 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,1}; + pos[] = {0,0,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,0}; + }; +}; + +class Stage5 { + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnelGlass(2)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +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/repair/data/trailObjects_steel_damage.rvmat b/addons/repair/data/trailObjects_steel_damage.rvmat new file mode 100644 index 0000000000..f797f4ac61 --- /dev/null +++ b/addons/repair/data/trailObjects_steel_damage.rvmat @@ -0,0 +1,91 @@ +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,0}; +specular[] = {0.01,0.01,0.01,0.01}; +specularPower = 500; +surfaceInfo = "a3\data_f\penetration\metal.bisurf"; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\repair\data\trailObjects_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + 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 = "#(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,0}; + }; +}; + +class Stage5 { + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnelGlass(2)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +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/repair/data/trailObjects_steel_destruct.rvmat b/addons/repair/data/trailObjects_steel_destruct.rvmat new file mode 100644 index 0000000000..5be6a7c912 --- /dev/null +++ b/addons/repair/data/trailObjects_steel_destruct.rvmat @@ -0,0 +1,91 @@ +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,0}; +specular[] = {0.01,0.01,0.01,0.01}; +specularPower = 500; +surfaceInfo = "a3\data_f\penetration\metal.bisurf"; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\repair\data\trailObjects_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + 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 = "#(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,0}; + }; +}; + +class Stage5 { + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnelGlass(2)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +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/repair/data/trailObjects_tyre.rvmat b/addons/repair/data/trailObjects_tyre.rvmat new file mode 100644 index 0000000000..f92ea9113f --- /dev/null +++ b/addons/repair/data/trailObjects_tyre.rvmat @@ -0,0 +1,91 @@ +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,0}; +specular[] = {0.01,0.01,0.01,0.01}; +specularPower = 500; +surfaceInfo = "a3\data_f\penetration\metal.bisurf"; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\repair\data\trailObjects_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + 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,1}; + 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,1}; + pos[] = {0,0,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,0}; + }; +}; + +class Stage5 { + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnelGlass(2)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +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/repair/data/trailObjects_tyre_damage.rvmat b/addons/repair/data/trailObjects_tyre_damage.rvmat new file mode 100644 index 0000000000..00bb746293 --- /dev/null +++ b/addons/repair/data/trailObjects_tyre_damage.rvmat @@ -0,0 +1,91 @@ +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,0}; +specular[] = {0.01,0.01,0.01,0.01}; +specularPower = 500; +surfaceInfo = "a3\data_f\penetration\metal.bisurf"; +PixelShaderID = "Super"; +VertexShaderID = "Super"; + +class Stage1 { + texture = "z\ace\addons\repair\data\trailObjects_nohq.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + 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 = "#(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,0}; + }; +}; + +class Stage5 { + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +class Stage6 { + texture = "#(ai,64,64,1)fresnelGlass(2)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; + +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/repair/dev/draw_showRepairInfo.sqf b/addons/repair/dev/draw_showRepairInfo.sqf new file mode 100644 index 0000000000..3a1f0c8d0f --- /dev/null +++ b/addons/repair/dev/draw_showRepairInfo.sqf @@ -0,0 +1,69 @@ +// PabstMirror +// [] execVM "\z\ace\addons\repair\dev\draw_showRepairInfo.sqf"; + +#include "\z\ace\addons\repair\script_component.hpp" + +addMissionEventHandler ["Draw3D", { + if !((cursorObject isKindOf "Car") || (cursorObject isKindOf "Tank") || (cursorObject isKindOf "Air")) exitWith {}; + private _config = configFile >> "CfgVehicles" >> (typeOf cursorObject); + + private _hitpointPositions = getArray (_config >> QGVAR(hitpointPositions)); + private _hitpointGroups = getArray (_config >> QGVAR(hitpointGroups)); + + (getAllHitPointsDamage cursorObject) params [["_hitPoints", []], ["_hitSelections", []]]; + ([cursorObject] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + + private _output = []; + + { + private _selection = _x; + private _hitpoint = _hitPoints select _forEachIndex; + + if ((_selection != "") && {_hitPoint != ""}) then { + if (((toLower _hitPoint) find "glass") != -1) exitWith {}; + + private _info = ""; + private _color = [1,0,0,1]; + if (_selection in _wheelHitSelections) then { + _info = _info + "[Wheel]"; + _color = [0,1,0,1]; + }; + if (!((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) then { + _info = _info + format ["[depends: %1]", getText (_config>> "HitPoints" >> _hitpoint >> "depends")]; + _color = [0,0,1,1] + }; + + private _position = cursorObject selectionPosition [_selection, "HitPoints"]; + { + _x params ["_hit", "_pos"]; + if (_hitpoint == _hit) exitWith { + _info = _info + format ["[hitPos: %1]", _pos]; + if (_pos isEqualType []) exitWith { + _position = _pos; + }; + if (_pos isEqualType "") exitWith { + _position = cursorObject selectionPosition [_pos, "HitPoints"]; + }; + }; + } forEach _hitpointPositions; + + private _parentHitpoint = ""; + { + private _xParent = _x select 0; + { + if (_hitpoint == _x) exitWith { + _info = _info + format ["[Parent: %1]", _xParent]; + _parentHitpoint = _xParent; + }; + } forEach (_x select 1); + } forEach _hitpointGroups; + + if (_parentHitpoint == "") then { + drawIcon3D ["", _color, (cursorObject modelToWorld _position), 0.5, 0.5, 0, format ["%1 [%2]", _hitpoint, _selection], 0.5, 0.025, "TahomaB"]; + }; + _output pushBack format ["%1: %2[%3] = %4", _forEachIndex, _hitPoint, _selection, cursorObject getHitIndex _forEachIndex]; + _output pushBack format ["- %1 -",_info]; + }; + } forEach _hitSelections; + hintSilent (_output joinString "\n"); +}]; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 8359850a3e..5761206b3e 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2, SilentSpike * Checks if the vehicles class already has the actions initialized, otherwise add all available repair options. Calleed from init EH. @@ -13,53 +14,51 @@ * * Public: No */ -#include "script_component.hpp" 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"]; - -_type = typeOf _vehicle; - -_initializedClasses = GETMVAR(GVAR(initializedClasses),[]); +private _type = typeOf _vehicle; +TRACE_2("addRepairActions", _vehicle,_type); // do nothing if the class is already initialized +private _initializedClasses = GETMVAR(GVAR(initializedClasses),[]); if (_type in _initializedClasses) exitWith {}; // get all hitpoints and selections -(getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; +(getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // Since 1.82 these are all lower case // 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 = ["a3\ui_f\data\igui\cfg\actions\repair_ca.paa", "#FFFFFF"]; + +// Custom position can be defined via config for associated hitpoint +private _hitpointPositions = getArray (configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointPositions)); +// Associated hitpoints can be grouped via config to produce a single repair action +private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointGroups)); { - _selection = _x; - _hitpoint = _hitPoints select _forEachIndex; - + private _selection = _x; + private _hitpoint = toLower (_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]; - _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 _name = format ["Remove_%1_%2", _forEachIndex, _hitpoint]; + private _text = localize LSTRING(RemoveWheel); + 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 @@ -70,57 +69,53 @@ _processedHitpoints = []; _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); } else { - //Skip glass hitpoints - if (((toLower _hitPoint) find "glass") != -1) exitWith { - TRACE_3("Skipping Glass",_hitpoint,_forEachIndex,_selection); - }; // Empty selections don't exist + if (_selection isEqualTo "") exitWith { TRACE_3("Skipping Empty Sel",_hitpoint,_forEachIndex,_selection); }; // Empty hitpoints don't contain enough information - if (_selection isEqualTo "") exitWith { TRACE_3("Selection Empty",_hitpoint,_forEachIndex,_selection); }; - if (_hitpoint isEqualTo "") exitWith { TRACE_3("Hitpoint Empty",_hitpoint,_forEachIndex,_selection); }; + if (_hitpoint isEqualTo "") exitWith { TRACE_3("Skipping Empty Hit",_hitpoint,_forEachIndex,_selection); }; + // Ignore glass hitpoints + if ((_hitPoint find "glass") != -1) exitWith { TRACE_3("Skipping Glass",_hitpoint,_forEachIndex,_selection); }; + // Ignore hitpoints starting with # (seems to be lights) + if ((_hitpoint select [0,1]) == "#") exitWith { TRACE_3("Skipping # hit",_hitpoint,_forEachIndex,_selection); }; + // Ignore ERA/Slat armor (vanilla uses hitera_/hitslat_, pre-1.82 RHS uses era_) + // ToDo: see how community utilizes new armor system, could also check getText (_hitpointConfig >> "simulation") + if (((_hitpoint select [0,7]) == "hitera_") || {(_hitpoint select [0,8]) == "hitslat_"} || {(_hitpoint select [0,4]) == "era_"}) exitWith { TRACE_3("Skipping ERA/SLAT",_hitpoint,_forEachIndex,_selection); }; + + //Depends hitpoints shouldn't be modified directly (will be normalized) - if (isText (configFile >> "CfgVehicles" >> _type >> "HitPoints" >> _hitpoint >> "depends")) exitWith { + // Biki: Clearing 'depends' in case of inheritance cannot be an empty string (rpt warnings), but rather a "0" value. + if (!((getText (configFile >> "CfgVehicles" >> _type >> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) exitWith { TRACE_3("Skip Depends",_hitpoint,_forEachIndex,_selection); }; - // Associated hitpoints can be grouped via config to produce a single repair action - _groupsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointGroups); - _childHitPoint = false; - if (isArray _groupsConfig) then { + private _childHitPoint = false; + { { - { - if (_hitpoint == _x) exitWith { - _childHitPoint = true; - }; - } forEach (_x select 1); - } forEach (getArray _groupsConfig); - }; + if (_hitpoint == _x) exitWith { + _childHitPoint = true; + }; + } forEach (_x select 1); + } forEach _hitpointGroups; // If the current selection is associated with a child hitpoint, then skip if (_childHitPoint) exitWith { TRACE_3("childHitpoint",_hitpoint,_forEachIndex,_selection); }; // Find the action position - _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; - - // Custom position can be defined via config for associated hitpoint - _positionsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointPositions); - if (isArray _positionsConfig) then { - { - _x params ["_hit", "_pos"]; - if (_hitpoint == _hit) exitWith { - if (_pos isEqualType []) exitWith { - _position = _pos; // Position in model space - }; - if (_pos isEqualType "") exitWith { - _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _pos]; - }; - ACE_LOGERROR_3("Invalid custom position %1 of hitpoint %2 in vehicle %3.",_position,_hitpoint,_type); + private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; + { + _x params ["_hit", "_pos"]; + if (_hitpoint == _hit) exitWith { + if (_pos isEqualType []) exitWith { + _position = _pos; // Position in model space }; - } forEach (getArray _positionsConfig); - }; + if (_pos isEqualType "") exitWith { + _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _pos]; + }; + ERROR_3("Invalid custom position %1 of hitpoint %2 in vehicle %3.",_position,_hitpoint,_type); + }; + } forEach _hitpointPositions; - // Prepair the repair action - _name = format ["Repair_%1_%2", _forEachIndex, _selection]; - _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; + // Prepare the repair action + 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"]; @@ -131,21 +126,17 @@ _processedHitpoints = []; if (_hitpoint in TRACK_HITPOINTS) then { // Tracks should always be unique if (_hitpoint in _processedHitpoints) exitWith {TRACE_3("Duplicate Track",_hitpoint,_forEachIndex,_selection);}; - if (_hitpoint == "HitLTrack") then { - _position = compile format ["private _return = _target selectionPosition ['%1', 'HitPoints']; _return set [1, 0]; _return", _selection]; - } else { - _position = compile format ["private _return = _target selectionPosition ['%1', 'HitPoints']; _return set [1, 0]; _return", _selection]; - }; + _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); @@ -154,13 +145,13 @@ _processedHitpoints = []; }; }; - _processedHitPoints pushBack _hitPoint; + _processedHitPoints pushBack _hitpoint; }; } 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_addSpareParts.sqf b/addons/repair/functions/fnc_addSpareParts.sqf index 63fe11fb6d..c83397ed4b 100644 --- a/addons/repair/functions/fnc_addSpareParts.sqf +++ b/addons/repair/functions/fnc_addSpareParts.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Adds spare parts to the vehicle. Before SettingsInitialized only collect for later execution. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle", ["_amount", 1], ["_part", ""], ["_force", false]]; TRACE_2("params",_vehicle,_amount); diff --git a/addons/repair/functions/fnc_canMiscRepair.sqf b/addons/repair/functions/fnc_canMiscRepair.sqf index 7ebfb5c5a8..b9fe842a19 100644 --- a/addons/repair/functions/fnc_canMiscRepair.sqf +++ b/addons/repair/functions/fnc_canMiscRepair.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Check if misc repair action can be done, called from callbackSuccess. @@ -16,20 +17,17 @@ * Public: No */ -#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,9 +35,10 @@ 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 _subHitpoint = _x; + private _subHitIndex = _allHitPoints findIf {_x == _subHitpoint}; if (_subHitIndex == -1) then { - ERROR("Hitpoint Not Found"); + ERROR_2("Invalid hitpoint %1 in hitpointGroups of %2",_subHitpoint,_target); } else { _hitpointGroup pushBack _subHitIndex; }; @@ -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_canRemove.sqf b/addons/repair/functions/fnc_canRemove.sqf index 9f06e8d148..77fc7b0eb4 100644 --- a/addons/repair/functions/fnc_canRemove.sqf +++ b/addons/repair/functions/fnc_canRemove.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit can remove given wheel/track of the vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", "_hitPoint"]; TRACE_3("params",_unit,_target,_hitPoint); diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index 6027a34fd5..93d5eef7a0 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if the repair action can be performed. @@ -16,19 +17,16 @@ * * Public: Yes */ -#include "script_component.hpp" 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_canRepairTrack.sqf b/addons/repair/functions/fnc_canRepairTrack.sqf index e1ff4a5628..8559ff1a9c 100644 --- a/addons/repair/functions/fnc_canRepairTrack.sqf +++ b/addons/repair/functions/fnc_canRepairTrack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit can replace given track of the vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", "_hitPoint"]; TRACE_3("params",_unit,_target,_hitPoint); diff --git a/addons/repair/functions/fnc_canReplaceTrack.sqf b/addons/repair/functions/fnc_canReplaceTrack.sqf index a272a0d176..d975c60efb 100644 --- a/addons/repair/functions/fnc_canReplaceTrack.sqf +++ b/addons/repair/functions/fnc_canReplaceTrack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit can replace given track of the vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", "_hitPoint"]; TRACE_3("params",_unit,_target,_hitPoint); diff --git a/addons/repair/functions/fnc_canReplaceWheel.sqf b/addons/repair/functions/fnc_canReplaceWheel.sqf index 0b7f7ad4e7..54e8e8cdf6 100644 --- a/addons/repair/functions/fnc_canReplaceWheel.sqf +++ b/addons/repair/functions/fnc_canReplaceWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Check if the unit can replace given wheel of the vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_target", "_hitPoint"]; TRACE_3("params",_unit,_target,_hitPoint); diff --git a/addons/repair/functions/fnc_doFullRepair.sqf b/addons/repair/functions/fnc_doFullRepair.sqf index ed67a69e99..fb248e6a2f 100644 --- a/addons/repair/functions/fnc_doFullRepair.sqf +++ b/addons/repair/functions/fnc_doFullRepair.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * Author: Glowbal - * Fully repairs vehicle + * Fully repairs vehicle. * * Arguments: * 0: Unit that does the repairing (not used) @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["", "_vehicle"]; TRACE_1("params",_vehicle); diff --git a/addons/repair/functions/fnc_doRemoveTrack.sqf b/addons/repair/functions/fnc_doRemoveTrack.sqf index ca6ac58ffd..d15993752f 100644 --- a/addons/repair/functions/fnc_doRemoveTrack.sqf +++ b/addons/repair/functions/fnc_doRemoveTrack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_vehicle", "_hitPoint"]; TRACE_3("params",_unit,_vehicle,_hitPoint); diff --git a/addons/repair/functions/fnc_doRemoveWheel.sqf b/addons/repair/functions/fnc_doRemoveWheel.sqf index dafe603a18..127859a5b9 100644 --- a/addons/repair/functions/fnc_doRemoveWheel.sqf +++ b/addons/repair/functions/fnc_doRemoveWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_vehicle", "_hitPoint"]; TRACE_3("params",_unit,_vehicle,_hitPoint); diff --git a/addons/repair/functions/fnc_doRepair.sqf b/addons/repair/functions/fnc_doRepair.sqf index ede096a1fb..c17858d8b3 100644 --- a/addons/repair/functions/fnc_doRepair.sqf +++ b/addons/repair/functions/fnc_doRepair.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_vehicle", "_hitPointIndex"]; TRACE_3("params",_unit,_vehicle,_hitPointIndex); @@ -47,9 +47,10 @@ if (isArray _hitpointGroupConfig) then { // Exit using found hitpoint group if this hitpoint is leader of any if (_masterHitpoint == _hitPointClassname) exitWith { { - private _subHitIndex = _allHitPoints find _x; //convert hitpoint classname to index + private _subHitpoint = _x; + private _subHitIndex = _allHitPoints findIf {_x == _subHitpoint}; //convert hitpoint classname to index if (_subHitIndex == -1) then { - ACE_LOGERROR_2("Invalid hitpoint %1 in hitpointGroups of %2",_x,_vehicle); + ERROR_2("Invalid hitpoint %1 in hitpointGroups of %2",_subHitpoint,_vehicle); } else { private _subPointCurDamage = _vehicle getHitIndex _hitPointIndex; private _subPointNewDamage = (_subPointCurDamage - 0.5) max _postRepairDamageMin; diff --git a/addons/repair/functions/fnc_doRepairTrack.sqf b/addons/repair/functions/fnc_doRepairTrack.sqf index 34f29506a3..71d06b60f2 100644 --- a/addons/repair/functions/fnc_doRepairTrack.sqf +++ b/addons/repair/functions/fnc_doRepairTrack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Called by repair action / progress bar. Raise events to set the new hitpoint damage. @@ -19,14 +20,13 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_vehicle", "_hitPoint", "", "", "", "_claimedObjects"]; TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ACE_LOGERROR_1("Bad Track", _claimedObjects); + ERROR_1("Bad Track", _claimedObjects); }; // can't use a destroyed track diff --git a/addons/repair/functions/fnc_doReplaceTrack.sqf b/addons/repair/functions/fnc_doReplaceTrack.sqf index b0b71e5b61..60dd486f44 100644 --- a/addons/repair/functions/fnc_doReplaceTrack.sqf +++ b/addons/repair/functions/fnc_doReplaceTrack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Replaces a track. @@ -19,14 +20,13 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_vehicle", "_hitPoint", "", "", "", "_claimedObjects"]; TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ACE_LOGERROR_1("Bad Track", _claimedObjects); + ERROR_1("Bad Track", _claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_doReplaceWheel.sqf b/addons/repair/functions/fnc_doReplaceWheel.sqf index 24b995a45f..e42c7cabf2 100644 --- a/addons/repair/functions/fnc_doReplaceWheel.sqf +++ b/addons/repair/functions/fnc_doReplaceWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Repairs a vehicle's wheel with a ACE_wheel spare part object. @@ -19,14 +20,13 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_vehicle", "_hitPoint", "", "", "", "_claimedObjects"]; TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_wheel", objNull]]; if ((isNull _wheel) || {!([_unit, _wheel, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ACE_LOGWARNING_1("Bad Claimed Wheel", _claimedObjects); + WARNING_1("Bad Claimed Wheel", _claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_getClaimObjects.sqf b/addons/repair/functions/fnc_getClaimObjects.sqf index c2311a467f..a654952417 100644 --- a/addons/repair/functions/fnc_getClaimObjects.sqf +++ b/addons/repair/functions/fnc_getClaimObjects.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * 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 @@ -15,7 +16,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_maxRange", "_objectsToClaim"]; TRACE_3("params",_unit,_maxRange,_objectsToClaim); diff --git a/addons/repair/functions/fnc_getHitPointString.sqf b/addons/repair/functions/fnc_getHitPointString.sqf index fd108e4b1f..8394b4f5ac 100644 --- a/addons/repair/functions/fnc_getHitPointString.sqf +++ b/addons/repair/functions/fnc_getHitPointString.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Finds the localized string of the given hitpoint name or uses default text if none found. @@ -9,24 +10,21 @@ * 3: Track Added Hitpoints (default: false) * * Return Value: - * 0: Text - * 1: Added Hitpoint (default: []) + * 0: Text + * 1: Added Hitpoint (default: []) * * Example: * ["HitFuel", "Repairing %1 ...", "Repairing HitFuel"] call ace_repair_fnc_getHitPointString * * Public: No */ -#include "script_component.hpp" 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); @@ -84,7 +82,7 @@ for "_i" from 0 to (count _hitPoint) do { // Don't display part name if no string is found in stringtable if (_text == LSTRING(Hit)) then { - if (_hitPoint != "") then { ACE_LOGWARNING_1("Hitpoint [%1] - could not be localized", _hitPoint); }; + if (_hitPoint != "") then { LOG_1("Hitpoint [%1] - could not be localized", _hitPoint); }; _text = _textDefault; }; diff --git a/addons/repair/functions/fnc_getPostRepairDamage.sqf b/addons/repair/functions/fnc_getPostRepairDamage.sqf index 9388f4474d..d8ed7d3804 100644 --- a/addons/repair/functions/fnc_getPostRepairDamage.sqf +++ b/addons/repair/functions/fnc_getPostRepairDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns the damage threshold based on settings and unit type. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); @@ -22,7 +22,7 @@ TRACE_1("params",_unit); if (([_unit] call FUNC(isInRepairFacility) || {[_unit] call FUNC(isNearRepairVehicle)})) exitWith {0}; private _class = _unit getVariable ["ACE_IsEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer")]; -//If specialist or more qualified than min, then use engineer threshold: +//If advanced or more qualified than min, then use engineer threshold: if ((_class isEqualTo 2) || {[_unit, GVAR(engineerSetting_Repair) + 1] call FUNC(isEngineer)}) exitWith { (GVAR(repairDamageThreshold_Engineer) min GVAR(repairDamageThreshold)) }; diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf index 93f4883063..fe072859b2 100644 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Returns the wheel hitpoints and their selections. @@ -14,13 +15,10 @@ * * Public: No */ -#include "script_component.hpp" 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..9b54647c8d 100644 --- a/addons/repair/functions/fnc_hasItems.sqf +++ b/addons/repair/functions/fnc_hasItems.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if the engineer has all items. @@ -14,14 +15,11 @@ * * Public: Yes */ -#include "script_component.hpp" 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 d07c12af64..6a80b1012e 100644 --- a/addons/repair/functions/fnc_isEngineer.sqf +++ b/addons/repair/functions/fnc_isEngineer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, KoffeinFlummi, commy2 * Check if a unit is any engineer class. @@ -14,16 +15,14 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", ["_engineerN", 1]]; -TRACE_2("params",_unit,_engineerN); -private ["_class"]; -_class = _unit getVariable ["ACE_IsEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "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. if (_class isEqualType false) then {_class = [0, 1] select _class}; +TRACE_3("isEngineer",_unit,_engineerN,_class); _class >= _engineerN; diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf index b72d8a5985..10ef95ed66 100644 --- a/addons/repair/functions/fnc_isInRepairFacility.sqf +++ b/addons/repair/functions/fnc_isInRepairFacility.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Checks if a unit is in a repair facility. @@ -13,30 +14,29 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_object"]; TRACE_1("params",_object); -private ["_position","_objects","_isInBuilding","_repairFacility"]; +private _position = getPosASL _object; +private _isInBuilding = false; -_position = getPosASL _object; -_isInBuilding = false; -_repairFacility = []; - -_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 { +private _checkObject = { + if ( + _x getVariable ["ACE_isRepairFacility", getNumber (configFile >> "CfgVehicles" >> typeOf _x >> QGVAR(canRepair))] > 0 + && {!(_x isKindOf "AllVehicles")} // check if it's not repair vehicle + && {alive _x} + ) exitWith { _isInBuilding = true; }; -} forEach _objects; - -if (!_isInBuilding) then { - _objects = position _object nearObjects 7.5; - { - if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitWith { - _isInBuilding = true; - }; - } forEach _objects; }; -_isInBuilding; + +private _objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position select 2)], _object modelToWorldVisual [0, 0, (_position select 2) +10], _object]); +_checkObject forEach _objects; + +if (_isInBuilding) exitWith {true}; + +_objects = _object nearObjects 7.5; +_checkObject forEach _objects; + +_isInBuilding diff --git a/addons/repair/functions/fnc_isNearRepairVehicle.sqf b/addons/repair/functions/fnc_isNearRepairVehicle.sqf index 463e281faa..1243c0f95b 100644 --- a/addons/repair/functions/fnc_isNearRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isNearRepairVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi * Checks if a unit is near an engineering vehicle. @@ -13,18 +14,15 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; TRACE_1("params",_unit); -private ["_nearObjects", "_return"]; +private _nearObjects = nearestObjects [_unit, ["Air", "LandVehicle", "Slingload_base_F"], 20]; -_nearObjects = nearestObjects [_unit, ["Air","LandVehicle"], 20]; - -_return = false; +private _return = false; { - if ([_x] call FUNC(isRepairVehicle)) exitWith {_return = true;}; + if (alive _x && {[_x] call FUNC(isRepairVehicle)}) exitWith {_return = true;}; } forEach _nearObjects; _return; diff --git a/addons/repair/functions/fnc_isRepairVehicle.sqf b/addons/repair/functions/fnc_isRepairVehicle.sqf index 2c0b5a1e21..6e7ddcab27 100644 --- a/addons/repair/functions/fnc_isRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isRepairVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Check if vehicle is a engineering vehicle. @@ -5,7 +6,7 @@ * Arguments: * 0: Vehicle * - * ReturnValue: + * Return Value: * Is engineering vehicle * * Example: @@ -13,11 +14,12 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_vehicle"]; TRACE_1("params",_vehicle); if (_vehicle isKindOf "CAManBase") exitWith {false}; -((_vehicle getVariable ["ACE_isRepairVehicle", getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(canRepair))]) > 0); +// Value can be integer or boolean +private _value = _vehicle getVariable ["ACE_isRepairVehicle", getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(canRepair))]; +_value in [1, true] // return diff --git a/addons/repair/functions/fnc_modifyInteraction.sqf b/addons/repair/functions/fnc_modifyInteraction.sqf new file mode 100644 index 0000000000..235afd9223 --- /dev/null +++ b/addons/repair/functions/fnc_modifyInteraction.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror, mharis001 + * Modifies the base interaction point for repair items to show its current damage. + * + * Arguments: + * 0: Target + * 1: Player (not used) + * 2: Args (not used) + * 3: Action Data + * + * Return Value: + * None + * + * Example: + * [cursorObject, ACE_player, [], []] call ace_repair_fnc_modifyInteraction + * + * Public: No + */ + +params ["_target", "", "", "_actionData"]; + +// Convert damage to number (round up to show even slight damage) +private _color = ceil linearConversion [0, 1, damage _target, 0, 8, true]; +TRACE_2("Modifying icon color",_target,_color); +(_actionData select 2) set [1, DAMAGE_COLOR_SCALE select _color]; + diff --git a/addons/repair/functions/fnc_modifySelectionInteraction.sqf b/addons/repair/functions/fnc_modifySelectionInteraction.sqf new file mode 100644 index 0000000000..66d7ae5e4b --- /dev/null +++ b/addons/repair/functions/fnc_modifySelectionInteraction.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: 654wak654, mharis001 + * Modifies interaction icon color of vehicle selection to show its current damage. + * + * Arguments: + * 0: Target + * 1: Player (not used) + * 2: Args + * 3: Action Data + * + * Return Value: + * None + * + * Example: + * [cursorObject, ACE_player, [], []] call ace_repair_fnc_modifySelectionInteraction + * + * Public: No + */ + +params ["_target", "", "_args", "_actionData"]; + +// Convert damage to number (round up to show even slight damage) +private _color = ceil linearConversion [0, 1, _target getHitPointDamage (_args select 0), 0, 8, true]; +TRACE_2("Modifying icon color",_target,_color); +(_actionData select 2) set [1, DAMAGE_COLOR_SCALE select _color]; diff --git a/addons/repair/functions/fnc_moduleAddSpareParts.sqf b/addons/repair/functions/fnc_moduleAddSpareParts.sqf index bc2502c0f4..a70f821ffc 100644 --- a/addons/repair/functions/fnc_moduleAddSpareParts.sqf +++ b/addons/repair/functions/fnc_moduleAddSpareParts.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Adds spare parts to a vehicle. @@ -15,15 +16,13 @@ * * Public: No */ -#include "script_component.hpp" 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..1949da087a 100644 --- a/addons/repair/functions/fnc_moduleAssignEngineer.sqf +++ b/addons/repair/functions/fnc_moduleAssignEngineer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Assign an engineer role to a unit. @@ -15,14 +16,12 @@ * * Public: No */ -#include "script_component.hpp" 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..c071058ad6 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Assign a repair facility. @@ -15,14 +16,12 @@ * * Public: No */ -#include "script_component.hpp" 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..4f5c601cce 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Assign a repair vehicle. @@ -15,14 +16,12 @@ * * Public: No */ -#include "script_component.hpp" 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 770af07449..831b9a2619 100644 --- a/addons/repair/functions/fnc_moduleRepairSettings.sqf +++ b/addons/repair/functions/fnc_moduleRepairSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Adjusts repair damage settings. @@ -13,12 +14,9 @@ * * Public: No */ -#include "script_component.hpp" 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); @@ -33,4 +31,4 @@ if (!isServer) exitWith {}; [_logic, QGVAR(wheelRepairRequiredItems), "wheelRepairRequiredItems"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO("Repair Module Initialized."); +INFO("Repair Module Initialized."); diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf index a73dfcfe0d..fb07147a6a 100644 --- a/addons/repair/functions/fnc_normalizeHitPoints.sqf +++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Used to normalize dependant hitpoints. May overwrite some global variables that are named like hitpoints or "Total" though... @@ -13,13 +14,12 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; TRACE_2("params",_vehicle, typeOf _vehicle); // Can't execute all commands if the vehicle isn't local, exit if that's so -if !(local _vehicle) exitWith {ACE_LOGERROR_1("Vehicle Not Local %1", _vehicle);}; +if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1", _vehicle);}; (getAllHitPointsDamage _vehicle) params [["_allHitPoints", []]]; @@ -33,7 +33,7 @@ private _dependentHitPointScripts = []; { if ((_x != "") && {isClass (_config >> _x)} && {!(_x in _realHitPoints)}) then { _realHitPoints pushBack _x; - if (isText (_config >> _x >> "depends")) then { + if (!((getText (_config >> _x >> "depends")) in ["", "0"])) then { _dependentHitPoints pushBack _x; _dependentHitPointScripts pushBack compile getText (_config >> _x >> "depends"); }; diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index d4f5412e6f..9363f53671 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, KoffeinFlummi * Starts the repair process. @@ -16,17 +17,14 @@ * * Public: Yes */ -#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,35 +167,48 @@ 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); }; -//Get repair time -_repairTime = if (isNumber (_config >> "repairingTime")) then { - getNumber (_config >> "repairingTime"); -} else { - if (isText (_config >> "repairingTime")) exitWith { - _repairTimeConfig = getText(_config >> "repairingTime"); - if (isNil _repairTimeConfig) then { - _repairTimeConfig = compile _repairTimeConfig; - } else { - _repairTimeConfig = missionNamespace getVariable _repairTimeConfig; +private _soundPosition = AGLToASL (_caller modelToWorldVisual (_caller selectionPosition "RightHand")); +["Acts_carFixingWheel", _soundPosition, nil, 50] call EFUNC(common,playConfigSound3D); + +// Get repair time +private _repairTime = [ + configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(repairTimes) >> configName _config, + "number", + -1 +] call CBA_fnc_getConfigEntry; + +if (_repairTime < 0) then { + _repairTime = if (isNumber (_config >> "repairingTime")) then { + getNumber (_config >> "repairingTime"); + } else { + if (isText (_config >> "repairingTime")) exitWith { + private _repairTimeConfig = getText (_config >> "repairingTime"); + if (isNil _repairTimeConfig) then { + _repairTimeConfig = compile _repairTimeConfig; + } else { + _repairTimeConfig = missionNamespace getVariable _repairTimeConfig; + }; + if (_repairTimeConfig isEqualType 0) exitWith { + _repairTimeConfig; + }; + [_caller, _target, _hitPoint, _className] call _repairTimeConfig; }; - if (_repairTimeConfig isEqualType 0) exitWith { - _repairTimeConfig; - }; - [_caller, _target, _hitPoint, _className] call _repairTimeConfig; + 0; }; - 0; }; // Find localized string -_hitPointClassname = if (_hitPoint isEqualType "") then { +private _hitPointClassname = if (_hitPoint isEqualType "") then { _hitPoint } else { ((getAllHitPointsDamage _target) select 0) select _hitPoint @@ -216,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 8616dd4808..83cce85e0d 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Callback when repair fails. @@ -20,27 +21,24 @@ * * Public: No */ -#include "script_component.hpp" 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 { - _caller action ["SwitchWeapon", _caller, _caller, 99]; + _caller action ["SwitchWeapon", _caller, _caller, 299]; }; { @@ -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 c18116f862..a86be84244 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Glowbal * Callback when repair completes. @@ -20,27 +21,24 @@ * * Public: No */ -#include "script_component.hpp" 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 { - _caller action ["SwitchWeapon", _caller, _caller, 99]; + _caller action ["SwitchWeapon", _caller, _caller, 299]; }; //Unclaim repair objects: @@ -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_setDamage.sqf b/addons/repair/functions/fnc_setDamage.sqf index 78c7cae709..fbae505fae 100644 --- a/addons/repair/functions/fnc_setDamage.sqf +++ b/addons/repair/functions/fnc_setDamage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Sets the structural damage of a vehicle without altering the hitPoints, requires local vehicle. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_damage"]; TRACE_2("params",_vehicle,_damage); diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index 01a29eb377..f0313315e9 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -1,12 +1,14 @@ +#include "script_component.hpp" /* * 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 @@ -16,42 +18,33 @@ * * Public: No */ -#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 {ACE_LOGERROR_1("Vehicle Not Local %1", _vehicle);}; - -//Check for bad typeName (changed from orignal v3.3 that took string) -if (_hitPointIndex isEqualType "") then { - ACE_DEPRECATED("repair-setHitPointDamage (hit point name ","3.5.0","hit index "); - _hitPointIndex = _allHitPoints find _hitPointIndex; -}; +if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1", _vehicle);}; // get all hitpoints and selections and damages (getAllHitPointsDamage _vehicle) params [["_allHitPoints", []], ["_allHitPointsSelections", []], ["_allHitPointDamages", []]]; // exit if the hitpoint is not valid -if ((_hitPointIndex < 0) || {_hitPointIndex >= (count _allHitPoints)}) exitWith {ACE_LOGERROR_2("NOT A VALID HITPOINT: %1-%2", _hitPointIndex,_vehicle);}; +if ((_hitPointIndex < 0) || {_hitPointIndex >= (count _allHitPoints)}) exitWith {ERROR_2("NOT A VALID HITPOINT: %1-%2", _hitPointIndex,_vehicle);}; // 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; - if ((((toLower _x) find "glass") == -1) && {!isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")}) then { + if ((((toLower _x) find "glass") == -1) && {(getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")) in ["", "0"]}) then { _hitPointDamageSumOld = _hitPointDamageSumOld + (_allHitPointDamages select _forEachIndex); if (_forEachIndex == _hitPointIndex) then { _hitPointDamageRepaired = (_allHitPointDamages select _forEachIndex) - _hitPointDamage; @@ -61,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); @@ -69,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_spawnObject.sqf b/addons/repair/functions/fnc_spawnObject.sqf index e927a19651..9dce6a7e01 100644 --- a/addons/repair/functions/fnc_spawnObject.sqf +++ b/addons/repair/functions/fnc_spawnObject.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Spawns an object of specified string, at specified position with specified damage taken. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_item", "_position", ["_damage", 0]]; TRACE_3("params",_item,_position,_damage); diff --git a/addons/repair/functions/fnc_useItem.sqf b/addons/repair/functions/fnc_useItem.sqf index 02daeed33e..760be7a39b 100644 --- a/addons/repair/functions/fnc_useItem.sqf +++ b/addons/repair/functions/fnc_useItem.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Use Equipment if any is available. @@ -6,7 +7,7 @@ * 0: Unit * 1: Item classname * - * ReturnValue: + * Return Value: * [Had Item to Use , Unit ] * * Example: @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", "_item"]; TRACE_2("params",_unit,_item); diff --git a/addons/repair/functions/fnc_useItems.sqf b/addons/repair/functions/fnc_useItems.sqf index 14dcb6223c..b6da87aecc 100644 --- a/addons/repair/functions/fnc_useItems.sqf +++ b/addons/repair/functions/fnc_useItems.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Use Equipment items if any is available. @@ -6,7 +7,7 @@ * 0: Unit * 1: Item classnames * - * ReturnValue: + * Return Value: * [Had Item to Use , Array of units that used the items ] * * Example: @@ -14,26 +15,23 @@ * * Public: Yes */ -#include "script_component.hpp" 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/initSettings.sqf b/addons/repair/initSettings.sqf new file mode 100644 index 0000000000..c392711218 --- /dev/null +++ b/addons/repair/initSettings.sqf @@ -0,0 +1,100 @@ +// CBA Settings [ADDON: ace_repair]: + +[ + QGVAR(displayTextOnRepair), "CHECKBOX", + [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + true, // default value + false, // isGlobal + {[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(engineerSetting_repair), "LIST", + [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(engineerSetting_wheel), "LIST", + [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(repairDamageThreshold), "SLIDER", + [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [0,1,0.6,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(repairDamageThreshold_engineer), "SLIDER", + [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [0,1,0.4,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(consumeItem_toolKit), "LIST", // fnc_repair expects number + [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(fullRepairLocation), "LIST", + [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(engineerSetting_fullRepair), "LIST", + [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(addSpareParts), "CHECKBOX", + [LSTRING(addSpareParts_name), LSTRING(addSpareParts_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + true, // default value + true, // isGlobal + {[QGVAR(addSpareParts), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(wheelRepairRequiredItems), "LIST", + [LSTRING(wheelRepairRequiredItems_name), LSTRING(wheelRepairRequiredItems_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + [[0,1],["None", "ToolKit"],0], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(wheelRepairRequiredItems), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(autoShutOffEngineWhenStartingRepair), "CHECKBOX", + [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], + [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + false, // default value + true, // isGlobal + {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; diff --git a/addons/repair/script_component.hpp b/addons/repair/script_component.hpp index c2bad9328d..7ec3be3233 100644 --- a/addons/repair/script_component.hpp +++ b/addons/repair/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_REPAIR @@ -17,4 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define TRACK_HITPOINTS ["HitLTrack", "HitRTrack"] +#define TRACK_HITPOINTS ["hitltrack", "hitrtrack"] + +#define DAMAGE_COLOR_SCALE ["#FFFFFF", "#FFFF7E", "#FFEC4D", "#FFD52C", "#FCB121", "#FF9916", "#FF7D16", "#FF4400", "#FF0000"] diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index a5fabc0965..4d4f14cb49 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Cingolo di scorta Pót lánctalp Запасная гусеница + 予備履帯 + 예비 궤도 + 备用履带 + 備用履帶 Spare Wheel @@ -24,6 +28,10 @@ Ruota di scorta Pótkerék Запасное колесо + 予備タイヤ + 예비 바퀴 + 备用轮胎 + 備用輪胎 Change Wheel @@ -36,6 +44,10 @@ Kerék cseréje Поменять колесо Vyměnit kolo + タイヤを変える + 바퀴 교체 + 更换轮胎 + 更換輪胎 Replacing Wheel... @@ -45,8 +57,12 @@ Замена колеса... Měním kolo... Cambiando rueda... - Sto sostituendo la ruota... + Sostituendo la ruota... Remplacement de la roue... + タイヤを交換しています・・・ + 바퀴 교체중... + 更换轮胎中... + 更換輪胎中... Wheel replaced @@ -58,6 +74,10 @@ Rueda cambiada Ruota sostituita Roue remplacée + タイヤを交換しました + 바퀴 교체됨 + 轮胎更换完毕 + 輪胎更換完畢 Remove Wheel @@ -70,6 +90,10 @@ Rimuovi la ruota Kerék leszerelése Снять колесо + タイヤを外す + 바퀴 제거 + 卸下轮胎 + 卸下輪胎 Removing Wheel... @@ -79,8 +103,12 @@ Снятие колеса... Odstraňuji kolo... Quitando rueda... - Sto rimuovendo la ruota... + Rimuovendo la ruota... Démontage de la roue... + タイヤを外しています・・・ + 바퀴 제거중... + 卸下轮胎中... + 卸下輪胎中... Wheel removed @@ -92,6 +120,10 @@ Rueda quitada Ruota rimossa Roue démontée + タイヤを外しました + 바퀴 제거됨 + 轮胎卸下完毕 + 輪胎卸下完畢 Change Track @@ -103,6 +135,10 @@ Cambiar oruga Cambia cingolo Changer la chenille + 履帯を変える + 궤도 교체 + 更换履带 + 更換履帶 Replacing Track... @@ -112,8 +148,12 @@ Замена гусеницы... Měním pás... Cambiando oruga... - Sto sostituendo il cingolo... + Sostituendo il cingolo... Remplacement de la chenille... + 履帯を交換しています・・・ + 궤도 교체중... + 更换履带中... + 更換履帶中... Track replaced @@ -125,6 +165,10 @@ Oruga cambiada Cingolo sostituito Chenille remplacée + 履帯を交換しました + 궤도 교체됨 + 履带更换完毕 + 履帶更換完畢 Remove Track @@ -136,6 +180,10 @@ Quitar oruga Rimuovi cingolo Enlever la chenille + 履帯を外す + 궤도 제거 + 卸下履带 + 卸下履帶 Removing Track... @@ -145,8 +193,12 @@ Снятие гусеницы... Odstraňuji pás... Quitando oruga... - Sto rimuovendo il cingolo... + Rimuovendo il cingolo... Enlèvement de la chenille... + 履帯を外しています・・・ + 궤도 제거중... + 卸下履带中... + 卸下履帶中... Track removed @@ -158,6 +210,10 @@ Oruga quitada Cingolo rimosso Chenille enlevée + 履帯を外しました + 궤도 제거됨 + 履带卸下完毕 + 履帶卸下完畢 Full Repair @@ -169,6 +225,10 @@ Reparación completa Riparazione completa Réparations complètes + 完全に修理 + 완전수리 + 完整维修 + 完整維修 Repairing Vehicle... @@ -178,8 +238,12 @@ Ремонт транспорта... Opravuji vozidlo... Reparando vehículo... - Sto riparando il veicolo... + Riparando il veicolo... Réparation du véhicule... + 車両を修理しています・・・ + 차량 수리중... + 维修载具中... + 維修載具中... Full Repair Locations @@ -191,6 +255,10 @@ Lugares de reparación completa Luoghi Riparazione Completa Lieu de réparation complète + 完全修理できる場所 + 완전수리 구역 + 完整维修地点 + 完整維修地點 At what locations can a vehicle be fully repaired? @@ -202,6 +270,10 @@ 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 ? + どのような場所で車両の完全な修理を出来るようにしますか? + 어느 구역에서 차량을 완전히 수리할 수 있게 합니까? + 什么位置可以完整维修载具? + 什麼位置可以完整維修載具? Allow Full Repair @@ -213,6 +285,10 @@ Permitir reparación completa Consenti Riparazione Completa Autoriser les réparations complètes. + 完全修理を許可 + 완전 수리 활성화 + 允许完整维修 + 允許完整維修 Who can perform a full repair on a vehicle? @@ -224,6 +300,10 @@ 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 ? + 誰が車両の完全な修理を出来るようにしますか? + 누가 완전 수리를 할 수 있습니까? + 谁可以完整维修载具? + 誰可以完整維修載具? Add Spare Parts @@ -235,6 +315,10 @@ Přidat náhradní díly Aggiungi Parti di Ricambio Ajouter des pièces de rechange + 予備部品を追加 + 예비 부품 더하기 + 添加备件 + 添加備件 Add spare parts to vehicles (requires Cargo component)? @@ -246,6 +330,10 @@ 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) + 車両へ予備部品を追加しますか(カーゴ コンポーネントが必要)? + 차량에 예비 부품을 더합니까?(짐칸 요소 필요) + 添加载具备件 (需相关货物组件)? + 添加載具備件 (需相關貨物組件)? Repair @@ -258,6 +346,10 @@ Ripara Szerelés Ремонт + 修理 + 수리 + 维修 + 維修 Display text on repair @@ -269,6 +361,10 @@ Mostrar texto en la reparación Mostra testo mentre ripari Afficher du texte pendant la réparation + 修理時に文章で通知する + 수리시 화면에 글자 표시 + 显示维修文本 + 顯示維修文本 Display a notification whenever you repair a vehicle @@ -280,6 +376,10 @@ Zobrazit oznámení kdykoliv opravíš vozidlo Mostra una notifica quando stai riparando un veicolo Afficher une notification lorsque l'on répare un véhicule + 車両の修理を始めると、画面に通知を出します + 수리시 화면에 글자로 알림이 뜹니다 + 每当维修载具时显示通知 + 每當維修載具時顯示通知 Repairing... @@ -289,9 +389,13 @@ Naprawianie... Opravuji... Reparando... - Sto riparando... + Riparando... javítása... Ремонтируем... + 修理しています・・・ + 수리중... + 维修中... + 維修中... Repairing %1... @@ -301,9 +405,13 @@ Naprawianie %1... Opravuji %1... Reparando %1... - Sto riparando %1... + Riparando %1... %1 javítása... Ремонтируем %1... + %1 を修理しています・・・ + %1 수리중... + 维修%1中... + 維修%1中... Repaired %1 @@ -316,6 +424,10 @@ %1 Riparata/o %1 megjavítva %1 отремонтирован + %1 を修理しました + %1 수리됨 + 已维修%1 + 已維修%1 Fully repaired part @@ -327,6 +439,10 @@ Parte totalmente reparado Parte riparata completamente Pièce entièrement réparée + 完全に修理された部品 + 부분 완벽히 수리됨 + 完整维修部分 + 完整維修部分 Partially repaired %1 @@ -338,6 +454,10 @@ %1 - částečně opraveno %1 parzialmente riparato %1 pratiquement réparée + %1 を部分的に修理しました + %1 부분적으로 수리됨 + %1已完成部分维修 + %1已完成部分維修 Fully repaired %1 @@ -349,6 +469,10 @@ Totalmente reparada %1 %1 completamente riparato %1 entièrement réparée + %1 を完全に修理しました + %1 완전히 수리됨 + %1已完整维修 + %1已完整維修 Partially repaired %1 @@ -360,6 +484,10 @@ %1 - částečně opraveno %1 parzialmente riparato %1 pratiquement réparée + %1 を部分的に修理しました + %1 부분적으로 수리됨 + %1已完成部分维修 + %1已完成部分維修 Body @@ -372,6 +500,10 @@ Carrozzeria Test Кузов + 車体 + 몸체 + 车身 + 車身 Hull @@ -384,6 +516,10 @@ Scafo Test Корпус + 機体 + 선체 + 车壳 + 車殼 Engine @@ -396,6 +532,10 @@ Motore Motor Двигатель + エンジン + 엔진 + 引擎 + 引擎 Left Horizontal Stabilizer @@ -407,6 +547,10 @@ Stabilizzatore Orizzontale Sinistro Stabilisateur horizontal gauche Linkes Höhenleitwerk + 左側の水平安定機 + 왼쪽 수평안정판 + 左侧悬挂稳定 + 左側懸掛穩定 Right Horizontal Stabilizer @@ -418,6 +562,10 @@ Stabilizzatore Orizzontale Destro Stabilisateur horizontal droit Rechtes Höhenleitwerk + 右側の水平安定機 + 오른쪽 수평안정판 + 右侧悬挂稳定 + 右側懸掛穩定 Vertical Stabilizer @@ -429,6 +577,10 @@ Stabilizzatore Verticale Stabilisateur vertical Seitenleitwerk + 車両スタビライザ + 수직 안정판 + 垂直稳定 + 垂直穩定 Fuel Tank @@ -441,6 +593,10 @@ Serbatoio Üzemanyagtank Топливный бак + 燃料タンク + 연료 탱크 + 油箱 + 油箱 Transmission @@ -452,6 +608,10 @@ Transmisión Trasmissione Instruments + 変速機 + 변속기 + 变速箱 + 變速箱 Gear @@ -463,6 +623,10 @@ Podvozek Motore Trains d'attérissage + ギア + 기어 + 齿轮 + 齒輪 Starter @@ -474,6 +638,10 @@ Motor de arranque Motore d'avviamento Démarreur + スターター + 점화기 + 发动机 + 發動機 Tail @@ -485,6 +653,10 @@ Cauda Coda Queue + 尾翼 + 꼬리 + 尾翼 + 尾翼 Pitot Tube @@ -496,6 +668,10 @@ Tubo del pitot Tubo di Pitot Sonde pitot + ピトー管 + 동압관 + 空速管 + 空速管 Static Port @@ -507,6 +683,10 @@ Statický port Porta Statica Port statique + スタティック ポート + 정압공 + 静态端口 + 靜態端口 Ammo @@ -518,6 +698,10 @@ Munición Munizioni Munitions + 弾薬 + 탄약 + 弹药 + 彈藥 Turret @@ -530,6 +714,10 @@ Torretta Lövegtorony Башню + 砲塔 + 포탑 + 炮塔 + 砲塔 Gun @@ -542,6 +730,42 @@ Cannone Ágyú Пушку + + + + + + + Commander Turret + Kommandant Turm + Comandante Torreta + Commander Tourelle + Dowódca Wieżyczka + Velitel Věž + Comandante Torre + Comandante Torretta + Parancsnok Lövegtorony + Башня командира + 車長の砲塔 + 지휘관 포탑 + 指挥官 炮塔 + 指揮官 砲塔 + + + Commander Gun + Kommandant Kanone + Comandante Cañón + Commander Canon + Dowódca Działo + Velitel Kanón + Comandante Canhão + Comandante Cannone + Parancsnok Ágyú + Пушка командира + 車長の砲 + 지휘관 포 + 指挥官 枪 + 指揮官 槍 Missiles @@ -553,6 +777,10 @@ Misiles Missili Missiles + ミサイル + 미사일 + 导弹 + 導彈 Left Track @@ -565,6 +793,10 @@ Cingolo sinistro Bal lánctalp Левую гусеницу + 左の履帯 + 왼쪽 궤도 + 左履带 + 左履帶 Right Track @@ -577,6 +809,10 @@ Cingolo destro Jobb lánctalp Правую гусеницу + 右の履帯 + 오른쪽 궤도 + 右履带 + 右履帶 Left Front Wheel @@ -589,6 +825,10 @@ Ruota frontale sinistra Bal első kerék Левое переднее колесо + 左の前輪 + 왼쪽 앞바퀴 + 左前轮 + 左前輪 Right Front Wheel @@ -601,6 +841,10 @@ Ruota frontale destra Jobb első kerék Правое переднее колесо + 右の前輪 + 오른쪽 앞바퀴 + 右前轮 + 右前輪 Second Left Front Wheel @@ -613,6 +857,10 @@ Seconda ruota frontale sinistra Második bal első kerék Второе переднее левое колесо + 左の 2 つめの前輪 + 왼쪽 두번째 바퀴 + 第二左前轮 + 第二左前輪 Second Right Front Wheel @@ -625,6 +873,10 @@ Seconda ruota frontale destra Második jobb hátsó kerék Второе правое переднее колесо + 右の 2 つめの前輪 + 오른쪽 두번째 바퀴 + 第二右前轮 + 第二右前輪 Left Middle Wheel @@ -637,6 +889,10 @@ Ruota centrale sinistra Bal középső kerék Левое среднее колесо + 左の中央の前輪 + 왼쪽 가운데 바퀴 + 左中轮 + 左中輪 Right Middle Wheel @@ -649,6 +905,10 @@ Ruota centrale destra Jobb középső kerék Правое среднее колесо + 右の中央の前輪 + 오른족 가운데 바퀴 + 右中轮 + 右中輪 Left Rear Wheel @@ -661,6 +921,10 @@ Ruota posteriore sinistra Bal hátsó kerék Левое заднее колесо + 左の後輪 + 왼쪽 뒤쪽 바퀴 + 左后轮 + 左後輪 Right Rear Wheel @@ -673,6 +937,10 @@ Ruota posteriore destra Jobb hátsó kerék Правое заднее колесо + 右の後輪 + 오른쪽 뒤쪽 바퀴 + 右后轮 + 右後輪 Avionics @@ -685,6 +953,10 @@ Avionica Avionika Авионику + アビオニクス + 항공 전자 + 航电系统 + 航電系統 Main Rotor @@ -697,6 +969,10 @@ Rotore principale Főrotor Несущий винт + 主翼 + 주 로터 + 主旋翼 + 主旋翼 Tail Rotor @@ -709,6 +985,10 @@ Rotore di coda Farokrotor Рулевой винт + テイル ローター + 꼬리 로터 + 尾桨 + 尾槳 Winch @@ -720,6 +1000,10 @@ Naviják Gancio Treuil + ウィンチ + 윈치 + 绞盘 + 絞盤 Glass (right) @@ -732,6 +1016,10 @@ Vetro destro Jobb szélvédő Стекло (справа) + ガラス (右) + 유리 (오른쪽) + 玻璃 (右) + 玻璃 (右) Glass (left) @@ -744,6 +1032,10 @@ Vetro sinistro Bal szélvédő Стекло (слава) + ガラス (左) + 유리 (왼쪽) + 玻璃 (左) + 玻璃 (左) Glass @@ -756,6 +1048,10 @@ Vetro Üveg Стекло + ガラス + 유리 + 玻璃 + 玻璃 ERA @@ -767,6 +1063,10 @@ ERA ERA ДЗ + ERA + 폭발반응장갑 + 爆炸式反应装甲 + 爆炸式反應裝甲 Repair Settings @@ -778,6 +1078,10 @@ Nastavení oprav Impostazioni Riparazioni Réglages de réparation + 修理設定 + 수리 설정 + 修复设定 + 修復設定 Provides a repair system for all types of vehicles. @@ -789,6 +1093,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 @@ -800,6 +1108,10 @@ Cualquiera Chiunque Tout le monde + だれでも + 모두 + 任何人 + 任何人 Engineer only @@ -811,19 +1123,22 @@ Solo ingeniero Solo Geniere Ingénieurs seulement + 工兵のみ + 오직 정비공만 + 只有工兵 + 只有工兵 - - Repair Specialist only - Nur Reparaturspezialist - Tylko inżynierowie - Somente especialista em reparos - Только ремонтные специалисты - Pouze specialista na opravování - Solo especialista en reparación - Solo Specialista Riparazioni - Spécialistes de réparation seulement + + Advanced Engineer only + Instandsetzer + Solo Geniere avanzato + 上級工兵のみ + 只有维修专精兵 + 只有維修專精兵 + Tylko zaawansowani mechanicy + 고급 정비공만 - + Allow Wheel Erlaube Radwechsel Wymiana kół @@ -833,8 +1148,12 @@ Permitir rueda Consenti Ruota Autoriser les roues + タイヤを許可 + 바퀴 허가 + 允许轮胎 + 允許輪胎 - + Who can remove and replace wheels? Wer kann Radwechsel durchführern? Kto może zdejmować i zmieniać koła? @@ -844,8 +1163,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 @@ -855,8 +1178,12 @@ Permitir reparación Consenti Riparazioni Autoriser les réparations + 修理を許可 + 수리 허가 + 允许维修 + 允許維修 - + Who can perform repair actions? Wer kann eine Reperatur durchführen? Kto może wykonywać czynności związane z naprawą pojazdów? @@ -866,10 +1193,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 Лимит ремкомплекта @@ -877,10 +1208,14 @@ Práh oprav Limite Riparazioni Seuil de réparation + 修理のしきい値 + 정비 한계치 + 维修门槛 + 維修門檻 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? Какой максимальный урон можно починить с помощью ремкомплекта? @@ -888,10 +1223,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) Лимит инженера @@ -899,10 +1238,14 @@ Práh oprav (Inženýr) Limite Riparazioni (Geniere) Seuil de réparatoin (ingénieur) + 修理のしきい値 (工兵) + 정비 한계치 (정비공) + 维修门槛 (工兵) + 維修門檻 (工兵) 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? Какой максимальный урон может починить инженер? @@ -910,6 +1253,10 @@ 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 ? + 工兵が修理できる、最大の損傷許容範囲を設定しますか? + 정비공은 어느정도의 피해까지 수리할 수 있습니까? + 工兵可以修复的最大损坏值? + 工兵可以修復的最大損壞值? Remove toolkit on use @@ -921,6 +1268,10 @@ Odstranit sadu nástrojů po použití Rimuovi Toolkit dopo l'uso Enlever la trousse à outils après usage + ツールキットを使うと削除 + 툴킷 사용후 제거 + 使用后删除工具包 + 使用後刪除工具包 Should the toolkit be removed on usage? @@ -932,6 +1283,10 @@ 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 ? + ツールキットを使うと削除しますか? + 툴킷을 사용하면 제거를 합니까? + 要在使用后删除工具包吗? + 要在使用後刪除工具包嗎? Anywhere @@ -943,6 +1298,10 @@ En cualquier sitio Ovunque N'importe où + どこでも + 어디서나 + 任何地点 + 任何地點 Repair Vehicle only @@ -954,6 +1313,10 @@ Pouze opravárenské vozidlo Solo Veicoli Riparazioni Véhicule de réparation seulement + 修理車両のみ + 오직 수리 차량만 + 维修载具旁 + 維修載具旁 Repair Facility only @@ -965,6 +1328,10 @@ Pouze opravárenské zařízení Solo Strutture Riparazioni Installation de réparation seulement + 修理施設のみ + 오직 수리 시설만 + 维修设施旁 + 維修設施旁 Repair Facility or Vehicle @@ -976,6 +1343,10 @@ Opravárenské zařízení nebo vozidlo Strutture Riparazioni o Veicoli Installations ou véhicule de réparation + 修理施設または車両のみ + 수리 시설혹은 차량 + 维修设施或载具旁 + 維修設施或載具旁 Assign Engineer @@ -987,6 +1358,10 @@ Asignar ingeniero Assegna Geniere Assigner le rôle d'ingénieur + 工兵にする + 정비공 등록 + 指派工兵 + 指派工兵 List @@ -998,6 +1373,10 @@ Lista Lista Liste + 一覧 + 목록 + 名单 + 名單 List of unit names that will be classified as engineer, separated by commas. @@ -1009,6 +1388,10 @@ Seznam jmen jednotek, které budou klasifikovány jako inženýr, oddělit čárkami. Lista di unità che verranno classificate come genieri, separate da virgole. Liste des noms d'unités qui seront considérées ingénieurs. Séparé par des virgules + 一覧に記載されたユニット名を、工兵として指定します。コンマで複数を指定できます。 + 목록내 보직이름은 정비공으로 분류됩니다. 쉼표로 구분합니다. + 工兵名单,把单位名称输入在这边即可定义其为工兵。每个单位使用逗号以做区隔。 + 工兵名單,把單位名稱輸入在這邊即可定義其為工兵。每個單位使用逗號以做區隔。 Is Engineer @@ -1020,6 +1403,10 @@ Inženýr E' Geniere Est ingénieur + 工兵とする + 은 정비공이다 + 是工兵 + 是工兵 Select the engineering skill level of the unit @@ -1031,6 +1418,10 @@ Vyberte úroveň dovednosti inženýra pro jednotku Seleziona il livello di abilità geniere dell'unità Sélectionner le niveau d'habilité en réparation de l'unité + ユニットへの工兵スキルを選択 + 선택한 인원의 정비 실력을 고르십시요 + 选择工兵的技术水平 + 選擇工兵的技術水平 None @@ -1042,6 +1433,10 @@ Ningún Nessuna Aucun + なし + 없음 + + Engineer @@ -1053,17 +1448,21 @@ Ingeniero Geniere Ingénieur + 工兵 + 정비공 + 工兵 + 工兵 - - Specialist - Reparaturspezialist - Inżynier - Especialista - Специалист - Specialista - Especialista - Specialista Riparazioni - Spécialiste + + + Adv. Engineer + Instandsetzer + Adv. Geniere + 上級工兵 + 专精 + 專精 + Zaaw. mechanik + 고급 정비공 Assign one or multiple units as an engineer @@ -1075,6 +1474,10 @@ Přiřaďte jednu nebo více osob jako inženýra Assegna una o più unità come genieri Assigner un ou plusieurs unités comme ingénieur + 修理車両として指定 + 하나 혹은 여러 인원을 정비공으로 등록합니다 + 指定一个或多个单位为工兵 + 指定一個或多個單位為工兵 Assign Repair Vehicle @@ -1086,6 +1489,10 @@ Přiřaďte opraváresnké vozidlo Assegna Veicolo Riparazioni Assigner en tant que véhicule de réparation + 修理車両として指定 + 정비 차량 등록 + 指定维修载具 + 指定維修載具 List @@ -1097,6 +1504,10 @@ Lista Lista Liste + 一覧 + 목록 + 名单 + 名單 List of vehicles that will be classified as repair vehicle, separated by commas. @@ -1108,6 +1519,10 @@ Seznam vozidel, která budou klasifikována jako opravárenská, oddělit čárkami. Lista di Veicoli che verranno considerati veicoli riparazioni, separati da virgole. Liste de véhicules qui seront considérés comme véhicules de réparation. Séparé par des virgules. + 一覧に記載されたユニット名を、修理車両として指定します。コンマで複数を指定できます。 + 목록내 차량은 정비 차량으로 분류됩니다. 쉼표로 구분합니다. + 载具名单,把载具名称输入在这边即可定义其为维修载具。每个载具使用逗号以做区隔。 + 載具名單,把載具名稱輸入在這邊即可定義其為維修載具。每個載具使用逗號以做區隔。 Is Repair Vehicle @@ -1119,6 +1534,10 @@ Opravárenské vozidlo E' Veicolo Riparazioni Est un véhicule de réparation + 修理車両とする + 은 정비 차량이다 + 是维修载具 + 是維修載具 Is the vehicle classified as a repair vehicle? @@ -1130,6 +1549,10 @@ 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 ? + 車両を修理車両と指定しますか? + 이 차량을 정비 차량으로 분류합니까? + 此载具是维修载具吗? + 此載具是維修載具嗎? Assign one or multiple vehicles as a repair vehicle @@ -1141,6 +1564,10 @@ Přiřaďte jedno nebo více vozidel jako opravárenské vozidlo Assegna uno o più veicoli come veicoli riparazioni Assigner un ou plusieurs véhicules en tant que véhicule de réparation + 単体、または複数の車両を修理車両とします + 하나 혹은 여러 차량을 정비 차량으로 등록합니다 + 指定一个或多个载具作为维修载具 + 指定一個或多個載具作為維修載具 Assign Repair Facility @@ -1152,6 +1579,10 @@ Přiřaďte opravárenské zařízení Assegna Struttura Riparazioni Assigner en tant qu'installation de réparation + 修理施設とする + 정비 시설 등록 + 指定维修设施 + 指定維修設施 List @@ -1163,6 +1594,10 @@ Lista Lista Liste + 一覧 + 목록 + 名单 + 名單 List of objects that will be classified as repair Facility, separated by commas. @@ -1174,6 +1609,10 @@ Seznam objektů, které budou klasifikovány jako opravárenské zařízení, oddělit čárkami. Lista di oggetti che verranno classificati come strutture riparazioni, separate da virgole. Liste des objets considérés comme installations de réparation. Séparé par des virgules + 一覧に記載されたユニット名を、修理施設として指定します。コンマで複数を指定できます。 + 목록내 시설은 정비 시설으로 분류됩니다. 쉼표로 구분합니다. + 设施名单,把设施名称输入在这边即可定义其为维修设施。每个设施使用逗号以做区隔。 + 設施名單,把設施名稱輸入在這邊即可定義其為維修設施。每個設施使用逗號以做區隔。 Is Repair Facility @@ -1185,6 +1624,10 @@ Opravárenské zařízení E' Struttura Riparazioni Est une installation de réparation + 修理施設とする + 은 정비 시설이다 + 是维修设施 + 是維修設施 Is the object classified as a repair Facility? @@ -1196,6 +1639,10 @@ 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 ? + オブジェクトを修理施設として指定しますか? + 이 시설을 정비 시설로 분류합니까? + 此设施是维修设施吗? + 此設施是維修設施嗎? Assign one or multiple objects as a repair Facility @@ -1207,6 +1654,10 @@ Přiřaďte jeden nebo více objektů jako opravárenské zařízení Assegna uno o più oggetti come strutture riparazioni Assigner un ou plusieurs objets en tant que véhicule de réparation + ひとつ、または複数オブジェクトに予備部品を追加 + 하나 혹은 여러 시설을 정비 시설로 등록합니다 + 指定一个或多个对象作为维修设施 + 指定一個或多個對象作為維修設施 Add Spare Parts @@ -1218,6 +1669,10 @@ Přidat náhradní díly Aggiungi Parti di Ricambio Ajouter des pièces de rechange + 予備部品を追加 + 예비 부품 더하기 + 添加备件 + 添加備件 Add spare parts to one or multiple objects @@ -1229,6 +1684,10 @@ Přidat náhradní díly do jednoho nebo více objektů Aggiungi parti di ricambio ad uno o più oggetti Ajouter des pièces de rechange à un ou plusieurs objets + 一覧に追加されたオブジェクトへ予備部品を与えます。コンマで複数を指定できます。 + 하나 혹은 여러 물체가 예비 부품을 더합니다 + 添加备件到一个或多个对象上 + 添加備件到一個或多個對象上 List @@ -1240,6 +1699,10 @@ Seznam Lista Liste + 一覧 + 목록 + 名单 + 名單 List of objects that will get spare parts added, separated by commas. @@ -1251,6 +1714,10 @@ Seznam objektů, které dostanou náhradní díly, oddělit čárkami. Lista di oggetti a cui verranno aggiunte parti di ricambio, separate da virgole. Liste des objets qui recevront des pièces de réparation en plus. Séparé par des virgules + 一覧に追加されたオブジェクトへ予備部品を与えます。コンマで複数を指定できます。 + 목록내 물체는 예비 부품을 받습니다, 쉼표로 구분합니다. + 添加备件到名单的载具上。每个载具使用逗号以做区隔。 + 添加備件到名單的載具上。每個載具使用逗號以做區隔。 Part @@ -1262,6 +1729,10 @@ Díl Parte Pièce + 部品 + 부품 + 零件 + 零件 Spare part. @@ -1273,6 +1744,10 @@ Náhradní díl. Parte di ricambio. Pièce de rechange + 予備部品 + 예비 부품 + 备用零件 + 備用零件 Amount @@ -1284,6 +1759,10 @@ Množství Quantità Quantité + + 수량 + 数量 + 數量 Number of selected spare parts. @@ -1295,6 +1774,10 @@ Počet vybraných náhradních dílů. Numero di parti di ricambio selezionate. Nombre de pièces de rechange séléctionnées + 選択された予備部品の数を選択します。 + 선택한 부품의 수 + 选择的备件数量 + 選擇的備件數量 Wheel repair requirements @@ -1306,6 +1789,10 @@ Vyžaduje opravu kol Requisiti riparazione ruote Exigences de réparation de roue + タイヤの修理を必要 + 바퀴 교체 요구사항 + 维修轮胎限制 + 維修輪胎限制 Items required to remove/replace wheels @@ -1317,6 +1804,10 @@ Položka vyžaduje odstraněná/vyměněná kola Oggetti richiesti per riparare/rimuovere ruote Items exigés pour enlever/remplacer les roues + タイヤの除去と交換にアイテムを必要としますか? + 바퀴를 제거/교체하는데 필요한 물건 + 需要特定物品来移除/更换车轮 + 需要特定物品來移除/更換車輪 Engine must be off to repair @@ -1326,6 +1817,58 @@ O motor deve estar desligado para manutenção Le moteur doit être éteins pour réparer Двигатель должен быть выключен для ремонта + 修理のためにエンジンを停止させる必要があります。 + Silnik musi być wyłączony w celu naprawy + 수리를 위해서는 엔진을 꺼야만 합니다 + Il motore deve essere spento per poter riparare + 引擎必须先关闭才能开始进行维修 + 引擎必須先關閉才能開始進行維修 + + + 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. + 設定載具在貨艙內攜帶的備用輪胎數量 + 设定载具在货舱内携带的备用轮胎数量。 + + + Auto shut off engine on repair + 修理時にエンジン自動停止 + 维修时自动关闭发动机。 + 維修時自動關閉引擎 + Motore spento automaticamente durante la riparazione + + + Automatically shut off the engine when doing repairs. + 修理時にエンジンを自動で停止します。 + 修理时自动关闭发动机。 + 維修時自動關閉引擎 + Spegne automaticamente il motore quando si fanno riparazioni. - \ No newline at end of file + 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..c5e30a3028 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,8 +70,8 @@ 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,9 +109,9 @@ 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,9 +131,9 @@ 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,9 +153,9 @@ 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,9 +176,9 @@ 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,9 +198,9 @@ 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,9 +220,9 @@ 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/XEH_preInit.sqf b/addons/respawn/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/respawn/XEH_preInit.sqf +++ b/addons/respawn/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/respawn/config.cpp b/addons/respawn/config.cpp index cd87087e20..79fbf69d74 100644 --- a/addons/respawn/config.cpp +++ b/addons/respawn/config.cpp @@ -19,8 +19,3 @@ class CfgPatches { #include "CfgVehicleClasses.hpp" #include "CfgVehicles.hpp" #include "ACE_Settings.hpp" - -class ACE_newEvents { - rallypointMoved = "ace_rallypointMoved"; - killedByFriendly = "ace_killedByFriendly"; -}; diff --git a/addons/respawn/functions/fnc_canMoveRallypoint.sqf b/addons/respawn/functions/fnc_canMoveRallypoint.sqf index 174d76c69d..f37ad34265 100644 --- a/addons/respawn/functions/fnc_canMoveRallypoint.sqf +++ b/addons/respawn/functions/fnc_canMoveRallypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Checks if a unit can move a rally point. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_side"]; diff --git a/addons/respawn/functions/fnc_handleInitPostServer.sqf b/addons/respawn/functions/fnc_handleInitPostServer.sqf index e8f4f1d110..4de502a9ea 100644 --- a/addons/respawn/functions/fnc_handleInitPostServer.sqf +++ b/addons/respawn/functions/fnc_handleInitPostServer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle XEH Init Post on Server. @@ -14,15 +15,12 @@ * * Public: No */ -#include "script_component.hpp" 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,13 +31,15 @@ _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 { // assign JIP unit as rallypoint leader if (str _unit == _leaderVarName) then { - _unit setVariable ["ACE_canMoveRallypoint", true, true]; + if (isNil {_unit getVariable "ACE_canMoveRallypoint"}) then { + _unit setVariable ["ACE_canMoveRallypoint", true, true]; + }; }; }; @@ -61,4 +61,6 @@ if (_leaderVarName == "") then { // prevent group from getting multiple leaders; use this to assign rallypoint moving ability on JIP _groupUnit setVariable [QGVAR(leaderVarName), _leaderVarName]; -_unit setVariable ["ACE_canMoveRallypoint", true, true]; +if (isNil {_unit getVariable "ACE_canMoveRallypoint"}) then { + _unit setVariable ["ACE_canMoveRallypoint", true, true]; +}; diff --git a/addons/respawn/functions/fnc_handleKilled.sqf b/addons/respawn/functions/fnc_handleKilled.sqf index 6ca816e8a4..0a6fcd8ce8 100644 --- a/addons/respawn/functions/fnc_handleKilled.sqf +++ b/addons/respawn/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Handles the XEH killed event. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/respawn/functions/fnc_handlePlayerChanged.sqf b/addons/respawn/functions/fnc_handlePlayerChanged.sqf index 97592db06f..9fc71af9b7 100644 --- a/addons/respawn/functions/fnc_handlePlayerChanged.sqf +++ b/addons/respawn/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle player changed event. Updates visibility of Rallypoint markers. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_newUnit"]; diff --git a/addons/respawn/functions/fnc_handleRespawn.sqf b/addons/respawn/functions/fnc_handleRespawn.sqf index 3b1ae1c86f..a8c65056b3 100644 --- a/addons/respawn/functions/fnc_handleRespawn.sqf +++ b/addons/respawn/functions/fnc_handleRespawn.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Handles the XEH Respawn event. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/respawn/functions/fnc_initRallypoint.sqf b/addons/respawn/functions/fnc_initRallypoint.sqf index b012344379..0286813cef 100644 --- a/addons/respawn/functions/fnc_initRallypoint.sqf +++ b/addons/respawn/functions/fnc_initRallypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Init code for rallypoints. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_rallypoint", "_respawnMarker", "_side"]; @@ -35,7 +35,7 @@ if (isNil _name) then { }; } else { deleteVehicle _rallypoint; - ACE_LOGERROR("Multiple Rallypoints of same type."); + ERROR("Multiple Rallypoints of same type."); }; // init visible marker diff --git a/addons/respawn/functions/fnc_module.sqf b/addons/respawn/functions/fnc_module.sqf index bc4f197c07..72b4003bbc 100644 --- a/addons/respawn/functions/fnc_module.sqf +++ b/addons/respawn/functions/fnc_module.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, bux578, esteldunedain, commy2 * Initializes the respawn module. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_logic", "_units", "_activated"]; @@ -24,4 +24,4 @@ if (!_activated) exitWith {}; [_logic, QGVAR(SavePreDeathGear), "SavePreDeathGear"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(RemoveDeadBodiesDisconnected), "RemoveDeadBodiesDisconnected"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO("Respawn Module Initialized."); +INFO("Respawn Module Initialized."); diff --git a/addons/respawn/functions/fnc_moduleFriendlyFire.sqf b/addons/respawn/functions/fnc_moduleFriendlyFire.sqf index 3c3c02b3c9..2801e26b26 100644 --- a/addons/respawn/functions/fnc_moduleFriendlyFire.sqf +++ b/addons/respawn/functions/fnc_moduleFriendlyFire.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Initializes the friendly fire module. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_logic", "_units", "_activated"]; @@ -30,4 +30,4 @@ if (isServer) then { [], 0.1] call CBA_fnc_waitAndExecute; }; -ACE_LOGINFO("Friendly Fire Messages Module Initialized."); +INFO("Friendly Fire Messages Module Initialized."); diff --git a/addons/respawn/functions/fnc_moduleRallypoint.sqf b/addons/respawn/functions/fnc_moduleRallypoint.sqf index 89baed660f..a06220fec8 100644 --- a/addons/respawn/functions/fnc_moduleRallypoint.sqf +++ b/addons/respawn/functions/fnc_moduleRallypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Initializes the Rallypoint module. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_logic", "_units", "_activated"]; @@ -26,4 +26,4 @@ if !(_activated) exitWith {}; false } count _units; -ACE_LOGINFO("Rallypoint Module Initialized."); +INFO("Rallypoint Module Initialized."); diff --git a/addons/respawn/functions/fnc_moveRallypoint.sqf b/addons/respawn/functions/fnc_moveRallypoint.sqf index 353d90e56a..d0e191829e 100644 --- a/addons/respawn/functions/fnc_moveRallypoint.sqf +++ b/addons/respawn/functions/fnc_moveRallypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Moves a rallypoint to the players location. @@ -14,13 +15,10 @@ * * Public: No */ -#include "script_component.hpp" 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 a035bdd52d..990fa77ea8 100644 --- a/addons/respawn/functions/fnc_restoreGear.sqf +++ b/addons/respawn/functions/fnc_restoreGear.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578, commy2 * Restores previously saved gear. @@ -14,12 +15,18 @@ * * Public: No */ -#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; }; @@ -44,7 +51,7 @@ if (!isNil "_activeWeaponAndMuzzle") then { private _index = 0; while { - _index < 100 && {currentWeaponMode _unit != _activeWeaponMode} + _index < 299 && {currentWeaponMode _unit != _activeWeaponMode} } do { _unit action ["SwitchWeapon", _unit, _unit, _index]; _index = _index + 1; diff --git a/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf b/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf index 388302150d..a20c9926f5 100644 --- a/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf +++ b/addons/respawn/functions/fnc_showFriendlyFireMessage.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Shows a message in system chat of who killed whom. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_killer"]; diff --git a/addons/respawn/functions/fnc_teleportToRallypoint.sqf b/addons/respawn/functions/fnc_teleportToRallypoint.sqf index 9f2da46640..6c8a697279 100644 --- a/addons/respawn/functions/fnc_teleportToRallypoint.sqf +++ b/addons/respawn/functions/fnc_teleportToRallypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Teleports a unit to a rallypoint @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_side", "_rallypoint"]; diff --git a/addons/respawn/functions/fnc_updateRallypoint.sqf b/addons/respawn/functions/fnc_updateRallypoint.sqf index 8b34f87019..363e12972b 100644 --- a/addons/respawn/functions/fnc_updateRallypoint.sqf +++ b/addons/respawn/functions/fnc_updateRallypoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Updates marker position and texts. @@ -15,16 +16,13 @@ * * Public: No */ -#include "script_component.hpp" 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/script_component.hpp b/addons/respawn/script_component.hpp index 2fcd01ee37..95428c3332 100644 --- a/addons/respawn/script_component.hpp +++ b/addons/respawn/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_RESPAWN diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index e0d04aabfa..98c4bec01a 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... @@ -12,6 +19,10 @@ Kihelyezés 5 másodperc múlva... Dispiegamento in 5 secondi... Será posicionado em 5 segundos... + 設置まであと 5 秒・・・ + 5초 후 재배치... + 5秒后完成布署... + 5秒後完成佈署... Rallypoint deployed @@ -24,6 +35,10 @@ Gyülekezőpont elhelyezve Rallypoint dispiegato Rallypoints posicionado + ラリーポイントを設置しました + 집결지 배치됨 + 集合点布署完成 + 集合點佈署完成 Teleport to Base @@ -36,6 +51,10 @@ Teletransportar para a Base Bázisra teleportálás Teleporta alla base + ベースへ移動 + 기지로 순간이동 + 传送至基地 + 傳送至基地 Teleport to Rallypoint @@ -48,6 +67,10 @@ Teletransportar para o ponto de encontro Gyülekezőpontra teleportálás Teleporta al rallypoint + ラリーポイントへ移動 + 집결지로 순간이동 + 传送至集合点 + 傳送至集合點 Teleported to Base @@ -60,6 +83,10 @@ Bázisra teleportálva Teleportato alla base Teletransportado para a Base + ベースへ移動しました + 기지로 순간이동함 + 已传送至基地 + 已傳送至基地 Teleported to Rallypoint @@ -72,6 +99,10 @@ Gyülekezőpontra teleportálva Teleportato al rallypoint Teletransportado para o Rallypoints + ラリーポイントへ移動しました + 집결지로 순간이동함 + 已传送至集合点 + 已傳送至集合點 Rallypoint West (Base) @@ -84,6 +115,10 @@ Gyülekezőpont, Nyugat (Bázis) Rallypoint Západ (Základna) Ponto de encontro Oeste (Base) + ラリーポイント 同盟軍 (ベース) + 蓝方集合点 (基地) + 藍方集合點 (基地) + 청군 집결지 (기지) Rallypoint East (Base) @@ -96,6 +131,10 @@ Gyülekezőpont, Kelet (Bázis) Ralllypoint Východ (Základna) Ponto de encontro Lest (Base) + ラリーポイント OPFOR軍 (ベース) + 红方集合点 (基地) + 紅方集合點 (基地) + 대항군 집결지 (기지) Rallypoint Independent (Base) @@ -108,6 +147,10 @@ Gyülekezőpont, Független (Bázis) Rallypoint Nezávislý (Základna) Ponto de encontro Independente (Base) + ラリーポイント 独立軍 (ベース) + 独立方集合点 (基地) + 獨立方集合點 (基地) + 독립군 집결지 (기지) Rallypoint West @@ -120,6 +163,10 @@ Gyülekezőpont, Nyugat Rallypoint Západ Ponto de encontro Oeste + ラリーポイント 同盟軍 + 蓝方集合点 + 藍方集合點 + 청군 집결지 Rallypoint East @@ -132,6 +179,10 @@ Gyülekezőpont, Kelet Rallypoint Východ Ponto de encontro Leste + ラリーポイント OPFOR軍 + 红方集合点 + 紅方集合點 + 대항군 집결지 Rallypoint Independent @@ -144,6 +195,10 @@ Gyülekezőpont, Független Rallypoint Nezávislý Ponto de encontro Independente + ラリーポイント 独立軍 + 独立方集合点 + 獨立方集合點 + 독립군 집결지 Respawn System @@ -156,6 +211,10 @@ Respawn-rendszer Возрождение Sistema Respawn + リスポン システム + 재배치 시스템 + 重生系统 + 重生系統 Save Gear? @@ -168,6 +227,10 @@ Felszerelés elmentése? Сохранять снаряжение? Salva Equipaggiamento? + 装備を保存? + 장비를 저장합니까? + 储存装备? + 儲存裝備? Respawn with the gear a soldier had just before his death? @@ -180,6 +243,10 @@ 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? + ユニットが死ぬ前に持っていた装備でリスポンしますか? + 죽기 전에 가지고 있던 장비로 재배치합니까? + 是否在重生时载入死亡前的装备? + 是否在重生時載入死亡前的裝備? Remove bodies? @@ -192,6 +259,10 @@ Holttestek eltávolítása? Удалять трупы? Rimuovi corpi? + 死体を削除? + 시체를 제거합니까? + 删除尸体? + 刪除屍體? Remove player bodies after disconnect? @@ -204,6 +275,17 @@ 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. @@ -215,6 +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的重生功能 Friendly Fire Messages @@ -227,6 +313,10 @@ Baráti tűz üzenetek Сообщения об огне по своим Messaggi Fuoco Amico + 友軍誤射の表示 + 아군사격 메세지 + 友军误击讯息 + 友軍誤擊訊息 Using this module in your mission will make it so any friendly fire kills will be displayed in form of a message in chat. @@ -238,6 +328,10 @@ Ce module permet l'affiche de message dans le chat lors d'un tir fraticide et indique qui a tué qui. Usando questo modulo nella tua missione farà in modo che ogni uccisione per fuoco amico venga mostrata in forma di messaggio in chat. El usar este módulo, todas las muertes por fuego amigo serán indicadas en el chat. + もし友軍誤射による死者が出た場合は、チャットにてその旨を表示します。 + 이 모듈은 미션 중 아군사격으로 인한 사망자 발생시 채팅창에 메세지를 표시해줍니다. + 摆放此模块后,当有发生友军误击致死的事件,会显示提示讯息在聊天视窗中。 + 擺放此模塊後,當有發生友軍誤擊致死的事件,會顯示提示訊息在聊天視窗中 Rallypoint System @@ -250,6 +344,10 @@ Gyülekezőpont-rendszer Система точек сбора Sistema Punto di Raccolta + ラリーポイント システム + 집결지 시스템 + 集合点系统 + 集合點系統 This module allows you to use rally points in missions, to which you can quickly teleport from base flag. Requires placing special objects on map - base and flag. Both available in category Empty -> ACE Respawn. @@ -261,6 +359,10 @@ Questo modulo ti consente di usare Punti di Raccolta in missione, a cui ti puoi teleportare rapidamente dalla bandiera in base. Richiede il piazzamento di oggetti speciali in mappa - base e bandiera. Entrambi disponibili nella categoria Vuoto -> Respawn ACE Este módulo permite usar puntos de reunión en la misión, a los que pueden teletransportarse las unidades desde la bandera de base. Requiere colocar objetos especiales en el mapa: las banderas de base y de reunión, ambas disponibles en la categoría Vacio-> Reaparición ACE 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 重生裡面的基地與旗幟 Move Rallypoint @@ -273,6 +375,10 @@ Gyülekezőpont mozgatása Двигать точку сбора Sposta Punto di Raccolta + ラリーポイントを移動 + 집결지 이동 + 移动集合点 + 移動集合點 ACE Respawn @@ -284,7 +390,11 @@ ACE Respawn ACE Respawn ACE Возрождение - Respawn ACE + Rigenerazione ACE + ACE リスポン + ACE 재배치 + ACE 重生 + ACE 重生 - \ No newline at end of file + 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/XEH_preInit.sqf b/addons/safemode/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/safemode/XEH_preInit.sqf +++ b/addons/safemode/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/safemode/functions/fnc_lockSafety.sqf b/addons/safemode/functions/fnc_lockSafety.sqf index 2675068e94..e3c1b71f30 100644 --- a/addons/safemode/functions/fnc_lockSafety.sqf +++ b/addons/safemode/functions/fnc_lockSafety.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Put weapon on safety, or take it off safety if safety is already put on. @@ -15,16 +16,13 @@ * * Public: No */ -#include "script_component.hpp" // don't immediately switch back 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..d013d29696 100644 --- a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Play weapon firemode change sound. @@ -14,20 +15,17 @@ * * Public: No */ -#include "script_component.hpp" 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_setSafeModeVisual.sqf b/addons/safemode/functions/fnc_setSafeModeVisual.sqf index cc11be3806..587ac882d3 100644 --- a/addons/safemode/functions/fnc_setSafeModeVisual.sqf +++ b/addons/safemode/functions/fnc_setSafeModeVisual.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Show firemode indicator, representing safety lock @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_show"]; diff --git a/addons/safemode/functions/fnc_unlockSafety.sqf b/addons/safemode/functions/fnc_unlockSafety.sqf index b1c2fda540..5a787277e4 100644 --- a/addons/safemode/functions/fnc_unlockSafety.sqf +++ b/addons/safemode/functions/fnc_unlockSafety.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Take weapon of safety lock. @@ -15,13 +16,10 @@ * * Public: No */ -#include "script_component.hpp" 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,12 +47,12 @@ 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 < 100 && {currentMuzzle _unit != _weapon || {currentWeaponMode _unit != _mode}} + _index < 299 && {currentMuzzle _unit != _weapon || {currentWeaponMode _unit != _mode}} } do { _unit action ["SwitchWeapon", _unit, _unit, _index]; _index = _index + 1; @@ -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/script_component.hpp b/addons/safemode/script_component.hpp index d9972b6226..746510cdd5 100644 --- a/addons/safemode/script_component.hpp +++ b/addons/safemode/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_SAFEMODE diff --git a/addons/safemode/stringtable.xml b/addons/safemode/stringtable.xml index 9717ba4dae..e5eff7255c 100644 --- a/addons/safemode/stringtable.xml +++ b/addons/safemode/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -10,8 +10,12 @@ Biztonságos mód Предохранитель Sécurité - Sicura inserita + Modalità Sicura Modo de segurança + 安全装置 + 안전 모드 + 保险模式 + 保險模式 Take off Safety @@ -24,6 +28,10 @@ Enlever sécurité Togli la sicura Tirar segurança + 安全装置を外す + 안전장치 해제 + 开保险 + 開保險 Put on Safety @@ -32,10 +40,14 @@ Zabezpieczono broń Zbraň zajistěna Biztonsági kapcsoló helyretolása - Поставить на предохранитель + Поставлено на предохранитель Sécurité mise Sicura inserita Colocar Segurança + 安全装置をかけました + 안전장치 적용 + 关保险 + 關保險 Took off Safety @@ -44,10 +56,14 @@ Odbezpieczono broń Zbraň odjištěna Biztonságos mód megszüntetve - Снят с предохранителя + Снято с предохранителя Sécurité enlevée Sicura tolta Tirou Segurança + 安全装置を外しました + 안전장치 해제됨 + 已开保险 + 已開保險 - \ No newline at end of file + diff --git a/addons/sandbag/CfgVehicles.hpp b/addons/sandbag/CfgVehicles.hpp index df18b42c06..8f4dd85336 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; @@ -12,7 +12,6 @@ class CfgVehicles { statement = QUOTE([ARR_2({_this call FUNC(deploy)},_this)] call CBA_fnc_execNextFrame); exceptions[] = {"isNotSwimming"}; showDisabled = 0; - priority = 4; icon = QPATHTOF(UI\icon_sandbag_ca.paa); }; }; @@ -25,6 +24,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 +49,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 +81,7 @@ class CfgVehicles { class ACE_MainActions { selection = ""; distance = 5; - condition = "true"; + condition = "(true)"; class ACE_PickUp { selection = ""; @@ -89,11 +91,14 @@ class CfgVehicles { statement = QUOTE([ARR_2(_player,_target)] call FUNC(pickup)); showDisabled = 0; exceptions[] = {}; - priority = 5; icon = QPATHTOF(UI\icon_sandbag_ca.paa); }; }; }; + + 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/XEH_preInit.sqf b/addons/sandbag/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/sandbag/XEH_preInit.sqf +++ b/addons/sandbag/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/sandbag/config.cpp b/addons/sandbag/config.cpp index 9c28b948ac..80e3f71808 100644 --- a/addons/sandbag/config.cpp +++ b/addons/sandbag/config.cpp @@ -17,7 +17,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; -}; 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_canDeploy.sqf b/addons/sandbag/functions/fnc_canDeploy.sqf index b9bd025dff..88ecd03093 100644 --- a/addons/sandbag/functions/fnc_canDeploy.sqf +++ b/addons/sandbag/functions/fnc_canDeploy.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: Ruthberg, commy2 - * Checks if the player can deploy a sandbag + * Checks if the player can deploy a sandbag. * * Arguments: - * None + * 0: Unit * * Return Value: * Can deploy @@ -13,17 +14,9 @@ * * Public: No */ -#include "script_component.hpp" - -#define SURFACE_BLACKLIST ["water", "concrete", "tarmac", "wood", "metal", "roof_tin", "roof_tiles", "wood_int", "concrete_int", "tiles_int", "metal_int", "stony", "rock", "int_concrete", "int_tiles", "int_wood", "tiling", "wavymetal", "int_metal"] params ["_unit"]; -if !("ACE_Sandbag_empty" in items _unit) exitWith {false}; +if !("ACE_Sandbag_empty" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; -private ["_surfaceClass", "_surfaceType"]; - -_surfaceClass = (surfaceType getPosASL _unit) select [1]; -_surfaceType = getText (configFile >> "CfgSurfaces" >> _surfaceClass >> "soundEnviron"); - -!(_surfaceType in SURFACE_BLACKLIST) +_unit call EFUNC(common,canDig) diff --git a/addons/sandbag/functions/fnc_deploy.sqf b/addons/sandbag/functions/fnc_deploy.sqf index af7d5c0a2f..b336cee0a0 100644 --- a/addons/sandbag/functions/fnc_deploy.sqf +++ b/addons/sandbag/functions/fnc_deploy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Starts the deploy process for sandbags. @@ -13,12 +14,12 @@ * * Public: No */ -#include "script_component.hpp" 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..6c5fb1e88a 100644 --- a/addons/sandbag/functions/fnc_deployCancel.sqf +++ b/addons/sandbag/functions/fnc_deployCancel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Cancels sandbag deployment @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_key"]; @@ -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 47b74533a1..e8abb586ee 100644 --- a/addons/sandbag/functions/fnc_deployConfirm.sqf +++ b/addons/sandbag/functions/fnc_deployConfirm.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Confirms sandbag deployment @@ -13,12 +14,12 @@ * * Public: No */ -#include "script_component.hpp" 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"; @@ -29,14 +30,12 @@ _unit removeItem "ACE_Sandbag_empty"; params ["_unit"]; - private ["_position", "_direction", "_sandBag"]; - - _position = getPosASL GVAR(sandBag); - _direction = getDir GVAR(sandBag); + private _position = getPosASL GVAR(sandBag); + private _direction = getDir GVAR(sandBag); deleteVehicle GVAR(sandBag); - _sandBag = createVehicle ["ACE_SandbagObject", [0, 0, 0], [], 0, "NONE"]; + private _sandBag = createVehicle ["ACE_SandbagObject", [0, 0, 0], [], 0, "NONE"]; _sandBag setPosASL _position; _sandBag setDir _direction; diff --git a/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf b/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf index f4ea5891c7..7683520c84 100644 --- a/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_sandbag_fnc_handleInteractMenuOpened + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/sandbag/functions/fnc_handleKilled.sqf b/addons/sandbag/functions/fnc_handleKilled.sqf index 63babd3f52..b778de6cc6 100644 --- a/addons/sandbag/functions/fnc_handleKilled.sqf +++ b/addons/sandbag/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle death. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_sandbag_fnc_handleKilled + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/sandbag/functions/fnc_handlePlayerChanged.sqf b/addons/sandbag/functions/fnc_handlePlayerChanged.sqf index f27a295903..2ba996f760 100644 --- a/addons/sandbag/functions/fnc_handlePlayerChanged.sqf +++ b/addons/sandbag/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle player changes. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ace_sandbag_fnc_handlePlayerChanged + * * Public: No */ -#include "script_component.hpp" params ["_newPlayer", "_oldPlayer"]; diff --git a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf b/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf index 9f5920edd1..53674d8e86 100644 --- a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf +++ b/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle the InventoryChanged event. @@ -9,14 +10,16 @@ * Return Value: * None * + * Example: + * [bob, "weapon"] call ace_sandbag_fnc_handlePlayerInventoryChanged + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; if (_unit getVariable [QGVAR(isDeploying), false]) then { - if !("ACE_Sandbag_empty" in items _unit) then { + if !("ACE_Sandbag_empty" in (_unit call EFUNC(common,uniqueItems))) then { [_unit] call FUNC(deployCancel); }; }; diff --git a/addons/sandbag/functions/fnc_handleScrollWheel.sqf b/addons/sandbag/functions/fnc_handleScrollWheel.sqf index 20d403a7a1..515e40053b 100644 --- a/addons/sandbag/functions/fnc_handleScrollWheel.sqf +++ b/addons/sandbag/functions/fnc_handleScrollWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg * Handles sandbag rotation @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (GVAR(deployPFH) == -1) exitWith {false}; diff --git a/addons/sandbag/functions/fnc_handleUnconscious.sqf b/addons/sandbag/functions/fnc_handleUnconscious.sqf index 7e0e257158..9b514007fb 100644 --- a/addons/sandbag/functions/fnc_handleUnconscious.sqf +++ b/addons/sandbag/functions/fnc_handleUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle unconsciousness. @@ -8,12 +9,16 @@ * Return Value: * None * + * Example: + * [bob] call ace_sandbag_fnc_handleUnconscious + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; +if (!local _unit) exitWith {}; + if (_unit getVariable [QGVAR(isDeploying), false]) then { [_unit] call FUNC(deployCancel); }; diff --git a/addons/sandbag/functions/fnc_pickup.sqf b/addons/sandbag/functions/fnc_pickup.sqf index f7eaca9b72..7db56cdfbe 100644 --- a/addons/sandbag/functions/fnc_pickup.sqf +++ b/addons/sandbag/functions/fnc_pickup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Pick up sandbag @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_sandbag"]; diff --git a/addons/sandbag/script_component.hpp b/addons/sandbag/script_component.hpp index a7ce4ddb59..6bd2e8a4ca 100644 --- a/addons/sandbag/script_component.hpp +++ b/addons/sandbag/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_SANDBAG diff --git a/addons/sandbag/stringtable.xml b/addons/sandbag/stringtable.xml index 99be2bddf1..9284d23468 100644 --- a/addons/sandbag/stringtable.xml +++ b/addons/sandbag/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Sacco di Sabbia Homokzsák Saco de Areia + 土のう + 모래주머니 + 沙包 + 沙包 Sandbag (empty) @@ -21,9 +25,13 @@ 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) + 土のう (空) + 모래주머니(비어있음) + 沙包 (空) + 沙包 (空) Cannot build here @@ -36,6 +44,10 @@ Impossibile costruire qui Nem teheted ide Não pode contruir aqui + ここでは作れません + 여기에 지을 수 없습니다 + 无法放置在此 + 無法放置在此 Pick up Sandbag @@ -48,6 +60,10 @@ Prendi Sacco di Sabbia Homokzsák felvétele Pegar saco de areia + 土のうを拾う + 모래주머니 줍기 + 捡起沙包 + 撿起沙包 Carry Sandbag @@ -60,6 +76,10 @@ Trasporta Sacco di Sabbia Homokzsák cipelése Carregar saco de areia + 土のうを運ぶ + 모래주머니 옮기기 + 搬运沙包 + 搬運沙包 End Carrying @@ -72,6 +92,10 @@ Fine Trasporto Cipelés abbahagyása Parar de carregar + 下ろす + 그만 옮기기 + 停止搬运 + 停止搬運 Drop Sandbag @@ -84,6 +108,10 @@ Lascia Sacco di Sabbia Homokzsák eldobása Derrubar saco de areia + 土のうを落とす + 여기에 놓기 + 放下沙包 + 放下沙包 Confirm Deployment @@ -96,6 +124,10 @@ Conferma Posizionamento Lerak Confirmar implantação + ここで作る + 설치 확인 + 确认布署 + 確認佈署 Cancel Deployment @@ -108,6 +140,10 @@ Cancella Posizionamento Visszavonás Cancelar implantação + 作るのを止める + 설치 취소 + 取消布署 + 取消佈署 Deploy Sandbag @@ -120,6 +156,10 @@ Posiziona Sacco di Sabbia Homokzsák lerakása Implantar saco de areia + 土のうを設置 + 모래주머니 설치 + 布署沙包 + 佈署沙包 Sandbag Box @@ -132,6 +172,10 @@ Contenitore Sacchi di Sabbia Homokzsákos láda Caixa de saco de areia + 土のう入れ + 모래주머니 상자 + 沙包箱 + 沙包箱 Here is no sand @@ -144,6 +188,10 @@ Qui non cè Sabbia Itt nincs homok Aqui não tem areia + ここに土はありません + 흙이 없습니다 + 这里没有沙 + 這裡沒有沙 Rotate @@ -156,6 +204,10 @@ Obrót Rotaciona Bращать + 回転 + 돌리기 + 旋转 + 旋轉 diff --git a/addons/scopes/ACE_Arsenal_Stats.hpp b/addons/scopes/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..1e2ebd91ea --- /dev/null +++ b/addons/scopes/ACE_Arsenal_Stats.hpp @@ -0,0 +1,18 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_scopeHorizontalLimits: statBase { + scope = 2; + priority = 3; + stats[] = {"ACE_ScopeAdjust_Horizontal", "ACE_ScopeAdjust_HorizontalIncrement"}; + displayName = CSTRING(statHorizontalLimits); + showText = 1; + textStatement = QUOTE(params[ARR_2('_stat','_config')]; private _limits = getArray (_config >> _stat select 0); format [ARR_4('%1 / %2 MIL (∆ %3 MIL)', _limits select 0, _limits select 1, getNumber (_config >> _stat select 1))]); + condition = QUOTE(params[ARR_2('_stat', '_config')]; !((getArray (_config >> _stat select 0)) isEqualTo [])); + tabs[] = {{}, {0}}; + }; + class ACE_scopeVerticalLimits: ACE_scopeHorizontalLimits { + stats[] = {"ACE_ScopeAdjust_Vertical", "ACE_ScopeAdjust_VerticalIncrement"}; + priority = 2; + displayName = CSTRING(statVerticalLimits); + }; +}; diff --git a/addons/scopes/ACE_Settings.hpp b/addons/scopes/ACE_Settings.hpp new file mode 100644 index 0000000000..04e0e92ffb --- /dev/null +++ b/addons/scopes/ACE_Settings.hpp @@ -0,0 +1,93 @@ +class ACE_Settings { + class GVAR(enabled) { + category = CSTRING(DisplayName); + typeName = "BOOL"; + value = 1; + displayName = CSTRING(enabled_displayName); + description = CSTRING(enabled_description); + }; + // 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); + description = CSTRING(forceUseOfAdjustmentTurrets_description); + }; + + // Auto corrects the zeroing in both vanilla- and advanced ballistics + class GVAR(correctZeroing) { + category = CSTRING(DisplayName); + typeName = "BOOL"; + value = 1; + displayName = CSTRING(correctZeroing_displayName); + description = CSTRING(correctZeroing_description); + }; + // 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); + description = CSTRING(overwriteZeroRange_description); + }; + // 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.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 8a17384933..f3d7126b06 100644 --- a/addons/scopes/CfgVehicles.hpp +++ b/addons/scopes/CfgVehicles.hpp @@ -9,11 +9,96 @@ class CfgVehicles { condition = QUOTE([ACE_player] call FUNC(canAdjustZero)); statement = QUOTE([ACE_player] call FUNC(adjustZero)); 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; + //icon = QPATHTOF(UI\...); // TODO + exceptions[] = {"notOnMap", "isNotInside", "isNotSwimming", "isNotSitting"}; }; }; }; }; + class ACE_Module; + class GVAR(ModuleSettings): ACE_Module { + scope = 1; + displayName = CSTRING(DisplayName); + //icon = ""; // needs an icon + category = "ACE"; + function = QUOTE(DFUNC(initModuleSettings)); + functionPriority = 1; + isGlobal = 1; + isTriggerActivated = 0; + author = ECSTRING(common,ACETeam); + class Arguments { + class enabled { + displayName = CSTRING(enabled_DisplayName); + description = CSTRING(enabled_Description); + typeName = "BOOL"; + defaultValue = 1; + }; + class forceUseOfAdjustmentTurrets { + displayName = CSTRING(forceUseOfAdjustmentTurrets_DisplayName); + description = CSTRING(forceUseOfAdjustmentTurrets_Description); + typeName = "BOOL"; + defaultValue = 0; + }; + class correctZeroing { + displayName = CSTRING(correctZeroing_DisplayName); + description = CSTRING(correctZeroing_Description); + typeName = "BOOL"; + defaultValue = 1; + }; + class overwriteZeroRange { + displayName = CSTRING(overwriteZeroRange_DisplayName); + description = CSTRING(overwriteZeroRange_Description); + typeName = "BOOL"; + defaultValue = 0; + }; + class defaultZeroRange { + displayName = CSTRING(defaultZeroRange_DisplayName); + description = CSTRING(defaultZeroRange_Description); + typeName = "NUMBER"; + defaultValue = 100; + }; + class zeroReferenceTemperature { + displayName = CSTRING(zeroReferenceTemperature_DisplayName); + description = CSTRING(zeroReferenceTemperature_Description); + typeName = "NUMBER"; + defaultValue = 15; + }; + class zeroReferenceBarometricPressure { + displayName = CSTRING(zeroReferenceBarometricPressure_DisplayName); + description = CSTRING(zeroReferenceBarometricPressure_Description); + typeName = "NUMBER"; + defaultValue = 1013.25; + }; + class zeroReferenceHumidity { + displayName = CSTRING(zeroReferenceHumidity_DisplayName); + description = CSTRING(zeroReferenceHumidity_Description); + typeName = "NUMBER"; + defaultValue = 0.0; + }; + class deduceBarometricPressureFromTerrainAltitude { + displayName = CSTRING(deduceBarometricPressureFromTerrainAltitude_DisplayName); + description = CSTRING(deduceBarometricPressureFromTerrainAltitude_Description); + 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 cd87167f22..2a5be51ee0 100644 --- a/addons/scopes/CfgWeapons.hpp +++ b/addons/scopes/CfgWeapons.hpp @@ -1,8 +1,109 @@ +class Mode_SemiAuto; +class Mode_Burst; +class Mode_FullAuto; + class CfgWeapons { class ItemCore; class InventoryOpticsItem_Base_F; - + + class optic_Yorris : ItemCore { + ACE_ScopeHeightAboveRail = 2.77224; + }; + + class optic_MRD : ItemCore { + ACE_ScopeHeightAboveRail = 2.8; + }; + + class optic_Aco : ItemCore { + ACE_ScopeHeightAboveRail = 3.69248; + }; + + class optic_ACO_grn : ItemCore { + ACE_ScopeHeightAboveRail = 3.69248; + }; + + class optic_ACO_grn_smg : ItemCore { + ACE_ScopeHeightAboveRail = 3.69248; + }; + + class optic_ACO_smg : ItemCore { + ACE_ScopeHeightAboveRail = 3.69248; + }; + + class optic_Holosight : ItemCore { + ACE_ScopeHeightAboveRail = 4.66933; + }; + + class optic_Holosight_smg : ItemCore { + ACE_ScopeHeightAboveRail = 4.66933; + }; + + class optic_Arco : ItemCore { + ACE_ScopeHeightAboveRail = 4.89287; + }; + + class optic_ERCO_blk_F : optic_Arco { + ACE_ScopeHeightAboveRail = 3.48836; + }; + + class optic_Hamr : ItemCore { + ACE_ScopeHeightAboveRail = 4.48584; + }; + + class optic_MRCO : ItemCore { + ACE_ScopeHeightAboveRail = 3.88405; + }; + + class optic_Nightstalker : ItemCore { + ACE_ScopeHeightAboveRail = 5.54325; + ACE_ScopeAdjust_Vertical[] = {-4, 30}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo : InventoryOpticsItem_Base_F { + class OpticsModes { + class NCTALKEP { + discreteDistance[] = {200}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class optic_NVS : ItemCore { + ACE_ScopeHeightAboveRail = 5.54325; + ACE_ScopeAdjust_Vertical[] = {-4, 30}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo : InventoryOpticsItem_Base_F { + class OpticsModes { + class NVS { + discreteDistance[] = {300}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + + class optic_TWS : ItemCore { + ACE_ScopeHeightAboveRail = 5.52874; + ACE_ScopeAdjust_Vertical[] = {-4, 30}; + ACE_ScopeAdjust_Horizontal[] = {-6, 6}; + ACE_ScopeAdjust_VerticalIncrement = 0.1; + ACE_ScopeAdjust_HorizontalIncrement = 0.1; + class ItemInfo : InventoryOpticsItem_Base_F { + class OpticsModes { + class TWS { + discreteDistance[] = {300}; + discreteDistanceInitIndex = 0; + }; + }; + }; + }; + class optic_LRPS : ItemCore { + ACE_ScopeHeightAboveRail = 4.2098; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -22,6 +123,7 @@ class CfgWeapons { }; class optic_SOS : ItemCore { + ACE_ScopeHeightAboveRail = 4.41328; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -37,6 +139,7 @@ class CfgWeapons { }; class optic_DMS : ItemCore { + ACE_ScopeHeightAboveRail = 3.86253; ACE_ScopeAdjust_Vertical[] = {-4, 20}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -52,6 +155,7 @@ class CfgWeapons { }; class optic_AMS_base : ItemCore { + ACE_ScopeHeightAboveRail = 3.8933; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -71,6 +175,7 @@ class CfgWeapons { }; class optic_KHS_base : ItemCore { + ACE_ScopeHeightAboveRail = 4.30723; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -90,6 +195,7 @@ class CfgWeapons { }; class optic_KHS_old : ItemCore { + ACE_ScopeHeightAboveRail = 4.30723; ACE_ScopeAdjust_Vertical[] = {-4, 30}; ACE_ScopeAdjust_Horizontal[] = {-6, 6}; ACE_ScopeAdjust_VerticalIncrement = 0.1; @@ -107,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 908d8064f0..58b4e494f2 100644 --- a/addons/scopes/XEH_PREP.hpp +++ b/addons/scopes/XEH_PREP.hpp @@ -2,8 +2,15 @@ PREP(adjustScope); 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 bef16a0bc1..a7720c62f5 100644 --- a/addons/scopes/XEH_postInit.sqf +++ b/addons/scopes/XEH_postInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, esteldunedain, Ruthberg * @@ -5,126 +6,141 @@ * Defines key bindings * */ -#include "script_component.hpp" if (!hasInterface) exitWith {}; -// Check inventory when it changes -["loadout", FUNC(inventoryCheck)] call CBA_fnc_addPlayerEventHandler; +GVAR(Optics) = ["", "", ""]; +GVAR(Guns) = ["", "", ""]; +GVAR(canAdjustElevation) = [false, false, false]; +GVAR(canAdjustWindage) = [false, false, false]; +GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; -// Instantly hide knobs when scoping in -["cameraView", { - params ["_player", "_newCameraView"]; +["ace_settingsInitialized", { - if (_newCameraView == "GUNNER") then { - private _layer = [QGVAR(Zeroing)] call BIS_fnc_rscLayer; - _layer cutText ["", "PLAIN", 0]; + if (!GVAR(enabled)) exitWith {}; - if !(isNil QGVAR(fadePFH)) then { - [GVAR(fadePFH)] call CBA_fnc_removePerFrameHandler; - GVAR(fadePFH) = nil; - }; + if (GVAR(deduceBarometricPressureFromTerrainAltitude)) then { + GVAR(zeroReferenceBarometricPressure) = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; }; -}] call CBA_fnc_addPlayerEventHandler; -// Add keybinds -["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), localize LSTRING(AdjustUpMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Check inventory when it changes + ["loadout", FUNC(inventoryCheck), true] call CBA_fnc_addPlayerEventHandler; - [ACE_player] call FUNC(inventoryCheck); + // Instantly hide knobs when scoping in + ["cameraView", { + params ["_player", "_newCameraView"]; - // Statement - [ACE_player, ELEVATION_UP, MINOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [201, [false, false, false]], true] call CBA_fnc_addKeybind; + if (_newCameraView == "GUNNER") then { + private _layer = [QGVAR(Zeroing)] call BIS_fnc_rscLayer; + _layer cutText ["", "PLAIN", 0]; -["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), localize LSTRING(AdjustDownMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !(isNil QGVAR(fadePFH)) then { + [GVAR(fadePFH)] call CBA_fnc_removePerFrameHandler; + GVAR(fadePFH) = nil; + }; + }; + }] call CBA_fnc_addPlayerEventHandler; - [ACE_player] call FUNC(inventoryCheck); + // Add keybinds + ["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), localize LSTRING(AdjustUpMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - // Statement - [ACE_player, ELEVATION_DOWN, MINOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [209, [false, false, false]], true] call CBA_fnc_addKeybind; + [ACE_player] call FUNC(inventoryCheck); -["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), localize LSTRING(AdjustLeftMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Statement + [ACE_player, ELEVATION_UP, MINOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [201, [false, false, false]], true] call CBA_fnc_addKeybind; - [ACE_player] call FUNC(inventoryCheck); + ["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), localize LSTRING(AdjustDownMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - // Statement - [ACE_player, WINDAGE_LEFT, MINOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [209, [false, true, false]], true] call CBA_fnc_addKeybind; + [ACE_player] call FUNC(inventoryCheck); -["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), localize LSTRING(AdjustRightMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Statement + [ACE_player, ELEVATION_DOWN, MINOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [209, [false, false, false]], true] call CBA_fnc_addKeybind; - [ACE_player] call FUNC(inventoryCheck); + ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), localize LSTRING(AdjustLeftMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - // Statement - [ACE_player, WINDAGE_RIGHT, MINOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [201, [false, true, false]], true] call CBA_fnc_addKeybind; + [ACE_player] call FUNC(inventoryCheck); -["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), localize LSTRING(AdjustUpMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Statement + [ACE_player, WINDAGE_LEFT, MINOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [209, [false, true, false]], true] call CBA_fnc_addKeybind; - [ACE_player] call FUNC(inventoryCheck); + ["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), localize LSTRING(AdjustRightMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - // Statement - [ACE_player, ELEVATION_UP, MAJOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [201, [true, false, false]], true] call CBA_fnc_addKeybind; + [ACE_player] call FUNC(inventoryCheck); -["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), localize LSTRING(AdjustDownMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Statement + [ACE_player, WINDAGE_RIGHT, MINOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [201, [false, true, false]], true] call CBA_fnc_addKeybind; - [ACE_player] call FUNC(inventoryCheck); + ["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), localize LSTRING(AdjustUpMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - // Statement - [ACE_player, ELEVATION_DOWN, MAJOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [209, [true, false, false]], true] call CBA_fnc_addKeybind; + [ACE_player] call FUNC(inventoryCheck); -["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), localize LSTRING(AdjustLeftMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Statement + [ACE_player, ELEVATION_UP, MAJOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [201, [true, false, false]], true] call CBA_fnc_addKeybind; - [ACE_player] call FUNC(inventoryCheck); + ["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), localize LSTRING(AdjustDownMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - // Statement - [ACE_player, WINDAGE_LEFT, MAJOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [209, [true, true, false]], true] call CBA_fnc_addKeybind; + [ACE_player] call FUNC(inventoryCheck); -["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), localize LSTRING(AdjustRightMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + // Statement + [ACE_player, ELEVATION_DOWN, MAJOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [209, [true, false, false]], true] call CBA_fnc_addKeybind; - [ACE_player] call FUNC(inventoryCheck); + ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), localize LSTRING(AdjustLeftMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - // Statement - [ACE_player, WINDAGE_RIGHT, MAJOR_INCREMENT] call FUNC(adjustScope); -}, {false}, [201, [true, true, false]], true] call CBA_fnc_addKeybind; + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_LEFT, MAJOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [209, [true, true, false]], true] call CBA_fnc_addKeybind; + + ["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), localize LSTRING(AdjustRightMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_RIGHT, MAJOR_INCREMENT] call FUNC(adjustScope); + }, {false}, [201, [true, true, false]], true] call CBA_fnc_addKeybind; -// Register fire event handler -["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; -["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; + // 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/XEH_preInit.sqf b/addons/scopes/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/scopes/XEH_preInit.sqf +++ b/addons/scopes/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/scopes/config.cpp b/addons/scopes/config.cpp index 8388b2d04b..4bef442049 100644 --- a/addons/scopes/config.cpp +++ b/addons/scopes/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = { "ace_common" }; author = ECSTRING(common,ACETeam); - authors[] = {"KoffeinFlummi", "esteldunedain"}; + authors[] = {"KoffeinFlummi", "esteldunedain", "Ruthberg"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; @@ -19,3 +19,5 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "RscTitles.hpp" +#include "ACE_Settings.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/scopes/functions/fnc_adjustScope.sqf b/addons/scopes/functions/fnc_adjustScope.sqf index 9a38ef40cb..1d99e3605f 100644 --- a/addons/scopes/functions/fnc_adjustScope.sqf +++ b/addons/scopes/functions/fnc_adjustScope.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Changes the adjustment for the current scope @@ -15,41 +16,28 @@ * * Public: No */ -#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); -if (isNil "_adjustment") then { - _adjustment = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; // [Windage, Elevation, Zero] -}; +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_LEFT, WINDAGE_RIGHT])) exitWith {false}; -if (isNil QGVAR(Optics)) then { - GVAR(Optics) = ["", "", ""]; -}; - -_optic = GVAR(Optics) select _weaponIndex; -_opticConfig = configFile >> "CfgWeapons" >> _optic; -_verticalIncrement = getNumber (_opticConfig >> "ACE_ScopeAdjust_VerticalIncrement"); -_horizontalIncrement = getNumber (_opticConfig >> "ACE_ScopeAdjust_HorizontalIncrement"); -_maxVertical = getArray (_opticConfig >> "ACE_ScopeAdjust_Vertical"); -_maxHorizontal = getArray (_opticConfig >> "ACE_ScopeAdjust_Horizontal"); - -if ((count _maxHorizontal < 2) || (count _maxVertical < 2)) exitWith {false}; -if ((_verticalIncrement == 0) && (_turretAndDirection in [ELEVATION_UP, ELEVATION_DOWN])) exitWith {false}; -if ((_horizontalIncrement == 0) && (_turretAndDirection in [WINDAGE_UP, WINDAGE_DOWN])) 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 }; case ELEVATION_DOWN: { _elevation = _elevation - _verticalIncrement }; @@ -66,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 9e953d0523..56c3404a7c 100644 --- a/addons/scopes/functions/fnc_adjustZero.sqf +++ b/addons/scopes/functions/fnc_adjustZero.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg - * Updates the zero reference for the current scope + * Updates the zero adjustment of the current scope * * Arguments: * 0: Unit @@ -13,29 +14,29 @@ * * Public: No */ -#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); -if (isNil "_adjustment") then { - // [Windage, Elevation, Zero] - _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 7067b0442c..e64abb30fc 100644 --- a/addons/scopes/functions/fnc_applyScopeAdjustment.sqf +++ b/addons/scopes/functions/fnc_applyScopeAdjustment.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, Ruthberg * Applies the adjustment for the current scope @@ -16,22 +17,13 @@ * * Public: No */ -#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); -if (isNil "_adjustment") then { - // [Windage, Elevation, Zero] - _adjustment = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; - _unit setVariable [QGVAR(Adjustment), _adjustment]; -}; - -_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]]; @@ -41,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 new file mode 100644 index 0000000000..017c617ebc --- /dev/null +++ b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf @@ -0,0 +1,77 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Calculates the zero angle correction for the new zero range based on current zero range and bore height (distance between bore- and sight axis) + * + * Arguments: + * 0: Zero range + * 1: Bore height + * 2: Weapon + * 3: Ammo + * 4: Magazine + * 5: Advanced Ballistics enabled? + * + * Return Value: + * zeroAngleCorrection + * + * Example: + * [5, 6, gun, ammo, magazine, true] call ace_scopes_fnc_calculateZeroAngleCorrection + * + * Public: No + */ + +params ["_oldZeroRange", "_newZeroRange", "_boreHeight"/*in cm*/, "_weapon", "_ammo", "_magazine", "_advancedBallistics"]; + +private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); +private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); +private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed"); +if (_initSpeedCoef > 0) then { + _initSpeed = _initSpeedCoef; +}; +if (_initSpeedCoef < 0) then { + _initSpeed = _initSpeed * (-1 * _initSpeedCoef); +}; + +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 ["calcZero:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight]; + (parseNumber _zeroAngle) +} else { + // Get Weapon and Ammo Configurations + private _AmmoCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _ammo]; + if (isNil "_AmmoCacheEntry") then { + _AmmoCacheEntry = _ammo call EFUNC(advanced_ballistics,readAmmoDataFromConfig); + }; + private _WeaponCacheEntry = uiNamespace getVariable format[QEGVAR(advanced_ballistics,%1), _weapon]; + if (isNil "_WeaponCacheEntry") then { + _WeaponCacheEntry = _weapon call EFUNC(advanced_ballistics,readWeaponDataFromConfig); + }; + + _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 { + private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _initSpeed] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); + _initSpeed = _initSpeed + _barrelVelocityShift; + }; + + 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) +}; + +private _zeroAngleCorrection = _trueZero - _vanillaZero; + +missionNamespace setVariable [format[QGVAR(%1_%2_%3_%4_%5_%6_%7), _oldZeroRange, _newZeroRange, _boreHeight, _weapon, _ammo, _magazine, _advancedBallistics], _zeroAngleCorrection]; + +_zeroAngleCorrection diff --git a/addons/scopes/functions/fnc_canAdjustZero.sqf b/addons/scopes/functions/fnc_canAdjustZero.sqf index 477dc12635..d9c2903cbd 100644 --- a/addons/scopes/functions/fnc_canAdjustZero.sqf +++ b/addons/scopes/functions/fnc_canAdjustZero.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * 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 @@ -13,26 +14,19 @@ * * Public: No */ -#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); -if (isNil "_adjustment") then { - // [Windage, Elevation, Zero] - _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..c398294684 --- /dev/null +++ b/addons/scopes/functions/fnc_canResetZero.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 5d3b975dbf..8870592885 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: KoffeinFlummi, esteldunedain + * Author: KoffeinFlummi, esteldunedain, Ruthberg * Adjusts the flight path of the bullet according to the zeroing. Called from the unified fired EH only for local and non-local players on foot. * * Arguments: @@ -8,26 +9,49 @@ * Return Value: * None * + * Example: + * call ace_scopes_fnc_firedEH + * * 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 _adjustment = _unit getVariable [QGVAR(Adjustment), []]; -if (_adjustment isEqualTo []) exitWith {}; +if (!(_ammo isKindOf "BulletBase")) exitWith {}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; -private _zeroing = _adjustment select _weaponIndex; +private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _zeroing = (_adjustment select _weaponIndex) vectorMultiply 0.05729578; // Convert zeroing from mils to degrees (value of MRAD_TO_DEG(1)) TRACE_1("Adjusting With",_zeroing); +if (GVAR(correctZeroing) || GVAR(simplifiedZeroing)) then { + private _advancedBallistics = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; + 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); + TRACE_7("new calc",_oldZeroRange,_newZeroRange,_boreHeight,_weapon,_ammo,_magazine,_advancedBallistics); + TRACE_1("",_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 +}; + +TRACE_1("",_zeroing); if (_zeroing isEqualTo [0, 0, 0]) exitWith {}; -// Convert zeroing from mils to degrees -_zeroing = _zeroing vectorMultiply 0.05625; _zeroing params ["_elevation", "_windage", "_zero"]; [_projectile, _windage, _elevation + _zero, 0] call EFUNC(common,changeProjectileDirection); diff --git a/addons/scopes/functions/fnc_getBaseAngle.sqf b/addons/scopes/functions/fnc_getBaseAngle.sqf new file mode 100644 index 0000000000..da5e965938 --- /dev/null +++ b/addons/scopes/functions/fnc_getBaseAngle.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 new file mode 100644 index 0000000000..8926585989 --- /dev/null +++ b/addons/scopes/functions/fnc_getBoreHeight.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Gets the bore height of the weapon & optic combination with the given weapon index + * + * Arguments: + * 0: Unit + * 1: Weapon index + * + * Return Value: + * bore height + * + * Example: + * [player, 0] call ace_scopes_fnc_getBoreHeight + * + * Public: Yes + */ + +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; + +if (_opticsClass == "") then { _opticsClass = _weaponClass; }; + +// Determine rail height above bore +private _railHeightAboveBore = 0; +private _weaponConfig = configFile >> "CfgWeapons" >> _weaponClass; +if (isNumber (_weaponConfig >> "ACE_RailHeightAboveBore")) then { + _railHeightAboveBore = getNumber(_weaponConfig >> "ACE_RailHeightAboveBore"); +} else { + switch (_weaponIndex) do { + case 0: { _railHeightAboveBore = 3.0; }; // Rifle + case 2: { _railHeightAboveBore = 0.7; }; // Pistol + }; +}; +// Determine scope height above rail +private _scopeHeightAboveRail = 0; +private _opticConfig = configFile >> "CfgWeapons" >> _opticsClass; +if (isNumber (_opticConfig >> "ACE_ScopeHeightAboveRail")) then { + _scopeHeightAboveRail = getNumber(_opticConfig >> "ACE_ScopeHeightAboveRail"); +} else { + switch (getNumber(_opticConfig >> "ItemInfo" >> "opticType")) do { + case 1: { _scopeHeightAboveRail = 4.5; }; // RCO or similar + case 2: { _scopeHeightAboveRail = 4.0; }; // High power scope + default { + switch (_weaponIndex) do { + case 0: { _scopeHeightAboveRail = 2.0; }; // Rifle iron sights + case 2: { _scopeHeightAboveRail = 1.0; }; // Pistol iron sights + }; + }; + }; +}; + +(_railHeightAboveBore + _scopeHeightAboveRail) diff --git a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf new file mode 100644 index 0000000000..6425fe047a --- /dev/null +++ b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +/* + * Author: Ruthberg + * Gets the zero range of the currently used optic + * + * Arguments: + * 0: Unit + * + * Return Value: + * current zero range + * + * Example: + * [player] call ace_scopes_fnc_getCurrentZeroRange + * + * Public: No + */ + +params ["_unit"]; + +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 { + if (!(GVAR(canAdjustElevation) select _weaponIndex)) exitWith { currentZeroing _unit }; + 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 { + (configFile >> "CfgWeapons" >> _optic) +} else { + (configFile >> "CfgWeapons" >> (GVAR(Guns) select _weaponIndex)) +}; + +private _zeroRange = currentZeroing _unit; +if (GVAR(overwriteZeroRange) && {GVAR(canAdjustElevation) select _weaponIndex}) then { + _zeroRange = GVAR(defaultZeroRange); +}; +if (isNumber (_opticConfig >> "ACE_ScopeZeroRange")) then { + _zeroRange = getNumber(_opticConfig >> "ACE_ScopeZeroRange"); +}; + +_zeroRange diff --git a/addons/scopes/functions/fnc_getOptics.sqf b/addons/scopes/functions/fnc_getOptics.sqf index 64ad73ebdd..c9c1216d99 100644 --- a/addons/scopes/functions/fnc_getOptics.sqf +++ b/addons/scopes/functions/fnc_getOptics.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Gets the optic classnames of all currently equipped weapons. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/scopes/functions/fnc_initModuleSettings.sqf b/addons/scopes/functions/fnc_initModuleSettings.sqf new file mode 100644 index 0000000000..b0bf38492d --- /dev/null +++ b/addons/scopes/functions/fnc_initModuleSettings.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" +/* + * Author: Glowbal, Ruthberg + * Module for adjusting the scopes settings + * + * Arguments: + * 0: The module logic + * 1: units + * 2: activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_scopes_fnc_initModuleSettings + * + * Public: No + */ + +params ["_logic","_units", "_activated"]; + +if !(_activated) exitWith {}; + +[_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(forceUseOfAdjustmentTurrets), "forceUseOfAdjustmentTurrets"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(correctZeroing), "correctZeroing"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(overwriteZeroRange), "overwriteZeroRange"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(defaultZeroRange), "defaultZeroRange"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(zeroReferenceTemperature), "zeroReferenceTemperature"] call EFUNC(common,readSettingFromModule); +[_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) 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 1a79ef0418..68a76e6ffe 100644 --- a/addons/scopes/functions/fnc_inventoryCheck.sqf +++ b/addons/scopes/functions/fnc_inventoryCheck.sqf @@ -1,5 +1,6 @@ +#include "script_component.hpp" /* - * Author: KoffeinFlummi, Commy2 + * Author: KoffeinFlummi, Commy2, Ruthberg * Check if weapon optics changed and reset zeroing if needed * * Arguments: @@ -13,32 +14,136 @@ * * Public: No */ -#include "script_component.hpp" params ["_player"]; -private _adjustment = ACE_player getVariable QGVAR(Adjustment); -if (isNil "_adjustment") then { - // [Windage, Elevation, Zero] - _adjustment = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; - ACE_player setVariable [QGVAR(Adjustment), _adjustment]; - [ACE_player, QGVAR(Adjustment), _adjustment, 0.5] call EFUNC(common,setVariablePublic); -}; +private _adjustment = ACE_player getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; +private _updateAdjustment = false; -if (isNil QGVAR(Optics)) then { - GVAR(Optics) = ["", "", ""]; -}; private _newOptics = [_player] call FUNC(getOptics); - { if (_newOptics select _forEachIndex != _x) then { - // The optic for this weapon changed, set adjustment to zero - if (!((_adjustment select _forEachIndex) isEqualTo [0, 0, 0])) then { - _adjustment set [_forEachIndex, [0, 0, 0]]; - [ACE_player, QGVAR(Adjustment), _adjustment, 0.5] call EFUNC(common,setVariablePublic); + private _opticConfig = configFile >> "CfgWeapons" >> (_newOptics select _forEachIndex); + private _opticType = getNumber(_opticConfig >> "ItemInfo" >> "opticType"); + private _maxVertical = []; + private _verticalIncrement = -1; + private _maxHorizontal = []; + 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 (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]; + (GVAR(scopeAdjust) select _forEachIndex) set [2, _maxHorizontal]; + (GVAR(scopeAdjust) select _forEachIndex) set [3, _horizontalIncrement]; + GVAR(canAdjustElevation) set [_forEachIndex, (_verticalIncrement > 0) && !(_maxVertical isEqualTo [0, 0])]; + GVAR(canAdjustWindage) set [_forEachIndex, (_horizontalIncrement > 0) && !(_maxHorizontal isEqualTo [0, 0])]; }; } forEach GVAR(Optics); -_adjustment = ACE_player getVariable QGVAR(Adjustment); +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 { + _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 _maxVertical = [0, 0]; + private _verticalIncrement = 0; + private _maxHorizontal = [0, 0]; + 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); + (GVAR(scopeAdjust) select _x) set [0, _maxVertical]; + (GVAR(scopeAdjust) select _x) set [1, _verticalIncrement]; + (GVAR(scopeAdjust) select _x) set [2, _maxHorizontal]; + (GVAR(scopeAdjust) select _x) set [3, _horizontalIncrement]; + 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); +}; + GVAR(Optics) = _newOptics; +GVAR(Guns) = _newGuns; diff --git a/addons/scopes/functions/fnc_resetZero.sqf b/addons/scopes/functions/fnc_resetZero.sqf new file mode 100644 index 0000000000..4f4510a55d --- /dev/null +++ b/addons/scopes/functions/fnc_resetZero.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 530f5cb1d2..ada869b5fd 100644 --- a/addons/scopes/functions/fnc_showZeroing.sqf +++ b/addons/scopes/functions/fnc_showZeroing.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: KoffeinFlummi, esteldunedain * Display the adjustment knobs, update their value and fade them out later @@ -13,18 +14,13 @@ * * Public: No */ -#include "script_component.hpp" disableSerialization; private _weaponIndex = [ACE_player, currentWeapon ACE_player] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; -private _adjustment = ACE_player getVariable QGVAR(Adjustment); -if (isNil "_adjustment") then { - // [Windage, Elevation, Zero] - _adjustment = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; -}; +private _adjustment = ACE_player getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; // Display the adjustment knobs private _layer = [QGVAR(Zeroing)] call BIS_fnc_rscLayer; @@ -39,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 402f390f63..9e867a9bd2 100644 --- a/addons/scopes/script_component.hpp +++ b/addons/scopes/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #define ELEVATION_UP 0 @@ -15,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 8dc7a9eba0..a5e5dcec33 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -1,113 +1,456 @@ - + + + Scopes + Zielfernrohre + スコープ + 조준경 + Celowniki optyczne + Scopes + Mirini + 瞄准镜 + 瞄準鏡 + + + Enable ACE Scope adjustment + Aktiviere das Nullen von Zielfernrohren + ACE スコープ調節を有効化 + ACE 조준경 영점조작 활성화 + Włącz ustawienia celowników optycznych ACE + Active ACE Scope adjustment + Abilita Regolazione mirino ACE + 开启ACE瞄准镜归零调节 + 開啟ACE瞄準鏡歸零調節 + + + Enable adjustment turrets on high powered scopes + Aktiviere Absehenverstellungen für Waffen mit Zielfernrohren + 高倍率スコープでACE スコープ調節を有効化 + 고성능 조준경 조절 나사 활성화 + Włącz pokrętła regulacyjne + Permet de régler la hausse et la dérive sur les optiques de visée à fort grossissement + Abilita la regolazione delle torrette nei mirini a lunga gittata + 开启高倍率瞄准镜归零调节 + 開啟高倍率瞄準鏡歸零調節 + + + Force adjustment turrets + Erzwinge Absehenverstellungen + ACE スコープ調節を有効化 + 조절 나사 강제 + Wymuś użycie pokręteł regulacyjnych + Impose le réglage de la hausse/dérive + Forza la regolazione delle torrette + 强制使用归零调节 + 強制使用歸零調節 + + + 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 + Impose le réglage de la hausse/dérive sur les optiques de visée à fort grossissement + Forza l'uso della regolazione nei mirini a lunga gittata + 强制为高倍率瞄准镜开启归零调节 + 強制為高倍率瞄準鏡開啟歸零調節 + + + Correct zeroing + Nullungsanpassung + ゼロイン調節 + 영점 고치기 + Poprawka zerowania + Corrige le zérotage + Correggi azzeramento + 修正归零 + 修正歸零 + + + Corrects the zeroing of all small arms sights + Korrigiert alle Nullungen von Handfeuerwaffen + 全ての小口径用照準器のゼロインを調節します + 모든 소화기의 영점을 고칩니다 + Poprawia zerowanie wszystkich celowników broni ręcznej + Corrige le zérotage des optiques de visée des petites armes + Corregge l'azzeramento di tutti i mirini di bassa portata + 为所有小口径武器修正归零 + 為所有小口徑武器修正歸零 + + + Overwrite zero distance + Überschreibe Nullung + ゼロイン距離を上書き + 영점거리 덮어쓰기 + Nadpisuje ustawienie dla zerowego dystansu + Remplace la distance de zérotage + Sovrascrivi la distanza zero + 覆写归零距离 + 覆寫歸零距離 + + + 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 + Utilise le paramètre 'defaultZeroRange' pour remplacer la distance de zérotage sur les optiques de visée à fort grossissement + Usa le impostazioni di "defaultZeroRange" (Portata Zero Predefinita) per sovrascrivere la portata zero dei mirini a lunga gittata + 使用'defaultZeroRange'来为高倍率瞄准镜覆写预设归零距离 + 使用'defaultZeroRange'來為高倍率瞄準鏡覆寫預設歸零距離 + + + Default zero distance + Standard Nullung + 標準のゼロイン距離 + 기본설정 영점거리 + Domyślne zerowanie + Distance de zérotage par défaut + Distanza zero predefinita + 预设归零距离 + 預設歸零距離 + + + 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 + Distance de zérotage par défaut des optiques de visée à fort grossissement + I mirini a lunga gittata verranno azzerrati a questa distanza + 高倍率瞄准镜将归零在这个距离上 + 高倍率瞄準鏡將歸零在這個距離上 + + + Reference temperature + Bezugstemperatur + 温度の参照 + 온도 기준 + Referencyjna temperatura + Température de référence + Temperatura di riferimento + 参考温度 + 參考溫度 + + + Temperature at which the scope was zeroed + Temperatur bei der das Zielfernrohr genullt wurde + スコープがゼロインされる温度 + 조준경 영점조준시 온도 + Temperatura, przy której celownik został wyzerowany + Température de référence pour le zérotage des optiques + Temperatura a cui è stato azzerato il mirino + 武器参考多少温度来进行归零. + 武器參考多少溫度來進行歸零. + + + Reference barometric pressure + Bezugsluftdruck + 気圧の参照 + 기압 기준 + Referencyjne ciśnienie barometryczne + Pression barométrique de référence + Pressione barometrica di riferimento + 参考大气压力 + 參考大氣壓力 + + + 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ść + Humidité de référence + Umidità di riferimento + 参考湿度 + 參考濕度 + + + 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 + Pression selon l'altitude + Ricava la pressione dall'altitudine + 高度影响大气压力 + 高度影響大氣壓力 + + + Deduce the barometric pressure from the terrain altitude + Abgeleiteter Luftdruck der Geländeumgebung + 標高により気圧が減少されます + 주변 고도에 맞춰 기압을 설정합니다 + Określ ciśnienie barometryczne na podstawie wysokości terenu + Détermine la pression barométrique selon l'altitude du terrain + Ricava la pressione barometrica dall'altitudine del terreno + 在不同高度上会有不同的大气压力 + 在不同高度上會有不同的大氣壓力 + + + 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. + 라이플스코프 용 바닐라 영점조정 시스템을 복제합니다. + 使用原版的歸零系統來取代ACE複雜的歸零模擬。 + 使用原版的归零系统来取代ACE复杂的归零模拟。 + 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ě) + 僅かに上へ調節 + 위로 조절 + 向上微调 + 向上微調 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ě) + 僅かに下へ調節 + 아래로 조절 + 向下微调 + 向下微調 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ě) + 僅かに右へ調節 + 오론쪽으로 조절 + 向右微调 + 向右微調 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ě) + 僅かに左へ調節 + 왼쪽으로 조절 + 向左微调 + 向左微調 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 + 大きく上へ調節 + 크게 위로 조절 + 向上调整 + 向上調整 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ů + 大きく下へ調節 + 크게 아래로 조절 + 向下调整 + 向下調整 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 + 大きく右へ調節 + 크게 오른쪽으로 조절 + 向右调整 + 向右調整 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 + 大きく左へ調節 + 크게 왼쪽으로 조절 + 向左调整 + 向左調整 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 + ゼロインを調節 + 영점 초기화 + 设定归零 + 設定歸零 + + + 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 + + + Horizontal limits + 水平限制 + 水平制限 + Limite orrizontale + + + Vertical limits + 垂直限制 + 垂直制限 + Limite verticale - \ No newline at end of file + diff --git a/addons/sitting/$PBOPREFIX$ b/addons/sitting/$PBOPREFIX$ deleted file mode 100644 index 419bf892be..0000000000 --- a/addons/sitting/$PBOPREFIX$ +++ /dev/null @@ -1 +0,0 @@ -z\ace\addons\sitting \ No newline at end of file diff --git a/addons/sitting/ACE_Settings.hpp b/addons/sitting/ACE_Settings.hpp deleted file mode 100644 index 49d3e27929..0000000000 --- a/addons/sitting/ACE_Settings.hpp +++ /dev/null @@ -1,7 +0,0 @@ -class ACE_Settings { - class GVAR(enable) { - value = 0; - typeName = "BOOL"; - displayName = CSTRING(Enable); - }; -}; diff --git a/addons/sitting/CfgEventHandlers.hpp b/addons/sitting/CfgEventHandlers.hpp deleted file mode 100644 index 0d7f0a3f64..0000000000 --- a/addons/sitting/CfgEventHandlers.hpp +++ /dev/null @@ -1,35 +0,0 @@ - -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_clientInit)); - }; -}; - -class Extended_Killed_EventHandlers { - class CAManBase { - class ADDON { - killed = QUOTE(_this call DFUNC(handleInterrupt)); - }; - }; -}; - -// Need initPost or there are problems with setVariable -class Extended_InitPost_EventHandlers { - class ThingX { - class ADDON { - init = QUOTE(_this call DFUNC(addSitActions)); - }; - }; -}; diff --git a/addons/sitting/CfgMoves.hpp b/addons/sitting/CfgMoves.hpp deleted file mode 100644 index f203203ed0..0000000000 --- a/addons/sitting/CfgMoves.hpp +++ /dev/null @@ -1,108 +0,0 @@ -// Force free-look, prevent body rotating and leaning -#define MACRO_ANIMATION \ - head = "headDefault"; \ - aimingBody = "aimingNo"; \ - forceAim = 1; \ - static = 1; - -class CfgMovesBasic; -class CfgMovesMaleSdr: CfgMovesBasic { - class States { - class HubSittingChairA_idle1; - class GVAR(HubSittingChairA_idle1): HubSittingChairA_idle1 { - MACRO_ANIMATION - }; - class HubSittingChairA_idle2; - class GVAR(HubSittingChairA_idle2): HubSittingChairA_idle2 { - MACRO_ANIMATION - }; - class HubSittingChairA_idle3; - class GVAR(HubSittingChairA_idle3): HubSittingChairA_idle3 { - MACRO_ANIMATION - }; - class HubSittingChairA_move1; - class GVAR(HubSittingChairA_move1): HubSittingChairA_move1 { - MACRO_ANIMATION - }; - class HubSittingChairB_idle1; - class GVAR(HubSittingChairB_idle1): HubSittingChairB_idle1 { - MACRO_ANIMATION - }; - class HubSittingChairB_idle2; - class GVAR(HubSittingChairB_idle2): HubSittingChairB_idle2 { - MACRO_ANIMATION - }; - class HubSittingChairB_idle3; - class GVAR(HubSittingChairB_idle3): HubSittingChairB_idle3 { - MACRO_ANIMATION - }; - class HubSittingChairB_move1; - class GVAR(HubSittingChairB_move1): HubSittingChairB_move1 { - MACRO_ANIMATION - }; - class HubSittingChairC_idle1; - class GVAR(HubSittingChairC_idle1): HubSittingChairC_idle1 { - MACRO_ANIMATION - }; - class HubSittingChairC_idle2; - class GVAR(HubSittingChairC_idle2): HubSittingChairC_idle2 { - MACRO_ANIMATION - }; - class HubSittingChairC_idle3; - class GVAR(HubSittingChairC_idle3): HubSittingChairC_idle3 { - MACRO_ANIMATION - }; - class HubSittingChairC_move1; - class GVAR(HubSittingChairC_move1): HubSittingChairC_move1 { - MACRO_ANIMATION - }; - class HubSittingChairUA_idle1; - class GVAR(HubSittingChairUA_idle1): HubSittingChairUA_idle1 { - MACRO_ANIMATION - }; - class HubSittingChairUA_idle2; - class GVAR(HubSittingChairUA_idle2): HubSittingChairUA_idle2 { - MACRO_ANIMATION - }; - class HubSittingChairUA_idle3; - class GVAR(HubSittingChairUA_idle3): HubSittingChairUA_idle3 { - MACRO_ANIMATION - }; - class HubSittingChairUA_move1; - class GVAR(HubSittingChairUA_move1): HubSittingChairUA_move1 { - MACRO_ANIMATION - }; - class HubSittingChairUB_idle1; - class GVAR(HubSittingChairUB_idle1): HubSittingChairUB_idle1 { - MACRO_ANIMATION - }; - class HubSittingChairUB_idle2; - class GVAR(HubSittingChairUB_idle2): HubSittingChairUB_idle2 { - MACRO_ANIMATION - }; - class HubSittingChairUB_idle3; - class GVAR(HubSittingChairUB_idle3): HubSittingChairUB_idle3 { - MACRO_ANIMATION - }; - class HubSittingChairUB_move1; - class GVAR(HubSittingChairUB_move1): HubSittingChairUB_move1 { - MACRO_ANIMATION - }; - class HubSittingChairUC_idle1; - class GVAR(HubSittingChairUC_idle1): HubSittingChairUC_idle1 { - MACRO_ANIMATION - }; - class HubSittingChairUC_idle2; - class GVAR(HubSittingChairUC_idle2): HubSittingChairUC_idle2 { - MACRO_ANIMATION - }; - class HubSittingChairUC_idle3; - class GVAR(HubSittingChairUC_idle3): HubSittingChairUC_idle3 { - MACRO_ANIMATION - }; - class HubSittingChairUC_move1; - class GVAR(HubSittingChairUC_move1): HubSittingChairUC_move1 { - MACRO_ANIMATION - }; - }; -}; diff --git a/addons/sitting/CfgVehicles.hpp b/addons/sitting/CfgVehicles.hpp deleted file mode 100644 index 95deed0dd6..0000000000 --- a/addons/sitting/CfgVehicles.hpp +++ /dev/null @@ -1,123 +0,0 @@ - -class CBA_Extended_EventHandlers; - -class CfgVehicles { - class ACE_Module; - class ACE_ModuleSitting: ACE_Module { - author = ECSTRING(common,ACETeam); - category = "ACE"; - displayName = CSTRING(ModuleDisplayName); - function = QFUNC(moduleInit); - scope = 1; - isGlobal = 1; - isSingular = 1; - icon = QPATHTOF(UI\Icon_Module_Sitting_ca.paa); - class Arguments { - class enable { - displayName = CSTRING(Enable); - description = CSTRING(Enable); - typeName = "BOOL"; - defaultValue = 1; - }; - }; - class ModuleDescription { - description = CSTRING(ModuleDescription); - }; - }; - - class Man; - class CAManBase: Man { - class ACE_SelfActions { - class GVAR(Stand) { - displayName = CSTRING(Stand); - condition = QUOTE(_player call FUNC(canStand)); - exceptions[] = {"isNotSitting"}; - statement = QUOTE(_player call FUNC(stand)); - priority = 0; - icon = QPATHTOF(UI\stand_ca.paa); - }; - }; - }; - - // Folding Chair - class ThingX; - class Land_CampingChair_V1_F: ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(canSit) = 1; - GVAR(sitDirection) = 180; - GVAR(sitPosition)[] = {0, -0.1, -0.45}; - EGVAR(dragging,canCarry) = 1; - EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; - EGVAR(dragging,carryDirection) = 180; - }; - // Camping Chair - class Land_CampingChair_V2_F: ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(canSit) = 1; - GVAR(sitDirection) = 180; - GVAR(sitPosition)[] = {0, -0.1, -0.45}; - EGVAR(dragging,canCarry) = 1; - EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; - EGVAR(dragging,carryDirection) = 180; - }; - - // Chair (Plastic) - class Furniture_base_F: ThingX {}; - class Land_ChairPlastic_F: Furniture_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(canSit) = 1; - GVAR(sitDirection) = 90; - GVAR(sitPosition)[] = {0, 0, -0.5}; - EGVAR(dragging,canCarry) = 1; - EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; - EGVAR(dragging,carryDirection) = 270; - }; - // Chair (Wooden) - class Land_ChairWood_F: Furniture_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(canSit) = 1; - GVAR(sitDirection) = 180; - GVAR(sitPosition)[] = {0, -0.05, 0}; - EGVAR(dragging,canCarry) = 1; - EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; - EGVAR(dragging,carryDirection) = 180; - }; - // Office Chair - class Land_OfficeChair_01_F: Furniture_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(canSit) = 1; - GVAR(sitDirection) = 180; - GVAR(sitPosition)[] = {0, 0, -0.6}; - EGVAR(dragging,canCarry) = 1; - EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; - EGVAR(dragging,carryDirection) = 180; - }; - // Rattan Chair - class Land_RattanChair_01_F: Furniture_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - GVAR(canSit) = 1; - GVAR(sitDirection) = 180; - GVAR(sitPosition)[] = {0, -0.1, -1}; // Z must be -1 due to chair's geometry (magic floating seat point) - EGVAR(dragging,canCarry) = 1; - EGVAR(dragging,carryPosition)[] = {0, 0.75, 0.5}; - EGVAR(dragging,carryDirection) = 180; - }; -}; diff --git a/addons/sitting/README.md b/addons/sitting/README.md deleted file mode 100644 index 5237c7145e..0000000000 --- a/addons/sitting/README.md +++ /dev/null @@ -1,11 +0,0 @@ -ace_sitting -=============== - -The Sitting module introduces ability to sit on chairs. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [Jonpas](https://github.com/jonpas) diff --git a/addons/sitting/UI/Icon_Module_Sitting_ca.paa b/addons/sitting/UI/Icon_Module_Sitting_ca.paa deleted file mode 100644 index 1d4bbccb70..0000000000 Binary files a/addons/sitting/UI/Icon_Module_Sitting_ca.paa and /dev/null differ diff --git a/addons/sitting/UI/sit_ca.paa b/addons/sitting/UI/sit_ca.paa deleted file mode 100644 index 1191c3b1e0..0000000000 Binary files a/addons/sitting/UI/sit_ca.paa and /dev/null differ diff --git a/addons/sitting/UI/stand_ca.paa b/addons/sitting/UI/stand_ca.paa deleted file mode 100644 index 08c136f668..0000000000 Binary files a/addons/sitting/UI/stand_ca.paa and /dev/null differ diff --git a/addons/sitting/XEH_PREP.hpp b/addons/sitting/XEH_PREP.hpp deleted file mode 100644 index cb7f51cfd5..0000000000 --- a/addons/sitting/XEH_PREP.hpp +++ /dev/null @@ -1,9 +0,0 @@ - -PREP(addSitActions); -PREP(canSit); -PREP(canStand); -PREP(getRandomAnimation); -PREP(handleInterrupt); -PREP(moduleInit); -PREP(sit); -PREP(stand); diff --git a/addons/sitting/XEH_clientInit.sqf b/addons/sitting/XEH_clientInit.sqf deleted file mode 100644 index 3b6b0ba6c8..0000000000 --- a/addons/sitting/XEH_clientInit.sqf +++ /dev/null @@ -1,17 +0,0 @@ -#include "script_component.hpp" - -// Exit on Headless -if (!hasInterface) exitWith {}; - -["ace_settingsInitialized", { - if ([[QUOTE(ADDON), QGVAR(enable)], ["acex_sitting", "acex_sitting_enable"], "3.8.0"] call EFUNC(common,deprecateComponent)) exitwith {}; - //If not enabled, then do not add CanInteractWith Condition or event handlers: - if (!GVAR(enable)) exitWith {}; - - // Add interaction menu exception - ["isNotSitting", {isNil {(_this select 0) getVariable QGVAR(isSitting)}}] call EFUNC(common,addCanInteractWithCondition); - - // Handle interruptions - ["ace_unconscious", {_this call DFUNC(handleInterrupt)}] call CBA_fnc_addEventHandler; - [QEGVAR(captives,setHandcuffed), {_this call DFUNC(handleInterrupt)}] call CBA_fnc_addEventHandler; -}] call CBA_fnc_addEventHandler; diff --git a/addons/sitting/XEH_preInit.sqf b/addons/sitting/XEH_preInit.sqf deleted file mode 100644 index ea21067b30..0000000000 --- a/addons/sitting/XEH_preInit.sqf +++ /dev/null @@ -1,9 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -#include "XEH_PREP.hpp" - -GVAR(initializedClasses) = []; - -ADDON = true; diff --git a/addons/sitting/config.cpp b/addons/sitting/config.cpp deleted file mode 100644 index 785cb75aeb..0000000000 --- a/addons/sitting/config.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "script_component.hpp" - -class CfgPatches { - class ADDON { - name = COMPONENT_NAME; - units[] = {}; - weapons[] = {}; - requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_interaction"}; - author = ECSTRING(common,ACETeam); - authors[] = {"Jonpas"}; - url = ECSTRING(main,URL); - VERSION_CONFIG; - }; -}; - -#include "ACE_Settings.hpp" -#include "CfgEventHandlers.hpp" -#include "CfgMoves.hpp" -#include "CfgVehicles.hpp" - -class ACE_newEvents { - SetHandcuffed = QEGVAR(captives,setHandcuffed); -}; diff --git a/addons/sitting/functions/fnc_addSitActions.sqf b/addons/sitting/functions/fnc_addSitActions.sqf deleted file mode 100644 index 4c449bac52..0000000000 --- a/addons/sitting/functions/fnc_addSitActions.sqf +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Author: Jonpas - * Adds sit actions. - * - * Arguments: - * 0: Seat - * - * Return Value: - * None - * - * Example: - * [seat] call ace_sitting_fnc_addSitActions - * - * Public: No - */ -#include "script_component.hpp" - -params ["_seat"]; - -private _type = typeOf _seat; - -// Exit if the object is not specified as a seat -if (getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(canSit)) != 1) exitWith {}; - -// only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addSitActions), _this]; -}; - -//If not enabled, don't add actions: -if (!GVAR(enable)) exitWith {}; - -// Exit if class already initialized -if (_type in GVAR(initializedClasses)) exitWith {}; - -GVAR(initializedClasses) pushBack _type; - -TRACE_1("Adding Sit Action",_type); - -private _sitAction = [ - QGVAR(Sit), - localize LSTRING(Sit), - QPATHTOF(UI\sit_ca.paa), - {_this call FUNC(sit)}, - {_this call FUNC(canSit)}, - {}, - [], - [0, 0, 0], - 1.5 -] call EFUNC(interact_menu,createAction); -[_type, 0, ["ACE_MainActions"], _sitAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/sitting/functions/fnc_canSit.sqf b/addons/sitting/functions/fnc_canSit.sqf deleted file mode 100644 index 0ea8f06bc8..0000000000 --- a/addons/sitting/functions/fnc_canSit.sqf +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Author: Jonpas - * Check if the player can sit down. - * - * Arguments: - * 0: Seat - * - * Return Value: - * Can Sit Down - * - * Example: - * [seat] call ace_sitting_fnc_canSit - * - * Public: No - */ -#include "script_component.hpp" - -params ["_seat"]; - -// Sitting enabled, is seat object, not occupied and standing up (or not on a big slope) -GVAR(enable) && -{!(_seat call EFUNC(common,owned))} && -{round (vectorUp _seat select 0) == 0 && {round (vectorUp _seat select 1) == 0} && {round (vectorUp _seat select 2) == 1}} diff --git a/addons/sitting/functions/fnc_canStand.sqf b/addons/sitting/functions/fnc_canStand.sqf deleted file mode 100644 index a051e1784e..0000000000 --- a/addons/sitting/functions/fnc_canStand.sqf +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Author: Jonpas - * Check if the player can stand up (is in sitting position). - * - * Arguments: - * Player - * - * Return Value: - * Can Stand Up - * - * Example: - * player call ace_sitting_fnc_canStand; - * - * Public: No - */ -#include "script_component.hpp" - -params ["_player"]; - -// Sitting -!isNil {_player getVariable QGVAR(isSitting)} diff --git a/addons/sitting/functions/fnc_getRandomAnimation.sqf b/addons/sitting/functions/fnc_getRandomAnimation.sqf deleted file mode 100644 index 8dfe4b8cb3..0000000000 --- a/addons/sitting/functions/fnc_getRandomAnimation.sqf +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Author: Jonpas - * Gets a random animations from the list. - * - * Arguments: - * None - * - * Return Value: - * Random Animation - * - * Example: - * _animation = call ace_sitting_fnc_getRandomAnimation - * - * Public: No - */ -#include "script_component.hpp" - -// Select random animation from Animations Pool -selectRandom [ - QGVAR(HubSittingChairA_idle1), - QGVAR(HubSittingChairA_idle2), - QGVAR(HubSittingChairA_idle3), - QGVAR(HubSittingChairA_move1), - QGVAR(HubSittingChairB_idle1), - QGVAR(HubSittingChairB_idle2), - QGVAR(HubSittingChairB_idle3), - QGVAR(HubSittingChairB_move1), - QGVAR(HubSittingChairC_idle1), - QGVAR(HubSittingChairC_idle2), - QGVAR(HubSittingChairC_idle3), - QGVAR(HubSittingChairC_move1), - QGVAR(HubSittingChairUA_idle1), - QGVAR(HubSittingChairUA_idle2), - QGVAR(HubSittingChairUA_idle3), - QGVAR(HubSittingChairUA_move1), - QGVAR(HubSittingChairUB_idle1), - QGVAR(HubSittingChairUB_idle2), - QGVAR(HubSittingChairUB_idle3), - QGVAR(HubSittingChairUB_move1), - QGVAR(HubSittingChairUC_idle1), - QGVAR(HubSittingChairUC_idle2), - QGVAR(HubSittingChairUC_idle3), - QGVAR(HubSittingChairUC_move1) -] diff --git a/addons/sitting/functions/fnc_handleInterrupt.sqf b/addons/sitting/functions/fnc_handleInterrupt.sqf deleted file mode 100644 index c7e0a545ff..0000000000 --- a/addons/sitting/functions/fnc_handleInterrupt.sqf +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Author: Jonpas - * Handles interruptions of sitting, like killed or unconsciousness. - * - * Arguments: - * 0: Player - * - * Return Value: - * None - * - * Example: - * player call ace_sitting_fnc_handleInterrupt - * - * Public: No - */ -#include "script_component.hpp" - -params ["_player"]; - -if (!isNil {_player getVariable QGVAR(isSitting)}) then { - _player call FUNC(stand); -}; diff --git a/addons/sitting/functions/fnc_moduleInit.sqf b/addons/sitting/functions/fnc_moduleInit.sqf deleted file mode 100644 index c21d92afbb..0000000000 --- a/addons/sitting/functions/fnc_moduleInit.sqf +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Author: Jonpas - * Initializes the Sitting module. - * - * Arguments: - * 0: The module logic - * 1: Units - * 2: Activated - * - * Return Value: - * None - * - * Public: No - */ -#include "script_component.hpp" - -if !(isServer) exitWith {}; - -params ["_logic", "_units", "_activated"]; - -if (!_activated) exitWith {}; - -[_logic, QGVAR(enable), "enable"] call EFUNC(common,readSettingFromModule); - -ACE_LOGINFO("Sitting Module Initialized."); diff --git a/addons/sitting/functions/fnc_sit.sqf b/addons/sitting/functions/fnc_sit.sqf deleted file mode 100644 index c2ca725d5d..0000000000 --- a/addons/sitting/functions/fnc_sit.sqf +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Author: Jonpas - * Sits down the player. - * - * Arguments: - * 0: Seat - * 1: Player - * - * Return Value: - * None - * - * Example: - * [seat, player] call ace_sitting_fnc_sit; - * - * Public: No - */ -#include "script_component.hpp" - -params ["_seat", "_player"]; - -// Overwrite weird position, because Arma decides to set it differently based on current animation/stance... -_player switchMove "amovpknlmstpsraswrfldnon"; - -// Add scroll-wheel action to release object -private _actionID = _player addAction [ - format ["%1", localize LSTRING(Stand)], - QUOTE((_this select 0) call FUNC(stand)), - nil, - 20, - false, - true, - "GetOut", - QUOTE(_this call FUNC(canStand)) -]; - -// Read config -private _configFile = configFile >> "CfgVehicles" >> typeOf _seat; -private _sitDirection = (getDir _seat) + getNumber (_configFile >> QGVAR(sitDirection)); -private _sitPosition = getArray (_configFile >> QGVAR(sitPosition)); - -// Get random animation and perform it (before moving player to ensure correct placement) -[_player, call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations -[_player, "", 1] call EFUNC(common,doAnimation); // Correctly applies animation's config values (such as disallow throwing of grenades, intercept keybinds... etc). - -// Set direction and position -_player setDir _sitDirection; -//modelToWorld returns AGL -_player setPosASL (AGLtoASL (_seat modelToWorld _sitPosition)); - -// Set variables, save seat object on player -_player setVariable [QGVAR(isSitting), [_seat, _actionID]]; -[_player, _seat] call EFUNC(common,claim); // To prevent multiple people sitting on one seat - - -// Add automatical stand PFH in case of interruptions -private _seatPosOrig = getPosASL _seat; -[{ - params ["_args", "_pfhId"]; - _args params ["_player", "_seat", "_seatPosOrig"]; - - // Remove PFH if not sitting any more - if (isNil {_player getVariable QGVAR(isSitting)}) exitWith { - [_pfhId] call CBA_fnc_removePerFrameHandler; - TRACE_1("Remove PFH",_player getVariable [ARR_2(QGVAR(isSitting), false)]); - }; - - // Stand up if chair gets deleted or moved - if (isNull _seat || !((getPosASL _seat) isEqualTo _seatPosOrig)) exitWith { - _player call FUNC(stand); - TRACE_2("Chair moved",getPosASL _seat,_seatPosOrig); - }; -}, 0, [_player, _seat, _seatPosOrig]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/sitting/functions/fnc_stand.sqf b/addons/sitting/functions/fnc_stand.sqf deleted file mode 100644 index 7c6a93c662..0000000000 --- a/addons/sitting/functions/fnc_stand.sqf +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Author: Jonpas - * Stands up the player. - * - * Arguments: - * Player - * - * Return Value: - * None - * - * Example: - * player call ace_sitting_fnc_stand; - * - * Public: No - */ -#include "script_component.hpp" - -params ["_player"]; - -(_player getVariable QGVAR(isSitting)) params ["_seat", "_actionID"]; - -// Remove scroll-wheel action -_player removeAction _actionID; - -// Restore animation -private _animation = switch (currentWeapon _player) do { - case "": {"amovpercmstpsnonwnondnon"}; - case (primaryWeapon _player): {"amovpercmstpslowwrfldnon"}; - case (handgunWeapon _player): {"amovpercmstpslowwpstdnon"}; - default {"amovpercmstpsnonwnondnon"}; -}; - -[_player, _animation, 2] call EFUNC(common,doAnimation); - -// Set variables to nil -_player setVariable [QGVAR(isSitting), nil]; -if (isNull _seat) exitWith {}; -[objNull, _seat] call EFUNC(common,claim); diff --git a/addons/sitting/functions/script_component.hpp b/addons/sitting/functions/script_component.hpp deleted file mode 100644 index 1360c56284..0000000000 --- a/addons/sitting/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\sitting\script_component.hpp" \ No newline at end of file diff --git a/addons/sitting/script_component.hpp b/addons/sitting/script_component.hpp deleted file mode 100644 index 7324da1875..0000000000 --- a/addons/sitting/script_component.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#define COMPONENT sitting -#define COMPONENT_BEAUTIFIED Sitting -#include "\z\ace\addons\main\script_mod.hpp" - -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS -// #define ENABLE_PERFORMANCE_COUNTERS - -#ifdef DEBUG_ENABLED_SITTING - #define DEBUG_MODE_FULL -#endif - -#ifdef DEBUG_SETTINGS_SITTING - #define DEBUG_SETTINGS DEBUG_SETTINGS_SITTING -#endif - -#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/sitting/stringtable.xml b/addons/sitting/stringtable.xml deleted file mode 100644 index f7c7b84b93..0000000000 --- a/addons/sitting/stringtable.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - Sit Down - Hinsetzen - Usiądź - Sentar - Sednout si - Sentarse - S'assoir - Leülés - Сесть - Siediti - - - Stand Up - Aufstehen - Wstań - Levantar - Vstát - Levantarse - Se lever - Felállás - Встать - Alzati - - - Enable Sitting - Sitzen ermöglichen - Habilitar opção para sentar - Aktywuj siadanie - Povolit sezení - Activar asiento - Permettre de s'assoir - Ülés engedélyezése - Разрешить сидение - Abilita seduta - - - Sitting - Hinsetzen - Sentado - Siadanie - Sezení - Sentarse - S'assoir - Ülés - Сидение - Sedersi - - - This module allows you to disable the ability to sit on chairs. - Dieses Modul eröffnet die Möglichkeit, sich auf Stühlen hinzusetzen. - Este módulo permite que você desabilite a capacidade de sentar-se em cadeiras e banheiros. - Moduł ten pozwala na włączenie lub wyłączenie możliwości siadania na krzesłach i toaletach. - Tento modul dovoluje zakázat možnost sedět na židlých a toaletách. - Este módulo te permite desactivar la capacidad de sentarse en sillas. - Ce module contrôle la capacité de s'assoir sur des chaises ou sur des toilettes - Ez a modul lehetővé teszi a székekre és toalettekre való leülés letiltását. - Этот модуль позволяет вам запретить возможность садиться на стулья и туалеты. - Questo modulo ti permette di disabilitare la possibilità di sederti sulle sedie. - - - \ No newline at end of file diff --git a/addons/slideshow/CfgVehicles.hpp b/addons/slideshow/CfgVehicles.hpp index af3108eb59..6c11ba866c 100644 --- a/addons/slideshow/CfgVehicles.hpp +++ b/addons/slideshow/CfgVehicles.hpp @@ -35,6 +35,12 @@ class CfgVehicles { typeName = "STRING"; defaultValue = ""; }; + class SetName { + displayName = CSTRING(SetName_DisplayName); + description = CSTRING(SetName_Description); + typeName = "STRING"; + defaultValue = ""; + }; class Duration { displayName = CSTRING(Duration_DisplayName); description = CSTRING(Duration_Description); diff --git a/addons/slideshow/XEH_preInit.sqf b/addons/slideshow/XEH_preInit.sqf index 8943a367f8..fdd70d447b 100644 --- a/addons/slideshow/XEH_preInit.sqf +++ b/addons/slideshow/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(slideshows) = 0; diff --git a/addons/slideshow/functions/fnc_addSlideActions.sqf b/addons/slideshow/functions/fnc_addSlideActions.sqf index 177627bb7b..6acd304d32 100644 --- a/addons/slideshow/functions/fnc_addSlideActions.sqf +++ b/addons/slideshow/functions/fnc_addSlideActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Adds controller slide actions. @@ -17,7 +18,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_objects", "_images", "_names", "_controller", "_currentSlideshow"]; diff --git a/addons/slideshow/functions/fnc_autoTransition.sqf b/addons/slideshow/functions/fnc_autoTransition.sqf index fda7b8ce1b..50e8b1d13d 100644 --- a/addons/slideshow/functions/fnc_autoTransition.sqf +++ b/addons/slideshow/functions/fnc_autoTransition.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Handles automatic slide transitions using waitAndExecute in a PFH-like manner resulting in no performance loss. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_objects", "_images", "_varString", "_duration"]; diff --git a/addons/slideshow/functions/fnc_createSlideshow.sqf b/addons/slideshow/functions/fnc_createSlideshow.sqf index 42d1498b88..965a823941 100644 --- a/addons/slideshow/functions/fnc_createSlideshow.sqf +++ b/addons/slideshow/functions/fnc_createSlideshow.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas, DaC * Prepares necessary variables and default image. @@ -8,32 +9,32 @@ * 2: Image Paths * 3: Action Names * 4: Slide Duration (0 disables automatic transitions) + * 5: Set Name (default: localized "Slides") * * Return Value: * None * * Example: - * [[object1, object2, object3], [controller1], ["images\image1.paa", "images\image2.paa"], ["Action1", "Action2"], 5] call ace_slideshow_fnc_createSlideshow + * [[object1, object2, object3], [controller1], ["images\image1.paa", "images\image2.paa"], ["Action1", "Action2"], 5, "My Slides"] call ace_slideshow_fnc_createSlideshow * * Public: Yes */ -#include "script_component.hpp" -private ["_currentSlideshow", "_slidesAction", "_varString"]; params [ ["_objects", [], [[]] ], ["_controllers", [], [[]] ], ["_images", [], [[]] ], ["_names", [], [[]] ], - ["_duration", 0, [0]] + ["_duration", 0, [0]], + ["_setName", localize LSTRING(Interaction), [""]] ]; // Verify data if (_objects isEqualTo []) exitWith { - ACE_LOGERROR("Slideshow Objects field must NOT be empty!"); + ERROR("Slideshow Objects field must NOT be empty!"); }; if (count _images != count _names || {_images isEqualTo []} || {_names isEqualTo []}) exitWith { - ACE_LOGERROR("Slideshow Images or Names fields must NOT be empty and must have equal number of items!"); + ERROR("Slideshow Images or Names fields must NOT be empty and must have equal number of items!"); }; // If no controllers use objects as controllers @@ -41,31 +42,45 @@ if (_controllers isEqualTo []) then { _controllers = _objects; }; -TRACE_4("Information",_objects,_controllers,_images,_names); +TRACE_5("Information",_objects,_controllers,_images,_names,_setName); if (isServer) then { // Default images on whiteboards (first image) { _x setObjectTextureGlobal [0, _images select 0]; } count _objects; - - // Number of slideshows (multiple modules support) - GVAR(slideshows) = GVAR(slideshows) + 1; }; -_currentSlideshow = GVAR(slideshows); // Local variable in case GVAR gets changed during execution of below code +// Number of slideshows (multiple modules support) +GVAR(slideshows) = GVAR(slideshows) + 1; + +private _currentSlideshow = GVAR(slideshows); // Local variable in case GVAR gets changed during execution of below code // If interaction menu module is not present, set default duration value if !(["ace_interact_menu"] call EFUNC(common,isModLoaded)) then { _duration = NOINTERACTMENU_DURATION; - ACE_LOGINFO_1("Interaction Menu module not present, defaulting duration value to %1",_duration); + INFO_1("Interaction Menu module not present, defaulting duration value to %1",_duration); }; // Add interactions if automatic transitions are disabled, else setup automatic transitions if (_duration == 0) then { { + if (_setName == "") then { + _setName = localize LSTRING(Interaction); + }; + // Add Slides sub-action and populate with images - _slidesAction = [QGVAR(Slides), localize LSTRING(Interaction), "", {}, {true}, {(_this select 2) call FUNC(addSlideActions)}, [_objects, _images, _names, _x, _currentSlideshow], [0, 0, 0], 2] call EFUNC(interact_menu,createAction); + private _slidesAction = [ + format [QGVAR(slideshow%1), _currentSlideshow], + _setName, + "", + {}, + {true}, + {(_this select 2) call FUNC(addSlideActions)}, + [_objects, _images, _names, _x, _currentSlideshow], + [0, 0, 0], + 2 + ] call EFUNC(interact_menu,createAction); [_x, 0, ["ACE_MainActions"], _slidesAction] call EFUNC(interact_menu,addActionToObject); nil } count _controllers; @@ -73,7 +88,7 @@ if (_duration == 0) then { if !(isServer) exitWith {}; // Formatted GVAR string (multiple modules support) - _varString = format [QGVAR(slideshow%1), _currentSlideshow]; + private _varString = format [QGVAR(slideshow%1), _currentSlideshow]; TRACE_1("Current Slide",_varString); // Set formatted GVAR to first slide diff --git a/addons/slideshow/functions/fnc_moduleInit.sqf b/addons/slideshow/functions/fnc_moduleInit.sqf index 9c99d15a11..b3cbf8bf43 100644 --- a/addons/slideshow/functions/fnc_moduleInit.sqf +++ b/addons/slideshow/functions/fnc_moduleInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Initializes the module. @@ -10,25 +11,27 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_slideshow_fnc_moduleInit + * * Public: No */ -#include "script_component.hpp" // Exit on Headless Client if (!hasInterface && !isDedicated) exitWith {}; -private ["_objects", "_controllers", "_images", "_names", "_duration"]; params [["_logic", objNull, [objNull]], "_units", "_activated"]; if !(_activated) exitWith {}; if (isNull _logic) exitWith {}; // Extract variables from logic -_objects = [_logic getVariable ["Objects", ""], true, true] call EFUNC(common,parseList); -_controllers = [_logic getVariable ["Controllers", ""], true, true] call EFUNC(common,parseList); -_images = [_logic getVariable ["Images", ""], false, false] call EFUNC(common,parseList); -_names = [_logic getVariable ["Names", ""], false, false] call EFUNC(common,parseList); -_duration = _logic getVariable ["Duration", 0]; +private _objects = [_logic getVariable ["Objects", ""], true, true] call EFUNC(common,parseList); +private _controllers = [_logic getVariable ["Controllers", ""], true, true] call EFUNC(common,parseList); +private _images = [_logic getVariable ["Images", ""], false, false] call EFUNC(common,parseList); +private _names = [_logic getVariable ["Names", ""], false, false] call EFUNC(common,parseList); +private _setName = _logic getVariable ["SetName", ""]; +private _duration = _logic getVariable ["Duration", 0]; // Objects synced to the module { @@ -37,6 +40,6 @@ _duration = _logic getVariable ["Duration", 0]; } count (synchronizedObjects _logic); // Prepare with actions -[_objects, _controllers, _images, _names, _duration] call FUNC(createSlideshow); +[_objects, _controllers, _images, _names, _duration, _setName] call FUNC(createSlideshow); -ACE_LOGINFO_1("Slideshow Module Initialized on %1 Objects", count _objects); +INFO_1("Slideshow Module Initialized on %1 Objects", count _objects); diff --git a/addons/slideshow/script_component.hpp b/addons/slideshow/script_component.hpp index eb8b8746ee..a58ad27b46 100644 --- a/addons/slideshow/script_component.hpp +++ b/addons/slideshow/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_SLIDESHOW diff --git a/addons/slideshow/stringtable.xml b/addons/slideshow/stringtable.xml index 4c45399ba6..7f37e06b01 100644 --- a/addons/slideshow/stringtable.xml +++ b/addons/slideshow/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Prezentace Presentación de diapositivas Mostra Diapositive + スライドショー + 슬라이드 쇼 + 幻燈片 + 幻灯片 This module allows you to set up slide-shows on different objects. One module per image list. Only objects with hiddenSelection 0 are supported. @@ -24,6 +28,10 @@ Este módulo permite configurar una presentación de diapositivas en diferentes objetos. Un módulo por lista de imágenes. Sólo son soportados objetos con hiddenSelection 0. Tento modul umožňuje nastavit prezentaci na různé objekty. Jeden modul na seznam s obrázky. Podporované jsou pouze objekty s hiddenSelection 0. 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) Objects @@ -36,23 +44,31 @@ Objekty Objetos Oggetti + オブジェクト + 물체 + 物件 + 物件 - Object names (can also be synchronized objects) slide-show will be displayed on, separated by commas if multiple. Reference INFO for object support. - Objektnamen (können auch synchronisierte Objekte sein) auf denen die Diavorführung abgepielt wird. Werden ggf. durch Kommata getrennt. Weiteres in der INFO für unterstützte Objekte. + Object names (can also be synchronized objects) slide-show will be displayed on, separated by commas if multiple. + Objektnamen (können auch synchronisierte Objekte sein) auf denen die Diavorführung abgepielt wird. Werden ggf. durch Kommata getrennt. Nom d'objets (peuvent aussi être des objets synchronisés) sur lesquels les diaporamas vont être affichées, séparation par virgule si plusieurs. - Nazwy obiektów (mogą to też być zsynchronizowane obiekty) na których pokaz slajdów zostanie pokazany, oddzielony przecinkiem jeżeli jest ich więcej niż 1. Sprawdź opis modułu aby dowiedzieć się jakie obiekty są wspierane przez moduł. - Objektum nevek (szinkronizált is lehet) amik a vetítésen megjelennek, több darab esetén vesszővel elválasztva. Objektumtámogatásért az INFO-t tekintsd meg. - Nomes dos objetos (também podem ser objetos sincronizados) em que a apresentação de slides será mostrada, separado por vírgulas se for mais de um. Referência INFO para suporte do objeto. - Имена объектов (так же могут использоваться синхронизированные объекты), на которых будет отображаться слайд-шоу, разделенные запятыми. Посмотрите описание, чтобы понять, какие объекты поддерживаются. - Los nombres de objetos (también pueden ser objetos sincronizados) de diapositivas se mostrarán en, separados por comas. Referencia INFO para el soporte del objeto. - Jména objektů (lze také použít synchronizované objekty) které se budou zobrazovat v prezentaci, oddělit čárkou pokud jich je více. Zkontrolujte POPIS abyste zjistili, zda je objekt podporován modulem. - Nomi di oggetti (possono anche essere oggetti sincronizzati) che verranno usati per la presentazione di diapositive, separato da virgole se più di uno. Fai riferimento ad INFO per gli oggetti supportati. + Nazwy obiektów (mogą to też być zsynchronizowane obiekty) na których pokaz slajdów zostanie pokazany, oddzielony przecinkiem jeżeli jest ich więcej niż 1. + Objektum nevek (szinkronizált is lehet) amik a vetítésen megjelennek, több darab esetén vesszővel elválasztva. + Nomes dos objetos (também podem ser objetos sincronizados) em que a apresentação de slides será mostrada, separado por vírgulas se for mais de um. + Имена объектов (так же могут использоваться синхронизированные объекты), на которых будет отображаться слайд-шоу, разделенные запятыми. + Los nombres de objetos (también pueden ser objetos sincronizados) de diapositivas se mostrarán en, separados por comas. + Jména objektů (lze také použít synchronizované objekty) které se budou zobrazovat v prezentaci, oddělit čárkou pokud jich je více. + Nomi di oggetti (possono anche essere oggetti sincronizzati) che verranno usati per la presentazione di diapositive, separato da virgole se più di uno. + スライドショーを表示するオブジェクト名 (オブジェクトとの同期も可)。複数ある場合はコンマで区切れます + 슬라이드 쇼가 보여질 물체(동기화 되는 물체도 가능합니다) 명칭, 다수의 경우 쉼표로 구분합니다. + 物件名稱 (也可使用同步線來設定),幻燈片將會顯示在該物件上,如有多個物件,請以逗號作區隔 + 物件名称 (也可使用同步线来设定),幻灯片将会显示在该物件上,如有多个物件,请以逗号作区隔 Controllers Steuereinheit - Controleurs + Contrôleurs Kontroler Vezérlők Controles @@ -60,17 +76,25 @@ Controladores Kontrolor Controllori + コントローラ + 조종 장치 + 控制器 + 控制器 Controller object names, separated by commas if multiple. Objekte die als Steuereinheit fungieren. Werden ggf. durch Kommata getrennt. - Noms de controleur d'objets, séparation par virgule si plusieurs + Noms de contrôleur d'objets, séparation par virgule si plusieurs Nazwa obiektu - kontrolera, oddzielona przecinkami jeżeli jest ich więcej niż 1. Vezérlő objektum nevek, vesszővel elválasztva több darab esetén. Nome dos objetos de controle, separado por vírgula se mais de um. Имена объектов-контроллеров, разделенные запятыми. Nombres de objeto de controlador, separados por comas. Nomi di oggetti controllori, separati da virgole se multipli. + コントローラに指定するオブジェクト名を記入し、複数ある場合はコンマで区切れます。 + 조종 장치 물체 명칭, 다수의 경우 쉼표로 구분됩니다. + 指定是控制器的物件名稱,如有多個物件,請以逗號作區隔 + 指定是控制器的物件名称,如有多个物件,请以逗号作区隔 Images @@ -83,6 +107,10 @@ Obrázky Imágenes Immagini + 画像 + 사진 + 圖片 + 图片 List of images that will be used for the slide-show, separated by commas, with full path correctly formatted (eg. images\image.paa). @@ -95,6 +123,10 @@ Lista de imágenes que se utilizarán para la presentación de diapositivas, separadas por comas, con la ruta completa en formato correcto (ej. imágenes\image.paa). Seznam obrázků které budou použity v prezentaci, oddělené čárkami, s kompletní cestou ve správném formátu (např. image\image.paa). 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) Interaction Names @@ -107,6 +139,10 @@ Nombres de interacción Nomi Interazioni Interaktionsnamen + インタラクション名 + 상호작용 명칭 + 互動鍵名稱 + 互动键名称 List of names that will be used for interaction entries, separated by commas, in order of images. @@ -118,10 +154,36 @@ Lista de nombres que se utilizarán para las entradas de interacción, separados por comas, en el orden de las imágenes. Lista di nomi che verranno usati per per le interazioni, separati da virgole, in ordine per immagini. 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 - Durée d'une diapositive + Durée d'un diaporama Czas trwania slajdów Dia időtartam Duração do Slide @@ -130,10 +192,14 @@ Doba trvání snímku Durata Diapositiva Länge der Diavorführung pro Bild + スライドの持続時間 + 슬라이드 지속시간 + 幻燈片顯示時間 + 幻灯片显示时间 Duration of each slide. Default: 0 (Automatic Transitions Disabled) - Durée de chaque diapositive. Dafaut: 0 (transition automatique désactivée) + Durée de chaque diaporama. Défaut: 0 (transition automatique désactivée) Czas trwania poszczególnych slajdów. Domyślnie: 0 (Automatyczne przejścia wyłączone) A diák időtartama. Alapértelmezett: 0 (Automatikus váltás letiltva) Duração de cada slide. Padrão: 0 (Transição automática desabilitada) @@ -142,10 +208,14 @@ Doba trvání každého snímku. Výchozí: 0 (Automatické posouvání je zakázáno) Durata di ogni diapositiva. Default: 0 (Transizioni Automatiche Disabilitate) Länge der Diavorführung pro Bild. Standard: 0 (Automatischer Wechsel deaktiviert) + 各スライドの持続時間。標準:0 (自動的な切り替えは無効) + 매 슬라이드의 지속시간. 기본설정: 0 (자동 전환 비활성화) + 每張幻燈片顯示的時間。 預設:0 (自動換圖已禁用) + 每张幻灯片显示的时间。 预设:0 (自动换图已禁用) Slides - Diapositives + Diapo Slajdy Diák Slides @@ -154,6 +224,10 @@ Snímky Diapositive Dias + スライド + 슬라이드 + 幻燈片 + 幻灯片 - \ No newline at end of file + 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/smallarms/CfgWeapons.hpp b/addons/smallarms/CfgWeapons.hpp index 1cb7979d5b..cc7e3cbf2e 100644 --- a/addons/smallarms/CfgWeapons.hpp +++ b/addons/smallarms/CfgWeapons.hpp @@ -4,7 +4,8 @@ class Mode_FullAuto; class CfgWeapons { class Rifle_Base_F; - class Rifle_Long_Base_F; + class Rifle_Short_Base_F: Rifle_Base_F {}; + class Rifle_Long_Base_F: Rifle_Base_F {}; /////////////////////////////////////////////////////////////////////////////// //////////// SMALL ARMS WEAPONS /////////////////////////////////////////////// @@ -91,7 +92,7 @@ class CfgWeapons { // SMG Vermin //////////////////////////////////////////////////// - class SMG_01_Base: Rifle_Base_F { + class SMG_01_Base: Rifle_Short_Base_F { // http://kriss-usa.com/pdf/operatormanual/ // 1200 rpm class Single: Mode_SemiAuto { @@ -110,7 +111,7 @@ class CfgWeapons { // SMG Scorpion //////////////////////////////////////////////////// - class SMG_02_base_F: Rifle_Base_F { + class SMG_02_base_F: Rifle_Short_Base_F { //http://www.czub.cz/zbrojovka/cz-manual/Instruction-Manual-Scorpion-EVO-3-A1_en.pdf // 1150 rpm @@ -131,7 +132,7 @@ class CfgWeapons { // SMG PDW2000 /////////////////////////////////////////////////// - class pdw2000_base_F: Rifle_Base_F { + class pdw2000_base_F: Rifle_Short_Base_F { modes[] = {"Single", "FullAuto"}; // No burst on this thing class Single: Mode_SemiAuto { diff --git a/addons/smallarms/script_component.hpp b/addons/smallarms/script_component.hpp index ebb2d1539d..9d6d48fa14 100644 --- a/addons/smallarms/script_component.hpp +++ b/addons/smallarms/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_SMALLARMS 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 392cd9a43d..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; - maxHistoryDelay = 10e10; - 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 bdf0c72bd4..8220b21520 100644 --- a/addons/spectator/XEH_preInit.sqf +++ b/addons/spectator/XEH_preInit.sqf @@ -2,41 +2,19 @@ ADDON = false; +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 cadde0db9d..359b96135b 100644 --- a/addons/spectator/config.cpp +++ b/addons/spectator/config.cpp @@ -17,16 +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(Settings_DisplayName); onPlayerKilled = QFUNC(respawnTemplate); onPlayerRespawn = QFUNC(respawnTemplate); + respawnTypes[] = {1,2,3,4,5}; }; }; - -class ACE_newEvents { - spectatorStaged = "ace_spectatorStaged"; - spectatorSet = "ace_spectatorSet"; -}; \ No newline at end of file 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..d61fff40c1 --- /dev/null +++ b/addons/spectator/functions/fnc_cam.sqf @@ -0,0 +1,149 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..236924b255 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_prepareTarget.sqf @@ -0,0 +1,54 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..5286d944e3 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_resetTarget.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..3943823f8a --- /dev/null +++ b/addons/spectator/functions/fnc_cam_setCameraMode.sqf @@ -0,0 +1,88 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..4587af8c34 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_setTarget.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * 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 + */ +#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..ccc761934d --- /dev/null +++ b/addons/spectator/functions/fnc_cam_setVisionMode.sqf @@ -0,0 +1,44 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..3ec0dbe5e6 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_tick.sqf @@ -0,0 +1,83 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..47ad2a2106 --- /dev/null +++ b/addons/spectator/functions/fnc_cam_toggleSlow.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..158bcbd0a5 --- /dev/null +++ b/addons/spectator/functions/fnc_compat_counter.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * 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 + */ +#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..f8817468f1 --- /dev/null +++ b/addons/spectator/functions/fnc_compat_spectatorBI.sqf @@ -0,0 +1,55 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..a8f190bdd4 --- /dev/null +++ b/addons/spectator/functions/fnc_compat_zeus.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..d9e53082ed --- /dev/null +++ b/addons/spectator/functions/fnc_getCameraAttributes.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..a408df73dc --- /dev/null +++ b/addons/spectator/functions/fnc_getGroupIcon.sqf @@ -0,0 +1,161 @@ +#include "script_component.hpp" +/* + * 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 + */ +#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..162967a1aa --- /dev/null +++ b/addons/spectator/functions/fnc_getTargetEntities.sqf @@ -0,0 +1,44 @@ +#include "script_component.hpp" +/* + * 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 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 ce384c496c..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 ((_unit modelToWorldVisual [0,0,0]) 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 a65cc9ddce..0000000000 --- a/addons/spectator/functions/fnc_handleCompass.sqf +++ /dev/null @@ -1,67 +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 = if (_heading < 90) then { - [_SW, _WN, _NE, _ES] -} else { - if (_heading < 180) then { - [_WN, _NE, _ES, _SW] - } else { - if (_heading < 270) then { - [_NE, _ES, _SW, _WN] - } else { - [_ES, _SW, _WN, _NE] - }; - }; -}; - - -{ - _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..b2efb97a5d --- /dev/null +++ b/addons/spectator/functions/fnc_handleFired.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 d1f83690ff..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 [0,0,30], 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\map\markers\military\dot_CA.paa", _color, _x modelToWorldVisual [0,0,3], 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 e5bb7498e0..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",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 52b6e5d8fa..267ce5615f 100644 --- a/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf +++ b/addons/spectator/functions/fnc_moduleSpectatorSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Read spectator settings from module @@ -8,18 +9,18 @@ * 2: activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_spectator_fnc_moduleSpectatorSettings * * Public: No */ -#include "script_component.hpp" - 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..f79c6ce5e9 --- /dev/null +++ b/addons/spectator/functions/fnc_players.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" +/* + * 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 + */ + +allPlayers select { GETVAR(_x,GVAR(isSet),false) } diff --git a/addons/spectator/functions/fnc_respawnTemplate.sqf b/addons/spectator/functions/fnc_respawnTemplate.sqf index 1a36170202..9cd54ac005 100644 --- a/addons/spectator/functions/fnc_respawnTemplate.sqf +++ b/addons/spectator/functions/fnc_respawnTemplate.sqf @@ -1,7 +1,9 @@ +#include "script_component.hpp" /* * 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,33 +13,30 @@ * 3: Respawn Delay * * Return Value: - * None + * None + * + * Example: + * [bob, kevin, 3, 6] call ace_spectator_fnc_respawnTemplate * * Public: No */ -#include "script_component.hpp" +params [["_newCorpse",objNull,[objNull]], ["_oldKiller",objNull,[objNull]], ["_respawn",0,[0]], ["_respawnDelay",0,[0]]]; +TRACE_4("respawnTemplate",_newCorpse,_oldKiller,_respawn,_respawnDelay); -params [["_unit",objNull,[objNull]], ["_killer",objNull,[objNull]], ["_respawn",0,[0]], ["_respawnDelay",0,[0]]]; - -// 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..2ee5140d80 100644 --- a/addons/spectator/functions/fnc_setCameraAttributes.sqf +++ b/addons/spectator/functions/fnc_setCameraAttributes.sqf @@ -1,27 +1,31 @@ +#include "script_component.hpp" /* * 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 @@ -29,40 +33,65 @@ * Public: Yes */ -#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..f524341a1f --- /dev/null +++ b/addons/spectator/functions/fnc_setFocus.sqf @@ -0,0 +1,58 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..d9942cc3ab 100644 --- a/addons/spectator/functions/fnc_setSpectator.sqf +++ b/addons/spectator/functions/fnc_setSpectator.sqf @@ -1,17 +1,18 @@ +#include "script_component.hpp" /* * 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 @@ -19,49 +20,44 @@ * Public: Yes */ -#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 +66,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 +73,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 +89,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 +97,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 8e6c32f568..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 - ACE_LOGWARNING("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..8083a15e0f --- /dev/null +++ b/addons/spectator/functions/fnc_switchFocus.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 31472702fc..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: - * [_dsiplay, 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..c135c74a69 --- /dev/null +++ b/addons/spectator/functions/fnc_ui.sqf @@ -0,0 +1,190 @@ +#include "script_component.hpp" +/* + * Author: SilentSpike + * Handles UI initialisation and destruction + * + * Arguments: + * 0: Init/Terminate + * + * Return Value: + * None + * + * Example: + * [false] call ace_spectator_fnc_ui + * + * Public: No + */ + +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..744e1bfe5e --- /dev/null +++ b/addons/spectator/functions/fnc_ui_draw3D.sqf @@ -0,0 +1,139 @@ +#include "script_component.hpp" +/* + * 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 + */ +#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..c365ca4824 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_fadeList.sqf @@ -0,0 +1,49 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..73d6cf8e89 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_getTreeDataIndex.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..abebcbc69f --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleChildDestroyed.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..aa10af0358 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleKeyDown.sqf @@ -0,0 +1,199 @@ +#include "script_component.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" +/* + * 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 + */ + +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..1ab7213aa1 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleKeyUp.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" +/* + * 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 + */ + +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..225623668d --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleListClick.sqf @@ -0,0 +1,56 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..bcaf90a699 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleLoad.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..6d4e17e401 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMapClick.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..0602c7b4d2 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMapDraw.sqf @@ -0,0 +1,86 @@ +#include "script_component.hpp" +/* + * 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 + */ +#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..ec7632e207 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseButtonDblClick.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..da74c071ba --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseButtonDown.sqf @@ -0,0 +1,51 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..de652f8845 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseMoving.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..8b109d430c --- /dev/null +++ b/addons/spectator/functions/fnc_ui_handleMouseZChanged.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * 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 + */ +#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..c968f39512 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_toggleMap.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" +/* + * Author: Nelson Duarte, AACO + * Function used to toggle the map + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_toggleMap + * + * Public: No + */ + +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..7e6716ba5e --- /dev/null +++ b/addons/spectator/functions/fnc_ui_toggleUI.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..77a8b3ca17 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateCamButtons.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * 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 + */ + +// 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..f715cb1eca --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateHelp.sqf @@ -0,0 +1,138 @@ +#include "script_component.hpp" +#include "\A3\ui_f\hpp\defineDIKCodes.inc" +/* + * 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 + */ +#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..db3065c360 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateIconsToDraw.sqf @@ -0,0 +1,144 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..640f860ec0 --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateListEntities.sqf @@ -0,0 +1,216 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..3ac112e2cb --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateListFocus.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..32337eae3d --- /dev/null +++ b/addons/spectator/functions/fnc_ui_updateWidget.sqf @@ -0,0 +1,89 @@ +#include "script_component.hpp" +/* + * Author: Nelson Duarte, SilentSpike + * Updates spectator UI unit info widget + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_spectator_fnc_ui_updateWidget + * + * Public: No + */ +#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 de1611823b..f6408c786d 100644 --- a/addons/spectator/functions/fnc_updateCameraModes.sqf +++ b/addons/spectator/functions/fnc_updateCameraModes.sqf @@ -1,10 +1,13 @@ +#include "script_component.hpp" /* * Author: SilentSpike * 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 @@ -19,15 +22,16 @@ * Public: Yes */ -#include "script_component.hpp" +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [DFUNC(updateCameraModes),_this]; +}; 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; @@ -35,14 +39,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_updateSides.sqf b/addons/spectator/functions/fnc_updateSides.sqf new file mode 100644 index 0000000000..1f612a3080 --- /dev/null +++ b/addons/spectator/functions/fnc_updateSides.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: SilentSpike + * Adds or removes sides from the selection available to spectate. Local effect. + * + * Default selection is [west,east,resistance,civilian] + * + * Arguments: + * 0: Sides to add + * 1: Sides to remove + * + * Return Value: + * Sides available + * + * Example: + * [[west], [east,civilian]] call ace_spectator_fnc_updateSides + * + * Public: Yes + */ + +params [["_addSides",[],[[]]], ["_removeSides",[],[[]]]]; + +// Add and remove sides +_addSides append (GVAR(availableSides) - _removeSides); + +// Only need array of unique sides +_addSides = _addSides arrayIntersect _addSides; + +GVAR(availableSides) = _addSides; + +_addSides diff --git a/addons/spectator/functions/fnc_updateSpectatableSides.sqf b/addons/spectator/functions/fnc_updateSpectatableSides.sqf deleted file mode 100644 index 57f7756d54..0000000000 --- a/addons/spectator/functions/fnc_updateSpectatableSides.sqf +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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. - * - * Default selection is [west,east,resistance,civilian] - * - * Arguments: - * 0: Sides to add - * 1: Sides to remove - * - * Return Value: - * Spectatable sides - * - * Example: - * [[west], [east,civilian]] call ace_spectator_fnc_updateSpectatableSides - * - * Public: Yes - */ - -#include "script_component.hpp" - -params [["_addSides",[],[[]]], ["_removeSides",[],[[]]]]; - -// Add and remove sides -_addSides append (GVAR(availableSides) - _removeSides); - -// Only need array of unique sides -_addSides = _addSides arrayIntersect _addSides; - -GVAR(availableSides) = _addSides; - -_addSides diff --git a/addons/spectator/functions/fnc_updateUnits.sqf b/addons/spectator/functions/fnc_updateUnits.sqf index e5b15b6bc1..a32198c3de 100644 --- a/addons/spectator/functions/fnc_updateUnits.sqf +++ b/addons/spectator/functions/fnc_updateUnits.sqf @@ -1,75 +1,30 @@ +#include "script_component.hpp" /* * 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",[],[[]]]]; -private ["_sides","_cond","_filteredUnits","_filteredGroups"]; +// Add to the whitelist and prevent list overlap +GVAR(unitBlacklist) = GVAR(unitBlacklist) - _addUnits; +GVAR(unitWhitelist) append _addUnits; -// Unit setting filter -_newUnits = [[],allPlayers,playableUnits,allUnits] select GVAR(filterUnits); - -// Side setting filter -_sides = []; -_cond = [{_this == (side group player)},{(_this getFriend (side group player)) >= 0.6},{(_this getFriend (side group player)) < 0.6},{true}] select GVAR(filterSides); -{ - if (_x call _cond) then { - _sides pushBack _x; - }; -} forEach GVAR(availableSides); - -// Filter units and append to list -_filteredUnits = []; -{ - if ( - (alive _x) && - {(_x isKindOf "CAManBase")} && - {(side group _x) in _sides} && // Side filter - {simulationEnabled _x} && - {!(_x getVariable [QGVAR(isStaged), false])} // Who watches the watchmen? - ) then { - _filteredUnits pushBack _x; - }; -} forEach (_newUnits - GVAR(unitBlacklist)); -_filteredUnits append GVAR(unitWhitelist); - -// Cache icons and colour for drawing -_filteredGroups = []; -{ - // Intentionally re-applied to units in case their status changes - [_x] call FUNC(cacheUnitInfo); - _filteredGroups pushBack (group _x); -} forEach _filteredUnits; - -// Replace previous lists entirely (removes any no longer valid) -GVAR(unitList) = _filteredUnits arrayIntersect _filteredUnits; -GVAR(groupList) = _filteredGroups arrayIntersect _filteredGroups; +// 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 c2bbb09167..eb0e07f256 100644 --- a/addons/spectator/functions/fnc_updateVisionModes.sqf +++ b/addons/spectator/functions/fnc_updateVisionModes.sqf @@ -1,7 +1,8 @@ +#include "script_component.hpp" /* * 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 +15,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 @@ -27,15 +30,16 @@ * Public: Yes */ -#include "script_component.hpp" +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [DFUNC(updateVisionModes),_this]; +}; 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; @@ -43,14 +47,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 7084a88a6d..b4e7c82ac8 100644 --- a/addons/spectator/script_component.hpp +++ b/addons/spectator/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_SPECTATOR @@ -25,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 1a6fef2473..a0f3cb62c7 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -1,16 +1,25 @@ - + + + Spectator + Zuschauer + Spettatore + 旁觀者 + 旁观者 + スペクテイター + 관전자 + - Spectator Settings - Zuschauer Einstellungen - Ustawienia obserwatora - Preferências de Espectador - Настройки спектатора - Nastavení pozorovatele - Ajustes de espectador - Impostazioni Spettatore - Réglages de spectateur + ACE Spectator + ACE Zuschauer + ACE スペクテイター + Spettatore ACE + Spectateur ACE + ACE 旁观者 + ACE 旁觀者 + Obserwator ACE + ACE 관전자 Configure how the spectator system will operate by default. @@ -22,138 +31,28 @@ Konfigurovat výchozí nastavení pozorovatele Configura come il sistema spettatore si comporterà di default. 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 @@ -165,9 +64,13 @@ Modos de cámara Modalità camera Mode de caméra + カメラ モード + 카메라 모드 + 摄影机模式 + 攝影機模式 - 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 @@ -176,6 +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 @@ -187,40 +94,29 @@ Todos Tutte Tous + 全て + 모두 + 所有 + 所有 - - 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 카메라 + 一人称と三人称 + 第一人稱與第三人稱 + 第一人称与第三人称 Vision modes - Sichtmodi + Sichtmodus Tryby wizji Modos de visão Режимы видения @@ -228,9 +124,13 @@ Módy zobrazení Modalità visuali Modes de vision + ビジョン モード + 시야 모드 + 视觉模式 + 視覺模式 - 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 @@ -239,6 +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 @@ -250,6 +154,10 @@ Visión nocturna Visione Notturna Vision nocturne + 夜間暗視 + 야간투시경 + 夜视 + 夜視 Thermal imaging @@ -261,29 +169,26 @@ Imagen térmica Visione Termica Vision thermique + 熱源画像 + 열화상 + 热成像 + 熱成像 - - 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 @@ -295,15 +200,11 @@ Libre Libera Libre + 自由視点 + 자유 + 自由模式 + 自由模式 - - 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 @@ -314,6 +215,10 @@ Normal Normale Normale + 通常 + 정상 + 正常 + 正常 Night @@ -325,6 +230,10 @@ Nocturna Notturno Nuit + 暗視装置 + 야간 + 夜视 + 夜視 Thermal @@ -336,249 +245,29 @@ Térmica Termico Thermique + 熱源画像 + 열상 + 热成像 + 熱成像 - - 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 @@ -588,8 +277,12 @@ Следующий юнит Následující jednotka Siguiente unidad - Prossima Unità + Unità Successiva Unité suivante + 次のユニット + 다음 인원 + 下个单位 + 下個單位 Previous Unit @@ -599,96 +292,30 @@ Предыдущий юнит Předchozí jednotka Anterior unidad - Precedente Unità + Unità Precedente Unité précédente + 前のユニット + 이전 인원 + 上个单位 + 上個單位 - 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à + 慢速度 + 慢速度 + 느린 속도 - \ No newline at end of file + 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 84ce5f177f..d961f0d36b 100644 --- a/addons/spottingscope/CfgVehicles.hpp +++ b/addons/spottingscope/CfgVehicles.hpp @@ -11,13 +11,20 @@ class CfgVehicles { condition = QUOTE([ARR_2(_player,'ACE_SpottingScope')] call EFUNC(common,hasItem)); statement = QUOTE([ARR_2(_player,'ACE_SpottingScope')] call FUNC(place)); showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\w_spottingscope_ca.paa); }; }; }; }; + 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; @@ -43,7 +50,7 @@ class CfgVehicles { class ACE_Actions: ACE_Actions{ class ACE_MainActions: ACE_MainActions { - selection = "main_gun"; + selection = "main_turret_axis"; class ACE_Pickup { selection = ""; displayName = CSTRING(PickUp); @@ -52,7 +59,6 @@ class CfgVehicles { statement = QUOTE([ARR_2(_target,_player)] call FUNC(pickup)); showDisabled = 0; exceptions[] = {}; - priority = 5; icon = QPATHTOF(UI\w_spottingscope_ca.paa); }; }; @@ -74,6 +80,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 +144,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 +193,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 +218,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 a7feade1c3..e80d5e4ef9 100644 --- a/addons/spottingscope/XEH_preInit.sqf +++ b/addons/spottingscope/XEH_preInit.sqf @@ -2,6 +2,18 @@ ADDON = false; +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 969d0b37f5..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/spottingscope/functions/fnc_animateReticle.sqf b/addons/spottingscope/functions/fnc_animateReticle.sqf index 10bbf9b564..adca733814 100644 --- a/addons/spottingscope/functions/fnc_animateReticle.sqf +++ b/addons/spottingscope/functions/fnc_animateReticle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Animate scripted reticle of spotting scope. @@ -8,14 +9,16 @@ * Return Value: * None * + * Example: + * [DISPLAY] call ace_spottingscope_fnc_animateReticle + * * Public: No */ -#include "script_component.hpp" disableSerialization; params ["_display"]; -uinamespace setVariable [QGVAR(dlgSpottingScope), _display]; +uinamespace setVariable [QGVAR(dlgSpottingScope), _display]; private _ctrlReticle = _display displayCtrl IDC_RETICLE; private _ctrlBody = _display displayCtrl IDC_BODY; diff --git a/addons/spottingscope/functions/fnc_pickup.sqf b/addons/spottingscope/functions/fnc_pickup.sqf index 1a15bd7880..2e8a5cc9e2 100644 --- a/addons/spottingscope/functions/fnc_pickup.sqf +++ b/addons/spottingscope/functions/fnc_pickup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * Pick up spotting scope @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_spottingScope", "_unit"]; diff --git a/addons/spottingscope/functions/fnc_place.sqf b/addons/spottingscope/functions/fnc_place.sqf index 06f0e0d63a..ddf02d7e1e 100644 --- a/addons/spottingscope/functions/fnc_place.sqf +++ b/addons/spottingscope/functions/fnc_place.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * Place down spotting scope @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_scopeClass"]; diff --git a/addons/spottingscope/script_component.hpp b/addons/spottingscope/script_component.hpp index f6cc09af7a..14e7867285 100644 --- a/addons/spottingscope/script_component.hpp +++ b/addons/spottingscope/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_SPOTTINGSCOPE diff --git a/addons/spottingscope/stringtable.xml b/addons/spottingscope/stringtable.xml index 3a0b89b857..b11bff24ac 100644 --- a/addons/spottingscope/stringtable.xml +++ b/addons/spottingscope/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -9,9 +9,13 @@ Telescopio Téléscope de visée Zaměřovací dalekohled - Spotting Scope + Cannocchiale Megfigyelő távcső Luneta de observador + 観測用スコープ + 감적 망원경 + 观测镜 + 觀測鏡 Pick up Spotting Scope @@ -21,9 +25,13 @@ Coger telescopio Prendre téléscope de visée Zvednout zaměřovací dalekohled - Raccogli spottingscope + Raccogli Cannocchiale Mefgigy. távcső felvétele Pegar luneta de observador + 観測用スコープを拾う + 감적 망원경 줍기 + 捡起观测镜 + 撿起觀測鏡 Place Spotting Scope @@ -33,9 +41,13 @@ Colocar telescopio Placer téléscope de visée Položit zaměřovací dalekohled - Posiziona spottingscope + Posiziona Cannocchiale Megfigy. távcső elhelyezése Colocar luneta de observador + 観測用スコープを置く + 감적 망원경 배치 + 放置观测镜 + 放置觀測鏡 - \ No newline at end of file + 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..cffac8b57f 100644 --- a/addons/switchunits/XEH_postInit.sqf +++ b/addons/switchunits/XEH_postInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Initializes the SwitchUnits pbo. @@ -14,14 +15,12 @@ * Public: No */ -#include "script_component.hpp" - 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/XEH_preInit.sqf b/addons/switchunits/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/switchunits/XEH_preInit.sqf +++ b/addons/switchunits/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/switchunits/functions/fnc_addMapFunction.sqf b/addons/switchunits/functions/fnc_addMapFunction.sqf index 3a7b20601c..28d9f05b78 100644 --- a/addons/switchunits/functions/fnc_addMapFunction.sqf +++ b/addons/switchunits/functions/fnc_addMapFunction.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Adds a mapClick Eventhandler @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_sides"]; diff --git a/addons/switchunits/functions/fnc_handleMapClick.sqf b/addons/switchunits/functions/fnc_handleMapClick.sqf index b0984631d7..4e8a527445 100644 --- a/addons/switchunits/functions/fnc_handleMapClick.sqf +++ b/addons/switchunits/functions/fnc_handleMapClick.sqf @@ -1,9 +1,10 @@ +#include "script_component.hpp" /* * Author: bux578 * Switches to a unit close to a clicked map position * * Arguments: - * 0: Faction + * 0: Faction * 0: unit * 1: sides * 1: Map Position @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_faction", "_pos"]; _faction params ["", "_sides"]; diff --git a/addons/switchunits/functions/fnc_initPlayer.sqf b/addons/switchunits/functions/fnc_initPlayer.sqf index 7b0c8f2603..e4d663f746 100644 --- a/addons/switchunits/functions/fnc_initPlayer.sqf +++ b/addons/switchunits/functions/fnc_initPlayer.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Initializes the player @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_playerUnit", "_sides"]; diff --git a/addons/switchunits/functions/fnc_isValidAi.sqf b/addons/switchunits/functions/fnc_isValidAi.sqf index 0b6a35c257..39fd0db94d 100644 --- a/addons/switchunits/functions/fnc_isValidAi.sqf +++ b/addons/switchunits/functions/fnc_isValidAi.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Checks if AI is a valid target for switching. @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/switchunits/functions/fnc_markAiOnMap.sqf b/addons/switchunits/functions/fnc_markAiOnMap.sqf index 5d7eac6f1a..5dc1017c48 100644 --- a/addons/switchunits/functions/fnc_markAiOnMap.sqf +++ b/addons/switchunits/functions/fnc_markAiOnMap.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Creates markers for AI units for given sides. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_sidesToShow"]; diff --git a/addons/switchunits/functions/fnc_module.sqf b/addons/switchunits/functions/fnc_module.sqf index 9da63a9510..a2346ff2f4 100644 --- a/addons/switchunits/functions/fnc_module.sqf +++ b/addons/switchunits/functions/fnc_module.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Initializes the SwitchUnits module @@ -15,9 +16,6 @@ * * Public: No */ -#include "script_component.hpp" - -if !(isServer) exitWith {}; params ["_logic", "_units", "_activated"]; @@ -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; -ACE_LOGINFO("SwitchUnits Module Initialized."); +INFO("SwitchUnits Module Initialized."); diff --git a/addons/switchunits/functions/fnc_nearestPlayers.sqf b/addons/switchunits/functions/fnc_nearestPlayers.sqf index f20d5fcf02..9f60c1a6b7 100644 --- a/addons/switchunits/functions/fnc_nearestPlayers.sqf +++ b/addons/switchunits/functions/fnc_nearestPlayers.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Returns an array of alive players in a given radius around a given location @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_position", "_radius"]; diff --git a/addons/switchunits/functions/fnc_startSwitchUnits.sqf b/addons/switchunits/functions/fnc_startSwitchUnits.sqf index 8d4707f040..759ae3cbf4 100644 --- a/addons/switchunits/functions/fnc_startSwitchUnits.sqf +++ b/addons/switchunits/functions/fnc_startSwitchUnits.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Starts the SwitchUnits functionality @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_player"]; if (GVAR(EnableSwitchUnits)) then { diff --git a/addons/switchunits/functions/fnc_switchBack.sqf b/addons/switchunits/functions/fnc_switchBack.sqf index 4c3d05ae54..9762547545 100644 --- a/addons/switchunits/functions/fnc_switchBack.sqf +++ b/addons/switchunits/functions/fnc_switchBack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Switches back to the original player unit @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_originalPlayerUnit"]; diff --git a/addons/switchunits/functions/fnc_switchUnit.sqf b/addons/switchunits/functions/fnc_switchUnit.sqf index 84b766de4d..ab2867c3ef 100644 --- a/addons/switchunits/functions/fnc_switchUnit.sqf +++ b/addons/switchunits/functions/fnc_switchUnit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: bux578 * Switches to the new given player unit @@ -13,7 +14,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/switchunits/script_component.hpp b/addons/switchunits/script_component.hpp index 868fbc0a5d..ec34efc9cd 100644 --- a/addons/switchunits/script_component.hpp +++ b/addons/switchunits/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_SWITCHUNITS diff --git a/addons/switchunits/stringtable.xml b/addons/switchunits/stringtable.xml index 31ba1f1c05..dd2486cbb0 100644 --- a/addons/switchunits/stringtable.xml +++ b/addons/switchunits/stringtable.xml @@ -1,6 +1,15 @@ - + + + Switch Units + Cambia Unità + 切換單位 + 切换单位 + ユニット切り替え + 병력 전환 + Einheitenwechsel + Switched unit Einheit gewechselt @@ -10,19 +19,27 @@ Cambiado de unidad Unité changée Egység átváltva - Cambia unità + Unità cambiata Trocado de unidade + ユニットを切り替え + 切换单位 + 切換單位 + 인원 전환 Trying to switch Versuche zu Wechseln Snažím se přehodit Próba zmiany - Sto provando a cambiare + Provando a cambiare Intentando cambiar Essaye de basculer Tentando trocar Попытка переключения + 切り替えを試す + 전환 시도중 + 尝试切换中 + 嘗試切換中 This unit is too close to the enemy. @@ -35,18 +52,10 @@ Ez az egység túl közel van az ellenséghez. Questa unità è troppo vicina al nemico. 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à + このユニットは敵に近すぎます。 + 그 인원은 적과 너무 가깝습니다. + 这单位太接近敌人了 + 這單位太接近敵人了 Switch to West? @@ -59,6 +68,10 @@ Átváltás BLUFOR-ra? На синих? Cambia per BLUFOR? + 同盟軍へ切り替えますか? + 切换至蓝方? + 切換至藍方? + 청군으로 전환합니까? Allow switching to west units? @@ -71,6 +84,10 @@ Nyugat-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на синих юнитов? Consenti passaggio ad unità BLUFOR? + 同盟軍側ユニットへ切り替えられるようにしますか? + 允许切换至蓝方? + 允許切換至藍方? + 청군 인원으로 전환합니까? Switch to East? @@ -83,6 +100,10 @@ Átváltás OPFOR-ra? На красных? Cambia per OPFOR? + OPFOR軍側へ切り替えますか? + 切换至红方? + 切換至紅方? + 대항군으로 전환합니까? Allow switching to east units? @@ -95,6 +116,10 @@ Kelet-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на красных юнитов? Consenti passaggio ad unità OPFOR? + OPFOR軍側ユニットへ切り替えられるようにしますか? + 允许切换至红方? + 允許切換至紅方? + 대항군 인원으로 전환합니까? Switch to Independent? @@ -107,6 +132,10 @@ Átváltás INDFOR-ra? На независимых? Cambia per INDFOR? + 独立軍へ切り替えますか? + 切换至独立方? + 切換至獨立方? + 독립군 으로 전환합니까? Allow switching to independent units? @@ -119,6 +148,10 @@ Független egységekre való váltás engedélyezése? Разрешить переключаться на независимых юнитов? Consenti passaggio ad unità INDFOR? + 独立軍側ユニットへ切り替えられるようにしますか? + 允许切换至独立方? + 允許切換至獨立方? + 독립군 인원으로 전환합니까? Switch to Civilian? @@ -131,6 +164,10 @@ Átváltás civilre? На гражданских? Cambia per Civili? + 市民へ切り替えますか? + 민간인으로 전환합니까? + 切换至平民方? + 切換至平民方? Allow switching to civilian units? @@ -143,6 +180,10 @@ Civil egységekre való váltás engedélyezése? Разрешить переключаться на гражданских юнитов? Consenti passaggio ad unità civili? + 市民側ユニットへ切り替えられるようにしますか? + 민간인으로 전환하는걸 허가합니까? + 允许切换至平民方? + 允許切換至平民方? Enable Safe Zone? @@ -155,6 +196,10 @@ Biztonságos zóna engedélyezése? Безопасная зона Abilita Zona Sicura? + 安全地帯を有効にしますか? + 안전 지대 활성화? + 启用安全区? + 啟用安全區? Enable a safe zone around enemy units? Players can't switch to units inside of the safe zone. @@ -167,6 +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 @@ -179,18 +228,26 @@ Biztonságos zóna hatóköre Радиус безопасной зоны Raggio Zona Sicura + 安全地帯の半径 + 안전 지대 반경 + 安全区半径 + 安全區半徑 - 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 + 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. @@ -202,6 +259,10 @@ Ce module permet le changement de faction des joueurs Questo modulo ti permette di cambiare lato durante la partita. El módulo permite a las unidades cambiar de bando durante el juego. + モジュールはゲームにおいて、陣営の切り替えを有効にします。 + 이 모듈은 당신을 게임 중에 진영을 바꿀 수 있게 해줍니다. + 此模块允许你在游戏中切换至另一方 + 此模塊允許你在遊戲中切換至另一方 - \ No newline at end of file + diff --git a/addons/tacticalladder/CfgVehicles.hpp b/addons/tacticalladder/CfgVehicles.hpp index 564a034614..d6cf8324b3 100644 --- a/addons/tacticalladder/CfgVehicles.hpp +++ b/addons/tacticalladder/CfgVehicles.hpp @@ -12,7 +12,6 @@ class CfgVehicles { statement = QUOTE([_player] call FUNC(deployTL)); exceptions[] = {}; showDisabled = 1; - priority = 4; }; }; }; @@ -21,6 +20,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); @@ -85,7 +85,6 @@ class CfgVehicles { statement = QUOTE([ARR_2(_player,_target)] call FUNC(pickupTL)); showDisabled = 0; exceptions[] = {}; - priority = 5; }; class ACE_Position { @@ -97,7 +96,6 @@ class CfgVehicles { statement = QUOTE([ARR_2({_this call FUNC(positionTL)},[ARR_2(_player,_target)])] call CBA_fnc_execNextFrame); showDisabled = 0; exceptions[] = {}; - priority = 5; }; }; }; diff --git a/addons/tacticalladder/XEH_preInit.sqf b/addons/tacticalladder/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/tacticalladder/XEH_preInit.sqf +++ b/addons/tacticalladder/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/tacticalladder/config.cpp b/addons/tacticalladder/config.cpp index eddca58449..def7b0ce96 100644 --- a/addons/tacticalladder/config.cpp +++ b/addons/tacticalladder/config.cpp @@ -16,7 +16,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; -}; diff --git a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf index b009028c93..dac503a828 100644 --- a/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_cancelTLdeploy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg, commy2 * Cancel tactical ladder deployment @@ -10,11 +11,10 @@ * None * * Example: - * [_ladder] call ace_tacticalladder_fnc_cancelTLdeploy + * [player, 1] call ace_tacticalladder_fnc_cancelTLdeploy * * Public: No */ -#include "script_component.hpp" #define __ANIMS ["extract_1","extract_2","extract_3","extract_4","extract_5","extract_6","extract_7","extract_8","extract_9","extract_10","extract_11"] @@ -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); @@ -31,6 +32,7 @@ GVAR(ladder) animate ["rotate", 0]; { GVAR(ladder) animate [_x, 0]; + true } count __ANIMS; // remove mouse buttons and hint diff --git a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf index 3703fe1f47..755d13d132 100644 --- a/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf +++ b/addons/tacticalladder/functions/fnc_confirmTLdeploy.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg, commy2 * Confirm tactical ladder deployment @@ -14,17 +15,15 @@ * * Public: No */ -#include "script_component.hpp" 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..1005cf5100 100644 --- a/addons/tacticalladder/functions/fnc_deployTL.sqf +++ b/addons/tacticalladder/functions/fnc_deployTL.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * Deploy tactical ladder @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; @@ -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 c7187acd55..54963d00ae 100644 --- a/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/tacticalladder/functions/fnc_handleInteractMenuOpened.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. @@ -8,12 +9,14 @@ * Return Value: * None * + * Example: + * [bob] call ace_tacticalladder_fnc_handleInteractMenuOpened + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; -if (!isNull (GETMVAR(GVAR(ladder),objNull)) && {GVAR(ladder) in attachedObjects _unit}) then { - [_unit, GVAR(ladder)] call FUNC(cancelTLdeploy); +if (!isNull GETMVAR(GVAR(ladder),objNull) && {GVAR(ladder) in attachedObjects _unit}) then { + [_unit, 1] call FUNC(cancelTLdeploy); }; diff --git a/addons/tacticalladder/functions/fnc_handleKilled.sqf b/addons/tacticalladder/functions/fnc_handleKilled.sqf index c5d6aa1314..a67b41368e 100644 --- a/addons/tacticalladder/functions/fnc_handleKilled.sqf +++ b/addons/tacticalladder/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle death. @@ -8,12 +9,14 @@ * Return Value: * None * + * Example: + * [bob] call ace_tacticalladder_fnc_handleKilled + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; -if (!isNull (GETMVAR(ladder,objNull)) && {GVAR(ladder) in attachedObjects _unit}) then { - [_unit, GVAR(ladder)] call FUNC(cancelTLdeploy); +if (!isNull GETMVAR(ladder,objNull) && {GVAR(ladder) in attachedObjects _unit}) then { + [_unit, 1] call FUNC(cancelTLdeploy); }; diff --git a/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf b/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf index 07118acbaf..25be5fe7bf 100644 --- a/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf +++ b/addons/tacticalladder/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle player changes. @@ -9,18 +10,20 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ace_tacticalladder_fnc_handlePlayerChanged + * * Public: No */ -#include "script_component.hpp" -if (isNull (GETGVAR(ladder,objNull))) exitWith {}; +if (isNull GETGVAR(ladder,objNull)) exitWith {}; params ["_newPlayer", "_oldPlayer"]; if (GVAR(ladder) in attachedObjects _newPlayer) then { - [_newPlayer, GVAR(ladder)] call FUNC(cancelTLdeploy); + [_newPlayer, 1] call FUNC(cancelTLdeploy); }; if (GVAR(ladder) in attachedObjects _oldPlayer) then { - [_oldPlayer, GVAR(ladder)] call FUNC(cancelTLdeploy); + [_oldPlayer, 1] call FUNC(cancelTLdeploy); }; diff --git a/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf b/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf index e7d4136526..4e46b61d4e 100644 --- a/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf +++ b/addons/tacticalladder/functions/fnc_handleScrollWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * Handles lengthening and tilting of the ladder @@ -13,17 +14,15 @@ * * Public: No */ -#include "script_component.hpp" 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 e9ce28d524..ed966a9f72 100644 --- a/addons/tacticalladder/functions/fnc_handleUnconscious.sqf +++ b/addons/tacticalladder/functions/fnc_handleUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle unconsciousness. @@ -8,12 +9,16 @@ * Return Value: * None * + * Example: + * [bob] call ace_tacticalladder_fnc_handleUnconscious + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; -if (!isNull (GETMVAR(ladder,objNull)) && {GVAR(ladder) in attachedObjects _unit}) then { - [_unit, GVAR(ladder)] call FUNC(cancelTLdeploy); +if (!local _unit) exitWith {}; + +if (!isNull GETMVAR(ladder,objNull) && {GVAR(ladder) in attachedObjects _unit}) then { + [_unit, 1] call FUNC(cancelTLdeploy); }; diff --git a/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf b/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf index 8267faf3c4..47c646ef29 100644 --- a/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf +++ b/addons/tacticalladder/functions/fnc_isLadderEmpty.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Checks if Tactical Ladder is empty (no one climbing it). @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_ladder"]; diff --git a/addons/tacticalladder/functions/fnc_pickupTL.sqf b/addons/tacticalladder/functions/fnc_pickupTL.sqf index d8e313a17b..76cbea27d6 100644 --- a/addons/tacticalladder/functions/fnc_pickupTL.sqf +++ b/addons/tacticalladder/functions/fnc_pickupTL.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg, commy2 * Pick up tactical ladder @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_ladder"]; diff --git a/addons/tacticalladder/functions/fnc_positionTL.sqf b/addons/tacticalladder/functions/fnc_positionTL.sqf index c47733dd5a..bbfd877c2f 100644 --- a/addons/tacticalladder/functions/fnc_positionTL.sqf +++ b/addons/tacticalladder/functions/fnc_positionTL.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * Position tactical ladder @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" #define __ANIMS ["extract_1","extract_2","extract_3","extract_4","extract_5","extract_6","extract_7","extract_8","extract_9","extract_10","extract_11"] @@ -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/tacticalladder/script_component.hpp b/addons/tacticalladder/script_component.hpp index b58aa42e38..081ce8c473 100644 --- a/addons/tacticalladder/script_component.hpp +++ b/addons/tacticalladder/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_TACTICALLADDER diff --git a/addons/tacticalladder/stringtable.xml b/addons/tacticalladder/stringtable.xml index 7a60933ceb..bec5b05e64 100644 --- a/addons/tacticalladder/stringtable.xml +++ b/addons/tacticalladder/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -9,9 +9,13 @@ Escalera telescópica Echelle téléscopique Teleskopický žebřík - Telescopic Ladder + Scala Telescopica Teleszkopikus létra Escada telescópica + タクティカル ラダー + 로프 사다리 + 伸缩梯子 + 伸縮梯子 Deploy ladder @@ -21,9 +25,13 @@ Despelgar escalera Déployer l'échelle Rozložit žebřík - Deploy ladder + Piazza scala Létra lerakása Implantar escada + ラダーを設置 + 사다리 배치 + 布署梯子 + 佈署梯子 Drop ladder @@ -33,9 +41,13 @@ Soltar escalera Lacher l'échelle Položit žebřík - Drop ladder + Lascia scala Létra eldobása Derrubar escada + ラダーを落とす + 사다리 놓기 + 降下梯子 + 降下梯子 Extend @@ -44,9 +56,13 @@ Extender Разложить Prodloužit - Estendi, +Ctrl ruota + Estendi Extender Déployer + 伸ばす + 늘리기 + 伸长梯子 + 伸長梯子 +Ctrl tilt @@ -58,6 +74,10 @@ +Ctrl inclinar +Ctrl incliner +Ctrl per inclinare + +Ctrl で傾ける + +컨트롤키 기울이기 + +Ctrl 倾斜 + +Ctrl 傾斜 Position ladder @@ -67,9 +87,13 @@ Colocar escalera Positionner l'échelle Umístit žebřík - Position ladder + Posiziona scala Létra elhelyezése Posicionar escada + ラダーの位置 + 사다리 위치 + 梯子位置 + 梯子位置 Pickup ladder @@ -79,9 +103,13 @@ Recoger escalera Prendre l'échelle Vzít žebřík - Pickup ladder + Prendi scala Létra felvétele Pegar escada + ラダーを拾う + 사다리 줍기 + 捡起梯子 + 撿起梯子 - \ No newline at end of file + 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/XEH_postInit.sqf b/addons/tagging/XEH_postInit.sqf index ddac9b9ab9..1e7003281a 100644 --- a/addons/tagging/XEH_postInit.sqf +++ b/addons/tagging/XEH_postInit.sqf @@ -3,8 +3,7 @@ // Cache for static objects -GVAR(cacheStaticModels) = createLocation ["ACE_HashLocation", [-10000,-10000,-10000], 0, 0]; -GVAR(cacheStaticModels) setText QGVAR(cacheStaticModels); +GVAR(cacheStaticModels) = [false] call CBA_fnc_createNamespace; // Consider static everything vehicle that inherit from Static // This include houses (which we don't need), but also walls, that we do @@ -17,7 +16,7 @@ for "_index" from 0 to (_countOptions - 1) do { private _model = getText (_cfgClass >> "model"); if (_model != "") then { private _array = _model splitString "\"; - GVAR(cacheStaticModels) setVariable [toLower (_array select ((count _array) - 2)), _cfgClass]; + GVAR(cacheStaticModels) setVariable [(_array select ((count _array) - 1)), true]; }; }; }; @@ -33,7 +32,7 @@ for "_index" from 0 to (_countOptions - 1) do { private _model = getText (_cfgClass >> "model"); if (_model != "") then { private _array = _model splitString "\"; - GVAR(cacheStaticModels) setVariable [toLower (_array select ((count _array) - 2)), _cfgClass]; + GVAR(cacheStaticModels) setVariable [(_array select ((count _array) - 1)), true]; }; }; }; diff --git a/addons/tagging/XEH_preInit.sqf b/addons/tagging/XEH_preInit.sqf index 66458c6995..e1487c671f 100644 --- a/addons/tagging/XEH_preInit.sqf +++ b/addons/tagging/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(cachedTags) = []; GVAR(cachedRequiredItems) = []; diff --git a/addons/tagging/config.cpp b/addons/tagging/config.cpp index e066bcafe5..6ec32da0a6 100644 --- a/addons/tagging/config.cpp +++ b/addons/tagging/config.cpp @@ -19,8 +19,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" - -class ACE_newEvents { - createTag = QGVAR(createTag); - tagCreated = "ace_tagCreated"; -}; diff --git a/addons/tagging/functions/fnc_addCustomTag.sqf b/addons/tagging/functions/fnc_addCustomTag.sqf index 455b33ffd8..cb426493b3 100644 --- a/addons/tagging/functions/fnc_addCustomTag.sqf +++ b/addons/tagging/functions/fnc_addCustomTag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Adds custom tag. Has to be executed on one machine only. @@ -17,7 +18,6 @@ * * Public: Yes */ -#include "script_component.hpp" params [ ["_identifier", "", [""]], @@ -29,26 +29,25 @@ params [ // Verify if (_identifier == "") exitWith { - ACE_LOGERROR("Failed adding custom tag - missing identifier"); + ERROR("Failed adding custom tag - missing identifier"); }; if (_displayName == "") exitWith { - ACE_LOGERROR_1("Failed adding custom tag: %1 - missing displayName",_identifier); + ERROR_1("Failed adding custom tag: %1 - missing displayName",_identifier); }; if (_requiredItem == "") exitWith { - ACE_LOGERROR_1("Failed adding custom tag: %1 - missing requiredItem",_identifier); + ERROR_1("Failed adding custom tag: %1 - missing requiredItem",_identifier); }; if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) exitWith { - ACE_LOGERROR_2("Failed adding custom tag: %1 - requiredItem %2 does not exist",_identifier,_requiredItem); + ERROR_2("Failed adding custom tag: %1 - requiredItem %2 does not exist",_identifier,_requiredItem); }; if (_textures isEqualTo []) exitWith { - ACE_LOGERROR_1("Failed adding custom tag: %1 - missing textures",_identifier); + ERROR_1("Failed adding custom tag: %1 - missing textures",_identifier); }; -_identifier = [_identifier] call EFUNC(common,stringRemoveWhiteSpace); -_requiredItem = toLower _requiredItem; +_identifier = [_identifier] call CBA_fnc_removeWhitespace; // Add [QGVAR(applyCustomTag), [_identifier, _displayName, _requiredItem, _textures, _icon]] call CBA_fnc_globalEventJIP; diff --git a/addons/tagging/functions/fnc_addTagActions.sqf b/addons/tagging/functions/fnc_addTagActions.sqf index 82acf253ad..a5fdcd219a 100644 --- a/addons/tagging/functions/fnc_addTagActions.sqf +++ b/addons/tagging/functions/fnc_addTagActions.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Compiles tags from ACE_Tags and returns children actions. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit"]; @@ -33,7 +33,7 @@ private _actions = []; }, { (_this select 2) params ["_unit", "", "", "_requiredItem"]; - _requiredItem in ((items _unit) apply {toLower _x}) + _requiredItem in (_unit call EFUNC(common,uniqueItems)) }, {}, [_unit, _class, _textures, _requiredItem] diff --git a/addons/tagging/functions/fnc_applyCustomTag.sqf b/addons/tagging/functions/fnc_applyCustomTag.sqf index e2b91fe853..be73d85021 100644 --- a/addons/tagging/functions/fnc_applyCustomTag.sqf +++ b/addons/tagging/functions/fnc_applyCustomTag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Applies custom tag to the cache. @@ -17,14 +18,15 @@ * * Public: No */ -#include "script_component.hpp" params ["_identifier", "_displayName", "_requiredItem"]; // Add only if tag not already added (compare identifiers) if !(GVAR(cachedTags) select {_x select 0 == _identifier} isEqualTo []) exitWith { - ACE_LOGINFO_2("Tag with selected identifier already exists: %1 (%2)",_identifier,_displayName) + INFO_2("Tag with selected identifier already exists: %1 (%2)",_identifier,_displayName) }; +_requiredItem = configName (configFile >> "CfgWeapons" >> _requiredItem); // Convert To config case +_this set [2, _requiredItem]; GVAR(cachedTags) pushBack _this; GVAR(cachedRequiredItems) pushBackUnique _requiredItem; diff --git a/addons/tagging/functions/fnc_checkTaggable.sqf b/addons/tagging/functions/fnc_checkTaggable.sqf index d739bbfec5..3a022ca2b7 100644 --- a/addons/tagging/functions/fnc_checkTaggable.sqf +++ b/addons/tagging/functions/fnc_checkTaggable.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut, esteldunedain * Checks if there is a taggable surface within 2.5m in front of the player. @@ -9,20 +10,18 @@ * Is surface taggable * * Example: - * [unit] call ace_tagging_fnc_checkTaggable + * [player] call ace_tagging_fnc_checkTaggable * * Public: No */ -#include "script_component.hpp" - -params ["_unit"]; - -[[_unit], { +[_this, { params ["_unit"]; // Exit if no required item in inventory - if ((GVAR(cachedRequiredItems) arrayIntersect ((items _unit) apply {toLower _x})) isEqualTo []) exitWith {false}; + if ([_unit, { + GVAR(cachedRequiredItems) arrayIntersect (_unit call EFUNC(common,uniqueItems)) isEqualTo [] + }, _unit, QGVAR(checkRequiredItemsCache), 9999, "cba_events_loadoutEvent"] call EFUNC(common,cachedCall)) exitWith {false}; private _startPosASL = eyePos _unit; private _cameraPosASL = AGLToASL positionCameraToWorld [0, 0, 0]; @@ -39,21 +38,16 @@ params ["_unit"]; // Exit if trying to tag a non static object TRACE_1("Obj:",_intersections); - // Exit if trying to tag a non static object if ((!isNull _object) && { // If the class is alright, do not exit if (_object isKindOf "Static") exitWith {false}; // If the class is not categorized correctly search the cache - private _array = str(_object) splitString " "; - private _str = toLower (_array select 1); - TRACE_1("Object:",_str); - private _objClass = GVAR(cacheStaticModels) getVariable _str; + private _modelName = (getModelInfo _object) select 0; + private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit - if (isNil "_objClass") exitWith { - false - }; - true + (!_isStatic) }) exitWith { TRACE_1("Pointed object is non static",_object); false diff --git a/addons/tagging/functions/fnc_compileConfigTags.sqf b/addons/tagging/functions/fnc_compileConfigTags.sqf index 29f4acd1d4..c9aaca9506 100644 --- a/addons/tagging/functions/fnc_compileConfigTags.sqf +++ b/addons/tagging/functions/fnc_compileConfigTags.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Compiles and caches tags from ACE_Tags config. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" { private _failure = false; @@ -21,24 +21,26 @@ private _displayName = getText (_x >> "displayName"); if (_displayName == "") then { - ACE_LOGERROR_1("Failed compiling ACE_Tags for tag: %1 - missing displayName",_class); + ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing displayName",_class); _failure = true; }; - private _requiredItem = toLower (getText (_x >> "requiredItem")); + private _requiredItem = getText (_x >> "requiredItem"); if (_requiredItem == "") then { - ACE_LOGERROR_1("Failed compiling ACE_Tags for tag: %1 - missing requiredItem",_class); + ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing requiredItem",_class); _failure = true; } else { if (!isClass (configFile >> "CfgWeapons" >> _requiredItem)) then { - ACE_LOGERROR_2("Failed compiling ACE_Tags for tag: %1 - requiredItem %2 does not exist",_class,_requiredItem); + ERROR_2("Failed compiling ACE_Tags for tag: %1 - requiredItem %2 does not exist",_class,_requiredItem); _failure = true; + } else { + _requiredItem = configName (configFile >> "CfgWeapons" >> _requiredItem); // convert to config case }; }; private _textures = getArray (_x >> "textures"); if (_textures isEqualTo []) then { - ACE_LOGERROR_1("Failed compiling ACE_Tags for tag: %1 - missing textures",_class); + ERROR_1("Failed compiling ACE_Tags for tag: %1 - missing textures",_class); _failure = true; }; diff --git a/addons/tagging/functions/fnc_createTag.sqf b/addons/tagging/functions/fnc_createTag.sqf index 20ca33bd2e..296fc4503f 100644 --- a/addons/tagging/functions/fnc_createTag.sqf +++ b/addons/tagging/functions/fnc_createTag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut, esteldunedain * Creates a tag and handle its destruction. Only execute on the server. @@ -18,19 +19,16 @@ * Public: No */ -#include "script_component.hpp" - params ["_tagPosASL", "_vectorDirAndUp", "_texture", "_object", "_unit"]; TRACE_5("createTag:",_tagPosASL,_vectorDirAndUp,_texture,_object,_unit); if (_texture == "") exitWith { - ACE_LOGERROR_1("%1 is not a valid tag texture.",_texture); + ERROR_1("%1 is not a valid tag texture.",_texture); false }; -private _tag = "UserTexture1m_F" createVehicle [0,0,0]; +private _tag = createSimpleObject ["UserTexture1m_F", _tagPosASL]; _tag setObjectTextureGlobal [0, _texture]; -_tag setPosASL _tagPosASL; _tag setVectorDirAndUp _vectorDirAndUp; // Throw a global event for mision makers diff --git a/addons/tagging/functions/fnc_moduleInit.sqf b/addons/tagging/functions/fnc_moduleInit.sqf index c9d3172d57..3f1048e1e5 100644 --- a/addons/tagging/functions/fnc_moduleInit.sqf +++ b/addons/tagging/functions/fnc_moduleInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Initializes the Tagging module. @@ -10,11 +11,11 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_tagging_fnc_moduleInit + * * Public: No */ -#include "script_component.hpp" - -if (!isServer) exitWith {}; params ["_logic", "", "_activated"]; @@ -22,4 +23,4 @@ if (!_activated) exitWith {}; [_logic, QGVAR(quickTag), "quickTag"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO("Tagging Module Initialized."); +INFO("Tagging Module Initialized."); diff --git a/addons/tagging/functions/fnc_quickTag.sqf b/addons/tagging/functions/fnc_quickTag.sqf index 7f0a1d706e..bb672ed947 100644 --- a/addons/tagging/functions/fnc_quickTag.sqf +++ b/addons/tagging/functions/fnc_quickTag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Selects random tag and applies it. @@ -14,27 +15,28 @@ * Public: No */ -#include "script_component.hpp" - // Exit if Quick Tag disabled 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; }; @@ -46,6 +48,6 @@ if (GVAR(quickTag) == 3) then { // Tag if !(_possibleTags isEqualTo []) then { - private _availableTags = _possibleTags select {(_x select 2) in ((items _unit) apply {toLower _x})}; + private _availableTags = _possibleTags select {(_x select 2) in (_unit call EFUNC(common,uniqueItems))}; [_unit, selectRandom ((selectRandom _availableTags) select 3)] call FUNC(tag); }; diff --git a/addons/tagging/functions/fnc_tag.sqf b/addons/tagging/functions/fnc_tag.sqf index b6e332e313..2f129ece28 100644 --- a/addons/tagging/functions/fnc_tag.sqf +++ b/addons/tagging/functions/fnc_tag.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: BaerMitUmlaut, esteldunedain * Creates a tag on a wall that is on the closest surface within 2m on front of the unit. @@ -15,15 +16,13 @@ * Public: Yes */ -#include "script_component.hpp" - params [ ["_unit", objNull, [objNull]], ["_texture", "", [""]] ]; if (isNull _unit || {_texture == ""}) exitWith { - ACE_LOGERROR_2("Tag parameters invalid. Unit: %1, Texture: %2",_unit,_texture); + ERROR_2("Tag parameters invalid. Unit: %1, Texture: %2",_unit,_texture); }; private _startPosASL = eyePos _unit; @@ -49,15 +48,11 @@ if ((!isNull _object) && { if (_object isKindOf "Static") exitWith {false}; // If the class is not categorized correctly search the cache - private _array = str(_object) splitString " "; - private _str = toLower (_array select 1); - TRACE_1("Object:",_str); - private _objClass = GVAR(cacheStaticModels) getVariable _str; + private _modelName = (getModelInfo _object) select 0; + private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit - if (isNil "_objClass") exitWith { - false - }; - true + (!_isStatic) }) exitWith { TRACE_1("Pointed object is non static",_object); false @@ -81,7 +76,7 @@ private _v3 = _v2 vectorCrossProduct _v1; TRACE_3("Reference:", _v1, _v2, _v3); -_fnc_isOk = { +private _fnc_isOk = { params ["_rx", "_ry"]; private _startPosASL2 = _touchingPoint vectorAdd (_v2 vectorMultiply _rx) vectorAdd (_v3 vectorMultiply _ry) vectorAdd (_v1 vectorMultiply (-0.06)); private _endPosASL2 = _startPosASL2 vectorAdd (_v1 vectorMultiply (0.12)); diff --git a/addons/tagging/functions/fnc_tagTestingThread.sqf b/addons/tagging/functions/fnc_tagTestingThread.sqf index ead21f8d91..dcfb5e0bac 100644 --- a/addons/tagging/functions/fnc_tagTestingThread.sqf +++ b/addons/tagging/functions/fnc_tagTestingThread.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain * Checks if tags are still leaning on an object periodically. @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - GVAR(tagsToTest) = GVAR(tagsToTest) select { _x params ["_tag", "_tagPosASL", "_vectorDirAndUp"]; @@ -27,12 +26,13 @@ GVAR(tagsToTest) = GVAR(tagsToTest) select { private _intersections = lineIntersectsSurfaces [_tagPosASL, _endPosASL, _tag, objNull, true, 1, "GEOM", "FIRE"]; // If there's no intersections - if (_intersections isEqualTo []) exitWith { + if (_intersections isEqualTo []) then { TRACE_1("No intersections, deleting:",_tag); deleteVehicle _tag; false + } else { + true }; - true }; // If there's no more tag diff --git a/addons/tagging/script_component.hpp b/addons/tagging/script_component.hpp index 5eca5d92d7..0509667dda 100644 --- a/addons/tagging/script_component.hpp +++ b/addons/tagging/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_TAGGING diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 6fda8926ce..75de55efcc 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -1,44 +1,104 @@ - + Tagging Маркировка + タグ付け + Tagowanie + Markierungssystem (Spraydose) + 뿌리기 + Marquage + Marcamento + 喷漆 + 噴漆 Configure how the tagging system will operate by default. Настройка работы системы спрей-маркеров по-умолчанию. + 標準で開くタグ付けシステムの設定を行います。 + Skonfiguruj zachowanie systemu tagowania. + Konfiguriert, wie das Markierungssystem standardmäßig funktioniert. + 뿌리기 시스템의 기본사항을 설정합니다. + 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 (Spraydose) + 빠른 뿌리기 + Marquage rapide + Marcamento Rapido + 快速喷漆 + 快速噴漆 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 + 최근 사용 + Dernier utilisé + Ultimo Usato + 上次最后使用 + 上次最後使用 Random X Случайный Х + 無作為なX印 + Losowy X + Zufällig X + 무작위 X + Aléatoire X + Random X + 随机X标记 + 隨機X標記 Random Случайный + 無作為 + Losowy + Zufällig + 무작위 + Aléatoire + Random + 随机 + 隨機 Tag - Markieren + Markieren (Spraydose) Marcar Oznakuj - Tag Marca Označit Marcar Маркер + タグ + 뿌리기 + Tag + 喷漆 + 噴漆 X black @@ -50,6 +110,10 @@ X černě X em preto Черный Х + 黒のX印 + 검정 X + 黑色X标记 + 黑色X標記 X red @@ -61,6 +125,10 @@ X červeně X em vermelho Красный Х + 赤のX印 + 빨간 X + 红色X标记 + 紅色X標記 X green @@ -72,6 +140,10 @@ X zeleně X em verde Зеленый Х + 緑のX印 + 초록 X + 绿色X标记 + 綠色X標記 X blue @@ -83,6 +155,10 @@ X modře X em azul Синий Х + 青のX印 + 파랑 X + 蓝色X标记 + 藍色X標記 Black spray paint @@ -94,6 +170,10 @@ Černý sprej Spray de tinta preta Черный спрей + 黒のスプレー缶 + 검정 스프레이 + 黑色喷漆 + 黑色噴漆 Red spray paint @@ -105,6 +185,10 @@ Červený sprej Spray de tinta vermelha Красный спрей + 赤のスプレー缶 + 빨강 스프레이 + 红色喷漆 + 紅色噴漆 Green spray paint @@ -116,6 +200,10 @@ Zelený sprej Spray de tinta verde Зеленый спрей + 緑のスプレー缶 + 초록 스프레이 + 绿色喷漆 + 綠色噴漆 Blue spray paint @@ -127,17 +215,25 @@ Modrý sprej Spray de tinta azul Синий спрей + 青のスプレー缶 + 파랑 스프레이 + 蓝色喷漆 + 藍色噴漆 A can of spray paint for tagging walls. Eine Farbsprühdose um Wände zu markieren. Lata de pintura en aerosol para marcar. Farba w sprayu, służy do oznakowywania terenu. - Un spray de peinture pour taguer les murs. + Un spray de peinture pour marquer les murs. Una bomboletta di spay per contrassegnare i muri. Plechovka se sprejem k vytváření značek. Uma lata de tinta spray para marcar paredes. Балончик спрея для рисования маркеров на стенах. + スプレー缶は壁にタグ付できます。 + 벽에 뿌릴 수 있는 스프레이캔 입니다. + 喷漆可喷涂在墙壁上 + 噴漆可噴塗在牆壁上 - \ No newline at end of file + 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/thermals/script_component.hpp b/addons/thermals/script_component.hpp index c7ac2263ce..fc3edae09b 100644 --- a/addons/thermals/script_component.hpp +++ b/addons/thermals/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_THERMALS diff --git a/addons/trenches/CfgVehicles.hpp b/addons/trenches/CfgVehicles.hpp index 9c93e555ac..3b13be21a8 100644 --- a/addons/trenches/CfgVehicles.hpp +++ b/addons/trenches/CfgVehicles.hpp @@ -10,13 +10,11 @@ class CBA_Extended_EventHandlers; displayName = CSTRING(ContinueDiggingTrench); \ condition = QUOTE([ARR_2(_target,_player)] call FUNC(canContinueDiggingTrench)); \ statement = QUOTE([ARR_2(_target,_player)] call FUNC(continueDiggingTrench);); \ - priority = -1; \ }; \ class ACE_RemoveTrench { \ displayName = CSTRING(RemoveEnvelope); \ condition = QUOTE([ARR_2(_target,_player)] call FUNC(canRemoveTrench)); \ statement = QUOTE([ARR_2(_target,_player)] call FUNC(removeTrench);); \ - priority = -1; \ }; \ }; \ } @@ -33,7 +31,6 @@ class CfgVehicles { statement = QUOTE([ARR_2({_this call FUNC(placeTrench)},[ARR_2(_this select 0,'ACE_envelope_small')])] call CBA_fnc_execNextFrame); exceptions[] = {}; showDisabled = 0; - priority = 4; //icon = QPATHTOF(UI\icon_sandbag_ca.paa); }; class GVAR(digEnvelopeBig) { @@ -43,7 +40,6 @@ class CfgVehicles { statement = QUOTE([ARR_2({_this call FUNC(placeTrench)},[ARR_2(_this select 0,'ACE_envelope_big')])] call CBA_fnc_execNextFrame); exceptions[] = {}; showDisabled = 0; - priority = 4; //icon = QPATHTOF(UI\icon_sandbag_ca.paa); }; }; 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/XEH_preInit.sqf b/addons/trenches/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/trenches/XEH_preInit.sqf +++ b/addons/trenches/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/trenches/config.cpp b/addons/trenches/config.cpp index 2b4f3c9051..3f76f012ed 100644 --- a/addons/trenches/config.cpp +++ b/addons/trenches/config.cpp @@ -17,7 +17,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; -}; diff --git a/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf b/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf index 2e1942d6b8..97fee957b0 100644 --- a/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf +++ b/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Checks if a unit can continue digging a trench @@ -14,11 +15,10 @@ * * Public: No */ -#include "script_component.hpp" params ["_trench", "_unit"]; -if !("ACE_EntrenchingTool" in items _unit) exitWith {false}; +if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; if ((_trench getVariable [QGVAR(progress), 0]) >= 1) exitWith {false}; // Prevent removing/digging trench by more than one person diff --git a/addons/trenches/functions/fnc_canDigTrench.sqf b/addons/trenches/functions/fnc_canDigTrench.sqf index 0cbed2d9b7..d6bf05993d 100644 --- a/addons/trenches/functions/fnc_canDigTrench.sqf +++ b/addons/trenches/functions/fnc_canDigTrench.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * Author: Ruthberg, commy2, esteldunedain - * Checks if a unit can dig a trench + * Checks if a unit can dig a trench. * * Arguments: * 0: Unit @@ -13,19 +14,9 @@ * * Public: No */ -#include "script_component.hpp" - -#define SURFACE_BLACKLIST ["water", "concrete", "tarmac", "wood", "metal", "roof_tin", "roof_tiles", "wood_int", "concrete_int", "tiles_int", "metal_int", "stony", "rock", "int_concrete", "int_tiles", "int_wood", "tiling", "wavymetal", "int_metal"] params ["_unit"]; -if !("ACE_EntrenchingTool" in items _unit) exitWith {false}; +if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; -// Can't dig trench if above ground level -if ((getPosATL _unit) select 2 > 0.05) exitWith {false}; - -private _surfaceClass = (surfaceType getPosASL _unit) select [1]; -private _surfaceType = getText (configFile >> "CfgSurfaces" >> _surfaceClass >> "soundEnviron"); -TRACE_1("",_surfaceType); - -!(_surfaceType in SURFACE_BLACKLIST) +_unit call EFUNC(common,canDig) diff --git a/addons/trenches/functions/fnc_canRemoveTrench.sqf b/addons/trenches/functions/fnc_canRemoveTrench.sqf index 4e33857637..23347fc310 100644 --- a/addons/trenches/functions/fnc_canRemoveTrench.sqf +++ b/addons/trenches/functions/fnc_canRemoveTrench.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SzwedzikPL * Checks if a unit can remove a trench @@ -14,11 +15,10 @@ * * Public: No */ -#include "script_component.hpp" params ["_trench", "_unit"]; -if !("ACE_EntrenchingTool" in items _unit) exitWith {false}; +if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; // Prevent removing/digging trench by more than one person if (_trench getVariable [QGVAR(digging), false]) exitWith {false}; diff --git a/addons/trenches/functions/fnc_continueDiggingTrench.sqf b/addons/trenches/functions/fnc_continueDiggingTrench.sqf index 954eed1ca3..efedfa031b 100644 --- a/addons/trenches/functions/fnc_continueDiggingTrench.sqf +++ b/addons/trenches/functions/fnc_continueDiggingTrench.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support, esteldunedain * Continue process of digging trench. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_trench", "_unit"]; TRACE_2("continueDiggingTrench",_trench,_unit); @@ -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_handleInteractMenuOpened.sqf b/addons/trenches/functions/fnc_handleInteractMenuOpened.sqf index 91d6b0140b..1a27e28d60 100644 --- a/addons/trenches/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/trenches/functions/fnc_handleInteractMenuOpened.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_trenches_fnc_handleInteractMenuOpened + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/trenches/functions/fnc_handleKilled.sqf b/addons/trenches/functions/fnc_handleKilled.sqf index e9f0353cb1..1142ad0f3b 100644 --- a/addons/trenches/functions/fnc_handleKilled.sqf +++ b/addons/trenches/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle death. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_trenches_fnc_handleKilled + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/trenches/functions/fnc_handlePlayerChanged.sqf b/addons/trenches/functions/fnc_handlePlayerChanged.sqf index 684ccc22ce..77a152e421 100644 --- a/addons/trenches/functions/fnc_handlePlayerChanged.sqf +++ b/addons/trenches/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle player changes. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob, kevin] call ace_trenches_fnc_handlePlayerChanged + * * Public: No */ -#include "script_component.hpp" params ["_newPlayer", "_oldPlayer"]; diff --git a/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf b/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf index cbae02d07a..682cbae81e 100644 --- a/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf +++ b/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle the InventoryChanged event. @@ -9,14 +10,16 @@ * Return Value: * None * + * Example: + * [bob, "weapon"] call ace_trenches_fnc_handlePlayerInverntoryChanged + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; if (_unit getVariable [QGVAR(isPlacing), false]) then { - if !("ACE_EntrenchingTool" in items _unit) then { + if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) then { [_unit] call FUNC(placeCancel); }; }; diff --git a/addons/trenches/functions/fnc_handleScrollWheel.sqf b/addons/trenches/functions/fnc_handleScrollWheel.sqf index 5dbe661417..242b79f1f0 100644 --- a/addons/trenches/functions/fnc_handleScrollWheel.sqf +++ b/addons/trenches/functions/fnc_handleScrollWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg * Handles sandbag rotation @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" if (GVAR(digPFH) == -1) exitWith {false}; diff --git a/addons/trenches/functions/fnc_handleUnconscious.sqf b/addons/trenches/functions/fnc_handleUnconscious.sqf index e4fc2814b2..6f600cecdf 100644 --- a/addons/trenches/functions/fnc_handleUnconscious.sqf +++ b/addons/trenches/functions/fnc_handleUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle unconsciousness. @@ -8,12 +9,16 @@ * Return Value: * None * + * Example: + * [bob] call ace_trenches_fnc_handleUnconscious + * * Public: No */ -#include "script_component.hpp" 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..36bf5c8023 100644 --- a/addons/trenches/functions/fnc_placeCancel.sqf +++ b/addons/trenches/functions/fnc_placeCancel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support * Cancels trench dig @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_key"]; @@ -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..25d675d09b 100644 --- a/addons/trenches/functions/fnc_placeConfirm.sqf +++ b/addons/trenches/functions/fnc_placeConfirm.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support and esteldunedain * Confirms trench dig @@ -13,12 +14,12 @@ * * Public: No */ -#include "script_component.hpp" 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..0f52786561 100644 --- a/addons/trenches/functions/fnc_placeTrench.sqf +++ b/addons/trenches/functions/fnc_placeTrench.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support, esteldunedain * Starts the place process for trench. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_trenchClass"]; @@ -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..3a549eb16f 100644 --- a/addons/trenches/functions/fnc_removeTrench.sqf +++ b/addons/trenches/functions/fnc_removeTrench.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support and esteldunedain * Removes trench @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_trench", "_unit"]; TRACE_2("removeTrench",_trench,_unit); @@ -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/functions/fnc_setTrenchPlacement.sqf b/addons/trenches/functions/fnc_setTrenchPlacement.sqf index 49c1efdaae..c314914efe 100644 --- a/addons/trenches/functions/fnc_setTrenchPlacement.sqf +++ b/addons/trenches/functions/fnc_setTrenchPlacement.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support and esteldunedain * Sets trench placement @@ -18,7 +19,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_trench", "_trenchId", "_pos", "_vecDirAndUp", "_progress"]; diff --git a/addons/trenches/script_component.hpp b/addons/trenches/script_component.hpp index f3e97493e5..338347a1a7 100644 --- a/addons/trenches/script_component.hpp +++ b/addons/trenches/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_TRENCHES diff --git a/addons/trenches/stringtable.xml b/addons/trenches/stringtable.xml index 84cae860a5..9e0c1364da 100644 --- a/addons/trenches/stringtable.xml +++ b/addons/trenches/stringtable.xml @@ -1,27 +1,35 @@ - + Entrenching Tool - Schanzzeug + Klappspaten Saperka - Pala + Pala da Trincea Pala para trincheras Outil de tranchée Polní lopatka Ferramenta de trincheira Саперная лопата + シャベル + 야전삽 + 战备锹 + 戰備鍬 Entrenching Tool Saperka, używana do budowy wnęk - Mit Schanzzeug können Erdwälle oder Gräben ausgehoben werden. - Pala + Mit dem Klappspaten können Erdwälle oder Gräben ausgehoben werden. + Pala da Trincea Pala para trincheras Outil de tranchée Polní lopatky se používají k zákopovým a jiným pracem. Ferramenta de trincheira Саперная лопата + シャベル + 야전용 삽. 군인들의 영원한 친구 + 战备锹 + 戰備鍬 Envelope - Small @@ -32,6 +40,10 @@ Envelope - petite Trincheira - Pequena Окоп - Малый + 塹壕 - 小型 + 참호 - 소형 + 掩体 - 小 + 掩體 - 小 Small Personal Trench @@ -43,6 +55,10 @@ Malý zákop pro jednoho Trincheira pessoal pequena Малый персональный окоп + 小型の個人用塹壕 + 소형 개인참호 + 小型个人掩体 + 小型個人掩體 Dig Small Trench @@ -54,6 +70,10 @@ Vykopat malý zákop Cavar trincheira pequena Вырыть малый окоп + 小型塹壕を掘る + 소형참호 파기 + 盖小掩体 + 蓋小掩體 Envelope - Big @@ -64,6 +84,10 @@ Enveloppe - grande Trincheira - Grande Окоп - Большой + 塹壕 - 大型 + 참호 - 대형 + 掩体 - 大 + 掩體 - 大 Large Personal Trench @@ -75,6 +99,10 @@ Velký zákop pro jednoho Trincheira pessoal grande Большой персональный окоп + 大型の塹壕を掘る + 대형 참호 + 大型个人掩体 + 大型個人掩體 Dig Big Trench @@ -86,28 +114,40 @@ Vykopat velký zákop Cavar trincheira grande Вырыть большой окоп + 大型の塹壕を掘る + 대형참호 파기 + 盖大掩体 + 蓋大掩體 Confirm Dig Graben bestätigen Potwierdź kopanie - Conferma Scava + Conferma Scavo Confirmar cavado Confirmer la creusée Potvrdit kopání Confirmar excavação Копать + ここに掘る + 여기에 파기 + 确认开工 + 確認開工 Cancel Dig Graben abbrechen Anuluj kopanie - Cancella Scava + Annulla Scavo Cancelar cavado Annuler la creusée Zrušit kopání Cancelar excavação Отменить копание + 掘るのを中止 + 취소하기 + 取消动作 + 取消動作 Rotate @@ -120,17 +160,25 @@ Obrót Rotaciona Bращать + 回転 + 돌리기 + 旋转 + 旋轉 Digging Trench Grabe Schützengraben Kopanie wnęki - Sto Scavando la Trincea + Scavando la Trincea Cavando trinchera Creuse la tranchée Vykopat zákop Cavando trincheira Копание окопа + 塹壕を掘っている + 참호 파는중 + 正在盖掩体中 + 正在蓋掩體中 Continue Digging Trench @@ -139,6 +187,12 @@ Continuer à creuser la tranchée Продолжить копание окопа Pokračovat v kopání + 塹壕を掘りつづける + Graben fortsetzen + 계속해서 참호파기 + Continuando a Scavare la Trincea + 继续盖掩体 + 繼續蓋掩體 Remove Trench @@ -147,6 +201,12 @@ Retirer la tranchée Убрать окоп Odstranit zákop + 塹壕を消す + Schützengraben entfernen + 참호 제거 + Rimuovi Trincea + 移除掩体 + 移除掩體 Removing Trench @@ -155,6 +215,12 @@ Retirement de la tranchée Убирание окопа Odstraňuji zákop + 塹壕を消しています + Entferne Schützengraben + 참호 제거중... + Rimuovendo la Trincea + 移除掩体中 + 移除掩體中 - \ No newline at end of file + diff --git a/addons/tripod/CfgVehicles.hpp b/addons/tripod/CfgVehicles.hpp index b1d804e393..31888ab5dd 100644 --- a/addons/tripod/CfgVehicles.hpp +++ b/addons/tripod/CfgVehicles.hpp @@ -11,7 +11,6 @@ class CfgVehicles { condition = QUOTE([ARR_2(_player,'ACE_Tripod')] call EFUNC(common,hasItem)); statement = QUOTE([ARR_2(_player,'ACE_Tripod')] call FUNC(place)); showDisabled = 0; - priority = 2; icon = QPATHTOF(UI\w_sniper_tripod_ca.paa); }; }; @@ -49,12 +48,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,19 +65,18 @@ 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[] = {}; - priority = 5; icon = QPATHTOF(UI\w_sniper_tripod_ca.paa); }; @@ -85,15 +84,18 @@ 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; exceptions[] = {}; - priority = 5; icon = QPATHTOF(UI\w_sniper_tripod_ca.paa); }; }; }; + + 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 a7feade1c3..0b9469c746 100644 --- a/addons/tripod/XEH_preInit.sqf +++ b/addons/tripod/XEH_preInit.sqf @@ -2,6 +2,13 @@ ADDON = false; +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/config.cpp b/addons/tripod/config.cpp index 8251e0c469..8d068d2d9a 100644 --- a/addons/tripod/config.cpp +++ b/addons/tripod/config.cpp @@ -17,7 +17,3 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" - -class ACE_newEvents { - interactMenuOpened = "ace_interactMenuOpened"; -}; 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..42af65be74 100644 --- a/addons/tripod/functions/fnc_adjust.sqf +++ b/addons/tripod/functions/fnc_adjust.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Adjust tripod height @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_tripod"]; @@ -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_handleInteractMenuOpened.sqf b/addons/tripod/functions/fnc_handleInteractMenuOpened.sqf index 8c49359d96..0103c0a590 100644 --- a/addons/tripod/functions/fnc_handleInteractMenuOpened.sqf +++ b/addons/tripod/functions/fnc_handleInteractMenuOpened.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle opening of interaction menu. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_tripod_fnc_handleInteractMenuOpened + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/tripod/functions/fnc_handleKilled.sqf b/addons/tripod/functions/fnc_handleKilled.sqf index ee28fc1f45..1ce7ce5e0b 100644 --- a/addons/tripod/functions/fnc_handleKilled.sqf +++ b/addons/tripod/functions/fnc_handleKilled.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle death. @@ -8,9 +9,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_tripod_fnc_handleKilled + * * Public: No */ -#include "script_component.hpp" params ["_unit"]; diff --git a/addons/tripod/functions/fnc_handlePlayerChanged.sqf b/addons/tripod/functions/fnc_handlePlayerChanged.sqf index dd0cad6533..506699c293 100644 --- a/addons/tripod/functions/fnc_handlePlayerChanged.sqf +++ b/addons/tripod/functions/fnc_handlePlayerChanged.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle player changes. @@ -9,9 +10,11 @@ * Return Value: * None * + * Example: + * [bob] call ace_tripod_fnc_handlePlayerChanged + * * Public: No */ -#include "script_component.hpp" params ["_newPlayer", "_oldPlayer"]; diff --git a/addons/tripod/functions/fnc_handleScrollWheel.sqf b/addons/tripod/functions/fnc_handleScrollWheel.sqf index 1589bbc476..d1cc67272c 100644 --- a/addons/tripod/functions/fnc_handleScrollWheel.sqf +++ b/addons/tripod/functions/fnc_handleScrollWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg * Handles sandbag rotation @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_scroll"]; diff --git a/addons/tripod/functions/fnc_handleUnconscious.sqf b/addons/tripod/functions/fnc_handleUnconscious.sqf index f81cecea58..632be51e0d 100644 --- a/addons/tripod/functions/fnc_handleUnconscious.sqf +++ b/addons/tripod/functions/fnc_handleUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Handle unconsciousness. @@ -8,12 +9,16 @@ * Return Value: * None * + * Example: + * [bob] call ace_tripod_fnc_handleUnconscious + * * Public: No */ -#include "script_component.hpp" 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_pickup.sqf b/addons/tripod/functions/fnc_pickup.sqf index dc8b990515..931efaddfa 100644 --- a/addons/tripod/functions/fnc_pickup.sqf +++ b/addons/tripod/functions/fnc_pickup.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * Pick up tripod @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_tripod"]; diff --git a/addons/tripod/functions/fnc_place.sqf b/addons/tripod/functions/fnc_place.sqf index b4b6790ef6..c903c0148d 100644 --- a/addons/tripod/functions/fnc_place.sqf +++ b/addons/tripod/functions/fnc_place.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Rocko, Ruthberg * Place down tripod @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_tripodClass"]; @@ -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 28be9b780e..ccd4119239 100644 --- a/addons/tripod/script_component.hpp +++ b/addons/tripod/script_component.hpp @@ -2,10 +2,9 @@ #define COMPONENT_BEAUTIFIED Tripod #include "\z\ace\addons\main\script_mod.hpp" -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS -// #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/tripod/stringtable.xml b/addons/tripod/stringtable.xml index a57c6ca51d..daea7e95fd 100644 --- a/addons/tripod/stringtable.xml +++ b/addons/tripod/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ SSWT Kit SSWT Készlet Kit SSWT + SSWT キット + SSWT 키트 + 狙击手专用三脚架 + 狙擊手專用三腳架 Place SSWT Kit @@ -24,6 +28,10 @@ Place SSWT Kit SSWT készlet elhelyezése Colocar kit SSWT + SSWT キットを置く + SSWT 키트 배치 + 放置狙击手专用三脚架 + 放置狙擊手專用三腳架 Pick up SSWT Kit @@ -36,6 +44,10 @@ SSWT készlet felvétele Подобрать снайперский штатив Prendi Kit SSWT + SSWT キットを拾う + SSWT 키트 줍기 + 捡起狙击手专用三脚架 + 撿起狙擊手專用三腳架 Adjust SSWT Kit @@ -48,6 +60,10 @@ SSWT készlet állítása Выровнять снайперский штатив Aggiusta Kit SSWT + SSWT キットを調節 + SSWT 키트 조절 + 调整狙击手专用三脚架 + 調整狙擊手專用三腳架 Done @@ -60,6 +76,10 @@ Kész Готово Fatto + 完了 + 완료 + 完成 + 完成 adjust @@ -71,7 +91,11 @@ régler szabályzás подстройка - aggiusta + regola + 調節 + 조절 + 调整 + 調整 - \ No newline at end of file + 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/XEH_preInit.sqf b/addons/ui/XEH_preInit.sqf index 3dee364f02..b937d5d81c 100644 --- a/addons/ui/XEH_preInit.sqf +++ b/addons/ui/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; GVAR(interfaceInitialized) = false; diff --git a/addons/ui/functions/fnc_compileConfigUI.sqf b/addons/ui/functions/fnc_compileConfigUI.sqf index 8bda2c3ce4..0baaa8ca5c 100644 --- a/addons/ui/functions/fnc_compileConfigUI.sqf +++ b/addons/ui/functions/fnc_compileConfigUI.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Compiles and caches UI from ACE_UI config. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" { private _failure = false; @@ -23,13 +23,13 @@ private _elements = getArray (_x >> "elements"); if (_elements isEqualTo []) then { - ACE_LOGERROR_1("Failed compiling ACE_UI for Element: %1 - missing elements",_class); + ERROR_1("Failed compiling ACE_UI for Element: %1 - missing elements",_class); _failure = true; }; private _location = getNumber (_x >> "location"); if !(_location in [ANYWHERE, GROUND_ONLY, VEHICLE_ONLY]) then { - ACE_LOGERROR_2("Failed compiling ACE_UI for Element: %1 - missing or invalid location %2",_class,_location); + ERROR_2("Failed compiling ACE_UI for Element: %1 - missing or invalid location %2",_class,_location); _failure = true; }; diff --git a/addons/ui/functions/fnc_moduleInit.sqf b/addons/ui/functions/fnc_moduleInit.sqf index 6bfe29392f..b1295a6c10 100644 --- a/addons/ui/functions/fnc_moduleInit.sqf +++ b/addons/ui/functions/fnc_moduleInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Initializes the UI module. @@ -9,10 +10,12 @@ * * Return Value: * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_ui_fnc_moduleInit + * + * Public: No */ -#include "script_component.hpp" - -if (!isServer) exitWith {}; params ["_logic", "_units", "_activated"]; @@ -23,7 +26,7 @@ if (!_activated) exitWith {}; // Basic if (isArray (missionConfigFile >> "showHUD")) then { // HUD visibility is hardcoded in mission config and showHUD command is overriden - ACE_LOGINFO("User Interface Module Failed to Initialize Basic settings - showHUD overriden in mission config!"); + INFO("User Interface Module Failed to Initialize Basic settings - showHUD overriden in mission config!"); } else { [_logic, QGVAR(soldierVehicleWeaponInfo), "soldierVehicleWeaponInfo"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(vehicleRadar), "vehicleRadar"] call EFUNC(common,readSettingFromModule); @@ -63,4 +66,4 @@ if (isArray (missionConfigFile >> "showHUD")) then { [_logic, QGVAR(vehicleDamage), "vehicleDamage"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(vehicleInfoBackground), "vehicleInfoBackground"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO_1("User Interface Module Initialized. Allow client modifications: %1",GVAR(allowSelectiveUI)); +INFO_1("User Interface Module Initialized. Allow client modifications: %1",GVAR(allowSelectiveUI)); diff --git a/addons/ui/functions/fnc_setAdvancedElement.sqf b/addons/ui/functions/fnc_setAdvancedElement.sqf index 0e46badd09..0b5a174c5a 100644 --- a/addons/ui/functions/fnc_setAdvancedElement.sqf +++ b/addons/ui/functions/fnc_setAdvancedElement.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Sets advanced visible element of the UI using displays and controls. @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]] ]; @@ -40,7 +40,7 @@ if ((_canUseWeapon && {_location == 2}) || {!_canUseWeapon && {_location == 1}}) // Display and print info which component forced the element except for default vehicle check if (_showHint) then { [LSTRING(Disabled), 2] call EFUNC(common,displayTextStructured); - ACE_LOGINFO_2("Attempted modification of a forced User Interface element '%1' by '%2'.",_element,_x select 1); + INFO_2("Attempted modification of a forced User Interface element '%1' by '%2'.",_element,_x select 1); }; _show = false; }; @@ -53,7 +53,7 @@ if (!_force) then { _setElement params ["_sourceSet", "_showSet"]; if (_showHint) then { [LSTRING(Disabled), 2] call EFUNC(common,displayTextStructured); - ACE_LOGINFO_2("Attempted modification of a forced User Interface element '%1' by '%2'.",_element,_sourceSet); + INFO_2("Attempted modification of a forced User Interface element '%1' by '%2'.",_element,_sourceSet); }; _show = _showSet; }; diff --git a/addons/ui/functions/fnc_setElementVisibility.sqf b/addons/ui/functions/fnc_setElementVisibility.sqf index efc73a681e..f6c4525828 100644 --- a/addons/ui/functions/fnc_setElementVisibility.sqf +++ b/addons/ui/functions/fnc_setElementVisibility.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Setter for toggling advanced element visibility. @@ -16,7 +17,6 @@ * * Public: Yes */ -#include "script_component.hpp" params [ ["_source", "", [""]], @@ -26,7 +26,7 @@ params [ ]; if (_source == "" || {_element == ""}) exitWith { - ACE_LOGWARNING("Source or Element may not be empty strings!"); + WARNING("Source or Element may not be empty strings!"); }; _element = toLower _element; @@ -34,7 +34,7 @@ _element = toLower _element; // Verify element is bound private _cachedElement = GVAR(configCache) getVariable _element; if (isNil "_cachedElement") exitWith { - ACE_LOGWARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source); + WARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source); }; private _setElement = GVAR(elementsSet) getVariable _element; @@ -53,7 +53,7 @@ if (isNil "_setElement") then { if (_set) then { if (GVAR(interfaceInitialized)) then { - ACE_LOGWARNING_3("Element '%1' already set by '%2' - modification by '%3' failed.",_element,_sourceSet,_source); + WARNING_3("Element '%1' already set by '%2' - modification by '%3' failed.",_element,_sourceSet,_source); }; } else { TRACE_3("Unsetting element",_sourceSet,_element,_show); diff --git a/addons/ui/functions/fnc_setElements.sqf b/addons/ui/functions/fnc_setElements.sqf index f029a9f5ae..8e7da0eb3d 100644 --- a/addons/ui/functions/fnc_setElements.sqf +++ b/addons/ui/functions/fnc_setElements.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Sets basic visible elements of the UI using showHUD setter. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params [["_showHint", false]]; @@ -31,5 +31,7 @@ if (isArray (missionConfigFile >> "showHUD")) exitWith { true, GVAR(commandMenu), GVAR(groupBar), + true, + true, true ]] call EFUNC(common,showHud); diff --git a/addons/ui/script_component.hpp b/addons/ui/script_component.hpp index 3666ad36c3..11b0d08715 100644 --- a/addons/ui/script_component.hpp +++ b/addons/ui/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_UI diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 1327630551..06b253238b 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -7,6 +7,13 @@ Interface do usuário Interface utilisateur Интерфейс + ユーザ インタフェイス + Interfejs użytkownika + Benutzeroberfläche + 사용자 인터페이스 + Interfaccia Utente + 使用者介面 + 使用者介面 User Interface @@ -14,12 +21,26 @@ Interface do usuário Interface utilisateur Пользовательский интерфейс + ユーザ インタフェイス + Interfejs użytkownika + Benutzeroberfläche + 사용자 인터페이스 + Interfaccia Utente + 使用者介面 + 使用者介面 This module allows toggling visible user interface parts. 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 @@ -27,6 +48,13 @@ Permitir IU Selecionável Permettre l'IU selective Включить настраиваемый интерфейс + UI 選択性を許可 + Zezwól na selektywne UI + Erlaube selektives UI + 선택적 사용자 인터페이스 허가 + Permette l'UI Selettiva + 允许调整使用者介面 + 允許調整使用者介面 Allow client to modify their UI. @@ -34,6 +62,13 @@ Permite o cliente modificar sua IU. Permet aux clients de modifier leur IU Позволить клиентам изменять их пользовательский интерфейс. + クライアントがユーザ インタフェイスを編集できるようにします。 + Zezwól klientowi na modyfikację UI. + Erlaube Clients, ihr UI zu modifizieren. + 클라이언트가 선택적 사용자 인터페이스 사용하는것을 허가합니다 + Permette al client di modificare la propria UI. + 允许客户端自行调整使用者介面 + 允許客戶端自行調整使用者介面 Soldier/Vehicle/Weapon Information @@ -41,6 +76,13 @@ Informação de Soldado/Veículo/Armamento Soldat/Véhicule/Arme/Informations Информация о Солдате/Технике/Оружии + 兵士/車両/武器の情報 + Informacje o żołnierzu/pojeździe/broni + Soldat/Fahrzeug/Waffe Information + 병사/차량/무기 정보 + Informazioni Soldato/Veicolo/Arma + 士兵/载具/武器资讯栏 + 士兵/載具/武器資訊欄 Vehicle Radar @@ -48,6 +90,13 @@ Radar de Veículo Radar de véhicule Радар в технике + 車両のレーダ + Radar w pojeździe + Fahrzeugradar + 차량 레이더 + Rada Veicolo + 载具雷达 + 載具雷達 Vehicle Compass @@ -55,6 +104,13 @@ Bússola de Veículo Compas de véhicule Компас в технике + 車両のレーダ + Kompas w pojeździe + Fahrzeugkompass + 차량 나침반 + Bussola Veicolo + 载具指北针 + 載具指北針 Command Menu @@ -62,6 +118,13 @@ Menu de Comando Menu de commandement Командное меню + 指揮メニュー + Menu dowodzenia + Kommandomenü + 지휘 메뉴 + Menù di Comando + 指挥选单 + 指揮選單 Group Bar @@ -69,6 +132,13 @@ Barra de Grupo Barre de groupe Панель командира + 指揮メニュー + Pasek grupy + Gruppenleiste + 그룹 막대 + Barra del Gruppo + 小队状态栏 + 小隊狀態欄 Weapon Name @@ -76,6 +146,13 @@ Nome do Armamento Nom de l''arme Название оружия + 武器名 + Nazwa broni + Waffenname + 무기 이름 + Nome Arma + 武器名称 + 武器名稱 Weapon Name Background @@ -83,6 +160,13 @@ Fundo do Nome do Armamento Arrière-plan du nom de l'arme Фон названия оружия + 武器名の背景表示 + Tło nazwy broni + Waffenname Hintergrund + 무기 이름 배경 + Nome Sfondo Arma + 武器名称背景 + 武器名稱背景 Firing Mode @@ -90,6 +174,13 @@ Modo de Disparo Mode de tir Режим стрельбы + 射撃モード + Tryb ognia + Feuermodus + 사격 모드 + Modalità di Fuoco + 射击模式 + 射擊模式 Ammo Type @@ -97,6 +188,13 @@ Tipo de Munição Type de munitions Тип боеприпасов + 弾種 + Typ amunicji + Munitionstyp + 탄종 + Tipo Munizioni + 弹药类型 + 彈藥類型 Ammo Count @@ -104,6 +202,13 @@ Quantidade de Munição Nombre de munitions Количество боеприпасов + 弾薬数 + Ilość amunicji + Munitionsanzahl + 탄약수 + Contatore Munizioni + 弹药数量 + 彈藥數量 Magazine Count @@ -111,6 +216,13 @@ Quantidade de Carregadores Nombre de chargeurs Количество магазинов + 弾倉装填数 + Ilość magazynków + Magazinanzahl + 탄창수 + Contatore Caricatore + 弹匣数量 + 彈匣數量 Throwable Type @@ -118,6 +230,13 @@ Tipo de Arremessável Type d'objets de lancer Тип гранаты + 投げる種類 + Typ granatu + Wurfobjekt-Typ + 투척물 종류 + Tipo Lanciabile + 投掷物类型 + 投擲物類型 Throwable Count @@ -125,6 +244,13 @@ Quantidade de Arremessável Nombre d'objets de lancer Количество гранат + 投げられる数 + Ilość granatów + Wurfobjekt-Anzahl + 투척물 개수 + Contatore Lanciabili + 投掷物数量 + 投擲物數量 Zeroing @@ -132,12 +258,26 @@ Zerar a mira Mise à zéro Дальность стрельбы + ゼロイン + Wyzerowanie broni + Nullung + 영점 + Azzeramento + 归零距离 + 歸零距離 Weapon Lower Info Background Informações na parte de baixo do fundo do Armamento Arrière-plan des informations inférieures de l'arme Фон ниформации об оружии снизу + 武器名の背景表示 (下側) + Tło dolnej części informacji o broni + Hintergrund der unteren Waffen-Info-Leiste + 무기 상세 정보 배경 + Informazioni Sfondo Arma Bassa + 武器底部资讯栏背景 + 武器底部資訊欄背景 Stance @@ -145,6 +285,13 @@ Postura Posture Стойка + 姿勢 + Postura + Haltung + 자세 + Postura + 姿态 + 姿態 Stamina Bar @@ -152,66 +299,143 @@ Barra de Energia Barre d'endurance Полоса выносливости + 体力バー + Pasek staminy + Ausdaueranzeige + 체력 막대 + Barra Stamina + 体力栏 + 體力欄 Gunner Weapon Name Nome da arma do fuzileiro Nom de l'arme du tireur Название орудия наводчика + 射手用の武器名 + Nazwa broni strzelca + Richtschütze Waffenname + 사수 무기 명칭 + Nome Arma Artigliere + 炮手武器名称 + 砲手武器名稱 Gunner Weapon Name Background Fundo do nome da arma do fuzileiro Arrière-plan du nom de l'arme (tireur) Фон названия орудия наводчика + 射手用の武器名の背景表示 + Tło nazwy broni strzelca + Richtschütze Waffenname Hintergrund + 사수 무기 명칭 배경 + Nome Sfondo Arma Artigliere + 炮手武器名称背景 + 砲手武器名稱背景 Gunner Firing Mode Modo de disparo do fuzileiro Mode de tir (tireur) Режим стрельбы наводчика + 射手用の発射モード + Tryb ognia strzelca + Richtschütze Feuermodus + 사수 사격 모드 + Modalità di Fuoco Artigliere + 炮手射击模式 + 砲手射擊模式 Gunner Ammo Type Tipo de Munição do fuzileiro Type de munitions (tireur) Тип боеприпасов наводчика + 射手用の弾種 + Typ amunicji strzelca + Richtschütze Munitionstyp + 사수 탄종 + Tipo Munizioni Artigliere + 炮手弹药类型 + 砲手彈藥類型 Gunner Ammo Count Quantidade de Munição do fuzileiro Nombre de munitions (tireur) Количество боеприпасов наводчика + 射手用の弾数 + Ilość amunicji strzelca + Richtschütze Munitionsanzahl + 사수 탄약 수량 + Contatore Munizioni Artigliere + 炮手弹药数量 + 砲手彈藥數量 Gunner Magazine Count Quantidade de Carregadores do fuzileiro Nombre de chargeurs (tireur) Количество магазинов наводчика + 射手用の弾倉数 + Ilość magazynków strzelca + Richtschütze Magazinanzahl + 사수 탄창 수량 + Contatore Caricatore Artigliere + 炮手弹匣数量 + 砲手彈匣數量 Gunner Launchable Type Tipo de Arremessável do fuzileiro Type d'objets jetable ( tireur) Тип пусковой установки наводчика + 射手用のランチャーの種類 + Typ rakiet strzelca + Richtschütze Raketentyp + 사수 발사체 종류 + Tipo Lanciabile Artigliere + 炮手发射物类型 + 砲手發射物類型 Gunner Launchable Count Quantidade de Arremessável do fuzileiro Nombre d'objets jetable (tireur) Количество снарядов пусковой установки наводчика + 射手用のランチャー弾薬数 + Ilość rakiet strzelca + Richtschütze Raketenanzahl + 사수 발사체 수량 + Contatore Lanciabili Artigliere + 炮手发射物数量 + 砲手發射物數量 Gunner Zeroing Zerar a mira do fuzileiro Mise à zéro ( tireur) Дальность стрельбы наводчика + 射手用ゼロイン + Wyzerowanie broni strzelca + Richtschütze Nullung + 사수 영점 + Azzeramento Artigliere + 炮手归零距离 + 砲手歸零距離 Gunner Weapon Lower Info Background Informações na parte de baixo do fundo do Armamento do fuzileiro Arrière-plan des informations inférieures (tireur) Фон ниформации об орудии наводчика снизу + 射手用の武器名の背景表示 (下側) + Tło dolnej części informacji o broni strzelca + Hintergrund der unteren Waffen-Info-Leiste (Richtschütze) + 사수 무기 상세 정보 배경 + Informazioni Sfondo Arma Artigliere Bassa + 炮手武器底部资讯栏背景 + 砲手武器底部資訊欄背景 Vehicle Name @@ -219,6 +443,13 @@ Nome do Veículo Nom du véhicule Название техники + 車両名 + Nazwa pojazdu + Fahrzeugname + 차량 명칭 + Nome Veicolo + 载具名称 + 載具名稱 Vehicle Name Background @@ -226,6 +457,13 @@ Fundo do Nome do Veículo Arrière-plan du nom du véhicule Фон названия техники + 車両名の背景 + Tło nazwy pojazdu + Fahrzeugname Hintergrund + 차량 명칭 배경 + Nome Sfondo Veicolo + 载具名称背景 + 載具名稱背景 Vehicle Fuel Bar @@ -233,6 +471,13 @@ Barra de Combustível do Veículo Barre d'éssence du véhicule Полоса топлива + 車両の燃料計 + Pasek paliwa + Fahrzeug-Treibstoffleiste + 차량 연료 막대 + Barra Carburante Veicolo + 载具燃料栏 + 載具燃料欄 Vehicle Speed @@ -240,6 +485,13 @@ Velocidade do Veículo Vitesse du véhicule Скорость техники + 車両の速度計 + Prędkościomierz + Fahrzeuggeschwindigkeit + 차량 속도 + Velocità Veicolo + 载具速度 + 載具速度 Vehicle Altitude @@ -247,6 +499,13 @@ Altitude do Veículo Altitude du véhicule Высота полета + 車両の高度計 + Wysokościomierz radarowy + Fahrzeughöhe + 차량 고도 + Altitudine Veicolo + 载具高度 + 載具高度 Vehicle Damage @@ -254,6 +513,13 @@ Dano do Veículo Dégats du véhicule Повреждение техники + 車両の損傷表示 + Uszkodzenia pojazdu + Fahrzeugschaden + 차량 피해 + Danno Veicolo + 载具伤害 + 載具傷害 Vehicle Info Background @@ -261,6 +527,13 @@ Fundo das informações do veículo Arrière-plan des informations du véhicule Фон информации о технике + 車両状態の背景 + Tło informacji o pojeździe + Fahrzeug Info Hintergrund + 차량 정보 배경 + Informazioni Sfondo Veicolo + 载具资讯栏背景 + 載具資訊欄背景 Requires Soldier/Vehicle/Weapon Information. @@ -268,6 +541,13 @@ Requer informações de Soldado/Veículo/Armamento Requiert les informations de soldat/Vehicule/Arme. Требуется Информация о Солдате/Технике/Оружии. + 兵士/車両/武器の情報を必要とします。 + Wymaga informacji o żołnierzu/pojeździe/broni. + Benötigt Soldat/Fahrzeug/Waffe Information. + 병사/차량/무기의 정보가 필요합니다. + Richiede informazione Soldato/Veicolo/Arma. + 需要士兵/载具/武器的资讯. + 需要士兵/載具/武器的資訊. Modifying User Interface is disabled. @@ -275,12 +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é + 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. + 无法编辑已被锁定的使用者介面元件 + 無法編輯已被鎖定的使用者介面元件 - \ No newline at end of file + diff --git a/addons/vector/CfgVehicles.hpp b/addons/vector/CfgVehicles.hpp index f06f79aa12..23aa8d7412 100644 --- a/addons/vector/CfgVehicles.hpp +++ b/addons/vector/CfgVehicles.hpp @@ -6,15 +6,15 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(VectorName); vehicleClass = "Items"; - class TransportWeapons { - MACRO_ADDWEAPON(ACE_Vector,1); + class TransportItems { + MACRO_ADDITEM(ACE_Vector,1); }; }; class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { - class TransportWeapons { - MACRO_ADDWEAPON(ACE_Vector,6); + class TransportItems { + MACRO_ADDITEM(ACE_Vector,6); }; }; }; diff --git a/addons/vector/XEH_preInit.sqf b/addons/vector/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/vector/XEH_preInit.sqf +++ b/addons/vector/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/vector/config.cpp b/addons/vector/config.cpp index 2f2302d9af..cf6f235a5e 100644 --- a/addons/vector/config.cpp +++ b/addons/vector/config.cpp @@ -20,7 +20,3 @@ class CfgPatches { #include "CfgWeapons.hpp" #include "RscInGameUI.hpp" - -class ACE_newEvents { - RangerfinderData = QGVAR(rangefinderData); -}; diff --git a/addons/vector/functions/fnc_adjustBrightness.sqf b/addons/vector/functions/fnc_adjustBrightness.sqf index da951322af..2cf2d5a923 100644 --- a/addons/vector/functions/fnc_adjustBrightness.sqf +++ b/addons/vector/functions/fnc_adjustBrightness.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * 0: Number + * + * Return Value: + * None + * + * Example: + * [5] call ace_vector_fnc_adjustBrigthness + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_clearDisplay.sqf b/addons/vector/functions/fnc_clearDisplay.sqf index 73ef7dfcc6..b54a3f534f 100644 --- a/addons/vector/functions/fnc_clearDisplay.sqf +++ b/addons/vector/functions/fnc_clearDisplay.sqf @@ -1,11 +1,19 @@ -/* - -by commy2 - -Clears the vectors control items. - -*/ #include "script_component.hpp" +/* + * Author: commy2 + * Clears the vectors control items. + * + * Arguments: + * 0: String + * + * Return Value: + * None + * + * Example: + * [5] call ace_vector_fnc_clearDisplay + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_convertToTexturesDegree.sqf b/addons/vector/functions/fnc_convertToTexturesDegree.sqf index 7e04cfccd2..17754244f1 100644 --- a/addons/vector/functions/fnc_convertToTexturesDegree.sqf +++ b/addons/vector/functions/fnc_convertToTexturesDegree.sqf @@ -1,10 +1,19 @@ -/* by commy2 - -converts azimuth into array of textures for the vectors scripted info control - -*/ - #include "script_component.hpp" +/* + * Author: commy2 + * converts azimuth into array of textures for the vectors scripted info control + * + * Arguments: + * 0: Number + * + * Return Value: + * None + * + * Example: + * [5] call ace_vector_fnc_convertToTexturesDegree + * + * Public: No + */ params ["_number"]; @@ -24,8 +33,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 eb39febfe8..cb2f1ba990 100644 --- a/addons/vector/functions/fnc_convertToTexturesDistance.sqf +++ b/addons/vector/functions/fnc_convertToTexturesDistance.sqf @@ -1,29 +1,34 @@ -/* by commy2 - -converts rangefinder distance into array of textures for the vectors scripted info control - -*/ - #include "script_component.hpp" - -private ["_number", "_isNegative"]; - -_number = _this select 0; +/* + * Author: commy2 + * converts rangefinder distance into array of textures for the vectors scripted info control + * + * Arguments: + * 0: Number + * + * Return Value: + * Array + * + * Example: + * [5] call ace_vector_fnc_convertToTexturesDistance + * + * Public: No + */ +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 7a77a3aab8..eb9e6f840c 100644 --- a/addons/vector/functions/fnc_convertToTexturesFOS.sqf +++ b/addons/vector/functions/fnc_convertToTexturesFOS.sqf @@ -1,31 +1,35 @@ -/* by commy2 - -converts rangefinder distance into array of textures for the vectors scripted info control - -*/ - #include "script_component.hpp" - -private ["_number", "_coordinate", "_isNegative"]; - -_number = _this select 0; -_coordinate = _this select 1; +/* + * Author: commy2 + * converts rangefinder distance into array of textures for the vectors scripted info control + * + * Arguments: + * 0: Number + * 1: Number + * + * Return Value: + * Array + * + * Example: + * [5, 6] call ace_vector_fnc_convertToTexturesFOS + * + * Public: No + */ +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 f99490f04c..a1ee95df0c 100644 --- a/addons/vector/functions/fnc_dataTransfer.sqf +++ b/addons/vector/functions/fnc_dataTransfer.sqf @@ -1,25 +1,23 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Data transfer over a connected cable. Based on page 14 of pdf. * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * [] call ace_vector_fnc_dataTransfer * * Public: No */ -#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_getDirection.sqf b/addons/vector/functions/fnc_getDirection.sqf index c34826e218..1103a55458 100644 --- a/addons/vector/functions/fnc_getDirection.sqf +++ b/addons/vector/functions/fnc_getDirection.sqf @@ -1,11 +1,23 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * Array + * + * Example: + * call ace_vector_fnc_getDirection + * + * Public: No + */ /* -private "_dlgVector"; - disableSerialization; -_dlgVector = GETUVAR(ACE_dlgVector, displayNull); +private _dlgVector = GETUVAR(ACE_dlgVector, displayNull); [ round parseNumber ctrlText (_dlgVector displayCtrl 156), diff --git a/addons/vector/functions/fnc_getDistance.sqf b/addons/vector/functions/fnc_getDistance.sqf index f1312be511..8c38cc619f 100644 --- a/addons/vector/functions/fnc_getDistance.sqf +++ b/addons/vector/functions/fnc_getDistance.sqf @@ -1,15 +1,27 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * Array + * + * Example: + * call ace_vector_fnc_getDistance + * + * Public: No + */ #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 365a41518e..8ff1f38332 100644 --- a/addons/vector/functions/fnc_getFallOfShot.sqf +++ b/addons/vector/functions/fnc_getFallOfShot.sqf @@ -1,23 +1,32 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * Array + * + * Example: + * call ace_vector_fnc_getFallOfShot + * + * Public: No + */ -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 9ec0919917..768436677c 100644 --- a/addons/vector/functions/fnc_getHeightDistance.sqf +++ b/addons/vector/functions/fnc_getHeightDistance.sqf @@ -1,13 +1,25 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * Array + * + * Example: + * call ace_vector_fnc_getHeightDistance + * + * Public: No + */ -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 765d3d6ec4..2abcd8238d 100644 --- a/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf +++ b/addons/vector/functions/fnc_getRelativeAzimuthDistance.sqf @@ -1,28 +1,38 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * Array + * + * Example: + * call ace_vector_fnc_getRelativeAzimuthDistance + * + * Public: No + */ -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 9c6dc38943..71abfda53d 100644 --- a/addons/vector/functions/fnc_getRelativeDistance.sqf +++ b/addons/vector/functions/fnc_getRelativeDistance.sqf @@ -1,22 +1,33 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * Number + * + * Example: + * call ace_vector_fnc_getRelativeDistance + * + * Public: No + */ -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 319b11b6a6..2bd6e4795c 100644 --- a/addons/vector/functions/fnc_getRelativeHeightLength.sqf +++ b/addons/vector/functions/fnc_getRelativeHeightLength.sqf @@ -1,24 +1,33 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * Array + * + * Example: + * call ace_vector_fnc_getRelativeHeightLength + * + * Public: No + */ -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/vector/functions/fnc_illuminate.sqf b/addons/vector/functions/fnc_illuminate.sqf index 03508aae9e..18535d2861 100644 --- a/addons/vector/functions/fnc_illuminate.sqf +++ b/addons/vector/functions/fnc_illuminate.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * 0: String + * + * Return Value: + * None + * + * Example: + * ["5"] call ace_vector_fnc_illuminate + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_nextMode.sqf b/addons/vector/functions/fnc_nextMode.sqf index 53054e85e6..74250ca1f2 100644 --- a/addons/vector/functions/fnc_nextMode.sqf +++ b/addons/vector/functions/fnc_nextMode.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * 0: String + * + * Return Value: + * Array + * + * Example: + * ["5"] call ace_vector_fnc_nextMode + * + * Public: No + */ switch (_this select 0) do { case ("settings"): { diff --git a/addons/vector/functions/fnc_onKeyDown.sqf b/addons/vector/functions/fnc_onKeyDown.sqf index 830fb3c3c5..6a58ff96fc 100644 --- a/addons/vector/functions/fnc_onKeyDown.sqf +++ b/addons/vector/functions/fnc_onKeyDown.sqf @@ -1,11 +1,19 @@ -/* - -by commy2 - -Handles pressing the special vector keys. - -*/ #include "script_component.hpp" +/* + * Author: commy2 + * Handles pressing the special vector keys. + * + * Arguments: + * 0: String + * + * Return Value: + * None + * + * Example: + * ["5"] call ace_vector_fnc_onKeyDown + * + * Public: No + */ // set vector config settings switch (GVAR(modeReticle)) do { diff --git a/addons/vector/functions/fnc_onKeyHold.sqf b/addons/vector/functions/fnc_onKeyHold.sqf index 3fdd637b61..cefdc3236b 100644 --- a/addons/vector/functions/fnc_onKeyHold.sqf +++ b/addons/vector/functions/fnc_onKeyHold.sqf @@ -1,11 +1,20 @@ -/* - -by commy2 - -PFH executed while holding a vector key down. - -*/ #include "script_component.hpp" +/* + * Author: commy2 + * PFH executed while holding a vector key down. + * + * Arguments: + * 0: String + * 1: Number + * + * Return Value: + * None + * + * Example: + * ["5", 5] call ace_vector_fnc_onKeyHold + * + * Public: No + */ if (!((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"])) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/addons/vector/functions/fnc_onKeyUp.sqf b/addons/vector/functions/fnc_onKeyUp.sqf index fc3d17700e..2e315d7c0e 100644 --- a/addons/vector/functions/fnc_onKeyUp.sqf +++ b/addons/vector/functions/fnc_onKeyUp.sqf @@ -1,11 +1,19 @@ -/* - -by commy2 - -Handles releasing the special vector keys. - -*/ #include "script_component.hpp" +/* + * Author: commy2 + * Handles releasing the special vector keys. + * + * Arguments: + * 0: String + * + * Return Value: + * None + * + * Example: + * ["5"] call ace_vector_fnc_onKeyUp + * + * Public: No + */ private _fnc_setPFH = { if (GVAR(holdKeyHandler) > -1) then { diff --git a/addons/vector/functions/fnc_showAzimuth.sqf b/addons/vector/functions/fnc_showAzimuth.sqf index 2bedd4bf52..4a0854f3d5 100644 --- a/addons/vector/functions/fnc_showAzimuth.sqf +++ b/addons/vector/functions/fnc_showAzimuth.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showAzimuth + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showAzimuthInclination.sqf b/addons/vector/functions/fnc_showAzimuthInclination.sqf index b00c035890..15e206fbbd 100644 --- a/addons/vector/functions/fnc_showAzimuthInclination.sqf +++ b/addons/vector/functions/fnc_showAzimuthInclination.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showAzimuthInclination + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showCenter.sqf b/addons/vector/functions/fnc_showCenter.sqf index 4870b10a69..fef128240f 100644 --- a/addons/vector/functions/fnc_showCenter.sqf +++ b/addons/vector/functions/fnc_showCenter.sqf @@ -1,11 +1,19 @@ -/* - -by commy2 - -Shows or hides the vectors center square thingy. - -*/ #include "script_component.hpp" +/* + * Author: commy2 + * Shows or hides the vectors center square thingy. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showCenter + * + * Public: No + */ ((GETUVAR(ACE_dlgVector,displayNull)) displayCtrl 1301) ctrlSetText (["", QPATHTOF(rsc\vector_center.paa)] select (_this select 0)); diff --git a/addons/vector/functions/fnc_showDistance.sqf b/addons/vector/functions/fnc_showDistance.sqf index 380f784bbc..447622355c 100644 --- a/addons/vector/functions/fnc_showDistance.sqf +++ b/addons/vector/functions/fnc_showDistance.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showDistance + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showFallOfShot.sqf b/addons/vector/functions/fnc_showFallOfShot.sqf index b7bed77a0b..3df9fa8357 100644 --- a/addons/vector/functions/fnc_showFallOfShot.sqf +++ b/addons/vector/functions/fnc_showFallOfShot.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * 0: Unknown + * + * Return Value: + * None + * + * Example: + * [?] call ace_vector_fnc_showFallOfShot + * + * Public: No + */ GVAR(FOSState) = _this select 0; diff --git a/addons/vector/functions/fnc_showHeightDistance.sqf b/addons/vector/functions/fnc_showHeightDistance.sqf index b34e8111bc..7c8c0cc02e 100644 --- a/addons/vector/functions/fnc_showHeightDistance.sqf +++ b/addons/vector/functions/fnc_showHeightDistance.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showHeightDistance + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showP1.sqf b/addons/vector/functions/fnc_showP1.sqf index 8d509d575f..2d587e03d1 100644 --- a/addons/vector/functions/fnc_showP1.sqf +++ b/addons/vector/functions/fnc_showP1.sqf @@ -1,11 +1,19 @@ -/* - -by commy2 - -Shows or hides the 1-P text line. - -*/ #include "script_component.hpp" +/* + * Author: commy2 + * Shows or hides the 1-P text line. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showP1 + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf b/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf index 95797b9d6c..82f1f7eaf6 100644 --- a/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf +++ b/addons/vector/functions/fnc_showRelativeAzimuthDistance.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showRelativeAzimuthDistance + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showRelativeDistance.sqf b/addons/vector/functions/fnc_showRelativeDistance.sqf index 74b778d8bf..0bd4d23ec0 100644 --- a/addons/vector/functions/fnc_showRelativeDistance.sqf +++ b/addons/vector/functions/fnc_showRelativeDistance.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showRelativeDistance + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showRelativeHeightLength.sqf b/addons/vector/functions/fnc_showRelativeHeightLength.sqf index 0b9f5c1928..fe9823e170 100644 --- a/addons/vector/functions/fnc_showRelativeHeightLength.sqf +++ b/addons/vector/functions/fnc_showRelativeHeightLength.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showRelativeHeightLength + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/functions/fnc_showReticle.sqf b/addons/vector/functions/fnc_showReticle.sqf index bcd565774f..5fd1729c4f 100644 --- a/addons/vector/functions/fnc_showReticle.sqf +++ b/addons/vector/functions/fnc_showReticle.sqf @@ -1,11 +1,19 @@ -/* - -by commy2 - -Shows or hides the electronic reticle. - -*/ #include "script_component.hpp" +/* + * Author: commy2 + * Shows or hides the electronic reticle. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_vector_fnc_showReticle + * + * Public: No + */ ((GETUVAR(ACE_dlgVector,displayNull)) displayCtrl 1302) ctrlSetText (["", QPATHTOF(rsc\vector_crosshair.paa)] select (_this select 0)); diff --git a/addons/vector/functions/fnc_showText.sqf b/addons/vector/functions/fnc_showText.sqf index b578269115..a8556e7a58 100644 --- a/addons/vector/functions/fnc_showText.sqf +++ b/addons/vector/functions/fnc_showText.sqf @@ -1,5 +1,19 @@ -// by commy2 #include "script_component.hpp" +/* + * Author: commy2 + * + * + * Arguments: + * 0: String + * + * Return Value: + * None + * + * Example: + * ["5"] call ace_vector_fnc_showText + * + * Public: No + */ disableSerialization; private _dlgVector = GETUVAR(ACE_dlgVector,displayNull); diff --git a/addons/vector/script_component.hpp b/addons/vector/script_component.hpp index 091481fbcd..15787b140f 100644 --- a/addons/vector/script_component.hpp +++ b/addons/vector/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_VECTOR diff --git a/addons/vector/stringtable.xml b/addons/vector/stringtable.xml index fd8d73858c..76feaa2b5c 100644 --- a/addons/vector/stringtable.xml +++ b/addons/vector/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Vector 21 Nite Vector 21 Nite Vector 21 Nite + ベクター 21 ナイト + Vector 21 Nite + Vector 21 Nite + Vector 21 Nite Vector 21 @@ -24,6 +28,10 @@ Vector 21 Vector 21 Vector 21 + ベクター 21 + Vector 21 + Vector 21 + Vector 21 Rangefinder @@ -36,6 +44,10 @@ Távolságmérő Medidor de Distância Дальномер + 測距機器 + 거리측정기 + 测距仪 + 測距儀 Vector - Azimuth Key @@ -48,6 +60,10 @@ Vector - Tecla de Azimute Vector - Irányszög gomb Vector – Азимут + ベクター - 方位角キー + Vector - 방위각 키 + Vector - 方位按键 + Vector - 方位按鍵 Vector - Distance Key @@ -60,6 +76,10 @@ Vector - Tecla de Distância Vector - Távolság gomb Vector – Расстояние + ベクター - 距離キー + Vector - 거리 키 + Vector - 距离按键 + Vector - 距離按鍵 diff --git a/addons/vehiclelock/ACE_Settings.hpp b/addons/vehiclelock/ACE_Settings.hpp index f8a431410f..29367b707f 100644 --- a/addons/vehiclelock/ACE_Settings.hpp +++ b/addons/vehiclelock/ACE_Settings.hpp @@ -1,20 +1,11 @@ class ACE_Settings { class GVAR(defaultLockpickStrength) { - displayName = CSTRING(DefaultLockpickStrength_DisplayName); - description = CSTRING(DefaultLockpickStrength_Description); - value = 10; - typeName = "SCALAR"; + movedToSQF = 1; }; class GVAR(lockVehicleInventory) { - displayName = CSTRING(LockVehicleInventory_DisplayName); - description = CSTRING(LockVehicleInventory_Description); - value = 0; - typeName = "BOOL"; + movedToSQF = 1; }; class GVAR(vehicleStartingLockState) { - displayName = CSTRING(VehicleStartingLockState_DisplayName); - description = CSTRING(VehicleStartingLockState_Description); - value = -1; - typeName = "SCALAR"; + movedToSQF = 1; }; }; diff --git a/addons/vehiclelock/CfgVehicles.hpp b/addons/vehiclelock/CfgVehicles.hpp index bf4231f426..1115928057 100644 --- a/addons/vehiclelock/CfgVehicles.hpp +++ b/addons/vehiclelock/CfgVehicles.hpp @@ -4,21 +4,18 @@ displayName = CSTRING(Action_UnLock); \ 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); \ - priority = 0.3; \ icon = QPATHTOF(UI\key_menuIcon_ca.paa); \ }; \ class ACE_lockVehicle { \ displayName = CSTRING(Action_Lock); \ 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); \ - priority = 0.2; \ icon = QPATHTOF(UI\key_menuIcon_ca.paa); \ }; \ class ACE_lockpickVehicle { \ displayName = CSTRING(Action_Lockpick); \ condition = QUOTE([ARR_3(_player, _target, 'canLockpick')] call FUNC(lockpick)); \ statement = QUOTE([ARR_3(_player, _target, 'startLockpick')] call FUNC(lockpick)); \ - priority = 0.1; \ }; \ }; \ class ACE_Actions { \ @@ -28,7 +25,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); \ - priority = 0.3; \ + exceptions[] = {"isNotSwimming"}; \ icon = QPATHTOF(UI\key_menuIcon_ca.paa); \ }; \ class ACE_lockVehicle { \ @@ -36,7 +33,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); \ - priority = 0.2; \ + exceptions[] = {"isNotSwimming"}; \ icon = QPATHTOF(UI\key_menuIcon_ca.paa); \ }; \ class ACE_lockpickVehicle { \ @@ -44,7 +41,7 @@ distance = 4; \ condition = QUOTE([ARR_3(_player, _target, 'canLockpick')] call FUNC(lockpick)); \ statement = QUOTE([ARR_3(_player, _target, 'startLockpick')] call FUNC(lockpick)); \ - priority = 0.1; \ + exceptions[] = {"isNotSwimming"}; \ }; \ }; \ }; @@ -61,6 +58,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 +76,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/XEH_preInit.sqf b/addons/vehiclelock/XEH_preInit.sqf index a7feade1c3..9361d05015 100644 --- a/addons/vehiclelock/XEH_preInit.sqf +++ b/addons/vehiclelock/XEH_preInit.sqf @@ -2,6 +2,10 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +#include "initSettings.sqf" ADDON = true; diff --git a/addons/vehiclelock/config.cpp b/addons/vehiclelock/config.cpp index 52299ca512..454fb4952a 100644 --- a/addons/vehiclelock/config.cpp +++ b/addons/vehiclelock/config.cpp @@ -20,8 +20,3 @@ class CfgPatches { #include "CfgMagazines.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" - -class ACE_newEvents { - VehicleLock_SetVehicleLock = QGVAR(setVehicleLock); - VehicleLock_SetupCustomKey = QGVAR(setupCustomKey); -}; diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index b45bf150f3..e88105e398 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Adds a key to a unit that will open a vehicle @@ -16,9 +17,6 @@ * * Public: Yes */ -#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..5e78e55edb 100644 --- a/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf +++ b/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Returns the side specifc key for a vehicle @@ -13,19 +14,16 @@ * * Public: No */ -#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..e79a7b1573 100644 --- a/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf +++ b/addons/vehiclelock/functions/fnc_handleVehicleInitPost.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * For every lockable vehicle, sets the starting lock state to a sane value. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" if (!isServer) exitWith {}; @@ -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..149ece1f95 100644 --- a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Returns if user has a valid key for the vehicle @@ -14,9 +15,6 @@ * * Public: No */ -#include "script_component.hpp" - -private ["_returnValue","_sideKeyName","_customKeys"]; params ["_unit", "_veh"]; TRACE_2("params",_unit,_veh); @@ -24,17 +22,18 @@ 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}; +private _items = _unit call EFUNC(common,uniqueItems); +if ("ACE_key_master" in _items) then {_returnValue = true}; //Check side key -_sideKeyName = [_veh] call FUNC(getVehicleSideKey); -if (_sideKeyName in (items _unit)) then {_returnValue = true}; +private _sideKeyName = [_veh] call FUNC(getVehicleSideKey); +if (_sideKeyName in _items) 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 bf15a6eadd..66ed89fa6f 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles lockpick functionality. Three different functions: @@ -18,9 +19,6 @@ * * Public: No */ -#include "script_component.hpp" - -private ["_vehLockpickStrenth","_condition","_returnValue"]; params ["_unit", "_veh", "_funcType"]; TRACE_3("params",_unit,_veh,_funcType); @@ -32,16 +30,16 @@ if (isNull _veh) exitWith {ERROR("null vehicle"); false}; if ((locked _veh) == 0) exitWith {false}; //need lockpick item -if (!("ACE_key_lockpick" in (items _unit))) exitWith {false}; +if !("ACE_key_lockpick" in (_unit call EFUNC(common,uniqueItems))) 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,10 +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] 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..16e81e85ea 100644 --- a/addons/vehiclelock/functions/fnc_moduleInit.sqf +++ b/addons/vehiclelock/functions/fnc_moduleInit.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Function for setup module. Sets default lockpick strength and default lock state. @@ -15,9 +16,6 @@ * * Public: No */ -#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..f65ad5399d 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Function for sync module. Assigns keys for all synced vehicles to any players that are synced. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" if (!isServer) exitWith {}; @@ -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/functions/fnc_onOpenInventory.sqf b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf index fb8972ef1d..836cccc21d 100644 --- a/addons/vehiclelock/functions/fnc_onOpenInventory.sqf +++ b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handles the inventory opening. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_container"]; TRACE_2("params",_unit,_container); diff --git a/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf b/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf index 957619a057..7018e67bcb 100644 --- a/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf +++ b/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * On the server: Adds a key (magazineDetail name) to approved keys for a vehicle. @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_veh", "_key"]; TRACE_2("params",_veh,_key); diff --git a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf index 113a4ad505..8f38d48f37 100644 --- a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf +++ b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Sets a vehicle lock state because of a "ace_vehiclelock_setVehicleLock" event @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_veh", "_isLocked"]; TRACE_2("params",_veh,_isLocked); diff --git a/addons/vehiclelock/initSettings.sqf b/addons/vehiclelock/initSettings.sqf new file mode 100644 index 0000000000..238268a8dc --- /dev/null +++ b/addons/vehiclelock/initSettings.sqf @@ -0,0 +1,28 @@ +// CBA Settings [ADDON: ace_vehicleLock]: + +[ + QGVAR(defaultLockpickStrength), "SLIDER", + [LSTRING(DefaultLockpickStrength_DisplayName), LSTRING(DefaultLockpickStrength_Description)], + LSTRING(DisplayName), + [-1,60,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true, // isGlobal + {[QGVAR(defaultLockpickStrength), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(lockVehicleInventory), "CHECKBOX", + [LSTRING(LockVehicleInventory_DisplayName), LSTRING(LockVehicleInventory_Description)], + LSTRING(DisplayName), + false, // default value + true, // isGlobal + {[QGVAR(lockVehicleInventory), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; + +[ + QGVAR(vehicleStartingLockState), "LIST", + [LSTRING(VehicleStartingLockState_DisplayName), LSTRING(VehicleStartingLockState_Description)], + LSTRING(DisplayName), + [[-1,0,1,2],["str_cfg_envsounds_default", LSTRING(VehicleStartingLockState_AsIs), LSTRING(VehicleStartingLockState_Locked), LSTRING(VehicleStartingLockState_Unlocked)], 0], // [values, titles, defaultIndex] + true, // isGlobal + {[QGVAR(vehicleStartingLockState), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_settings_fnc_init; diff --git a/addons/vehiclelock/script_component.hpp b/addons/vehiclelock/script_component.hpp index 8846951780..77b7186373 100644 --- a/addons/vehiclelock/script_component.hpp +++ b/addons/vehiclelock/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_VEHICLELOCK diff --git a/addons/vehiclelock/stringtable.xml b/addons/vehiclelock/stringtable.xml index 32e9c762d0..3898f74e16 100644 --- a/addons/vehiclelock/stringtable.xml +++ b/addons/vehiclelock/stringtable.xml @@ -1,6 +1,15 @@ - + + + ACE Vehicle Lock + ACE Blocco Veicolo + ACE 載具上鎖 + ACE 载具上锁 + ACE 車両の施錠 + ACE 차량 잠금 + ACE Fahrzeugsperre + Unlock Vehicle Fahrzeug aufschließen @@ -10,8 +19,12 @@ Odemknout vozidlo Jármű nyitása Открыть машину - Sblocca il veicolo + Sblocca il Veicolo Destravar veículo + 車両の鍵を開ける + 차량 잠금열기 + 载具解锁 + 載具解鎖 Lock Vehicle @@ -22,8 +35,12 @@ Zamknout vozidlo Jármű zárása Закрыть машину - Chiudi il veicolo a chiave + Chiudi il Veicolo a chiave Travar Veículo + 車両を施錠 + 차량 잠그기 + 载具上锁 + 載具上鎖 Lockpick Vehicle @@ -36,6 +53,10 @@ Взломать замок Scassina veicolo Usar mixa no Veículo + 鍵をこじ開ける + 차량 문따기 + 解锁载具 + 解鎖載具 Picking Lock... @@ -48,6 +69,10 @@ Взламываем замок... Scassino il veicolo... Usando Mixa... + 鍵をこじ開けている・・・ + 문따는중... + 解锁中... + 解鎖中... A custom key that will open a specific vehicle. @@ -60,6 +85,10 @@ Ключ от конкретной машины. Una chiave personalizzata che apre determinati veicoli. Uma chave específica que abre um veículo específico. + カスタム キーは特定車両を開けられます。 + 특정 차량을 여는 특수 열쇠 + 使用指定的钥匙来开启特定的载具 + 使用指定的鑰匙來開啟特定的載具 A Master Key will open any lock, no matter what! @@ -72,6 +101,10 @@ Универсальный ключ, открывающий любой замок. Un passe-partout che apre qualsiasi serratura! Uma chave mestre irá abrir qualquer fechadura, não importa qual! + マスター キーは全ての鍵を開けられます。 + 어떤 차량도 열 수 있는 마스터키 입니다! + 万用解锁钥匙,能解锁任何载具 + 萬用解鎖鑰匙,能解鎖任何載具 A lockpick set that can pick the locks of most vehicles. @@ -84,6 +117,10 @@ Набор отмычек, которым можно взломать почти любую машину. Un grimardello per forzare la maggior parte dei veicoli Um set de chave mixas que pode abrir a maioria dos veículos. + ピッキング ツールでは多くの車両をこじ開けられます。 + 거의 모든 차량을 열 수 있게 해주는 해정도구 모음입니다. + 一组解锁钥匙 (可解锁大部份载具) + 一組解鎖鑰匙 (可解鎖大部份載具) A key that should open most WEST vehicles. @@ -96,6 +133,10 @@ Ключ для открытия большинства машин Красных. Una chiave che apre la maggior parte dei veicoli occidentali Uma chave que abre a maioria dos veículos ocidentais + このキーは多くの同盟軍車両を開けられます。 + 거의 모든 서방진영 차량을 여는 열쇠입니다. + 一组解锁钥匙 (可解锁大部份蓝方载具) + 一組解鎖鑰匙 (可解鎖大部份藍方載具) A key that should open most EAST vehicle. @@ -108,6 +149,10 @@ Ключ для открытия большинства машин Синих. Una chaive che apre la maggior parte dei veicoli orientali Uma chave que abre a maioria dos veículos orientais + このキーは多くのOPFOR軍車両を開けられます。 + 거의 모든 동방진영 차량을 여는 열쇠입니다. + 一组解锁钥匙 (可解锁大部份红方载具) + 一組解鎖鑰匙 (可解鎖大部份紅方載具) A key that should open most INDEP vehicle. @@ -120,6 +165,10 @@ Ключ для открытия большинства машин Независимых. Una chaive che apre la maggior parte dei veicoli degli indipendenti Uma chave que abre a maioria dos veículos independentes + このキーは多くの独立軍車両を開けられます。 + 거의 모든 중립진영 차량을 여는 열쇠입니다. + 一组解锁钥匙 (可解锁大部份独立方载具) + 一組解鎖鑰匙 (可解鎖大部份獨立方載具) A key that should open most CIV vehicle. @@ -132,6 +181,10 @@ Ключ для открытия большинства машин Гражданских. Una chaive che apr ela maggior parte dei veicoli civili Uma chave que abre a maioria dos veículos civis. + このキーは多くの市民車両を開けられます。 + 거의 모든 민간인 차량을 여는 열쇠입니다 + 一组解锁钥匙 (可解锁大部份平民载具) + 一組解鎖鑰匙 (可解鎖大部份平民載具) Vehicle Lock Setup @@ -144,6 +197,10 @@ Jármű-zár beállítás Запирание транспорта Impostazioni Blocco Veicolo + 車両の施錠設定 + 차량 잠금 설정 + 载具上锁设置 + 載具上鎖設置 Lock Vehicle Inventory @@ -156,6 +213,10 @@ Jármű rakodótér zárás Закрывать инвентарь транспорта Blocca Inventario Veicolo + 施錠されている車両のインベントリ + 차량 소지품 잠금 + 上锁载具的车箱 + 上鎖載具的車箱 Locks the inventory of locked vehicles @@ -168,6 +229,10 @@ Bezárja a zárt járművek rakterét is Закрывать инвентарь транспорта, если транспорт закрыт Blocca l'inventario di un veicolo bloccato + 施錠されている車両の開けないインベントリ + 잠긴 차량의 소지품을 뒤지지못하게 합니다. + 上锁载具的车箱,使玩家不能拿取/查看载具内的装备 + 上鎖載具的車箱,使玩家不能拿取/查看載具內的裝備 Vehicle Starting Lock State @@ -180,6 +245,10 @@ Jármű kezdő zár-állapot Начальное состояние замков Stato Iniziale del Blocco per Veicoli + 開始時における車両の鍵の状態 + 시작시 차량 잠금 상태 + 载具初始上锁状态 + 載具初始上鎖狀態 Set lock state for all vehicles (removes ambiguous lock states) @@ -192,6 +261,10 @@ 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) + 全車両へ鍵の状態を設定します。(あいまいな鍵の状態を削除) + 모든 차량의 잠금 상태를 정합니다. (애매한 잠금 상태는 모두 없앱니다.) + 设定所有载具的初始上锁状态 (移除不明确的锁定状态) + 設定所有載具的初始上鎖狀態 (移除不明確的鎖定狀態) As Is @@ -204,6 +277,10 @@ Úgy-ahogy Как есть Com'è + そのまま + 그대로 + 无变化 + 無變化 Locked @@ -216,6 +293,10 @@ Zárva Закрыт Bloccato + 施錠ずみ + 잠김 + 上锁 + 上鎖 Unlocked @@ -228,6 +309,10 @@ Nyitva Открыт Sbloccato + 開錠ずみ + 열림 + 解锁 + 解鎖 Default Lockpick Strength @@ -240,6 +325,10 @@ Alapértelmezett zártörő-erősség Сила отмычки по-умолчанию Durabilità Default del Grimaldello + ピッキング ツールの能力設定 + 기본 해정도구 설정 + 预设开锁能力 + 預設開鎖能力 Default Time to lockpick (in seconds). Default: 10 @@ -252,6 +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 Settings for lockpick strength and initial vehicle lock state. Removes ambiguous lock states. @@ -264,6 +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 @@ -276,6 +373,10 @@ Járműkulcs-osztás Назначение ключей от транспорта Assegna Chiavi Veicoli + 車両の鍵を割り当て + 차량 열쇠 등록 + 指定载具钥匙 + 指定載具鑰匙 Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Only valid for objects present at mission start. @@ -288,6 +389,10 @@ Szinkronizál a járművekkel és játékosokkal. Egyedi kulcsokat oszt ki a játékosoknak minden szinkronizált járműhöz. Csak a küldetés indításakor jelenlévő járművekhez érvényes. Синхронизируйте с транспортом и игроком. Это выдаст игроку ключи от всех синхронизированных транспортных средств. Работает только для объектов, присутствующих на старте миссии 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/CfgVehicles.hpp b/addons/vehicles/CfgVehicles.hpp index 8834cc1d4d..ff79ed26f4 100644 --- a/addons/vehicles/CfgVehicles.hpp +++ b/addons/vehicles/CfgVehicles.hpp @@ -68,44 +68,17 @@ class CfgVehicles { class APC_Tracked_01_base_F: Tank_F { fuelCapacity = 500 * FUEL_FACTOR; - class Turrets: Turrets { - class MainTurret: MainTurret { - class Turrets; - }; - }; }; class APC_Tracked_02_base_F: Tank_F { fuelCapacity = 600 * FUEL_FACTOR; // NO FUCKING DATA - class Turrets: Turrets { - class MainTurret: MainTurret { - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; - }; - }; - }; - - class O_APC_Tracked_02_base_F: APC_Tracked_02_base_F {}; - - class O_APC_Tracked_02_cannon_F: O_APC_Tracked_02_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - weapons[] = {"autocannon_30mm_CTWS","ACE_LMG_coax_PKT_mem2","missiles_titan"}; - magazines[] = {"140Rnd_30mm_MP_shells_Tracer_Green","60Rnd_30mm_APFSDS_shells_Tracer_Green","2000Rnd_762x51_Belt_Green","2Rnd_GAT_missiles"}; - }; - }; }; class APC_Tracked_03_base_F: Tank_F { fuelCapacity = 660 * FUEL_FACTOR; class Turrets: Turrets { class MainTurret: MainTurret { - weapons[] = {"autocannon_30mm","ACE_LMG_coax_L94A1_mem3"}; - magazines[] = {"140Rnd_30mm_MP_shells_Tracer_Yellow","60Rnd_30mm_APFSDS_shells_Tracer_Yellow","1000Rnd_762x51_Belt_Yellow","1000Rnd_762x51_Belt_Yellow"}; - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; + weapons[] = {"autocannon_30mm","ACE_LMG_coax_L94A1_mem3"}; // Base 1.82: "autocannon_30mm","LMG_coax" }; }; }; @@ -114,11 +87,7 @@ class CfgVehicles { fuelCapacity = 550 * FUEL_FACTOR; class Turrets: Turrets { class MainTurret: MainTurret { - weapons[] = {"cannon_120mm_long","ACE_LMG_coax_MAG58_mem3"}; - magazines[] = {"28Rnd_120mm_APFSDS_shells_Tracer_Yellow","14Rnd_120mm_HE_shells_Tracer_Yellow","2000Rnd_762x51_Belt_Yellow","2000Rnd_762x51_Belt_Yellow"}; - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; + weapons[] = {"cannon_120mm_long","ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "cannon_120mm_long","LMG_coax" }; }; }; @@ -127,64 +96,54 @@ class CfgVehicles { fuelCapacity = 500 * FUEL_FACTOR; class Turrets: Turrets { class MainTurret: MainTurret { - weapons[] = {"cannon_120mm","ACE_LMG_coax_MAG58_mem2"}; - magazines[] = {"32Rnd_120mm_APFSDS_shells_Tracer_Red","16Rnd_120mm_HE_shells_Tracer_Red","2000Rnd_762x51_Belt_Red","2000Rnd_762x51_Belt_Red"}; - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; + weapons[] = {"cannon_120mm", "ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "cannon_120mm","LMG_coax" }; }; }; class B_MBT_01_base_F: MBT_01_base_F {}; - class B_MBT_01_cannon_F: B_MBT_01_base_F {}; - - class MBT_02_base_F: Tank_F { - fuelCapacity = 600 * FUEL_FACTOR; // again, couldn't find proper data + class B_MBT_01_TUSK_F: B_MBT_01_cannon_F { class Turrets: Turrets { class MainTurret: MainTurret { - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; + weapons[] = {"cannon_120mm", "ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "cannon_120mm","LMG_coax" }; }; }; + + + + class MBT_02_base_F: Tank_F { + fuelCapacity = 600 * FUEL_FACTOR; // again, couldn't find proper data + }; + + + // Change boat minigun ammo to 7.62 class Ship_F: Ship {}; - class Boat_F: Ship_F {}; - class Boat_Armed_01_base_F: Boat_F { class Turrets: Turrets { class FrontTurret; class RearTurret: FrontTurret {}; }; }; - - class Boat_Armed_01_minigun_base_F: Boat_Armed_01_base_F {}; - - class B_Boat_Armed_01_minigun_F: Boat_Armed_01_minigun_base_F { + class Boat_Armed_01_minigun_base_F: Boat_Armed_01_base_F { class Turrets: Turrets { - class FrontTurret: FrontTurret {}; class RearTurret: RearTurret { - magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; + magazines[] = {"2000Rnd_762x51_Belt_T_Red"}; // Base 1.82: "2000Rnd_65x39_belt_Tracer_Red" }; }; }; - class I_Boat_Armed_01_minigun_F: Boat_Armed_01_minigun_base_F { class Turrets: Turrets { - class FrontTurret: FrontTurret {}; class RearTurret: RearTurret { - magazines[] = {"2000Rnd_762x51_Belt_T_Yellow"}; + magazines[] = {"2000Rnd_762x51_Belt_T_Yellow"}; // Base 1.82: "2000Rnd_65x39_Belt_Tracer_Yellow" }; }; }; - class Truck_F: Car_F { - class Turrets: Turrets {}; - }; + class Truck_F: Car_F {}; class MRAP_01_base_F: Car_F { fuelCapacity = 510 * FUEL_FACTOR; @@ -193,15 +152,7 @@ class CfgVehicles { class MRAP_02_base_F: Car_F { fuelCapacity = 500 * FUEL_FACTOR; // couldn't find any data for the punisher }; - - class O_MRAP_02_F: MRAP_02_base_F { - class Turrets; - }; - - class Offroad_01_base_F: Car_F { - //fuelCapacity = 45; - }; - + class MRAP_03_base_F: Car_F { fuelCapacity = 860 * FUEL_FACTOR; smokeLauncherGrenadeCount = 3; @@ -217,7 +168,6 @@ class CfgVehicles { smokeLauncherGrenadeCount = 3; smokeLauncherAngle = 80; class Turrets: Turrets { - class MainTurret: MainTurret {}; class CommanderTurret: CommanderTurret { stabilizedInAxes = 3; }; @@ -228,7 +178,6 @@ class CfgVehicles { smokeLauncherGrenadeCount = 3; smokeLauncherAngle = 80; class Turrets: Turrets { - class MainTurret: MainTurret {}; class CommanderTurret: CommanderTurret { stabilizedInAxes = 3; }; @@ -237,190 +186,96 @@ class CfgVehicles { class Truck_01_base_F: Truck_F { fuelCapacity = 644 * FUEL_FACTOR; - class Turrets; }; class Truck_02_base_F: Truck_F { fuelCapacity = 1100 * FUEL_FACTOR; - class Turrets; }; class Truck_03_base_F: Truck_F { fuelCapacity = 900 * FUEL_FACTOR; // NO. FUCKING. DATA. - class Turrets; - }; - - class Hatchback_01_base_F: Car_F { - //fuelCapacity = 45; - class Turrets; - }; - - class SUV_01_base_F: Car_F { - //fuelCapacity = 45; - class Turrets; - }; - - class Van_01_base_F: Truck_F { - //fuelCapacity = 45; - class Turrets; }; class APC_Wheeled_01_base_F: Wheeled_APC_F { fuelCapacity = 800 * FUEL_FACTOR; class Turrets: Turrets { - class MainTurret: MainTurret { - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; - }; + class MainTurret: MainTurret {}; }; }; - class B_APC_Wheeled_01_base_F: APC_Wheeled_01_base_F {}; - class B_APC_Wheeled_01_cannon_F: B_APC_Wheeled_01_base_F { class Turrets: Turrets { class MainTurret: MainTurret { - weapons[] = {"autocannon_40mm_CTWS","ACE_LMG_coax_MAG58_mem2"}; - magazines[] = {"60Rnd_40mm_GPR_Tracer_Red_shells","40Rnd_40mm_APFSDS_Tracer_Red_shells","2000Rnd_762x51_Belt_Red"}; + weapons[] = {"autocannon_40mm_CTWS","ACE_LMG_coax_MAG58_mem3"}; // Base 1.82: "autocannon_40mm_CTWS","LMG_coax" }; }; }; class APC_Wheeled_02_base_F: Wheeled_APC_F { fuelCapacity = 700 * FUEL_FACTOR; - class Turrets: Turrets { - class MainTurret: MainTurret { - class Turrets; - }; - - class CommanderOptics: CommanderOptics {}; - }; - }; - - class B_MBT_01_TUSK_F: B_MBT_01_cannon_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - weapons[] = {"cannon_105mm","ACE_LMG_coax_MAG58_mem2"}; - magazines[] = {"40Rnd_105mm_APFSDS_T_Red","20Rnd_105mm_HEAT_MP_T_Red","2000Rnd_762x51_Belt_Red","2000Rnd_762x51_Belt_Red"}; - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; - }; - }; - }; }; class APC_Wheeled_03_base_F: Wheeled_APC_F { fuelCapacity = 700 * FUEL_FACTOR; + class Turrets: Turrets { + class MainTurret: MainTurret {}; + }; + }; + class I_APC_Wheeled_03_base_F: APC_Wheeled_03_base_F {}; + class I_APC_Wheeled_03_cannon_F: I_APC_Wheeled_03_base_F { class Turrets: Turrets { class MainTurret: MainTurret { - class Turrets: Turrets { - class CommanderOptics: CommanderOptics {}; + weapons[] = {"autocannon_30mm_CTWS","ACE_LMG_coax_ext_MAG58", "missiles_titan"}; // Base 1.82: "autocannon_30mm_CTWS","LMG_coax_ext","missiles_titan" + }; + }; + }; + + // Tanks DLC Wiesel 2 + class LT_01_base_F : Tank_F { + class Turrets : Turrets { + class MainTurret : MainTurret {}; + }; + }; + class LT_01_cannon_base_F : LT_01_base_F { + class Turrets : Turrets { + class MainTurret : MainTurret { + weapons[] = { + "SmokeLauncher", + "ACE_LMG_coax_ext_MG3", + "ACE_cannon_20mm_Rh202" }; }; }; }; - class I_APC_Wheeled_03_base_F: APC_Wheeled_03_base_F {}; - - class I_APC_Wheeled_03_cannon_F: I_APC_Wheeled_03_base_F { - class Turrets: Turrets { + // Tanks DLC Rooikat 120 + class AFV_Wheeled_01_base_F : wheeled_APC_F { + class Turrets : Turrets { class MainTurret: MainTurret { - weapons[] = {"autocannon_30mm_CTWS","ACE_LMG_coax_MAG58_mem2","missiles_titan"}; - magazines[] = {"140Rnd_30mm_MP_shells_Tracer_Yellow","60Rnd_30mm_APFSDS_shells_Tracer_Yellow","2000Rnd_762x51_Belt_Yellow","2Rnd_GAT_missiles"}; + weapons[] = {"ACE_cannon_120mm_GT12","ACE_LMG_coax_DenelMG4"}; + magazines[] = {"12Rnd_120mm_APFSDS_shells_Tracer_Red","8Rnd_120mm_HE_shells_Tracer_Red","8Rnd_120mm_HEAT_MP_T_Red","4Rnd_120mm_LG_cannon_missiles","200Rnd_762x51_Belt_T_Red","200Rnd_762x51_Belt_T_Red","200Rnd_762x51_Belt_T_Red","200Rnd_762x51_Belt_T_Red"}; }; }; }; - // static mgs shouldn't use 500 rnd mags. - class StaticWeapon: LandVehicle { - class Turrets { - class MainTurret; //: NewTurret {}; - }; - }; - - class StaticMGWeapon: StaticWeapon {}; - - class HMG_01_base_F: StaticMGWeapon { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag","100Rnd_127x99_mag","100Rnd_127x99_mag","100Rnd_127x99_mag","100Rnd_127x99_mag"}; + // Tanks DLC Armata + class MBT_04_base_F : Tank_F { + class Turrets : Turrets { + class MainTurret : MainTurret { + class Turrets : Turrets { + class CommanderOptics: CommanderOptics {}; + }; }; }; }; - - class B_HMG_01_F: HMG_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red"}; - }; - }; - }; - - class O_HMG_01_F: HMG_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green"}; - }; - }; - }; - - class I_HMG_01_F: HMG_01_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow"}; - }; - }; - }; - - class HMG_01_high_base_F: HMG_01_base_F {}; - - class B_HMG_01_high_F: HMG_01_high_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red"}; - }; - }; - }; - - class O_HMG_01_high_F: HMG_01_high_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green"}; - }; - }; - }; - - class I_HMG_01_high_F: HMG_01_high_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow"}; - }; - }; - }; - - class HMG_01_A_base_F: HMG_01_base_F {}; - - class B_HMG_01_A_F: HMG_01_A_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red","100Rnd_127x99_mag_Tracer_Red"}; - }; - }; - }; - - class O_HMG_01_A_F: HMG_01_A_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green","100Rnd_127x99_mag_Tracer_Green"}; - }; - }; - }; - - class I_HMG_01_A_F: HMG_01_A_base_F { - class Turrets: Turrets { - class MainTurret: MainTurret { - magazines[] = {"100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow","100Rnd_127x99_mag_Tracer_Yellow"}; + class MBT_04_cannon_base_F : MBT_04_base_F { + class Turrets : Turrets { + class MainTurret : MainTurret { + class Turrets : Turrets { + class CommanderOptics: CommanderOptics { + weapons[] = {"ACE_HMG_127_KORD","SmokeLauncher"}; + }; + }; }; }; }; diff --git a/addons/vehicles/CfgWeapons.hpp b/addons/vehicles/CfgWeapons.hpp index c4d28c3e31..4c1c4575b9 100644 --- a/addons/vehicles/CfgWeapons.hpp +++ b/addons/vehicles/CfgWeapons.hpp @@ -3,31 +3,18 @@ class CfgWeapons { class MGunCore; class MGun: MGunCore {}; class LMG_RCWS: MGun {}; + class LMG_coax: LMG_RCWS {}; + class LMG_coax_ext: LMG_coax {}; - class LMG_coax; class ACE_LMG_coax_L94A1_mem3: LMG_coax {}; - class ACE_LMG_coax_PKT_mem2: LMG_coax { - class GunParticles { - class effect1 { - positionName = "usti hlavne2"; - directionName = "konec hlavne2"; - effectName = "MachineGunCloud"; - }; - }; - }; class ACE_LMG_coax_MAG58_mem3: LMG_coax {}; - class ACE_LMG_coax_MAG58_mem2: LMG_coax { - class GunParticles { - class effect1 { - positionName = "usti hlavne2"; - directionName = "konec hlavne2"; - effectName = "MachineGunCloud"; - }; - }; - }; + class ACE_LMG_coax_ext_MAG58: LMG_coax_ext {}; + class ACE_LMG_coax_ext_MG3: LMG_coax_ext {}; + class ACE_LMG_coax_DenelMG4 : LMG_coax {}; class LMG_Minigun: LMG_RCWS { - magazines[] = {"1000Rnd_65x39_Belt","1000Rnd_65x39_Belt_Green","1000Rnd_65x39_Belt_Tracer_Green","1000Rnd_65x39_Belt_Tracer_Red","1000Rnd_65x39_Belt_Tracer_Yellow","1000Rnd_65x39_Belt_Yellow","2000Rnd_65x39_Belt","2000Rnd_65x39_Belt_Green","2000Rnd_65x39_Belt_Tracer_Green","2000Rnd_65x39_Belt_Tracer_Green_Splash","2000Rnd_65x39_Belt_Tracer_Red","2000Rnd_65x39_Belt_Tracer_Yellow","2000Rnd_65x39_Belt_Tracer_Yellow_Splash","2000Rnd_65x39_Belt_Yellow","2000Rnd_762x51_Belt_T_Green","2000Rnd_762x51_Belt_T_Red","2000Rnd_762x51_Belt_T_Yellow","200Rnd_65x39_Belt","200Rnd_65x39_Belt_Tracer_Green","200Rnd_65x39_Belt_Tracer_Red","200Rnd_65x39_Belt_Tracer_Yellow","5000Rnd_762x51_Belt","5000Rnd_762x51_Yellow_Belt","500Rnd_65x39_Belt","500Rnd_65x39_Belt_Tracer_Red_Splash","500Rnd_65x39_Belt_Tracer_Green_Splash","500Rnd_65x39_Belt_Tracer_Yellow_Splash"}; + // Add the following: "2000Rnd_762x51_Belt_T_Green","2000Rnd_762x51_Belt_T_Red","2000Rnd_762x51_Belt_T_Yellow","5000Rnd_762x51_Belt","5000Rnd_762x51_Yellow_Belt" + magazines[] = {"PylonWeapon_2000Rnd_65x39_belt", "1000Rnd_65x39_Belt","1000Rnd_65x39_Belt_Green","1000Rnd_65x39_Belt_Tracer_Green","1000Rnd_65x39_Belt_Tracer_Red","1000Rnd_65x39_Belt_Tracer_Yellow","1000Rnd_65x39_Belt_Yellow","2000Rnd_65x39_Belt","2000Rnd_65x39_Belt_Green","2000Rnd_65x39_Belt_Tracer_Green","2000Rnd_65x39_Belt_Tracer_Green_Splash","2000Rnd_65x39_Belt_Tracer_Red","2000Rnd_65x39_Belt_Tracer_Yellow","2000Rnd_65x39_Belt_Tracer_Yellow_Splash","2000Rnd_65x39_Belt_Yellow","2000Rnd_762x51_Belt_T_Green","2000Rnd_762x51_Belt_T_Red","2000Rnd_762x51_Belt_T_Yellow","200Rnd_65x39_Belt","200Rnd_65x39_Belt_Tracer_Green","200Rnd_65x39_Belt_Tracer_Red","200Rnd_65x39_Belt_Tracer_Yellow","5000Rnd_762x51_Belt","5000Rnd_762x51_Yellow_Belt","500Rnd_65x39_Belt","500Rnd_65x39_Belt_Tracer_Red_Splash","500Rnd_65x39_Belt_Tracer_Green_Splash","500Rnd_65x39_Belt_Tracer_Yellow_Splash"}; }; class HMG_127: LMG_RCWS { @@ -36,36 +23,21 @@ class CfgWeapons { class HMG_01: HMG_127 { reloadTime = 0.23; - class manual: manual { reloadTime = 0.23; }; - class close: manual {}; - class short: close {}; - class medium: close {}; - 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; - }; + class HMG_127_APC : HMG_127 {}; + class ACE_HMG_127_KORD : HMG_127_APC {}; - 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; - }; + // Tanks DLC: weapons for Wiesel and Rooikat + class CannonCore; + class autocannon_Base_F : CannonCore {}; + class cannon_20mm : autocannon_Base_F {}; + class ACE_cannon_20mm_Rh202 : cannon_20mm {}; - muzzles[] = {"AP"}; - }; + class cannon_120mm : CannonCore {}; + class ACE_cannon_120mm_GT12 : cannon_120mm {}; - // 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..3afea03187 100644 --- a/addons/vehicles/XEH_postInit.sqf +++ b/addons/vehicles/XEH_postInit.sqf @@ -15,10 +15,10 @@ 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' || + {vehicle ACE_player isKindOf 'Car' || {vehicle ACE_player isKindOf 'Tank'}}) exitWith {false}; GVAR(isUAV) = false; @@ -30,3 +30,19 @@ GVAR(isSpeedLimiter) = false; }, {false}, [211, [false, false, false]], false] call CBA_fnc_addKeybind; //DELETE Key + +["ACE3 Vehicles", QGVAR(scrollUp), localize LSTRING(IncreaseSpeedLimit), { + if (GVAR(isSpeedLimiter)) then { + GVAR(speedLimit) = round (GVAR(speedLimit) + 1) max 5; + [["%1: %2", LSTRING(SpeedLimit), GVAR(speedLimit)]] call EFUNC(common,displayTextStructured); + true + }; +}, {false}, [MOUSE_SCROLL_UP, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + Mouse Wheel Scroll Up + +["ACE3 Vehicles", QGVAR(scrollDown), localize LSTRING(DecreaseSpeedLimit), { + if (GVAR(isSpeedLimiter)) then { + GVAR(speedLimit) = round (GVAR(speedLimit) - 1) max 5; + [["%1: %2", LSTRING(SpeedLimit), GVAR(speedLimit)]] call EFUNC(common,displayTextStructured); + true + }; +}, {false}, [MOUSE_SCROLL_DOWN, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + Mouse Wheel Scroll Down diff --git a/addons/vehicles/XEH_preInit.sqf b/addons/vehicles/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/vehicles/XEH_preInit.sqf +++ b/addons/vehicles/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/vehicles/functions/fnc_speedLimiter.sqf b/addons/vehicles/functions/fnc_speedLimiter.sqf index 2d445be3c8..da2f7bf19a 100644 --- a/addons/vehicles/functions/fnc_speedLimiter.sqf +++ b/addons/vehicles/functions/fnc_speedLimiter.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Toggle speed limiter for Driver in Vehicle. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_driver", "_vehicle"]; @@ -28,11 +28,11 @@ if (GVAR(isSpeedLimiter)) exitWith { playSound "ACE_Sound_Click"; GVAR(isSpeedLimiter) = true; -private _maxSpeed = speed _vehicle max 10; +GVAR(speedLimit) = speed _vehicle max 5; [{ params ["_args", "_idPFH"]; - _args params ["_driver", "_vehicle", "_maxSpeed"]; + _args params ["_driver", "_vehicle"]; if (GVAR(isUAV)) then { private _uavControll = UAVControl _vehicle; @@ -51,8 +51,8 @@ private _maxSpeed = speed _vehicle max 10; private _speed = speed _vehicle; - if (_speed > _maxSpeed) then { - _vehicle setVelocity ((velocity _vehicle) vectorMultiply ((_maxSpeed / _speed) - 0.00001)); // fix 1.42-hotfix PhysX libraries applying force in previous direction when turning + if (_speed > GVAR(speedLimit)) then { + _vehicle setVelocity ((velocity _vehicle) vectorMultiply ((GVAR(speedLimit) / _speed) - 0.00001)); // fix 1.42-hotfix PhysX libraries applying force in previous direction when turning }; -} , 0, [_driver, _vehicle, _maxSpeed]] call CBA_fnc_addPerFrameHandler; +}, 0, [_driver, _vehicle]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/vehicles/functions/fnc_startEngine.sqf b/addons/vehicles/functions/fnc_startEngine.sqf index 8b0d0f17bb..507036b0cb 100644 --- a/addons/vehicles/functions/fnc_startEngine.sqf +++ b/addons/vehicles/functions/fnc_startEngine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Delays engine start of vehicle. @@ -14,11 +15,10 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle", "_isEngineOn"]; -if (!_isEngineOn || {floor abs speed _vehicle > 0}) exitWith {}; +if (!_isEngineOn || {floor abs speed _vehicle > 0 || {!isNull isVehicleCargo _vehicle}}) exitWith {}; [{ params ["_args", "_idPFH"]; diff --git a/addons/vehicles/script_component.hpp b/addons/vehicles/script_component.hpp index d8143e3fdc..b985da6632 100644 --- a/addons/vehicles/script_component.hpp +++ b/addons/vehicles/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_VEHICLES @@ -17,5 +16,8 @@ #include "\z\ace\addons\main\script_macros.hpp" +#define MOUSE_SCROLL_UP 0xF8 +#define MOUSE_SCROLL_DOWN 0xF9 + #define FUEL_FACTOR 0.165 // fuel capacity = range in km * FUEL_FACTOR #define STARTUP_DELAY 1.3 diff --git a/addons/vehicles/stringtable.xml b/addons/vehicles/stringtable.xml index 005bba53a3..6456cfbf6b 100644 --- a/addons/vehicles/stringtable.xml +++ b/addons/vehicles/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Sebességkorlátozó bekapcsolva Limitador de Velocidade Ativo Limitatore Attivo + 速度制限を有効化 + 속도 제한기 켜짐 + 启用速度限制 + 啟用速度限制 Speed Limiter off @@ -24,6 +28,15 @@ Sebességkorlátozó kikapcsolva Limitador de Velocidade Desativado Limitatore Non Attivo + 速度制限を無効化 + 속도 제한기 꺼짐 + 停用速度限制 + 停用速度限制 + + + Speed Limit + Limite di velocità + 速度制限 Speed Limiter @@ -36,6 +49,20 @@ Sebességkorlátozó Limitador de Velocidade Limitatore di Velocità + 速度制限 + 속도 제한기 + 速度限制器 + 速度限制器 + + + Increase Speed Limit + Aumenta limite di velocità + 速度制限を増やす + + + Decrease Speed Limit + Diminuisce limite di velocità + 速度制限を減らす - \ No newline at end of file + 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/XEH_preInit.sqf b/addons/viewdistance/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/viewdistance/XEH_preInit.sqf +++ b/addons/viewdistance/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/viewdistance/functions/fnc_adaptViewDistance.sqf b/addons/viewdistance/functions/fnc_adaptViewDistance.sqf index 4816ee946e..d83b8ae746 100644 --- a/addons/viewdistance/functions/fnc_adaptViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_adaptViewDistance.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Winter * Sets the player's current view distance according to whether s/he is on foot, in a land vehicle or in an air vehicle. @@ -14,14 +15,18 @@ * Public: No */ -#include "script_component.hpp" - params ["_showPrompt"]; 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_changeViewDistance.sqf b/addons/viewdistance/functions/fnc_changeViewDistance.sqf index c5f39ff2f8..40d07cf100 100644 --- a/addons/viewdistance/functions/fnc_changeViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_changeViewDistance.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Winter * Sets the player's current view distance according to allowed values. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_indexRequested", "_showPrompt"]; diff --git a/addons/viewdistance/functions/fnc_initModule.sqf b/addons/viewdistance/functions/fnc_initModule.sqf index 231cd74c7b..b33b6b532c 100644 --- a/addons/viewdistance/functions/fnc_initModule.sqf +++ b/addons/viewdistance/functions/fnc_initModule.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Winter * Initializes the view distance limiter module. @@ -9,19 +10,20 @@ * * Return Value: * None + * + * Example: + * [LOGIC; [bob, kevin], true] call ace_viewdistance_fnc_initModule + * + * Public: No */ -#include "script_component.hpp" - -if (!isServer) exitWith {}; - params ["_logic", "_units", "_activated"]; if (!_activated) exitWith { - ACE_LOGWARNING("View Distance Limit Module is placed but NOT active."); + WARNING("View Distance Limit Module is placed but NOT active."); }; [_logic, QGVAR(enabled),"moduleViewDistanceEnabled"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(limitViewDistance),"moduleViewDistanceLimit"] call EFUNC(common,readSettingFromModule); -ACE_LOGINFO_1("View Distance Limit Module Initialized. Limit set by module: %1",GVAR(limitViewDistance)); +INFO_1("View Distance Limit Module Initialized. Limit set by module: %1",GVAR(limitViewDistance)); diff --git a/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf b/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf index 257dca2995..5cc17be8bb 100644 --- a/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf +++ b/addons/viewdistance/functions/fnc_returnObjectCoeff.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Winter * Returns the object view distance coefficient according to the given index @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_index"]; switch (_index) do { diff --git a/addons/viewdistance/functions/fnc_returnValue.sqf b/addons/viewdistance/functions/fnc_returnValue.sqf index 35c0894520..480a9ce7ae 100644 --- a/addons/viewdistance/functions/fnc_returnValue.sqf +++ b/addons/viewdistance/functions/fnc_returnValue.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Winter * Returns the view distance value according to the given index. @@ -14,8 +15,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_index"]; switch (_index) do { diff --git a/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf b/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf index 4a57747d97..e419687ac6 100644 --- a/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf +++ b/addons/viewdistance/functions/fnc_setFovBasedOvdPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Sets Object View Distance dynamically based on current Field of View, between Object View Distance (minimal value) and View Distance (maximum value) set before this PFH starts. @@ -15,8 +16,6 @@ * Public: No */ -#include "script_component.hpp" - params ["", "_idPFH"]; // Remove PFH and set Object View Distance back to what it was before @@ -25,7 +24,7 @@ if (GVAR(objectViewDistanceCoeff) < 6) exitWith { GVAR(fovBasedPFHminimalViewDistance) = nil; }; -private _zoom = (call CBA_fnc_getFov) select 1; +private _zoom = ([] call CBA_fnc_getFov) select 1; if (_zoom > VD_ZOOM_NORMAL) then { // Dynamically set Object View Distance based on player's Zoom Level and View Distance diff --git a/addons/viewdistance/script_component.hpp b/addons/viewdistance/script_component.hpp index f78bfcbc1c..d02d4ab691 100644 --- a/addons/viewdistance/script_component.hpp +++ b/addons/viewdistance/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_VIEWDISTANCE diff --git a/addons/viewdistance/stringtable.xml b/addons/viewdistance/stringtable.xml index a0f2bceb68..5c2d2ec287 100644 --- a/addons/viewdistance/stringtable.xml +++ b/addons/viewdistance/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Látótáv-korlátozó Ограничитель дальности видимости Limitatore Distanza Visiva + 視界距離の制限 + 시야 제한기 + 视野距离限制器 + 視野距離限制器 Allows limiting maximum view distance that can be set by players. @@ -24,6 +28,10 @@ Lehetővé teszi a játékosok által a látótávolság maximumának korlátozását. Позволяет ограничить максимальную дальность видимости, которая может быть установлена игроками. Consente di limitare la distanza visiva massima che può essere impostata dai giocatori. + プレイヤーへ最大の視界距離を制限できます。 + 플레이어가 볼 수 있는 최대 시야를 제한합니다. + 允许玩家最大的可视距离 + 允許玩家最大的可視距離 Enable ACE viewdistance @@ -36,6 +44,10 @@ ACE látótávolság engedélyezése Ограничить дальность видимости Abilita distanza visiva ACE + ACE 視界距離を有効化 + ACE 시야 활성화 + 启用ACE视距 + 啟用ACE視距 Enables ACE viewdistance @@ -48,6 +60,10 @@ Engedélyezi az ACE látótávolságot Включает ограничитель дальности видимости ACE Abilita distanza visiva ACE + ACE 視界距離を有効化 + ACE 시야 활성화 + 启用ACE视距 + 啟用ACE視距 View Distance Limit @@ -60,6 +76,10 @@ Látótáv-korlát Дальность видимости Limite Distanza Visiva + 視界距離の制限 + 시야 제한기 + 视野距离限制 + 視野距離限制 Sets the limit for how high clients can raise their view distance (up to 10000) @@ -72,6 +92,10 @@ Korlátozza, mekkora látótávolságot állíthatnak be a kliensek (maximum 10000-ig) Устанавливает предел дальности, насколько клиенты могут увеличить свою дальность видимости (до 10000) Imposta il limite massimo a cui i client possono alzare la propria distanza visiva (massimo 10000) + 各クライアントが最大まで設定できる視界距離を設定します。(最大 10000) + 클라이언트가 최대 얼마나 멀리 볼 수 있는지 제한을 둡니다 (10000 까지 가능) + 设定客户端最高可显示的视野距离 (最高至10000) + 設定客戶端最高可顯示的視野距離 (最高至10000) Limit for client's view distance set here and can overridden by module @@ -84,6 +108,10 @@ A kliens látótávolsága itt állítható be, és felülbírálható modulok által Предел дальности видимости клиентов устанавливается здесь и может быть переопределен модулем Limite per la distanza visiva del client impostato qui e può essere scavalcato dal modulo + クライアントへの視界距離の設定や、それをモジュールにより上書きできます + 클라이언트의 시야를 이 모듈로 치환할 수 있습니다. + 玩家的视距限制可在此设定,也可透过模块改写 + 玩家的視距限制可在此設定,也可透過模塊改寫 Client View Distance (On Foot) @@ -96,6 +124,10 @@ Kliens látótáv (gyalog) Дальность видимости (Пешком) Distanza Visiva Client (a Piedi) + クライアント側視界距離 (地上) + 클라이언트 시야 (보병) + 客户端视野距离 (步行) + 客戶端視野距離 (步行) Changes in game view distance when the player is on foot. @@ -108,6 +140,10 @@ Megváltoztatja a játékon belüli látótávolságot, amennyiben a játékos gyalogosan van. Изменяет дальность видимости в игре, когда игрок перемещается пешком. Cambia la distanza visiva in gioco quando il giocatore è a piedi. + プレイヤーが地上にいる時の視界距離を変更します。 + 플레이어가 보병일 경우의 시야를 바꿀 수 있습니다. + 改变玩家步行时的视野距离. + 改變玩家步行時的視野距離. Client View Distance (Land Vehicle) @@ -120,6 +156,10 @@ Kliens látótáv (szárazföldi jármű) Дальность видимости (В наземном трансп.) Distanza Visiva Client (Veicolo Terrestre) + クライアント側視界距離 (車両) + 클라이언트 시야 (차량) + 客户端视野距离 (地面载具) + 客戶端視野距離 (地面載具) Changes in game view distance when the player is in a land vehicle. @@ -132,6 +172,10 @@ Megváltoztatja a játékon belüli látótávolságot, amennyiben a játékos szárazföldi járműben van. Изменяет дальность видимости в игре, когда игрок перемещается в наземном транспорте. Cambia la distanza visiva in gioco quando il giocatore è in un veicolo terrestre. + プレイヤーが車両の時の視界距離を変更します。 + 플레이어가 차량 내부일 경우의 시야를 바꿀 수 있습니다. + 改变玩家于地面载具内时的视野距离 + 改變玩家於地面載具內時的視野距離 Client View Distance (Air Vehicle) @@ -144,6 +188,10 @@ Kliens látótáv (légi jármű) Дальность видимости (В воздушном трансп.) Distanza Visiva Client (Veicoli d'Aria) + クライアント側視界距離 (航空機) + 클라이언트 시야 (항공기) + 客户端视野距离 (空中载具) + 客戶端視野距離 (空中載具) Changes in game view distance when the player is in an air vehicle. @@ -156,6 +204,10 @@ Megváltoztatja a játékon belüli látótávolságot, amennyiben a játékos légi járműben van. Изменяет дальность видимости в игре, когда игрок перемещается в воздушном транспорте. Cambia la distanza visiva in gioco quando il giocatore è in un mezzo aereo. + プレイヤーが航空機に乗っている時の視界距離を変更します。 + 플레이어가 항공기 내부일 경우의 시야를 바꿀 수 있습니다. + 改变玩家于空中载具内时的视野距离 + 改變玩家於空中載具內時的視野距離 Dynamic Object View Distance @@ -168,6 +220,10 @@ Dinamikus objektum-látótáv Динамич. дальность отрисовки объектов Distanza Visiva Oggetti Dinamica + 動的なオブジェクトの描画距離 + 동적 물체 시야 + 动态物件的视野距离 + 動態物件的視野距離 Sets the object view distance as a coefficient of the view distance or based on field of view. FoV Based's lowest and highest value is the value which is set when enabling the option. @@ -180,6 +236,10 @@ Beállítja az objektum-látótávot a megadott látótáv koefficienseként. Устанавливает дальность отрисовки объектов как коэффициент от общей дальности видимости. Imposta la distanza visiva degli oggetti come un coefficiente basato sulla distanza visiva oppure basato sul campo visivo. + 視野角を元にするか、視界距離によるオブジェクト描画距離を決定します。視野角を元にするオプションを有効化した場合、視野角により最低と最高値が変動します。 + 설정된 시야 혹은 시계(FoV)에 계수를 적용해 물체 시야를 적용합니다. 시계를 바탕으로 하는 옵션을 활성화할 경우 시계에 의한 최저와 최고치가 변동됩니다. + 设定物件可被观察的距离,透过视野距离或是视野角度来决定。 + 設定物件可被觀察的距離,透過視野距離或是視野角度來決定。 Off @@ -192,6 +252,10 @@ Kikapcsolva Выкл. Disabilitato + 無効 + 끄기 + 关闭 + 關閉 Very Low @@ -204,6 +268,10 @@ Minimális Очень низкая Molto Basso + 最低 + 매우 낮음 + 非常低 + 非常低 Low @@ -216,6 +284,10 @@ Alacsony Низкая Basso + + 낮음 + + Medium @@ -228,6 +300,10 @@ Közepes Средняя Medio + 通常 + 중간 + + High @@ -240,6 +316,10 @@ Magas Высокая Alto + + 높음 + + Very High @@ -252,6 +332,10 @@ Maximális Очень высокая Molto Alto + 最高 + 매우 높음 + 非常高 + 非常高 FoV Based @@ -263,6 +347,10 @@ Basato su Campo Visivo (FoV) Basada en campo de visión Champ de vision basé + 視野角を元にする + 시계(FoV) + 由视野角度决定 + 由視野角度決定 View Distance: @@ -275,6 +363,10 @@ Látótávolság: Дальность видимости: Distanza Visiva: + 視界距離: + 시야: + 视野距离: + 視野距離: Object View Distance is @@ -287,6 +379,10 @@ Az objektum-látótávolság: Дальность видимости объектов: Distanza Visiva Oggetti è + オブジェクト描画距離は + 동적 물체 시야는 + 物件视野距离为 + 物件視野距離為 That option is invalid! The limit is @@ -299,6 +395,10 @@ Ez a beállítás érvénytelen! A maximum mennyiség Настройка не верна! Текущий предел Questa opzione è invalida! Il limite è + このオプションは無効です!制限は + 이 옵션은 불가능합니다! 제한은 + 该选项是无效的! 限制是 + 該選項是無效的! 限制是 Video Settings @@ -311,6 +411,10 @@ Videobeállítások Видео настройки Impostazioni Video + 映像設定 + 영상 설정 + 影像设定 + 影像設定 diff --git a/addons/weaponselect/ACE_Settings.hpp b/addons/weaponselect/ACE_Settings.hpp index 5b58659f6e..ba3ccca74f 100644 --- a/addons/weaponselect/ACE_Settings.hpp +++ b/addons/weaponselect/ACE_Settings.hpp @@ -1,10 +1,6 @@ class ACE_Settings { class GVAR(displayText) { - typeName = "BOOL"; - isClientSettable = 1; - value = 1; - displayName = CSTRING(SettingDisplayTextName); - description = CSTRING(SettingDisplayTextDesc); + movedToSQF = 1; }; }; diff --git a/addons/weaponselect/XEH_postInit.sqf b/addons/weaponselect/XEH_postInit.sqf index 7020b5dea5..4706363271 100644 --- a/addons/weaponselect/XEH_postInit.sqf +++ b/addons/weaponselect/XEH_postInit.sqf @@ -72,6 +72,8 @@ if (!hasInterface) exitWith {}; ["ACE3 Weapons", QGVAR(SelectGrenadeFrag), localize LSTRING(SelectGrenadeFrag), { // Conditions: canInteract if !([ACE_player, ACE_player, ["isNotInside", "isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active + if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement [ACE_player, 1] call FUNC(selectNextGrenade); @@ -83,6 +85,8 @@ if (!hasInterface) exitWith {}; ["ACE3 Weapons", QGVAR(SelectGrenadeOther), localize LSTRING(SelectGrenadeOther), { // Conditions: canInteract if !([ACE_player, ACE_player, ["isNotInside", "isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active + if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement [ACE_player, 2] call FUNC(selectNextGrenade); @@ -192,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/XEH_preInit.sqf b/addons/weaponselect/XEH_preInit.sqf index 4166247505..01c9f2484f 100644 --- a/addons/weaponselect/XEH_preInit.sqf +++ b/addons/weaponselect/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; // collect frag and other grenades separately GVAR(GrenadesAll) = []; @@ -24,4 +26,6 @@ GVAR(GrenadesNonFrag) = []; false } count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); +#include "initSettings.sqf" + ADDON = true; diff --git a/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf b/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf index 288531df2c..c87047a787 100644 --- a/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf +++ b/addons/weaponselect/functions/fnc_displayGrenadeTypeAndNumber.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: esteldunedain, commy2 * Display a grenade type and quantity. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" if !(GVAR(DisplayText)) exitWith {}; diff --git a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf index bb877ea3cd..f1bd108926 100644 --- a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf +++ b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Fire Vehicle Smoke Launcher. @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_vehicle"]; diff --git a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf index a7c3f13936..86945dbaac 100644 --- a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Play weapon firemode change sound. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon"]; diff --git a/addons/weaponselect/functions/fnc_putWeaponAway.sqf b/addons/weaponselect/functions/fnc_putWeaponAway.sqf index d2747bf23f..e74a9c4c6b 100644 --- a/addons/weaponselect/functions/fnc_putWeaponAway.sqf +++ b/addons/weaponselect/functions/fnc_putWeaponAway.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * The unit will put its current weapon away. @@ -13,10 +14,9 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit"]; _unit call EFUNC(common,fixLoweredRifleAnimation); -_unit action ["SwitchWeapon", _unit, _unit, 99]; +_unit action ["SwitchWeapon", _unit, _unit, 299]; diff --git a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf index f4b48a1b1e..21f07639f4 100644 --- a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf +++ b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Select the next grenade. @@ -14,7 +15,6 @@ * * Public: Yes */ -#include "script_component.hpp" params ["_unit", ["_type", 0]]; diff --git a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf index 80784778de..8812a63525 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * The player will select the specified weapon or will change to the next firing mode if the weapon was already selected. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon"]; @@ -42,7 +42,7 @@ private _mode = _modes select _index; _index = 0; while { - _index < 100 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}} + _index < 299 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}} } do { _unit action ["SwitchWeapon", _unit, _unit, _index]; _index = _index + 1; diff --git a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf index 973d34f7c8..ff2d48baf4 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * The player will select the specified weapon and change to the first additional muzzle. E.g. the grenade launcher of a assault rifle. @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_weapon"]; @@ -42,7 +42,7 @@ private _muzzle = _muzzles select _index; _index = 0; while { - _index < 100 && {currentMuzzle _unit != _muzzle} + _index < 299 && {currentMuzzle _unit != _muzzle} } do { _unit action ["SwitchWeapon", _unit, _unit, _index]; _index = _index + 1; diff --git a/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf b/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf index 7435dd30d8..b3fa528532 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Select weapon for unit in vehicle. @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_unit", "_vehicle", "_index"]; @@ -31,7 +31,7 @@ if (_turret isEqualTo [] && {_unit == driver _vehicle}) then { _index = 0; while { - _index < 100 && {currentWeapon _vehicle != _weapon} + _index < 299 && {currentWeapon _vehicle != _weapon} } do { _unit action ["SwitchWeapon", _vehicle, _unit, _index]; _index = _index + 1; @@ -46,7 +46,7 @@ if (_turret isEqualTo [] && {_unit == driver _vehicle}) then { _index = 0; while { - _index < 100 && {_vehicle currentWeaponTurret _turret != _weapon} + _index < 299 && {_vehicle currentWeaponTurret _turret != _weapon} } do { _unit action ["SwitchWeapon", _vehicle, _unit, _index]; _index = _index + 1; diff --git a/addons/weaponselect/functions/fnc_throwGrenade.sqf b/addons/weaponselect/functions/fnc_throwGrenade.sqf index 3f55e02f51..1214bdc84b 100644 --- a/addons/weaponselect/functions/fnc_throwGrenade.sqf +++ b/addons/weaponselect/functions/fnc_throwGrenade.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: commy2 * Display Grenade information on grenade throw. Called from the unified fired EH only for the local player. @@ -13,14 +14,13 @@ * * 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); if (_weapon != "Throw") exitWith {}; -private _count = {_x == _magazine} count magazines _unit; +private _count = ({_x == _magazine} count uniformItems _unit) + ({_x == _magazine} count vestItems _unit) + ({_x == _magazine} count backpackItems _unit); [_magazine, _count] call FUNC(displayGrenadeTypeAndNumber); diff --git a/addons/weaponselect/initSettings.sqf b/addons/weaponselect/initSettings.sqf new file mode 100644 index 0000000000..d4fc725783 --- /dev/null +++ b/addons/weaponselect/initSettings.sqf @@ -0,0 +1,8 @@ +// CBA Settings [ADDON: ace_weaponselect]: + +[QGVAR(displayText), "CHECKBOX", +[LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], +localize ELSTRING(common,ACEKeybindCategoryWeapons), +true, // default value +false, // isGlobal +{[QGVAR(displayText), _this] call EFUNC(common,cbaSettings_settingChanged)}] call CBA_settings_fnc_init; diff --git a/addons/weaponselect/script_component.hpp b/addons/weaponselect/script_component.hpp index 743d471a2a..9988a67e94 100644 --- a/addons/weaponselect/script_component.hpp +++ b/addons/weaponselect/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_WEAPONSELECT diff --git a/addons/weaponselect/stringtable.xml b/addons/weaponselect/stringtable.xml index c9a8e43f60..c59c2684b8 100644 --- a/addons/weaponselect/stringtable.xml +++ b/addons/weaponselect/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Szöveg mutatása gránát eldobásakor Mostra indicazioni nel lancio granate Mostrat texto ao lançar granada + 手榴弾を投げるときに通知 + 수류탄 투척시 화면에 문자 표시 + 投掷手榴弹时显示提示讯息 + 投擲手榴彈時顯示提示訊息 Display a hint or text on grenade throw. @@ -24,6 +28,10 @@ Jelez egy súgót vagy szöveget a gránát eldobásakor. Mostra una notifica quando si lanciano granate Mostra um hint ou texto ao lançar uma granada + 手榴弾を投げるときに、ヒントか文で通知します。 + 수류탄 투척시 화면에 문자나 힌트를 표시합니다. + 投掷手榴弹时显示提示讯息。 + 投擲手榴彈時顯示提示訊息 Select Pistol @@ -36,6 +44,10 @@ Pisztoly Kiválasztása Selecionar Pistola Seleziona la Pistola + 拳銃を選択 + 권총 선택 + 选择手枪 + 選擇手槍 Select Rifle @@ -48,6 +60,10 @@ Puska Kiválasztása Selecionar Rifle Seleziona il fucile + 小銃を選択 + 소총 선택 + 选择步枪 + 選擇步槍 Select Launcher @@ -60,6 +76,10 @@ Rakétavető Kiválasztása Selecionar Lançador Seleziona il lanciamissili + ランチャーを選択 + 발사기 선택 + 选择发射器 + 選擇發射器 Select Grenade Launcher @@ -72,6 +92,10 @@ Gránátvető Kiválasztása Selecionar Lança-Granadas Seleziona il lanciagranate + グレネード ランチャーを選択 + 유탄발사기 선택 + 选择榴弹发射器 + 選擇榴彈發射器 Select Binoculars @@ -84,6 +108,10 @@ Távcső Kiválasztása Selecionar Binóculos Seleziona il Binocolo + 双眼鏡を選択 + 망원경 선택 + 选择望远镜 + 選擇望遠鏡 Holster Weapon @@ -96,6 +124,10 @@ Fegyvert tokba Guardar Arma Nascondi l'arma + 武器をしまう + 무기 집어넣기 + 武器套 + 武器套 Engine on @@ -108,6 +140,10 @@ Ligar Motor Motore acceso Включить двигатель + エンジン始動 + 엔진 켜기 + 引擎发动 + 引擎發動 Engine off @@ -120,6 +156,10 @@ Desligar Motor Motore spento Выключить двигатель + エンジン停止 + 엔진 끄기 + 引擎熄火 + 引擎熄火 Select Main Gun @@ -132,6 +172,10 @@ Selecionar Arma Principal Seleziona Arma Primaria Выбрать основное оружие + 主砲を選択 + 주포 선택 + 选择主武器 + 選擇主武器 Select Machine Gun @@ -144,6 +188,10 @@ Selecionar Metralhadora Seleziona Mitragliatrice Выбрать пулемёт + 機関砲を選択 + 기관총 선택 + 选择机枪 + 選擇機槍 Select Missiles @@ -156,6 +204,10 @@ Selecionar Mísseis Seleziona Missili Выбрать ракеты + ミサイルを選択 + 미사일 선택 + 选择导弹 + 選擇導彈 Grenade %1 @@ -168,6 +220,10 @@ Grenade %1 Granata %1 Granada %1 + %1 手榴弾 + %1 수류탄 + 手榴弹 %1 + 手榴彈 %1 Ready Grenade @@ -180,6 +236,10 @@ Grenade prête Granata pronta Granada pronta + 投てきよし + 투척물 준비 + 准备手榴弹 + 準備手榴彈 Select Frag Grenade @@ -192,6 +252,10 @@ Selecionar Granada de Fragmentação Seleziona Granata a Frammentazione Выбрать осколочную гранату + 破片手榴弾を選択 + 살상 투척물 선택 + 选择破片手榴弹 + 選擇破片手榴彈 Select Non-Frag Grenade @@ -204,6 +268,10 @@ Selecionar Granada Seleziona granate non a frammentazione Выбрать гранату + その他の手榴弾を選択 + 비살상 투척물 선택 + 选择非破片手榴弹 + 選擇非破片手榴彈 Throw Selected Grenade @@ -216,6 +284,10 @@ Lançar Granada Selecionada Lancia la Granata Selezionata Бросить выбранную гранату + 選択された手榴弾を投げる + 선택된 투척물 투척 + 投掷选择的手榴弹 + 投擲選擇的手榴彈 No grenades left @@ -228,6 +300,10 @@ Гранат не осталось Granate esaurite Sem mais granadas + もう手榴弾は無い + 투척물 없음 + 已无手榴弹 + 已無手榴彈 No frags left @@ -240,6 +316,10 @@ Não há granadas de fragmentação restantes Nessuna granata a frammentazione rimanente Осколочных гранат нет + もう破片手榴弾は無い + 세열 수류탄 없음 + 已无破片手榴弹 + 已無破片手榴彈 No misc. grenades left @@ -252,6 +332,10 @@ Não há outras granadas restantes Nessun'altra granata rimanente. Нелетальные гранаты закончились + もうその他の手榴弾は無い + 기타 투척물 없음 + 已无其他手榴弹 + 已無其他手榴彈 No grenade selected @@ -264,6 +348,10 @@ Nenhuma granada selecionada Nessuna granata selezionata Нет выбранной гранаты + 手榴弾は選択されていない + 선택된 수류탄 없음 + 未选择手榴弹 + 未選擇手榴彈 Fire Smoke Launcher @@ -276,6 +364,18 @@ Пустить дымовую завесу Lancia fumogeno Lançador de fumaça + 発煙弾発射機を発射 + 연막발사기 박사 + 发射烟雾发射器 + 發射煙霧發射器 + + + Toggle Collision Lights + Attiva Luci di Collisione + 충돌 표시등 토글 + 切換碰撞燈 + 切换碰撞灯 + 衝突防止灯を切り替え - \ No newline at end of file + 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 569dd87dc4..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,43 +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)); - - //Create a 0 sec delay PFEH to update rain every frame: - if (GVAR(syncRain)) then { - [{ - 0 setRain GVAR(ACE_rain); - }, 0, []] call CBA_fnc_addPerFrameHandler; - }; - - //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/XEH_preInit.sqf b/addons/weather/XEH_preInit.sqf index f0161c7173..1b551f133e 100644 --- a/addons/weather/XEH_preInit.sqf +++ b/addons/weather/XEH_preInit.sqf @@ -3,7 +3,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; // Make sure this data is read before client/server postInit call FUNC(getMapData); diff --git a/addons/weather/functions/fnc_calculateAirDensity.sqf b/addons/weather/functions/fnc_calculateAirDensity.sqf index bda8410ddd..43da78eab9 100644 --- a/addons/weather/functions/fnc_calculateAirDensity.sqf +++ b/addons/weather/functions/fnc_calculateAirDensity.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the air density @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_temperature", "_pressure", "_relativeHumidity"]; @@ -23,7 +23,8 @@ _pressure = _pressure * 100; // hPa to Pa if (_relativeHumidity > 0) then { // Saturation vapor pressure calculated according to: http://wahiduddin.net/calc/density_algorithms.htm - private _pSat = 6.1078 * 10 ^ ((7.5 * _temperature) / (_temperature + 237.3)); + // 610.78 gives pressure in Pa - https://en.wikipedia.org/wiki/Density_of_air + private _pSat = 610.78 * 10 ^ ((7.5 * _temperature) / (_temperature + 237.3)); private _vaporPressure = _relativeHumidity * _pSat; private _partialPressure = _pressure - _vaporPressure; diff --git a/addons/weather/functions/fnc_calculateBarometricPressure.sqf b/addons/weather/functions/fnc_calculateBarometricPressure.sqf index 29b8fa7877..70cdf370bf 100644 --- a/addons/weather/functions/fnc_calculateBarometricPressure.sqf +++ b/addons/weather/functions/fnc_calculateBarometricPressure.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the barometric pressure based on altitude and weather @@ -13,6 +14,5 @@ * * Public: No */ -#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_calculateDensityAltitude.sqf b/addons/weather/functions/fnc_calculateDensityAltitude.sqf index 8dea9849b1..fdfe57877d 100644 --- a/addons/weather/functions/fnc_calculateDensityAltitude.sqf +++ b/addons/weather/functions/fnc_calculateDensityAltitude.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates density altitude for a given air density @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" // Source: http://wahiduddin.net/calc/density_altitude.htm diff --git a/addons/weather/functions/fnc_calculateDewPoint.sqf b/addons/weather/functions/fnc_calculateDewPoint.sqf index 81db9565dc..5f020f47d1 100644 --- a/addons/weather/functions/fnc_calculateDewPoint.sqf +++ b/addons/weather/functions/fnc_calculateDewPoint.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates dew point based on temperature and relative humidity @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" #define __b 17.67 #define __c 243.5 diff --git a/addons/weather/functions/fnc_calculateHeatIndex.sqf b/addons/weather/functions/fnc_calculateHeatIndex.sqf index a4626128de..de333d801f 100644 --- a/addons/weather/functions/fnc_calculateHeatIndex.sqf +++ b/addons/weather/functions/fnc_calculateHeatIndex.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates heat index based on temperature and relative humidity @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" #define __C1 0.363445176 #define __C2 0.988622465 diff --git a/addons/weather/functions/fnc_calculateRoughnessLength.sqf b/addons/weather/functions/fnc_calculateRoughnessLength.sqf index 423f3fc3d6..17519c8092 100644 --- a/addons/weather/functions/fnc_calculateRoughnessLength.sqf +++ b/addons/weather/functions/fnc_calculateRoughnessLength.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the terrain roughness length at a given world position @@ -13,12 +14,11 @@ * * Public: No */ -#include "script_component.hpp" // 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..90d524e560 100644 --- a/addons/weather/functions/fnc_calculateSpeedOfSound.sqf +++ b/addons/weather/functions/fnc_calculateSpeedOfSound.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the speed of sound for a given temperature @@ -13,6 +14,5 @@ * * Public: No */ -#include "script_component.hpp" -(331.3 + (0.6 * _this)) +(331.3 * sqrt(1 + (_this / 273.15))) diff --git a/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf b/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf index e33b8213eb..c392b15900 100644 --- a/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf +++ b/addons/weather/functions/fnc_calculateTemperatureAtHeight.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the temperature based on altitude and weather @@ -13,6 +14,5 @@ * * Public: No */ -#include "script_component.hpp" (GVAR(currentTemperature) - 0.0065 * _this) diff --git a/addons/weather/functions/fnc_calculateWetBulb.sqf b/addons/weather/functions/fnc_calculateWetBulb.sqf index a8a58b0dc3..5ebb497a16 100644 --- a/addons/weather/functions/fnc_calculateWetBulb.sqf +++ b/addons/weather/functions/fnc_calculateWetBulb.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates wet bulb based on temperature and relative humidity @@ -15,7 +16,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_temperature", "_pressure", "_relativeHumidity"]; diff --git a/addons/weather/functions/fnc_calculateWindChill.sqf b/addons/weather/functions/fnc_calculateWindChill.sqf index 0e17d53377..f657cba638 100644 --- a/addons/weather/functions/fnc_calculateWindChill.sqf +++ b/addons/weather/functions/fnc_calculateWindChill.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates wind chill based on temperature and wind speed @@ -14,7 +15,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_t", "_v"]; diff --git a/addons/weather/functions/fnc_calculateWindSpeed.sqf b/addons/weather/functions/fnc_calculateWindSpeed.sqf index 206bc1d298..f14d6dfbfc 100644 --- a/addons/weather/functions/fnc_calculateWindSpeed.sqf +++ b/addons/weather/functions/fnc_calculateWindSpeed.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Calculates the true wind speed at a given world position @@ -16,7 +17,6 @@ * * Public: No */ -#include "script_component.hpp" params ["_position", "_windGradientEnabled", "_terrainEffectEnabled", "_obstacleEffectEnabled"]; @@ -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..35c840bf85 100644 --- a/addons/weather/functions/fnc_displayWindInfo.sqf +++ b/addons/weather/functions/fnc_displayWindInfo.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Displays a wind info (colored arrow) in the top left corner of the screen @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" #define __dsp (uiNamespace getVariable "RscWindIntuitive") #define __ctrl (__dsp displayCtrl 132948) @@ -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 08a6f38568..20a8f1df70 100644 --- a/addons/weather/functions/fnc_getMapData.sqf +++ b/addons/weather/functions/fnc_getMapData.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Ruthberg, esteldunedain * Get the weather data for the current map @@ -13,9 +14,12 @@ * * Public: No */ -#include "script_component.hpp" -// Assume default wind values +private _worldName = toLower worldName; +TRACE_1("getting map data",_worldName); + +// Set default values + // Source: https://weatherspark.com/averages/32194/Lemnos-Limnos-North-Aegean-Islands-Greece GVAR(WindSpeedMax) = [[8.8, 5.5], [8.8, 5], [8.6, 4.8], [7.6, 3.4], [7.0, 3.0], [7.1, 3.0], [7.5, 3.1], [8.0, 3.2], [7.6, 3.5], [7.8, 4.6], [7.9, 5.0], [8.2, 5.5]]; GVAR(WindSpeedMean) = [4.8, 4.9, 4.6, 4.1, 3.5, 3.5, 4.3, 4.4, 4.1, 4.5, 4.5, 5.0]; @@ -35,23 +39,43 @@ GVAR(WindDirectionProbabilities) = [ [0.06, 0.37, 0.05, 0.03, 0.18, 0.04, 0.02, 0.02] // December ]; -// Check if the wind data is defined in the map config -if (isArray (configFile >> "CfgWorlds" >> worldName >> "ACE_WindSpeedMean")) then { - GVAR(WindSpeedMin) = getArray (configFile >> "CfgWorlds" >> worldName >> "ACE_WindSpeedMin"); - GVAR(WindSpeedMean) = getArray (configFile >> "CfgWorlds" >> worldName >> "ACE_WindSpeedMean"); - GVAR(WindSpeedMax) = getArray (configFile >> "CfgWorlds" >> worldName >> "ACE_WindSpeedMax"); - GVAR(WindDirectionProbabilities) = getArray (configFile >> "CfgWorlds" >> worldName >> "ACE_WindDirectionProbabilities"); -}; +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]; -// Check if the weather data is defined in the map config -if (isArray (configFile >> "CfgWorlds" >> worldName >> "ACE_TempDay")) exitWith { - GVAR(TempDay) = getArray (configFile >> "CfgWorlds" >> worldName >> "ACE_TempDay"); - GVAR(TempNight) = getArray (configFile >> "CfgWorlds" >> worldName >> "ACE_TempNight"); - GVAR(Humidity) = getArray (configFile >> "CfgWorlds" >> worldName >> "ACE_Humidity"); +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]; +// And check if any custom non-inherited weather is defined through config and use that if so +if ((configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay") in _nonInheritedArrays) exitWith { + if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay")) then { + GVAR(TempDay) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay"); + }; + if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight")) then { + GVAR(TempNight) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight"); + }; + if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity")) then { + GVAR(Humidity) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity"); + }; + if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin")) then { + GVAR(WindSpeedMin) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin"); + }; + if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean")) then { + GVAR(WindSpeedMean) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean"); + }; + if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax")) then { + GVAR(WindSpeedMax) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax"); + }; + if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities")) then { + GVAR(WindDirectionProbabilities) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities"); + }; }; // Check if the map is among the most popular -if (toLower worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) then { +if (_worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) then { // Source: http://www.iten-online.ch/klima/europa/tschechien/prag.htm 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]; @@ -78,7 +102,7 @@ if (toLower worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) ]; }; -if (toLower worldName in ["takistan", "zargabad", "mountains_acr", "shapur_baf", "provinggrounds_pmc"]) exitWith { +if (_worldName in ["takistan", "zargabad", "mountains_acr", "shapur_baf", "provinggrounds_pmc"]) exitWith { // Source: http://www.iten-online.ch/klima/asien/afghanistan/kabul.htm GVAR(TempDay) = [4.5, 5.5, 12.5, 19.2, 24.4, 30.2, 32.1, 32, 28.5, 22.4, 15, 8.3]; GVAR(TempNight) = [-7.1, -5.7, 0.7, 6, 8.8, 12.4, 15.3, 14.3, 9.4, 3.9, -1.2, -4.7]; @@ -105,7 +129,7 @@ if (toLower worldName in ["takistan", "zargabad", "mountains_acr", "shapur_baf", ]; }; -if (toLower worldName in ["fallujah"]) exitWith { +if (_worldName in ["fallujah"]) exitWith { // Source: http://www.iten-online.ch/klima/asien/irak/bagdad.htm GVAR(TempDay) = [16, 19, 23, 29, 36, 41, 43, 43, 40, 33, 24, 17]; GVAR(TempNight) = [4, 6, 10, 15, 20, 23, 25, 25, 21, 16, 10, 5]; @@ -113,8 +137,8 @@ if (toLower worldName in ["fallujah"]) exitWith { GVAR(Humidity) = [69, 60, 55, 50, 36, 23, 21, 22, 29, 38, 58, 68]; }; -if (toLower worldName in ["fata", "Abbottabad"]) exitWith { - // Source: http://www.iten-online.ch/klima/asien/pakistan/zhob.htm +if (_worldName in ["fata", "abbottabad"]) exitWith { + // Source: http://www.iten-online.ch/klima/asien/pakistan/zhob.htm GVAR(TempDay) = [12.4, 15.8, 20.8, 26.9, 32.8, 37, 36.8, 35.9, 33.8, 28.2, 22.2, 16.2]; GVAR(TempNight) = [-0.6, 2.4, 7.4, 13.1, 18.2, 22.8, 23.8, 22.9, 19.2, 12, 5.6, 1.2]; // Source: http://www.weather-and-climate.com/average-monthly-Humidity-perc,Zhob,Pakistan @@ -140,24 +164,24 @@ if (toLower worldName in ["fata", "Abbottabad"]) exitWith { ]; }; -if (worldName in ["sfp_wamako"]) exitWith { - // Source: http://www.iten-online.ch/klima/afrika/niger/tahoua.htm +if (_worldName in ["sfp_wamako"]) exitWith { + // Source: http://www.iten-online.ch/klima/afrika/niger/tahoua.htm GVAR(TempDay) = [33.4, 35, 38.4, 41.5, 41.4, 40, 35.6, 32.9, 35.8, 38.2, 36.4, 33.1]; GVAR(TempNight) = [14.9, 16.3, 20.4, 23.7, 25.8, 24.8, 23.1, 22, 22.6, 21.6, 18.6, 15.3]; // Source: http://www.weather-and-climate.com/average-monthly-Humidity-perc,Tahoua,Niger GVAR(Humidity) = [68, 60, 57, 50, 32, 22, 20, 21, 25, 38, 58, 69]; }; -if (worldName in ["sfp_sturko"]) exitWith { - // Source: http://www.iten-online.ch/klima/afrika/niger/tahoua.htm +if (_worldName in ["sfp_sturko"]) exitWith { + // Source: http://www.iten-online.ch/klima/afrika/niger/tahoua.htm GVAR(TempDay) = [2.2, 2.4, 5.1, 10.2, 16.1, 20.1, 21.1, 20.9, 17.2, 12.7, 7.4, 3.9]; GVAR(TempNight) = [-2, -2.3, -0.7, 2.6, 7.1, 11.4, 13.1, 12.7, 10, 6.9, 3.1, -0.1]; // Source: http://www.weather-and-climate.com/average-monthly-Humidity-perc,karlskrona,Sweden GVAR(Humidity) = [86, 85, 80, 72, 68, 69, 74, 77, 79, 81, 86, 88]; }; -if (worldName in ["Bornholm"]) exitWith { - // Source: http://www.iten-online.ch/klima/afrika/niger/tahoua.htm +if (_worldName in ["bornholm"]) exitWith { + // Source: http://www.iten-online.ch/klima/afrika/niger/tahoua.htm GVAR(TempDay) = [1.9, 1.7, 3.8, 8.1, 14, 18.1, 19.6, 19.8, 16.2, 11.9, 7.3, 3.9]; GVAR(TempNight) = [-1.6, -2.1, -0.7, 1.7, 6.2, 10.7, 13, 13.1, 10.6, 7.2, 3.5, 0.1]; // Source: http://www.weather-and-climate.com/average-monthly-Humidity-perc,allinge,Denmark @@ -182,15 +206,15 @@ if (worldName in ["Bornholm"]) exitWith { [0.08, 0.05, 0.06, 0.04, 0.10, 0.14, 0.19, 0.07] // December ]; }; -if (worldName in ["Imrali"]) exitWith { - // Source: http://www.iten-online.ch/klima/europa/tuerkei/bursa.htm +if (_worldName in ["imrali"]) exitWith { + // Source: http://www.iten-online.ch/klima/europa/tuerkei/bursa.htm GVAR(TempDay) = [9.3, 10.7, 13.6, 18.8, 23.5, 28.2, 30.3, 30.2, 27, 21.4, 16.5, 11.8]; GVAR(TempNight) = [1.4, 2.4, 3.7, 7.1, 10.9, 14.3, 16.5, 16.3, 13, 9.5, 6, 3.8]; // Source: http://www.weather-and-climate.com/average-monthly-Humidity-perc,Bursa,Turkey GVAR(Humidity) = [78, 75, 70, 70, 71, 61, 58, 59, 63, 69, 77, 76]; }; -if (worldName in ["Kunduz"]) exitWith { - // Source: http://www.iten-online.ch/klima/asien/afghanistan/kunduz.htm +if (_worldName in ["kunduz"]) exitWith { + // Source: http://www.iten-online.ch/klima/asien/afghanistan/kunduz.htm GVAR(TempDay) = [6.3, 9.5, 15.8, 23, 29.8, 37.3, 39, 36.9, 31.8, 24.5, 16, 9.7]; GVAR(TempNight) = [-2.4, 0, 5.7, 11.6, 15.7, 20.9, 21.5, 21.5, 16.3, 10.6, 4.1, 0]; // Source: http://www.weather-and-climate.com/average-monthly-Humidity-perc,Kabul,Afghanistan @@ -215,11 +239,3 @@ if (worldName in ["Kunduz"]) exitWith { [0.04, 0.02, 0.05, 0.14, 0.19, 0.07, 0.10, 0.07] // December ]; }; - -// Assume default values -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; 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..3b306398f9 100644 --- a/addons/weather/functions/fnc_initModuleSettings.sqf +++ b/addons/weather/functions/fnc_initModuleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Ruthberg * Module for adjusting the wind deflection settings @@ -16,24 +17,17 @@ * Public: No */ -#include "script_component.hpp" - 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..29e4e7dbe8 100644 --- a/addons/weather/functions/fnc_initWind.sqf +++ b/addons/weather/functions/fnc_initWind.sqf @@ -1,6 +1,7 @@ +#include "script_component.hpp" /* * Author: Ruthberg - * Inits the wind variables on mission start + * Inits the wind variables on the server (on mission start) * * Arguments: * None @@ -13,13 +14,10 @@ * * Public: No */ -#include "script_component.hpp" 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 acd103615b..2660076f9f 100644 --- a/addons/weather/functions/fnc_updateHumidity.sqf +++ b/addons/weather/functions/fnc_updateHumidity.sqf @@ -1,34 +1,32 @@ +#include "script_component.hpp" /* * Author: ACE2 Team - * Updates GVAR(currentHumidity) + * Smoothly updates GVAR(currentHumidity) on the server (based on time of day and map data) * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * [] call ace_weather_fnc_updateHumidity * * Public: No */ -#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 b073a6a24c..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: - * Nothing - * - * Return Value: - * Nothing - * - * 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 6f2d911c15..ea7a84a269 100644 --- a/addons/weather/functions/fnc_updateTemperature.sqf +++ b/addons/weather/functions/fnc_updateTemperature.sqf @@ -1,27 +1,25 @@ +#include "script_component.hpp" /* * 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: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * [] call ace_weather_fnc_updateTemperature * * Public: No */ -#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..c573d190ce --- /dev/null +++ b/addons/weather/functions/fnc_updateWeather.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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 72ae0470ba..569179dce8 100644 --- a/addons/weather/functions/fnc_updateWind.sqf +++ b/addons/weather/functions/fnc_updateWind.sqf @@ -1,30 +1,21 @@ +#include "script_component.hpp" /* * 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: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: * [] call ace_weather_fnc_updateWind * * Public: No */ -#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/script_component.hpp b/addons/weather/script_component.hpp index 7148fa4bb1..ea2f61ce8b 100644 --- a/addons/weather/script_component.hpp +++ b/addons/weather/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_WEATHER diff --git a/addons/weather/stringtable.xml b/addons/weather/stringtable.xml index 908e73ea3d..0bca096192 100644 --- a/addons/weather/stringtable.xml +++ b/addons/weather/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Széladatok mutatása Zobrazit údaje o větru Mostrar informação do vento + 風速を表示 + 바람 정보 표시 + 显示风力资讯 + 顯示風力資訊 Show Wind Info (Toggle) @@ -24,6 +28,10 @@ Széladatok mutatása (pecek) Zobrazit údaje o větru (přep.) Mostrar informação do vento (alternar) + 風速を表示 (切り替え) + 바람 정보 표시 (토글) + 显示风力资讯(切换) + 顯示風力資訊(切換) Weather @@ -36,6 +44,10 @@ Időjárás Погода Meteo + 天候 + 기후 + 天气 + 天氣 Multiplayer synchronized ACE weather module @@ -48,32 +60,12 @@ Többjátékos szinkronizált ACE időjárás modul ACE Модуль для синхронизации погоды в мультиплеере Modulo Sincronizzazione Meteo ACE Multiplayer + ACE 天候モジュールではマルチプレイで同期します。 + ACE 기후 모듈과 멀티플레이가 동기화됩니다. + 使用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 @@ -84,92 +76,21 @@ ACE Időjárás Погода ACE Meteo ACE + ACE 天候 + ACE 기후 + 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) + + 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 @@ -179,9 +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 @@ -191,7 +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/XEH_preInit.sqf b/addons/winddeflection/XEH_preInit.sqf index 9104abccdb..b47cf6628d 100644 --- a/addons/winddeflection/XEH_preInit.sqf +++ b/addons/winddeflection/XEH_preInit.sqf @@ -1,17 +1,9 @@ -/** - * XEH_preInit.sqf - * @Descr: N/A - * @Author: Glowbal - * - * @Arguments: [] - * @Return: - * @PublicAPI: false - */ - #include "script_component.hpp" ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/winddeflection/functions/fnc_handleFired.sqf b/addons/winddeflection/functions/fnc_handleFired.sqf index e78620471d..f43b40f455 100644 --- a/addons/winddeflection/functions/fnc_handleFired.sqf +++ b/addons/winddeflection/functions/fnc_handleFired.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Ruthberg * Handles wind deflection for projectiles. Called from the unified fired EH only for players on foot and their vehicles if required by settings. @@ -6,21 +7,29 @@ * None. Parameters inherited from EFUNC(common,firedEH) * * Return Value: - * Nothing + * None * * Example: * [clientFiredBIS-XEH] call ace_advanced_ballistics_fnc_handleFired * * 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); -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 037ce15c47..39e7fc6f31 100644 --- a/addons/winddeflection/functions/fnc_initModuleSettings.sqf +++ b/addons/winddeflection/functions/fnc_initModuleSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Ruthberg * Module for adjusting the wind deflection settings @@ -10,11 +11,12 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_winddeflection_fnc_initModuelSettings + * * Public: No */ -#include "script_component.hpp" - params ["_logic", "_units", "_activated"]; if !(_activated) exitWith {}; @@ -22,6 +24,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 acf8b2a9fa..e0a6b5da54 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal, Ruthberg * Handles wind deflection for projectiles. @@ -7,45 +8,42 @@ * 1: airFriction - air friction of the bullet * * Return Value: - * Nothing + * None * * Example: + * [bullet, 2] call ace_winddeflection_fnc_updateTrajectoryPFH * * Public: No */ -// #define ENABLE_PERFORMANCE_COUNTERS -#include "script_component.hpp" [{ // BEGIN_COUNTER(pfeh); - private ["_accel", "_accelRef", "_bulletSpeed", "_bulletVelocity", "_deleted", "_deltaT", "_drag", "_dragRef", "_isWind", "_trueSpeed", "_trueVelocity"]; params ["_args"]; _args params ["_lastTime"]; - _deltaT = CBA_missionTime - _lastTime; + private _deltaT = CBA_missionTime - _lastTime; _args set [0, CBA_missionTime]; - _deleted = 0; - _isWind = (vectorMagnitude ACE_wind > 0); + private _isWind = (vectorMagnitude wind > 0); { _x params ["_bullet", "_airFriction"]; - _bulletVelocity = velocity _bullet; - _bulletSpeed = vectorMagnitude _bulletVelocity; + private _bulletVelocity = velocity _bullet; + private _bulletSpeedSqr = vectorMagnitudeSqr _bulletVelocity; - if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeed < 100}}) then { + if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeedSqr < 10000}}) then { GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); } else { if (_isWind) then { - _trueVelocity = _bulletVelocity vectorDiff ACE_wind; - _trueSpeed = vectorMagnitude _trueVelocity; + private _trueVelocity = _bulletVelocity vectorDiff wind; + private _trueSpeed = vectorMagnitude _trueVelocity; - _dragRef = _deltaT * _airFriction * _bulletSpeed * _bulletSpeed; - _accelRef = (vectorNormalized _bulletVelocity) vectorMultiply (_dragRef); + private _dragRef = _deltaT * _airFriction * _bulletSpeedSqr; + private _accelRef = (vectorNormalized _bulletVelocity) vectorMultiply (_dragRef); _bulletVelocity = _bulletVelocity vectorDiff _accelRef; - _drag = _deltaT * _airFriction * _trueSpeed; - _accel = _trueVelocity vectorMultiply (_drag); + private _drag = _deltaT * _airFriction * _trueSpeed; + private _accel = _trueVelocity vectorMultiply (_drag); _bulletVelocity = _bulletVelocity vectorAdd _accel; }; _bullet setVelocity _bulletVelocity; diff --git a/addons/winddeflection/script_component.hpp b/addons/winddeflection/script_component.hpp index 10deceddd8..d1a0c96c68 100644 --- a/addons/winddeflection/script_component.hpp +++ b/addons/winddeflection/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_WINDDEFLECTION diff --git a/addons/winddeflection/stringtable.xml b/addons/winddeflection/stringtable.xml index 6cb4858d21..53648b2e37 100644 --- a/addons/winddeflection/stringtable.xml +++ b/addons/winddeflection/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Szélinformáció Informazioni sul vento Informação do vento + 風の情報 + 바람 정보 + 风力资讯 + 風力資訊 Direction: %1 @@ -24,6 +28,10 @@ Irány: %1 Direzione: %1° Direção: %1 + 風向: %1 + 방향: %1 + 风向: %1 + 風向: %1 Speed: %1 m/s @@ -36,6 +44,10 @@ Sebesség: %1 m/s Velocità: %1 m/s Velocidade: %1 m/s + 風速: %1 m/s + 풍속: %1 m/s + 风速: %1 m/s + 風速: %1 m/s Weather Information @@ -48,6 +60,10 @@ Időjárás-Információ Meteo Informação Meteorológica + 天候の情報 + 기상 정보 + 天气资讯 + 天氣資訊 Humidity: %1% @@ -60,6 +76,10 @@ Páratartalom: %1% Umidità: %1% Humidade: %1% + 湿度: %1% + 습도: %1% + 湿度: %1% + 濕度: %1% Wind Deflection @@ -72,6 +92,10 @@ Szél-hárítás Отклонение ветром Deviazione del Vento + 風向の変化 + 풍향 변화 + 风偏 + 風偏 Wind Deflection @@ -84,6 +108,10 @@ Szél-hárítás Отклонение ветром Deviazione del Vento + 風向の変化 + 풍향 변화 + 风偏 + 風偏 Enables wind deflection @@ -96,6 +124,10 @@ Engedélyezi a szél-hárítást Включает отклонение ветром Abilita deviazione del vento + 風向の変化を有効化 + 풍향 변화를 적용합니다 + 开启风偏效果 + 開啟風偏效果 Vehicle Enabled @@ -108,6 +140,10 @@ Jármű engedélyezve Для техники Abilita per Veicoli + 車両へ有効化 + 차량 적용 + 启用风偏给载具 + 啟用風偏給載具 Enables wind deflection for static/vehicle gunners @@ -120,6 +156,10 @@ 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 + 重火器や車両へ、風向の変化を有効化 + 차량이나 거치식 무기 사수에게 풍향 변화를 적용합니다 + 使风偏作用在固定式武器与载具炮手身上 + 使風偏作用在固定式武器與載具砲手身上 Simulation Interval @@ -132,6 +172,10 @@ Szimulációs intervallum Интервал симуляции Intervallo Simulazione + シミュレーションの間隔 + 模拟间隔 + 模擬間隔 + 시뮬레이션 간격 Defines the interval between every calculation step @@ -144,30 +188,10 @@ Megszabja a számítási lépések közötti intervallumot Определяет временной интервал между расчетами Definisce l'intervallo tra ogni passaggio di calcolo - - - 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 @@ -180,6 +204,10 @@ Szél hatása a lövedékek röppályájára Влияние втера на траекторию снарядов Influenza del vento sulla traiettoria dei proiettili + 風を弾道へ影響させます + 발사체의 궤도에 풍향 변화를 줍니다. + 风力的大小会引响到弹道的轨迹 + 風力的大小會引響到彈道的軌跡 - \ No newline at end of file + diff --git a/addons/yardage450/CfgVehicles.hpp b/addons/yardage450/CfgVehicles.hpp index d8f2ccabe3..2dc52de68a 100644 --- a/addons/yardage450/CfgVehicles.hpp +++ b/addons/yardage450/CfgVehicles.hpp @@ -6,15 +6,15 @@ class CfgVehicles { scopeCurator = 2; displayName = CSTRING(DisplayName); vehicleClass = "Items"; - class TransportWeapons { - MACRO_ADDWEAPON(ACE_Yardage450,1); + class TransportItems { + MACRO_ADDITEM(ACE_Yardage450,1); }; }; class Box_NATO_Support_F; class ACE_Box_Misc: Box_NATO_Support_F { - class TransportWeapons { - MACRO_ADDWEAPON(ACE_Yardage450,4); + class TransportItems { + MACRO_ADDITEM(ACE_Yardage450,4); }; }; }; diff --git a/addons/yardage450/XEH_preInit.sqf b/addons/yardage450/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/yardage450/XEH_preInit.sqf +++ b/addons/yardage450/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/yardage450/functions/fnc_acquireTarget.sqf b/addons/yardage450/functions/fnc_acquireTarget.sqf index a7e56e815d..a6fb23f3f7 100644 --- a/addons/yardage450/functions/fnc_acquireTarget.sqf +++ b/addons/yardage450/functions/fnc_acquireTarget.sqf @@ -1,26 +1,25 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Fires the laser to acquire the target * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: + * call ace_yardage450_fnc_acquireTarget * * Public: No */ -#include "script_component.hpp" // Reference: http://www.optcorp.com/pdf/Bushnell/YardageProSport.pdf #define MIN_DISTANCE ([9, 10] select GVAR(useYards)) #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; @@ -33,24 +32,17 @@ GVAR(distanceIndex) = -1; [_this select 1] call CBA_fnc_removePerFrameHandler; }; - _result = [eyePos ACE_player, ACE_player weaponDirection (currentWeapon 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 a56bddb016..05ae3db398 100644 --- a/addons/yardage450/functions/fnc_turnOn.sqf +++ b/addons/yardage450/functions/fnc_turnOn.sqf @@ -1,18 +1,19 @@ +#include "script_component.hpp" /* * Author: Ruthberg * Shows the Yardage 450 screen elements * * Arguments: - * Nothing + * None * * Return Value: - * Nothing + * None * * Example: + * call ace_yardage450_fnc_turnOn * * Public: No */ -#include "script_component.hpp" #define __dsp (uiNamespace getVariable "ACE_RscYardage450") #define __ctrlTarget (__dsp displayCtrl 720041) diff --git a/addons/yardage450/script_component.hpp b/addons/yardage450/script_component.hpp index bb901a9b50..5aed3a836c 100644 --- a/addons/yardage450/script_component.hpp +++ b/addons/yardage450/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_YARDAGE450 diff --git a/addons/yardage450/stringtable.xml b/addons/yardage450/stringtable.xml index c9f1c94b1b..6ab95aff7f 100644 --- a/addons/yardage450/stringtable.xml +++ b/addons/yardage450/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -12,6 +12,10 @@ Yardage 450 Yardage 450 Yardage 450 + ヤードエイジ 450 + Yardage 450 + Yardage 450 + Yardage 450 Laser Rangefinder @@ -24,6 +28,10 @@ Лазерный дальномер Distanziometro Laser Télémètre laser + レーザー測距機 + 레이저 거리측정기 + 雷射测距仪 + 雷射測距儀 Yardage 450 - Power Button @@ -36,6 +44,10 @@ Yardage 450 - Кнопка питания Yardage 450 - Bottone Accensione Yardage 450 - bouton d'alimentation + ヤードエイジ 450 - 起動ボタン + Yardage 450 - 전원 버튼 + Yardage 450 - 电源按钮 + Yardage 450 - 電源按鈕 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/CfgFactionClasses.hpp b/addons/zeus/CfgFactionClasses.hpp new file mode 100644 index 0000000000..6c164a3c5d --- /dev/null +++ b/addons/zeus/CfgFactionClasses.hpp @@ -0,0 +1,32 @@ +class CfgFactionClasses { + class GVAR(AI) { + displayName = "ACE AI"; + priority = 2; + side = 7; + }; + class GVAR(Captive) { + displayName = "ACE Captive"; + priority = 2; + side = 7; + }; + class GVAR(Medical) { + displayName = "ACE Medical"; + priority = 2; + side = 7; + }; + class GVAR(Repair) { + displayName = "ACE Repair"; + priority = 2; + side = 7; + }; + class GVAR(Utility) { + displayName = "ACE Utility"; + priority = 2; + side = 7; + }; + class GVAR(Arsenal) { + displayName = "ACE Arsenal"; + priority = 2; + side = 7; + }; +}; diff --git a/addons/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 4ab9ad871c..74095cb4a2 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"; @@ -86,6 +86,7 @@ class CfgVehicles { class GVAR(moduleBase): Module_F { author = ECSTRING(common,ACETeam); category = "ACE"; + function = QEFUNC(common,dummy); functionPriority = 1; isGlobal = 1; isTriggerActivated = 0; @@ -94,84 +95,226 @@ class CfgVehicles { }; class GVAR(moduleAddSpareTrack): GVAR(moduleBase) { curatorCanAttach = 1; + 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(moduleSetEngineer): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Repair); + displayName = CSTRING(ModuleSetEngineer_DisplayName); + curatorInfoType = QGVAR(RscSetEngineer); + icon = "a3\ui_f\data\IGUI\Cfg\Actions\repair_ca.paa"; + }; + class GVAR(moduleSetRepairFacility): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Repair); + displayName = CSTRING(ModuleSetRepairFacility_DisplayName); + function = QFUNC(moduleSetRepairFacility); + icon = "a3\ui_f\data\IGUI\Cfg\Actions\repair_ca.paa"; + }; + class GVAR(moduleSetRepairVehicle): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Repair); + displayName = CSTRING(ModuleSetRepairVehicle_DisplayName); + function = QFUNC(moduleSetRepairVehicle); + icon = "a3\ui_f\data\IGUI\Cfg\Actions\repair_ca.paa"; + }; + class GVAR(moduleAddOrRemoveFRIES): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleAddOrRemoveFRIES_DisplayName); + function = QFUNC(moduleAddOrRemoveFRIES); }; class GVAR(moduleCaptive): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Captive); displayName = CSTRING(ModuleCaptive_DisplayName); 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); displayName = CSTRING(ModuleDefendArea_DisplayName); curatorInfoType = QGVAR(RscDefendArea); }; + class GVAR(moduleEditableObjects): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleEditableObjects_DisplayName); + curatorInfoType = QGVAR(RscEditableObjects); + icon = QPATHTOF(ui\Icon_Module_Zeus_Editable_Objects_ca.paa); + }; class GVAR(moduleGlobalSetSkill): GVAR(moduleBase) { + category = QGVAR(AI); displayName = CSTRING(ModuleGlobalSetSkill_DisplayName); curatorInfoType = QGVAR(RscGlobalSetSkill); }; class GVAR(moduleGroupSide): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Utility); displayName = CSTRING(ModuleGroupSide_DisplayName); curatorInfoType = QGVAR(RscGroupSide); }; + class GVAR(moduleHeal): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Medical); + displayName = CSTRING(ModuleHeal_DisplayName); + function = QFUNC(moduleHeal); + icon = QPATHTOF(ui\Icon_Module_Zeus_Heal_ca.paa); + }; + 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); displayName = CSTRING(ModulePatrolArea_DisplayName); curatorInfoType = QGVAR(RscPatrolArea); }; class GVAR(moduleSearchArea): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(AI); displayName = CSTRING(ModuleSearchArea_DisplayName); curatorInfoType = QGVAR(RscSearchArea); }; class GVAR(moduleSearchNearby): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(AI); displayName = CSTRING(ModuleSearchNearby_DisplayName); function = QFUNC(moduleSearchNearby); }; + class GVAR(moduleSuppressiveFire): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(AI); + displayName = CSTRING(ModuleSuppressiveFire_DisplayName); + function = QFUNC(moduleSuppressiveFire); + }; class GVAR(moduleSetMedic): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Medical); displayName = CSTRING(ModuleSetMedic_DisplayName); function = QFUNC(moduleSetMedic); icon = QPATHTOF(UI\Icon_Module_Zeus_Medic_ca.paa); }; class GVAR(moduleSetMedicalFacility): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Medical); displayName = CSTRING(ModuleSetMedicalFacility_DisplayName); function = QFUNC(moduleSetMedicalFacility); icon = QPATHTOF(UI\Icon_Module_Zeus_Medic_ca.paa); }; class GVAR(moduleSetMedicalVehicle): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Medical); displayName = CSTRING(ModuleSetMedicalVehicle_DisplayName); function = QFUNC(moduleSetMedicalVehicle); icon = QPATHTOF(UI\Icon_Module_Zeus_Medic_ca.paa); }; + class GVAR(moduleSimulation): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleSimulation_DisplayName); + function = QFUNC(moduleSimulation); + }; + class GVAR(moduleSuicideBomber): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(AI); + displayName = CSTRING(ModuleSuicideBomber_DisplayName); + curatorInfoType = QGVAR(RscSuicideBomber); + }; class GVAR(moduleSurrender): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Captive); displayName = CSTRING(ModuleSurrender_DisplayName); function = QFUNC(moduleSurrender); icon = QPATHTOF(UI\Icon_Module_Zeus_Surrender_ca.paa); }; class GVAR(moduleTeleportPlayers): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Utility); displayName = CSTRING(ModuleTeleportPlayers_DisplayName); curatorInfoType = QGVAR(RscTeleportPlayers); }; class GVAR(moduleUnconscious): GVAR(moduleBase) { curatorCanAttach = 1; + category = QGVAR(Medical); displayName = CSTRING(ModuleUnconscious_DisplayName); 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); + icon = QPATHTOF(ui\Icon_Module_Zeus_Flashlight_ca.paa); + }; + class GVAR(AddFullArsenal): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleAddFullArsenal_DisplayName); + function = QFUNC(moduleAddArsenal); + }; + class GVAR(RemoveFullArsenal): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleRemoveArsenal_DisplayName); + function = QFUNC(moduleRemoveArsenal); + }; + class GVAR(AddFullAceArsenal): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Arsenal); + displayName = CSTRING(ModuleAddFullACEArsenal_DisplayName); + function = QFUNC(moduleAddAceArsenal); + }; + class GVAR(RemoveFullAceArsenal): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Arsenal); + displayName = CSTRING(ModuleRemoveACEArsenal_DisplayName); + function = QFUNC(moduleRemoveAceArsenal); + }; + class ModuleArsenal_F: Module_F { + function=QFUNC(bi_moduleArsenal); + }; }; diff --git a/addons/zeus/XEH_PREP.hpp b/addons/zeus/XEH_PREP.hpp index eb70a8529d..910b0db4d1 100644 --- a/addons/zeus/XEH_PREP.hpp +++ b/addons/zeus/XEH_PREP.hpp @@ -1,30 +1,57 @@ PREP(addObjectToCurator); +PREP(bi_moduleArsenal); PREP(bi_moduleCurator); PREP(bi_moduleMine); PREP(bi_moduleProjectile); PREP(bi_moduleRemoteControl); +PREP(getModuleDestination); PREP(handleZeusUnitAssigned); +PREP(moduleAddArsenal); +PREP(moduleAddAceArsenal); PREP(moduleAddSpareTrack); PREP(moduleAddSpareWheel); +PREP(moduleAddOrRemoveFRIES); PREP(moduleCaptive); +PREP(moduleConfigurePylons); +PREP(moduleGarrison); PREP(moduleGlobalSetSkill); PREP(moduleGroupSide); +PREP(moduleHeal); +PREP(moduleLoadIntoCargo); +PREP(moduleRemoveArsenal); +PREP(moduleRemoveAceArsenal); PREP(moduleSearchNearby); +PREP(moduleSetEngineer); PREP(moduleSetMedic); PREP(moduleSetMedicalVehicle); PREP(moduleSetMedicalFacility); +PREP(moduleSetRepairFacility); +PREP(moduleSetRepairVehicle); +PREP(moduleSimulation); +PREP(moduleSuicideBomber); +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_setEngineer); +PREP(ui_suicideBomber); 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 9062ae5e9a..63a62d5948 100644 --- a/addons/zeus/XEH_postInit.sqf +++ b/addons/zeus/XEH_postInit.sqf @@ -2,7 +2,7 @@ ["ace_settingsInitialized",{ // Only add an InitPost EH if setting is enabled (and apply retroactively) - if (isServer && GVAR(autoAddObjects)) then { + if (isServer && {GVAR(autoAddObjects)}) then { ["AllVehicles", "InitPost", FUNC(addObjectToCurator), true, [], true] call CBA_fnc_addClassEventHandler; }; }] call CBA_fnc_addEventHandler; @@ -10,7 +10,33 @@ // Global skill module PVs values for persistence, just listen for the PV QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); +[QGVAR(moveToRespawnPosition), BIS_fnc_moveToRespawnPosition] call CBA_fnc_addEventHandler; [QGVAR(moduleDefendArea), CBA_fnc_taskDefend] call CBA_fnc_addEventHandler; [QGVAR(modulePatrolArea), CBA_fnc_taskPatrol] call CBA_fnc_addEventHandler; [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; + +// Editable object commands must be ran on server, this events are used in the respective module +if (isServer) then { + [QGVAR(equipFries), EFUNC(fastroping,equipFRIES)] call CBA_fnc_addEventHandler; + + [QGVAR(addObjects), { + params ["_objects", ["_curator", objNull]]; + + if (!isNull _curator) exitWith {_curator addCuratorEditableObjects [_objects, true]}; + + { + _x addCuratorEditableObjects [_objects, true]; + } forEach allCurators; + }] call CBA_fnc_addEventHandler; + [QGVAR(removeObjects), { + params ["_objects", ["_curator", objNull]]; + + if (!isNull _curator) exitWith {_curator removeCuratorEditableObjects [_objects, true]}; + + { + _x removeCuratorEditableObjects [_objects, true]; + } forEach allCurators; + }] call CBA_fnc_addEventHandler; +}; diff --git a/addons/zeus/XEH_preInit.sqf b/addons/zeus/XEH_preInit.sqf index 47a1adefa3..a55f9c304e 100644 --- a/addons/zeus/XEH_preInit.sqf +++ b/addons/zeus/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; if (isServer) then { [QGVAR(zeusUnitAssigned), FUNC(handleZeusUnitAssigned)] call CBA_fnc_addEventHandler; diff --git a/addons/zeus/config.cpp b/addons/zeus/config.cpp index 4c9a831fd0..37cfa24dd4 100644 --- a/addons/zeus/config.cpp +++ b/addons/zeus/config.cpp @@ -4,23 +4,40 @@ 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(moduleTeleportPlayers) + QGVAR(moduleGarrison), + QGVAR(moduleUnGarrison), + QGVAR(moduleTeleportPlayers), + QGVAR(moduleToggleNvg), + QGVAR(moduleToggleFlashlight), + QGVAR(moduleSimulation), + QGVAR(moduleSuppressiveFire), + QGVAR(AddFullArsenal), + QGVAR(RemoveFullArsenal), + QGVAR(moduleTeleportPlayers), + QGVAR(moduleHeal), + QGVAR(moduleSuicideBomber), + QGVAR(AddFullAceArsenal), + QGVAR(RemoveFullAceArsenal) }; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_common", "ace_ai"}; author = ECSTRING(common,ACETeam); - authors[] = {"SilentSpike"}; + authors[] = {"SilentSpike", "mharis001"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; - // Use additional cfgPatches to contextually remove modules from zeus + + // Use additional CfgPatches to contextually remove modules from zeus class GVAR(captives): ADDON { units[] = { QGVAR(moduleCaptive), @@ -35,28 +52,55 @@ class CfgPatches { QGVAR(moduleSetMedicalFacility) }; }; + class GVAR(cargo): ADDON { + units[] = { + QGVAR(moduleLoadIntoCargo) + }; + }; + class GVAR(repair): ADDON { + units[] = { + QGVAR(moduleSetEngineer), + QGVAR(moduleSetRepairVehicle), + QGVAR(moduleSetRepairFacility) + }; + }; class GVAR(cargoAndRepair): ADDON { units[] = { QGVAR(moduleAddSpareTrack), QGVAR(moduleAddSpareWheel) }; }; + class GVAR(fastroping): ADDON { + units[] = { + QGVAR(moduleAddOrRemoveFRIES) + }; + }; + class GVAR(pylons): ADDON { + units[] = { + QGVAR(moduleConfigurePylons) + }; + }; + class GVAR(arsenal): ADDON { + units[] = { + QGVAR(AddFullAceArsenal), + QGVAR(RemoveFullAceArsenal) + }; + }; }; class ACE_Curator { GVAR(captives) = "ace_captives"; GVAR(medical) = "ace_medical"; + GVAR(cargo) = "ace_cargo"; + GVAR(repair) = "ace_repair"; GVAR(cargoAndRepair)[] = {"ace_cargo", "ace_repair"}; + GVAR(fastroping) = "ace_fastroping"; + GVAR(pylons) = "ace_pylons"; + GVAR(arsenal) = "ace_arsenal"; }; +#include "CfgFactionClasses.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "ACE_Settings.hpp" #include "ui\RscAttributes.hpp" - -class ACE_newEvents { - zeusUnitAssigned = QGVAR(zeusUnitAssigned); - SetSurrendered = QEGVAR(captives,setSurrendered); - SetHandcuffed = QEGVAR(captives,setHandcuffed); - AddCargoByClass = "ace_addCargo"; -}; diff --git a/addons/zeus/functions/fnc_addObjectToCurator.sqf b/addons/zeus/functions/fnc_addObjectToCurator.sqf index cab5b3da6f..975da83f93 100644 --- a/addons/zeus/functions/fnc_addObjectToCurator.sqf +++ b/addons/zeus/functions/fnc_addObjectToCurator.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Glowbal * Adds an object to curator upon spawn @@ -8,11 +9,12 @@ * Return Value: * None * + * Example: + * [object] call ace_zeus_fnc_addObjectToCurator + * * Public: No */ -#include "script_component.hpp" - params ["_object"]; if (!(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)])) exitWith {}; diff --git a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf new file mode 100644 index 0000000000..fffca62fc3 --- /dev/null +++ b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf @@ -0,0 +1,65 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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_moduleCurator.sqf b/addons/zeus/functions/fnc_bi_moduleCurator.sqf index 231f2cb08d..b74cc28781 100644 --- a/addons/zeus/functions/fnc_bi_moduleCurator.sqf +++ b/addons/zeus/functions/fnc_bi_moduleCurator.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Bohemia Interactive * Module function for initalizing zeus @@ -10,13 +11,14 @@ * 2: activated * * Return Value: - * nil + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_bi_moduleCurator * * Public: No */ -#include "script_component.hpp" - params ["_logic", "_units", "_activated"]; if (_activated) then { @@ -98,7 +100,7 @@ if (_activated) then { //--- Handle ownership [_logic,_ownerVar,_ownerUID,_adminVar] spawn { scriptname "BIS_fnc_moduleCurator: Owner"; - + params ["_logic", "_ownerVar", "_ownerUID", "_adminVar"]; if (_adminVar != "") then {_ownerVar = _adminVar;}; diff --git a/addons/zeus/functions/fnc_bi_moduleMine.sqf b/addons/zeus/functions/fnc_bi_moduleMine.sqf index 5a14fbe218..6b8866aaa4 100644 --- a/addons/zeus/functions/fnc_bi_moduleMine.sqf +++ b/addons/zeus/functions/fnc_bi_moduleMine.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Bohemia Interactive * Module function for spawning mines @@ -9,17 +10,18 @@ * 2: activated * * Return Value: - * nil + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_bi_moduleMine * * Public: No */ -#include "script_component.hpp" - 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]; @@ -41,7 +43,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 1a9da0ab02..4439ad3517 100644 --- a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf +++ b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Bohemia Interactive * Module function for spawning projectiles @@ -10,40 +11,38 @@ * 2: activated * * Return Value: - * nil + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_bi_moduleProjectile * * Public: No */ -#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; @@ -104,15 +103,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]; @@ -121,7 +120,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); }; @@ -140,13 +139,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 { @@ -158,7 +157,7 @@ if (_activated) then { _projectile setposasl _posNew; _pos = getposatl _logic; _dir = direction _logic; - missionnamespace setVariable [_dirVar,_dir]; + //missionnamespace setvariable [_dirVar,_dir]; See L37 }; sleep 0.1; isnull _projectile || isnull _logic @@ -177,7 +176,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 { @@ -188,6 +187,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 f32afef130..b35c8a508c 100644 --- a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf +++ b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Bohemia Interactive * Module function for remote controlling units as zeus @@ -9,13 +10,14 @@ * 2: activated * * Return Value: - * nil + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_bi_moduleRemoteControl * * Public: No */ -#include "script_component.hpp" - _logic = _this select 0; _units = _this select 1; _activated = _this select 2; @@ -31,13 +33,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 new file mode 100644 index 0000000000..2066d5887e --- /dev/null +++ b/addons/zeus/functions/fnc_getModuleDestination.sqf @@ -0,0 +1,120 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Allows zeus to click to indicate a 3d position. + * + * Arguments: + * 0: The souce object + * 1: Code to run when position is ready + * - 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]) + * 5: Icon Angle (default: 0) + * + * Return Value: + * None + * + * Example: + * [player, {systemChat format ["Done %1", _this]}] call ace_zeus_fnc_getModuleDestination + * + * Public: No + */ + +params ["_object", "_code", ["_text", ""], ["_icon", "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa"], ["_color", [1,0,0,1]], ["_angle", 0]]; + +if (missionNamespace getVariable [QGVAR(moduleDestination_running), false]) exitWith { + [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_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]; + _pos2d + } else { + AGLToASL (screenToWorld getMousePosition); + }; + TRACE_2("placed",_object,_mousePosASL); + + [true, _object, _mousePosASL, _shift, _ctrl, _alt] call _code; + GVAR(moduleDestination_running) = false; +}, [_object, _code]] call CBA_fnc_addBISEventHandler; + +// 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", "_angle"]; + + private _pos2d = (((findDisplay 312) displayCtrl 50) ctrlMapScreenToWorld getMousePosition); + _mapCtrl drawIcon [_icon, _color, _pos2d, 24, 24, _angle, _text, 1, 0.03, "TahomaB", "right"]; + _mapCtrl drawLine [getPos _object, _pos2d, _color]; +}, [_object, _text, _icon, _color, _angle]] 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", "_angle"]; + 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], false, false, false] call _code; + }; + if (GVAR(moduleDestination_running)) then { + // Draw the 3d icon and line + private _mousePosAGL = screenToWorld getMousePosition; + drawIcon3D [_icon, _color, _mousePosAGL, 1.5, 1.5, _angle, _text]; + drawLine3D [_mousePosAGL, ASLtoAGL (getPosASL _object), _color];; + } else { + 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_displayEHMouse)]; + (findDisplay 312) displayRemoveEventHandler ["KeyDown", GVAR(moduleDestination_displayEHKeyboard)]; + ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["draw", GVAR(moduleDestination_mapDrawEH)]; + GVAR(moduleDestination_displayEHMouse) = nil; + GVAR(moduleDestination_displayEHKeyboard) = nil; + GVAR(moduleDestination_mapDrawEH) = nil; + }; +}, 0, [_object, _code, _text, _icon, _color, _angle]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf b/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf index 65663e65fd..05bf5fdfb3 100644 --- a/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf +++ b/addons/zeus/functions/fnc_handleZeusUnitAssigned.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Contextually removes addons (given in ACE_Curator) from zeus based on their required addon(s) @@ -12,39 +13,34 @@ * 1: The zeus player * * Return Value: - * nil + * None + * + * Example: + * [LOGIC, bob] call ace_zeus_fnc_handleZeusUnitAssigned * * Public: No */ -#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_moduleAddAceArsenal.sqf b/addons/zeus/functions/fnc_moduleAddAceArsenal.sqf new file mode 100644 index 0000000000..5bdb2803f9 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleAddAceArsenal.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * Author: alganthe + * Add a full ACE Arsenal to an object + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Public: No + */ + +params ["_logic"]; +if (!local _logic) exitWith {}; + +private _object = attachedTo _logic; +TRACE_3("moduleAddArsenal",_logic,_object,typeOf _object); + +switch (true) do { + case (isNull _object): { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + case (isPlayer _object): { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call FUNC(showMessage); + }; + case (!alive _object): { + [LSTRING(OnlyAlive)] call FUNC(showMessage); + }; + default { + [_object, true] call EFUNC(arsenal,removeBox); + [_object, true, true] call EFUNC(arsenal,initBox); + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleAddArsenal.sqf b/addons/zeus/functions/fnc_moduleAddArsenal.sqf new file mode 100644 index 0000000000..d284b9bb08 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleAddArsenal.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: alganthe + * Add a full arsenal to an object + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Public: No + */ + +params ["_logic"]; +if (!local _logic) exitWith {}; + +private _object = attachedTo _logic; +TRACE_3("moduleAddArsenal",_logic,_object,typeOf _object); + +switch (true) do { + case (isNull _object): { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + case (isPlayer _object): { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call FUNC(showMessage); + }; + case (!alive _object): { + [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; + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf b/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf new file mode 100644 index 0000000000..967edc9396 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleAddOrRemoveFRIES.sqf @@ -0,0 +1,56 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Add/Removes FRIES from a helicopter. + * + * Arguments: + * 0: The module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleAddOrRemoveFRIES + * + * Public: No + */ + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +if !(["ace_fastroping"] call EFUNC(common,isModLoaded)) then { + [LSTRING(RequiresAddon)] call FUNC(showMessage); +} else { + (GETMVAR(BIS_fnc_curatorObjectPlaced_mouseOver,[""])) params ["_mouseOverType", "_mouseOverUnit"]; + + if (_mouseOverType != "OBJECT") then { + [LSTRING(NothingSelected)] call FUNC(showMessage); + } else { + if !(alive _mouseOverUnit) then { + [LSTRING(OnlyAlive)] call FUNC(showMessage); + } else { + private _config = configFile >> "CfgVehicles" >> typeOf _mouseOverUnit; + private _displayName = getText (_config >> "displayName"); + if !(isNumber (_config >> QEGVAR(fastroping,enabled))) then { + [LSTRING(NotFastRopeCompatible), _displayName] call FUNC(showMessage); + } else { + private _fries = GETVAR(_mouseOverUnit,EGVAR(fastroping,FRIES),objNull); + if (isNull _fries) then { + [QGVAR(equipFries), [_mouseOverUnit]] call CBA_fnc_serverEvent; + } else { + if ([_mouseOverUnit] call EFUNC(fastroping,canCutRopes)) then { + [LSTRING(CantRemoveFRIES), _displayName] call FUNC(showMessage); + } else { + [_mouseOverUnit] call EFUNC(fastroping,cutRopes); + deleteVehicle _fries; + }; + }; + }; + }; + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf index 2926fafcf9..580d691996 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Adds a Spare Track to the vehicle. @@ -10,27 +11,29 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleAddSpareTrack + * * Public: No */ -#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 EFUNC(common,displayTextStructured); + [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { (GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""])) params ["_mouseOverType", "_mouseOverUnit"]; if (_mouseOverType != "OBJECT") then { - [LSTRING(NothingSelected)] call EFUNC(common,displayTextStructured); + [LSTRING(NothingSelected)] call FUNC(showMessage); } else { if !(alive _mouseOverUnit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { if (getNumber (configFile >> "CfgVehicles" >> "ACE_Track" >> QEGVAR(cargo,size)) > [_mouseOverUnit] call EFUNC(cargo,getCargoSpaceLeft)) then { - [LSTRING(OnlyEnoughCargoSpace)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyEnoughCargoSpace)] call FUNC(showMessage); } else { ["ace_addCargo", ["ACE_Track", _mouseOverUnit, 1, true]] call CBA_fnc_localEvent; }; diff --git a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf index 2c051c94b6..b08af3ed9d 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: Jonpas * Adds a Spare Wheel to the vehicle. @@ -10,27 +11,29 @@ * Return Value: * None * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleAddSpareWheel + * * Public: No */ -#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 EFUNC(common,displayTextStructured); + [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { (GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""])) params ["_mouseOverType", "_mouseOverUnit"]; if (_mouseOverType != "OBJECT") then { - [LSTRING(NothingSelected)] call EFUNC(common,displayTextStructured); + [LSTRING(NothingSelected)] call FUNC(showMessage); } else { if !(alive _mouseOverUnit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { if (getNumber (configFile >> "CfgVehicles" >> "ACE_Wheel" >> QEGVAR(cargo,size)) > [_mouseOverUnit] call EFUNC(cargo,getCargoSpaceLeft)) then { - [LSTRING(OnlyEnoughCargoSpace)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyEnoughCargoSpace)] call FUNC(showMessage); } else { ["ace_addCargo", ["ACE_Wheel", _mouseOverUnit, 1, true]] call CBA_fnc_localEvent; }; diff --git a/addons/zeus/functions/fnc_moduleCaptive.sqf b/addons/zeus/functions/fnc_moduleCaptive.sqf index 7d1c46f873..6420559a3f 100644 --- a/addons/zeus/functions/fnc_moduleCaptive.sqf +++ b/addons/zeus/functions/fnc_moduleCaptive.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Flips the capture state of the unit the module is placed on. @@ -8,35 +9,35 @@ * 2: Activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleCaptive * * Public: No */ -#include "script_component.hpp" +params ["_logic"]; -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_captive"]; - -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if (isNil QEFUNC(captives,setHandcuffed)) then { - [LSTRING(RequiresAddon)] call EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [LSTRING(OnlyInfantry)] call FUNC(showMessage); } else { if !(alive _unit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [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..6371183192 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleConfigurePylons.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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..ae0dd4292e --- /dev/null +++ b/addons/zeus/functions/fnc_moduleGarrison.sqf @@ -0,0 +1,61 @@ +#include "script_component.hpp" +/* + * 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 +*/ + +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 35c6476cc0..a43ba78189 100644 --- a/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf +++ b/addons/zeus/functions/fnc_moduleGlobalSetSkill.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * PV event handler to update the AI skill on all machines when set by zeus module @@ -7,18 +8,16 @@ * 1: Variable new value * * Return Value: - * None + * None * * Example: - * "ace_zeus_GlobalSkillAI" addPublicVariableEventHandler ace_zeus_fnc_moduleGlobalSetSkill + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleGlobalSetSkill * * Public: No */ -#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 fa37ca3463..397320f0ee 100644 --- a/addons/zeus/functions/fnc_moduleGroupSide.sqf +++ b/addons/zeus/functions/fnc_moduleGroupSide.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Zeus module function to change side of a group on dialog confirmation @@ -7,7 +8,7 @@ * 1: Chosen side * * Return Value: - * None + * None * * Example: * [this, west] call ace_zeus_fnc_moduleGroupSide @@ -15,9 +16,7 @@ * Public: No */ -#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_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf new file mode 100644 index 0000000000..647112f67a --- /dev/null +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -0,0 +1,58 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Full heal unit. + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleHeal + * + * Public: No + */ + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _unit = attachedTo _logic; + +// Validate module target +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; + }; +}; + +// Heal validated target +if (["ace_medical"] call EFUNC(common,isModLoaded) && {EGVAR(medical,level) > 0}) then { + [QEGVAR(medical,treatmentAdvanced_fullHealLocal), [_unit, _unit], _unit] call CBA_fnc_targetEvent; +} else { + // BI's scripted revive system + if ((missionNamespace getVariable ["bis_revive_mode", 0]) != 0) then { + ["#rev", 1, _unit] call BIS_fnc_reviveOnState; + _unit setVariable ["#rev", 1, true]; + } else { + _unit setDamage 0; + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf b/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf new file mode 100644 index 0000000000..b13c0cc29b --- /dev/null +++ b/addons/zeus/functions/fnc_moduleLoadIntoCargo.sqf @@ -0,0 +1,66 @@ +#include "script_component.hpp" +/* + * 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 + */ + +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, true]) param [0, objNull]; // 2d distance search + 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, true] 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_moduleRemoveAceArsenal.sqf b/addons/zeus/functions/fnc_moduleRemoveAceArsenal.sqf new file mode 100644 index 0000000000..bc6ba69d87 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleRemoveAceArsenal.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" +/* + * Author: alganthe + * Remove ACE Arsenal from an object + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_logic"]; +if (!local _logic) exitWith {}; + +private _object = attachedTo _logic; +TRACE_3("moduleRemoveArsenal",_logic,_object,typeOf _object); + +switch (true) do { + case (isNull _object): { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + case (isPlayer _object): { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call FUNC(showMessage); + }; + case (!alive _object): { + [LSTRING(OnlyAlive)] call FUNC(showMessage); + }; + default { + [_object, true, true] call EFUNC(arsenal,removeBox); + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf new file mode 100644 index 0000000000..ec203572e4 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * Author: alganthe + * Remove arsenal from an object + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_logic"]; +if (!local _logic) exitWith {}; + +private _object = attachedTo _logic; +TRACE_3("moduleRemoveArsenal",_logic,_object,typeOf _object); + +switch (true) do { + case (isNull _object): { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + case (isPlayer _object): { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call FUNC(showMessage); + }; + case (!alive _object): { + [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; + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleSearchNearby.sqf b/addons/zeus/functions/fnc_moduleSearchNearby.sqf index 48f35bbfee..9515ab3fdc 100644 --- a/addons/zeus/functions/fnc_moduleSearchNearby.sqf +++ b/addons/zeus/functions/fnc_moduleSearchNearby.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Commands the group the module is placed on to search the nearest building @@ -8,16 +9,17 @@ * 2: Activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleSearchNearby * * Public: No */ -#include "script_component.hpp" +params ["_logic"]; -params ["_logic","_units","_activated"]; - -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; //Validate the module target: private _unit = effectiveCommander (attachedTo _logic); @@ -27,7 +29,7 @@ scopeName "Main"; private _fnc_errorAndClose = { params ["_msg"]; deleteVehicle _logic; - [_msg] call EFUNC(common,displayTextStructured); + [_msg] call FUNC(showMessage); breakOut "Main"; }; diff --git a/addons/zeus/functions/fnc_moduleSetEngineer.sqf b/addons/zeus/functions/fnc_moduleSetEngineer.sqf new file mode 100644 index 0000000000..8280d75e65 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSetEngineer.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Zeus module function to set unit engineer skill. + * + * Arguments: + * 0: Unit + * 1: Skill level (1 - Engineer, 2 - Adv. Engineer) (default: 1) + * + * Return Value: + * None + * + * Example: + * [unit, 2] call ace_zeus_fnc_moduleSetEngineer + * + * Public: No + */ + +params ["_unit", ["_engineerN", 1]]; + +if (isNull _unit) exitWith { + ERROR("Passed unit is null"); +}; + +if !([_unit, _engineerN] call EFUNC(repair,isEngineer)) then { + _unit setVariable ["ACE_IsEngineer", _engineerN, true]; +}; diff --git a/addons/zeus/functions/fnc_moduleSetMedic.sqf b/addons/zeus/functions/fnc_moduleSetMedic.sqf index d4acda3f54..63b962d429 100644 --- a/addons/zeus/functions/fnc_moduleSetMedic.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedic.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike, Glowbal * Assigns a medic role from the medical module to a unit @@ -8,38 +9,38 @@ * 2: Activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleSetMedic * * Public: No */ -#include "script_component.hpp" +params ["_logic"]; -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_medicN"]; - -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { - [LSTRING(RequiresAddon)] call EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [LSTRING(OnlyInfantry)] call FUNC(showMessage); } else { if !(alive _unit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { - [LSTRING(OnlyNonCaptive)] call EFUNC(common,displayTextStructured); + [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 1e710bf41b..ec8106d9ff 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike, Glowbal * Assigns a medic role from the medical module to a unit @@ -8,36 +9,36 @@ * 2: Activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleSetMedicalFacility * * Public: No */ -#include "script_component.hpp" +params ["_logic"]; -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit"]; - -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { - [LSTRING(RequiresAddon)] call EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [LSTRING(OnlyStructures)] call FUNC(showMessage); } else { if !(alive _unit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { - [LSTRING(OnlyNonCaptive)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { if (!(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false))) then { _unit setVariable [QEGVAR(medical,isMedicalFacility), true, true]; diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index 4ffec3460e..afcacc0c25 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike, Glowbal * Assigns a medic role from the medical module to a unit @@ -8,38 +9,38 @@ * 2: Activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleSetMedicalVehicle * * Public: No */ -#include "script_component.hpp" +params ["_logic"]; -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_medicN"]; - -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { - [LSTRING(RequiresAddon)] call EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [LSTRING(OnlyVehicles)] call FUNC(showMessage); } else { if !(alive _unit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { - [LSTRING(OnlyNonCaptive)] call EFUNC(common,displayTextStructured); + [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_moduleSetRepairFacility.sqf b/addons/zeus/functions/fnc_moduleSetRepairFacility.sqf new file mode 100644 index 0000000000..e8d5fa84a3 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSetRepairFacility.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Assigns object as repair facility. + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleSetRepairFacility + * + * Public: No + */ + + params ["_logic"]; + + if !(local _logic) exitWith {}; + +if !(["ace_repair"] call EFUNC(common,isModLoaded)) then { + [LSTRING(RequiresAddon)] call FUNC(showMessage); +} else { + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + + if ((_mouseOver select 0) != "OBJECT") then { + [LSTRING(NothingSelected)] call FUNC(showMessage); + } else { + private _unit = (_mouseOver select 1); + + if (_unit isKindOf "Man" || {!(_unit isKindOf "Building")}) then { + [LSTRING(OnlyStructures)] call FUNC(showMessage); + } else { + if !(alive _unit) then { + [LSTRING(OnlyAlive)] call FUNC(showMessage); + } else { + if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { + [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); + } else { + if ((_unit getVariable ["ACE_isRepairFacility", 0]) < 1) then { + _unit setVariable ["ACE_isRepairFacility", 1, true]; + }; + }; + }; + }; + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleSetRepairVehicle.sqf b/addons/zeus/functions/fnc_moduleSetRepairVehicle.sqf new file mode 100644 index 0000000000..79c89dfa88 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSetRepairVehicle.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Assigns object as repair vehicle. + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleSetRepairVehicle + * + * Public: No + */ + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +if !(["ace_repair"] call EFUNC(common,isModLoaded)) then { + [LSTRING(RequiresAddon)] call FUNC(showMessage); +} else { + private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); + + if ((_mouseOver select 0) != "OBJECT") then { + [LSTRING(NothingSelected)] call FUNC(showMessage); + } else { + private _unit = _mouseOver select 1; + + if (_unit isKindOf "Man" || (_unit isKindOf "Building")) then { + [LSTRING(OnlyVehicles)] call FUNC(showMessage); + } else { + if !(alive _unit) then { + [LSTRING(OnlyAlive)] call FUNC(showMessage); + } else { + if !([_unit] call EFUNC(repair,isRepairVehicle)) then { + _unit setVariable ["ACE_isRepairVehicle", 1, true]; + }; + }; + }; + }; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleSimulation.sqf b/addons/zeus/functions/fnc_moduleSimulation.sqf new file mode 100644 index 0000000000..69d7abe36c --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSimulation.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * Author: Fisher, SilentSpike + * Toggle Simulation on object. + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleSimulation + * + * Public: No + */ + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _object = attachedTo _logic; +if (isNull _object) then { + [LSTRING(NothingSelected)] call FUNC(showMessage); +} else { + [QEGVAR(common,enableSimulationGlobal), [_object, !(simulationEnabled _object)]] call CBA_fnc_serverEvent; +}; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf new file mode 100644 index 0000000000..c659ca7a9a --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf @@ -0,0 +1,110 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Zeus module function to make unit a suicide bomber. + * + * Arguments: + * 0: Unit that is suicide bomber + * 1: Activation side (default: west) + * 2: Activation radius (default: 10) + * 3: Explosion size (0 - Small, 1 - Medium, 2 - Large) (default: 0) + * 4: Auto seek (default: false) + * + * Return Value: + * None + * + * Example: + * [unit, west, 10, 0, true] call ace_zeus_fnc_moduleSuicideBomber + * + * Public: No + */ + +#define EXPLOSIVES ["R_TBG32V_F", "M_Mo_120mm_AT", "Bo_GBU12_LGB"] +#define DISTANCE_FAR 15 +#define DISTANCE_CLOSE 2 +#define MOVE_TIME 10 +#define SCANNING_PERIOD 1 + +#ifdef DEBUG_MODE_FULL + #define SCANNING_PERIOD 0 +#endif + +TRACE_1("params",_this); + +if (isNull (_this select 0)) exitWith {}; + +// Prevent another suicide bomber module being attached +_unit setVariable [QGVAR(suicideBomber), true, true]; + +// One time behaviour changes +if (_autoSeek) then { + [QEGVAR(ai,setUnitPos), [_unit, "UP"], _unit] call CBA_fnc_targetEvent; + [QEGVAR(ai,setSpeedMode), [_unit, "FULL"], _unit] call CBA_fnc_targetEvent; + [QEGVAR(ai,setBehaviour), [[_unit], "CARELESS"], _unit] call CBA_fnc_targetEvent; + [QEGVAR(ai,setCombatMode), [_unit, "BLUE"], _unit] call CBA_fnc_targetEvent; + [QEGVAR(ai,AISection), [[_unit], ["TARGET", "AUTOTARGET"], false], _unit] call CBA_fnc_targetEvent; + [QEGVAR(ai,allowFleeing), [_unit, 0], _unit] call CBA_fnc_targetEvent; +}; + +// Run PFH to make unit a suicide bomber +[{ + params ["_args", "_pfhID"]; + _args params [["_unit", objNull], ["_activationSide", west], ["_activationRadius", 10], ["_explosionSize", 0], ["_autoSeek", false]]; + + // Unit deleted or killed + if (isNull _unit || {!alive _unit}) exitWith { + [_pfhID] call CBA_fnc_removePerFrameHandler; + LOG("Unit deleted or killed, PFH removed"); + }; + + if (!([_unit] call EFUNC(common,isAwake))) exitWith {}; + + // Detonation + private _nearObjects = (_unit nearObjects _activationRadius) select {side _x == _activationSide && {_x != _unit} && {alive _x}}; + if !(_nearObjects isEqualTo []) then { + createVehicle [EXPLOSIVES select _explosionSize, _unit, [], 0, "CAN_COLLIDE"]; + [_pfhID] call CBA_fnc_removePerFrameHandler; + LOG("Explosion created, PFH removed"); + }; + + // Auto Seek + if (!_autoSeek) exitWith {}; + + private _memory = _unit getVariable [QGVAR(suicideBomber_memory), [nil, CBA_missionTime]]; + _memory params ["_lastMove", "_lastTime"]; + + private _range = 100 + 100 * (_unit skillFinal "spotDistance"); // 100-200 + private _nearestObjects = nearestObjects [_unit, [], _range] select {side _x == _activationSide && {_x != _unit} && {alive _x}}; + + #ifdef DEBUG_MODE_FULL + if !(isNil "_lastMove") then { + drawLine3D [_unit modelToWorldVisual [0, 0, 1], _lastMove, [1, 0, 0, 1]]; + }; + for "_i" from 0 to 35 do { + drawLine3D [(_unit getRelPos [_range, _i * 10]) vectorAdd [0, 0, 1], (_unit getRelPos [_range, (_i + 1) * 10]) vectorAdd [0, 0, 1], [0, 1, 0, 1]]; + }; + for "_i" from 0 to 35 do { + drawLine3D [(_unit getRelPos [_activationRadius, _i * 10]) vectorAdd [0, 0, 1], (_unit getRelPos [_activationRadius, (_i + 1) * 10]) vectorAdd [0, 0, 1], [0, 0, 1, 1]]; + }; + for "_i" from 0 to 359 do { + if (_i >= linearConversion [_lastTime - MOVE_TIME, _lastTime, CBA_missionTime, 0, 359, true]) then { + drawLine3D [(_unit getRelPos [2, _i]) vectorAdd [0, 0, 1], (_unit getRelPos [2, _i + 1]) vectorAdd [0, 0, 1], [1, 1, 0, 1]]; + }; + }; + #endif + + if (_nearestObjects isEqualTo []) exitWith {}; + + // Get relative position close to target to avoid bug where AI wont path to a certain position + private _moveToPos = (_nearestObjects select 0) getPos [1, random 360]; + + if (isNil "_lastMove" || // No move given yet + {_lastMove distance _moveToPos > DISTANCE_FAR} || // New target is too far from last move + {_lastMove distance _unit < DISTANCE_CLOSE} || // Unit has reached last move + {CBA_missionTime >= _lastTime} // Too much time passed between last move (also acts as a fail-safe if unit gets stuck) + ) then { + [QEGVAR(ai,doMove), [[[_unit, _moveToPos]]], _unit] call CBA_fnc_targetEvent; + _unit setVariable [QGVAR(suicideBomber_memory), [_moveToPos, CBA_missionTime + MOVE_TIME]]; + TRACE_2("Moving unit",_moveToPos,CBA_missionTime); + }; +}, SCANNING_PERIOD, _this] call CBA_fnc_addPerFrameHandler; diff --git a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf new file mode 100644 index 0000000000..1900e5a7a3 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf @@ -0,0 +1,119 @@ +#include "script_component.hpp" +/* + * Author: bux, PabstMirror + * Commands the selected unit or group to start suppressive fire on the unit, group or location the 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_moduleSuppressiveFire + * + * Public: No + */ +// #define DRAW_ZEUS_INFO + +if (canSuspend) exitWith {[FUNC(moduleSuppressiveFire), _this] call CBA_fnc_directCall;}; + +params ["_logic", "_units", "_activated"]; + +if !(_activated && {local _logic}) exitWith {}; + +// Validate the module target +private _unit = effectiveCommander (attachedTo _logic); +TRACE_3("moduleSuppressiveFire placed",_unit,typeOf _unit,typeOf _logic); + +deleteVehicle _logic; // cleanup logic now, we just needed it to get the attached unit + +if (isNull _unit) exitWith { + [LSTRING(NothingSelected)] call FUNC(showMessage); +}; +if (!alive _unit) exitWith { + [LSTRING(OnlyAlive)] call FUNC(showMessage); +}; +if ([_unit] call EFUNC(common,isPlayer)) exitWith { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call FUNC(showMessage); +}; + +[_unit, { + params ["_successful", "_unit", "_mousePosASL"]; + TRACE_3("getModuleDestination return",_successful,_unit,_mousePosASL); + 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; + private _artilleryMag = ""; + + if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "artilleryScanner")) == 1) then { + // Artillery - Get mortar ammo type and verify in range + if (isNull gunner _vehicle) exitWith {_targetASL = [];}; + { + private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); + private _hit = getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit"); + if (_hit > 20) exitWith {_artilleryMag = _x;}; + } forEach getArtilleryAmmo [_vehicle]; + TRACE_1("getArtilleryAmmo",_artilleryMag); + if (_artilleryMag == "") exitWith {_targetASL = [];}; + private _eta = _vehicle getArtilleryETA [ASLtoAGL _targetASL, _artilleryMag]; + TRACE_1("getArtilleryETA",_eta); + if (_eta < 0) exitWith { + [ELSTRING(Interaction,NotInRange)] call FUNC(showMessage); + _targetASL = []; + }; + ["TOF: %1 sec", _eta toFixed 1] call FUNC(showMessage); + } else { + // Direct fire - Get a target position that will work + private _lis = lineIntersectsSurfaces [eyePos _unit, _targetASL, _unit, _vehicle]; + if ((count _lis) > 0) then { // If point is hidden, unit won't fire, do a ray cast to find where they should shoot at + _targetASL = ((_lis select 0) select 0); + TRACE_1("using ray cast pos",_mousePosASL distance _targetASL); + }; + if (_unit isEqualTo _vehicle) then { // Max range a unit can fire seems to be based on the weapon's config + private _distance = _targetASL vectorDistance eyePos _unit; + private _maxWeaponRange = getNumber (configFile >> "CfgWeapons" >> (currentWeapon _unit) >> "maxRange"); + TRACE_3("",_distance,_maxWeaponRange,currentWeapon _unit); + if (_distance > (_maxWeaponRange - 50)) then { + if (_distance > (2.5 * _maxWeaponRange)) then { + _targetASL = []; + [ELSTRING(Interaction,NotInRange)] call FUNC(showMessage); + } else { + // 1-2.5x the weapon max range, find a virtual point the AI can shoot at (won't have accurate elevation, but it will put rounds downrange) + private _fakeElevation = (_distance / 100000) * (_distance - _maxWeaponRange); + _targetASL = (eyePos _unit) vectorAdd (((eyePos _unit) vectorFromTo _targetASL) vectorMultiply (_maxWeaponRange - 50)) vectorAdd [0,0,_fakeElevation]; + TRACE_2("using virtual halfway point",_mousePosASL distance _targetASL,_fakeElevation); + }; + }; + }; + }; + + if (_targetASL isEqualTo []) exitWith {}; + + private _units = [_unit]; + if (_unit == (leader _unit)) then {_units = units _unit;}; + if (_artilleryMag != "") then {_units = [gunner _vehicle];}; + + { + if (((_unit distance _x) < 30) && {!([_x] call EFUNC(common,isPlayer))} && {[_x] call EFUNC(common,isAwake)}) then { + TRACE_2("sending event",_x,_targetASL); + [QGVAR(suppressiveFire), [_x, _targetASL, _artilleryMag], _x] call CBA_fnc_targetEvent; + }; + } forEach _units; + +#ifdef DRAW_ZEUS_INFO + [eyePos _unit, _mousePosASL, [0,0,1,1]] call EFUNC(common,addLineToDebugDraw); + [eyePos _unit, _targetASL, [1,0,0,1]] call EFUNC(common,addLineToDebugDraw); + if (_unit != _vehicle) then { + [_vehicle] call CBA_fnc_addUnitTrackProjectiles; + } else { + { + [_x] call CBA_fnc_addUnitTrackProjectiles; + } forEach _units; + }; +#endif + +}, localize LSTRING(ModuleSuppressiveFire_DisplayName), "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa", [1, 0, 0, 1], 45] call FUNC(getModuleDestination); diff --git a/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf b/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf new file mode 100644 index 0000000000..2512269865 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSuppressiveFireLocal.sqf @@ -0,0 +1,42 @@ +#include "script_component.hpp" +/* + * Author: bux, PabstMirror + * Commands the selected unit or group to start suppressive fire on the unit, group or location the module is placed on + * + * Arguments: + * 0: Unit + * 1: Fire Pos ASL + * 2: Artiller Magazine + * + * Return Value: + * None + * + * Example: + * [bob, [5, 6, 7], "bigmagazine"] call ace_zeus_fnc_moduleSuppressiveFireLocal + * + * Public: No + */ + +params ["_unit", "_targetASL", "_artilleryMag"]; +TRACE_4("moduleSuppressiveFireLocal",_unit,local _unit,_targetASL,_artilleryMag); + +if (_artilleryMag != "") exitWith { + (vehicle _unit) doArtilleryFire [ASLtoAGL _targetASL, _artilleryMag, 4]; + TRACE_3("doArtilleryFire",_unit,_targetASL,_artilleryMag); +}; + +[{ + params ["_unit", "_burstsLeft", "_nextRun", "_targetASL", "_artilleryMag"]; + if (!alive _unit) exitWith {true}; + if (CBA_missionTime >= _nextRun) then { + _burstsLeft = _burstsLeft - 1; + _this set [1, _burstsLeft]; + _this set [2, _nextRun + 4]; + _unit doSuppressiveFire _targetASL; + TRACE_2("doSuppressiveFire",_unit,_targetASL); + }; + (_burstsLeft <= 0) +}, { + TRACE_1("Done",_this); +}, [_unit, 11, CBA_missionTime, _targetASL, _artilleryMag]] call CBA_fnc_waitUntilAndExecute; + diff --git a/addons/zeus/functions/fnc_moduleSurrender.sqf b/addons/zeus/functions/fnc_moduleSurrender.sqf index e14501feb0..5fc0ae9e0c 100644 --- a/addons/zeus/functions/fnc_moduleSurrender.sqf +++ b/addons/zeus/functions/fnc_moduleSurrender.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Flips the surrender state of the unit the module is placed on. @@ -8,38 +9,38 @@ * 2: Activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleSurrender * * Public: No */ -#include "script_component.hpp" +params ["_logic"]; -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_surrendering"]; - -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if (isNil QEFUNC(captives,setSurrendered)) then { - [LSTRING(RequiresAddon)] call EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [LSTRING(OnlyInfantry)] call FUNC(showMessage); } else { if !(alive _unit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { - [LSTRING(OnlyNonCaptive)] call EFUNC(common,displayTextStructured); + [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_moduleTeleportPlayers.sqf b/addons/zeus/functions/fnc_moduleTeleportPlayers.sqf index decdb21999..c120ee14f9 100644 --- a/addons/zeus/functions/fnc_moduleTeleportPlayers.sqf +++ b/addons/zeus/functions/fnc_moduleTeleportPlayers.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Zeus module function to teleport players on dialog confirmation @@ -8,7 +9,7 @@ * 2: Teleport group * * Return Value: - * None + * None * * Example: * [player, "5854854754", false] call ace_zeus_fnc_moduleTeleportPlayers @@ -16,8 +17,6 @@ * Public: No */ -#include "script_component.hpp" - params ["_logic","_uid","_group"]; // Get the chosen unit @@ -36,8 +35,11 @@ if (_group) then { private _attached = attachedTo _logic; if (isNull _attached) then { - [_x, _logic] call BIS_fnc_moveToRespawnPosition; + // Function takes position AGL and must be ran where local + [QGVAR(moveToRespawnPosition), [_x, _logic modelToWorld [0,0,0]], _x] call CBA_fnc_targetEvent; } else { - [_x, _attached] call BIS_fnc_moveToRespawnPosition; + [QGVAR(moveToRespawnPosition), [_x, _attached], _x] call CBA_fnc_targetEvent; }; } forEach _player; + +deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf b/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf new file mode 100644 index 0000000000..3f169028a5 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleToggleFlashlight.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" +/* + * Author: alganthe, mharis001 + * Zeus module function to toggle flashlights. + * + * Arguments: + * 0: Logic object + * 1: Toggle mode + * 2: Add gear + * 3: Target units (-1 - Selected group, 0 - BLUFOR, 1 - OPFOR, 2 - Independent, 3 - Civilian) + * + * Return Value: + * None + * + * Example: + * [LOGIC, true, true, -1] call ace_zeus_fnc_moduleToggleFlashlight + * + * Public: No + */ + +params ["_logic", "_toggle", "_addGear", "_target"]; +TRACE_1("params",_this); + +// Create array of target units +private _units = []; + +if (_target == -1) then { + _units = (units attachedTo _logic) select {alive _x && {!([_x] call EFUNC(common,isPlayer))} && {!(currentWeapon _x isEqualTo "")}}; +} else { + private _side = [west, east, independent, civilian] select _target; + _units = allUnits select {alive _x && {side _x == _side} && {!([_x] call EFUNC(common,isPlayer))} && {!(currentWeapon _x isEqualTo "")}}; +}; + +// Toggle flashlights for units +if (_toggle) then { + private _cfgWeapons = configFile >> "CfgWeapons"; + { + private _weapon = currentWeapon _x; + private _pointer = (_x weaponAccessories _weapon) select 1; + + if (!(_pointer isEqualTo "") && {getNumber (_cfgWeapons >> _pointer >> "ItemInfo" >> "FlashLight" >> "size") > 0}) then { + [QEGVAR(ai,enableGunLights), [_x, "forceOn"], _x] call CBA_fnc_targetEvent; + } else { + if (_addGear) then { + // Get compatible items for pointer slot + private _compatibleItems = [_weapon, "pointer"] call CBA_fnc_compatibleItems; + + // Get random flashlight from compatible pointer slot items + private _flashlightItem = selectRandom (_compatibleItems select {getNumber (_cfgWeapons >> _x >> "ItemInfo" >> "FlashLight" >> "size") > 0}); + + // Add flashlight to weapon and enable + [QEGVAR(common,addWeaponItem), [_x, _weapon, _flashlightItem], _x] call CBA_fnc_targetEvent; + [QEGVAR(ai,enableGunLights), [_x, "forceOn"], _x] call CBA_fnc_targetEvent; + TRACE_2("Added flashlight to unit",_x,_flashlightItem); + }; + }; + } forEach _units; +} else { + { + [QEGVAR(ai,enableGunLights), [_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..f8627acfe6 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleToggleNvg.sqf @@ -0,0 +1,76 @@ +#include "script_component.hpp" +/* + * Author: alganthe, mharis001 + * Zeus module function to toggle NVGs. + * + * Arguments: + * 0: Logic object + * 1: Toggle mode + * 2: Target units (-1 - Selected group, 0 - BLUFOR, 1 - OPFOR, 2 - Independent, 3 - Civilian) + * + * Return Value: + * None + * + * Example: + * [LOGIC, true, -1] call ace_zeus_fnc_moduleToggleNvg + * + * Public: No + */ + +params ["_logic", "_toggle", "_target"]; +TRACE_1("params",_this); + +// Create array of target units +private _units = []; + +if (_target == -1) then { + _units = (units attachedTo _logic) select {alive _x && {!([_x] call EFUNC(common,isPlayer))}}; +} else { + private _side = [west, east, independent, civilian] select _target; + _units = allUnits select {alive _x && {side _x == _side} && {!([_x] call EFUNC(common,isPlayer))}}; +}; + +// Add or remove NVGs from units +private _cfgVehicles = configFile >> "CfgVehicles"; +private _cfgWeapons = configFile >> "CfgWeapons"; + +if (_toggle) then { + { + if (hmd _x isEqualTo "") then { + // Get NVG item and helmet from unit config + private _linkedItems = getArray (_cfgVehicles >> typeOf _x >> "linkedItems"); + private _nvgItem = _linkedItems select {_x isKindOf ["NVGoggles", _cfgWeapons]}; + private _nvgHelmet = _linkedItems select {!(getArray (_cfgWeapons >> _x >> "subItems") isEqualTo [])}; + + // Add NVG helmet if defined + if !(_nvgHelmet isEqualTo []) exitWith { + _x addHeadgear (_nvgHelmet select 0); + }; + + // Add NVGs if defined + if !(_nvgItem isEqualTo []) exitWith { + _x linkItem (_nvgItem select 0); + }; + + // Default: add basic NVGs + _x linkItem "NVGoggles"; + }; + } forEach _units; +} else { + { + // Get unit current NVGs or helmet with NVG built-in + private _nvgItem = hmd _x; + private _nvgHelmet = getArray (_cfgWeapons >> headgear _x >> "subItems") isEqualTo []; + + // Remove NVG equipment from unit + if !(_nvgHelmet) then { + removeHeadgear _x; + }; + + if !(_nvgItem isEqualTo "") then { + _x unlinkItem _nvgItem; + }; + } 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..5ac9ea5dcf --- /dev/null +++ b/addons/zeus/functions/fnc_moduleUnGarrison.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: alganthe + * Un-garrison a garrisoned group. + * + * Arguments: + * 0: Module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleUngarrison + * + * Public: No +*/ + +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 d9f9031cee..fbba773b04 100644 --- a/addons/zeus/functions/fnc_moduleUnconscious.sqf +++ b/addons/zeus/functions/fnc_moduleUnconscious.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Flips the unconscious state of the unit the module is placed on. @@ -8,35 +9,35 @@ * 2: Activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleUnconscious * * Public: No */ -#include "script_component.hpp" +params ["_logic"]; -params ["_logic", "_units", "_activated"]; -private ["_mouseOver", "_unit", "_conscious"]; - -if !(_activated && local _logic) exitWith {}; +if !(local _logic) exitWith {}; if (isNil QEFUNC(medical,setUnconscious)) then { - [LSTRING(RequiresAddon)] call EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [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 EFUNC(common,displayTextStructured); + [LSTRING(OnlyInfantry)] call FUNC(showMessage); } else { if !(alive _unit) then { - [LSTRING(OnlyAlive)] call EFUNC(common,displayTextStructured); + [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 0f3d720599..6024126952 100644 --- a/addons/zeus/functions/fnc_moduleZeusSettings.sqf +++ b/addons/zeus/functions/fnc_moduleZeusSettings.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Module for adjusting various aspects of zeus @@ -8,16 +9,15 @@ * 2: activated * * Return Value: - * None + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleZeusSettings * * Public: No */ -#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 new file mode 100644 index 0000000000..b38652eeba --- /dev/null +++ b/addons/zeus/functions/fnc_showMessage.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: 654wak654 + * Shows a Zeus message through the BIS function, handles localization. + * If multiple args are given, they get formatted. + * + * Arguments: + * 0: Message + * N: Anything (default: nil) + * + * Return Value: + * None + * + * Example: + * ["something"] call ace_zeus_fnc_showMessage + * ["something %1 in %2", "strange", getPos neighborhood] call ace_zeus_fnc_showMessage + * + * Public: Yes + */ + +if (!(_this isEqualTypeParams [""])) exitWith {ERROR_1("First arg must be string [%1]",_this);}; + +private _message = _this apply {if ((_x isEqualType "") && {isLocalized _x}) then {localize _x} else {_x}}; +[objNull, format _message] call BIS_fnc_showCuratorFeedbackMessage; diff --git a/addons/zeus/functions/fnc_ui_attributeCargo.sqf b/addons/zeus/functions/fnc_ui_attributeCargo.sqf index 444fa5e7e2..b4fc156127 100644 --- a/addons/zeus/functions/fnc_ui_attributeCargo.sqf +++ b/addons/zeus/functions/fnc_ui_attributeCargo.sqf @@ -1,33 +1,94 @@ +#include "script_component.hpp" /* - * Author: PabstMirror - * Initalises the ace_cargo attribute of the zeus vehicle attributes display + * Author: PabstMirror, mharis001 + * Initializes the ace_cargo attribute of the zeus vehicle attributes display. * (the display shown on double click) * * Arguments: * 0: ace_cargo controls group * * Return Value: - * None + * None * * Example: - * onSetFocus = "_this call ace_zeus_fnc_ui_vehCargo" + * [CONTROL] call ace_zeus_fnc_ui_attributeCargo * * Public: No */ -#include "script_component.hpp" - params ["_control"]; TRACE_1("params",_control); -private _veh = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); -TRACE_1("",_veh); +private _vehicle = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); +TRACE_1("",_vehicle); -private _loaded = _veh getVariable [QEGVAR(cargo,loaded), []]; +private _loaded = _vehicle getVariable [QEGVAR(cargo,loaded), []]; TRACE_1("",_loaded); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Init cargo list +private _listbox = _control controlsGroupCtrl 80086; { - (_control controlsGroupCtrl 80086) lbAdd (str _x); + private _class = if (_x isEqualType "") then {_x} else {typeOf _x}; + private _displayName = getText (configFile >> "CfgVehicles" >> _class >> "displayName"); + _listbox lbAdd _displayName; } forEach _loaded; + +// Init unload button +private _button = _control controlsGroupCtrl 80087; + +private _fnc_onButtonUnload = { + params ["_button"]; + + // Validate vehicle + private _vehicle = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); + if (isNull _vehicle || {!alive _vehicle}) exitWith { + LOG("Vehicle deleted or killed, cannot unload"); + }; + + // Handle selection + private _index = lbCurSel ((ctrlParent _button) displayCtrl 80086); + private _cargoArray = _vehicle getVariable [QEGVAR(cargo,loaded), []]; + if ((_index < 0) || {_index >= (count _cargoArray)}) exitWith { + [LSTRING(SelectCargo)] call FUNC(showMessage); + }; + + // Unload selected cargo + private _item = _cargoArray select _index; + private _class = if (_item isEqualType "") then {_item} else {typeOf _item}; + private _itemName = getText (configFile >> "CfgVehicles" >> _class >> "displayName"); + if ([_item, _vehicle] call EFUNC(cargo,unloadItem)) then { + private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + private _message = [localize ELSTRING(cargo,UnloadedItem), "
", " "] call CBA_fnc_replace; + [_message, _itemName, _vehicleName] call FUNC(showMessage); + } else { + private _message = [localize ELSTRING(cargo,UnloadingFailed), "
", " "] call CBA_fnc_replace; + [_message, _itemName] call FUNC(showMessage); + }; +}; + +_button ctrlAddEventHandler ["ButtonClick", _fnc_onButtonUnload]; + +// Add PFH to update cargo list +[{ + params ["_args", "_pfhID"]; + _args params ["_vehicle", "_listbox"]; + + // Display closed or vehicle deleted + if (isNull _listbox || {isNull _vehicle || {!alive _vehicle}}) exitWith { + [_pfhID] call CBA_fnc_removePerFrameHandler; + LOG("Display closed or vehicle deleted, PFH removed"); + }; + + // Update cargo list + private _loaded = _vehicle getVariable [QEGVAR(cargo,loaded), []]; + + lbClear _listbox; + { + private _class = if (_x isEqualType "") then {_x} else {typeOf _x}; + private _displayName = getText (configFile >> "CfgVehicles" >> _class >> "displayName"); + _listbox lbAdd _displayName; + } forEach _loaded; +}, 0.25, [_vehicle, _listbox]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/zeus/functions/fnc_ui_attributePosition.sqf b/addons/zeus/functions/fnc_ui_attributePosition.sqf deleted file mode 100644 index 95557a891b..0000000000 --- a/addons/zeus/functions/fnc_ui_attributePosition.sqf +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Author: SilentSpike - * Initalises the `position` zeus module attribute - * - * Arguments: - * 0: position controls group - * - * Return Value: - * None - * - * Public: No - */ - -#include "script_component.hpp" - -disableSerialization; - -//Generic Init: -params ["_control"]; -private _display = ctrlParent _control; -private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); - -_control ctrlRemoveAllEventHandlers "setFocus"; - -//Specific on-load stuff: -private _map = _control controlsGroupCtrl 26469; - -// Centre map on the logic initially -_map ctrlMapAnimAdd [0, ctrlMapScale _map, _logic]; -ctrlMapAnimCommit _map; - -private _fnc_onDraw = { - params ["_map"]; - - private _display = ctrlParent _map; - private _pos = GETVAR(_display,GVAR(position),[]); - private _radius = GETVAR(_display,GVAR(radius),0); - - if !(_pos isEqualTo []) then { - // Works alongside radius attribute - if (_radius == 0) then { - _map drawIcon ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [0,0,0,1], _pos, 19, 19, 0, "", 0, 0]; - } else { - _map drawEllipse [_pos, _radius, _radius, 0, [0,0,0,1], ""]; - }; - }; -}; - -private _fnc_onMapClick = { - params ["_map","_button","_x","_y","_shift","_ctrl","_alt"]; - - if (_button == 0) then { - private _display = ctrlParent _map; - SETVAR(_display,GVAR(position),_pos); - }; -}; - -SETVAR(_display,GVAR(position),getPos _logic); -_map ctrlAddEventHandler ["draw",_fnc_onDraw]; -_map ctrlAddEventHandler ["mouseButtonDown",_fnc_onMapClick]; diff --git a/addons/zeus/functions/fnc_ui_attributeRadius.sqf b/addons/zeus/functions/fnc_ui_attributeRadius.sqf index c26f8ac97d..d8a0c46305 100644 --- a/addons/zeus/functions/fnc_ui_attributeRadius.sqf +++ b/addons/zeus/functions/fnc_ui_attributeRadius.sqf @@ -1,27 +1,27 @@ +#include "script_component.hpp" /* * Author: SilentSpike - * Initalises the `radius` zeus module attribute + * Initializes the "Radius" Zeus module attribute. * * Arguments: * 0: radius controls group * * Return Value: - * None + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_attributeRadius * * Public: No */ -#include "script_component.hpp" - -disableSerialization; - -//Generic Init: +// Generic init params ["_control"]; private _display = ctrlParent _control; -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; -//Specific on-load stuff: +// Specific onLoad stuff private _edit = _control controlsGroupCtrl 26467; _edit ctrlSetText "100"; @@ -44,4 +44,4 @@ private _fnc_onKeyUp = { }; [_display] call _fnc_onKeyUp; -_display displayAddEventHandler ["keyUp", _fnc_onKeyUp]; +_display displayAddEventHandler ["KeyUp", _fnc_onKeyUp]; diff --git a/addons/zeus/functions/fnc_ui_defendArea.sqf b/addons/zeus/functions/fnc_ui_defendArea.sqf index 6fcb4a17d5..aaa05adbbf 100644 --- a/addons/zeus/functions/fnc_ui_defendArea.sqf +++ b/addons/zeus/functions/fnc_ui_defendArea.sqf @@ -1,28 +1,28 @@ +#include "script_component.hpp" /* * Author: SilentSpike - * Initalises the `defend area` zeus module display + * Initializes the "Defend Area" Zeus module display. * * Arguments: * 0: dummy controls group * * Return Value: - * None + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_defendArea * * Public: No */ -#include "script_component.hpp" - -disableSerialization; - -//Generic Init: +// Generic init params ["_control"]; private _display = ctrlParent _control; -private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; -//Validate the module target: +// Validate module target private _unit = effectiveCommander (attachedTo _logic); scopeName "Main"; @@ -30,7 +30,7 @@ private _fnc_errorAndClose = { params ["_msg"]; _display closeDisplay 0; deleteVehicle _logic; - [_msg] call EFUNC(common,displayTextStructured); + [_msg] call FUNC(showMessage); breakOut "Main"; }; @@ -47,30 +47,28 @@ switch (false) do { }; private _fnc_onUnload = { - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; - if (_this select 1 == 2) then { - deleteVehicle _logic; - }; + deleteVehicle _logic; }; private _fnc_onConfirm = { params [["_ctrlButtonOK", controlNull, [controlNull]]]; - private _display = ctrlparent _ctrlButtonOK; + private _display = ctrlParent _ctrlButtonOK; if (isNull _display) exitWith {}; - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; private _unit = effectiveCommander (attachedTo _logic); - private _radius = GETVAR(_display,GVAR(radius),50); - private _position = GETVAR(_display,GVAR(position),getPos _logic); + private _radius = GETVAR(_display,GVAR(radius),100); + private _position = getPos _logic; - [QGVAR(moduleDefendArea), [_unit,_position,_radius], _unit] call CBA_fnc_targetEvent; + [QGVAR(moduleDefendArea), [_unit, _position, _radius], _unit] call CBA_fnc_targetEvent; deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_control ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_control ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_editableObjects.sqf b/addons/zeus/functions/fnc_ui_editableObjects.sqf new file mode 100644 index 0000000000..b21b50ea26 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_editableObjects.sqf @@ -0,0 +1,72 @@ +#include "script_component.hpp" +/* + * Author: Fisher, SilentSpike, mharis001 + * Initializes the "Editable Objects" Zeus module display. + * + * Arguments: + * 0: editableObjects controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_editableObjects + * + * Public: No + */ + +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("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Specific onLoad stuff +(_display displayCtrl 19181) lbSetCurSel 1; +(_display displayCtrl 19182) lbSetCurSel 1; + +private _fnc_onUnload = { + 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 _radius = GETVAR(_display,GVAR(radius),100); + private _editingMode = lbCurSel (_display displayCtrl 19181) > 0; + private _allCurators = [getAssignedCuratorLogic player, objNull] select lbCurSel (_display displayCtrl 19182); + private _additionalObjects = lbCurSel (_display displayCtrl 19183); + + private _objects = nearestObjects [_logic, ["All"], _radius]; + if (_additionalObjects == 1) then { + _objects append call CBA_fnc_players; + } else { + if (_additionalObjects == 2) then { + _objects append (allUnits + allDeadMen select {!(_x isKindOf "HeadlessClient_F")}); + }; + }; + + if (_editingMode) then { + [QGVAR(addObjects), [_objects, _allCurators]] call CBA_fnc_serverEvent; + } else { + [QGVAR(removeObjects), [_objects, _allCurators]] call CBA_fnc_serverEvent; + }; + + deleteVehicle _logic; +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_garrison.sqf b/addons/zeus/functions/fnc_ui_garrison.sqf new file mode 100644 index 0000000000..a0843b5866 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_garrison.sqf @@ -0,0 +1,81 @@ +#include "script_component.hpp" +/* + * Author: alganthe, mharis001 + * Initializes the "Garrison" Zeus module display. + * + * Arguments: + * 0: Garrison controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_garrison + * + * Public: No +*/ + +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("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +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 onLoad stuff +private _fnc_onUnload = { + 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 _radius = GETVAR(_display,GVAR(radius),50); + private _teleport = lbCurSel (_display displayCtrl 73061) > 0; + private _topDown = lbCurSel (_display displayCtrl 73062) > 0; + private _fillingMode = lbCurSel (_display displayCtrl 73063); + + [_logic, getPos _logic, _radius, _fillingMode, _topDown, _teleport] call FUNC(moduleGarrison); +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf index 8dcac19bce..79e7ea077d 100644 --- a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf +++ b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Initalises the `global skill` zeus module display @@ -6,25 +7,21 @@ * 0: globalSetSkill controls group * * Return Value: - * None + * None * * Example: - * onSetFocus = "_this call ace_zeus_fnc_ui_globalSetSkill" + * [CONTROL] call ace_zeus_fnc_ui_globalSetSkill * * Public: No */ -#include "script_component.hpp" - -disableSerialization; - params ["_control"]; TRACE_1("params",_control); //Generic Init: -private _display = ctrlparent _control; -private _ctrlButtonOK = _display displayctrl 1; //IDC_OK -private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +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"; diff --git a/addons/zeus/functions/fnc_ui_groupSide.sqf b/addons/zeus/functions/fnc_ui_groupSide.sqf index be3298c8da..e74ab97c9e 100644 --- a/addons/zeus/functions/fnc_ui_groupSide.sqf +++ b/addons/zeus/functions/fnc_ui_groupSide.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: SilentSpike * Initalises the `group side` zeus module display @@ -6,25 +7,21 @@ * 0: groupSide controls group * * Return Value: - * NONE + * None * * Example: - * onSetFocus = "_this call ace_zeus_fnc_ui_groupSide" + * [CONTROL] call ace_zeus_fnc_ui_groupSide * * Public: No */ - -#include "script_component.hpp" #define IDCs [31201,31200,31202,31203] -disableSerialization; - params ["_control"]; //Generic Init: -private _display = ctrlparent _control; -private _ctrlButtonOK = _display displayctrl 1; //IDC_OK -private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +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"; @@ -38,7 +35,7 @@ private _fnc_errorAndClose = { params ["_msg"]; _display closeDisplay 0; deleteVehicle _logic; - [_msg] call EFUNC(common,displayTextStructured); + [_msg] call FUNC(showMessage); breakOut "Main"; }; @@ -117,7 +114,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_patrolArea.sqf b/addons/zeus/functions/fnc_ui_patrolArea.sqf index d4fbc092a0..93cae24aa5 100644 --- a/addons/zeus/functions/fnc_ui_patrolArea.sqf +++ b/addons/zeus/functions/fnc_ui_patrolArea.sqf @@ -1,28 +1,28 @@ +#include "script_component.hpp" /* * Author: SilentSpike - * Initalises the `patrol area` zeus module display + * Initializes the "Patrol Area" Zeus module display. * * Arguments: * 0: dummy controls group * * Return Value: - * None + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_patrolArea * * Public: No */ -#include "script_component.hpp" - -disableSerialization; - -//Generic Init: +// Generic init params ["_control"]; private _display = ctrlParent _control; -private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; -//Validate the module target: +// Validate module target private _unit = effectiveCommander (attachedTo _logic); scopeName "Main"; @@ -30,7 +30,7 @@ private _fnc_errorAndClose = { params ["_msg"]; _display closeDisplay 0; deleteVehicle _logic; - [_msg] call EFUNC(common,displayTextStructured); + [_msg] call FUNC(showMessage); breakOut "Main"; }; @@ -47,30 +47,28 @@ switch (false) do { }; private _fnc_onUnload = { - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; - if (_this select 1 == 2) then { - deleteVehicle _logic; - }; + deleteVehicle _logic; }; private _fnc_onConfirm = { params [["_ctrlButtonOK", controlNull, [controlNull]]]; - private _display = ctrlparent _ctrlButtonOK; + private _display = ctrlParent _ctrlButtonOK; if (isNull _display) exitWith {}; - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; private _unit = effectiveCommander (attachedTo _logic); - private _radius = GETVAR(_display,GVAR(radius),50); - private _position = GETVAR(_display,GVAR(position),getPos _logic); + private _radius = GETVAR(_display,GVAR(radius),100); + private _position = getPos _logic; - [QGVAR(modulePatrolArea), [_unit,_position,_radius,5], _unit] call CBA_fnc_targetEvent; + [QGVAR(modulePatrolArea), [_unit, _position, _radius, 5], _unit] call CBA_fnc_targetEvent; deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_control ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_control ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_searchArea.sqf b/addons/zeus/functions/fnc_ui_searchArea.sqf index 3da147b963..db2748e629 100644 --- a/addons/zeus/functions/fnc_ui_searchArea.sqf +++ b/addons/zeus/functions/fnc_ui_searchArea.sqf @@ -1,28 +1,28 @@ +#include "script_component.hpp" /* * Author: SilentSpike - * Initalises the `search area` zeus module display + * Initializes the "Search Area" Zeus module display. * * Arguments: * 0: dummy controls group * * Return Value: - * None + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_searchArea * * Public: No */ -#include "script_component.hpp" - -disableSerialization; - -//Generic Init: +// Generic init params ["_control"]; private _display = ctrlParent _control; -private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); +private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; -//Validate the module target: +// Validate module target private _unit = effectiveCommander (attachedTo _logic); scopeName "Main"; @@ -30,7 +30,7 @@ private _fnc_errorAndClose = { params ["_msg"]; _display closeDisplay 0; deleteVehicle _logic; - [_msg] call EFUNC(common,displayTextStructured); + [_msg] call FUNC(showMessage); breakOut "Main"; }; @@ -47,36 +47,34 @@ switch (false) do { }; private _fnc_onUnload = { - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; - if (_this select 1 == 2) then { - deleteVehicle _logic; - }; + deleteVehicle _logic; }; private _fnc_onConfirm = { params [["_ctrlButtonOK", controlNull, [controlNull]]]; - private _display = ctrlparent _ctrlButtonOK; + private _display = ctrlParent _ctrlButtonOK; if (isNull _display) exitWith {}; - private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); + private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); if (isNull _logic) exitWith {}; private _unit = effectiveCommander (attachedTo _logic); - private _radius = GETVAR(_display,GVAR(radius),50); - private _position = GETVAR(_display,GVAR(position),getPos _logic); - private _marker = QGVAR(ModuleSearchArea) + str(_unit); + private _radius = GETVAR(_display,GVAR(radius),100); + private _position = getPos _logic; + private _marker = QGVAR(ModuleSearchArea) + str _unit; createMarker [_marker, _position]; _marker setMarkerAlpha 0; _marker setMarkerShape "ELLIPSE"; - _marker setMarkerSize [_radius,_radius]; + _marker setMarkerSize [_radius, _radius]; - [QGVAR(moduleSearchArea), [_unit,_marker], _unit] call CBA_fnc_targetEvent; + [QGVAR(moduleSearchArea), [_unit, _marker], _unit] call CBA_fnc_targetEvent; deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_control ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_control ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_setEngineer.sqf b/addons/zeus/functions/fnc_ui_setEngineer.sqf new file mode 100644 index 0000000000..20e8113c7a --- /dev/null +++ b/addons/zeus/functions/fnc_ui_setEngineer.sqf @@ -0,0 +1,75 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Initalizes the "Set Engineer" Zeus module display. + * + * Arguments: + * 0: setEngineer controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_setEngineer + * + * Public: No + */ + +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"; + +// Validate module target +private _unit = attachedTo _logic; +TRACE_1("unit",_unit); + +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; + }; +}; + +// Specific onLoad stuff +private _fnc_onUnload = { + 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 _value = lbCurSel (_display displayCtrl 86947); + [attachedTo _logic, _value + 1] call FUNC(moduleSetEngineer); // +1 since lbCurSel zero-indexed +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_suicideBomber.sqf b/addons/zeus/functions/fnc_ui_suicideBomber.sqf new file mode 100644 index 0000000000..060618e536 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_suicideBomber.sqf @@ -0,0 +1,151 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Initializes the "Suicide Bomber" Zeus module display. + * + * Arguments: + * 0: suicideBomber controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_suicideBomber + * + * Public: No + */ + +#define SIDE_IDCs [83580, 83581, 83582, 83583] + +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("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +private _unit = attachedTo _logic; +TRACE_1("Unit",_unit); + +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 !([_unit] call EFUNC(common,isPlayer)): { + ["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call _fnc_errorAndClose; + }; + case !(_unit getVariable [QGVAR(suicideBomber), false]): { + [LSTRING(ModuleSuicideBomber_AlreadyBomber)] call _fnc_errorAndClose; + }; +}; + +// Specific onLoad stuff + +// Activation side +private _fnc_onSelection = { + params [["_activeCtrl", controlNull, [controlNull]]]; + + private _display = ctrlParent _activeCtrl; + if (isNUll _display) exitWith {}; + + // Update button colours and scales + { + private _ctrl = _display displayCtrl _x; + private _color = _ctrl getVariable "color"; + private _scale = 1; + + if (ctrlIDC _activeCtrl == _x) then { + _color set [3, 1]; + _scale = 1.2; + } else { + _color set [3, 0.5]; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; + } forEach SIDE_IDCs; + + // Save selected side + SETVAR(_display,activationSide,(ctrlIDC _activeCtrl) - 83580); +}; + +// Init side buttons +{ + private _ctrl = _display displayCtrl _x; + private _color = [_x - 83580] call BIS_fnc_sideColor; + _ctrl setVariable ["color", _color]; + _ctrl ctrlSetActiveColor _color; + + _color set [3, 0.5]; + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSelection]; +} forEach SIDE_IDCs; + +// Activation radius +private _fnc_onSliderMove = { + params ["_slider"]; + + private _display = ctrlParent _slider; + (_display displayCtrl 83573) ctrlSetText (str round sliderPosition _slider); +}; + +private _slider = _display displayCtrl 83572; +private _edit = _display displayCtrl 83573; + +_slider sliderSetRange [5, 50]; +_slider sliderSetSpeed [1, 1]; +_slider sliderSetPosition 10; +_edit ctrlSetText "10"; + +_slider ctrlAddEventHandler ["SliderPosChanged", _fnc_onSliderMove]; + +// Confirm and Cancel +private _fnc_onUnload = { + 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 _unit = attachedTo _logic; + private _side = [GETVAR(_display,activationSide,1)] call BIS_fnc_sideType; + private _radius = round sliderPosition (_display displayCtrl 83572); + private _expSize = lbCurSel (_display displayCtrl 83574); + private _autoSeek = lbCurSel (_display displayCtrl 83575) > 0; + + [_unit, _side, _radius, _expSize, _autoSeek] call FUNC(moduleSuicideBomber); + + deleteVehicle _logic; +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf index bdcd8ae93f..0594554dc5 100644 --- a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf +++ b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf @@ -1,29 +1,26 @@ +#include "script_component.hpp" /* - * Author: SilentSpike - * Initalises the `teleport players` zeus module display + * Author: SilentSpike, mharis001 + * Initalizes the "Teleport Players" Zeus module display. * * Arguments: * 0: teleportPlayers controls group * * Return Value: - * NONE + * None * * Example: - * onSetFocus = "_this call ace_zeus_fnc_ui_teleportPlayers" + * [CONTROL] call ace_zeus_fnc_ui_teleportPlayers * * 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); +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"; @@ -34,11 +31,38 @@ private _listbox = _display displayCtrl 16189; if (alive _x) then { _listbox lbSetData [_listbox lbAdd (name _x), getPlayerUID _x]; }; -} forEach allPlayers; +} forEach ([] call CBA_fnc_players); _listbox lbSetCurSel 0; (_display displayCtrl 16188) cbSetChecked (_logic getVariable ["tpGroup",false]); +private _fnc_onKeyUp = { + params ["_display"]; + + private _listbox = _display displayCtrl 16189; + private _edit = _display displayCtrl 16190; + private _text = toLower ctrlText _edit; + + lbClear _listbox; + + { + if (alive _x) then { + if ([toLower name _x, _text] call CBA_fnc_find > -1) then { + _listbox lbSetData [_listbox lbAdd (name _x), getPlayerUID _x]; + }; + }; + } forEach ([] call CBA_fnc_players); + + // Alert user to zero search matches + if (lbSize _listbox == 0) then { + _edit ctrlSetTooltip (localize LSTRING(ModuleTeleportPlayers_noneFound)); + _edit ctrlSetTextColor [1, 0, 0, 1]; + } else { + _edit ctrlSetTooltip ""; + _edit ctrlSetTextColor [1, 1, 1, 1]; + }; +}; + private _fnc_onUnload = { params ["_display"]; @@ -66,5 +90,6 @@ private _fnc_onConfirm = { [_logic, _uid, _group] call FUNC(moduleTeleportPlayers); }; +_display displayAddEventHandler ["KeyUp", _fnc_onKeyUp]; _display displayAddEventHandler ["unload", _fnc_onUnload]; _ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf new file mode 100644 index 0000000000..333da80ac3 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf @@ -0,0 +1,85 @@ +#include "script_component.hpp" +/* + * Author: alganthe, mharis001 + * Initializes the "Toggle Flashlights" Zeus module display. + * + * Arguments: + * 0: toggleFlashlight controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_toggleFlashlight + * + * Public: No + */ + +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("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +private _unit = effectiveCommander attachedTo _logic; + +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 onLoad stuff +// Remove selected group option in not placed on unit and set default flashlight status +if (isNull _unit) then { + (_display displayCtrl 56220) lbDelete 0; +} else { + (_display displayCtrl 56218) lbSetCurSel ([0, 1] select (_unit isFlashlightOn currentWeapon _unit)); +}; + +private _fnc_onUnload = { + 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 _toggle = lbCurSel (_display displayCtrl 56218) > 0; + private _addGear = lbCurSel (_display displayCtrl 56219) > 0; + private _combo = _display displayCtrl 56220; + private _target = lbCurSel _combo; + if (lbSize _combo > 4) then {DEC(_target)}; + + [_logic, _toggle, _addGear, _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..037c216205 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_toggleNvg.sqf @@ -0,0 +1,84 @@ +#include "script_component.hpp" +/* + * Author: alganthe, mharis001 + * Initializes the "Toggle NVGs" Zeus module display. + * + * Arguments: + * 0: toggleNvg controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_toggleNvg + * + * Public: No + */ + +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("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +private _unit = effectiveCommander attachedTo _logic; + +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 onLoad stuff +// Remove selected group option in not placed on unit and set default NVG status +if (isNull _unit) then { + (_display displayCtrl 92856) lbDelete 0; +} else { + (_display displayCtrl 92855) lbSetCurSel ([0, 1] select !(hmd _unit isEqualTo "")); +}; + +private _fnc_onUnload = { + 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 _toggle = lbCurSel (_display displayCtrl 92855) > 0; + private _combo = _display displayCtrl 92856; + private _target = lbCurSel _combo; + if (lbSize _combo > 4) then {DEC(_target)}; + + [_logic, _toggle, _target] call FUNC(moduleToggleNvg); +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_zeusAttributes.sqf b/addons/zeus/functions/fnc_zeusAttributes.sqf index dcbef69510..4e2b3eb897 100644 --- a/addons/zeus/functions/fnc_zeusAttributes.sqf +++ b/addons/zeus/functions/fnc_zeusAttributes.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Dummy function to include BIS script file. @@ -9,7 +10,7 @@ * 2: Display class name * * Return Value: - * None + * None * * Example: * onLoad = "['onLoad',_this,'RscDisplayExample'] call ace_zeus_fnc_zeusAttributes" @@ -17,8 +18,6 @@ * Public: No */ -#include "script_component.hpp" - TRACE_1("params",_this); #include "\a3\ui_f_curator\UI\Displays\RscDisplayAttributes.sqf" diff --git a/addons/zeus/script_component.hpp b/addons/zeus/script_component.hpp index ba32164b87..edbc5b2954 100644 --- a/addons/zeus/script_component.hpp +++ b/addons/zeus/script_component.hpp @@ -4,7 +4,6 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE -// #define CBA_DEBUG_SYNCHRONOUS // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_ZEUS @@ -18,9 +17,9 @@ #include "\z\ace\addons\main\script_macros.hpp" // UI grid -#define SIZEX ((safezoneW / safezoneH) min 1.2) +#define SIZEX ((safeZoneW / safeZoneH) min 1.2) #define SIZEY (SIZEX / 1.2) #define W_PART(num) (num * (SIZEX / 40)) #define H_PART(num) (num * (SIZEY / 25)) -#define X_PART(num) (W_PART(num) + (safezoneX + (safezoneW - SIZEX)/2)) -#define Y_PART(num) (H_PART(num) + (safezoneY + (safezoneH - SIZEY)/2)) +#define X_PART(num) (W_PART(num) + (safeZoneX + (safeZoneW - SIZEX) / 2)) +#define Y_PART(num) (H_PART(num) + (safeZoneY + (safeZoneH - SIZEY) / 2)) diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index c800afa5f3..22e45e304c 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -1,6 +1,14 @@ - + + + Zeus + Zeus + 宙斯 + 宙斯 + Zeus + 제우스 + Zeus Settings Ustawienia Zeusa @@ -12,6 +20,10 @@ Zeus beállítások Настройки Зевса Impostazioni Zeus + Zeus 設定 + Zeus 설정 + 宙斯设定 + 宙斯設定 Provides control over various aspects of Zeus. @@ -20,14 +32,18 @@ Poskytuje kontrolu na různými aspekty Zeuse. Bietet die Steuerung verschiedener Zeus-Optionen an. Proporciona controle sobre diversos aspectos do Zeus. - Fourni le contrôle des différents aspects de Zeus + Fourni le contrôle des différents aspects de Zeus. 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에게 다양한 방면의 조작을 제공해줍니다 + 提供宙斯各个方面的控制权 + 提供宙斯各個方面的控制權 Ascension Messages - Wiad. o nowym Zeusie + Wiadomość o nowym Zeusie Mensajes de ascensión Zpráva o novém Zeusovi Aufstiegsnachrichten @@ -36,6 +52,10 @@ Felemelkedési üzenetek Сообщения о вознесении Messaggi di Ascesa + 転生表示 + 재림 메세지 + 宙斯上任讯息 + 宙斯上任訊息 Display global popup messages when a player is assigned as Zeus. @@ -44,10 +64,14 @@ Zobrazit globální zprávu když je hráč přiřazen jako Zeus. Zeige globale Popup-Nachrichten wenn ein Spieler zu Zeus wird. Mostra uma mensagem popup quando um jogador é atribuido ao Zeus. - Affiche un message global quand un joueur est assigné en tant que Zeus + Affiche un message global quand un joueur est assigné en tant que Zeus. Globális üzeneteket jelez ki, ha egy játékos Zeus-nak lesz beosztva. Отображает глобальное всплывающее сообщение, когда один из игроков становится Зевсом. Mostra messaggi popup globali quando un giocatore viene assegnato come Zeus. + プレイヤーが Zeus になるとき、全体へポップアップ表示をおこないます。 + 플레이어가 Zeus 될 시 서버에 이를 알리는 팝업이 등장합니다. + 当一位玩家被指定为宙斯时显示全域讯息 + 當一位玩家被指定為宙斯時顯示全域訊息 Zeus Eagle @@ -60,6 +84,10 @@ Zeus sas Орел Зевса Aquila Zeus + Zeus イーグル + Zeus 독수리 + 宙斯鹰眼模式 + 宙斯鷹眼模式 Spawn an eagle that follows the Zeus camera. @@ -72,6 +100,10 @@ Lerak egy sast, ami követi a Zeus kamerát. Спавнит орла, который следует за камерой Зевса. Crea un'aquila che segue la camera Zeus. + Zeus カメラを追うイーグルを出現します。 + Zeus의 카메라를 따라다니는 독수리를 생성합니다. + 生成一个老鹰跟着宙斯的摄影机 + 生成一個老鷹跟著宙斯的攝影機 Wind Sounds @@ -84,6 +116,10 @@ Szélhangok Звук ветра Suoni del Vento + 風の音 + 바람 소리 + 风声 + 風聲 Play wind sounds when Zeus remote controls a unit. @@ -92,14 +128,18 @@ Přehrát varování (vítr) když Zeus převezmě kontrolu nad jednotkou. Spiele Windgeräusche ab, wenn Zeus eine Einheit steuert. Reproduz sons de vento quando uma unidade é remotamente controlada pelo Zeus. - Joue des bruits de vent quand Zeus controle une unité + Joue des bruits de vent quand Zeus controle une unité. Szélhangokat játszik le, ha a Zeus távvezérel egy egységet. Проигрывает звук ветра каждый раз, когда Зевс вселяется в юнита. Esegui rumori di vento quando Zeus controlla un'unità in remoto. + ユニットが Zeus 遠隔操作になったとき、風の音がします。 + Zeus가 유닛을 조작할 때 바람소리가 납니다. + 当宙斯开始控制单位时利用风的声音提示 + 當宙斯開始控制單位時利用風的聲音提示 Ordnance Warning - Ostrz. o ostrzale arty. + Ostrzeżenie o ostrzale artyleryjskim Advertencia de artefactos explosivos Varování před dělostřelectvem Artilleriewarnung @@ -108,6 +148,10 @@ Tüzérségi figyelmeztetés Предупреждение об арте Allarme Esplosivi + 砲撃の警告 + 폭격 경고 + 武装警告 + 武裝警告 Play a radio warning when Zeus uses ordnance. @@ -116,10 +160,14 @@ Přehrát varování (rádio) když Zeus použije dělostřelectvo. Spiele eine Radiowarnung ab, wenn Zeus Artillerie verwendet. Reproduz uma aviso via rádio quando o Zeus usa um explosivo. - Joue un son radio quand le Zeus utilise du matériel militaire + Joue un son radio quand le Zeus utilise du matériel militaire. Rádiós figyelmeztetés kiadása, ha a Zeus tüzérséget használ. Проигрывает звук радио каждый раз, когда Зевс использует артиллерию. - Esegui un messaggio radio quando Zeus usa esplosivi. + Riproduci un messaggio radio quando Zeus usa esplosivi. + Zeus が砲撃をつかうときに、無線で警告を流します。 + Zeus가 폭격시 경고 무전을 재생합니다. + 当宙斯开始攻击时使用无线电警告 + 當宙斯開始攻擊時使用無線電警告 Reveal Mines @@ -132,6 +180,10 @@ Aknák feltárása Показывать мины Rivela Mine + 地雷の表示 + 지뢰 표시 + 显示地雷 + 顯示地雷 Reveal mines to allies and place map markers. @@ -140,10 +192,14 @@ Odhalí miny pro spojence a umístnit jejich značku na mapu. Melde Minen gegenüber Verbündeten und platziere entsprechende Kartenmarkierungen. Revelar minas para aliados e colocar marcadores no mapa. - Révéler les mines et placer un marqueur sur la carte + Révéler les mines et placer un marqueur sur la carte. Feltárja az aknákat a szövetségeseknek, és jelölőket helyez el a térképen. Показывает мины союзникам и отмечает их маркерами на карте. Rivela mine ad alleati e piazza marcatori in mappa. + 友軍に地雷と地図へ設置マーカーを表示します。 + 아군에게 지도 상의 모든 지뢰를 표시합니다. + 地图将标记队友放置的地雷 + 地圖將標記隊友放置的地雷 Reveal to Allies @@ -156,6 +212,10 @@ Feltárás a szövetségeseknek Показывать союзникам Rivela ad Alleati + 友軍へ表示 + 모든 아군에게 표시 + 透露给盟军 + 透露給盟軍 Allies + Map Markers @@ -168,6 +228,10 @@ Szövetségesek + térkép jelölők Союзники + Маркеры на карте Alleati + Marcatori Mappa + 友軍と地図マーカー + 아군 + 지도 마커 + 显示盟军+地图标记 + 顯示盟軍+地圖標記 Toggle Captive @@ -179,103 +243,286 @@ Basculer en captif Elfogott állapot váltása Пленный (вкл./выкл.) - Apri Catturato + Attivatore Prigioniero + 捕虜として切り替え + 포로 토글 + 切换俘虏 + 切換俘虜 Defend Area Défendre la zone Защитить зону Bránit oblast + 防衛範囲 + Broń obszaru + Verteidige Gebiet + 지역 방어 + Difendi Area + 防御区域 + 防禦區域 + + + Update Editable Objects + Aktualisiere bearbeitbare Objekte + 編集可能なオブジェクトを更新 + Aktualizuj edytowalne obiekty + 수정 가능한 물체 갱신 + Màj les objets éditables + Aggiorna Oggetti Modificabili + 更新可编辑的物件 + 更新可編輯的物件 + + + Editing Mode + 編輯模式 + Modalità per editare + + + Add or remove editable objects from Zeus + 新增或移除可編輯物件給宙斯 + Agguingi o rimuovi oggetti che Zeus può modificare + + + Add Objects + 新增物件 + Aggiungi Oggetti + + + Remove Objects + Entferne Objekte + オブジェクトの削除 + 물체 삭제 + Usuń obiekty + Enlève les objets + Rimuovi Oggetti + 移除物件 + 移除物件 + + + All Curators + Alle Zeus' + 全キュレーター + 모든 큐레이터 + Wszyscy kuratorzy + Tous curateurs + Tutti i Moderatori + 所有编辑者 + 所有編輯者 + + + Apply changes to all curators + Änderungen bei allen Zeus' aktualisieren + 全キュレーターへ変更を適用 + 모든 큐레이터에 변화를 적용합니다 + Zatwierdź zmiany dla wszystkich kuratorów + Applique les changements à tous les curateurs + Applica i cambiamenti a tutti i moderatori + 确认变更给所有编辑者 + 確認變更給所有編輯者 + + + Additional Objects + Oggetti aggiuntivi + + + Additional objects to include in the action regardless of Task Radius + Oggetti aggiuntivi da includere nell'azione indipendentemente dal Raggio di Attività Global AI Skill Compétence global de l'IA Мастерство ботов Globální zkušenosti AI + 総合的な AI スキル + Globalne umiejętności AI + Globale KI-Fähigkeit + 서버 인공지능 실력 + Abilità AI Globale + AI技巧设定 + AI技巧設定 General Skill Compétence générale Общий уровень Primární zkušenosti + 総合スキル + Ogólne umiejętności + Allgemeine Fähigkeit + 전반적 실력 + Abilità Generale + 总体技巧 + 總體技巧 Changes: general, commanding, courage Change: general, commanding, courage Изменяет: general, commanding, courage Upravuje: general, commanding, courage + 変更: general, commanding, courage + Zmienia: ogólne, dowodzenie, odwaga + Ändert: general, commanding, courage + 변화: 전반적, 지휘, 사기 + Cambia: generale, comando, + 改变: 战斗技巧,指挥技巧,勇气大小 + 改變: 戰鬥技巧,指揮技巧,勇氣大小 Accuracy Précision Меткость Přesnost + 精度 + Precyzja + Genauigkeit + 명중률 + Precisione + 精确度 + 精確度 Changes: aimingAccuracy - Change: aimingAccuracy + Change : aimingAccuracy Изменяет: aimingAccuracy Upravuje: aimingAccuracy + 変更: aimingAccuracy + Zmienia: precyzję celowania + Ändert: aimingAccuracy + 변화: 조준 명중률 + Cambia: aimingAccuracy + 改变: 瞄准精确度 + 改變: 瞄準精確度 Weapon Handling Maniement d'armes Владение оружием Zacházení se zbraní + 武器の扱い + Obsługa broni + Waffenhandhabung + 무기 조작 + Uso dell'Arma + 武器掌握 + 武器掌握 Changes: aimingShake, aimingSpeed, reloadSpeed - Change: aimingShake, aimingSpeed, reloadSpeed + Change : aimingShake, aimingSpeed, reloadSpeed Изменяет: aimingShake, aimingSpeed, reloadSpeed Upravuje: aimingShake, aimingSpeed, reloadSpeed + 変更: aimingShake, aimingSpeed, reloadSpeed + Zmienia: drżenie broni, szybkość celowania, szybkość przeładowania + Ändert: aimingShake, aimingSpeed, reloadSpeed + 변화: 조준시 흔들림, 조준 속도, 재장전 속도 + Cambia: aimingShake, aimingSpeed, reloadSpeed + 改变: 手晃幅度,瞄准速度, 重新装填速度 + 改變: 手晃幅度,瞄準速度, 重新裝填速度 Spotting - repérage + Repérage Обнаружение Vnímavost + 索敵 + Rozpoznanie + Aufklärung + 탐지 + Ricognizione + 索敌能力 + 索敵能力 Changes: spotDistance, spotTime - Change: spotDistance, spotTime + Change : spotDistance, spotTime Изменяет: spotDistance, spotTime Upravuje: spotDistance, spotTime + 変更: spotDistance, spotTime + Zmienia: zasięg rozpoznawania, czas rozpoznawania + Ändert: spotDistance, spotTime + 변화: 탐지 거리, 탐지까지의 시간 + Cambia: spotDistance, spotTime + 改变: 搜索距离, 发现时间 + 改變: 搜索距離, 發現時間 Seek Cover - Chercher couverture + Chercher des couvertures Поиск укрытий Vyhledávat krytí + 遮蔽 + Szukaj osłon + Deckungssuche + 엄폐물 찾기 + Cerca Copertura + 寻找掩护 + 尋找掩護 Should AI seek cover - L'IA devrait elle chercher couverture + L'IA devrait elle chercher des couvertures Должны ли боты искать укрытия AI se bude snažit vyhledávat krytí + AI は遮蔽を取るようになります + Czy AI powinno szukać osłon + Soll KI nach Deckung suchen + 인공지능이 엄폐물을 찾아갑니다 + Le AI dovrebbero cercare una copertura + 决定AI是否会寻找掩护 + 決定AI是否會尋找掩護 Auto Combat Combat automatique Авто режим боя Automatický režim boje + 自動戦闘 + Auto walka + Automatischer Kampfmodus + 자동 교전 + Combattimento Automatico + 自动交战 + 自動交戰 Should AI automatically switch to combat mode L'IA devrait elle passer automatiquement en mode combat Должны ли боты автоматически переходить в режим боя AI se automaticky přepne do bojového režimu + AI は自動的に戦闘状態へ切り替えます + Czy AI powinno automatycznie przechodzić w tryb walki + Soll KI automatisch in Kampfmodus umschalten + 인공지능이 자동적으로 교전 상태에 돌입합니다 + Le AI dovrebbero passare in modalità di combattimento automaticamente + 决定AI是否会自动与敌人交战 + 決定AI是否會自動與敵人交戰 Group Side Côté du groupe Сторона группы Strana skupiny + グループ側 + Strona grupy + Gruppenseite + 진영 측 + Fazione del Gruppo + 小队阵营 + 小隊陣營 Patrol Area Zone de patrouille Патрулировать зону Oblast hlídkování + 哨戒範囲 + Patrol obszaru + Patrouillengebiet + 정찰 구역 + Area di Pattugliamento + 巡逻区域 + 巡邏區域 Toggle Surrender @@ -287,37 +534,109 @@ Basculer en capitulation Kapituláló állapot váltása Сдавшийся (вкл./выкл.) - Apri Resa + Attivatore Resa + 投降として切り替え + 항복 토글 + 切换投降 + 切換投降 + + + Add/Remove FRIES + FRIES Hinzufügen/Entfernen + FRIES の追加と削除 + 패스트로프 추가/제거 + Dodaj/usuń FRIES + Aj./Enlève FRIES + Aggiungi/Rimuovi FRIES + 增加/移除快速垂降进场撤离系统 + 增加/移除快速垂降進場撤離系統 + + + %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無法使用快速繩降系統 + + + 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 Téléporter joueurs Телепортиваровать игроков Teleportovat hráče + プレイヤーを移動 + Teleportuj graczy + Spieler teleportieren + 플레이어 순간이동 + Teletrasporta Giocatori + 传送玩家 + 傳送玩家 Player Joueur Игрока Hráč + プレイヤー + Gracz + Spieler + 플레이어 + Giocatore + 玩家 + 玩家 Teleport selected player to module position 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 + 모듈의 위치로 플레이어 순간이동 + Teletrasporta il giocatore selezionato nella posizione del modulo + 传送选定的玩家至模块位置 + 傳送選定的玩家至模塊位置 Teleport Group Téléporter le groupe Телепортировать Группу Teleportovat skupinu + グループを移動 + Teleport grupy + Gruppe teleportieren + 그룹 순간이동 + Teletrasporta Gruppo + 传送小队 + 傳送小隊 Teleports all units in group Téléporte toutes les unités du groupe Телепортирует всех юнитов в группе Teleportuje všechny jednotky ve skupině + グループ内の全ユニットを移動させます + Teleportuje wszystkie jednostki w grupie + Teleportiert alle Einheiten der Gruppe + 그룹내에 모든 인원을 순간이동 시킵니다 + Teletrasporta tutte le unità del gruppo + 传送全部小队成员 + 傳送全部小隊成員 Toggle Unconscious @@ -329,19 +648,37 @@ Basculer en inconscient Eszméletlen állapot váltása Без сознания (вкл./выкл.) - Apri Incosciente + Attivatore Incoscienza + 気絶を切り替え + 기절 토글 + 切换昏迷 + 切換昏迷 Search Area Chercher la zone Обыскать зону Prohledat oblast + 捜索範囲 + Przeszukaj teren + Durchsuche Gebiet + 지역 수색 + Area di Ricerca + 搜索区域 + 搜索區域 Search Nearby Building Chercher le bâtiment proche Обыскать ближайшие здания Prohledat nejbližší budovu + 近くの建物を捜索します + Przeszukaj najbliższy budynek + Durchsuche nahegelegenes Gebäude + 근처 건물 수색 + Cerca Edifici nelle Vicinanze + 搜索附近的建筑物 + 搜索附近的建築物 Assign Medic @@ -353,6 +690,10 @@ Asignar médico Assegna Medico Assigner médecin + 衛生兵に割り当て + 의무병 임명 + 指定医疗兵 + 指定醫療兵 Assign Medical Vehicle @@ -364,6 +705,10 @@ Asignar vehículo médico Assegna Veicolo Medico Assigner véhicule médical + 医療車両として割り当て + 의무 차량 임명 + 指定医疗载具 + 指定醫療載具 Assign Medical Facility @@ -375,6 +720,21 @@ Asignar instalación médica Assegna Struttura Medica Assigner installation médicale + 医療施設として割り当て + 의무 시설 임명 + 指定医疗设施 + 指定醫療設施 + + + Toggle Simulation + Ändere Simulation + Przełącz symulację + シミュレーションを切り替え + 재현 토글 + Bascule Simulation + Attivatore Simulazione + 切换模拟 + 切換模擬 Add Spare Wheel @@ -386,6 +746,10 @@ Ersatzrad hinzufügen Agregar rueda de auxilio Ajouter pièce de rechange + 予備タイヤを追加 + 예비 바퀴 추가 + 增加备用轮胎 + 增加備用輪胎 Add Spare Track @@ -397,6 +761,10 @@ Ersatzkette hinzufügen Agregar oruga de repuesto Ajouter une chenille de secours + 車両へ予備タイヤを追加します。 + 예비 궤도 추가 + 增加备用履带 + 增加備用履帶 Unit must be alive @@ -409,6 +777,10 @@ Csak élő egységeken használni Si può fare solo su persone vive Usar somente em unidades vivas + ユニットを生存させます + 대상이 반드시 살아있어야 합니다 + 单位必须是活着 + 單位必須是活著 Unit must be infantry @@ -421,6 +793,10 @@ Csak járműben kívül lévő egységeken használni Si può usare solo su fanteria a piedi Usar somente em infantaria desmontada + ユニットを歩兵にさせます + 대상이 반드시 보병이어야 합니다 + 单位必须是步兵 + 單位必須是步兵 Unit must be a structure @@ -432,6 +808,10 @@ Jednotka musí být budova Si può usare solo su strutture L'unité doit être une structure + ユニットを構造物とします + 대상이 반드시 건축물이어야만 합니다 + 单位必须是建筑 + 單位必須是建築 Unit must be a vehicle @@ -443,6 +823,10 @@ Jednotka musí být vozidlo Si può usare solo su veicoli L'unité doit être un véhicule + ユニットを車両とします + 대상이 반드시 차량이어야만 합니다 + 单位必须是载具 + 單位必須是載具 Unit must be a vehicle with cargo space @@ -454,6 +838,10 @@ Einheit muss ein Fahrzeug mit Ladekapazität sein La unidad debe ser un vehículo con espacio de carga L'unité doit être un véhicule avec de l'espace de cargaison + ユニットをカーゴ スペースがある車両にします + 대상이 반드시 화물을 실을 수 있는 차량이어야 합니다 + 单位必须是载具且有载货空间 + 單位必須是載具且有載貨空間 Unit must have cargo space left @@ -465,6 +853,10 @@ Einheit muss freie Ladekapazität haben La unidad debe tener espacio de carga disponible L'unité doit avoir de l'espace libre en cargaison + ユニットへカーゴ スペースを与えます + 대상의 화물공간이 남아있어야합니다 + 单位必须有剩余的载货空间 + 單位必須有剩餘的載貨空間 Unit must not be captive @@ -477,18 +869,36 @@ Csak elfogatlan egységeken használni Юнит не должен быть пленным L'unità non dev'essere un prigioniero + ユニットを捕虜にさせません + 대상이 포로면 안됩니다 + 单位不能被俘虏 + 單位不能被俘虜 Unit must belong to an appropriate side L'unité doit appartenir à un côté approprié Юнит должен принадлежать соответствующей стороне Jednotka musí patřit k příslušné straně + ユニットを適切な陣営にします + Jednostka musi należeć do odpowiedniej strony + Einheit muss einer passenden Seite angehören + 대상이 적절한 진영에 속해야만합니다 + L'unità deve appartenere ad una fazione coerente + 单位必须属于一个合适的一边 + 單位必須屬於一個合適的一邊 Nearest building is too far away Le bâtiment le plus proche est trop loin Ближайшие здания слишком далеко Nejbližší budova je příliš daleko + 近くに建物がありません。 + Najbliższy budynek jest zbyt daleko + Nächstgelegenes Gebäude ist zu weit entfernt + 가장가까운 건물이 너무 멈 + L'edificio più vicino è troppo lontano + 最近的房子离太远了 + 最近的房子離太遠了 Place on a unit @@ -501,6 +911,10 @@ Ничего не выделено Semmi sincs az egér alatt Piazza su una unità + ユニットの上に設置 + 대상에 배치하기 + 放置在一个单位上 + 放置在一個單位上 Requires an addon that is not present @@ -513,6 +927,22 @@ Egy jelenleg hiányzó bővítményt igényel Требуется аддон, который отсутствует Richiede un addon che non è presente + 要求されたアドオンは存在していません + 需要一个不存在的插件 + 需要一個不存在的插件 + 현재 없는 애드온을 필요로 합니다 + + + None + Niente + + + Players + Giocatori + + + Players and AI + Giocati e AI Add Objects to Curator @@ -524,6 +954,10 @@ Aggiungi Oggetti al Curatore Ajouter des objets au curateur (Zeus) Fügt Objekte zum Kurator hinzu + キュレーターにオブジェクトを追加 + 큐레이터에 물체 추가 + 增加物件给任务策划人 + 增加物件給任務策劃人 Adds any spawned object to all curators in the mission @@ -535,39 +969,495 @@ Aggiungi ogni oggetto creato a tutti i Curatori in missione Ajoute n'importe quel objet spawné à tous les curateurs de la mission Fügt jedes gespawnte Objekt allen Kuratoren der Mission hinzu + ミッション内で作成されたオブジェクトに全キュレーターを追加 + 미션 내 큐레이터에 모든 생성 물체 추가 + 在任务中生成物件给所有的任务策划人 + 在任務中生成物件給所有的任務策劃人 Cargo: - Cargo: + Cargo : Груз: Náklad: + カーゴ: + Ładunek: + Ladung: + 화물: + Cargo: + 货物: + 貨物: - - Task Position - Position de la tâche - Местоположение задания - Pozice úkolu - - - Select a position to perform the task at - Sélectionne une position où accomplir la tâche - Выбрать местоположение для выполнения задания + + Select cargo to unload + 選擇要卸載的貨物 + Scegli il carico da scaricare + 選択したカーゴを降ろす Task Radius Rayon de la tâche Радиус задания + タスク範囲 + Obszar zadania + Radius der Aufgabe + 작업 반경 + Raggio Incarico + 目标半径 + 目標半徑 - + Radius to perform the task within Rayon dans lequel la tâche prend place Радиус выполнения задания + 次の範囲をタスクとして実行 + Obszar na którym zadanie powinno zostać wykonane + Radius, in dem die Aufgabe ausgeführt werden soll + 다음 반경 내에서 작업 + Raggio per eseguire un incarico + 设定目标范围半径 + 設定目標範圍半徑 Invalid radius entered - rayon invalide entré + Rayon invalide entré Введен неправильный радиус Vložen neplatný parametr + 無効な半径が入力されました + Wpisano nieprawidłowy promień + Ungültiger Radius eingegeben + 알 수 없는 반경 입력됨 + Raggio Invalido Inserito + 错误的半径值 + 錯誤的半徑值 + + + Suppressive Fire + Unterdrückungsfeuer + Fuoco di Soppressione + Tir de suppression + 制圧射撃 + 火力压制 + 火力壓制 + Ogień zaporowy + 엄호사격 + + + Add Full Arsenal + Füge ganzes Arsenal hinzu + Ajouter Arsenal Complet + Aggiungi Arsenale Completo + オブジェクトに完全なアーセナルを追加 + 增加完整的虚拟军火库到物件上 + 增加完整的虛擬軍火庫到物件上 + Dodaj Wirtualny Arsenał + 아스날 놓기 + + + 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 Target + 目標を切り替え + 切换目标 + 切換目標 + Scambia obiettivo + + + Units affected by the toggle + ユニットは切り替えに影響を受けます + 被选单位受切换影响 + 受切換所影響的單位 + Unità influenzate dallo scambio + + + Selected Group + Ausgewählte Gruppe + Groupe sélectionné + Gruppo selezionato + 選択されたグループ + 選擇小隊 + 选择小队 + 그룹 선택 + + + Toggle Flashlights + Ändere Taschenlampen + Basculer lampes torches + Attiva torce + フラッシュライトの切り替え + 切換手電筒 + 切换手电筒 + 손전등 토글 + + + Flashlights + 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 + 解除駐軍駐守狀態 + 解除驻军驻守状态 + 주둔해제 + + + No players found + 沒有玩家找到 + 没有玩家找到 + Nije pronađen nijedan igrač + Aucun joueur trouvé + Keine Spieler gefunden + Nincsenek játékosok + Nessun giocatore trovato + プレーヤーが見つかりません + 플레이어가 없습니다. + Nie znaleziono graczy + Nenhum jogador encontrado + Игроки не найдены + No se encontraron jugadores + + + Assign Repair Vehicle + 分配維修車輛 + 分配维修车辆 + Přiřaďte opravárenské vozidlo + Affecter un véhicule de réparation + Fahrzeug reparieren zuweisen + Hozzárendelés javítóműhöz + Assegna veicolo di riparazione + 修理車両を割り当てる + 수리 차량 지정 + Przydziel pojazd do naprawy + Atribuir veículo de reparação + Назначить ремонтный автомобиль + Asignar vehículo de reparación + + + Assign Repair Facility + 分配修理設施 + 分配修理设施 + Přiřaďte opravu + Affecter une installation de réparation + Zuweisen von Reparatureinrichtung + Hozzárendelés javításhoz + Assegna struttura di riparazione + 修理施設を割り当てる + 수리 시설 지정 + Przydziel naprawę + Atribuir facilidade de reparação + Назначить ремонтный комплекс + Asignar instalación de reparación + + + Assign Engineer + 指派工程師 + 指派工程师 + Přiřadit inženýra + Affecter ingénieur + Engineer zuweisen + Engedélyezze a mérnököt + Assign Engineer + 担当エンジニア + 엔지니어 지정 + Przydziel inżyniera + Encarregar o engenheiro + Назначить инженера + Asignar Ingeniero + + + Engineer Skill + 工程師技能 + 工程师技能 + Inženýrská dovednost + Compétence d'ingénieur + Ingenieur Fähigkeit + Mérnöki készség + Abilità ingegnere + エンジニアのスキル + 기술자의 기술 + Umiejętność inżyniera + Habilidade do engenheiro + Инженерное мастерство + Habilidad de Ingeniero + + + Full Heal + 完全治愈 + 完全治愈 + Plné uzdravení + Guérison complète + Vollständige Heilung + Teljes gyógyítás + Guarigione completa + 完全に回復 + 완전 치유 + Pełne uleczenie + Cura completa + Полное исцеление + Totalmente curado + + + Suicide Bomber + 自殺式炸彈襲擊者 + 自杀式炸弹袭击者 + Samovražedný bombardér + Kamikaze + Selbstmordattentäter + Öngyilkos merénylő + Kamikaze + 自爆テロ犯 + 자살 폭탄 + Samobójca + Bombardeiro suicida + Террорист-смертник + Bombardeo suicida + + + Activation Side + 激活方 + 激活方 + Aktivační strana + Activation latérale + Aktivierungsseite + Aktiválási oldal + Lato di attivazione + 対象陣営 + 활성화면 + Strona aktywacji + Lado de ativação + Сторона активации + Lado de activación + + + Activation Radius + 激活半徑 + 激活半径 + Aktivační poloměr + Rayon d'activation + Aktivierungsradius + Aktiválási sugár + Raggio di attivazione + 活性化半径 + 활성화 반경 + Promień aktywacji + Rádio de ativação + Радиус активации + Radio de activación + + + Explosion Size + 爆炸尺寸 + 爆炸尺寸 + Velikost výbuchu + Taille d'explosion + Explosionsgröße + Robbanásméret + Dimensione di esplosione + 爆発サイズ + 폭발 크기 + Rozmiar wybuchu + Tamanho da Explosão + Размер взрыва + Tamaño de Explosión + + + Auto Seek + 自動尋求 + 自动寻求 + Auto Seek + Recherche automatique + Automatische Suche + Automatikus keresés + Ricerca automatica + 自動誘導 + 자동 탐색 + Auto Seek + Busca automática + Автоматический поиск + Búsqueda automática + + + Unit will actively try to find and move towards nearby units of the activation side. The range of Auto Seek is based on the unit's spot distance skill with a minimum of 100 meters. + 單位將主動嘗試尋找並移動到附近的激活方單位。自動搜索的範圍是基於單位的距離技能,最少100米 + 单位将主动尝试寻找并移动到附近的激活方单位。自动搜索的范围是基于单位的距离技能,最少100米。 + Jednotka se bude aktivně snažit najít a přejít na blízké jednotky na straně aktivace. Rozsah Auto Seek je založen na dovednosti spotové vzdálenosti jednotky s minimem 100 metrů. + L'unité essayera activement de trouver et de se déplacer vers les unités à proximité du côté d'activation. La portée d'Auto Seek est basée sur la compétence de distance de l'unité avec un minimum de 100 mètres. + Die Einheit versucht aktiv, in der Nähe befindliche Einheiten der Aktivierungsseite zu finden und sich dorthin zu bewegen. Der Bereich der automatischen Suche basiert auf der Fähigkeit der Zielentfernung der Einheit mit einer Mindestentfernung von 100 Metern. + Az egység aktívan megpróbálja megtalálni és elmozdulni az aktivációs oldal közeli egységei felé.Az automatikus keresési tartomány az egység helyszíni szakértelmén alapul, legalább 100 méterrel. + L'unità cercherà attivamente di trovare e spostarsi verso le unità vicine del lato di attivazione. La gamma di Auto Seek si basa sull'abilità a distanza spot dell'unità con un minimo di 100 metri. + 対象陣営ユニットを見つけて移動しようと積極的に試みます。自動誘導の範囲は、ユニットの索敵能力に基づいており、最低100メートルです。 + 유닛은 액티브 측의 근접 유닛을 향해 적극적으로 찾아서 이동하려고 시도합니다. 자동 시크의 범위는 유닛의 스팟 거리 스킬을 기준으로 최소 100 미터입니다. + Jednostka będzie aktywnie próbowała znaleźć i ruszyć w kierunku pobliskich jednostek strony aktywacji. Zasięg Auto Seek opiera się na umiejętności punktowej odległości jednostki z minimum 100 metrów. + A unidade tentará ativamente encontrar e se mover para as unidades próximas do lado da ativação. O alcance da Auto Seek é baseado na habilidade de distância do ponto da unidade com um mínimo de 100 metros. + Устройство будет активно пытаться найти и перейти к соседним единицам активации. Диапазон автоматического поиска основан на умении снимать расстояние на расстоянии не менее 100 метров. + La unidad intentará buscar activamente y moverse hacia las unidades cercanas del lado de activación. El rango de Auto Seek se basa en la habilidad de distancia al punto de la unidad con un mínimo de 100 metros. + + + Unit is already a suicide bomber + 這個單位已經是自殺炸彈手了 + 这个单位已经是自杀炸弹手了 + Jednotka je již samovražedným bombardérem + L'unité est déjà un kamikaze + Die Einheit ist bereits ein Selbstmordattentäter + Az egység már öngyilkos bombázó + L'unità è già un kamikaze + すでに自爆ユニットです + 유닛은 이미 자살 폭탄 테러범이다. + Jednostka jest już zamachowcem-samobójcą + A unidade já é um suicida + Единица уже является террористом-смертником + La unidad ya es un terrorista suicida + + + Add full ACE Arsenal + ACE 武器庫を追加 + 添加ACE模式军火库 + 增加完整的ACE軍火庫 + Aggiungi l'arsenale ACE completo + + + Remove ACE Arsenal + ACE 武器庫を削除 + 删除ACE模式军火库 + 移除ACE軍火庫 + Rimuovi l'arsenale ACE - \ No newline at end of file + diff --git a/addons/zeus/ui/Icon_Module_Zeus_Editable_Objects_ca.paa b/addons/zeus/ui/Icon_Module_Zeus_Editable_Objects_ca.paa new file mode 100644 index 0000000000..89828a42c5 Binary files /dev/null and b/addons/zeus/ui/Icon_Module_Zeus_Editable_Objects_ca.paa differ diff --git a/addons/zeus/ui/Icon_Module_Zeus_Flashlight_ca.paa b/addons/zeus/ui/Icon_Module_Zeus_Flashlight_ca.paa new file mode 100644 index 0000000000..276411b7aa Binary files /dev/null and b/addons/zeus/ui/Icon_Module_Zeus_Flashlight_ca.paa differ 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_Heal_ca.paa b/addons/zeus/ui/Icon_Module_Zeus_Heal_ca.paa new file mode 100644 index 0000000000..03f808203c Binary files /dev/null and b/addons/zeus/ui/Icon_Module_Zeus_Heal_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 1efcde2c66..1174267466 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -8,6 +8,9 @@ class RscXSliderH; class RscCheckBox; class RscActivePicture; class RscMapControl; +class RscPicture; +class ctrlToolbox; +class RscButton; class RscDisplayAttributes { class Controls { @@ -27,67 +30,38 @@ class GVAR(AttributeRadius): RscControlsGroupNoScrollbars { x = 0; y = 0; w = W_PART(26); - h = H_PART(1.2); + h = H_PART(1.1); class controls { - class Title1: RscText { + class Label: RscText { idc = -1; text = CSTRING(AttributeRadius); - toolTip = CSTRING(AttributeRadius_desc); + tooltip = CSTRING(AttributeRadius_Tooltip); x = 0; y = H_PART(0.1); w = W_PART(10); h = H_PART(1); - colorBackground[] = {0,0,0,0.5}; + colorBackground[] = {0, 0, 0, 0.5}; }; class Radius: RscEdit { idc = 26467; x = W_PART(10.1); y = H_PART(0.1); - w = W_PART(15.8); + w = W_PART(15.9); h = H_PART(1); autocomplete = ""; }; }; }; -class GVAR(AttributePosition): RscControlsGroupNoScrollbars { - onSetFocus = QUOTE(_this call FUNC(ui_attributePosition)); - idc = 26468; - x = 0; - y = 0; - w = W_PART(26); - h = H_PART(26); - class controls { - class Title1: RscText { - idc = -1; - text = CSTRING(AttributePosition); - toolTip = CSTRING(AttributePosition_desc); - x = 0; - y = 0; - w = W_PART(26); - h = H_PART(1); - colorBackground[] = {0,0,0,0.5}; - }; - class Position: RscMapControl { - idc = 26469; - x = W_PART(0.5); - y = H_PART(1.1); - w = W_PART(25); - h = H_PART(24.8); - }; - }; -}; - class GVAR(RscDefendArea): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscDefendArea)))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscDefendArea)))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscDefendArea))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscDefendArea))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; class Content: Content { class Controls { class radius: GVAR(AttributeRadius) {}; - //class position: GVAR(AttributePosition) {}; }; }; class ButtonOK: ButtonOK { @@ -97,9 +71,76 @@ class GVAR(RscDefendArea): RscDisplayAttributes { }; }; +class GVAR(RscEditableObjects): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscEditableObjects))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscEditableObjects))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class radius: GVAR(AttributeRadius) {}; + class editableObjects: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_editableObjects)); + idc = 19180; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(3.2); + class controls { + class EditingModeLabel: RscText { + idc = -1; + text = CSTRING(ModuleEditableObjects_EditingMode); + tooltip = CSTRING(ModuleEditableObjects_EditingMode_Tooltip); + x = 0; + y = 0; + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class EditingMode: ctrlToolbox { + idc = 19181; + x = W_PART(10.1); + y = 0; + w = W_PART(15.9); + h = H_PART(1); + rows = 1; + columns = 2; + strings[] = {CSTRING(ModuleEditableObjects_RemoveObjects), CSTRING(ModuleEditableObjects_AddObjects)}; + }; + class AllCuratorsLabel: EditingModeLabel { + text = CSTRING(ModuleEditableObjects_AllCurators); + tooltip = CSTRING(ModuleEditableObjects_AllCurators_Tooltip); + y = H_PART(1.1); + }; + class AllCurators: EditingMode { + idc = 19182; + y = H_PART(1.1); + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class AdditionalObjectsLabel: EditingModeLabel { + text = CSTRING(ModuleEditableObjects_AdditionalObjects); + tooltip = CSTRING(ModuleEditableObjects_AdditionalObjects_Tooltip); + y = H_PART(2.2); + }; + class AdditionalObjects: EditingMode { + idc = 19183; + y = H_PART(2.2); + columns = 3; + strings[] = {CSTRING(None), CSTRING(Players), CSTRING(PlayersAndAI)}; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; + class GVAR(RscGlobalSetSkill): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscGlobalSetSkill)))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscGlobalSetSkill)))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscGlobalSetSkill))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscGlobalSetSkill))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -193,8 +234,8 @@ class GVAR(RscGlobalSetSkill): RscDisplayAttributes { }; class GVAR(RscGroupSide): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscGroupSide)))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscGroupSide)))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscGroupSide))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscGroupSide))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -227,7 +268,7 @@ class GVAR(RscGroupSide): RscDisplayAttributes { }; class BLUFOR: RscActivePicture { idc = 31200; - text = "\a3\Ui_f\data\Map\Markers\NATO\b_unknown.paa"; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; x = W_PART(12.5); y = H_PART(0.25); w = W_PART(2); @@ -236,7 +277,7 @@ class GVAR(RscGroupSide): RscDisplayAttributes { }; class OPFOR: BLUFOR { idc = 31201; - text = "\a3\Ui_f\data\Map\Markers\NATO\o_unknown.paa"; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; x = W_PART(15.5); y = H_PART(0.25); w = W_PART(2); @@ -245,7 +286,7 @@ class GVAR(RscGroupSide): RscDisplayAttributes { }; class Independent: BLUFOR { idc = 31202; - text = "\a3\Ui_f\data\Map\Markers\NATO\n_unknown.paa"; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; x = W_PART(18.5); y = H_PART(0.25); w = W_PART(2); @@ -254,7 +295,7 @@ class GVAR(RscGroupSide): RscDisplayAttributes { }; class Civilian: BLUFOR { idc = 31203; - text = "\a3\Ui_f\data\Map\Markers\NATO\n_unknown.paa"; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; x = W_PART(21.5); y = H_PART(0.25); w = W_PART(2); @@ -271,15 +312,14 @@ class GVAR(RscGroupSide): RscDisplayAttributes { }; class GVAR(RscPatrolArea): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscPatrolArea)))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscPatrolArea)))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscPatrolArea))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscPatrolArea))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; class Content: Content { class Controls { class radius: GVAR(AttributeRadius) {}; - //class position: GVAR(AttributePosition) {}; }; }; class ButtonOK: ButtonOK { @@ -290,15 +330,14 @@ class GVAR(RscPatrolArea): RscDisplayAttributes { }; class GVAR(RscSearchArea): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscSearchArea)))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscSearchArea)))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscSearchArea))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscSearchArea))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; class Content: Content { class Controls { class radius: GVAR(AttributeRadius) {}; - //class position: GVAR(AttributePosition) {}; }; }; class ButtonOK: ButtonOK { @@ -309,8 +348,8 @@ class GVAR(RscSearchArea): RscDisplayAttributes { }; class GVAR(RscTeleportPlayers): RscDisplayAttributes { - onLoad = QUOTE([ARR_3('onLoad', _this, QUOTE(QGVAR(RscTeleportPlayers)))] call FUNC(zeusAttributes)); - onUnload = QUOTE([ARR_3('onUnload', _this, QUOTE(QGVAR(RscTeleportPlayers)))] call FUNC(zeusAttributes)); + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscTeleportPlayers))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscTeleportPlayers))] call FUNC(zeusAttributes)); class Controls: Controls { class Background: Background {}; class Title: Title {}; @@ -322,7 +361,7 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { x = 0; y = 0; w = W_PART(26); - h = H_PART(8.5); + h = H_PART(8.1); class controls { class Title: RscText { idc = -1; @@ -332,7 +371,7 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { y = 0; w = W_PART(26); h = H_PART(1); - colorBackground[] = {0,0,0,0.5}; + colorBackground[] = {0, 0, 0, 0.5}; }; class Unit: RscListbox { idc = 16189; @@ -341,16 +380,41 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { w = W_PART(26); h = H_PART(5.9); }; - class Label: Title { + class SearchBackground: RscText { + idc = -1; + x = 0; + y = H_PART(7.1); + w = W_PART(1); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class SearchPicture: RscPicture { + idc = -1; + text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; + x = 0; + y = H_PART(7.1); + w = W_PART(1); + h = H_PART(1); + }; + class Search: RscEdit { + idc = 16190; + x = W_PART(1.2); + y = H_PART(7.1); + w = W_PART(14.5); + h = H_PART(1); + autocomplete = ""; + }; + class LabelGroup: Title { idc = -1; text = CSTRING(ModuleTeleportPlayers_group); toolTip = CSTRING(ModuleTeleportPlayers_group_desc); + x = W_PART(15.9); y = H_PART(7.1); - w = W_PART(10); + w = W_PART(9); }; class UseGroup: RscCheckBox { idc = 16188; - x = W_PART(10.1); + x = W_PART(25); y = H_PART(7.1); w = W_PART(1); h = H_PART(1); @@ -364,7 +428,6 @@ class GVAR(RscTeleportPlayers): RscDisplayAttributes { }; }; - class GVAR(AttributeCargo): RscControlsGroupNoScrollbars { onSetFocus = QUOTE(_this call FUNC(ui_attributeCargo)); idc = -1; @@ -379,7 +442,7 @@ class GVAR(AttributeCargo): RscControlsGroupNoScrollbars { x = 0; y = 0; w = W_PART(10); - h = H_PART(3); + h = H_PART(2); colorBackground[] = {0,0,0,0.5}; }; class Background: RscText { @@ -397,7 +460,15 @@ class GVAR(AttributeCargo): RscControlsGroupNoScrollbars { w = W_PART(16); h = H_PART(3); }; - + class Unload: RscButton { + idc = 80087; + text = ECSTRING(cargo,unloadObject); + x = 0; + y = H_PART(2); + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.7}; + }; }; }; @@ -420,3 +491,427 @@ class RscDisplayAttributesVehicleEmpty: RscDisplayAttributes { }; }; }; + +class GVAR(RscGarrison): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscGarrison))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscGarrison))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class radius: GVAR(AttributeRadius) {}; + class Garrison: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_garrison)); + idc = 73060; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(6.2); + class controls { + class TeleportLabel: RscText { + idc = -1; + text = CSTRING(ModuleGarrison_TeleportText); + x = 0; + y = 0; + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Teleport: ctrlToolbox { + idc = 73061; + x = W_PART(10.1); + y = 0; + w = W_PART(15.9); + h = H_PART(1); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class TopDownLabel: TeleportLabel { + text = CSTRING(ModuleGarrison_TopDownFillingText); + tooltip = CSTRING(ModuleGarrison_TopDownFillingTooltip); + y = H_PART(1.1); + }; + class TopDown: Teleport { + idc = 73062; + y = H_PART(1.1); + }; + class FillingModeLabel: TeleportLabel { + text = CSTRING(ModuleGarrison_FillingModeText); + y = H_PART(2.2); + w = W_PART(26); + }; + class FillingMode: RscListbox { + idc = 73063; + x = 0; + y = H_PART(3.2); + w = W_PART(26); + h = H_PART(3); + class Items { + class Even { + text = CSTRING(ModuleGarrison_FillingModeEven); + default = 1; + }; + class Building { + text = CSTRING(ModuleGarrison_FillingModeBuilding); + }; + class Random { + text = CSTRING(ModuleGarrison_FillingModeRandom); + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; + +class GVAR(RscToggleNvg): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscToggleNvg))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(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(2.1); + class controls { + class ToggleLabel: RscText { + idc = -1; + text = CSTRING(ModuleToggleNVG_NvgEquipment); + tooltip = CSTRING(ModuleToggleNVG_NvgEquipment_tooltip); + x = 0; + y = 0; + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Toggle: ctrlToolbox { + idc = 92855; + x = W_PART(10.1); + y = 0; + w = W_PART(15.9); + h = H_PART(1); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,Disabled), ECSTRING(common,Enabled)}; + }; + class TargetLabel: ToggleLabel { + text = CSTRING(ToggleTarget); + tooltip = CSTRING(ToggleTarget_Tooltip); + y = H_PART(1.1); + }; + class Target: RscCombo { + idc = 92856; + x = W_PART(10.1); + y = H_PART(1.1); + w = W_PART(15.9); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.7}; + class Items { + class Group { + text = CSTRING(SelectedGroup); + picture = "\a3\ui_f_curator\data\displays\rscdisplaycurator\modegroups_ca.paa"; + default = 1; + }; + class BLUFOR { + text = "$STR_WEST"; + picture = "\a3\ui_f\data\map\diary\icons\playerwest_ca.paa"; + }; + class OPFOR { + text = "$STR_EAST"; + picture = "\a3\ui_f\data\map\diary\icons\playereast_ca.paa"; + }; + class Independent { + text = "$STR_guerrila"; + picture = "\a3\ui_f\data\map\diary\icons\playerguer_ca.paa"; + }; + class Civilian { + text = "$STR_Civilian"; + picture = "\a3\ui_f\data\map\diary\icons\playerciv_ca.paa"; + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; + +class GVAR(RscToggleFlashlight): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscToggleFlashlight))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(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(3.2); + class controls { + class ToggleLabel: RscText { + idc = -1; + text = CSTRING(ModuleToggleFlashlight_Flashlights); + x = 0; + y = 0; + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Toggle: ctrlToolbox { + idc = 56218; + x = W_PART(10.1); + y = 0; + w = W_PART(15.9); + h = H_PART(1); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,Disabled), ECSTRING(common,Enabled)}; + }; + class AddGearLabel: ToggleLabel { + text = CSTRING(ModuleToggleFlashlight_AddGear); + y = H_PART(1.1); + }; + class AddGear: Toggle { + idc = 56219; + y = H_PART(1.1); + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class TargetLabel: ToggleLabel { + text = CSTRING(ToggleTarget); + tooltip = CSTRING(ToggleTarget_Tooltip); + y = H_PART(2.2); + }; + class Target: RscCombo { + idc = 56220; + x = W_PART(10.1); + y = H_PART(2.2); + w = W_PART(15.9); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.7}; + class Items { + class Group { + text = CSTRING(SelectedGroup); + picture = "\a3\ui_f_curator\data\displays\rscdisplaycurator\modegroups_ca.paa"; + default = 1; + }; + class BLUFOR { + text = "$STR_WEST"; + picture = "\a3\ui_f\data\map\diary\icons\playerwest_ca.paa"; + }; + class OPFOR { + text = "$STR_EAST"; + picture = "\a3\ui_f\data\map\diary\icons\playereast_ca.paa"; + }; + class Independent { + text = "$STR_guerrila"; + picture = "\a3\ui_f\data\map\diary\icons\playerguer_ca.paa"; + }; + class Civilian { + text = "$STR_Civilian"; + picture = "\a3\ui_f\data\map\diary\icons\playerciv_ca.paa"; + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; + +class GVAR(RscSetEngineer): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscSetEngineer))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscSetEngineer))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class setEngineer: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_setEngineer)); + idc = 86946; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(1.2); + class controls { + class Label: RscText { + idc = -1; + text = CSTRING(ModuleSetEngineer_skill); + toolTip = ECSTRING(repair,AssignEngineerRole_role_Description); + x = 0; + y = H_PART(0.1); + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Roles: ctrlToolbox { + idc = 86947; + x = W_PART(10.1); + y = H_PART(0.1); + w = W_PART(15.9); + h = H_PART(1); + rows = 1; + columns = 2; + strings[] = {ECSTRING(repair,AssignEngineerRole_role_engineer), ECSTRING(repair,AssignEngineerRole_role_advanced)}; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; + +class GVAR(RscSuicideBomber): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(RscSuicideBomber))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(RscSuicideBomber))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class suicideBomber: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_suicideBomber)); + idc = 83470; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(5.8); + class controls { + class ActivationSide: RscControlsGroupNoScrollbars { + idc = 83571; + x = 0; + y = 0; + w = W_PART(26); + h = H_PART(2.5); + class controls { + class Label: RscText { + idc = -1; + text = CSTRING(ModuleSuicideBomber_ActivationSide); + x = 0; + y = 0; + w = W_PART(10); + h = H_PART(2.5); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = W_PART(10); + y = 0; + w = W_PART(16); + h = H_PART(2.5); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class BLUFOR: RscActivePicture { + idc = 83581; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; + x = W_PART(12.5); + y = H_PART(0.25); + w = W_PART(2); + h = H_PART(2); + tooltip = "$STR_WEST"; + }; + class OPFOR: BLUFOR { + idc = 83580; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; + x = W_PART(15.5); + tooltip = "$STR_EAST"; + }; + class Independent: BLUFOR { + idc = 83582; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; + x = W_PART(18.5); + tooltip = "$STR_guerrila"; + }; + class Civilian: BLUFOR { + idc = 83583; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; + x = W_PART(21.5); + tooltip = "$STR_Civilian"; + }; + }; + }; + class DistanceLabel: RscText { + idc = -1; + text = CSTRING(ModuleSuicideBomber_ActivationRadius); + x = 0; + y = H_PART(2.6); + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class DistanceSlider: RscXSliderH { + idc = 83572; + x = W_PART(10.1); + y = H_PART(2.6); + w = W_PART(13.9); + h = H_PART(1); + }; + class DistanceEdit: RscEdit { + idc = 83573; + x = W_PART(24.1); + y = H_PART(2.6); + w = W_PART(1.9); + h = H_PART(1); + autocomplete = ""; + maxChars = 3; + canModify = 0; + }; + class ExplosionLabel: DistanceLabel { + idc = -1; + text = CSTRING(ModuleSuicideBomber_ExplosionSize); + y = H_PART(3.7); + }; + class Explosion: ctrlToolbox { + idc = 83574; + x = W_PART(10.1); + y = H_PART(3.7); + w = W_PART(15.9); + h = H_PART(1); + rows = 1; + columns = 3; + strings[] = {"$STR_small", "$STR_medium", "$STR_large"}; + }; + class AutoSeekLabel: DistanceLabel { + idc = -1; + text = CSTRING(ModuleSuicideBomber_AutoSeek); + y = H_PART(4.8); + toolTip = CSTRING(ModuleSuicideBomber_AutoSeek_tooltip); + }; + class AutoSeek: Explosion { + idc = 83575; + y = H_PART(4.8); + columns = 2; + strings[] = {ECSTRING(common,Disabled), ECSTRING(common,Enabled)}; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000000..2cdec68b4a --- /dev/null +++ b/circle.yml @@ -0,0 +1,22 @@ +version: 2 +jobs: + build: + docker: + - image: acemod/armake + steps: + - checkout + - run: + name: Validate SQF And Config style + command: python tools/sqf_validator.py && python tools/config_style_checker.py + - run: + name: Build + command: armake --version + - deploy: + name: Update documentation and translation statistics + command: | + if [ "${CIRCLE_BRANCH}" == "master" ] && [ "${CIRCLE_PROJECT_USERNAME}" == "acemod" ]; then + pip install pygithub pygithub3 + python3 tools/deploy.py + else + echo "Skipping, not on acemod/ACE3 master branch..." + fi diff --git a/docs/.dockerignore b/docs/.dockerignore new file mode 100644 index 0000000000..85de9cf933 --- /dev/null +++ b/docs/.dockerignore @@ -0,0 +1 @@ +src diff --git a/docs/.gitattributes b/docs/.gitattributes index 3c59efe684..de2616570b 100644 --- a/docs/.gitattributes +++ b/docs/.gitattributes @@ -2,3 +2,4 @@ *.png binary *.jpg binary *.paa binary +*.sh eol=lf diff --git a/docs/.gitignore b/docs/.gitignore index 3232b5a935..7836aaf3f3 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -18,3 +18,5 @@ addons CNAME tools/temp + +Gemfile.lock diff --git a/docs/Dockerfile b/docs/Dockerfile new file mode 100644 index 0000000000..d8ae94bc6a --- /dev/null +++ b/docs/Dockerfile @@ -0,0 +1,6 @@ +FROM phpcommunity/github-pages +LABEL maintainer "bux" + +COPY ./entrypoint.sh /usr/src/app + +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/Gemfile.lock b/docs/Gemfile.lock deleted file mode 100644 index faafb3cd3d..0000000000 --- a/docs/Gemfile.lock +++ /dev/null @@ -1,135 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - RedCloth (4.2.9) - RedCloth (4.2.9-x86-mingw32) - activesupport (4.2.5.2) - i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - addressable (2.3.8) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.10.0) - colorator (0.1) - ethon (0.8.1) - ffi (>= 1.3.0) - execjs (2.6.0) - faraday (0.9.2) - multipart-post (>= 1.2, < 3) - ffi (1.9.10) - ffi (1.9.10-x86-mingw32) - gemoji (2.1.0) - github-pages (52) - RedCloth (= 4.2.9) - github-pages-health-check (= 1.0.1) - jekyll (= 3.0.3) - jekyll-coffeescript (= 1.0.1) - jekyll-feed (= 0.4.0) - jekyll-gist (= 1.4.0) - jekyll-mentions (= 1.0.1) - jekyll-paginate (= 1.1.0) - jekyll-redirect-from (= 0.9.1) - jekyll-sass-converter (= 1.3.0) - jekyll-seo-tag (= 1.3.1) - jekyll-sitemap (= 0.10.0) - jekyll-textile-converter (= 0.1.0) - jemoji (= 0.5.1) - kramdown (= 1.9.0) - liquid (= 3.0.6) - mercenary (~> 0.3) - rdiscount (= 2.1.8) - redcarpet (= 3.3.3) - rouge (= 1.10.1) - terminal-table (~> 1.4) - github-pages-health-check (1.0.1) - addressable (~> 2.3) - net-dns (~> 0.8) - octokit (~> 4.0) - public_suffix (~> 1.4) - typhoeus (~> 0.7) - html-pipeline (2.3.0) - activesupport (>= 2, < 5) - nokogiri (>= 1.4) - i18n (0.7.0) - jekyll (3.0.3) - colorator (~> 0.1) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 1.1) - kramdown (~> 1.3) - liquid (~> 3.0) - mercenary (~> 0.3.3) - rouge (~> 1.7) - safe_yaml (~> 1.0) - jekyll-coffeescript (1.0.1) - coffee-script (~> 2.2) - jekyll-feed (0.4.0) - jekyll-gist (1.4.0) - octokit (~> 4.2) - jekyll-mentions (1.0.1) - html-pipeline (~> 2.3) - jekyll (~> 3.0) - jekyll-paginate (1.1.0) - jekyll-redirect-from (0.9.1) - jekyll (>= 2.0) - jekyll-sass-converter (1.3.0) - sass (~> 3.2) - jekyll-seo-tag (1.3.1) - jekyll (~> 3.0) - jekyll-sitemap (0.10.0) - jekyll-textile-converter (0.1.0) - RedCloth (~> 4.0) - jekyll-watch (1.3.1) - listen (~> 3.0) - jemoji (0.5.1) - gemoji (~> 2.0) - html-pipeline (~> 2.2) - jekyll (>= 2.0) - json (1.8.3) - kramdown (1.9.0) - liquid (3.0.6) - listen (3.0.6) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9.7) - mercenary (0.3.5) - mini_portile2 (2.0.0) - minitest (5.8.4) - multipart-post (2.0.0) - net-dns (0.8.0) - nokogiri (1.6.7.2) - mini_portile2 (~> 2.0.0.rc2) - nokogiri (1.6.7.2-x86-mingw32) - mini_portile2 (~> 2.0.0.rc2) - octokit (4.2.0) - sawyer (~> 0.6.0, >= 0.5.3) - public_suffix (1.5.3) - rb-fsevent (0.9.7) - rb-inotify (0.9.7) - ffi (>= 0.5.0) - rdiscount (2.1.8) - redcarpet (3.3.3) - rouge (1.10.1) - safe_yaml (1.0.4) - sass (3.4.21) - sawyer (0.6.0) - addressable (~> 2.3.5) - faraday (~> 0.8, < 0.10) - terminal-table (1.5.2) - thread_safe (0.3.5) - typhoeus (0.8.0) - ethon (>= 0.8.0) - tzinfo (1.2.2) - thread_safe (~> 0.1) - -PLATFORMS - ruby - x86-mingw32 - -DEPENDENCIES - github-pages - -BUNDLED WITH - 1.12.5 diff --git a/docs/README.md b/docs/README.md index 9c20ecb281..ee47a3cdd9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,52 @@ -# Source of http://ace3mod.com/ +# Source of https://ace3mod.com/ -## Setting up the development environment +## Updating compiled JavaScript and CSS files -### Installing prerequisites +- Install [Node.js](https://nodejs.org/download/) +- Open Command Prompt and navigate to `src` directory + ``` + cd /docs/src + ``` -#### Windows (CMD) +- Install Node packages + ``` + npm install + ``` + _On Bash on Ubuntu on Windows also install `nodejs-legacy` in case of errors._ + +- Update files + ``` + grunt + ``` + +## Setting up the Jekyll environment + +### Using Docker + +We include files for [Docker](https://www.docker.com/) to run Jekyll in a separate container. This allows you to not having to install anything apart from Docker on your computer. + +#### Running the Dockerfile + +- Install [Docker](https://www.docker.com/) +- cd into the `/docs/` directory +- Open Command Prompt and navigate to this directory + ``` + cd /docs + ``` + +- Build and run the container + ``` + docker-compose up + ``` + +- Navigate to [http://localhost:4000](http://localhost:4000) + + +### Manually + +#### Installing prerequisites + +##### Windows (CMD) - Install [Ruby 2.0.0-p648 (x64)](http://rubyinstaller.org/downloads/) - Install [Ruby DevKit for 2.0 (x64)](http://rubyinstaller.org/downloads/) @@ -23,6 +65,7 @@ bundle install ``` + #### Debian / Bash on Ubuntu on Windows - Open Bash and navigate to this directory @@ -32,14 +75,14 @@ - Install `make` and `gcc` ``` - sudo apt-get make gcc + sudo apt-get install make gcc ``` -- Install `ruby 2.0`, `rbuy2.0-dev` and `ruby-switch` +- Install `ruby2.0`, `ruby2.0-dev` and `ruby-switch` ``` sudo apt-add-repository ppa:brightbox/ruby-ng - sudo apt update - sudo apt install ruby2.0 ruby2.0-dev ruby-switch + sudo apt-get update + sudo apt-get install ruby2.0 ruby2.0-dev ruby-switch ``` - Set Ruby version @@ -62,7 +105,7 @@ find ~/.bundle/cache -type d -exec chmod 0755 {} + ``` -### Running +#### Running - Run Jekyll through bundler ``` @@ -72,21 +115,3 @@ - Navigate to http://localhost:4000 -### Updating compiled JavaScript and CSS files - -- Install [Node.js](https://nodejs.org/download/) -- Open Command Prompt and navigate to `src` directory - ``` - cd /docs/src - ``` - -- Install Node packages - ``` - npm install - ``` - _On Bash on Ubuntu on Windows also install `nodejs-legacy` in case of errors._ - -- Update files - ``` - grunt - ``` diff --git a/docs/README_DE.md b/docs/README_DE.md index 9e1bcec8ab..4847ee7c01 100644 --- a/docs/README_DE.md +++ b/docs/README_DE.md @@ -4,7 +4,7 @@

- ACE3 Version + ACE3 Version ACE3 Fehlermeldungen @@ -15,11 +15,11 @@ ACE3 Lizenz - - ACE3 Slack + + ACE3 Slack - - ACE3 Build Status + + ACE3 Build Status

@@ -70,14 +70,14 @@ Die Mod ist **modular aufgebaut**. Beinahe jede PBO kann entfernt werden, sodass #### Anleitungen Du hast ACE3 installiert, hast aber keine Ahnung was und wie alles funktioniert und wo sich was befindet? -- [Erste Schritte](http://ace3mod.com/wiki/user/getting-started.html). +- [Erste Schritte](https://ace3mod.com/wiki/user/getting-started.html). #### Mitwirken Wenn du bei der Entwicklung von ACE3 mithelfen möchtest, kannst du dies tun, indem du nach Fehlern Ausschau hältst oder neue Funktionen vorschlägst. Um etwas beizutragen, "Forke" dieses Repository und erstelle deine "Pull-Requests", welche von anderen Entwicklern und Beiträgern überprüft werden. Bitte trage dich dabei in [`AUTHORS.txt`](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) mit deinem Nutzernamen und einer gültigen Email-Adresse ein. Um uns einen Fehler, Anregungen oder neue Funktionalitäten mitzuteilen: Nutze unseren [Issue Tracker](https://github.com/acemod/ACE3/issues). Besuche auch: -- [Wie kann ich ein Problem melden](http://ace3mod.com/wiki/user/how-to-report-an-issue.html) -- [Wie kann ich ein Wunsch zu einer neuen Funktion mitteilen?](http://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) +- [Wie kann ich ein Problem melden](https://ace3mod.com/wiki/user/how-to-report-an-issue.html) +- [Wie kann ich ein Wunsch zu einer neuen Funktion mitteilen?](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) #### Testen & Mod erstellen Wenn du die neusten Entwicklungen erleben und uns dabei helfen möchtest bestehende Fehler zu entdecken, lade dir die "Master Branch" herunter. Entweder nutzt du [Git](https://help.github.com/articles/fetching-a-remote/) - wenn die Schritte bekannt sind - oder du lädst es dir direkt über [diesen Link](https://github.com/acemod/ACE3/archive/master.zip) herunter. diff --git a/docs/README_PL.md b/docs/README_PL.md index 703613142e..e75ba8691f 100644 --- a/docs/README_PL.md +++ b/docs/README_PL.md @@ -3,7 +3,7 @@

- ACE3 Wersja + ACE3 Wersja ACE3 Zagadnienia @@ -14,11 +14,11 @@ ACE3 Licencja - - ACE3 Slack + + ACE3 Slack - - ACE3 Build Status + + ACE3 Build Status

Wymaga najnowszej wersji CBA A3. Odwiedź nas na Facebook | YouTube | Twitter | Reddit

@@ -65,15 +65,15 @@ Modyfikacja ta jest **budowana modułowo**, dzięki temu prawie każdy dostarczo ### Poradniki i instrukcje Jeżeli zainstalowałeś ACE3 lecz masz problem ze zrozumieniem jak to wszystko działa, lub gdzie zacząć, zacznij od przeczytania tego: -- [Wprowadzenie](http://ace3mod.com/wiki/user/getting-started.html) +- [Wprowadzenie](https://ace3mod.com/wiki/user/getting-started.html) #### Współpraca Możesz pomóc w rozwoju addonu szukając potencjalnych bugów w naszym kodzie, lub zgłaszając nowe funkcje. Aby wnieść swój wkład do ACE3, po prostu zforkuj to repozytorium na swoje konto GitHub i zgłoś swoje pull requesty do przeglądu przez innych współpracowników. Pamiętaj, aby dodać siebie do listy autorów każdego PBO jakie edytujesz oraz do pliku ['AUTHORS.txt'](https://github.com/acemod/ACE3/blob/master/AUTHORS.txt) dodając także swój adres e-mail. Używaj naszego [Issue Tracker-a](https://github.com/acemod/ACE3/issues) aby zgłaszać bugi, proponować nowe funkcje lub sugerować zmiany do aktualnie istniejących. Zobacz także: -- [Jak zgłosić bug-a](http://ace3mod.com/wiki/user/how-to-report-an-issue.html) -- [Jak zgłosić feature request-a](http://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) +- [Jak zgłosić bug-a](https://ace3mod.com/wiki/user/how-to-report-an-issue.html) +- [Jak zgłosić feature request-a](https://ace3mod.com/wiki/user/how-to-make-a-feature-request.html) #### Testowanie i budowanie Aby pomóc nam w testowaniu najnowszych zmian rozwojowych, pobierz nasz master branch ([bezpośrednio](https://github.com/acemod/ACE3/archive/master.zip), lub [korzystając z git](https://help.github.com/articles/fetching-a-remote/)), a następnie złóż testowego build-a: -- [Konfiguracja środowiska do testów](http://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – intrukcja krok-po-kroku jak poprawnie ustawić i zbudować wersję ACE3 do celów testowych. +- [Konfiguracja środowiska do testów](https://ace3mod.com/wiki/development/setting-up-the-development-environment.html) – intrukcja krok-po-kroku jak poprawnie ustawić i zbudować wersję ACE3 do celów testowych. diff --git a/docs/_config.yml b/docs/_config.yml index a1ee07ad0b..2ae92cadb6 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,26 +1,24 @@ -#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 -productionUrl: http://ace3mod.com +productionUrl: https://ace3mod.com ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 6 - patch: 2 - build: 0 + minor: 12 + patch: 3 + build: 36 acex: githubUrl: https://github.com/acemod/ACEX version: major: 3 - minor: 0 - patch: 0 - build: 0 + minor: 3 + patch: 1 + build: 8 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/_config_dev.yml b/docs/_config_dev.yml index 65ce74e48c..09dddceed8 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: 6 - patch: 2 - build: 0 + minor: 12 + patch: 3 + build: 36 acex: githubUrl: https://github.com/acemod/ACEX version: major: 3 - minor: 0 - patch: 0 - build: 0 + minor: 3 + patch: 1 + build: 8 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/_footer.html b/docs/_includes/_footer.html index d391330c6e..8763b6c35a 100644 --- a/docs/_includes/_footer.html +++ b/docs/_includes/_footer.html @@ -3,22 +3,22 @@

ACE3

ACE3 is a joint effort by the teams behind ACE2, AGM and CSE to improve the realism and authenticity of Arma 3.

-

If you want to contribute something to ACE3, simply fork the GitHub repository and submit your pull requests for review.

+

If you want to contribute something to ACE3, simply fork the GitHub repository and submit your pull requests for review.

Issues / Feedback

-

Issues, feature requests and feedback are welcome at the ACE3 GitHub issue tracker.

-

Before reporting an issue, please read the wiki entry "How to report an issue".

-

We have created a single issue for feature requests.

+

Issues, feature requests and feedback are welcome at the ACE3 GitHub issue tracker.

+

Before reporting an issue, please read the wiki entry "How to report an issue".

+

We have created a single issue for feature requests.

Social Media

- +
diff --git a/docs/_includes/_header.html b/docs/_includes/_header.html index 8737b505ae..84bcab8d2e 100644 --- a/docs/_includes/_header.html +++ b/docs/_includes/_header.html @@ -8,7 +8,7 @@ - + @@ -19,8 +19,11 @@ - + + + + diff --git a/docs/_includes/dependencies_list.md b/docs/_includes/dependencies_list.md index 115ebe34c8..40abe57472 100644 --- a/docs/_includes/dependencies_list.md +++ b/docs/_includes/dependencies_list.md @@ -22,8 +22,12 @@ `ace_main` {% endif %} +{% if include.component == "arsenal" %} +`ace_common` +{% endif %} + {% if include.component == "atragmx" %} -`ACE_common`, `ACE_weather` +`ACE_Advanced_Ballistics`, `ACE_common`, `ACE_weather` {% endif %} {% if include.component == "attach" %} @@ -75,7 +79,7 @@ {% endif %} {% if include.component == "dogtags" %} -`ace_common` +`ace_interaction` {% endif %} {% if include.component == "dragging" %} @@ -138,6 +142,10 @@ `ace_interaction` {% endif %} +{% if include.component == "hellfire" %} +`ace_interaction`, `ace_missileguidance` +{% endif %} + {% if include.component == "hitreactions" %} `ace_common` {% endif %} @@ -170,10 +178,6 @@ `ace_common` {% endif %} -{% if include.component == "laser_selfdesignate" %} -`ace_laser` -{% endif %} - {% if include.component == "laserpointer" %} `ace_common` {% endif %} @@ -206,6 +210,10 @@ `ace_common` {% endif %} +{% if include.component == "maverick" %} +`ace_missileguidance` +{% endif %} + {% if include.component == "medical" %} `ace_interaction`, `ace_apl` {% endif %} @@ -214,6 +222,10 @@ `ace_medical` {% endif %} +{% if include.component == "medical_blood" %} +`ace_main` +{% endif %} + {% if include.component == "medical_menu" %} `ace_medical` {% endif %} @@ -258,6 +270,10 @@ `ace_common` {% endif %} +{% if include.component == "nlaw" %} +`ace_missileguidance` +{% endif %} + {% if include.component == "noidle" %} `ace_common` {% endif %} @@ -290,12 +306,16 @@ `ace_common` {% endif %} -{% if include.component == "particles" %} +{% if include.component == "pylons" %} +`ace_interact_menu`, `ace_zeus` +{% endif %} + +{% if include.component == "quickmount" %} `ace_common` {% endif %} {% if include.component == "rangecard" %} -`ACE_Advanced_Ballistics` +`ACE_Advanced_Ballistics`, `ace_scopes` {% endif %} {% if include.component == "realisticnames" %} @@ -346,10 +366,6 @@ `ace_common` {% endif %} -{% if include.component == "sitting" %} -`ace_interaction` -{% endif %} - {% if include.component == "slideshow" %} `ace_common` {% endif %} @@ -427,6 +443,70 @@ {% endif %} {% if include.component == "zeus" %} +`ace_common`, `ace_ai` +{% endif %} + +{% if include.component == "compat_adr_97" %} +`A3_Weapons_F_Mod` +{% endif %} + +{% if include.component == "compat_r3f" %} +`r3f_armes_c`, `r3f_armes`, `r3f_acc` +{% endif %} + +{% if include.component == "compat_rh_acc" %} +`RH_acc` +{% endif %} + +{% if include.component == "compat_rh_de" %} +`RH_de_cfg` +{% endif %} + +{% if include.component == "compat_rh_m4" %} +`RH_m4_cfg` +{% endif %} + +{% if include.component == "compat_rh_pdw" %} +`RH_PDW` +{% endif %} + +{% if include.component == "compat_rhs_afrf3" %} +`ace_rearm`, `ace_refuel`, `ace_repair`, `rhs_c_weapons`, `rhs_c_troops`, `rhs_c_bmd`, `rhs_c_bmp`, `rhs_c_bmp3`, `rhs_c_a2port_armor`, `rhs_c_btr`, `rhs_c_sprut`, `rhs_c_t72`, `rhs_c_tanks`, `rhs_c_a2port_air`, `rhs_c_a2port_car`, `rhs_c_cars`, `rhs_c_trucks`, `rhs_c_2s3`, `rhs_c_rva`, `rhs_c_heavyweapons` +{% endif %} + +{% if include.component == "compat_rhs_gref3" %} +`rhsgref_main`, `rhsgref_c_weapons` +{% endif %} + +{% if include.component == "compat_rhs_usf3" %} +`ace_javelin`, `ace_rearm`, `ace_refuel`, `ace_repair`, `rhsusf_c_weapons`, `rhsusf_c_troops`, `rhsusf_c_m1a1`, `rhsusf_c_m1a2`, `RHS_US_A2_AirImport`, `rhsusf_c_m109`, `rhsusf_c_HEMTT_A4`, `rhsusf_c_hmmwv`, `rhsusf_c_rg33`, `rhsusf_c_fmtv`, `rhsusf_c_m113`, `RHS_US_A2Port_Armor`, `rhsusf_c_melb` +{% endif %} + +{% if include.component == "compat_rksl_pm_ii" %} +`RKSL_PMII` +{% endif %} + +{% if include.component == "compat_sma3_iansky" %} +`iansky_opt` +{% endif %} + +{% if include.component == "noactionmenu" %} `ace_common` {% endif %} +{% if include.component == "nocrosshair" %} +`ace_common` +{% endif %} + +{% if include.component == "nouniformrestrictions" %} +`ace_common` +{% endif %} + +{% if include.component == "particles" %} +`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/2015-07-30-ace3-version320.md b/docs/_posts/2015-07-30-ace3-version320.md index 8abb849250..850717f47c 100644 --- a/docs/_posts/2015-07-30-ace3-version320.md +++ b/docs/_posts/2015-07-30-ace3-version320.md @@ -29,7 +29,7 @@ While porting some of ACE 2's AGM's and CSE's features we've ported some of the Fixing errors we were additionally working on further optimizing existing code and we've managed to achieve a big performance boost in our wind deflection code. -Furthermore a problem with vanilla damage being applied to some units has been fixed. If you still encounter this issue please report it following this guideline: http://ace3mod.com/wiki/user/how-to-report-an-issue.html +Furthermore a problem with vanilla damage being applied to some units has been fixed. If you still encounter this issue please report it following this guideline: {{ site.baseurl }}/wiki/user/how-to-report-an-issue.html ### The Shiny Things diff --git a/docs/_posts/2015-09-17-ace3-version331.md b/docs/_posts/2015-09-17-ace3-version331.md index 13d6435d90..2a4fbb46fe 100644 --- a/docs/_posts/2015-09-17-ace3-version331.md +++ b/docs/_posts/2015-09-17-ace3-version331.md @@ -72,4 +72,4 @@ https://github.com/acemod/ACE3/releases/tag/v3.3.0 With the changes of 3.3.1 which can be found here: https://github.com/acemod/ACE3/releases/tag/v3.3.1 (Be sure to download v3.3.1) -If you want to chat with fellow ACE3 users or with a dev feel free to join our public slack chat. Registration is free and open for everyone: http://slackin.ace3mod.com/ +If you want to chat with fellow ACE3 users or with a dev feel free to join our public slack chat. Registration is free and open for everyone: https://slackin.ace3mod.com/ diff --git a/docs/_posts/2015-12-03-ace3-version340.md b/docs/_posts/2015-12-03-ace3-version340.md index ddaf1bd890..1382663470 100644 --- a/docs/_posts/2015-12-03-ace3-version340.md +++ b/docs/_posts/2015-12-03-ace3-version340.md @@ -62,4 +62,4 @@ The complete change log of 3.4.0 can be found at: https://github.com/acemod/ACE3 And most important: If you want to chat with fellow ACE3 users or with a dev, if you have an idea or are in need of help feel free to join our public slack chat. -Registration is open for everyone: http://slackin.ace3mod.com/ +Registration is open for everyone: https://slackin.ace3mod.com/ diff --git a/docs/_posts/2016-03-02-ace3-version350.md b/docs/_posts/2016-03-02-ace3-version350.md index 668e0adee5..a6b6b89d8c 100644 --- a/docs/_posts/2016-03-02-ace3-version350.md +++ b/docs/_posts/2016-03-02-ace3-version350.md @@ -82,4 +82,4 @@ Make sure to [follow us on twitter](https://twitter.com/intent/follow?screen_nam **And most important:** If you want to chat with fellow ACE3 users or with a dev, if you have an idea or are in need of help feel free to join our public slack chat. -**Registration is open for everyone: [http://slackin.ace3mod.com/](http://slackin.ace3mod.com/)** +**Registration is open for everyone: [https://slackin.ace3mod.com/](https://slackin.ace3mod.com/)** diff --git a/docs/_posts/2016-06-21-moving-ace3-frameworks-to-cba.md b/docs/_posts/2016-06-21-moving-ace3-frameworks-to-cba.md index 1e7ccc8a1b..e5effd04b2 100644 --- a/docs/_posts/2016-06-21-moving-ace3-frameworks-to-cba.md +++ b/docs/_posts/2016-06-21-moving-ace3-frameworks-to-cba.md @@ -66,7 +66,7 @@ This update does not mean that if your mod depends on any of this functionality ### Replacing deprecated functionality -It is recommended to replace any functionality that is deprecated with its replacement as soon as possible. If you are in need of any help with moving from deprecated ACE3 functionality to it's replacement, please visit our [Public Slack team at http://slackin.ace3mod.com](http://slackin.ace3mod.com){:target="_blank"}. +It is recommended to replace any functionality that is deprecated with its replacement as soon as possible. If you are in need of any help with moving from deprecated ACE3 functionality to it's replacement, please visit our [Public Slack team at https://slackin.ace3mod.com](https://slackin.ace3mod.com){:target="_blank"}. ## ACE3 Events @@ -77,4 +77,4 @@ Any code currently using the old ACE3 event functions will still function correc --- -We hope you like the new frameworks made publicly available in CBA A3 and without needing a dependency on ACE3. Feel free to leave your feedback either on the [CBA BI forum thread](https://forums.bistudio.com/topic/168277-cba-community-base-addons-arma-3/){:target="_blank"}, the [ACE3 BI forum thread](https://forums.bistudio.com/topic/181341-ace3-a-collaborative-merger-between-agm-cse-and-ace/){:target="_blank"} or in our [public chat](http://slackin.ace3mod.com){:target="_blank"}. +We hope you like the new frameworks made publicly available in CBA A3 and without needing a dependency on ACE3. Feel free to leave your feedback either on the [CBA BI forum thread](https://forums.bistudio.com/topic/168277-cba-community-base-addons-arma-3/){:target="_blank"}, the [ACE3 BI forum thread](https://forums.bistudio.com/topic/181341-ace3-a-collaborative-merger-between-agm-cse-and-ace/){:target="_blank"} or in our [public chat](https://slackin.ace3mod.com){:target="_blank"}. diff --git a/docs/_posts/2016-06-30-ace3-version360.md b/docs/_posts/2016-06-30-ace3-version360.md index 3471d85b3a..c8e4ed9a20 100644 --- a/docs/_posts/2016-06-30-ace3-version360.md +++ b/docs/_posts/2016-06-30-ace3-version360.md @@ -100,6 +100,6 @@ The full changelog for ACE3 v3.6.0 can be found here: [https://github.com/acemod 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 appreciated. And most finally, we would like to invite you to our ACE3 public Slack chat. Here you can chat with fellow ACE3 users and developers, ask questions and receive help. -Registration is open for everyone: [http://slackin.ace3mod.com](http://slackin.ace3mod.com){:target="_blank"}. +Registration is open for everyone: [https://slackin.ace3mod.com](https://slackin.ace3mod.com){:target="_blank"}. 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/2016-09-17-ace3-version370.md b/docs/_posts/2016-09-17-ace3-version370.md new file mode 100644 index 0000000000..bd25b4c0fd --- /dev/null +++ b/docs/_posts/2016-09-17-ace3-version370.md @@ -0,0 +1,76 @@ +--- +title: ACEREP #00006 +description: Status report on ACE3 version 3.7.0 +parent: posts +image: /img/news/160912_grenade.jpg +author: glowbal +layout: post +--- + +It is [here](https://github.com/acemod/ace3/releases/v3.7.0){:target="_blank"}! The new ACE 3.7.0 update. We've been hard at work adding in a couple of exciting new features. As is per usual for us, we have also worked on a large collection of bug fixes, optimizations and general improvements to existing functionality. + + + +At this stage, we'd like to take the opportunity to briefly look back to the past year. Almost a year ago, in December 2015, we released ACE 3.3.2. At that time we had over 31.000 Steam subscribers and over 23.000 downloads on Github for ACE3. + +Since then, we've introduced a large number of new functionality; trenches, fast roping, mine detectors and our initial release for ACEX are just a few. We have worked on stability and polishing existing functionality, and our team has grown with new members ([@jonpas](https://github.com/jonpas){:target="_blank"}, [@BaerMitUmlaut](https://github.com/BaerMitUmlaut){:target="_blank"}). + +Now, we are close to 150.000 subscribers on Steam, and nearly 193.000 downloads combined on Github. That's a huge growth. Thanks to all our supporters! + +## What's new + +It is time to tell you about some of the exciting new things that come with the new update. + +### Advanced Throwing + +Earlier this year, [@dslyecxi](https://twitter.com/Dslyecxi){:target="_blank"} posted a YouTube video showing his implementation of a grenade throwing system. He has kindly donated his proof of concept to ACE3. Since then we've been hard at work integrating it into ACE3. And the result pays off! + + + + + Here is a video showing it in action: + +
+ +### Chemlight improvements + +One of the things we love about Arma 3 are the chemlights. With the 3.7.0 release, [@voiperr](https://github.com/voiperr){:target="_blank"}, one of our valued contributors has submitted his Chemlight enchancements. Here are some comparison screenshots: + +- [Vanilla Normal](http://i.imgur.com/zn61eiy.jpg){:target="_blank"} vs [ACE3 Normal](http://i.imgur.com/uOkzGwB.jpg){:target="_blank"} +- [Vanilla Night Vision](http://i.imgur.com/aR0p59M.jpg){:target="_blank"} vs [ACE3 Night Vision](http://i.imgur.com/QqM7iDI.jpg){:target="_blank"} + +### Cook off + +Back in the ACE2 days, this was one of the big features. And now it's back. Our own [@commy2](https://github.com/commy2){:target="_blank"} has implemented ammo cook off again. Here is a video: + + + + +### Medical AI + +Since the CBA release 2.5.1 the state machine implementation from [@BaerMitUmlaut](https://github.com/BaerMitUmlaut){:target="_blank"} has been available. Within ACE, we are using this to add our first implementation of medical AI. This means that AI medics will be able to treat themselves and members from their squad. + +For now, this is only enabled for Basic Medical. We are looking to expand this to Advanced Medical as well. + +## Future + +We are still at work on improving medical. Unfortunally we did not manage to finish our overhaul for the 3.7.0 release, but we hope to have the first stages completed and included before the end of the year. + +We are also working on new features such as Blue Force Tracking, Burning and more ports from ACE2, AGM and CSE. We are also open to any features submitted for ACE3. If you have exciting functionality that you feel could belong in ACE3, we are accepting pull requests. + +## The End Things + +The full changelog for ACE3 v3.7.0 can be found here: [https://github.com/acemod/ACE3/releases/v3.7.0](https://github.com/acemod/ACE3/releases/v3.7.0){: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 appreciated. + +
+
+ Slack Monochrome black logo +
+
+ +And most finally, we would like to invite you to our ACE3 public Slack chat. Here you can chat with fellow ACE3 users and developers, ask questions and receive help. +Registration is open for everyone: [https://slackin.ace3mod.com](https://slackin.ace3mod.com){:target="_blank"}. + +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/2016-11-04-ace3-version381.md b/docs/_posts/2016-11-04-ace3-version381.md new file mode 100644 index 0000000000..0ba73a5c2d --- /dev/null +++ b/docs/_posts/2016-11-04-ace3-version381.md @@ -0,0 +1,60 @@ +--- +title: ACEREP #00007 +description: Status report on ACE3 version 3.8.1 +parent: posts +image: /img/news/161104_blood.jpg +author: bux +layout: post +--- + +Just about two month ago we've released 3.7.0. A version that had most of the bugs fixed even before the official release. For the first time we were actively supplying users interested in helping us with pre release versions of the mod - so called release candidates. Quite a lot of communities tested the several release candidates and provided us with very valuable feedback. Especially on bugs and quirks that are near impossible to test alone. + + + +A big shoutout to those who helped testing! Thank you. + +We've used this approach for 3.8.0 as well and hope that again most of the bugs have been fixed already and that you can enjoy ACE3 without annoying interruptions. + +We will keep this approach for the future and invite you to join to test the release candidates. All information will be posted in our public chat to which you're invited too. You can access it here: [https://slackin.ace3mod.com](https://slackin.ace3mod.com){:target="_blank"} + +So, why didn't we release any minor releases for 3.7.0 (e.g. 3.7.1)? In short: We didn't feel that it was necessary. During and directly after the release we had already added new and awesome features so that we had to do a major release. + +Two new features have made it into 3.8.0 which are "blood splatters" and "ammo box cook off". +Wounded units will now leave more visible trails of blood on the ground which could make for interesting missions like escaping as a wounded soldier who is being tracked down by enemy combatants. +When ammo boxes are destroyed the contained ammunition now will cook off in a multitude of small explosions and the boxes won't just sink into the ground. + +
+
+ A wounded insurgent in front of a damaged truck. +
+
+ +With 3.8.0 the map tools will allow you to draw straight lines again. A feature that sadly is missing in vanilla Arma 3. + +## The Future things + +### Medical rewrite + +If you're following ACE3 development on GitHub closely you might already have spotted it: The medical system gets a huge rewrite. That's true, we're completely redoing the medical system. Until now the medical system has been a merge of the AGM and CSE medical systems. The AGM one kind of became what you know as the "basic system" and CSE's respectively the "advanced system". Being two separate systems it was always hard for us to improve one or the other without reworking the other one too. Not an ideal situation. Another issue we will address with this rewrite is the amount of influence a medical condition has on gameplay. An issue we've often heard from different communities as well. There's an [interesting discussion going on GitHub with a lot of different ideas and feature requests](https://github.com/acemod/ACE3/issues/3134){:target="_blank"}. Worth a read. + +With the state machine system that has been introduced in CBA we are now able to strictly define various health states of players such as unconsciousness or cardiac arrest and what can happen in those states. This allows us to massively declutter the code which will not only reduce the possibility of bugs, but also enable us to add more features and gameplay elements to the medical system - with no performance loss at all. + +We're really looking forward to the result and how you will like it. + +### Night Vision Googles Improvements + +If you've [watched dslyecxi's recent YouTube videos](https://www.youtube.com/user/Dslyecxi){:target="_blank"} or if you're [following us on twitter](https://twitter.com/intent/follow?screen_name=ace3mod&tw_p=followbutton){:target="_blank"} you might already have seen that dslyecxi has put together a mod vastly improving night vision googles and the resulting very limiting view. Check out his video with the explanation why vanilla Arma 3 NVGs are a bad representation of real life NVGs and what he has done to improve that. + + + + +dslyecxi has donated his mod to ACE3 and we're looking into integrating it for a future release. + +## The End Things + +The full changelog for ACE3 v3.8.1 can be found here: [https://github.com/acemod/ACE3/releases/v3.8.1](https://github.com/acemod/ACE3/releases/v3.8.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-02-21-ace3-version390.md b/docs/_posts/2017-02-21-ace3-version390.md new file mode 100644 index 0000000000..42368de04e --- /dev/null +++ b/docs/_posts/2017-02-21-ace3-version390.md @@ -0,0 +1,48 @@ +--- +title: ACEREP #00008 +description: Status report on ACE3 version 3.9.0 +parent: posts +image: /img/news/170221_csatconvoy.jpg +author: bux +layout: post +--- + +Another year, another release. 3.9.0 is the first release of 2017 and we'd like to thank everyone who has helped us to make it a smooth one. + + + + + + +The release candidate testing was very successful and we have received important feedback helping us to fix some issues beforehand. + +
+
+ CSAT driving a convoy through one of Tanoa's villages while two CSAT soldiers are arresting two civilians. +
+
+ +This update mainly features quite a lot of bug and compatibility fixes as well as necessary changes for the next Arma 3 update. In particular we've added the 64bit compatible DLL files. Though, don't expect any dramatic performance increases as the DLLs were just rebuilt to make them compatible. + +A new component has been added which removes the restriction for picking up and wearing enemy uniforms. You can find it in the `/optionals` folder in ACE3 and to use it you could e.g. copy it to the `/addons` folder. We've decided to put it into optionals because being able to wear an enemy's uniform isn't always the desired behavior for everyone. + +We have invested some time in polishing the ballistic features of ACE3. As an example the range cards and the ATragMX now respect the distance between the center of the bore and the center of the scope to more accurately calculate firing solutions. If you're an addon maker [we've added new config entries which can be added to your addon or a compatibility patch](/wiki/framework/scopes-framework.html). And as an added benefit, shooting with this change is even more accurate than in vanilla. +Speaking of the ATragMX it is now closer to the real life counter part than ever before: It now features a muzzle velocity/temperature interpolation, calculating muzzle velocity by factoring in powder burn rates at different temperatures and the "Truing Drop" feature which helps a shooter calculate a better flight path based on actual shooting results. And because "our" ATragMX is models closely to the real world one you could even use the [real manual to read about those features](https://www.horusvision.com/download/manual_Horus_ATrag-v385.pdf){:target="_blank"}. + +And even Zeus got a little love in this update. You can find new helper modules in the Zeus interface like teleporting players, adding FRIES to a helicopter, toggle the simulation of objects and more. The modules have been cleaned up into distinct categories to make them easier to find. + +
+
+ Showcasing the Zeus interface with the new ACE3 sections and utility modules. A helicopter is getting FRIES attached using ACE3 Zeus. +
+
+ +As mentioned in our [last ACEREP](/2016/11/04/ace3-version381.html) we're still working on our big medical rewrite. Progress though has stalled a little bit due to the holidays and real life occupations. But it's already in quite a good state. More on that will follow in a future ACEREP. + +## The End Things + +The full (and funny) changelog for ACE3 v3.9.0 can be found here: [https://github.com/acemod/ACE3/releases/v3.9.0](https://github.com/acemod/ACE3/releases/v3.9.0){: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-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. + +
+
+ A pilot and two deck crew members rearming an F-18 Black Wasp. +
+
+ +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/acebot.json b/docs/acebot.json new file mode 100644 index 0000000000..8aea4186b2 --- /dev/null +++ b/docs/acebot.json @@ -0,0 +1,102 @@ +[ + // General + { + "name": "Arsenal", + "url": "https://ace3mod.com/wiki/feature/arsenal.html" + }, + // Interaction + { + "name": "AdvancedThrowing", + "url": "https://ace3mod.com/wiki/feature/advanced-throwing.html" + }, + { + "name": "Captives", + "url": "https://ace3mod.com/wiki/feature/captives.html" + }, + { + "name": "Explosives", + "url": "https://ace3mod.com/wiki/feature/explosives.html" + }, + { + "name": "Interaction", + "url": "https://ace3mod.com/wiki/feature/interaction.html" + }, + { + "name": "MapGestures", + "url": "https://ace3mod.com/wiki/feature/map-gestures.html" + }, + { + "name": "Nametags", + "url": "https://ace3mod.com/wiki/feature/nametags.html" + }, + { + "name": "Pylons", + "url": "https://ace3mod.com/wiki/feature/pylons.html" + }, + { + "name": "Refuel", + "url": "https://ace3mod.com/wiki/feature/refuel.html" + }, + { + "name": "Reload", + "url": "https://ace3mod.com/wiki/feature/reload.html" + }, + { + "name": "Repair", + "url": "https://ace3mod.com/wiki/feature/repair.html" + }, + { + "name": "Slideshow", + "url": "https://ace3mod.com/wiki/feature/slideshow.html" + }, + { + "name": "Spectator", + "url": "https://ace3mod.com/wiki/feature/spectator.html" + }, + // Realism + { + "name": "AdvancedBallistics", + "url": "https://ace3mod.com/wiki/feature/advanced-ballistics.html" + }, + { + "name": "Hearing", + "url": "https://ace3mod.com/wiki/feature/hearing.html" + }, + { + "name": "MedicalSystem", + "url": "https://ace3mod.com/wiki/feature/medical-system.html" + }, + { + "name": "Overheating", + "url": "https://ace3mod.com/wiki/feature/overheating.html" + }, + { + "name": "Weather", + "url": "https://ace3mod.com/wiki/feature/weather.html" + }, + // Equipment + { + "name": "ATragMX", + "url": "https://ace3mod.com/wiki/feature/atragmx.html" + }, + { + "name": "Hellfire", + "url": "https://ace3mod.com/wiki/feature/hellfire.html" + }, + { + "name": "Kestrel4500", + "url": "https://ace3mod.com/wiki/feature/kestrel4500.html" + }, + { + "name": "MapTools", + "url": "https://ace3mod.com/wiki/feature/maptools.html" + }, + { + "name": "MicroDAGR", + "url": "https://ace3mod.com/wiki/feature/microdagr.html" + }, + { + "name": "Nightvision", + "url": "https://ace3mod.com/wiki/feature/nightvision.html" + } +] diff --git a/docs/css/app.css b/docs/css/app.css index 21f0120b27..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 -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 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:0.875rem;padding-right:1.75rem;padding-bottom:0.9375rem;padding-left:1.75rem;font-size:0.8125rem}button.tiny,.button.tiny{padding-top:0.625rem;padding-right:1.25rem;padding-bottom:0.6875rem;padding-left:1.25rem;font-size:0.6875rem}button.expand,.button.expand{padding-right:0;padding-left:0;width:100%}button.left-align,.button.left-align{text-align:left;text-indent:0.75rem}button.right-align,.button.right-align{text-align:right;padding-right:0.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:0.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:0.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:0.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:0.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:0.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:0.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:0.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 -0.5rem}form .row .row .column,form .row .row .columns{padding:0 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:0.5rem}label{font-size:0.875rem;color:#4d4d4d;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:0.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:0.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:0.875rem;margin:0 0 1rem 0;padding:0.5rem;height:2.3125rem;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:all 0.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:0.5rem;font-size:0.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:#f3f3f3;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:0.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 0.1875rem;margin:0;margin-left:-0.1875rem}[data-abide] .error small.error,[data-abide] .error span.error,[data-abide] span.error,[data-abide] small.error{display:block;padding:0.375rem 0.5625rem 0.5625rem;margin-top:-1px;margin-bottom:1rem;font-size:0.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:0.375rem 0.5625rem 0.5625rem;margin-top:-1px;margin-bottom:1rem;font-size:0.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:0.375rem 0.5625rem 0.5625rem;margin-top:-1px;margin-bottom:1rem;font-size:0.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:-0.9375rem;margin-right:-0.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:0.9375rem;padding-right:0.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:0.9375rem;padding-right:0.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:0.9375rem;padding-right:0.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:0.9375rem;padding-right:0.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:0.9375rem;padding-right:0.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:0.9375rem;padding-right:0.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:0.9375rem;padding-right:0.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:0.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:0.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:0.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 0.4375rem 0;font-size:0.875rem;font-weight:400}.side-nav li a:not(.button){display:block;color:#ba2619;margin:0;padding:0.4375rem 0.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:0.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:0.5rem 0.625rem 0.625rem;font-size:0.875rem;font-weight:700;color:#222}table tfoot{background:#f5f5f5}table tfoot tr th,table tfoot tr td{padding:0.5rem 0.625rem 0.625rem;font-size:0.875rem;font-weight:700;color:#222}table tr th,table tr td{padding:0.5625rem 0.625rem;font-size:0.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:0.75rem}.top-bar .button,.top-bar button{padding-top:0.4125rem;padding-bottom:0.4125rem;margin-bottom:0;font-size:0.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 0.9375rem}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;text-transform:uppercase;font-size:0.8125rem;font-weight:700;position:relative;display:block;padding:0 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 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:0.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 #1a1a1a;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:0.9375rem;font-family:"Open Sans","Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;font-size:0.8125rem;font-weight:400;text-transform:none}.top-bar-section ul li>a.button{font-size:0.8125rem;padding-right:0.9375rem;padding-left:0.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:0.8125rem;padding-right:0.9375rem;padding-left:0.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:0.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:0.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 0.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 0.9375rem}.top-bar-section .dropdown li .button,.top-bar-section .dropdown li button{top:auto}.top-bar-section .dropdown label{padding:8px 0.9375rem 2px;margin-bottom:0;text-transform:uppercase;color:#777;font-weight:700;font-size:0.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:0.875rem;position:relative;height:1.75rem;top:0.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 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 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 0.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 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:0.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:0.2rem;margin-bottom:0.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:0.9375rem}h5{font-size:1rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;font-weight:400;margin-top:0.2rem;margin-bottom:0.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:0.125rem 0.3125rem 0.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:0.3rem;font-weight:700}dl dd{margin-bottom:0.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:0.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:0.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:0.625rem 0.75rem}.vcard li{margin:0;display:block}.vcard .fn{font-weight:700;font-size:0.9375rem}.vevent .summary{font-weight:700}.vevent abbr{cursor:default;text-decoration:none;font-weight:700;border:none;padding:0 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:0.25}.slick-prev:before,.slick-next:before{font-family:"FontAwesome";font-size:20px;line-height:1;color:#ba2619;opacity:0.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:15px;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:0.25;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-dots li.slick-active button:before{color:#ba2619;opacity:0.75}/*! +/*! 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:0.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:0.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} + */@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 new file mode 100644 index 0000000000..0795ef1b5c --- /dev/null +++ b/docs/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.2" + +services: + docs: + container_name: ace3mod_jekyll + build: + context: . + dockerfile: Dockerfile + environment: + - JEKYLLARGS=--incremental + ports: + - "4000:4000" + volumes: + - ./:/usr/src/app 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/icons/icon-128x128.png b/docs/img/icons/icon-128x128.png new file mode 100644 index 0000000000..611f8d1a5c Binary files /dev/null and b/docs/img/icons/icon-128x128.png differ diff --git a/docs/img/icons/icon-144x144.png b/docs/img/icons/icon-144x144.png new file mode 100644 index 0000000000..e56c7c1f65 Binary files /dev/null and b/docs/img/icons/icon-144x144.png differ diff --git a/docs/img/icons/icon-256x256.png b/docs/img/icons/icon-256x256.png new file mode 100644 index 0000000000..5e6e534e05 Binary files /dev/null and b/docs/img/icons/icon-256x256.png differ diff --git a/docs/img/icons/icon-384x384.png b/docs/img/icons/icon-384x384.png new file mode 100644 index 0000000000..004a24c094 Binary files /dev/null and b/docs/img/icons/icon-384x384.png differ diff --git a/docs/img/icons/icon-48x48.png b/docs/img/icons/icon-48x48.png new file mode 100644 index 0000000000..2eaecef162 Binary files /dev/null and b/docs/img/icons/icon-48x48.png differ diff --git a/docs/img/icons/icon-512x512.png b/docs/img/icons/icon-512x512.png new file mode 100644 index 0000000000..94192e6a23 Binary files /dev/null and b/docs/img/icons/icon-512x512.png differ diff --git a/docs/img/icons/icon-96x96.png b/docs/img/icons/icon-96x96.png new file mode 100644 index 0000000000..3d24b64374 Binary files /dev/null and b/docs/img/icons/icon-96x96.png differ diff --git a/docs/img/news/160912_grenade.jpg b/docs/img/news/160912_grenade.jpg new file mode 100644 index 0000000000..6b9a3ad00c Binary files /dev/null and b/docs/img/news/160912_grenade.jpg differ diff --git a/docs/img/news/160912_slack_monochrome_black-950x442.png b/docs/img/news/160912_slack_monochrome_black-950x442.png new file mode 100644 index 0000000000..09446f582e Binary files /dev/null and b/docs/img/news/160912_slack_monochrome_black-950x442.png differ diff --git a/docs/img/news/161104_blood.jpg b/docs/img/news/161104_blood.jpg new file mode 100644 index 0000000000..80af0fdd04 Binary files /dev/null and b/docs/img/news/161104_blood.jpg differ diff --git a/docs/img/news/170221_Zeus.jpg b/docs/img/news/170221_Zeus.jpg new file mode 100644 index 0000000000..8d52b28aee Binary files /dev/null and b/docs/img/news/170221_Zeus.jpg differ diff --git a/docs/img/news/170221_csatconvoy.jpg b/docs/img/news/170221_csatconvoy.jpg new file mode 100644 index 0000000000..b80b907468 Binary files /dev/null and b/docs/img/news/170221_csatconvoy.jpg differ 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/slider01.jpg b/docs/img/slider01.jpg old mode 100644 new mode 100755 index 2e5961d58a..e19d19c848 Binary files a/docs/img/slider01.jpg and b/docs/img/slider01.jpg differ diff --git a/docs/img/slider01_mobile.jpg b/docs/img/slider01_mobile.jpg old mode 100644 new mode 100755 index 5034e8021b..7ccc2942c2 Binary files a/docs/img/slider01_mobile.jpg and b/docs/img/slider01_mobile.jpg differ diff --git a/docs/img/slider02.jpg b/docs/img/slider02.jpg old mode 100644 new mode 100755 index 63ca4cc676..87d6fc4cc9 Binary files a/docs/img/slider02.jpg and b/docs/img/slider02.jpg differ diff --git a/docs/img/slider02_mobile.jpg b/docs/img/slider02_mobile.jpg old mode 100644 new mode 100755 index 37989dfdf0..d3d4c6744c Binary files a/docs/img/slider02_mobile.jpg and b/docs/img/slider02_mobile.jpg differ diff --git a/docs/img/slider03.jpg b/docs/img/slider03.jpg old mode 100644 new mode 100755 index 4249c163b3..18a6804e19 Binary files a/docs/img/slider03.jpg and b/docs/img/slider03.jpg differ diff --git a/docs/img/slider03_mobile.jpg b/docs/img/slider03_mobile.jpg old mode 100644 new mode 100755 index eaaea83f60..9ec4d304ff Binary files a/docs/img/slider03_mobile.jpg and b/docs/img/slider03_mobile.jpg differ diff --git a/docs/img/wiki/feature/ab_ingame.png b/docs/img/wiki/feature/ab_ingame.png new file mode 100644 index 0000000000..6f53d714d7 Binary files /dev/null and b/docs/img/wiki/feature/ab_ingame.png 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/abtools_inventory.png b/docs/img/wiki/feature/abtools_inventory.png new file mode 100644 index 0000000000..72e1607689 Binary files /dev/null and b/docs/img/wiki/feature/abtools_inventory.png differ diff --git a/docs/img/wiki/feature/ace_blood_screen.jpg b/docs/img/wiki/feature/ace_blood_screen.jpg new file mode 100644 index 0000000000..89a07bdfb6 Binary files /dev/null and b/docs/img/wiki/feature/ace_blood_screen.jpg differ diff --git a/docs/img/wiki/feature/atragmx1.png b/docs/img/wiki/feature/atragmx1.png new file mode 100644 index 0000000000..e32a31c899 Binary files /dev/null and b/docs/img/wiki/feature/atragmx1.png differ diff --git a/docs/img/wiki/feature/atragmx2.png b/docs/img/wiki/feature/atragmx2.png new file mode 100644 index 0000000000..6cdaabd3f8 Binary files /dev/null and b/docs/img/wiki/feature/atragmx2.png differ diff --git a/docs/img/wiki/feature/atragmx31.png b/docs/img/wiki/feature/atragmx31.png new file mode 100644 index 0000000000..58afd1863e Binary files /dev/null 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/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/rangecard_menu.jpg b/docs/img/wiki/feature/rangecard_menu.jpg new file mode 100644 index 0000000000..d41ba9fe6b Binary files /dev/null and b/docs/img/wiki/feature/rangecard_menu.jpg 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/index.html b/docs/index.html index 3bc84a2b03..13bbd53fc1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,7 +8,7 @@ sitemap: exclude: "yes" --- -Fork me on GitHub +Fork me on GitHub @@ -64,7 +64,7 @@ sitemap:

Useful frameworks and features

@@ -81,11 +81,11 @@ sitemap:
Everything you need to know about using the mod or developing for it.

-

ACE3 on Github
Latest code, issue reports, feature requests +

ACE3 on Github
Latest code, issue reports, feature requests and more.

-

ACE3 Public Chat
+

ACE3 Public Chat
Join our public chat! We're glad to answer questions concerning ACE3, development or Arma things.
If you made something with this mod (screen shots, artwork, videos) we'd love to see it.

diff --git a/docs/js/footer.dev.js b/docs/js/footer.dev.js index 0981fbe843..b594d22c70 100644 --- a/docs/js/footer.dev.js +++ b/docs/js/footer.dev.js @@ -2,743 +2,1594 @@ * Build: http://modernizr.com/download/#-shiv-cssclasses-load */ ;window.Modernizr=function(a,b,c){function u(a){j.cssText=a}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function w(a,b){return typeof a===b}function x(a,b){return!!~(""+a).indexOf(b)}function y(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:w(f,"function")?f.bind(d||b):f}return!1}var d="2.8.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m={},n={},o={},p=[],q=p.slice,r,s={}.hasOwnProperty,t;!w(s,"undefined")&&!w(s.call,"undefined")?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=q.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(q.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(q.call(arguments)))};return e});for(var z in m)t(m,z)&&(r=z.toLowerCase(),e[r]=m[z](),p.push((e[r]?"":"no-")+r));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)t(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},u(""),i=k=null,function(a,b){function l(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 m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.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:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+p.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.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=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[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,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f img._pfLastSize) { + img._pfLastSize = img.offsetWidth; + sizes = img.sizes; + img.sizes += ",100vw"; + setTimeout(function () { + img.sizes = sizes; + }); + } + }; - // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers - info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; + var findPictureImgs = function () { + var i; + var imgs = document.querySelectorAll("picture > img, img[srcset][sizes]"); + for (i = 0; i < imgs.length; i++) { + fixRespimg(imgs[i]); + } + }; + var onResize = function () { + clearTimeout(timer); + timer = setTimeout(findPictureImgs, 99); + }; + var mq = window.matchMedia && matchMedia("(orientation: landscape)"); + var init = function () { + onResize(); - styleMedia = { - matchMedium: function(media) { - var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; + if (mq && mq.addListener) { + mq.addListener(onResize); + } + }; - // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers - if (style.styleSheet) { - style.styleSheet.cssText = text; - } else { - style.textContent = text; - } + dummySrc.srcset = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - // Test if media query is true or false - return info.width === '1px'; - } - }; - } + if (/^[c|i]|d$/.test(document.readyState || "")) { + init(); + } else { + document.addEventListener("DOMContentLoaded", init); + } - return function(media) { - return { - matches: styleMedia.matchMedium(media || 'all'), - media: media || 'all' - }; - }; -}()); -/*! Picturefill - Responsive Images that work today. -* Author: Scott Jehl, Filament Group, 2012 ( new proposal implemented by Shawn Jansepar ) -* License: MIT/GPLv2 -* Spec: http://picture.responsiveimages.org/ -*/ -(function( w, doc, image ) { - // Enable strict mode - "use strict"; + return onResize; + })()); + } +})(window); - function expose(picturefill) { - /* expose picturefill */ - if ( typeof module === "object" && typeof module.exports === "object" ) { - // CommonJS, just export - module.exports = picturefill; - } else if ( typeof define === "function" && define.amd ) { - // AMD support - define( "picturefill", function() { return picturefill; } ); - } - if ( typeof w === "object" ) { - // If no AMD and we are in the browser, attach to window - w.picturefill = picturefill; - } - } +/*! Picturefill - v3.0.2 + * http://scottjehl.github.io/picturefill + * Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; + * License: MIT + */ - // If picture is supported, well, that's awesome. Let's get outta here... - if ( w.HTMLPictureElement ) { - expose(function() { }); - return; - } +(function (window, document, undefined) { + // Enable strict mode + "use strict"; - // HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround) - doc.createElement( "picture" ); + // HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround) + document.createElement("picture"); - // local object for method references and testing exposure - var pf = w.picturefill || {}; + var warn, eminpx, alwaysCheckWDescriptor, evalId; + // local object for method references and testing exposure + var pf = {}; + var isSupportTestReady = false; + var noop = function () { + }; + var image = document.createElement("img"); + var getImgAttr = image.getAttribute; + var setImgAttr = image.setAttribute; + var removeImgAttr = image.removeAttribute; + var docElem = document.documentElement; + var types = {}; + var cfg = { + //resource selection: + algorithm: "" + }; + var srcAttr = "data-pfsrc"; + var srcsetAttr = srcAttr + "set"; + // ua sniffing is done for undetectable img loading features, + // to do some non crucial perf optimizations + var ua = navigator.userAgent; + var supportAbort = (/rident/).test(ua) || ((/ecko/).test(ua) && ua.match(/rv\:(\d+)/) && RegExp.$1 > 35 ); + var curSrcProp = "currentSrc"; + var regWDesc = /\s+\+?\d+(e\d+)?w/; + var regSize = /(\([^)]+\))?\s*(.+)/; + var setOptions = window.picturefillCFG; + /** + * Shortcut property for https://w3c.github.io/webappsec/specs/mixedcontent/#restricts-mixed-content ( for easy overriding in tests ) + */ + // baseStyle also used by getEmValue (i.e.: width: 1em is important) + var baseStyle = "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)"; + var fsCss = "font-size:100%!important;"; + var isVwDirty = true; - var regWDesc = /\s+\+?\d+(e\d+)?w/; + var cssCache = {}; + var sizeLengthCache = {}; + var DPR = window.devicePixelRatio; + var units = { + px: 1, + "in": 96 + }; + var anchor = document.createElement("a"); + /** + * alreadyRun flag used for setOptions. is it true setOptions will reevaluate + * @type {boolean} + */ + var alreadyRun = false; - // namespace - pf.ns = "picturefill"; + // Reusable, non-"g" Regexes - // srcset support test - (function() { - pf.srcsetSupported = "srcset" in image; - pf.sizesSupported = "sizes" in image; - })(); + // (Don't use \s, to avoid matching non-breaking space.) + var regexLeadingSpaces = /^[ \t\n\r\u000c]+/, + regexLeadingCommasOrSpaces = /^[, \t\n\r\u000c]+/, + regexLeadingNotSpaces = /^[^ \t\n\r\u000c]+/, + regexTrailingCommas = /[,]+$/, + regexNonNegativeInteger = /^\d+$/, - // just a string trim workaround - pf.trim = function( str ) { - return str.trim ? str.trim() : str.replace( /^\s+|\s+$/g, "" ); - }; + // ( Positive or negative or unsigned integers or decimals, without or without exponents. + // Must include at least one digit. + // According to spec tests any decimal point must be followed by a digit. + // No leading plus sign is allowed.) + // https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number + regexFloatingPoint = /^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/; - /** - * Gets a string and returns the absolute URL - * @param src - * @returns {String} absolute URL - */ - pf.makeUrl = (function() { - var anchor = doc.createElement( "a" ); - return function(src) { - anchor.href = src; - return anchor.href; - }; - })(); + var on = function (obj, evt, fn, capture) { + if (obj.addEventListener) { + obj.addEventListener(evt, fn, capture || false); + } else if (obj.attachEvent) { + obj.attachEvent("on" + evt, fn); + } + }; - /** - * Shortcut method for https://w3c.github.io/webappsec/specs/mixedcontent/#restricts-mixed-content ( for easy overriding in tests ) - */ - pf.restrictsMixedContent = function() { - return w.location.protocol === "https:"; - }; - /** - * Shortcut method for matchMedia ( for easy overriding in tests ) - */ + /** + * simple memoize function: + */ - pf.matchesMedia = function( media ) { - return w.matchMedia && w.matchMedia( media ).matches; - }; + var memoize = function (fn) { + var cache = {}; + return function (input) { + if (!(input in cache)) { + cache[input] = fn(input); + } + return cache[input]; + }; + }; - // Shortcut method for `devicePixelRatio` ( for easy overriding in tests ) - pf.getDpr = function() { - return ( w.devicePixelRatio || 1 ); - }; + // UTILITY FUNCTIONS - /** - * Get width in css pixel value from a "length" value - * http://dev.w3.org/csswg/css-values-3/#length-value - */ - pf.getWidthFromLength = function( length ) { - var cssValue; - // If a length is specified and doesn’t contain a percentage, and it is greater than 0 or using `calc`, use it. Else, abort. - if ( !(length && length.indexOf( "%" ) > -1 === false && ( parseFloat( length ) > 0 || length.indexOf( "calc(" ) > -1 )) ) { - return false; + // Manual is faster than RegEx + // http://jsperf.com/whitespace-character/5 + function isSpace(c) { + return (c === "\u0020" || // space + c === "\u0009" || // horizontal tab + c === "\u000A" || // new line + c === "\u000C" || // form feed + c === "\u000D"); // carriage return + } + + /** + * gets a mediaquery and returns a boolean or gets a css length and returns a number + * @param css mediaqueries or css length + * @returns {boolean|number} + * + * based on: https://gist.github.com/jonathantneal/db4f77009b155f083738 + */ + var evalCSS = (function () { + + var regLength = /^([\d\.]+)(em|vw|px)$/; + var replace = function () { + var args = arguments, index = 0, string = args[0]; + while (++index in args) { + string = string.replace(args[index], args[++index]); + } + return string; + }; + + var buildStr = memoize(function (css) { + + return "return " + replace((css || "").toLowerCase(), + // interpret `and` + /\band\b/g, "&&", + + // interpret `,` + /,/g, "||", + + // interpret `min-` as >= + /min-([a-z-\s]+):/g, "e.$1>=", + + // interpret `max-` as <= + /max-([a-z-\s]+):/g, "e.$1<=", + + //calc value + /calc([^)]+)/g, "($1)", + + // interpret css values + /(\d+[\.]*[\d]*)([a-z]+)/g, "($1 * e.$2)", + //make eval less evil + /^(?!(e.[a-z]|[0-9\.&=|><\+\-\*\(\)\/])).*/ig, "" + ) + ";"; + }); + + return function (css, length) { + var parsedLength; + if (!(css in cssCache)) { + cssCache[css] = false; + if (length && (parsedLength = css.match(regLength))) { + cssCache[css] = parsedLength[1] * units[parsedLength[2]]; + } else { + /*jshint evil:true */ + try { + cssCache[css] = new Function("e", buildStr(css))(units); + } catch (e) { + } + /*jshint evil:false */ + } + } + return cssCache[css]; + }; + })(); + + var setResolution = function (candidate, sizesattr) { + if (candidate.w) { // h = means height: || descriptor.type === 'h' do not handle yet... + candidate.cWidth = pf.calcListLength(sizesattr || "100vw"); + candidate.res = candidate.w / candidate.cWidth; + } else { + candidate.res = candidate.d; + } + return candidate; + }; + + /** + * + * @param opt + */ + var picturefill = function (opt) { + + if (!isSupportTestReady) { + return; } - /** - * If length is specified in `vw` units, use `%` instead since the div we’re measuring - * is injected at the top of the document. - * - * TODO: maybe we should put this behind a feature test for `vw`? The risk of doing this is possible browser inconsistancies with vw vs % - */ - length = length.replace( "vw", "%" ); + var elements, i, plen; - // Create a cached element for getting length value widths - if ( !pf.lengthEl ) { - pf.lengthEl = doc.createElement( "div" ); + var options = opt || {}; - // Positioning styles help prevent padding/margin/width on `html` or `body` from throwing calculations off. - pf.lengthEl.style.cssText = "border:0;display:block;font-size:1em;left:0;margin:0;padding:0;position:absolute;visibility:hidden"; + if (options.elements && options.elements.nodeType === 1) { + if (options.elements.nodeName.toUpperCase() === "IMG") { + options.elements = [options.elements]; + } else { + options.context = options.elements; + options.elements = null; + } + } - // Add a class, so that everyone knows where this element comes from - pf.lengthEl.className = "helper-from-picturefill-js"; - } + elements = options.elements || pf.qsa((options.context || document), ( options.reevaluate || options.reselect ) ? pf.sel : pf.selShort); - pf.lengthEl.style.width = "0px"; + if ((plen = elements.length)) { - try { - pf.lengthEl.style.width = length; - } catch ( e ) {} + pf.setupRun(options); + alreadyRun = true; - doc.body.appendChild(pf.lengthEl); + // Loop through all elements + for (i = 0; i < plen; i++) { + pf.fillImg(elements[i], options); + } - cssValue = pf.lengthEl.offsetWidth; + pf.teardownRun(options); + } + }; - if ( cssValue <= 0 ) { - cssValue = false; - } + /** + * outputs a warning for the developer + * @param {message} + * @type {Function} + */ + warn = ( window.console && console.warn ) ? + function (message) { + console.warn(message); + } : + noop + ; - doc.body.removeChild( pf.lengthEl ); + if (!(curSrcProp in image)) { + curSrcProp = "src"; + } - return cssValue; - }; + // Add support for standard mime types. + types["image/jpeg"] = true; + types["image/gif"] = true; + types["image/png"] = true; - pf.detectTypeSupport = function( type, typeUri ) { + function detectTypeSupport(type, typeUri) { // based on Modernizr's lossless img-webp test // note: asynchronous - var image = new w.Image(); - image.onerror = function() { - pf.types[ type ] = false; + var image = new window.Image(); + image.onerror = function () { + types[type] = false; picturefill(); }; - image.onload = function() { - pf.types[ type ] = image.width === 1; + image.onload = function () { + types[type] = image.width === 1; picturefill(); }; image.src = typeUri; - return "pending"; - }; - // container of supported mime types that one might need to qualify before using - pf.types = pf.types || {}; + } - pf.initTypeDetects = function() { - // Add support for standard mime types - pf.types[ "image/jpeg" ] = true; - pf.types[ "image/gif" ] = true; - pf.types[ "image/png" ] = true; - pf.types[ "image/svg+xml" ] = doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1"); - pf.types[ "image/webp" ] = pf.detectTypeSupport("image/webp", "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA="); - }; + // test svg support + types["image/svg+xml"] = document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1"); - pf.verifyTypeSupport = function( source ) { - var type = source.getAttribute( "type" ); - // if type attribute exists, return test result, otherwise return true - if ( type === null || type === "" ) { - return true; - } else { - var pfType = pf.types[ type ]; - // if the type test is a function, run it and return "pending" status. The function will rerun picturefill on pending elements once finished. - if ( typeof pfType === "string" && pfType !== "pending") { - pf.types[ type ] = pf.detectTypeSupport( type, pfType ); - return "pending"; - } else if ( typeof pfType === "function" ) { - pfType(); - return "pending"; - } else { - return pfType; - } - } - }; + /** + * updates the internal vW property with the current viewport width in px + */ + function updateMetrics() { - // Parses an individual `size` and returns the length, and optional media query - pf.parseSize = function( sourceSizeStr ) { - var match = /(\([^)]+\))?\s*(.+)/g.exec( sourceSizeStr ); - return { - media: match && match[1], - length: match && match[2] - }; - }; + isVwDirty = false; + DPR = window.devicePixelRatio; + cssCache = {}; + sizeLengthCache = {}; - // Takes a string of sizes and returns the width in pixels as a number - pf.findWidthFromSourceSize = function( sourceSizeListStr ) { - // Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33% - // or (min-width:30em) calc(30% - 15px) - var sourceSizeList = pf.trim( sourceSizeListStr ).split( /\s*,\s*/ ), - winningLength; + pf.DPR = DPR || 1; - for ( var i = 0, len = sourceSizeList.length; i < len; i++ ) { - // Match ? length, ie ( min-width: 50em ) 100% - var sourceSize = sourceSizeList[ i ], - // Split "( min-width: 50em ) 100%" into separate strings - parsedSize = pf.parseSize( sourceSize ), - length = parsedSize.length, - media = parsedSize.media; + units.width = Math.max(window.innerWidth || 0, docElem.clientWidth); + units.height = Math.max(window.innerHeight || 0, docElem.clientHeight); - if ( !length ) { - continue; - } - // if there is no media query or it matches, choose this as our winning length - if ( (!media || pf.matchesMedia( media )) && - // pass the length to a method that can properly determine length - // in pixels based on these formats: http://dev.w3.org/csswg/css-values-3/#length-value - (winningLength = pf.getWidthFromLength( length )) ) { - break; - } - } + units.vw = units.width / 100; + units.vh = units.height / 100; - //if we have no winningLength fallback to 100vw - return winningLength || Math.max(w.innerWidth || 0, doc.documentElement.clientWidth); - }; + evalId = [units.height, units.width, DPR].join("-"); - pf.parseSrcset = function( srcset ) { - /** - * A lot of this was pulled from Boris Smus’ parser for the now-defunct WHATWG `srcset` - * https://github.com/borismus/srcset-polyfill/blob/master/js/srcset-info.js - * - * 1. Let input (`srcset`) be the value passed to this algorithm. - * 2. Let position be a pointer into input, initially pointing at the start of the string. - * 3. Let raw candidates be an initially empty ordered list of URLs with associated - * unparsed descriptors. The order of entries in the list is the order in which entries - * are added to the list. - */ - var candidates = []; + units.em = pf.getEmValue(); + units.rem = units.em; + } - while ( srcset !== "" ) { - srcset = srcset.replace( /^\s+/g, "" ); + function chooseLowRes(lowerValue, higherValue, dprValue, isCached) { + var bonusFactor, tooMuch, bonus, meanDensity; - // 5. Collect a sequence of characters that are not space characters, and let that be url. - var pos = srcset.search(/\s/g), - url, descriptor = null; + //experimental + if (cfg.algorithm === "saveData") { + if (lowerValue > 2.7) { + meanDensity = dprValue + 1; + } else { + tooMuch = higherValue - dprValue; + bonusFactor = Math.pow(lowerValue - 0.6, 1.5); - if ( pos !== -1 ) { - url = srcset.slice( 0, pos ); + bonus = tooMuch * bonusFactor; - var last = url.slice(-1); + if (isCached) { + bonus += 0.1 * bonusFactor; + } - // 6. If url ends with a U+002C COMMA character (,), remove that character from url - // and let descriptors be the empty string. Otherwise, follow these substeps - // 6.1. If url is empty, then jump to the step labeled descriptor parser. - - if ( last === "," || url === "" ) { - url = url.replace( /,+$/, "" ); - descriptor = ""; - } - srcset = srcset.slice( pos + 1 ); - - // 6.2. Collect a sequence of characters that are not U+002C COMMA characters (,), and - // let that be descriptors. - if ( descriptor === null ) { - var descpos = srcset.indexOf( "," ); - if ( descpos !== -1 ) { - descriptor = srcset.slice( 0, descpos ); - srcset = srcset.slice( descpos + 1 ); - } else { - descriptor = srcset; - srcset = ""; - } - } - } else { - url = srcset; - srcset = ""; - } - - // 7. Add url to raw candidates, associated with descriptors. - if ( url || descriptor ) { - candidates.push({ - url: url, - descriptor: descriptor - }); - } - } - return candidates; - }; - - pf.parseDescriptor = function( descriptor, sizesattr ) { - // 11. Descriptor parser: Let candidates be an initially empty source set. The order of entries in the list - // is the order in which entries are added to the list. - var sizes = sizesattr || "100vw", - sizeDescriptor = descriptor && descriptor.replace( /(^\s+|\s+$)/g, "" ), - widthInCssPixels = pf.findWidthFromSourceSize( sizes ), - resCandidate; - - if ( sizeDescriptor ) { - var splitDescriptor = sizeDescriptor.split(" "); - - for (var i = splitDescriptor.length - 1; i >= 0; i--) { - var curr = splitDescriptor[ i ], - lastchar = curr && curr.slice( curr.length - 1 ); - - if ( ( lastchar === "h" || lastchar === "w" ) && !pf.sizesSupported ) { - resCandidate = parseFloat( ( parseInt( curr, 10 ) / widthInCssPixels ) ); - } else if ( lastchar === "x" ) { - var res = curr && parseFloat( curr, 10 ); - resCandidate = res && !isNaN( res ) ? res : 1; - } - } - } - return resCandidate || 1; - }; - - /** - * Takes a srcset in the form of url/ - * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or - * "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or - * "images/pic-small.png" - * Get an array of image candidates in the form of - * {url: "/foo/bar.png", resolution: 1} - * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value - * If sizes is specified, resolution is calculated - */ - pf.getCandidatesFromSourceSet = function( srcset, sizes ) { - var candidates = pf.parseSrcset( srcset ), - formattedCandidates = []; - - for ( var i = 0, len = candidates.length; i < len; i++ ) { - var candidate = candidates[ i ]; - - formattedCandidates.push({ - url: candidate.url, - resolution: pf.parseDescriptor( candidate.descriptor, sizes ) - }); - } - return formattedCandidates; - }; - - /** - * if it's an img element and it has a srcset property, - * we need to remove the attribute so we can manipulate src - * (the property's existence infers native srcset support, and a srcset-supporting browser will prioritize srcset's value over our winning picture candidate) - * this moves srcset's value to memory for later use and removes the attr - */ - pf.dodgeSrcset = function( img ) { - if ( img.srcset ) { - img[ pf.ns ].srcset = img.srcset; - img.srcset = ""; - img.setAttribute( "data-pfsrcset", img[ pf.ns ].srcset ); - } - }; - - // Accept a source or img element and process its srcset and sizes attrs - pf.processSourceSet = function( el ) { - var srcset = el.getAttribute( "srcset" ), - sizes = el.getAttribute( "sizes" ), - candidates = []; - - // if it's an img element, use the cached srcset property (defined or not) - if ( el.nodeName.toUpperCase() === "IMG" && el[ pf.ns ] && el[ pf.ns ].srcset ) { - srcset = el[ pf.ns ].srcset; - } - - if ( srcset ) { - candidates = pf.getCandidatesFromSourceSet( srcset, sizes ); - } - return candidates; - }; - - pf.backfaceVisibilityFix = function( picImg ) { - // See: https://github.com/scottjehl/picturefill/issues/332 - var style = picImg.style || {}, - WebkitBackfaceVisibility = "webkitBackfaceVisibility" in style, - currentZoom = style.zoom; - - if (WebkitBackfaceVisibility) { - style.zoom = ".999"; - - WebkitBackfaceVisibility = picImg.offsetWidth; - - style.zoom = currentZoom; - } - }; - - pf.setIntrinsicSize = (function() { - var urlCache = {}; - var setSize = function( picImg, width, res ) { - if ( width ) { - picImg.setAttribute( "width", parseInt(width / res, 10) ); + meanDensity = lowerValue + bonus; } - }; - return function( picImg, bestCandidate ) { - var img; - if ( !picImg[ pf.ns ] || w.pfStopIntrinsicSize ) { - return; - } - if ( picImg[ pf.ns ].dims === undefined ) { - picImg[ pf.ns].dims = picImg.getAttribute("width") || picImg.getAttribute("height"); - } - if ( picImg[ pf.ns].dims ) { return; } + } else { + meanDensity = (dprValue > 1) ? + Math.sqrt(lowerValue * higherValue) : + lowerValue; + } - if ( bestCandidate.url in urlCache ) { - setSize( picImg, urlCache[bestCandidate.url], bestCandidate.resolution ); - } else { - img = doc.createElement( "img" ); - img.onload = function() { - urlCache[bestCandidate.url] = img.width; + return meanDensity > dprValue; + } - //IE 10/11 don't calculate width for svg outside document - if ( !urlCache[bestCandidate.url] ) { - try { - doc.body.appendChild( img ); - urlCache[bestCandidate.url] = img.width || img.offsetWidth; - doc.body.removeChild( img ); - } catch(e){} + function applyBestCandidate(img) { + var srcSetCandidates; + var matchingSet = pf.getSet(img); + var evaluated = false; + if (matchingSet !== "pending") { + evaluated = evalId; + if (matchingSet) { + srcSetCandidates = pf.setRes(matchingSet); + pf.applySetCandidate(srcSetCandidates, img); + } + } + img[pf.ns].evaled = evaluated; + } + + function ascendingSort(a, b) { + return a.res - b.res; + } + + function setSrcToCur(img, src, set) { + var candidate; + if (!set && src) { + set = img[pf.ns].sets; + set = set && set[set.length - 1]; + } + + candidate = getCandidateForSrc(src, set); + + if (candidate) { + src = pf.makeUrl(src); + img[pf.ns].curSrc = src; + img[pf.ns].curCan = candidate; + + if (!candidate.res) { + setResolution(candidate, candidate.set.sizes); + } + } + return candidate; + } + + function getCandidateForSrc(src, set) { + var i, candidate, candidates; + if (src && set) { + candidates = pf.parseSet(set); + src = pf.makeUrl(src); + for (i = 0; i < candidates.length; i++) { + if (src === pf.makeUrl(candidates[i].url)) { + candidate = candidates[i]; + break; + } + } + } + return candidate; + } + + function getAllSourceElements(picture, candidates) { + var i, len, source, srcset; + + // SPEC mismatch intended for size and perf: + // actually only source elements preceding the img should be used + // also note: don't use qsa here, because IE8 sometimes doesn't like source as the key part in a selector + var sources = picture.getElementsByTagName("source"); + + for (i = 0, len = sources.length; i < len; i++) { + source = sources[i]; + source[pf.ns] = true; + srcset = source.getAttribute("srcset"); + + // if source does not have a srcset attribute, skip + if (srcset) { + candidates.push({ + srcset: srcset, + media: source.getAttribute("media"), + type: source.getAttribute("type"), + sizes: source.getAttribute("sizes") + }); + } + } + } + + /** + * Srcset Parser + * By Alex Bell | MIT License + * + * @returns Array [{url: _, d: _, w: _, h:_, set:_(????)}, ...] + * + * Based super duper closely on the reference algorithm at: + * https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute + */ + + // 1. Let input be the value passed to this algorithm. + // (TO-DO : Explain what "set" argument is here. Maybe choose a more + // descriptive & more searchable name. Since passing the "set" in really has + // nothing to do with parsing proper, I would prefer this assignment eventually + // go in an external fn.) + function parseSrcset(input, set) { + + function collectCharacters(regEx) { + var chars, + match = regEx.exec(input.substring(pos)); + if (match) { + chars = match[0]; + pos += chars.length; + return chars; + } + } + + var inputLength = input.length, + url, + descriptors, + currentDescriptor, + state, + c, + + // 2. Let position be a pointer into input, initially pointing at the start + // of the string. + pos = 0, + + // 3. Let candidates be an initially empty source set. + candidates = []; + + /** + * Adds descriptor properties to a candidate, pushes to the candidates array + * @return undefined + */ + // (Declared outside of the while loop so that it's only created once. + // (This fn is defined before it is used, in order to pass JSHINT. + // Unfortunately this breaks the sequencing of the spec comments. :/ ) + function parseDescriptors() { + + // 9. Descriptor parser: Let error be no. + var pError = false, + + // 10. Let width be absent. + // 11. Let density be absent. + // 12. Let future-compat-h be absent. (We're implementing it now as h) + w, d, h, i, + candidate = {}, + desc, lastChar, value, intVal, floatVal; + + // 13. For each descriptor in descriptors, run the appropriate set of steps + // from the following list: + for (i = 0; i < descriptors.length; i++) { + desc = descriptors[i]; + + lastChar = desc[desc.length - 1]; + value = desc.substring(0, desc.length - 1); + intVal = parseInt(value, 10); + floatVal = parseFloat(value); + + // If the descriptor consists of a valid non-negative integer followed by + // a U+0077 LATIN SMALL LETTER W character + if (regexNonNegativeInteger.test(value) && (lastChar === "w")) { + + // If width and density are not both absent, then let error be yes. + if (w || d) { + pError = true; } - if ( picImg.src === bestCandidate.url ) { - setSize( picImg, urlCache[bestCandidate.url], bestCandidate.resolution ); - } - picImg = null; - img.onload = null; - img = null; - }; - img.src = bestCandidate.url; - } - }; - })(); + // Apply the rules for parsing non-negative integers to the descriptor. + // If the result is zero, let error be yes. + // Otherwise, let width be the result. + if (intVal === 0) { + pError = true; + } else { + w = intVal; + } - pf.applyBestCandidate = function( candidates, picImg ) { - var candidate, - length, - bestCandidate; + // If the descriptor consists of a valid floating-point number followed by + // a U+0078 LATIN SMALL LETTER X character + } else if (regexFloatingPoint.test(value) && (lastChar === "x")) { - candidates.sort( pf.ascendingSort ); + // If width, density and future-compat-h are not all absent, then let error + // be yes. + if (w || d || h) { + pError = true; + } - length = candidates.length; - bestCandidate = candidates[ length - 1 ]; + // Apply the rules for parsing floating-point number values to the descriptor. + // If the result is less than zero, let error be yes. Otherwise, let density + // be the result. + if (floatVal < 0) { + pError = true; + } else { + d = floatVal; + } - for ( var i = 0; i < length; i++ ) { - candidate = candidates[ i ]; - if ( candidate.resolution >= pf.getDpr() ) { - bestCandidate = candidate; - break; - } - } + // If the descriptor consists of a valid non-negative integer followed by + // a U+0068 LATIN SMALL LETTER H character + } else if (regexNonNegativeInteger.test(value) && (lastChar === "h")) { - if ( bestCandidate ) { + // If height and density are not both absent, then let error be yes. + if (h || d) { + pError = true; + } - bestCandidate.url = pf.makeUrl( bestCandidate.url ); + // Apply the rules for parsing non-negative integers to the descriptor. + // If the result is zero, let error be yes. Otherwise, let future-compat-h + // be the result. + if (intVal === 0) { + pError = true; + } else { + h = intVal; + } - if ( picImg.src !== bestCandidate.url ) { - if ( pf.restrictsMixedContent() && bestCandidate.url.substr(0, "http:".length).toLowerCase() === "http:" ) { - if ( window.console !== undefined ) { - console.warn( "Blocked mixed content image " + bestCandidate.url ); - } - } else { - picImg.src = bestCandidate.url; - // currentSrc attribute and property to match - // http://picture.responsiveimages.org/#the-img-element - picImg.currentSrc = picImg.src; + // Anything else, Let error be yes. + } else { + pError = true; + } + } // (close step 13 for loop) - pf.backfaceVisibilityFix( picImg ); - } - } + // 15. If error is still no, then append a new image source to candidates whose + // URL is url, associated with a width width if not absent and a pixel + // density density if not absent. Otherwise, there is a parse error. + if (!pError) { + candidate.url = url; - pf.setIntrinsicSize(picImg, bestCandidate); - } - }; + if (w) { + candidate.w = w; + } + if (d) { + candidate.d = d; + } + if (h) { + candidate.h = h; + } + if (!h && !d && !w) { + candidate.d = 1; + } + if (candidate.d === 1) { + set.has1x = true; + } + candidate.set = set; - pf.ascendingSort = function( a, b ) { - return a.resolution - b.resolution; - }; + candidates.push(candidate); + } + } // (close parseDescriptors fn) - /** - * In IE9, elements get removed if they aren't children of - * video elements. Thus, we conditionally wrap source elements - * using - * and must account for that here by moving those source elements - * back into the picture element. - */ - pf.removeVideoShim = function( picture ) { - var videos = picture.getElementsByTagName( "video" ); - if ( videos.length ) { - var video = videos[ 0 ], - vsources = video.getElementsByTagName( "source" ); - while ( vsources.length ) { - picture.insertBefore( vsources[ 0 ], video ); - } - // Remove the video element once we're finished removing its children - video.parentNode.removeChild( video ); - } - }; + /** + * Tokenizes descriptor properties prior to parsing + * Returns undefined. + * (Again, this fn is defined before it is used, in order to pass JSHINT. + * Unfortunately this breaks the logical sequencing of the spec comments. :/ ) + */ + function tokenize() { - /** - * Find all `img` elements, and add them to the candidate list if they have - * a `picture` parent, a `sizes` attribute in basic `srcset` supporting browsers, - * a `srcset` attribute at all, and they haven’t been evaluated already. - */ - pf.getAllElements = function() { - var elems = [], - imgs = doc.getElementsByTagName( "img" ); + // 8.1. Descriptor tokeniser: Skip whitespace + collectCharacters(regexLeadingSpaces); - for ( var h = 0, len = imgs.length; h < len; h++ ) { - var currImg = imgs[ h ]; + // 8.2. Let current descriptor be the empty string. + currentDescriptor = ""; - if ( currImg.parentNode.nodeName.toUpperCase() === "PICTURE" || - ( currImg.getAttribute( "srcset" ) !== null ) || currImg[ pf.ns ] && currImg[ pf.ns ].srcset !== null ) { - elems.push( currImg ); - } - } - return elems; - }; + // 8.3. Let state be in descriptor. + state = "in descriptor"; - pf.getMatch = function( img, picture ) { - var sources = picture.childNodes, - match; + while (true) { - // Go through each child, and if they have media queries, evaluate them - for ( var j = 0, slen = sources.length; j < slen; j++ ) { - var source = sources[ j ]; + // 8.4. Let c be the character at position. + c = input.charAt(pos); - // ignore non-element nodes - if ( source.nodeType !== 1 ) { - continue; - } + // Do the following depending on the value of state. + // For the purpose of this step, "EOF" is a special character representing + // that position is past the end of input. - // Hitting the `img` element that started everything stops the search for `sources`. - // If no previous `source` matches, the `img` itself is evaluated later. - if ( source === img ) { - return match; - } + // In descriptor + if (state === "in descriptor") { + // Do the following, depending on the value of c: - // ignore non-`source` nodes - if ( source.nodeName.toUpperCase() !== "SOURCE" ) { - continue; - } - // if it's a source element that has the `src` property set, throw a warning in the console - if ( source.getAttribute( "src" ) !== null && typeof console !== undefined ) { - console.warn("The `src` attribute is invalid on `picture` `source` element; instead, use `srcset`."); - } + // Space character + // If current descriptor is not empty, append current descriptor to + // descriptors and let current descriptor be the empty string. + // Set state to after descriptor. + if (isSpace(c)) { + if (currentDescriptor) { + descriptors.push(currentDescriptor); + currentDescriptor = ""; + state = "after descriptor"; + } - var media = source.getAttribute( "media" ); + // U+002C COMMA (,) + // Advance position to the next character in input. If current descriptor + // is not empty, append current descriptor to descriptors. Jump to the step + // labeled descriptor parser. + } else if (c === ",") { + pos += 1; + if (currentDescriptor) { + descriptors.push(currentDescriptor); + } + parseDescriptors(); + return; - // if source does not have a srcset attribute, skip - if ( !source.getAttribute( "srcset" ) ) { - continue; - } + // U+0028 LEFT PARENTHESIS (() + // Append c to current descriptor. Set state to in parens. + } else if (c === "\u0028") { + currentDescriptor = currentDescriptor + c; + state = "in parens"; - // if there's no media specified, OR w.matchMedia is supported - if ( ( !media || pf.matchesMedia( media ) ) ) { - var typeSupported = pf.verifyTypeSupport( source ); + // EOF + // If current descriptor is not empty, append current descriptor to + // descriptors. Jump to the step labeled descriptor parser. + } else if (c === "") { + if (currentDescriptor) { + descriptors.push(currentDescriptor); + } + parseDescriptors(); + return; - if ( typeSupported === true ) { - match = source; - break; - } else if ( typeSupported === "pending" ) { - return false; - } - } - } + // Anything else + // Append c to current descriptor. + } else { + currentDescriptor = currentDescriptor + c; + } + // (end "in descriptor" - return match; - }; + // In parens + } else if (state === "in parens") { - function picturefill( opt ) { - var elements, - element, - parent, - firstMatch, - candidates, - options = opt || {}; + // U+0029 RIGHT PARENTHESIS ()) + // Append c to current descriptor. Set state to in descriptor. + if (c === ")") { + currentDescriptor = currentDescriptor + c; + state = "in descriptor"; - elements = options.elements || pf.getAllElements(); + // EOF + // Append current descriptor to descriptors. Jump to the step labeled + // descriptor parser. + } else if (c === "") { + descriptors.push(currentDescriptor); + parseDescriptors(); + return; - // Loop through all elements - for ( var i = 0, plen = elements.length; i < plen; i++ ) { - element = elements[ i ]; - parent = element.parentNode; - firstMatch = undefined; - candidates = undefined; + // Anything else + // Append c to current descriptor. + } else { + currentDescriptor = currentDescriptor + c; + } - // immediately skip non-`img` nodes - if ( element.nodeName.toUpperCase() !== "IMG" ) { - continue; - } + // After descriptor + } else if (state === "after descriptor") { - // expando for caching data on the img - if ( !element[ pf.ns ] ) { - element[ pf.ns ] = {}; - } + // Do the following, depending on the value of c: + // Space character: Stay in this state. + if (isSpace(c)) { - // if the element has already been evaluated, skip it unless - // `options.reevaluate` is set to true ( this, for example, - // is set to true when running `picturefill` on `resize` ). - if ( !options.reevaluate && element[ pf.ns ].evaluated ) { - continue; - } + // EOF: Jump to the step labeled descriptor parser. + } else if (c === "") { + parseDescriptors(); + return; - // if `img` is in a `picture` element - if ( parent && parent.nodeName.toUpperCase() === "PICTURE" ) { + // Anything else + // Set state to in descriptor. Set position to the previous character in input. + } else { + state = "in descriptor"; + pos -= 1; - // IE9 video workaround - pf.removeVideoShim( parent ); + } + } - // return the first match which might undefined - // returns false if there is a pending source - // TODO the return type here is brutal, cleanup - firstMatch = pf.getMatch( element, parent ); + // Advance position to the next character in input. + pos += 1; - // if any sources are pending in this picture due to async type test(s) - // remove the evaluated attr and skip for now ( the pending test will - // rerun picturefill on this element when complete) - if ( firstMatch === false ) { - continue; - } - } else { - firstMatch = undefined; - } + // Repeat this step. + } // (close while true loop) + } - // Cache and remove `srcset` if present and we’re going to be doing `picture`/`srcset`/`sizes` polyfilling to it. - if ( ( parent && parent.nodeName.toUpperCase() === "PICTURE" ) || - ( !pf.sizesSupported && ( element.srcset && regWDesc.test( element.srcset ) ) ) ) { - pf.dodgeSrcset( element ); - } + // 4. Splitting loop: Collect a sequence of characters that are space + // characters or U+002C COMMA characters. If any U+002C COMMA characters + // were collected, that is a parse error. + while (true) { + collectCharacters(regexLeadingCommasOrSpaces); - if ( firstMatch ) { - candidates = pf.processSourceSet( firstMatch ); - pf.applyBestCandidate( candidates, element ); - } else { - // No sources matched, so we’re down to processing the inner `img` as a source. - candidates = pf.processSourceSet( element ); + // 5. If position is past the end of input, return candidates and abort these steps. + if (pos >= inputLength) { + return candidates; // (we're done, this is the sole return path) + } - if ( element.srcset === undefined || element[ pf.ns ].srcset ) { - // Either `srcset` is completely unsupported, or we need to polyfill `sizes` functionality. - pf.applyBestCandidate( candidates, element ); - } // Else, resolution-only `srcset` is supported natively. - } + // 6. Collect a sequence of characters that are not space characters, + // and let that be url. + url = collectCharacters(regexLeadingNotSpaces); - // set evaluated to true to avoid unnecessary reparsing - element[ pf.ns ].evaluated = true; - } - } + // 7. Let descriptors be a new empty list. + descriptors = []; - /** - * Sets up picture polyfill by polling the document and running - * the polyfill every 250ms until the document is ready. - * Also attaches picturefill on resize - */ - function runPicturefill() { - pf.initTypeDetects(); - picturefill(); - var intervalId = setInterval( function() { - // When the document has finished loading, stop checking for new images - // https://github.com/ded/domready/blob/master/ready.js#L15 - picturefill(); + // 8. If url ends with a U+002C COMMA character (,), follow these substeps: + // (1). Remove all trailing U+002C COMMA characters from url. If this removed + // more than one character, that is a parse error. + if (url.slice(-1) === ",") { + url = url.replace(regexTrailingCommas, ""); + // (Jump ahead to step 9 to skip tokenization and just push the candidate). + parseDescriptors(); - if ( /^loaded|^i|^c/.test( doc.readyState ) ) { - clearInterval( intervalId ); - return; - } - }, 250 ); + // Otherwise, follow these substeps: + } else { + tokenize(); + } // (close else of step 8) - function checkResize() { - var resizeThrottle; + // 16. Return to the step labeled splitting loop. + } // (Close of big while loop.) + } - if ( !w._picturefillWorking ) { - w._picturefillWorking = true; - w.clearTimeout( resizeThrottle ); - resizeThrottle = w.setTimeout( function() { - picturefill({ reevaluate: true }); - w._picturefillWorking = false; - }, 60 ); - } - } + /* + * Sizes Parser + * + * By Alex Bell | MIT License + * + * Non-strict but accurate and lightweight JS Parser for the string value + * + * Reference algorithm at: + * https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-sizes-attribute + * + * Most comments are copied in directly from the spec + * (except for comments in parens). + * + * Grammar is: + * = # [ , ]? | + * = + * = + * http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-sizes + * + * E.g. "(max-width: 30em) 100vw, (max-width: 50em) 70vw, 100vw" + * or "(min-width: 30em), calc(30vw - 15px)" or just "30vw" + * + * Returns the first valid with a media condition that evaluates to true, + * or "100vw" if all valid media conditions evaluate to false. + * + */ - if ( w.addEventListener ) { - w.addEventListener( "resize", checkResize, false ); - } else if ( w.attachEvent ) { - w.attachEvent( "onresize", checkResize ); - } - } + function parseSizes(strValue) { - runPicturefill(); + // (Percentage CSS lengths are not allowed in this case, to avoid confusion: + // https://html.spec.whatwg.org/multipage/embedded-content.html#valid-source-size-list + // CSS allows a single optional plus or minus sign: + // http://www.w3.org/TR/CSS2/syndata.html#numbers + // CSS is ASCII case-insensitive: + // http://www.w3.org/TR/CSS2/syndata.html#characters ) + // Spec allows exponential notation for type: + // http://dev.w3.org/csswg/css-values/#numbers + var regexCssLengthWithUnits = /^(?:[+-]?[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?(?:ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmin|vmax|vw)$/i; - /* expose methods for testing */ - picturefill._ = pf; + // (This is a quick and lenient test. Because of optional unlimited-depth internal + // grouping parens and strict spacing rules, this could get very complicated.) + var regexCssCalc = /^calc\((?:[0-9a-z \.\+\-\*\/\(\)]+)\)$/i; - expose( picturefill ); + var i; + var unparsedSizesList; + var unparsedSizesListLength; + var unparsedSize; + var lastComponentValue; + var size; -} )( window, window.document, new window.Image() ); + // UTILITY FUNCTIONS + + // (Toy CSS parser. The goals here are: + // 1) expansive test coverage without the weight of a full CSS parser. + // 2) Avoiding regex wherever convenient. + // Quick tests: http://jsfiddle.net/gtntL4gr/3/ + // Returns an array of arrays.) + function parseComponentValues(str) { + var chrctr; + var component = ""; + var componentArray = []; + var listArray = []; + var parenDepth = 0; + var pos = 0; + var inComment = false; + + function pushComponent() { + if (component) { + componentArray.push(component); + component = ""; + } + } + + function pushComponentArray() { + if (componentArray[0]) { + listArray.push(componentArray); + componentArray = []; + } + } + + // (Loop forwards from the beginning of the string.) + while (true) { + chrctr = str.charAt(pos); + + if (chrctr === "") { // ( End of string reached.) + pushComponent(); + pushComponentArray(); + return listArray; + } else if (inComment) { + if ((chrctr === "*") && (str[pos + 1] === "/")) { // (At end of a comment.) + inComment = false; + pos += 2; + pushComponent(); + continue; + } else { + pos += 1; // (Skip all characters inside comments.) + continue; + } + } else if (isSpace(chrctr)) { + // (If previous character in loop was also a space, or if + // at the beginning of the string, do not add space char to + // component.) + if ((str.charAt(pos - 1) && isSpace(str.charAt(pos - 1)) ) || !component) { + pos += 1; + continue; + } else if (parenDepth === 0) { + pushComponent(); + pos += 1; + continue; + } else { + // (Replace any space character with a plain space for legibility.) + chrctr = " "; + } + } else if (chrctr === "(") { + parenDepth += 1; + } else if (chrctr === ")") { + parenDepth -= 1; + } else if (chrctr === ",") { + pushComponent(); + pushComponentArray(); + pos += 1; + continue; + } else if ((chrctr === "/") && (str.charAt(pos + 1) === "*")) { + inComment = true; + pos += 2; + continue; + } + + component = component + chrctr; + pos += 1; + } + } + + function isValidNonNegativeSourceSizeValue(s) { + if (regexCssLengthWithUnits.test(s) && (parseFloat(s) >= 0)) { + return true; + } + if (regexCssCalc.test(s)) { + return true; + } + // ( http://www.w3.org/TR/CSS2/syndata.html#numbers says: + // "-0 is equivalent to 0 and is not a negative number." which means that + // unitless zero and unitless negative zero must be accepted as special cases.) + if ((s === "0") || (s === "-0") || (s === "+0")) { + return true; + } + return false; + } + + // When asked to parse a sizes attribute from an element, parse a + // comma-separated list of component values from the value of the element's + // sizes attribute (or the empty string, if the attribute is absent), and let + // unparsed sizes list be the result. + // http://dev.w3.org/csswg/css-syntax/#parse-comma-separated-list-of-component-values + + unparsedSizesList = parseComponentValues(strValue); + unparsedSizesListLength = unparsedSizesList.length; + + // For each unparsed size in unparsed sizes list: + for (i = 0; i < unparsedSizesListLength; i++) { + unparsedSize = unparsedSizesList[i]; + + // 1. Remove all consecutive s from the end of unparsed size. + // ( parseComponentValues() already omits spaces outside of parens. ) + + // If unparsed size is now empty, that is a parse error; continue to the next + // iteration of this algorithm. + // ( parseComponentValues() won't push an empty array. ) + + // 2. If the last component value in unparsed size is a valid non-negative + // , let size be its value and remove the component value + // from unparsed size. Any CSS function other than the calc() function is + // invalid. Otherwise, there is a parse error; continue to the next iteration + // of this algorithm. + // http://dev.w3.org/csswg/css-syntax/#parse-component-value + lastComponentValue = unparsedSize[unparsedSize.length - 1]; + + if (isValidNonNegativeSourceSizeValue(lastComponentValue)) { + size = lastComponentValue; + unparsedSize.pop(); + } else { + continue; + } + + // 3. Remove all consecutive s from the end of unparsed + // size. If unparsed size is now empty, return size and exit this algorithm. + // If this was not the last item in unparsed sizes list, that is a parse error. + if (unparsedSize.length === 0) { + return size; + } + + // 4. Parse the remaining component values in unparsed size as a + // . If it does not parse correctly, or it does parse + // correctly but the evaluates to false, continue to the + // next iteration of this algorithm. + // (Parsing all possible compound media conditions in JS is heavy, complicated, + // and the payoff is unclear. Is there ever an situation where the + // media condition parses incorrectly but still somehow evaluates to true? + // Can we just rely on the browser/polyfill to do it?) + unparsedSize = unparsedSize.join(" "); + if (!(pf.matchesMedia(unparsedSize) )) { + continue; + } + + // 5. Return size and exit this algorithm. + return size; + } + + // If the above algorithm exhausts unparsed sizes list without returning a + // size value, return 100vw. + return "100vw"; + } + + // namespace + pf.ns = ("pf" + new Date().getTime()).substr(0, 9); + + // srcset support test + pf.supSrcset = "srcset" in image; + pf.supSizes = "sizes" in image; + pf.supPicture = !!window.HTMLPictureElement; + + // UC browser does claim to support srcset and picture, but not sizes, + // this extended test reveals the browser does support nothing + if (pf.supSrcset && pf.supPicture && !pf.supSizes) { + (function (image2) { + image.srcset = "data:,a"; + image2.src = "data:,a"; + pf.supSrcset = image.complete === image2.complete; + pf.supPicture = pf.supSrcset && pf.supPicture; + })(document.createElement("img")); + } + + // Safari9 has basic support for sizes, but does't expose the `sizes` idl attribute + if (pf.supSrcset && !pf.supSizes) { + + (function () { + var width2 = "data:image/gif;base64,R0lGODlhAgABAPAAAP///wAAACH5BAAAAAAALAAAAAACAAEAAAICBAoAOw=="; + var width1 = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + var img = document.createElement("img"); + var test = function () { + var width = img.width; + + if (width === 2) { + pf.supSizes = true; + } + + alwaysCheckWDescriptor = pf.supSrcset && !pf.supSizes; + + isSupportTestReady = true; + // force async + setTimeout(picturefill); + }; + + img.onload = test; + img.onerror = test; + img.setAttribute("sizes", "9px"); + + img.srcset = width1 + " 1w," + width2 + " 9w"; + img.src = width1; + })(); + + } else { + isSupportTestReady = true; + } + + // using pf.qsa instead of dom traversing does scale much better, + // especially on sites mixing responsive and non-responsive images + pf.selShort = "picture>img,img[srcset]"; + pf.sel = pf.selShort; + pf.cfg = cfg; + + /** + * Shortcut property for `devicePixelRatio` ( for easy overriding in tests ) + */ + pf.DPR = (DPR || 1 ); + pf.u = units; + + // container of supported mime types that one might need to qualify before using + pf.types = types; + + pf.setSize = noop; + + /** + * Gets a string and returns the absolute URL + * @param src + * @returns {String} absolute URL + */ + + pf.makeUrl = memoize(function (src) { + anchor.href = src; + return anchor.href; + }); + + /** + * Gets a DOM element or document and a selctor and returns the found matches + * Can be extended with jQuery/Sizzle for IE7 support + * @param context + * @param sel + * @returns {NodeList|Array} + */ + pf.qsa = function (context, sel) { + return ( "querySelector" in context ) ? context.querySelectorAll(sel) : []; + }; + + /** + * Shortcut method for matchMedia ( for easy overriding in tests ) + * wether native or pf.mMQ is used will be decided lazy on first call + * @returns {boolean} + */ + pf.matchesMedia = function () { + if (window.matchMedia && (matchMedia("(min-width: 0.1em)") || {}).matches) { + pf.matchesMedia = function (media) { + return !media || ( matchMedia(media).matches ); + }; + } else { + pf.matchesMedia = pf.mMQ; + } + + return pf.matchesMedia.apply(this, arguments); + }; + + /** + * A simplified matchMedia implementation for IE8 and IE9 + * handles only min-width/max-width with px or em values + * @param media + * @returns {boolean} + */ + pf.mMQ = function (media) { + return media ? evalCSS(media) : true; + }; + + /** + * Returns the calculated length in css pixel from the given sourceSizeValue + * http://dev.w3.org/csswg/css-values-3/#length-value + * intended Spec mismatches: + * * Does not check for invalid use of CSS functions + * * Does handle a computed length of 0 the same as a negative and therefore invalid value + * @param sourceSizeValue + * @returns {Number} + */ + pf.calcLength = function (sourceSizeValue) { + + var value = evalCSS(sourceSizeValue, true) || false; + if (value < 0) { + value = false; + } + + return value; + }; + + /** + * Takes a type string and checks if its supported + */ + + pf.supportsType = function (type) { + return ( type ) ? types[type] : true; + }; + + /** + * Parses a sourceSize into mediaCondition (media) and sourceSizeValue (length) + * @param sourceSizeStr + * @returns {*} + */ + pf.parseSize = memoize(function (sourceSizeStr) { + var match = ( sourceSizeStr || "" ).match(regSize); + return { + media: match && match[1], + length: match && match[2] + }; + }); + + pf.parseSet = function (set) { + if (!set.cands) { + set.cands = parseSrcset(set.srcset, set); + } + return set.cands; + }; + + /** + * returns 1em in css px for html/body default size + * function taken from respondjs + * @returns {*|number} + */ + pf.getEmValue = function () { + var body; + if (!eminpx && (body = document.body)) { + var div = document.createElement("div"), + originalHTMLCSS = docElem.style.cssText, + originalBodyCSS = body.style.cssText; + + div.style.cssText = baseStyle; + + // 1em in a media query is the value of the default font size of the browser + // reset docElem and body to ensure the correct value is returned + docElem.style.cssText = fsCss; + body.style.cssText = fsCss; + + body.appendChild(div); + eminpx = div.offsetWidth; + body.removeChild(div); + + //also update eminpx before returning + eminpx = parseFloat(eminpx, 10); + + // restore the original values + docElem.style.cssText = originalHTMLCSS; + body.style.cssText = originalBodyCSS; + + } + return eminpx || 16; + }; + + /** + * Takes a string of sizes and returns the width in pixels as a number + */ + pf.calcListLength = function (sourceSizeListStr) { + // Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33% + // + // or (min-width:30em) calc(30% - 15px) + if (!(sourceSizeListStr in sizeLengthCache) || cfg.uT) { + var winningLength = pf.calcLength(parseSizes(sourceSizeListStr)); + + sizeLengthCache[sourceSizeListStr] = !winningLength ? units.width : winningLength; + } + + return sizeLengthCache[sourceSizeListStr]; + }; + + /** + * Takes a candidate object with a srcset property in the form of url/ + * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or + * "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or + * "images/pic-small.png" + * Get an array of image candidates in the form of + * {url: "/foo/bar.png", resolution: 1} + * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value + * If sizes is specified, res is calculated + */ + pf.setRes = function (set) { + var candidates; + if (set) { + + candidates = pf.parseSet(set); + + for (var i = 0, len = candidates.length; i < len; i++) { + setResolution(candidates[i], set.sizes); + } + } + return candidates; + }; + + pf.setRes.res = setResolution; + + pf.applySetCandidate = function (candidates, img) { + if (!candidates.length) { + return; + } + var candidate, + i, + j, + length, + bestCandidate, + curSrc, + curCan, + candidateSrc, + abortCurSrc; + + var imageData = img[pf.ns]; + var dpr = pf.DPR; + + curSrc = imageData.curSrc || img[curSrcProp]; + + curCan = imageData.curCan || setSrcToCur(img, curSrc, candidates[0].set); + + // if we have a current source, we might either become lazy or give this source some advantage + if (curCan && curCan.set === candidates[0].set) { + + // if browser can abort image request and the image has a higher pixel density than needed + // and this image isn't downloaded yet, we skip next part and try to save bandwidth + abortCurSrc = (supportAbort && !img.complete && curCan.res - 0.1 > dpr); + + if (!abortCurSrc) { + curCan.cached = true; + + // if current candidate is "best", "better" or "okay", + // set it to bestCandidate + if (curCan.res >= dpr) { + bestCandidate = curCan; + } + } + } + + if (!bestCandidate) { + + candidates.sort(ascendingSort); + + length = candidates.length; + bestCandidate = candidates[length - 1]; + + for (i = 0; i < length; i++) { + candidate = candidates[i]; + if (candidate.res >= dpr) { + j = i - 1; + + // we have found the perfect candidate, + // but let's improve this a little bit with some assumptions ;-) + if (candidates[j] && + (abortCurSrc || curSrc !== pf.makeUrl(candidate.url)) && + chooseLowRes(candidates[j].res, candidate.res, dpr, candidates[j].cached)) { + + bestCandidate = candidates[j]; + + } else { + bestCandidate = candidate; + } + break; + } + } + } + + if (bestCandidate) { + + candidateSrc = pf.makeUrl(bestCandidate.url); + + imageData.curSrc = candidateSrc; + imageData.curCan = bestCandidate; + + if (candidateSrc !== curSrc) { + pf.setSrc(img, bestCandidate); + } + pf.setSize(img); + } + }; + + pf.setSrc = function (img, bestCandidate) { + var origWidth; + img.src = bestCandidate.url; + + // although this is a specific Safari issue, we don't want to take too much different code paths + if (bestCandidate.set.type === "image/svg+xml") { + origWidth = img.style.width; + img.style.width = (img.offsetWidth + 1) + "px"; + + // next line only should trigger a repaint + // if... is only done to trick dead code removal + if (img.offsetWidth + 1) { + img.style.width = origWidth; + } + } + }; + + pf.getSet = function (img) { + var i, set, supportsType; + var match = false; + var sets = img [pf.ns].sets; + + for (i = 0; i < sets.length && !match; i++) { + set = sets[i]; + + if (!set.srcset || !pf.matchesMedia(set.media) || !(supportsType = pf.supportsType(set.type))) { + continue; + } + + if (supportsType === "pending") { + set = supportsType; + } + + match = set; + break; + } + + return match; + }; + + pf.parseSets = function (element, parent, options) { + var srcsetAttribute, imageSet, isWDescripor, srcsetParsed; + + var hasPicture = parent && parent.nodeName.toUpperCase() === "PICTURE"; + var imageData = element[pf.ns]; + + if (imageData.src === undefined || options.src) { + imageData.src = getImgAttr.call(element, "src"); + if (imageData.src) { + setImgAttr.call(element, srcAttr, imageData.src); + } else { + removeImgAttr.call(element, srcAttr); + } + } + + if (imageData.srcset === undefined || options.srcset || !pf.supSrcset || element.srcset) { + srcsetAttribute = getImgAttr.call(element, "srcset"); + imageData.srcset = srcsetAttribute; + srcsetParsed = true; + } + + imageData.sets = []; + + if (hasPicture) { + imageData.pic = true; + getAllSourceElements(parent, imageData.sets); + } + + if (imageData.srcset) { + imageSet = { + srcset: imageData.srcset, + sizes: getImgAttr.call(element, "sizes") + }; + + imageData.sets.push(imageSet); + + isWDescripor = (alwaysCheckWDescriptor || imageData.src) && regWDesc.test(imageData.srcset || ""); + + // add normal src as candidate, if source has no w descriptor + if (!isWDescripor && imageData.src && !getCandidateForSrc(imageData.src, imageSet) && !imageSet.has1x) { + imageSet.srcset += ", " + imageData.src; + imageSet.cands.push({ + url: imageData.src, + d: 1, + set: imageSet + }); + } + + } else if (imageData.src) { + imageData.sets.push({ + srcset: imageData.src, + sizes: null + }); + } + + imageData.curCan = null; + imageData.curSrc = undefined; + + // if img has picture or the srcset was removed or has a srcset and does not support srcset at all + // or has a w descriptor (and does not support sizes) set support to false to evaluate + imageData.supported = !( hasPicture || ( imageSet && !pf.supSrcset ) || (isWDescripor && !pf.supSizes) ); + + if (srcsetParsed && pf.supSrcset && !imageData.supported) { + if (srcsetAttribute) { + setImgAttr.call(element, srcsetAttr, srcsetAttribute); + element.srcset = ""; + } else { + removeImgAttr.call(element, srcsetAttr); + } + } + + if (imageData.supported && !imageData.srcset && ((!imageData.src && element.src) || element.src !== pf.makeUrl(imageData.src))) { + if (imageData.src === null) { + element.removeAttribute("src"); + } else { + element.src = imageData.src; + } + } + + imageData.parsed = true; + }; + + pf.fillImg = function (element, options) { + var imageData; + var extreme = options.reselect || options.reevaluate; + + // expando for caching data on the img + if (!element[pf.ns]) { + element[pf.ns] = {}; + } + + imageData = element[pf.ns]; + + // if the element has already been evaluated, skip it + // unless `options.reevaluate` is set to true ( this, for example, + // is set to true when running `picturefill` on `resize` ). + if (!extreme && imageData.evaled === evalId) { + return; + } + + if (!imageData.parsed || options.reevaluate) { + pf.parseSets(element, element.parentNode, options); + } + + if (!imageData.supported) { + applyBestCandidate(element); + } else { + imageData.evaled = evalId; + } + }; + + pf.setupRun = function () { + if (!alreadyRun || isVwDirty || (DPR !== window.devicePixelRatio)) { + updateMetrics(); + } + }; + + // If picture is supported, well, that's awesome. + if (pf.supPicture) { + picturefill = noop; + pf.fillImg = noop; + } else { + + // Set up picture polyfill by polling the document + (function () { + var isDomReady; + var regReady = window.attachEvent ? /d$|^c/ : /d$|^c|^i/; + + var run = function () { + var readyState = document.readyState || ""; + + timerId = setTimeout(run, readyState === "loading" ? 200 : 999); + if (document.body) { + pf.fillImgs(); + isDomReady = isDomReady || regReady.test(readyState); + if (isDomReady) { + clearTimeout(timerId); + } + + } + }; + + var timerId = setTimeout(run, document.body ? 9 : 99); + + // Also attach picturefill on resize and readystatechange + // http://modernjavascript.blogspot.com/2013/08/building-better-debounce.html + var debounce = function (func, wait) { + var timeout, timestamp; + var later = function () { + var last = (new Date()) - timestamp; + + if (last < wait) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + func(); + } + }; + + return function () { + timestamp = new Date(); + + if (!timeout) { + timeout = setTimeout(later, wait); + } + }; + }; + var lastClientWidth = docElem.clientHeight; + var onResize = function () { + isVwDirty = Math.max(window.innerWidth || 0, docElem.clientWidth) !== units.width || docElem.clientHeight !== lastClientWidth; + lastClientWidth = docElem.clientHeight; + if (isVwDirty) { + pf.fillImgs(); + } + }; + + on(window, "resize", debounce(onResize, 99)); + on(document, "readystatechange", run); + })(); + } + + pf.picturefill = picturefill; + //use this internally for easy monkey patching/performance testing + pf.fillImgs = picturefill; + pf.teardownRun = noop; + + /* expose methods for testing */ + picturefill._ = pf; + + window.picturefillCFG = { + pf: pf, + push: function (args) { + var name = args.shift(); + if (typeof pf[name] === "function") { + pf[name].apply(pf, args); + } else { + cfg[name] = args[0]; + if (alreadyRun) { + pf.fillImgs({reselect: true}); + } + } + } + }; + + while (setOptions && setOptions.length) { + window.picturefillCFG.push(setOptions.shift()); + } + + /* expose picturefill */ + window.picturefill = picturefill; + + /* expose picturefill */ + if (typeof module === "object" && typeof module.exports === "object") { + // CommonJS, just export + module.exports = picturefill; + } else if (typeof define === "function" && define.amd) { + // AMD support + define("picturefill", function () { + return picturefill; + }); + } + + // IE8 evals this sync, so it must be the last thing we do + if (!pf.supPicture) { + types["image/webp"] = detectTypeSupport("image/webp", "data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA=="); + } + +})(window, document); /*! jQuery v2.2.0 | (c) jQuery Foundation | jquery.org/license */ !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!k.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c}catch(e){}O.set(a,b,c); @@ -2467,7 +3318,7 @@ window.matchMedia || (window.matchMedia = function() { |___/_|_|\___|_|\_(_)/ |___/ |__/ - Version: 1.4.1 + Version: 1.6.0 Author: Ken Wheeler Website: http://kenwheeler.github.io Docs: http://kenwheeler.github.io/slick @@ -2475,9 +3326,7 @@ window.matchMedia || (window.matchMedia = function() { Issues: http://github.com/kenwheeler/slick/issues */ - /* global window, document, define, jQuery, setInterval, clearInterval */ - (function(factory) { 'use strict'; if (typeof define === 'function' && define.amd) { @@ -2498,8 +3347,7 @@ window.matchMedia || (window.matchMedia = function() { function Slick(element, settings) { - var _ = this, - dataSettings, responsiveSettings, breakpoint; + var _ = this, dataSettings; _.defaults = { accessibility: true, @@ -2508,15 +3356,15 @@ window.matchMedia || (window.matchMedia = function() { appendDots: $(element), arrows: true, asNavFor: null, - prevArrow: '', - nextArrow: '', + prevArrow: '', + nextArrow: '', autoplay: false, autoplaySpeed: 3000, centerMode: false, centerPadding: '50px', cssEase: 'ease', customPaging: function(slider, i) { - return ''; + return $('