diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..17906fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Editor +.vscode +!tools/.vscode + +# Releases +release + +# Tool cache +__pycache__ + +# Arma +mission.sqm +!framework/rsc/loadouts/!*.sqf +framework/rsc/loadouts/*.sqf +framework/rsc/scripts/*.sqf + +# Todos and changelogs +TODO.md +CHANGELOG.md + +# template files +framework/components/_blank +framework/components/*/functions/fn_empty.sqf \ No newline at end of file diff --git a/extras/blank/XEH_playerInit.sqf b/extras/blank/XEH_playerInit.sqf new file mode 100644 index 0000000..421c54b --- /dev/null +++ b/extras/blank/XEH_playerInit.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" diff --git a/extras/blank/XEH_postInit.sqf b/extras/blank/XEH_postInit.sqf new file mode 100644 index 0000000..421c54b --- /dev/null +++ b/extras/blank/XEH_postInit.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" diff --git a/extras/blank/XEH_preInit.sqf b/extras/blank/XEH_preInit.sqf new file mode 100644 index 0000000..421c54b --- /dev/null +++ b/extras/blank/XEH_preInit.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" diff --git a/extras/blank/XEH_serverInit.sqf b/extras/blank/XEH_serverInit.sqf new file mode 100644 index 0000000..421c54b --- /dev/null +++ b/extras/blank/XEH_serverInit.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" diff --git a/extras/blank/fn_empty.sqf b/extras/blank/functions/fn_empty.sqf similarity index 97% rename from extras/blank/fn_empty.sqf rename to extras/blank/functions/fn_empty.sqf index eab21d5..726d666 100644 --- a/extras/blank/fn_empty.sqf +++ b/extras/blank/functions/fn_empty.sqf @@ -1,3 +1,3 @@ -#include "script_component.hpp" - +#include "script_component.hpp" + diag_log text format ["This is here as an example!!!"]; \ No newline at end of file diff --git a/extras/blank/functions/script_component.hpp b/extras/blank/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/extras/blank/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/TODO.md b/framework/TODO.md new file mode 100644 index 0000000..1a51268 --- /dev/null +++ b/framework/TODO.md @@ -0,0 +1,146 @@ +# TODO LIST + +## enhancedVehicles + - [X] Fuel leaks when tank isn't leaking + - [X] If the leaking vehicle is type car light the crew on fire as well + - [X] Hard lag when entering a vehicle (issue with viewdistance, just get niggas to unfuck their settings) + - [ ] Offroad should be made clientside for the player, stop it from running for AI aswell + - [X] Chance of being lit on fire if engine is kill or fuel is kill + - [X] Move autoinit into init + - [X] Disable engineOn when vehicle gets disabled + - [ ] Add Portable fuel canisters (and spawn them in vehicles, should add the space i takes to not make vehicle cargo small) + - [ ] Add function to rename vehicle, auto assign name if vehicle is assigned squad + +## utility + - [X] clearVehicleCargo clears ammocrates as well + - [ ] Remove in favor of common or other categories + +## logistics (new category) + - [X] Make crate names show when looking at crate (update name in ACE cargo aswell) + - [ ] Make a virtual arsenal crate filling tool (just use kosher arsenal but set the target to the crate rather than the player's inventory containers) + (due to the inherent way kosher arsenal works, the arsenal would be locked to your role) + - [ ] Set default names for certain crates (fireteam crate, medical crate) + - [X] Create resupply crates from loadoutfile function. + - [X] Create a crate spawner + - [ ] Look into overriding vehicle cargo crate naming + +## 3den + - [X] Finish the mission data tool (split general mission data and warno) + - [X] Maybe finish the config tool (might be a bit too much work rn) + - [ ] Add categories and icons for all 3den tools + - [ ] Add tool to assign vehicle to group (for TO&E) + - [ ] Fix Bug where the unitspawner infantry squads prefers to start at charlie rather than alpha + - [ ] Add icons for HMG, MMG, MAT and HAT and all ground and air vehicles (remove CUP dependency) + - [X] Add icons for gametypes + - [ ] Add gametype to briefingName (3den name attribute) + - [X] Add gametype icon to overview picture + - [ ] Add WARNO situation to overview text + - [ ] Create resupply crates from loadoutfile function. + - [ ] Kosher Arsenal Loadout Tool, change out list classes for custom class inherited from: https://github.com/acemod/ACE3/blob/master/addons/arsenal/ui/RscAttributes.hpp. + (CT_LISTNBOX can take a idc on left or right side, put checkbox on right side) +- [ ] Move 3DEN Entity Tools to it's own component called 3den_tools +- [X] Extend warno to include a callsign table in Command and Signal +- [X] Create function to display warning order in mission +- [ ] Enable consistent marker in 3den +- [ ] Checklist and validation when mission gets exported (e.g. warning if no repsawn was added) +- [ ] Rename functions again to make more sense and move some of the stuff in init.sqf to postInit + +## kosherArsenal + - [ ] Loadout validity test (so when something is wrong it will throw a proper stacktrace) + +## AI + - [X] Create an eventhandler to put ai in the panic action when on fire + - [X] Silence AI once and for all + - [X] Make transferToServer apply to all AI on init (cba_fnc_addEventhandlerToClass) + - [ ] Automatically call artillery on called out units using taskArtillery from lambs + - [X] Maybe use taskCreep rather than taskRush + +## kosherAI + - [ ] Update kosherAI to hash the config data it grabs + - [X] Sometimes spawns without magazines on dedicated server + - [X] Sometimes failes to remove handguns and facewear on dedicated server + - [X] Switches to binoculars or secondary instead of primary after loadout has ben set + +## main + - [X] hide chat messages: + replace join messages with: "X joined SIDE in GROUP" before game start and "X re-jipped" after game start. After game on: everything else should only be shown to zeus + - [X] Chat message needs to handle multi word names (trim away the first and last element in splitString) + - [X] Call loading bug fix automatically if player is in respawn menu with loading screen + - [X] Show changelog when a newer version is available for player + - [X] ACRE2 down mute not working, radio works, but proximity doesn't + - [X] Make a warning order file (and look into a way of parsing it to display on a webpage) + - [ ] Add https://community.bistudio.com/wiki/BIS_fnc_functionsDebug to debugging + - [X] Add ScriptError event handler to track script errors in CMF + +## aar (new category) + - [ ] Test diagAAR and see if it does what i want + - [X] AARs should be a part of the game now. submitted AARs should be saved to an array to the target. At the end of the game, everyone gets the chance to write AARs to all, zeus, leader, group or individual players + - [ ] Fix bug where viewing AARs counts wrongly and going left and right doesn't properly work + - [ ] Show notification in spectator for newly submitted AARs + - [ ] Show a count of how many players have submitted an AAR over the amount of players in mission + +## Organization (new category) +- [ ] Add dynamic orbat system (assign squad, platoon and company automatically) +- [ ] Remove roster and only have TO&E +- [ ] Make TO&E static and only update it on JIP +- [ ] Weather diary should be static, never update. Only get how it was at mission start +- [ ] ORBAT Command & Signal should link to TO&E Diary +- [ ] Comms plan diary, should auto generate based on player teams, link in Command & Signal + +## gameplay + - [X] safestart briefing phase isn't showing up at 8pm anymore + - [ ] Replace custom mission name decode function with this: https://cbateam.github.io/CBA_A3/docs/files/strings/fnc_decodeURL-sqf.html#CBA_fnc_decodeURL + - [X] disable autocombat on all AI when safestart is enabled + - [ ] Craters from artillery rounds + - [ ] Fix bug with environment times for twilight + - [X] Fix timezone for safestart + - [X] Freeze time when safestart is enabled (check if freezetime is already enabled, if it isn't do) + - [X] Add automatic safestart phases: Setup Phase (before 7), Overtime Phase (after 8:30) + +## respawn + - [X] Ping SL for rallypoint from respawn menu + - [ ] Make vehicle into rallypoint + +## common + - [ ] setCallsign ranks don't work since the playerObject doesn't exist at serverinit, maybe move ranking to player init and just check what ranks should be given based on the group + - [X] Move ranks to the unit spawner in 3den and remove the CMF_ORBAT section from cmf_config + - [X] Also add function to set keybinds similar to addSetting + +## player + - [ ] Find icons for group ace actions + - [X] Group ACE actions are kinda broken for team selection, switches when hovered + - [X] Make a projectreality camera shake when firing big guns from vehicles + - [ ] Create camera shake when vehicle is hit by big round + - [ ] When close to a ACE fire create an orange tint based on the fire intensity + - [X] Reset map marker scale when map is closed (to unfuck sizes on ctrlMap controls) + - [x] Treatment messages for patient (fixed in `KAT - Advanced Medical` in next update) + - [ ] Change icon for submitting an AAR from spectator + - [ ] Add button to view submitted AARs after closing + - [ ] markerSize does not get size of zeus markers (wtf BI?) + +## menu + - [ ] Move safestart into an admin menu + - [X] Add diagnostics menu with client and server sub-menu + - [X] Add FPS counter and scripts counters for server and client. https://community.bistudio.com/wiki/diag_activeScripts / https://community.bistudio.com/wiki/diag_fps, https://community.bistudio.com/wiki/getClientState + For server also add info from monitor (players lobby, players role selection, players briefing, players in-game and players debriefing) + - [ ] Add shortest, average and longest frame time using diag_deltaTime + - [ ] Add a AFK function that attaches the player to the closest player (within a max distance), make player invisible, muted and deaf. + If the person attached to dies; player dies + +## cleanup + - [ ] Add Readme to each module + - [ ] Cleanup ui files + - [ ] Follow ACE Code rules and remove sleeps, spawns etc. Get everything unscheduled: + https://ace3.acemod.org/wiki/development/arma-3-scheduler-and-our-practices.html + - [ ] Make sure every string is localized + - [ ] Make sure debug is disabled on everything and that there are no unwanted systemchats + - [ ] Replace custom eventhandlers with CBA ones. (basically remove the spawned waitUntils where i can) holy fuck, "retroactivly": https://cbateam.github.io/CBA_A3/docs/files/xeh/fnc_addClassEventHandler-sqf.html#CBA_fnc_addClassEventHandler + - [ ] Replace all eventhandlers with CBA eventhandlers + - [ ] Consider changing vanilla compile with: https://cbateam.github.io/CBA_A3/docs/files/xeh/fnc_compileFunction-sqf.html + - [ ] Clear scripts, img and loadouts directory of non-cmf files + - [X] Change sound files to .wss file type (arma sound files) + - [ ] Where script is spawned per unit, instead have one spawn that works with an updated array of units + - [ ] Code optimization
https://community.bistudio.com/wiki/Code_Optimisation#Lazy_Evaluation +https://community.bistudio.com/wiki/Code_Optimisation#if_and_switch +https://community.bistudio.com/wiki/Code_Optimisation#objectParent_and_vehicle +https://community.bistudio.com/wiki/Code_Optimisation#Array_Manipulation \ No newline at end of file diff --git a/framework/WARNO.sqf b/framework/WARNO.sqf new file mode 100644 index 0000000..11c2da0 --- /dev/null +++ b/framework/WARNO.sqf @@ -0,0 +1,115 @@ +/* + * Warning order explanation, markdown glossary general information: + * https://wiki.cluster-community.com/index.php?title=CMF3:_Warno#Editing + * + */ + +/* SITUATION */ +[" +## Situation + + +## Enemy Forces +### Composition + + +### Capabilities / Limitations + + +### Most Likely Course of Action + + +### Most Dangerous Course of Action + + +## Friendly Forces +### Adjacent Units + + +### Supporting + + +## Civilian Considerations + + +## Terrain Considerations + +", + +/* MISSION */ +" +## Description + + +## Situation Overview + + +## Objectives + +", + +/* EXECUTION */ +" +## Commander's Intent +### Center of Gravity + + +### Critical Vulnerability + + +### Desired Endstate + + +## Concept of Operations + + +## Scheme of Maneuver + +", + +/* ADMINISTRATION AND LOGISTICS */ +" +## Administration +### Enemy Prisoners of War (EPW) Plan + + +### Casualty Evacuation (CASEVAC) Plan + + +### Support + + +## Logistics +### Supply + + +### Assets + + +### Required Equipment + +", + +/* COMMAND AND SIGNAL */ +" +## Command +### Rules of Engagement + + +### Standard operating procedures + + +### Succession of Command + + +## Signal +### Table of Communications + + +### Callsign Table + +", + +/* WARNO Version (DO NOT CHANGE) */ +"1.0" +]; \ No newline at end of file diff --git a/framework/changelog.md b/framework/changelog.md new file mode 100644 index 0000000..5e3a102 --- /dev/null +++ b/framework/changelog.md @@ -0,0 +1,116 @@ +# Changelog v2.1.1.56 => v2.1.1.57 +## Added +- New diagnostics module +- New settings system +- Notification function +- New viewdistance system (to fix lag with old one) +- Added a RscImports file for UI to keep all imported classes collected +- Added new logging functions +- Added function to get closest match from a array of numbers +- Added function to add keybinds + +## Changed +- Many minor things i no longer remember +- Freezetime is now toggleable +- Safestart will have time frozen until game start +- Changed how keybinds are listed in CMF diary + +## Fixed +- Bug where hideHud wouldn't work with hotkey +- Bug with whitelisted URIs + +## Removed +- Removed old ACE Medical sub category in favor of ace's own category + + + +# Changelog v2.1.0 => v2.1.1 +## Added +- Added CMF Info Diary +- Added gamemode and mission name intro +- Added Function to block looting of own body +- Added function to load state of player before disconnect when reconnecting +- Added function to get a unit's role +- Added function to parse strings with hex codes to ASCII +- Added function to parse CBA Keybinds to human-readable strings +- Added function to get the respawn limit +- Added function to get the remaining respawns +- Added Player Roster Diary +- Added Table of Organization & Equipment for Leaders +- Added chance of fuel leak catching fire in enhancedVehicles +- Added function to restore acre radio configuration on respawn +- Added a variable to track if player has fully loaded +- Added Ace interaction actions to organize team for team leaders +- Added so ACRE audio is muted when player is down +- Added new "player x has connected" message for safestart and re-jip +- Added a way to override safestart +- Added text based AAR system +- Added button to ping rallypoint-capable units to place a rallypoint +- Added ACE Arsenal medical and radio sub-categories to the 3den editor +- Added Logistics component +- Added Function to view crate names +- Added "suicide" bug fix when stuck at [0, 0, 0] +- Added function to set config value +- Added 3den display to set mission data +- Added game type icons +- Added setCombatbehaviour "CARELESS" and setCombatMode "BLUE" during safestart, this will stop AI from engaging targets +- Added DHAT and ANVIL to 3DEN Unit Spawner +- Added Function to display changelog on game start +- Added function to automate ACRE2 Babel languages +- Added so crew gets lit on fire if vehicle is on fire +- Added function to silence friendly AI for good (cmf_ai_fnc_silenceAI) +- Added functions to return angle of sun and time of angle of sun (cmf_utility_fnc_sunAngle and cmf_utility_fnc_getTimeOfSunAngle) +- Added diary for environment (weather and time of twilight and sun set/rise) +- Added function to create camerashake when firing from vehicles (cmf_enhancedVehicles_fnc_gunEffectEH) +- Added functions to add, remove or check a line from the 3den entity init +- Added 3den tool to toggle ace carry on objects +- Added 3den tool to toggle ace drag on objects +- Added 3den tool to write warning orders +- Added function to handle AI Panic (retreat or surrender) +- Added function to display treatment information by remote parties +- Added ability to whitelist/blacklist classes and factions in kosherAI +- Added Config entry for adding flashlights in cmf tracers config +- Added logistical crate definers and spawners +- Added Warning Order Function +- Added unconcious timer +- Added hostage follow script + +## Changed +- Changed safestart to display meta information before mission start +- Fixed kosher arsenal force close bug +- Moved hydration tab into equipment tab +- Force Primary is no longer true by default in kosher arsenal +- Changed default respawns to 2 +- Hearing no longer affects ACRE volume, only in-game volume +- Removed the "Remaining Respawns" message in limitedRespawns +- Fixed bug with "Fix Loading Screen Bug", it should now work again +- Fixed bug with map gesture colors +- Moved all functions in components into a sub directory called "functions" +- Respawns will not be decreased on death during safestart +- Added icons to the 3den CMF Menu +- Renamed Cluster ORBAT unit Spawner to Unit spawner +- Changed kosherArsenal init to use a better method of tracking respawns +- Enable and disable simulation in 3DEN tool has been combined to a toggle tool +- Moved bug fixes into a sub menu +- Fixed dropping while carrying / dragging in safestart phase +- Fixed fortify deploying in safestart phase +- Fixed kosherArsenal Rearm Arsenal Action being accessable from any distance +- Added new KAT Medical items to the medical submenu in ACE arsenal +- Changed getConfigParam to cache config params to a global config CBA Hash +- Added Bodybags to standard medic loadout. +- Changed loadoutfile format to allow for resupply crate generation. +- Moved setRanks into unit constructor +- Reset marker size when the map is closed to fix their scale on GPS or other map controls +- Moved enhancedVehicles Damage Handler and fuel Leak handler to seperate function files (cmf_enhancedVehicles_fnc_damageEH and cmf_enhancedVehicles_fnc_fuelLeakEH) +- Changed transferToServer to use CBA logic in an attempt to enhance performance. +- Renamed 3den functions for better organization. +- Refactored prevent prone to use CBA XEH. +- Changed reinforcing AIs tactic from rush to creep. +- Moved kosherAI into it's own component +- Added crewman, rotary pilot and fixed-wing pilot to possible kosherAI roles +- Majot code cleanup + +## Removed +- Removed the "Display Roles" action from CC Menu, it's replaced by the TO&E Diary Entry +- Removed CMF_ORBAT from cmf_config.hpp +- Removed autoinit from enhancedVehicles (replaced by init) \ No newline at end of file diff --git a/framework/cmf_config.hpp b/framework/cmf_config.hpp deleted file mode 100644 index 74f970f..0000000 --- a/framework/cmf_config.hpp +++ /dev/null @@ -1,115 +0,0 @@ -class CMF { - class SETTINGS { - class player { - switchMapTextures = 1; - hideRespawnMarkers = 1; - consistentMarkers = 1; - restrictLauncher = 1; - - /* Hearing settings */ - class hearing { - enable = 1; - attenuateHeadgear = 1; - earplugsVolume = 0.5; - }; - }; - - /* Gameplay settings */ - class gameplay { - overrideFlashbangs = 1; - - /* safestart settings */ - class safestart { - enable = 1; - delay = 60; - }; - - /* tracers settings */ - class tracers { - enable = 1; - side[] = {"east"}; - }; - }; - - /* Rallypoint settings */ - class rallypoint { - cooldown = 300; - enemyKillRadius = 10; - rallyObjectClass = "Misc_backpackheap_EP1"; - }; - - /* ai settings */ - class ai { - transferToServer = 1; - reinforce = 1; - reinforceRange = 1000; - preventProne = 1; - forceSkill = 1; - }; - - /* Utility settings */ - class utility { - clearVehicleCargo = 1; - freezeTime = 0; - }; - - /* Enhanced Vehicles Settings */ - class enhancedVehicles { - enable = 1; - visualEffects = 1; - soundEffects = 1; - offroadBumpy = 1; - offroadDamage = 1; - }; - - blacklistedAddons[] = {}; - }; -}; - -/* Disable forced complex flightmodel */ -forceRotorLibSimulation = 0; - -/* Respawn delay (in seconds) */ -respawnDelay = 3; - -/* Enable Debug console for eric (you can add your own aswell) */ -enableDebugConsole[] = {"76561198065818848"}; - -/* CMF ORBAT Settings */ -class CMF_ORBAT { - class SIZES { - class BAT { - leadRank = "COLONEL"; - generalRank = "MAJOR"; - }; - class COY { - leadRank = "CAPTAIN"; - generalRank = "CAPTAIN"; - }; - class PLT { - leadRank = "LIEUTENANT"; - generalRank = "LIEUTENANT"; - }; - class SQD { - leadRank = "SERGEANT"; - generalRank = "CORPORAL"; - }; - class FT { - leadRank = "CORPORAL"; - generalRank = "PRIVATE"; - }; - }; - - class TYPES { - class INF {}; - class ARMOR {}; - class TRANS {}; - class CAS {}; - class LOGI {}; - class WEAPONS {}; - class SUPPORT {}; - class MECH {}; - class MOTOR {}; - class HQ {}; - }; -}; diff --git a/framework/components/3den/XEH_3denInit.sqf b/framework/components/3den/XEH_3denInit.sqf new file mode 100644 index 0000000..f5c1532 --- /dev/null +++ b/framework/components/3den/XEH_3denInit.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +[] call FUNC(init); \ No newline at end of file diff --git a/framework/components/3den/XEH_PREP.sqf b/framework/components/3den/XEH_PREP.sqf new file mode 100644 index 0000000..a6b08d4 --- /dev/null +++ b/framework/components/3den/XEH_PREP.sqf @@ -0,0 +1,15 @@ +#include "script_component.hpp" +/* + * This XEH_PREP will also define functions from other parts of CMF (since the CMF state machine won't be called in 3den) + */ + +PREP(init); + +PREP(addMenuItem); +PREP(inInit); +PREP(addToInit); +PREP(removeFromInit); + +PREP(main_iconViewer); +PREP(main_setConfig); +PREP(unit_constructor); diff --git a/framework/components/3den/XEH_postInit.sqf b/framework/components/3den/XEH_postInit.sqf new file mode 100644 index 0000000..84f2529 --- /dev/null +++ b/framework/components/3den/XEH_postInit.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" \ No newline at end of file diff --git a/framework/components/3den/fn_addRadioRack.sqf b/framework/components/3den/fn_addRadioRack.sqf deleted file mode 100644 index de481e5..0000000 --- a/framework/components/3den/fn_addRadioRack.sqf +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Author: Eric - * Adds a entry to add a radio rack and radio to selected vehicle in 3DEN - * - * Arguments: - * 0: Menu - * - * Return Value: - * None - * - * Public: No - */ - -FUNC(addRadioRack) = { - params ["_menuCtrl", "_path"]; - - private _action = ' - private _display3DEN = uiNamespace getVariable "Display3DEN"; - private _display = _display3DEN createDisplay "cmf_3den_addRack"; - - /* Collect button controls */ - private _addCtrl = _display displayCtrl 1; - private _radioCtrl = _display displayCtrl 100; - - /* Fill combobox with data */ - { - private _index = _radioCtrl lbAdd ([(_x select 1) + "_ID_1"] call acre_api_fnc_getDisplayName); - _radioCtrl lbSetData [_index, str _x]; - } forEach [["ACRE_VRC103", "ACRE_PRC117F"], ["ACRE_VRC64", "ACRE_PRC77"], ["ACRE_VRC110", "ACRE_PRC152"], ["ACRE_VRC111", "ACRE_PRC148"], ["ACRE_SEM90", "ACRE_SEM70"]]; - _radioCtrl lbSetSelected [1, true]; - - /* Handle unit spawn */ - _addCtrl ctrlAddEventHandler ["ButtonClick", { - params ["_ctrl"]; - - private _display = ctrlParent _ctrl; - private _vehicles = get3DENSelected "object"; - private _comboCtrl = _display displayCtrl 100; - private _radio = call compile (_comboCtrl lbData (lbCurSel _comboCtrl)); - - if (isNil "_radio") exitWith { - ["You need to select a radio", 1, 1] call BIS_fnc_3DENNotification; - }; - - if (count _vehicles isEqualTo 0) exitWith { - ["You need to select at least one vehicle", 1, 1] call BIS_fnc_3DENNotification; - }; - - { - private _oldInit = (_x get3DENAttribute "Init") select 0; - private _newInit = format["[this, [""%1"", ""Rack"", ""Rack"", false, [""crew""], [], ""%2"", [], []], true, {}] call acre_api_fnc_addRackToVehicle;", (_radio select 0), (_radio select 1)]; - - _x set3DENAttribute ["Init", _oldInit + _newInit]; - } forEach _vehicles; - - ["Added radio to vehicles", 0, 1] call BIS_fnc_3DENNotification; - }]; - '; - - private _actionIndex = _menuCtrl menuAdd [_path, "Add Radio to Vehicle"]; - _menuCtrl menuSetAction [_path + [_actionIndex], _action]; -}; diff --git a/framework/components/3den/fn_iconViewer.sqf b/framework/components/3den/fn_iconViewer.sqf deleted file mode 100644 index 537807f..0000000 --- a/framework/components/3den/fn_iconViewer.sqf +++ /dev/null @@ -1,435 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Hal, Eric - * Opens a window where you can see all textures in arma and copy their path - * - * Arguments: - * 0: Mode - * 1: Arguments - * - * Return Value: - * None - * - * Example: - * ["onload"] call cmf_3den_fnc_iconViewer - * - * Public: Yes - */ -SCRIPT(iconViewer); - -FUNC(iconViewer) = { - params [ - ["_mode", "", [""]], - ["_args", [], [[]]] - ]; - - if (!hasInterface) exitWith {}; - disableSerialization; - - private _fnc_GRID_X = { - pixelW * pixelGridNoUIScale * (((_this) * (2)) / 4) - }; - - private _fnc_GRID_Y = { - pixelH * pixelGridNoUIScale * ((_this * 2) / 4) - }; - - switch _mode do { - case "onload": { - private _display = findDisplay 313 createDisplay "RscDisplayEmpty"; - if (isNull _display) exitWith {}; - - uiNamespace setVariable [QGVAR(icons_idd), _display]; - - ["create", []] call FUNC(iconViewer); - - if (isNil {localNamespace getVariable QGVAR(gameIcons)}) then { - [] spawn { - systemChat "Fetching images from available pbos."; - - private _icons = []; - private _addons = allAddonsInfo apply {_x select 0}; - { - _icons append (addonFiles [_x, ".paa"]); - _icons append (addonFiles [_x, ".jpg"]); - _icons append (addonFiles [_x, ".tga"]); - _icons append (addonFiles [_x, ".bmp"]); - } forEach _addons; - - localNamespace setVariable [QGVAR(gameIcons), _icons]; - localNamespace setVariable [QGVAR(icons_numIcons), count _icons]; - localNamespace setVariable [QGVAR(icons), _icons]; - - ["update", []] call FUNC(iconViewer); - }; - } else { - ["update", []] call FUNC(iconViewer); - }; - }; - - case "create": { - private _display = uiNamespace getVariable [QGVAR(icons_idd), displayNull]; - if (isNull _display) exitWith {}; - - private _TABLE_WIDTH = 130; - private _TABLE_HEIGHT = 120; - - private _pos = [ - safeZoneX + (safeZoneW / 2) - (((_TABLE_WIDTH / 2) call _fnc_GRID_X)), - safeZoneY + (safeZoneH / 2) - (((_TABLE_HEIGHT / 2) call _fnc_GRID_Y)), - ((_TABLE_WIDTH) call _fnc_GRID_X), - ((_TABLE_HEIGHT) call _fnc_GRID_Y) - ]; - - private _ctrlGroupMain = _display ctrlCreate ["RscControlsGroupNoScrollbars", -1]; - _ctrlGroupMain ctrlSetPosition _pos; - _ctrlGroupMain ctrlCommit 0; - - private _background = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; - _background ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; - _background ctrlSetBackgroundColor [0.05, 0.05, 0.05, 0.95]; - _background ctrlEnable false; - _background ctrlCommit 0; - - private _headerBackground = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; - _headerBackground ctrlSetPosition [0, 0, _pos select 2, ((3) call _fnc_GRID_Y)]; - _headerBackground ctrlSetBackgroundColor [ - profilenamespace getvariable ['GUI_BCG_RGB_R', 0.3843], - profilenamespace getvariable ['GUI_BCG_RGB_G', 0.7019], - profilenamespace getvariable ['GUI_BCG_RGB_B', 0.8862], - 1 - ]; - _headerBackground ctrlEnable false; - _headerBackground ctrlCommit 0; - - private _headerText = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; - _headerText ctrlSetPosition [0, 0, _pos select 2, ((3) call _fnc_GRID_Y)]; - _headerText ctrlSetFont "RobotoCondensed"; - _headerText ctrlSetTextColor [0.95, 0.95, 0.95, 1]; - _headerText ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); - _headerText ctrlSetText "Icon Viewer"; - _headerText ctrlEnable false; - _headerText ctrlCommit 0; - - private _closeButton = _display ctrlCreate ["ctrlButtonPictureKeepAspect", -1, _ctrlGroupMain]; - _closeButton ctrlSetText "\a3\3DEN\Data\Displays\Display3DEN\search_end_ca.paa"; - _closeButton ctrlSetPosition [(_pos select 2) - ((3 + 0.5) call _fnc_GRID_X), 0, ((3 + 0.5) call _fnc_GRID_X), ((3) call _fnc_GRID_Y)]; - _closeButton ctrlAddEventHandler ["ButtonClick", { - private _display = uiNamespace getVariable [QGVAR(icons_idd), displayNull]; - if (!isNull _display) then {_display closeDisplay 2;}; - }]; - _closeButton ctrlCommit 0; - - private _footerBackground = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; - _footerBackground ctrlSetPosition [0, (_pos select 3) - ((5) call _fnc_GRID_Y), _pos select 2, ((5) call _fnc_GRID_Y)]; - _footerBackground ctrlSetBackgroundColor [0.1, 0.1, 0.1, 1]; - _footerBackground ctrlEnable false; - _footerBackground ctrlCommit 0; - - private _ctrlGroupList = _display ctrlCreate ["RscControlsGroupNoScrollbars", 12002, _ctrlGroupMain]; - _ctrlGroupList ctrlSetPosition [ - 0, - ((3 + 0.5) call _fnc_GRID_Y), - _pos select 2, - (_pos select 3) - ((3 + 0.5 + 0.5 + 5) call _fnc_GRID_Y) - ]; - _ctrlGroupList ctrlSetBackgroundColor [1, 1, 1, 0.9]; - _ctrlGroupList ctrlCommit 0; - - private _origPos = ctrlPosition _ctrlGroupList; - private _boxesX = localNamespace getVariable [QGVAR(icons_boxesX), 5]; - private _boxesY = localNamespace getVariable [QGVAR(icons_boxesY), 5]; - - private _w0 = ( - (_origPos select 2) - ((_boxesX + 1) * ((0.5) call _fnc_GRID_X)) - ) / _boxesX; - private _h0 = ( - (_origPos select 3) - ((_boxesY + 1) * ((0.5) call _fnc_GRID_Y)) - ) / _boxesY; - private _x0 = (0.5) call _fnc_GRID_X; - private _y0 = (0.5) call _fnc_GRID_Y; - - private _ctrls = []; - for [{_i = 0}, {_i < _boxesY}, {_i = _i + 1}] do { - private _y = _y0 + (((0.5) call _fnc_GRID_Y) + _h0) * _i; - private _x = _x0; - - for [{_j = 0}, {_j < _boxesX}, {_j = _j + 1}] do { - _x = _x0 + (((0.5) call _fnc_GRID_X) + _w0) * _j; - private _pos = [_x, _y, _w0, _h0]; - - private _ctrlBox = _display ctrlCreate ["RscControlsGroupNoScrollbars", -1, _ctrlGroupList]; - _ctrlBox setVariable ["data", ""]; - _ctrlBox ctrlShow false; - - _ctrlBox ctrlSetPosition _pos; - _ctrlBox ctrlCommit 0; - - private _ctrlTextBG = _display ctrlCreate ["RscText", -1, _ctrlBox]; - _ctrlTextBG ctrlSetBackgroundColor [1, 1, 1, 0.15]; - - _ctrlTextBG ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; - _ctrlTextBG ctrlEnable false; - _ctrlTextBG ctrlCommit 0; - - private _ctrlPicture = _display ctrlCreate ["RscPictureKeepAspect", -1, _ctrlBox]; - _ctrlPicture ctrlSetText ""; - _ctrlPicture ctrlSetBackgroundColor [1, 1, 1, 0.25]; - - _ctrlPicture ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; - _ctrlPicture ctrlEnable false; - _ctrlPicture ctrlCommit 0; - - private _ctrlTextTitle = _display ctrlCreate ["RscStructuredText", -1, _ctrlBox]; - _ctrlTextTitle ctrlSetStructuredText parseText format ["%1", - "a3\ui_f_oldman\data\displays\rscdisplaymain\spotlight_1_old_man_ca.paa" - ]; - _ctrlTextTitle setVariable ["bg", _ctrlTextBG]; - - _ctrlTextTitle ctrlSetPosition [0, 0, _pos select 2, (ctrlTextHeight _ctrlTextTitle) min (_pos select 3)]; - _ctrlTextTitle ctrlEnable false; - _ctrlTextTitle ctrlCommit 0; - - private _ctrlButton = _display ctrlCreate ["ctrlActivePictureKeepAspect", -1, _ctrlBox]; - _ctrlButton setVariable ["bg", _ctrlTextBG]; - _ctrlButton ctrlAddEventHandler ["ButtonDown", { - private _ctrl = _this select 0; - private _data = _ctrl getVariable "data"; - - if (!isNil "_data") then { - copyToClipboard str _data; - hint LSTRING(copied_to_clipboard); - }; - }]; - _ctrlButton ctrlAddEventHandler ["MouseEnter", { - private _ctrl = (_this select 0) getVariable "bg"; - _ctrl ctrlSetBackgroundColor [0, 0.3, 0.6, 0.6]; - }]; - _ctrlButton ctrlAddEventHandler ["MouseExit", { - private _ctrl = (_this select 0) getVariable "bg"; - _ctrl ctrlSetBackgroundColor [1, 1, 1, 0.15]; - }]; - - _ctrlButton ctrlSetText "\a3\Data_f\clear_empty.paa"; - _ctrlButton ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; - _ctrlButton ctrlEnable true; - _ctrlButton ctrlCommit 0; - - _ctrlBox setVariable ["ctrls", [_ctrlTextBG, _ctrlTextTitle, _ctrlPicture, _ctrlButton]]; - _ctrls pushBack _ctrlBox; - }; - }; - - _ctrlGroupList setVariable ["ctrls", _ctrls]; - _display setVariable ["ctrlList", _ctrlGroupList]; - - private _ctrlSearchInfo = _display ctrlCreate ["RscStructuredText", -1, _ctrlGroupMain]; - _ctrlSearchInfo ctrlSetPosition [ - ((0.5) call _fnc_GRID_X), - (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), - ((_TABLE_WIDTH - 0.5*2) call _fnc_GRID_X), - ((3) call _fnc_GRID_Y) - ]; - _ctrlSearchInfo ctrlSetTextColor [0.95, 0.95, 0.95, 1]; - _ctrlSearchInfo ctrlEnable false; - _ctrlSearchInfo ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); - _ctrlSearchInfo ctrlSetStructuredText parseText format ["%1 "+LSTRING(images_found)+"", 0]; - _ctrlSearchInfo ctrlCommit 0; - - _display setVariable ["searchInfo", _ctrlSearchInfo]; - - private _ctrlSearchCheckbox = _display ctrlCreate ["ctrlCheckbox", 12001, _ctrlGroupMain]; - _ctrlSearchCheckbox ctrlSetPosition [ - ((_TABLE_WIDTH / 2) call _fnc_GRID_X) - ((_TABLE_WIDTH / 4) call _fnc_GRID_X) - ((3 + 0.5) call _fnc_GRID_X), - (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), - ((3) call _fnc_GRID_X), - ((3) call _fnc_GRID_Y) - ]; - _ctrlSearchCheckbox ctrlAddEventHandler ["CheckedChanged", { - private _checked = (_this select 1) == 1; - - (_this select 0) ctrlSetTooltip ([LSTRING(case_insensitive), LSTRING(case_sensitive)] select _checked); - localNamespace setVariable [QGVAR(icons_caseSensitive), _checked]; - - ["filterItems", []] call FUNC(iconViewer); - }]; - _ctrlSearchCheckbox ctrlCommit 0; - - private _checked = localNamespace getVariable [QGVAR(icons_caseSensitive), true]; - _ctrlSearchCheckbox ctrlSetTooltip ([LSTRING(case_insensitive), LSTRING(case_sensitive)] select _checked); - _ctrlSearchCheckbox cbSetChecked _checked; - - private _ctrlSearch = _display ctrlCreate ["RscEdit", 12001, _ctrlGroupMain]; - _ctrlSearch ctrlSetPosition [ - ((_TABLE_WIDTH / 2) call _fnc_GRID_X) - ((_TABLE_WIDTH / 4) call _fnc_GRID_X), - (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), - ((_TABLE_WIDTH / 2) call _fnc_GRID_X), - ((3) call _fnc_GRID_Y) - ]; - _ctrlSearch ctrlSetFont "RobotoCondensed"; - _ctrlSearch ctrlSetTextColor [0.95, 0.95, 0.95, 1]; - _ctrlSearch ctrlSetText (localNamespace getVariable [QGVAR(icons_searchText), ""]); - _ctrlSearch ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); - _ctrlSearch ctrlSetBackgroundColor [0, 0, 0, 0.7]; - _ctrlSearch ctrlCommit 0; - - private _ctrlButtonSearch = _display ctrlCreate ["ctrlButtonPictureKeepAspect", 12001, _ctrlGroupMain]; - _ctrlButtonSearch ctrlSetPosition [ - ((_TABLE_WIDTH / 2) call _fnc_GRID_X) - ((_TABLE_WIDTH / 4) call _fnc_GRID_X) + ((_TABLE_WIDTH / 2) call _fnc_GRID_X) + ((0.5) call _fnc_GRID_Y), - (_pos select 3) - ((4) call _fnc_GRID_Y), - ((3) call _fnc_GRID_X), - ((3) call _fnc_GRID_Y) - ]; - _ctrlButtonSearch ctrlSetText "\a3\3DEN\Data\Displays\Display3DEN\search_start_ca.paa"; - _ctrlButtonSearch ctrlSetBackgroundColor [0, 0, 0, 0]; - _ctrlSearch setVariable ["button", _ctrlButtonSearch]; - _ctrlButtonSearch setVariable ["edit", _ctrlSearch]; - - _ctrlButtonSearch ctrlAddEventHandler ["ButtonClick", { - params [ - ["_ctrl", controlNull, [controlNull]] - ]; - - private _ctrlEditSearch = _ctrl getVariable ["edit", controlNull]; - private _searchText = ctrlText _ctrlEditSearch; - private _oldText = localNamespace getVariable [QGVAR(icons_searchText), ""]; - - if (_searchText != _oldText) then { - localNamespace setVariable [QGVAR(icons_searchText), _searchText]; - - ["filterItems", []] call FUNC(iconViewer); - }; - }]; - _ctrlButtonSearch ctrlCommit 0; - - private _ctrlPageInfo = _display ctrlCreate ["RscStructuredText", -1, _ctrlGroupMain]; - _ctrlPageInfo ctrlSetPosition [ - (1 + 3 + 0.5) call _fnc_GRID_X, - (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), - ((10) call _fnc_GRID_X), - ((5) call _fnc_GRID_Y) - ]; - _ctrlPageInfo ctrlSetTextColor [0.95, 0.95, 0.95, 1]; - _ctrlPageInfo ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); - _ctrlPageInfo ctrlSetStructuredText parseText format ["1 | %2", 99, 99]; - _ctrlPageInfo ctrlEnable false; - _ctrlPageInfo ctrlCommit 0; - - _display setVariable ["pageInfo", _ctrlPageInfo]; - - private _ctrlButtonL = _display ctrlCreate ["ctrlButton", -1, _ctrlGroupMain]; - _ctrlButtonL ctrlSetPosition [ - (1) call _fnc_GRID_X, - (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), - ((3) call _fnc_GRID_X), - ((3) call _fnc_GRID_Y) - ]; - _ctrlButtonL ctrlSetFont "PuristaMedium"; - _ctrlButtonL ctrlSetText "<"; - _ctrlButtonL ctrlSetTooltip LSTRING(previous_page); - _ctrlButtonL ctrlSetBackgroundColor [1, 1, 1, 0.15]; - _ctrlButtonL ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); - _ctrlButtonL ctrlSetTextColor [0.95, 0.95, 0.95, 1]; - _ctrlButtonL ctrlAddEventHandler ["ButtonClick", {["changePage", [-1]] call FUNC(iconViewer);}]; - _ctrlButtonL ctrlCommit 0; - - private _ctrlButtonR = _display ctrlCreate ["ctrlButton", -1, _ctrlGroupMain]; - _ctrlButtonR ctrlSetPosition [ - (1 + 3 + 0.5 + 10 + 0.5) call _fnc_GRID_X, - (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), - ((3) call _fnc_GRID_X), - ((3) call _fnc_GRID_Y) - ]; - _ctrlButtonR ctrlSetFont "PuristaMedium"; - _ctrlButtonR ctrlSetText ">"; - _ctrlButtonR ctrlSetTooltip LSTRING(next_page); - _ctrlButtonR ctrlSetBackgroundColor [1, 1, 1, 0.15]; - _ctrlButtonR ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); - _ctrlButtonR ctrlSetTextColor [0.95, 0.95, 0.95, 1]; - _ctrlButtonR ctrlAddEventHandler ["ButtonClick", {["changePage", [1]] call FUNC(iconViewer);}]; - _ctrlButtonR ctrlCommit 0; - }; - - case "filterItems": { - private _searchText = localNamespace getVariable [QGVAR(icons_searchText), ""]; - private _items = localNamespace getVariable [QGVAR(gameIcons), []]; - - if (_searchText != "") then { - if (localNamespace getVariable [QGVAR(icons_caseSensitive), true]) then { - _items = _items select {(_x find _searchText) > -1}; - } else { - _searchText = toLowerANSI _searchText; - - _items = _items select {(toLowerANSI _x find _searchText) > -1}; - }; - }; - - localNamespace setVariable [QGVAR(icons), _items]; - localNamespace setVariable [QGVAR(icons_page), 0]; - ["update", []] call FUNC(iconViewer); - }; - - case "changePage": { - private _maxIcons = count (localNamespace getVariable [QGVAR(icons), []]); - private _iconsPerPage = (localNamespace getVariable [QGVAR(icons_boxesX), 5]) * (localNamespace getVariable [QGVAR(icons_boxesY), 5]); - private _maxPages = ceil (_maxIcons / _iconsPerPage); - - if (_maxPages == 0) exitWith { - localNamespace setVariable [QGVAR(icons_page), 0]; - ["update", []] call FUNC(iconViewer); - }; - - private _page = localNamespace getVariable [QGVAR(icons_page), 0]; - private _amt = (_args param [0, 0, [0]]) + _page; - - if (_amt < 0) then { - _amt = _maxPages - 1; - } else { - _amt = _amt % _maxPages; - }; - - localNamespace setVariable [QGVAR(icons_page), _amt]; - ["update", []] call FUNC(iconViewer); - }; - - case "update": { - private _display = uiNamespace getVariable [QGVAR(icons_idd), displayNull]; - private _ctrlGroupList = _display getVariable ["ctrlList", controlNull]; - private _ctrls = _ctrlGroupList getVariable ["ctrls", []]; - - private _items = localNamespace getVariable [QGVAR(icons), []]; - if (_items isEqualTo []) then { - {_x ctrlShow false} forEach _ctrls; - - (_display getVariable ["pageInfo", controlNull]) ctrlSetStructuredText parseText format ["0 | 0"]; - (_display getVariable ["searchInfo", controlNull]) ctrlSetStructuredText parseText format ["0 images found."]; - } else { - private _page = localNamespace getVariable [QGVAR(icons_page), 0]; - private _iconsPerPage = (localNamespace getVariable [QGVAR(icons_boxesX), 5]) * (localNamespace getVariable [QGVAR(icons_boxesY), 5]); - private _maxPages = ceil (count _items / _iconsPerPage); - - private _n = count _items; - for [{_i = 0}, {_i < _iconsPerPage}, {_i = _i + 1}] do { - private _ctrlBox = _ctrls select _i; - - private _idx = _page * _iconsPerPage + _i; - if (_idx < _n) then { - private _img = _items select _idx; - (_ctrlBox getVariable ["ctrls", []]) params ["", "_ctrlTextTitle", "_ctrlPicture", "_ctrlButton"]; - - _ctrlPicture ctrlSetText _img; - _ctrlTextTitle ctrlSetStructuredText parseText format ["%1", _img]; - _ctrlButton setVariable ["data", _img]; - - _ctrlBox ctrlShow true; - } else { - _ctrlBox ctrlShow false; - }; - }; - - (_display getVariable ["pageInfo", controlNull]) ctrlSetStructuredText parseText format ["%1 | %2", _page + 1, _maxPages]; - (_display getVariable ["searchInfo", controlNull]) ctrlSetStructuredText parseText format ["%1 images found.", count _items]; - }; - }; - }; -}; diff --git a/framework/components/3den/fn_init.sqf b/framework/components/3den/fn_init.sqf deleted file mode 100644 index e26ff56..0000000 --- a/framework/components/3den/fn_init.sqf +++ /dev/null @@ -1,161 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * 3DEN function init, adds all 3den tools for cmf - * - * Arguments: - * 0: Argument Name - * - * Return Value: - * Return Name - * - * Example: - * [] execVM "functions\3den\fn_init.sqf" - * - * Public: No - */ -SCRIPT(init); - -/* Include custom functions */ -#include "fn_unitConstructor.sqf" -#include "fn_unitSpawner.sqf" -#include "fn_iconViewer.sqf" -#include "fn_addRadioRack.sqf" - -/* Define the string localize function */ -EFUNC(main,localize) = compile preprocessFileLineNumbers QUOTE(PATHTO_SYS(main,fn_localize)); - -/* Creates menu in top bar */ -disableSerialization; - -/* Check if menu already exists and if it does delete it */ -private _ctrlMenuStrip = findDisplay 313 displayCtrl 120; -for "_i" from 0 to (_ctrlMenuStrip menuSize []) -1 step 1 do { - if (_ctrlMenuStrip menuText [_i] isEqualTo "CMF") then { - _ctrlMenuStrip menuDelete [_i]; - }; -}; - -/* Create CMF menu */ -private _indexMain = _ctrlMenuStrip menuAdd [[], "CMF"]; - -/* Create unit spawner menu */ -private _unitSpawner = _ctrlMenuStrip menuAdd [[_indexMain], LSTRING(unitSpawner_displayName)]; - -/* Unit sizes (fireteam, squad, platoon, Company) */ -private _unitSizes = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(infantry_elements_displayName)]; -private _fireteamSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _unitSizes], LSTRING(fireteam_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _unitSizes, _fireteamSpawner], "[""FIRETEAM""] spawn cmf_3den_fnc_unitSpawner"]; -private _squadSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _unitSizes], LSTRING(squad_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _unitSizes, _squadSpawner], "[""SQUAD""] spawn cmf_3den_fnc_unitSpawner"]; -private _platoonSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _unitSizes], LSTRING(platoon_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _unitSizes, _platoonSpawner], "[""PLATOON""] spawn cmf_3den_fnc_unitSpawner"]; -private _CompanySpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _unitSizes], LSTRING(company_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _unitSizes, _CompanySpawner], "[""COMPANY""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Air Elements */ -private _airUnits = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(air_elements_displayName)]; -private _phantomSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _airUnits], LSTRING(light_rotary_cas_trans_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _airUnits, _phantomSpawner], "[""PHANTOM""] spawn cmf_3den_fnc_unitSpawner"]; -private _reaperSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _airUnits], LSTRING(rotary_cas)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _airUnits, _reaperSpawner], "[""REAPER""] spawn cmf_3den_fnc_unitSpawner"]; -private _uglySpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _airUnits], LSTRING(heavy_rotary_cas_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _airUnits, _uglySpawner], "[""UGLY""] spawn cmf_3den_fnc_unitSpawner"]; -private _hawgSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _airUnits], LSTRING(ground_attack_jet_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _airUnits, _hawgSpawner], "[""HAWG""] spawn cmf_3den_fnc_unitSpawner"]; -private _pavementSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _airUnits], LSTRING(fighter_bomber_jet_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _airUnits, _pavementSpawner], "[""PAVEMENT""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Armor Elements */ -private _armorUnits = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(armor_elements_displayName)]; -private _sierraSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _armorUnits], LSTRING(apc_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _armorUnits, _sierraSpawner], "[""SIERRA""] spawn cmf_3den_fnc_unitSpawner"]; -private _mikeSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _armorUnits], LSTRING(ifv_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _armorUnits, _mikeSpawner], "[""MIKE""] spawn cmf_3den_fnc_unitSpawner"]; -private _tangoSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _armorUnits], LSTRING(mbt_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _armorUnits, _tangoSpawner], "[""TANGO""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Support Elements */ -private _supportUnits = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(support_elements_displayName)]; -private _mortarsSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _supportUnits], LSTRING(mortar_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _supportUnits, _mortarsSpawner], "[""MORTARS""] spawn cmf_3den_fnc_unitSpawner"]; -private _romeoSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _supportUnits], LSTRING(recon_sniper_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _supportUnits, _romeoSpawner], "[""ROMEO""] spawn cmf_3den_fnc_unitSpawner"]; -private _logiSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _supportUnits], LSTRING(logistics_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _supportUnits, _logiSpawner], "[""LOGI""] spawn cmf_3den_fnc_unitSpawner"]; -private _engiSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _supportUnits], LSTRING(engineers_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _supportUnits, _engiSpawner], "[""ENGI""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Weapons Elements */ -private _weaponUnits = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(weapons_elements_displayName)]; -private _mmgSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _weaponUnits], LSTRING(mmg_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _weaponUnits, _mmgSpawner], "[""MMG""] spawn cmf_3den_fnc_unitSpawner"]; -private _hmgSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _weaponUnits], LSTRING(hmg_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _weaponUnits, _hmgSpawner], "[""HMG""] spawn cmf_3den_fnc_unitSpawner"]; -private _matSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _weaponUnits], LSTRING(mat_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _weaponUnits, _matSpawner], "[""MAT""] spawn cmf_3den_fnc_unitSpawner"]; -private _hatSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _weaponUnits], LSTRING(hat_team_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _weaponUnits, _hatSpawner], "[""HAT""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Special Elements */ -private _specialUnits = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(special_elements_displayName)]; -private _rgrRifleSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _specialUnits], LSTRING(rgr_riflesquad_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _specialUnits, _rgrRifleSpawner], "[""RGR_RFL_SQUAD""] spawn cmf_3den_fnc_unitSpawner"]; -private _rgrMGSpawner = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner, _specialUnits], LSTRING(rgr_machinegunsquad_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _specialUnits, _rgrMGSpawner], "[""RGR_MG_SQUAD""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Custom unit */ -private _singleUnit = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(custom_unit_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _singleUnit], "[""UNIT""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Zeus unit */ -private _zeusUnit = _ctrlMenuStrip menuAdd [[_indexMain, _unitSpawner], LSTRING(zeus_unit_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _unitSpawner, _zeusUnit], "[""ZEUS""] spawn cmf_3den_fnc_unitSpawner"]; - -/* Create a tools menu */ -private _tools = _ctrlMenuStrip menuAdd [[_indexMain], LSTRING(tools_displayName)]; - -/* Add ACRE rack tool */ -[_ctrlMenuStrip, [_indexMain, _tools]] call FUNC(addRadioRack); - -/* Enable simulation for selected objects */ -private _3denSimulationEn = _ctrlMenuStrip menuAdd [[_indexMain, _tools], LSTRING(enable_sim_3den_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _tools, _3denSimulationEn], "{ _x enableSimulation true; } forEach get3DENSelected ""object"""]; - -/* Disable simulation for selected objects */ -private _3denSimulationDis = _ctrlMenuStrip menuAdd [[_indexMain, _tools], LSTRING(disable_sim_3den_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _tools, _3denSimulationDis], "{ _x enableSimulation false; } forEach get3DENSelected ""object"""]; - -/* Make simple objects and disable simulation and damage */ -private _simpleObj = _ctrlMenuStrip menuAdd [[_indexMain, _tools], LSTRING(make_obj_simple_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _tools, _simpleObj], " - { - _x set3DENAttribute [""enableSimulation"", false]; - _x set3DENAttribute [""allowDamage"", false]; - _x set3DENAttribute [""Init"", "" - this spawn { - private _obj = createSimpleObject[(typeof _this), (getposASL _this), false]; - _obj setVectorDirAndUp [(vectorDir _this), (vectorUp _this)]; - deleteVehicle _this; - } - ""]; - - } forEach get3DENSelected ""object""" -]; - -/* Make selected objects into ammoboxes */ -private _3denSimulationDis = _ctrlMenuStrip menuAdd [[_indexMain, _tools], LSTRING(make_ammobox_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _tools, _3denSimulationDis], "{ _x set3DENAttribute [""Init"", ""[this] call cmf_kosherArsenal_fnc_ammobox;""]; } forEach get3DENSelected ""object"""]; - -/* Shortcut to lobby manager */ -private _lobbyManager = _ctrlMenuStrip menuAdd [[_indexMain], LSTRING(lobby_manager_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _lobbyManager], "call (uiNamespace getVariable 'CBA_fnc_openLobbyManager')"]; - -/* Open menu where you can view all the textures in arma */ -private _iconViewer = _ctrlMenuStrip menuAdd [[_indexMain], LSTRING(iconviewer_displayName)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _iconViewer], "[""onload""] call cmf_3den_fnc_iconViewer;"]; - -/* Report a bug with CMF */ -private _reportBug = _ctrlMenuStrip menuAdd [[_indexMain], LSTRING(report_bug)]; -_ctrlMenuStrip menuSetAction [[_indexMain, _reportBug], " createDialog ""cmf_utility_reportBug"" "]; -_ctrlMenuStrip menuSetPicture [[_indexMain, _reportBug], "\a3\3DEN\Data\Controls\ctrlMenu\link_ca.paa"] diff --git a/framework/components/3den/fn_unitConstructor.sqf b/framework/components/3den/fn_unitConstructor.sqf deleted file mode 100644 index 86f828e..0000000 --- a/framework/components/3den/fn_unitConstructor.sqf +++ /dev/null @@ -1,775 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Constructs unit arrays to be used with the units spawner - * - * Arguments: - * 0: unitIdentifier - * - * Return Value: - * UnitArray - * - * Example: - * ["SQUAD"] call cmf_3den_fnc_unitConstructor - * - * Public: No - */ -SCRIPT(unitConstructor); - -GVAR(fnc_unitConstructor) = { - params ["_unitID"]; - - // Finds a valid platoon number - private _fnc_findPlatoon = { - params [["_searchName", "%1 PLT HQ"]]; - - private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; - private _pltID = 1; - for "_id" from 1 to 100 step 1 do { - if !((format[_searchName, _id]) in _sqds) exitWith { - _pltID = _id; - }; - }; - - _pltID; - }; - - // Finds a valid squadname - private _fnc_findSquad = { - params [["_possibleSquadNames", ["%1 - ASL", "%1 - BSL", "%1 - CSL"]]]; - - private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; - - private _sqdName = "? - ?SL"; - for "_id" from 1 to 100 step 1 do { - { - if !((format[_x, _id]) in _sqds) exitWith { - _sqdName = format[_x, _id]; - }; - } forEach _possibleSquadNames; - if (_sqdName != "? - ?SL") exitWith {}; - }; - - _sqdName; - }; - - // Finds a valid squadname - private _fnc_findSquadAndFireteam = { - private _possibleNames = [["%1 - ASL", ["%1 - A1", "%1 - A2"]], ["%1 - BSL", ["%1 - B1", "%1 - B2"]], ["%1 - CSL", ["%1 - C1", "%1 - C2"]]]; - - private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; - - private _sqdName = ["? - ?SL", "? - ?1", "? - ?2"]; - for "_id" from 1 to 100 step 1 do { - { - private _squad = _x; - - if !((format[(_squad select 0), _id]) in _sqds) then { - private _valid = 0; - { - private _fireteam = _x; - - if !((format[_fireteam, _id]) in _sqds) then { - _valid = _valid + 1; - } - } forEach (_squad select 1); - - if (_valid isEqualTo 2) exitWith { - _sqdName = [format[(_squad select 0), _id], format[((_squad select 1) select 0), _id], format[((_squad select 1) select 1), _id]]; - }; - }; - } forEach _possibleNames; - if !(_sqdName isEqualTo ["? - ?SL", "? - ?1", "? - ?2"]) exitWith {}; - }; - - _sqdName; - }; - - // Finds a valid fireteam name - private _fnc_findFireteam = { - params [["_possibleFireteamNames", ["%1 - A1", "%1 - A2", "%1 - B1", "%1 - B2", "%1 - C1", "%1 - C2"]]]; - - private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; - - private _fireteamName = "? - ?1"; - for "_id" from 1 to 100 step 1 do { - { - if !((format[_x, _id]) in _sqds) exitWith { - _fireteamName = format[_x, _id]; - }; - } forEach _possibleFireteamNames; - if (_fireteamName != "? - ?1") exitWith {}; - }; - - _fireteamName; - }; - - private _fnc_customUnitControl = { - private _display3DEN = uiNamespace getVariable "Display3DEN"; - private _display = _display3DEN createDisplay "cmf_3den_customUnitMenu"; - - /* Collect button controls */ - private _spawnCtrl = _display displayCtrl 1; - //private _cancelCtrl = _display displayCtrl 2; - - private _grpTypeCtrl = _display displayCtrl 103; - private _grpSizeCtrl = _display displayCtrl 104; - - /* Fill comboboxes with data */ - { - _grpTypeCtrl lbAdd (configName _x); - } forEach ("true" configClasses (missionConfigFile >> "CMF_ORBAT" >> "TYPES")); - _grpTypeCtrl lbSetSelected [1, true]; - - { - _grpSizeCtrl lbAdd (configName _x); - } forEach ("true" configClasses (missionConfigFile >> "CMF_ORBAT" >> "SIZES")); - _grpSizeCtrl lbSetSelected [1, true]; - - /* Handle unit spawn */ - _spawnCtrl ctrlAddEventHandler ["ButtonClick", { - params ["_ctrl"]; - - private _display = ctrlParent _ctrl; - - private _paramsArray = []; - { - _paramsArray pushBack (ctrlText (_display displayCtrl _x)); - } forEach [100, 101, 102]; - - { - _paramsArray pushBack ((_display displayCtrl _x) lbText (lbCurSel (_display displayCtrl _x))); - } forEach [103, 104]; - - { - if (_x isEqualTo "") exitWith { - _paramsArray = ["failed"] - }; - } forEach _paramsArray; - - GVAR(unitConstructor_customMenuReturn) = _paramsArray; - //_display spawn {ctrlDelete _this}; - }]; - }; - - private _unitArr = []; - switch (_unitID) do { - case ("COMPANY"): { - _unitArr = [ - [ // COY HQ - ("COY HQ"), "COY HQ", "INF", "COY", 0, [ - ["B_officer_F", "Company Commander", "CO", true, 0, 0], - ["B_officer_F", "Company Executive Officer", "CEO", false, 0, 0], - ["B_medic_F", "Company Medic", "MED", false, 1, 0], - ["B_officer_F", "Forward Air Controller (FAC)", "FAC", false, 0, 0] - ] - ], - [ // 1 PLT HQ - ("1 PLT HQ"), "1 PLT HQ", "INF", "PLT", -1, [ - ["B_officer_F", "Platoon Leader", "PL", true, 0, 0], - ["B_officer_F", "Platoon Sergeant", "PS", false, -1, 0], - ["B_medic_F", "Platoon Medic", "MED", false, -2, 0] - ] - ], - [ // ASL - "1 - ASL", "ASL", "INF", "SQD", -2, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // A1 - "1 - A1", "A1", "INF", "FT", -3, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // A2 - "1 - A2", "A2", "INF", "FT", -3, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ], - [ // BSL - "1 - BSL", "BSL", "INF", "SQD", -4, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // B1 - "1 - B1", "B1", "INF", "FT", -5, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // B2 - "1 - B2", "B2", "INF", "FT", -5, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ], - [ // CSL - "1 - CSL", "CSL", "INF", "SQD", -6, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // C1 - "1 - C1", "C1", "INF", "FT", -7, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // C2 - "1 - C2", "C2", "INF", "FT", -7, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ], - [ // 2 PLT HQ - ("2 PLT HQ"), "2 PLT HQ", "INF", "PLT", -8, [ - ["B_officer_F", "Platoon Leader", "PL", true, 0, 0], - ["B_officer_F", "Platoon Sergeant", "PS", false, -1, 0], - ["B_medic_F", "Platoon Medic", "MED", false, -2, 0] - ] - ], - [ // ASL - "2 - ASL", "ASL", "INF", "SQD", -9, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // A1 - "2 - A1", "A1", "INF", "FT", -10, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // A2 - "2 - A2", "A2", "INF", "FT", -10, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ], - [ // BSL - "2 - BSL", "BSL", "INF", "SQD", -11, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // B1 - "2 - B1", "B1", "INF", "FT", -12, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // B2 - "2 - B2", "B2", "INF", "FT", -12, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ], - [ // CSL - "2 - CSL", "CSL", "INF", "SQD", -13, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // C1 - "2 - C1", "C1", "INF", "FT", -14, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // C2 - "2 - C2", "C2", "INF", "FT", -14, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ] - ]; - }; - - case ("PLATOON"): { - private _pltID = [] call _fnc_findPlatoon; - - _unitArr = [ - [ // PLT HQ - (str _pltID + " PLT HQ"), (str _pltID + " PLT HQ"), "INF", "PLT", 0, [ - ["B_officer_F", "Platoon Leader", "PL", true, 0, 0], - ["B_officer_F", "Platoon Sergeant", "PS", false, 1, 0], - ["B_medic_F", "Platoon Medic", "MED", false, 2, 0] - ] - ], - [ // ASL - (str _pltID + " - ASL"), "ASL", "INF", "SQD", -1, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // A1 - (str _pltID + " - A1"), "A1", "INF", "FT", -2, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // A2 - (str _pltID + " - A2"), "A2", "INF", "FT", -2, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ], - [ // BSL - (str _pltID + " - BSL"), "BSL", "INF", "SQD", -3, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // B1 - (str _pltID + " - B1"), "B1", "INF", "FT", -4, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // B2 - (str _pltID + " - B2"), "B2", "INF", "FT", -4, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ], - [ // CSL - (str _pltID + " - CSL"), "CSL", "INF", "SQD", -5, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ // C1 - (str _pltID + " - C1"), "C1", "INF", "FT", -6, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ // C2 - (str _pltID + " - C2"), "C2", "INF", "FT", -6, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ] - ]; - }; - - case ("SQUAD"): { - private _squadID = [] call _fnc_findSquadAndFireteam; - _unitArr = [ - [ // Squadleader - (_squadID select 0), (_squadID select 0) select [3], "INF", "SQD", 0, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ //Fireteam 1 - (_squadID select 1), (_squadID select 1) select [3], "INF", "FT", -1, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ //Fireteam 2 - (_squadID select 2), (_squadID select 2) select [3], "INF", "FT", -1, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ] - ]; - }; - - case ("FIRETEAM"): { - private _ftID = [] call _fnc_findFireteam; - - _unitArr = [ - [ - _ftID, _ftID select [3], "INF", "FT", -1, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ] - ]; - }; - - case ("UNIT"): { - // Call for custom unit control [_role, _lobbyRole, _grpName, _grpType, _grpSize] - GVAR(unitConstructor_customMenuReturn) = []; - [] spawn _fnc_customUnitControl; - - waitUntil {(count GVAR(unitConstructor_customMenuReturn)) > 0}; - private _params = GVAR(unitConstructor_customMenuReturn); - - if ((_params select 0) isEqualTo "failed") exitWith { - ["Missing parameters", 1, 1] call BIS_fnc_3DENNotification; - _unitArr = []; - }; - - if ((_params select 0) isEqualTo "exited") exitWith { - _unitArr = []; - }; - - _unitArr = [ - [ - (_params select 2), (_params select 3), (_params select 4), 0, [ - ["B_Soldier_F", (_params select 1), (_params select 0), true, 0, 0] - ] - ] - ]; - }; - - case ("ZEUS"): { - _unitArr = [ - [ - "Off Game", "Off Game", "INF", "BAT", 0, [ - ["B_Soldier_F", "Zeus", "ZEUS", true, 0, 0] - ] - ] - ]; - }; - - case ("PHANTOM"): { - private _uID = ["PHANTOM %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("PHANTOM " + str _uID), ("PHANTOM " + str _uID), "TRANS", "PLT", 0, [ - ["B_Helipilot_F", "Pilot", "PILOT", true, 0, 0], - ["B_helicrew_F", "Co-Pilot", "PILOT", false, -1, 0] - ] - ] - ]; - }; - - case ("REAPER"): { - private _uID = ["REAPER %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("REAPER " + str _uID), ("REAPER " + str _uID), "CAS", "PLT", 0, [ - ["B_Helipilot_F", "Pilot", "PILOT", true, 0, 0], - ["B_helicrew_F", "Co-Pilot", "PILOT", false, -1, 0] - ] - ] - ]; - }; - - case ("UGLY"): { - private _uID = ["UGLY %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("UGLY " + str _uID), ("UGLY " + str _uID), "CAS", "PLT", 0, [ - ["B_Helipilot_F", "Pilot", "PILOT", true, 0, 0], - ["B_helicrew_F", "Gunner", "PILOT", false, -1, 0] - ] - ] - ]; - }; - - case ("HAWG"): { - private _uID = ["HAWG %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("HAWG " + str _uID), ("HAWG " + str _uID), "CAS", "PLT", 0, [ - ["B_Fighter_Pilot_F", "Pilot", "PILOT", true, 0, 0] - ] - ] - ]; - }; - - case ("PAVEMENT"): { - private _uID = ["PAVEMENT %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("PAVEMENT " + str _uID), ("PAVEMENT " + str _uID), "CAS", "PLT", 0, [ - ["B_Fighter_Pilot_F", "Pilot", "PILOT", true, 0, 0] - ] - ] - ]; - }; - - case ("SIERRA"): { - private _uID = ["SIERRA %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("SIERRA " + str _uID), ("SIERRA " + str _uID), "ARMOR", "PLT", 0, [ - ["B_crew_F", "Commander", "CRW", true, 0, 0], - ["B_crew_F", "Gunner", "CRW", false, -1, 0], - ["B_crew_F", "Driver", "CRW", false, -2, 0] - ] - ] - ]; - }; - - case ("MIKE"): { - private _uID = ["MIKE %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("MIKE " + str _uID), ("MIKE " + str _uID), "ARMOR", "PLT", 0, [ - ["B_crew_F", "Commander", "CRW", true, 0, 0], - ["B_crew_F", "Gunner", "CRW", false, -1, 0], - ["B_crew_F", "Driver", "CRW", false, -2, 0] - ] - ] - ]; - }; - - case ("TANGO"): { - private _uID = ["TANGO %1"] call _fnc_findPlatoon; - - _unitArr = [ - [ - ("TANGO " + str _uID), ("TANGO " + str _uID), "ARMOR", "PLT", 0, [ - ["B_crew_F", "Commander", "CRW", true, 0, 0], - ["B_crew_F", "Gunner", "CRW", false, -1, 0], - ["B_crew_F", "Driver", "CRW", false, -2, 0] - ] - ] - ]; - }; - - case ("MORTARS"): { - private _uID = [["%1 - MORTARS"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "MORTARS", "SUPPORT", "SQD", 0, [ - ["B_officer_F", "Gunnery Leader", "CRW", true, 0, 0], - ["B_Soldier_F", "Gunnery Gunner", "CRW", false, -1, 0] - ] - ] - ]; - }; - - case ("ROMEO"): { - private _uID = [["%1 - ROMEO"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "ROMEO", "SUPPORT", "SQD", 0, [ - ["B_officer_F", "Spotter", "SPOT", true, 0, 0], - ["B_Soldier_F", "Sniper", "SNPR", false, -1, 0] - ] - ] - ]; - }; - - case ("ENGI"): { - private _uID = [["%1 - ENGI"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "ENGI", "SUPPORT", "SQD", 0, [ - ["B_officer_F", "Engineer Leader", "ENG", true, 0, 0], - ["B_Soldier_F", "Engineer", "ENG", false, -1, 0] - ] - ] - ]; - }; - - case ("LOGI"): { - private _uID = [["%1 - LOGI"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "LOGI", "SUPPORT", "SQD", 0, [ - ["B_officer_F", "Logistics Leader", "FTL", true, 0, 0], - ["B_Soldier_F", "Logistics Driver", "RFL", false, -1, 0] - ] - ] - ]; - }; - - case ("MMG"): { - private _uID = [["%1 - MMG"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "MMG", "WEAPONS", "SQD", 0, [ - ["B_officer_F", "MMG Leader", "FTL", true, 0, 0], - ["B_Soldier_F", "Machinegunner, medium (MMG)", "MMG", false, -1, 0], - ["B_Soldier_F", "Assistant Machinegunner", "AMMG", false, -2, 0] - ] - ] - ]; - }; - - case ("HMG"): { - private _uID = [["%1 - HMG"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "HMG", "WEAPONS", "SQD", 0, [ - ["B_officer_F", "HMG Leader", "FTL", true, 0, 0], - ["B_Soldier_F", "Machinegunner, heavy (HMG)", "HMG", false, -1, 0], - ["B_Soldier_F", "Assistant Machinegunner", "AHMG", false, -2, 0] - ] - ] - ]; - }; - - case ("MAT"): { - private _uID = [["%1 - MAT"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "MAT", "WEAPONS", "SQD", 0, [ - ["B_officer_F", "MAT Leader", "FTL", true, 0, 0], - ["B_Soldier_F", "Anti-Tank, medium (MAT)", "MAT", false, -1, 0], - ["B_Soldier_F", "Anti-Tank, medium (MAT)", "MAT", false, -2, 0] - ] - ] - ]; - }; - - case ("HAT"): { - private _uID = [["%1 - HAT"]] call _fnc_findSquad; - - _unitArr = [ - [ - _uID, "HAT", "WEAPONS", "SQD", 0, [ - ["B_officer_F", "HAT Leader", "FTL", true, 0, 0], - ["B_Soldier_F", "Anti-Tank, heavy (HAT)", "HAT", false, -1, 0], - ["B_Soldier_F", "Anti-Tank, heavy (HAT)", "HAT", false, -2, 0] - ] - ] - ]; - }; - - case ("RGR_RFL_SQUAD"): { - private _squadID = [] call _fnc_findSquadAndFireteam; - _unitArr = [ - [ // Squadleader - (_squadID select 0), (_squadID select 0) select [3], "INF", "SQD", 0, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ //Fireteam 1 - (_squadID select 1), (_squadID select 1) select [3], "INF", "FT", -1, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, -2, -1], - ["B_Soldier_GL_F", "Grenadier", "GRD", false, -3, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, -4, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, -5, -4] - ] - ], - [ //Fireteam 2 - (_squadID select 2), (_squadID select 2) select [3], "INF", "FT", -1, [ - ["B_officer_F", "Fireteam Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Autorifleman", "AR", false, 3, -1], - ["B_Soldier_GL_F", "Grenadier", "GRD", false, 4, -2], - ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", false, 5, -3], - ["B_Soldier_F", "Rifleman", "RFL", false, 6, -4] - ] - ] - ]; - }; - - case ("RGR_MG_SQUAD"): { - private _squadID = [] call _fnc_findSquadAndFireteam; - _unitArr = [ - [ // Squadleader - (_squadID select 0), (_squadID select 0) select [3], "INF", "SQD", 0, [ - ["B_officer_F", "Squad Leader", "SL", true, 0, 0], - ["B_medic_F", "Squad Medic", "MED", false, 1, 0] - ] - ], - [ //Fireteam 1 - "Gun Team 1", "Gun Team 1", "INF", "FT", -1, [ - ["B_officer_F", "Gun Team Leader", "FTL", true, -1, 0], - ["B_soldier_AR_F", "Machinegunner, Medium", "MMG", false, -2, -1] - ] - ], - [ //Fireteam 2 - "Gun Team 2", "Gun Team 2", "INF", "FT", -1, [ - ["B_officer_F", "Gun Team Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Machinegunner, Medium", "MMG", false, -2, -1] - ] - ], - [ //Fireteam 3 - "Gun Team 3", "Gun Team 3", "INF", "FT", -1, [ - ["B_officer_F", "Gun Team Leader", "FTL", true, 2, 0], - ["B_soldier_AR_F", "Machinegunner, Medium", "MMG", false, -2, -1] - ] - ] - ]; - }; - - default { - [format["unit type: %1 is not configured yet!", str _unitID], 1, 1] call BIS_fnc_3DENNotification; - }; - }; - - _unitArr; -}; diff --git a/framework/components/3den/functions/fn_addMenuItem.sqf b/framework/components/3den/functions/fn_addMenuItem.sqf new file mode 100644 index 0000000..da8e6ef --- /dev/null +++ b/framework/components/3den/functions/fn_addMenuItem.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Adds a menu item at given path + * + * Arguments: + * 0: Path + * 1: Name + * 2: Icon (Default: "") + * 3: Action (Default: {}) + * 4: Action Params (Default: []) + * 5: Children + * + * Return Value: + * Item index + * + * Example: + * [[0, 1], "My Menu", "", { systemChat (_this select 0) }, ["Hello World!"]] call cmf_3den_fnc_addMenuItem + * + * Public: Yes + */ +SCRIPT(addMenuItem); + +params ["_path", "_name", ["_icon", ""], ["_action", nil], ["_actionParams", []], "_children"]; + +private _ctrlMenuStrip = findDisplay 313 displayCtrl 120; +private _index = _ctrlMenuStrip menuAdd [_path, _name]; +private _path = _path + [_index]; + +if (_icon != "") then { + _ctrlMenuStrip menuSetPicture [_path, _icon]; +}; + +if (!isNil "_action") then { + private _stringAction = toString _action; + private _stringActionParams = str _actionParams; + _ctrlMenuStrip menuSetAction [_path, format ["%1 spawn {%2}", _stringActionParams, _stringAction]]; +}; + +if (!isNil "_children") then { + { + ([_path] + _x) call FUNC(addMenuItem); + } forEach _children; +}; + +_index; diff --git a/framework/components/3den/functions/fn_addToInit.sqf b/framework/components/3den/functions/fn_addToInit.sqf new file mode 100644 index 0000000..ebd674b --- /dev/null +++ b/framework/components/3den/functions/fn_addToInit.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Adds a line to a 3den entity's init + * + * Arguments: + * 0: 3DEN Entity + * 1: Line to add + * + * Return Value: + * None + * + * Example: + * [] call cmf_3den_fnc_addToInit + * + * Public: No + */ + +params ["_entity", "_line"]; + +private _init = (_entity get3DENAttribute "Init") select 0; +_init = _init splitString toString [13, 10]; + +if (_line isEqualType {}) then { + _line = toString _line; +}; + +if ((_line select [(count _line - 1), 1]) != ";") then { + _line = [_line, ";"] joinString ""; +}; + +_init pushBack _line; +_init = _init joinString endl; + +_entity set3DENAttribute ["Init", _init]; \ No newline at end of file diff --git a/framework/components/3den/functions/fn_inInit.sqf b/framework/components/3den/functions/fn_inInit.sqf new file mode 100644 index 0000000..46db196 --- /dev/null +++ b/framework/components/3den/functions/fn_inInit.sqf @@ -0,0 +1,21 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Checks if a line is in a 3den entity's init + * + * Arguments: + * 0: 3DEN Entity + * 1: Line to add + * + * Return Value: + * In Init + * + * Example: + * [] call cmf_3den_fnc_inInit + * + * Public: No + */ +params ["_entity", "_line"]; + +private _init = (_entity get3DENAttribute "Init") select 0; +toUpper _line in toUpper _init; \ No newline at end of file diff --git a/framework/components/3den/functions/fn_init.sqf b/framework/components/3den/functions/fn_init.sqf new file mode 100644 index 0000000..c380d95 --- /dev/null +++ b/framework/components/3den/functions/fn_init.sqf @@ -0,0 +1,72 @@ +disableSerialization; +#include "script_component.hpp" +/* + * Author: Eric + * 3DEN function init, adds all 3den tools for cmf + * + * Arguments: + * 0: Argument Name + * + * Return Value: + * Return Name + * + * Example: + * [] execVM "functions\3den\fn_init.sqf" + * + * Public: No + */ +SCRIPT(init); + +/* Check if menu already exists and if it does delete it */ +private _ctrlMenuStrip = findDisplay 313 displayCtrl 120; +for "_i" from 0 to (_ctrlMenuStrip menuSize []) -1 step 1 do { + if (_ctrlMenuStrip menuText [_i] isEqualTo "CMF") then { + _ctrlMenuStrip menuDelete [_i]; + }; +}; + +/* Set default */ +"Multiplayer" set3DENMissionAttribute ["GameType", "coop"]; + +/* Create CMF menu */ +private _indexMain = [[], "CMF"] call FUNC(addMenuItem); + +private _indexConfig = [ + [_indexMain], + "CMF Settings", + "a3\3den\data\displays\display3den\entitymenu\findconfig_ca.paa", + { + // @TODO: Figure out how to open it on the page for CMF + [findDisplay 313] execVM "x\cba\addons\settings\fnc_openSettingsMenu.sqf"; + [findDisplay 151 displayCtrl 9002] execVM "x\cba\addons\settings\fnc_gui_sourceChanged.sqf"; + } +] call FUNC(addMenuItem); + +private _indexMission = [ + [_indexMain], + "CMF Mission Data", + "a3\ui_f\data\gui\rsc\rscdisplayarsenal\map_ca.paa", + { + call cmf_3den_fnc_setConfig_missionDataHandler; + } +] call FUNC(addMenuItem); + +[_indexMain] call FUNC(main_setConfig); +private _indexUnits = [[_indexMain], LSTRING(unit_spawner_displayName), "a3\ui_f\data\igui\rscingameui\rscunitinfo\si_stand_ca.paa"] call FUNC(addMenuItem); +private _indexTools = [[_indexMain], LSTRING(tools_displayName), "a3\ui_f\data\gui\rsc\rscdisplayarcademap\icon_functions_ca.paa"] call FUNC(addMenuItem); + +private _indexLobby = [[_indexMain], LSTRING(lobby_manager_displayName), "a3\ui_f\data\gui\rsc\rscdisplaymain\menu_multiplayer_ca.paa", { + call (uiNamespace getVariable 'CBA_fnc_openLobbyManager'); +}] call FUNC(addMenuItem); + +private _indexIcons = [[_indexMain], LSTRING(iconviewer_displayName), "a3\3den\data\displays\display3den\panelleft\entitylist_layershow_ca.paa", { + ["onload"] call FUNC(main_iconViewer); +}] call FUNC(addMenuItem); + +private _indexBug = [[_indexMain], LSTRING(report_bug), "a3\3DEN\Data\Controls\ctrlMenu\link_ca.paa", { + createDialog "cmf_utility_reportBug"; +}] call FUNC(addMenuItem); + +missionNameSpace setVariable [QGVAR(menu_main), [_indexMain]]; +missionNameSpace setVariable [QGVAR(menu_unit), [_indexMain, _indexUnits]]; +missionNameSpace setVariable [QGVAR(menu_entity), [_indexMain, _indexTools]]; \ No newline at end of file diff --git a/framework/components/3den/functions/fn_main_iconViewer.sqf b/framework/components/3den/functions/fn_main_iconViewer.sqf new file mode 100644 index 0000000..52079f0 --- /dev/null +++ b/framework/components/3den/functions/fn_main_iconViewer.sqf @@ -0,0 +1,429 @@ +#include "script_component.hpp" +/* + * Author: Hal, Eric + * Opens a window where you can see all textures in arma and copy their path + * + * Arguments: + * 0: Mode + * 1: Arguments + * + * Return Value: + * None + * + * Example: + * ["onload"] call cmf_3den_fnc_main_iconViewer + * + * Public: Yes + */ +SCRIPT(iconViewer); + +params [ +["_mode", "", [""]], +["_args", [], [[]]] +]; + +if (!hasInterface) exitWith {}; +disableSerialization; + +private _fnc_GRID_X = { + pixelW * pixelGridNoUIScale * (((_this) * (2)) / 4) +}; + +private _fnc_GRID_Y = { + pixelH * pixelGridNoUIScale * ((_this * 2) / 4) +}; + +switch _mode do { + case "onload": { + private _display = findDisplay 313 createDisplay "RscDisplayEmpty"; + if (isNull _display) exitWith {}; + + uiNamespace setVariable [QGVAR(icons_idd), _display]; + + ["create", []] call FUNC(main_iconViewer); + + if (isNil {localNamespace getVariable QGVAR(gameIcons)}) then { + [] spawn { + systemChat "Fetching images from available pbos."; + + private _icons = []; + private _addons = allAddonsInfo apply {_x select 0}; + { + _icons append (addonFiles [_x, ".paa"]); + _icons append (addonFiles [_x, ".jpg"]); + _icons append (addonFiles [_x, ".tga"]); + _icons append (addonFiles [_x, ".bmp"]); + } forEach _addons; + + localNamespace setVariable [QGVAR(gameIcons), _icons]; + localNamespace setVariable [QGVAR(icons_numIcons), count _icons]; + localNamespace setVariable [QGVAR(icons), _icons]; + + ["update", []] call FUNC(main_iconViewer); + }; + } else { + ["update", []] call FUNC(main_iconViewer); + }; + }; + + case "create": { + private _display = uiNamespace getVariable [QGVAR(icons_idd), displayNull]; + if (isNull _display) exitWith {}; + + private _TABLE_WIDTH = 130; + private _TABLE_HEIGHT = 120; + + private _pos = [ + safeZoneX + (safeZoneW / 2) - (((_TABLE_WIDTH / 2) call _fnc_GRID_X)), + safeZoneY + (safeZoneH / 2) - (((_TABLE_HEIGHT / 2) call _fnc_GRID_Y)), + ((_TABLE_WIDTH) call _fnc_GRID_X), + ((_TABLE_HEIGHT) call _fnc_GRID_Y) + ]; + + private _ctrlGroupMain = _display ctrlCreate ["RscControlsGroupNoScrollbars", -1]; + _ctrlGroupMain ctrlSetPosition _pos; + _ctrlGroupMain ctrlCommit 0; + + private _background = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; + _background ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; + _background ctrlSetBackgroundColor [0.05, 0.05, 0.05, 0.95]; + _background ctrlEnable false; + _background ctrlCommit 0; + + private _headerBackground = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; + _headerBackground ctrlSetPosition [0, 0, _pos select 2, ((3) call _fnc_GRID_Y)]; + _headerBackground ctrlSetBackgroundColor [ + profilenamespace getvariable ['GUI_BCG_RGB_R', 0.3843], + profilenamespace getvariable ['GUI_BCG_RGB_G', 0.7019], + profilenamespace getvariable ['GUI_BCG_RGB_B', 0.8862], + 1 + ]; + _headerBackground ctrlEnable false; + _headerBackground ctrlCommit 0; + + private _headerText = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; + _headerText ctrlSetPosition [0, 0, _pos select 2, ((3) call _fnc_GRID_Y)]; + _headerText ctrlSetFont "RobotoCondensed"; + _headerText ctrlSetTextColor [0.95, 0.95, 0.95, 1]; + _headerText ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); + _headerText ctrlSetText "Icon Viewer"; + _headerText ctrlEnable false; + _headerText ctrlCommit 0; + + private _closeButton = _display ctrlCreate ["ctrlButtonPictureKeepAspect", -1, _ctrlGroupMain]; + _closeButton ctrlSetText "\a3\3DEN\Data\Displays\Display3DEN\search_end_ca.paa"; + _closeButton ctrlSetPosition [(_pos select 2) - ((3 + 0.5) call _fnc_GRID_X), 0, ((3 + 0.5) call _fnc_GRID_X), ((3) call _fnc_GRID_Y)]; + _closeButton ctrlAddEventHandler ["ButtonClick", { + private _display = uiNamespace getVariable [QGVAR(icons_idd), displayNull]; + if (!isNull _display) then {_display closeDisplay 2;}; + }]; + _closeButton ctrlCommit 0; + + private _footerBackground = _display ctrlCreate ["RscText", -1, _ctrlGroupMain]; + _footerBackground ctrlSetPosition [0, (_pos select 3) - ((5) call _fnc_GRID_Y), _pos select 2, ((5) call _fnc_GRID_Y)]; + _footerBackground ctrlSetBackgroundColor [0.1, 0.1, 0.1, 1]; + _footerBackground ctrlEnable false; + _footerBackground ctrlCommit 0; + + private _ctrlGroupList = _display ctrlCreate ["RscControlsGroupNoScrollbars", 12002, _ctrlGroupMain]; + _ctrlGroupList ctrlSetPosition [ + 0, + ((3 + 0.5) call _fnc_GRID_Y), + _pos select 2, + (_pos select 3) - ((3 + 0.5 + 0.5 + 5) call _fnc_GRID_Y) + ]; + _ctrlGroupList ctrlSetBackgroundColor [1, 1, 1, 0.9]; + _ctrlGroupList ctrlCommit 0; + + private _origPos = ctrlPosition _ctrlGroupList; + private _boxesX = localNamespace getVariable [QGVAR(icons_boxesX), 5]; + private _boxesY = localNamespace getVariable [QGVAR(icons_boxesY), 5]; + + private _w0 = ((_origPos select 2) - ((_boxesX + 1) * ((0.5) call _fnc_GRID_X))) / _boxesX; + private _h0 = ((_origPos select 3) - ((_boxesY + 1) * ((0.5) call _fnc_GRID_Y))) / _boxesY; + private _x0 = (0.5) call _fnc_GRID_X; + private _y0 = (0.5) call _fnc_GRID_Y; + + private _ctrls = []; + for [{_i = 0}, {_i < _boxesY}, {_i = _i + 1}] do { + private _y = _y0 + (((0.5) call _fnc_GRID_Y) + _h0) * _i; + private _x = _x0; + + for [{_j = 0}, {_j < _boxesX}, {_j = _j + 1}] do { + _x = _x0 + (((0.5) call _fnc_GRID_X) + _w0) * _j; + private _pos = [_x, _y, _w0, _h0]; + + private _ctrlBox = _display ctrlCreate ["RscControlsGroupNoScrollbars", -1, _ctrlGroupList]; + _ctrlBox setVariable ["data", ""]; + _ctrlBox ctrlShow false; + + _ctrlBox ctrlSetPosition _pos; + _ctrlBox ctrlCommit 0; + + private _ctrlTextBG = _display ctrlCreate ["RscText", -1, _ctrlBox]; + _ctrlTextBG ctrlSetBackgroundColor [1, 1, 1, 0.15]; + + _ctrlTextBG ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; + _ctrlTextBG ctrlEnable false; + _ctrlTextBG ctrlCommit 0; + + private _ctrlPicture = _display ctrlCreate ["RscPictureKeepAspect", -1, _ctrlBox]; + _ctrlPicture ctrlSetText ""; + _ctrlPicture ctrlSetBackgroundColor [1, 1, 1, 0.25]; + + _ctrlPicture ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; + _ctrlPicture ctrlEnable false; + _ctrlPicture ctrlCommit 0; + + private _ctrlTextTitle = _display ctrlCreate ["RscStructuredText", -1, _ctrlBox]; + _ctrlTextTitle ctrlSetStructuredText parseText format ["%1", + "a3\ui_f_oldman\data\displays\rscdisplaymain\spotlight_1_old_man_ca.paa" + ]; + _ctrlTextTitle setVariable ["bg", _ctrlTextBG]; + + _ctrlTextTitle ctrlSetPosition [0, 0, _pos select 2, (ctrlTextHeight _ctrlTextTitle) min (_pos select 3)]; + _ctrlTextTitle ctrlEnable false; + _ctrlTextTitle ctrlCommit 0; + + private _ctrlButton = _display ctrlCreate ["ctrlActivePictureKeepAspect", -1, _ctrlBox]; + _ctrlButton setVariable ["bg", _ctrlTextBG]; + _ctrlButton ctrlAddEventHandler ["ButtonDown", { + private _ctrl = _this select 0; + private _data = _ctrl getVariable "data"; + + if (!isNil "_data") then { + copyToClipboard str _data; + hint LSTRING(copied_to_clipboard); + }; + }]; + _ctrlButton ctrlAddEventHandler ["MouseEnter", { + private _ctrl = (_this select 0) getVariable "bg"; + _ctrl ctrlSetBackgroundColor [0, 0.3, 0.6, 0.6]; + }]; + _ctrlButton ctrlAddEventHandler ["MouseExit", { + private _ctrl = (_this select 0) getVariable "bg"; + _ctrl ctrlSetBackgroundColor [1, 1, 1, 0.15]; + }]; + + _ctrlButton ctrlSetText "\a3\Data_f\clear_empty.paa"; + _ctrlButton ctrlSetPosition [0, 0, _pos select 2, _pos select 3]; + _ctrlButton ctrlEnable true; + _ctrlButton ctrlCommit 0; + + _ctrlBox setVariable ["ctrls", [_ctrlTextBG, _ctrlTextTitle, _ctrlPicture, _ctrlButton]]; + _ctrls pushBack _ctrlBox; + }; + }; + + _ctrlGroupList setVariable ["ctrls", _ctrls]; + _display setVariable ["ctrlList", _ctrlGroupList]; + + private _ctrlSearchInfo = _display ctrlCreate ["RscStructuredText", -1, _ctrlGroupMain]; + _ctrlSearchInfo ctrlSetPosition [ + ((0.5) call _fnc_GRID_X), + (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), + ((_TABLE_WIDTH - 0.5*2) call _fnc_GRID_X), + ((3) call _fnc_GRID_Y) + ]; + _ctrlSearchInfo ctrlSetTextColor [0.95, 0.95, 0.95, 1]; + _ctrlSearchInfo ctrlEnable false; + _ctrlSearchInfo ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); + _ctrlSearchInfo ctrlSetStructuredText parseText format ["%1 "+LSTRING(images_found)+"", 0]; + _ctrlSearchInfo ctrlCommit 0; + + _display setVariable ["searchInfo", _ctrlSearchInfo]; + + private _ctrlSearchCheckbox = _display ctrlCreate ["ctrlCheckbox", 12001, _ctrlGroupMain]; + _ctrlSearchCheckbox ctrlSetPosition [ + ((_TABLE_WIDTH / 2) call _fnc_GRID_X) - ((_TABLE_WIDTH / 4) call _fnc_GRID_X) - ((3 + 0.5) call _fnc_GRID_X), + (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), + ((3) call _fnc_GRID_X), + ((3) call _fnc_GRID_Y) + ]; + _ctrlSearchCheckbox ctrlAddEventHandler ["CheckedChanged", { + private _checked = (_this select 1) == 1; + + (_this select 0) ctrlSetTooltip ([LSTRING(case_insensitive), LSTRING(case_sensitive)] select _checked); + localNamespace setVariable [QGVAR(icons_caseSensitive), _checked]; + + ["filterItems", []] call FUNC(main_iconViewer); + }]; + _ctrlSearchCheckbox ctrlCommit 0; + + private _checked = localNamespace getVariable [QGVAR(icons_caseSensitive), true]; + _ctrlSearchCheckbox ctrlSetTooltip ([LSTRING(case_insensitive), LSTRING(case_sensitive)] select _checked); + _ctrlSearchCheckbox cbSetChecked _checked; + + private _ctrlSearch = _display ctrlCreate ["RscEdit", 12001, _ctrlGroupMain]; + _ctrlSearch ctrlSetPosition [ + ((_TABLE_WIDTH / 2) call _fnc_GRID_X) - ((_TABLE_WIDTH / 4) call _fnc_GRID_X), + (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), + ((_TABLE_WIDTH / 2) call _fnc_GRID_X), + ((3) call _fnc_GRID_Y) + ]; + _ctrlSearch ctrlSetFont "RobotoCondensed"; + _ctrlSearch ctrlSetTextColor [0.95, 0.95, 0.95, 1]; + _ctrlSearch ctrlSetText (localNamespace getVariable [QGVAR(icons_searchText), ""]); + _ctrlSearch ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); + _ctrlSearch ctrlSetBackgroundColor [0, 0, 0, 0.7]; + _ctrlSearch ctrlCommit 0; + + private _ctrlButtonSearch = _display ctrlCreate ["ctrlButtonPictureKeepAspect", 12001, _ctrlGroupMain]; + _ctrlButtonSearch ctrlSetPosition [ + ((_TABLE_WIDTH / 2) call _fnc_GRID_X) - ((_TABLE_WIDTH / 4) call _fnc_GRID_X) + ((_TABLE_WIDTH / 2) call _fnc_GRID_X) + ((0.5) call _fnc_GRID_Y), + (_pos select 3) - ((4) call _fnc_GRID_Y), + ((3) call _fnc_GRID_X), + ((3) call _fnc_GRID_Y) + ]; + _ctrlButtonSearch ctrlSetText "\a3\3DEN\Data\Displays\Display3DEN\search_start_ca.paa"; + _ctrlButtonSearch ctrlSetBackgroundColor [0, 0, 0, 0]; + _ctrlSearch setVariable ["button", _ctrlButtonSearch]; + _ctrlButtonSearch setVariable ["edit", _ctrlSearch]; + + _ctrlButtonSearch ctrlAddEventHandler ["ButtonClick", { + params [ + ["_ctrl", controlNull, [controlNull]] + ]; + + private _ctrlEditSearch = _ctrl getVariable ["edit", controlNull]; + private _searchText = ctrlText _ctrlEditSearch; + private _oldText = localNamespace getVariable [QGVAR(icons_searchText), ""]; + + if (_searchText != _oldText) then { + localNamespace setVariable [QGVAR(icons_searchText), _searchText]; + + ["filterItems", []] call FUNC(main_iconViewer); + }; + }]; + _ctrlButtonSearch ctrlCommit 0; + + private _ctrlPageInfo = _display ctrlCreate ["RscStructuredText", -1, _ctrlGroupMain]; + _ctrlPageInfo ctrlSetPosition [ + (1 + 3 + 0.5) call _fnc_GRID_X, + (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), + ((10) call _fnc_GRID_X), + ((5) call _fnc_GRID_Y) + ]; + _ctrlPageInfo ctrlSetTextColor [0.95, 0.95, 0.95, 1]; + _ctrlPageInfo ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); + _ctrlPageInfo ctrlSetStructuredText parseText format ["1 | %2", 99, 99]; + _ctrlPageInfo ctrlEnable false; + _ctrlPageInfo ctrlCommit 0; + + _display setVariable ["pageInfo", _ctrlPageInfo]; + + private _ctrlButtonL = _display ctrlCreate ["ctrlButton", -1, _ctrlGroupMain]; + _ctrlButtonL ctrlSetPosition [ + (1) call _fnc_GRID_X, + (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), + ((3) call _fnc_GRID_X), + ((3) call _fnc_GRID_Y) + ]; + _ctrlButtonL ctrlSetFont "PuristaMedium"; + _ctrlButtonL ctrlSetText "<"; + _ctrlButtonL ctrlSetTooltip LSTRING(previous_page); + _ctrlButtonL ctrlSetBackgroundColor [1, 1, 1, 0.15]; + _ctrlButtonL ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); + _ctrlButtonL ctrlSetTextColor [0.95, 0.95, 0.95, 1]; + _ctrlButtonL ctrlAddEventHandler ["ButtonClick", {["changePage", [-1]] call FUNC(main_iconViewer);}]; + _ctrlButtonL ctrlCommit 0; + + private _ctrlButtonR = _display ctrlCreate ["ctrlButton", -1, _ctrlGroupMain]; + _ctrlButtonR ctrlSetPosition [ + (1 + 3 + 0.5 + 10 + 0.5) call _fnc_GRID_X, + (_pos select 3) - ((1 + 3) call _fnc_GRID_Y), + ((3) call _fnc_GRID_X), + ((3) call _fnc_GRID_Y) + ]; + _ctrlButtonR ctrlSetFont "PuristaMedium"; + _ctrlButtonR ctrlSetText ">"; + _ctrlButtonR ctrlSetTooltip LSTRING(next_page); + _ctrlButtonR ctrlSetBackgroundColor [1, 1, 1, 0.15]; + _ctrlButtonR ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); + _ctrlButtonR ctrlSetTextColor [0.95, 0.95, 0.95, 1]; + _ctrlButtonR ctrlAddEventHandler ["ButtonClick", {["changePage", [1]] call FUNC(main_iconViewer);}]; + _ctrlButtonR ctrlCommit 0; + }; + + case "filterItems": { + private _searchText = localNamespace getVariable [QGVAR(icons_searchText), ""]; + private _items = localNamespace getVariable [QGVAR(gameIcons), []]; + + if (_searchText != "") then { + if (localNamespace getVariable [QGVAR(icons_caseSensitive), true]) then { + _items = _items select {(_x find _searchText) > -1}; + } else { + _searchText = toLowerANSI _searchText; + + _items = _items select {(toLowerANSI _x find _searchText) > -1}; + }; + }; + + localNamespace setVariable [QGVAR(icons), _items]; + localNamespace setVariable [QGVAR(icons_page), 0]; + ["update", []] call FUNC(main_iconViewer); + }; + + case "changePage": { + private _maxIcons = count (localNamespace getVariable [QGVAR(icons), []]); + private _iconsPerPage = (localNamespace getVariable [QGVAR(icons_boxesX), 5]) * (localNamespace getVariable [QGVAR(icons_boxesY), 5]); + private _maxPages = ceil (_maxIcons / _iconsPerPage); + + if (_maxPages == 0) exitWith { + localNamespace setVariable [QGVAR(icons_page), 0]; + ["update", []] call FUNC(main_iconViewer); + }; + + private _page = localNamespace getVariable [QGVAR(icons_page), 0]; + private _amt = (_args param [0, 0, [0]]) + _page; + + if (_amt < 0) then { + _amt = _maxPages - 1; + } else { + _amt = _amt % _maxPages; + }; + + localNamespace setVariable [QGVAR(icons_page), _amt]; + ["update", []] call FUNC(main_iconViewer); + }; + + case "update": { + private _display = uiNamespace getVariable [QGVAR(icons_idd), displayNull]; + private _ctrlGroupList = _display getVariable ["ctrlList", controlNull]; + private _ctrls = _ctrlGroupList getVariable ["ctrls", []]; + + private _items = localNamespace getVariable [QGVAR(icons), []]; + if (_items isEqualTo []) then { + {_x ctrlShow false} forEach _ctrls; + + (_display getVariable ["pageInfo", controlNull]) ctrlSetStructuredText parseText format ["0 | 0"]; + (_display getVariable ["searchInfo", controlNull]) ctrlSetStructuredText parseText format ["0 images found."]; + } else { + private _page = localNamespace getVariable [QGVAR(icons_page), 0]; + private _iconsPerPage = (localNamespace getVariable [QGVAR(icons_boxesX), 5]) * (localNamespace getVariable [QGVAR(icons_boxesY), 5]); + private _maxPages = ceil (count _items / _iconsPerPage); + + private _n = count _items; + for [{_i = 0}, {_i < _iconsPerPage}, {_i = _i + 1}] do { + private _ctrlBox = _ctrls select _i; + + private _idx = _page * _iconsPerPage + _i; + if (_idx < _n) then { + private _img = _items select _idx; + (_ctrlBox getVariable ["ctrls", []]) params ["", "_ctrlTextTitle", "_ctrlPicture", "_ctrlButton"]; + + _ctrlPicture ctrlSetText _img; + _ctrlTextTitle ctrlSetStructuredText parseText format ["%1", _img]; + _ctrlButton setVariable ["data", _img]; + + _ctrlBox ctrlShow true; + } else { + _ctrlBox ctrlShow false; + }; + }; + + (_display getVariable ["pageInfo", controlNull]) ctrlSetStructuredText parseText format ["%1 | %2", _page + 1, _maxPages]; + (_display getVariable ["searchInfo", controlNull]) ctrlSetStructuredText parseText format ["%1 images found.", count _items]; + }; + }; +}; diff --git a/framework/components/3den/functions/fn_main_setConfig.sqf b/framework/components/3den/functions/fn_main_setConfig.sqf new file mode 100644 index 0000000..ccf3e08 --- /dev/null +++ b/framework/components/3den/functions/fn_main_setConfig.sqf @@ -0,0 +1,143 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Sets CMF Mission Data + * + * Arguments: + * 0: CMF Menu Index + * + * Return Value: + * None + * + * Example: + * [] call cmf_3den_fnc_setConfig + * + * Public: No + */ + +params ["_cmfMenu"]; + +/* Handle player attempting to delete logic */ +{ + if ((_x get3DENAttribute 'Name') isEqualTo ['cmf_3den_missionDataLogic']) then { + _x addEventHandler ['UnregisteredFromWorld3DEN', { + params ['_entity']; + ['Deleted CMF Mission Data', 1, 1] call BIS_fnc_3DENNotification; + }]; + }; +} forEach (all3DENEntities select 0); + +/* Handle Mission Data */ +FUNC(setConfig_missionDataHandler) = { + private _logics = (all3DENEntities select 0) select { (_x get3DENAttribute 'Name') isEqualTo ['cmf_3den_missionDataLogic'] }; + private _logic = objNull; + if (count _logics isEqualTo 0) then { + _logic = create3DENEntity ['Object', 'Logic', [0,0,0], true]; + _logic set3DENAttribute ['Name', QGVAR(missionDataLogic)]; + } else { + _logic = _logics select 0; + }; + + GVAR(missionDataLogic) = _logic; + + _logic addEventHandler ['UnregisteredFromWorld3DEN', { + params ['_entity']; + ['Deleted CMF Mission Data', 1, 1] call BIS_fnc_3DENNotification; + }]; + + /* Open mission data display */ + private _display3DEN = uiNamespace getVariable "Display3DEN"; + private _display = _display3DEN createDisplay QGVAR(missionMenu); + + [_display, _logic] spawn { + params ["_display", "_logic"]; + + waitUntil { !isNull _display }; + + /* load previous data */ + [] call compile ((_logic get3DENAttribute "Init") select 0); + if (!isNil QEGVAR(common,missionData)) then { + private _hash = [EGVAR(common,missionData)] call CBA_fnc_hashCreate; + + (_display displayCtrl 100) ctrlSetText ([_hash, "M_TITLE", ""] call CBA_fnc_hashGet); + (_display displayCtrl 101) lbSetCurSel (([_hash, "M_TYPE", [0]] call CBA_fnc_hashGet) select 0); + (_display displayCtrl 102) ctrlSetText ([_hash, "M_CTYPE", ""] call CBA_fnc_hashGet); + (_display displayCtrl 200) ctrlSetText ([_hash, "E_MAP", ""] call CBA_fnc_hashGet); + (_display displayCtrl 201) ctrlSetText ([_hash, "E_GPS", ""] call CBA_fnc_hashGet); + (_display displayCtrl 202) ctrlSetText ([_hash, "E_RADIO", ""] call CBA_fnc_hashGet); + (_display displayCtrl 203) ctrlSetText ([_hash, "E_NVG", ""] call CBA_fnc_hashGet); + (_display displayCtrl 204) ctrlSetText ([_hash, "E_FLASHLIGHT", ""] call CBA_fnc_hashGet); + (_display displayCtrl 205) ctrlSetText ([_hash, "E_FLARE", ""] call CBA_fnc_hashGet); + }; + + private _btnConfirm = _display displayCtrl 1; + _btnConfirm ctrlAddEventHandler ["ButtonClick", { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + + /* Create Hash Map of values */ + _hash = []; + + /* Mission Title */ + _hash pushBack ["M_TITLE", ctrlText (_display displayCtrl 100)]; + + /* Mission Type */ + _hash pushBack ["M_TYPE", [lbCurSel (_display displayCtrl 101), (_display displayCtrl 101) lbData (lbCurSel (_display displayCtrl 101))]]; + _hash pushBack ["M_CTYPE", ctrlText (_display displayCtrl 102)]; + + /* Equipment Map */ + _hash pushBack ["E_MAP", ctrlText (_display displayCtrl 200)]; + + /* Equipment GPS */ + _hash pushBack ["E_GPS", ctrlText (_display displayCtrl 201)]; + + /* Equipment Radio */ + _hash pushBack ["E_RADIO", ctrlText (_display displayCtrl 202)]; + + /* Equipment NVG */ + _hash pushBack ["E_NVG", ctrlText (_display displayCtrl 203)]; + + /* Equipment Flashlight */ + _hash pushBack ["E_FLASHLIGHT", ctrlText (_display displayCtrl 204)]; + + /* Equipment Flare */ + _hash pushBack ["E_FLARE", ctrlText (_display displayCtrl 205)]; + + /* Save to logic init */ + GVAR(missionDataLogic) set3DENAttribute ["Init", format ["if (!isServer) exitWith { }; missionNamespace setVariable [""%1"", %2, true];", QEGVAR(common,missionData), str _hash]]; + + /* Set mission attributes */ + _hash = [_hash] call CBA_fnc_hashCreate; + private _pictures = [ + "rsc\data\icon_gametype_scenario_ca.paa", + "rsc\data\icon_gametype_custom_ca.paa", + "rsc\data\icon_gametype_sandbox_ca.paa", + "rsc\data\icon_gametype_training_ca.paa", + "rsc\data\icon_gametype_invasion_ca.paa", + "rsc\data\icon_gametype_assault_ca.paa", + "rsc\data\icon_gametype_defence_ca.paa", + "rsc\data\icon_gametype_csar_ca.paa", + "rsc\data\icon_gametype_qrf_ca.paa" + ]; + private _picture = if ((lbCurSel (_display displayCtrl 101)) > count _pictures - 1) then { + "rsc\data\icon_gametype_empty_ca.paa" + } else { + _pictures select (lbCurSel (_display displayCtrl 101)) + }; + private _gameType = [([_hash, "M_TYPE"] call CBA_fnc_hashGet) select 1, [_hash, "M_CTYPE"] call CBA_fnc_hashGet] select ((([_hash, "M_TYPE"] call CBA_fnc_hashGet) select 1) isEqualTo "custom"); + private _author = profileName; + private _gameName = [_hash, "M_TITLE"] call CBA_fnc_hashGet; + + set3DENMissionAttributes [ + ["intel", "IntelBriefingName", _gameName], + ["Scenario", "Author", _author], + ["Scenario", "OverviewPicture", _picture], + ["Scenario", "OverviewPictureLocked", _picture], + ["Scenario", "LoadScreen", _picture] + ]; + + ["Saved Mission Data", 0, 4] call BIS_fnc_3DENNotification; + }]; + }; +}; \ No newline at end of file diff --git a/framework/components/3den/functions/fn_missionSettings.sqf b/framework/components/3den/functions/fn_missionSettings.sqf new file mode 100644 index 0000000..265f2d3 --- /dev/null +++ b/framework/components/3den/functions/fn_missionSettings.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Sets variables that can be accessed in the mission + * + * Arguments: + * 0: Variable Name + * 1: Variable Value + * 2: Namespace (optional, default: { missionNameSpace }) + * + * Return Value: + * None + * + * Example: + * ["myVariable", _myValue, missionNameSpace] call cmf_3den_fnc_missionSettings + * + * Public: Yes + */ +params ["_varName", "_varValue", ["_namespace", { missionNameSpace }]]; + +/* Find logic */ +private _logics = (all3DENEntities select 0) select { (_x get3DENAttribute 'Name') isEqualTo [QGVAR(data)] }; +private _logic = objNull; +if (count _logics isEqualTo 0) then { + _logic = create3DENEntity ['Object', 'Logic', [0,0,0], true]; + _logic set3DENAttribute ['Name', QGVAR(data)]; + + _logic addEventHandler ['UnregisteredFromWorld3DEN', { + params ['_entity']; + ['Deleted CMF Data! It is recommended to undo deletion!', 1, 5] call BIS_fnc_3DENNotification; + }]; +} else { + _logic = _logics select 0; +}; + +private _logicInit = (_logic get3DENAttribute "Init") select 0; + +private _commands = _logicInit regexReplace [format ["([^;]*?%1.*?);", _varname], format ["%1 setVariable [""%2"", %3]"]]; // @TODO: Fix variable settting + + +/* Set data */ +GVAR(missionDataLogic) set3DENAttribute [ + "Init", + format [ + "if (!isServer) exitWith { }; %1 setVariable [""%2"", %3, true];", + _namespace, + QEGVAR(common,missionData), + str _hash + ] +]; + +// @TODO: Finish this function \ No newline at end of file diff --git a/framework/components/3den/functions/fn_removeFromInit.sqf b/framework/components/3den/functions/fn_removeFromInit.sqf new file mode 100644 index 0000000..5275f24 --- /dev/null +++ b/framework/components/3den/functions/fn_removeFromInit.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Removes a line to a 3den entity's init + * + * Arguments: + * 0: 3DEN Entity + * 1: Line to add + * + * Return Value: + * Deleted Success + * + * Example: + * [] call cmf_3den_fnc_addToInit + * + * Public: No + */ + +params ["_entity", "_line"]; + +private _init = (_entity get3DENAttribute "Init") select 0; + +private _index = _init find _line; +if (_index isEqualTo -1) exitWith { false }; +private _p1 = _init select [0, _index]; + +private _deleteRange = count _line + _index; +if ((_init select [(count _line) + _index, 1]) isEqualTo ";") then { + _deleteRange = count _line + 1 + _index; +}; +private _p2 = _init select [_deleteRange, count _init]; + +_init = (_p1 + _p2) splitString toString [13, 10]; +_init = _init select { _x != " " && _x != "" }; +_init = _init joinString toString [13, 10]; + +_entity set3DENAttribute ["Init", _init]; +true; \ No newline at end of file diff --git a/framework/components/3den/functions/fn_unit_constructor.sqf b/framework/components/3den/functions/fn_unit_constructor.sqf new file mode 100644 index 0000000..7f37e6e --- /dev/null +++ b/framework/components/3den/functions/fn_unit_constructor.sqf @@ -0,0 +1,799 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Constructs unit arrays to be used with the units spawner + * + * Arguments: + * 0: unitIdentifier + * + * Return Value: + * UnitArray + * + * Example: + * ["SQUAD"] call cmf_3den_fnc_unitConstructor + * + * Public: No + */ +SCRIPT(unitConstructor); + +params ["_unitID"]; + +// Finds a valid platoon number +private _fnc_findPlatoon = { + params [["_searchName", "%1 PLT HQ"]]; + + private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; + private _pltID = 1; + for "_id" from 1 to 100 step 1 do { + if !((format[_searchName, _id]) in _sqds) exitWith { + _pltID = _id; + }; + }; + + _pltID; +}; + +// Finds a valid squadname +private _fnc_findSquad = { + params [["_possibleSquadNames", ["%1 - ASL", "%1 - BSL", "%1 - CSL"]]]; + + private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; + + private _sqdName = "? - ?SL"; + for "_id" from 1 to 100 step 1 do { + { + if !((format[_x, _id]) in _sqds) exitWith { + _sqdName = format[_x, _id]; + }; + } forEach _possibleSquadNames; + if (_sqdName != "? - ?SL") exitWith {}; + }; + + _sqdName; +}; + +// Finds a valid squadname +private _fnc_findSquadAndFireteam = { + private _possibleNames = [["%1 - ASL", ["%1 - A1", "%1 - A2"]], ["%1 - BSL", ["%1 - B1", "%1 - B2"]], ["%1 - CSL", ["%1 - C1", "%1 - C2"]]]; + + private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; + + private _sqdName = ["? - ?SL", "? - ?1", "? - ?2"]; + for "_id" from 1 to 100 step 1 do { + { + private _squad = _x; + + if !((format[(_squad select 0), _id]) in _sqds) then { + private _valid = 0; + { + private _fireteam = _x; + + if !((format[_fireteam, _id]) in _sqds) then { + _valid = _valid + 1; + } + } forEach (_squad select 1); + + if (_valid isEqualTo 2) exitWith { + _sqdName = [format[(_squad select 0), _id], format[((_squad select 1) select 0), _id], format[((_squad select 1) select 1), _id]]; + }; + }; + } forEach _possibleNames; + if !(_sqdName isEqualTo ["? - ?SL", "? - ?1", "? - ?2"]) exitWith {}; + }; + + _sqdName; +}; + +// Finds a valid fireteam name +private _fnc_findFireteam = { + params [["_possibleFireteamNames", ["%1 - A1", "%1 - A2", "%1 - B1", "%1 - B2", "%1 - C1", "%1 - C2"]]]; + + private _sqds = (all3DENEntities select 1) apply {(str _x) select [2, count (str _x) - 1]}; + + private _fireteamName = "? - ?1"; + for "_id" from 1 to 100 step 1 do { + { + if !((format[_x, _id]) in _sqds) exitWith { + _fireteamName = format[_x, _id]; + }; + } forEach _possibleFireteamNames; + if (_fireteamName != "? - ?1") exitWith {}; + }; + + _fireteamName; +}; + +private _fnc_customUnitControl = { + private _display3DEN = uiNamespace getVariable "Display3DEN"; + private _display = _display3DEN createDisplay "cmf_3den_customUnitMenu"; + + /* Collect button controls */ + private _spawnCtrl = _display displayCtrl 1; + //private _cancelCtrl = _display displayCtrl 2; + + private _grpTypeCtrl = _display displayCtrl 103; + private _grpSizeCtrl = _display displayCtrl 104; + + /* Fill comboboxes with data */ + { + _grpTypeCtrl lbAdd (configName _x); + } forEach ["INF", "ARMOR", "TRANS", "CAS", "LOGI", "WEAPONS", "SUPPORT", "MECH", "MOTOR", "HQ"]; + _grpTypeCtrl lbSetSelected [1, true]; + + { + _grpSizeCtrl lbAdd (configName _x); + } forEach ["BAT", "COY", "PLT", "SQD", "FT"]; + _grpSizeCtrl lbSetSelected [1, true]; + + /* Handle unit spawn */ + _spawnCtrl ctrlAddEventHandler ["ButtonClick", { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + + private _paramsArray = []; + { + _paramsArray pushBack (ctrlText (_display displayCtrl _x)); + } forEach [100, 101, 102]; + + { + _paramsArray pushBack ((_display displayCtrl _x) lbText (lbCurSel (_display displayCtrl _x))); + } forEach [103, 104]; + + { + if (_x isEqualTo "") exitWith { + _paramsArray = ["failed"] + }; + } forEach _paramsArray; + + GVAR(unitConstructor_customMenuReturn) = _paramsArray; + //_display spawn {ctrlDelete _this}; + }]; +}; + +private _unitArr = []; +switch (_unitID) do { + case ("COMPANY"): { + _unitArr = [ + [ // COY HQ + ("COY HQ"), "COY HQ", "INF", "COY", 0, [ + ["B_officer_F", "Company Commander", "CO", "CAPTAIN", true, 0, 0], + ["B_officer_F", "Company Executive Officer", "CAPTAIN", "CEO", false, 0, 0], + ["B_medic_F", "Company Medic", "MED", "CAPTAIN", false, 1, 0], + ["B_officer_F", "Forward Air Controller (FAC)", "CAPTAIN", "FAC", false, 0, 0] + ] + ], + [ // 1 PLT HQ + ("1 PLT HQ"), "1 PLT HQ", "INF", "PLT", -1, [ + ["B_officer_F", "Platoon Leader", "PL", "LIEUTENANT", true, 0, 0], + ["B_officer_F", "Platoon Sergeant", "PS", "LIEUTENANT", false, -1, 0], + ["B_medic_F", "Platoon Medic", "MED", "LIEUTENANT", false, -2, 0] + ] + ], + [ // ASL + "1 - ASL", "ASL", "INF", "SQD", -2, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // A1 + "1 - A1", "A1", "INF", "FT", -3, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // A2 + "1 - A2", "A2", "INF", "FT", -3, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ], + [ // BSL + "1 - BSL", "BSL", "INF", "SQD", -4, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // B1 + "1 - B1", "B1", "INF", "FT", -5, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // B2 + "1 - B2", "B2", "INF", "FT", -5, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ], + [ // CSL + "1 - CSL", "CSL", "INF", "SQD", -6, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // C1 + "1 - C1", "C1", "INF", "FT", -7, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // C2 + "1 - C2", "C2", "INF", "FT", -7, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ], + [ // 2 PLT HQ + ("2 PLT HQ"), "2 PLT HQ", "INF", "PLT", -8, [ + ["B_officer_F", "Platoon Leader", "PL", "LIEUTENANT", true, 0, 0], + ["B_officer_F", "Platoon Sergeant", "PS", "LIEUTENANT", false, -1, 0], + ["B_medic_F", "Platoon Medic", "MED", "LIEUTENANT", false, -2, 0] + ] + ], + [ // ASL + "2 - ASL", "ASL", "INF", "SQD", -9, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // A1 + "2 - A1", "A1", "INF", "FT", -10, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // A2 + "2 - A2", "A2", "INF", "FT", -10, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ], + [ // BSL + "2 - BSL", "BSL", "INF", "SQD", -11, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // B1 + "2 - B1", "B1", "INF", "FT", -12, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // B2 + "2 - B2", "B2", "INF", "FT", -12, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ], + [ // CSL + "2 - CSL", "CSL", "INF", "SQD", -13, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // C1 + "2 - C1", "C1", "INF", "FT", -14, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // C2 + "2 - C2", "C2", "INF", "FT", -14, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ] + ]; + }; + + case ("PLATOON"): { + private _pltID = [] call _fnc_findPlatoon; + + _unitArr = [ + [ // PLT HQ + (str _pltID + " PLT HQ"), (str _pltID + " PLT HQ"), "INF", "PLT", 0, [ + ["B_officer_F", "Platoon Leader", "PL", "LIEUTENANT", true, 1.5, 0], + ["B_officer_F", "Platoon Sergeant", "PS", "LIEUTENANT", false, 0.5, 0], + ["B_medic_F", "Platoon Medic", "MED", "LIEUTENANT", false, -0.5, 0] + ] + ], + [ // ASL + (str _pltID + " - ASL"), "ASL", "INF", "SQD", -1, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // A1 + (str _pltID + " - A1"), "A1", "INF", "FT", -2, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ], + [ // A2 + (str _pltID + " - A2"), "A2", "INF", "FT", -2, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // BSL + (str _pltID + " - BSL"), "BSL", "INF", "SQD", -3, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // B1 + (str _pltID + " - B1"), "B1", "INF", "FT", -4, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // B2 + (str _pltID + " - B2"), "B2", "INF", "FT", -4, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ], + [ // CSL + (str _pltID + " - CSL"), "CSL", "INF", "SQD", -5, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ // C1 + (str _pltID + " - C1"), "C1", "INF", "FT", -6, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ // C2 + (str _pltID + " - C2"), "C2", "INF", "FT", -6, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ] + ]; + }; + + case ("SQUAD"): { + private _squadID = [] call _fnc_findSquadAndFireteam; + _unitArr = [ + [ // Squadleader + (_squadID select 0), (_squadID select 0) select [3], "INF", "SQD", 0, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ //Fireteam 1 + (_squadID select 1), (_squadID select 1) select [3], "INF", "FT", -1, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ //Fireteam 2 + (_squadID select 2), (_squadID select 2) select [3], "INF", "FT", -1, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ] + ]; + }; + + case ("FIRETEAM"): { + private _ftID = [] call _fnc_findFireteam; + + _unitArr = [ + [ + _ftID, _ftID select [3], "INF", "FT", -1, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, 3, -1], + ["B_soldier_AAR_F", "Assistant Autorifleman", "AAR", "PRIVATE", false, 4, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, 5, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, 6, -4] + ] + ] + ]; + }; + + case ("UNIT"): { + // Call for custom unit control [_role, _lobbyRole, _grpName, _grpType, _grpSize] + GVAR(unitConstructor_customMenuReturn) = []; + [] spawn _fnc_customUnitControl; + + waitUntil {(count GVAR(unitConstructor_customMenuReturn)) > 0}; + private _params = GVAR(unitConstructor_customMenuReturn); + + if ((_params select 0) isEqualTo "failed") exitWith { + ["Missing parameters", 1, 1] call BIS_fnc_3DENNotification; + _unitArr = []; + }; + + if ((_params select 0) isEqualTo "exited") exitWith { + _unitArr = []; + }; + + _unitArr = [[ + (_params select 2), (_params select 2), (_params select 3), (_params select 4), 0, [ + ["B_Soldier_F", (_params select 1), (_params select 0), "PRIVATE", true, 0, 0] + ] + ]]; + }; + + case ("ZEUS"): { + _unitArr = [ + [ + "Off Game", "Off Game", "INF", "BAT", 0, [ + ["B_Soldier_F", "Zeus", "ZEUS", "MAJOR", true, 0, 0] + ] + ] + ]; + }; + + case ("PHANTOM"): { + private _uID = ["PHANTOM %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("PHANTOM " + str _uID), ("PHANTOM " + str _uID), "TRANS", "PLT", 0, [ + ["B_Helipilot_F", "Pilot", "PILOT", "LIEUTENANT", true, 0, 0], + ["B_helicrew_F", "Co-Pilot", "PILOT", "LIEUTENANT", false, -1, 0] + ] + ] + ]; + }; + + case ("REAPER"): { + private _uID = ["REAPER %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("REAPER " + str _uID), ("REAPER " + str _uID), "CAS", "PLT", 0, [ + ["B_Helipilot_F", "Pilot", "PILOT", "LIEUTENANT", true, 0, 0], + ["B_helicrew_F", "Co-Pilot", "PILOT", "LIEUTENANT", false, -1, 0] + ] + ] + ]; + }; + + case ("UGLY"): { + private _uID = ["UGLY %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("UGLY " + str _uID), ("UGLY " + str _uID), "CAS", "PLT", 0, [ + ["B_Helipilot_F", "Pilot", "PILOT", "LIEUTENANT", true, 0, 0], + ["B_helicrew_F", "Gunner", "PILOT", "LIEUTENANT", false, -1, 0] + ] + ] + ]; + }; + + case ("HAWG"): { + private _uID = ["HAWG %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("HAWG " + str _uID), ("HAWG " + str _uID), "CAS", "PLT", 0, [ + ["B_Fighter_Pilot_F", "Pilot", "PILOT", "LIEUTENANT", true, 0, 0] + ] + ] + ]; + }; + + case ("PAVEMENT"): { + private _uID = ["PAVEMENT %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("PAVEMENT " + str _uID), ("PAVEMENT " + str _uID), "CAS", "PLT", 0, [ + ["B_Fighter_Pilot_F", "Pilot", "PILOT", "LIEUTENANT", true, 0, 0] + ] + ] + ]; + }; + + case ("SIERRA"): { + private _uID = ["SIERRA %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("SIERRA " + str _uID), ("SIERRA " + str _uID), "ARMOR", "PLT", 0, [ + ["B_crew_F", "Commander", "CRW", "LIEUTENANT", true, 0, 0], + ["B_crew_F", "Gunner", "CRW", "LIEUTENANT", false, -1, 0], + ["B_crew_F", "Driver", "CRW", "LIEUTENANT", false, -2, 0] + ] + ] + ]; + }; + + case ("MIKE"): { + private _uID = ["MIKE %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("MIKE " + str _uID), ("MIKE " + str _uID), "ARMOR", "PLT", 0, [ + ["B_crew_F", "Commander", "CRW", "LIEUTENANT", true, 0, 0], + ["B_crew_F", "Gunner", "CRW", "LIEUTENANT", false, -1, 0], + ["B_crew_F", "Driver", "CRW", "LIEUTENANT", false, -2, 0] + ] + ] + ]; + }; + + case ("TANGO"): { + private _uID = ["TANGO %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("TANGO " + str _uID), ("TANGO " + str _uID), "ARMOR", "PLT", 0, [ + ["B_crew_F", "Commander", "CRW", "LIEUTENANT", true, 0, 0], + ["B_crew_F", "Gunner", "CRW", "LIEUTENANT", false, -1, 0], + ["B_crew_F", "Driver", "CRW", "LIEUTENANT", false, -2, 0] + ] + ] + ]; + }; + + case ("ANVIL"): { + private _uID = ["ANVIL %1"] call _fnc_findPlatoon; + + _unitArr = [ + [ + ("ANVIL " + str _uID), ("ANVIL " + str _uID), "ARMOR", "PLT", 0, [ + ["B_crew_F", "Commander", "CRW", "LIEUTENANT", true, 0, 0], + ["B_crew_F", "Gunner", "CRW", "LIEUTENANT", false, -1, 0], + ["B_crew_F", "Driver", "CRW", "LIEUTENANT", false, -2, 0] + ] + ] + ]; + }; + + case ("MORTARS"): { + private _uID = [["%1 - MORTARS"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "MORTARS", "SUPPORT", "SQD", 0, [ + ["B_officer_F", "Gunnery Leader", "CRW", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Gunnery Gunner", "CRW", "CORPORAL", false, -1, 0] + ] + ] + ]; + }; + + case ("ROMEO"): { + private _uID = [["%1 - ROMEO"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "ROMEO", "SUPPORT", "SQD", 0, [ + ["B_officer_F", "Spotter", "SPOT", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Sniper", "SNPR", "CORPORAL", false, -1, 0] + ] + ] + ]; + }; + + case ("ENGI"): { + private _uID = [["%1 - ENGI"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "ENGI", "SUPPORT", "SQD", 0, [ + ["B_officer_F", "Engineer Leader", "ENG", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Engineer", "ENG", "CORPORAL", false, -1, 0] + ] + ] + ]; + }; + + case ("LOGI"): { + private _uID = [["%1 - LOGI"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "LOGI", "SUPPORT", "SQD", 0, [ + ["B_officer_F", "Logistics Leader", "FTL", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Logistics Driver", "RFL", "CORPORAL", false, -1, 0] + ] + ] + ]; + }; + + case ("MMG"): { + private _uID = [["%1 - MMG"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "MMG", "WEAPONS", "SQD", 0, [ + ["B_officer_F", "MMG Leader", "FTL", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Machinegunner, medium (MMG)", "MMG", "CORPORAL", false, -1, 0], + ["B_Soldier_F", "Assistant Machinegunner", "AMMG", "CORPORAL", false, -2, 0] + ] + ] + ]; + }; + + case ("HMG"): { + private _uID = [["%1 - HMG"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "HMG", "WEAPONS", "SQD", 0, [ + ["B_officer_F", "HMG Leader", "FTL", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Machinegunner, heavy (HMG)", "HMG", "CORPORAL", false, -1, 0], + ["B_Soldier_F", "Assistant Machinegunner", "AHMG", "CORPORAL", false, -2, 0] + ] + ] + ]; + }; + + case ("MAT"): { + private _uID = [["%1 - MAT"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "MAT", "WEAPONS", "SQD", 0, [ + ["B_officer_F", "MAT Leader", "FTL", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Anti-Tank, medium (MAT)", "MAT", "CORPORAL", false, -1, 0], + ["B_Soldier_F", "Anti-Tank, medium (MAT)", "MAT", "CORPORAL", false, -2, 0] + ] + ] + ]; + }; + + case ("HAT"): { + private _uID = [["%1 - HAT"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "HAT", "WEAPONS", "SQD", 0, [ + ["B_officer_F", "HAT Leader", "FTL", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Anti-Tank, heavy (HAT)", "HAT", "CORPORAL", false, -1, 0], + ["B_Soldier_F", "Anti-Tank, heavy (HAT)", "HAT", "CORPORAL", false, -2, 0] + ] + ] + ]; + }; + + case ("DHAT"): { + private _uID = [["%1 - DHAT"]] call _fnc_findSquad; + + _unitArr = [ + [ + _uID, "DHAT", "WEAPONS", "SQD", 0, [ + ["B_officer_F", "DHAT Leader", "FTL", "SERGEANT", true, 0, 0], + ["B_Soldier_F", "Gunner", "DHATG", "CORPORAL", false, -1, 0], + ["B_Soldier_F", "Assistant Gunner", "DHATAG", "CORPORAL", false, -2, 0] + ] + ] + ]; + }; + + case ("RGR_RFL_SQUAD"): { + private _squadID = [] call _fnc_findSquadAndFireteam; + _unitArr = [ + [ // Squadleader + (_squadID select 0), (_squadID select 0) select [3], "INF", "SQD", 0, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ //Fireteam 1 + (_squadID select 1), (_squadID select 1) select [3], "INF", "FT", -1, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_Soldier_GL_F", "Grenadier", "GRD", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ], + [ //Fireteam 2 + (_squadID select 2), (_squadID select 2) select [3], "INF", "FT", -1, [ + ["B_officer_F", "Fireteam Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Autorifleman", "AR", "PRIVATE", false, -2, -1], + ["B_Soldier_GL_F", "Grenadier", "GRD", "PRIVATE", false, -3, -2], + ["B_soldier_LAT2_F", "Anti-Tank, Light (LAT)", "LAT", "PRIVATE", false, -4, -3], + ["B_Soldier_F", "Rifleman", "RFL", "PRIVATE", false, -5, -4] + ] + ] + ]; + }; + + case ("RGR_MG_SQUAD"): { + private _squadID = [] call _fnc_findSquadAndFireteam; + _unitArr = [ + [ // Squadleader + (_squadID select 0), (_squadID select 0) select [3], "INF", "SQD", 0, [ + ["B_officer_F", "Squad Leader", "SL", "SERGEANT", true, 0, 0], + ["B_medic_F", "Squad Medic", "MED", "CORPORAL", false, 1, 0] + ] + ], + [ //Fireteam 1 + "Gun Team 1", "Gun Team 1", "INF", "FT", -1, [ + ["B_officer_F", "Gun Team Leader", "FTL", "CORPORAL", true, -1, 0], + ["B_soldier_AR_F", "Machinegunner, Medium", "MMG", "PRIVATE", false, -2, -1] + ] + ], + [ //Fireteam 2 + "Gun Team 2", "Gun Team 2", "INF", "FT", -1, [ + ["B_officer_F", "Gun Team Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Machinegunner, Medium", "MMG", "PRIVATE", false, -2, -1] + ] + ], + [ //Fireteam 3 + "Gun Team 3", "Gun Team 3", "INF", "FT", -1, [ + ["B_officer_F", "Gun Team Leader", "FTL", "CORPORAL", true, 2, 0], + ["B_soldier_AR_F", "Machinegunner, Medium", "MMG", "PRIVATE", false, -2, -1] + ] + ] + ]; + }; + + default { + [format["unit type: %1 is not configured yet!", str _unitID], 1, 1] call BIS_fnc_3DENNotification; + }; +}; + +_unitArr; diff --git a/framework/components/3den/functions/script_component.hpp b/framework/components/3den/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/3den/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/3den/script_component.hpp b/framework/components/3den/script_component.hpp index ce62202..46c1085 100644 --- a/framework/components/3den/script_component.hpp +++ b/framework/components/3den/script_component.hpp @@ -1,5 +1,15 @@ #define MODULE 3den +#define MODULE_BEAUTIFIED 3DEN + #define REQUIRED_ADDONS [] #define REQUIRED_MODULES [] +#ifdef DEBUG_ENABLED_3DEN + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_3DEN + #define DEBUG_SETTINGS DEBUG_SETTINGS_3DEN +#endif + #include "..\main\script_component.hpp" diff --git a/framework/components/3den/stringtable.sqf b/framework/components/3den/stringtable.sqf index ae5f102..742f1bc 100644 --- a/framework/components/3den/stringtable.sqf +++ b/framework/components/3den/stringtable.sqf @@ -32,152 +32,14 @@ ["English", "Next page"], ["Spanish", "Siguiente página"] ]], - - - [DSTRING(unitSpawner_displayName), [ - ["English", "Cluster ORBAT unit Spawner"], - ["Spanish", "Cluster ORBAT unidad Spawner"] - ]], - [DSTRING(infantry_elements_displayName), [ - ["English", "Infantry Elements"], - ["Spanish", "Elementos De Infantería"] - ]], - [DSTRING(fireteam_displayName), [ - ["English", "Fireteam"], - ["Spanish", "Equipo de fuego"] - ]], - [DSTRING(squad_displayName), [ - ["English", "Squad"], - ["Spanish", "Escuadra"] - ]], - [DSTRING(platoon_displayName), [ - ["English", "Platoon"], - ["Spanish", "Pelotón"] - ]], - [DSTRING(company_displayName), [ - ["English", "Company"], - ["Spanish", "Compañía"] - ]], - [DSTRING(air_elements_displayName), [ - ["English", "Air Elements"], - ["Spanish", "Air Elements"] - ]], - [DSTRING(light_rotary_cas_trans_displayName), [ - ["English", "Phantom (Light Rotary CAS/Trans)"], - ["Spanish", "Phantom (Rotary CAS/Trans Ligero)"] - ]], - [DSTRING(rotary_cas), [ - ["English", "Reaper (Rotary CAS)"], - ["Spanish", "Reaper (Rotary CAS/Trans Pesado)"] - ]], - [DSTRING(heavy_rotary_cas_displayName), [ - ["English", "Ugly (Heavy Rotary CAS)"], - ["Spanish", "Elementos De Infantería"] - ]], - [DSTRING(ground_attack_jet_displayName), [ - ["English", "Hawg (Ground-Attack Jet)"], - ["Spanish", "Hawg (Avión de ataque a tierra)"] - ]], - [DSTRING(fighter_bomber_jet_displayName), [ - ["English", "Pavement (Fighter / Bomber Jet)"], - ["Spanish", "Pavement (Avión Caza/bombardero)"] - ]], - [DSTRING(armor_elements_displayName), [ - ["English", "Armor Elements"], - ["Spanish", "Armor Elements"] - ]], - [DSTRING(apc_displayName), [ - ["English", "Sierra (APC)"], - ["Spanish", "Sierra (APC)"] - ]], - [DSTRING(ifv_displayName), [ - ["English", "Mike (IFV)"], - ["Spanish", "Mike (IFV)"] - ]], - [DSTRING(mbt_displayName), [ - ["English", "Tango (MBT)"], - ["Spanish", "Tango (MBT)"] - ]], - [DSTRING(support_elements_displayName), [ - ["English", "Support Elements"], - ["Spanish", "Support Elements"] - ]], - [DSTRING(mortar_team_displayName), [ - ["English", "Mortars (Mortar Team)"], - ["Spanish", "Mortars (Equipo de mortero)"] - ]], - [DSTRING(recon_sniper_team_displayName), [ - ["English", "Romeo (Recon / Sniper Team)"], - ["Spanish", "Romeo (Equipo de Reconocimiento / Francotirador)"] - ]], - [DSTRING(logistics_team_displayName), [ - ["English", "Logi (Logistics Team)"], - ["Spanish", "Logi (Equipo logístico)"] - ]], - [DSTRING(engineers_team_displayName), [ - ["English", "Engi (Engineers Team)"], - ["Spanish", "Engi (Equipo de enginieros)"] - ]], - [DSTRING(weapons_elements_displayName), [ - ["English", "Weapons Elements"], - ["Spanish", "Weapons Elements"] - ]], - [DSTRING(mmg_team_displayName), [ - ["English", "MMG (Medium Machinegunner Team)"], - ["Spanish", "MMG (Equipo de ametralladora media)"] - ]], - [DSTRING(hmg_team_displayName), [ - ["English", "HMG (Heavy Machinegunner Team)"], - ["Spanish", "HMG (Equipo de ametralladora pesado)"] - ]], - [DSTRING(mat_team_displayName), [ - ["English", "MAT (Medium Anti-Tank Team)"], - ["Spanish", "MAT (Equipo anti-tanque medio)"] - ]], - [DSTRING(hat_team_displayName), [ - ["English", "HAT (Heavy Anti-Tank Team)"], - ["Spanish", "HAT (Equipo anti-tanque pesado)"] - ]], - [DSTRING(special_elements_displayName), [ - ["English", "Special Elements"], - ["Spanish", "Special Elements"] - ]], - [DSTRING(rgr_riflesquad_displayName), [ - ["English", "Ranger Rifle Squad"], - ["Spanish", "Escuadra de fusileros Ranger"] - ]], - [DSTRING(rgr_machinegunsquad_displayName), [ - ["English", "Ranger Machinegun Squad"], - ["Spanish", "Escuadra de ametralladoras Ranger"] - ]], - [DSTRING(custom_unit_displayName), [ - ["English", "Custom Unit"], - ["Spanish", "Unidad personalizada"] - ]], - [DSTRING(zeus_unit_displayName), [ - ["English", "Zeus Unit"], - ["Spanish", "Unidad Zeus"] + [DSTRING(unit_spawner_displayName), [ + ["English", "Unit Spawner"], + ["Spanish", "Unidad Spawner"] ]], [DSTRING(tools_displayName), [ ["English", "Entity Tools"], ["Spanish", "Herramientas"] ]], - [DSTRING(enable_sim_3den_displayName), [ - ["English", "Enable Simulation in 3den (will only be enabled in 3den)"], - ["Spanish", "Activar simulación en 3den (Solo se activara en el editor 3den)"] - ]], - [DSTRING(disable_sim_3den_displayName), [ - ["English", "Disable Simulation in 3den (will only be disabled in 3den)"], - ["Spanish", "Desactivar simulación en 3den (Solo se desactivara en el editor 3den)"] - ]], - [DSTRING(make_obj_simple_displayName), [ - ["English", "Make object simple"], - ["Spanish", "Crear objeto simple"] - ]], - [DSTRING(make_ammobox_displayName), [ - ["English", "Make kosherArsenal Ammobox"], - ["Spanish", "Crear Caja de munición KosherArsenal"] - ]], [DSTRING(lobby_manager_displayName), [ ["English", "Lobby manager"], ["Spanish", "Gestor de Lobby"] diff --git a/framework/components/aar/XEH_PREP.sqf b/framework/components/aar/XEH_PREP.sqf new file mode 100644 index 0000000..95b531a --- /dev/null +++ b/framework/components/aar/XEH_PREP.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +PREP(record); +PREP(playback); +PREP(submitAAR); +PREP(stats); +PREP(endMission); diff --git a/framework/components/aar/XEH_postInit.sqf b/framework/components/aar/XEH_postInit.sqf new file mode 100644 index 0000000..811e9f4 --- /dev/null +++ b/framework/components/aar/XEH_postInit.sqf @@ -0,0 +1,4 @@ +#include "script_component.hpp" + +[] call FUNC(stats); +[] call FUNC(endMission); \ No newline at end of file diff --git a/framework/components/aar/functions/fn_endMission.sqf b/framework/components/aar/functions/fn_endMission.sqf new file mode 100644 index 0000000..4acf685 --- /dev/null +++ b/framework/components/aar/functions/fn_endMission.sqf @@ -0,0 +1,186 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Hijacks the endMission Module to show a custom mission ending + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_aar_fnc_endMission + * + * Public: No + */ + +/* Custom end mission function */ +EFUNC(inline_aar,endMission) = { + /* Close mission end type dialog (or timeout if user doesn't have dialog)*/ + private _timeout = time + 3; + waitUntil { if (_timeout < time) exitWith {}; !isNull (uiNamespace getVariable "RscDisplayAttributesModuleEndMission") }; + if (isNull (uiNamespace getVariable "RscDisplayAttributesModuleEndMission")) exitWith { }; + (uiNamespace getVariable "RscDisplayAttributesModuleEndMission") closeDisplay 2; + + /* Custom end mission display */ + private _statement = { + /* remoteExecute for all players */ + [(_this select 0), { + params ["_opSuccess", "_tacSuccess", "_objectivesState", "_message"]; + + /* Generate the seperate sections */ + private _missionData = missionNameSpace getVariable [QEGVAR(common,missionData), []]; + private _hash = [_missionData] call CBA_fnc_hashCreate; + private _operationName = [_hash, "M_TITLE", [getMissionConfigValue ['IntelBriefingName', briefingName]] call EFUNC(utility,hexToASCII)] call CBA_fnc_hashGet; + private _op = format ["%1 was an operational %2", _operationName, (["Success", "Failure"] select !(_opSuccess)), (["fcba03", "fc3d03"] select !(_opSuccess))]; + private _tac = format ["%1 was a tactical %2", _operationName, (["Success", "Failure"] select !(_tacSuccess))]; + private _message = _message splitString toString [13,10] joinString "
"; + if (_message != "") then { _message = format ["
%1", _message]; }; + private _objectives = _objectivesState splitString toString [13,10] joinString "
"; + if (_objectives != "") then { _objectives = format ["
%1", _objectives]; }; + + /* Get group statistics */ + private _groupDeaths = 0; + { _groupDeaths = _groupDeaths + (_x getVariable [QGVAR(stats_deaths), 0]) } forEach units (group player); + private _enemyGroupKills = 0; + { _enemyGroupKills = _enemyGroupKills + (_x getVariable [QGVAR(stats_E_kills), 0]) } forEach units (group player); + private _friendlyGroupKills = 0; + { _friendlyGroupKills = _friendlyGroupKills + (_x getVariable [QGVAR(stats_F_kills), 0]) } forEach units (group player); + private _civilianGroupKills = 0; + { _civilianGroupKills = _civilianGroupKills + (_x getVariable [QGVAR(stats_C_kills), 0]) } forEach units (group player); + + private _stats = composeText [ + "", + format [" Group Deaths: %1
", _groupDeaths], + format [" Group Enemy Kills: %1
", _enemyGroupKills], + format ["Group Friendly Kills: %1
", _friendlyGroupKills], + format ["Group Civilian Kills: %1", _civilianGroupKills], + "

", + format [" Your Deaths: %1
", (player getVariable [QGVAR(stats_deaths), 0])], + format [" Your Enemy Kills: %1
", (player getVariable [QGVAR(stats_E_kills), 0])], + format [" Your Friendly Kills: %1
", (player getVariable [QGVAR(stats_F_kills), 0])], + format [" Your Civilian Kills: %1
", (player getVariable [QGVAR(stats_C_kills), 0])], + "
" + ]; + + private _text = format [ + "%1
%2%3%4

%5", _op, _tac, _message, _objectives, _stats + ]; + + sleep 1; + [0, "BLACK", 6, 0] spawn BIS_fnc_fadeEffect; + [_text, -1, -1, 6, 1] spawn BIS_fnc_dynamicText; + sleep 10; + [1, "BLACK", 3, 0] spawn BIS_fnc_fadeEffect; + + /* Put everyone in spectator*/ + [true, true, true] call ace_spectator_fnc_setSpectator; + + /* Show kill and death stats aslong as spectator is active */ + [_groupDeaths, _enemyGroupKills, _friendlyGroupKills, _civilianGroupKills, _op, _tac, _message, _objectives] spawn { + player setVariable [QGVAR(spectatorStatus), true, true]; + ["ace_spectator_displayUnloaded", { player setVariable [QGVAR(spectatorStatus), false, true] }] call CBA_fnc_addEventHandler; + + private _statsText = format ["%1
%2%3%4

", (_this select 4), (_this select 5), (_this select 6), (_this select 7)]; + + _statsText = _statsText + ""; + _statsText = _statsText + format["Group Deaths: %1
", _this select 0]; + _statsText = _statsText + format["Group Enemy Kills: %1
", _this select 1]; + _statsText = _statsText + format["Group Friendly Kills: %1
", _this select 2]; + _statsText = _statsText + format["Group Civilian Kills: %1
", _this select 3]; + _statsText = _statsText + "
"; + _statsText = _statsText + format["Your Deaths: %1
", (player getVariable [QGVAR(stats_deaths), 0])]; + _statsText = _statsText + format["Your Enemy Kills: %1
", (player getVariable [QGVAR(stats_E_kills), 0])]; + _statsText = _statsText + format["Your Friendly Kills: %1
", (player getVariable [QGVAR(stats_F_kills), 0])]; + _statsText = _statsText + format["Your Civilian Kills: %1
", (player getVariable [QGVAR(stats_C_kills), 0])]; + + while { player getVariable QGVAR(spectatorStatus) } do { + hintSilent parseText _statsText; + sleep 1; + }; + hintSilent ""; + }; + + /* make players type out an AAR */ + sleep 2; + call FUNC(submitAAR); + waitUntil { isNull (uiNamespace getVariable "zen_common_display") }; + + /* Open dialog for reading */ + waitUntil { count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []]) != 0 }; + + private _display = (findDisplay 60000) createDisplay QGVAR(aarReadingDisplay); + uiNamespace setVariable [QGVAR(aarIndex), 0]; + + /* Set first AAR entry */ + private _currentAAR = ( missionNameSpace getVariable [QGVAR(AAR_playerReports), []]) select 0; + (_display displayCtrl 100) ctrlSetText (_currentAAR select 0); + (_display displayCtrl 101) ctrlSetText (_currentAAR select 1); + (_display displayCtrl 102) ctrlSetText (_currentAAR select 2); + (_display displayCtrl 300) ctrlSetText format ["AAR Feedback (%1/%2)", (uiNamespace getVariable [QGVAR(aarIndex), 0]) + 1, (count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []]))]; + + /* Update AAR amount */ + _display spawn { + private _curValue = (count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []])); + while { !isNull _this } do { + waitUntil { (count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []])) != _curValue }; + private _curValue = (count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []])); + ((ctrlParent _ctrl) displayCtrl 300) ctrlSetText format ["AAR Feedback (%1/%2)", (uiNamespace getVariable [QGVAR(aarIndex), 0]) + 1, _curValue]; + }; + }; + + /* Previous */ + (_display displayCtrl 200) ctrlAddEventHandler ["ButtonClick", { + params ["_ctrl"]; + + private _index = uiNamespace getVariable [QGVAR(aarIndex), 0]; + private _currentAAR = ( missionNameSpace getVariable [QGVAR(AAR_playerReports), []]) select (0 max (_index - 1)); + ((ctrlParent _ctrl) displayCtrl 100) ctrlSetText (_currentAAR select 0); + ((ctrlParent _ctrl) displayCtrl 101) ctrlSetText (_currentAAR select 1); + ((ctrlParent _ctrl) displayCtrl 102) ctrlSetText (_currentAAR select 2); + ((ctrlParent _ctrl) displayCtrl 300) ctrlSetText format ["AAR Feedback (%1/%2)", (0 max (_index + 1)), (count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []]))]; + + uiNamespace setVariable [QGVAR(aarIndex), (0 max (_index - 1))]; + }]; + + /* Next */ + (_display displayCtrl 201) ctrlAddEventHandler ["ButtonClick", { + params ["_ctrl"]; + + private _index = uiNamespace getVariable [QGVAR(aarIndex), 0]; + private _currentAAR = ( missionNameSpace getVariable [QGVAR(AAR_playerReports), []]) select ((count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []])) min (_index + 1)); + ((ctrlParent _ctrl) displayCtrl 100) ctrlSetText (_currentAAR select 0); + ((ctrlParent _ctrl) displayCtrl 101) ctrlSetText (_currentAAR select 1); + ((ctrlParent _ctrl) displayCtrl 102) ctrlSetText (_currentAAR select 2); + ((ctrlParent _ctrl) displayCtrl 300) ctrlSetText format ["AAR Feedback (%1/%2)", + ((count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []])) min (_index + 2)), + (count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []])) + ]; + + uiNamespace setVariable [QGVAR(aarIndex), ((count (missionNameSpace getVariable [QGVAR(AAR_playerReports), []])) min (_index + 1))]; + }]; + + }] remoteExec ["spawn", 0, true]; + }; + + /* Create dialog for zeus */ + ["End Scenario", [ + ["CHECKBOX", ["Operational success", "Was the operation/mission successfull?"], true], + ["CHECKBOX", ["tactical success", "Was the tactical aspect of the operation successfull (did the operation stay below the casualty or resource limit)?"], true], + ["EDIT:MULTI", ["Completed Objectives (SHIFT + ENTER for new line) ", "Write a list of objectives and their state (completed, failed)."], ""], + ["EDIT:MULTI", ["Message (SHIFT + ENTER for new line) ", "Message displayed in operation end screen"], ""] + ], _statement, {}] call zen_dialog_fnc_create; +}; + +/* Hijack module */ +private _EHIndex = addMissionEventHandler ["EntityCreated", { + params ["_entity"]; + + if ((typeof _entity) isEqualTo "ModuleEndMission_F") then { + deleteVehicle _entity; + [] spawn EFUNC(inline_aar,endMission); + }; +}]; + +missionNameSpace setVariable [QGVAR(endMission_moduleOverride), ["EntityCreated", _EHIndex]]; diff --git a/framework/components/aar/functions/fn_playback.sqf b/framework/components/aar/functions/fn_playback.sqf new file mode 100644 index 0000000..0f89829 --- /dev/null +++ b/framework/components/aar/functions/fn_playback.sqf @@ -0,0 +1,51 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Plays back recorded AAR data + * + * Arguments: + * 0: Data (Optional, Default: cmf_aar_AAR_data) + * + * Return Value: + * None + * + * Example: + * [] call cmf_aar_fnc_playback + * + * Public: Yes + */ +SCRIPT(playback); + +_this spawn { + params ["_data"]; + + /* Get AAR data */ + if (isNil "_data") then { + _data = profileNamespace getVariable [QGVAR(AAR_data), ["Failed", "Failed", 0, [], []]] + }; + + /* Get objects data */ + private _objects = _data select 3; + + /* Get markers data */ + private _markers = _data select 4; + + /* Get length of recording */ + private _timeSpan = [0, ((_objects select (count _objects - 1)) select 0) - (_data select 2)]; + + /* Loop through data */ + while { true } do { + private _curTime = missionNameSpace getVariable [QGVAR(playBack_curTime), 0]; + + waitUntil { _curTime != missionNameSpace getVariable [QGVAR(playBack_curTime), 0] }; + }; + + /* Create time controls */ + [] spawn { + while { true } do { + private _oldCurTime = missionNameSpace getVariable [QGVAR(playBack_curTime), 0]; + missionNameSpace setVariable [QGVAR(playBack_curTime), (_oldCurTime + 1), true]; + sleep 1; + }; + }; +} diff --git a/framework/components/aar/functions/fn_record.sqf b/framework/components/aar/functions/fn_record.sqf new file mode 100644 index 0000000..d4dee37 --- /dev/null +++ b/framework/components/aar/functions/fn_record.sqf @@ -0,0 +1,87 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Initializes AAR recording on server + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_aar_fnc_record + * + * Public: No + */ +SCRIPT(record); + +if (!isServer) exitWith { }; + +/* handle new entities */ +addMissionEventHandler ["EntityCreated", { + params ["_entity"]; + + if ((_entity in allUnits || _entity in allMapMarkers || _entity in vehicles) && !isNull _entity) then { + _entity addEventHandler ["Fired", { + params ["_unit", "_weapon", "", "", "", "", "_projectile"]; + + [_unit, _projectile, _weapon] spawn { + params ["_unit", "_projectile", "_weapon"]; + private _fireData = _unit getVariable [QGVAR(fire_data), []]; + private _projectilePos1 = getPosASL _projectile; + sleep 0.1; + + if (!isNull _projectile) then { + private _projectilePos2 = getPosASL _projectile; + + _fireData pushBack [_weapon, [_projectilePos1, _projectilePos2]]; + _unit setVariable [QGVAR(fire_data), _fireData, true]; + }; + }; + }]; + }; +}]; + +_this spawn { + /* Get title of mission */ + private _missionTitle = if (!isNil { missionNameSpace getVariable QGVAR(safestart_title) }) then { + missionNameSpace getVariable QGVAR(safestart_title) + } else { + [getMissionConfigValue ['IntelBriefingName', briefingName]] call cmf_utility_fnc_hexToASCII; + }; + + /* Set base AAR data (and overwrite any old data) */ + profileNamespace setVariable [QGVAR(AAR_data), [_missionTitle, worldName, time, [], []]]; + private _recordStep = 1; + + LOG("Started AAR recording"); + while {missionNamespace getVariable [QGVAR(recordActive), true]} do { + _prevData = profileNamespace getVariable [QGVAR(AAR_data), ["Failed", "Failed", [], []]]; + private _time = EGVAR(main,unifiedTime); + + /* Get object data */ + private _objects = _prevData select 2; + { + private _fireData = _x getVariable [QGVAR(fire_data), []]; + _objects pushBack [_x, typeof _x, side _x, lifeState _x, getPosASL _x, getDir _x, crew _x, _fireData]; + + _x setVariable [QGVAR(fire_data), [], true]; + } forEach (allUnits + allDead); + private _objectArray = [_time, _objects]; + + /* get marker data */ + private _markers = _prevData select 3; + { + _markers pushBack [_x, markerText _x, markerType _x, markerColor _x, markerSize _x, getMarkerPos _x, markerDir _x]; + } forEach allMapMarkers; + private _markerArray = [_time, _markers]; + + profileNamespace setVariable [QGVAR(AAR_data), [_prevData select 0, _prevData select 1, _objectArray, _markerArray]]; + private _prevData = nil; + private _objects = nil; + private _markers = nil; + + sleep _recordStep; + }; +}; diff --git a/framework/components/aar/functions/fn_stats.sqf b/framework/components/aar/functions/fn_stats.sqf new file mode 100644 index 0000000..c2a0aa5 --- /dev/null +++ b/framework/components/aar/functions/fn_stats.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Collects player stats and saves them to the player objects namespace + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_aar_fnc_stats + * + * Public: No + */ +SCRIPT(stats); + +if (!isServer) exitWith { }; + +addMissionEventHandler ["EntityKilled", { + /* Track deaths */ + if (isPlayer (_this select 0)) then { + private _deaths = (_this select 0) getVariable [QGVAR(stats_deaths), -1]; + (_this select 0) setVariable [QGVAR(stats_deaths), _deaths + 1, true]; + }; + + /* Don't count suicides as kills */ + if ((_this select 1) isEqualTo (_this select 0)) exitWith { }; + + /* Track kills */ + if (isPlayer (_this select 1) && (_this select 0) isKindOf "Man") then { + switch (true) do { + case (([side (_this select 1), side group (_this select 0)] call BIS_fnc_sideIsEnemy) && (side group (_this select 0) != civilian)): { + private _kills = (_this select 1) getVariable [QGVAR(stats_E_kills), 0]; + (_this select 1) setVariable [QGVAR(stats_E_kills), _kills + 1, true]; + }; + + case (([side (_this select 1), side group (_this select 0)] call BIS_fnc_sideIsFriendly) && (side group (_this select 0) != civilian)): { + private _kills = (_this select 1) getVariable [QGVAR(stats_F_kills), 0]; + (_this select 1) setVariable [QGVAR(stats_F_kills), _kills + 1, true]; + }; + + case (side group (_this select 0) == civilian): { + private _kills = (_this select 1) getVariable [QGVAR(stats_C_kills), 0]; + (_this select 1) setVariable [QGVAR(stats_C_kills), _kills + 1, true]; + }; + }; + }; +}]; diff --git a/framework/components/aar/functions/fn_submitAAR.sqf b/framework/components/aar/functions/fn_submitAAR.sqf new file mode 100644 index 0000000..0f964c8 --- /dev/null +++ b/framework/components/aar/functions/fn_submitAAR.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Opens a dialog to submit an after action report, this will only work on the clusterCommunity server. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_aar_fnc_submitAAR + * + * Public: No + */ +SCRIPT(submitReportAction); + +/* Code to submit report */ +private _submit = { + (_this select 0) params ["_anon", "_mission", "_player"]; + + /* Check if player wants to be anonymous */ + private _name = [name player, ""] select _anon; + + /* Call script serverside (extDB3 only installed serverside) */ + private _oldReports = missionNameSpace getVariable [QGVAR(AAR_playerReports), []]; + missionNameSpace setVariable [QGVAR(AAR_playerReports), _oldReports + [[_name, _mission, _player, (name player)]], true]; + + /* Raise event */ + [QGVAR(debrief_onSubmit), []] call CBA_fnc_localEvent; +}; + +/* Create dialog using Zeus Enhanced */ +private _dialog = [LSTRING(performance_report_displayname), [ + ["CHECKBOX", [LSTRING(anonymous_title), LSTRING(anonymous_tooltip)], true], + ["EDIT:MULTI", [LSTRING(mission_feedback_title), LSTRING(mission_feedback_tooltip)], [""]], + ["EDIT:MULTI", [LSTRING(player_feedback_title), LSTRING(player_feedback_tooltip)], [""]] +], _submit] call zen_dialog_fnc_create; diff --git a/framework/components/aar/functions/script_component.hpp b/framework/components/aar/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/aar/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/aar/script_component.hpp b/framework/components/aar/script_component.hpp new file mode 100644 index 0000000..4b2be6b --- /dev/null +++ b/framework/components/aar/script_component.hpp @@ -0,0 +1,15 @@ +#define MODULE aar +#define MODULE_BEAUTIFIED After Action Report (AAR) + +#define REQUIRED_ADDONS [] +#define REQUIRED_MODULES ["common"] + +#ifdef DEBUG_ENABLED_AAR + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_AAR + #define DEBUG_SETTINGS DEBUG_SETTINGS_AAR +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/aar/stringtable.sqf b/framework/components/aar/stringtable.sqf new file mode 100644 index 0000000..f888990 --- /dev/null +++ b/framework/components/aar/stringtable.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: Eric + * aar_stringtable + */ +[ + [DSTRING(performance_report_displayname), [ + ["English", "Performance report"], + ["Spanish", "Reporte de rendimiento"] + ]], + [DSTRING(anonymous_title), [ + ["English", "Anonymous"], + ["Spanish", "Anónimo"] + ]], + [DSTRING(anonymous_tooltip), [ + ["English", "Would you like to be anonymous? (note that if profanity or deragatory terms are used, your anonymity is void)"], + ["Spanish", "¿Desea que este artículo informativo permanezca en el anonimato?"] + ]], + [DSTRING(player_feedback_title), [ + ["English", "Player Performance Feedback"], + ["Spanish", "Comentarios sobre el rendimiento de los jugadores"] + ]], + [DSTRING(player_feedback_tooltip), [ + ["English", "Constructive Feedback on player performance"], + ["Spanish", "Comentarios sobre el rendimiento de los jugadores"] + ]], + [DSTRING(mission_feedback_title), [ + ["English", "Mission Feedback"], + ["Spanish", "Comentarios sobre la misión"] + ]], + [DSTRING(mission_feedback_tooltip), [ + ["English", "Constructive Feedback on mission"], + ["Spanish", "Comentarios sobre la misión"] + ]] +] diff --git a/framework/components/ai/XEH_3denInit.sqf b/framework/components/ai/XEH_3denInit.sqf new file mode 100644 index 0000000..aa6eeb2 --- /dev/null +++ b/framework/components/ai/XEH_3denInit.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" + +waitUntil { !isNil { missionNameSpace getVariable QEGVAR(3den,menu_entity) } }; + +private _path = missionNameSpace getVariable QEGVAR(3den,menu_entity); + +private _preventProneAction = [ + "Toggle preventProne", + "a3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa", + { + if (count get3DENSelected "object" == 0) exitWith { + ["No Objects selected", 0, 1] call BIS_fnc_3DENNotification; + }; + + private _command = toString { this setVariable [QEGVAR(utility,preventProne_disable), false] }; + { + if !([_x, _command] call EFUNC(3den,inInit)) then { + [_x, _command] call EFUNC(3den,addToInit); + } else { + [_x, _command] call EFUNC(3den,removeFromInit); + }; + } forEach get3DENSelected "object"; + + ["Toggled preventProne on selected units", 0, 1] call BIS_fnc_3DENNotification; + } +]; + +[ + _path, + "AI", + "a3\3den\data\displays\display3den\toolbar\open_ca.paa", + {}, + [], + [ + _preventProneAction + ] +] call EFUNC(3den,addMenuItem); \ No newline at end of file diff --git a/framework/components/ai/XEH_PREP.sqf b/framework/components/ai/XEH_PREP.sqf index 518cca8..7f905c2 100644 --- a/framework/components/ai/XEH_PREP.sqf +++ b/framework/components/ai/XEH_PREP.sqf @@ -1,5 +1,9 @@ #include "script_component.hpp" -IPREP(preventProne); -IPREP(reinforce); -IPREP(setSkill); +PREP(preventProne); +PREP(reinforce); +PREP(setSkill); +PREP(fireEH); +PREP(silenceAI); +PREP(panic); +PREP(hostage); diff --git a/framework/components/ai/XEH_postInit.sqf b/framework/components/ai/XEH_postInit.sqf new file mode 100644 index 0000000..13eec0a --- /dev/null +++ b/framework/components/ai/XEH_postInit.sqf @@ -0,0 +1,8 @@ +#include "script_component.hpp" + +[] call FUNC(preventProne); +[] call FUNC(reinforce); +[] call FUNC(setSkill); +[] call FUNC(fireEH); +[] call FUNC(silenceAI); +[] call FUNC(panic); \ No newline at end of file diff --git a/framework/components/ai/fn_preventProne.sqf b/framework/components/ai/fn_preventProne.sqf deleted file mode 100644 index ed58744..0000000 --- a/framework/components/ai/fn_preventProne.sqf +++ /dev/null @@ -1,36 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Prevents AI 'from going prone - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_ai_fnc_preventProne - * - * Public: No - */ -SCRIPT(preventProne); - -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,ai,preventProne) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -/* preventProne on AI units */ -[] spawn { - while { !(missionNamespace getVariable [QEGVAR(utility,preventProne_disable), false]) } do { - { - if ((!isPlayer _x) && !(_x getVariable [QEGVAR(utility,preventProne_initialized), false])) then { - [_x] call EFUNC(utility,preventProne); - _x setVariable [QEGVAR(utility,preventProne_initialized), true]; - - LOG_1("Enabled preventProne for %1", name _x); - }; - } forEach allUnits; - sleep 5; - }; -}; diff --git a/framework/components/ai/fn_reinforce.sqf b/framework/components/ai/fn_reinforce.sqf deleted file mode 100644 index e39eef3..0000000 --- a/framework/components/ai/fn_reinforce.sqf +++ /dev/null @@ -1,66 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Makes ai reinforce groups in contact - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [300, 15] call cmf_ai_fnc_reinforce - * - * public: Yes -*/ -SCRIPT(reinforce); - -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,ai,reinforce) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -if (!isServer) exitWith {}; - -/* Enable LAMBS reinforcements on unit */ -while { !(missionNamespace getVariable [QGVAR(reinforce_disable), false]) } do { - { - if !(_x getVariable [QGVAR(reinforce_initialized), false]) then { - { - [[_x], true] call lambs_danger_fnc_setReinforcement; - [[_x], true] call lambs_danger_fnc_setHasRadio; - } forEach units _x; - - /* Add eventhandler to make group rush to contact */ - ["lambs_danger_OnInformationShared", { - _thisArgs params ["_thisGroup"]; - params ["", "_group", "_target"]; - - if (_thisGroup getVariable [QGVAR(reinforce_disableGroup), false]) exitWith {}; - - if ((group _target) getVariable [QGVAR(reinforce_disableTarget), false]) exitWith {}; - - private _range = CONFIG_PARAM_3(SETTINGS,ai,reinforceRange); - if ( (leader _thisGroup distance leader _group) < _range && _thisGroup != _group && !(_thisGroup getVariable [QGVAR(reinforce_targetGroup), grpNull] isEqualTo _group) && side _thisGroup isEqualTo side _group ) then { - LOG_2("%1 reinforcing %2(TaskRush)", groupId _thisGroup, groupId _group); - - [_thisGroup, 100, 15, [], getPos _target, false] spawn lambs_wp_fnc_taskRush; - - /* Delete old waypoints and add new */ - for "_i" from count waypoints _thisGroup - 1 to 0 step -1 do { - deleteWaypoint [_thisGroup, _i]; - }; - private _wp = _thisGroup addWaypoint [_target, 0]; - _wp setWaypointType "MOVE"; - _thisGroup setVariable [QGVAR(reinforce_targetGroup), _group, true]; - }; - - }, _x] call CBA_fnc_addEventHandlerArgs; - - LOG_1("Enabled reinforce on %1", groupId _x); - _x setVariable [QGVAR(reinforce_initialized), true, true]; - }; - sleep 0.03; - } forEach allGroups; - sleep 1; -}; diff --git a/framework/components/ai/fn_setSkill.sqf b/framework/components/ai/fn_setSkill.sqf deleted file mode 100644 index 37220d3..0000000 --- a/framework/components/ai/fn_setSkill.sqf +++ /dev/null @@ -1,45 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Sets AI Skill to be more balanced. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_ai_fnc_setSkill - * - * public: Yes -*/ -SCRIPT(setSkill); - -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,ai,forceSkill) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -/* Set skill on all units */ -_this spawn { - while { !(missionNamespace getVariable [QGVAR(setSkill_disable), false]) } do { - { - if (!isPlayer _x && !(_x getVariable [QGVAR(setSkill_initialized), false])) then { - _x setSkill ["aimingAccuracy", 0.3 ]; - _x setSkill ["aimingShake", 0.5 ]; - _x setSkill ["aimingSpeed", 0.3 ]; - _x setSkill ["spotDistance", 0.5 ]; - _x setSkill ["spotTime", 0.5 ]; - _x setSkill ["courage", 0.5 ]; - _x setSkill ["commanding", 0.5 ]; - _x setSkill ["general", 0.4 ]; - _x setSkill ["reloadSpeed", 0.5 ]; - _x setSkill ["endurance", 0.5 ]; - - _x setVariable [QGVAR(setSkill_initialized), true, true]; - } - } forEach allUnits; - - sleep 1; - }; -}; diff --git a/framework/components/ai/fn_transferToServer.sqf b/framework/components/ai/fn_transferToServer.sqf deleted file mode 100644 index 0975fe0..0000000 --- a/framework/components/ai/fn_transferToServer.sqf +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Author: Eric - * Transfers zeus spawned AI to server for better ai calculations and better performance for the zeus client - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_ai_fnc_transferToServer - * - * Public: No - */ -SCRIPT(transferToServer); - -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,ai,transferToServer) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -[] spawn { - if (isDedicated) exitWith {}; - - waitUntil{!isnull (getAssignedCuratorLogic player)}; - (getAssignedCuratorLogic player) addEventHandler ["CuratorObjectPlaced", { - private _entity = _this select 1; - - if ( count crew _entity > 0 ) then { - /* Call function on server */ - [[group effectiveCommander _entity], { - params [["_group", grpNull]]; - - if !( (owner leader _group) isEqualTo 2 ) then { - /* Set group owner to server */ - _group setGroupOwner 2; - LOG_1("Transfered %1 to server", groupId _group); - }; - }] remoteExec ["call", 2]; - }; - }]; -}; diff --git a/framework/components/ai/functions/fn_fireEH.sqf b/framework/components/ai/functions/fn_fireEH.sqf new file mode 100644 index 0000000..d015413 --- /dev/null +++ b/framework/components/ai/functions/fn_fireEH.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Handles AI reaction to being lit on fire + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_ai_fnc_fireEH + * + * Public: Yes + */ + +["ace_fire_addFireSource", { + params ["_unit"]; + + if (_unit isEqualType []) exitWith {}; + + /* Make unit enter panic action */ + if (_unit isKindOf "Man" && !isPlayer _unit) then { + _unit setBehaviour "CARELESS"; + _unit disableAI "FSM"; + _unit setUnitPosWeak "UP"; + //_unit playAction "Panic"; // Broken as of Arma 3 v2.12 + _unit switchMove "ApanPercMstpSnonWnonDnon_ApanPknlMstpSnonWnonDnon"; + + private _runTarget = _unit getPos [50 * sqrt random 1, random 360]; + doGetOut _unit; + _unit doMove _runTarget; + }; +}] call CBA_fnc_addEventHandler; \ No newline at end of file diff --git a/framework/components/ai/functions/fn_hostage.sqf b/framework/components/ai/functions/fn_hostage.sqf new file mode 100644 index 0000000..05addaf --- /dev/null +++ b/framework/components/ai/functions/fn_hostage.sqf @@ -0,0 +1,106 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Make unit a hostage + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [this, true, true] call cmf_ai_fnc_hostage + * + * Public: No + */ +params ["_unit", ["_captive", true], ["_blindfold", false]]; + +_unit disableAI "FSM"; +_unit disableAI "AUTOCOMBAT"; +[_unit] joinSilent createGroup civilian; +_unit setBehaviour "CARELESS"; +_unit setUnloadInCombat [false, false]; +_unit setVariable ["lambs_danger_disableAI", true, true]; + +GVAR(hostage_translateStance) = { + params ["_stance"]; + + if (_stance isEqualTo "STAND") exitWith { "UP" }; + if (_stance isEqualTo "CROUCH") exitWith { "MIDDLE" }; + if (_stance isEqualTo "PRONE") exitWith { "DOWN" }; + + ""; +}; + +GVAR(hostage_releaseFNC) = { + params ["_hostage", "_target"]; + + _hostage setVariable [QGVAR(hostage_owner), objNull, true]; + [_hostage] joinSilent createGroup civilian; + [_hostage getVariable QGVAR(hostage_handler)] call CBA_fnc_removePerFrameHandler; +}; + +GVAR(hostage_followPlayerFNC) = { + params ["_hostage", "_target"]; + + _hostage setVariable [QGVAR(hostage_owner), _target, true]; + [_hostage] joinSilent createGroup side _target; + + private _handle = [{ + (_this select 0) params ["_hostage", "_target"]; + + if (!alive _target) exitWith { + _target setVariable [QGVAR(hostage_owner), objNull, true]; + [_hostage] joinSilent createGroup civilian; + [_hostage getVariable QGVAR(hostage_handler)] call CBA_fnc_removePerFrameHandler; + }; + + if ((vehicle _target) isEqualTo _target) then { + if (vehicle _hostage != _hostage) then { + unassignVehicle _hostage; + }; + + [_hostage] doMove (_target modelToWorld [0, -0.5, 0]); + _hostage setUnitPos ([stance _target] call GVAR(hostage_translateStance)); + } else { + if (vehicle _hostage != _hostage) exitWith { + _hostage moveInCargo [vehicle _target, (vehicle _target) getCargoIndex _hostage]; + }; + + private _getSeat = [vehicle _target] call ace_captives_fnc_findEmptyNonFFVCargoSeat; + _getSeat params ["_cargoIndex"]; + if (_cargoIndex == -1) exitWith {}; + + _hostage assignAsCargoIndex [vehicle _target, _cargoIndex]; + [_hostage] orderGetIn true; + } + }, 0.3, [_hostage, _target]] call CBA_fnc_addPerFrameHandler; + + _hostage setVariable [QGVAR(hostage_handler), _handle, true]; +}; + +if (_captive) then { + [_unit, true] call ACE_captives_fnc_setHandcuffed; +}; + +/* Follow player action */ +private _followAction = [QGVAR(hostageFollow), "Follow Me!", "", + GVAR(hostage_followPlayerFNC), + { + isNull ((_this select 0) getVariable [QGVAR(hostage_owner), objNull]) && + !((_this select 0) getVariable ["ace_captives_isHandcuffed", false]) + } +] call ace_interact_menu_fnc_createAction; + +/* Stop following action */ +private _stopAction = [QGVAR(hostageFollow), "Stay Here!", "", + GVAR(hostage_releaseFNC), + { + !isNull ((_this select 0) getVariable [QGVAR(hostage_owner), objNull]) + } +] call ace_interact_menu_fnc_createAction; + +[_unit, 0, ["ACE_MainActions"], _followAction] call ace_interact_menu_fnc_addActionToObject; +[_unit, 0, ["ACE_MainActions"], _stopAction] call ace_interact_menu_fnc_addActionToObject; + diff --git a/framework/components/ai/functions/fn_panic.sqf b/framework/components/ai/functions/fn_panic.sqf new file mode 100644 index 0000000..5ae3113 --- /dev/null +++ b/framework/components/ai/functions/fn_panic.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: Eric + * When AI enteres panic mode they will either attempt to retreat or surrender + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_ai_fnc_panic + * + * Public: No + */ + +["lambs_danger_OnPanic", { + params ["_unit", "_group"]; + + LOG_1("%1 Entered Panic Mode", _unit); + + if (isPlayer _unit) exitWith {}; + if (_unit getVariable [QGVAR(disablePanic), false]) exitWith {}; + + private _groupUnits = units _group; + + /* 5% chance of surrendering */ + if (5 > random 100) exitWith { // @TODO: Consider making it a configurable parameter + LOG_1("%1 is surrendering", _unit); + _unit playAction "Surrender"; + }; + + /* 50% Chance of group retreating when paniced */ + if (50 > random 100) then { // @TODO: Consider making it a configurable parameter + LOG_1("%1 is Retreating", _unit); + private _attackDir = _unit getDir (getAttackTarget _unit); + private _retreatDir = (_attackDir + 180) % 360; + private _retreatPos = _unit getPos [_retreatDir, random 500]; + + /* Reset AI after retreat is successful */ + [_unit, _retreatPos, true] spawn lambs_wp_fnc_taskAssault; + [_unit, _retreatPos] spawn { + params ["_unit", "_pos"]; + + waitUntil { _unit distance2D _pos < 30 }; + [_unit] call lambs_wp_fnc_taskReset; + }; + }; +}] call CBA_fnc_addEventHandler; \ No newline at end of file diff --git a/framework/components/ai/functions/fn_preventProne.sqf b/framework/components/ai/functions/fn_preventProne.sqf new file mode 100644 index 0000000..3e622fa --- /dev/null +++ b/framework/components/ai/functions/fn_preventProne.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Prevents AI 'from going prone + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_ai_fnc_preventProne + * + * Public: No + */ +SCRIPT(preventProne); + +/* preventProne on AI units */ +["CAManBase", "init", { + params ["_unit"]; + + if (!GVAR(setting_preventProne)) exitWith {}; + + if (missionNamespace getVariable [QEGVAR(utility,preventProne_disable), false]) exitWith {}; + if (_unit getVariable [QEGVAR(utility,preventProne_disable), false]) exitWith {}; + if (isPlayer _unit) exitWith {}; + + [_unit] call EFUNC(utility,preventProne); + LOG_1("Enabled preventProne for %1", _unit); +}, true, [], true] call CBA_fnc_addClassEventHandler; \ No newline at end of file diff --git a/framework/components/ai/functions/fn_reinforce.sqf b/framework/components/ai/functions/fn_reinforce.sqf new file mode 100644 index 0000000..cd25ae7 --- /dev/null +++ b/framework/components/ai/functions/fn_reinforce.sqf @@ -0,0 +1,61 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Makes ai reinforce groups in contact + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [300, 15] call cmf_ai_fnc_reinforce + * + * public: Yes +*/ +SCRIPT(reinforce); + +if (!isServer) exitWith {}; + +/* Transfer all new AI groups to server */ +["CAManBase", "init", { + params ["_unit"]; + + if (!GVAR(setting_reinforce)) exitWith {}; + + private _group = group _unit; + + if (_group getVariable [QGVAR(reinforce_initialized), false]) exitWith {}; + + { + [[_group], true] call lambs_danger_fnc_setReinforcement; + [[_group], true] call lambs_danger_fnc_setHasRadio; + } forEach units _group; + + /* Add eventhandler to make group rush to contact */ + ["lambs_danger_OnInformationShared", { + _thisArgs params ["_reinforceGroup"]; + params ["", "_shareGroup", "_target"]; + + if (_reinforceGroup getVariable [QGVAR(reinforce_disableGroup), false]) exitWith {}; + if ((group _target) getVariable [QGVAR(reinforce_disableTarget), false]) exitWith {}; + + if ( (leader _reinforceGroup distance leader _shareGroup) < GVAR(setting_reinforceRange) && _reinforceGroup != _shareGroup && !(_reinforceGroup getVariable [QGVAR(reinforce_targetGroup), grpNull] isEqualTo _shareGroup) && side _reinforceGroup isEqualTo side _shareGroup ) then { + LOG_2("%1 reinforcing %2(TaskRush)", groupId _reinforceGroup, groupId _shareGroup); + + [_reinforceGroup, 200, 15, [], getPos _target, false] spawn lambs_wp_fnc_taskRush; + + /* Delete old waypoints and add new */ + for "_i" from count waypoints _reinforceGroup - 1 to 0 step -1 do { + deleteWaypoint [_reinforceGroup, _i]; + }; + private _wp = _reinforceGroup addWaypoint [_target, 0]; + _wp setWaypointType "MOVE"; + _reinforceGroup setVariable [QGVAR(reinforce_targetGroup), _shareGroup, true]; + }; + }, _group] call CBA_fnc_addEventHandlerArgs; + + LOG_1("Enabled reinforce on %1", groupId _group); + _group setVariable [QGVAR(reinforce_initialized), true, true]; +}, true, [], true] call CBA_fnc_addClassEventHandler; \ No newline at end of file diff --git a/framework/components/ai/functions/fn_setSkill.sqf b/framework/components/ai/functions/fn_setSkill.sqf new file mode 100644 index 0000000..c288cb6 --- /dev/null +++ b/framework/components/ai/functions/fn_setSkill.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Sets AI Skill to be more balanced. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_ai_fnc_setSkill + * + * public: Yes +*/ +SCRIPT(setSkill); + +/* Set skill on all units */ +["CAManBase", "init", { + params ["_unit"]; + + if (!GVAR(setting_skill)) exitWith {}; + + _unit setSkill ["aimingAccuracy", 0.3 ]; + _unit setSkill ["aimingShake", 0.5 ]; + _unit setSkill ["aimingSpeed", 0.3 ]; + _unit setSkill ["spotDistance", 0.5 ]; + _unit setSkill ["spotTime", 0.5 ]; + _unit setSkill ["courage", 0.5 ]; + _unit setSkill ["commanding", 0.5 ]; + _unit setSkill ["general", 0.4 ]; + _unit setSkill ["reloadSpeed", 0.5 ]; + _unit setSkill ["endurance", 0.5 ]; +}, true, [], true] call CBA_fnc_addClassEventHandler; \ No newline at end of file diff --git a/framework/components/ai/functions/fn_silenceAI.sqf b/framework/components/ai/functions/fn_silenceAI.sqf new file mode 100644 index 0000000..444e990 --- /dev/null +++ b/framework/components/ai/functions/fn_silenceAI.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Silences friendly AI + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * [] call cmf_ai_fnc_silenceAI + * + * Public: Yes + */ + +/* Disable AI contact reports */ +enableSentences false; + +["CAManBase", "init", { + params ["_unit"]; + + if ([side player, side _unit] call BIS_fnc_sideIsFriendly) then { + _unit setVariable ["BIS_noCoreConversations", true, false]; + while {!conversationDisabled _unit} do {_unit disableConversation true}; + } +}] call CBA_fnc_addClassEventHandler; diff --git a/framework/components/ai/functions/fn_transferToServer.sqf b/framework/components/ai/functions/fn_transferToServer.sqf new file mode 100644 index 0000000..4fade9f --- /dev/null +++ b/framework/components/ai/functions/fn_transferToServer.sqf @@ -0,0 +1,33 @@ +/* + * Author: Eric + * Transfers zeus spawned AI to server for better ai calculations and better performance for the zeus client + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_ai_fnc_transferToServer + * + * Public: No + */ +SCRIPT(transferToServer); + +if (!isServer) exitWith {}; + +/* Transfer all new AI groups to server */ +["CAManBase", "init", { + params ["_unit"]; + + if (!GVAR(setting_serverTransfer)) exitWith {}; + + if (isPlayer _unit) exitWith {}; + + private _group = group _unit; + if (groupowner _group isEqualTo 2) exitWith {}; + + _group setGroupOwner 2; + LOG_1("Transfered %1 to server", groupId _group); +}, true, [], true] call CBA_fnc_addClassEventHandler; diff --git a/framework/components/ai/functions/script_component.hpp b/framework/components/ai/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/ai/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/ai/initSettings.sqf b/framework/components/ai/initSettings.sqf new file mode 100644 index 0000000..abc9982 --- /dev/null +++ b/framework/components/ai/initSettings.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" + +[ + QGVAR(setting_serverTransfer), + "CHECKBOX", + ["Transfer to Server", "Transfers AI ownership to Server"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_preventProne), + "CHECKBOX", + ["Prevent Prone", "Stops AI from going prone"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_skill), + "CHECKBOX", + ["Force Skill", "Forces AI skill to the CC Default"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_reinforce), + "CHECKBOX", + ["Auto Reinforce", "Makes AI automatically move towards reported enemy groups"], + QUOTE(MODULE_BEAUTIFIED - Reinforce), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_reinforceRange), + "SLIDER", + ["Reinforce Max Distance", "Maximum distance a AI group will move to reinforce"], + QUOTE(MODULE_BEAUTIFIED - Reinforce), + [0, 5000, 300, 0, false], + 1 +] call EFUNC(common,addSetting); \ No newline at end of file diff --git a/framework/components/ai/script_component.hpp b/framework/components/ai/script_component.hpp index e03926e..89e57c1 100644 --- a/framework/components/ai/script_component.hpp +++ b/framework/components/ai/script_component.hpp @@ -1,5 +1,15 @@ #define MODULE ai +#define MODULE_BEAUTIFIED AI + #define REQUIRED_ADDONS ["lambs_danger"] #define REQUIRED_MODULES ["common"] -#include "..\main\script_component.hpp" +#ifdef DEBUG_ENABLED_AI + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_AI + #define DEBUG_SETTINGS DEBUG_SETTINGS_AI +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/common/XEH_3denInit.sqf b/framework/components/common/XEH_3denInit.sqf new file mode 100644 index 0000000..8f6d0c9 --- /dev/null +++ b/framework/components/common/XEH_3denInit.sqf @@ -0,0 +1,206 @@ +#include "script_component.hpp" + +waitUntil { !isNil { missionNameSpace getVariable QEGVAR(3den,menu_entity) } }; + +private _path = missionNameSpace getVariable QEGVAR(3den,menu_entity); + +/* Action to add a radio rack to a vehicle */ +private _acreRadioRackAction = [ + "Add Radio Rack (ACRE)", + "a3\ui_f\data\gui\rsc\rscdisplayarsenal\radio_ca.paa", + { + if (count get3DENSelected "object" == 0) exitWith { + ["No Objects selected", 0, 1] call BIS_fnc_3DENNotification; + }; + + private _display3DEN = uiNamespace getVariable "Display3DEN"; + private _display = _display3DEN createDisplay QEGVAR(3den,addRack); + + private _addCtrl = _display displayCtrl 1; + private _radioCtrl = _display displayCtrl 100; + + { + private _index = _radioCtrl lbAdd ([(_x select 1) + "_ID_1"] call acre_api_fnc_getDisplayName); + _radioCtrl lbSetData [_index, str _x]; + } forEach [["ACRE_VRC103", "ACRE_PRC117F"], ["ACRE_VRC64", "ACRE_PRC77"], ["ACRE_VRC110", "ACRE_PRC152"], ["ACRE_VRC111", "ACRE_PRC148"], ["ACRE_SEM90", "ACRE_SEM70"]]; + _radioCtrl lbSetSelected [1, true]; + + _addCtrl ctrlAddEventHandler ["ButtonClick", { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + private _vehicles = get3DENSelected "object"; + private _comboCtrl = _display displayCtrl 100; + private _radio = call compile (_comboCtrl lbData (lbCurSel _comboCtrl)); + + if (isNil "_radio") exitWith { + ["You need to select a radio", 1, 1] call BIS_fnc_3DENNotification; + }; + + if (count _vehicles isEqualTo 0) exitWith { + ["You need to select at least one object", 1, 1] call BIS_fnc_3DENNotification; + }; + + { + private _oldInit = (_x get3DENAttribute "Init") select 0; + private _newInit = format["[this, {[_this, [""%1"", ""Rack"", ""Rack"", false, [""crew""], [], ""%2"", [], []], true, {}], acre_api_fnc_addRackToVehicle}] remoteExec [""call"", 0, true];", (_radio select 0), (_radio select 1)]; + + _x set3DENAttribute ["Init", _oldInit + _newInit]; + } forEach _vehicles; + + ["Added radio to vehicles", 0, 1] call BIS_fnc_3DENNotification; + }]; + } +]; + +private _simulationAction = [ + LSTRING(toggle_sim_3den_displayName), + "a3\modules_f\data\editterrainobject\textureunchecked_wall_ca.paa", + { + if (count get3DENSelected "object" == 0) exitWith { + ["No Objects selected", 0, 1] call BIS_fnc_3DENNotification; + }; + + private _selections = get3DENSelected "object"; + private _first = (_selections) select 0; + private _toggle = (simulationEnabled _first); + + { + _x enableSimulation _toggle; + } forEach _selections; + + private _statusText = format ["%1 3DEN Simulation for %2 object(s)", ["Disabled", "Enabled"] select _toggle, count _selections]; + [_statusText, 0, 1] call BIS_fnc_3DENNotification; + } +]; + +private _simpleAction = [ + LSTRING(make_obj_simple_displayName), + "z\ace\addons\zeus\ui\icon_module_zeus_editable_objects_ca.paa", + { + if (count get3DENSelected "object" == 0) exitWith { + ["No Objects selected", 0, 1] call BIS_fnc_3DENNotification; + }; + + { + _command = toString { + this spawn { + private _obj = createSimpleObject[(typeof _this), (getposASL _this), false]; + _obj setVectorDirAndUp [(vectorDir _this), (vectorUp _this)]; + deleteVehicle _this; + }; + }; + + if !([_x, _command] call EFUNC(3den,inInit)) then { + [_x, _command] call EFUNC(3den,addToInit); + _x set3DENAttribute ["enableSimulation", false]; + _x set3DENAttribute ["allowDamage", false]; + } else { + [_x, _command] call EFUNC(3den,removeFromInit); + _x set3DENAttribute ["enableSimulation", true]; + _x set3DENAttribute ["allowDamage", true]; + }; + } forEach get3DENSelected "object"; + + ["Toggled Simplified selected objects", 0, 1] call BIS_fnc_3DENNotification; + } +]; + +[ + _path, + "General", + "a3\3den\data\displays\display3den\toolbar\open_ca.paa", + {}, + [], + [ + _acreRadioRackAction, + _simulationAction, + _simpleAction + ] +] call EFUNC(3den,addMenuItem); + +private _carryAction = [ + "Toggle ACE Carryable", + "z\ace\addons\dragging\ui\icons\box_carry.paa", + { + if (count get3DENSelected "object" == 0) exitWith { + ["No Objects selected", 0, 1] call BIS_fnc_3DENNotification; + }; + + private _enableCommand = "[this, true] call ace_dragging_fnc_setCarryable"; + private _disableCommand = "[this, fales] call ace_dragging_fnc_setCarryable"; + + private _selections = get3DENSelected "object"; + private _first = (_selections) select 0; + private _isSet = ([_first, _enableCommand] call EFUNC(3den,inInit) || [_first, _disableCommand] call EFUNC(3den,inInit)); + private _toggle = ([_first, _enableCommand] call EFUNC(3den,inInit) || !_isSet); + + { + if (_toggle) then { + if ([_x, _disableCommand] call EFUNC(3den,inInit)) then { + [_x, _disableCommand] call EFUNC(3den,removeFromInit); + }; + + [_x, _enableCommand] call EFUNC(3den,addToInit); + } else { + if ([_x, _enableCommand] call EFUNC(3den,inInit)) then { + [_x, _enableCommand] call EFUNC(3den,removeFromInit); + }; + + [_x, _disableCommand] call EFUNC(3den,addToInit); + }; + } forEach _selections; + + private _statusText = format ["%1 Carrying for %2 object(s)", ["Disabled", "Enabled"] select _toggle, count _selections]; + [_statusText, 0, 1] call BIS_fnc_3DENNotification; + } +]; + +private _dragAction = [ + "Toggle ACE Draggable", + "z\ace\addons\dragging\ui\icons\box_carry.paa", + { + if (count get3DENSelected "object" == 0) exitWith { + ["No Objects selected", 0, 1] call BIS_fnc_3DENNotification; + }; + + private _enableCommand = "[this, true] call ace_dragging_fnc_setDraggable"; + private _disableCommand = "[this, fales] call ace_dragging_fnc_setDraggable"; + + private _selections = get3DENSelected "object"; + private _first = (_selections) select 0; + private _isSet = ([_first, _enableCommand] call EFUNC(3den,inInit) || [_first, _disableCommand] call EFUNC(3den,inInit)); + private _toggle = ([_first, _enableCommand] call EFUNC(3den,inInit) || !_isSet); + + { + if (_toggle) then { + if ([_x, _disableCommand] call EFUNC(3den,inInit)) then { + [_x, _disableCommand] call EFUNC(3den,removeFromInit); + }; + + [_x, _enableCommand] call EFUNC(3den,addToInit); + } else { + if ([_x, _enableCommand] call EFUNC(3den,inInit)) then { + [_x, _enableCommand] call EFUNC(3den,removeFromInit); + }; + + [_x, _disableCommand] call EFUNC(3den,addToInit); + }; + } forEach _selections; + + private _statusText = format ["%1 Dragging for %2 object(s)", ["Disabled", "Enabled"] select _toggle, count _selections]; + [_statusText, 0, 1] call BIS_fnc_3DENNotification; + } +]; + +[ + _path, + "ACE3", + "z\ace\addons\common\data\logo_ace3_ca.paa", + {}, + [], + [ + _carryAction, + _dragAction + ] +] call EFUNC(3den,addMenuItem); \ No newline at end of file diff --git a/framework/components/common/XEH_PREP.sqf b/framework/components/common/XEH_PREP.sqf index e92d21b..270d462 100644 --- a/framework/components/common/XEH_PREP.sqf +++ b/framework/components/common/XEH_PREP.sqf @@ -1,6 +1,10 @@ #include "script_component.hpp" -PREP(getConfigParam); -PREP(setRole); -PREP(isRole); +PREP(addSetting); +PREP(addKeybind); PREP(setCallsign); +PREP(getCallsign); +PREP(keybindToString); +PREP(nearestNumber); +PREP(notification); +PREP(diary); \ No newline at end of file diff --git a/framework/components/common/XEH_postInit.sqf b/framework/components/common/XEH_postInit.sqf new file mode 100644 index 0000000..8850cc5 --- /dev/null +++ b/framework/components/common/XEH_postInit.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" + +/* Create cmf_player */ +cmf_player = player; +["unit", { + params ["_unit"]; + + if !(_unit isKindOf "Man") exitWith {}; + + cmf_player = _unit; +}] call CBA_fnc_addPlayerEventHandler; + +/* Create CMF Info Diary */ +[] spawn FUNC(diary); + +/* Remove statistics diary */ +cmf_player removeDiarySubject "Statistics"; + +/* Remove team diary */ +cmf_player removeDiarySubject "Units"; + +/* Create notification colors */ +GVAR(notificationColors) = createHashMapFromArray [ + ["DEFAULT", [0.69, 0.69, 0.69, 0.50]], + ["INFO", [0.00, 0.75, 0.75, 0.50]], + ["DEBUG", [0.99, 0.42, 0.98, 0.50]], + ["WARNING", [0.78, 0.78, 0.00, 0.50]], + ["ERROR", [0.81, 0.20, 0.17, 0.50]] +]; \ No newline at end of file diff --git a/framework/components/common/fn_getConfigParam.sqf b/framework/components/common/fn_getConfigParam.sqf deleted file mode 100644 index d985795..0000000 --- a/framework/components/common/fn_getConfigParam.sqf +++ /dev/null @@ -1,44 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Returns the config parameter at the given path - * - * Arguments: - * 0: Parameter Path - * - * Return Value: - * Parameter Value - * - * Example: - * [["SETTINGS", "init", "CLEAR_VEHICLE_CARGO"]] call cmf_common_fnc_getConfigParam - * - * Public: Yes - */ -SCRIPT(getConfigParam); -params [["_path", [], [[]]]]; - -/* If config array doesn't exist already define it and make it global */ -if (isNil QGVAR(configParameters)) then { - missionNamespace setVariable [QGVAR(configParameters), createHashMap, true]; -}; - -/* Check if there is a value in the configparameters variable */ -private _value = GVAR(configParameters); -{ - private _key = _x; - if !(IS_HASHMAP(_value)) exitWith {_value = _value}; - if !(_key in _value) exitWith {_value = nil}; - _value = _value get _key; -} forEach _path; - -/* If there is no value defined check the config */ -if (isNil "_value") then { - _value = (["CMF"] + _path) call BIS_fnc_getCfgData; -}; - -/* If it's still nil return empty string */ -if (isNil "_value") then { - _value = ""; -}; - -_value; diff --git a/framework/components/common/fn_setCallsign.sqf b/framework/components/common/fn_setCallsign.sqf deleted file mode 100644 index 31e8886..0000000 --- a/framework/components/common/fn_setCallsign.sqf +++ /dev/null @@ -1,105 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Sets squad callsign and optionally type and level - * - * Arguments: - * 0: Group - * 1: Callsign - * 2: Type (Optional) - * 3: Command Level (Optional) - * - * Return Value: - * None - * - * Example: - * [_myGroup, "A1", "ARMOR", "PLT"] call cmf_common_fnc_setCallsign - * - * Public: Yes - */ -SCRIPT(setCallsign); -if (!isServer) exitWith {}; -params["_group", "_callsign", ["_type", "INF"], ["_level", "FT"]]; - -/* Set the group's callsign */ -_group setGroupId [_callsign]; -_group setVariable [QGVAR(sqd_callsign), _callsign, true]; - -/* Set the group's squad type */ -_group setVariable [QGVAR(sqd_type), _type, true]; - -/* Set the groups size and the group's unit's the ranks */ -private _sizes = ("true" configClasses (missionConfigFile >> "CMF_ORBAT" >> "SIZES")) apply {configName _x}; -_group setVariable [QGVAR(sqd_size), _level, true]; -if (_level in _sizes) then { - private _leaderRank = getText (missionConfigFile >> "CMF_ORBAT" >> "SIZES" >> toUpper _level >> "leadRank"); - private _generalRank = getText (missionConfigFile >> "CMF_ORBAT" >> "SIZES" >> toUpper _level >> "generalRank"); - { - if ((rank _x) isEqualTo "PRIVATE") then { - if (_x isEqualTo (leader _group)) then { - [_x, _leaderRank] remoteExec ["setRank", 0, true]; - } else { - [_x, _generalRank] remoteExec ["setRank", 0, true]; - }; - }; - } forEach units _group; -} else { - if ((rank (leader _group)) isEqualTo "PRIVATE") then { - [(leader _group), "SERGEANT"] remoteExec ["setRank", 0, true]; - }; -}; - -/* Set group gesture colors */ -private _color = [1,0.88,0,0.7]; -private _leadColor = [1,0.88,0,0.95]; -switch (_level) do { - - /* Set colors for fireteam elements */ - case ("FT"): { - switch (true) do { - case (["A", _callsign] call BIS_fnc_inString): { _color = [1,0,0,0.7]; _leadColor = [1,0,0,0.95] }; - case (["B", _callsign] call BIS_fnc_inString): { _color = [0,1,0,0.7]; _leadColor = [0,1,0,0.95] }; - case (["C", _callsign] call BIS_fnc_inString): { _color = [0,0,1,0.7]; _leadColor = [0,0,1,0.95] }; - default { _color = [1,0.54,0,0.7]; _leadColor = [1,0.54,0,0.95] }; - }; - }; - - /* Set colors for squad elements */ - case ("SQD"): { - switch (true) do { - case (["ASL", _callsign] call BIS_fnc_inString): { _color = [1,0,0,0.7]; _leadColor = [1,0,0,0.95] }; - case (["BSL", _callsign] call BIS_fnc_inString): { _color = [0,1,0,0.7]; _leadColor = [0,1,0,0.95] }; - case (["CSL", _callsign] call BIS_fnc_inString): { _color = [0,0,1,0.7]; _leadColor = [0,0,1,0.95] }; - default { _color = [1,0.54,0,0.7]; _leadColor = [1,0.54,0,0.95] }; - }; - }; - - /* Set color for platoon elements */ - case ("PLT"): { - switch (true) do { - case (["HQ", _callsign] call BIS_fnc_inString): { _color = [1,1,0,0.7]; _leadColor = [1,1,0,0.95] }; - case (["PHANTOM", _callsign] call BIS_fnc_inString): { _color = [0,0,1,0.7]; _leadColor = [0,0,1,0.95] }; - case (["REAPER", _callsign] call BIS_fnc_inString): { _color = [0,0,1,0.7]; _leadColor = [0,0,1,0.95] }; - case (["UGLY", _callsign] call BIS_fnc_inString): { _color = [0,0,1,0.7]; _leadColor = [0,0,1,0.95] }; - case (["HAWG", _callsign] call BIS_fnc_inString): { _color = [0.85,0.64,0.12,0.7]; _leadColor = [0.85,0.64,0.12,0.95] }; - case (["PAVEMENT", _callsign] call BIS_fnc_inString): { _color = [0.85,0.64,0.12,0.7]; _leadColor = [0.85,0.64,0.12,0.95] }; - default { _color = [1,0.54,0,0.7]; _leadColor = [1,0.54,0,0.95] }; - }; - }; - - /* Set color for company elements */ - case ("COY"): { - switch (true) do { - case (["HQ", _callsign] call BIS_fnc_inString): { _color = [0.05,0.05,0.05,0.7]; _leadColor = [0.05,0.05,0.05,0.95] }; - }; - }; -}; -[[_callsign, _color, _leadColor], ace_map_gestures_fnc_addGroupColorMapping] remoteExec ["call", 0, true]; - -/* Set the group parameters for each unit in the group */ -{ - _x setVariable [QGVAR(group), [_callsign, _type, _level], true]; -} forEach units _group; - -/* Raise event */ -[QGVAR(onGroupCallsignChanged), _this, _group] call CBA_fnc_targetEvent; diff --git a/framework/components/common/functions/fn_addKeybind.sqf b/framework/components/common/functions/fn_addKeybind.sqf new file mode 100644 index 0000000..8bcdf75 --- /dev/null +++ b/framework/components/common/functions/fn_addKeybind.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Adds a CBA Keybind for CMF + * + * Arguments: + * 0: Category + * 1: Variable Name + * 2: Title + * 3: Down Code + * 4: Up Code + * 5: Keybind + * - DIK Key + * - Shift, Ctrl, Alt + * 6: Hold Key + * 7: Hold Delay + * 8: Overwrite + * + * Return Value: + * None + * + * Example: + * ["myCategory", ["My Setting", "My Tooltip"], "MySetting", {}, {}, [DIK_TAB, [false, true, false]]] call cmf_common_fnc_addKeybind; + * + * Public: Yes + */ +params["_category", "_uniqueName", "_title", "_downCode", "_upCode", "_defaultKeybind", ["_holdKey", false], ["_holdDelay", 0], ["_overwrite", false]]; + +if (isNil QGVAR(clientKeybinds)) then { + GVAR(clientKeybinds) = [] call CBA_fnc_hashCreate; +}; + +[_category, _uniqueName, _title, _downCode, _upCode, _defaultKeybind, _holdKey, _holdDelay, _overwrite] call CBA_fnc_addKeybind; + +/* Update keybinds hash */ +private _keybindCategory = [GVAR(clientKeybinds), _category, []] call CBA_fnc_hashGet; +_keybindCategory pushBack [_uniqueName, _title]; +GVAR(clientKeybinds) = [GVAR(clientKeybinds), _category, _keybindCategory] call CBA_fnc_hashSet; \ No newline at end of file diff --git a/framework/components/common/functions/fn_addSetting.sqf b/framework/components/common/functions/fn_addSetting.sqf new file mode 100644 index 0000000..f623fea --- /dev/null +++ b/framework/components/common/functions/fn_addSetting.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Adds a CMF setting for configuring cmf + * + * Arguments: + * 0: Variable Name + * 1: Setting Type + * 2: Title + * 3: Category + * + * Return Value: + * None + * + * Example: + * ["myVariable", "CHECKBOX", ["My Setting", "My Tooltip"], "Setting Category"] call cmf_common_fnc_addSetting; + * + * Public: Yes + */ +params["_uniqueName", "_type", "_title", "_category", "_valueInfo", ["_isGlobal", 0], ["_script", {}]]; + +if (isNil QGVAR(missionSettings)) then { + GVAR(missionSettings) = [] call CBA_fnc_hashCreate; +}; + +if (isNil QGVAR(clientSettings)) then { + GVAR(clientSettings) = [] call CBA_fnc_hashCreate; +}; + +if (_isGlobal isEqualTo 0) then { + [_uniqueName, _type, _title, [QUOTE(FRAMEWORK - Client), _category], _valueInfo, _isGlobal] call CBA_fnc_addSetting; + + /* Update settings hash */ + private _settingCategory = [GVAR(clientSettings), _category, []] call CBA_fnc_hashGet; + _settingCategory pushBack [_uniqueName, _title, _isGlobal]; + GVAR(clientSettings) = [GVAR(clientSettings), _category, _settingCategory] call CBA_fnc_hashSet; +} else { + [_uniqueName, _type, _title, [QUOTE(FRAMEWORK - Mission), _category], _valueInfo, _isGlobal] call CBA_fnc_addSetting; + + /* Update settings hash */ + private _settingCategory = [GVAR(missionSettings), _category, []] call CBA_fnc_hashGet; + _settingCategory pushBack [_uniqueName, _title, _isGlobal]; + GVAR(missionSettings) = [GVAR(missionSettings), _category, _settingCategory] call CBA_fnc_hashSet; +}; + diff --git a/framework/components/common/functions/fn_diary.sqf b/framework/components/common/functions/fn_diary.sqf new file mode 100644 index 0000000..d05cd8a --- /dev/null +++ b/framework/components/common/functions/fn_diary.sqf @@ -0,0 +1,115 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Creates a diary entry containing information about the installed version of CMF + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] spawn cmf_main_fnc_diary + * + * Public: No + */ + +[{ missionNamespace getVariable [QEGVAR(main,server_initialized), false] && (!isNull player && alive player) }, { + /* Create subject */ + player createDiarySubject [QGVAR(diary), QUOTE(FRAMEWORK)]; + + addMissionEventHandler ["Map", { + params ["_mapIsOpened"]; + + if (!_mapIsOpened) then { + /* Remove outdated info */ + { + player removeDiaryRecord [QGVAR(diary), _x select 8] + } forEach (player allDiaryRecords QGVAR(diary)); + } else { + /* Credits */ + player createDiaryRecord [QGVAR(diary), ["Credits", "
Cluster Mod Team:
-
Eric"]]; + + /* List CMF Keybinds */ + private _clientKeybinds = "
"; + { + private _category = _x; + _clientKeybinds = _clientKeybinds + format ["%1:
", _category]; + + private _keybindsArr = [GVAR(clientKeybinds), _category] call CBA_fnc_hashGet; + { + private _title = [_x select 1, (_x select 1) select 0] select ((_x select 1) isEqualType []); + _clientKeybinds = _clientKeybinds + format [ + " %1: %2
", + _title, + [([_category, _x select 0] call CBA_fnc_getKeybind) select 5] call cmf_common_fnc_keybindToString + ]; + } forEach _keybindsArr; + _clientKeybinds = _clientKeybinds + "
"; + } forEach ([GVAR(clientKeybinds)] call CBA_fnc_hashKeys); + player createDiaryRecord [QGVAR(diary), ["Keybinds", _clientKeybinds]]; + + /* List CMF Settings */ + private _clientSettings = "
"; + { + _clientSettings = _clientSettings + format ["%1:
", _x]; + + private _settingsArr = [GVAR(clientSettings), _x] call CBA_fnc_hashGet; + { + private _title = [_x select 1, (_x select 1) select 0] select ((_x select 1) isEqualType []); + _clientSettings = _clientSettings + format [ + " %1: %2
", + _title, + str (missionNamespace getVariable [_x select 0, ""]) + ]; + } forEach _settingsArr; + _clientSettings = _clientSettings + "
"; + } forEach ([GVAR(clientSettings)] call CBA_fnc_hashKeys); + + player createDiaryRecord [QGVAR(diary), ["Client Settings", _clientSettings]]; + + private _missionSettings = "
"; + { + _missionSettings = _missionSettings + format ["%1:
", _x]; + + private _settingsArr = [GVAR(missionSettings), _x] call CBA_fnc_hashGet; + { + private _title = [_x select 1, (_x select 1) select 0] select ((_x select 1) isEqualType []); + _missionSettings = _missionSettings + format [ + " %1: %2
", + _title, + str (missionNamespace getVariable [_x select 0, ""]) + ]; + } forEach _settingsArr; + _missionSettings = _missionSettings + "
"; + } forEach ([GVAR(missionSettings)] call CBA_fnc_hashKeys); + + player createDiaryRecord [QGVAR(diary), ["Mission Settings", _missionSettings]]; + + /* List loaded CMF Components */ + private _componentString = "
"; + + { + _componentString = _componentString + format[" - %1
", _x] + } forEach EGVAR(main,components); + + player createDiaryRecord [QGVAR(diary), ["Components", _componentString]]; + + /* List version number for CMF and it's dependencies */ + private _versionString = "
"; + + private _cmfVersion = ["CMF3", missionNamespace getVariable QEGVAR(main,version)]; + private _cbaVersion = ["CBA3", getText (configFile >> "CfgPatches" >> "cba_main" >> "versionStr")]; + private _aceVersion = ["ACE3", getText (configFile >> "CfgPatches" >> "ace_main" >> "versionStr")]; + private _zenVersion = ["ZEN3", getText (configFile >> "CfgPatches" >> "zen_main" >> "versionStr")]; + + { + _versionString = _versionString + format["%1 VERSION: %2
", _x select 0, _x select 1] + } forEach [_cmfVersion, _cbaVersion, _aceVersion, _zenVersion]; + + player createDiaryRecord [QGVAR(diary), ["Version", _versionString]]; + }; + }]; +}] call CBA_fnc_waitUntilAndExecute; + diff --git a/framework/components/common/functions/fn_getCallsign.sqf b/framework/components/common/functions/fn_getCallsign.sqf new file mode 100644 index 0000000..c940ead --- /dev/null +++ b/framework/components/common/functions/fn_getCallsign.sqf @@ -0,0 +1,29 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Returns a group;s callsign data + * + * Arguments: + * 0: Group + * + * Return Value: + * Group Callsign Data + * + * Example: + * [myGroup] call cmf_common_fnc_getCallsign + * + * Public: No + */ + +params ["_group"]; + +/* Get callsign */ +private _callsign = _group getVariable [QGVAR(sqd_callsign),""]; + +/* Get Type */ +private _type = _group getVariable [QGVAR(sqd_type), ""]; + +/* Get Size */ +private _size = _group getVariable [QGVAR(sqd_size), ""]; + +[_callsign, _type, _size] diff --git a/framework/components/common/functions/fn_keybindToString.sqf b/framework/components/common/functions/fn_keybindToString.sqf new file mode 100644 index 0000000..5928c8b --- /dev/null +++ b/framework/components/common/functions/fn_keybindToString.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Parses CBA keybinds to strings + * + * Arguments: + * 0: CBA Keybind + * + * Return Value: + * Keybind string + * + * Example: + * [[33, [false, true, false]]] call cmf_utility_fnc_keybindToString + * + * Public: Yes + */ +params["_keybind"]; + +private _dikCode = _keybind select 0; +(_keybind select 1) params ["_shift", "_ctrl", "_alt"]; + +_keyString = call compile keyName _dikCode; + +if (_shift && {_dikCode != 42}) then { + _keyString = format ["Shift + %1", _keyString]; +}; + +if (_alt && {_dikCode != 56}) then { + _keyString = format ["Alt + %1", _keyString]; +}; + +if (_ctrl && {_dikCode != 29}) then { + _keyString = format ["Ctrl + %1", _keyString]; +}; + +_keyString diff --git a/framework/components/common/functions/fn_nearestNumber.sqf b/framework/components/common/functions/fn_nearestNumber.sqf new file mode 100644 index 0000000..c9d36b3 --- /dev/null +++ b/framework/components/common/functions/fn_nearestNumber.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Returns the closest match from array + * + * Arguments: + * 0: Array of Numbers + * 1: Number to match + * + * Return Value: + * Nearest Match + * + * Example: + * [] call cmf_common_fnc_nearestNumber + * + * Public: Yes + */ + +params ["_arr", "_number"]; + +private _max = -log 0; +private _nearest = [0,0,0]; + +{ + private _dist = abs (_x - _number); + if (_dist < _max) then { + _max = _dist; + _nearest = _x; + }; +} count _arr; + +_nearest; \ No newline at end of file diff --git a/framework/components/common/functions/fn_notification.sqf b/framework/components/common/functions/fn_notification.sqf new file mode 100644 index 0000000..7e24712 --- /dev/null +++ b/framework/components/common/functions/fn_notification.sqf @@ -0,0 +1,107 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Displays a notification + * + * 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: cmf_player) + * 3: Custom Width (default: 10) + * + * Return Value: + * None + * + * Example: + * [["Test: %1", 123], 1.5] call cmf_common_fnc_notification + * ["wow", 1, cmf_player, 3] call cmf_common_fnc_notification + * + * Public: Yes + */ +params [["_text",""], ["_color", GVAR(notificationColors) get "DEFAULT"], ["_speed", 4], ["_displaySide", "right"]]; + +if (isDedicated || !hasInterface) exitWith {}; +if(isNil QGVAR(notifications)) then { + GVAR(notifications) = []; +}; + +disableSerialization; +private _display = findDisplay 46; + +if (_text isEqualType "") then { + _text = parseText _text; +}; + +private _height = 0.01; +private _posX = 0; +private _posY = 0; + +if(_displaySide == "left") then { + _posX = NOTIFICATION_M + safeZoneX; +} else { + _posX = safeZoneW + safeZoneX - NOTIFICATION_M - NOTIFICATION_W; +}; + +private _borderCtrl = _display ctrlCreate ["RscText", -1]; +private _textCtrl = _display ctrlCreate ["RscStructuredText", -1]; + +_borderCtrl ctrlSetPosition [_posX, _posY, NOTIFICATION_BORDER_W, _height]; +_borderCtrl ctrlSetBackgroundColor _color; +_borderCtrl ctrlSetFade 1; +_borderCtrl ctrlCommit 0; +_borderCtrl ctrlSetFade 0; +_borderCtrl ctrlCommit 0.4; + +_textCtrl ctrlSetStructuredText _text; +_textCtrl ctrlSetPosition [(_posX + NOTIFICATION_BORDER_W), _posY, NOTIFICATION_W - NOTIFICATION_BORDER_W, _height]; +_adjustedHeight = (ctrlTextHeight _textCtrl); +_textCtrl ctrlSetPosition [(_posX + NOTIFICATION_BORDER_W), _posY, NOTIFICATION_W - NOTIFICATION_BORDER_W, _adjustedHeight]; +_textCtrl ctrlCommit 0; +_borderCtrl ctrlSetPosition [_posX, _posY, NOTIFICATION_BORDER_W, _adjustedHeight]; +_borderCtrl ctrlCommit 0; +_textCtrl ctrlSetBackgroundColor [0.129,0.129,0.129, 0.129]; +_textCtrl ctrlSetFade 1; +_textCtrl ctrlCommit 0; +_textCtrl ctrlSetFade 0; +_textCtrl ctrlCommit 0.4; + +[{ + disableSerialization; + { + _x ctrlSetFade 1; + _x ctrlCommit 0.3; + } forEach _this; +}, [_textCtrl, _borderCtrl], _speed] call CBA_fnc_waitAndExecute; + +[{ + { + ctrlDelete _x; + } forEach _this; +}, [_textCtrl, _borderCtrl], _speed + 0.3] call CBA_fnc_waitAndExecute; + +GVAR(notifications) = ([[_borderCtrl, _textCtrl]] + GVAR(notifications)) select {!isNull (_x select 0) && !isNull (_x select 1)}; + +private _offsetY = 0; +if (count GVAR(notifications) > 0) then { + private _activeNotifications = 0; + { + _x params ["_ctrlBorder", "_ctrlText"]; + + if (_x findIf { isNull _x } isEqualTo -1) then { + _ctrlBorder ctrlSetPosition [_posX, (_posY + _offsetY)]; + _ctrlText ctrlSetPosition [(_posX + NOTIFICATION_BORDER_W), (_posY + _offsetY)]; + _ctrlBorder ctrlCommit 0.25; + _ctrlText ctrlCommit 0.25; + _offsetY = _offsetY + NOTIFICATION_M + ((ctrlPosition _ctrlText) select 3); + + if (_activeNotifications > 3) then { + _ctrlText ctrlSetFade 1; + _ctrlText ctrlCommit 0.2; + _ctrlBorder ctrlSetFade 1; + _ctrlBorder ctrlCommit 0.2; + }; + + _activeNotifications = _activeNotifications + 1; + }; + } forEach GVAR(notifications); +}; \ No newline at end of file diff --git a/framework/components/common/functions/fn_setCallsign.sqf b/framework/components/common/functions/fn_setCallsign.sqf new file mode 100644 index 0000000..63cc504 --- /dev/null +++ b/framework/components/common/functions/fn_setCallsign.sqf @@ -0,0 +1,40 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Sets squad callsign and optionally type and level + * + * Arguments: + * 0: Group + * 1: Callsign + * 2: Type (Optional) + * 3: Command Level (Optional) + * + * Return Value: + * None + * + * Example: + * [_myGroup, "A1", "ARMOR", "PLT"] call cmf_common_fnc_setCallsign + * + * Public: Yes + */ +SCRIPT(setCallsign); +if (!isServer) exitWith {}; +params["_group", "_callsign", ["_type", "INF"], ["_level", "FT"]]; + +/* Set the group's callsign */ +_group setGroupId [_callsign]; +_group setVariable [QGVAR(sqd_callsign), _callsign, true]; + +/* Set the group's squad type */ +_group setVariable [QGVAR(sqd_type), _type, true]; + +/* Set the groups size */ +_group setVariable [QGVAR(sqd_size), _level, true]; + +/* Set the group parameters for each unit in the group */ +{ + _x setVariable [QGVAR(group), [_callsign, _type, _level], true]; +} forEach units _group; + +/* Raise event */ +[QGVAR(onGroupCallsignChanged), _this, _group] call CBA_fnc_targetEvent; diff --git a/framework/components/common/functions/script_component.hpp b/framework/components/common/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/common/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/common/initSettings.sqf b/framework/components/common/initSettings.sqf new file mode 100644 index 0000000..8c33611 --- /dev/null +++ b/framework/components/common/initSettings.sqf @@ -0,0 +1,10 @@ +#include "script_component.hpp" + +[ + QGVAR(setting_blacklistedAddons), + "EDITBOX", + ["Blacklisted Addons", "Kicks players who loads these addons. Sepperated by comma (,)"], + QUOTE(MODULE_BEAUTIFIED), + "TF21_ChemlightDrop", + 1 +] call FUNC(addSetting); \ No newline at end of file diff --git a/framework/components/common/script_component.hpp b/framework/components/common/script_component.hpp index 1400b74..133b01d 100644 --- a/framework/components/common/script_component.hpp +++ b/framework/components/common/script_component.hpp @@ -1,5 +1,19 @@ #define MODULE common -#define REQUIRED_ADDONS [] +#define MODULE_BEAUTIFIED Common + +#define REQUIRED_ADDONS ["cba_settings"] #define REQUIRED_MODULES [] +#ifdef DEBUG_ENABLED_COMMON + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_COMMON + #define DEBUG_SETTINGS DEBUG_SETTINGS_COMMON +#endif + #include "..\main\script_component.hpp" + +#define NOTIFICATION_M 0.01 +#define NOTIFICATION_W 300 * pixelW +#define NOTIFICATION_BORDER_W 10 * pixelW diff --git a/framework/components/common/stringtable.sqf b/framework/components/common/stringtable.sqf index 7cb53b2..8049b94 100644 --- a/framework/components/common/stringtable.sqf +++ b/framework/components/common/stringtable.sqf @@ -4,5 +4,12 @@ * 3den_stringtable */ [ - + [DSTRING(toggle_sim_3den_displayName), [ + ["English", "Toggle Simulation in 3den (will only be enabled in 3den)"], + ["Spanish", "Alterné simulación en 3den (Solo se activara en el editor 3den)"] + ]], + [DSTRING(make_obj_simple_displayName), [ + ["English", "Toggle simple objects"], + ["Spanish", "Crear objeto simple"] + ]] ] diff --git a/framework/components/diagnostic/README.md b/framework/components/diagnostic/README.md new file mode 100644 index 0000000..607278b --- /dev/null +++ b/framework/components/diagnostic/README.md @@ -0,0 +1,2 @@ +# Diagnostic +Adds diagnostic tools to CMF3 \ No newline at end of file diff --git a/framework/components/diagnostic/XEH_3denInit.sqf b/framework/components/diagnostic/XEH_3denInit.sqf new file mode 100644 index 0000000..84f2529 --- /dev/null +++ b/framework/components/diagnostic/XEH_3denInit.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" \ No newline at end of file diff --git a/framework/components/diagnostic/XEH_PREP.sqf b/framework/components/diagnostic/XEH_PREP.sqf new file mode 100644 index 0000000..3bfb2b1 --- /dev/null +++ b/framework/components/diagnostic/XEH_PREP.sqf @@ -0,0 +1,6 @@ +#include "script_component.hpp" + +PREP(log); +PREP(error); +PREP(logFlush); +PREP(errorFlush); \ No newline at end of file diff --git a/framework/components/diagnostic/XEH_postInit.sqf b/framework/components/diagnostic/XEH_postInit.sqf new file mode 100644 index 0000000..890da58 --- /dev/null +++ b/framework/components/diagnostic/XEH_postInit.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +/* Display notification for script errors for admins and zeuses */ +[QGVAR(scriptError), { + params ["_errorText", "_sourceFile", "_lineNumber", "_errorPos", "_content", "_stackTraceOutput"]; + + if (!is3DENPreview && { isNull getAssignedCuratorLogic cmf_player && { call BIS_fnc_admin isEqualTo 0 } }) exitWith {}; + + private _notif = composeText [ + text format ["[SCRIPT] ERROR: %1", _errorText], + lineBreak, + text format ["at %1:%2", _sourceFile, _lineNumber] + ]; + + GVAR(errorOut) pushBack [QUOTE(PREFIX), QUOTE(MODULE), _errorText, _errorPos, _sourceFile, _lineNumber]; + + [_notif, EGVAR(common,notificationColors) get "ERROR", 8] call EFUNC(common,notification); +}] call CBA_fnc_addEventHandler; \ No newline at end of file diff --git a/framework/components/diagnostic/XEH_preInit.sqf b/framework/components/diagnostic/XEH_preInit.sqf new file mode 100644 index 0000000..a896cff --- /dev/null +++ b/framework/components/diagnostic/XEH_preInit.sqf @@ -0,0 +1,10 @@ +#include "script_component.hpp" + +/* Create log collector */ +GVAR(logOut) = []; +GVAR(errorOut) = []; + +/* Log Script errors */ +addMissionEventHandler ["ScriptError", { + [QGVAR(scriptError), _this] call CBA_fnc_globalEvent; +}]; \ No newline at end of file diff --git a/framework/components/diagnostic/functions/fn_error.sqf b/framework/components/diagnostic/functions/fn_error.sqf new file mode 100644 index 0000000..2757208 --- /dev/null +++ b/framework/components/diagnostic/functions/fn_error.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Writes error to array before sending it to CBA + * + * Arguments: + * 0: Addon name (optional, defaut: "cba") + * 1: Component name (optional, default: "diagnostic") + * 2: Title of the error + * 3: Error message (use "\n" for newline) + * 4: Name of file + * 5: Line of file + * + * Return Value: + * nil + * + * Example: + * ["Player got banana"] call cmf_diagnostic_fnc_error + * + * Public: no + */ + +if (!is3DEN) then { _nil = GVAR(errorOut) pushBack _this }; + +_this call CBA_fnc_error; diff --git a/framework/components/diagnostic/functions/fn_errorFlush.sqf b/framework/components/diagnostic/functions/fn_errorFlush.sqf new file mode 100644 index 0000000..b61ef7f --- /dev/null +++ b/framework/components/diagnostic/functions/fn_errorFlush.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Empties error array + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_diagnostic_fnc_errorFlush + * + * Public: no + */ + +GVAR(errorOut) = []; diff --git a/framework/components/diagnostic/functions/fn_log.sqf b/framework/components/diagnostic/functions/fn_log.sqf new file mode 100644 index 0000000..401dd60 --- /dev/null +++ b/framework/components/diagnostic/functions/fn_log.sqf @@ -0,0 +1,20 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Writes log to array before sending it to CBA + * + * Arguments: + * 0: Message + * + * Return Value: + * nil + * + * Example: + * ["Player got banana"] call cmf_diagnostic_fnc_log + * + * Public: no + */ + +if (!is3DEN) then { _nil = GVAR(logOut) pushBack _this }; + +_this call CBA_fnc_log; \ No newline at end of file diff --git a/framework/components/diagnostic/functions/fn_logFlush.sqf b/framework/components/diagnostic/functions/fn_logFlush.sqf new file mode 100644 index 0000000..cab7435 --- /dev/null +++ b/framework/components/diagnostic/functions/fn_logFlush.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Empties log array + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_diagnostic_fnc_logFlush + * + * Public: no + */ + +GVAR(logOut) = []; diff --git a/framework/components/diagnostic/functions/script_component.hpp b/framework/components/diagnostic/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/diagnostic/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/diagnostic/initSettings.sqf b/framework/components/diagnostic/initSettings.sqf new file mode 100644 index 0000000..84f2529 --- /dev/null +++ b/framework/components/diagnostic/initSettings.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" \ No newline at end of file diff --git a/framework/components/diagnostic/script_component.hpp b/framework/components/diagnostic/script_component.hpp new file mode 100644 index 0000000..1034b9a --- /dev/null +++ b/framework/components/diagnostic/script_component.hpp @@ -0,0 +1,15 @@ +#define MODULE diagnostic +#define MODULE_BEAUTIFIED Diagnostic + +#define REQUIRED_ADDONS [] +#define REQUIRED_MODULES ["common"] + +#include "..\main\script_component.hpp" + +#ifdef DEBUG_ENABLED_DIAGNOSTIC + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_DIAGNOSTIC + #define DEBUG_SETTINGS DEBUG_SETTINGS_DIAGNOSTIC +#endif \ No newline at end of file diff --git a/framework/components/diagnostic/stringtable.sqf b/framework/components/diagnostic/stringtable.sqf new file mode 100644 index 0000000..fafbb11 --- /dev/null +++ b/framework/components/diagnostic/stringtable.sqf @@ -0,0 +1,8 @@ +#include "script_component.hpp" +/* + * Author: Eric + * diagnostic_stringtable + */ +[ + +] diff --git a/framework/components/enhancedVehicles/XEH_PREP.sqf b/framework/components/enhancedVehicles/XEH_PREP.sqf index 55ac783..cc51358 100644 --- a/framework/components/enhancedVehicles/XEH_PREP.sqf +++ b/framework/components/enhancedVehicles/XEH_PREP.sqf @@ -1,8 +1,10 @@ #include "script_component.hpp" -PREP(init); +PREP(gunEffectEH); +PREP(damageEH); +PREP(fuelLeakEH); PREP(localEffect); PREP(medicalHandler); PREP(offroading); PREP(getSurfaceParams); -IPREP(autoInit); +PREP(fire); \ No newline at end of file diff --git a/framework/components/enhancedVehicles/XEH_postInit.sqf b/framework/components/enhancedVehicles/XEH_postInit.sqf new file mode 100644 index 0000000..8dbbfbc --- /dev/null +++ b/framework/components/enhancedVehicles/XEH_postInit.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" + +/* Projectile cache */ +GVAR(projectileCache) = [] call CBA_fnc_hashCreate; + +/* Vehicle cache */ +GVAR(vehicleCache) = [] call CBA_fnc_hashCreate; + +/* Add the eventhandler */ +private _fnc_initEH = { + params ["_vehicle"]; + + /* Exit if enhancedVehicles is disabled on vehicle or globally */ + if (!GVAR(setting_enable)) exitWith {}; + if (_vehicle getVariable [QGVAR(disable), false]) exitWith {}; + + _vehicle setVariable ["ace_cookoff_enable", false, true]; + _vehicle addEventHandler ["HandleDamage", FUNC(damageEH)]; + + // Disable engine when damage is 0.8 + _vehicle addEventHandler ["Engine", { + params ["_vehicle", "_engineState"]; + if (!_engineState || (_vehicle gethit "engine") < 0.8) exitWith {}; + _vehicle engineOn false; + }]; + + /* Fual leak */ + _vehicle spawn FUNC(fuelLeakEH); + + /* Offroading */ + [_vehicle] call FUNC(offroading); + + LOG_1("Enabled EnhancedVehicles on %1", typeOf _vehicle); +}; + +["Car", "init", _fnc_initEH, true, [], true] call CBA_fnc_addClassEventHandler; +["Tank", "init", _fnc_initEH, true, [], true] call CBA_fnc_addClassEventHandler; + +[] call FUNC(gunEffectEH); \ No newline at end of file diff --git a/framework/components/enhancedVehicles/fn_autoInit.sqf b/framework/components/enhancedVehicles/fn_autoInit.sqf deleted file mode 100644 index 493c387..0000000 --- a/framework/components/enhancedVehicles/fn_autoInit.sqf +++ /dev/null @@ -1,35 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Initializes enhanced vehicles if autoinit is enabled - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_enhancedVehicles_fnc_autoInit - * - * Public: No - */ -SCRIPT(autoInit); - -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,enhancedVehicles,enable) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -/* Initialize EnhancedVehicles on all mission vehicles */ -_this spawn { - while { !(missionNamespace getVariable [QGVAR(disable), false]) } do { - { - /* Check if vehicle is already initialized */ - if !(_x getVariable [QGVAR(initialized), false]) then { - [[_x], FUNC(init)] remoteExec ["call", 0, true]; - _x setVariable [QGVAR(initialized), true, true]; - }; - } forEach vehicles; - sleep 1; - }; -}; diff --git a/framework/components/enhancedVehicles/fn_init.sqf b/framework/components/enhancedVehicles/fn_init.sqf deleted file mode 100644 index 977aeba..0000000 --- a/framework/components/enhancedVehicles/fn_init.sqf +++ /dev/null @@ -1,113 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Initializes enhanced vehicles on passed vehicle. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * [myVehicle] call cmf_enhancedVehicles_fnc_init - * - * Public: Yes - */ -SCRIPT(init); - -params["_veh"]; - -/* Projectile cache */ -GVAR(projectileCache) = [] call CBA_fnc_hashCreate; - -/* Vehicle cache */ -GVAR(vehicleCache) = [] call CBA_fnc_hashCreate; - -/* Code to handle damage */ -private _damageHandle = { - params ["_veh", "_selection", "_damage", "", "_projectile", "", "", "_hitPoint"]; - - /* Check if vehicle is local */ - if !(local _veh) exitWith {}; - - /* Check if enhancedVehicles has been disabled */ - if (missionNamespace getVariable [QGVAR(disable), false]) exitWith {}; - - /* Get the projectile type the vehicle was hit with */ - private _projectileType = [GVAR(projectileCache), _selection, nil] call CBA_fnc_hashGet; - if (isNil "_projectileType") then { - _projectileType = getNumber (configfile >> "CfgAmmo" >> _projectile >> "explosive"); - - if (isNil "_projectileType") then { - _projectileType = 0; - }; - - GVAR(projectileCache) = [GVAR(projectileCache), typeOf _veh, _projectileType] call CBA_fnc_hashSet; - }; - - /* Get the vehicle selectionNames */ - private _vehicleSelections = [GVAR(vehicleCache), typeOf _veh, []] call CBA_fnc_hashGet; - if (_vehicleSelections isEqualTo []) then { - private _engineName = getText (configFile >> "cfgVehicles" >> (typeOf _veh) >> "HitPoints" >> "HitEngine" >> "name"); - private _fuelName = getText (configFile >> "cfgVehicles" >> (typeOf _veh) >> "HitPoints" >> "HitFuel" >> "name"); - - _vehicleSelections = [_engineName, _fuelName]; - - GVAR(vehicleCache) = [GVAR(vehicleCache), typeOf _veh, _vehicleSelections] call CBA_fnc_hashSet; - }; - - - /* Check if the damage is enough to kill the vehicle, and if it is take over the damage handling */ - //LOG_2("%1 in %2 || %1 == """"", _selection, str _vehicleSelections); - if (_damage > 0.8 && ((_selection in _vehicleSelections) || _selection isEqualTo "")) then { - LOG_2("Registered damage on selection: %1 = %2", _selection, str _damage); - - /* If the projectile type was explosive play cool visual and audiable effects */ - if ((_projectileType isEqualTo 1)) then { - [_veh, _projectile, _hitPoint] spawn { - params["_veh", "_projectile", "_hitPoint"]; - { - /* Handle medical for units in hit vehicle */ - [[_veh, _projectile, _hitPoint], FUNC(medicalHandler)] remoteExec ["call", _x]; - - /* Handle local sound and visual effects for players in vehicle */ - if (isPlayer _x) then { - [[], FUNC(localEffect)] remoteExec ["call", _x]; - }; - } forEach crew _veh; - }; - }; - - /* Disable engine */ - if (_veh getHit "motor" != 1) then { - LOG_2("Vehicled disabled: %1 = %2", _selection, str _damage); - _veh setHit ["motor", 1]; - }; - - _damage = 0.8; - - /* Raise event */ - [QGVAR(onDisabled), [_veh, _projectile, _hitPoint], _veh] call CBA_fnc_targetEvent; - }; - - /* Set the damage amount on the vehicle */ - _damage; -}; - -/* Add the eventhandler */ -if (_veh isKindOf "car" || _veh isKindOf "tank") then { - _veh setVariable ["ace_cookoff_enable", false, true]; - _veh addEventHandler ["HandleDamage", _damageHandle]; - - LOG_1("Added EnhancedVehicles to %1", typeOf _veh); - - /* Raise event */ - [QGVAR(enableEnhancedVehicles), [_veh], _veh] call CBA_fnc_targetEvent; -}; - -/* Initialize Offroading script on vehicle */ -if (_veh isKindOf "car") then { - [_veh] call FUNC(offroading); - LOG_1("Added Offroading to %1", typeOf _veh); -}; diff --git a/framework/components/enhancedVehicles/fn_localEffect.sqf b/framework/components/enhancedVehicles/fn_localEffect.sqf deleted file mode 100644 index afbca1e..0000000 --- a/framework/components/enhancedVehicles/fn_localEffect.sqf +++ /dev/null @@ -1,60 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Handles local effects for crew in ehv enabled vehicles - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_enhancedVehicles_fnc_localEffect - * - * Public: No - */ -SCRIPT(localEffect); - -_this spawn { - private _enableSoundEffects = ( CONFIG_PARAM_3(SETTINGS,enhancedVehicles,soundEffects) ) isEqualTo 1; - private _enableVisualEffects = ( CONFIG_PARAM_3(SETTINGS,enhancedVehicles,visualEffects) ) isEqualTo 1; - - /* Play sound effects */ - if (_enableSoundEffects) then { - [] spawn { - player setVariable ["defaultVolume", soundVolume]; - 0 fadeSound 0.2; - playsound "ACE_Combat_Deafness_Medium_NoRing"; - playsound "ACE_Ring_Backblast"; - - sleep 15; - private _defaultVolume = player getVariable ["defaultVolume", soundVolume]; - 60 fadesound _defaultVolume; - }; - }; - - /* Show visual effects */ - if (_enableVisualEffects) then { - addCamShake [5,2,9]; - private _visualEffect = ppEffectCreate ["RadialBlur", 10000]; - cutText ["", "BLACK OUT", 0.001]; - sleep 1; - titleCut ["", "BLACK IN", 10]; - _visualEffect ppEffectEnable true; - _visualEffect ppEffectAdjust[0.1,0,0,0]; - _visualEffect ppEffectCommit 2; - sleep 2; - _visualEffect ppEffectAdjust[0,0.1,0,0]; - _visualEffect ppEffectCommit 2; - sleep 2; - _visualEffect ppEffectAdjust[0.1,0,0,0]; - _visualEffect ppEffectCommit 2; - sleep 7; - _visualEffect ppEffectAdjust[0,0,0,0]; - _visualEffect ppEffectCommit 2; - sleep 3; - _visualEffect ppEffectEnable false; - ppEffectDestroy _visualEffect; - }; -}; diff --git a/framework/components/enhancedVehicles/fn_medicalHandler.sqf b/framework/components/enhancedVehicles/fn_medicalHandler.sqf deleted file mode 100644 index e9c2ffe..0000000 --- a/framework/components/enhancedVehicles/fn_medicalHandler.sqf +++ /dev/null @@ -1,24 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Handles medical damage for crew in ehv enabled vehicles - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_enhancedVehicles_fnc_medicalHandler - * - * Public: No - */ -SCRIPT(medicalHandler); - -/* apply damage to player */ -[player, 0.7, "rightleg", "explosive"] call ace_medical_fnc_addDamageToUnit; -[player, 0.7, "leftleg", "explosive"] call ace_medical_fnc_addDamageToUnit; -[player, 0.5, "rightarm", "explosive"] call ace_medical_fnc_addDamageToUnit; -[player, 0.5, "leftarm", "explosive"] call ace_medical_fnc_addDamageToUnit; -[player, 0.3] call ace_medical_fnc_adjustPainLevel; diff --git a/framework/components/enhancedVehicles/functions/fn_damageEH.sqf b/framework/components/enhancedVehicles/functions/fn_damageEH.sqf new file mode 100644 index 0000000..f8027fc --- /dev/null +++ b/framework/components/enhancedVehicles/functions/fn_damageEH.sqf @@ -0,0 +1,104 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Handles vehicle damage for enhancedVehicles + * + * Arguments: + * 0: Vehicle + * 1: Selection + * 2: Damage + * 3: Source + * 4: Projectile + * 5: hitIndex + * 6: Instigator + * 7: HitPoint + * 8: directHit + * + * Return Value: + * None + * + * Example: + * this addEventHandler ["HandleDamage", cmf_enhancedVehicles_fnc_damageEH]; + * + * Public: Yes + */ + +params ["_veh", "_selection", "_damage", "", "_projectile", "", "", "_hitPoint"]; + +/* Check if vehicle is local */ +if !(local _veh) exitWith {}; + +/* Check if enhancedVehicles has been disabled */ +if (missionNamespace getVariable [QGVAR(disable), false]) exitWith {}; + +/* Get the projectile type the vehicle was hit with */ +private _projectileType = [GVAR(projectileCache), _selection, nil] call CBA_fnc_hashGet; +if (isNil "_projectileType") then { + _projectileType = getNumber (configfile >> "CfgAmmo" >> _projectile >> "explosive"); + + if (isNil "_projectileType") then { + _projectileType = 0; + }; + + GVAR(projectileCache) = [GVAR(projectileCache), typeOf _veh, _projectileType] call CBA_fnc_hashSet; +}; + +/* Get the vehicle selectionNames */ +private _vehicleSelections = [GVAR(vehicleCache), typeOf _veh, []] call CBA_fnc_hashGet; +if (_vehicleSelections isEqualTo []) then { + private _engineName = getText (configFile >> "cfgVehicles" >> (typeOf _veh) >> "HitPoints" >> "HitEngine" >> "name"); + private _fuelName = getText (configFile >> "cfgVehicles" >> (typeOf _veh) >> "HitPoints" >> "HitFuel" >> "name"); + + _vehicleSelections = [_engineName, _fuelName]; + + GVAR(vehicleCache) = [GVAR(vehicleCache), typeOf _veh, _vehicleSelections] call CBA_fnc_hashSet; +}; + + +/* Check if the damage is enough to kill the vehicle, and if it is take over the damage handling */ +//LOG_2("%1 in %2 || %1 == """"", _selection, str _vehicleSelections); +if (_damage > 0.8 && ((_selection in _vehicleSelections) || _selection isEqualTo "")) then { + LOG_2("Registered damage on selection: %1 = %2", _selection, str _damage); + + /* If the projectile type was explosive play cool visual and audiable effects */ + if ((_projectileType isEqualTo 1)) then { + [_veh, _projectile, _hitPoint] spawn { + params["_veh", "_projectile", "_hitPoint"]; + { + /* Handle medical for units in hit vehicle */ + [[_veh, _projectile, _hitPoint], FUNC(medicalHandler)] remoteExec ["call", _x]; + + /* Handle local sound and visual effects for players in vehicle */ + if (isPlayer _x) then { + [[], FUNC(localEffect)] remoteExec ["call", _x]; + }; + } forEach crew _veh; + }; + }; + + /* Disable engine */ + if (_veh getHit "engine" != 1) then { + LOG_2("Vehicled disabled: %1 = %2", _selection, str _damage); + _veh setHit ["engine", 1]; + _veh engineOn false; + }; + + /* Allow fueltank to start leaking */ + if (_selection != "fuel") then { + _damage = 0.8; + }; + + /* Dissembark ai crew */ + { + if (!isPlayer _x) then { + unassignVehicle _x; + doGetOut _x; + } + } forEach crew _veh; + + /* Raise event */ + [QGVAR(onDisabled), [_veh, _projectile, _hitPoint], _veh] call CBA_fnc_targetEvent; +}; + +/* Set the damage amount on the vehicle */ +_damage; \ No newline at end of file diff --git a/framework/components/enhancedVehicles/functions/fn_fire.sqf b/framework/components/enhancedVehicles/functions/fn_fire.sqf new file mode 100644 index 0000000..8782f68 --- /dev/null +++ b/framework/components/enhancedVehicles/functions/fn_fire.sqf @@ -0,0 +1,85 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Creates a fire of given radius + * + * Arguments: + * 0: Position of Fire or Object + * 1: Radius of Fire + * 2: Intensity of Fire [0,10] + * 3: Condition of fire (Default: { true }) + * 4: Condition Parameters (Default: []) + * + * Return Value: + * FireObject + * + * Example: + * [getPosASL _fuel, 5, 10] call cmf_enhancedVehicles_fnc_fire + * + * Public: Yes + */ + +[_this, { + params ["_source", "_radius", "_intensity", ["_condition", { true }], ["_params", []]]; + + private _fireEmitter = "#particlesource" createVehicle [0, 0, 0]; + private _smokeEmitter = "#particlesource" createVehicle [0, 0, 0]; + if (_source isEqualType objNull) then { + _fireEmitter setPosASL getPosASL _source; + _fireEmitter attachTo [_source]; + _smokeEmitter setPosASL getPosASL _source; + _smokeEmitter attachTo [_source]; + } else { + _fireEmitter setPosASL _source; + _smokeEmitter setPosASL _source; + }; + + private _life = (_radius * 0.7) * 0.4; + private _speed = 0.4; + private _size = 0.9; + private _effectSize = (_radius * 0.8) * 0.8; + private _orientation = 0; + private _density = (_radius * 0.7) * 30; + + /* Fire Particle effect creation */ + _fireEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal", 16, 10, 32, 1], "", "Billboard", 1, 1.5, [0, 0, 0], [0, 1, 0], 0, 0.045, 0.04, 0.05, [1.8, 0.12], [[1,1,1,-1]], [0.5, 1], 0, 0, "", "", _fireEmitter]; + _fireEmitter setDropInterval (0.15 - 0.01 * _radius); + _fireEmitter setParticleRandom [0.4, [_radius - 0.1, _radius - 0.1, 0.3], [0.1, 0.5, 0.1], 0, 0.1, [0.1,0.1,0.1,0], 0, 0, 0.1]; + + /* Smoke Particle effect creation */ + _smokeEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal_02", 8, 0, 40, 1], "", "Billboard", 1, 22, [0,0,0], [0,2.5,0], 1, 0.05, 0.04, 0.05, [2, 20], [[0.35,0.35,0.35,0.6],[0.35,0.35,0.35,0.75],[0.35,0.35,0.35,0.45],[0.42,0.42,0.42,0.28],[0.42,0.42,0.42,0.16],[0.42,0.42,0.42,0.09], + [0.42,0.42,0.42,0.06],[0.5,0.5,0.5,0.02],[0.5,0.5,0.5,0]], [1,0.55,0.35], 0.3, 0.2, "", "", _smokeEmitter]; + _smokeEmitter setDropInterval (0.65 - 0.05 * _radius); + _smokeEmitter setParticleRandom [8, [5,5,0.15], [0.25,0.5,1.25], 0.5, 0, [0,0,0,0.06], 0, 0, 0.5]; + + /* Light creation */ + _lightSize = (1 + (_radius * 0.7)) / 2; + _light = "#lightpoint" createVehicleLocal (getPos _fireEmitter); + if (_source isEqualType objNull) then { + _light setPosASL [(getPosASL _source) select 0, (getPosASL _source) select 1, ((getPosASL _source) select 2) + 0.5]; + _light attachTo [_source]; + } else { + _light setPosASL [_source select 0, _source select 1, (_source select 2) + 0.5]; + }; + _light setLightBrightness 1.0; + _light setLightColor [1, 0.65, 0.4]; + _light setLightAmbient [0.15, 0.05, 0]; + _light setLightIntensity (50 + 400 * _lightSize); + _light setLightAttenuation [0, 0, 0, 1]; + _light setLightDayLight false; + + ["ace_fire_addFireSource", [_source, _radius, _intensity, _source, _condition, _params]] call CBA_fnc_serverEvent; + + [ + { !(((_this select 0) select 4) call ((_this select 0) select 3)) }, + { + params ["", "_fireEmitter", "_light", "_smokeEmitter"]; + + deleteVehicle _fireEmitter; + deleteVehicle _light; + sleep 10; + deleteVehicle _smokeEmitter; + }, + [_this, _fireEmitter, _light, _smokeEmitter] + ] call CBA_fnc_waitUntilAndExecute; +}] remoteExec ["call", 0, false] diff --git a/framework/components/enhancedVehicles/functions/fn_fuelLeakEH.sqf b/framework/components/enhancedVehicles/functions/fn_fuelLeakEH.sqf new file mode 100644 index 0000000..9b5df0a --- /dev/null +++ b/framework/components/enhancedVehicles/functions/fn_fuelLeakEH.sqf @@ -0,0 +1,78 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Handles fuel leaks from vehicle for enhancedVehicles + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * this spawn cmf_enhancedVehicles_fnc_fuelLeakEH; + * + * Public: Yes + */ + +params ["_veh"]; + +if (!isServer) exitWith { }; + +while { alive _veh } do { + waitUntil { (_veh getHitPointDamage "HitFuel") >= 0.9 }; + + private _fuelPos = getPosATL _veh; + _fuelPos set [2, 0]; + + /* Create fuel tank and simulate the spill getting larger and larger */ + private _fuel = createSimpleObject ["WaterSpill_01_Large_Foam_F", [0, 0, 0]]; + [_fuel, 0.01] remoteExec ["setObjectScale", 0]; + sleep 0.1; + _fuel setPosATL _fuelPos; + _fuel setVectorUp surfaceNormal getPos _fuel; + _fuel setDir random 360; + + /* Handle fuel expansion */ + private _expHandler = [_fuel, _veh] spawn { + params ["_fuel", "_veh"]; + + private _fuelAmount = fuel _veh; + private _finalScale = 0.01; + for "_scale" from 0.01 to _fuelAmount step 0.001 do { + if (_fuel distance2D _veh >= 5) exitWith { }; + [_fuel, _scale] remoteExec ["setObjectScale", 0]; + sleep 0.08; + _finalScale = _scale; + }; + + /* Sync it for JIP players */ + [_fuel, _finalScale] remoteExec ["setObjectScale", 0, true]; + }; + + /* Handle fuel fire probability */ + [_fuel, _veh, _expHandler] spawn { + params ["_fuel", "_veh", "_expHandler"]; + + while { _veh distance2D _fuel <= 2 } do { + sleep 5; + + if (random 100 < 10) exitWith { + terminate _expHandler; + private _boundingRect = boundingBoxReal _fuel; + private _radius = ((((_boundingRect select 1) select 1) - ((_boundingRect select 0) select 0)) / 2) * getObjectScale _fuel; + + private _burnEnd = time + 300; + [getPosASL _fuel, _radius, 10, { (_this select 0) > time }, [_burnEnd]] call FUNC(fire); + + /* Light crew on fire */ + { + ["ace_fire_addFireSource", [_x, 1, 4, _x]] call CBA_fnc_serverEvent; + } forEach crew _veh; + }; + }; + }; + + waitUntil { _fuel distance2D _veh >= 2 }; + sleep 1; +} \ No newline at end of file diff --git a/framework/components/enhancedVehicles/fn_getSurfaceParams.sqf b/framework/components/enhancedVehicles/functions/fn_getSurfaceParams.sqf similarity index 100% rename from framework/components/enhancedVehicles/fn_getSurfaceParams.sqf rename to framework/components/enhancedVehicles/functions/fn_getSurfaceParams.sqf diff --git a/framework/components/enhancedVehicles/functions/fn_gunEffectEH.sqf b/framework/components/enhancedVehicles/functions/fn_gunEffectEH.sqf new file mode 100644 index 0000000..0c91889 --- /dev/null +++ b/framework/components/enhancedVehicles/functions/fn_gunEffectEH.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Adds camera shake when firing a gun + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * this spawn cmf_enhancedVehicles_fnc_gunEffectEH; + * + * Public: Yes + */ + +private _fnc_initEH = { + params ["_veh"]; + + _veh addEventHandler ["Fired", { + params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; + + if (_gunner isEqualTo player) then { + addCamShake [2, 0.2, 25]; + }; + }]; +}; + +["Car", "init", _fnc_initEH, true, [], true] call CBA_fnc_addClassEventHandler; +["Tank", "init", _fnc_initEH, true, [], true] call CBA_fnc_addClassEventHandler; +["Ship", "init", _fnc_initEH, true, [], true] call CBA_fnc_addClassEventHandler; +["StaticWeapon", "init", _fnc_initEH, true, [], true] call CBA_fnc_addClassEventHandler; \ No newline at end of file diff --git a/framework/components/enhancedVehicles/functions/fn_localEffect.sqf b/framework/components/enhancedVehicles/functions/fn_localEffect.sqf new file mode 100644 index 0000000..ffb9800 --- /dev/null +++ b/framework/components/enhancedVehicles/functions/fn_localEffect.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Handles local effects for crew in ehv enabled vehicles + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_enhancedVehicles_fnc_localEffect + * + * Public: No + */ +SCRIPT(localEffect); + +/* Play sound effects */ +if (GVAR(setting_audiable)) then { + player setVariable ["defaultVolume", soundVolume]; + 0 fadeSound 0.2; + playsound "ACE_Combat_Deafness_Medium_NoRing"; + playsound "ACE_Ring_Backblast"; + + [{ + private _defaultVolume = player getVariable ["defaultVolume", soundVolume]; + 60 fadesound _defaultVolume; + }, 0, 15] call CBA_fnc_waitAndExecute; +}; + +/* Show visual effects */ +if (GVAR(setting_visual)) then { + addCamShake [5,2,9]; + private _visualEffect = ppEffectCreate ["RadialBlur", 10000]; + cutText ["", "BLACK OUT", 0.001]; + + [{ + titleCut ["", "BLACK IN", 10]; + _this ppEffectEnable true; + _this ppEffectAdjust[0.1,0,0,0]; + _this ppEffectCommit 2; + }, _visualEffect, 1] call CBA_fnc_waitAndExecute; + + [{ + _this ppEffectAdjust[0,0.1,0,0]; + _this ppEffectCommit 2; + }, _visualEffect, 3] call CBA_fnc_waitAndExecute; + + [{ + _this ppEffectAdjust[0.1,0,0,0]; + _this ppEffectCommit 2; + }, _visualEffect, 5] call CBA_fnc_waitAndExecute; + + [{ + _this ppEffectAdjust[0,0,0,0]; + _this ppEffectCommit 2; + }, _visualEffect, 12] call CBA_fnc_waitAndExecute; + + [{ + _this ppEffectEnable false; + ppEffectDestroy _this; + }, _visualEffect, 15] call CBA_fnc_waitAndExecute; +}; diff --git a/framework/components/enhancedVehicles/functions/fn_medicalHandler.sqf b/framework/components/enhancedVehicles/functions/fn_medicalHandler.sqf new file mode 100644 index 0000000..bab2db6 --- /dev/null +++ b/framework/components/enhancedVehicles/functions/fn_medicalHandler.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Handles medical damage for crew in ehv enabled vehicles + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_enhancedVehicles_fnc_medicalHandler + * + * Public: No + */ +params ["_veh", "_projectile", "_hitPoint"]; +SCRIPT(medicalHandler); + +/* apply damage to crew */ +{ + [_x, 0.7, "rightleg", "explosive"] call ace_medical_fnc_addDamageToUnit; + [_x, 0.7, "leftleg", "explosive"] call ace_medical_fnc_addDamageToUnit; + [_x, 0.5, "rightarm", "explosive"] call ace_medical_fnc_addDamageToUnit; + [_x, 0.5, "leftarm", "explosive"] call ace_medical_fnc_addDamageToUnit; + [_x, 0.3] call ace_medical_fnc_adjustPainLevel; +} forEach crew _veh; diff --git a/framework/components/enhancedVehicles/fn_offroading.sqf b/framework/components/enhancedVehicles/functions/fn_offroading.sqf similarity index 89% rename from framework/components/enhancedVehicles/fn_offroading.sqf rename to framework/components/enhancedVehicles/functions/fn_offroading.sqf index 200229d..c914612 100644 --- a/framework/components/enhancedVehicles/fn_offroading.sqf +++ b/framework/components/enhancedVehicles/functions/fn_offroading.sqf @@ -16,15 +16,15 @@ */ SCRIPT(offroading); +/* Only run on server */ +if (!isServer) exitWith {}; + /* Spawn code to handle offroad feature */ +// @TODO: replace spawn _this spawn { params["_veh"]; - /* Get which parts are enabled */ - private _offroadBumpEnabled = ( CONFIG_PARAM_3(SETTINGS,enhancedVehicles,offroadBumpy) ) isEqualTo 1; - private _offroadDamageEnabled = ( CONFIG_PARAM_3(SETTINGS,enhancedVehicles,offroadDamage) ) isEqualTo 1; - - if (!_offroadBumpEnabled && !_offroadDamageEnabled) exitWith {}; + if (!GVAR(setting_offroadBumps) && !GVAR(setting_offroadDamage)) exitWith {}; /* Get the configSettings */ private _bumpSpeed = getNumber (missionConfigFile >> "CfgEnhancedVehicles" >> "bumpSpeed"); @@ -58,6 +58,7 @@ _this spawn { private _wheelmass = call compile (format['getNumber (%1)', ([_cfgbin,"",true] call BIS_fnc_configPath)]); /* check if vehicle is offroad */ + // @TODO: replace spawn [_veh] spawn { params ["_veh"]; @@ -72,13 +73,11 @@ _this spawn { }; /* Script that handles bumps */ - if (_offroadBumpEnabled) then { + if (GVAR(setting_offroadBumps)) then { + // @TODO: replace spawn [_veh, _bumpSpeed, _i3, _i2] spawn { params["_veh", "_bumpSpeed", "_ix", "_iy"]; - /* Only run it if the vehicle is local and you are the driver */ - if (!(local _veh) || (player != driver _veh)) exitWith {}; - /* Loop the offroad checks */ while { alive _veh && !(missionNamespace getVariable [QGVAR(disable), false]) } do { waitUntil{ uiSleep 0.02; ((speed _veh) > 1) && !(isOnRoad getPos _veh) && (isTouchingGround _veh) }; @@ -108,13 +107,11 @@ _this spawn { }; /* Script that handles damage */ - if (_offroadDamageEnabled) then { + if (GVAR(setting_offroadDamage)) then { + // @TODO: replace spawn [_veh, _damageModifier, _damagespeed, _wheelmass, _wheelIndex] spawn { params["_veh", "_damageModifier", "_damageSpeed", "_wheelmass", "_index"]; - /* Only run it if the vehicle is local and you are the driver */ - if (!(local _veh) || (player != driver _veh)) exitWith {}; - /* Loop the offroad checks */ while { alive _veh && !(missionNamespace getVariable [QGVAR(disable), false])} do { waitUntil{ uiSleep 0.02; ((speed _veh) > 1) && !(isOnRoad getPos _veh) && (isTouchingGround _veh) }; diff --git a/framework/components/enhancedVehicles/functions/script_component.hpp b/framework/components/enhancedVehicles/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/enhancedVehicles/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/enhancedVehicles/initSettings.sqf b/framework/components/enhancedVehicles/initSettings.sqf new file mode 100644 index 0000000..eac6942 --- /dev/null +++ b/framework/components/enhancedVehicles/initSettings.sqf @@ -0,0 +1,46 @@ +#include "script_component.hpp" + +[ + QGVAR(setting_enable), + "CHECKBOX", + ["Enhanced Vehicles", "Enables an enhanced damage model"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_visual), + "CHECKBOX", + ["Visual Effects", "Show visual effects on vehicle disable"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_audiable), + "CHECKBOX", + ["Audiable Effects", "Play audiable effects on vehicle disable"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_offroadBumps), + "CHECKBOX", + ["Bumps", "Going offroad gets bumpy"], + QUOTE(MODULE_BEAUTIFIED - Offroad), + false, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_offroadDamage), + "CHECKBOX", + ["Damage", "Going offroad can damage a vehicle at high speeds"], + QUOTE(MODULE_BEAUTIFIED - Offroad), + false, + 1 +] call EFUNC(common,addSetting); \ No newline at end of file diff --git a/framework/components/enhancedVehicles/script_component.hpp b/framework/components/enhancedVehicles/script_component.hpp index dd2a36a..df79021 100644 --- a/framework/components/enhancedVehicles/script_component.hpp +++ b/framework/components/enhancedVehicles/script_component.hpp @@ -1,8 +1,15 @@ #define MODULE enhancedVehicles +#define MODULE_BEAUTIFIED Enhanced Vehicles + #define REQUIRED_ADDONS [] #define REQUIRED_MODULES [] -//#define DEBUG_MODE_FULL -//#define DEBUG_SYSTEMCHAT +#ifdef DEBUG_ENABLED_ENHANCEDVEHICLES + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_ENHANCEDVEHICLES + #define DEBUG_SETTINGS DEBUG_SETTINGS_ENHANCEDVEHICLES +#endif -#include "..\main\script_component.hpp" +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/gameplay/XEH_PREP.sqf b/framework/components/gameplay/XEH_PREP.sqf index 9974169..8202437 100644 --- a/framework/components/gameplay/XEH_PREP.sqf +++ b/framework/components/gameplay/XEH_PREP.sqf @@ -2,6 +2,7 @@ PREP(repairRearmStation); PREP(restrictedVehicle); -IPREP(tracers); -IPREP(safestart); -IPREP(flashbangOverride); +PREP(environment); +PREP(tracers); +PREP(safestart); +PREP(flashbangOverride); \ No newline at end of file diff --git a/framework/components/gameplay/XEH_postInit.sqf b/framework/components/gameplay/XEH_postInit.sqf new file mode 100644 index 0000000..4169ad7 --- /dev/null +++ b/framework/components/gameplay/XEH_postInit.sqf @@ -0,0 +1,6 @@ +#include "script_component.hpp" + +[] call FUNC(environment); +[] call FUNC(tracers); +[] call FUNC(safestart); +[] call FUNC(flashbangOverride); \ No newline at end of file diff --git a/framework/components/gameplay/fn_flashbangOverride.sqf b/framework/components/gameplay/fn_flashbangOverride.sqf deleted file mode 100644 index ecafc67..0000000 --- a/framework/components/gameplay/fn_flashbangOverride.sqf +++ /dev/null @@ -1,223 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Overrides flashbang explosions - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_gameplay_fnc_flashbangOverride - * - * Public: No - */ -SCRIPT(flashbangOverride); - -/* Check if it is enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,gameplay,overrideFlashbangs) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -/* Define a variable to configure grenades */ -GVAR(flashbang_grenades) = [["rhs_mag_mk84", [1.2]], ["ACE_M84", [1.2]], ["rhs_mag_fakel", [1.2]], ["rhs_mag_plamyam", [1.2]], ["rhs_mag_fakels", [1.2]], ["rhs_mag_zarya2", [1.2]], ["rhssaf_mag_rshb_p98", [1.2]], ["ACE_CTS9", [1.2, 9, {0.5}]]]; - -/* Extra particle effects if the player is inside */ -GVAR(flashbang_extraEffects) = { - if (_this select 1) then { - private _SmokeEmitter = "#particlesource" createVehicleLocal [((_this select 0) select 0), ((_this select 0) select 1), ((_this select 0) select 2) + 0.1]; - private _sparkEmitter = "#particlesource" createVehicleLocal [((_this select 0) select 0), ((_this select 0) select 1), ((_this select 0) select 2) + 0.1]; - - [_SmokeEmitter, _sparkEmitter] spawn { - params["_SmokeEmitter", "_sparkEmitter"]; - _sparkEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,0,12,0],"","Billboard",1,20,[0,0,1.2],[0,0,0],0,10.071,7.9,0,[0.005,0.005,0.005,0.005,0.005,0.005,0.005,0.005,0.005,0],[[1,1,1,-6.5],[1,1,1,-6],[1,1,1,-5.5],[1,1,1,-4.5]],[1000],1,0,"","","",0,false,0,[[20000,13000,8000,0.5]]]; - _sparkEmitter setParticleRandom [1,[2,2,1],[0,0,0],0,0,[0,0.15,0.15,0],0,0,1,0]; - _sparkEmitter setDropInterval 0.5; - _SmokeEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,13,0],"","Billboard",1,30,[0,0,0],[0,0,0],0,0.051,0.04,0,[3.5],[[0.305037,0.301192,0.3,0.05]],[1000],0.001,0.008,"","","",0,false,0,[[0,0,0,0]]]; - _SmokeEmitter setParticleRandom [1,[4,1.5,1],[0,0,0],0,0,[0,0,0,0],0,0,1,0]; - _SmokeEmitter setDropInterval 0.0005; - - _smokeEmitter spawn { - sleep 0.1; - _this setDropInterval 50; - }; - - [_smokeEmitter, _sparkEmitter] spawn { - sleep 3; - deleteVehicle (_this select 1); - sleep 37; - deleteVehicle (_this select 0); - }; - }; - }; -}; - -/* Explosion effect */ -GVAR(flashbang_explosion) = { - private _soundSource = "HeliHEmpty" createVehicleLocal (_this select 0); - private _expSparkEmitter = "#particlesource" createVehicleLocal (_this select 0); - private _expSmokeEmitter = "#particlesource" createVehicleLocal (_this select 0); - private _explight = "#lightpoint" createVehicleLocal (_this select 0); - - _explight setLightColor [1, 0.8, 0.7]; - _explight setLightAmbient [1, 0.8, 0.7]; - _explight setLightUseFlare true; - _explight setLightFlareSize 2; - _explight setLightFlareMaxDistance 20; - _explight setLightBrightness 8; - _explight setLightIntensity 9000; - _explight setLightDayLight true; - _explight setLightAttenuation [1, 0.1, 10, 0.3, 0.1, 30]; - - _expSparkEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,0,12,0],"","Billboard",0.1,0.1,[0,0,0],[0,0,1],1,2,0.3,0,[0.03],[[1,1,1,-6.5],[1,1,1,-6],[1,1,1,-5.5],[1,1,1,-4.5]],[-2],0,0,"","","",0,false,1,[[20000,13000,8000,0.5]]]; - _expSparkEmitter setParticleRandom [2,[0.5,0.5,0.1],[2.5,2.5,1],1,0.5,[0.05,0.05,0.05,0],0,0,360,1]; - _expSparkEmitter setDropInterval 0.0001; - - _expSmokeEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,13,0],"","Billboard",0.1,0.1,[0,0,0],[0,0,1],1,0.8,0.3,0.4,[1],[[1,1,1,0.5],[1,1,1,0.2],[1,1,1,0.6],[1,1,1,0]],[-2],0,0,"","","",0,false,1,[[0,0,0,0.5]]]; - _expSmokeEmitter setParticleRandom [2,[0.5,0.5,0.5],[6,6,4],1,0.5,[0.05,0.05,0.05,0],0,0,360,1]; - _expSmokeEmitter setDropInterval 0.0003; - - [_expSparkEmitter, _expSmokeEmitter, _explight] spawn { - sleep 0.1; - (_this select 0) setDropInterval 50; - (_this select 1) setDropInterval 50; - (_this select 1) setParticleRandom [0.5,[0.5,0.5,0.5],[1,1,4],1,0.5,[0.05,0.05,0.05,0],0,0,360,1]; - deleteVehicle (_this select 2); - }; - - [_expSparkEmitter, _expSmokeEmitter] spawn { - sleep 4; - deleteVehicle (_this select 0); - deleteVehicle (_this select 1); - }; - - if (_this select 1) then { - _soundSource spawn { - _this say3D "cmf_flashbang_inside"; - _this say3D "cmf_flashbang_inside"; - _this say3D "cmf_flashbang_inside"; - _this say3D "cmf_flashbang_inside"; - _this say3D "cmf_flashbang_inside"; - _this say3D "cmf_flashbang_inside"; - - sleep 4; - deleteVehicle _this; - }; - } else { - _soundSource spawn { - _this say3D "cmf_flashbang_outside"; - _this say3D "cmf_flashbang_outside"; - _this say3D "cmf_flashbang_outside"; - _this say3D "cmf_flashbang_outside"; - _this say3D "cmf_flashbang_outside"; - _this say3D "cmf_flashbang_outside"; - - sleep 4; - deleteVehicle _this; - }; - }; -}; - -/* Check if player fired */ -private _fired_event = { - private _grenadeConfig = (createHashMapFromArray GVAR(flashbang_grenades)) getOrDefault [(_this select 5), [-1]]; - if ((_grenadeConfig select 0) > -1) then { - [(_this select 6), _grenadeConfig] spawn { - params["_grenade", "_grenadeConfig", ""]; - _grenadeConfig params["_grenadeFuze", ["_bangs", 1], ["_bangDelay", {random [0.1, 0.3, 0.8]}]]; - - sleep _grenadeFuze; - - private _posASL = (getPosASL _grenade); - private _pos = (getPos _grenade); - private _classname = (typeOf _grenade); - private _height = ((lineIntersectsSurfaces [_posASL, [(_posASL select 0), (_posASL select 1), 0], _grenade] select 0) select 0) select 2; - if (isNil "_height") then {_height = 0}; - - private _grenadeObject = createVehicle [_classname, [_pos select 0, _pos select 1], [], 0, "NONE"]; - _grenadeObject setPosASL [(_pos select 0), (_pos select 1), _height + 0.03]; - _grenadeObject setVectorUp [(random(selectRandom[1,-1])),(random(selectRandom[1,-1])),0]; - _grenadeObject enableSimulation false; - - /* Disable ACE Pickup on grenades */ - private _acePickup = "Land_Can_V2_F" createVehicle getPos _grenadeObject; - _acePickup setPosASL getPosASL _grenadeObject; - _acePickup hideObjectGlobal true; - _acePickup setVectorUp [(random(selectRandom[1,-1])),(random(selectRandom[1,-1])),0]; - [_grenadeObject, _acePickup] call BIS_fnc_attachToRelative; - _acePickup setVariable ["ace_advanced_throwing_disablePickUp", true, true]; - _acePickup enableSimulation false; - - _grenade setPos [0,0,0]; - deleteVehicle _grenade; - - /* Check if the player is inside */ - lineIntersectsSurfaces [ - getPosWorld _grenadeObject, - getPosWorld _grenadeObject vectorAdd [0, 0, 50], - _grenadeObject, objNull, true, 1, "GEOM", "NONE" - ] select 0 params ["","","","_inHouse"]; - private _inHOuse = !isNil "_inHouse"; - - if (_bangDelay isEqualType {}) then { - _bangDelay = call _bangDelay; - }; - - if (_bangs > 1) then { - [[_pos, _inHouse], GVAR(flashbang_extraEffects)] remoteExec ["call"]; - for "_i" from 0 to _bangs do { - _pos = [((_pos select 0)+random[-0.5,0,0.5]), ((_pos select 1)+random[-0.5,0,0.5]), (_pos select 2)]; - [[_pos, _inHouse], GVAR(flashbang_explosion)] remoteExec ["call"]; - - private _units = _pos nearEntities 10; - { - private _inRoom = [_x, "VIEW"] checkVisibility [eyePos _x, _posASL]; - if (!isplayer _x && _inRoom > 0.6 && lifeState _x != "INCAPACITATED") then { - _x spawn { - [_this, "Acts_CrouchingCoveringRifle01"] remoteExec ["switchMove"]; - [_this, "all"] remoteExec ["disableAI"]; - sleep 5; - [_this, "all"] remoteExec ["enableAI"]; - if (animationState _this == "Acts_CrouchingCoveringRifle01") then { - [_this, ""] remoteExec ["switchMove"]; - }; - }; - } - } forEach _units; - sleep _bangDelay; - private _newPos = (getPos _grenadeObject) getPos [(random 1), (random 360)]; - if ([_grenadeObject, "VIEW"] checkVisibility [[(_newPos select 0), (_newPos select 1), _height + 0.5], [(_posASL select 0), (_posASL select 1), _height + 0.5]] > 0.6) then { - _grenadeObject setPosASL [(_newPos select 0), (_newPos select 1), _height + 0.03]; - _grenadeObject setVectorUp [(random(selectRandom[1,-1])),(random(selectRandom[1,-1])),0]; - _pos = getPos _grenadeObject; - _posASL = getPosASL _grenadeObject; - }; - }; - } else { - [[_pos, _inHouse], GVAR(flashbang_extraEffects)] remoteExec ["call"]; - [[_pos, _inHouse], GVAR(flashbang_explosion)] remoteExec ["call"]; - - private _units = _pos nearEntities 10; - { - private _inRoom = [_x, "VIEW"] checkVisibility [eyePos _x, _posASL]; - if (!isplayer _x && _inRoom > 0.6 && lifeState _x != "INCAPACITATED") then { - _x spawn { - [_this, "Acts_CrouchingCoveringRifle01"] remoteExec ["switchMove"]; - [_this, "all"] remoteExec ["disableAI"]; - sleep 5; - [_this, "all"] remoteExec ["enableAI"]; - if (animationState _this == "Acts_CrouchingCoveringRifle01") then { - [_this, ""] remoteExec ["switchMove"]; - }; - }; - } - } forEach _units; - }; - }; - }; -}; - -player addEventHandler ["Fired", _fired_event]; - -["ace_firedPlayer", _fired_event] call CBA_fnc_addEventHandler; diff --git a/framework/components/gameplay/fn_repairRearmStation.sqf b/framework/components/gameplay/fn_repairRearmStation.sqf deleted file mode 100644 index 573a9b3..0000000 --- a/framework/components/gameplay/fn_repairRearmStation.sqf +++ /dev/null @@ -1,150 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Repairs and rearms player vehicles inside radius. (BROKEN) - * - * Arguments: - * 0: Center Position - * 1: Radius [Default: 5] - * 2: Types to repair [Default: ["Car", "Tank", "Plane", "Helicopter", "Ship"]] - * - * Return Value: - * None - * - * Example: - * [_myPos, 10, ["Helicopter", "Plane"]] call cmf_gameplay_fnc_repairRearmStation - * - * public: Yes -*/ -SCRIPT(repairRearmStation); - -if (!isServer) exitWith {}; - -_this spawn { - private _fnc_repairRearm = { - params ["_veh"]; - - private _type = typeOf _veh; - private _name = getText(configFile >> "CfgVehicles" >> _type >> "displayname"); - private _reloadTimeFactor = 1; - - _veh setVehicleAmmo 1; - QGVAR(reapirRearm_info) cutText [format ["Servicing %1... Please stand by...", _name], "PLAIN DOWN"]; - - private _magazines = getArray(configFile >> "CfgVehicles" >> _type >> "magazines"); - - /* Reload vehicle magazines */ - if (count _magazines > 0) then { - private _removed = []; - { - if (!(_x in _removed)) then { - _veh removeMagazines _x; - _removed = _removed + [_x]; - }; - } forEach _magazines; - - { - - private _name = getText(configFile >> "CfgMagazines" >> _x >> "displayname"); - QGVAR(reapirRearm_info) cutText [format ["Reloading %1 [%2/%3]", _name, _forEachIndex + 1, count _magazines], "PLAIN DOWN"]; - sleep _reloadTimeFactor; - _veh addMagazine _x; - } forEach _magazines; - }; - - /* Get ammount of turrets on vehicle */ - private _turrets = count (configFile >> "CfgVehicles" >> _type >> "Turrets"); - - /* Reload magazines */ - if (_turrets > 0) then { - for "_i" from 0 to (_turrets - 1) do { - private _config = (configFile >> "CfgVehicles" >> _type >> "Turrets") select _i; - private _turretName = configName _config; - _magazines = getArray(_config >> "magazines"); - private _removed = []; - { - if (!(_x in _removed)) then { - _veh removeMagazines _x; - _removed = _removed + [_x]; - }; - } forEach _magazines; - - { - private _name = getText(configFile >> "CfgMagazines" >> _x >> "displayname"); - QGVAR(reapirRearm_info) cutText [format ["Reloading Turret %1 with %2 [%3/%4]", _turretName, _name, _forEachIndex + 1, count _magazines], "PLAIN DOWN"]; - sleep _reloadTimeFactor; - _veh addMagazine _x; - sleep _reloadTimeFactor; - } forEach _magazines; - - private _count_other = count (_config >> "Turrets"); - if (_count_other > 0) then { - for "_i" from 0 to (_count_other - 1) do { - private _config2 = (_config >> "Turrets") select _i; - _magazines = getArray(_config2 >> "magazines"); - _removed = []; - { - if (!(_x in _removed)) then { - _veh removeMagazines _x; - _removed = _removed + [_x]; - }; - } forEach _magazines; - - { - private _name = getText(configFile >> "CfgMagazines" >> _x >> "displayname"); - QGVAR(reapirRearm_info) cutText [format ["Reloading Turret %1 with %2 [%3/%4]", _turretName, _name, _forEachIndex + 1, count _magazines], "PLAIN DOWN"]; - sleep _reloadTimeFactor; - _veh addMagazine _x; - sleep _reloadTimeFactor; - } forEach _magazines; - }; - }; - }; - }; - - /* Reload turrets / drivers magazine */ - _veh setVehicleAmmo 1; - - /* Repair vehicle*/ - sleep _reloadTimeFactor; - //_veh vehicleChat "Repairing..."; - QGVAR(reapirRearm_info) cutText ["Repairing...", "PLAIN DOWN"]; - _veh setDamage 0; - - /* Refuel vehicle */ - sleep _reloadTimeFactor; - //_veh vehicleChat "Refuelling..."; - QGVAR(reapirRearm_info) cutText ["Refueling...", "PLAIN DOWN"]; - while {fuel _veh < 0.99} do { - _veh setFuel ((fuel _veh + 0.01) min 1); - sleep 0.05; - }; - sleep _reloadTimeFactor; - //_veh vehicleChat format ["%1 is ready...", _name]; - QGVAR(reapirRearm_info) cutText [format ["%1 is ready...", _name], "PLAIN DOWN"]; - }; - - /* Make all players self verify */ - [[_this, _fnc_repairRearm], { - (_this select 0) params ["_centerPos", ["_centerRadius", 5], ["_types", ["Car", "Tank", "Plane", "Helicopter", "Ship"]]]; - - while { !(missionNamespace getVariable [QGVAR(repairRearm_disable), false]) } do { - waitUntil { vehicle player != player && (vehicle player distance _centerPos) < _centerRadius && _types findIf { vehicle player isKindOf _x } != -1 }; - private _vehicle = vehicle player; - - LOG("reapirRearm %1", typeOf _vehicle); - - /* Spawn the repair and rearm script */ - private _repairRearmHandle = _vehicle spawn (_this select 1); - - /* Wait until player leaves radius */ - waitUntil { (vehicle player distance _centerPos) > _centerRadius }; - if (!scriptDone _repairRearmHandle) then { - terminate _repairRearmHandle; - QGVAR(reapirRearm_info) cutText ["Cancelled Operation!", "PLAIN DOWN"]; - }; - - sleep 0.1; - }; - }] remoteExec ["spawn", 0, true]; -}; diff --git a/framework/components/gameplay/fn_restrictedVehicle.sqf b/framework/components/gameplay/fn_restrictedVehicle.sqf deleted file mode 100644 index a6cbfca..0000000 --- a/framework/components/gameplay/fn_restrictedVehicle.sqf +++ /dev/null @@ -1,55 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Restricts vehicle operator positions based on supplied condition. (BROKEN) - * - * Arguments: - * 0: Vehicle - * 1: Condition - * - * Return Value: - * None - * - * Example: - * [_myVehicle, { [_this, "CREW"] call cmf_common_fnc_isRole }] call cmf_gameplay_fnc_restrictedVehicle - * - * public: Yes -*/ -SCRIPT(restrictedVehicle); -params ["_vehicle", "_condition"]; - -_vehicle setVariable [QGVAR(restrictedVehicle_condition), _condition, true]; - -/* Check units entering vehicle */ -_vehicle addEventHandler ["GetIn", { - params ["_vehicle", "_role", "_unit", "_role"]; - - LOG("Unit entered vehicle"); - - //if (!isPlayer _unit) exitWith {}; - private _condition = _unit call (_vehicle getVariable [QGVAR(restrictedVehicle_condition), { true }]); - private _role = (assignedVehicleRole _unit) select 0; - - /* Check if player is allowed to be in seat */ - if ((_role in ["driver", "Turret"]) && !_condition) then { - ["You do not know how to operate this vehicle"] remoteExec ["hint", _unit]; - _unit action ["getOut", _vehicle]; - LOG_2("Kicked %1 out of vehicle %2", name _unit, typeOf _vehicle); - }; -}]; - -/* Check units switching seats */ -_vehicle addEventHandler ["SeatSwitched", { - params ["_vehicle", "_unit"]; - - if (!isPlayer _unit) exitWith {}; - private _role = (assignedVehicleRole _unit) select 0; - private _condition = _unit call (_vehicle getVariable [QGVAR(restrictedVehicle_condition), { true }]); - - /* Check if player is allowed to be in seat */ - if ((_role in ["driver", "Turret"]) && !_condition) then { - ["You do not know how to operate this vehicle"] remoteExec ["hint", _unit]; - _unit action ["getOut", _vehicle]; - LOG_2("Kicked %1 out of vehicle %2", name _unit, typeOf _vehicle); - }; -}]; diff --git a/framework/components/gameplay/fn_safestart.sqf b/framework/components/gameplay/fn_safestart.sqf deleted file mode 100644 index aa7de87..0000000 --- a/framework/components/gameplay/fn_safestart.sqf +++ /dev/null @@ -1,97 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * disables shooting and throwing grenades upon mission start until zeus starts mission. - * - * Arguments: - * None - * - * Return Value: - * - * - * Example: - * call cmf_gameplay_fnc_safeStart - * - * public: Yes -*/ -SCRIPT(safestart); - -if (!isServer) exitWith {}; - -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_4(SETTINGS,gameplay,safestart,enable) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -LOG("Enabled safestart"); - -_this spawn { - missionNamespace setVariable [QGVAR(safestart_disable), false, true]; - - /* Raise event */ - [QGVAR(safestart_onEnable), []] call CBA_fnc_globalEvent; - - /* Add events for respawned */ - addMissionEventHandler ["EntityRespawned", { - params ["_unit"]; - - /* If the unit is not a player exit */ - if (!isPlayer _unit) exitWith {}; - - /* If safestart has been disabled delete this eventHandler */ - if (missionNamespace getVariable [QGVAR(safestart_disable), false]) exitWith { - removeMissionEventHandler ["EntityRespawned", _thisEventHandler]; - _unit allowDamage true; - }; - - /* Execute code where unit is local */ - [_this, { - params ["_newEntity", "_oldEntity"]; - - /* Delete old body */ - deleteVehicle _oldEntity; - - /* Make unit invincible */ - _newEntity allowDamage false; - - /* Add action to block shooting */ - private _action = _newEntity addAction ["", { - params ["_target", "_caller", "_actionId"]; - - /* Remove action if game has started */ - if ( missionNamespace getVariable [QGVAR(safestart_disable), false] ) exitWith { _target removeAction _actionId }; - - /* show message in sidechat */ - _caller sideChat "Weapons are cold, game hasn't started"; - }, "", 0, false, true, "DefaultAction", "!((animationState player) in ['acinpknlmstpsraswrfldnon', 'acinpknlmwlksraswrfldb']) && !(missionNameSpace getVariable ['"+QGVAR(safestart_disable)+"', false])"]; - - /* Add event to block throwing grenades the vanilla way */ - ["ace_firedPlayer", { - params ["_unit", "", "_muzzle", "", "", "", "_projectile"]; - - /* Remove action if game has started */ - if (missionNamespace getVariable [QGVAR(safestart_disable), false]) exitWith { - ["ace_firedPlayer", _thisId] call CBA_fnc_removeEventHandler; - player removeAction _thisArgs; - }; - - /* If the projectile is a grenade delete it */ - if ((configname (inheritsFrom (configFile >> "cfgWeapons" >> "throw" >> _muzzle)) isEqualTo "ThrowMuzzle")) then { - _projectile setPos [0,0,0]; - deleteVehicle _projectile; - _unit sideChat LSTRING(weapons_cold); - }; - }, _action] call CBA_fnc_addEventHandlerArgs; - - }] remoteExec ["call", (_this select 0)]; - }]; - - - /* When the game is started show a hint and enable damage for all units */ - waitUntil{ missionNamespace getVariable [QGVAR(safestart_disable), false] }; - [LSTRING(weapons_hot)] remoteExec ["hintSilent", 0]; - - { [_x, true] remoteExec ["allowDamage", 0, true] } forEach allPlayers; - - /* Raise event */ - [QGVAR(safestart_onDisable), []] call CBA_fnc_globalEvent; -}; diff --git a/framework/components/gameplay/fn_tracers.sqf b/framework/components/gameplay/fn_tracers.sqf deleted file mode 100644 index 1b436d6..0000000 --- a/framework/components/gameplay/fn_tracers.sqf +++ /dev/null @@ -1,155 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Replaces AI's ammunition with tracer rounds. - * - * Arguments: - * 0: Side or Unit - * 1: flashlight - * 2: Random Magazine - * - * Return Value: - * None - * - * Example: - * [east, true, false] call cmf_gameplay_fnc_tracers - * - * Public: Yes - */ -SCRIPT(tracers); - -if (!isServer) exitWith {}; - -private _fnc_applyTracers = { - params ["_unit", ["_flash", true], ["_randomModel", false]]; - - if ( !(_unit getVariable [QGVAR(tracers_initialized), false]) ) then { - private _primaryWeaon = primaryWeapon _unit; - private _supportedMags = [_primaryWeaon] call CBA_fnc_compatibleMagazines; - - private _tracerMags = []; - { - if ((getNumber (configfile >> "CfgMagazines" >> _x >> "tracersEvery")) > 0) then { - _tracerMags pushBack _x; - }; - } forEach _supportedMags; - - if (count _tracerMags > 0) then { - private _newMagazine = []; - if (_randomModel) then { - _newMagazine pushBack (_tracerMags select (random (count _tracerMags))); - } else { - { - private _curMag = getText (configfile >> "CfgMagazines" >> _x >> "model"); - private _curprimaryMag = getText (configfile >> "CfgMagazines" >> ((primaryWeaponMagazine _unit) select 0) >> "model"); - if (isNil "_curprimaryMag") then { - _curprimaryMag = ""; - }; - - if (_curMag isEqualTo _curprimaryMag) then { - _newMagazine pushBack _x; - }; - } forEach _tracerMags; - - if ((count _newMagazine) == 0) then - { - _newMagazine pushBack (_tracerMags select 0); - }; - }; - _newMagazine = _newMagazine select 0; - - private _magReplace = []; - private _magCount = 1; - { - if (_x in _supportedMags) then { - _magReplace = _magReplace + [_x]; - _magCount = _magCount + 1; - }; - } forEach magazines _unit; - - if (!isNil "_newMagazine") then { - _unit addMagazines [_newMagazine, 1]; - _unit reload [primaryWeapon _unit, _newMagazine]; - { - [_unit, _x] call CBA_fnc_removeMagazine; - } forEach _magReplace; - - _unit addMagazines [_newMagazine, _magCount]; - }; - - LOG_1("Added tracers for %1", name _unit); - _unit setVariable [QGVAR(tracers_initialized), true, true]; - }; - - if (_flash) then { - private _flashLights = []; - private _compatMods = [_primaryWeaon] call CBA_fnc_compatibleItems; - { - if (isClass(configfile >> "CfgWeapons" >> _x >> "ItemInfo" >> "FlashLight")) then { - if (getNumber(configfile >> "CfgWeapons" >> _x >> "ItemInfo" >> "FlashLight" >> "intensity") != 0) then { - _flashLights pushBack _x; - }; - }; - } forEach _compatMods; - if (count _flashLights > 0) then { - _unit addPrimaryWeaponItem (_flashLights select (random (count _flashLights))); - _unit enableGunLights "ForceOn"; - }; - }; - }; -}; - -params [["_unit", nil], ["_flash", true], ["_randomModel", false]]; - -LOG_1("tracers called with params %1", str _this); - -/* Assumed autoinit */ -if (isNil "_unit") then { - [_fnc_applyTracers] spawn { - params ["_fnc_applyTracers"]; - - /* Check if it's enabled */ - private _enabled = ( CONFIG_PARAM_4(SETTINGS,gameplay,tracers,enable) ) isEqualTo 1; - if !(_enabled) exitWith {}; - - private _sides = CONFIG_PARAM_4(SETTINGS,gameplay,tracers,side); - - while { !(missionNamespace getVariable [QGVAR(tracers_disable), false]) } do { - { - - { - if (!isPlayer _x) then { - [_x, false, false] spawn _fnc_applyTracers; - sleep 0.03; - }; - } forEach units call compile _x; - sleep 0.03; - } forEach _sides; - sleep 1; - }; - }; -}; - -/* For unit */ -if (IS_OBJECT(_unit)) exitWith { - if (!isPlayer _unit) then { - [_unit, _flash, _randomModel] call _fnc_applyTracers; - }; -}; - -/* For side */ -if (IS_SIDE(_unit)) exitWith { - [_unit, _flash, _randomModel, _fnc_applyTracers] spawn { - params ["_unit", "_flash", "_randomModel", "_fnc_applyTracers"]; - - while { !(missionNamespace getVariable [QGVAR(tracers_disable), false]) } do { - { - if (!isPlayer _x) then { - [_x, _flash, _randomModel] spawn _fnc_applyTracers; - sleep 0.03; - }; - } forEach units _unit; - sleep 1; - }; - }; -}; diff --git a/framework/components/gameplay/functions/fn_environment.sqf b/framework/components/gameplay/functions/fn_environment.sqf new file mode 100644 index 0000000..0f957c9 --- /dev/null +++ b/framework/components/gameplay/functions/fn_environment.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Creates an environment overview for mission in diary + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_gameplay_fnc_environment + * + * Public: No + */ + +[{ !isNull player && alive player }, { + player createDiarySubject ["cmf_environment", "Environment"]; + + addMissionEventHandler ["Map", { + params ["_mapIsOpened"]; + + if (!_mapIsOpened) then { + /* Remove outdated environment */ + { + player removeDiaryRecord ["cmf_environment", _x select 8] + } forEach (player allDiaryRecords "cmf_environment"); + } else { + private _date = date; + private _weather = [] call EFUNC(utility,getWeatherDescriptors); + + private _weatherText = [ + format["%1", _weather select 0], + format["%1", _weather select 1], + format["Wind: %1", _weather select 2], + format["Humidity: %1", _weather select 3], + format["Moon Phase: %1", _weather select 4] + ]; + _weatherText = _weatherText joinString "
"; + + /* Get Dawn and Dusk Times */ + _dawnDuskText = [ + _date call { + private _sunrise = (_this call BIS_fnc_sunriseSunsetTime) select 0; + format["%1:%2 | %3", floor _sunrise, [((_sunrise * 60) % 60), 2] call CBA_fnc_formatNumber, "Sunrise"]; + }, + _date call { + private _sundown = (_this call BIS_fnc_sunriseSunsetTime) select 1; + format["%1:%2 | %3", floor _sundown, [((_sundown * 60) % 60), 2] call CBA_fnc_formatNumber, "Sunset"]; + } + ]; + _dawnDuskText = _dawnDuskText joinString "
"; + + player createDiaryRecord ["cmf_environment", ["Weather", _weatherText]]; + player createDiaryRecord ["cmf_environment", ["Dawn & Dusk", _dawnDuskText]]; + }; + }]; +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/gameplay/functions/fn_flashbangOverride.sqf b/framework/components/gameplay/functions/fn_flashbangOverride.sqf new file mode 100644 index 0000000..eb93eb2 --- /dev/null +++ b/framework/components/gameplay/functions/fn_flashbangOverride.sqf @@ -0,0 +1,221 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Overrides flashbang explosions + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_gameplay_fnc_flashbangOverride + * + * Public: No + */ +SCRIPT(flashbangOverride); + +/* Define a variable to configure grenades */ +GVAR(flashbang_grenades) = [["rhs_mag_mk84", [1.2]], ["ACE_M84", [1.2]], ["rhs_mag_fakel", [1.2]], ["rhs_mag_plamyam", [1.2]], ["rhs_mag_fakels", [1.2]], ["rhs_mag_zarya2", [1.2]], ["rhssaf_mag_rshb_p98", [1.2]], ["ACE_CTS9", [1.2, 9, {0.5}]]]; + +/* Extra particle effects if the player is inside */ +GVAR(flashbang_extraEffects) = { + if (_this select 1) then { + private _SmokeEmitter = "#particlesource" createVehicleLocal [((_this select 0) select 0), ((_this select 0) select 1), ((_this select 0) select 2) + 0.1]; + private _sparkEmitter = "#particlesource" createVehicleLocal [((_this select 0) select 0), ((_this select 0) select 1), ((_this select 0) select 2) + 0.1]; + + [_SmokeEmitter, _sparkEmitter] spawn { + params["_SmokeEmitter", "_sparkEmitter"]; + _sparkEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,0,12,0],"","Billboard",1,20,[0,0,1.2],[0,0,0],0,10.071,7.9,0,[0.005,0.005,0.005,0.005,0.005,0.005,0.005,0.005,0.005,0],[[1,1,1,-6.5],[1,1,1,-6],[1,1,1,-5.5],[1,1,1,-4.5]],[1000],1,0,"","","",0,false,0,[[20000,13000,8000,0.5]]]; + _sparkEmitter setParticleRandom [1,[2,2,1],[0,0,0],0,0,[0,0.15,0.15,0],0,0,1,0]; + _sparkEmitter setDropInterval 0.5; + _SmokeEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,13,0],"","Billboard",1,30,[0,0,0],[0,0,0],0,0.051,0.04,0,[3.5],[[0.305037,0.301192,0.3,0.05]],[1000],0.001,0.008,"","","",0,false,0,[[0,0,0,0]]]; + _SmokeEmitter setParticleRandom [1,[4,1.5,1],[0,0,0],0,0,[0,0,0,0],0,0,1,0]; + _SmokeEmitter setDropInterval 0.0005; + + _smokeEmitter spawn { + sleep 0.1; + _this setDropInterval 50; + }; + + [_smokeEmitter, _sparkEmitter] spawn { + sleep 3; + deleteVehicle (_this select 1); + sleep 37; + deleteVehicle (_this select 0); + }; + }; + }; +}; + +/* Explosion effect */ +GVAR(flashbang_explosion) = { + private _soundSource = "HeliHEmpty" createVehicleLocal (_this select 0); + private _expSparkEmitter = "#particlesource" createVehicleLocal (_this select 0); + private _expSmokeEmitter = "#particlesource" createVehicleLocal (_this select 0); + private _explight = "#lightpoint" createVehicleLocal (_this select 0); + + _explight setLightColor [1, 0.8, 0.7]; + _explight setLightAmbient [1, 0.8, 0.7]; + _explight setLightUseFlare true; + _explight setLightFlareSize 2; + _explight setLightFlareMaxDistance 20; + _explight setLightBrightness 8; + _explight setLightIntensity 9000; + _explight setLightDayLight true; + _explight setLightAttenuation [1, 0.1, 10, 0.3, 0.1, 30]; + + _expSparkEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,0,12,0],"","Billboard",0.1,0.1,[0,0,0],[0,0,1],1,2,0.3,0,[0.03],[[1,1,1,-6.5],[1,1,1,-6],[1,1,1,-5.5],[1,1,1,-4.5]],[-2],0,0,"","","",0,false,1,[[20000,13000,8000,0.5]]]; + _expSparkEmitter setParticleRandom [2,[0.5,0.5,0.1],[2.5,2.5,1],1,0.5,[0.05,0.05,0.05,0],0,0,360,1]; + _expSparkEmitter setDropInterval 0.0001; + + _expSmokeEmitter setParticleParams [["\A3\data_f\ParticleEffects\Universal\Universal.p3d",16,12,13,0],"","Billboard",0.1,0.1,[0,0,0],[0,0,1],1,0.8,0.3,0.4,[1],[[1,1,1,0.5],[1,1,1,0.2],[1,1,1,0.6],[1,1,1,0]],[-2],0,0,"","","",0,false,1,[[0,0,0,0.5]]]; + _expSmokeEmitter setParticleRandom [2,[0.5,0.5,0.5],[6,6,4],1,0.5,[0.05,0.05,0.05,0],0,0,360,1]; + _expSmokeEmitter setDropInterval 0.0003; + + [_expSparkEmitter, _expSmokeEmitter, _explight] spawn { + sleep 0.1; + (_this select 0) setDropInterval 50; + (_this select 1) setDropInterval 50; + (_this select 1) setParticleRandom [0.5,[0.5,0.5,0.5],[1,1,4],1,0.5,[0.05,0.05,0.05,0],0,0,360,1]; + deleteVehicle (_this select 2); + }; + + [_expSparkEmitter, _expSmokeEmitter] spawn { + sleep 4; + deleteVehicle (_this select 0); + deleteVehicle (_this select 1); + }; + + if (_this select 1) then { + _soundSource spawn { + _this say3D "cmf_flashbang_inside"; + _this say3D "cmf_flashbang_inside"; + _this say3D "cmf_flashbang_inside"; + _this say3D "cmf_flashbang_inside"; + _this say3D "cmf_flashbang_inside"; + _this say3D "cmf_flashbang_inside"; + + sleep 4; + deleteVehicle _this; + }; + } else { + _soundSource spawn { + _this say3D "cmf_flashbang_outside"; + _this say3D "cmf_flashbang_outside"; + _this say3D "cmf_flashbang_outside"; + _this say3D "cmf_flashbang_outside"; + _this say3D "cmf_flashbang_outside"; + _this say3D "cmf_flashbang_outside"; + + sleep 4; + deleteVehicle _this; + }; + }; +}; + +/* Check if player fired */ +private _fired_event = { + if (!GVAR(setting_flashbang)) exitWith {}; + + private _grenadeConfig = (createHashMapFromArray GVAR(flashbang_grenades)) getOrDefault [(_this select 5), [-1]]; + if ((_grenadeConfig select 0) > -1) then { + [(_this select 6), _grenadeConfig] spawn { + params["_grenade", "_grenadeConfig", ""]; + _grenadeConfig params["_grenadeFuze", ["_bangs", 1], ["_bangDelay", {random [0.1, 0.3, 0.8]}]]; + + sleep _grenadeFuze; + + private _posASL = (getPosASL _grenade); + private _pos = (getPos _grenade); + private _classname = (typeOf _grenade); + private _height = ((lineIntersectsSurfaces [_posASL, [(_posASL select 0), (_posASL select 1), 0], _grenade] select 0) select 0) select 2; + if (isNil "_height") then {_height = 0}; + + private _grenadeObject = createVehicle [_classname, [_pos select 0, _pos select 1], [], 0, "NONE"]; + _grenadeObject setPosASL [(_pos select 0), (_pos select 1), _height + 0.03]; + _grenadeObject setVectorUp [(random(selectRandom[1,-1])),(random(selectRandom[1,-1])),0]; + _grenadeObject enableSimulation false; + + /* Disable ACE Pickup on grenades */ + private _acePickup = "Land_Can_V2_F" createVehicle getPos _grenadeObject; + _acePickup setPosASL getPosASL _grenadeObject; + _acePickup hideObjectGlobal true; + _acePickup setVectorUp [(random(selectRandom[1,-1])),(random(selectRandom[1,-1])),0]; + [_grenadeObject, _acePickup] call BIS_fnc_attachToRelative; + _acePickup setVariable ["ace_advanced_throwing_disablePickUp", true, true]; + _acePickup enableSimulation false; + + _grenade setPos [0,0,0]; + deleteVehicle _grenade; + + /* Check if the player is inside */ + lineIntersectsSurfaces [ + getPosWorld _grenadeObject, + getPosWorld _grenadeObject vectorAdd [0, 0, 50], + _grenadeObject, objNull, true, 1, "GEOM", "NONE" + ] select 0 params ["","","","_inHouse"]; + private _inHOuse = !isNil "_inHouse"; + + if (_bangDelay isEqualType {}) then { + _bangDelay = call _bangDelay; + }; + + if (_bangs > 1) then { + [[_pos, _inHouse], GVAR(flashbang_extraEffects)] remoteExec ["call"]; + for "_i" from 0 to _bangs do { + _pos = [((_pos select 0)+random[-0.5,0,0.5]), ((_pos select 1)+random[-0.5,0,0.5]), (_pos select 2)]; + [[_pos, _inHouse], GVAR(flashbang_explosion)] remoteExec ["call"]; + + private _units = _pos nearEntities 10; + { + private _inRoom = [_x, "VIEW"] checkVisibility [eyePos _x, _posASL]; + if (!isplayer _x && _inRoom > 0.6 && lifeState _x != "INCAPACITATED") then { + _x spawn { + [_this, "Acts_CrouchingCoveringRifle01"] remoteExec ["switchMove"]; + [_this, "all"] remoteExec ["disableAI"]; + sleep 5; + [_this, "all"] remoteExec ["enableAI"]; + if (animationState _this == "Acts_CrouchingCoveringRifle01") then { + [_this, ""] remoteExec ["switchMove"]; + }; + }; + } + } forEach _units; + sleep _bangDelay; + private _newPos = (getPos _grenadeObject) getPos [(random 1), (random 360)]; + if ([_grenadeObject, "VIEW"] checkVisibility [[(_newPos select 0), (_newPos select 1), _height + 0.5], [(_posASL select 0), (_posASL select 1), _height + 0.5]] > 0.6) then { + _grenadeObject setPosASL [(_newPos select 0), (_newPos select 1), _height + 0.03]; + _grenadeObject setVectorUp [(random(selectRandom[1,-1])),(random(selectRandom[1,-1])),0]; + _pos = getPos _grenadeObject; + _posASL = getPosASL _grenadeObject; + }; + }; + } else { + [[_pos, _inHouse], GVAR(flashbang_extraEffects)] remoteExec ["call"]; + [[_pos, _inHouse], GVAR(flashbang_explosion)] remoteExec ["call"]; + + private _units = _pos nearEntities 10; + { + private _inRoom = [_x, "VIEW"] checkVisibility [eyePos _x, _posASL]; + if (!isplayer _x && _inRoom > 0.6 && lifeState _x != "INCAPACITATED") then { + _x spawn { + [_this, "Acts_CrouchingCoveringRifle01"] remoteExec ["switchMove"]; + [_this, "all"] remoteExec ["disableAI"]; + sleep 5; + [_this, "all"] remoteExec ["enableAI"]; + if (animationState _this == "Acts_CrouchingCoveringRifle01") then { + [_this, ""] remoteExec ["switchMove"]; + }; + }; + } + } forEach _units; + }; + }; + }; +}; + +player addEventHandler ["Fired", _fired_event]; + +["ace_firedPlayer", _fired_event] call CBA_fnc_addEventHandler; diff --git a/framework/components/gameplay/functions/fn_repairRearmStation.sqf b/framework/components/gameplay/functions/fn_repairRearmStation.sqf new file mode 100644 index 0000000..ce71f62 --- /dev/null +++ b/framework/components/gameplay/functions/fn_repairRearmStation.sqf @@ -0,0 +1,153 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Repairs and rearms player vehicles inside radius. (BROKEN) + * + * Arguments: + * 0: Center Position + * 1: Radius [Default: 5] + * 2: Types to repair [Default: ["Car", "Tank", "Plane", "Helicopter", "Ship"]] + * + * Return Value: + * None + * + * Example: + * [_myPos, 10, ["Helicopter", "Plane"]] call cmf_gameplay_fnc_repairRearmStation + * + * public: Yes +*/ +SCRIPT(repairRearmStation); + +if (!isServer) exitWith {}; + +// @TODO: replace spawn +_this spawn { + private _fnc_repairRearm = { + params ["_veh"]; + + private _type = typeOf _veh; + private _name = getText(configFile >> "CfgVehicles" >> _type >> "displayname"); + private _reloadTimeFactor = 1; + + _veh setVehicleAmmo 1; + QGVAR(reapirRearm_info) cutText [format ["Servicing %1... Please stand by...", _name], "PLAIN DOWN"]; + + private _magazines = getArray(configFile >> "CfgVehicles" >> _type >> "magazines"); + + /* Reload vehicle magazines */ + if (count _magazines > 0) then { + private _removed = []; + { + if (!(_x in _removed)) then { + _veh removeMagazines _x; + _removed = _removed + [_x]; + }; + } forEach _magazines; + + { + + private _name = getText(configFile >> "CfgMagazines" >> _x >> "displayname"); + QGVAR(reapirRearm_info) cutText [format ["Reloading %1 [%2/%3]", _name, _forEachIndex + 1, count _magazines], "PLAIN DOWN"]; + sleep _reloadTimeFactor; + _veh addMagazine _x; + } forEach _magazines; + }; + + /* Get ammount of turrets on vehicle */ + private _turrets = count (configFile >> "CfgVehicles" >> _type >> "Turrets"); + + /* Reload magazines */ + if (_turrets > 0) then { + for "_i" from 0 to (_turrets - 1) do { + private _config = (configFile >> "CfgVehicles" >> _type >> "Turrets") select _i; + private _turretName = configName _config; + _magazines = getArray(_config >> "magazines"); + private _removed = []; + { + if (!(_x in _removed)) then { + _veh removeMagazines _x; + _removed = _removed + [_x]; + }; + } forEach _magazines; + + { + private _name = getText(configFile >> "CfgMagazines" >> _x >> "displayname"); + QGVAR(reapirRearm_info) cutText [format ["Reloading Turret %1 with %2 [%3/%4]", _turretName, _name, _forEachIndex + 1, count _magazines], "PLAIN DOWN"]; + sleep _reloadTimeFactor; + _veh addMagazine _x; + sleep _reloadTimeFactor; + } forEach _magazines; + + private _count_other = count (_config >> "Turrets"); + if (_count_other > 0) then { + for "_i" from 0 to (_count_other - 1) do { + private _config2 = (_config >> "Turrets") select _i; + _magazines = getArray(_config2 >> "magazines"); + _removed = []; + { + if (!(_x in _removed)) then { + _veh removeMagazines _x; + _removed = _removed + [_x]; + }; + } forEach _magazines; + + { + private _name = getText(configFile >> "CfgMagazines" >> _x >> "displayname"); + QGVAR(reapirRearm_info) cutText [format ["Reloading Turret %1 with %2 [%3/%4]", _turretName, _name, _forEachIndex + 1, count _magazines], "PLAIN DOWN"]; + sleep _reloadTimeFactor; + _veh addMagazine _x; + sleep _reloadTimeFactor; + } forEach _magazines; + }; + }; + }; + }; + + /* Reload turrets / drivers magazine */ + _veh setVehicleAmmo 1; + + /* Repair vehicle*/ + sleep _reloadTimeFactor; + //_veh vehicleChat "Repairing..."; + QGVAR(reapirRearm_info) cutText ["Repairing...", "PLAIN DOWN"]; + _veh setDamage 0; + + /* Refuel vehicle */ + sleep _reloadTimeFactor; + //_veh vehicleChat "Refuelling..."; + QGVAR(reapirRearm_info) cutText ["Refueling...", "PLAIN DOWN"]; + while {fuel _veh < 0.99} do { + _veh setFuel ((fuel _veh + 0.01) min 1); + sleep 0.05; + }; + sleep _reloadTimeFactor; + //_veh vehicleChat format ["%1 is ready...", _name]; + QGVAR(reapirRearm_info) cutText [format ["%1 is ready...", _name], "PLAIN DOWN"]; + }; + + /* Make all players self verify */ + // @TODO: replace spawn + [[_this, _fnc_repairRearm], { + (_this select 0) params ["_centerPos", ["_centerRadius", 5], ["_types", ["Car", "Tank", "Plane", "Helicopter", "Ship"]]]; + + while { !(missionNamespace getVariable [QGVAR(repairRearm_disable), false]) } do { + waitUntil { vehicle player != player && (vehicle player distance _centerPos) < _centerRadius && _types findIf { vehicle player isKindOf _x } != -1 }; + private _vehicle = vehicle player; + + LOG("reapirRearm %1", typeOf _vehicle); + + /* Spawn the repair and rearm script */ + // @TODO: replace spawn + private _repairRearmHandle = _vehicle spawn (_this select 1); + + /* Wait until player leaves radius */ + waitUntil { (vehicle player distance _centerPos) > _centerRadius }; + if (!scriptDone _repairRearmHandle) then { + terminate _repairRearmHandle; + QGVAR(reapirRearm_info) cutText ["Cancelled Operation!", "PLAIN DOWN"]; + }; + + sleep 0.1; + }; + }] remoteExec ["spawn", 0, true]; +}; diff --git a/framework/components/gameplay/functions/fn_restrictedVehicle.sqf b/framework/components/gameplay/functions/fn_restrictedVehicle.sqf new file mode 100644 index 0000000..01cd81b --- /dev/null +++ b/framework/components/gameplay/functions/fn_restrictedVehicle.sqf @@ -0,0 +1,55 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Restricts vehicle operator positions based on supplied condition. (BROKEN) + * + * Arguments: + * 0: Vehicle + * 1: Condition + * + * Return Value: + * None + * + * Example: + * [_myVehicle, { [_this, "CREW"] call cmf_common_fnc_isRole }] call cmf_gameplay_fnc_restrictedVehicle + * + * public: Yes +*/ +SCRIPT(restrictedVehicle); +params ["_vehicle", "_condition"]; + +_vehicle setVariable [QGVAR(restrictedVehicle_condition), _condition, true]; + +/* Check units entering vehicle */ +_vehicle addEventHandler ["GetIn", { + params ["_vehicle", "_role", "_unit", "_role"]; + + LOG("Unit entered vehicle"); + + //if (!isPlayer _unit) exitWith {}; + private _condition = _unit call (_vehicle getVariable [QGVAR(restrictedVehicle_condition), { true }]); + private _role = (assignedVehicleRole _unit) select 0; + + /* Check if player is allowed to be in seat */ + if ((_role in ["driver", "Turret"]) && !_condition) then { + ["You do not know how to operate this vehicle"] remoteExec ["hint", _unit]; + _unit action ["getOut", _vehicle]; + LOG_2("Kicked %1 out of vehicle %2", name _unit, typeOf _vehicle); + }; +}]; + +/* Check units switching seats */ +_vehicle addEventHandler ["SeatSwitched", { + params ["_vehicle", "_unit"]; + + if (!isPlayer _unit) exitWith {}; + private _role = (assignedVehicleRole _unit) select 0; + private _condition = _unit call (_vehicle getVariable [QGVAR(restrictedVehicle_condition), { true }]); + + /* Check if player is allowed to be in seat */ + if ((_role in ["driver", "Turret"]) && !_condition) then { + ["You do not know how to operate this vehicle"] remoteExec ["hint", _unit]; + _unit action ["getOut", _vehicle]; + LOG_2("Kicked %1 out of vehicle %2", name _unit, typeOf _vehicle); + }; +}]; diff --git a/framework/components/gameplay/functions/fn_safestart.sqf b/framework/components/gameplay/functions/fn_safestart.sqf new file mode 100644 index 0000000..5353b0e --- /dev/null +++ b/framework/components/gameplay/functions/fn_safestart.sqf @@ -0,0 +1,232 @@ +#include "script_component.hpp" +/* + * Author: Eric + * disables shooting and throwing grenades upon mission start until zeus starts mission. + * + * Arguments: + * None + * + * Return Value: + * + * + * Example: + * call cmf_gameplay_fnc_safeStart + * + * public: Yes +*/ +SCRIPT(safestart); + +if (!isServer) exitWith {}; + +if !(GVAR(setting_safestart)) exitWith {}; + +LOG("Enabled safestart"); + +/* Automatic phases */ +missionNameSpace setVariable [QGVAR(safestart_phase), ["Setup", 0], true]; + +[{ (systemTime select 3) >= 19 }, { + missionNameSpace setVariable [QGVAR(safestart_phase), ["Pre-Start", time], true]; +}] call CBA_fnc_waitUntilAndExecute; + +[{ (systemTime select 3) >= 20 }, { + missionNameSpace setVariable [QGVAR(safestart_phase), ["Briefing", time], true]; +}] call CBA_fnc_waitUntilAndExecute; + +[{ (systemTime select 3) >= 20 && { (systemTime select 4) >= 30 } }, { + missionNameSpace setVariable [QGVAR(safestart_phase), ["Overtime", time], true]; +}] call CBA_fnc_waitUntilAndExecute; + +/* Freeze Time */ +GVAR(safestart_freezeTimeState) = EGVAR(utility,setting_freezeTime); +if (!EGVAR(utility,setting_freezeTime)) then { + missionNamespace setVariable [QEGVAR(utility,setting_freezeTime), true, true]; +}; + +addMissionEventHandler ["EntityRespawned", { + params ["_unit", "_body"]; + + /* Delete old body */ + deleteVehicle _body; + + /* If the unit is not a player exit */ + if (!isPlayer _unit) exitWith { }; + + /* If safestart has been disabled delete this eventHandler */ + if (missionNamespace getVariable [QGVAR(safestart_disable), false]) exitWith { + removeMissionEventHandler ["EntityRespawned", _thisEventHandler]; + _unit allowDamage true; + }; + + /* Execute code where unit is local */ + [_this, { + params ["_unit"]; + + /* Show hint to player while safestart is active */ + [{ + private _safestartHint = "SafeStart
"; + + /* Safestart Mission Title */ + private _missionData = missionNameSpace getVariable [QEGVAR(common,missionData), []]; + private _hash = [_missionData] call CBA_fnc_hashCreate; + + private _title = [_hash, "M_TITLE", [getMissionConfigValue ['IntelBriefingName', briefingName]] call EFUNC(utility,hexToASCII)] call CBA_fnc_hashGet; + private _safestartHint = _safestartHint + format["%1
", _title]; + + /* Safestart phase */ + private _phase = missionNameSpace getVariable [QGVAR(safestart_phase), ["Pre-Start", 0]]; + private _startTime = _phase select 1; + + _safestartHint = _safestartHint + format [ + "%1 %2
", + (_phase select 0), + [(time - _startTime), 'MM:SS'] call BIS_fnc_secondsToString + ]; + + /* Cutoffs */ + private _cutoffPhases = missionNameSpace getVariable [QGVAR(safestart_phaseCutOffs), []]; + { + if ((_x select 1) > ((time - _startTime))) then { + _safestartHint = _safestartHint + format [ + "%1 Cut-off %2
", + (_x select 0), + [(_x select 1) - (time), 'MM:SS'] call BIS_fnc_secondsToString + ]; + } else { + [] spawn compile (_x select 2); + _cutoffPhases deleteAt (_cutoffPhases find _x); + }; + } forEach _cutoffPhases; + missionNameSpace setVariable [QGVAR(safestart_phaseCutOffs), _cutoffPhases, true]; + + _safestartHint = _safestartHint + "

"; + + /* Safestart mission meta */ + _safestartHint = _safestartHint + ""; + private _missionData = missionNameSpace getVariable [QEGVAR(common,missionData), []]; + private _equipment = [_missionData] call CBA_fnc_hashCreate; + if (([_equipment, "E_MAP", ""] call CBA_fnc_hashGet) != "") then {_safestartHint = _safestartHint + format["Maps: %1
", [_equipment, "E_MAP"] call CBA_fnc_hashGet]; }; + if (([_equipment, "E_GPS", ""] call CBA_fnc_hashGet) != "") then {_safestartHint = _safestartHint + format["GPS: %1
", [_equipment, "E_GPS"] call CBA_fnc_hashGet]; }; + if (([_equipment, "E_RADIO", ""] call CBA_fnc_hashGet) != "") then {_safestartHint = _safestartHint + format["Radios: %1
", [_equipment, "E_RADIO"] call CBA_fnc_hashGet]; }; + if (([_equipment, "E_NVG", ""] call CBA_fnc_hashGet) != "") then {_safestartHint = _safestartHint + format["NVGs: %1
", [_equipment, "E_NVG"] call CBA_fnc_hashGet]; }; + if (([_equipment, "E_FLASHLIGHT", ""] call CBA_fnc_hashGet) != "") then {_safestartHint = _safestartHint + format["Flashlights: %1
", [_equipment, "E_FLASHLIGHT"] call CBA_fnc_hashGet]; }; + if (([_equipment, "E_FLARE", ""] call CBA_fnc_hashGet) != "") then {_safestartHint = _safestartHint + format["Flares: %1
", [_equipment, "E_FLARE"] call CBA_fnc_hashGet]; }; + if (uniform player != '') then { + _safestartHint = _safestartHint + format["Uniform: %1
", [configFile >> "CfgWeapons" >> (uniform player)] call BIS_fnc_displayName]; + }; + if (primaryWeapon player != '') then { + _safestartHint = _safestartHint + format["Loadout: %1
", [configFile >> "CfgWeapons" >> (primaryWeapon player)] call BIS_fnc_displayName]; + }; + if ([player] call EFUNC(respawn,getLimit) != -1) then { + _safestartHint = _safestartHint + format["Respawns: %1
", [player] call EFUNC(respawn,getLimit)]; + }; + _safestartHint = _safestartHint + "
"; + + /* Get radio info */ + private _pttAssign = [] call acre_api_fnc_getMultiPushToTalkAssignment; + { + _safestartHint = _safestartHint + format[ + "%1 Chan %2 PTT %3, %4
", + [_x] call acre_api_fnc_getDisplayName, + [_x] call acre_api_fnc_getRadioChannel, + (_pttAssign find _x) + 1, + switch (([_x] call acre_api_fnc_getRadioSpatial)) do { case "LEFT": { "L" }; case "RIGHT": { "R" }; case "CENTER": { "B" }; } + ]; + } forEach call acre_api_fnc_getCurrentRadioList; + _safestartHint = _safestartHint + "
"; + + /* Group and player info */ + _safestartHint = _safestartHint + format ["%1
", groupId group player]; + { + _safestartHint = _safestartHint + format[ + "%1 %2, %3kg %4
", + name _x, + [_x] call EFUNC(organization,getRole), + ((loadAbs _x / 10) / 2.205) toFixed 2, + switch (rank _x) do { + case 'PRIVATE': { "Pvt" }; + case 'CORPORAL': { "Cpl" }; + case 'SERGEANT': { "Sgt" }; + case 'LIEUTENANT': { "Lt" }; + case 'CAPTAIN': { "Cpt" }; + case 'MAJOR': { "Maj" }; + case 'COLONEL': { "Col" }; + default { "" }; + } + ]; + } forEach units group player; + + /* Exit if safestart countdown has been called */ + if (missionNameSpace getVariable [QGVAR(safestart_Countdown), false]) exitWith {}; + + /* Show hint if hud isn't disabled */ + if (missionNameSpace getVariable [QEGVAR(menu,hud_show), true]) then { + hintSilent parseText _safestartHint; // @TODO: create a control instead and attach it to display 46 + } else { + hintSilent ""; + }; + }, 1] call CBAFUNC(addPerFrameHandler); + + /* Make unit invincible */ + _unit allowDamage false; + + /* Add action to block shooting */ + private _action = _unit addAction ["", { + params ["_target", "_caller", "_actionId"]; + + /* Remove action if game has started */ + if ( missionNamespace getVariable [QGVAR(safestart_disable), false] ) exitWith { _target removeAction _actionId }; + + /* show message in sidechat */ + ["Safestart is active", -1, safezoneY + 0.1] spawn bis_fnc_dynamicText; + }, "", 0, false, true, "DefaultAction", "!(missionNameSpace getVariable ['"+QGVAR(safestart_disable)+"', false]) && !(missionNamespace getVariable ["QGVAR(safestart_override)", false]) && !(_this getVariable ['ace_dragging_isCarrying', false])"]; + + /* Add event to block throwing grenades the vanilla way */ + ["ace_firedPlayer", { + params ["_unit", "", "_muzzle", "", "", "", "_projectile"]; + + /* Remove action if game has started */ + if (missionNamespace getVariable [QGVAR(safestart_disable), false]) exitWith { + ["ace_firedPlayer", _thisId] call CBA_fnc_removeEventHandler; + player removeAction _thisArgs; + }; + + /* If the projectile is a grenade delete it */ + if ((configname (inheritsFrom (configFile >> "cfgWeapons" >> "throw" >> _muzzle)) isEqualTo "ThrowMuzzle")) then { + _projectile setPos [0,0,0]; + deleteVehicle _projectile; + ["Safestart is active", -1, safezoneY + 0.1] spawn bis_fnc_dynamicText; + }; + }, _action] call CBA_fnc_addEventHandlerArgs; + + }] remoteExec ["call", (_this select 0)]; +}]; + +[{ + missionNamespace getVariable [QGVAR(safestart_disable), false] +}, { + [[], { titleText ["Game on!", "PLAIN", 0.2] }] remoteExec ["call", 0]; + + /* Restate freezeTime */ + missionNamespace setVariable [QEGVAR(utility,setting_freezeTime), GVAR(safestart_freezeTimeState), true]; + + /* Renable damage */ + { [_x, true] remoteExec ["allowDamage", 0, true] } forEach allPlayers; + + /* Raise event */ + [QGVAR(safestart_onDisable), []] call CBA_fnc_globalEvent; + + [{ + private _missionData = missionNameSpace getVariable [QEGVAR(common,missionData), []]; + private _hash = [_missionData] call CBA_fnc_hashCreate; + + private _title = [_hash, "M_TITLE", [getMissionConfigValue ['IntelBriefingName', briefingName]] call EFUNC(utility,hexToASCII)] call CBA_fnc_hashGet; + private _gamemode = ([_hash, "M_TYPE", [-1, getText (getMissionConfig "Header" >> 'GameType')]] call CBA_fnc_hashGet) select 1; + + if (_gamemode isEqualTo "custom") then { + _gamemode = [_hash, "M_CTYPE", getText (getMissionConfig "Header" >> 'GameType')] call CBA_fnc_hashGet; + }; + + [format [" %1: %2 ", toUpper _gamemode, _title], [safeZoneX, safeZoneW - safeZoneX], safezoneH - 0.8, 4] spawn BIS_fnc_dynamicText + }, [], 3] call CBA_fnc_waitAndExecute; +}] call CBAFUNC(waitUntilAndExecute); diff --git a/framework/components/gameplay/functions/fn_tracers.sqf b/framework/components/gameplay/functions/fn_tracers.sqf new file mode 100644 index 0000000..e532f2c --- /dev/null +++ b/framework/components/gameplay/functions/fn_tracers.sqf @@ -0,0 +1,154 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Replaces AI's ammunition with tracer rounds. + * + * Arguments: + * 0: Side or Unit + * 1: flashlight + * 2: Random Magazine + * + * Return Value: + * None + * + * Example: + * [east, true, false] call cmf_gameplay_fnc_tracers + * + * Public: Yes + */ +SCRIPT(tracers); + +if (!isServer) exitWith {}; + +FUNC(tracers_apply) = { + params ["_unit", ["_flash", true], ["_randomModel", false]]; + + if ( !(_unit getVariable [QGVAR(tracers_initialized), false]) ) then { + private _primaryWeaon = primaryWeapon _unit; + private _supportedMags = [_primaryWeaon] call CBA_fnc_compatibleMagazines; + + private _tracerMags = []; + { + if ((getNumber (configfile >> "CfgMagazines" >> _x >> "tracersEvery")) > 0) then { + _tracerMags pushBack _x; + }; + } forEach _supportedMags; + + if (count _tracerMags > 0) then { + private _newMagazine = []; + if (_randomModel) then { + _newMagazine pushBack (_tracerMags select (random (count _tracerMags))); + } else { + { + private _curMag = getText (configfile >> "CfgMagazines" >> _x >> "model"); + private _curprimaryMag = getText (configfile >> "CfgMagazines" >> ((primaryWeaponMagazine _unit) select 0) >> "model"); + if (isNil "_curprimaryMag") then { + _curprimaryMag = ""; + }; + + if (_curMag isEqualTo _curprimaryMag) then { + _newMagazine pushBack _x; + }; + } forEach _tracerMags; + + if ((count _newMagazine) == 0) then + { + _newMagazine pushBack (_tracerMags select 0); + }; + }; + _newMagazine = _newMagazine select 0; + + private _magReplace = []; + private _magCount = 1; + { + if (_x in _supportedMags) then { + _magReplace = _magReplace + [_x]; + _magCount = _magCount + 1; + }; + } forEach magazines _unit; + + if (!isNil "_newMagazine") then { + _unit addMagazines [_newMagazine, 1]; + _unit reload [primaryWeapon _unit, _newMagazine]; + { + [_unit, _x] call CBA_fnc_removeMagazine; + } forEach _magReplace; + + _unit addMagazines [_newMagazine, _magCount]; + }; + + LOG_1("Added tracers for %1", name _unit); + _unit setVariable [QGVAR(tracers_initialized), true, true]; + }; + + if (_flash) then { + private _flashLights = []; + private _compatMods = [_primaryWeaon] call CBA_fnc_compatibleItems; + { + if (isClass(configfile >> "CfgWeapons" >> _x >> "ItemInfo" >> "FlashLight")) then { + if (getNumber(configfile >> "CfgWeapons" >> _x >> "ItemInfo" >> "FlashLight" >> "intensity") != 0) then { + _flashLights pushBack _x; + }; + }; + } forEach _compatMods; + if (count _flashLights > 0) then { + _unit addPrimaryWeaponItem (_flashLights select (random (count _flashLights))); + _unit enableGunLights "ForceOn"; + }; + }; + }; +}; + +params [["_unit", nil], ["_flash", true], ["_randomModel", false]]; + +LOG_1("tracers called with params %1", str _this); + +/* Assumed autoinit */ +if (isNil "_unit") then { + /* Check if it's enabled */ + + + ["CAManBase", "init", { + if !(GVAR(setting_tracers)) exitWith {}; + params ["_unit"]; + + if (isPlayer _unit) exitWith { }; + + if (_unit getVariable [QGVAR(tracers_disable), false]) exitWith { }; + + [{ + private _sides = call compile format ["[%1]", GVAR(setting_tracersSides)]; + + if (_this in _sides) then { + // @TODO: replace spawn + [_x, GVAR(setting_tracersFlashlight), false] spawn FUNC(tracers_apply); + }; + }, _unit, 0.4] call CBA_fnc_waitAndExecute; + }, true, [], true] call CBA_fnc_addClassEventHandler; +}; + +/* For unit */ +if (IS_OBJECT(_unit)) exitWith { + if (!isPlayer _unit) then { + [_unit, _flash, _randomModel] call FUNC(tracers_apply); + }; +}; + +/* For side */ +if (IS_SIDE(_unit)) exitWith { + // @TODO: replace spawn + [_unit, _flash, _randomModel] spawn { + params ["_unit", "_flash", "_randomModel"]; + + while { !(missionNamespace getVariable [QGVAR(tracers_disable), false]) } do { + { + if (!isPlayer _x) then { + // @TODO: replace spawn + [_x, _flash, _randomModel] spawn FUNC(tracers_apply); + sleep 0.03; + }; + } forEach units _unit; + sleep 1; + }; + }; +}; diff --git a/framework/components/gameplay/functions/script_component.hpp b/framework/components/gameplay/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/gameplay/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/gameplay/initSettings.sqf b/framework/components/gameplay/initSettings.sqf new file mode 100644 index 0000000..70700f5 --- /dev/null +++ b/framework/components/gameplay/initSettings.sqf @@ -0,0 +1,55 @@ +#include "script_component.hpp" + +[ + QGVAR(setting_flashbang), + "CHECKBOX", + ["Override Flashbangs", "Replace default flashbang effects"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_safestart), + "CHECKBOX", + ["Safestart", "Dissalow combat at start of mission"], + QUOTE(MODULE_BEAUTIFIED - Safestart), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_safestartDelay), + "TIME", + ["Safestart Delay", "Delay in seconds for safestart to be disabled"], + QUOTE(MODULE_BEAUTIFIED - Safestart), + [0, 60, 5], + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_tracers), + "CHECKBOX", + ["Tracers", "Replaces AIs ammunition with tracer munitions"], + QUOTE(MODULE_BEAUTIFIED - Tracers), + false, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_tracersFlashlight), + "CHECKBOX", + ["Flashlights", "Give AI flashlights (tracers must be enabled)"], + QUOTE(MODULE_BEAUTIFIED - Tracers), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_tracersSides), + "EDITBOX", + ["Sides", "Sides to apply function to. sepperated by comma (,)"], + QUOTE(MODULE_BEAUTIFIED - Tracers), + "east, independent", + 1 +] call EFUNC(common,addSetting); \ No newline at end of file diff --git a/framework/components/gameplay/script_component.hpp b/framework/components/gameplay/script_component.hpp index acd1c6f..284b025 100644 --- a/framework/components/gameplay/script_component.hpp +++ b/framework/components/gameplay/script_component.hpp @@ -1,5 +1,15 @@ #define MODULE gameplay +#define MODULE_BEAUTIFIED Gameplay + #define REQUIRED_ADDONS [] #define REQUIRED_MODULES ["common"] -#include "..\main\script_component.hpp" +#ifdef DEBUG_ENABLED_GAMEPLAY + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_GAMEPLAY + #define DEBUG_SETTINGS DEBUG_SETTINGS_GAMEPLAY +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/kosherAI/XEH_PREP.sqf b/framework/components/kosherAI/XEH_PREP.sqf new file mode 100644 index 0000000..491bd78 --- /dev/null +++ b/framework/components/kosherAI/XEH_PREP.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +PREP(init); +PREP(getRole); +PREP(setLoadout); diff --git a/framework/components/kosherAI/functions/fn_getRole.sqf b/framework/components/kosherAI/functions/fn_getRole.sqf new file mode 100644 index 0000000..2d03a0c --- /dev/null +++ b/framework/components/kosherAI/functions/fn_getRole.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Estimates the AI unit's role and assigns a kosher ai role. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Role + * + * Example: + * [_myUnit] call cmf_kosherAI_fnc_getRole + * + * Public: No + */ + +params["_unit"]; + +/* Function to check if unit is in a vehicle's operator position */ +private _fnc_isOperator = { + private _unit = _this; + + _unit isEqualTo (commander (vehicle _unit)) || + { _unit isEqualTo (driver (vehicle _unit)) || + { _unit isEqualTo (gunner (vehicle _unit)) }}; +}; + +/* Crewman */ +if ((vehicle _unit) isKindOf "Tank" && (_unit call _fnc_isOperator)) exitWith {_unit setVariable[QGVAR(kosherai_role), "CRW"]; "CRW"}; + +/* Rotary Pilot */ +if ((vehicle _unit) isKindOf "Helicopter" && (_unit call _fnc_isOperator)) exitWith {_unit setVariable[QGVAR(kosherai_role), "RPIL"]; "RPIL"}; + +/* Fixed Wing Pilot */ +if ((vehicle _unit) isKindOf "Plane" && (_unit call _fnc_isOperator)) exitWith {_unit setVariable[QGVAR(kosherai_role), "WPIL"]; "WPIL"}; + +/* Medic */ +if (getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "attendant") isEqualTo 1) exitWith {_unit setVariable[QGVAR(kosherai_role), "MED"]; "MED"}; + +/* Engineer */ +if (getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer") isEqualTo 1) exitWith {_unit setVariable[QGVAR(kosherai_role), "ENG"]; "ENG"}; + +/* Anti-tank */ +if ((secondaryWeapon _unit) != "") exitWith {_unit setVariable[QGVAR(kosherai_role), "AT"]; "AT"}; + +/* Machinegunner */ +if (((primaryweapon _unit) call BIS_fnc_itemtype) select 1 == "MachineGun") exitWith {_unit setVariable[QGVAR(kosherai_role), "MG"]; "MG"}; + +/* Sniper */ +if (((primaryweapon _unit) call BIS_fnc_itemtype) select 1 == "SniperRifle") exitWith {_unit setVariable[QGVAR(kosherai_role), "MAR"]; "MAR"}; + +/* Squad Leader */ +if ((leader _unit) isEqualTo _unit) exitWith {_unit setVariable[QGVAR(kosherai_role), "SL"]; "SL"}; + +/* Rifleman */ +_unit setVariable[QGVAR(kosherai_role), "RFL"]; "RFL" \ No newline at end of file diff --git a/framework/components/kosherAI/functions/fn_init.sqf b/framework/components/kosherAI/functions/fn_init.sqf new file mode 100644 index 0000000..bb8a352 --- /dev/null +++ b/framework/components/kosherAI/functions/fn_init.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" +/* + * Author: Eric + * allows using kosherArsenal files with ai units + * + * Arguments: + * 0: kosherAI config + * - side + * - file + * - Classlist [Default: []] + * - is whitelist? [Default: true] + * ... + * + * Return Value: + * None + * + * Example: + * [[east, "exampleLoadout"], [west, "exampleLoadout2", ["myFactionClass", "myUnitClass"]]] call cmf_kosherAI_fnc_init + * + * Public: Yes + */ +SCRIPT(kosherAI); + +/* Save the configs */ +missionNamespace setVariable [QGVAR(configs), _this]; + +if (!isServer) exitWith {}; + +["CAManBase", "init", { + _this spawn { + params ["_unit"]; + + if (isPlayer _unit) exitWith { }; + + if (_unit getVariable [QGVAR(disable), false]) exitWith { }; + + sleep 0.3; + + /* Check if unit is to be ignored */ + private _unitClass = typeOf _unit; + private _unitFaction = faction _unit; + { + _x params ["_side", "_loadout", ["_list", []], ["_whitelist", false]]; + + if (_whitelist) then { + if (side _unit isEqualTo _side && { (_unitClass in _list) || (_unitFaction in _list) }) exitWith { + private _role = [_unit] call FUNC(getRole); + private _whitelist = ([_role] call compile(preprocessFileLineNumbers format["rsc\loadouts\%1.sqf", _loadout])) select 1; + + /* Set the unit's loadout */ + [_unit, _role, _whitelist] spawn FUNC(setLoadout); + }; + } else { + if (side _unit isEqualTo _side && { !(_unitClass in _list) && !(_unitFaction in _list) }) exitWith { + private _role = [_unit] call FUNC(getRole); + private _whitelist = ([_role] call compile(preprocessFileLineNumbers format["rsc\loadouts\%1.sqf", _loadout])) select 1; + + /* Set the unit's loadout */ + [_unit, _role, _whitelist] spawn FUNC(setLoadout); + }; + }; + } forEach (missionNamespace getVariable [QGVAR(configs), []]); + }; +}, true, [], true] call CBA_fnc_addClassEventHandler; \ No newline at end of file diff --git a/framework/components/kosherAI/functions/fn_setLoadout.sqf b/framework/components/kosherAI/functions/fn_setLoadout.sqf new file mode 100644 index 0000000..9de7510 --- /dev/null +++ b/framework/components/kosherAI/functions/fn_setLoadout.sqf @@ -0,0 +1,120 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Set's randomized loadout on AI from loadoutfile + * + * Arguments: + * 0: Unit + * 1: Role + * 2: Whitelist + * + * Return Value: + * None + * + * Example: + * [_unit, "SL", _myLoadoutFile] call cmf_kosherAI_fnc_setLoadout + * + * Public: No + */ + +params["_unit", "_role", "_whitelist"]; + +/* Strip unit naked */ +[_unit] call EFUNC(utility,stripUnit); + +/* Randomize the loadout they get based on the available items */ +_unit addBackpack (selectRandom (_whitelist select 0)); +_unit addVest (selectRandom (_whitelist select 1)); +_unit forceAddUniform (selectRandom (_whitelist select 2)); +_unit addGoggles (selectRandom (_whitelist select 3)); +_unit addHeadgear (selectRandom (_whitelist select 4)); + +/* Add random weapons for each slot */ +private _primaries = (_whitelist select 7) select { getNumber (configFile >> "CfgWeapons" >> _x >> "type") isEqualTo 1 }; +private _secondaries = (_whitelist select 7) select { getNumber (configFile >> "CfgWeapons" >> _x >> "type") isEqualTo 4 }; +private _handguns = (_whitelist select 7) select { getNumber (configFile >> "CfgWeapons" >> _x >> "type") isEqualTo 2 }; +private _primary = selectRandom _primaries; +private _secondary = selectRandom _secondaries; +private _handgun = selectRandom _handguns; + +/* Seperate grenades from magazines */ +private _grenades = (_whitelist select 6) select { _x call BIS_fnc_isThrowable }; +private _magazines = (_whitelist select 6) select { !(_x call BIS_fnc_isThrowable) }; + +if (!isNil "_primary") then { + [_unit, _primary] remoteExec ["addWeapon", _unit]; + + if (_primary != primaryWeapon _unit) then { + [_unit, _primary] remoteExec ["addWeapon", _unit]; + WARNING("Failed to add primary weapon on unit"); + }; + + private _primaryMagazines = _magazines select { _x in (compatibleMagazines _primary) }; + for "_i" from 0 to round (random 5) do { + _unit addMagazineGlobal selectRandom _primaryMagazines; + }; +}; + +if (!isNil "_secondary") then { + [_unit, _secondary] remoteExec ["addWeapon", _unit]; + + if (_secondary != secondaryWeapon _unit) then { + [_unit, _secondary] remoteExec ["addWeapon", _unit]; + WARNING("Failed to add secondary weapon on unit"); + }; + + private _secondaryMagazines = _magazines select { _x in (compatibleMagazines _secondary) }; + for "_i" from 0 to round (random 4) do { + _unit addMagazineGlobal selectRandom _secondaryMagazines; + }; +}; + +if (!isNil "_handgun") then { + [_unit, _handgun] remoteExec ["addWeapon", _unit]; + + if (_handgun != handgunWeapon _unit) then { + [_unit, _handgun] remoteExec ["addWeapon", _unit]; + WARNING("Failed to add handgun weapon on unit"); + }; + + private _handgunMagazines = _magazines select { _x in (compatibleMagazines _handgun) }; + for "_i" from 0 to round (random 2) do { + _unit addMagazineGlobal selectRandom _handgunMagazines; + }; +}; + +/* Add random weapon attachments if they are available */ +for "_i" from 0 to 2 do { + _unit addPrimaryWeaponItem (selectRandom (_whitelist select 5)); +}; + +/* Add grenades */ +for "_i" from 0 to round (random 3) do { + _unit addMagazineGlobal selectRandom _grenades; +}; + +/* Add Explosives */ +private _compatibleMagazines = (compatibleMagazines primaryWeapon _unit) + (compatibleMagazines handgunWeapon _unit) + (compatibleMagazines secondaryWeapon _unit); +private _explosives = _magazines select { !(_x in _compatibleMagazines) }; +for "_i" from 0 to round (random 2) do { + _unit addMagazineGlobal selectRandom _explosives; +}; + +/* Add medical equipment */ +if (_role == "MED") then { + for "_i" from 0 to (random 30) do { + _unit addItem (selectRandom (_whitelist select 8)); + } +} else { + _unit addItem "Medikit"; _unit addItem "Medikit"; +}; + +/* Add basic shit */ +_unit linkItem "ItemMap"; +_unit linkItem "ItemCompass"; +_unit linkItem "ItemWatch"; + +/* Force Ai to use primary after loadout has been set */ +if (primaryweapon _unit != "") then { + _unit selectweapon primaryWeapon _unit; +}; \ No newline at end of file diff --git a/framework/components/kosherAI/functions/script_component.hpp b/framework/components/kosherAI/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/kosherAI/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/kosherAI/script_component.hpp b/framework/components/kosherAI/script_component.hpp new file mode 100644 index 0000000..bf1e1bc --- /dev/null +++ b/framework/components/kosherAI/script_component.hpp @@ -0,0 +1,15 @@ +#define MODULE kosherAI +#define MODULE_BEAUTIFIED Kosher AI + +#define REQUIRED_ADDONS ["ace_arsenal"] +#define REQUIRED_MODULES ["common"] + +#ifdef DEBUG_ENABLED_KOSHERAI + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_KOSHERAI + #define DEBUG_SETTINGS DEBUG_SETTINGS_KOSHERAI +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/kosherAI/stringtable.sqf b/framework/components/kosherAI/stringtable.sqf new file mode 100644 index 0000000..07544f3 --- /dev/null +++ b/framework/components/kosherAI/stringtable.sqf @@ -0,0 +1,15 @@ +#include "script_component.hpp" +/* + * Author: Eric + * 3den_stringtable + */ +[ + [DSTRING(rearm_ammobox), [ + ["English", "Rearm at arsenal"], + ["Spanish", "Rearmar en el arsenal"] + ]], + [DSTRING(required_primary), [ + ["English", "You are required to have a primary firearm"], + ["Spanish", "Es obligatorio que tengas un arma de fuego principal"] + ]] +] diff --git a/framework/components/kosherArsenal/XEH_3denInit.sqf b/framework/components/kosherArsenal/XEH_3denInit.sqf new file mode 100644 index 0000000..44ff7e1 --- /dev/null +++ b/framework/components/kosherArsenal/XEH_3denInit.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" + +waitUntil { !isNil { missionNameSpace getVariable QEGVAR(3den,menu_entity) } }; + +private _path = missionNameSpace getVariable QEGVAR(3den,menu_entity); + +private _ammoBoxAction = [ + LSTRING(3den_ammobox_displayName), + "a3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa", + { + if (count get3DENSelected "object" == 0) exitWith { + ["No Objects selected", 0, 1] call BIS_fnc_3DENNotification; + }; + + private _command = toString {[this] call FUNC(ammobox)}; + { + if !([_x, _command] call EFUNC(3den,inInit)) then { + [_x, _command] call EFUNC(3den,addToInit); + } else { + [_x, _command] call EFUNC(3den,removeFromInit); + }; + } forEach get3DENSelected "object"; + + ["Toggled selected objects as kosher arsenal ammoboxes", 0, 1] call BIS_fnc_3DENNotification; + } +]; + +[ + _path, + "Kosher Arsenal", + "a3\3den\data\displays\display3den\toolbar\open_ca.paa", + {}, + [], + [ + _ammoBoxAction + ] +] call EFUNC(3den,addMenuItem); \ No newline at end of file diff --git a/framework/components/kosherArsenal/XEH_PREP.sqf b/framework/components/kosherArsenal/XEH_PREP.sqf index db5c546..d8c1b30 100644 --- a/framework/components/kosherArsenal/XEH_PREP.sqf +++ b/framework/components/kosherArsenal/XEH_PREP.sqf @@ -2,5 +2,5 @@ PREP(init); PREP(ammobox); -PREP(forceArsenal); -PREP(kosherAI); +PREP(forceClose); +PREP(forceArsenal); \ No newline at end of file diff --git a/framework/components/kosherArsenal/fn_ammobox.sqf b/framework/components/kosherArsenal/fn_ammobox.sqf deleted file mode 100644 index c9ca856..0000000 --- a/framework/components/kosherArsenal/fn_ammobox.sqf +++ /dev/null @@ -1,104 +0,0 @@ -#include "script_component.hpp" -#include "\z\ace\addons\arsenal\defines.hpp" -/* - * Author: Eric - * initializes an object as a ammobox - * - * Arguments: - * 0: object - * - * Return Value: - * Success - * - * Example: - * [this] call cmf_kosherArsenal_fnc_ammobox - * - * Public: Yes - */ -SCRIPT(ammobox); - -params ["_object"]; - -/* Check if ammobox already initialized on object */ -if (_object getVariable [QGVAR(ammobox_initialized), false]) exitWith { false }; - -/* ammobox function */ -private _onOpen = { - /* Create the arsenal object and initialize ace arsenal on it */ - private _arsenal = "HeliHEmpty" createVehicleLocal [0,0,0]; - [_arsenal, []] call ace_arsenal_fnc_initBox; - - /* Get player's role and loadout */ - private _role = player getVariable [QEGVAR(common,role), "RFL"]; - private _loadout = player getVariable [QGVAR(loadout), ""]; - - /* Check if the file exists and load the whitelist */ - if !(FILE_EXISTS(_loadout)) exitWith { ERROR_1("Loadoutfile %1 does not exist!",_loadout) }; - private _whitelist = [_role, player, true] call compile(preprocessFileLineNumbers _loadout); - - /* Get gear from whitelist and check loadout file version */ - private _permittedGear = []; - if (isNil "_whitelist") then { - /* Backwards compatability with old loadoutfiles */ - _permittedGear = player getVariable ["EMF_KA_permittedGear", 0]; - } else { - _permittedGear = (_whitelist select 1); - }; - - /* Add the allowed gear to the arsenal */ - { - [_arsenal, _x] call ace_arsenal_fnc_addVirtualItems; - } forEach _permittedGear; - - /* Open the arsenal */ - [_arsenal, player, false] call ace_arsenal_fnc_openBox; - - waitUntil{!isNull findDisplay IDD_ace_arsenal}; - [findDisplay IDD_ace_arsenal, (findDisplay IDD_ace_arsenal) displayCtrl IDC_buttonUniform] call ace_arsenal_fnc_fillLeftPanel; - - /* Hide unwanted parts of the arsenal for ammobox */ - private _hideUI = [] spawn { - while { true } do { - if (isNil "ace_arsenal_currentLeftPanel") exitWith {}; - { - if ( (ace_arsenal_currentLeftPanel isEqualTo IDC_buttonSecondaryWeapon) && (_x in [IDC_blockLeftFrame, IDC_blockLeftBackground, IDC_leftTabContent, IDC_sortLeftTab, IDC_leftSearchbar, IDC_leftSearchbarButton]) ) then { - ((findDisplay IDD_ace_arsenal) displayCtrl _x) ctrlShow true; - } else { - ((findDisplay IDD_ace_arsenal) displayCtrl _x) ctrlShow false; - } - } forEach [ - IDC_blockLeftFrame, IDC_blockLeftBackground, IDC_leftTabContent, IDC_sortLeftTab, IDC_leftSearchbar, IDC_leftSearchbarButton, IDC_iconBackgroundPrimaryWeapon, IDC_buttonPrimaryWeapon, - IDC_iconBackgroundHandgun, IDC_buttonHandgun, IDC_iconBackgroundHeadgear, IDC_buttonHeadgear, IDC_iconBackgroundGoggles, IDC_buttonGoggles, - IDC_iconBackgroundNVG, IDC_buttonNVG, IDC_iconBackgroundBinoculars, IDC_buttonBinoculars, IDC_iconBackgroundMap, IDC_buttonMap, IDC_iconBackgroundGPS, IDC_buttonGPS, IDC_iconBackgroundRadio, IDC_buttonRadio, - IDC_iconBackgroundCompass, IDC_buttonCompass, IDC_iconBackgroundWatch, IDC_buttonWatch, IDC_iconBackgroundFace, IDC_buttonFace, IDC_iconBackgroundVoice, IDC_buttonVoice, IDC_iconBackgroundInsigna, IDC_buttonInsignia, - /*IDC_buttonLoadouts,*/ IDC_buttonExport, IDC_buttonImport]; - sleep 0.1; - }; - }; - - /* Hide unwanted parts of the arsenal loadout display */ - private _hideUI = [] spawn { - while { true } do { - ((findDisplay IDD_loadouts_display ) displayCtrl IDC_buttonLoad ) ctrlShow false; - sleep 0.1; - }; - }; - - /* When the arsenal is closed terminate the hiding script and delete the arsenal object */ - ["ace_arsenal_displayClosed", { - terminate (_thisArgs select 0); - deleteVehicle (_thisArgs select 1); - - /* Raise event */ - [QGVAR(onAmmoboxClose), []] call CBA_fnc_localEvent; - }, [_hideUI, _arsenal]] call CBA_fnc_addEventHandlerArgs; - - /* Raise event */ - [QGVAR(onAmmoboxOpen), []] call CBA_fnc_localEvent; -}; - -/* Add addAction to open arsenal */ -[_object, [LSTRING(rearm_ammobox), _onOpen, [], 6, true, false,"", "_this getVariable ['"+QGVAR(loadout)+"', ''] != ''"]] remoteExec ["addAction", 0, true]; -_object setVariable [QGVAR(ammobox_initialized), true, true]; - -true; diff --git a/framework/components/kosherArsenal/fn_kosherAI.sqf b/framework/components/kosherArsenal/fn_kosherAI.sqf deleted file mode 100644 index 3242d84..0000000 --- a/framework/components/kosherArsenal/fn_kosherAI.sqf +++ /dev/null @@ -1,172 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * allows using kosherArsenal files with ai units - * - * Arguments: - * 0: side - * 1: file - * - * Return Value: - * None - * - * Example: - * [east, "exampleLoadout"] call cmf_kosherArsenal_fnc_kosherAI - * - * Public: Yes - */ -SCRIPT(kosherAI); - -params ["_side", "_loadoutFile"]; - -if (!isServer) exitWith {}; - -/* Function to set an ai unit's role */ -private _fnc_aiType = { - params["_unit"]; - /* Squad Leader */ - if ((leader _unit) isEqualTo _unit) exitWith {_unit setVariable[QGVAR(kosherai_role), "SL"]; "SL"}; - - /* Medic */ - if (getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "attendant") isEqualTo 1) exitWith {_unit setVariable[QGVAR(kosherai_role), "MED"]; "MED"}; - - /* Engineer */ - if (getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer") isEqualTo 1) exitWith {_unit setVariable[QGVAR(kosherai_role), "ENG"]; "ENG"}; - - /* Anti-tank */ - if ((secondaryWeapon _unit) != "") exitWith {_unit setVariable[QGVAR(kosherai_role), "AT"]; "AT"}; - - /* Machinegunner */ - if (((primaryweapon _unit) call BIS_fnc_itemtype) select 1 == "MachineGun") exitWith {_unit setVariable[QGVAR(kosherai_role), "MG"]; "MG"}; - - /* Sniper */ - if (((primaryweapon _unit) call BIS_fnc_itemtype) select 1 == "SniperRifle") exitWith {_unit setVariable[QGVAR(kosherai_role), "MAR"]; "MAR"}; - - /* Rifleman */ - _unit setVariable[QGVAR(kosherai_role), "RFL"]; "RFL" -}; - -/* Function to set a units loadout */ -private _fnc_setLoadout = { - params["_unit", "_role", "_whitelist"]; - - /* Strip unit naked */ - [_unit] call EFUNC(utility,stripUnit); - - /* Randomize the loadout they get based on the available items */ - _unit addBackpack (selectRandom (_whitelist select 0)); - _unit addVest (selectRandom (_whitelist select 1)); - _unit forceAddUniform (selectRandom (_whitelist select 2)); - _unit addGoggles (selectRandom (_whitelist select 3)); - _unit addHeadgear (selectRandom (_whitelist select 4)); - - /* Add random weapons for each slot */ - private _primaries = (_whitelist select 7) select { getNumber (configFile >> "CfgWeapons" >> _x >> "type") isEqualTo 1 }; - private _secondaries = (_whitelist select 7) select { getNumber (configFile >> "CfgWeapons" >> _x >> "type") isEqualTo 4 }; - private _handguns = (_whitelist select 7) select { getNumber (configFile >> "CfgWeapons" >> _x >> "type") isEqualTo 2 }; - private _primary = selectRandom _primaries; - private _secondary = selectRandom _secondaries; - private _handgun = selectRandom _handguns; - - /* Seperate grenades from magazines */ - private _grenades = (_whitelist select 6) select { _x call BIS_fnc_isThrowable }; - private _magazines = (_whitelist select 6) select { !(_x call BIS_fnc_isThrowable) }; - - if (!isNil "_primary") then { - [_unit, _primary] remoteExec ["addWeapon", _unit]; - - if (_primary != primaryWeapon _unit) then { - [_unit, _primary] remoteExec ["addWeapon", _unit]; - WARNING("Failed to add primary weapon on unit"); - }; - - private _primaryMagazines = _magazines select { _x in (compatibleMagazines _primary) }; - for "_i" from 0 to round (random 5) do { - _unit addMagazineGlobal selectRandom _primaryMagazines; - }; - }; - - if (!isNil "_secondary") then { - [_unit, _secondary] remoteExec ["addWeapon", _unit]; - - if (_secondary != secondaryWeapon _unit) then { - [_unit, _secondary] remoteExec ["addWeapon", _unit]; - WARNING("Failed to add secondary weapon on unit"); - }; - - private _secondaryMagazines = _magazines select { _x in (compatibleMagazines _secondary) }; - for "_i" from 0 to round (random 4) do { - _unit addMagazineGlobal selectRandom _secondaryMagazines; - }; - }; - - if (!isNil "_handgun") then { - [_unit, _handgun] remoteExec ["addWeapon", _unit]; - - if (_handgun != handgunWeapon _unit) then { - [_unit, _handgun] remoteExec ["addWeapon", _unit]; - WARNING("Failed to add handgun weapon on unit"); - }; - - private _handgunMagazines = _magazines select { _x in (compatibleMagazines _handgun) }; - for "_i" from 0 to round (random 2) do { - _unit addMagazineGlobal selectRandom _handgunMagazines; - }; - }; - - /* Add random weapon attachments if they are available */ - for "_i" from 0 to 2 do { - _unit addPrimaryWeaponItem (selectRandom (_whitelist select 5)); - }; - - /* Add grenades */ - for "_i" from 0 to round (random 3) do { - _unit addMagazineGlobal selectRandom _grenades; - }; - - /* Add Explosives */ - private _compatibleMagazines = (compatibleMagazines primaryWeapon _unit) + (compatibleMagazines handgunWeapon _unit) + (compatibleMagazines secondaryWeapon _unit); - private _explosives = _magazines select { !(_x in _compatibleMagazines) }; - for "_i" from 0 to round (random 2) do { - _unit addMagazineGlobal selectRandom _explosives; - }; - - /* Add medical equipment */ - if (_role == "MED") then { - for "_i" from 0 to (random 30) do { - _unit addItem (selectRandom (_whitelist select 8)); - } - } else { - _unit addItem "Medikit"; _unit addItem "Medikit"; - }; - - /* Add basic shit */ - _unit linkItem "ItemMap"; - _unit linkItem "ItemCompass"; - _unit linkItem "ItemWatch"; -}; - -/* loop over all units and add to non-initialized units */ -[_side, _loadoutFile, _fnc_aiType, _fnc_setLoadout] spawn { - params ["_side", "_loadoutFile", "_fnc_aiType", "_fnc_setLoadout"]; - while { missionNamespace getVariable [QGVAR(kosherai_disable), true] } do { - { - if (side _x isEqualTo _side && !isPlayer _x && !(_x getVariable [QGVAR(kosherai_initialized), false])) then { - /* Get unit's role */ - private _role = [_x] call _fnc_aiType; - - /* Get the loadout file */ - private _whitelist = ([_role] call compile(preprocessFileLineNumbers format["rsc\loadouts\%1.sqf", _loadoutFile])) select 1; - - /* Set the unit's loadout */ - [_x, _role, _whitelist] spawn _fnc_setLoadout; - _x setVariable [QGVAR(kosherai_initialized), true]; - - /* Raise event */ - [QGVAR(kosherai_onEnabled), [_x, _role]] call CBA_fnc_globalEvent; - }; - sleep 0.03; - } forEach allUnits; - sleep 1; - }; -}; diff --git a/framework/components/kosherArsenal/functions/fn_ammobox.sqf b/framework/components/kosherArsenal/functions/fn_ammobox.sqf new file mode 100644 index 0000000..85842b9 --- /dev/null +++ b/framework/components/kosherArsenal/functions/fn_ammobox.sqf @@ -0,0 +1,112 @@ +#include "script_component.hpp" +#include "\z\ace\addons\arsenal\defines.hpp" +/* + * Author: Eric + * initializes an object as a ammobox + * + * Arguments: + * 0: object + * + * Return Value: + * Success + * + * Example: + * [this] call cmf_kosherArsenal_fnc_ammobox + * + * Public: Yes + */ +SCRIPT(ammobox); + +params ["_object"]; + +/* Check if ammobox already initialized on object */ +if (_object getVariable [QGVAR(ammobox_initialized), false]) exitWith { false }; + +/* ammobox function */ +private _onOpen = { + // @TODO: replace spawn + _this spawn { + /* Create the arsenal object and initialize ace arsenal on it */ + private _arsenal = "HeliHEmpty" createVehicleLocal [0,0,0]; + [_arsenal, []] call ace_arsenal_fnc_initBox; + + /* Get player's role and loadout */ + private _role = player getVariable [QEGVAR(organization,role), "RFL"]; + private _loadout = player getVariable [QGVAR(loadout), ""]; + + /* Check if the file exists and load the whitelist */ + if !(FILE_EXISTS(_loadout)) exitWith { ERROR_1("Loadoutfile %1 does not exist!",_loadout) }; + private _whitelist = [_role, player, true] call compile(preprocessFileLineNumbers _loadout); + + /* Get gear from whitelist and check loadout file version */ + private _permittedGear = []; + if (isNil "_whitelist") then { + /* Backwards compatability with old loadoutfiles */ + _permittedGear = player getVariable ["EMF_KA_permittedGear", 0]; + } else { + _permittedGear = (_whitelist select 1); + }; + + /* Add the allowed gear to the arsenal */ + { + [_arsenal, _x] call ace_arsenal_fnc_addVirtualItems; + } forEach _permittedGear; + + /* Open the arsenal */ + [_arsenal, player, false] call ace_arsenal_fnc_openBox; + + waitUntil{!isNull findDisplay IDD_ace_arsenal}; + [findDisplay IDD_ace_arsenal, (findDisplay IDD_ace_arsenal) displayCtrl IDC_buttonUniform] call ace_arsenal_fnc_fillLeftPanel; + + /* Hide unwanted parts of the arsenal for ammobox */ + private _hideUI = [] spawn { + while { true } do { + if (isNil "ace_arsenal_currentLeftPanel") exitWith {}; + { + if ( (ace_arsenal_currentLeftPanel isEqualTo IDC_buttonSecondaryWeapon) && (_x in [IDC_blockLeftFrame, IDC_blockLeftBackground, IDC_leftTabContent, IDC_sortLeftTab, IDC_leftSearchbar, IDC_leftSearchbarButton]) ) then { + ((findDisplay IDD_ace_arsenal) displayCtrl _x) ctrlShow true; + } else { + ((findDisplay IDD_ace_arsenal) displayCtrl _x) ctrlShow false; + } + } forEach [ + IDC_blockLeftFrame, IDC_blockLeftBackground, IDC_leftTabContent, IDC_sortLeftTab, IDC_leftSearchbar, IDC_leftSearchbarButton, IDC_iconBackgroundPrimaryWeapon, IDC_buttonPrimaryWeapon, + IDC_iconBackgroundHandgun, IDC_buttonHandgun, IDC_iconBackgroundHeadgear, IDC_buttonHeadgear, IDC_iconBackgroundGoggles, IDC_buttonGoggles, + IDC_iconBackgroundNVG, IDC_buttonNVG, IDC_iconBackgroundBinoculars, IDC_buttonBinoculars, IDC_iconBackgroundMap, IDC_buttonMap, IDC_iconBackgroundGPS, IDC_buttonGPS, IDC_iconBackgroundRadio, IDC_buttonRadio, + IDC_iconBackgroundCompass, IDC_buttonCompass, IDC_iconBackgroundWatch, IDC_buttonWatch, IDC_iconBackgroundFace, IDC_buttonFace, IDC_iconBackgroundVoice, IDC_buttonVoice, IDC_iconBackgroundInsigna, IDC_buttonInsignia, + /*IDC_buttonLoadouts,*/ IDC_buttonExport, IDC_buttonImport]; + sleep 0.1; + }; + }; + + /* Hide unwanted parts of the arsenal loadout display */ + private _hideUI = [] spawn { + while { true } do { + ((findDisplay IDD_loadouts_display ) displayCtrl IDC_buttonLoad ) ctrlShow false; + sleep 0.1; + }; + }; + + /* When the arsenal is closed terminate the hiding script and delete the arsenal object */ + ["ace_arsenal_displayClosed", { + terminate (_thisArgs select 0); + deleteVehicle (_thisArgs select 1); + + /* Raise event */ + [QGVAR(onAmmoboxClose), []] call CBA_fnc_localEvent; + }, [_hideUI, _arsenal]] call CBA_fnc_addEventHandlerArgs; + + /* Raise event */ + [QGVAR(onAmmoboxOpen), []] call CBA_fnc_localEvent; + }; +}; + +/* Add addAction to open arsenal */ +[_object, [LSTRING(rearm_ammobox), _onOpen, [], 6, true, false,"", "(_this getVariable ['"+QGVAR(loadout)+"', ''] != '') && ((_this distance _target) < 5)"]] remoteExec ["addAction", 0, true]; + +/* Add ACE Interaction to open arsenal */ +private _action = [QGVAR(rearm), LSTRING(rearm_ammobox), "", _onOpen, { _player getVariable [QGVAR(loadout), ''] != '' }] call ace_interact_menu_fnc_createAction; +[_object, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToObject; + +_object setVariable [QGVAR(ammobox_initialized), true, true]; + +true; diff --git a/framework/components/kosherArsenal/fn_forceArsenal.sqf b/framework/components/kosherArsenal/functions/fn_forceArsenal.sqf similarity index 90% rename from framework/components/kosherArsenal/fn_forceArsenal.sqf rename to framework/components/kosherArsenal/functions/fn_forceArsenal.sqf index 7912cd3..2c3831d 100644 --- a/framework/components/kosherArsenal/fn_forceArsenal.sqf +++ b/framework/components/kosherArsenal/functions/fn_forceArsenal.sqf @@ -24,7 +24,7 @@ params ["_unit", ["_forcePrimary", true]]; { /* Get unit loadout */ private _loadout = player getVariable [QGVAR(loadout), ""]; - private _role = player getVariable [QEGVAR(common,role), "RFL"]; + private _role = player getVariable [QEGVAR(organization,role), "RFL"]; /* Create arsenal object and initilize ace arsenal */ private _arsenal = "HeliHEmpty" createVehicleLocal [0,0,0]; @@ -38,9 +38,9 @@ params ["_unit", ["_forcePrimary", true]]; private _permittedGear = []; if (isNil "_whitelist") then { /* Backwards compatability with old loadoutfiles */ - _permittedGear = player getVariable ["EMF_KA_permittedGear", 0]; + _permittedGear = player getVariable ["EMF_KA_permittedGear", 0]; } else { - _permittedGear = (_whitelist select 1); + _permittedGear = (_whitelist select 1); }; /* Add the allowed gear to the arsenal */ @@ -84,12 +84,12 @@ params ["_unit", ["_forcePrimary", true]]; player setVariable [QGVAR(close), false, true]; /* Raise event */ - [QGVAR(onClose), [(player getVariable [QGVAR(close), false])]] call CBA_fnc_localEvent; + [QGVAR(onClose), [(player getVariable [QGVAR(close), false])]] call CBA_fnc_localEvent; }; /* Add closed eventhandler */ ["ace_arsenal_displayClosed", _onClose, [_forcePrimary, _arsenal]] call CBA_fnc_addEventHandlerArgs; /* Raise event */ - [QGVAR(onOpen), [true]] call CBA_fnc_localEvent; + [QGVAR(onOpen), [true]] call CBA_fnc_localEvent; } remoteExec ["call", _unit, true]; diff --git a/framework/components/kosherArsenal/fn_forceClose.sqf b/framework/components/kosherArsenal/functions/fn_forceClose.sqf similarity index 100% rename from framework/components/kosherArsenal/fn_forceClose.sqf rename to framework/components/kosherArsenal/functions/fn_forceClose.sqf diff --git a/framework/components/kosherArsenal/fn_init.sqf b/framework/components/kosherArsenal/functions/fn_init.sqf similarity index 85% rename from framework/components/kosherArsenal/fn_init.sqf rename to framework/components/kosherArsenal/functions/fn_init.sqf index 5cad6fa..4f64015 100644 --- a/framework/components/kosherArsenal/fn_init.sqf +++ b/framework/components/kosherArsenal/functions/fn_init.sqf @@ -20,15 +20,15 @@ */ SCRIPT(init); -_this spawn { - params[["_loadouts", nil, [[]]], ["_light", false], ["_forcePrimary", true], ["_randomPos", false]]; +// @TODO: replace spawn +_this spawn { // @BUG: Sometimes fails to init for players (?) + params[["_loadouts", nil, [[]]], ["_light", false], ["_forcePrimary", false], ["_randomPos", false]]; if (!hasInterface) exitWith {}; if (isNil "_loadouts") exitWith { ERROR_MSG("No loadoutfiles defined"); }; /* Wait until player spawns in */ - waitUntil {!alive Player}; - waitUntil {alive Player}; + waitUntil { player getVariable [QEGVAR(main,player_loaded), false] && alive player }; sleep 0.1; /* Randomize player spawn position if enabled */ @@ -37,8 +37,8 @@ _this spawn { }; /* Get the unit's loadout */ - private _team = player getVariable [QEGVAR(common,team), 0]; - private _role = player getVariable [QEGVAR(common,role), "RFL"]; + private _team = player getVariable [QEGVAR(organization,team), 0]; + private _role = player getVariable [QEGVAR(organization,role), "RFL"]; if (((count _loadouts) - 1) < _team) then { _team = (count _loadouts) - 1; }; @@ -51,6 +51,13 @@ _this spawn { if !(FILE_EXISTS(_loadout)) exitWith { ERROR_MSG_1("Unable to find loadoutfile: %1", _loadout); }; player setVariable [QGVAR(loadout), _loadout, true]; + /* If player is Re-Jip in same role exit */ + private _reJip = false; + private _disconUnits = missionNameSpace getVariable [QEGVAR(main,disconUnits), createHashMap]; + if (!isNil { _disconUnits get (getPlayerUID player) }) then { _reJip = true; }; + + if (_reJip && ( EGVAR(gameplay,setting_safestart) && missionNamespace getVariable [QEGVAR(gameplay,safestart_disable), false] )) exitWith { }; + /* Create the arsenal object and initialize ace arsenal */ private _arsenal = "HeliHEmpty" createVehicleLocal [0,0,0]; [_arsenal, []] call ace_arsenal_fnc_initBox; @@ -62,7 +69,7 @@ _this spawn { private _permittedGear = []; if (isNil "_whitelist") then { /* Backwards compatability with old loadoutfiles */ - _permittedGear = player getVariable ["EMF_KA_permittedGear", 0]; + _permittedGear = player getVariable ["EMF_KA_permittedGear", 0]; /* remove arsenal added by old loadout format */ { @@ -71,7 +78,7 @@ _this spawn { } } forEach (actionIDs player) } else { - _permittedGear = (_whitelist select 1); + _permittedGear = (_whitelist select 1); /* Strip the unit */ [player] call EFUNC(utility,stripUnit); @@ -106,6 +113,7 @@ _this spawn { [_arsenal, player, false] call ace_arsenal_fnc_openBox; /* add the force close button and disable voices and insignias */ + // @TODO: replace spawn [] spawn { waitUntil{!isNull (findDisplay IDD_ace_arsenal)}; ((findDisplay IDD_ace_arsenal) displayCtrl IDC_buttonImport) ctrlShow false; @@ -127,9 +135,11 @@ _this spawn { /* if force primary is enabled and the player doesn't have a primary selected kick him back into the arsenal */ if (_forcedprimary && (primaryWeapon player == "") && !(player getVariable [QGVAR(close), false])) exitWith { [""+LSTRING(required_primary)+"", -1, -1, 5, 1, 0, 9459] spawn bis_fnc_dynamicText; + // @TODO: replace spawn _arsenal spawn { sleep 0.1; [_this, player, false] call ace_arsenal_fnc_openBox; + // @TODO: replace spawn [] spawn { waitUntil{!isNull (findDisplay IDD_ace_arsenal)}; ((findDisplay IDD_ace_arsenal) displayCtrl IDC_buttonImport) ctrlShow false; @@ -155,6 +165,7 @@ _this spawn { }; /* Handle force closing the arsenal */ + // @TODO: replace spawn [] spawn { waitUntil{(player getVariable [QGVAR(close), false])}; (findDisplay IDD_ace_arsenal) closeDisplay 1; diff --git a/framework/components/kosherArsenal/functions/script_component.hpp b/framework/components/kosherArsenal/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/kosherArsenal/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/kosherArsenal/script_component.hpp b/framework/components/kosherArsenal/script_component.hpp index 0efd8ff..491589c 100644 --- a/framework/components/kosherArsenal/script_component.hpp +++ b/framework/components/kosherArsenal/script_component.hpp @@ -1,5 +1,15 @@ #define MODULE kosherArsenal +#define MODULE_BEAUTIFIED Kosher Arsenal + #define REQUIRED_ADDONS ["ace_arsenal"] #define REQUIRED_MODULES ["common"] -#include "..\main\script_component.hpp" +#ifdef DEBUG_ENABLED_KOSHERARSENAL + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_KOSHERARSENAL + #define DEBUG_SETTINGS DEBUG_SETTINGS_KOSHERARSENAL +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/kosherArsenal/stringtable.sqf b/framework/components/kosherArsenal/stringtable.sqf index 07544f3..3cfa9f5 100644 --- a/framework/components/kosherArsenal/stringtable.sqf +++ b/framework/components/kosherArsenal/stringtable.sqf @@ -11,5 +11,9 @@ [DSTRING(required_primary), [ ["English", "You are required to have a primary firearm"], ["Spanish", "Es obligatorio que tengas un arma de fuego principal"] + ]], + [DSTRING(3den_ammobox_displayName), [ + ["English", "Toggle kosherArsenal Ammobox"], + ["Spanish", "Crear Caja de munición KosherArsenal"] ]] ] diff --git a/framework/components/kosherGarage/fn_init.sqf b/framework/components/kosherGarage/fn_init.sqf deleted file mode 100644 index 5074fd8..0000000 --- a/framework/components/kosherGarage/fn_init.sqf +++ /dev/null @@ -1,307 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Makes the arma garage function multiplayer compatible. - * - * Arguments: - * 0: AddAction Object - * 1: Garage Object - * 2: Garage Direction [Default: 0] - * 3: WhitelistID [Default: "ALL"] - * 4: Clear range [Default: 8] - * - * Return Value: - * None - * - * Example: - * [this, _myGarageObject, 75, "myLoadoutID", 5] call cmf_kosherGarage_fnc_init - * - * Public: Yes - */ -SCRIPT(init); -if (!isServer) exitWith {}; - -_this spawn { - params["_actionObject"]; - - /* Get all available pylon weapons */ - if (isNil QGVAR(pylonWeapons)) then { - call FUNC(getAllPylonWeapons); - }; - - /* Create an addAction */ - [_actionObject, [LSTRING(open_garage), { - (_this select 3) params["_actionObject", "_garageObject", ["_garageDirection", 0], ["_whitelist", nil], ["_clearRange", 8]]; - - /* Create events to check if garage is open */ - [missionNamespace, "garageOpened", { - missionNamespace setVariable [QGVAR(open), true]; - uiNamespace setVariable [QGVAR(display), (_this select 0)]; - private _display = (_this select 0); - - /* Make player temporarily invincible, if they are kileld while in the garage the game breaks */ - player allowDamage false; - - /* Handle whitelists */ - private _spawnHandle = _display spawn { - - /* Remove vehicles, camos and components that aren't whitelisted */ - _this spawn { - private _display = _this; - private _data = missionnamespace getvariable "bis_fnc_garage_data"; - private _whitelist = missionNameSpace getVariable [QGVAR(whitelist), nil]; - if (isNil "_whitelist") exitWith {}; - - //////////////////////////// Whitelist vehicles ///////////////////////////// - { - /* Get the list control for the current vehicle type */ - private _ctrlList = _display displayctrl (960 + _forEachIndex); - private _idc = _forEachIndex; - waitUntil{ lbSize _ctrlList > 0 }; - - private _allItems = lbSize _ctrlList; - - - private _indexOffset = 0; - - /* If the all is in the whitelist whitelist all vehicles from that class */ - if !( - ((_idc == 0) && "allCars" in (_whitelist select 1)) || - ((_idc == 1) && "allArmor" in (_whitelist select 1)) || - ((_idc == 2) && "allHelis" in (_whitelist select 1)) || - ((_idc == 3) && "allPlanes" in (_whitelist select 1)) || - ((_idc == 4) && "allNaval" in (_whitelist select 1)) || - ((_idc == 5) && "allTurrets" in (_whitelist select 1)) - ) then { - for "_i" from 0 to _allItems - 1 do { - private _index = 0 + _indexOffset; - private _configs = (_data select _idc) select (_ctrlList lbValue _index) + 1; - - /* loop over all configs for this vehicle */ - { - private _config = [str _x] call BIS_fnc_configPath; - private _configName = _config select ((count _config) - 1); - if !(_configName in (_whitelist select 1)) exitWith { - _ctrlList lbDelete _index; - }; - _indexOffset = _indexOffset + 1; - } forEach _configs; - }; - } else { - _indexOffset = 1; - }; - - { - (_display displayCtrl _x) ctrlShow (_indexOffset > 0); - (_display displayCtrl _x) ctrlEnable (_indexOffset > 0); - } forEach [(930 + _idc), (860 + _idc), (960 + _idc), (900 + _idc)]; - } forEach _data; - - //////////////////////////// Whitelist right ///////////////////////////// - while {true} do { - /* Whitelist camos/textures */ - private _ctrlList = _display displayctrl 980; - if (lbSize _ctrlList > 0) then { - private _allItems = lbSize _ctrlList; - private _indexOffset = 0; - - for "_i" from 0 to _allItems - 1 do { - private _index = 0 + _indexOffset; - - private _configName = _ctrlList lbData _index; - if (!(_configName in (_whitelist select 4)) && ((_whitelist select 4) select 0) != "ALL") then { - _ctrlList lbDelete _index; - } else { - _indexOffset = _indexOffset + 1; - }; - }; - }; - - /* Whitelist components */ - private _ctrlList = _display displayctrl 979; - if (lbSize _ctrlList > 0) then { - private _allItems = lbSize _ctrlList; - private _indexOffset = 0; - - for "_i" from 0 to _allItems - 1 do { - private _index = 0 + _indexOffset; - - private _configName = _ctrlList lbData _index; - if (!(_configName in (_whitelist select 5)) && ((_whitelist select 5) select 0) != "ALL") then { - _ctrlList lbDelete _index; - } else { - _indexOffset = _indexOffset + 1; - }; - }; - }; - - sleep 0.1; - }; - }; - - /* Add a custom interface for selecting pylons */ - _this call FUNC(garageInterface); - - /* Remove the crew selection tab */ - while{ true } do { - { - (_this displayCtrl _x) ctrlShow false; - (_this displayCtrl _x) ctrlEnable false; - } forEach [918, 978, 878, 948]; - - sleep 0.01; - }; - }; - - /* Remove this eventHandler when the garage is closed */ - _thisScriptedEventHandler spawn { - waitUntil{ !(missionNamespace getVariable [QGVAR(open), true]) }; - [missionNamespace, "garageOpened", _this] call BIS_fnc_removeScriptedEventHandler; - }; - - /* Raise event */ - [QGVAR(onOpen), [_display]] call CBA_fnc_localEvent; - - private _handles = missionNameSpace getVariable [QGVAR(spawns), []]; - _handles pushBack _spawnHandle; - missionNameSpace setVariable [QGVAR(spawns), _handles]; - }] call BIS_fnc_addScriptedEventHandler; - - /* Create event to check if the garage is closed */ - [missionNamespace, "garageClosed", { - missionNamespace setVariable [QGVAR(open), false]; - uiNamespace setVariable [QGVAR(display), displayNull]; - - /* Make player take damage again */ - player allowDamage true; - - /* Stop the custom interface event handler */ - [QGVAR(FrameEvent), "onEachFrame"] call BIS_fnc_removeStackedEventHandler; - - /* Delete all custom controls */ - { - ctrlDelete (_x select 0); - } forEach GVAR(loadout_controls); - GVAR(loadout_controls) = []; - - /* Cleanup any remaining script handles */ - private _handles = missionNameSpace getVariable [QGVAR(spawns), []]; - { - terminate _x; - } forEach _handles; - - /* Get the selected vehicle */ - private _veh = missionNameSpace getVariable "BIS_fnc_garage_center"; - - /* Respawn it as a global vehicle */ - private _spawnHandle = _veh spawn FUNC(syncVehicle); - - /* pushback the script handle incase it fails so it can be terminated manually later */ - private _handles = missionNameSpace getVariable [QGVAR(spawns), []]; - _handles pushBack _spawnHandle; - missionNameSpace setVariable [QGVAR(spawns), _handles]; - - /* Remove this event handler */ - [missionNamespace, "garageClosed", _thisScriptedEventHandler] call BIS_fnc_removeScriptedEventHandler; - - /* Raise event */ - [QGVAR(onClose), []] call CBA_fnc_localEvent; - }] call BIS_fnc_addScriptedEventHandler; - - /* Set the direction and position of newly selected vehicles */ - [_garageDirection, (getPos _garageObject)] spawn { - params["_garageDirection", "_garagePosition"]; - private _veh = objNull; - waitUntil{missionNamespace getVariable [QGVAR(open), false]}; - while { missionNamespace getVariable [QGVAR(open), false] } do { - /* wait until a new vehicle is selected */ - waitUntil{ - if (isNil { (missionNamespace getVariable "BIS_fnc_arsenal_center") }) exitWith { true }; - (typeof (missionNamespace getVariable "BIS_fnc_arsenal_center")) != (typeof _veh) - }; - - /* Get the newly selected vehicle */ - _veh = (missionNamespace getVariable "BIS_fnc_arsenal_center"); - if (isNil "_veh") exitWith {}; - - /* Set the position and direction */ - _veh setPos _garagePosition; - _veh setDir _garageDirection; - - /* Raise event */ - [QGVAR(onSelect), [_veh]] call CBA_fnc_localEvent; - }; - }; - - - /* Parse the whitelist */ - if (!isNil "_whitelist") then { - private _whitelistsArray = missionNamespace getVariable [QGVAR(whitelists), createHashMap]; - private _loadoutFile = _whitelistsArray getOrDefault [_whitelist, ""]; - if (FILE_EXISTS(_loadoutFile)) then { - _whitelist = [player] call compile(preprocessFileLineNumbers _loadoutFile); - } else { - _whitelist = nil; - WARNING("The kosherGarage whitelist does not exist"); - }; - }; - - /* Get all vehicles within 8 meters of the spawn center and check if any of them were spawned with the virtual garage */ - private _objs = (getPos _garageObject) nearEntities [["Air", "Car", "Tank", "Ship", "staticWeapon"], _clearRange]; - reverse _objs; - private _garageObjs = []; - { - if (_x getVariable [QGVAR(vehicle), false]) then { - _garageObjs pushBack _x; - } else { - deleteVehicle _x; - }; - } forEach _objs; - - /* If there exists a previous virtual garage vehicle use that as center else create a empty helipad */ - private "_vehicle"; - if (count _garageObjs > 0) then { - _vehicle = _garageObjs select 0; - { if (_forEachIndex != 0) then { deleteVehicle _x } } forEach _garageObjs; - } else { - _vehicle = createVehicle [ "Land_HelipadEmpty_F", (getPos _garageObject), [], 0, "CAN_COLLIDE"]; - }; - - /* if there is a whitelist select a whitelisted vehicle as the default vehicle */ - if (!isNil "_whitelist") then { - private _ranSel = (selectRandom (_whitelist select 1)); - - /* If the selection is a Fill type select random from types */ - if (_ranSel in ["allCars", "allArmor", "allHelis", "allPlanes", "allNaval", "allTurrets"]) then { - private _searchClass = "Car"; - switch (_ranSel) do { - case ("allArmor"): { _searchClass = "Tank" }; - case ("allHelis"): { _searchClass = "Helicopter" }; - case ("allPlanes"): { _searchClass = "Plane" }; - case ("allNaval"): { _searchClass = "Ship" }; - case ("allTurrets"): { _searchClass = "StaticWeapon" }; - }; - - _ranSel = selectRandom ((format["( - (getNumber (_x >> 'scope') >= 2) && - { - getNumber (_x >> 'side') == 1 && - { (configName _x) isKindOf '%1' } - } - )", _searchClass] configClasses (configFile >> "CfgVehicles")) apply {configName _x}); - }; - - uinamespace setvariable ["bis_fnc_garage_defaultClass", _ranSel]; - }; - - if (isNil "_whitelist") then { - missionNameSpace setVariable [QGVAR(whitelist), nil]; - } else { - missionNameSpace setVariable [QGVAR(whitelist), _whitelist]; - }; - - /* Open garage UI */ - ["Open", [true, _vehicle]] call BIS_fnc_garage; - - }, _this]] remoteExec ["addAction", 0, true]; -}; diff --git a/framework/components/kosherGarage/fn_garageInterface.sqf b/framework/components/kosherGarage/functions/fn_garageInterface.sqf similarity index 94% rename from framework/components/kosherGarage/fn_garageInterface.sqf rename to framework/components/kosherGarage/functions/fn_garageInterface.sqf index b316234..7268935 100644 --- a/framework/components/kosherGarage/fn_garageInterface.sqf +++ b/framework/components/kosherGarage/functions/fn_garageInterface.sqf @@ -17,6 +17,7 @@ SCRIPT(garageInterface); /* Spawn the interface script handle */ +// @TODO: replace spawn private _handle = _this spawn { private _display = _this; private _veh = objNull; @@ -79,20 +80,20 @@ private _handle = _this spawn { /* Add the pylon magazines to the selection if they are whitelisted */ private _whitelist = missionNameSpace getVariable [QGVAR(whitelist), nil]; - private _pylonOptions = []; - if (!isNil "_whitelist") then { - if (count (_whitelist select 3) > 0) then { + private _pylonOptions = []; + if (!isNil "_whitelist") then { + if (count (_whitelist select 3) > 0) then { if (((_whitelist select 3) select 0) != "ALL") then { _pylonOptions = []; { private _pylon = _x; - if (_whitelist select 2) then { - if (_pylon in (_veh getCompatiblePylonMagazines _pylonName)) then { - _pylonOptions pushBack ((GVAR(pylonWeapons) select {(_x select 1) isEqualTo _pylon}) select 0); - }; - } else { - _pylonOptions pushBack ((GVAR(pylonWeapons) select {(_x select 1) isEqualTo _pylon}) select 0); - }; + if (_whitelist select 2) then { + if (_pylon in (_veh getCompatiblePylonMagazines _pylonName)) then { + _pylonOptions pushBack ((GVAR(pylonWeapons) select {(_x select 1) isEqualTo _pylon}) select 0); + }; + } else { + _pylonOptions pushBack ((GVAR(pylonWeapons) select {(_x select 1) isEqualTo _pylon}) select 0); + }; } forEach (_whitelist select 3); } else { if (_whitelist select 2) then { @@ -105,8 +106,8 @@ private _handle = _this spawn { _pylonOptions = GVAR(pylonWeapons); }; }; - }; - } else { + }; + } else { _pylonOptions = GVAR(pylonWeapons); }; diff --git a/framework/components/kosherGarage/fn_getAllPylonWeapons.sqf b/framework/components/kosherGarage/functions/fn_getAllPylonWeapons.sqf similarity index 98% rename from framework/components/kosherGarage/fn_getAllPylonWeapons.sqf rename to framework/components/kosherGarage/functions/fn_getAllPylonWeapons.sqf index 93e33b3..9dc8a12 100644 --- a/framework/components/kosherGarage/fn_getAllPylonWeapons.sqf +++ b/framework/components/kosherGarage/functions/fn_getAllPylonWeapons.sqf @@ -15,6 +15,7 @@ * Public: No */ +// @TODO: replace spawn _this spawn { if(isNil QGVAR(pylonWeapons)) then { GVAR(pylonWeapons) = []; diff --git a/framework/components/kosherGarage/functions/fn_init.sqf b/framework/components/kosherGarage/functions/fn_init.sqf new file mode 100644 index 0000000..3420319 --- /dev/null +++ b/framework/components/kosherGarage/functions/fn_init.sqf @@ -0,0 +1,313 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Makes the arma garage function multiplayer compatible. + * + * Arguments: + * 0: AddAction Object + * 1: Garage Object + * 2: Garage Direction [Default: 0] + * 3: WhitelistID [Default: "ALL"] + * 4: Clear range [Default: 8] + * + * Return Value: + * None + * + * Example: + * [this, _myGarageObject, 75, "myLoadoutID", 5] call cmf_kosherGarage_fnc_init + * + * Public: Yes + */ +SCRIPT(init); +if (!isServer) exitWith {}; + +// @TODO: replace spawn +_this spawn { + params["_actionObject"]; + + /* Get all available pylon weapons */ + if (isNil QGVAR(pylonWeapons)) then { + call FUNC(getAllPylonWeapons); + }; + + /* Create an addAction */ + [_actionObject, [LSTRING(open_garage), { + (_this select 3) params["_actionObject", "_garageObject", ["_garageDirection", 0], ["_whitelist", nil], ["_clearRange", 8]]; + + /* Create events to check if garage is open */ + [missionNamespace, "garageOpened", { + missionNamespace setVariable [QGVAR(open), true]; + uiNamespace setVariable [QGVAR(display), (_this select 0)]; + private _display = (_this select 0); + + /* Make player temporarily invincible, if they are kileld while in the garage the game breaks */ + player allowDamage false; + + /* Handle whitelists */ + // @TODO: replace spawn + private _spawnHandle = _display spawn { + + /* Remove vehicles, camos and components that aren't whitelisted */ + // @TODO: replace spawn + _this spawn { + private _display = _this; + private _data = missionnamespace getvariable "bis_fnc_garage_data"; + private _whitelist = missionNameSpace getVariable [QGVAR(whitelist), nil]; + if (isNil "_whitelist") exitWith {}; + + //////////////////////////// Whitelist vehicles ///////////////////////////// + { + /* Get the list control for the current vehicle type */ + private _ctrlList = _display displayctrl (960 + _forEachIndex); + private _idc = _forEachIndex; + waitUntil{ lbSize _ctrlList > 0 }; + + private _allItems = lbSize _ctrlList; + + + private _indexOffset = 0; + + /* If the all is in the whitelist whitelist all vehicles from that class */ + if !( + ((_idc == 0) && "allCars" in (_whitelist select 1)) || + ((_idc == 1) && "allArmor" in (_whitelist select 1)) || + ((_idc == 2) && "allHelis" in (_whitelist select 1)) || + ((_idc == 3) && "allPlanes" in (_whitelist select 1)) || + ((_idc == 4) && "allNaval" in (_whitelist select 1)) || + ((_idc == 5) && "allTurrets" in (_whitelist select 1)) + ) then { + for "_i" from 0 to _allItems - 1 do { + private _index = 0 + _indexOffset; + private _configs = (_data select _idc) select (_ctrlList lbValue _index) + 1; + + /* loop over all configs for this vehicle */ + { + private _config = [str _x] call BIS_fnc_configPath; + private _configName = _config select ((count _config) - 1); + if !(_configName in (_whitelist select 1)) exitWith { + _ctrlList lbDelete _index; + }; + _indexOffset = _indexOffset + 1; + } forEach _configs; + }; + } else { + _indexOffset = 1; + }; + + { + (_display displayCtrl _x) ctrlShow (_indexOffset > 0); + (_display displayCtrl _x) ctrlEnable (_indexOffset > 0); + } forEach [(930 + _idc), (860 + _idc), (960 + _idc), (900 + _idc)]; + } forEach _data; + + //////////////////////////// Whitelist right ///////////////////////////// + while {true} do { + /* Whitelist camos/textures */ + private _ctrlList = _display displayctrl 980; + if (lbSize _ctrlList > 0) then { + private _allItems = lbSize _ctrlList; + private _indexOffset = 0; + + for "_i" from 0 to _allItems - 1 do { + private _index = 0 + _indexOffset; + + private _configName = _ctrlList lbData _index; + if (!(_configName in (_whitelist select 4)) && ((_whitelist select 4) select 0) != "ALL") then { + _ctrlList lbDelete _index; + } else { + _indexOffset = _indexOffset + 1; + }; + }; + }; + + /* Whitelist components */ + private _ctrlList = _display displayctrl 979; + if (lbSize _ctrlList > 0) then { + private _allItems = lbSize _ctrlList; + private _indexOffset = 0; + + for "_i" from 0 to _allItems - 1 do { + private _index = 0 + _indexOffset; + + private _configName = _ctrlList lbData _index; + if (!(_configName in (_whitelist select 5)) && ((_whitelist select 5) select 0) != "ALL") then { + _ctrlList lbDelete _index; + } else { + _indexOffset = _indexOffset + 1; + }; + }; + }; + + sleep 0.1; + }; + }; + + /* Add a custom interface for selecting pylons */ + _this call FUNC(garageInterface); + + /* Remove the crew selection tab */ + while{ true } do { + { + (_this displayCtrl _x) ctrlShow false; + (_this displayCtrl _x) ctrlEnable false; + } forEach [918, 978, 878, 948]; + + sleep 0.01; + }; + }; + + /* Remove this eventHandler when the garage is closed */ + // @TODO: replace spawn + _thisScriptedEventHandler spawn { + waitUntil{ !(missionNamespace getVariable [QGVAR(open), true]) }; + [missionNamespace, "garageOpened", _this] call BIS_fnc_removeScriptedEventHandler; + }; + + /* Raise event */ + [QGVAR(onOpen), [_display]] call CBA_fnc_localEvent; + + private _handles = missionNameSpace getVariable [QGVAR(spawns), []]; + _handles pushBack _spawnHandle; + missionNameSpace setVariable [QGVAR(spawns), _handles]; + }] call BIS_fnc_addScriptedEventHandler; + + /* Create event to check if the garage is closed */ + [missionNamespace, "garageClosed", { + missionNamespace setVariable [QGVAR(open), false]; + uiNamespace setVariable [QGVAR(display), displayNull]; + + /* Make player take damage again */ + player allowDamage true; + + /* Stop the custom interface event handler */ + [QGVAR(FrameEvent), "onEachFrame"] call BIS_fnc_removeStackedEventHandler; + + /* Delete all custom controls */ + { + ctrlDelete (_x select 0); + } forEach GVAR(loadout_controls); + GVAR(loadout_controls) = []; + + /* Cleanup any remaining script handles */ + private _handles = missionNameSpace getVariable [QGVAR(spawns), []]; + { + terminate _x; + } forEach _handles; + + /* Get the selected vehicle */ + private _veh = missionNameSpace getVariable "BIS_fnc_garage_center"; + + /* Respawn it as a global vehicle */ + // @TODO: replace spawn + private _spawnHandle = _veh spawn FUNC(syncVehicle); + + /* pushback the script handle incase it fails so it can be terminated manually later */ + private _handles = missionNameSpace getVariable [QGVAR(spawns), []]; + _handles pushBack _spawnHandle; + missionNameSpace setVariable [QGVAR(spawns), _handles]; + + /* Remove this event handler */ + [missionNamespace, "garageClosed", _thisScriptedEventHandler] call BIS_fnc_removeScriptedEventHandler; + + /* Raise event */ + [QGVAR(onClose), []] call CBA_fnc_localEvent; + }] call BIS_fnc_addScriptedEventHandler; + + /* Set the direction and position of newly selected vehicles */ + // @TODO: replace spawn + [_garageDirection, (getPos _garageObject)] spawn { + params["_garageDirection", "_garagePosition"]; + private _veh = objNull; + waitUntil{missionNamespace getVariable [QGVAR(open), false]}; + while { missionNamespace getVariable [QGVAR(open), false] } do { + /* wait until a new vehicle is selected */ + waitUntil{ + if (isNil { (missionNamespace getVariable "BIS_fnc_arsenal_center") }) exitWith { true }; + (typeof (missionNamespace getVariable "BIS_fnc_arsenal_center")) != (typeof _veh) + }; + + /* Get the newly selected vehicle */ + _veh = (missionNamespace getVariable "BIS_fnc_arsenal_center"); + if (isNil "_veh") exitWith {}; + + /* Set the position and direction */ + _veh setPos _garagePosition; + _veh setDir _garageDirection; + + /* Raise event */ + [QGVAR(onSelect), [_veh]] call CBA_fnc_localEvent; + }; + }; + + + /* Parse the whitelist */ + if (!isNil "_whitelist") then { + private _whitelistsArray = missionNamespace getVariable [QGVAR(whitelists), createHashMap]; + private _loadoutFile = _whitelistsArray getOrDefault [_whitelist, ""]; + if (FILE_EXISTS(_loadoutFile)) then { + _whitelist = [player] call compile(preprocessFileLineNumbers _loadoutFile); + } else { + _whitelist = nil; + WARNING("The kosherGarage whitelist does not exist"); + }; + }; + + /* Get all vehicles within 8 meters of the spawn center and check if any of them were spawned with the virtual garage */ + private _objs = (getPos _garageObject) nearEntities [["Air", "Car", "Tank", "Ship", "staticWeapon"], _clearRange]; + reverse _objs; + private _garageObjs = []; + { + if (_x getVariable [QGVAR(vehicle), false]) then { + _garageObjs pushBack _x; + } else { + deleteVehicle _x; + }; + } forEach _objs; + + /* If there exists a previous virtual garage vehicle use that as center else create a empty helipad */ + private "_vehicle"; + if (count _garageObjs > 0) then { + _vehicle = _garageObjs select 0; + { if (_forEachIndex != 0) then { deleteVehicle _x } } forEach _garageObjs; + } else { + _vehicle = createVehicle [ "Land_HelipadEmpty_F", (getPos _garageObject), [], 0, "CAN_COLLIDE"]; + }; + + /* if there is a whitelist select a whitelisted vehicle as the default vehicle */ + if (!isNil "_whitelist") then { + private _ranSel = (selectRandom (_whitelist select 1)); + + /* If the selection is a Fill type select random from types */ + if (_ranSel in ["allCars", "allArmor", "allHelis", "allPlanes", "allNaval", "allTurrets"]) then { + private _searchClass = "Car"; + switch (_ranSel) do { + case ("allArmor"): { _searchClass = "Tank" }; + case ("allHelis"): { _searchClass = "Helicopter" }; + case ("allPlanes"): { _searchClass = "Plane" }; + case ("allNaval"): { _searchClass = "Ship" }; + case ("allTurrets"): { _searchClass = "StaticWeapon" }; + }; + + _ranSel = selectRandom ((format["( + (getNumber (_x >> 'scope') >= 2) && + { + getNumber (_x >> 'side') == 1 && + { (configName _x) isKindOf '%1' } + } + )", _searchClass] configClasses (configFile >> "CfgVehicles")) apply {configName _x}); + }; + + uinamespace setvariable ["bis_fnc_garage_defaultClass", _ranSel]; + }; + + if (isNil "_whitelist") then { + missionNameSpace setVariable [QGVAR(whitelist), nil]; + } else { + missionNameSpace setVariable [QGVAR(whitelist), _whitelist]; + }; + + /* Open garage UI */ + ["Open", [true, _vehicle]] call BIS_fnc_garage; + + }, _this]] remoteExec ["addAction", 0, true]; +}; diff --git a/framework/components/kosherGarage/fn_registerWhitelist.sqf b/framework/components/kosherGarage/functions/fn_registerWhitelist.sqf similarity index 100% rename from framework/components/kosherGarage/fn_registerWhitelist.sqf rename to framework/components/kosherGarage/functions/fn_registerWhitelist.sqf diff --git a/framework/components/kosherGarage/fn_syncVehicle.sqf b/framework/components/kosherGarage/functions/fn_syncVehicle.sqf similarity index 100% rename from framework/components/kosherGarage/fn_syncVehicle.sqf rename to framework/components/kosherGarage/functions/fn_syncVehicle.sqf diff --git a/framework/components/kosherGarage/functions/script_component.hpp b/framework/components/kosherGarage/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/kosherGarage/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/kosherGarage/script_component.hpp b/framework/components/kosherGarage/script_component.hpp index c953cd1..f02e24e 100644 --- a/framework/components/kosherGarage/script_component.hpp +++ b/framework/components/kosherGarage/script_component.hpp @@ -1,5 +1,15 @@ #define MODULE kosherGarage +#define MODULE_BEAUTIFIED Kosher Garage + #define REQUIRED_ADDONS ["A3_Functions_F"] #define REQUIRED_MODULES ["common"] -#include "..\main\script_component.hpp" +#ifdef DEBUG_ENABLED_KOSHERGARAGE + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_KOSHERGARAGE + #define DEBUG_SETTINGS DEBUG_SETTINGS_KOSHERGARAGE +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/logistics/XEH_PREP.sqf b/framework/components/logistics/XEH_PREP.sqf new file mode 100644 index 0000000..9fd039a --- /dev/null +++ b/framework/components/logistics/XEH_PREP.sqf @@ -0,0 +1,8 @@ +#include "script_component.hpp" + +PREP(cratePFH); +PREP(crateInit); +PREP(crateActions); +PREP(cratePreset); +PREP(presetCompile); +PREP(crateSpawner); diff --git a/framework/components/logistics/XEH_postInit.sqf b/framework/components/logistics/XEH_postInit.sqf new file mode 100644 index 0000000..f020ae8 --- /dev/null +++ b/framework/components/logistics/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +[] call FUNC(cratePFH); +[] call FUNC(crateInit); +[] call FUNC(crateActions); \ No newline at end of file diff --git a/framework/components/logistics/functions/fn_crateActions.sqf b/framework/components/logistics/functions/fn_crateActions.sqf new file mode 100644 index 0000000..66616f0 --- /dev/null +++ b/framework/components/logistics/functions/fn_crateActions.sqf @@ -0,0 +1,56 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Adds ACE Interaction menu actions to logistics crates + * + * Arguments: + * No + * + * Return Value: + * No + * + * Example: + * [] call cmf_logistics_fnc_crateActions + * + * Public: No + */ + +/* Create actions */ +private _action = [QGVAR(crate_menu), "Other", "", {}, { true }, { + private _actions = []; + + /* Rename object */ + private _action = [QGVAR(renameObject), "Rename", "a3\3den\data\displays\display3den\panelright\customcomposition_edit_ca.paa", { + ace_cargo_interactionVehicle = _target; + createDialog "ace_cargo_renameMenu"; + }, { + ace_cargo_enable && + { ace_cargo_enableRename } && + { (_target getVariable ["ace_cargo_canLoad", getNumber (configOf _target >> "ace_cargo_canLoad")]) in [true, 1] } && + { alive _target } && + { [_player, _target, ["isNotSwimming"]] call ace_common_fnc_canInteractWith } + }] call ace_interact_menu_fnc_createAction; + _actions pushBack [_action, [], _target]; + + /* Destroy crate */ + private _action = ([QGVAR(renameObject), "Destroy Crate", "a3\ui_f_curator\data\cfgmarkers\kia_ca.paa", { + _target spawn { + private _result = ["Are you sure?", "Confirm", true, true] call BIS_fnc_guiMessage; + if (_result) then { + deleteVehicle _this; + }; + }; + }, { + ace_cargo_enable && + { missionNamespace getVariable [QGVAR(enableDestroy), true] } && + { (_target getVariable ["ace_cargo_canLoad", getNumber (configOf _target >> "ace_cargo_canLoad")]) in [true, 1] } && + { alive _target } && + { [_player, _target, ["isNotSwimming"]] call ace_common_fnc_canInteractWith } + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + _actions; +}] call ace_interact_menu_fnc_createAction; + +/* Add action to class */ +["ReammoBox_F", 0, ["ACE_MainActions"], _action, true] call ace_interact_menu_fnc_addActionToClass; diff --git a/framework/components/logistics/functions/fn_crateInit.sqf b/framework/components/logistics/functions/fn_crateInit.sqf new file mode 100644 index 0000000..0df9de6 --- /dev/null +++ b/framework/components/logistics/functions/fn_crateInit.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Initializes supply crates + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_logistics_fnc_crateInit + * + * Public: No + */ + +/* Add ACE interaction menu actions */ +["ReammoBox_F", "init", { + params ["_crate"]; + + /* hide original ace rename action */ + _crate setVariable ["ace_cargo_noRename", 1]; +}, true, [], true] call CBA_fnc_addClassEventHandler; diff --git a/framework/components/logistics/functions/fn_cratePFH.sqf b/framework/components/logistics/functions/fn_cratePFH.sqf new file mode 100644 index 0000000..7c51d59 --- /dev/null +++ b/framework/components/logistics/functions/fn_cratePFH.sqf @@ -0,0 +1,49 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Shows the crate name when looking at it + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_logistics_fnc_cratePFH + * + * Public: No + */ + +[{ + /* Get object player is looking at */ + private _newObject = cursorObject; + + /* Get previously looked at object */ + private _oldObject = missionNamespace getVariable [QGVAR(observedCrate), [objNull, scriptNull]]; + + /* If HUD is disabled exit */ + if !(missionNameSpace getVariable [QEGVAR(menu,hud_show), true]) exitWith { + terminate (_oldObject select 1); + (["cmf_logistics_name"] call BIS_fnc_rscLayer) cutText ["","plain"]; + missionNamespace setVariable [QGVAR(observedCrate), [objNull, scriptNull], false]; + }; + + /* Exit if player is looking at same object */ + if (_newObject isEqualTo (_oldObject select 0)) exitWith {}; + + /* Hide previous text */ + if (player distance _newObject > 5) then { + terminate (_oldObject select 1); + (["cmf_logistics_name"] call BIS_fnc_rscLayer) cutText ["","plain"]; + }; + + /* Show new text if there is any */ + private _name = _newObject getVariable ["ace_cargo_customName", nil]; + if (!isNil "_name") then { + private _handle = [format ["%1", _name], -1, -1, 9999, 0.5, 0, (["cmf_logistics_name"] call BIS_fnc_rscLayer)] spawn BIS_fnc_dynamicText; + missionNamespace setVariable [QGVAR(observedCrate), [_newObject, _handle], false]; + } else { + missionNamespace setVariable [QGVAR(observedCrate), [objNull, scriptNull], false]; + }; +}] call CBA_fnc_addPerFrameHandler; diff --git a/framework/components/logistics/functions/fn_cratePreset.sqf b/framework/components/logistics/functions/fn_cratePreset.sqf new file mode 100644 index 0000000..963bf5e --- /dev/null +++ b/framework/components/logistics/functions/fn_cratePreset.sqf @@ -0,0 +1,69 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Loads logistics crate defines from given preset + * + * Arguments: + * 0: Preset name + * + * Return Value: + * None + * + * Example: + * ["myLogistics"] call cmf_logistics_fnc_cratepreset + * + * Public: Yes + */ +params ["_name"]; + +if (isNil "_name") exitWith { ERROR_MSG("No preset defined") }; +private _path = format["rsc\loadouts\%1.sqf", _name]; +if !(FILE_EXISTS(_path)) exitWith { ERROR_MSG_1("Unable to find preset: %1", _name); }; + +private _presets = [call compile preprocessFileLineNumbers _path] call CBA_fnc_hashCreate; +missionNamespace setVariable [QGVAR(crateConfig), _presets, true]; + +{ + private _key = _x; + private _preset = [_presets, _x] call CBA_fnc_hashGet; + + private _presetData = [_preset] call FUNC(presetCompile); + + /* Create amount tracker */ + private _crateHash = missionNamespace getVariable [QGVAR(crateHash), [] call CBA_fnc_hashCreate]; + private _newAmount = [_crateHash, _key, 0] call CBA_fnc_hashSet; + missionNamespace setVariable [QGVAR(crateHash), _newAmount, true]; + + /* Using this method won't allow for using the same crate for different crates */ + [(_presetData select 1), "init", compile (" + params ['_crate']; + if (_crate getVariable ['ace_cargo_customName', ''] isEqualTo '') then { + _crate setVariable ['ace_cargo_customName', '" + _key + " Crate | ', true]; + }; + [_crate, true] call ace_dragging_fnc_setCarryable; + [_crate, true] call ace_dragging_fnc_setDraggable; + + clearItemCargoGlobal _crate; + clearMagazineCargoGlobal _crate; + clearWeaponCargoGlobal _crate; + clearBackpackCargoGlobal _crate; + + {_crate addWeaponCargoGlobal _x} forEach "+str(_presetData select 2)+"; + {_crate addMagazineCargoGlobal _x} forEach "+str(_presetData select 3)+"; + {_crate addItemCargoGlobal _x} forEach "+str(_presetData select 4)+"; + + if (count "+str(_presetData select 5)+" > 0) then { + private _cargoSpace = 0; + { + _cargoSpace = _cargoSpace + _x; + } forEach ("+str(_presetData select 5)+" apply { ([_x select 0] call ace_cargo_fnc_getSizeItem) * (_x select 1) }); + [_crate, _cargoSpace] call ace_cargo_fnc_setSpace; + { + private _cargo = _x; + for '_i' from 0 to (_cargo select 1) do { + [(_cargo select 0), _crate] call ace_cargo_fnc_loadItem; + }; + } forEach "+str(_presetData select 5)+"; + }; + "), true, [], true] call CBA_fnc_addClassEventHandler; +} forEach ([_presets] call CBA_fnc_hashKeys); \ No newline at end of file diff --git a/framework/components/logistics/functions/fn_crateSpawner.sqf b/framework/components/logistics/functions/fn_crateSpawner.sqf new file mode 100644 index 0000000..9e6aab3 --- /dev/null +++ b/framework/components/logistics/functions/fn_crateSpawner.sqf @@ -0,0 +1,69 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Creates an ace action to spawn logistical crates + * + * Arguments: + * 0: Object + * + * Return Value: + * None + * + * Example: + * [this] call cmf_logistics_fnc_crateSpawner + * + * Public: Yes + */ +_this spawn { + params ["_obj"]; + + /* Wait until a preset is loaded */ + waitUntil { !isNil { missionNamespace getVariable QGVAR(crateConfig) } }; + + /* Create Logistics root menu */ + private _action = [QGVAR(root), "Logistics", "", {}, { true }] call ace_interact_menu_fnc_createAction; + [_obj, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToObject; + + /* Create crate spawning actions */ + private _config = missionNamespace getVariable [QGVAR(crateConfig), [] call CBA_fnc_hashCreate]; + { + private _key = _x; + private _preset = [_config, _key] call CBA_fnc_hashGet; + private _presetData = [_preset] call FUNC(presetCompile); + + private _action = [ + format [QGVAR(_%1), _key], + format ["Create %1 Crate", _key], + "", + { + params ["_target", "_player", "_params"]; + _params params ["_preset", "_key"]; + + private _crateHash = missionNamespace getVariable [QGVAR(crateHash), [] call CBA_fnc_hashCreate]; + private _oldAmount = [_crateHash, _key] call CBA_fnc_hashGet; + if (_oldAmount >= (_preset select 0)) exitWith {}; + + private _crate = (_preset select 1) createVehicle [0, 0, 0]; + private _position = [_target, _crate, _player] call ace_common_fnc_findUnloadPosition; + _crate setPos _position; + [_player, _crate] call ace_cargo_fnc_unloadCarryItem; + + private _newHash = [_crateHash, _key, _oldAmount + 1] call CBA_fnc_hashSet; + missionNamespace setVariable [QGVAR(crateHash), _newHash, true]; + }, + { true }, {}, [_presetData, _key], [0, 0, 0], 2, [false, false, false, false, false], + { + params ["_target", "_player", "_params", "_actionData"]; + _params params ["_preset", "_key"]; + + private _crateHash = missionNamespace getVariable [QGVAR(crateHash), [] call CBA_fnc_hashCreate]; + private _oldAmount = [_crateHash, _key, 0] call CBA_fnc_hashGet; + + private _color = ["#888888", "#ffffff"] select (_oldAmount < (_preset select 0)); + _actionData set [1, format ["Create %1 Crate [%2/%3]", _key, _oldAmount, _preset select 0, _color]]; + } + ] call ace_interact_menu_fnc_createAction; + + [_obj, 0, ["ACE_MainActions", QGVAR(root)], _action] call ace_interact_menu_fnc_addActionToObject; + } forEach ([_config] call CBA_fnc_hashKeys); +} diff --git a/framework/components/logistics/functions/fn_presetCompile.sqf b/framework/components/logistics/functions/fn_presetCompile.sqf new file mode 100644 index 0000000..cb7d439 --- /dev/null +++ b/framework/components/logistics/functions/fn_presetCompile.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Compiles a preset into a CBA Hash + * + * Arguments: + * 0: Preset data + * + * Return Value: + * Compiled Preset data + * + * Example: + * [_myPreset] call cmf_logistics_fnc_presetCompile + * + * Public: No + */ +params ["_preset"]; + +private _code = toString _preset; +_code = _code + +"[ + [_available, 0] select (isNil '_available'), + [_class, ''] select (isNil '_class'), + [_weapons, []] select (isNil '_weapons'), + ([_magazines, []] select (isNil '_magazines'))+ + ([_grenades, []] select (isNil '_grenades')), + [_items, []] select (isNil '_items'), + [_cargo, []] select (isNil '_cargo') +]"; + +call compile _code; \ No newline at end of file diff --git a/framework/components/logistics/functions/script_component.hpp b/framework/components/logistics/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/logistics/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/logistics/script_component.hpp b/framework/components/logistics/script_component.hpp new file mode 100644 index 0000000..ac3bca8 --- /dev/null +++ b/framework/components/logistics/script_component.hpp @@ -0,0 +1,15 @@ +#define MODULE logistics +#define MODULE_BEAUTIFIED Logistics + +#define REQUIRED_ADDONS [] +#define REQUIRED_MODULES ["common"] + +#ifdef DEBUG_ENABLED_LOGISTICS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_LOGISTICS + #define DEBUG_SETTINGS DEBUG_SETTINGS_LOGISTICS +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/logistics/stringtable.sqf b/framework/components/logistics/stringtable.sqf new file mode 100644 index 0000000..f888990 --- /dev/null +++ b/framework/components/logistics/stringtable.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: Eric + * aar_stringtable + */ +[ + [DSTRING(performance_report_displayname), [ + ["English", "Performance report"], + ["Spanish", "Reporte de rendimiento"] + ]], + [DSTRING(anonymous_title), [ + ["English", "Anonymous"], + ["Spanish", "Anónimo"] + ]], + [DSTRING(anonymous_tooltip), [ + ["English", "Would you like to be anonymous? (note that if profanity or deragatory terms are used, your anonymity is void)"], + ["Spanish", "¿Desea que este artículo informativo permanezca en el anonimato?"] + ]], + [DSTRING(player_feedback_title), [ + ["English", "Player Performance Feedback"], + ["Spanish", "Comentarios sobre el rendimiento de los jugadores"] + ]], + [DSTRING(player_feedback_tooltip), [ + ["English", "Constructive Feedback on player performance"], + ["Spanish", "Comentarios sobre el rendimiento de los jugadores"] + ]], + [DSTRING(mission_feedback_title), [ + ["English", "Mission Feedback"], + ["Spanish", "Comentarios sobre la misión"] + ]], + [DSTRING(mission_feedback_tooltip), [ + ["English", "Constructive Feedback on mission"], + ["Spanish", "Comentarios sobre la misión"] + ]] +] diff --git a/framework/components/main/XEH_3denInit.sqf b/framework/components/main/XEH_3denInit.sqf new file mode 100644 index 0000000..e2b4a3f --- /dev/null +++ b/framework/components/main/XEH_3denInit.sqf @@ -0,0 +1,4 @@ +#include "script_component.hpp" + +/* Load ace settings */ +call compile preprocessFileLineNumbers "components\main\initAceSettings.sqf"; \ No newline at end of file diff --git a/framework/components/main/XEH_MODULE.sqf b/framework/components/main/XEH_MODULE.sqf index 5503372..fd46ac9 100644 --- a/framework/components/main/XEH_MODULE.sqf +++ b/framework/components/main/XEH_MODULE.sqf @@ -8,37 +8,152 @@ SCRIPT(XEH_MODULE); LOG("Initializing components"); -missionNamespace setVariable [QGVAR(components_initialized), false, true]; +missionNamespace setVariable [QGVAR(components_initialized), false]; /* CMF Modules to define */ GVAR(components) = [ "main", "common", + "diagnostic", + "3den", "viewdistance", "menu", "gameplay", "enhancedVehicles", "kosherArsenal", + "kosherAI", "kosherGarage", "respawn", "utility", "zeus", "ai", + "aar", + "logistics", + "organization", "player" ]; -/* Call the files that compiles and defines the module's functions */ -{ - private _modulePrepPath = format["components\%1\XEH_PREP.sqf", _x]; - if (FILE_EXISTS(_modulePrepPath)) then { - [_x] call compile preprocessFileLineNumbers _modulePrepPath; +// @TODO: cleanup file loading (Create function that takes path/name, and condition) +private _loadPrep = { + params ["_module"]; + + private _path = format ["components\%1\XEH_PREP.sqf", _module]; + + if (fileExists _path) then { + [] call compile preprocessFileLineNumbers _path; } else { - WARNING_1("Failed to find module %1", _modulePrepPath); + WARNING_1("Failed to find module %1", _path); + }; +}; + +private _loadSettings = { // @TODO: Add for initKeybinds aswell + params ["_module"]; + + private _path = format ["components\%1\initSettings.sqf", _module]; + + if (fileExists _path) then { + waitUntil { !isNil "CBA_fnc_addSetting" }; + [compile preprocessFileLineNumbers _path] call CBA_fnc_directCall; // Make sure it's run unscheduled + }; +}; + +private _loadKeybinds = { + params ["_module"]; + + private _path = format ["components\%1\initKeybinds.sqf", _module]; + + if (fileExists _path) then { + waitUntil { !isNil "CBA_fnc_addKeybind" }; + [compile preprocessFileLineNumbers _path] call CBA_fnc_directCall; // Make sure it's run unscheduled + }; +}; + +private _loadPreInit = { + if (is3DEN) exitWith {}; + params ["_module"]; + + private _path = format ["components\%1\XEH_preInit.sqf", _module]; + + if (fileExists _path) then { + [] call compile preprocessFileLineNumbers _path; + }; +}; + +private _loadPostInit = { + if (is3DEN) exitWith {}; + params ["_module"]; + + private _path = format ["components\%1\XEH_postInit.sqf", _module]; + + if (fileExists _path) then { + [ + { missionNamespace getVariable [QGVAR(components_initialized), false] }, + { [] call compile preprocessFileLineNumbers _this }, + _path + ] call CBA_fnc_waitUntilAndExecute; }; +}; + +private _loadServerInit = { + if (is3DEN) exitWith {}; + params ["_module"]; + + if (!isServer) exitWith {}; + + private _path = format ["components\%1\XEH_serverInit.sqf", _module]; + + if (fileExists _path) then { + [] call compile preprocessFileLineNumbers _path; + }; +}; + +private _loadPlayerInit = { + if (is3DEN) exitWith {}; + params ["_module"]; + + private _path = format ["components\%1\XEH_playerInit.sqf", _module]; + + if (fileExists _path) then { + [ + { (missionNamespace getVariable [QGVAR(server_initialized), false]) && !isNull player }, + { + [] call compile preprocessFileLineNumbers _this; + }, + _path + ] call CBA_fnc_waitUntilAndExecute; + }; +}; + +private _load3denInit = { + if (!is3DEN) exitWith {}; + params ["_module"]; + + private _path = format ["components\%1\XEH_3denInit.sqf", _module]; + + if (fileExists _path) then { + waitUntil { missionNamespace getVariable [QGVAR(components_initialized), false] }; + [] spawn compile preprocessFileLineNumbers _path; + }; +}; + +/* Compile module */ +{ + /* Compile modules */ + [_x] call _loadPrep; + + /* Compile settings */ + [_x] spawn _loadSettings; + + /* Compile Keybinds */ + [_x] spawn _loadKeybinds; + + /* Compile xeh events */ + [_x] call _loadPreInit; + [_x] call _loadPostInit; + [_x] call _loadServerInit; + [_x] call _loadPlayerInit; + [_x] spawn _load3denInit; } forEach GVAR(components); INFO("Initialized components"); -missionNamespace setVariable [QGVAR(components_initialized), true, true]; - -/* Raise event */ -[QGVAR(modules_initialized), []] call CBA_fnc_globalEvent; +missionNamespace setVariable [QGVAR(components_initialized), true]; \ No newline at end of file diff --git a/framework/components/main/XEH_PREP.sqf b/framework/components/main/XEH_PREP.sqf index 6231bf8..b5638d9 100644 --- a/framework/components/main/XEH_PREP.sqf +++ b/framework/components/main/XEH_PREP.sqf @@ -1,7 +1,8 @@ #include "script_component.hpp" PREP(localize); -PREP(playerInit); -IPREP(serverInit); -IPREP(missionInit); -IPREP(addonBlacklist); +PREP(acreRestore); +PREP(fortify); +PREP(addonBlacklist); +PREP(chatHandler); +PREP(changelog); diff --git a/framework/components/main/XEH_playerInit.sqf b/framework/components/main/XEH_playerInit.sqf new file mode 100644 index 0000000..7613649 --- /dev/null +++ b/framework/components/main/XEH_playerInit.sqf @@ -0,0 +1,208 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +LOG_1("Initializing player %1...", (name player)); +missionNamespace setVariable [QGVAR(player_initialized), false]; + +/* Load ace settings */ +call compile preprocessFileLineNumbers "components\main\initAceSettings.sqf"; // @TODO: Move to common and load preInit + +/* Load Shacktack UI changes */ +call compile preprocessFileLineNumbers "components\main\initSTUISettings.sqf"; // @TODO: Move to common and load preInit + +/* Remove KP ranks ace interactions */ +// @TODO: Move to common +[{ + if (isNil { ([(ace_interact_menu_ActSelfNamespace getVariable (typeOf player)), ["ACE_SelfActions","KPR_Admin"]] call ace_interact_menu_fnc_findActionNode) }) exitWith {}; + + [(typeOf player), 1, ["ACE_SelfActions", "KPR_Admin"]] call ace_interact_menu_fnc_removeActionFromClass; + [(typeOf player), 1, ["ACE_SelfActions", "ACE_Equipment", "KPR_Check"]] call ace_interact_menu_fnc_removeActionFromClass; + [(typeOf player), 1, ["ACE_SelfActions", "KPR_Admin", "KPR_UniformManage"]] call ace_interact_menu_fnc_removeActionFromClass; + [(typeOf player), 1, ["ACE_SelfActions", "KPR_Admin", "KPR_PlayerManage"]] call ace_interact_menu_fnc_removeActionFromClass; +}, 10] call CBA_fnc_addPerFrameHandler; + +/* Disable Unsung vietnamese voices */ +RUG_DSAI_TerminalDistance = -1; // @TODO: Move to AI + +/* Create ACRE2 Babel handler */ +// @TODO: Move to common +["unit", { + params ["_player"]; + + private _languages = _player getVariable [QGVAR(acre_langs), ["en"]]; + _languages call acre_api_fnc_babelSetSpokenLanguages; +}, true] call CBA_fnc_addPlayerEventHandler; + +/* Modify ACEX fortify */ +[] call FUNC(fortify); // @TODO: Delete function and make part of safestart + +/* Block looting own corpse */ // @TODO: Move to respawn +player addEventHandler ["InventoryOpened", { + params ["_unit", "_container"]; + _override = false; + if (name player isEqualTo name _container && !alive _container) then { + ["You can't loot your own corpse", -1, safezoneY + 0.1] spawn bis_fnc_dynamicText; + _override = true; + }; + _override +}]; + +player addEventHandler ["Take", { + params ["_unit", "_container", "_item"]; + + if (name player isEqualTo name _container && !alive _container) then { + ["You can't loot your own corpse", -1, safezoneY + 0.1] spawn bis_fnc_dynamicText; + player removeMagazine _item; + player removeItem _item; + }; + + _override; +}]; + +/* Mute ACRE when player is down */ // @TODO: Move to player +["ace_unconscious", { + params ["_unit", "_active"]; + + if (_unit != player) exitWith { }; + + if (_active) then { + if (!isNil "acre_api_fnc_setGlobalVolume") then { + private _acreGlobalVolume = [] call acre_api_fnc_getGlobalVolume; + if (isNil "_acreGlobalVolume") then { _acreGlobalVolume = 1 }; + private _globalVolume = soundVolume; + player setVariable [QGVAR(acre_globalVolume), _acreGlobalVolume, true]; + player setVariable [QGVAR(globalVolume), _globalVolume, true]; + [0] call acre_api_fnc_setGlobalVolume; + 0 fadeSound 0.1; + 0 fadeRadio 0.1; + }; + } else { + if (!isNil "acre_api_fnc_setGlobalVolume") then { + private _acreGlobalVolume = player getVariable [QGVAR(acre_globalVolume), 1]; + private _globalVolume = player getVariable [QGVAR(globalVolume), 1]; + [_acreGlobalVolume] call acre_api_fnc_setGlobalVolume; + 0 fadeSound _globalVolume; + 0 fadeRadio _globalVolume; + }; + }; +}] call CBA_fnc_addEventHandler; + +if (!isNil "acre_api_fnc_setCustomSignalFunc") then { + [{ + private _coreSignal = _this call acre_sys_signal_fnc_getSignalCore; + _coreSignal params ["_Px", "_maxSignal"]; + + if (player getVariable ["ACE_isUnconscious", false]) then { + _Px = 0; + }; + + [_Px, _maxSignal] + }] call acre_api_fnc_setCustomSignalFunc; +}; + +/* Show changelog */ +[] call FUNC(changelog); + +/* Player killed event */ // @TODO: Move Some of this to common +player addEventHandler ["Killed", { + params ["_unit"]; + /* Save loadout */ + player setVariable [QGVAR(player_loadout), getUnitLoadout _unit]; + + /* Save group upon player death */ + player setVariable [QGVAR(player_group), (group _unit)]; + + /* Save team assigned upon player death */ + player setVariable [QGVAR(player_team), (assignedTeam _unit)]; + + /* Set player to fully loaded (first death is automatic so player's can choose their spawn location) */ + player setVariable [QGVAR(player_loaded), true]; + + /* Call event script */ + _this execVM "events\onPlayerKilled.sqf" +}]; + +/* Player respawn event */ // @TODO: Move some of this to common +player addEventHandler ["Respawn", { + params ["_unit", "_corpse"]; + + /* Make sure player is able to use ACRE */ + player setVariable ["acre_sys_core_isDisabled", false, true]; + player setVariable ["acre_sys_core_isDisabledRadio", false, true]; + + /* Load loadout */ + _unit setUnitLoadout (player getVariable [QGVAR(player_loadout),[]]); + + /* Only run if players are not spectating */ + if !((player getVariable[QEGVAR(respawn,respawns), 1]) isEqualTo (player getVariable [QEGVAR(respawn,deaths), 0])) then { + /* Join previous group */ + [_unit] joinSilent (player getVariable [QGVAR(player_group), (group player)]); + + /* Assign previous team */ + _unit assignTeam (player getVariable [QGVAR(player_team), (assignedTeam player)]); + }; + + /* Restore ACRE radio configurations on respawn */ + [] call cmf_main_fnc_acreRestore; + + /* Call event script */ + _this execVM "events\onPlayerRespawn.sqf" +}]; + +/* Bring disconnected player back */ +// @TODO: replace spawn and move to respawn +[] spawn { + private _disconUnits = missionNameSpace getVariable [QGVAR(disconUnits), createHashMap]; + private _disconUnit = _disconUnits get (getPlayerUID player); + missionNameSpace setVariable [QGVAR(player_rejip), true, false]; + + if (!isNil "_disconUnit") then { + if ( !EGVAR(gameplay,setting_safestart) || missionNamespace getVariable [QEGVAR(gameplay,safestart_disable), false] ) then { + waitUntil { player getVariable [QGVAR(player_loaded), false] && alive player }; + sleep 0.1; + + /* Set old role (incase they try to rejoin as a different role) */ + [player, (_disconUnit select 0)] call EFUNC(common,setRole); + + /* Set old loadout */ + player setUnitLoadout [(_disconUnit select 3), false]; + + /* Join old group */ + [player] joinSilent (_disconUnit select 1); + + /* Attempt to set the same stance as the squad leader */ + switch (unitPos leader (_disconUnit select 1)) do { + case ("UP"): { player playAction "PlayerStand" }; + case ("MIDDLE"): { player playAction "PlayerCrouch" }; + case ("DOWN"): { player playAction "PlayerProne" }; + }; + + /* Set respawns */ + player setVariable [QEGVAR(respawn,respawns), ((_disconUnit select 4) select 0), true]; + player setVariable [QEGVAR(respawn,deaths), ((_disconUnit select 4) select 1), true]; + + /* set player position and if leader is in vehicle attempt to move into vehicle cargo */ + if (!isNull leader (_disconUnit select 1)) then { + player setPosASL getPosASL leader (_disconUnit select 1); + if (vehicle leader (_disconUnit select 1) != leader (_disconUnit select 1)) then { + player moveInCargo vehicle leader (_disconUnit select 1); + + if (vehicle player == player && (vehicle player) isKindOf "Helicopter") then { + private _groundPos = getposATL player; + _groundPos set [2, 0]; + player setPosATL _groundPos; + }; + }; + }; + + ["Loaded pre-disconnect state"] spawn bis_fnc_dynamicText; + }; + }; +}; + +/* Raise event */ +[QGVAR(player_initialized), []] call CBA_fnc_localEvent; + +INFO_1("Player %1 Initialized!", (name player)); +missionNamespace setVariable [QGVAR(player_initialized), true]; \ No newline at end of file diff --git a/framework/components/main/XEH_postInit.sqf b/framework/components/main/XEH_postInit.sqf new file mode 100644 index 0000000..6f1ef7f --- /dev/null +++ b/framework/components/main/XEH_postInit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +[] call FUNC(addonBlacklist); +[] call FUNC(chatHandler); + +[{ time > 0 }, { + /* On safestart disable event */ + [{ (missionNamespace getVariable [QEGVAR(gameplay,safestart_disable), false]) }, { + [[], "events\onGameStart.sqf"] remoteExec ["execVM", 0, true]; + }] call CBA_fnc_waitUntilAndExecute; + + /* Raise event */ + [QGVAR(mission_initialized), []] call CBA_fnc_globalEvent; +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/main/XEH_serverInit.sqf b/framework/components/main/XEH_serverInit.sqf new file mode 100644 index 0000000..eb40ff5 --- /dev/null +++ b/framework/components/main/XEH_serverInit.sqf @@ -0,0 +1,89 @@ +#include "script_component.hpp" + +LOG_1("Initializing CMF v%1...", VERSION_STR); +missionNamespace setVariable [QGVAR(server_initialized), false, true]; + +/* Print a warning if mission is run in singleplayer */ // @TODO: Move to common +if (is3DENPreview && !is3DENMultiplayer) then { + "CBA_diagnostic_Error" cutRsc ["CBA_diagnostic_Error", "PLAIN"]; + private _control = uiNamespace getVariable "CBA_diagnostic_Error"; + + _control ctrlSetStructuredText composeText [ + lineBreak, parseText "CMF: Singleplayer<\t>", lineBreak, lineBreak, + "Certain parts of CMF might not work in a singleplayer enviroment. Any testing should be done in a multiplayer enviroment!" + ]; +}; + +/* Store CMF Version Number in variable */ +missionNamespace setVariable [QGVAR(version), VERSION_STR, true]; + +/* Change ACE carrying / draggin max carry weight */ // @TODO: Move to common +ACE_maxWeightCarry = 1500; +ACE_maxWeightDrag = 1500; + +/* Disable Shacktac UI groupBar */ // @TODO: Move to common together with STUI settings +STHud_NoSquadBarMode = true; + +/* Disable CTAB on ground vehicles */ // @TODO: Move to common +cTab_vehicleClass_has_FBCB2 = []; + +/* Disable Vietnamese voices from Unsung */ // @TODO: Move to AI +RUG_DSAI_TerminalDistance = -1; + +/* band aid - remove this once they fix PlayerConnected mission event handler */ +// https://forums.bistudio.com/topic/143930-general-discussion-dev-branch/page-942#entry3003074 +["cmf_onMissionStart_opcfix", "onPlayerConnected", {}] call BIS_fnc_addStackedEventHandler; +["cmf_onMissionStart_opcfix", "onPlayerConnected"] call BIS_fnc_removeStackedEventHandler; + +/* Register player */ +addMissionEventHandler ["PlayerConnected", { + private _owner = _this select 4; + + /* Raise event */ + [QGVAR(server_onPlayerConnected), _this] call CBA_fnc_globalEvent; +}]; + +/* Handle disconnects */ // @TODO: Move to common +addMissionEventHandler ["HandleDisconnect", { + params ["_unit", "", "_uid"]; + + /* Save unit loadout, position and direction before disconnect */ + private _disconUnits = missionNameSpace getVariable [QGVAR(disconUnits), createHashMap]; + _disconUnits set [_uid, [[_unit] call EFUNC(common,getRole), group _unit, getDir _unit, getUnitLoadout _unit, [_obj getVariable[QEGVAR(respawn,respawns), -1], _obj getVariable[QEGVAR(respawn,deaths), 0]]]]; + missionNameSpace setVariable [QGVAR(disconUnits), _disconUnits, true]; + + false; +}]; + +/* Share server diagnostic */ // @TODO: Move to common +// @TODO: Replace spawn +[] spawn { + if (!isServer) exitWith {}; + while { true } do { + missionNameSpace setVariable [QGVAR(serverFPS), diag_fps, true]; + missionNameSpace setVariable [QGVAR(serverScripts), diag_activeScripts, true]; + sleep 2; + }; +}; + +/* Report performance when it drops below 15 FPS */ +0 spawn { // @TODO: Move to common + while { true } do { + waitUntil { diag_fps < 15 }; + + // @TODO: Show message to admins + private _activeScripts = diag_activeScripts; + private _warningMessage = format ["Low Server FPS detected: %1 | Spawn: %2 | ExecVM: %3 | Exec: %4 | execFSM: %5", + str diag_fps, str (_activeScripts select 0), str (_activeScripts select 1), str (_activeScripts select 2), str (_activeScripts select 3)]; + + WARNING(_warningMessage); + + sleep 30; + }; +}; + +INFO_1("CMF v%1 Initialized!", VERSION_STR); +missionNamespace setVariable [QGVAR(server_initialized), true, true]; + +/* Raise event */ +[QGVAR(server_initialized), _this] call CBA_fnc_globalEvent; diff --git a/framework/components/main/changelog.sqf b/framework/components/main/changelog.sqf new file mode 100644 index 0000000..97302c8 --- /dev/null +++ b/framework/components/main/changelog.sqf @@ -0,0 +1,26 @@ +" +CMFv2.1.1.56 > CMFv2.1.1.57 + +Added ++ New diagnostics module ++ New settings system ++ Notification function ++ New viewdistance system (to fix lag with old one) ++ Added a RscImports file for UI to keep all imported classes collected ++ Added new logging functions ++ Added function to get closest match from a array of numbers ++ Added function to add keybinds + +Changed +~ Many minor things i no longer remember +~ Freezetime is now toggleable +~ Safestart will now have time frozen until game start +~ Changed how keybinds are listed in CMF diary + +Fixed +~ Bug where hideHud wouldn't work with hotkey +~ Bug with whitelisted URIs + +Removed +- Removed old ACE Medical sub category in favor of ace's own category +" \ No newline at end of file diff --git a/framework/components/main/fn_missionInit.sqf b/framework/components/main/fn_missionInit.sqf deleted file mode 100644 index ad4229f..0000000 --- a/framework/components/main/fn_missionInit.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Initializes mission for CMF (executed postInit). - * - * Public: No - */ -SCRIPT(missionInit); - -/* Wait until mission is initialized */ -waitUntil{ time > 0 }; - -/* On safestart disable event */ -[] spawn { - waitUntil{ (missionNamespace getVariable [QEGVAR(gameplay,safestart_disable), false]) }; - [[], "events\onGameStart.sqf"] remoteExec ["execVM", 0, true]; -}; - -/* Raise event */ -[QGVAR(mission_initialized), []] call CBA_fnc_globalEvent; diff --git a/framework/components/main/fn_playerInit.sqf b/framework/components/main/fn_playerInit.sqf deleted file mode 100644 index d0f5f3d..0000000 --- a/framework/components/main/fn_playerInit.sqf +++ /dev/null @@ -1,83 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Initializes players for CMF (executed when new player connects). - * - * Public: No - */ -SCRIPT(playerInit); - -if (!hasInterface) exitWith {}; - -LOG_1("Initializing player %1...", (name player)); -missionNamespace setVariable [QGVAR(player_initialized), false]; - -/* Disable removing grass */ -tawvd_disablenone = true; - -/* Load ace settings */ -call compile preprocessFileLineNumbers "components\main\initAceSettings.sqf"; - -/* Load Shacktack UI changes */ -call compile preprocessFileLineNumbers "components\main\initSTUISettings.sqf"; - -/* Remove KP ranks ace interactions */ -[] spawn { - while {true} do { - waitUntil{ !isNil{([(ace_interact_menu_ActSelfNamespace getVariable (typeOf player)), ["ACE_SelfActions","KPR_Admin"]] call ace_interact_menu_fnc_findActionNode)} }; - [(typeOf player), 1, ["ACE_SelfActions", "KPR_Admin"]] call ace_interact_menu_fnc_removeActionFromClass; - [(typeOf player), 1, ["ACE_SelfActions", "ACE_Equipment", "KPR_Check"]] call ace_interact_menu_fnc_removeActionFromClass; - [(typeOf player), 1, ["ACE_SelfActions", "KPR_Admin", "KPR_UniformManage"]] call ace_interact_menu_fnc_removeActionFromClass; - [(typeOf player), 1, ["ACE_SelfActions", "KPR_Admin", "KPR_PlayerManage"]] call ace_interact_menu_fnc_removeActionFromClass; - sleep 10; - }; -}; - -/* Load ace interaction menu */ -[] spawn EFUNC(menu,init); - -/* Disable Unsung vietnamese voices */ -RUG_DSAI_TerminalDistance = -1; - -/* Disable AI sentences */ -enableSentences false; - -/* Player killed event */ -player addEventHandler ["Killed", { - /* Save loadout */ - player setVariable [QGVAR(player_loadout), getUnitLoadout player]; - - /* Save group upon player death */ - player setVariable [QGVAR(player_group), (group player)]; - - /* Save team assigned upon player death */ - player setVariable [QGVAR(player_team), (assignedTeam player)]; - - /* Call event script */ - _this execVM "events\onPlayerKilled.sqf" -}]; - -/* Player respawn event */ -player addEventHandler ["Respawn", { - /* Load loadout */ - player setUnitLoadout (player getVariable [QGVAR(player_loadout),[]]); - - /* Only run if players are not spectating */ - if !((player getVariable[QEGVAR(respawn,respawns), 1]) isEqualTo (player getVariable [QEGVAR(respawn,deaths), 0])) then { - /* Join previous group */ - [player] joinSilent (player getVariable [QGVAR(player_group), (group player)]); - - /* Assign previous team */ - player assignTeam (player getVariable [QGVAR(player_team), (assignedTeam player)]); - }; - - - /* Call event script */ - _this execVM "events\onPlayerRespawn.sqf" -}]; - -/* Raise event */ -[QGVAR(player_initialized), []] call CBA_fnc_localEvent; - -INFO_1("Player %1 Initialized!", (name player)); -missionNamespace setVariable [QGVAR(player_initialized), true]; diff --git a/framework/components/main/fn_serverInit.sqf b/framework/components/main/fn_serverInit.sqf deleted file mode 100644 index bde6317..0000000 --- a/framework/components/main/fn_serverInit.sqf +++ /dev/null @@ -1,60 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Initializes Server for CMF (executed preInit). - * - * Public: No - */ -SCRIPT(serverInit); - -if (!isServer) exitWith {}; - -LOG_1("Initializing CMF v%1...", VERSION_STR); -missionNamespace setVariable [QGVAR(server_initialized), false, true]; - -/* Print a warning if mission is run in singleplayer */ -if (is3DENPreview && !is3DENMultiplayer) then { - "CBA_diagnostic_Error" cutRsc ["CBA_diagnostic_Error", "PLAIN"]; - private _control = uiNamespace getVariable "CBA_diagnostic_Error"; - - _control ctrlSetStructuredText composeText [ - lineBreak, parseText "CMF: Singleplayer<\t>", lineBreak, lineBreak, - "Certain parts of CMF might not work in a singleplayer enviroment. Any testing should be done in a multiplayer enviroment!" - ]; -}; - -/* Store CMF Version Number in variable */ -missionNamespace setVariable [QGVAR(version), VERSION_STR]; - -/* Disable removing grass */ -tawvd_disablenone = true; - -/* Disable Shacktac UI groupBar */ -STHud_NoSquadBarMode = true; - -/* Disable CTAB on ground vehicles */ -cTab_vehicleClass_has_FBCB2 = []; - -/* Disable Vietnamese voices from Unsung */ -RUG_DSAI_TerminalDistance = -1; - -/* band aid - remove this once they fix PlayerConnected mission event handler */ -// https://forums.bistudio.com/topic/143930-general-discussion-dev-branch/page-942#entry3003074 -["cmf_onMissionStart_opcfix", "onPlayerConnected", {}] call BIS_fnc_addStackedEventHandler; -["cmf_onMissionStart_opcfix", "onPlayerConnected"] call BIS_fnc_removeStackedEventHandler; - -/* Register player */ -addMissionEventHandler ["PlayerConnected", { - private _owner = _this select 4; - - /* Raise event */ - [QGVAR(server_onPlayerConnected), _this] call CBA_fnc_globalEvent; - - [_this, FUNC(playerInit)] remoteExec ["call", _owner]; -}]; - -INFO_1("CMF v%1 Initialized!", VERSION_STR); -missionNamespace setVariable [QGVAR(server_initialized), true, true]; - -/* Raise event */ -[QGVAR(server_initialized), _this] call CBA_fnc_globalEvent; diff --git a/framework/components/main/functions/fn_acreRestore.sqf b/framework/components/main/functions/fn_acreRestore.sqf new file mode 100644 index 0000000..bc6bfe5 --- /dev/null +++ b/framework/components/main/functions/fn_acreRestore.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" +/* + * Author: MildlyInterested, Eric + * This will restore unit's radio config on respawn. It gets called from fn_playerInit automatically. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_main_fnc_acreRestore + * + * Public: No + */ +params ["_newUnit", "_oldUnit"]; +// @TODO: Move to common +private _oldPTT = [] call acre_api_fnc_getMultiPushToTalkAssignment; +private _oldRadios = ([_oldUnit] call acre_sys_core_fnc_getGear) select { ([_x] call acre_api_fnc_getBaseRadio) != "" }; +private _newRadios = ([_newUnit] call acre_sys_core_fnc_getGear) select { ([_x] call acre_api_fnc_getBaseRadio) != "" }; + +/* If old unit had no radios exit this script */ +if (count _oldRadios isEqualTo 0) exitWith { }; + +/* Get radio config for old radios */ +{ + private _radio = _x; + private _index = _forEachIndex; + + private _baseClass = [_radio] call acre_api_fnc_getBaseRadio; + private _channel = [_radio] call acre_api_fnc_getRadioChannel; + private _volume = [_radio] call acre_api_fnc_getRadioVolume; + private _spatial = [_radio] call acre_api_fnc_getRadioSpatial; + private _ptt = _oldPTT find _radio; + + /* Set config on new radios */ + private _newRadio = _newRadios select { [_x, _baseClass] call acre_api_fnc_isKindOf } select 0; + [_newRadio, _channel] call acre_api_fnc_setRadioChannel; + [_newRadio, _volume] call acre_api_fnc_setRadioVolume; + [_newRadio, _spatial] call acre_api_fnc_setRadioSpatial; + + if (_ptt != -1) then { + private _newPTT = [] call acre_api_fnc_getMultiPushToTalkAssignment; + _newPTT set [_ptt, _newRadio]; + [_newPTT] call acre_api_fnc_setMultiPushToTalkAssignment; + }; + + /* Remove radio from array to avoid duplicates */ + _newRadios deleteAt (_arr find _newRadio); + +} forEach _oldRadios; diff --git a/framework/components/main/fn_addonBlacklist.sqf b/framework/components/main/functions/fn_addonBlacklist.sqf similarity index 73% rename from framework/components/main/fn_addonBlacklist.sqf rename to framework/components/main/functions/fn_addonBlacklist.sqf index 0340773..e8c8017 100644 --- a/framework/components/main/fn_addonBlacklist.sqf +++ b/framework/components/main/functions/fn_addonBlacklist.sqf @@ -18,6 +18,8 @@ SCRIPT(addonBlacklist); if (!isServer) exitWith {}; +// @TODO: Move to common + /* Save server addons to a variable */ private _serverAddons = ("true" configClasses (configFile >> "CfgPatches")) apply { configname _x }; missionNamespace setVariable [QGVAR(serverAddons), _serverAddons, true]; @@ -37,9 +39,10 @@ addMissionEventHandler ["PlayerConnected", { player setVariable [QGVAR(addonDifference), _addonDifference, true]; /* Check if any addons are blacklisted */ - private _addonBlacklist = CONFIG_PARAM_2(SETTINGS,blacklistedAddons); - if (_clientAddons findIf {_x in _addonBlacklist} != -1) then { + private _illegalAddons = _clientAddons select { _x in EGVAR(common,setting_blacklistedAddons) }; + if (_clientAddons findIf { _x in EGVAR(common,setting_blacklistedAddons) } != -1) then { + [format ["%1 has been blacklisted! Please remove it from your modset to join the server", (_illegalAddons joinString ", ")], "Blacklisted Addon", true, false] call BIS_fnc_guiMessage; QGVAR(blacklistedAddon) call BIS_fnc_endMission; }; - }] remoteExec ["call", _owner]; + }] remoteExec ["spawn", _owner]; }]; diff --git a/framework/components/main/functions/fn_changelog.sqf b/framework/components/main/functions/fn_changelog.sqf new file mode 100644 index 0000000..734ca60 --- /dev/null +++ b/framework/components/main/functions/fn_changelog.sqf @@ -0,0 +1,49 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Shows a changelog if there is a new version of CMF since last time + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_main_fnc_changelog + * + * Public: No + */ + +addMissionEventHandler ["Map", { + params ["_mapIsOpened", "_mapIsForced"]; + + private _lastVersion = profileNamespace getVariable [QGVAR(changelog_lastVersion), "0.0.0.0"]; + private _disabled = profileNamespace getVariable [QGVAR(changelog_off), false]; + private _curVersion = GVAR(version); + + if !(([_lastVersion, _curVersion] call EFUNC(utility,versionCompare)) isEqualTo 1 && _disabled isEqualTo 0) exitWith {}; + + if (_mapIsOpened && !isNull ((findDisplay 12) displayCtrl 88800)) then { + /* Show warning if server version is older than the latest CMF version */ + if ([_lastVersion, _curVersion] call EFUNC(utility,versionCompare) isEqualTo -1) then { + [format ["Version Mismatch! (Machine: %1 (%4) version: %3, serverVersion: %2)", player, _curVersion, _lastVersion, name player], "CMF", [CBA_display_ingame_warnings, true, true]] call CBA_fnc_debug; + }; + + private _display = (findDisplay 12) createDisplay QGVAR(changelogDisplay); + + waitUntil {!isNull _display}; + private _changelog = call compile preprocessFileLineNumbers "components\main\changelog.sqf"; + _changelogLines = _changelog splitString toString [13,10]; + _changelog = _changelogLines joinString "
"; + + (_display displayCtrl 100) ctrlSetStructuredText parseText _changelog; + private _height = (count _changelogLines) * 0.038; + + (_display displayCtrl 100) ctrlSetPositionH _height; + (_display displayCtrl 100) ctrlCommit 0; + }; + + profileNamespace setVariable [QGVAR(changelog_lastVersion), _curVersion]; + removeMissionEventHandler ["Map", _thisEventHandler]; +}]; diff --git a/framework/components/main/functions/fn_chatHandler.sqf b/framework/components/main/functions/fn_chatHandler.sqf new file mode 100644 index 0000000..4a0c6c8 --- /dev/null +++ b/framework/components/main/functions/fn_chatHandler.sqf @@ -0,0 +1,63 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Handles chat messages + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_main_fnc_chatHandler + * + * Public: No + */ + +/* Own join message */ // @TODO: Move to common +if (hasInterface) then { + // @TODO: replace spawn + _this spawn { + private _sideLUT = ["OPFOR", "BLUFOR", "INDEPENDENT", "CIVILIAN", "UNKNOWN", "ENEMY", "FRIENDLY", "LOGIC", "EMPTY", "AMBIENT"]; + + waitUntil { !isNull player }; + + private _roleDescription = "Unknown"; + if (roleDescription player != "") then { + _roleDescription = ((roleDescription player) splitString "@") select 0; + }; + + private _disconUnits = missionNameSpace getVariable [QGVAR(disconUnits), createHashMap]; + private _disconUnit = _disconUnits get (getPlayerUID player); + + if (!isNil "_disconUnit") then { + if ( !EGVAR(gameplay,setting_safestart) || missionNamespace getVariable [QEGVAR(gameplay,safestart_disable), false] ) then { + [format ["%1 Re-jipped", name player]] remoteExec ["systemChat", 0, false]; + } else { + [format ["%1 Joined %2 in ""%3"" as a ""%4""", name player, _sideLUT select ((side player) call BIS_fnc_sideID), groupID group player, _roleDescription]] remoteExec ["systemChat", 0, false]; + }; + } else { + [format ["%1 Joined %2 in ""%3"" as a ""%4""", name player, _sideLUT select ((side player) call BIS_fnc_sideID), groupID group player, _roleDescription]] remoteExec ["systemChat", 0, false]; + }; + + }; +}; + +/* Stop vanilla connected messages */ +addMissionEventHandler ["HandleChatMessage", { + params ["_channel", "_owner", "_from", "_text"]; + + private _return = false; + + if (" CONNECTED" in toUpper _text) then { + private _name = (_text splitString " "); + _name deleteAt 0; + _name deleteAt (count _name - 1); + _name = _name joinString " "; + private _message = format ["%1 in lobby selection", _name]; + _return = ["", _message]; + }; + + _return +}]; diff --git a/framework/components/main/functions/fn_fortify.sqf b/framework/components/main/functions/fn_fortify.sqf new file mode 100644 index 0000000..f4bdee5 --- /dev/null +++ b/framework/components/main/functions/fn_fortify.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Modify ACEX Fortify + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_main_fnc_fortify + * + * Public: No + */ + +/* On deployment start */ +["acex_fortify_onDeployStart", { + params ["_unit", "_object", "_cost"]; + missionNamespace setVariable [QEGVAR(gameplay,safestart_override), true, false]; +}] call CBA_fnc_addEventHandler; + +/* On deployment object placed */ +["ace_fortify_deployFinished", { + params ["_unit", "_side", "_objectClass", "_pos", "_vectorDir", "_vectorUp"]; + missionNamespace setVariable [QEGVAR(gameplay,safestart_override), false, false]; +}] call CBA_fnc_addEventHandler; + +/* On deployment cancelled */ +["ace_fortify_deployCanceled", { + params ["_unit", "_side", "_objectClass", "_pos", "_vectorDir", "_vectorUp"]; + missionNamespace setVariable [QEGVAR(gameplay,safestart_override), false, false]; +}] call CBA_fnc_addEventHandler; diff --git a/framework/components/main/fn_localize.sqf b/framework/components/main/functions/fn_localize.sqf similarity index 91% rename from framework/components/main/fn_localize.sqf rename to framework/components/main/functions/fn_localize.sqf index f2d196e..2dcddea 100644 --- a/framework/components/main/fn_localize.sqf +++ b/framework/components/main/functions/fn_localize.sqf @@ -30,6 +30,13 @@ private _hashStringtable = [(call compile preProcessFileLineNumbers _stringtable /* Get string entry from stringtable */ private _stringHash = [_hashStringtable, _string] call CBA_fnc_hashGet; + +/* Check if string exists */ +if (isNil "_stringHash") exitWith { + WARNING_1("Failed to localize %1", _string); + _string +}; + _stringHash = [_stringHash] call CBA_fnc_hashCreate; /* Check if string exists */ diff --git a/framework/components/main/functions/script_component.hpp b/framework/components/main/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/main/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/main/initAceSettings.sqf b/framework/components/main/initAceSettings.sqf index d1e4dce..781504c 100644 --- a/framework/components/main/initAceSettings.sqf +++ b/framework/components/main/initAceSettings.sqf @@ -7,22 +7,66 @@ */ SCRIPT(initAceSettings); -private _medicalEquipment = [ - "kat_aatKit", "kat_accuvac", "kat_X_AED", "Attachable_Helistretcher", "kat_AED", "adv_aceCPR_AED", "kat_crossPanel", "ACE_bloodIV", "kat_bloodIV_O", "kat_bloodIV_A", "kat_bloodIV_AB", "kat_bloodIV_B", "ACE_bloodIV_250", "kat_bloodIV_O_250", "kat_bloodIV_A_250", "kat_bloodIV_AB_250", "kat_bloodIV_B_250", "ACE_bloodIV_500", "kat_bloodIV_O_500", "kat_bloodIV_A_500", "kat_bloodIV_AB_500", "kat_bloodIV_B_500", "ACE_bodyBag", "usm_fielddressing", - "KAT_Empty_bloodIV_250", "KAT_Empty_bloodIV_500", "FirstAidKit", "Medikit", "ACE_salineIV", "ACE_salineIV_250", "ACE_salineIV_500", "vtx_stretcher_item", "ACE_adenosine", "ACE_fieldDressing", "ACE_elasticBandage", "ACE_packingBandage", "ACE_quikclot", "kat_chestSeal", "ACE_epinephrine", "kat_guedel", "kat_larynx", "ACE_morphine", "ACE_personalAidKit", "ACE_plasmaIV", "ACE_plasmaIV_250", "ACE_plasmaIV_500", "ACE_splint", "kat_stethoscope", - "ACE_surgicalKit", "ACE_tourniquet", "kat_IV_16", "kat_amiodarone", "kat_atropine", "kat_IO_FAST", "kat_lidocaine", "kat_naloxone", "kat_nitroglycerin", "kat_norepinephrine", "kat_phenylephrine", "kat_TXA", "kat_Pulseoximeter", "kat_bloodIV_O_N", "kat_bloodIV_A_N", "kat_bloodIV_AB_N", "kat_bloodIV_B_N", "kat_bloodIV_O_250_N", "kat_bloodIV_A_250_N", "kat_bloodIV_AB_250_N", "kat_bloodIV_B_250_N", "kat_bloodIV_O_500_N", "kat_bloodIV_A_500_N", - "kat_bloodIV_AB_500_N", "kat_bloodIV_B_500_N" -]; - private _radioEquipment = [ "ACRE_PRC117F", "ACRE_PRC148", "ACRE_PRC152", "ACRE_PRC343", "ACRE_PRC77", "ACRE_SEM52SL", "ACRE_SEM70", "ACRE_VHF30108SPIKE", "ACRE_VHF30108", "ACRE_VHF30108MAST", "ACRE_BF888S" ]; -/* Create medical submenu */ -[_medicalEquipment, "Medical", "\z\ace\addons\medical_gui\data\categories\medication.paa", 0] call ace_arsenal_fnc_addRightPanelButton; - /* Create radio submenu */ [_radioEquipment, "Radios", "\a3\Ui_f\data\GUI\Cfg\CommunicationMenu\call_ca.paa", 1] call ace_arsenal_fnc_addRightPanelButton; +/* Set map gesture group colors */ +if (!is3DEN) then { + ["CAManBase", "init", { + params ["_unit"]; + + private _group = group _unit; + if (!isNil { ace_map_gestures_GroupColorCfgMappingNew getVariable [groupID _group, nil] }) exitWith { }; + + private _infantryColors = [ + ["ASL", [1,0,0,0.7], [1,0,0,0.95]], + ["A1", [1,0,0,0.7], [1,0,0,0.95]], + ["A2", [1,0,0,0.7], [1,0,0,0.95]], + ["A3", [1,0,0,0.7], [1,0,0,0.95]], + ["BSL", [0,1,0,0.7], [0,1,0,0.95]], + ["B1", [0,1,0,0.7], [0,1,0,0.95]], + ["B2", [0,1,0,0.7], [0,1,0,0.95]], + ["B3", [0,1,0,0.7], [0,1,0,0.95]], + ["CSL", [0,0,1,0.7], [0,0,1,0.95]], + ["C1", [0,0,1,0.7], [0,0,1,0.95]], + ["C2", [0,0,1,0.7], [0,0,1,0.95]], + ["C3", [0,0,1,0.7], [0,0,1,0.95]], + ["DSL", [0.5,0,0,0.7], [0.5,0,0,0.95]], + ["D1", [0.5,0,0,0.7], [0.5,0,0,0.95]], + ["D2", [0.5,0,0,0.7], [0.5,0,0,0.95]], + ["D3", [0.5,0,0,0.7], [0.5,0,0,0.95]], + ["ESL", [0,0.5,0,0.7], [0,0.5,0,0.95]], + ["E1", [0,0.5,0,0.7], [0,0.5,0,0.95]], + ["E2", [0,0.5,0,0.7], [0,0.5,0,0.95]], + ["E3", [0,0.5,0,0.7], [0,0.5,0,0.95]], + ["FSL", [0,0.3,0.6,0.7], [0,0.3,0.6,0.95]], + ["F1", [0,0.3,0.6,0.7], [0,0.3,0.6,0.95]], + ["F2", [0,0.3,0.6,0.7], [0,0.3,0.6,0.95]], + ["F3", [0,0.3,0.6,0.7], [0,0.3,0.6,0.95]], + ["PLT HQ", [1,1,0,0.7], [1,1,0,0.95]], + ["COY HQ", [0.05,0.05,0.05,0.7], [0.05,0.05,0.05,0.95]], + ["SIERRA", [0.85,0.4,0,0.7], [0.85,0.4,0,0.95]], + ["MIKE", [0.85,0.4,0,0.7], [0.85,0.4,0,0.95]], + ["TANGO", [0.85,0.4,0,0.7], [0.85,0.4,0,0.95]], + ["ANVIL", [0.85,0.4,0,0.7], [0.85,0.4,0,0.95]], + ["PHANTOM", [0,0,1,0.7], [0,0,1,0.95]], + ["REAPER", [0,0,1,0.7], [0,0,1,0.95]], + ["UGLY", [0,0,1,0.7], [0,0,1,0.95]], + ["HAWG", [0.85,0.64,0.12,0.7], [0.85,0.64,0.12,0.95]], + ["PAVEMENT", [0.85,0.64,0.12,0.7], [0.85,0.64,0.12,0.95]] + ]; + + private _index = _infantryColors findIf { (_x select 0) in toUpper (groupID _group) }; + if (_index > -1) then { + private _groupColors = _infantryColors select _index; + [groupID _group, _groupColors select 1, _groupColors select 2] call ace_map_gestures_fnc_addGroupColorMapping; + }; + }, true, [], true] call CBA_fnc_addClassEventHandler; +}; + /* Raise event */ -[QGVAR(onAddedAceSettings), [[0, "Medical", _medicalEquipment], [1, "Radios", _radioEquipment]]] call CBA_fnc_localEvent; +[QGVAR(onAddedAceSettings), [[0, "Radios", _radioEquipment]]] call CBA_fnc_localEvent; diff --git a/framework/components/main/initSTUISettings.sqf b/framework/components/main/initSTUISettings.sqf index 47f8447..cb4e334 100644 --- a/framework/components/main/initSTUISettings.sqf +++ b/framework/components/main/initSTUISettings.sqf @@ -1,51 +1,54 @@ #include "script_component.hpp" /* - * Author: Eric + * Author: Dsylexci, Eric * Orders the group playerlist by color and leader * * Public: No */ SCRIPT(initSTUISettings); -/* Redefine the namelist function */ +// @TODO: Change so invisible units don't show on the stui +// @TODO: Change so fireteam level teams (XSL, X1 and X2) show on the list of grouped players + +/* Order the name list based on color team */ STHud_Namelist = { params ["_canvas"]; private _units = []; { - if (count(_units) >= count(STHud_Namepos)) exitWith {}; + if (count(_units) >= count(STHud_Namepos)) exitWith {}; - if (alive(_x) || {!isNil {_x getVariable "sth_name"}}) then { - _units pushBack [_x, _x call STHud_Colour_Text]; - }; + if (alive(_x) || {!isNil {_x getVariable "sth_name"}}) then { + _units pushBack [_x, _x call STHud_Colour_Text]; + }; } forEach (units(player)); private _unitsCount = count(_units); // Could expand this to check if the player is a driver, gunner, or commander, but I don't recall what exactly is needed to check to catch multiple turrets etc while excluding FFV. if (STHud_ShowBearingInVehicle && {vehicle player != player}) then { - private _viewVec = positionCameratoWorld [0,0,0] vectorFromTo (positionCameraToWorld [0,0,50]); - private _bearing = ((_viewVec select 0) atan2 (_viewVec select 1) + 360) % 360; - - private _bearingBase = (str round _bearing); - private _bearingPretty = ""; - - switch (count _bearingBase) do - { - case 1: {_bearingPretty = "00" + _bearingBase}; - case 2: {_bearingPretty = "0" + _bearingBase}; - case 3: {_bearingPretty = _bearingBase}; - }; - - private _bearingColour = [[1,1,1,.9], "STUI_Unconscious_Fade_HUD_Bearing"] call STHud_UnconsciousColourFade; - - _canvas drawIcon - [ - "#(argb,8,8,3)color(0,0,0,0)", _bearingColour, - STHud_Bearing, - 16, 16, 0, - _bearingPretty, STHud_TextShadow, 0.035, STHud_Font, "Center" - ]; + private _viewVec = positionCameratoWorld [0,0,0] vectorFromTo (positionCameraToWorld [0,0,50]); + private _bearing = ((_viewVec select 0) atan2 (_viewVec select 1) + 360) % 360; + + private _bearingBase = (str round _bearing); + private _bearingPretty = ""; + + switch (count _bearingBase) do + { + case 1: {_bearingPretty = "00" + _bearingBase}; + case 2: {_bearingPretty = "0" + _bearingBase}; + case 3: {_bearingPretty = _bearingBase}; + }; + + private _bearingColour = [[1,1,1,.9], "STUI_Unconscious_Fade_HUD_Bearing"] call STHud_UnconsciousColourFade; + + _canvas drawIcon + [ + "#(argb,8,8,3)color(0,0,0,0)", _bearingColour, + STHud_Bearing, + 16, 16, 0, + _bearingPretty, STHud_TextShadow, 0.035, STHud_Font, "Center" + ]; }; if (_unitsCount == 1) exitWith {}; @@ -53,73 +56,181 @@ STHud_Namelist = { private _fullName = _unitsCount < 7; _units = [_units, [], { - if ((leader group (_x select 0)) isEqualTo (_x select 0)) exitWith { 0 }; - if ((assignedTeam leader group (_x select 0)) isEqualTo (assignedTeam (_x select 0))) exitWith { 1 }; - switch (_x select 1) do { - case [1,1,1,1]: { 2 }; - case [1,1,0.67,1]: { 3 }; - case [1,0.67,0.67,1]: { 4 }; - case [0.67,1,0.67,1]: { 5 }; - case [0.67,0.67,1,1]: { 6 }; - default { 5 }; - }; + if ((leader group (_x select 0)) isEqualTo (_x select 0)) exitWith { 0 }; + if ((assignedTeam leader group (_x select 0)) isEqualTo (assignedTeam (_x select 0))) exitWith { 1 }; + switch (_x select 1) do { + case [1,1,1,1]: { 2 }; + case [1,1,0.67,1]: { 3 }; + case [1,0.67,0.67,1]: { 4 }; + case [0.67,1,0.67,1]: { 5 }; + case [0.67,0.67,1,1]: { 6 }; + default { 5 }; + }; }] call BIS_fnc_sortBy; { - _x params ["_unit", "_colour"]; - private _isUnitSelected = if ([player] call STHUD_IsGroupLeader) then {_unit in (groupSelectedUnits player)} else {false}; // Check if they're leader, if not, ignore. - private _selIndicator = ""; - if (_isUnitSelected) then { _selIndicator = "> " }; // Tried this on the left and right. Being on the left seems to make it 'pop' more. - private _icon = [_unit, false] call STHud_Icon; - - private _finalName = ([_unit, _fullName] call STHud_GetName); - - if (STHud_NoSquadBarMode) then {_finalName = _selIndicator + _finalName;}; - - if (count (groupSelectedUnits player) > 0 && STHud_NoSquadBarMode) then - { - private _tempName = vehicleVarName _unit; - _unit setVehicleVarName ""; - private _strName = str(_x); - _unit setVehicleVarName _tempName; - private _pl = _strName find ":"; - private _numStr = _strName select [_pl +1,2]; - if (_numStr find "," > -1 || _numStr find " " > -1) then {_numStr = _numStr select [0,1]}; - - private _selectedUnitsColour = [[1,1,1,1], "STUI_Unconscious_Fade_HUD_SelectedUnits"] call STHud_UnconsciousColourFade; - - _canvas drawIcon - [ - "#(argb,1,1,1)color(0,0,0,0)", _selectedUnitsColour, - STHud_Selectpos select _forEachIndex, - 1, 1, 0, - _numStr, STHud_TextShadow, 0.035, STHud_Font, "Left" - ]; - }; - - private _nameColour = [_colour, "STUI_Unconscious_Fade_HUD_Names"] call STHud_UnconsciousColourFade; - - _canvas drawIcon - [ - _icon, _nameColour, - STHud_Namepos select _forEachIndex, - 16, 16, 0, - _finalName, STHud_TextShadow, 0.035, STHud_Font, "Right" - ]; + _x params ["_unit", "_colour"]; + private _isUnitSelected = if ([player] call STHUD_IsGroupLeader) then {_unit in (groupSelectedUnits player)} else {false}; // Check if they're leader, if not, ignore. + private _selIndicator = ""; + if (_isUnitSelected) then { _selIndicator = "> " }; // Tried this on the left and right. Being on the left seems to make it 'pop' more. + private _icon = [_unit, false] call STHud_Icon; + + private _finalName = ([_unit, _fullName] call STHud_GetName); + + if (STHud_NoSquadBarMode) then {_finalName = _selIndicator + _finalName;}; + + if (count (groupSelectedUnits player) > 0 && STHud_NoSquadBarMode) then + { + private _tempName = vehicleVarName _unit; + _unit setVehicleVarName ""; + private _strName = str(_x); + _unit setVehicleVarName _tempName; + private _pl = _strName find ":"; + private _numStr = _strName select [_pl +1,2]; + if (_numStr find "," > -1 || _numStr find " " > -1) then {_numStr = _numStr select [0,1]}; + + private _selectedUnitsColour = [[1,1,1,1], "STUI_Unconscious_Fade_HUD_SelectedUnits"] call STHud_UnconsciousColourFade; + + _canvas drawIcon + [ + "#(argb,1,1,1)color(0,0,0,0)", _selectedUnitsColour, + STHud_Selectpos select _forEachIndex, + 1, 1, 0, + _numStr, STHud_TextShadow, 0.035, STHud_Font, "Left" + ]; + }; + + private _nameColour = [_colour, "STUI_Unconscious_Fade_HUD_Names"] call STHud_UnconsciousColourFade; + + _canvas drawIcon + [ + _icon, _nameColour, + STHud_Namepos select _forEachIndex, + 16, 16, 0, + _finalName, STHud_TextShadow, 0.035, STHud_Font, "Right" + ]; } forEach (_units); if (count (groupSelectedUnits player) > 0 && STHud_NoSquadBarMode) then { - private _groupNameColour = [[1,1,1,1], "STUI_Unconscious_Fade_HUD_GroupName"] call STHud_UnconsciousColourFade; - - _canvas drawIcon - [ - "#(argb,1,1,1)color(0,0,0,0)", _groupNameColour, - STHud_GroupNamePos, - 16, 16, 0, - group(player) getVariable ["STMF_GroupID", ""], STHud_TextShadow, 0.035, STHud_Font, "Right" - ]; + private _groupNameColour = [[1,1,1,1], "STUI_Unconscious_Fade_HUD_GroupName"] call STHud_UnconsciousColourFade; + + _canvas drawIcon + [ + "#(argb,1,1,1)color(0,0,0,0)", _groupNameColour, + STHud_GroupNamePos, + 16, 16, 0, + group(player) getVariable ["STMF_GroupID", ""], STHud_TextShadow, 0.035, STHud_Font, "Right" + ]; + }; +}; + +/* Set icon dynamically */ +STHud_IsAttendant = { + params ["_type", "_unit"]; + (getNumber(configFile >> "CfgVehicles" >> _type >> "attendant") == 1) || (_unit getVariable ["ace_medical_medicClass", 0] > 0); +}; + +STHud_IsEngineer = { + params ["_type", "_unit"]; + (getNumber(configFile >> "CfgVehicles" >> _type >> "engineer") == 1) || (_unit getVariable ["ACE_IsEngineer", 0] > 0); +}; + +STHud_IsEOD = { + params ["_type", "_unit"]; + (getNumber(configFile >> "CfgVehicles" >> _type >> "canDeactivateMines") == 1) || (_unit getVariable ["ACE_IsEOD", 0] > 0); +}; + +STHud_Icon = { + params ["_unit", ["_disableVehicleIcons", true]]; + + //checking if the player is in a vehicle and if vehicle role icons are disabled + //we only want to change the role icon next to their name on the HUD + if (vehicle _unit != _unit && !_disableVehicleIcons) exitWith { + //selecting this specific _unit from vehicle crew array and determining role + private _crewInfo = ((fullCrew (vehicle _unit)) select {_x select 0 isEqualTo _unit}) select 0; + _crewInfo params ["", "_role", "_index", "_turretPath", "_isTurret"]; + if (_role == "cargo") exitWith { + "a3\ui_f\data\igui\cfg\commandbar\imagecargo_ca.paa" + }; + + if (_role == "driver") exitWith { + if (vehicle _unit isKindOf "Air") then { + //no suitable icons for this so we are using a resized one + "@stui\addons\grouphud\imagepilot_ca.paa" + } else { + "a3\ui_f\data\igui\cfg\commandbar\imagedriver_ca.paa" + }; + }; + + //FFV + if (_role == "turret" && _isTurret) exitWith { + "a3\ui_f\data\igui\cfg\simpletasks\types\rifle_ca.paa" + }; + + //gunners and sometimes copilots + if (_role == "gunner" || (_role == "turret" && !_isTurret)) exitWith { + "a3\ui_f\data\igui\cfg\commandbar\imagegunner_ca.paa" + }; + + if (_role == "commander") exitWith { + "a3\ui_f\data\igui\cfg\commandbar\imagecommander_ca.paa" + }; + }; + + if (leader(_unit) == _unit) exitWith { + "\A3\ui_f\data\map\vehicleicons\iconManLeader_ca.paa"; + }; + + private _type = typeof(_unit); + private _isatd = player getVariable ("isatd_"+_type); + _isatd = [_type, _unit] call STHud_IsAttendant; + player setVariable ["isatd_" + _type, _isatd]; + if (_isatd) exitWith { + "\A3\ui_f\data\map\vehicleicons\iconManMedic_ca.paa"; + }; + + private _type = typeof(_unit); + private _iseng = player getVariable ("iseng_"+_type); + _iseng = [_type, _unit] call STHud_IsEngineer; + player setVariable ["iseng_" + _type, _iseng]; + if (_iseng) exitWith { + "\A3\ui_f\data\map\vehicleicons\iconManEngineer_ca.paa"; + }; + + private _type = typeof(_unit); + private _isEOD = player getVariable ("isEOD_"+_type); + _isEOD = [_type, _unit] call STHud_IsEOD; + player setVariable ["isEOD_" + _type, _isEOD]; + if (_isEOD) exitWith { + "\A3\ui_f\data\map\vehicleicons\iconManExplosive_ca.paa"; + }; + + private _prim = primaryWeapon(_unit); + private _ismg = player getVariable ("ismg_" + _prim); + if (isNil {_ismg}) then { + _ismg = _prim call STHud_IsMG; + player setVariable ["ismg_" + _prim, _ismg]; }; + + if (_ismg) exitWith { + "\A3\ui_f\data\map\vehicleicons\iconManMG_ca.paa"; + }; + + private _BadArr = ["UK3CB_BAF_L16_Tripod", "UK3CB_BAF_L111A1", "UK3CB_BAF_L134A1", "UK3CB_BAF_M6", "UK3CB_BAF_Tripod"]; + private _sec = secondaryWeapon(_unit); + private _isat = player getVariable ("isat_"+_sec); + if (isNil {_isat}) then { + if ((_BadArr find _sec) <= 0) then { + _isat = _sec call STHud_IsAT; + }; + player setVariable ["isat_"+_sec, _isat]; + }; + if (_isat and !_ismg and !_isEOD and !_isatd and !_iseng) exitWith { + "\A3\ui_f\data\map\vehicleicons\iconManAT_ca.paa"; + }; + + STHud_BGIcon; }; /* Raise event */ diff --git a/framework/components/main/script_component.hpp b/framework/components/main/script_component.hpp index fc423cf..2e3ec5c 100644 --- a/framework/components/main/script_component.hpp +++ b/framework/components/main/script_component.hpp @@ -1,5 +1,6 @@ #ifndef MODULE #define MODULE main + #define MODULE_BEAUTIFIED Main #endif #define REQUIRED_ADDONS [] @@ -7,8 +8,12 @@ #include "script_mod.hpp" -/* Define Debug mode */ -// #define DEBUG_MODE_FULL -// #define DEBUG_SYSTEMCHAT +#ifdef DEBUG_ENABLED_MAIN + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_MAIN + #define DEBUG_SETTINGS DEBUG_SETTINGS_MAIN +#endif #include "script_macros.hpp" diff --git a/framework/components/main/script_macros.hpp b/framework/components/main/script_macros.hpp index db3fb2a..fd25273 100644 --- a/framework/components/main/script_macros.hpp +++ b/framework/components/main/script_macros.hpp @@ -22,6 +22,11 @@ #define QQGVAR(var1) QUOTE(QGVAR(var1)) #define QQEGVAR(var1,var2) QUOTE(QEGVAR(var1,var2)) +// @TODO: replace ACE, CBA and BIS functions with these macros +#define ACEFUNC(var1,var2) TRIPLES(DOUBLES(ace,var1),fnc,var2) +#define CBAFUNC(var1) TRIPLES(CBA,fnc,var1) +#define BISFUNC(var1) TRIPLES(BIS,fnc,var1) + #define FUNC(var1) TRIPLES(DOUBLES(PREFIX,MODULE),fnc,var1) #define FUNCMAIN(var1) TRIPLES(PREFIX,fnc,var1) #define FUNC_INNER(var1,var2) TRIPLES(DOUBLES(PREFIX,var1),fnc,var2) @@ -36,7 +41,7 @@ #define QQEFUNC(var1,var2) QUOTE(QEFUNC(var1,var2)) #ifndef PATHTO_SYS - #define PATHTO_SYS(var1,var2) components\var1\var2.sqf + #define PATHTO_SYS(var1,var2) components\var1\functions\var2.sqf #endif #ifndef PATHTOF_SYS @@ -45,8 +50,8 @@ #define DSTRING(var1) QUOTE(TRIPLES(STR,COMPONENT,var1)) #define EDSTRING(var1,var2) QUOTE(TRIPLES(STR,DOUBLES(PREFIX,var1),var2)) -#define LSTRING(var1) ([QUOTE(PATHTO_SYS(MODULE,stringtable)), DSTRING(var1)] call EFUNC(main,localize)) -#define ELSTRING(var1,var2) ([QUOTE(PATHTO_SYS(var1,stringtable)), EDSTRING(var1,var2)] call EFUNC(main,localize)) +#define LSTRING(var1) ([QUOTE(PATHTOF_SYS(MODULE,stringtable.sqf)), DSTRING(var1)] call EFUNC(main,localize)) +#define ELSTRING(var1,var2) ([QUOTE(PATHTOF_SYS(var1,stringtable.sqf)), EDSTRING(var1,var2)] call EFUNC(main,localize)) #define ARRAY_FLATTEN(var1) (flatten var1) @@ -63,22 +68,12 @@ FUNC(var1) = {ERROR_1("%1 missing a required addon.",QFUNC(var1))}\ } -#define PREP(var1) PREP_ADDON(var1) -#define IPREP(var1) PREP(var1); [] spawn {waitUntil { missionNamespace getVariable [QEGVAR(main,components_initialized), false] }; [] spawn FUNC(var1)} +#define PREP(var1) if (!is3DEN) then { PREP_ADDON(var1) } else { PREP_SYS(var1) } #define FILE_EXISTS(FILE) (fileExists (FILE)) #define MISSION_PATH(FILE) (getMissionPath (FILE)) -#define CONFIG_PARAM_1(ARG1) ([[QUOTE(ARG1)]] call EFUNC(common,getConfigParam)) -#define CONFIG_PARAM_2(ARG1, ARG2) ([[QUOTE(ARG1), QUOTE(ARG2)]] call EFUNC(common,getConfigParam)) -#define CONFIG_PARAM_3(ARG1, ARG2, ARG3) ([[QUOTE(ARG1), QUOTE(ARG2), QUOTE(ARG3)]] call EFUNC(common,getConfigParam)) -#define CONFIG_PARAM_4(ARG1, ARG2, ARG3, ARG4) ([[QUOTE(ARG1), QUOTE(ARG2), QUOTE(ARG3), QUOTE(ARG4)]] call EFUNC(common,getConfigParam)) -#define CONFIG_PARAM_5(ARG1, ARG2, ARG3, ARG4, ARG5) ([[QUOTE(ARG1), QUOTE(ARG2), QUOTE(ARG3), QUOTE(ARG4), QUOTE(ARG5)]] call EFUNC(common,getConfigParam)) -#define CONFIG_PARAM_6(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) ([[QUOTE(ARG1), QUOTE(ARG2), QUOTE(ARG3), QUOTE(ARG4), QUOTE(ARG5), QUOTE(ARG6)]] call EFUNC(common,getConfigParam)) -#define CONFIG_PARAM_7(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) ([[QUOTE(ARG1), QUOTE(ARG2), QUOTE(ARG3), QUOTE(ARG4), QUOTE(ARG5), QUOTE(ARG6), QUOTE(ARG7)]] call EFUNC(common,getConfigParam)) -#define CONFIG_PARAM_8(ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) ([[QUOTE(ARG1), QUOTE(ARG2), QUOTE(ARG3), QUOTE(ARG4), QUOTE(ARG5), QUOTE(ARG6), QUOTE(ARG7), QUOTE(ARG8)]] call EFUNC(common,getConfigParam)) - #define CREATE_HASH_FROM_ARRAY(var1) (createHashMapFromArray var1) #define SCRIPT(NAME) scriptName 'components\MODULE\NAME' @@ -140,7 +135,7 @@ Macros: DEBUG_MODE_x #ifdef DEBUG_SYNCHRONOUS #define LOG_RPT(LEVEL,MESSAGE) diag_log text LOG_SYS_FORMAT(LEVEL,MESSAGE) #else - #define LOG_RPT(LEVEL,MESSAGE) LOG_SYS_FORMAT(LEVEL,MESSAGE) call CBA_fnc_log + #define LOG_RPT(LEVEL,MESSAGE) LOG_SYS_FORMAT(LEVEL,MESSAGE) call EFUNC(diagnostic,log) #endif // if defined should log to systemChat aswell @@ -249,7 +244,7 @@ Macro: ERROR_MSG() Parameters: MESSAGE - Message to record ------------------------------------------- */ -#define ERROR_MSG(MESSAGE) ['PREFIX', 'COMPONENT', nil, MESSAGE, __FILE__, __LINE__ + 1] call CBA_fnc_error +#define ERROR_MSG(MESSAGE) ['PREFIX', 'COMPONENT', nil, MESSAGE, __FILE__, __LINE__ + 1] call EFUNC(diagnostic,error) #define ERROR_MSG_1(MESSAGE,ARG1) ERROR_MSG(FORMAT_1(MESSAGE,ARG1)) #define ERROR_MSG_2(MESSAGE,ARG1,ARG2) ERROR_MSG(FORMAT_2(MESSAGE,ARG1,ARG2)) #define ERROR_MSG_3(MESSAGE,ARG1,ARG2,ARG3) ERROR_MSG(FORMAT_3(MESSAGE,ARG1,ARG2,ARG3)) @@ -268,7 +263,7 @@ Macro: ERROR_WITH_TITLE() TITLE - Title of error message MESSAGE - Body of error message ------------------------------------------- */ -#define ERROR_WITH_TITLE(TITLE,MESSAGE) ['PREFIX', 'COMPONENT', TITLE, MESSAGE, __FILE__, __LINE__ + 1] call CBA_fnc_error +#define ERROR_WITH_TITLE(TITLE,MESSAGE) ['PREFIX', 'COMPONENT', TITLE, MESSAGE, __FILE__, __LINE__ + 1] call EFUNC(diagnostic,error) #define ERROR_WITH_TITLE_1(TITLE,MESSAGE,ARG1) ERROR_WITH_TITLE(TITLE,FORMAT_1(MESSAGE,ARG1)) #define ERROR_WITH_TITLE_2(TITLE,MESSAGE,ARG1,ARG2) ERROR_WITH_TITLE(TITLE,FORMAT_2(MESSAGE,ARG1,ARG2)) #define ERROR_WITH_TITLE_3(TITLE,MESSAGE,ARG1,ARG2,ARG3) ERROR_WITH_TITLE(TITLE,FORMAT_3(MESSAGE,ARG1,ARG2,ARG3)) diff --git a/framework/components/main/script_mod.hpp b/framework/components/main/script_mod.hpp index 57ca2a2..f62f536 100644 --- a/framework/components/main/script_mod.hpp +++ b/framework/components/main/script_mod.hpp @@ -1,3 +1,5 @@ +#define FRAMEWORK CMF3 +#define FRAMEWORK_BEAUTIFIED Cluster Mission Framework (CMF3) #define PREFIX cmf #include "script_version.hpp" diff --git a/framework/components/main/script_version.hpp b/framework/components/main/script_version.hpp index 026162f..e254de1 100644 --- a/framework/components/main/script_version.hpp +++ b/framework/components/main/script_version.hpp @@ -1,4 +1,4 @@ #define MAJOR 2 #define MINOR 1 -#define PATCHLVL 0 -#define BUILD 0 +#define PATCHLVL 1 +#define BUILD 57 diff --git a/framework/components/menu/XEH_PREP.sqf b/framework/components/menu/XEH_PREP.sqf index b27b313..c683a27 100644 --- a/framework/components/menu/XEH_PREP.sqf +++ b/framework/components/menu/XEH_PREP.sqf @@ -1,9 +1,6 @@ #include "script_component.hpp" -PREP(delayedSafestartAction); -PREP(displayRolesAction); -PREP(fixLoadingBug); -PREP(fixMapAction); -PREP(toggleHUDAction); -PREP(viewDistanceAction); -PREP(init); +PREP(bugs); +PREP(safestart); +PREP(hideHUD); +PREP(diagnostics); diff --git a/framework/components/menu/XEH_playerInit.sqf b/framework/components/menu/XEH_playerInit.sqf new file mode 100644 index 0000000..e051961 --- /dev/null +++ b/framework/components/menu/XEH_playerInit.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +[] spawn FUNC(init); \ No newline at end of file diff --git a/framework/components/menu/XEH_postInit.sqf b/framework/components/menu/XEH_postInit.sqf new file mode 100644 index 0000000..10ea8bb --- /dev/null +++ b/framework/components/menu/XEH_postInit.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +/* Add zeus actions */ +private _children = { + params ["_target"]; + + private _actions = []; + + _actions pushBack [[_target] call FUNC(bugs), [], _target]; + _actions pushBack [[_target] call FUNC(diagnostics), [], _target]; + _actions pushBack [[_target] call FUNC(safestart), [], _target]; + + private _action = ([QGVAR(submitAAR), LSTRING(aar_displayname), "rsc\data\icon_ace_debrief_ca.paa", { _this call EFUNC(aar,submitAAR) }, { true }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + private _action = ([QGVAR(viewDistance), LSTRING(viewdistance_displayname), "rsc\data\icon_ace_viewDistance_ca.paa", { createDialog QEGVAR(viewdistance,menu); }, { true }] call ACEFUNC(interact_menu,createAction)); + _actions pushBack [_action, [], _target]; + + _actions; +}; + +private _zeusAction = [QGVAR(main), LSTRING(cc_menu_displayname), "rsc\data\icon_ace_settings_ca.paa", {}, { true }, _children] call ACEFUNC(interact_menu,createAction); +[["ACE_ZeusActions"], _zeusAction] call ace_interact_menu_fnc_addActionToZeus; \ No newline at end of file diff --git a/framework/components/menu/XEH_preInit.sqf b/framework/components/menu/XEH_preInit.sqf new file mode 100644 index 0000000..6d2776a --- /dev/null +++ b/framework/components/menu/XEH_preInit.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" + +/* Add player self actions */ +["ace_interact_menu_newControllableObject", { + params ["_type"]; + + if (!(_type isKindOf "Man")) exitWith {}; + + + private _children = { + params ["_target"]; + + private _actions = []; + + _actions pushBack [[_target] call FUNC(bugs), [], _target]; + _actions pushBack [[_target] call FUNC(diagnostics), [], _target]; + _actions pushBack [[_target] call FUNC(safestart), [], _target]; + _actions pushBack [[_target] call FUNC(hideHUD), [], _target]; + + private _action = ([QGVAR(submitAAR), LSTRING(aar_displayname), "rsc\data\icon_ace_debrief_ca.paa", { _this call EFUNC(aar,submitAAR) }, { true }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + private _action = ([QGVAR(viewDistance), LSTRING(viewdistance_displayname), "rsc\data\icon_ace_viewDistance_ca.paa", { createDialog QEGVAR(viewdistance,menu); }, { true }] call ACEFUNC(interact_menu,createAction)); + _actions pushBack [_action, [], _target]; + + _actions; + }; + + private _action = [QGVAR(main), LSTRING(cc_menu_displayname), "rsc\data\icon_ace_settings_ca.paa", {}, { true }, _children] call ACEFUNC(interact_menu,createAction); + [_type, 1, ["ACE_SelfActions"], _action, true] call ACEFUNC(interact_menu,addActionToClass); +}] call CBAFUNC(addEventHandler); \ No newline at end of file diff --git a/framework/components/menu/fn_delayedSafestartAction.sqf b/framework/components/menu/fn_delayedSafestartAction.sqf deleted file mode 100644 index 96a6390..0000000 --- a/framework/components/menu/fn_delayedSafestartAction.sqf +++ /dev/null @@ -1,25 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Starts a countdown which will disable safestart once it reaches 0. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_menu_fnc_delayedSafestartAction - * - * Public: No - */ -SCRIPT(delayedSafestartAction); - -/* Start the game after x seconds */ -[] spawn { - /* Get the configured delay time and start the countdown */ - private _delay = CONFIG_PARAM_4(SETTINGS,gameplay,safestart,delay); - [_delay, "Weapons are hot in: ", true] call EFUNC(utility,countDown); - missionNamespace setVariable [QEGVAR(gameplay,safestart_disable), true, true]; -}; diff --git a/framework/components/menu/fn_displayRolesAction.sqf b/framework/components/menu/fn_displayRolesAction.sqf deleted file mode 100644 index fecac56..0000000 --- a/framework/components/menu/fn_displayRolesAction.sqf +++ /dev/null @@ -1,31 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * creates action to display all players roles in ace. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_menu_fnc_displayRolesAction - * - * Public: No - */ -SCRIPT(displayRolesAction); - -/* Get a list of all player roles */ -private _roles = []; -{ - private _p = _x; - if (allCurators findIf {getAssignedCuratorUnit _x == _p} == -1) then { - _roles pushBack format["%2 %1", (name _p), (_p getVariable [QEGVAR(common,role), "RFL"])]; - } else { - _roles pushBack format["ZEUS %1", (name _p)]; - } -} forEach allPlayers; - -/* Display the roles */ -hint (_roles joinstring "\n"); diff --git a/framework/components/menu/fn_fixLoadingBug.sqf b/framework/components/menu/fn_fixLoadingBug.sqf deleted file mode 100644 index 9d8c795..0000000 --- a/framework/components/menu/fn_fixLoadingBug.sqf +++ /dev/null @@ -1,29 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Fixes the issue where players get stuck loading into the mission. (can only be run for other players) - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_menu_fnc_fixLoadingBug - * - * Public: No - */ -SCRIPT(fixLoadingBug); - -/* End the loading screen for the selected player */ -private _onConfirm = { - params["_value"]; - [[], EFUNC(utility,endLoadingScreen)] remoteExec ["call", _value, true]; -}; - -/* Open a menu where you can select the player to apply the fix to */ -private _players = allPlayers; -private _playerIds = _players apply {owner _x}; -private _playernames = _players apply {name _x}; -[LSTRING(select_player_displayname), [["LIST", [LSTRING(players), LSTRING(select_player_tooltip)], [_playerIds, _playernames, 0, 3]]], _onConfirm] call zen_dialog_fnc_create; diff --git a/framework/components/menu/fn_fixMapAction.sqf b/framework/components/menu/fn_fixMapAction.sqf deleted file mode 100644 index da599e9..0000000 --- a/framework/components/menu/fn_fixMapAction.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Fixes the RR immersive maps bug where the map gets stuck to the playerunit. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_menu_fnc_fixMapAction - * - * Public: No - */ -SCRIPT(fixMapAction); - -/* Fix RR_maps bug where the map is stuck */ -false call RR_mapStuff_fnc_mapEH; -{detach _x; deleteVehicle _x} forEach attachedObjects player; diff --git a/framework/components/menu/fn_init.sqf b/framework/components/menu/fn_init.sqf deleted file mode 100644 index 90c5357..0000000 --- a/framework/components/menu/fn_init.sqf +++ /dev/null @@ -1,116 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Initializes the CC menu in ace - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_menu_fnc_init - * - * Public: No - */ -SCRIPT(init); - -if (!hasInterface) exitWith {}; - -/* Waituntil player is alive */ -waitUntil { alive player && !isNull player }; - -/* Add configurable hotkeys */ -["CMF Common", QGVAR(toggleHUD), [LSTRING(toggle_hud_displayname), LSTRING(toggle_hud_tooltip)], {}, FUNC(toggleHUDAction), [15, [false, true, false]]] call CBA_fnc_addKeybind; - -/* Menu items for the selfActions menu */ -private _childrenSelf = { - params ["_target"]; - private _actions = []; - - /* Fix endless loading bug Action */ - private _action = ([QGVAR(loadingbug), LSTRING(loading_bug_displayname), "rsc\data\icon_ace_bug_ca.paa", { _this call FUNC(fixLoadingBug) }, { (!isNull (getAssignedCuratorLogic player)) || ((call BIS_fnc_admin) > 0) }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - /* Fix Map Bug Action */ - private _action = ([QGVAR(mapbug), LSTRING(map_bug_displayname), "rsc\data\icon_ace_bug_ca.paa", { _this call FUNC(fixMapAction) }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Disable safestart action */ - private _action = ([QGVAR(safestart_menu), LSTRING(disable_safestart_displayname), "rsc\data\icon_ace_startgame_ca.paa", {}, { is3DENPreview || (!(missionNamespace getVariable ["EMF_missionSafeStart", false]) && !isNull (getAssignedCuratorLogic player)) || ((call BIS_fnc_admin) > 0 && !(missionNamespace getVariable ["EMF_missionSafeStart", false])) }, { - private _actions = []; - - /* Disable instantly */ - private _action = ([QGVAR(safestart_instant), LSTRING(instant_displayname), "rsc\data\icon_ace_instant_ca.paa", { missionNamespace setVariable [QEGVAR(gameplay,safestart_disable), true, true] }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Delayed disable */ - private _action = ([QGVAR(safestart_delayed), LSTRING(delayed_displayname), "rsc\data\icon_ace_delayed_ca.paa", { _this call FUNC(delayedSafestartAction) }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - _actions; - }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Report Bug action */ - private _action = ([QGVAR(reportBug), ELSTRING(3den,report_bug), "\a3\3DEN\Data\Controls\ctrlMenu\link_ca.paa", { createDialog "cmf_utility_reportBug" }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* After Action Report Action */ - private _action = ([QGVAR(submitAAR), LSTRING(aar_displayname), "rsc\data\icon_ace_debrief_ca.paa", { _this call EFUNC(utility,submitAAR) }, { (serverName isEqualTo "Clustercommunity") }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Player Role List Action */ - private _action = ([QGVAR(submitAAR), LSTRING(player_roled_displayname), "rsc\data\icon_ace_team_ca.paa", { _this call FUNC(displayRolesAction) }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Hide HUD Action */ - private _action = ([QGVAR(toggleHUD), LSTRING(hide_hud_displayname), "rsc\data\icon_ace_viewDistance_ca.paa", { _this call FUNC(toggleHUDAction) }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Open View Distance Action */ - private _action = ([QGVAR(viewDistance), LSTRING(viewdistance_displayname), "rsc\data\icon_ace_viewDistance_ca.paa", { _this call FUNC(viewDistanceAction) }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - _actions; -}; - -/* Menu items for the zeusActions menu */ -private _childrenZeus = { - params ["_target"]; - private _actions = []; - - /* Disable safestart action */ - private _action = ([QGVAR(safestart_menu), LSTRING(disable_safestart_displayname), "rsc\data\icon_ace_startgame_ca.paa", { - private _actions = []; - - /* Disable instantly */ - private _action = ([QGVAR(safestart_instant), LSTRING(instant_displayname), "rsc\data\icon_ace_instant_ca.paa", { missionNamespace setVariable [QEGVAR(gameplay,disable), true, true] }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Delayed disable */ - private _action = ([QGVAR(safestart_delayed), LSTRING(delayed_displayname), "rsc\data\icon_ace_delayed_ca.paa", { _this call FUNC(delayedSafestartAction) }, { true }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - _actions; - }, { !(missionNamespace getVariable [QEGVAR(gameplay,safestart_disable), false]) }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - /* Fix endless loading bug Action */ - private _action = ([QGVAR(loadingbug), LSTRING(loading_bug_displayname), "rsc\data\icon_ace_bug_ca.paa", { _this call FUNC(fixLoadingBug) }, { (!isNull (getAssignedCuratorLogic player)) || ((call BIS_fnc_admin) > 0) }] call ace_interact_menu_fnc_createAction); - _actions pushBack [_action, [], _target]; - - _actions; -}; - -private _selfAction = [QGVAR(main), LSTRING(cc_menu_displayname), "rsc\data\icon_ace_settings_ca.paa", {}, { true }, _childrenSelf] call ace_interact_menu_fnc_createAction; -private _zeusAction = [QGVAR(main), LSTRING(cc_menu_displayname), "rsc\data\icon_ace_settings_ca.paa", {}, { true }, _childrenZeus] call ace_interact_menu_fnc_createAction; - -/* Add actions */ -[typeOf player, 1, ["ACE_SelfActions"], _selfAction] call ace_interact_menu_fnc_addActionToClass; -[["ACE_ZeusActions"], _zeusAction] call ace_interact_menu_fnc_addActionToZeus; - -LOG("Added CC menu"); - -/* Raise event */ -[QGVAR(addedMenu), []] call CBA_fnc_localEvent; diff --git a/framework/components/menu/fn_toggleHUDAction.sqf b/framework/components/menu/fn_toggleHUDAction.sqf deleted file mode 100644 index 77bca71..0000000 --- a/framework/components/menu/fn_toggleHUDAction.sqf +++ /dev/null @@ -1,88 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Toggles the HUD so players can take pictures without the HUD being visible - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_menu_fnc_toggleHUDAction - * - * Public: No - */ -SCRIPT(toggleHUDAction); - -/* Save the default showHUD parameters */ -if (isNil QGVAR(hud_default)) then { - GVAR(hud_default) = shownHUD; -}; - -/* Create variable to track if HUD is hidden */ -if (isNil QGVAR(hud_show)) then { - GVAR(hud_show) = true; -}; - -/* Toggle the HUD */ -private _staminaBarContainer = uiNamespace getVariable ["ace_advanced_fatigue_staminaBarContainer", controlNull]; -if (GVAR(hud_show)) then { - - GVAR(hud_show) = false; - - /* Hide vanilla elements */ - showHUD [false, false, false, false, false, false, false, false, false, false, false]; - - /* Hide Shacktac elements */ - GVAR(hud_STUI_UIMode) = STHud_Settings_HUDMode; - GVAR(hud_STUI_nametags) = STNT_Settings_Enabled; - GVAR(hud_STUI_groupIndicators) = STGI_Settings_Enabled; - STHud_UIMode = 0; - STNT_Enabled = false; - STGI_Enabled = false; - - /* Hide Ace elements */ - _staminaBarContainer ctrlShow false; - _staminaBarContainer ctrlCommit 0; - GVAR(hud_ace_nametags) = ace_nametags_showPlayerNames; - ace_nametags_showPlayerNames = 0; - call ace_nametags_fnc_updateSettings; - - /* Hide ACRE PAX */ // This code needs refactoring - [] spawn { - while { !GVAR(hud_show) && !(vehicle player isEqualTo player) } do { - ("acre_sys_gui_vehicleInfo" call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; - sleep 0.01; - }; - - if !(vehicle player isEqualTo player) then { - [true] call acre_sys_gui_fnc_showVehicleInfo; - }; - }; - - - /* Raise event */ - [QGVAR(onHUDHidden), []] call CBA_fnc_localEvent; -} else { - - GVAR(hud_show) = true; - - /* Show vanilla HUD */ - showHUD GVAR(hud_default); - - /* Show Shacktac elements */ - STHud_UIMode = GVAR(hud_STUI_UIMode); - STNT_Enabled = GVAR(hud_STUI_nametags); - STGI_Enabled = GVAR(hud_STUI_groupIndicators); - - /* Show Ace elements */ - _staminaBarContainer ctrlShow true; - _staminaBarContainer ctrlCommit 0; - ace_nametags_showPlayerNames = GVAR(hud_ace_nametags); - call ace_nametags_fnc_updateSettings; - - /* Raise event */ - [QGVAR(onHUDShown), []] call CBA_fnc_localEvent; -}; diff --git a/framework/components/menu/fn_viewDistanceAction.sqf b/framework/components/menu/fn_viewDistanceAction.sqf deleted file mode 100644 index 9de0eff..0000000 --- a/framework/components/menu/fn_viewDistanceAction.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Open viewdistance UI - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_menu_fnc_viewDistanceAction - * - * Public: No - */ -SCRIPT(viewDistanceAction); - -/* Call viewdistance open */ -_this call EFUNC(viewdistance,openDialog); diff --git a/framework/components/menu/functions/fn_bugs.sqf b/framework/components/menu/functions/fn_bugs.sqf new file mode 100644 index 0000000..93ba122 --- /dev/null +++ b/framework/components/menu/functions/fn_bugs.sqf @@ -0,0 +1,60 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Fix a bug + * + * Arguments: + * 0: Target + * + * Return Value: + * Child Action + * + * Example: + * [] call cmf_menu_fnc_reportBug + * + * Public: No + */ +params ["_target"]; + +private _action = ([QGVAR(bug_menu), "Bug Fixes", "rsc\data\icon_ace_bug_ca.paa", {}, { true }, { + private _actions = []; + + /* Fix endless loading bug Action */ + private _action = ([QGVAR(loadingbug), LSTRING(loading_bug_displayname), "rsc\data\icon_ace_bug_ca.paa", { + private _onConfirm = { + params["_value"]; + [[], EFUNC(utility,endLoadingScreen)] remoteExec ["call", _value, true]; + }; + + /* Open a menu where you can select the player to apply the fix to */ + private _players = allPlayers; + private _playerIds = _players apply { owner _x }; + private _playernames = _players apply { name _x }; + [LSTRING(select_player_displayname), [["LIST", [LSTRING(players), LSTRING(select_player_tooltip)], [_playerIds, _playernames, 0, 3]]], _onConfirm] call zen_dialog_fnc_create; + }, { (!isNull (getAssignedCuratorLogic player)) || ((call BIS_fnc_admin) > 0) }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Suicide action */ + private _action = ([QGVAR(suicide), "Suicide", "a3\ui_f_curator\data\cfgmarkers\kia_ca.paa", { + _target spawn { + private _result = ["Are you sure?", "Confirm", true, true] call BIS_fnc_guiMessage; + if (_result) then { + player setDamage 1; + }; + }; + }, { alive player }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + private _action = ([ // @BUG: Ironically, bug report is bugged, dialog is not created + QGVAR(reportBug), + ELSTRING(3den,report_bug), + "\a3\3DEN\Data\Controls\ctrlMenu\link_ca.paa", + { createDialog EGVAR(utility,reportBug) }, + { true } + ] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + _actions; +}] call ace_interact_menu_fnc_createAction); + +_action; \ No newline at end of file diff --git a/framework/components/menu/functions/fn_diagnostics.sqf b/framework/components/menu/functions/fn_diagnostics.sqf new file mode 100644 index 0000000..a7bb104 --- /dev/null +++ b/framework/components/menu/functions/fn_diagnostics.sqf @@ -0,0 +1,101 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Shows diagnostics + * + * Arguments: + * 0: Target + * + * Return Value: + * Child Action + * + * Example: + * [] call cmf_menu_fnc_diagnostics + * + * Public: Yes + */ +params ["_target"]; + +private _action = ([QGVAR(diag_menu), "Diagnostics", "z\ace\addons\medical_gui\data\categories\advanced_treatment.paa", {}, { true }, { + private _actions = []; + + /* Client */ + private _action = ([QGVAR(client), "Client", "a3\ui_f\data\gui\rsc\rscdisplaymultiplayersetup\disabledai_ca.paa", {}, { true }, { + private _actions = []; + + /* FPS */ + private _action = ([QGVAR(fps), "FPS:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["FPS: %1", diag_fps]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Spawned scripts */ + private _action = ([QGVAR(fps), "Spawned Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["Spawn Scripts: %1", diag_activeScripts select 0]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* execVM scripts */ + private _action = ([QGVAR(fps), "ExecVM Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["ExecVM Scripts: %1", diag_activeScripts select 1]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* exec scripts */ + private _action = ([QGVAR(fps), "Exec Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["Exec Scripts: %1", diag_activeScripts select 2]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* execFSM scripts */ + private _action = ([QGVAR(fps), "ExecFSM Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["ExecFSM Scripts: %1", diag_activeScripts select 3]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + _actions; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Server */ + private _action = ([QGVAR(server), "Server", "a3\3den\data\displays\display3den\statusbar\server_ca.paa", {}, { !isServer }, { + private _actions = []; + + /* FPS */ + private _action = ([QGVAR(fps), "FPS:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, {}, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["FPS: %1", missionNamespace getVariable [QEGVAR(main,serverFPS), "?"]]]; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Spawned scripts */ + private _action = ([QGVAR(fps), "Spawned Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["Spawn Scripts: %1", (missionNamespace getVariable [QEGVAR(main,serverScripts), ["?","?","?","?"]]) select 0]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* execVM scripts */ + private _action = ([QGVAR(fps), "ExecVM Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["ExecVM Scripts: %1", (missionNamespace getVariable [QEGVAR(main,serverScripts), ["?","?","?","?"]]) select 1]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* exec scripts */ + private _action = ([QGVAR(fps), "Exec Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["Exec Scripts: %1", (missionNamespace getVariable [QEGVAR(main,serverScripts), ["?","?","?","?"]]) select 2]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* execFSM scripts */ + private _action = ([QGVAR(fps), "ExecFSM Scripts:", "a3\structures_f_argo\commercial\billboards\data\billboard_transparent_co.paa", { }, { true }, { }, [], "", 4, [false, false, false, true, false], { + (_this select 3) set [1, format ["ExecFSM Scripts: %1", (missionNamespace getVariable [QEGVAR(main,serverScripts), ["?","?","?","?"]]) select 3]] + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + _actions; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + _actions; +}] call ace_interact_menu_fnc_createAction); + +_action; \ No newline at end of file diff --git a/framework/components/menu/functions/fn_hideHUD.sqf b/framework/components/menu/functions/fn_hideHUD.sqf new file mode 100644 index 0000000..580da58 --- /dev/null +++ b/framework/components/menu/functions/fn_hideHUD.sqf @@ -0,0 +1,99 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Toggles the HUD so players can take pictures without the HUD being visible + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_menu_fnc_toggleHUDAction + * + * Public: No + */ + +if (is3DEN) exitWith {}; + +private _action = [ + QGVAR(toggleHUD), + LSTRING(hide_hud_displayname), + "rsc\data\icon_ace_viewDistance_ca.paa", + { + /* Save the default showHUD parameters */ + if (isNil QGVAR(hud_default)) then { + GVAR(hud_default) = shownHUD; + }; + + /* Create variable to track if HUD is hidden */ + if (isNil QGVAR(hud_show)) then { + GVAR(hud_show) = true; + }; + + /* Toggle the HUD */ + private _staminaBarContainer = uiNamespace getVariable ["ace_advanced_fatigue_staminaBarContainer", controlNull]; + if (GVAR(hud_show)) then { + + GVAR(hud_show) = false; + + /* Hide vanilla elements */ + showHUD [false, false, false, false, false, false, false, false, false, false, false]; + + /* Hide Shacktac elements */ + GVAR(hud_STUI_UIMode) = STHud_Settings_HUDMode; + GVAR(hud_STUI_nametags) = STNT_Settings_Enabled; + GVAR(hud_STUI_groupIndicators) = STGI_Settings_Enabled; + STHud_UIMode = 0; + STNT_Enabled = false; + STGI_Enabled = false; + + /* Hide Ace elements */ + _staminaBarContainer ctrlShow false; + _staminaBarContainer ctrlCommit 0; + GVAR(hud_ace_nametags) = ace_nametags_showPlayerNames; + ace_nametags_showPlayerNames = 0; + call ace_nametags_fnc_updateSettings; + + /* Hide ACRE PAX */ // This code needs refactoring + [] spawn { + while { !GVAR(hud_show) && !(vehicle player isEqualTo player) } do { + ("acre_sys_gui_vehicleInfo" call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; + sleep 0.01; + }; + + if !(vehicle player isEqualTo player) then { + [true] call acre_sys_gui_fnc_showVehicleInfo; + }; + }; + + + /* Raise event */ + [QGVAR(onHUDHidden), []] call CBA_fnc_localEvent; + } else { + + GVAR(hud_show) = true; + + /* Show vanilla HUD */ + showHUD GVAR(hud_default); + + /* Show Shacktac elements */ + STHud_UIMode = GVAR(hud_STUI_UIMode); + STNT_Enabled = GVAR(hud_STUI_nametags); + STGI_Enabled = GVAR(hud_STUI_groupIndicators); + + /* Show Ace elements */ + _staminaBarContainer ctrlShow true; + _staminaBarContainer ctrlCommit 0; + ace_nametags_showPlayerNames = GVAR(hud_ace_nametags); + call ace_nametags_fnc_updateSettings; + + /* Raise event */ + [QGVAR(onHUDShown), []] call CBA_fnc_localEvent; + }; + }, + { true } +] call ace_interact_menu_fnc_createAction; + +_action; \ No newline at end of file diff --git a/framework/components/menu/functions/fn_safestart.sqf b/framework/components/menu/functions/fn_safestart.sqf new file mode 100644 index 0000000..d189e16 --- /dev/null +++ b/framework/components/menu/functions/fn_safestart.sqf @@ -0,0 +1,36 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Report a bug + * + * Arguments: + * 0: Target + * + * Return Value: + * Child Action + * + * Example: + * [] call cmf_menu_fnc_safestart + * + * Public: No + */ +params ["_target"]; + +private _action = ([QGVAR(safestart_menu), + LSTRING(disable_safestart_displayname), + "rsc\data\icon_ace_startgame_ca.paa", { + missionNameSpace setVariable [QEGVAR(gameplay,safestart_Countdown), true, true]; + + [[], { + [EGVAR(gameplay,setting_safestartDelay), "Weapons are live in: ", true] call EFUNC(utility,countDown); + missionNamespace setVariable [QEGVAR(gameplay,safestart_disable), true, true]; + }] remoteExec ["spawn", 0]; + }, + { + is3DENPreview || (!(missionNamespace getVariable [QEGVAR(gameplay,safestart_Countdown), false]) && + !isNull (getAssignedCuratorLogic player)) || ((call BIS_fnc_admin) > 0 && + !(missionNamespace getVariable [QEGVAR(gameplay,safestart_Countdown), false])) + } +] call ace_interact_menu_fnc_createAction); + +_action; \ No newline at end of file diff --git a/framework/components/menu/functions/script_component.hpp b/framework/components/menu/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/menu/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/menu/initKeybinds.sqf b/framework/components/menu/initKeybinds.sqf new file mode 100644 index 0000000..c3ceac0 --- /dev/null +++ b/framework/components/menu/initKeybinds.sqf @@ -0,0 +1,74 @@ +#include "script_component.hpp" + +[QUOTE(FRAMEWORK: Common), QGVAR(toggleHUD), [LSTRING(toggle_hud_displayname), LSTRING(toggle_hud_tooltip)], {}, { + /* Save the default showHUD parameters */ + if (isNil QGVAR(hud_default)) then { + GVAR(hud_default) = shownHUD; + }; + + /* Create variable to track if HUD is hidden */ + if (isNil QGVAR(hud_show)) then { + GVAR(hud_show) = true; + }; + + /* Toggle the HUD */ + private _staminaBarContainer = uiNamespace getVariable ["ace_advanced_fatigue_staminaBarContainer", controlNull]; + if (GVAR(hud_show)) then { + + GVAR(hud_show) = false; + + /* Hide vanilla elements */ + showHUD [false, false, false, false, false, false, false, false, false, false, false]; + + /* Hide Shacktac elements */ + GVAR(hud_STUI_UIMode) = STHud_Settings_HUDMode; + GVAR(hud_STUI_nametags) = STNT_Settings_Enabled; + GVAR(hud_STUI_groupIndicators) = STGI_Settings_Enabled; + STHud_UIMode = 0; + STNT_Enabled = false; + STGI_Enabled = false; + + /* Hide Ace elements */ + _staminaBarContainer ctrlShow false; + _staminaBarContainer ctrlCommit 0; + GVAR(hud_ace_nametags) = ace_nametags_showPlayerNames; + ace_nametags_showPlayerNames = 0; + call ace_nametags_fnc_updateSettings; + + /* Hide ACRE PAX */ // This code needs refactoring + [] spawn { + while { !GVAR(hud_show) && !(vehicle player isEqualTo player) } do { + ("acre_sys_gui_vehicleInfo" call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; + sleep 0.01; + }; + + if !(vehicle player isEqualTo player) then { + [true] call acre_sys_gui_fnc_showVehicleInfo; + }; + }; + + + /* Raise event */ + [QGVAR(onHUDHidden), []] call CBA_fnc_localEvent; + } else { + + GVAR(hud_show) = true; + + /* Show vanilla HUD */ + showHUD GVAR(hud_default); + + /* Show Shacktac elements */ + STHud_UIMode = GVAR(hud_STUI_UIMode); + STNT_Enabled = GVAR(hud_STUI_nametags); + STGI_Enabled = GVAR(hud_STUI_groupIndicators); + + /* Show Ace elements */ + _staminaBarContainer ctrlShow true; + _staminaBarContainer ctrlCommit 0; + ace_nametags_showPlayerNames = GVAR(hud_ace_nametags); + call ace_nametags_fnc_updateSettings; + + /* Raise event */ + [QGVAR(onHUDShown), []] call CBA_fnc_localEvent; + }; +}, [15, [false, true, false]]] call EFUNC(common,addKeybind); \ No newline at end of file diff --git a/framework/components/menu/script_component.hpp b/framework/components/menu/script_component.hpp index 742f700..cf7890b 100644 --- a/framework/components/menu/script_component.hpp +++ b/framework/components/menu/script_component.hpp @@ -1,5 +1,15 @@ #define MODULE menu +#define MODULE_BEAUTIFIED Menu + #define REQUIRED_ADDONS ["A3_Functions_F", "ace_interact_menu"] #define REQUIRED_MODULES ["common"] -#include "..\main\script_component.hpp" +#ifdef DEBUG_ENABLED_MENU + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_MENU + #define DEBUG_SETTINGS DEBUG_SETTINGS_MENU +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/organization/README.md b/framework/components/organization/README.md new file mode 100644 index 0000000..5510964 --- /dev/null +++ b/framework/components/organization/README.md @@ -0,0 +1,16 @@ +*(groupAssign cheatsheet for myself)* +## New Group Workflow +```mermaid +graph TD; + NEW_GROUP[/New Goup\]-->|function - registerGroup|REGISTER_GROUP[(Group Registry)]; + REGISTER_GROUP-->|event - newUnassignedGroup|GROUP_ENGINE{GROUP ENGINE}; + GROUP_ENGINE +``` + +## Engine Workflow +```mermaid +graph TD; + UNASSIGNED{{event - newUnassignedGroup}}; + DELETED{{event - deletedGroup}}; + UNASSIGNED-->ASSIGN_LEVEL +``` \ No newline at end of file diff --git a/framework/components/organization/XEH_3denInit.sqf b/framework/components/organization/XEH_3denInit.sqf new file mode 100644 index 0000000..3d9c0dd --- /dev/null +++ b/framework/components/organization/XEH_3denInit.sqf @@ -0,0 +1,53 @@ +#include "script_component.hpp" + +waitUntil { !isNil { missionNameSpace getVariable QEGVAR(3den,menu_unit) } }; + +private _path = missionNameSpace getVariable QEGVAR(3den,menu_unit); + +/* Unit sizes (fireteam, squad, platoon, Company) */ +private _infantryMenu = [_path, LSTRING(infantry_elements_displayName), "a3\ui_f\data\gui\cfg\hints\icon_text\b_inf_ca.paa"] call EFUNC(3den,addMenuItem); +[_path + [_infantryMenu], LSTRING(fireteam_displayName), "FIRETEAM", "ca\ui\data\markers\n_inf.paa"] call FUNC(3denUnitSpawner); +[_path + [_infantryMenu], LSTRING(squad_displayName), "SQUAD", "ca\ui\data\markers\n_inf.paa"] call FUNC(3denUnitSpawner); +[_path + [_infantryMenu], LSTRING(platoon_displayName), "PLATOON", "ca\ui\data\markers\n_inf.paa"] call FUNC(3denUnitSpawner); +[_path + [_infantryMenu], LSTRING(company_displayName), "COMPANY", "ca\ui\data\markers\n_inf.paa"] call FUNC(3denUnitSpawner); + +/* Air Elements */ +private _airMenu = [_path, LSTRING(air_elements_displayName), "a3\ui_f\data\gui\cfg\hints\icon_text\b_air_ca.paa"] call EFUNC(3den,addMenuItem); +[_path + [_airMenu], LSTRING(light_rotary_cas_trans_displayName), "PHANTOM", "CUP\AirVehicles\CUP_AirVehicles_AH6\data\ui\icon_mh6j_ca.paa"] call FUNC(3denUnitSpawner); +[_path + [_airMenu], LSTRING(rotary_cas), "REAPER", "CUP\AirVehicles\CUP_AirVehicles_AH6\data\ui\icon_mh6j_ca.paa"] call FUNC(3denUnitSpawner); +[_path + [_airMenu], LSTRING(heavy_rotary_cas_displayName), "UGLY", "CUP\AirVehicles\CUP_AirVehicles_AH1Z\data\ui\icomap_ah1z_ca.paa"] call FUNC(3denUnitSpawner); +[_path + [_airMenu], LSTRING(ground_attack_jet_displayName), "HAWG", "CUP\AirVehicles\CUP_AirVehicles_AV8B\data\ui\icomap_av8b_ca.paa"] call FUNC(3denUnitSpawner); +[_path + [_airMenu], LSTRING(fighter_bomber_jet_displayName), "PAVEMENT", "CUP\AirVehicles\CUP_AirVehicles_Su25\data\ui\icomap_su25.paa"] call FUNC(3denUnitSpawner); + +/* Armor Elements */ +private _armorMenu = [_path, LSTRING(armor_elements_displayName), "a3\ui_f\data\gui\cfg\hints\icon_text\b_armor_ca.paa"] call EFUNC(3den,addMenuItem); +[_path + [_armorMenu], LSTRING(apc_displayName), "SIERRA", "CUP\WheeledVehicles\CUP_WheeledVehicles_BRDM2\data\icomap_brdm_ca.paa"] call FUNC(3denUnitSpawner); +[_path + [_armorMenu], LSTRING(ifv_displayName), "MIKE", "CUP\TrackedVehicles\CUP_TrackedVehicles_BMP\data\map_ico\icomap_bmp2_ca.paa"] call FUNC(3denUnitSpawner); +[_path + [_armorMenu], LSTRING(mbt_displayName), "TANGO", "CUP\TrackedVehicles\CUP_TrackedVehicles_T90\data\ui\icomap_t90_ca.paa"] call FUNC(3denUnitSpawner); +[_path + [_armorMenu], "ANVIL (SPAAG/AAA)", "ANVIL", "CUP\TrackedVehicles\CUP_TrackedVehicles_T90\data\ui\icomap_t90_ca.paa"] call FUNC(3denUnitSpawner); + +/* Support Elements */ +private _supportMenu = [_path, LSTRING(support_elements_displayName), "ca\ui\data\markers\b_support.paa"] call EFUNC(3den,addMenuItem); +[_path + [_supportMenu], LSTRING(mortar_team_displayName), "MORTARS", "ca\ui\data\markers\n_mortar.paa"] call FUNC(3denUnitSpawner); +[_path + [_supportMenu], LSTRING(recon_sniper_team_displayName), "ROMEO", "ca\ui\data\markers\n_recon.paa"] call FUNC(3denUnitSpawner); +[_path + [_supportMenu], LSTRING(logistics_team_displayName), "LOGI", "ca\ui\data\markers\n_support.paa"] call FUNC(3denUnitSpawner); +[_path + [_supportMenu], LSTRING(engineers_team_displayName), "ENGI", "ca\ui\data\markers\n_maint.paa"] call FUNC(3denUnitSpawner); + +/* Weapons Elements */ +private _weaponsMenu = [_path, LSTRING(weapons_elements_displayName), "ca\ui\data\markers\b_mortar.paa"] call EFUNC(3den,addMenuItem); +[_path + [_weaponsMenu], LSTRING(mmg_team_displayName), "MMG", "ca\ui\data\markers\n_unknown.paa"] call FUNC(3denUnitSpawner); +[_path + [_weaponsMenu], LSTRING(hmg_team_displayName), "HMG", "ca\ui\data\markers\n_unknown.paa"] call FUNC(3denUnitSpawner); +[_path + [_weaponsMenu], LSTRING(mat_team_displayName), "MAT", "ca\ui\data\markers\n_unknown.paa"] call FUNC(3denUnitSpawner); +[_path + [_weaponsMenu], LSTRING(hat_team_displayName), "HAT", "ca\ui\data\markers\n_unknown.paa"] call FUNC(3denUnitSpawner); +[_path + [_weaponsMenu], "DHAT (Deployed Anti-Tank, Heavy)", "DHAT", "ca\ui\data\markers\n_unknown.paa"] call FUNC(3denUnitSpawner); + +/* Special Elements */ +private _specialMenu = [_path, LSTRING(special_elements_displayName), "ca\ui\data\markers\b_uav.paa"] call EFUNC(3den,addMenuItem); +[_path + [_specialMenu], LSTRING(rgr_riflesquad_displayName), "RGR_RFL_SQUAD", "ca\ui\data\markers\n_uav.paa"] call FUNC(3denUnitSpawner); +[_path + [_specialMenu], LSTRING(rgr_machinegunsquad_displayName), "RGR_MG_SQUAD", "ca\ui\data\markers\n_uav.paa"] call FUNC(3denUnitSpawner); + +/* Custom unit */ +[_path, LSTRING(custom_unit_displayName), "UNIT", "a3\ui_f\data\gui\cfg\hints\icon_text\b_unknown_ca.paa"] call FUNC(3denUnitSpawner); + +/* Zeus unit */ +[_path, LSTRING(zeus_unit_displayName), "ZEUS", "a3\ui_f_curator\data\logos\arma3_zeus_icon_ca.paa"] call FUNC(3denUnitSpawner); \ No newline at end of file diff --git a/framework/components/organization/XEH_PREP.sqf b/framework/components/organization/XEH_PREP.sqf new file mode 100644 index 0000000..ab63a83 --- /dev/null +++ b/framework/components/organization/XEH_PREP.sqf @@ -0,0 +1,10 @@ +#include "script_component.hpp" + +PREP(warno); +PREP(registerGroup); +PREP(setRole); +PREP(getRole); +PREP(isRole); +PREP(roster); +PREP(ToE); +PREP(3denUnitSpawner); \ No newline at end of file diff --git a/framework/components/organization/XEH_postInit.sqf b/framework/components/organization/XEH_postInit.sqf new file mode 100644 index 0000000..5243849 --- /dev/null +++ b/framework/components/organization/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +[] call FUNC(warno); +[] call FUNC(roster); +[] call FUNC(ToE); \ No newline at end of file diff --git a/framework/components/organization/XEH_preInit.sqf b/framework/components/organization/XEH_preInit.sqf new file mode 100644 index 0000000..e69de29 diff --git a/framework/components/3den/fn_unitSpawner.sqf b/framework/components/organization/functions/fn_3denUnitSpawner.sqf similarity index 81% rename from framework/components/3den/fn_unitSpawner.sqf rename to framework/components/organization/functions/fn_3denUnitSpawner.sqf index ec6b188..24b2e20 100644 --- a/framework/components/3den/fn_unitSpawner.sqf +++ b/framework/components/organization/functions/fn_3denUnitSpawner.sqf @@ -4,24 +4,29 @@ * Spawns units that follows Clustercommunity's ORBAT * * Arguments: - * 0: Type + * 0: Path + * 1: Name + * 2: Type + * 3: Icon * * Return Value: * None * * Example: - * ["SQUAD"] call cmf_3DEN_fnc_unitSpawner + * [[_myspawnMenu], "Squad", "SQUAD"] call cmf_organization_fnc_3denUnitSpawner * * Public: No */ -SCRIPT(unitSpawner); +SCRIPT(3denUnitSpawner); -GVAR(fnc_unitSpawner) = { +params ["_path", "_name", "_type", [ "_icon", ""]]; + +private _spawnScript = {_this spawn { params ["_type"]; private _position = screenToWorld [0.5, 0.5]; - private _unitArr = [_type] call FUNC(unitConstructor); + private _unitArr = [_type] call EFUNC(3den,unit_constructor); private _unitPos = (_position select 0); private _groupPos = (_position select 1); @@ -32,7 +37,7 @@ GVAR(fnc_unitSpawner) = { private _groupOffset = _groupPos + _groupOffset; private _unitGroup = grpNull; { - _x params["_class", "_roleName", "_role", "_isLeader", "_unitOffset", "_unitGroupOffset"]; + _x params["_class", "_roleName", "_role", "_rank", "_isLeader", "_unitOffset", "_unitGroupOffset"]; private _unitOffset = _unitPos + _unitOffset; private _groupOffset = _groupOffset + _unitGroupOffset; @@ -47,9 +52,10 @@ GVAR(fnc_unitSpawner) = { _unit setUnitLoadout [[],[],[],[],[],[],"","",[],["ItemMap","","","ItemCompass","ItemWatch",""]]; save3DENInventory [_unit]; _unit switchMove "amovpercmstpsnonwnondnon"; - _unit set3DENAttribute ["Init", format["[this, ""%1"", 0] call cmf_common_fnc_setRole;", _role]]; + _unit set3DENAttribute ["Init", format["[this, ""%1"", 0] call cmf_organization_fnc_setRole;", _role]]; _unit set3DENAttribute ["description", format["%1@%2", _roleName, _lobbyName]]; _unit set3DENAttribute ["ControlMP", true]; + _unit set3DENAttribute ["Rank", _rank]; // If unit is zeus add zeus module if (_type isEqualTo "ZEUS") then { @@ -76,10 +82,14 @@ GVAR(fnc_unitSpawner) = { /* Raise event */ [QGVAR(onGroupSpawned), [_unitGroup]] call CBA_fnc_localEvent; } forEach _unitArr; + if (count _unitArr != 0) then { [format["Spawned %1", _type], 0, 1] call BIS_fnc_3DENNotification; /* Raise event */ [QGVAR(onUnitTemplateSpawned), [_spawnedUnits, _spawnedGroups]] call CBA_fnc_localEvent; }; -}; +}}; + +/* Create menu */ +[_path, _name, _icon, _spawnScript, [_type]] call cmf_3den_fnc_addMenuItem; diff --git a/framework/components/organization/functions/fn_ToE.sqf b/framework/components/organization/functions/fn_ToE.sqf new file mode 100644 index 0000000..1e68843 --- /dev/null +++ b/framework/components/organization/functions/fn_ToE.sqf @@ -0,0 +1,82 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Creates a Table of Organization and Equipment for team leaders. It gets executed automatically. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_gameplay_fnc_ToE + * + * Public: No + */ + +[{ !isNull player && alive player }, { + player createDiarySubject ["cmf_toe", "TO&E"]; + + addMissionEventHandler ["Map", { + params ["_mapIsOpened"]; + + if (!_mapIsOpened) then { + /* Remove outdated roster */ + { + player removeDiaryRecord ["cmf_toe", _x select 8] + } forEach (player allDiaryRecords "cmf_toe"); + } else { + /* Display nothing if unit isn't a team leader */ + if (player != leader group player) exitWith {}; + + /* Get all player groups */ + private _allPlayerGroups = allPlayers apply { group _x }; + _allPlayerGroups = _allPlayerGroups arrayIntersect _allPlayerGroups; + _allPlayerGroups sort true; + + private _rosterString = "
"; + { + private _group = _x; + _rosterString = _rosterString + format ["%1
", groupId _group]; + + /* Get Group Vehicles */ + private _vehicles = [_group, true] call BIS_fnc_groupVehicles; + { + _rosterString = _rosterString + format [" %1
", [configFile >> "CfgVehicles" >> (typeof _x)] call BIS_fnc_displayName]; + } forEach _vehicles; + + { + private _unit = _x; + + private _roleDescription = "None"; + if (roleDescription _unit != "") then { + _roleDescription = ((roleDescription _unit) splitString "@") select 0; + }; + + /* Build equipment string */ + private _gear = []; + + /* Get unit's primary */ + _gear pushBack ([configFile >> "CfgWeapons" >> (primaryWeapon _unit)] call BIS_fnc_displayName); + + /* Get unit's launcher */ + _gear pushBack ([configFile >> "CfgWeapons" >> (secondaryWeapon _unit)] call BIS_fnc_displayName); + + /* Get unit's radios */ + private _radioGear = [_x] call acre_sys_core_fnc_getGear; + _radioGear = _radioGear apply { [_x] call acre_api_fnc_getBaseRadio }; + _radioGear = _radioGear select { _x != "" }; + _radioGear = _radioGear apply { [_x + "_ID_1"] call acre_api_fnc_getDisplayName }; + _gear append _radioGear; + + _gear = _gear select { _x != "" }; + _gear = _gear joinString ", "; + _rosterString = _rosterString + format [" %1, %2 - %3
", name _unit, _roleDescription, _gear]; + } forEach units _group; + } forEach _allPlayerGroups; + + player createDiaryRecord ["cmf_toe", ["TO&E", _rosterString]] + }; + }]; +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/organization/functions/fn_getGroupParent.sqf b/framework/components/organization/functions/fn_getGroupParent.sqf new file mode 100644 index 0000000..1e2548b --- /dev/null +++ b/framework/components/organization/functions/fn_getGroupParent.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Returns the unit data at given path + * + * Arguments: + * 0: Path + * + * Return Value: + * Unit Data + * + * Example: + * [["1", "1", "1", "Alpha"]] call cmf_organization_fnc_getGroupParent + * + * Public: Yes + */ +params ["_path"]; + +private _value = missionNamespace getVariable [QGVAR(configParameters), ["", [], ([] call CBA_fnc_hashCreate)]]; +{ + private _key = _x; + if !([_value select 2] call CBA_fnc_isHash) exitWith { }; + if !([_value select 2, _key] call CBA_fnc_hashHasKey) exitWith { _value = nil }; + _value = [_value select 2, _key, nil] call CBA_fnc_hashGet; +} forEach _path; \ No newline at end of file diff --git a/framework/components/organization/functions/fn_getRole.sqf b/framework/components/organization/functions/fn_getRole.sqf new file mode 100644 index 0000000..194745a --- /dev/null +++ b/framework/components/organization/functions/fn_getRole.sqf @@ -0,0 +1,20 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Get's a unit's role + * + * Arguments: + * 0: Unit + * + * Return Value: + * Role + * + * Example: + * [player] call cmf_organization_fnc_getRole + * + * Public: Yes + */ +SCRIPT(isRole); +params ["_unit"]; + +_unit getVariable [QGVAR(role), "NONE"]; diff --git a/framework/components/common/fn_isRole.sqf b/framework/components/organization/functions/fn_isRole.sqf similarity index 87% rename from framework/components/common/fn_isRole.sqf rename to framework/components/organization/functions/fn_isRole.sqf index 094e29d..bc6365a 100644 --- a/framework/components/common/fn_isRole.sqf +++ b/framework/components/organization/functions/fn_isRole.sqf @@ -11,7 +11,7 @@ * Is role * * Example: - * [player, "RFL"] call cmf_common_fnc_isRole + * [player, "RFL"] call cmf_organization_fnc_isRole * * Public: Yes */ diff --git a/framework/components/organization/functions/fn_registerGroup.sqf b/framework/components/organization/functions/fn_registerGroup.sqf new file mode 100644 index 0000000..e8bf9e6 --- /dev/null +++ b/framework/components/organization/functions/fn_registerGroup.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Register Group to the CMF ORBAT System + * + * Arguments: + * 0: Size ("FT", "SQD", "PLT", "COY", "BAT") + * 1: level ("FT", "SQD", "PLT", "COY", "BAT") + * 2: type + * 3: Group + * + * Return Value: + * None + * + * Example: + * ["FT", _myGroup] call cmf_organization_fnc_registerGroup + * + * Public: Yes + */ +if (!isServer) exitWith {}; + +params ["_size", "_level", "_type", "_group"]; + diff --git a/framework/components/organization/functions/fn_roster.sqf b/framework/components/organization/functions/fn_roster.sqf new file mode 100644 index 0000000..2e12b5f --- /dev/null +++ b/framework/components/organization/functions/fn_roster.sqf @@ -0,0 +1,48 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Creates a roster of the current players. Get's executed automatically + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_gameplay_fnc_roster + * + * Public: No + */ + +[{ !isNull player && alive player }, { + player createDiarySubject ["cmf_roster", "Roster"]; + + addMissionEventHandler ["Map", { + params ["_mapIsOpened"]; + + if (!_mapIsOpened) then { + /* Remove outdated roster */ + { + player removeDiaryRecord ["cmf_roster", _x select 8] + } forEach (player allDiaryRecords "cmf_roster"); + } else { + /* Get all player groups */ + private _allPlayerGroups = allPlayers apply { group _x }; + _allPlayerGroups = _allPlayerGroups arrayIntersect _allPlayerGroups; + _allPlayerGroups sort true; + + private _rosterString = "
"; + { + private _group = _x; + _rosterString = _rosterString + format ["%1
", groupId _group]; + { + private _unit = _x; + _rosterString = _rosterString + format [" %1
", name _unit]; + } forEach units _group; + } forEach _allPlayerGroups; + + player createDiaryRecord ["cmf_roster", ["Roster", _rosterString]] + }; + }]; +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/common/fn_setRole.sqf b/framework/components/organization/functions/fn_setRole.sqf similarity index 94% rename from framework/components/common/fn_setRole.sqf rename to framework/components/organization/functions/fn_setRole.sqf index c0610d8..719339a 100644 --- a/framework/components/common/fn_setRole.sqf +++ b/framework/components/organization/functions/fn_setRole.sqf @@ -12,7 +12,7 @@ * None * * Example: - * [_myUnit, "SL", 0] call cmf_common_fnc_setRole + * [_myUnit, "SL", 0] call cmf_organization_fnc_setRole * * public: Yes */ diff --git a/framework/components/organization/functions/fn_warno.sqf b/framework/components/organization/functions/fn_warno.sqf new file mode 100644 index 0000000..6caedec --- /dev/null +++ b/framework/components/organization/functions/fn_warno.sqf @@ -0,0 +1,57 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Displays a warning order on the map + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_organization_fnc_warno + * + * Public: No + */ + +if (!fileExists "WARNO.sqf") exitWith {}; + +[{ !isNull player }, { + private _warno = call compile preprocessFileLineNumbers "WARNO.sqf"; + + private _formattedDate = format ["%3/%2/%1 %4:%5", + date select 0, + (["", "0"] select (date select 1 < 10)) + str (date select 1), + (["", "0"] select (date select 2 < 10)) + str (date select 2), + (["", "0"] select (date select 3 < 10)) + str (date select 3), + (["", "0"] select (date select 4 < 10)) + str (date select 4) + ]; + + private _missionData = missionNameSpace getVariable [QEGVAR(common,missionData), []]; + private _hash = [_missionData] call CBA_fnc_hashCreate; + private _operationName = [_hash, "M_TITLE", [getMissionConfigValue ['IntelBriefingName', briefingName]] call EFUNC(utility,hexToASCII)] call CBA_fnc_hashGet; + + private _worldName = getText (configFile >> "CfgWorlds" >> worldName >> "description"); + + private _weather = [] call EFUNC(utility,getWeatherDescriptors); + private _env = "Date: " + _formattedDate + "
+ Operation: " + _operationName + "
+ Terrain: " + _worldName + "
+ Weather: " + (_weather select 0) + " at " + (_weather select 1) + " with winds at " + (_weather select 2) + "

"; + + /* Parse Markdown and remove chasing and trailing newlines */ + _warno = _warno apply { + _parsed = [_x, true] call EFUNC(utility,parseMarkdown); + _parsed = [_parsed, [_parsed, 5] call BIS_fnc_trimString] select (_parsed select [0, 5] isEqualTo "
"); + [_parsed, [_parsed, 0, (count _parsed) - 5] call BIS_fnc_trimString] select (_parsed select [(count _parsed) - 5, 5] isEqualTo "
") + }; + + player createDiaryRecord ["Diary", ["Command / Signal", _warno select 4]]; + player createDiaryRecord ["Diary", ["Administration / Logistics", _warno select 3]]; + player createDiaryRecord ["Diary", ["Execution", _warno select 2]]; + player createDiaryRecord ["Diary", ["Mission", _warno select 1]]; + + + player createDiaryRecord ["Diary", ["Situation", _env + (_warno select 0)]]; +}] call CBA_fnc_waitUntilAndExecute; diff --git a/framework/components/organization/functions/script_component.hpp b/framework/components/organization/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/organization/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/organization/script_component.hpp b/framework/components/organization/script_component.hpp new file mode 100644 index 0000000..2ab6a8d --- /dev/null +++ b/framework/components/organization/script_component.hpp @@ -0,0 +1,15 @@ +#define MODULE organization +#define MODULE_BEAUTIFIED Organization + +#define REQUIRED_ADDONS [] +#define REQUIRED_MODULES ["common"] + +#ifdef DEBUG_ENABLED_ORGANIZATION + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_ORGANIZATION + #define DEBUG_SETTINGS DEBUG_SETTINGS_ORGANIZATION +#endif + +#include "..\main\script_component.hpp" \ No newline at end of file diff --git a/framework/components/organization/stringtable.sqf b/framework/components/organization/stringtable.sqf new file mode 100644 index 0000000..74a5eb1 --- /dev/null +++ b/framework/components/organization/stringtable.sqf @@ -0,0 +1,127 @@ +#include "script_component.hpp" +/* + * Author: Eric + * 3den_stringtable + */ +[ + [DSTRING(infantry_elements_displayName), [ + ["English", "Infantry Elements"], + ["Spanish", "Elementos De Infantería"] + ]], + [DSTRING(fireteam_displayName), [ + ["English", "Fireteam"], + ["Spanish", "Equipo de fuego"] + ]], + [DSTRING(squad_displayName), [ + ["English", "Squad"], + ["Spanish", "Escuadra"] + ]], + [DSTRING(platoon_displayName), [ + ["English", "Platoon"], + ["Spanish", "Pelotón"] + ]], + [DSTRING(company_displayName), [ + ["English", "Company"], + ["Spanish", "Compañía"] + ]], + [DSTRING(air_elements_displayName), [ + ["English", "Air Elements"], + ["Spanish", "Air Elements"] + ]], + [DSTRING(light_rotary_cas_trans_displayName), [ + ["English", "Phantom (Light Rotary CAS/Trans)"], + ["Spanish", "Phantom (Rotary CAS/Trans Ligero)"] + ]], + [DSTRING(rotary_cas), [ + ["English", "Reaper (Rotary CAS)"], + ["Spanish", "Reaper (Rotary CAS/Trans Pesado)"] + ]], + [DSTRING(heavy_rotary_cas_displayName), [ + ["English", "Ugly (Heavy Rotary CAS)"], + ["Spanish", "Elementos De Infantería"] + ]], + [DSTRING(ground_attack_jet_displayName), [ + ["English", "Hawg (Ground-Attack Jet)"], + ["Spanish", "Hawg (Avión de ataque a tierra)"] + ]], + [DSTRING(fighter_bomber_jet_displayName), [ + ["English", "Pavement (Fighter / Bomber Jet)"], + ["Spanish", "Pavement (Avión Caza/bombardero)"] + ]], + [DSTRING(armor_elements_displayName), [ + ["English", "Armor Elements"], + ["Spanish", "Armor Elements"] + ]], + [DSTRING(apc_displayName), [ + ["English", "Sierra (APC)"], + ["Spanish", "Sierra (APC)"] + ]], + [DSTRING(ifv_displayName), [ + ["English", "Mike (IFV)"], + ["Spanish", "Mike (IFV)"] + ]], + [DSTRING(mbt_displayName), [ + ["English", "Tango (MBT)"], + ["Spanish", "Tango (MBT)"] + ]], + [DSTRING(support_elements_displayName), [ + ["English", "Support Elements"], + ["Spanish", "Support Elements"] + ]], + [DSTRING(mortar_team_displayName), [ + ["English", "Mortars (Mortar Team)"], + ["Spanish", "Mortars (Equipo de mortero)"] + ]], + [DSTRING(recon_sniper_team_displayName), [ + ["English", "Romeo (Recon / Sniper Team)"], + ["Spanish", "Romeo (Equipo de Reconocimiento / Francotirador)"] + ]], + [DSTRING(logistics_team_displayName), [ + ["English", "Logi (Logistics Team)"], + ["Spanish", "Logi (Equipo logístico)"] + ]], + [DSTRING(engineers_team_displayName), [ + ["English", "Engi (Engineers Team)"], + ["Spanish", "Engi (Equipo de enginieros)"] + ]], + [DSTRING(weapons_elements_displayName), [ + ["English", "Weapons Elements"], + ["Spanish", "Weapons Elements"] + ]], + [DSTRING(mmg_team_displayName), [ + ["English", "MMG (Medium Machinegunner Team)"], + ["Spanish", "MMG (Equipo de ametralladora media)"] + ]], + [DSTRING(hmg_team_displayName), [ + ["English", "HMG (Heavy Machinegunner Team)"], + ["Spanish", "HMG (Equipo de ametralladora pesado)"] + ]], + [DSTRING(mat_team_displayName), [ + ["English", "MAT (Medium Anti-Tank Team)"], + ["Spanish", "MAT (Equipo anti-tanque medio)"] + ]], + [DSTRING(hat_team_displayName), [ + ["English", "HAT (Heavy Anti-Tank Team)"], + ["Spanish", "HAT (Equipo anti-tanque pesado)"] + ]], + [DSTRING(special_elements_displayName), [ + ["English", "Special Elements"], + ["Spanish", "Special Elements"] + ]], + [DSTRING(rgr_riflesquad_displayName), [ + ["English", "Ranger Rifle Squad"], + ["Spanish", "Escuadra de fusileros Ranger"] + ]], + [DSTRING(rgr_machinegunsquad_displayName), [ + ["English", "Ranger Machinegun Squad"], + ["Spanish", "Escuadra de ametralladoras Ranger"] + ]], + [DSTRING(custom_unit_displayName), [ + ["English", "Custom Unit"], + ["Spanish", "Unidad personalizada"] + ]], + [DSTRING(zeus_unit_displayName), [ + ["English", "Zeus Unit"], + ["Spanish", "Unidad Zeus"] + ]] +] diff --git a/framework/components/player/XEH_PREP.sqf b/framework/components/player/XEH_PREP.sqf index 4bf0074..9af0561 100644 --- a/framework/components/player/XEH_PREP.sqf +++ b/framework/components/player/XEH_PREP.sqf @@ -1,9 +1,12 @@ #include "script_component.hpp" -IPREP(mapSwitchTextures); -IPREP(resizeMapMarkers); -IPREP(hearing); -IPREP(hideRespawnMarker); -IPREP(restrictLauncher); -IPREP(drinking); -IPREP(spectator); +PREP(mapSwitchTextures); +PREP(resizeMapMarkers); +PREP(hearing); +PREP(hideRespawnMarker); +PREP(restrictLauncher); +PREP(drinking); +PREP(spectator); +PREP(teamActions); +PREP(setRank); +PREP(treatment); diff --git a/framework/components/player/XEH_playerInit.sqf b/framework/components/player/XEH_playerInit.sqf new file mode 100644 index 0000000..efae628 --- /dev/null +++ b/framework/components/player/XEH_playerInit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +/* Fix Loading Bug */ +[] call EFUNC(utility,endLoadingScreen); + +[] call FUNC(mapSwitchTextures); +[] call FUNC(resizeMapMarkers); +[] call FUNC(hideRespawnMarker); +[] call FUNC(restrictLauncher); +[] call FUNC(drinking); +[] call FUNC(spectator); +[] call FUNC(teamActions); +[] call FUNC(setRank); +[] call FUNC(treatment); \ No newline at end of file diff --git a/framework/components/player/XEH_postInit.sqf b/framework/components/player/XEH_postInit.sqf new file mode 100644 index 0000000..84f2529 --- /dev/null +++ b/framework/components/player/XEH_postInit.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" \ No newline at end of file diff --git a/framework/components/player/XEH_preInit.sqf b/framework/components/player/XEH_preInit.sqf new file mode 100644 index 0000000..bbd3087 --- /dev/null +++ b/framework/components/player/XEH_preInit.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +[] call FUNC(hearing); \ No newline at end of file diff --git a/framework/components/player/fn_drinking.sqf b/framework/components/player/fn_drinking.sqf deleted file mode 100644 index 94e77d0..0000000 --- a/framework/components/player/fn_drinking.sqf +++ /dev/null @@ -1,135 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Allows players to drink to speed up stamina recovery - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_player_fnc_drinking - * - * Public: No - */ -SCRIPT(drinking); - -/* Waituntil player is alive */ -waitUntil { alive player && !isNull player }; - -GVAR(drinking_hydrationItems) = [ - ["ACE_Canteen", ["Land_Canteen_F", 0.2, 15]], ["ACE_Canteen_Half", ["Land_Canteen_F", 0.2, 15]], ["ACE_WaterBottle", ["Land_BottlePlastic_V2_F", 0.2, 15]], ["ACE_WaterBottle_Half", ["Land_BottlePlastic_V2_F", 0.2, 15]], - ["ACE_Can_Franta", ["Land_Can_V2_F", 0.1, 5]], ["ACE_Can_RedGull", ["Land_Can_V3_F", 0.1, 8]], ["ACE_Can_Spirit", ["Land_Can_V1_F", 0.1, 5]] -]; - -/* Drink function */ -GVAR(drinking_fnc_consume) = { - private _item = _this select 2; - private _stanceIndex = ["STAND", "CROUCH", "PRONE"] find stance player; - private _itemData = [[GVAR(drinking_hydrationItems)] call CBA_fnc_hashCreate, _item] call CBA_fnc_hashGet; - private _objClass = _itemData select 0; - private _replacementItem = getText (configFile >> "CfgWeapons" >> _item >> "acex_field_rations_replacementItem"); - private _animation = (getArray (configFile >> "CfgWeapons" >> _item >> "acex_field_rations_consumeAnims")) select _stanceIndex; - private _sound = (getArray (configFile >> "CfgWeapons" >> _item >> "acex_field_rations_consumeSounds")) select _stanceIndex; - - /* Play animation */ - [player, _animation, 1] call ace_common_fnc_doAnimation; - waitUntil {toUpper(animationState player) isEqualTo toUpper _animation}; - - /* If unit is prone don't use any physical objects */ - private ["_baseObj", "_drinkObj"]; - if (_stanceIndex isEqualTo 2) then { - /* Create physical objects */ - _baseObj = objNull; - _drinkObj = objNull; - } else { - /* Create physical objects */ - _baseObj = "Land_Can_V2_F" createVehicle getPos player; - _baseObj hideObjectGlobal true; - _drinkObj = _objClass createVehicle getPos player; - - _drinkObj attachTo [_baseObj, [0, 0, 0]]; - _baseObj attachTo [player, [-0.03, 0.0, -0.15], "righthandmiddle1"]; - }; - - /* Play the sound and animate the physical object */ - playSound _sound; - sleep 1; - for "_i" from 0 to 0.7 step 0.03 do { - private _rotation = [[-0.003, 0.007, 0.999], [-0.070, -0.997, 0.001], _i, 2.5] call BIS_fnc_interpolateVectorConstant; - _baseObj setVectorUp _rotation; - private _position = [[-0.03, 0.0, -0.15], [-0.03, (_itemData select 1), -0.02], _i, 0.4] call BIS_fnc_interpolateVectorConstant; - _baseObj attachTo [player, _position, "righthandmiddle1"]; - - sleep 0.03; - }; - _baseObj setVectorUp [-0.070, -0.997, 0.001]; - - private _oldFactor = ace_advanced_fatigue_recoveryFactor; - ace_advanced_fatigue_recoveryFactor = (_itemData select 2); - - sleep 5; - ace_advanced_fatigue_recoveryFactor = _oldFactor; - - for "_i" from 0.7 to 0 step -0.03 do { - private _rotation = [[-0.003, 0.007, 0.999], [-0.070, -0.997, 0.001], _i, 2] call BIS_fnc_interpolateVectorConstant; - _baseObj setVectorUp _rotation; - private _position = [[-0.03, 0.0, -0.15], [-0.03, (_itemData select 1), -0.02], _i, 0.4] call BIS_fnc_interpolateVectorConstant; - _baseObj attachTo [player, _position, "righthandmiddle1"]; - sleep 0.03; - }; - _baseObj setVectorUp [-0.003, 0.007, 0.999]; - - if (["Can", _animation] call BIS_fnc_inString) then { - sleep 0.3; - { - detach _x; - _x setVectorUp [-0.003, 0.700, 0.999]; - } forEach attachedObjects _baseObj; - deleteVehicle _baseObj; - } else { - sleep 0.5; - for "_i" from 0 to 0.3 step 0.03 do { - private _rotation = [[-0.003, 0.007, 0.999], [-0.003, 0.400, 0.999], _i, 1] call BIS_fnc_interpolateVectorConstant; - _baseObj setVectorUp _rotation; - sleep 0.03; - }; - deleteVehicle _drinkObj; - deleteVehicle _baseObj; - }; - - /* Remove and replace item with replacementItem */ - player removeItem _item; - if (_replacementItem != "") then { - player addItem _replacementItem; - }; -}; - -private _condition = { - (((items player) findIf {_x in ([[GVAR(drinking_hydrationItems)] call CBA_fnc_hashCreate] call CBA_fnc_hashKeys)}) != -1) - && vehicle player isEqualTo player - && !visibleMap -}; - -private _children = { - params ["_target"]; - - private _actions = []; - private _hydrationItems = []; - { - if ((_x in ([[GVAR(drinking_hydrationItems)] call CBA_fnc_hashCreate] call CBA_fnc_hashKeys)) && !(_x in _hydrationItems)) then { - private _displayName = getText (configFile >> "CfgWeapons" >> _x >> "displayName"); - private _icon = getText (configFile >> "CfgWeapons" >> _x >> "picture"); - private _action = [format [QGVAR(drinking_)+"%1", _x], format[LSTRING(drink_from), _displayName], _icon, { _this spawn GVAR(drinking_fnc_consume) }, { true }, {}, _x] call ace_interact_menu_fnc_createAction; - _actions pushBack [_action, [], _target]; - _hydrationItems pushBack _x; - }; - } forEach (items player); - - _actions; -}; - -private _action = [QGVAR(drinking_menu), LSTRING(hydration), "", {}, _condition, _children] call ace_interact_menu_fnc_createAction; -[typeOf player, 1, ["ACE_SelfActions"], _action] call ace_interact_menu_fnc_addActionToClass; diff --git a/framework/components/player/fn_hearing.sqf b/framework/components/player/fn_hearing.sqf deleted file mode 100644 index 0b3a890..0000000 --- a/framework/components/player/fn_hearing.sqf +++ /dev/null @@ -1,90 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Enables ACE hearing without ringing or deafness - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * [] call cmf_player_fnc_hearing - * - * Public: No - */ -SCRIPT(hearing); - -_this spawn { - - /* Check if it is enabled */ - private _enabled = ( CONFIG_PARAM_4(SETTINGS,player,hearing,enable) ) isEqualTo 1; - if !(_enabled) exitWith {}; - - /* Code for putting in the earplugs */ - private _codein = { - player setVariable [QGVAR(hearing_earplugsIn), true]; - - /* Raise event */ - [QGVAR(hearing_onEarplugsIn), []] call CBA_fnc_localEvent; - }; - - /* Code for taking out earplugs */ - private _codeout = { - player setVariable [QGVAR(hearing_earplugsIn), false]; - - /* Raise event */ - [QGVAR(hearing_onEarplugsOut), []] call CBA_fnc_localEvent; - }; - - /* Waituntil player is alive */ - waitUntil { alive player && !isNull player }; - - /* Add the ace action */ - private _actionIn = [QGVAR(hearing_insertEarplugs), "Insert earplugs", "", _codein, { "ACE_EarPlugs" in (items player) && !(player getVariable [QGVAR(hearing_earplugsIn), false]) }] call ace_interact_menu_fnc_createAction; - private _actionOut = [QGVAR(hearing_takeOutEarplugs), "Take out earplugs", "", _codeout, { (player getVariable [QGVAR(hearing_earplugsIn), false]) }] call ace_interact_menu_fnc_createAction; - [(typeOf player), 1, ["ACE_SelfActions", "ACE_Equipment"], _actionIn] call ace_interact_menu_fnc_addActionToClass; - [(typeOf player), 1, ["ACE_SelfActions", "ACE_Equipment"], _actionOut] call ace_interact_menu_fnc_addActionToClass; - - player addEventHandler ["Killed", _codeout]; - - /* Calculate the appropriate volume */ - [{ - private _headgearSetting = (CONFIG_PARAM_4(SETTINGS,player,hearing,attenuateHeadgear)) isEqualTo 1; - private _earplugVolumeSetting = CONFIG_PARAM_4(SETTINGS,player,hearing,earplugsVolume); - private _volumeAttenuation = 1; - - /* If player dies reset volume */ - if (!alive player) exitWith { - 0 fadeSound 1; - 0 fadeRadio 1; - if (!isNil "acre_api_fnc_setGlobalVolume") then { [1^0.33] call acre_api_fnc_setGlobalVolume }; - }; - - /* Get the hearing protection value from headgear */ - if (headgear player != "" && _headgearSetting) then { - private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear player >> "ace_hearing_lowerVolume") min 1; - _volumeAttenuation = _volumeAttenuation * (1 - _attenuation); - }; - - /* Get the hearing protection value from goggles */ - if (goggles player != "" && _headgearSetting) then { - private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles player >> "ace_hearing_lowerVolume") min 1; - _volumeAttenuation = _volumeAttenuation * (1 - _attenuation); - }; - - /* Check if earplugs are in */ - if (player getVariable [QGVAR(hearing_earplugsIn), false]) then { - private _attenuation = _earplugVolumeSetting; - _volumeAttenuation = _volumeAttenuation * (1 - _attenuation); - }; - - private _volume = _volumeAttenuation max 0.05; - - /* Set the final calculated volume */ - 0 fadeSound _volume; - 0 fadeRadio _volume; - if (!isNil "acre_api_fnc_setGlobalVolume") then { [_volume^0.33] call acre_api_fnc_setGlobalVolume }; - }, 0, []] call CBA_fnc_addPerFrameHandler; -}; diff --git a/framework/components/player/functions/fn_drinking.sqf b/framework/components/player/functions/fn_drinking.sqf new file mode 100644 index 0000000..17e45ab --- /dev/null +++ b/framework/components/player/functions/fn_drinking.sqf @@ -0,0 +1,135 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Allows players to drink to speed up stamina recovery + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_player_fnc_drinking + * + * Public: No + */ +SCRIPT(drinking); + +// @TODO: Move function declerations outside and pass them as args +[{ alive player && !isNull player }, { + GVAR(drinking_hydrationItems) = [ + ["ACE_Canteen", ["Land_Canteen_F", 0.2, 15]], ["ACE_Canteen_Half", ["Land_Canteen_F", 0.2, 15]], ["ACE_WaterBottle", ["Land_BottlePlastic_V2_F", 0.2, 15]], ["ACE_WaterBottle_Half", ["Land_BottlePlastic_V2_F", 0.2, 15]], + ["ACE_Can_Franta", ["Land_Can_V2_F", 0.1, 5]], ["ACE_Can_RedGull", ["Land_Can_V3_F", 0.1, 8]], ["ACE_Can_Spirit", ["Land_Can_V1_F", 0.1, 5]] + ]; + + /* Drink function */ + GVAR(drinking_fnc_consume) = { + private _item = _this select 2; + private _stanceIndex = ["STAND", "CROUCH", "PRONE"] find stance player; + private _itemData = [[GVAR(drinking_hydrationItems)] call CBA_fnc_hashCreate, _item] call CBA_fnc_hashGet; + private _objClass = _itemData select 0; + private _replacementItem = getText (configFile >> "CfgWeapons" >> _item >> "acex_field_rations_replacementItem"); + private _animation = (getArray (configFile >> "CfgWeapons" >> _item >> "acex_field_rations_consumeAnims")) select _stanceIndex; + private _sound = (getArray (configFile >> "CfgWeapons" >> _item >> "acex_field_rations_consumeSounds")) select _stanceIndex; + + /* Play animation */ + [player, _animation, 1] call ace_common_fnc_doAnimation; + waitUntil {toUpper(animationState player) isEqualTo toUpper _animation}; + + /* If unit is prone don't use any physical objects */ + private ["_baseObj", "_drinkObj"]; + if (_stanceIndex isEqualTo 2) then { + /* Create physical objects */ + _baseObj = objNull; + _drinkObj = objNull; + } else { + /* Create physical objects */ + _baseObj = "Land_Can_V2_F" createVehicle getPos player; + _baseObj hideObjectGlobal true; + _drinkObj = _objClass createVehicle getPos player; + + _drinkObj attachTo [_baseObj, [0, 0, 0]]; + _baseObj attachTo [player, [-0.03, 0.0, -0.15], "righthandmiddle1"]; + }; + + /* Play the sound and animate the physical object */ + playSound _sound; + sleep 1; + for "_i" from 0 to 0.7 step 0.03 do { + private _rotation = [[-0.003, 0.007, 0.999], [-0.070, -0.997, 0.001], _i, 2.5] call BIS_fnc_interpolateVectorConstant; + _baseObj setVectorUp _rotation; + private _position = [[-0.03, 0.0, -0.15], [-0.03, (_itemData select 1), -0.02], _i, 0.4] call BIS_fnc_interpolateVectorConstant; + _baseObj attachTo [player, _position, "righthandmiddle1"]; + + sleep 0.03; + }; + _baseObj setVectorUp [-0.070, -0.997, 0.001]; + + private _oldFactor = ace_advanced_fatigue_recoveryFactor; + ace_advanced_fatigue_recoveryFactor = (_itemData select 2); + + sleep 5; + ace_advanced_fatigue_recoveryFactor = _oldFactor; + + for "_i" from 0.7 to 0 step -0.03 do { + private _rotation = [[-0.003, 0.007, 0.999], [-0.070, -0.997, 0.001], _i, 2] call BIS_fnc_interpolateVectorConstant; + _baseObj setVectorUp _rotation; + private _position = [[-0.03, 0.0, -0.15], [-0.03, (_itemData select 1), -0.02], _i, 0.4] call BIS_fnc_interpolateVectorConstant; + _baseObj attachTo [player, _position, "righthandmiddle1"]; + sleep 0.03; + }; + _baseObj setVectorUp [-0.003, 0.007, 0.999]; + + if (["Can", _animation] call BIS_fnc_inString) then { + sleep 0.3; + { + detach _x; + _x setVectorUp [-0.003, 0.700, 0.999]; + } forEach attachedObjects _baseObj; + deleteVehicle _baseObj; + } else { + sleep 0.5; + for "_i" from 0 to 0.3 step 0.03 do { + private _rotation = [[-0.003, 0.007, 0.999], [-0.003, 0.400, 0.999], _i, 1] call BIS_fnc_interpolateVectorConstant; + _baseObj setVectorUp _rotation; + sleep 0.03; + }; + deleteVehicle _drinkObj; + deleteVehicle _baseObj; + }; + + /* Remove and replace item with replacementItem */ + player removeItem _item; + if (_replacementItem != "") then { + player addItem _replacementItem; + }; + }; + + private _condition = { + (((items player) findIf {_x in ([[GVAR(drinking_hydrationItems)] call CBA_fnc_hashCreate] call CBA_fnc_hashKeys)}) != -1) + && vehicle player isEqualTo player + && !visibleMap + }; + + private _children = { + params ["_target"]; + + private _actions = []; + private _hydrationItems = []; + { + if ((_x in ([[GVAR(drinking_hydrationItems)] call CBA_fnc_hashCreate] call CBA_fnc_hashKeys)) && !(_x in _hydrationItems)) then { + private _displayName = getText (configFile >> "CfgWeapons" >> _x >> "displayName"); + private _icon = getText (configFile >> "CfgWeapons" >> _x >> "picture"); + private _action = [format [QGVAR(drinking_)+"%1", _x], format[LSTRING(drink_from), _displayName], _icon, { _this spawn GVAR(drinking_fnc_consume) }, { true }, {}, _x] call ace_interact_menu_fnc_createAction; + _actions pushBack [_action, [], _target]; + _hydrationItems pushBack _x; + }; + } forEach (items player); + + _actions; + }; + + private _action = [QGVAR(drinking_menu), LSTRING(hydration), "rsc\data\icon_ace_hydration_ca.paa", {}, _condition, _children] call ace_interact_menu_fnc_createAction; + [typeOf player, 1, ["ACE_SelfActions", "ACE_Equipment"], _action] call ace_interact_menu_fnc_addActionToClass; // @TODO: Change how action is added +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/player/functions/fn_hearing.sqf b/framework/components/player/functions/fn_hearing.sqf new file mode 100644 index 0000000..f06c07c --- /dev/null +++ b/framework/components/player/functions/fn_hearing.sqf @@ -0,0 +1,88 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Enables ACE hearing without ringing or deafness + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_player_fnc_hearing + * + * Public: No + */ +SCRIPT(hearing); + +/* Check if it is enabled */ +if !(GVAR(setting_hearing)) exitWith {}; + +/* Code for putting in the earplugs */ +GVAR(hearing_fnc_codein) = { + player setVariable [QGVAR(hearing_earplugsIn), true]; + + /* Raise event */ + [QGVAR(hearing_onEarplugsIn), []] call CBA_fnc_localEvent; +}; + +/* Code for taking out earplugs */ +GVAR(hearing_fnc_codeout) = { + player setVariable [QGVAR(hearing_earplugsIn), false]; + + /* Raise event */ + [QGVAR(hearing_onEarplugsOut), []] call CBA_fnc_localEvent; +}; + +["ace_interact_menu_newControllableObject", { + params ["_type"]; + + if (!(_type isKindOf "Man")) exitWith {}; + + private _actionIn = [QGVAR(hearing_insertEarplugs), "Insert earplugs", "", GVAR(hearing_fnc_codein), + { "ACE_EarPlugs" in (items _player) && !(_player getVariable [QGVAR(hearing_earplugsIn), false]) }] call ace_interact_menu_fnc_createAction; + + private _actionOut = [QGVAR(hearing_takeOutEarplugs), "Take out earplugs", "", GVAR(hearing_fnc_codeout), + { (_player getVariable [QGVAR(hearing_earplugsIn), false]) }] call ace_interact_menu_fnc_createAction; + + [_type, 1, ["ACE_SelfActions", "ACE_Equipment"], _actionIn] call ace_interact_menu_fnc_addActionToClass; // @BUG: Action not shown + [_type, 1, ["ACE_SelfActions", "ACE_Equipment"], _actionOut] call ace_interact_menu_fnc_addActionToClass; +}] call CBAFUNC(addEventHandler); + +player addEventHandler ["Killed", GVAR(hearing_fnc_codeout)]; + +/* Calculate the appropriate volume */ +[{ + private _volumeAttenuation = 1; + + /* If player dies reset volume */ + if (!alive player) exitWith { + 0 fadeSound 1; + 0 fadeRadio 1; + }; + + /* Get the hearing protection value from headgear */ + if (headgear player != "" && GVAR(setting_attenuateHeadgear)) then { + private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear player >> "ace_hearing_lowerVolume") min 1; + _volumeAttenuation = _volumeAttenuation * (1 - _attenuation); + }; + + /* Get the hearing protection value from goggles */ + if (goggles player != "" && GVAR(setting_attenuateHeadgear)) then { + private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles player >> "ace_hearing_lowerVolume") min 1; + _volumeAttenuation = _volumeAttenuation * (1 - _attenuation); + }; + + /* Check if earplugs are in */ + if (player getVariable [QGVAR(hearing_earplugsIn), false]) then { + private _attenuation = GVAR(setting_earplugVolume); + _volumeAttenuation = _volumeAttenuation * (1 - _attenuation); + }; + + private _volume = _volumeAttenuation max 0.05; + + /* Set the final calculated volume */ + 0 fadeSound _volume; + 0 fadeRadio _volume; +}, 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/framework/components/player/fn_hideRespawnMarker.sqf b/framework/components/player/functions/fn_hideRespawnMarker.sqf similarity index 73% rename from framework/components/player/fn_hideRespawnMarker.sqf rename to framework/components/player/functions/fn_hideRespawnMarker.sqf index 81c1bf8..30a7026 100644 --- a/framework/components/player/fn_hideRespawnMarker.sqf +++ b/framework/components/player/functions/fn_hideRespawnMarker.sqf @@ -16,14 +16,10 @@ */ SCRIPT(hideRespawnMarker); -/* Check if it is enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,player,hideRespawnMarkers) ) isEqualTo 1; -if !(_enabled) exitWith {}; - -[] spawn { - waitUntil {!isNull findDisplay 12}; - +[{ !isNull findDisplay 12 }, { findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw", { + if !(GVAR(setting_hideRespawnMarkers)) exitWith {}; + if (visibleMap) then { { if (markerShape _x == "ICON" && markerType _x == "respawn_inf") then { @@ -32,4 +28,4 @@ if !(_enabled) exitWith {}; } forEach allMapMarkers; }; }]; -}; +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/player/fn_mapSwitchTextures.sqf b/framework/components/player/functions/fn_mapSwitchTextures.sqf similarity index 51% rename from framework/components/player/fn_mapSwitchTextures.sqf rename to framework/components/player/functions/fn_mapSwitchTextures.sqf index 2c92c42..9a572d5 100644 --- a/framework/components/player/fn_mapSwitchTextures.sqf +++ b/framework/components/player/functions/fn_mapSwitchTextures.sqf @@ -17,15 +17,11 @@ SCRIPT(mapSwitchTextures); /* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,player,switchMapTextures) ) isEqualTo 1; -if !(_enabled) exitWith {}; +if !(GVAR(setting_switchMapTextures)) exitWith {}; if ( isDedicated ) exitWith {}; -[] spawn { - /* waitUntil the map exists */ - waitUntil { !isNull findDisplay 12 }; - - /* Press the switch textures button */ - ctrlActivate ( ( findDisplay 12 ) displayCtrl 107 ); -}; +[{ !isNull findDisplay 12 }, { + /* Press the switch textures button */ + ctrlActivate ( ( findDisplay 12 ) displayCtrl 107 ); +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/player/fn_resizeMapMarkers.sqf b/framework/components/player/functions/fn_resizeMapMarkers.sqf similarity index 76% rename from framework/components/player/fn_resizeMapMarkers.sqf rename to framework/components/player/functions/fn_resizeMapMarkers.sqf index fd208c7..be38b9b 100644 --- a/framework/components/player/fn_resizeMapMarkers.sqf +++ b/framework/components/player/functions/fn_resizeMapMarkers.sqf @@ -16,16 +16,12 @@ */ SCRIPT(resizeMapMarkers); -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,player,consistentMarkers) ) isEqualTo 1; -if !(_enabled) exitWith {}; - if (!hasInterface) exitWith {}; -[] spawn { - waitUntil {!isNull findDisplay 12}; - +[{ !isNull findDisplay 12 }, { findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw", { + if !(GVAR(setting_consistentMarkers)) exitWith {}; + if (visibleMap) then { private _scale = 0.05 / ctrlMapScale (_this select 0); { @@ -59,4 +55,19 @@ if (!hasInterface) exitWith {}; } forEach allMapMarkers; }; }]; -}; + + /* Reset map marker size when map is closed */ + addMissionEventHandler ["Map", { + params ["_mapIsOpened"]; + + if !(GVAR(setting_consistentMarkers)) exitWith {}; + + if (!_mapIsOpened) then { + private _m = "cmf_init_resizeMapMarkers_markerSize_" + _x; + { + _markerSizeFinal = missionNamespace getVariable [_m, [1,1]]; + _x setMarkerSizeLocal _markerSizeFinal; + } forEach allMapmarkers; + }; + }]; +}] call CBA_fnc_waitUntilAndExecute; \ No newline at end of file diff --git a/framework/components/player/fn_restrictLauncher.sqf b/framework/components/player/functions/fn_restrictLauncher.sqf similarity index 91% rename from framework/components/player/fn_restrictLauncher.sqf rename to framework/components/player/functions/fn_restrictLauncher.sqf index 03ff309..4ad9ff3 100644 --- a/framework/components/player/fn_restrictLauncher.sqf +++ b/framework/components/player/functions/fn_restrictLauncher.sqf @@ -16,17 +16,15 @@ */ SCRIPT(restrictLauncher); -/* Check if it's enabled */ -private _enabled = ( CONFIG_PARAM_3(SETTINGS,player,restrictLauncher) ) isEqualTo 1; -if !(_enabled) exitWith {}; - if (!hasInterface) exitWith {}; player addEventHandler ["Respawn", { - params ["_unit"]; + params ["_unit"]; /* Create function to check if user has any launchers in loadout */ private _allowedLauncher = " + if !("+QGVAR(setting_restrictLauncher)+") exitWith { false }; + private _ret = true; private _loadoutFile = player getVariable ["QEGVAR(kosherArsenal,loadout)", """"]; private _role = player getVariable ["QEGVAR(common,role)", ""RFL""]; diff --git a/framework/components/player/functions/fn_setRank.sqf b/framework/components/player/functions/fn_setRank.sqf new file mode 100644 index 0000000..c31cf94 --- /dev/null +++ b/framework/components/player/functions/fn_setRank.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Sets the unit's rank based on their group + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_player_fnc_setRank + * + * Public: No + */ + +if (!hasInterface) exitWith { }; + +[{ !isNull player }, { + /* If player rank is different from default disregard */ + if ((rank player) != "PRIVATE") exitWith { }; + + /* Get group data */ + private _groupData = [group player] call EFUNC(common,getCallsign); + private _level = _groupData select 2; + + /* Set rank */ + if (isClass (missionConfigFile >> "CMF_ORBAT" >> "SIZES" >> _level)) then { + private _rank = getText (missionConfigFile >> "CMF_ORBAT" >> "SIZES" >> toUpper _level >> "leadRank"); + if ((player isEqualTo leader group player)) then { + _rank = getText (missionConfigFile >> "CMF_ORBAT" >> "SIZES" >> toUpper _level >> "leadRank"); + }; + + [player, _rank] remoteExec ["setUnitRank", 0, true]; + }; +}] call CBA_fnc_waitUntilAndExecute; + diff --git a/framework/components/player/fn_spectator.sqf b/framework/components/player/functions/fn_spectator.sqf similarity index 97% rename from framework/components/player/fn_spectator.sqf rename to framework/components/player/functions/fn_spectator.sqf index 36856c1..163e245 100644 --- a/framework/components/player/fn_spectator.sqf +++ b/framework/components/player/functions/fn_spectator.sqf @@ -16,6 +16,7 @@ */ /* Add control to ui when it's opened */ +// @TODO: replace spawn _this spawn { /* Check if it's being executed on the Clustercommunity server */ diff --git a/framework/components/player/functions/fn_teamActions.sqf b/framework/components/player/functions/fn_teamActions.sqf new file mode 100644 index 0000000..a0aaafb --- /dev/null +++ b/framework/components/player/functions/fn_teamActions.sqf @@ -0,0 +1,113 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Creates a group menu for team leaders to control their group. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_player_fnc_teamActions + * + * Public: No + */ + +if (!hasInterface) exitWith {}; + +[{ alive player && !isNull player }, { + /* Menu items for the group menu */ + private _childrenGroup = { + params ["_target"]; + private _actions = []; + + /* Create an action for each team member */ + { + if (_x != player) then { + private _action = ([format [QGVAR(member_%1), name _x], (name _x), "a3\ui_f\data\igui\rscingameui\rscunitinfo\si_stand_ca.paa", { }, { true }, { + params ["_target", "", "_unit"]; + private _actions = []; + + /* Assign red team */ + private _action = ([QGVAR(assignTeamRed), "Assign Red", "z\ace\interaction\ui\team\team_white_ca.paa", { + ["CBA_teamColorChanged", [(_this select 2), "RED"]] call CBA_fnc_globalEvent; + }, { assignedTeam (_this select 2) != "RED" }, {}, _unit, "", 4, [false, false, false, false, false], { + ['RED', '\z\ace\addons\interaction\UI\team\team_white_ca.paa', _this select 3] call ace_interaction_fnc_modifyTeamManagementAction; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Assign green team */ + private _action = ([QGVAR(assignTeamGreen), "Assign Green", "z\ace\interaction\ui\team\team_white_ca.paa", { + ["CBA_teamColorChanged", [(_this select 2), "GREEN"]] call CBA_fnc_globalEvent; + }, { assignedTeam (_this select 2) != "GREEN" }, {}, _unit, "", 4, [false, false, false, false, false], { + ['GREEN', '\z\ace\addons\interaction\UI\team\team_white_ca.paa', _this select 3] call ace_interaction_fnc_modifyTeamManagementAction; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Assign blue team */ + private _action = ([QGVAR(assignTeamBlue), "Assign Blue", "z\ace\interaction\ui\team\team_white_ca.paa", { + ["CBA_teamColorChanged", [(_this select 2), "BLUE"]] call CBA_fnc_globalEvent; + }, { assignedTeam (_this select 2) != "BLUE" }, {}, _unit, "", 4, [false, false, false, false, false], { + ['BLUE', '\z\ace\addons\interaction\UI\team\team_white_ca.paa', _this select 3] call ace_interaction_fnc_modifyTeamManagementAction; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Assign yellow team */ + private _action = ([QGVAR(assignTeamYellow), "Assign Yellow", "z\interaction\ace\ui\team\team_white_ca.paa", { + ["CBA_teamColorChanged", [(_this select 2), "YELLOW"]] call CBA_fnc_globalEvent; + }, { assignedTeam (_this select 2) != "YELLOW" }, {}, _unit, "", 4, [false, false, false, false, false], { + ['YELLOW', '\z\ace\addons\interaction\UI\team\team_white_ca.paa', _this select 3] call ace_interaction_fnc_modifyTeamManagementAction; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Unassigned team */ + private _action = ([QGVAR(unAssignTeam), "Kick from team", "z\ace\interaction\UI\team\team_white_ca.paa", { + ["CBA_teamColorChanged", [(_this select 2), "MAIN"]] call CBA_fnc_globalEvent; + }, { assignedTeam (_this select 2) != "MAIN" }, {}, _unit, "", 4, [false, false, false, false, false], { + ['MAIN', '\z\ace\addons\interaction\UI\team\team_white_ca.paa', _this select 3] call ace_interaction_fnc_modifyTeamManagementAction; + }] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + /* Kick from group */ + private _action = ([QGVAR(unAssignGroup), "Kick from group", "\z\ace\addons\interaction\UI\team\team_management_ca.paa", { + _oldGroup = units group (_this select 2); + _newGroup = createGroup side group (_this select 2); + [(_this select 2)] joinSilent _newGroup; {(_this select 2) reveal _x} forEach _oldGroup; + }, { true }, {}, _unit] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + + _actions; + }, _x] call ace_interact_menu_fnc_createAction); + _actions pushBack [_action, [], _target]; + }; + } forEach units group player; + + _actions; + }; + + /* Get icon that represents the group type */ + private _icon = switch ((group player) getVariable [QEGVAR(common,sqd_type), "INF"]) do { + case ("INF"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_inf_ca.paa" }; + case ("ARMOR"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_armor_ca.paa" }; + case ("TRANS"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_unknown_ca.paa" }; + case ("CAS"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_air_ca.paa" }; + case ("LOGI"): { "ca\ui\data\markers\b_support.paa" }; + case ("WEAPONS"): { "ca\ui\data\markers\b_mortar.paa" }; + case ("SUPPORT"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_unknown_ca.paa" }; + case ("MECH"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_mech_inf_ca.paa" }; + case ("MOTOR"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_motor_inf_ca.paa" }; + case ("HQ"): { "a3\ui_f\data\gui\cfg\hints\icon_text\b_hq_ca.paa" }; + default { "a3\ui_f\data\gui\cfg\hints\icon_text\b_unknown_ca.paa" }; + }; + + /* Change title to current group name */ + private _modifier = { + (_this select 3) set [1, (groupID group player)]; + }; + + private _groupAction = [QGVAR(team_main), (groupID group player), _icon, {}, { leader group player == player }, _childrenGroup, [], "", 4, [false, false, false, true, false], _modifier] call ace_interact_menu_fnc_createAction; + [typeOf player, 1, ["ACE_SelfActions", "ACE_TeamManagement"], _groupAction] call ace_interact_menu_fnc_addActionToClass; +}] call CBA_fnc_waitUntilAndExecute; + diff --git a/framework/components/player/functions/fn_treatment.sqf b/framework/components/player/functions/fn_treatment.sqf new file mode 100644 index 0000000..78b7280 --- /dev/null +++ b/framework/components/player/functions/fn_treatment.sqf @@ -0,0 +1,75 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Shows a hint when the player is being treated + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call cmf_player_fnc_treatment + * + * Public: No + */ + +["ace_treatmentStarted", { + params ["_caller", "_target", "_selectionName", "_className", "_itemUser", "_usedItem"]; + + /* Show a hint when player is being treated */ + [_this, { + params ["_caller", "_target", "_selectionName", "_className", "_itemUser", "_usedItem"]; + + if (_caller isEqualTo _target) exitWith {}; + if !(_target isEqualTo player) exitWith {}; + + private _text = "Somebody is treating you"; + if !(player getVariable ["ACE_isUnconscious", false]) then { + _text = format ["%1 is giving you a %2", name _caller, [(configFile >> "CfgVehicles" >> _usedItem + "Item")] call BIS_fnc_displayName]; + }; + + private _handler = [_text, [safeZoneX - 0.35, safeZoneW - safeZoneX], safezoneH - 0.7, 9999, 1, 0, ([QGVAR(treatment_notification)] call BIS_fnc_rscLayer)] spawn BIS_fnc_dynamicText; + _target setVariable [QGVAR(treatment_notifHandler), _handler, true]; + }] remoteExec ["call", _target]; +}] call CBA_fnc_addEventHandler; + +["ace_treatmentSucceded", { + params ["_caller", "_target", "_selectionName", "_className", "_itemUser", "_usedItem"]; + + /* Hide hint if it is up */ + [_this, { + params ["_caller", "_target", "_selectionName", "_className", "_itemUser", "_usedItem"]; + + if (_caller isEqualTo _target) exitWith {}; + if !(_target isEqualTo player) exitWith {}; + + private _handler = _target getVariable [QGVAR(treatment_notifHandler), nil]; + if (!isNil "_handler") then { + terminate _handler; + ([QGVAR(treatment_notification)] call BIS_fnc_rscLayer) cutText ["", "plain"]; + _target setVariable [QGVAR(treatment_notifHandler), nil, true]; + }; + }] remoteExec ["call", _target]; + +}] call CBA_fnc_addEventHandler; + +["ace_treatmentFailed", { + params ["_caller", "_target", "_selectionName", "_className", "_itemUser", "_usedItem"]; + + /* Hide hint if it is up */ + [_this, { + params ["_caller", "_target", "_selectionName", "_className", "_itemUser", "_usedItem"]; + + if (_caller isEqualTo _target) exitWith {}; + if !(_target isEqualTo player) exitWith {}; + + private _handler = _target getVariable [QGVAR(treatment_notifHandler), nil]; + if (!isNil "_handler") then { + terminate _handler; + ([QGVAR(treatment_notification)] call BIS_fnc_rscLayer) cutText ["", "plain"]; + _target setVariable [QGVAR(treatment_notifHandler), nil, true]; + }; + }] remoteExec ["call", _target]; +}] call CBA_fnc_addEventHandler; \ No newline at end of file diff --git a/framework/components/player/functions/script_component.hpp b/framework/components/player/functions/script_component.hpp new file mode 100644 index 0000000..fcf9da9 --- /dev/null +++ b/framework/components/player/functions/script_component.hpp @@ -0,0 +1 @@ +#include "..\script_component.hpp" diff --git a/framework/components/player/initSettings.sqf b/framework/components/player/initSettings.sqf new file mode 100644 index 0000000..6a1242c --- /dev/null +++ b/framework/components/player/initSettings.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" + +[ + QGVAR(setting_switchMapTextures), + "CHECKBOX", + ["Switch Map Textures", "Defaults map textures to topographic"], + QUOTE(MODULE_BEAUTIFIED), + true, + 0 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_hideRespawnMarkers), + "CHECKBOX", + ["Hide Respawn Markers", "Hides respawn markers from the map"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_consistentMarkers), + "CHECKBOX", + ["Consistent Marker Size", "Forces a consistent marker size regardless of zoom"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_restrictLauncher), + "CHECKBOX", + ["Restrict Launcher Access", "Restricts operation of launchers to those who has a launcher defined in their slot"], + QUOTE(MODULE_BEAUTIFIED), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_hearing), + "CHECKBOX", + ["Hearing", "Allows the use of items to reduce game volume"], + QUOTE(MODULE_BEAUTIFIED - Hearing), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_attenuateHeadgear), + "CHECKBOX", + ["Attenuate Headgear", "Headgear volume statistics will affect game volume"], + QUOTE(MODULE_BEAUTIFIED - Hearing), + true, + 1 +] call EFUNC(common,addSetting); + +[ + QGVAR(setting_earplugVolume), + "SLIDER", + ["Earplug Volume", "The volume that will be set when earplugs are inserted"], + QUOTE(MODULE_BEAUTIFIED - Hearing), + [0.01, 1.00, 0.50, 0, true], + 0 +] call EFUNC(common,addSetting); \ No newline at end of file diff --git a/framework/components/player/script_component.hpp b/framework/components/player/script_component.hpp index 96b4438..5c5ff82 100644 --- a/framework/components/player/script_component.hpp +++ b/framework/components/player/script_component.hpp @@ -1,7 +1,17 @@ #define MODULE player +#define MODULE_BEAUTIFIED Player + #define REQUIRED_ADDONS ["ace_hearing"] #define REQUIRED_MODULES ["common"] +#ifdef DEBUG_ENABLED_PLAYER + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_PLAYER + #define DEBUG_SETTINGS DEBUG_SETTINGS_PLAYER +#endif + #include "..\main\script_component.hpp" #define IDD_SPEC_DISPLAY 60000 diff --git a/framework/components/respawn/XEH_PREP.sqf b/framework/components/respawn/XEH_PREP.sqf index 6416433..93e9e2a 100644 --- a/framework/components/respawn/XEH_PREP.sqf +++ b/framework/components/respawn/XEH_PREP.sqf @@ -2,4 +2,10 @@ PREP(limit); PREP(setLimit); +PREP(getLimit); +PREP(getRemaining); PREP(rallyPoint); +PREP(countdown); +PREP(respawnButtonPFH); +PREP(unconciousEH); +PREP(respawnEH); diff --git a/framework/components/respawn/XEH_postInit.sqf b/framework/components/respawn/XEH_postInit.sqf new file mode 100644 index 0000000..de22a4d --- /dev/null +++ b/framework/components/respawn/XEH_postInit.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" + +[ + { !isNull (findDisplay 49) }, + { + disableSerialization; + private _ctrl = (findDisplay 49) ctrlCreate ["RscText", -1]; + _ctrl ctrlSetTextColor [1, 0.3, 0.3, 1]; + _ctrl ctrlSetFontHeight (((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1); + + _ctrl ctrlSetPosition [ + ( safeZoneX + ( safeZoneWAbs / 2 )) - ( 0.5 / 2 ), + (( safeZoneY + safeZoneH ) - 0.1) - 0.1, + 0.5, + 0.1 + ]; + + _ctrl ctrlShow false; + _ctrl ctrlCommit 0; + + uiNamespace setVariable [QGVAR(ctrlCounter), _ctrl]; + } +] call CBA_fnc_waitUntilAndExecute; + +GVAR(countdownHandler) = scriptNull; +GVAR(respawnState) = false; +GVAR(respawnTimer) = GVAR(setting_unconciousTimer); + +[FUNC(respawnButtonPFH)] call CBA_fnc_addPerFrameHandler; +["ace_unconscious", FUNC(unconciousEH)] call CBA_fnc_addEventHandler; +player addEventHandler ["Respawn", FUNC(respawnEH)]; \ No newline at end of file diff --git a/framework/components/respawn/fn_limit.sqf b/framework/components/respawn/fn_limit.sqf deleted file mode 100644 index c2d1605..0000000 --- a/framework/components/respawn/fn_limit.sqf +++ /dev/null @@ -1,77 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Eric - * Gives players a limited amount of lives which if all are spent will set player as a spectator. - * - * Arguments: - * 0: Respawns - * 1: condition [Default: {true}] - * - * Return Value: - * None - * - * Example: - * [5] call cmf_respawn_fnc_limit - * - * public: yes -*/ -SCRIPT(limit); - -params ["_respawns", ["_condition", { true }]]; - -/* Check if params are set and is of correct type */ -if (isNil "_respawns") exitWith { ERROR_MSG("respawns cannot be nil"); false }; - -if (call _condition) then { - /* Set the amount of allowed respawns */ - player setVariable[QGVAR(respawns), (_respawns + 1), true]; - - /* Check if player is out of lives on respawn */ - player addEventHandler ["Respawn", { - _respawns = player getVariable[QGVAR(respawns), 1]; - - if ((player getVariable[QGVAR(deaths), 0]) == _respawns) then { - if ((vehicle player) != player) then { - player action ["getOut", (vehicle player)]; - }; - - /* Put player in a new group and initialize spectator for him */ - [player] joinSilent (createGroup west); - [true, true, true] call ace_spectator_fnc_setSpectator; - } else { - /* Decrement the respawn counter */ - private _pCount = player getVariable[QGVAR(deaths), 0]; - private _pCount = _pCount + 1; - player setVariable[QGVAR(deaths), _pCount, true]; - [format[LSTRING(respawns_left), (_respawns - _pCount)], -1, -1, 5, 1, 0, 9459] spawn bis_fnc_dynamicText; - }; - }]; -}; - -/* Show an indicator of player lives for zeuses */ -[] spawn { - if (!hasInterface) exitwith {}; - waitUntil{!isnull (getAssignedCuratorLogic player)}; - - /* Get the respawns left for all players in mission and create 3D widget displaying the remaining respawns */ - if (player in (call bis_fnc_listcuratorplayers)) then { - addMissionEventHandler ["Draw3D", { - if (isNull curatorCamera) exitWith {}; - { - private _distance = position curatorCamera distance _x; - if (_distance < 1200) then { - private _respawnsLeft = (_x getVariable [QGVAR(respawns),1]) - (_x getVariable[QGVAR(deaths), 0]); - if (_respawnsLeft < 1) then { - private _iconPos = [(getPos _x select 0), (getPos _x select 1), (getPos _x select 2) - 0.5]; - drawIcon3D - ["", [1,0,0,0.7], _iconPos, 1, 2, 0, format["%1 Lives: %2", name _x, str _respawnsLeft], 0, 0.05, "PuristaMedium", "center"]; - } else { - private _iconPos = [(getPos _x select 0), (getPos _x select 1), (getPos _x select 2) - 0.5]; - drawIcon3D - ["", [1,1,1,0.7], _iconPos, 1, 2, 0, format["%1 Lives: %2", name _x, str _respawnsLeft], 0, 0.03, "PuristaMedium", "center"]; - }; - }; - } forEach allPlayers; - }]; - }; -}; diff --git a/framework/components/respawn/functions/fn_countdown.sqf b/framework/components/respawn/functions/fn_countdown.sqf new file mode 100644 index 0000000..deb4d7f --- /dev/null +++ b/framework/components/respawn/functions/fn_countdown.sqf @@ -0,0 +1,45 @@ +#include "script_component.hpp" +/* + * Author: Eric + * Displays countdown + * + * Arguments: + * None + * + * Return Value: + * Script Handle