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