{"name":"Arma 3: Vehicle Customisation","title":"Arma 3: Vehicle Customisation","type":"topic","url":"https://community.bistudio.com/wiki/Arma_3:_Vehicle_Customisation","revid":363627,"updated":"2024-04-08T16:20:15Z","aliases":["Arma 3 Vehicle Customization","Arma 3: Vehicle Customization","Vehicle Customization (VhC)"],"markdown":"Arma 3 v1.42\nThe **V**e**h**icle **C**ustomisation (VhC) is the system responsible for the customisation of vehicles, either, defined or randomised.\nIt consists of a set of config properties and classes and a set of functions.\nIt has been introduced in Arma 3 v1.42 in order to replace the old system which consisted in a set of scripts.\n\n### Usage\n\nRead BIS_fnc_initVehicle to find out how it works. Use BIS_fnc_saveVehicle to save a vehicle customisation and BIS_fnc_loadVehicle to load a previously saved appearance.\n\n### Implementation\n\n#### Missions\n\nThe system offers a simple way to define your own deliveries and to prevent randomisation of a given vehicle, its class or even its kind. Here an example of mission configuration file.\n\n##### Prevent randomisation\n\n```cpp\n// No action will be taken regarding the following vehicles (either, names, classes or kind)\ndisableRandomization[] =\n{\n    // \"AllVehicles\",        // No randomisation at all\n    // \"Air\",                // No randomisation at all for air vehicles\n    // \"land\",                // No randomisation at all for land vehicles\n    // \"Ship\",                // No randomisation at all for sea vehicles\n    \"air_f\",                // There won't be any randomisation on every air vehicles\n    \"C_Hatchback_01_F\",        // No random on Hatchbacks\n    \"truck_withoutRandom\"    // No random for this given vehicle\n};\n```\n\n##### Add your own liveries\n\nTo do so, a new mission config file has been introduced - CfgVehicleTemplates. It regroups every variants used from the main function (BIS_fnc_initVehicle)\n\n```cpp\nclass CfgVehicleTemplates\n{\n```\n\nThis variant has a *textureList* property, a list of texture sources directly defined from an addon, at the config level.\nIf there is more than 1 entry in the texture list, a weighted random will be performed between them.\nHaving one entry means this entry will be picked up on every call of the function.\n\n```cpp\nclass BIS_Offroad_01_default\n{\n    vehicles[] =  // It is used by the [[:Category:Eden Editor|Eden Editor]] to determine which vehicle classes can be supposed with use this template\n    {\n        \"classNameA\",\n        \"classNameB\"\n    };\n\n    displayName = \"Default\";        // <optional> Could be handy if you plan to add some UI, not used by the VhC\n    author = \"Bohemia Interactive\";    // <optional> Could be handy if you plan to add some UI, not used by the VhC\n    factions[] =                    // This template will be available for the following factions\n    {\n        \"BLU_F\", \"BLU_G_F\",    // Side Blufor\n        \"OPF_F\", \"OPF_G_F\",    // Side Opfor\n        \"IND_F\", \"IND_G_F\",    // Side independent\n        \"CIV_F\"                // Side civilian\n    };\n\n    // List of texture sources defined in ConfigFile >> \"CfgVehicles\" >> \"VehicleClass\" >> \"TextureSources\"\n    // Only on source will be chosen within the following by a weighted random\n    textureList[] =\n    {\n        \"guerilla_01\", 1,\n        \"guerilla_02\", 1,\n        \"guerilla_03\", 1,\n        \"guerilla_04\", 1\n    };\n\n    // Animation sources\n    animationList[] =\n    {\n        \"HideBumper1\", 1,    // Class of an animation source, probabily (wherein 1 means 100% to set the phase to 1)\n        \"HideBumper2\", 1,\n        \"HideConstruction\", 1,\n        \"HideDoor1\", 0,        // The phase of the animation source will always be set to 1\n        \"HideDoor2\", 0,\n        \"HideGlass2\", 0,\n        \"HideBackpacks\", 1,\n        \"HideDoor3\", 0.33     // There is a 33% chance that this animation source phease is set to 1\n    };\n};\n```\n\nThe following has textures[] instead of textureList[], meaning the function will define these texture files and won't search for texture sources.\n\n```cpp\nclass BIS_Offroad_01_stripped\n{\n    displayName = \"Stripped\";\n    author = \"Bohemia Interactive\";\n    textures[] =\n    {\n        \"\\A3\\Soft_F\\Offroad_01\\Data\\Offroad_02_ext_CO.paa\", //Must with extension!\n        \"\\A3\\Soft_F\\Offroad_01\\Data\\Offroad_02_ext_CO.paa\"\n    };\n\n    materials[] =\n    {\n        \"\", // Material to use for the first texture (ignore if the string is empty)\n        \"\\A3\\Structures_F\\Data\\Windows\\window_set.rvmat\" // Material to use for the second texture\n    };\n\n    animationList[] =\n    {\n        \"HideBumper1\", 1,\n        \"HideBumper2\", 1,\n        \"HideConstruction\", 1,\n        \"HideDoor1\", 1,\n        \"HideDoor2\", 1,\n        \"HideGlass2\", 1,\n        \"HideBackpacks\", 1,\n        \"HideDoor3\", 0.33\n    };\n};\n```\n\nThe following class interstates from \"BIS_Offroad_01_default\" which has a textureList, meaning this class contains textureList and textures.\nIn this case, the textures property will be used and textureList will be ignored.\n\n```cpp\nclass hotpink : BIS_Offroad_01_default\n{\n    displayName = \"hotpink (ugly test)\";\n    author = \"Tom_48_97\";\n    textures[] = { \"#(rgb,8,8,3)color(1,0.411,0.705,1)\" };\n};\n```\n\n... and the `CfgVehicleTemplates` closure bracket\n\n```cpp\n};\n```\n\n#### Addon\n\nIn the best case of use, the below classes and information should be defined in the base config class of the vehicle, but obviously, this is not always possible.\n\n##### Base class\n\n```cpp\nclass Dummy_vehicle_base_F : Helicopter_Base_H\n{\n    scope = 0; // A base class should has scope = 0 (private)\n    model = \"\\A3\\Dummy\\Dummy_vehicle\\dummy.p3d\";\n\n    class EventHandlers : EventHandlers\n    {\n        // (_this select 0): the vehicle\n        // \"\"\"\" Random texture source (pick one from the property textureList[])\n        // []: randomise the animation sources (accordingly to the animationList[] property)\n        // false: Don't change the mass even if an animation source has a defined mass\n        postInit = \"if (local (_this select 0)) then { [(_this select 0), \"\"\"\", [], false] call BIS_fnc_initVehicle; };\";\n    };\n\n    /*---------------------------------------------------------------------------\n        Animation sources\n    ---------------------------------------------------------------------------*/\n    class animationSources : animationSources\n    {\n        class animationSource1\n        {\n            // name of the animation / element (displayed in the Virtual Garage)\n            displayName = \"Add source...\";\n            // Author of the textures (displayed in the Virtual Garage)\n            author = \"$STR_A3_Bohemia_Interactive\";\n            source = \"user\";\n            animPeriod = 0.000001;\n            initPhase = 0;\n\n            // if the animation phase is 0, then the given cargo indexes (lockCargo) will be locked\n            // if undefined, default value of lockCargoAnimationPhase is 0\n            lockCargoAnimationPhase = 0;\n            lockCargo[] = { 0, 1, 5 };\n\n            // if forceAnimatePhase is equal to the phase of this animation sources, every sources from forceAnimate will be changed with their given phase\n            forceAnimatePhase = 0;\n            // animationSource1, phase, animationSource2, phase... No probabilities here, only true or false\n            forceAnimate[] = { \"animationSource1\", 0, \"animationSource2\", 1 };\n\n            // The following code is called by BIS_fnc_initVehicle each time the phase is changed\n            onPhaseChanged = \"if ((_this select 1) == 1) then { /* run if the phase is 1 */ } else { /* run if the phase is 0 */ };\";\n\n            // Mass of the source, can be negative or positive\n            // If the phase is 1, the given mass will be added, otherwise, it will be subtracted\n            mass = 20;\n        };\n\n        class animationSource2 : animationSource1 {};\n        class animationSource3 : animationSource1 {};\n        class animationSource4 : animationSource1 {};\n    };\n\n    /*---------------------------------------------------------------------------\n        Texture sources\n    ---------------------------------------------------------------------------*/\n    class textureSources\n    {\n        // This texture source will be available for every defined factions\n        class white\n        {\n            // Display name of the texture\n            displayName = \"White\";\n            // Author of the texture\n            author = \"$STR_A3_Bohemia_Interactive\";\n            // Paths to the texture files, in the same order as the hidden selections\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            // This source should be available for the following factions\n            factions[] =\n            {\n                \"BLU_F\", \"BLU_G_F\",    // Side Blufor\n                \"OPF_F\", \"OPF_G_F\",    // Side Opfor\n                \"IND_F\", \"IND_G_F\",    // Side independent\n                \"CIV_F\"                // Side civilian\n            };\n        };\n\n        // This texture source will be available for every factions (currents and futures)\n        class black\n        {\n            displayName = \"Black\";\n            author = \"$STR_A3_Bohemia_Interactive\";\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            factions[] = {};\n        };\n\n        // This texture source will be available only for the FIA (whatever its side)\n        class yellow\n        {\n            displayName = \"Yellow\";\n            author = \"$STR_A3_Bohemia_Interactive\";\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            factions[] =\n            {\n                \"BLU_G_F\",\n                \"OPF_G_F\",\n                \"IND_G_F\"\n            };\n        };\n\n        // This texture source will be available only for the BLU_F faction\n        class red\n        {\n            displayName = \"Red\";\n            author = \"$STR_A3_Bohemia_Interactive\";\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            factions[] =\n            {\n                \"BLU_F\"\n            };\n        };\n    };\n};\n```\n\n##### Variants / derivatives\n\n```cpp\nclass B_dummy_vehicle_F : Dummy_vehicle_1_base_F\n{\n    displayName = \"I'm nothing\";\n    author = \"$STR_A3_Bohemia_Interactive\";\n\n    scope = 2;\n    scopeCurator = 2;\n\n    side = 1;\n    faction = BLU_F;\n\n    textureList[] =\n    {\n        \"White\", 1,\n        \"Black\", 0.5,\n        \"Red\", 0.5,\n        \"Yellow\", 0.5\n    };\n\n    /* Random animations, also used to determine the allowed animation sources\n    1 means 100% - This state of the given source WILL BE set to 1, 0 means the opposite\n    [_animationSource1, probability1, _animationSource2, probability2, ...] */\n    animationList[] =\n    {\n        \"animationSource1\", 0.5,\n        \"animationSource2\", 0.5,\n        \"animationSource3\", 0.5,\n        \"animationSource4\", 0.5\n    };\n};\n\n/*---------------------------------------------------------------------------\n    Dummy vehicle used by the initVehicle function, for pre defined variants\n---------------------------------------------------------------------------*/\nclass B_dummy_vehicle_red_F : B_dummy_vehicle_F\n{\n    CFGVEHICLES_VARIANT_DISPLAYNAME(\"B_dummy_vehicle_F\", \"Red\")\n    CFGVEHICLES_VARIANT_DUMMY\n    textureList[] = { \"Red\", 1 };\n    animationList[] =\n    {\n        \"animationSource2\", 1,\n        \"animationSource3\", 1,\n        \"animationSource4\", 0.3\n    };\n};\n```","sections":[{"heading":null,"level":1,"markdown":"Arma 3 v1.42\nThe **V**e**h**icle **C**ustomisation (VhC) is the system responsible for the customisation of vehicles, either, defined or randomised.\nIt consists of a set of config properties and classes and a set of functions.\nIt has been introduced in Arma 3 v1.42 in order to replace the old system which consisted in a set of scripts."},{"heading":"Usage","level":3,"markdown":"Read BIS_fnc_initVehicle to find out how it works. Use BIS_fnc_saveVehicle to save a vehicle customisation and BIS_fnc_loadVehicle to load a previously saved appearance."},{"heading":"Implementation","level":3,"markdown":""},{"heading":"Missions","level":4,"markdown":"The system offers a simple way to define your own deliveries and to prevent randomisation of a given vehicle, its class or even its kind. Here an example of mission configuration file."},{"heading":"Prevent randomisation","level":5,"markdown":"```cpp\n// No action will be taken regarding the following vehicles (either, names, classes or kind)\ndisableRandomization[] =\n{\n    // \"AllVehicles\",        // No randomisation at all\n    // \"Air\",                // No randomisation at all for air vehicles\n    // \"land\",                // No randomisation at all for land vehicles\n    // \"Ship\",                // No randomisation at all for sea vehicles\n    \"air_f\",                // There won't be any randomisation on every air vehicles\n    \"C_Hatchback_01_F\",        // No random on Hatchbacks\n    \"truck_withoutRandom\"    // No random for this given vehicle\n};\n```"},{"heading":"Add your own liveries","level":5,"markdown":"To do so, a new mission config file has been introduced - CfgVehicleTemplates. It regroups every variants used from the main function (BIS_fnc_initVehicle)\n\n```cpp\nclass CfgVehicleTemplates\n{\n```\n\nThis variant has a *textureList* property, a list of texture sources directly defined from an addon, at the config level.\nIf there is more than 1 entry in the texture list, a weighted random will be performed between them.\nHaving one entry means this entry will be picked up on every call of the function.\n\n```cpp\nclass BIS_Offroad_01_default\n{\n    vehicles[] =  // It is used by the [[:Category:Eden Editor|Eden Editor]] to determine which vehicle classes can be supposed with use this template\n    {\n        \"classNameA\",\n        \"classNameB\"\n    };\n\n    displayName = \"Default\";        // <optional> Could be handy if you plan to add some UI, not used by the VhC\n    author = \"Bohemia Interactive\";    // <optional> Could be handy if you plan to add some UI, not used by the VhC\n    factions[] =                    // This template will be available for the following factions\n    {\n        \"BLU_F\", \"BLU_G_F\",    // Side Blufor\n        \"OPF_F\", \"OPF_G_F\",    // Side Opfor\n        \"IND_F\", \"IND_G_F\",    // Side independent\n        \"CIV_F\"                // Side civilian\n    };\n\n    // List of texture sources defined in ConfigFile >> \"CfgVehicles\" >> \"VehicleClass\" >> \"TextureSources\"\n    // Only on source will be chosen within the following by a weighted random\n    textureList[] =\n    {\n        \"guerilla_01\", 1,\n        \"guerilla_02\", 1,\n        \"guerilla_03\", 1,\n        \"guerilla_04\", 1\n    };\n\n    // Animation sources\n    animationList[] =\n    {\n        \"HideBumper1\", 1,    // Class of an animation source, probabily (wherein 1 means 100% to set the phase to 1)\n        \"HideBumper2\", 1,\n        \"HideConstruction\", 1,\n        \"HideDoor1\", 0,        // The phase of the animation source will always be set to 1\n        \"HideDoor2\", 0,\n        \"HideGlass2\", 0,\n        \"HideBackpacks\", 1,\n        \"HideDoor3\", 0.33     // There is a 33% chance that this animation source phease is set to 1\n    };\n};\n```\n\nThe following has textures[] instead of textureList[], meaning the function will define these texture files and won't search for texture sources.\n\n```cpp\nclass BIS_Offroad_01_stripped\n{\n    displayName = \"Stripped\";\n    author = \"Bohemia Interactive\";\n    textures[] =\n    {\n        \"\\A3\\Soft_F\\Offroad_01\\Data\\Offroad_02_ext_CO.paa\", //Must with extension!\n        \"\\A3\\Soft_F\\Offroad_01\\Data\\Offroad_02_ext_CO.paa\"\n    };\n\n    materials[] =\n    {\n        \"\", // Material to use for the first texture (ignore if the string is empty)\n        \"\\A3\\Structures_F\\Data\\Windows\\window_set.rvmat\" // Material to use for the second texture\n    };\n\n    animationList[] =\n    {\n        \"HideBumper1\", 1,\n        \"HideBumper2\", 1,\n        \"HideConstruction\", 1,\n        \"HideDoor1\", 1,\n        \"HideDoor2\", 1,\n        \"HideGlass2\", 1,\n        \"HideBackpacks\", 1,\n        \"HideDoor3\", 0.33\n    };\n};\n```\n\nThe following class interstates from \"BIS_Offroad_01_default\" which has a textureList, meaning this class contains textureList and textures.\nIn this case, the textures property will be used and textureList will be ignored.\n\n```cpp\nclass hotpink : BIS_Offroad_01_default\n{\n    displayName = \"hotpink (ugly test)\";\n    author = \"Tom_48_97\";\n    textures[] = { \"#(rgb,8,8,3)color(1,0.411,0.705,1)\" };\n};\n```\n\n... and the `CfgVehicleTemplates` closure bracket\n\n```cpp\n};\n```"},{"heading":"Addon","level":4,"markdown":"In the best case of use, the below classes and information should be defined in the base config class of the vehicle, but obviously, this is not always possible."},{"heading":"Base class","level":5,"markdown":"```cpp\nclass Dummy_vehicle_base_F : Helicopter_Base_H\n{\n    scope = 0; // A base class should has scope = 0 (private)\n    model = \"\\A3\\Dummy\\Dummy_vehicle\\dummy.p3d\";\n\n    class EventHandlers : EventHandlers\n    {\n        // (_this select 0): the vehicle\n        // \"\"\"\" Random texture source (pick one from the property textureList[])\n        // []: randomise the animation sources (accordingly to the animationList[] property)\n        // false: Don't change the mass even if an animation source has a defined mass\n        postInit = \"if (local (_this select 0)) then { [(_this select 0), \"\"\"\", [], false] call BIS_fnc_initVehicle; };\";\n    };\n\n    /*---------------------------------------------------------------------------\n        Animation sources\n    ---------------------------------------------------------------------------*/\n    class animationSources : animationSources\n    {\n        class animationSource1\n        {\n            // name of the animation / element (displayed in the Virtual Garage)\n            displayName = \"Add source...\";\n            // Author of the textures (displayed in the Virtual Garage)\n            author = \"$STR_A3_Bohemia_Interactive\";\n            source = \"user\";\n            animPeriod = 0.000001;\n            initPhase = 0;\n\n            // if the animation phase is 0, then the given cargo indexes (lockCargo) will be locked\n            // if undefined, default value of lockCargoAnimationPhase is 0\n            lockCargoAnimationPhase = 0;\n            lockCargo[] = { 0, 1, 5 };\n\n            // if forceAnimatePhase is equal to the phase of this animation sources, every sources from forceAnimate will be changed with their given phase\n            forceAnimatePhase = 0;\n            // animationSource1, phase, animationSource2, phase... No probabilities here, only true or false\n            forceAnimate[] = { \"animationSource1\", 0, \"animationSource2\", 1 };\n\n            // The following code is called by BIS_fnc_initVehicle each time the phase is changed\n            onPhaseChanged = \"if ((_this select 1) == 1) then { /* run if the phase is 1 */ } else { /* run if the phase is 0 */ };\";\n\n            // Mass of the source, can be negative or positive\n            // If the phase is 1, the given mass will be added, otherwise, it will be subtracted\n            mass = 20;\n        };\n\n        class animationSource2 : animationSource1 {};\n        class animationSource3 : animationSource1 {};\n        class animationSource4 : animationSource1 {};\n    };\n\n    /*---------------------------------------------------------------------------\n        Texture sources\n    ---------------------------------------------------------------------------*/\n    class textureSources\n    {\n        // This texture source will be available for every defined factions\n        class white\n        {\n            // Display name of the texture\n            displayName = \"White\";\n            // Author of the texture\n            author = \"$STR_A3_Bohemia_Interactive\";\n            // Paths to the texture files, in the same order as the hidden selections\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            // This source should be available for the following factions\n            factions[] =\n            {\n                \"BLU_F\", \"BLU_G_F\",    // Side Blufor\n                \"OPF_F\", \"OPF_G_F\",    // Side Opfor\n                \"IND_F\", \"IND_G_F\",    // Side independent\n                \"CIV_F\"                // Side civilian\n            };\n        };\n\n        // This texture source will be available for every factions (currents and futures)\n        class black\n        {\n            displayName = \"Black\";\n            author = \"$STR_A3_Bohemia_Interactive\";\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            factions[] = {};\n        };\n\n        // This texture source will be available only for the FIA (whatever its side)\n        class yellow\n        {\n            displayName = \"Yellow\";\n            author = \"$STR_A3_Bohemia_Interactive\";\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            factions[] =\n            {\n                \"BLU_G_F\",\n                \"OPF_G_F\",\n                \"IND_G_F\"\n            };\n        };\n\n        // This texture source will be available only for the BLU_F faction\n        class red\n        {\n            displayName = \"Red\";\n            author = \"$STR_A3_Bohemia_Interactive\";\n            textures[] = { \"\\A3\\Dummy\\Dummy_vehicle\\dummy_vehicle_ext_1_co.paa\" };\n            factions[] =\n            {\n                \"BLU_F\"\n            };\n        };\n    };\n};\n```"},{"heading":"Variants / derivatives","level":5,"markdown":"```cpp\nclass B_dummy_vehicle_F : Dummy_vehicle_1_base_F\n{\n    displayName = \"I'm nothing\";\n    author = \"$STR_A3_Bohemia_Interactive\";\n\n    scope = 2;\n    scopeCurator = 2;\n\n    side = 1;\n    faction = BLU_F;\n\n    textureList[] =\n    {\n        \"White\", 1,\n        \"Black\", 0.5,\n        \"Red\", 0.5,\n        \"Yellow\", 0.5\n    };\n\n    /* Random animations, also used to determine the allowed animation sources\n    1 means 100% - This state of the given source WILL BE set to 1, 0 means the opposite\n    [_animationSource1, probability1, _animationSource2, probability2, ...] */\n    animationList[] =\n    {\n        \"animationSource1\", 0.5,\n        \"animationSource2\", 0.5,\n        \"animationSource3\", 0.5,\n        \"animationSource4\", 0.5\n    };\n};\n\n/*---------------------------------------------------------------------------\n    Dummy vehicle used by the initVehicle function, for pre defined variants\n---------------------------------------------------------------------------*/\nclass B_dummy_vehicle_red_F : B_dummy_vehicle_F\n{\n    CFGVEHICLES_VARIANT_DISPLAYNAME(\"B_dummy_vehicle_F\", \"Red\")\n    CFGVEHICLES_VARIANT_DUMMY\n    textureList[] = { \"Red\", 1 };\n    animationList[] =\n    {\n        \"animationSource2\", 1,\n        \"animationSource3\", 1,\n        \"animationSource4\", 0.3\n    };\n};\n```"}],"categories":["Arma 3: Vehicle Configuration","Introduced with Arma 3 version 1.42"],"groups":["Configuration"]}