Compare commits

...

34 Commits

Author SHA1 Message Date
d946170831 skip large blue spark on objects 2024-02-10 20:48:36 -08:00
ba708a8aa9 mostly working 2024-02-10 16:13:42 -08:00
032377d7f6 still testing 2024-02-09 21:37:59 -08:00
e0e06eff5e add emp functionality 2024-02-08 19:43:55 -08:00
hizumi
2c733f77df Merge branch 'develop' of https://iceberg-gaming.com:5443/hizumi/MissionTemplate into develop 2024-02-08 19:00:15 -06:00
8ed6b8a5c6 Merge pull request 'misc-improvements' (#23) from misc-improvements into develop
Reviewed-on: https://17th-gs.iceberg-gaming.com:5443/hizumi/MissionTemplate/pulls/23
2024-02-08 18:35:52 -06:00
1d7e1ede37 Merge branch 'develop' into misc-improvements 2024-02-08 18:35:36 -06:00
363016d778 Merge pull request 'allow zeus add/remove of wheels/tracks from vehicles' (#22) from feature/set-wheels-tracks-with-zen-module into develop
Reviewed-on: https://17th-gs.iceberg-gaming.com:5443/hizumi/MissionTemplate/pulls/22
2024-02-08 18:28:57 -06:00
442cb0b0b2 bugfixing 2024-02-08 15:35:42 -08:00
2db018103c move local diary mgmt to common module, clarify clientInit complete msg 2024-02-08 15:04:22 -08:00
fba423e38d update mapcopy module with CBA events 2024-02-08 12:47:51 -08:00
7268d8fd50 change vehicle flag actions to use class inheritance instead of object 2024-02-08 12:01:51 -08:00
3217ec487d simplify resupply actions addition 2024-02-08 11:50:07 -08:00
7c903d1021 add some built in flags as options 2024-02-08 11:48:41 -08:00
hizumi
bbe798734a Update README.md
correct typo
2024-02-07 23:26:32 -06:00
hizumi
e372563e58 prepare v4.0.0 release 2024-02-07 23:25:23 -06:00
hizumi
8283f19b77 Update mission_settings.hpp
document and give a default example
2024-02-07 23:25:04 -06:00
644de22b32 Merge branch 'develop' into feature/set-wheels-tracks-with-zen-module 2024-02-07 22:06:13 -06:00
dfd79c0d70 adds more dev info to readme 2024-02-07 13:12:35 -08:00
5d3c28b807 ready for dedi 2024-02-07 13:11:58 -08:00
02e97b3e0e Merge pull request 'develop' (#21) from develop into main
Reviewed-on: https://17th-gs.iceberg-gaming.com:5443/hizumi/MissionTemplate/pulls/21
2024-02-06 23:17:30 -06:00
aa640d31a3 Merge pull request 'big CBA rework & improvements' (#19) from implement-cba-macros-for-some-modules into develop
Reviewed-on: https://17th-gs.iceberg-gaming.com:5443/hizumi/MissionTemplate/pulls/19
2024-02-06 23:14:46 -06:00
c44247061a bug fixes from dedicated testing 2024-02-06 20:56:42 -08:00
8a27abe6c5 add verbosity to 3d triageIcons tooltip under Enable, for clarity 2024-02-06 18:14:23 -08:00
91b982e06e ready for dedi -- improvements to resupply, triageIcons too 2024-02-06 17:36:01 -08:00
0a64d9e170 big refactor, WIP! 2024-02-06 01:52:25 -08:00
f588ffa4a0 many changes. includes rework of baselocation-asset storage format 2024-02-05 17:42:31 -08:00
f450f4611b wip, fbcb2_assets, init, util 2024-02-04 22:18:06 -08:00
4cfa159ee9 change root level folder name to framework, update resupply+vehicleflags
tested locally
2024-02-04 21:23:12 -08:00
c45f778188 Merge pull request 'move-supply-crates-to-cfg' (#17) from move-supply-crates-to-cfg into develop
Reviewed-on: https://17th-gs.iceberg-gaming.com:5443/hizumi/MissionTemplate/pulls/17
2024-02-04 22:56:25 -06:00
7cc8d9aaca Merge branch 'develop' into move-supply-crates-to-cfg 2024-02-04 22:55:58 -06:00
311a4c4007 Merge pull request 'move-flags-to-config' (#18) from move-flags-to-config into develop
Reviewed-on: https://17th-gs.iceberg-gaming.com:5443/hizumi/MissionTemplate/pulls/18
2024-02-04 22:54:40 -06:00
d7b8e5186e tested local 2024-02-03 22:55:21 -08:00
09dcde7471 wip 2024-02-03 20:59:51 -08:00
179 changed files with 6468 additions and 2344 deletions

View File

@@ -4,7 +4,32 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project badly attempts [Semantic Versioning](https://semver.org/spec/v2.0.0.html). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project badly attempts [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [3.2] - 2024-02-01 ## [4.0.0] - 2024-02-07
Version 4 marks a massive rewrite due in whole to @IndigoFox by updating the internals of the framework into CBA macros and functions.
### Added
- Added ability for FBCB2 Assets to locate themselves on player local map
- Added various framework utitily functions
- Added ability for mission maker to allow spawning of resupply boxes from arsenal boxes
- Added CBA settings for resupply box spawning
### Changed
- Documented purpose of `missionSeries` parameter in `mission_settings.hpp`
- Moved internal functions into new framework directory structure
- Moved FBCB2 internal data structure into multiple defintion files
- Moved resupply boxes internal data structures into their own definiton file
- Moved player inventory internal data structure into its own defintion file
- Moved vehicle flags internal data structure into its own defitinion file
- Use player's preferred ACE color settings for medical triage icons
### Deleted
- Leftover resupply box code from before version 3.2.0 update
## [3.2.0] - 2024-02-01
### Added ### Added
@@ -62,7 +87,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Lowered garbage collection times and range for dead bodies - Lowered garbage collection times and range for dead bodies
## [3.0] - 2023-05-03 ## [3.0.0] - 2023-05-03
### Added ### Added
@@ -79,7 +104,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Remove `CfgRemoteExec` from `description.ext` as it has been deprecated as of Arma v1.54 - Remove `CfgRemoteExec` from `description.ext` as it has been deprecated as of Arma v1.54
## [2.2] - 2023-04-23 ## [2.2.0] - 2023-04-23
### Added ### Added
@@ -93,7 +118,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Force `sideChat` CBA setting to 'disabled' on mission start by default - Force `sideChat` CBA setting to 'disabled' on mission start by default
## [2.1] - 2023-04-12 ## [2.1.0] - 2023-04-12
### Added ### Added
@@ -103,7 +128,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Allow `#admin` to enable or disable `sideChat` via CBA setting on a per mission file basis. - Allow `#admin` to enable or disable `sideChat` via CBA setting on a per mission file basis.
`Escape -> Configure -> Addon Options -> Server -> 17th Battalion -> Enable Side Chat` `Escape -> Configure -> Addon Options -> Server -> 17th Battalion -> Enable Side Chat`
## [2.0] -2023-04-12 ## [2.0.0] -2023-04-12
### Added ### Added
@@ -113,7 +138,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- mission.jpg to correct dimensions and optimize - mission.jpg to correct dimensions and optimize
## [1.9] - 2023-03-07 ## [1.9.0] - 2023-03-07
### Added ### Added

View File

@@ -1,22 +1,27 @@
# Installation Instructions # Installation Instructions
Once your mission has been created and saved in the Arma 3 Eden Editor, download the latest mission template zip and copy its contents to the folder where your mission file lives. The only file which should be pre-existing in your mission folder is `mission.sqm`, once freshly saved from Arma 3's EDEN Editor.
The only file which should be pre-existing in your mission folder is `mission.sqm` Download the latest mission template zip from the [latest release](https://17th-gs.iceberg-gaming.com:5443/hizumi/MissionTemplate/releases/latest) and copy its contents to the folder where your mission file lives.
Once copied, the final structure should appear similar to the following: Once copied, the final structure should appear similar to the following:
```markdown ```markdown
├── functions/ ├── aaFrameworkUtils/
├── defines/
├── framework/
├── images/ ├── images/
├── scripts/ ├── scripts/
├── sounds/ ├── sounds/
├── textures/ ├── textures/
├── CHANGELOG.md
├── description.ext ├── description.ext
├── mission_settings.hpp
├── mission.jpg ├── mission.jpg
├── mission.sqm ├── mission.sqm
├── mission_settings.hpp
``` ```
> **Note:** If you're building a mission for use and not actively developing code, the `aaFrameworkUtils` and `framework\x` directories **should be deleted**. *These are for the purposes of development and add size bloat to the mission download when players connect to your mission.*
After the requisite configuration file edits have been made, your mission is ready to be packed into a pbo for deployment. After the requisite configuration file edits have been made, your mission is ready to be packed into a pbo for deployment.
# Files # Files
@@ -40,14 +45,22 @@ The contents of the lower half of the file are where the mission maker is able t
This file will be displayed the client mission loading screen. This file will be displayed the client mission loading screen.
File should remain small *(under 300KiB)* and should optimally be `1024px by 512px` in resolution File should remain small *(under 300KiB)* and should optimally be `1024px by 512px` in resolution
## defines/
This directory contains the definition files use by the framework in various places. *Contents should not be edited*
## framework/
This directory contains the code for the mission framework. **Contents must not be edited.**
## images/ ## images/
This directory is for organizational purposes for any images you wish to use in your mission This directory is for organizational purposes for any images you wish to use in your mission
## scripts/ ## scripts/
This directory is for organizational purposes for any custom scripts you wish to use in your mission. This directory is for organizational purposes for any custom scripts you wish to use in your mission.
> **Note**: Scripts may need to be edited to account for their new location > **Note:** Scripts may need to be edited to account for their new location
## sounds/ ## sounds/
@@ -56,4 +69,58 @@ This directory is for organizational purposes for any custom scripts you wish to
## textures/ ## textures/
This directory is for organizational purposes for textures files used by mission scripts This directory is for organizational purposes for textures files used by mission scripts.
# Development Notes
All modules are broken apart as such in /framework. Client and server inits are managed in /framework/init.
Pay attention to framework/script_mod.hpp prior to deployment of releases, as the debug settings within will determine what is logged during prod missions.
CfgFunctions is sensitive to the folder/script_component.hpp of each module.
### `defines` Directory
This directory contains a number of hpp files used to define constants throughout the framework. These should ONLY be edited by or with the supervision of a developer to reflect format battalion-wide changes.
- `ApprovedAssets.hpp`: Contains subclasses for approved aerial assets with their assigned callsigns. Used primarily in `fbcb2_assets`.
- `BattalionInfo.hpp`: Used for representing Battalion structure, element callsigns, and radio frequency assignments. Used primarily in `fbcb2_main`.
- `DisallowedEquipment.hpp`: Contains flagged item classnames by category that players may not use, or may use only in specific roles. Used to monitor and enforce equipment restrictions.
- `SignalColors.hpp`: Contains smoke/flare/chemlight colors and what they represent in the field. Used primarily in `fbcb2_main` for the Signal Colors diary record.
- `SupplyCrates.hpp`: Contains the types, contents, and metadata for all supply crate types in the `resupply` module.
- `VehicleFlags.hpp`: Defines system information, flag categories, and flag options used to populate ACE3 interaction menus for vehicles. Used by the `vehicleFlags` module.
### Modules List
*Within `framework`:*
- `ambience`:
- Adds ambient flak capabilities.
- `client`:
- Contains core client-side event handlers and actions that don't fit into other modules.
- `common`:
- Contains common functions and variables used by multiple modules.
- `fbcb2_main`:
- Contains the main FBCB2 functionality and initialization code. Populates the briefing/diary with mission information.
- `fbcb2_assets`:
- A subcomponent of `fbcb2_main`. Used to gather, display, and manage diary records as intel for assets near known bases.
- `init`:
- Contains core initialization functions. Both server and client inits across all modules are managed here.
- `mapcopy`:
- Gives players the ability to copy each other's maps.
- `performance`:
- Contains functionality for monitoring and logging performance data.
- `reinsert`:
- Provides a reinsertion queue system for players and pilots to maximize efficiency of the reinsertion process.
- `resupply`:
- Provides a Zeus module and standalone function to spawn pre-equipped supply crates onto the battlefield.
- Supply crate definitions are stored in `defines/SupplyCrates.hpp`.
- Optionally, allows players to spawn supply crates from arsenal boxes.
- `triageIcons`:
- For those with medical permissions (`ace_medical`), provides a configurable 3D icon over unconscious units indicating their current ACE Triage Card status.
- `vehicleFlags`:
- Provides an ACE3 interaction menu that allows players to attach and remove flags from vehicles.
- Flags are defined in `defines/VehicleFlags.hpp`.

View File

@@ -8,7 +8,7 @@
#define RRC_CALLSIGN TIGER #define RRC_CALLSIGN TIGER
#define MEDIC_CALLSIGN LIFELINE #define MEDIC_CALLSIGN LIFELINE
#define ALPHA_CALLSIGN BLACKJACK #define ALPHA_CALLSIGN BLACKJACK
#define ECHO_CALLSIGN ZOOMER #define ECHO_CALLSIGN FIREBRAND
#define WPN_CALLSIGN BLACKFOOT #define WPN_CALLSIGN BLACKFOOT
// Define the frequencies for the Battalion // Define the frequencies for the Battalion
@@ -229,8 +229,8 @@ class BattalionInfo {
}; };
}; };
class Attack { class Armor {
callsign = CALLSIGN_ELEMENT(ECHO_CALLSIGN, ATTACK); callsign = CALLSIGN_ELEMENT(ECHO_CALLSIGN, ARMOR);
textColor = LVL4_TEXT_COLOR; textColor = LVL4_TEXT_COLOR;
frequencies[] = { frequencies[] = {
{"Contact", {}, {FREQ_ECHO_GROUND, FREQ_ECHO_FLIGHT_CAS}}, {"Contact", {}, {FREQ_ECHO_GROUND, FREQ_ECHO_FLIGHT_CAS}},

44
defines/SignalColors.hpp Normal file
View File

@@ -0,0 +1,44 @@
class SignalColors {
class White {
name = "White";
hexCode = "#FFFFFF";
usage = "Concealment, Light";
itemExamples[] = {"SmokeShell", "1Rnd_Smoke_Grenade_shell", "ACE_Chemlight_White"};
};
class Green {
name = "Green";
hexCode = "#00FF00";
usage = "Friendly Forces";
itemExamples[] = {"SmokeShellGreen", "1Rnd_SmokeGreen_Grenade_shell", "Chemlight_green"};
};
class Blue {
name = "Blue";
hexCode = "#0000FF";
usage = "LZ Marking";
itemExamples[] = {"SmokeShellBlue", "1Rnd_SmokeBlue_Grenade_shell", "Chemlight_blue"};
};
class Red {
name = "Red";
hexCode = "#FF0000";
usage = "Enemy Location";
itemExamples[] = {"SmokeShellRed", "1Rnd_SmokeRed_Grenade_shell", "Chemlight_red"};
};
class Orange {
name = "Orange";
hexCode = "#FFA500";
usage = "Resupply Marker";
itemExamples[] = {"SmokeShellOrange", "1Rnd_SmokeOrange_Grenade_shell", "ACE_Chemlight_Orange"};
};
class Yellow {
name = "Yellow";
hexCode = "#FFFF00";
usage = "Medical Emergency";
itemExamples[] = {"SmokeShellYellow", "1Rnd_SmokeYellow_Grenade_shell", "Chemlight_yellow"};
};
class Purple {
name = "Purple";
hexCode = "#800080";
usage = "Broken Arrow - 100m radius";
itemExamples[] = {"SmokeShellPurple", "1Rnd_SmokePurple_Grenade_shell"};
};
};

164
defines/VehicleFlags.hpp Normal file
View File

@@ -0,0 +1,164 @@
class VehicleFlags {
texturePBOName = "textures";
baseClassesToApplyActionsFor[] = {
"LandVehicle",
"Helicopter"
};
class ExcludedVehicles {
classesWithoutFlagProxies[] = {
"TF373_SOAR_MH47G_Base", // MH-47G Chinook
"RHS_MELB_base", // MELB AH-6M/MH-6M/H-6M Little Bird
"USAF_C17", // C17 Globemaster III
"USAF_C130J", // C130J Super Hercules
"USAF_AC130U", // AC130 Spooky II
"ej_UH60M_base", // UH-60M Black Hawk + DAP variants
"rhsusf_fmtv_base" // M1083A1P2 variants + SOV SOCOM variants
};
};
class FlagCategories {
class ChevronNumbers {
actionID = "flag_chevron_numbers";
actionTitle = "Chevron Numbers";
class Chevron1 {
actionID = "flag_chevron_id1";
actionTitle = "Flag 1";
texture = "textures\flag_number\flag_id_1_co.paa";
};
class Chevron2 {
actionID = "flag_chevron_id2";
actionTitle = "Flag 2";
texture = "textures\flag_number\flag_id_2_co.paa";
};
class Chevron3 {
actionID = "flag_chevron_id3";
actionTitle = "Flag 3";
texture = "textures\flag_number\flag_id_3_co.paa";
};
class Chevron4 {
actionID = "flag_chevron_id4";
actionTitle = "Flag 4";
texture = "textures\flag_number\flag_id_4_co.paa";
};
class Chevron5 {
actionID = "flag_chevron_id5";
actionTitle = "Flag 5";
texture = "textures\flag_number\flag_id_5_co.paa";
};
class Chevron6 {
actionID = "flag_chevron_id6";
actionTitle = "Flag 6";
texture = "textures\flag_number\flag_id_6_co.paa";
};
class Chevron7 {
actionID = "flag_chevron_id7";
actionTitle = "Flag 7";
texture = "textures\flag_number\flag_id_7_co.paa";
};
class Chevron8 {
actionID = "flag_chevron_id8";
actionTitle = "Flag 8";
texture = "textures\flag_number\flag_id_8_co.paa";
};
class Chevron9 {
actionID = "flag_chevron_id9";
actionTitle = "Flag 9";
texture = "textures\flag_number\flag_id_9_co.paa";
};
class Chevron10 {
actionID = "flag_chevron_id10";
actionTitle = "Flag 10";
texture = "textures\flag_number\flag_id_10_co.paa";
};
class ChevronHQ {
actionID = "flag_chevron_hq";
actionTitle = "Flag HQ";
texture = "textures\flag_number\flag_id_hq_co.paa";
};
};
class SimpleShapes {
actionID = "flag_simpleshape";
actionTitle = "Simple Shapes";
class GreenOctagon {
actionID = "flag_simpleshape_greenoctagon";
actionTitle = "Green Octagon";
texture = "textures\simple_shape\flag_simpleshape_greenoctagon_co.paa";
};
class BlueCircle {
actionID = "flag_simpleshape_bluecircle";
actionTitle = "Blue Circle";
texture = "textures\simple_shape\flag_simpleshape_bluecircle_co.paa";
};
class OrangeSquare {
actionID = "flag_simpleshape_orangesquare";
actionTitle = "Orange Square";
texture = "textures\simple_shape\flag_simpleshape_orangesquare_co.paa";
};
class PinkTriangle {
actionID = "flag_simpleshape_pinktriangle";
actionTitle = "Pink Triangle";
texture = "textures\simple_shape\flag_simpleshape_pinktriangle_co.paa";
};
class RedPentagon {
actionID = "flag_simpleshape_redpentagon";
actionTitle = "Red Pentagon";
texture = "textures\simple_shape\flag_simpleshape_redpentagon_co.paa";
};
};
class Miscellaneous {
actionID = "flag_misc";
actionTitle = "Miscellaneous";
class BattalionEmblem {
actionID = "flag_17th_emblem";
actionTitle = "17th Emblem";
texture = "textures\flags_misc\flag_17th_emblem_co.paa";
};
class RedCross {
actionID = "flag_redcross";
actionTitle = "Red Cross";
texture = "textures\flags_misc\flag_redcross_co.paa";
};
};
class BuiltIn {
actionID = "flag_builtin";
actionTitle = "Built-In";
class BlueFlag {
actionID = "flag_builtin_blue";
actionTitle = "Blue Flag";
texture = "\A3\Data_F\Flags\flag_blue_CO.paa";
};
class GreenFlag {
actionID = "flag_builtin_green";
actionTitle = "Green Flag";
texture = "\A3\Data_F\Flags\flag_green_CO.paa";
};
class RedFlag {
actionID = "flag_builtin_red";
actionTitle = "Red Flag";
texture = "\A3\Data_F\Flags\flag_red_CO.paa";
};
class WhiteFlag {
actionID = "flag_builtin_white";
actionTitle = "White Flag";
texture = "\A3\Data_F\Flags\flag_white_CO.paa";
};
class NATOFlag {
actionID = "flag_builtin_nato";
actionTitle = "NATO Flag";
texture = "\A3\Data_F\Flags\flag_NATO_CO.paa";
};
class UNFlag {
actionID = "flag_builtin_un";
actionTitle = "UN Flag";
texture = "\A3\Data_F\Flags\Flag_uno_CO.paa";
};
};
};
};

View File

@@ -17,10 +17,13 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "mission_settings.hpp" #include "mission_settings.hpp"
#include "framework\script_mod.hpp"
#include "defines\ApprovedAssets.hpp" #include "defines\ApprovedAssets.hpp"
#include "defines\BattalionInfo.hpp" #include "defines\BattalionInfo.hpp"
#include "defines\DisallowedEquipment.hpp" #include "defines\DisallowedEquipment.hpp"
#include "defines\SupplyCrates.hpp" #include "defines\SupplyCrates.hpp"
#include "defines\VehicleFlags.hpp"
#include "defines\SignalColors.hpp"
//-------------------------------------------MISSION INFO-------------------------------------------------------------------- //-------------------------------------------MISSION INFO--------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -91,11 +94,16 @@ class Params
}; };
class cfgFunctions // CfgFunctions
{ class CfgFunctions {
#include "functions\CfgFunctions.hpp" #include "framework\CfgFunctions.hpp"
}; };
class CfgSounds {
#include "framework\emp\CfgSounds.hpp"
};
class CfgDebriefingSections { class CfgDebriefingSections {
class acex_killTracker { class acex_killTracker {

200
framework/CfgFunctions.hpp Normal file
View File

@@ -0,0 +1,200 @@
#include "script_mod.hpp"
class DOUBLES(PREFIX,init) {
class functions {
file = "framework\init\functions";
class initServer { postInit = 1;};
class initClient { postInit = 1;};
class setDefaults { postInit = 1; };
class addAARChatHandler { postInit = 1; };
class addRespawnChatHandler { postInit = 1; };
};
};
class PREFIX {
class ambience {
file = "framework\ambience";
class flakInitVehicle {};
class flakEH {};
};
};
class DOUBLES(PREFIX,client) {
class functions {
file = "framework\client\functions";
class bindEmptyGroupGarbageCleanup { postInit = 1; };
class bindEventHandlers { postInit = 1; };
class bindVehicleActions { postInit = 1; };
class addZenModules {postInit = 1;};
};
};
class DOUBLES(PREFIX,common) {
class functions {
file = "framework\common\functions";
class addCBASettings { preInit = 1; };
class logMissionInfo {};
class addPlayerInfoToArray {};
class createOrUpdateDiaryRecord {};
class getApprovedAssetsCfg {};
class getBattalionCfg {};
class getNameOfBase {};
class getNearestBase {};
class log {};
class checkPlayerInventory {};
class logSettingChanged {};
class padString {};
class recurseSubclasses {};
};
};
class DOUBLES(PREFIX,emp) {
class functions {
file = "framework\emp\functions";
// class addCBASettings {preInit=1;};
class init {};
class addACEActions {};
class applyLocalObjectEffects {};
class applyLocalGroupEffects {};
class applyGlobalObjectEffects {};
class applyServerObjectEffects {};
class deploy {};
class getObjectsAndGroupsToAffect {};
class playLocalEffects {};
class playLocalEffectsForObject {};
class isItemElectronic {};
class removeUnitElectricInventoryItems {};
class removeVehicleElectricInventoryItems {};
};
};
class DOUBLES(PREFIX,fbcb2_assets) {
class functions {
file = "framework\fbcb2_assets\functions";
class addCBASettings {preInit=1;};
class initServer {};
class initClient {};
class getCallsignFromClassname {};
class getCurrentAssetsByBase {};
class getInventory {};
class getMagsForWeapon {};
class getStartingAndCurrentAssets {};
class getStartingAssetsByBase {};
class getVehicleData {};
class getWeaponry {};
class hintAllApprovedAssets {};
class isAssetInRangeOfBase {};
class removeAssetDiaryRecords {};
class removeMarkersOnMap {};
class showMarkersOnMap {};
class updateAssetDiary {};
class updateAssetsByBase {};
};
};
class DOUBLES(PREFIX,fbcb2_main) {
class functions {
file = "framework\fbcb2_main\functions";
class initClient {};
class addEnvironmentRecord {};
class addFrequenciesRecord {};
class addSignalColorsRecord {};
};
class util {
file = "framework\fbcb2_main\util";
class formatRadioElementForDiary {};
class generateElementFrequencyRecordText {};
};
};
class DOUBLES(PREFIX,mapcopy) {
class functions {
file = "framework\mapcopy\functions";
class addCBASettings {preInit=1;};
class initClient {};
class getMapMarkers {};
class loadMapMarkers {};
class mapMarkerToString {};
class stringToMapMarker {};
};
};
class DOUBLES(PREFIX,performance) {
class functions {
file = "framework\performance\functions";
class addCBASettings {preInit=1;};
class addDNI_PlayerFPS { postInit = 1; };
// PFHs managed in addCBASettings onChange code
class addClientStatsPFH {};
class calculateClientStats {};
class addServerStatsPFH {};
class calculateServerStats {};
};
};
class DOUBLES(PREFIX,reinsert) {
class functions {
file = "framework\reinsert\functions";
class addCBASettings {preInit=1;};
};
class server {
file = "framework\reinsert\server";
class initServer {};
class addToQueue {};
class globalShowQueue {};
class removeFromQueue {};
class returnReinsertQueueNotification {};
class validateQueue {};
};
class client {
file = "framework\reinsert\client";
class initClient {};
class addAceSelfActions {};
class addCheckQueueSelfAction {};
class requestShowQueue {};
};
};
class DOUBLES(PREFIX,resupply) {
class functions {
file = "framework\resupply\functions";
class addCBASettings {preInit=1;};
class initClient {};
class createBox {};
class getSupplyCratesCfg {};
class addArsenalObjectSpawnBoxActions {};
};
};
class DOUBLES(PREFIX,triageIcons) {
class functions {
file = "framework\triageIcons\functions";
class addCBASettings {preInit=1;};
class initClient {};
class addDrawIconsPFH {};
class addGetEntitiesPFH {};
class updateColors {};
};
};
class DOUBLES(PREFIX,vehicleFlags) {
class functions {
file = "framework\vehicleFlags\functions";
class initClient {};
class getActionsFlagCategories {};
class getVehicleFlagsCfg {};
class isClassExcluded {};
};
};
class DOUBLES(PREFIX,zeus) {
class functions {
file = "framework\zeus\functions";
class initClient {};
class addZenModules {};
};
};

View File

@@ -0,0 +1,41 @@
#include "..\script_component.hpp"
if ( !hasInterface ) exitWith {};
[
QUOTE(MODULE_CATEGORY_NAME),
"Grounds Cleanup",
{
params [["_pos", [0,0,0], [[]], 3], ["_target", objNull, [objNull]]];
_pos = [_pos#0, _pos#1, 0];
[
"Cleanup Area",
[
[ "SLIDER:RADIUS", "Radius (meters)", [50, 500, 100, 0, _pos, [0.8, 0.2, 0.2, 1.0]], true ]
],
{
params ["_dialog", "_args"];
_dialog params ["_radius"];
_args params ["_pos", "_target"];
_objects = _pos nearObjects ["GroundWeaponHolder", _radius];
{
deleteVehicle _x;
} forEach _objects
},
{},
[_pos, _target]
] call zen_dialog_fnc_create;
}
] call zen_custom_modules_fnc_register;
diag_log text "[MILSIM] (client) zeus modules added";
nil;

View File

@@ -0,0 +1,43 @@
#include "..\script_component.hpp"
[
LEVEL_INFO,
QUOTE(COMPONENT),
"Initializing empty group deletion PFH",
[]
] call EFUNC(common,log);
_emptyGroupPFH = [
{
{
if (local _x) then {
if ((count units _x) == 0) then {
deleteGroup _x;
};
};
} forEach allGroups;
},
300,
[],
{
[
LEVEL_INFO,
QUOTE(COMPONENT),
"Empty group deletion PFH loaded",
[]
] call EFUNC(common,log);
},
{ [
LEVEL_INFO,
QUOTE(COMPONENT),
"Empty group deletion PFH unloaded",
[]
] call EFUNC(common,log);
},
{ true },
{ false },
[]
] call CBA_fnc_createPerFrameHandlerObject;

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
if ( !hasInterface ) exitWith {}; if ( !hasInterface ) exitWith {};
player addEventHandler["Respawn", player addEventHandler["Respawn",
@@ -6,10 +8,11 @@ player addEventHandler["Respawn",
private _killer = _corpse getVariable ["ace_medical_causeOfDeath", "#scripted"]; private _killer = _corpse getVariable ["ace_medical_causeOfDeath", "#scripted"];
if (_killer == "respawn_button") then { if (_killer == "respawn_button") then {
[ [
"client", LEVEL_INFO,
QUOTE(COMPONENT),
"RESPAWNED WHILE UNCONSCIOUS", "RESPAWNED WHILE UNCONSCIOUS",
[_unit] call milsim_fnc_addPlayerInfoToArray [_unit] call EFUNC(common,addPlayerInfoToArray)
] remoteExec ["milsim_fnc_log", 2]; ] remoteExec [QEFUNC(common,log), 2];
// format["%1 was unconscious then clicked the respawn button", name _unit] remoteExec["systemChat", 0]; // format["%1 was unconscious then clicked the respawn button", name _unit] remoteExec["systemChat", 0];
}; };
} }
@@ -43,11 +46,11 @@ addMissionEventHandler ["HandleChatMessage",
["ace_arsenal_displayClosed", { ["ace_arsenal_displayClosed", {
[player] remoteExec ["milsim_fnc_logPlayerInventory", 2]; [player] remoteExec [QEFUNC(common,checkPlayerInventory), 2];
}] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler;
[missionNamespace, "arsenalClosed", { [missionNamespace, "arsenalClosed", {
[player] remoteExec ["milsim_fnc_logPlayerInventory", 2]; [player] remoteExec [QEFUNC(common,checkPlayerInventory), 2];
}] call BIS_fnc_addScriptedEventHandler; }] call BIS_fnc_addScriptedEventHandler;
diag_log text "[MILSIM] (client) event handlers bound"; diag_log text "[MILSIM] (client) event handlers bound";

View File

@@ -56,7 +56,7 @@ _patchTire =
"Patching" "Patching"
] call ace_common_fnc_progressBar ] call ace_common_fnc_progressBar
}, },
{ ( alive _target ) && ( [_player, "ToolKit"] call ace_common_fnc_hasItem ) && ( getDammage _target > 0.2 ) && ( _target getVariable["milsim_ace_repair_wheel_canPatch", true] ) } { ( alive _target ) && ( [_player, "ToolKit"] call ace_common_fnc_hasItem ) && ( damage _target > 0.2 ) && ( _target getVariable["milsim_ace_repair_wheel_canPatch", true] ) }
] call ace_interact_menu_fnc_createAction; ] call ace_interact_menu_fnc_createAction;
["ACE_Wheel", 0, ["ACE_MainActions"], _patchTire, true] call ace_interact_menu_fnc_addActionToClass; ["ACE_Wheel", 0, ["ACE_MainActions"], _patchTire, true] call ace_interact_menu_fnc_addActionToClass;

View File

@@ -0,0 +1,3 @@
#define COMPONENT client
#define COMPONENT_BEAUTIFIED Client
#include "../script_mod.hpp"

View File

@@ -0,0 +1,27 @@
#include "..\script_component.hpp"
//---------------------
// Side Chat
//---------------------
[
QGVARMAIN(sideChat),
"CHECKBOX",
"Side Chat Text Enabled",
[QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)],
false, // default value
true, // requires restart
{
params ["_value"];
[
QGVARMAIN(sideChat),
_value
] call EFUNC(common,logSettingChanged);
}
] call CBA_fnc_addSetting;
[QGVARMAIN(sideChat), false] call CBA_settings_fnc_set;
diag_log text "[MILSIM] (settings) Custom CBA settings initialized";
nil;

View File

@@ -1,4 +1,6 @@
params [["_playerObj", objNull], ["_arrayToModify", [], [[]]]]; #include "..\script_component.hpp"
params [["_playerObj", objNull, [nil, objNull]], ["_arrayToModify", [], [[]]]];
if (isNull _playerObj) exitWith {_arrayToModify}; if (isNull _playerObj) exitWith {_arrayToModify};
@@ -8,7 +10,7 @@ if (isNull _playerObj) exitWith {_arrayToModify};
["playerName", name _playerObj], ["playerName", name _playerObj],
["playerUID", getPlayerUID _playerObj], ["playerUID", getPlayerUID _playerObj],
["playerGroup", groupId (group _playerObj)], ["playerGroup", groupId (group _playerObj)],
["playerNetID", [_playerObj] call BIS_fnc_netId] ["playerNetID", _playerObj call BIS_fnc_netId]
]; ];
_arrayToModify; _arrayToModify;

View File

@@ -1,5 +1,5 @@
/* /*
Function: milsim_fnc_logPlayerInventory Function: milsim_common_fnc_checkPlayerInventory
Description: Description:
Checks a player's inventory for non-compliant items and logs results to all machines. Checks a player's inventory for non-compliant items and logs results to all machines.
@@ -13,16 +13,19 @@
<ARRAY> - Array of strings to be logged. <ARRAY> - Array of strings to be logged.
*/ */
#include "..\script_component.hpp"
params [ params [
["_player", objNull, [objNull]] ["_player", objNull, [objNull]]
]; ];
if (!isPlayer _player) exitWith { if (!isPlayer _player) exitWith {
[ [
"logPlayerInventory", LEVEL_ERROR,
QUOTE(COMPONENT),
"PARAM PLAYER IS NOT A PLAYER", "PARAM PLAYER IS NOT A PLAYER",
[["player", _player]] [["player", _player]]
] call milsim_fnc_log; ] call EFUNC(common,log);
}; };
// testing // testing
@@ -53,10 +56,11 @@ _playerItems pushBack (uniform _player);
[ [
"logPlayerInventory", LEVEL_DEBUG,
QUOTE(COMPONENT),
"CHECKING PLAYER INVENTORY", "CHECKING PLAYER INVENTORY",
[_player] call milsim_fnc_addPlayerInfoToArray [_player] call EFUNC(common,addPlayerInfoToArray)
] call milsim_fnc_log; ] call EFUNC(common,log);
//////////////////////////////////////// ////////////////////////////////////////
// HARDCODED DISALLOWED ITEMS - see functions/definitions/DisallowedEquipment.hpp // HARDCODED DISALLOWED ITEMS - see functions/definitions/DisallowedEquipment.hpp
@@ -115,10 +119,11 @@ private _thermalItems = _playerItems select {
// Only log compliance message if no non-compliant items were found // Only log compliance message if no non-compliant items were found
if (count _allFoundItemsSoFar isEqualTo 0) exitWith { if (count _allFoundItemsSoFar isEqualTo 0) exitWith {
[ [
"logPlayerInventory", LEVEL_INFO,
QUOTE(COMPONENT),
"PLAYER INVENTORY IS COMPLIANT", "PLAYER INVENTORY IS COMPLIANT",
[_player] call milsim_fnc_addPlayerInfoToArray [_player] call EFUNC(common,addPlayerInfoToArray)
] call milsim_fnc_log; ] call EFUNC(common,log);
}; };
// Log all non-compliant items // Log all non-compliant items
@@ -132,13 +137,14 @@ if (count _allFoundItemsSoFar isEqualTo 0) exitWith {
private _itemConfig = _itemClassName call CBA_fnc_getItemConfig; private _itemConfig = _itemClassName call CBA_fnc_getItemConfig;
// Log to RPT // Log to RPT
[ [
"logPlayerInventory", LEVEL_WARNING,
QUOTE(COMPONENT),
"NON-COMPLIANT ITEM", "NON-COMPLIANT ITEM",
[_player, [ [_player, [
["category", _categoryLabel], ["category", _categoryLabel],
["className", _itemClassName], ["className", _itemClassName],
["displayName", [_itemConfig] call BIS_fnc_displayName] ["displayName", [_itemConfig] call BIS_fnc_displayName]
]] call milsim_fnc_addPlayerInfoToArray ]] call EFUNC(common,addPlayerInfoToArray)
] call milsim_fnc_log; ] call EFUNC(common,log);
} forEach _items; } forEach _items;
} forEach _foundItemsKeyValue; } forEach _foundItemsKeyValue;

View File

@@ -0,0 +1,58 @@
#include "../script_component.hpp"
if (!hasInterface) exitWith {};
params [
["_subjectID", "", [""]],
["_recordTitle", "", [""]],
["_recordText", "", [""]],
["_recordIcon", "", [""]]
];
// Check if all parameters are provided
if (
count _subjectID isEqualTo 0 ||
count _recordTitle isEqualTo 0 ||
count _recordText isEqualTo 0
) exitWith {
[LEVEL_ERROR, QUOTE(COMPONENT), "Not all parameters provided"] call EFUNC(common,log);
};
// Check if already created
private _subjectRecords = GVAR(diaryRecords) getOrDefault [_subjectID, createHashMap, true];
private _existingRecord = _subjectRecords getOrDefault [_recordTitle, diaryRecordNull, true];
if (!isNull _existingRecord) then {
player setDiaryRecordText [[_subjectID, _existingRecord], [_recordTitle, _recordText, _recordIcon]];
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
format ["Updated diary record: %1", _recordTitle],
[
["subjectID", _subjectID],
["recordTitle", _recordTitle]
]
] call EFUNC(common,log);
} else {
private _new = player createDiaryRecord [
_subjectID,
[
_recordTitle,
_recordText,
_recordIcon
]
];
_subjectRecords set [_recordTitle, _new];
GVAR(diaryRecords) set [_subjectID, _subjectRecords];
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
format ["Created diary record: %1", _recordTitle],
[
["subjectID", _subjectID],
["recordTitle", _recordTitle]
]
] call EFUNC(common,log);
};

View File

@@ -0,0 +1,15 @@
#include "../script_component.hpp"
private _approvedAssetsCfg = (missionConfigFile >> "ApprovedAssets");
if (!IS_CONFIG(_approvedAssetsCfg) || {!isClass _approvedAssetsCfg}) exitWith {
[
LEVEL_ERROR,
QUOTE(COMPONENT),
"ERROR: Approved assets config not found. Check that the config is present and correctly named in the mission config file. See defines/ApprovedAssets.hpp and framework/util/functions/getApprovedAssetsCfg.sqf.",
[]
] call EFUNC(common,log);
configNull;
};
_approvedAssetsCfg;

View File

@@ -0,0 +1,15 @@
#include "../script_component.hpp"
private _battalionInfoCfg = (missionConfigFile >> "BattalionInfo");
if (!IS_CONFIG(_battalionInfoCfg) || {!isClass _battalionInfoCfg}) exitWith {
[
LEVEL_ERROR,
QUOTE(COMPONENT),
"ERROR: Battalion config not found. Check that the battalion config is present and correctly named in the mission config file. See defines/BattalionInfo.hpp and framework/util/functions/getBattalionCfg.sqf.",
[]
] call EFUNC(common,log);
configNull;
};
_battalionInfoCfg;

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
params [["_base", objNull, [objNull]]]; params [["_base", objNull, [objNull]]];
if (_base == objNull) exitWith {""}; if (_base == objNull) exitWith {""};

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
params [["_object", objNull, [objNull]]]; params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {objNull}; if (isNull _object) exitWith {objNull};

View File

@@ -0,0 +1,42 @@
/*
Function: milsim_common_fnc_log
Description:
Used to log messages to the server RPT file.
Parameters:
0: NUMBER - log level.
1: STRING - component name.
2: STRING - message to log.
3: ARRAY - key value pairs of data to log.
*/
#include "..\script_component.hpp"
params [
["_logLevel", 1, [-1,0,1,2,3]], // script_mod.hpp
["_component", "", [""]],
["_message", "", [""]],
["_data", [], [[]]]
];
if (_logLevel < DEBUG_MODE) exitWith {};
private _hash = createHashMapFromArray _data;
// Replace square brackets with round brackets to avoid parsing issues.
_message regexReplace ['(\[)', "("];
_message regexReplace ['(\])', ")"];
private _levelText = switch (_logLevel) do {
case (_logLevel isEqualTo -1) : {"TRACE"};
case (_logLevel isEqualTo 0) : {"DEBUG"};
case (_logLevel isEqualTo 1) : {"INFO"};
case (_logLevel isEqualTo 2) : {"WARN"};
case (_logLevel isEqualTo 3) : {"ERROR"};
default {"INFO"};
};
private _json = [_hash] call CBA_fnc_encodeJSON;
_log = format ["[%1] [%2] [%3] [%4] [%5] :: %6", QUOTE(PREFIX), _component, _fnc_scriptNameParent, _levelText, _message, _json];
diag_log text _log;

View File

@@ -1,5 +1,8 @@
#include "..\script_component.hpp"
[ [
"init", LEVEL_INFO,
QUOTE(COMPONENT),
"MISSION INFO", "MISSION INFO",
[ [
["serverName", serverName], ["serverName", serverName],
@@ -20,4 +23,4 @@
["LOGIC", playableSlotsNumber sideLogic] // 5 is LOGIC side ["LOGIC", playableSlotsNumber sideLogic] // 5 is LOGIC side
]] ]]
] ]
] call milsim_fnc_log; ] call FUNC(log);

View File

@@ -0,0 +1,16 @@
#include "..\script_component.hpp"
params [
["_settingName", "", [""]],
"_newValue"
];
[
LEVEL_INFO,
QUOTE(COMPONENT),
"SETTING CHANGED",
[
["setting", _settingName],
["newValue", _value]
]
] call EFUNC(common,log);

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
params [ params [
["_text", "", [""]], ["_text", "", [""]],
["_padSide", "left", ["left", "right"]], ["_padSide", "left", ["left", "right"]],

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
params [ params [
["_cfg", configNull, [configNull]], ["_cfg", configNull, [configNull]],
["_code", {}, [{}]] ["_code", {}, [{}]]

View File

@@ -0,0 +1,3 @@
#define COMPONENT common
#define COMPONENT_BEAUTIFIED Common
#include "../script_mod.hpp"

View File

@@ -0,0 +1,37 @@
#include "script_component.hpp"
class GVAR(sound_zap1) {
name = QGVAR(sound_zap1);
sound[] = {"framework\emp\sounds\zap1.wss", db+10, 1};
titles[] = {};
};
class GVAR(sound_zap2) {
name = QGVAR(sound_zap2);
sound[] = {"framework\emp\sounds\zap2.wss", db+10, 1};
titles[] = {};
};
class GVAR(sound_zap3) {
name = QGVAR(sound_zap3);
sound[] = {"framework\emp\sounds\zap3.wss", db+10, 1};
titles[] = {};
};
class GVAR(sound_zap4) {
name = QGVAR(sound_zap4);
sound[] = {"framework\emp\sounds\zap4.wss", db+10, 1};
titles[] = {};
};
class GVAR(sound_electric_explsion_impact_large) {
name = QGVAR(sound_electric_explsion_impact_large);
sound[] = {"framework\emp\sounds\electric_explsion_impact_large.wss", db+750, 1};
titles[] = {};
};
class GVAR(sound_echo3) {
name = QGVAR(sound_echo3);
sound[] = {"framework\emp\sounds\echo3.wss", db+500, 1};
titles[] = {1,""};
};
class GVAR(sound_ecou) {
name = QGVAR(sound_ecou);
sound[] = {"framework\emp\sounds\ecou.wss", db+100, 1};
titles[] = {1,""};
};

View File

@@ -0,0 +1,38 @@
#include "..\script_component.hpp"
if (!hasInterface) exitWith {};
private _rootAction = [
QGVAR(action_deploy),
"Deploy EMP Device",
"",
{
params ["_target", "_player", "_params"];
true;
},
{true},
{
params ["_target", "_player", "_params"];
private _childActions = [];
{
private _radius = _x;
private _action = [
format["%1_%2", QGVAR(action_deploy), _radius],
format["Deploy EMP Device (%1m)", _radius],
"",
{
params ["_target", "_player", "_params"];
_params params ["_radius"];
[GVAR(empDevice1), _radius] call FUNC(deploy);
},
{!isNull (missionNamespace getVariable [QGVAR(empDevice1), objNull]);},
nil,
[_radius]
] call ace_interact_menu_fnc_createAction;
_childActions pushBack [_action, [], _target];
false
} count [100,500,3000];
_childActions;
}
] call ace_interact_menu_fnc_createAction;
["CAManBase", 1, ["ACE_SelfActions"], _rootAction, true] call ace_interact_menu_fnc_addActionToClass;

View File

@@ -0,0 +1,35 @@
#include "..\script_component.hpp"
// Executed on all machines - global argument, local effect
// The effects must be applied on all machines
params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {};
_object setHitPointDamage ["hitturret",1];
_object setHitPointDamage ["hitcomturret",1];
_object setHitPointDamage ["hitcomgun",1];
_object setHitPointDamage ["#light_hitpoint",1];
_object setHitPointDamage ["HitBatteries",1];
_object setHitPointDamage ["HitLight",1];
_object setHitPointDamage ["#light_l",1];
_object setHitPointDamage ["#light_r",1];
_object setHitPointDamage ["#light_l_flare",1];
_object setHitPointDamage ["#light_r_flare",1];
_object setHitPointDamage ["light_l",1];
_object setHitPointDamage ["light_r",1];
_object setHitPointDamage ["light_l2",1];
_object setHitPointDamage ["light_r2",1];
_object setHitPointDamage ["hitEngine",1];
_object setHitPointDamage ["hitengine",1];
_object setHitPointDamage ["hitengine1",1];
_object setHitPointDamage ["hitengine2",1];
_object setHitPointDamage ["hitengine3",1];
_object setHitPointDamage ["HitEngine2",1];
_object setHitPointDamage ["HitAvionics",1];
_object setHitPointDamage ["HitHRotor",1];
_object setHitPointDamage ["HitVRotor",1];
_object setHitPointDamage ["HitHydraulics",1];
_object setHitPointDamage ["HitHStabilizerL1",1];
_object setHitPointDamage ["HitHStabilizerR1",1];
_object setHitPointDamage ["HitVStabilizer1",1];

View File

@@ -0,0 +1,9 @@
#include "..\script_component.hpp"
params [["_group", grpNull, [grpNull]]];
if (isNull _group) exitWith {};
if !(local _group) exitWith {};
//set gunlight status
_group enableGunLights "forceOff";
_group enableIRLasers true;

View File

@@ -0,0 +1,28 @@
#include "..\script_component.hpp"
// Executed on all clients, only continue if object is local.
// Local argument, global effect (the object owner broadcasts new state)
params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {};
if !(local _object) exitWith {};
_object disableAI "LIGHTS";
_object setPilotLight false;
_object setCollisionLight false;
if (_object isKindOf "CAManBase") then {
[_object] call FUNC(removeUnitElectricInventoryItems);
} else {
[_object] call FUNC(removeVehicleElectricInventoryItems);
};
[{ // once flicker effects are done, permanently disable lights
private _flickerHandle = _object getVariable QGVAR(flickerHandle);
!isNil "_flickerHandle" && {scriptDone _flickerHandle}
}, {
_object setHit ["light_1_hitpoint", 0.97]; //all possible light hitpoints
_object setHit ["light_2_hitpoint", 0.97]; //no lights escape this
_object setHit ["light_3_hitpoint", 0.97];
_object setHit ["light_4_hitpoint", 0.97];
}] call CBA_fnc_waitUntilAndExecute;

View File

@@ -0,0 +1,13 @@
#include "..\script_component.hpp"
// Executed on server only, global argument and global effect
// The server makes the change and broadcasts new state to all clients
if (!isServer) exitWith {};
params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {};
_object disableTIEquipment true;
_object disableNVGEquipment true;
_object setVariable ["A3TI_Disable", true, true];

View File

@@ -0,0 +1,31 @@
#include "..\script_component.hpp"
// This function is used to deploy an EMP device and trigger the EMP effects on all machines
// The EMP effect is triggered by the global event "QGVAR(event_empDeployed)"
// This function should be called on the server
if (!isServer) exitWith {};
//get center and radius
params [["_origin", objNull, [[], objNull]],["_radius",1500, [300]]];
if (_origin isEqualType []) then {
if (count _origin != 3) exitWith {
["Invalid origin position provided (%1)", _origin] call BIS_fnc_error;
};
};
if (_origin isEqualType objNull) then {
if (isNull _origin) exitWith {
["No origin object or position provided (%1)", _origin] call BIS_fnc_error;
};
_origin = getPosASL _origin;
};
[QGVAR(event_empDeployedPreCheck), [
random 100000,
_origin,
_radius
]] call CBA_fnc_globalEvent;
true;

View File

@@ -0,0 +1,68 @@
#include "..\script_component.hpp"
// This function will gather objects to be affected by the EMP blast
// It will return an array of objects within the radius of the EMP blast
params [["_origin", objNull, [[], objNull]],["_radius",1500]];
if (_origin isEqualType []) then {
if (count _origin != 3) exitWith {
["Invalid origin position provided (%1)", _origin] call BIS_fnc_error;
};
};
if (_origin isEqualType objNull) then {
if (isNull _origin) exitWith {
["No origin object or position provided (%1)", _origin] call BIS_fnc_error;
};
_origin = getPosASL _origin;
};
//search for and return objects
private _objectsToAffect = nearestObjects [
_origin,
[
"Car",
"Motorcycle",
"UAV",
"Tank",
"Air",
"Ship",
"StreetLamp",
"Lamps_base_F", //These are all the lights' base classes
"PowerLines_base_F",
"PowerLines_Small_base_F",
"Land_TTowerBig_1_F",
"Land_TTowerBig_2_F",
"Land_fs_roof_F",
"Land_NavigLight",
"PowerLines_Wires_base_F",
"Land_PowerPoleWooden_L_F",
"Land_Runway_PAPI",
"Land_fs_sign_F",
"Land_FuelStation_01_roof_malevil_F",
"Land_FuelStation_01_roof_F",
"Lamps",
"Helicopter",
"Plane",
"Autonomous",
"Armored",
"Land_MobileRadar_01_radar_F",
"Land_Camping_Light_F",
"Land_PowLines_WoodL",
"Land_A_GeneralStore_01",
"Land_A_GeneralStore_01a",
"Land_Mil_Guardhouse",
"Land_NAV_Lighthouse",
"Land_Mil_House",
"Land_LightHouse_F",
"Land_Hospital_side2_F"
],
_radius
];
private _affectedLocalGroups = _objectsToAffect apply {group _x};
_affectedLocalGroups = _affectedLocalGroups arrayIntersect _affectedLocalGroups;
_affectedLocalGroups = _affectedLocalGroups select {local _x} select {!isPlayer (leader _x)};
[_objectsToAffect, _affectedLocalGroups];

View File

@@ -0,0 +1,280 @@
#include "..\script_component.hpp"
GVAR(maxBrightDelay) = 3.25;
GVAR(zapSounds) = createHashMap;
{
private _cfg = missionConfigFile >> "CfgSounds" >> _x;
private _dataArr = getArray(_cfg >> "sound");
GVAR(zapSounds) set [_x, createHashMapFromArray [
["filename", _dataArr#0],
["volume", _dataArr#1],
["pitch", _dataArr#2]
]];
true;
} count [QGVAR(sound_zap1),QGVAR(sound_zap2),QGVAR(sound_zap3),QGVAR(sound_zap4)];
GVAR(echoSounds) = createHashMap;
{
private _cfg = missionConfigFile >> "CfgSounds" >> _x;
private _dataArr = getArray(_cfg >> "sound");
GVAR(echoSounds) set [_x, createHashMapFromArray [
["filename", _dataArr#0],
["volume", _dataArr#1],
["pitch", _dataArr#2]
]];
true;
} count [QGVAR(sound_ecou),QGVAR(sound_echo3)];
private _lgExplosionCfg = missionConfigFile >> "CfgSounds" >> QGVAR(sound_electric_explsion_impact_large);
private _lgExplosionDataArray = getArray(_lgExplosionCfg >> "sound");
GVAR(sound_electric_explsion_impact_large) = createHashMapFromArray [
["filename", _lgExplosionDataArray#0],
["volume", _lgExplosionDataArray#1],
["pitch", _lgExplosionDataArray#2]
];
if (hasInterface) then {
call FUNC(addACEActions);
};
GVAR(activeEMPs) = createHashMap;
// this precheck is sent to all clients from FUNC(deploy)
// machines will precache affected objects and signal they're ready in return
[QGVAR(event_empDeployedPreCheck), {
params ["_id", "_origin", "_radius"];
([_origin, _radius] call FUNC(getObjectsAndGroupsToAffect)) params ["_affectedObjects", "_affectedLocalGroups"];
GVAR(activeEMPs) set [_id, createHashMapFromArray [
["origin", _origin],
["radius", _radius],
["objects", _affectedObjects],
["localGroups", _affectedLocalGroups],
["machinesReady", []]
]];
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"EMP deployed precheck",
[
["id", _id],
["origin", _origin],
["radius", _radius],
["affectedObjects", count _affectedObjects],
["affectedLocalGroups", count _affectedLocalGroups]
]
] call EFUNC(common,log);
// notify the server we're ready to play effects
[QGVAR(event_readyForEmpEffects), [_id, clientOwner]] call CBA_fnc_serverEvent;
if (isServer) then {
// on the server, create a waiter for all machines to be ready
[{
_this params ["_id"];
private _empData = GVAR(activeEMPs) get _id;
count (_empData get "machinesReady") isEqualTo (count allUsers);
}, {
// when all machines are ready, play effects
_this params ["_id"];
private _empData = GVAR(activeEMPs) get _id;
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"Initiating EMP effects",
[
["id", _id],
["readyCount", count (_empData get "machinesReady")],
["allUsers", count allUsers]
]
] call EFUNC(common,log);
[QGVAR(event_initiateEMPEffects), [_id]] call CBA_fnc_globalEvent;
}, [_id]] call CBA_fnc_waitUntilAndExecute;
};
}] call CBA_fnc_addEventHandler;
// when a machine is ready to play effects, they'll trigger this on the server
if (isServer) then {
[QGVAR(event_readyForEmpEffects), {
params ["_id", "_machineID"];
private _empData = GVAR(activeEMPs) get _id;
private _machinesReady = _empData get "machinesReady";
if (!(_machineID in _machinesReady)) then {
_machinesReady pushBack _machineID;
_empData set ["machinesReady", _machinesReady];
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"Machine ready for EMP effects",
[
["id", _id],
["machineID", _machineID],
["readyCount", count _machinesReady]
]
] call EFUNC(common,log);
};
}] call CBA_fnc_addEventHandler;
};
// when all machines are ready, the server will trigger this on all machines to start effects
[QGVAR(event_initiateEMPEffects), {
params ["_id"];
private _empData = GVAR(activeEMPs) get _id;
private _origin = _empData get "origin";
private _affectedObjects = _empData get "objects";
private _affectedLocalGroups = _empData get "localGroups";
if (hasInterface) then {
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"Initiating EMP effects",
[
["id", _id],
["origin", _origin],
["affectedObjects", count _affectedObjects],
["affectedLocalGroups", count _affectedLocalGroups]
]
] call EFUNC(common,log);
[_origin] call FUNC(playLocalEffects);
// when emp effects reach max brightness, execute object effects
[{
params ["_affectedObjects", "_affectedLocalGroups"];
private _countLocalObjectEffectsPlayed = { // play effects on this machine
try {
[_x] call FUNC(playLocalEffectsForObject);
} catch {
[
LEVEL_WARNING,
QUOTE(COMPONENT),
"Failed to play local EMP effects for object",
[
["object", typeOf _x],
["error", _exception]
]
] call EFUNC(common,log);
};
true;
} count _affectedObjects;
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"Played EMP effects",
[
["localObjectEffectsPlayed", _countLocalObjectEffectsPlayed]
]
] call EFUNC(common,log);
}, [_affectedObjects, _affectedLocalGroups], GVAR(maxBrightDelay)] call CBA_fnc_waitAndExecute;
};
// around peak brightness
[{
params ["_affectedObjects", "_affectedLocalGroups"];
private _countLocalObjectEffectsApplied = { // apply affects to objects owned by this machine, start propagation to other machines
try {
[_x] call FUNC(applyLocalObjectEffects);
} catch {
[
LEVEL_WARNING,
QUOTE(COMPONENT),
"Failed to apply local EMP effects for object",
[
["object", typeOf _x],
["error", _exception]
]
] call EFUNC(common,log);
};
true;
} count (_affectedObjects select {local _x});
private _countLocalGroupEffectsApplied = { // apply affects to groups owned by this machine, start propagation to other machines
try {
[_x] call FUNC(applyLocalGroupEffects);
} catch {
[
LEVEL_WARNING,
QUOTE(COMPONENT),
"Failed to apply local EMP effects for group",
[
["group", _x],
["error", _exception]
]
] call EFUNC(common,log);
};
true;
} count _affectedLocalGroups;
if (isServer) then {
private _countServerObjectEffectsApplied = {
try {
[_x] call FUNC(applyServerObjectEffects);
} catch {
[
LEVEL_WARNING,
QUOTE(COMPONENT),
"Failed to apply server EMP effects for object",
[
["object", typeOf _x],
["error", _exception]
]
] call EFUNC(common,log);
};
true;
} count _affectedObjects;
};
private _countGlobalObjectEffectsApplied = {
try {
[_x] call FUNC(applyGlobalObjectEffects);
} catch {
[
LEVEL_WARNING,
QUOTE(COMPONENT),
"Failed to apply global EMP effects for object",
[
["object", typeOf _x],
["error", _exception]
]
] call EFUNC(common,log);
};
true;
} count _affectedObjects;
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"Applied EMP effects",
[
["localObjectEffects", _countLocalObjectEffectsApplied],
["localGroupEffects", _countLocalGroupEffectsApplied],
["serverObjectEffects", _countServerObjectEffectsApplied],
["globalObjectEffects", _countGlobalObjectEffectsApplied]
]
] call EFUNC(common,log);
}, [_affectedObjects, _affectedLocalGroups], GVAR(maxBrightDelay)] call CBA_fnc_waitAndExecute;
// clear EMP data after 30 seconds
[{
params ["_id"];
private _empData = GVAR(activeEMPs) get _id;
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"EMP effects finished",
[
["id", _id],
["affectedObjects", count (_empData get "objects")],
["affectedLocalGroups", count (_empData get "localGroups")]
]
] call EFUNC(common,log);
GVAR(activeEMPs) deleteAt _id;
}, [_id], 30] call CBA_fnc_waitAndExecute;
}] call CBA_fnc_addEventHandler;

View File

@@ -0,0 +1,38 @@
#include "..\script_component.hpp"
params [
["_itemClassname", "", [""]]
];
if (_itemClassname isEqualTo "") exitWith {
["Param _itemClassname is empty", ""] call BIS_fnc_error;
false
};
private _isTFARRadio = if (isClass (configFile >> "CfgPatches" >> "tfar_core")) then {_itemClassname call TFAR_fnc_isRadio} else {false};
if (_isTFARRadio) exitWith {true};
private _matchedSpecificClassnames = {(toLower _x) in (toLower _className)} count [
"ACE_microDAGR",
"Vector21",
"MineDetector",
"GPS"
];
if (_matchedSpecificClassnames > 0) exitWith {true};
// find items with NVG or TI capabilities
private _cfg = _className call CBA_fnc_getItemConfig;
private _modes = getArray(configfile >> "CfgWeapons" >> _className >> "visionMode");
private _subModes = [configfile >> "CfgWeapons" >> _className >> "ItemInfo" >> "OpticsModes", 1] call BIS_fnc_returnChildren;
{
_modes append getArray( _x >> "visionMode" );
} forEach _subModes;
private _hasTI = "ti" in (_modes apply { toLower _x });
private _hasNVG = "nvg" in (_modes apply { toLower _x });
if (_hasTI || _hasNVG) exitWith {true};
false;

View File

@@ -0,0 +1,101 @@
#include "..\script_component.hpp"
// Executed on all machines with an interface
// This plays the effects of the EMP itself going off
if (!hasInterface) exitWith {};
params [["_origin", [], [[]]]];
if (count _origin isEqualTo 0) exitWith {};
private _e_static3 = "#particlesource" createVehicleLocal (ASLToAGL _origin);
_e_static3 setParticleCircle [0, [0, 0, 0]];
_e_static3 setParticleRandom [0.2, [0,0,0], [0.175, 0.175, 0.175], 0.25, 0.15, [0, 0, 0, 1], 1, 0];
_e_static3 setParticleParams [["\A3\data_f\blesk1", 1, 0, 1], "", "SpaceObject", 1, 0.75, [0, 0, 1], [0, 0, 0], 0, 10, 7.9,0, [0, 0.2], [[1, 1, 0.1, 1], [1, 1, 1, 1]], [0.01], 1, 0, "", "", objNull,0,false,-1,[[100,100,100,1],[1,1,1,1]]];
_e_static3 setDropInterval 0.15;
private _ripple2 = "#particlesource" createVehicleLocal (ASLToAGL _origin);
_ripple2 setParticleCircle [0,[0,0,0]];
_ripple2 setParticleRandom [0.1,[0,0,0],[0,0,0],25,1,[0,0,0,0.1],0,0];
_ripple2 setParticleParams [["\A3\data_f\ParticleEffects\Universal\Refract.p3d",1,0,1], "", "Billboard", 1, 1, [0, 0, 1], [0, 0, 0],0,10,7.9,0, [5,0], [[1, 1, 1, 1], [1, 1, 1, 1]], [0.05], 1, 0, "", "", objNull];
_ripple2 setDropInterval 0.05;
private _light_emp = "#lightpoint" createVehiclelocal (ASLToAGL _origin);
// _light_emp lightAttachObject [objNull, [0,0,0.5]];
_light_emp setLightAmbient [0.1,0.1,1];
_light_emp setLightColor [0.1,0.1,1];
_light_emp setLightBrightness 0;
_light_emp setLightUseFlare true;
_light_emp setLightFlareSize 1;
_light_emp setLightFlareMaxDistance 2500;
_light_emp setLightDayLight true;
_light_emp setLightAttenuation [5,1,1,1,5,1000];
_brit = 0;
private _explSoundData = GVAR(sound_electric_explsion_impact_large);
// local only, last param
playSound3D [_explSoundData get "filename", nil, false, _origin, _explSoundData get "volume", _explSoundData get "pitch", 3500, 0, true];
[_light_emp, _brit, _ripple2] spawn {
params ["_light_emp", "_brit", "_ripple2"];
while {_brit < 6.5} do {
// takes ~1.73 seconds to reach full brightness
_light_emp setLightBrightness _brit;
_brit = _brit+0.02; //timing for next stage
sleep 0.01;
};
deleteVehicle _ripple2;
};
[{
params ["_origin", "_light_emp"];
private _e_static2 = "#particlesource" createVehicleLocal (ASLToAGL _origin);
_e_static2 setParticleCircle [0, [0, 0, 0]];
_e_static2 setParticleRandom [0.2, [0,0,0], [0, 0, 0], 0.25, 1.05, [0, 0, 0, 1], 1, 0];
_e_static2 setParticleParams [["\A3\data_f\blesk1", 1, 0, 1], "", "SpaceObject", 1, 0.75, [0, 0, 0], [0, 0, 1], 0, 10, 7.9,0, [0,0.5], [[1, 1, 0.1, 1], [1, 1, 1, 1]], [0.08], 1, 0, "", "", objNull,0,false,-1,[[100,100,100,1],[0,0,1,0.01]]];
_e_static2 setDropInterval 0.05;
private _wave = "#particlesource" createVehicleLocal (ASLToAGL _origin);
_wave setParticleCircle [0,[0,0,0]];
_wave setParticleRandom [0,[0,0,0],[0,0,0],10,0.25,[0,0,0,0.1],0,0];
_wave setParticleParams [["\A3\data_f\kouleSvetlo",1,0,1], "", "Billboard", 1, 3, [0, 0, 1], [0, 0, 0],0,10,7.9,0, [0,75], [[0,0,1,1],[0,0,0.25,0]], [0.01], 1, 0, "", "", objNull,0,false,-1,[[0,0,3,0.75],[0,0,1,0.01]]];
_wave setDropInterval 30;
private _ripple = "#particlesource" createVehicleLocal (ASLToAGL _origin);
_ripple setParticleCircle [0,[0,0,0]];
_ripple setParticleRandom [0,[0,0,0],[0,0,0],0,0.25,[0,0,0,0.1],0,0];
_ripple setParticleParams [["\A3\data_f\ParticleEffects\Universal\Refract.p3d",1,0,1], "", "Billboard", 1, 1.5, [0, 0, 1], [0, 0, 0],0,10,7.9,0, [0,500], [[1, 1, 1, 1], [1, 1, 1, 1]], [0.05], 1, 0, "", "", objNull];
_ripple setDropInterval 10;
[{deleteVehicle _this}, _ripple, 0.65] call CBA_fnc_waitAndExecute;
[{
params ["_e_static2", "_e_static3", "_brit", "_light_emp", "_wave"];
{
deleteVehicle _x;
} forEach [_e_static2, _e_static3];
[_light_emp, _brit, _wave] spawn {
params ["_light_emp", "_brit", "_wave"];
while {_brit > 0} do {
_light_emp setLightBrightness _brit;
_brit = _brit-2;
sleep 0.01;
};
deleteVehicle _light_emp;
deleteVehicle _wave;
};
}, [[_e_static2, _e_static3, 6.5, _light_emp, _wave]], 0.85] call CBA_fnc_waitAndExecute;
}, [_origin, _light_emp], GVAR(maxBrightDelay)] call CBA_fnc_waitAndExecute;
[{
params ["_origin"];
private _echosound = selectRandom (keys GVAR(echoSounds));
private _echoSoundData = GVAR(echoSounds) get _echosound;
// local only, last param
playSound3D [_echoSoundData get "filename", nil, false, _origin, _echoSoundData get "volume", _echoSoundData get "pitch", 4000, 0, true];
}, [_origin], GVAR(maxBrightDelay) + 0.65 + 2] call CBA_fnc_waitAndExecute;

View File

@@ -0,0 +1,79 @@
#include "..\script_component.hpp"
// executed on all clients with an interface
// flickers lights for light props/streetlamps and plays a spark sound
if (!hasInterface) exitWith {};
params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {};
// flicker the lights
private _flickerHandle = [_object] spawn {
params ["_object"];
for "_i" from 1 to 3 do {
_object switchLight "OFF";
sleep (random 0.3);
_object switchLight "ON";
sleep (random 0.3);
};
// always finish by shutting off
_object switchLight "OFF";
};
_object setVariable [QGVAR(flickerHandle), _flickerHandle];
[{scriptDone (_this getVariable QGVAR(flickerHandle));}, {
private _object = _this;
// sound
// private _spark_sound = selectRandom (keys GVAR(zapSounds));
// private _sparkSoundData = GVAR(zapSounds) get _spark_sound;
// playSound3D [_sparkSoundData get "filename", _object, false, getPosASL _object, _sparkSoundData get "volume", _sparkSoundData get "pitch", 75, 0, true];
// // particle effect, large blue spark
// private _e_static = "#particlesource" createVehicleLocal (getPosATL _object);
// _e_static setParticleCircle [1, [0, 0, 0]];
// _e_static setParticleRandom [0.2, [1.5,1.5,0], [0.175, 0.175, 0], 0.15, 0.2, [0, 0, 0, 1], 1, 0];
// _e_static setParticleParams [["\A3\data_f\blesk1", 1, 0, 1], "", "SpaceObject", 1, 0.05, [0, 0, 0], [0, 0, 0], 0, 10, 7.9,0, [0.01, 0.02, 0.01], [[1, 1, 0.1, 1], [1, 1, 1, 1]], [0.025], 1, 0, "", "", _object,0,false,-1,[[100,100,100,1],[0,0,1,0.01]]];
// _e_static setDropInterval 0.025;
// [{deleteVehicle _this;}, _e_static, 1] call CBA_fnc_waitAndExecute;
// play additional spark
_bbr = boundingBoxReal vehicle _object;
_p1 = _bbr select 0;
_p2 = _bbr select 1;
_maxHeight = abs ((_p2 select 2) - (_p1 select 2));
//_spark_poz_rel = [getPos _lamp select 0,getPos _lamp select 1,_maxHeight-0.5];
private _spark_poz_rel = (_maxHeight/2)-0.45;
private _spark_type = ["white","orange"] call BIS_fnc_selectRandom;
private _drop = 0.001+(random 0.05);
private _scantei_spark = "#particlesource" createVehicleLocal (getPosATL _object);
if (_spark_type=="orange") then
{
_scantei_spark setParticleCircle [0, [0, 0, 0]];
_scantei_spark setParticleRandom [1, [0.1, 0.1, 0.1], [0, 0, 0], 0, 0.25, [0, 0, 0, 0], 0, 0];
_scantei_spark setParticleParams [["\A3\data_f\proxies\muzzle_flash\muzzle_flash_silencer.p3d", 1, 0, 1], "", "SpaceObject", 1, 1, [0, 0,_spark_poz_rel], [0, 0, 0], 0, 15, 7.9, 0, [0.5,0.5,0.05], [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 0]], [0.08], 1, 0, "", "", _object,0,true,0.3,[[1,1,1,1]]];
_scantei_spark setDropInterval _drop;
} else
{
//hint "alb";
_scantei_spark setParticleCircle [0, [0, 0, 0]];
_scantei_spark setParticleRandom [1, [0.05, 0.05, 0.1], [5, 5, 3], 0, 0.0025, [0, 0, 0, 0], 0, 0];
_scantei_spark setParticleParams [["\A3\data_f\proxies\muzzle_flash\muzzle_flash_silencer.p3d", 1, 0, 1], "", "SpaceObject", 1, 1, [0, 0,_spark_poz_rel], [0, 0, 0], 0, 20, 7.9, 0, [0.5,0.5,0.05], [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 0]], [0.08], 1, 0, "", "", _object,0,true,0.3,[[5,5,3,1]]];
_scantei_spark setDropInterval 0.001;
};
private _spark_sound = selectRandom (keys GVAR(zapSounds));
private _sparkSoundData = GVAR(zapSounds) get _spark_sound;
playSound3D [_sparkSoundData get "filename", _object, false, getPosASL _object, _sparkSoundData get "volume", _sparkSoundData get "pitch", 75, 0, true];
[{deleteVehicle _this;}, _scantei_spark, 0.4 + (random 0.7)] call CBA_fnc_waitAndExecute;
}, _object] call CBA_fnc_waitUntilAndExecute;

View File

@@ -0,0 +1,53 @@
#include "..\script_component.hpp"
// Executed where object is local and removes electronics from inventory
params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {};
if (not (_object isKindOf "CAManBase")) exitWith {["Param _object is not a unit", _object] call BIS_fnc_error};
// process unit inventory
{
_object unassignItem _x;
_object removeItem _x;
} forEach ((items _object) + (assignedItems _object)) select {[_x] call FUNC(isItemElectronic)};
// replace backpack radio with base and restore items
if (isClass (configFile >> "CfgPatches" >> "tfar_core")) then {
private _backpackRadio = _object call TFAR_fnc_backpackLR;
if (!isNil "_backpackRadio") then {
_backpackRadio params ["_actualBackpack", "settings"];
private _baseBackpack = _actualBackpack call BIS_fnc_basicBackpack;
private _backpackItems = backpackItems _object;
removeBackpack _object;
_object addBackpack _baseBackpack;
{
_object addItemToBackpack _x;
} forEach _backpackItems;
};
};
//for player units
if (isPlayer _object) then {
_object action ["IRLaserOff", _object];
_object action ["nvGogglesOff", _object];
};
// remove flashlights/pointers on weapons
private _primaryFlashlightOrPointer = (primaryWeaponItems _object)#1;
if (_primaryFlashlightOrPointer != "") then {
_object removePrimaryWeaponItem _primaryFlashlightOrPointer;
_object removeItem _primaryFlashlightOrPointer;
};
private _secondaryFlashlightOrPointer = (secondaryWeaponItems _object)#1;
if (_secondaryFlashlightOrPointer != "") then {
_object removeSecondaryWeaponItem _secondaryFlashlightOrPointer;
_object removeItem _secondaryFlashlightOrPointer;
};
private _handgunFlashlightOrPointer = (handgunItems _object)#1;
if (_handgunFlashlightOrPointer != "") then {
_object removeHandgunItem _handgunFlashlightOrPointer;
_object removeItem _handgunFlashlightOrPointer;
};

View File

@@ -0,0 +1,34 @@
#include "..\script_component.hpp"
// Executed where object is local and removes electronics from inventory
params [["_object", objNull, [objNull]]];
if (isNull _object) exitWith {};
if (_object isKindOf "CAManBase") exitWith {["Param _object is not a vehicle: %1", _object] call BIS_fnc_error};
// get all items in vehicle that are electronic
private _vehicleItems = itemCargo _object;
// filter array to identify electronic items
_vehicleItems = _vehicleItems select {[_x] call FUNC(isItemElectronic)};
{
// remove item from vehicle
_object addItemCargoGlobal [_x, -1];
true;
} count _vehicleItems;
{ // forEach everyContainer _object - process vests, uniforms, backpacks in a vehicle
_x params ["_containerClass", "_containerObject"];
private _subItemsOfContainer = itemCargo _containerObject;
// filter array to identify electronic items
_subItemsOfContainer = _subItemsOfContainer select {[_x] call FUNC(isItemElectronic)};
{
// remove item from container
_subContainer addItemCargoGlobal [_x, -1];
true;
} count _subItemsOfContainer;
} forEach (everyContainer _object);
// vehicle is now empty of electronics
// built-in vehicle radios cannot be removed and are left in place

6
framework/emp/readme.md Normal file
View File

@@ -0,0 +1,6 @@
# EMP Module
Adapted from:
- KE_EB EMP Mission Script (unknown author, found by Sherman)
- EMP Systems (Murphy, Wenza) on [Steam Workshop](https://steamcommunity.com/sharedfiles/filedetails/?id=2225040619)

View File

@@ -0,0 +1,3 @@
#define COMPONENT emp
#define COMPONENT_BEAUTIFIED EMP
#include "../script_mod.hpp"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,27 @@
#include "..\script_component.hpp"
//---------------------
// Asset Diary and Markers Settings
[
QGVAR(setting_detectionRangeFromBase), // variable
"SLIDER", // type
["Detection Range From Base", "The range from a base that assets will be detected"], // title
[QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)], // category
[0, 1000, 750, 0, false], // [_min, _max, _default, _trailingDecimals, _isPercentage]
true, // global setting
{
params ["_value"];
[
QGVAR(setting_detectionRangeFromBase),
_value
] call EFUNC(common,logSettingChanged);
}
] call CBA_fnc_addSetting;
[
LEVEL_INFO,
QUOTE(COMPONENT),
"CREATED SETTINGS",
[]
] call EFUNC(common,log);

View File

@@ -0,0 +1,15 @@
#include "..\script_component.hpp"
params [
["_className", "", [""]]
];
// Get the approved assets config
private _approvedAssetsCfg = call EFUNC(common,getApprovedAssetsCfg);
if (isNull _approvedAssetsCfg) exitWith {""};
// Get the asset definition
private _assetDef = (_approvedAssetsCfg >> _className);
if (isClass _assetDef) exitWith {getText(_assetDef >> "callsign")};
"";

View File

@@ -0,0 +1,6 @@
#include "../script_component.hpp"
// return each base with its assets
GVARMAIN(baseObjects) apply {
[_x, _x getVariable [QGVAR(assetsAtThisBase), []]]
};

View File

@@ -0,0 +1,17 @@
#include "..\script_component.hpp"
// get all starting assets at each base and combine to array
private _startingAssetsByBase = call FUNC(getStartingAssetsByBase);
private _startingAssets = [];
{
_startingAssets append (_x#1);
} forEach _startingAssetsByBase;
// get all current assets at each base and combine to array
private _assetsByBase = call FUNC(getCurrentAssetsByBase);
private _assets = [];
{
_assets append (_x#1);
} forEach _assetsByBase;
[_startingAssets, _assets];

View File

@@ -0,0 +1,6 @@
#include "../script_component.hpp"
// return each base with its assets
GVARMAIN(baseObjects) apply {
[_x, _x getVariable [QGVAR(assetsStartedAtThisBase), []]]
};

View File

@@ -39,7 +39,7 @@ private _pylons = getAllPylonsInfo _vic;
/////////////////////////////////////////////// ///////////////////////////////////////////////
// WRITE TITLE // WRITE TITLE
/////////////////////////////////////////////// ///////////////////////////////////////////////
_title pushBack format["<font size='24' shadow='1' color='#e1701a' face='PuristaBold'>%1</font>", _dispName]; _title pushBack format["%1", _dispName];
/////////////////////////////////////////////// ///////////////////////////////////////////////
// WRITE IMAGE // WRITE IMAGE

View File

@@ -0,0 +1,94 @@
#include "..\script_component.hpp"
// get vehicles the mission started with at base locations
(call FUNC(getStartingAndCurrentAssets)) params [
"_startingAssets",
"_currentAssets"
];
// get distinct classnames to group by
private _distinctStartingAssetsClassNames = [];
{
_x params ["_netId", "_cfg"];
private _className = configName _cfg;
_distinctStartingAssetsClassNames pushBackUnique _className;
} forEach _startingAssets;
// get the approved assets config to identify callsigns
private _approvedAssetsCfg = call EFUNC(common,getApprovedAssetsCfg);
if (isNull _approvedAssetsCfg) exitWith {
[
LEVEL_ERROR,
QUOTE(COMPONENT),
"No approved assets defined.",
[]
] call EFUNC(common,log);
[
"ERROR: No approved assets defined. See defines/ApprovedAssets.hpp"
] call BIS_fnc_error;
};
_text = parseText "<t size='4'>MESSAGE</t>";
_text = composeText [_text, lineBreak ];
_text = composeText [_text, parseText "<t align='left' size='2'>Asset</t><t align='right' size='2'>Available</t>", lineBreak ];
{
private _className = _x;
// only approved assets
if (!isClass (_approvedAssetsCfg >> _className)) then {continue};
private _callsign = [_className] call FUNC(getCallsignFromClassname);
private _startingAssetsOfThisType = _startingAssets select {
// select all starting assets of this type
_x params ["_netId", "_cfg"];
_className isEqualTo (configName _cfg);
};
private _currentAssetsOfThisType = _currentAssets select {
_x params ["_netId", "_cfg"];
private _object = _netId call BIS_fnc_objectFromNetId;
// objNull if deleted, then check classname and if alive
!isNull _object && {
_className isEqualTo (typeOf _object) &&
alive _object
};
};
(_startingAssetsOfThisType#0) params [
"_assetNetId",
"_assetCfg"
];
_assigned = count _startingAssetsOfThisType;
_available = count _currentAssetsOfThisType;
// count (getMarkerPos "respawn_west" nearEntities [ _asset, 2000] );
_image = getText(_assetCfg >> "picture");
_name = getText(_assetCfg >> "displayName") select [0, 22];
private _data = format[
"<img size='1' align='left' image='%1'/><t size='1' align='left'> %2</t><t size='1' align='right'>%3 [ %4 ]</t>",
_image,
_name,
_available,
_assigned
];
// private _data = format[
// "<img size='1' align='left' image='%1'/>
// <t size='1' align='left'> %2</t>
// <t size='1' align='middle'>%3</t>
// <t size='1' align='right'>%4</t>",
// _image,
// _name,
// _assigned,
// _available
// ];
_text = composeText[ _text, parseText _data, lineBreak ];
} foreach _distinctStartingAssetsClassNames;
hint _text;

View File

@@ -0,0 +1,28 @@
#include "..\script_component.hpp"
if (!hasInterface) exitWith {};
call FUNC(updateAssetDiary);
// once the server has published that assets have been gathered and distributed to bases (respawn modules),
// we can update the asset diary on our end using that data
[QGVAR(assetsGathered), {
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"Received gathered base asset data from server",
[]
] call EFUNC(common,log);
// update the asset diary with the data we've received
FUNC(updateAssetDiary);
}] call CBA_fnc_addEventHandlerArgs;
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"initClient complete",
[]
] call EFUNC(common,log);
localNamespace setVariable [QGVAR(complete), true];

View File

@@ -0,0 +1,29 @@
#include "..\script_component.hpp"
if (!isServer) exitWith {};
// init asset stores at bases
[true] call FUNC(updateAssetsByBase);
// starting 5 minutes after postInit, update asset stores every 5 minutes
[{
[
{[false] call FUNC(updateAssetsByBase);},
60*5
] call CBA_fnc_addPerFrameHandler;
}, 60*5] call CBA_fnc_waitAndExecute;
// add end mission EH
addMissionEventHandler ["MPEnded", {
// log the "current" asset counts to RPT
[false, true] call FUNC(updateAssetsByBase);
}];
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"postInit complete",
[]
] call EFUNC(common,log);

View File

@@ -0,0 +1,8 @@
#include "..\script_component.hpp"
params [["_asset", objNull, [objNull]]];
private _closestBase = [_asset] call EFUNC(common,getNearestBase);
if (isNull _closestBase) exitWith {false};
(_asset distance2D _closestBase) <= GVAR(setting_detectionRangeFromBase)

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
if (!hasInterface) exitWith {}; if (!hasInterface) exitWith {};
{ {
@@ -10,7 +12,7 @@ if (!hasInterface) exitWith {};
player removeDiaryRecord [_diarySubject, _diaryRecord]; player removeDiaryRecord [_diarySubject, _diaryRecord];
} forEach _records; } forEach _records;
} forEach [ } forEach [
milsim_fbcb2_subjectAssetsFixedWingID, EGVAR(fbcb2_main,subjectAssetsFixedWingID),
milsim_fbcb2_subjectAssetsRotaryID, EGVAR(fbcb2_main,subjectAssetsRotaryID),
milsim_fbcb2_subjectAssetsGroundID EGVAR(fbcb2_main,subjectAssetsGroundID)
]; ];

View File

@@ -1,12 +1,11 @@
private _baseMarkerStoreVar = "milsim_fbcb2_assets_baseMarkerStore"; #include "..\script_component.hpp"
private _assetMarkerStoreVar = "milsim_fbcb2_assets_assetMarkerStore";
private _baseMarkerStore = localNamespace getVariable [ private _baseMarkerStore = localNamespace getVariable [
_baseMarkerStoreVar, QGVAR(baseMarkerStore),
[] []
]; ];
private _assetMarkerStore = localNamespace getVariable [ private _assetMarkerStore = localNamespace getVariable [
_assetMarkerStoreVar, QGVAR(assetMarkerStore),
[] []
]; ];
@@ -16,10 +15,10 @@ private _assetMarkerStore = localNamespace getVariable [
} forEach (_baseMarkerStore + _assetMarkerStore); } forEach (_baseMarkerStore + _assetMarkerStore);
localNamespace setVariable [ localNamespace setVariable [
_baseMarkerStoreVar, QGVAR(baseMarkerStore),
[] []
]; ];
localNamespace setVariable [ localNamespace setVariable [
_assetMarkerStoreVar, QGVAR(assetMarkerStore),
[] []
]; ];

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
params [ params [
["_className", "", [""]], ["_className", "", [""]],
["_markerType", "hd_dot", [""]], ["_markerType", "hd_dot", [""]],
@@ -12,11 +14,11 @@ if (count _markerColor isEqualTo 0) exitWith {
["No marker color provided!"] call BIS_fnc_error; ["No marker color provided!"] call BIS_fnc_error;
}; };
if (count _assetObjects isEqualTo 0) exitWith { if (count _assetObjects isEqualTo 0) exitWith {
["No vehicles provided!"] call BIS_fnc_error; ["No vehicles to draw markers for!"] call BIS_fnc_error;
}; };
private _baseMarkerStoreVar = "milsim_fbcb2_assets_baseMarkerStore"; private _baseMarkerStoreVar = QGVAR(baseMarkerStore);
private _assetMarkerStoreVar = "milsim_fbcb2_assets_assetMarkerStore"; private _assetMarkerStoreVar = QGVAR(assetMarkerStore);
private _baseMarkerStore = localNamespace getVariable [ private _baseMarkerStore = localNamespace getVariable [
_baseMarkerStoreVar, _baseMarkerStoreVar,
@@ -35,15 +37,15 @@ if (not (count _baseMarkerStore > 0)) then {
// create a circle marker with range as the detection range of assets // create a circle marker with range as the detection range of assets
_newMarker = createMarkerLocal [ _newMarker = createMarkerLocal [
format["milsim_fbcb2_assets_base_marker_%1", _forEachIndex + 1], format["%1_%2", QGVAR(baseCircleMarker), _forEachIndex + 1],
getPosASL _base getPosASL _base
]; ];
_newMarker setMarkerTypeLocal "mil_dot"; _newMarker setMarkerTypeLocal "mil_dot";
_newMarker setMarkerColorLocal "ColorGreen"; _newMarker setMarkerColorLocal "ColorGreen";
_newMarker setMarkerShapeLocal "ELLIPSE"; _newMarker setMarkerShapeLocal "ELLIPSE";
_newMarker setMarkerSizeLocal [ _newMarker setMarkerSizeLocal [
milsim_fbcb2_assets_setting_detectionRangeFromBase, GVAR(setting_detectionRangeFromBase),
milsim_fbcb2_assets_setting_detectionRangeFromBase GVAR(setting_detectionRangeFromBase)
]; ];
_newMarker setMarkerAlphaLocal 0.5; _newMarker setMarkerAlphaLocal 0.5;
_newMarker setMarkerTextLocal str(_forEachIndex + 1); _newMarker setMarkerTextLocal str(_forEachIndex + 1);
@@ -55,19 +57,19 @@ if (not (count _baseMarkerStore > 0)) then {
// create a flag marker at base position // create a flag marker at base position
_newMarker = createMarkerLocal [ _newMarker = createMarkerLocal [
format["milsim_fbcb2_assets_base_flag_marker_%1", _forEachIndex + 1], format["%1_%2", QGVAR(baseFlagMarker), _forEachIndex + 1],
getPosASL _base getPosASL _base
]; ];
_newMarker setMarkerTypeLocal "mil_flag"; _newMarker setMarkerTypeLocal "mil_flag";
_newMarker setMarkerColorLocal "ColorGreen"; _newMarker setMarkerColorLocal "ColorGreen";
_newMarker setMarkerSizeLocal [0.7, 0.7]; _newMarker setMarkerSizeLocal [0.7, 0.7];
_newMarker setMarkerTextLocal ([_base] call milsim_fnc_getNameOfBase); _newMarker setMarkerTextLocal ([_base] call EFUNC(common,getNameOfBase));
_baseMarkerStore pushBack [ _baseMarkerStore pushBack [
_base, _base,
_newMarker _newMarker
]; ];
} forEach milsim_baseObjects; } forEach GVARMAIN(baseObjects);
localNamespace setVariable [_baseMarkerStoreVar, _baseMarkerStore]; localNamespace setVariable [_baseMarkerStoreVar, _baseMarkerStore];
}; };
@@ -85,9 +87,12 @@ private _start = (count _assetMarkerStore) + 1;
> -1 > -1
) then {continue}; ) then {continue};
// check if the asset is within base detection range
if (not ([_asset] call FUNC(isAssetInRangeOfBase))) then {continue};
// create a marker for the asset // create a marker for the asset
private _newMarker = createMarkerLocal [ private _newMarker = createMarkerLocal [
format["milsim_fbcb2_assets_marker_%1", _start], format["%1_%2", QGVAR(assetMarker), _start],
getPosASL _asset getPosASL _asset
]; ];
_newMarker setMarkerAlphaLocal 1; _newMarker setMarkerAlphaLocal 1;

View File

@@ -0,0 +1,261 @@
#include "..\script_component.hpp"
if (!hasInterface) exitWith {};
// create diary records
// remove any existing asset map markers
call FUNC(removeMarkersOnMap);
// remove existing asset records
call FUNC(removeAssetDiaryRecords);
(call FUNC(getStartingAndCurrentAssets)) params [
"_startingAssets",
"_currentAssets"
];
// get distinct vehicle class names
private _distinctVehiclesClassNames = [];
{
_x params ["_netId", "_cfg"];
private _className = configName _cfg;
_distinctVehiclesClassNames pushBackUnique _className;
} forEach _startingAssets;
// for random color cycling
private _colorSelectionIndex = 0;
private _randomColors = [
["ColorRed", "#FF0000", "Red"],
["ColorGreen", "#00FF00", "Green"],
["ColorBlue", "#0000FF", "Blue"],
["ColorYellow", "#FFFF00", "Yellow"],
["ColorWhite", "#FFFFFF", "White"]
];
// ForEach unique vehicle class name, we'll find the first and gather its info
{
private _className = _x;
private _vehicleCallsign = toUpper (
[_className] call FUNC(getCallsignFromClassname)
);
// Get all starting assets of this type
private _startingAssetsOfThisType = _startingAssets select {
_x params ["_netId", "_cfg"];
_className isEqualTo (configName _cfg);
};
// Get all current assets of this type
private _currentAssetsOfThisType = _currentAssets select {
_x params ["_netId", "_cfg"];
private _object = _netId call BIS_fnc_objectFromNetId;
// objNull if deleted, then check classname and if alive
!isNull _object && {_className isEqualTo (typeOf _object) && alive _object};
};
// This should never happen, but...
if (count _startingAssetsOfThisType isEqualTo 0) then {continue};
// Try to find a not null vehicle that can be processed
private _exampleVehicleToProcess = objNull;
private _assetCfg = configNull;
private _exampleVehicleToProcessIndex = _startingAssetsOfThisType findIf {
_x params ["_netId", "_cfg"];
!isNull (_netId call BIS_fnc_objectFromNetId);
};
// If found, get the data
if (_exampleVehicleToProcessIndex > -1) then {
private _exampleData = _startingAssetsOfThisType select _exampleVehicleToProcessIndex;
_assetNetId = _exampleData#0;
_assetCfg = _exampleData#1;
_exampleVehicleToProcess = _assetNetId call BIS_fnc_objectFromNetId;
} else {
// otherwise, we only have the config to work with
private _exampleData = _startingAssetsOfThisType#0;
_assetCfg = _exampleData#1;
};
private _parentClassNames = [_assetCfg, true] call BIS_fnc_returnParents;
// Process the vehicle for extended info
// Exclusion list for display names
if (
[_assetCfg] call BIS_fnc_displayName
in ["Helicopter"]
) then {continue};
// Get the vehicle data
private _processed = [configNull, "", []];
if (!isNull _exampleVehicleToProcess) then {
_processed = [_exampleVehicleToProcess] call FUNC(getVehicleData);
};
_processed params ["_processedVehicleCfg", "_displayName", "_diaryTextSections"];
_diaryTextSections params [
["_title", "", [""]],
["_image", "", [""]],
["_info", "", [""]],
["_capacity", "", [""]]
// ["_weapons", "", [""]],
// ["_pylonWeapons", "", [""]],
// ["_inventory", "", [""]]
];
// Get what we can from the vehicle cfg
// Create the diary record
private _recordText = [];
// Add the title and image
if (count _title isEqualTo 0) then {
_title = format["%1", [_assetCfg] call BIS_fnc_displayName];
};
_recordText pushBack format[
"<font size='24' shadow='1' color='#e1701a' face='PuristaBold'>%1</font>",
_title
];
if (count _image isEqualTo 0) then {
_image = format["<img width='200' image='%1'/>", getText(_assetCfg >> 'editorPreview')];
};
_recordText pushBack _image;
_recordText pushBack "<br/>";
_recordText pushBack format[
"CALLSIGN: %1",
_vehicleCallsign
];
_recordText pushBack format[
"COUNT STARTED: %1",
count _startingAssetsOfThisType
];
_recordText pushBack format[
"COUNT ACTIVE: %1",
count _currentAssetsOfThisType
];
// Here, we'll create a link to show markers on the map for all vehicles of this kind
// get 'picture' for record
private _icon = getText(_assetCfg >> "picture");
// determine marker type
private _markerType = "mil_dot";
switch (true) do {
case ("Helicopter" in _parentClassNames): {
_markerType = "loc_heli";
};
case ("Air" in _parentClassNames): {
_markerType = "loc_plane";
};
case ("Ship" in _parentClassNames): {
_markerType = "loc_boat";
};
case ("Car" in _parentClassNames): {
_markerType = "loc_car";
};
default {
_markerType = "loc_truck";
};
};
private "_randomColor";
if (_colorSelectionIndex < count _randomColors) then {
_randomColor = _randomColors select _colorSelectionIndex;
INC(_colorSelectionIndex);
} else {
_colorSelectionIndex = 0;
_randomColor = _randomColors select _colorSelectionIndex;
};
// Link to show markers
private _showMarkersText = format[
"<execute expression='[""%1"",""%2"",""%3"",%4] call %5'>SHOW MARKERS for vehicles at base</execute> (in %6)",
_className,
_markerType,
_randomColor#0,
(_currentAssetsOfThisType apply {
_x params ["_netId", "_cfg"];
_netId;
}),
QFUNC(showMarkersOnMap),
format["<font color='%1'>%2</font>", _randomColor#1, _randomColor#2]
];
_recordText pushBack _showMarkersText;
// Link to hide markers
_recordText pushBack format[
"<execute expression=""call %1"">REMOVE ALL MARKERS showing asset positions</execute>",
QFUNC(removeMarkersOnMap)
];
// Link to update asset diary entries
_recordText pushBack format[
"<execute expression=""call %1"">UPDATE ENTRIES for all assets</execute>",
QFUNC(updateAssetDiary)
];
// link to display hint with all assets
_recordText pushBack format[
"<execute expression=""call %1"">SHOW APPROVED ASSET COUNTS via hint</execute>",
QFUNC(hintAllApprovedAssets)
];
_recordText pushBack format[
"<font size='10' color='#777777'>%1</font>",
"Notes:<br/>
- Markers are only displayed on your local machine.<br/>
- The REMOVE ALL option will remove all assets' markers from the map.<br/>
- UPDATE ENTRIES will update the asset diary with the latest information.<br/>
- Markers will only be displayed for assets that are within a certain distance of a base."
];
// Add info and capacity sections - exclude if no living examples were found
if (count _info > 0) then {
_recordText pushBack _info;
};
if (count _capacity > 0) then {
_recordText pushBack _capacity;
};
private _subjectID = "";
switch (true) do {
case ("Helicopter" in _parentClassNames): {
_subjectID = EGVAR(fbcb2_main,subjectAssetsRotaryID);
};
case ("Air" in _parentClassNames): {
_subjectID = EGVAR(fbcb2_main,subjectAssetsFixedWingID);
};
default {
_subjectID = EGVAR(fbcb2_main,subjectAssetsGroundID);
};
};
[
_subjectID,
format[
"[%1/%2] %3",
count _currentAssetsOfThisType,
count _startingAssetsOfThisType,
(_assetCfg) call BIS_fnc_displayName
],
_recordText joinString "<br/>",
_icon
] call EFUNC(common,createOrUpdateDiaryRecord);
// "\A3\ui_f\data\igui\cfg\simpleTasks\types\car_ca.paa"
} forEach _distinctVehiclesClassNames;
// log to RPT
[
LEVEL_INFO,
QUOTE(COMPONENT),
"UPDATED ASSET DIARY",
[
["startingAssetCount", count _startingAssets],
["startingAssetCountDistinct", count _distinctVehiclesClassNames],
["currentassetCount", count _currentAssets]
]
] call EFUNC(common,log);
true;

View File

@@ -0,0 +1,141 @@
#include "..\script_component.hpp"
params [
["_isInit", false, [false]],
["_logCurrentAssets", false, [false]]
];
if (!isServer) exitWith {};
GVARMAIN(baseObjects) = allMissionObjects "ModuleRespawnPosition_F";
// Get all approved assets on map, find the closest base
// Then determine if it's within range
// If it is, add it to the base's assets list
// This is to ensure bases with overlapping detection range don't have duplicate assets
private _allVehicles = vehicles;
private _allSaved = [];
private _assetsStartedAtThisBaseVar = QGVAR(assetsStartedAtThisBase);
private _assetsAtThisBaseVar = QGVAR(assetsAtThisBase);
private _approvedAssetsCfg = call EFUNC(common,getApprovedAssetsCfg);
if (isNull _approvedAssetsCfg) exitWith {};
private _currentBaseAssetsGathered = GVARMAIN(baseObjects) apply {[_x, []]};;
{
private _className = configName _x;
private _callsign = getText(_x >> "callsign");
private _found = _allVehicles select { typeOf _x == _className };
{
private _asset = _x;
// ignore assets beyond the range of bases
if (not ([_asset] call FUNC(isAssetInRangeOfBase))) then {continue};
// add to base's assets list
private _closestBase = [_asset] call EFUNC(common,getNearestBase);
private _closestBaseCurrentAssets = (_currentBaseAssetsGathered select { _x select 0 isEqualTo _closestBase })#0#1;
_closestBaseCurrentAssets pushBackUnique [
_asset call BIS_fnc_netId,
configOf _asset
];
} forEach _found;
} forEach (_approvedAssetsCfg call BIS_fnc_returnChildren);
// Add all ground vehicles (LandVehicle)
{
private _asset = _x;
// ignore assets beyond the range of bases
if (not ([_asset] call FUNC(isAssetInRangeOfBase))) then {continue};
// add to base's assets list
private _closestBase = [_asset] call EFUNC(common,getNearestBase);
private _closestBaseCurrentAssets = (_currentBaseAssetsGathered select { _x select 0 isEqualTo _closestBase })#0#1;
_closestBaseCurrentAssets pushBackUnique [
_asset call BIS_fnc_netId,
configOf _asset
];
} forEach (_allVehicles select { _x isKindOf "LandVehicle" });
////////////////////////////////////////////////////////////////////////
// publish updated base variables
////////////////////////////////////////////////////////////////////////
{
private _base = _x;
private _thisBaseCurrentAssets = (_currentBaseAssetsGathered select { _x select 0 isEqualTo _base })#0#1;
_base setVariable [_assetsAtThisBaseVar, _thisBaseCurrentAssets, true];
if (_isInit) then {
_base setVariable [_assetsStartedAtThisBaseVar, _thisBaseCurrentAssets, true];
};
} forEach GVARMAIN(baseObjects);
// send a CBA event to let other scripts know that assets have been gathered
[{[QGVAR(assetsGathered)] call CBA_fnc_globalEvent;}, 2] call CBA_fnc_waitAndExecute;
////////////////////////////////////////////////////////////////////////
// log starting assets if init
// log current assets if requested (for end of mission counts)
////////////////////////////////////////////////////////////////////////
if !(_isInit || _logCurrentAssets) exitWith {};
{
private _base = _x;
// get current assets
private _baseAssets = (_currentBaseAssetsGathered select { _x select 0 isEqualTo _base })#0#1;
// prepare key value for logging
private _baseAssetsHashesPrep = _baseAssets apply {
_x params ["_netId", "_cfg"];
[
["callsign", [configName _cfg] call FUNC(getCallsignFromClassname)],
["className", configName _cfg],
["displayName", [_cfg] call BIS_fnc_displayName]
];
};
_baseAssetsHashesPrep = _baseAssetsHashesPrep call BIS_fnc_consolidateArray;
private _baseAssetsHashes = [];
{
private _out = createHashMapFromArray (_x#0);
_out set ["count", _x#1];
_baseAssetsHashes pushBack _out;
} forEach _baseAssetsHashesPrep;
// if logging current assets
if (_logCurrentAssets) then {
{
[
LEVEL_INFO,
QUOTE(COMPONENT),
"CURRENT ASSETS",
[
["baseName", [[_base] call EFUNC(common,getNameOfBase)]],
["asset", _x]
]
] call EFUNC(common,log);
} forEach _baseAssetsHashes;
};
// if init, log starting assets
if (_isInit) then {
{
[
LEVEL_INFO,
QUOTE(COMPONENT),
"STARTING ASSETS",
[
["baseName", [[_base] call EFUNC(common,getNameOfBase)]],
["asset", _x]
]
] call EFUNC(common,log);
} forEach _baseAssetsHashes;
};
} forEach GVARMAIN(baseObjects);

View File

@@ -0,0 +1,3 @@
#define COMPONENT fbcb2_assets
#define COMPONENT_BEAUTIFIED FBCB2 - Assets
#include "../script_mod.hpp"

View File

@@ -0,0 +1,112 @@
#include "..\script_component.hpp"
private _recordTitle = "ENVIRONMENTAL CONDITIONS";
private _text = [
format[
"<font size='%1' color='%2' face='%3'>%4</font>",
GVAR(recordTitleSize),
GVAR(recordTitleColor),
GVAR(recordTitleFont),
_recordTitle
]
];
private _sunriseColor = "#4A86E8";
private _sunsetColor = "#6AA84F";
private _whiteColor = "#FFFFFF";
private _sunTimes = date call BIS_fnc_sunriseSunsetTime;
private _nearestBase = [player] call EFUNC(common,getNearestBase);
if (isNull _nearestBase) exitWith {
[
LEVEL_WARNING,
QUOTE(COMPONENT),
"WARNING: No bases found nearby to report weather!",
[player, [
["position", getPos player]
]] call EFUNC(common,addPlayerInfoToArray)
] call EFUNC(common,log);
["WARNING: No bases found nearby to report weather!"] call BIS_fnc_error;
};
_text pushBack format[
"<font size='%1'>Current conditions at nearest weather station: %2</font><br/>",
GVAR(recordTextBodySize),
[_nearestBase] call EFUNC(common,getNameOfBase)
];
private _weatherData = [];
if (isClass (configFile >> "CfgPatches" >> "ace_weather")) then {
// get ace_weather data
private _barometricPressure = ((getPosASL _nearestBase)#2) call ace_weather_fnc_calculateBarometricPressure;
private _relHumidity = missionNamespace getVariable ["ace_weather_currentHumidity", 0.5];
private _temperature = ((getPosASL _nearestBase)#2) call ace_weather_fnc_calculateTemperatureAtHeight;
private _dewPoint = [_temperature, _relHumidity] call ace_weather_fnc_calculateDewPoint;
private _windSpeed = [getPosASL _nearestBase, false, false, false] call ace_weather_fnc_calculateWindSpeed;
private _windChill = [_temperature, _windSpeed] call ace_weather_fnc_calculateWindChill;
private _heatIndex = [_temperature, _relHumidity] call ace_weather_fnc_calculateHeatIndex;
toFixed 2;
private _aceData = [
["Temperature", format["%1°C / %2°F", _temperature, _temperature * (9/5) + 32]],
["Wind Chill", format["%1°C / %2°F", _windChill, _windChill * (9/5) + 32]],
["Heat Index", format["%1°C / %2°F", _heatIndex, _heatIndex * (9/5) + 32]],
["Dew Point", format["%1°C / %2°F", _dewPoint, _dewPoint * (9/5) + 32]],
["Wind Speed", format["%1mph / %2kph / %3kts", _windSpeed * 2.237, _windSpeed * 3.6, _windSpeed * 1.944]],
["Wind Direction", ""],
["Barometric Pressure", format["%1 hPA", _barometricPressure]],
["Relative Humidity", format["%1%2", _relHumidity * 100, "%"]],
["Fog Cover", ""],
["Rain", ""],
["Overcast", ""]
];
toFixed -1;
{
_x params ["_name", "_value"];
[_weatherData, _name, _value] call BIS_fnc_setToPairs;
} forEach _aceData;
};
// always add built-in weather
toFixed 2;
private _vanillaData = [
["Temperature", format["%1°C", (ambientTemperature)#0]],
["Fog Cover", format["%1%2", fog * 100, "%"]],
["Overcast", format["%1%2", overcast * 100, "%"]],
["Rain", format["%1%2", rain * 100, "%"]],
["Wind Speed", format["%1m/s", windStr]],
["Wind Direction", format["%1°", windDir]]
];
toFixed -1;
_vanillaData pushBack ["Sunrise", ([_sunTimes select 0, "HH:MM"] call BIS_fnc_timeToString)];
_vanillaData pushBack ["Sunset", ([_sunTimes select 1, "HH:MM"] call BIS_fnc_timeToString)];
// override or set keys for vanilla data into weather data
{
_x params ["_name", "_value"];
[_weatherData, _name, _value] call BIS_fnc_setToPairs;
} forEach _vanillaData;
// write lines
{
_x params ["_name", "_value"];
_text pushBack format[
"<font size='%1' face='EtelkaMonospacePro'>%2%3</font>",
GVAR(recordTextBodySize)-4,
[_name, "right", " ", 23] call EFUNC(common,padString),
_value
];
} forEach _weatherData;
_text = _text joinString "<br/>";
[
GVAR(subjectIntelID),
_recordTitle,
_text
] call EFUNC(common,createOrUpdateDiaryRecord);

View File

@@ -1,11 +1,32 @@
// updated 2024-02-01 by IndigoFox // updated 2024-02-01 by IndigoFox
// now reads from the battalion config structure to generate the diary entries // now reads from the battalion config structure to generate the diary entries
#include "../script_component.hpp"
//////////////////////////////////////// ////////////////////////////////////////
// Get info from missionConfigFile // Get info from missionConfigFile
//////////////////////////////////////// ////////////////////////////////////////
private _battalionInfoCfg = call milsim_fnc_getBattalionCfg; private _battalionInfoCfg = call EFUNC(common,getBattalionCfg);
if (isNull _battalionInfoCfg) exitWith {
[
LEVEL_ERROR,
QUOTE(COMPONENT),
"Null Battalion Config",
[]
] call EFUNC(common,log);
["Null Battalion Config"] call BIS_fnc_error;
};
private _battalionElementCfgs = [_battalionInfoCfg >> "Command"] call BIS_fnc_returnChildren; private _battalionElementCfgs = [_battalionInfoCfg >> "Command"] call BIS_fnc_returnChildren;
if (count _battalionElementCfgs == 0) exitWith {
[
LEVEL_ERROR,
QUOTE(COMPONENT),
"ERROR: No battalion elements found. Check that the battalion config is correctly structured. See defines/BattalionInfo.hpp and framework/util/functions/getBattalionCfg.sqf.",
[]
] call EFUNC(common,log);
["ERROR: No battalion elements found. Check that the battalion config is correctly structured. See defines/BattalionInfo.hpp and framework/util/functions/getBattalionCfg.sqf."] call BIS_fnc_error;
};
//////////////////////////////////////// ////////////////////////////////////////
// Define formatting constants // Define formatting constants
@@ -29,22 +50,28 @@ private _FREQ_TEXT_COLOR = "#CCCCCC";
reverse _battalionElementCfgs; reverse _battalionElementCfgs;
{ {
// recursively generate diary text for all child elements of battalion-level elements
private _diaryTitleText = [_x, true] call milsim_fnc_generateElementFrequencyRecordText;
[ [
milsim_fbcb2_subjectFrequenciesID, LEVEL_TRACE,
QUOTE(COMPONENT),
format["Processing battalion element %1", configName _x],
[]
] call EFUNC(common,log);
// recursively generate diary text for all child elements of battalion-level elements
private _diaryTitleText = [_x, true] call FUNC(generateElementFrequencyRecordText);
[
GVAR(subjectFrequenciesID),
_diaryTitleText#0, _diaryTitleText#0,
_diaryTitleText#1 _diaryTitleText#1
] call milsim_fnc_createOrUpdateDiaryRecord; ] call EFUNC(common,createOrUpdateDiaryRecord);
} forEach _battalionElementCfgs; } forEach _battalionElementCfgs;
// add the battalion command to the top of the list // add the battalion command to the top of the list
// don't process child elements // don't process child elements
private _diaryTitleText = [_battalionInfoCfg >> "Command", false] call milsim_fnc_generateElementFrequencyRecordText; private _diaryTitleText = [_battalionInfoCfg >> "Command", false] call FUNC(generateElementFrequencyRecordText);
[ [
milsim_fbcb2_subjectFrequenciesID, GVAR(subjectFrequenciesID),
_diaryTitleText#0, _diaryTitleText#0,
_diaryTitleText#1 _diaryTitleText#1
] call milsim_fnc_createOrUpdateDiaryRecord; ] call EFUNC(common,createOrUpdateDiaryRecord);
true; true;

View File

@@ -0,0 +1,59 @@
#include "../script_component.hpp"
private _recordTitle = "SIGNAL COLORS";
private _text = [
// Title
format[
"<font size='%1' color='%2' face='%3'>%4</font>",
GVAR(recordTitleSize),
GVAR(recordTitleColor),
GVAR(recordTitleFont),
_recordTitle
]
];
private _signalColorDefs = (missionConfigFile >> "SignalColors") call BIS_fnc_returnChildren;
{
private _cfg = _x;
private _color = getText(_cfg >> "hexCode");
private _name = getText(_cfg >> "name");
private _usage = getText(_cfg >> "usage");
private _itemExamples = getArray(_cfg >> "itemExamples");
private _thisText = [];
_thisText pushBack format[
"<font size='%1'><font color='%2'>%3</font> - %4</font>",
GVAR(recordTextHeaderSize),
_color,
_name,
_usage
];
private _imagesLine = [];
{
private _itemClassname = _x;
private _itemCfg = [_itemClassname] call CBA_fnc_getItemConfig;
private _itemName = getText(_itemCfg >> "displayName");
private _itemImage = getText(_itemCfg >> "picture");
_imagesLine pushBack format[
"<img height='32' src='%1' title='%2'/>",
_itemImage,
_itemName
];
} forEach _itemExamples;
_thisText pushBack (_imagesLine joinString " ");
_text pushBack (_thisText joinString "<br/>");
} forEach _signalColorDefs;
_text = _text joinString "<br/><br/>";
[
GVAR(subjectIntelID),
_recordTitle,
_text
] call EFUNC(common,createOrUpdateDiaryRecord);

View File

@@ -0,0 +1,48 @@
#include "../script_component.hpp"
if ( !hasInterface ) exitWith {};
GVAR(recordTitleColor) = "#ff6666";
GVAR(recordTitleFont) = "PuristaMedium";
GVAR(recordTitleSize) = 20;
GVAR(recordTextHeaderSize) = 16;
GVAR(recordTextBodySize) = 14;
GVAR(subjectStatusID) = "FBCB2_Status";
GVAR(subjectIntelID) = "FBCB2_Intel";
GVAR(subjectMessagesID) = "FBCB2_Messages";
GVAR(subjectFrequenciesID) = "FBCB2_Frequencies";
GVAR(subjectAssetsFixedWingID) = "FBCB2_Assets_FixedWing";
GVAR(subjectAssetsRotaryID) = "FBCB2_Assets_Rotary";
GVAR(subjectAssetsGroundID) = "FBCB2_Assets_Ground";
player createDiarySubject[GVAR(subjectStatusID), "FBCB2 Status"];
player createDiarySubject[GVAR(subjectMessagesID), "FBCB2 Messages"];
player createDiarySubject[GVAR(subjectIntelID), "FBCB2 Intel"];
player createDiarySubject[GVAR(subjectFrequenciesID), "FBCB2 Frequencies"];
player createDiarySubject[GVAR(subjectAssetsFixedWingID), "FBCB2 Planes"];
player createDiarySubject[GVAR(subjectAssetsRotaryID), "FBCB2 Helicopters"];
player createDiarySubject[GVAR(subjectAssetsGroundID), "FBCB2 Ground"];
// run main inits
[] call FUNC(addFrequenciesRecord);
[] call FUNC(addSignalColorsRecord);
[] call FUNC(addEnvironmentRecord);
// starting 5 minutes after postInit, update weather diary record every 5 minutes
[{
[
{call FUNC(addEnvironmentRecord);},
60*5
] call CBA_fnc_addPerFrameHandler;
}, 60*5] call CBA_fnc_waitAndExecute;
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"initClient complete",
[]
] call EFUNC(common,log);
localNamespace setVariable [QGVAR(complete), true];

View File

@@ -0,0 +1,3 @@
#define COMPONENT fbcb2_main
#define COMPONENT_BEAUTIFIED FBCB2 - Main
#include "../script_mod.hpp"

View File

@@ -1,4 +1,6 @@
// called from milsim_fnc_processFBCB2RadioFrequencies // called from milsim_fnc_processFBCB2RadioFrequencies
#include "../script_component.hpp"
params ["_cfg", ["_indentCount", 1, [5]]]; params ["_cfg", ["_indentCount", 1, [5]]];
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
@@ -62,8 +64,8 @@ _freqLeadingSpace = _freqLeadingSpace joinString "";
_ELEMENT_FREQ_SIZE, _ELEMENT_FREQ_SIZE,
_ELEMENT_FREQ_FONT, _ELEMENT_FREQ_FONT,
_FREQ_TEXT_COLOR, _FREQ_TEXT_COLOR,
[_role, "right", " ", _FREQ_PAD_LENGTH] call milsim_fnc_padString, [_role, "right", " ", _FREQ_PAD_LENGTH] call EFUNC(common,padString),
[_srStr, "right", " ", _FREQ_PAD_LENGTH] call milsim_fnc_padString, [_srStr, "right", " ", _FREQ_PAD_LENGTH] call EFUNC(common,padString),
_lrStr _lrStr
]; ];
} forEach (getArray (_cfg >> "frequencies")); } forEach (getArray (_cfg >> "frequencies"));

View File

@@ -1,5 +1,8 @@
// called from milsim_fnc_processFBCB2RadioFrequencies ONLY // called from milsim_fnc_processFBCB2RadioFrequencies ONLY
// this function is called recursively to process all child elements of a battalion element in missionConfigFile // this function is called recursively to process all child elements of a battalion element in missionConfigFile
#include "../script_component.hpp"
params [ params [
["_elementCfg", configNull, [configNull]], ["_elementCfg", configNull, [configNull]],
["_shouldProcessChildCfgs", true] ["_shouldProcessChildCfgs", true]
@@ -40,9 +43,9 @@ _freqLeadingSpace = _freqLeadingSpace joinString "";
private _headers = [ private _headers = [
format[ format[
"<font size='%1' color='%2' face='%3'>%4</font>", "<font size='%1' color='%2' face='%3'>%4</font>",
milsim_fbcb2_recordTitleSize, GVAR(recordTitleSize),
milsim_fbcb2_recordTitleColor, GVAR(recordTitleColor),
milsim_fbcb2_recordTitleFont, GVAR(recordTitleFont),
_recordTitle _recordTitle
], ],
format[ format[
@@ -51,8 +54,8 @@ private _headers = [
_ELEMENT_FREQ_SIZE, _ELEMENT_FREQ_SIZE,
_ELEMENT_FREQ_FONT, _ELEMENT_FREQ_FONT,
_FREQ_TEXT_COLOR, _FREQ_TEXT_COLOR,
["ROLE", "right", " ", _FREQ_PAD_LENGTH] call milsim_fnc_padString, ["ROLE", "right", " ", _FREQ_PAD_LENGTH] call EFUNC(common,padString),
["SR", "right", " ", _FREQ_PAD_LENGTH] call milsim_fnc_padString, ["SR", "right", " ", _FREQ_PAD_LENGTH] call EFUNC(common,padString),
"LR" "LR"
] ]
]; ];
@@ -65,16 +68,30 @@ private _allText = [];
// get all child elements recursively and format them // get all child elements recursively and format them
if (_shouldProcessChildCfgs) then { if (_shouldProcessChildCfgs) then {
[
LEVEL_TRACE,
QUOTE(COMPONENT),
"Processing child elements for battalion element %1",
[]
] call EFUNC(common,log);
[_battalionElement, { [_battalionElement, {
params ["_cfg", "_recurseCounter"]; params ["_cfg", "_recurseCounter"];
// add config // add config
private _lines = [_cfg, _recurseCounter+1] call milsim_fnc_formatRadioElementForDiary; private _lines = [_cfg, _recurseCounter+1] call FUNC(formatRadioElementForDiary);
// private _lines = [_cfg, _indentCount] call t; // private _lines = [_cfg, _indentCount] call t;
_allText pushBack (_lines joinString "<br/>"); _allText pushBack (_lines joinString "<br/>");
}] call milsim_fnc_recurseSubclasses; }] call EFUNC(common,recurseSubclasses);
} else { } else {
[
LEVEL_TRACE,
QUOTE(COMPONENT),
"Skipping processing of child elements for battalion element %1",
[]
] call EFUNC(common,log);
// or if the param was false, just add the battalion element // or if the param was false, just add the battalion element
private _lines = [_battalionElement, 1] call milsim_fnc_formatRadioElementForDiary; private _lines = [_battalionElement, 1] call FUNC(formatRadioElementForDiary);
// private _lines = [_cfg, _indentCount] call t; // private _lines = [_cfg, _indentCount] call t;
_allText pushBack (_lines joinString "<br/>"); _allText pushBack (_lines joinString "<br/>");
}; };

View File

@@ -0,0 +1,18 @@
#include "..\script_component.hpp"
[
"saveaar",
{
[] remoteExec["ocap_fnc_exportData", 2];
},
"admin"
] call CBA_fnc_registerChatCommand;
[
LEVEL_INFO,
QUOTE(COMPONENT),
"OCAP chat handler registered",
[player] call EFUNC(common,addPlayerInfoToArray)
] call EFUNC(common,log);
nil;

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
[ [
"respawn", "respawn",
{ {
@@ -6,10 +8,11 @@
// log to server RPT // log to server RPT
[ [
"init", LEVEL_INFO,
QUOTE(COMPONENT),
"CHAT COMMAND RESPAWN", "CHAT COMMAND RESPAWN",
[player] call milsim_fnc_addPlayerInfoToArray [player] call EFUNC(common,addPlayerInfoToArray)
] remoteExec ["milsim_fnc_log", 2]; ] remoteExec [QEFUNC(common,log), 2];
// systemChat to all remote machines // systemChat to all remote machines
format["%1 claims they were glitched and respawned (%2)", name player, netID player] remoteExec["systemChat", -_clientID]; format["%1 claims they were glitched and respawned (%2)", name player, netID player] remoteExec["systemChat", -_clientID];
@@ -18,6 +21,11 @@
[clientOwner] [clientOwner]
] call CBA_fnc_registerChatCommand; ] call CBA_fnc_registerChatCommand;
diag_log text "[MILSIM] (settings) respawn chat handler registered"; [
LEVEL_INFO,
QUOTE(COMPONENT),
"respawn chat handler registered",
[player] call EFUNC(common,addPlayerInfoToArray)
] call EFUNC(common,log);
nil; nil;

View File

@@ -0,0 +1,39 @@
#include "..\script_component.hpp"
if ( !hasInterface ) exitWith {};
// make sure the server has finished init
waitUntil {!isNil QGVARMAIN(complete)};
["InitializePlayer", [player, true]] call BIS_fnc_dynamicGroups;
// Initialize a holder for managing local diary records
// store records in format:
// [subject, [
// [title, diaryRecord]
// ]]
EGVAR(common,diaryRecords) = createHashMap;
// initialize other modules
call EFUNC(emp,init);
call EFUNC(mapcopy,initClient);
call EFUNC(reinsert,initClient);
call EFUNC(resupply,initClient);
call EFUNC(triageIcons,initClient);
call EFUNC(vehicleFlags,initClient);
call EFUNC(zeus,initClient);
call EFUNC(fbcb2_main,initClient);
call EFUNC(fbcb2_assets,initClient);
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"initClient complete",
[]
] call EFUNC(common,log);
localNamespace setVariable [QGVAR(complete), true];
nil;

View File

@@ -0,0 +1,33 @@
#include "..\script_component.hpp"
if (!isServer) exitWith {};
// array of all respawn modules in the mission representing "bases"
GVARMAIN(baseObjects) = allMissionObjects "ModuleRespawnPosition_F";
publicVariable QGVARMAIN(baseObjects);
// Initializes the Dynamic Groups framework and groups
["Initialize", [true]] call BIS_fnc_dynamicGroups;
// initialize other modules
call EFUNC(common,logMissionInfo);
call EFUNC(fbcb2_assets,initServer);
call EFUNC(reinsert,initServer);
call EFUNC(emp,init);
// declare init complete to other modules
missionNamespace setVariable [QGVARMAIN(complete), true, true];
[
LEVEL_INFO,
QUOTE(COMPONENT),
format["%1: version %2", QGVARMAIN(complete), QUOTE(VERSION_STR)],
[["version", QUOTE(VERSION_STR)]]
] call EFUNC(common,log);
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"postInit complete",
[]
] call EFUNC(common,log);

View File

@@ -0,0 +1,34 @@
#include "..\script_component.hpp"
enableSaving[false, false];
enableRadio false;
enableSentences false;
missionNamespace setVariable ["ACE_maxWeightDrag", 2400];
missionNamespace setVariable ["ACE_maxWeightCarry", 1800];
if(isClass(configfile >> "CfgPatches" >> "rhs_main")) then {
rhs_vehicleRadioChatter = 0;
};
waitUntil {time > 0};
enableEnvironment[false, true];
[
LEVEL_INFO,
QUOTE(COMPONENT),
"Defaults set",
[
["enableSaving", [false, false]],
["enableRadio", false],
["enableSentences", false],
["ACE_maxWeightDrag", 2400],
["ACE_maxWeightCarry", 1800],
["rhs_vehicleRadioChatter", 0],
["enableEnvironment", [false, true]]
]
] call EFUNC(common,log);
nil;

View File

@@ -0,0 +1,3 @@
#define COMPONENT init
#define COMPONENT_BEAUTIFIED Init
#include "../script_mod.hpp"

View File

@@ -0,0 +1,24 @@
#include "..\script_component.hpp"
[
QGVAR(setting_enable),
"CHECKBOX",
"Allow Map Copying",
[QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)],
true, // default value
true, // is global
{
params ["_value"];
[
QGVAR(setting_enable),
_value
] call EFUNC(common,logSettingChanged);
}
] call CBA_fnc_addSetting;
[
LEVEL_INFO,
QUOTE(COMPONENT),
"CREATED SETTINGS",
[]
] call EFUNC(common,log);

View File

@@ -0,0 +1,15 @@
#include "..\script_component.hpp"
// serializes markers on local machine and returns them as array
_markerData = [];
{
_marker = toArray _x;
_marker resize 15;
if ( toString _marker == "_USER_DEFINED #" ) then {
_marker = _x call FUNC(mapMarkerToString);
_markerData pushBack _marker;
};
} forEach allMapMarkers;
_markerData;

View File

@@ -0,0 +1,57 @@
#include "..\script_component.hpp"
////////////////////////////////////////////////////////////////////
// Create action to copy map markers on all inheritors of CAManBase
////////////////////////////////////////////////////////////////////
private _mapCopyAction =
[
QGVAR(actionID),
"Copy Map",
"\a3\ui_f\data\igui\cfg\actions\talk_ca.paa",
{
params ["_target", "_player", "_params"];
format["Copying map markers from %1", name _target] call CBA_fnc_notify;
[QGVAR(mapCopyRequest), _this, _target] call CBA_fnc_targetEvent;
},
{
params ["_target", "_player", "_params"];
[QGVAR(setting_enable)] call CBA_settings_fnc_get && {
('ItemMap' in (assignedItems _player)) &&
('ItemMap' in (assignedItems _target)) &&
([_player, _target, []] call ace_common_fnc_canInteractWith)
};
}
] call ace_interact_menu_fnc_createAction;
["CAManBase", 0, ["ACE_MainActions"], _mapCopyAction, true] call ace_interact_menu_fnc_addActionToClass;
////////////////////////////////////////////////////////////////////
// Create CBA event to receive requests
////////////////////////////////////////////////////////////////////
[QGVAR(mapCopyRequest), {
params ["_me", "_requester", "_params"];
format["Your map is being copied by %1", name _requester] call CBA_fnc_notify;
private _myMarkers = _this call FUNC(getMapMarkers);
[QGVAR(mapCopyResponse), [_me, _myMarkers], _requester] call CBA_fnc_targetEvent;
}] call CBA_fnc_addEventHandler;
////////////////////////////////////////////////////////////////////
// Create CBA event to receive responses
////////////////////////////////////////////////////////////////////
[QGVAR(mapCopyResponse), {
params [["_responder", objNull, [objNull]], ["_markerList", [], [[]]]];
if ('ItemMap' in (assignedItems player)) then {
[_markerList] call FUNC(loadMapMarkers);
format["Copied %1 markers from %2", count _markerList, name _responder] call CBA_fnc_notify;
} else {
format["You need a map to copy onto!"] call CBA_fnc_notify;
};
}] call CBA_fnc_addEventHandler;
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"initClient complete",
[]
] call EFUNC(common,log);
localNamespace setVariable [QGVAR(complete), true];

View File

@@ -0,0 +1,8 @@
#include "..\script_component.hpp"
// accepts an array of serialized markers and adds them to local map
params [["_markerList", [], [[]]]];
{
_x call FUNC(stringToMapMarker);
} foreach _markerList;

View File

@@ -0,0 +1,3 @@
#define COMPONENT mapcopy
#define COMPONENT_BEAUTIFIED Map Copy
#include "../script_mod.hpp"

View File

@@ -0,0 +1,105 @@
#include "..\script_component.hpp"
//---------------------
// Server CPS
//---------------------
[
QGVAR(server_cps_enable),
"CHECKBOX",
"Server CPS Metrics Enabled",
[QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)],
true,
true,
{
params ["_value"];
[
QGVAR(cps_enable),
_value
] call EFUNC(common,logSettingChanged);
}
] call CBA_fnc_addSetting;
[QGVAR(cps_enable), true] call CBA_settings_fnc_set;
[
QGVAR(server_cps_interval),
"TIME",
"Server CPS Metrics Interval",
[QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)],
[60,300,120],
true,
{
if (!isServer) exitWith {};
params ["_value"];
[
QGVAR(cps_interval),
_value
] call EFUNC(common,logSettingChanged);
_cpsPFH = missionNamespace getVariable [QGVAR(server_cps_handler), ObjNull];
if (!isNull _cpsPFH) then {
_cpsPFH call CBA_fnc_deletePerFrameHandlerObject;
};
[] call FUNC(addServerStatsPFH);
}
] call CBA_fnc_addSetting;
//---------------------
// Client CPS
//---------------------
[
QGVAR(client_cps_enable),
"CHECKBOX",
"Client CPS Metrics Enabled",
[QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)],
true,
true,
{
params ["_value"];
[
QGVAR(client_cps_enable),
_value
] call EFUNC(common,logSettingChanged);
}
] call CBA_fnc_addSetting;
[QGVAR(client_cps_enable), true] call CBA_settings_fnc_set;
[
QGVAR(client_cps_interval),
"TIME",
"Client CPS Metrics Interval",
[QUOTE(SETTINGS_GROUP_NAME), QUOTE(COMPONENT_BEAUTIFIED)],
[60,300,120],
true,
{
if (!hasInterface) exitWith {};
params ["_value"];
[
QGVAR(client_cps_interval),
_value
] call EFUNC(common,logSettingChanged);
_cpsPFH = player getVariable [QGVAR(client_cps_handler), ObjNull];
if (!isNull _cpsPFH) then {
_cpsPFH call CBA_fnc_deletePerFrameHandlerObject;
};
[] call FUNC(addClientStatsPFH);
}
] call CBA_fnc_addSetting;
[
LEVEL_INFO,
QUOTE(COMPONENT),
"CREATED SETTINGS",
[]
] call EFUNC(common,log);

View File

@@ -0,0 +1,38 @@
#include "..\script_component.hpp"
if (!hasInterface) exitWith {};
[
LEVEL_INFO,
QUOTE(COMPONENT),
"Initializing client stats PFH",
[]
] call EFUNC(common,log);
_cpsPFH = [
{
[] call FUNC(calculateClientStats);
},
QGVAR(client_cps_interval) call CBA_settings_fnc_get,
[],
{
[
LEVEL_INFO,
QUOTE(COMPONENT),
"Client PFH loaded",
[["pfhInterval", QGVAR(client_cps_interval) call CBA_settings_fnc_get]]
] call EFUNC(common,log);
},
{ [
LEVEL_INFO,
QUOTE(COMPONENT),
"Client PFH unloaded",
[]
] call EFUNC(common,log);
},
{ QGVAR(client_cps_enable) call CBA_settings_fnc_get },
{ false },
[]
] call CBA_fnc_createPerFrameHandlerObject;
player setVariable [QGVAR(client_cps_handler), _cpsPFH];

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
if ( !hasInterface ) exitWith {}; if ( !hasInterface ) exitWith {};
diag_log text "[MILSIM] (DNI) writing variable loop"; diag_log text "[MILSIM] (DNI) writing variable loop";

View File

@@ -1,28 +1,48 @@
#include "..\script_component.hpp"
if (!isServer) exitWith {}; if (!isServer) exitWith {};
missionNamespace setVariable["milsim_raw_cps", 0]; missionNamespace setVariable[QGVAR(raw_cps), 0];
missionNamespace setVariable["milsim_cps", 0]; missionNamespace setVariable[QGVAR(cps), 0];
publicVariable "milsim_raw_cps"; publicVariable QGVAR(raw_cps);
publicVariable "milsim_cps"; publicVariable QGVAR(cps);
diag_log text format ["[MILSIM] (server) initializing Server Stats PFH"]; [
LEVEL_INFO,
QUOTE(COMPONENT),
"Initializing server stats PFH",
[]
] call EFUNC(common,log);
_serverCpsPFH = [ _serverCpsPFH = [
{ {
[] call milsim_fnc_calculateServerStats; [] call FUNC(calculateServerStats);
}, },
"milsim_server_cps_interval" call CBA_settings_fnc_get, QGVAR(server_cps_interval) call CBA_settings_fnc_get,
[], [],
{ diag_log text format ["[MILSIM] (server) Server PFH loaded with interval %1 seconds", "milsim_server_cps_interval" call CBA_settings_fnc_get ] }, {
{ diag_log text format ["[MILSIM] (server) Server PFH unloaded"] }, [
{ "milsim_server_cps_enable" call CBA_settings_fnc_get }, LEVEL_INFO,
QUOTE(COMPONENT),
"Server PFH loaded",
[["pfhInterval", QGVAR(server_cps_interval) call CBA_settings_fnc_get]]
] call EFUNC(common,log);
},
{ [
LEVEL_INFO,
QUOTE(COMPONENT),
"Server PFH unloaded",
[]
] call EFUNC(common,log);
},
{ QGVAR(server_cps_enable) call CBA_settings_fnc_get },
{ false }, { false },
[] []
] call CBA_fnc_createPerFrameHandlerObject; ] call CBA_fnc_createPerFrameHandlerObject;
missionNamespace setVariable ["milsim_server_cps_handler", _serverCpsPFH]; missionNamespace setVariable [QGVAR(server_cps_handler), _serverCpsPFH];
_playerCpsPFH = [ _playerCpsPFH = [
{ {

View File

@@ -1,3 +1,5 @@
#include "..\script_component.hpp"
[] spawn { [] spawn {
// warning: while loop without suspension executes multiple times per frame // warning: while loop without suspension executes multiple times per frame
private _counter = 0; private _counter = 0;
@@ -8,8 +10,8 @@
_counter = _counter + 1; _counter = _counter + 1;
}; };
// in an empty mission, the _counter may go well over 2000 times per frame! // in an empty mission, the _counter may go well over 2000 times per frame!
diag_log text format ["[MILSIM] (client) Average Execution: %1 times per frame", _counter / (diag_frameNo - _frameNo)]; private _rawCPS = _counter / (diag_frameNo - _frameNo);
player setVariable ["milsim_player_raw_cps", _counter / (diag_frameNo - _frameNo), true]; player setVariable [QGVAR(player_raw_cps), _rawCPS, true];
// with suspension // with suspension
private _counter = 0; private _counter = 0;
@@ -21,9 +23,23 @@
uiSleep 0.001; // waits at least 1 frame uiSleep 0.001; // waits at least 1 frame
}; };
// _counter says one per frame, as expected // _counter says one per frame, as expected
diag_log text format ["[MILSIM] (client) Average Execution: %1 times per frame", _counter / (diag_frameNo - _frameNo)]; private _playerCPS = _counter / (diag_frameNo - _frameNo);
player setVariable ["milsim_player_cps", _counter / (diag_frameNo - _frameNo), true]; player setVariable [QGVAR(player_cps), _playerCPS, true];
// log to RPT
[
{_this call EFUNC(common,log);},
[
LEVEL_INFO,
QUOTE(COMPONENT),
format ["Average Execution: %1 times per frame", _playerCPS],
[
["playerRawCPS", _rawCPS],
["playerCPS", _playerCPS]
]
]
] call CBA_fnc_directCall;
}; };
nil; nil;

View File

@@ -0,0 +1,54 @@
#include "..\script_component.hpp"
[] spawn {
// warning: while loop without suspension executes multiple times per frame
private _counter = 0;
private _endTime = diag_tickTime + 5;
private _frameNo = diag_frameNo;
while { diag_tickTime < _endTime } do
{
_counter = _counter + 1;
};
private _rawCPS = _counter / (diag_frameNo - _frameNo);
missionNamespace setVariable [QGVAR(server_raw_cps), _rawCPS];
publicVariable QGVAR(server_raw_cps);
// with suspension
private _counter = 0;
private _endTime = diag_tickTime + 5;
private _frameNo = diag_frameNo;
while { diag_tickTime < _endTime } do
{
_counter = _counter + 1;
uiSleep 0.001; // waits at least 1 frame
};
private _serverCPS = _counter / (diag_frameNo - _frameNo);
missionNamespace setVariable [QGVAR(server_cps), _counter / (diag_frameNo - _frameNo)];
publicVariable QGVAR(server_cps);
// log to RPT
[
{_this call EFUNC(common,log);},
[
LEVEL_INFO,
QUOTE(COMPONENT),
format ["Average Server Execution: %1 times per frame", _serverCPS],
[
["serverRawCPS", _rawCPS],
["serverCPS", _serverCPS]
]
]
] call CBA_fnc_directCall;
[QGVARMAIN(serverEfficiency), [
[
["float", QGVARMAIN(raw_cps), missionNamespace getVariable [QGVAR(server_raw_cps), -1]],
["float", QGVARMAIN(cps), missionNamespace getVariable [QGVAR(server_cps), -1]]
]
]] call CBA_fnc_localEvent;
};
nil;

View File

@@ -0,0 +1,3 @@
#define COMPONENT performance
#define COMPONENT_BEAUTIFIED Performance Monitoring
#include "../script_mod.hpp"

View File

@@ -0,0 +1,65 @@
#include "..\script_component.hpp"
params [
["_types", [], [[]]], // classnames to assign these action to
["_useInheritance", false, [false]]
];
{ // forEach _types
private _classToAddActionsTo = _x;
private _fileForReinsertAction = [
QGVAR(fileReinsertRequestAction),
"File Re-insert Request",
"\A3\ui_f\data\igui\cfg\simpleTasks\types\takeoff_ca.paa",
{ // statement
params ["_target", "_player", "_params"];
// find nearest base or location
private _base = [_player] call EFUNC(common,getNearestBase);
private _baseName = [_base] call EFUNC(common,getNameOfBase);
// send event to server
[QGVAR(fileReinsertRequest), [_player, _base]] call CBA_fnc_serverEvent;
// notify player their request was filed
[["Re-insert Request Filed"], [format["Location: %1", _baseName]]] call CBA_fnc_notify;
},
{ // condition
params ["_target", "_player", "_params"];
// find nearest base or location
private _base = [_player] call EFUNC(common,getNearestBase);
private _baseDistance = _player distance _base;
private _maxRangeToReady = [QGVAR(setting_maxRangeToReady)] call CBA_settings_fnc_get;
private _existingQueue = missionNamespace getVariable [QGVAR(reinsertionQueue), []];
// check if module is enabled, player is near a base, and player is not already in the queue
// (serverTime - GVAR(missionStartServerTime)) > 60*5 && // only allow after 15 minutes
[QGVAR(setting_enabled)] call CBA_settings_fnc_get &&
(_baseDistance < _maxRangeToReady) &&
not (_player in (_existingQueue apply {_x#0}))
}
] call ace_interact_menu_fnc_createAction;
[_classToAddActionsTo, 1, ["ACE_SelfActions"], _fileForReinsertAction, _useInheritance] call ace_interact_menu_fnc_addActionToClass;
private _removeFileForReinsertAction = [
QGVAR(removeReinsertRequestAction),
"Remove Re-insert Request",
"\A3\ui_f\data\igui\cfg\simpleTasks\types\land_ca.paa",
{ // statement
params ["_target", "_player", "_params"];
// send event to server
[QGVAR(removeReinsertRequest), [_player]] call CBA_fnc_serverEvent;
// notify player their request was rescinded
"Re-insert Request Rescinded" call CBA_fnc_notify;
},
{ // condition
params ["_target", "_player", "_params"];
private _existingQueue = missionNamespace getVariable [QGVAR(reinsertionQueue), []];
// check if module is enabled, player is in the queue
// (serverTime - GVAR(missionStartServerTime)) > 60*5 && // only allow after 15 minutes
[QGVAR(setting_enabled)] call CBA_settings_fnc_get &&
(_player in (_existingQueue apply {_x#0}))
}
] call ace_interact_menu_fnc_createAction;
[_classToAddActionsTo, 1, ["ACE_SelfActions"], _removeFileForReinsertAction, _useInheritance] call ace_interact_menu_fnc_addActionToClass;
} forEach _types;

View File

@@ -0,0 +1,28 @@
#include "..\script_component.hpp"
params [
["_types", [], [[]]], // classnames to assign these action to
["_useInheritance", false, [false]]
];
{ // forEach _types
private _classToAddActionsTo = _x;
private _checkReinsertQueueAction = [
QGVAR(checkReinsertQueue),
"[PILOT] Check Re-insert Queue",
"\A3\ui_f\data\igui\cfg\simpleTasks\types\land_ca.paa",
{
params ["_target", "_player", "_params"];
// request notification from the server
call FUNC(requestShowQueue);
// reset last check time
localNamespace setVariable [QGVAR(lastReinsertQueueCheck), diag_tickTime];
},
{
GVAR(setting_enabled);
} // condition
] call ace_interact_menu_fnc_createAction;
[_classToAddActionsTo, 1, ["ACE_SelfActions"], _checkReinsertQueueAction, _useInheritance] call ace_interact_menu_fnc_addActionToClass;
} forEach _types;

View File

@@ -0,0 +1,54 @@
#include "..\script_component.hpp"
if (!hasInterface) exitWith {};
// ACE SELF-INTERACTIONS FOR FILING AND RESCINDING REINSERT REQUESTS NEAR BASE - ALL PLAYERS
localNamespace setVariable [QGVAR(fileForReinsertClassesAdded), []];
// add actions to current class
[["CAManBase"], true] call FUNC(addAceSelfActions);
/////////////////////////////////////////////////////
// PILOTS ONLY
// ACE SELF-INTERACTIONS FOR CHECKING REINSERT QUEUE - ONLY FOR PILOTS
localNamespace setVariable [QGVAR(checkReinsertQueueClassesAdded), []];
localNamespace setVariable [QGVAR(lastReinsertQueueCheck), diag_tickTime];
// add actions to pilot classes, and don't apply to child classes
[["B_Helipilot_F", "B_helicrew_F"], false] call FUNC(addCheckQueueSelfAction);
/////////////////////////////////////////////////////
// ADD TIMER FOR PILOTS - IF REINSERT LIST NOT CHECKED FOR 20 MINUTES, SHOW NOTIFICATION AUTOMATICALLY
if ((typeOf player) in ["B_Helipilot_F", "B_helicrew_F"]) then {
[{
// if module not enabled and pilot forced check not enabled, exit
if (not (
[QGVAR(setting_enabled)] call CBA_settings_fnc_get and
[QGVAR(setting_pilotForcedCheckEnabled)] call CBA_settings_fnc_get
)) exitWith {};
// if last check was less than X minutes ago, skip
private _lastCheck = localNamespace getVariable [QGVAR(lastReinsertQueueCheck), diag_tickTime];
private _requiredCheckInterval = [QGVAR(setting_pilotForcedCheckInterval)] call CBA_settings_fnc_get;
if (
diag_tickTime - _lastCheck <
_requiredCheckInterval
) exitWith {}; // if last check was less than X minutes ago, skip
// last check was greater than X minutes ago
// reset last check time
localNamespace setVariable [QGVAR(lastReinsertQueueCheck), diag_tickTime];
// request notification from the server
call FUNC(requestShowQueue);
}, 30] call CBA_fnc_addPerFrameHandler;
};
/////////////////////////////////////////////////////
[
LEVEL_DEBUG,
QUOTE(COMPONENT),
"initClient complete",
[]
] call EFUNC(common,log);
localNamespace setVariable [QGVAR(complete), true];

Some files were not shown because too many files have changed in this diff Show More