BSO Loadouts is a system for applying loadouts to players and AI units in ArmA. By using BSO Loadouts correctly, we are able to avoid locality issues in the multiplayer environment. The loadouts saved to configs are then easy to share with other mission makers. These can then hook into other Beowulf systems for compatibility with automated mission testing, and other future projects.
The following provides a guide on how to use basic BSO Loadouts, and the advanced feature, and provide more information on the logic behind the functions themselves. Insert non-formatted text here
The BSO Loadouts system is fully implemented with examples in the Beowulf Mission Framework. The examples below will assume usage of the Beowulf Mission Framework, but will elaborate on functionality.
Current templates can be found in the Beowulf mission framework or on the Mission Makers GDrive
https://drive.google.com/drive/folders/1qSHHpn2iB8Sw9ZLBCSQ3Oxue098FJEDU?usp=sharing
As BSO Loadouts are created using configs, we must define the CfgBsoLoadouts
class in the mission config (description.ext). In the Beowulf Mission Framework, this is placed in the meta.cpp file.
class CfgBsoLoadouts {
#include "loadouts\blufor.cpp"
//#include "loadouts\opfor.cpp" //create this file by copying blufor.cpp and renaming
//#include "loadouts\indep.cpp" //create this file by copying blufor.cpp and renaming
};
The mission will now read the blufor.cpp
file in the missions\loadouts
folder. If you wish to add more files for easy management of several sets of loadouts (or factions), uncomment the other examples provided with a //
, or create your own and define them here.
In the included files, we are now able to define our faction and loadout.
class blufor //Name of your faction referenced in the init call
{
name = "Beowulf Loadout Faction"; //Friendly name of your faction
class Rifleman // Class Names
{
blufor refers to the FACTION for this set of loadouts. Factions allow for separation of loadouts. Normally these would be used as a per faction basis. The faction should be unique to the mission space when used in missions. So blufor is fine, but if we create a new faction we must change this to another name. class Rifleman
refers to the LOADOUT we will apply to our unit. Similar to FACTION These must be unique within the parent faction class. You can define as many individual loadouts you require for your mission.
With your loadout defined in a faction, we’re able to define the properties (or classes) of your loadout. This defines what equipment your loadout is given when the loadout is applied to them. When a loadout is applied, all prior equipment except for glasses will be removed. Examples of loadouts can be found within the template and the example blufor.cpp loadout in the Beowulf Mission Framework.
All Text fields MUST be a single string of text as below;
primaryWeapon = "arifle_TRG21_F";
You cannot change a text only class to an array as this is not what the system is expecting, and will cause an error.
All Array fields MUST be an array of strings of text as below;
magazines[] = {
"30Rnd_556x45_Stanag",
"30Rnd_556x45_Stanag",
"30Rnd_556x45_Stanag",
"30Rnd_556x45_Stanag",
"30Rnd_556x45_Stanag",
"30Rnd_556x45_Stanag_Tracer_Red",
"30Rnd_556x45_Stanag_Tracer_Red",
"HandGrenade",
"HandGrenade",
"SmokeShell"
};
You can of course only define a single string within the array. Ensure when using arrays, that each string is separated by ,
but the last entry must not have the following ,
as above. Some arrays can allow for multipliers. See Advanced use section.
Below is a full list of the text fields and arrays compatible with the Loadout system. Please read these carefully, and refer to the Beowulf Mission Framework example and template for additional information.
``name`` - Text - Friendly name for reference in Loadout selector
``primaryWeapon`` - Text - The primary weapon slot. Usually a rifle
``primaryWeaponItems[]`` - Array - Array of weapon items to be attached. Define a single magazine per muzzle to be pre-loaded into the weapon ( EG. Rifle + UGL)
``handgun`` - Text - Add pistol slot weapon here
``handgunItems[]`` - Array - Array for weapon items to be attached. Define a single magazine per muzzle to be pre-loaded into the weapon
``magazines[]`` - Array - Array of magazines to be first added to the Vest. Multipliers can be applied here. Captured in rejects array
``items[]`` - Array - Array of items to be first added to the Uniform. Multipliers can be applied here. Captured in rejects array
``personalRadios[]`` - Array - Array of ACRE radios to be added to the uniform. These will take priority over other items/magazines.
``assignedItems[]`` - Array - Array of assigned items. EG Watch, Map, GPS
``backpack`` - Text - Defines the backpack to be used
``backpackMagazines[]`` - Array - Array of magazines to be first added to the Backpack. Multipliers can be applied here. Captured in rejects array
``backpackItems[]`` - Array - Array of items to be first added to the Backpack. Multipliers can be applied here. Captured in rejects array. ACRE Backpack radios should go here, ideally as the first entry!
``launcher`` - Text - The secondary Weapon Slot. Usually a Launcher
``launcherItems[]`` - Array - Array of weapon items to be attached. Define a single magazine per muzzle to be pre-loaded into the weapon
``uniform[]`` - Array - Used to randomly select a single uniform from the array, to apply to the loadout.
``vest[]`` - Array - Used to randomly select a single vest from the array, to apply to the loadout.
``headgear[]`` - Array - Used to randomly select a single piece of headgear from the array, to apply to the loadout.
``nvg`` - Text - Define Night Vision Goggles here, these will be applied and correctly assigned to the headgear slot.
``binoculars`` - Text - Define a binoculars slot item here
``insignia`` - Text - Define a single insignia classname to apply an insignia to the uniform.
``glasses[]`` - Array - Primarily for AI usage as this will delete player profile glasses. Used to randomly select a single piece glasses item from the array, to apply to the loadout.
The Loadout system will attempt to add items to a specific inventory container uniform for items[]
, vest for magazines[]
, and backpack for backpackMagazines[]
and backpackItemsp[]
. Although the fields are named specifically for magazines or items, you can in fact place weapons, items, or magazines in these arrays and they’ll be handled the same. The main advantage is allowing you to dictate the container. For example, if you have a loadout you do not want the unit to have a vest for, you could put magazines in the items list. This is also useful for putting disposable launchers in backpacks or adding paraflares.
The Loadouts system also has a built-in overflow checker. Items that are added to the Uniform for items[]
, vest for magazines[]
, and backpack for backpackMagazines[]
arrays that do not fit in their respected container. Will be added to the overflow and then put inside any available space once the rest of the loadout has finished applying. Items that fail to be added in the overflow will be reported in the systemChat.
Included in the ACE Arsenal is the BSO Export button at the bottom of the screen, which allows you to export the current loadout into a BSO Loadout format to be pasted into your faction class. Apply Loadouts
With the loadouts created in the configs, we must now apply them to our unit. To apply a loadout to a unit, we use the following call to the applyLoadout function. Below is a basic example from the Beowulf Mission Framework, and a brief description on the variables used for the call. For more information, see the functions library ingame.
[this,"blufor","PlatoonLeader",true] call BSO_fnc_applyLoadout;
The first parameter is the unit we wish to apply the loadout to. As per the Beowulf Mission Framework, most loadouts are applied by putting the call in the init of the player. So “this” is the variable used to represent the unit.
"blufor"
refers to the faction to be used, and ”Platoonleader”
is the loadout. Both are from our config file where we set the faction and the loadout classnames.
Finally true means that this loadout will be applied whenever this unit respawns.
As of r36 (15/04/2021) “multiplier arrays” can be used as an alternative to macros to add many magazines with only one line in the array. This only applies to the items[]
, magazines[]
, backpackItems[]
and backpackMagazines[]
arrays. This can be used by creating an array within the array, and within this define your magazine name string, followed by the number of magazines/items you wish to add. See below for an example;
{"30Rnd_556x45_Stanag",5}
Below is an example for the magazines[] array.
magazines[] = { {"30Rnd_556x45_Stanag",5}, {"30Rnd_556x45_Stanag_Tracer_Red", 2}, {"HandGrenade",2}, "SmokeShell" };
As per the example, you can define several multiplier arrays within each class entry. You can also still single strings alongside for just defining single entries.
Config inheritance is part of ArmA, and can be used to speed up the creation of loadouts. By creating a base class with all the common entries across the loadouts we want to create for a faction. We then only have to be concerned with the classes we wish to change in the loadouts we use to inherit from this base class. You can inherit from a previously defined class by using a colon :
at the end of your new loadout’s class name, followed by the loadout you wish to inherit from. A loadout that inherits from a previously defined loadout, will have all the properties of the loadout it inherited from. We can then define properties within this new loadout, to overwrite the options that were in the previous loadout. This can be a time saver as for example, we only have to define our array of randomised headgear once, and then have all follow on loadouts use the same array. Then if we wish to change this in the future, it's only one place to change.
An example of this being used in three layers is below. Where the Riflemam
loadout inherits the base
class, and then the RiflemanLAT
class inherits from the Rifleman
class.
class Base // Class Names
{
name = "Base";
items[] = {
"ACE_entrenchingtool",
"ACE_salineIV_500",
"ACE_fieldDressing",
"ACE_fieldDressing",
"ACE_morphine",
"ACE_tourniquet",
"ACE_quikclot",
"ACE_fieldDressing",
"ACE_fieldDressing",
"ACE_elasticBandage",
"ACE_elasticBandage",
"ACE_elasticBandage",
"ACE_elasticBandage"
};
assignedItems[] = {
"ItemMap",
"ItemCompass",
"ItemWatch"
};
uniform[] = {"usm_bdum65_odg"};
vest[] = {"bso_chestrig2_P_classic4"};
headgear[] = {"usm_helmet_m1_ERDL","usm_helmet_m1v2_ERDL"};
nvg = "usm_nvg_giglovesscarf";
};
class Rifleman: Base
{
name = "Rifleman";
primaryWeapon = "hlc_rifle_STGW57";
primaryWeaponItems[] = {"hlc_24Rnd_75x55_ap_stgw"};
magazines[] = {
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_T_stgw",
"hlc_24Rnd_75x55_T_stgw",
"rhssaf_mag_br_m84",
"rhssaf_mag_br_m84",
"rhssaf_mag_brd_m83_white"
};
backpack = "UK3CB_B_Alice_Bedroll_2_K";
backpackMagazines[] = {
"rhsgref_296Rnd_792x57_SmK_belt",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_ap_stgw",
"hlc_24Rnd_75x55_T_stgw",
"hlc_24Rnd_75x55_T_stgw",
"rhssaf_mag_br_m84",
"rhssaf_mag_br_m84",
"rhssaf_mag_brd_m83_white"
};
backpackItems[] = {
"ACE_fieldDressing",
"ACE_fieldDressing",
"ACE_morphine"
};
};
class RiflemanLAT: Rifleman
{
name = "LAT";
launcher = "rhs_weap_m72_ASM";
};
As part of r36 a new system of applying loadouts to BSO Faction AI units has been implemented. Each unit in CfgVehicles will require a corresponding loadout. These will usually be added in a corresponding loadout file to avoid clutter in the main config. Below is an example of how this file is included in the config.cpp of the addon, so that it is part of the config files ready for use with the loadout system.
class CfgBsoLoadouts {
#include "scripts\bso_tno_ins.cpp"
};
To apply these loadouts, we need to ensure the base class used for the infantry units we wish to apply loadouts too, has an Extended Init to apply the loadout based on what is defined in their config. Below is an example of what is included in the config.cpp so that the base class calls the applyLoadout function, using the entries in its cfgVehicles entry.
class Extended_Init_EventHandlers {
class O_bso_tno_ins_BASE {
init = "[(_this select 0),(getText (configFile >> ""cfgVehicles"" >> (typeOf (_this select 0)) >> ""bsoLoadout_faction"")),(getText (configFile >> ""cfgVehicles"" >> (typeOf (_this select 0)) >> ""bsoLoadout_loadout""))] call BSO_fnc_applyLoadout";
};
};
Finally, we can now populate the classes for that unit to apply the correct faction and loadout. bsoLoadout_faction = "bso_tno_ins"; bsoLoadout_loadout = "base";
For the base unit, it's not essential which loadout is applied. Now, for all follow up units inheriting from the base unit, we can just define the corresponding loadout. bsoLoadout_loadout = "Rifleman";
How to randomly define uniforms By using the ``uniform[]`` array, we can define several uniforms. BSO Loadouts will then randomly select between these uniforms.
uniform[] = {"U_I_E_Uniform_01_F","U_I_E_Uniform_01_tanktop_F","U_I_E_Uniform_01_sweater_F","U_I_E_Uniform_01_shortsleeve_F"};