Config.cpp File Tutorial Final

by snYpir

Main Menu

 


*insert usual disclaimer here - screw your copy of OFP don't come crying to us*

References

  • Refer to this listing of all available config.cpp file commands.

  • Appendix A of the Unofficial Command Reference Manual contains an object class tree that will be of great help to addons makers. Click here to open the class tree up in a new window. Appendix B will also be useful when adding new weapons or ammunition.

  • If you want to know how to change model textures see this tutorial (advanced!).

  • The primary source of further information is our forum. Please use it to ask questions about the addon making process.

    Foreword

    The knowledge on how to make new addons started to surface around the time BIS put out the first new weapon and vehicle packs for the game. Kegetys, a-Lone-Wolf and ArmourDave made the first couple of new addons (when I say new I actually mean modified versions of existing weapons).

    Kegetys also changed the first texture on a weapon with his M16 Shotgun addon, which at the time seemed like black magic but is now common knowledge ;) Also early on, Gunslinger created his object addon, revealing how to add almost any new object to the game.

    After pulling apart a few of these unofficial addons and having a bit of a play around, I realised that it all wasn't that hard. Hence, I decided to write this tutorial to get the knowledge out there.

    This tutorial will not teach you how to make addons. It will merely show you the way. Creating an addon is not like designing a mission; it is not easy. Use this tutorial to get an understanding of how addons work, and then experiment. Start small (make some minor modifications) and then work up to making completely revamped weapons, units and vehicles.

    The
    examples section is very important if you are just starting out with addons. Here you will find copies of config.cpp files for other addons, that you can use to work out the various attributes of classes that you modify in order to make new addons.

    In August 2001, a-Lone-Wolf made some amazing discoveries that led to the extraction of every class for every unit in the game. I added these to the
    examples section of the page. Use these class defs to work out how every object in the game works.

    Ok, enough from me ;) This tutorial is big enough as it is. Good luck, and have fun!

    Introduction: What is config.cpp?

    If you are reading this tutorial I would hope that you already know about addons for OFP. They go in the 'addons' folder, and there are already a bunch of offical (Apache, Hummer etc) and unofficial (Javelin, Editor addon etc.) addons available.

    Now before you go any further with this tutorial please take the time to De-PBO some addons to get a feel for the file structure. The files in the offical addons are by default unencrypted. It is a very simple structure. The config.cpp file is the 'brain' of an addon, and all the other files are simply used for textures, sounds and in the case of official addons model data.

    Now every addon (Chinook, Apache, Vulcan etc.) uses a config.cpp file to tell Operation Flashpoint about itself. Every different type of unit in the game has it's own 'class'. If you want to add a new vehicle or weapon to the game, you have to define new classes in a config.cpp file. There can be only one config.cpp file per addon.

    Of course, at this stage we cannot import models into the game, but we sure as hell can make completely new weapons and vehicles based on the ones that are already in existance. This is done by creating a new class (based on an existing class) and modifying various attributes.

    This tutorial will not teach you 200 commands or turn you into Gunslinger overnight. It will, however, introduce you to the different parts of the config.cpp file and how you can use it to create new weapons and vehicles.

    The structure of this tutorial is not uniform.

    Before we do anything I will explain the structure of the config.cpp file. I suggest for this section you have open a config.cpp file in a text editor. Or click
    here to open an example config.cpp file in a new window. It is the config file for a civy vehicle.

    Following the introduction to the config.cpp file, I will describe how to make a weapon addon. The references for this are the 'Weapon addons' cpp file examples avaiable at the
    bottom of the page. This includes a discussion of the CfgRecoils class that you can use to set the recoil of weapons in the game.

    Secondly, Gunslinger's editor addon will be discussed and I will show how to make a very simple addon based on information contained with Gunslinger's config.cpp file.

    I will then describe how to make a vehicle addon. This will be by far the most advanced part of the tutorial. It is probaly not worth trying to make a vehicle addon until you are comfortable adding weapons and objects.

    Then there is a bunch of useful information; adding new groups and markers, how to install your addon and some hints and tips. The final part of the tutorial is where you can download example config.cpp files, in the 'examples' section. Good luck!
    If you make a worthwhile addon please submit it to the addons depot.

    Index

  • Defines
  • CfgPatches
  • Class specification
  • Adding a new class
  • Making a weapon addon
  • Using the CfgRecoils class (by Kegetys)
  • Making an object addon
  • Making a vehicle addon
  • Adding new groups
  • Adding new markers (and using TexView)
  • Installing your addon
  • Hints and tips
  • Examples

    Defines

    By now I expect you have a config.cpp file open in a text editor. Take a look at the overall structure, and firstly you will see a list of defines.

    Defines are always the first thing in the config.cpp file. You don't need them, but it is a very good idea to use them rather than trying to remember numbers for various attribute values.

    Defines are like 'constants' in a programming language, once you 'define' something you can use it throughout the cpp file instead of having to input the value every time. I assume that you can just copy and paste the defines listed below into your cpp file, depending on what type of weapon addon you are making.

    Defines common to ALL addons:

    // some basic defines
    #define TEast 0
    #define TWest 1
    #define TGuerrila 2
    #define TCivilian 3
    #define TSideUnknown 4
    #define TEnemy 5
    #define TFriendly 6
    #define TLogic 7

    #define true 1
    #define false 0

    // type scope
    #define private 0
    #define protected 1
    #define public 2

    Defines specifically for weapon addons:

    #define WeaponNoSlot 0// dummy weapons
    #define WeaponSlotPrimary 1// primary weapons
    #define WeaponSlotSecondary 16// secondary weapons
    #define WeaponSlotItem 256// items
    #define WeaponSlotBinocular 4096// binocular
    #define WeaponHardMounted 65536

    Defines used for the vulcan addon:

    #define CanSeeRadar 1
    #define CanSeeEye 2
    #define CanSeeOptics 4
    #define CanSeeEar 8
    #define CanSeeCompass 16
    #define CanSeeRadarC CanSeeRadar+CanSeeCompass
    #define CanSeeAll 31

    Note: I am sure that there are other defines (or other values that need defines). The above list is probably not comprehensive.

    CfgPatches

    The purpose of this class is two-fold. Firstly, it identifies the addons that this cpp file will add. It also sets the version of OFP required for this addon to work. Every config.cpp file you make requires a CfgPatches class. The syntax is as follows:

    class CfgPatches
    {
         class name of the new class
         {
             units[] = {new unit to be added};
             weapons[] = {new weapon to be added};
             requiredVersion = version of OFP required for this addon to work;
         };
    };

    for example, suppose my addon includes a new weapon called 'Plasmarifle' and a new unit call 'Terminator'. Also the addon requires version 1.20 to run.

    class CfgPatches
    {
         class Terminator
         {
             units[] = {Terminator};
             weapons[] = {};
             requiredVersion = 1.20;
         };
         class Plasmarifle
         {
             units[] = {};
             weapons[] = {Plasmarifle};
             requiredVersion = 1.20;
         };
    };

    Class specification

    Here is where the file will differ depending on if the addon is defining a new vehicle or a new weapon. If you are defining a new weapon, the classes that you will require are:

    CfgAmmo
    CfgWeapons

    If you are defining a new vehicle, the classes that you will need are:

    CfgVehicles
    CfgVehicleActions (not mandatory)
    CfgMovesMC (not mandatory)

    And common to both types you will need:

    CfgNonAIVehicles

    If you are making a custom face addon you will need:

    CfgFaces

    A config.cpp file can include any number or mixture of these classes, for example if you make a new weapon (with CfgAmmo and CfgWeapons) you can also define a new type of soldier to equip with the new weapon using the CfgVehicles class if you wish. Or, if you are making a new type of combat helicopter you may wish to define new weapon and ammunition types prior to the CfgVehicles class. Before I step though how to make new weapons and vehicles I will describe how to add a new class.

    Adding a new class

    Anyone who has done any form of object-oriented programming will find the class creation process very familiar. Any one who has not, well, I'll try to explain it here. The key concept to understand is called inheritance.

    Take a look at the following couple of lines:

    class CfgVehicles
    {
         class All {};
         class AllVehicles: All {};
         class Land: AllVehicles {};
         class LandVehicle: Land {};
         class Car: LandVehicle {};
         class Jeep : Car {};
         class HMMWV: Jeep
         {

    The end result of this section of code is to add a new type of vehicle to OFP. Right down until 'class HMMWV: Jeep' the code is simply defining EXACTLY what attributes the new class 'HMMWV' will be possess.

    Firsty we say that the new unit will inherit the characteristics of 'All'. Clearly every unit in the game will have 'All' as it's base. From there we get more specific. The new unit will inherit the characteristics of 'AllVehicles'. This continues through Land, LandVehicles, Car and finally we specify that the new unit will possess the characteristics of a Jeep. At the end of this process the HMMWV has all the characteristics it requires, and it will behave the way we want it to (ie 'like' a jeep).

    Then for the new vehicle we enter 'attributes'. This is information concerning how the new unit will look and behave in the world.

    class HMMWV: Jeep
    {
         // attributes of the hummer in here
    };

    Be aware that there are no 'mandatory' attributes. Because of the way 'inheritance' works, if we didn't enter any attributes at all we would have defined a unit exactly the same as a Jeep.

    Making a weapon addon

    To make a new weapon all that is needed is two classes: CfgAmmo and CfgWeapons. Again, programmers will find the concept very easy.

    CfgAmmo

    The way that you add a new weapon is to firstly define the characteristics of the ammunition that the weapon will fire (in the CfgAmmo class) and then define the characteristics of the weapon itself, including the new ammunition type (this is done in the CfgWeapons class).

    Lets take a look at how the RPG-29 weapon addon works. Firstly we are going to define the ammunition that the rocket launcher will fire. Examine the following lines:

    class CfgAmmo
    {
         class default {};
         class LAW : Default {};
         class RPG : LAW {};
         class RPG29ammo : RPG
         {
             hit=1520;
             indirectHit=500;
             indirectHitRange=5;
        
             picture="\dtaext\equip\w\w_at4launcher.paa";
         };
    };

    You can see that the ammunition of thr RPG (called RPG29ammo) will inherit the characteristics of 'RPG', which inherits the characteristics of 'LAW' which inherits the characteristics of 'Default' (obviously the default characteristics for all ammunition).

    And then, there are four commands used to define attributes for the new ammunition type. 'hit' and 'indirecthit' define the damage this ammunition type will do depending on how far away it explodes from a unit. 'indirectHitRange' is the range from a unit that the damage will be done at the value of 'hit'. 'picture' defines the the picture of this weapon in the briefing screen(?).

    Now you may be asking yourself: 'How can this ammunition type only have 4 characteristics?'. Remember how I said that this new ammunition type has inherited all the characteristics of it's parent classes? You can bet that there are many more characteristics, but we have only specified the ones that we want to change. All the other characteristics will be exactly the same as for the normal RPG rocket.

    CfgWeapons

    Ok, so we have defined a new class of ammunition called 'RPG29ammo'. Now to make the weapon itself. This is done using the CfgWeapons class. The following lines are all that are required:

    class CfgWeapons
    {
         class default {};
         class LAWLauncher : default {};
         class CarlGustavLauncher : LAWLauncher {};
         class AT4Launcher : CarlGustavLauncher {};
         class RPG29Launcher : AT4Launcher
         {
             model="\rpg29\rpg29.p3d";

             picture="\dtaext\equip\m\m_at4Launcher.paa";
             displayName = RPG29;
             displayNameMagazine = RPG29;
             shortNameMagazine = RPG29;

             ammo = RPG29ammo;
             initspeed=125;
             count = 1;
             maxLeadSpeed=150;
         };
    };

    So firstly we define this class, stating that this weapon will inherit characteristics from AT4Launcher, which inherits from CarlGustavLauncher, which inherits from LAWLauncher that inherits from the default class for all weapons.

    We define the 'model' for this weapon, which in this case is 'rpg29.p3d'. Until we can make new models we will be stuck copying existing models as has been done for this weapon (rpg29.p3d is a copy of the model for a normal rpg). The path specified by the 'model' attribute is relative either to the base directory of OFP (if the model is one that came shipped with OFP) or relative to the addons directory (if the model is contained in a pbo).

    If the model is in the 'data3d' directory of OFP (with all the default models) then the model path would be:

    model=\data3d\model name.p3d

    If our addon was called 'myaddon.pbo' and the model's .p3d file was stuffed into 'myaddon.pbo', we would use:

    model=\myaddon\model name.p3d

    Again, we define the picture of this weapon for the briefing screen. We then define names for the weapon and the magazine for the weapon (these names are how the user will refer to the weapon in the briefing for example, or perhaps using AddWeapon or AddMagazine commands).

    'ammo = RPG29ammo' takes our newly created RPG29ammo class and makes it the ammunition type for this weapon. So when the 'RPG29Launcher. fires it will fire 'RPG29ammo'. 'Initspeed' is the muzzle velocity of the weapon (the speed at which the rocket leaves the barrel) and 'count' is the number of rounds fired (?). 'maxLeadSpeed' is (?).

    And that wraps it up. We have a new weapon! After the CfgWeapons is finished, the following class needs to be added also:

    class CfgNonAIVehicles
    {
         class ProxyWeapon {};
         class ProxyRPG29: ProxyWeapon {};
    };

    This seems to make a new class of type 'ProxyRPG29' that inherits from 'ProxyWeapon'. Why this is needed I am unsure. Make sure you include it for every new weapon that you create though.

    Coming Soon: Step through making a new weapon

    Using the CfgRecoils class (by Kegetys)

    In your weapons class definitions you can specify the recoil to be used by a weapon.

    The pre-defined CfgRecoils class looks as follows:

    class CfgRecoils
    {
         empty[]={};
         impulse[]={0.050000,0.020000,0.200000,0.100000,0.030000,-0.100000,0.300000,0,0};
         riffleSingle[]={0.050000,0.020000,0.040000,0.050000,0,0};
         riffleSilenced[]={0.010000,0.004000,0.010000,0.050000,0,0};
         LAWSingle[]={0.020000,0,0,0.050000,0.080000,0.030000,0.100000,0.030000,0.015000,0.200000,0,0};
         sniperSingle[]={0.020000,0,0,0.050000,0.010000,0.020000,0.100000,0.008000,0.018000,0.200000,0,0};
         riffleBurst3[]={0.050000,0.020000,0.040000,0.050000,0,0};
        mgunBurst3[]={0.050000,0.020000,"0.04*1.35",0.050000,0.010000,"0.01*1.35",0.050000,0.030000,"0.04*1.35",0.050000,0.020000,"0.02*1.35",0.050000,0.040000,"0.04*1.35",0.010000,0,0};
    };

    In your addons you can make new recoils for your weapons!

    The basics is this:

    class CfgRecoils
    {
        MyRecoil[]={1.00,0.5,0.7};
    };

    That creates a new recoild named MyRecoil, that moves the weapon 0.5 units backwards and 0.7 units upwards, and doest that in 1 second. So the first number is how long the movement takes, the second is the amout of kickback and the third is the amout of upwards movement. But, thats not all. You can put many of those in a row, example:

    class CfgRecoils
    {
        shotgun[]={0.02,0,0.01,0.05,0.05,0.15,0.4,0,0};
    };

    That does a recoil that first does a 0.02 second movement that moves the gun 0.01 units up (very little). Then it does a 0.05 second movement that does a small kickback (0.05 units) and a nice 0.15 units kick upwards. Then, in 0.4 seconds it moves everything back to the normal pos (0,0). That last 0,0 transform is necessary to make it look good.

    Then, to use this recoil, put these to the CfgWeapons class:

    recoil=shotgun;
    recoilFixed=shotgun;

    The 'recoil' is apparently the recoil used when standing/walkin/running and fixed is for when you are lying on the ground.

    Sorry if this is a kind of messy explanation, hope you'll get it.

    Btw. try using some huge numbers on those recoils... you'll get nicely twisted soldiers :PP

    Making an object addon

    I have essentially devoted this entire section to Gunslinger's Editor Addon, because it is a perfect example of how to add virtually any object you want to the game, as well as show you how to import things such as new icons for the editor.

    Gunslinger's addon is aptley named, in that it is really just an 'editor addon'. It basically just takes a whole bunch of objects that are already in the game and makes them visible in the editor. In the process the author has done a number of cluey things to make a number of explosives etc such as shells and mines.

    Take a look at the config.cpp file for Gunslinger's addon now. Get it here. Ignore the scary stuff at the top of the file, you will not activate FADE by playing around with weapon, object and vehicle addons.

    Structure of Gunslinger's Addon

    By now I would hope that the structure is fairly familiar to you. Firstly there are the standard defines, followed by the CfgPatches class that instructs OFP to refer to this addon as 'EditorUpdate102' and specifies that version 1.07 is required to run this addon.

    Then the body of this config.cpp file starts, wrapped by the cfgVehicles class. Now it is important to note that everything in the world is a 'vehicle'. So unless you are adding weapons or ammunition you will be adding a type of 'vehicle' (yes even a solder is a vehicle and would be wrapped by a cfgVehicles class).

    For the first 100 lines or so the author is inputting all the classes that new objects added by this addon will inherit from. Everything originally inherits from class All {}. What we can see is a good representaion of the class structure for all objects in the game.

    All is the top level class. This is broken down into two subclasses:

    AllVehicles, Things

    AllVehicles can be Air, Land or Ship. Things in the editor addon can be BarrelHelper or ThingEffect.

    And then it breaks down further. For example, Land has subclasses of Man, LandVehicle and Static. And so on and so forth. I am sure Gunslinger's addon does not contain a comprehensive listing, but it can be used as a good guide as to the class heirarchy for objects that you might want to modify in an addon.

    And then the new object specification begins. I have expanded the first two new classes to make it a bit easier to understand. The author is essentially creating a new class for each new object, using existing models and making them visible to the editor through the line 'scope=public;'.

    Adding an object

    Each object is added in the same way as is done for all new vehicles.

    class name: parent class
    {
         attributes
    };

    If you look at the two examples I expanded, classes AAA77Z and AAA805 (explosive sabot round and the floating water mine) you can see the sort of attributes you need to set. Here are some of the attributes for the shell:

    scope=public;

    makes the object visible to all. Is this needed?

    setfuel=0; fuelCapacity=0;

    remove all fuel from the object (remember this object is a subclass of a helicopter).

    hideUnitInfo=1; - ?

    cost=0; - ?

    vehicleClass="Ammo";

    this sets the item that this object will appear under in the editor (ie. 'Support' or 'Ammo' or 'Object').

    displayName="Explosive SabotShell";

    the text displayed in the editor for this object

    destrType=destructengine;

    defines how this object will die. 'destructengine' I assume is an explosion. Other types include 'destructno' (no explosion), 'destructtree' and 'destructtent'.

    This shell is a subclass of a helicopter, not because we want to fly but because we want it to drop, and explode when it hits the ground (as a helicopter does). This is why fuel is set to zero and the damage is set almost to 1 (a slight impact will explode the shell).

    If you have a look at the exploding water mine, you can see how the author has made the mine float by making it's parent class 'BigShip', and setting the attribute 'canFloat' to 1. Again, damage is high and when damage = 1 it will explode.

    Adding a new icon for the editor

    I don't know why I even added this section, it should be bloody obvious from looking at the above examples. The attribute that is set to give an object a custom icon in the editor is:

    icon=path to icon image;

    Gunslinger used a subfolder named 'icons' in his addon to store a whole heap of .jpg images that were used as icons. These icons I assume were in the usual .paa format that OFP seems to require. See a seperate tutorial on converting images to the required format.

    So, for the floating water mine the following line was all the author required to add a custom icon:

    icon=\EditorUpgrade102\icons\mine.jpg;

    Let's make our own object addon!

    Suppose you don't want to use Gunslinger's addon at all, but your new mission really requires streetlamps. You need them bad. So you decide to make a new addon that contains one new object - and this object will be called the 'snYpir streetlamp'. You are going to pinch Gunslinger's image to use as the icon for your streetlamp (giving credit to Gunslinger of course).

    1. Make a new folder anywhere on your computer. Name that folder whatever you want. We will call it 'folder'.

    2. Inside 'folder' right click and make a new text file. Rename that text file to 'config.cpp'.

    3. Copy the icon that will be used in the editor from Gunslingers addon (that you have de-pbo'ed) into 'folder'. The image is called 'lightpole.jpg'.

    4. Open up the config.cpp file in a text editor.

    5. The first thing we are going to put in the cpp file is a header. Just saying some things about who the author is and giving credit to Gunslinger for the icon. We will need to use the double backslash because this will be a 'comment' in our file and we don't want OFP to see it. eg:

    // streetlamp addon by snYpir
    // cheers to Gunslinger for the icon

    6. Now we are going to enter in our defines. This is not really mandatory, but you never know when you might need to use one of these 'constants' in the file. So into the file we put:

    #define TEast 0
    #define TWest 1
    #define TGuerrila 2
    #define TCivilian 3
    #define TSideUnknown 4
    #define TEnemy 5
    #define TFriendly 6
    #define TLogic 7

    #define true 1
    #define false 0

    // type scope
    #define private 0
    #define protected 1
    #define public 2

    7. The next class we need (as for all addons) is the CfgPatches class. This new class we are making will be called 'snYpir_streetlamp'. We'll say that the user needs version 1.10 to use this addon.

    class CfgPatches
    {
         class snYpir_streetlamp
         {
             units[] = {snYpir_streetlamp};
             weapons[] = {};
             requiredVersion = 1.10;
         };
    };

    8. Ok now for the last and most important class. We are now going to define our cfgVehicles class, which will be the container holding our new object addon.

    class CfgVehicles
    {

    9. Now it's time to work out what the parent classes for our streetlamp will be. This is so the streetlamp will behave like a streetlamp, and not like a helicopter or a jeep ;). To do this I am going to look inside Gunslinger's file, and trace his streetlamp addon right back up to class All {}. By the end of this process I have identified the following class heirarchy (that I have entered into the config.cpp file):

         class All {};
         class AllVehicles: All {};
         class Land: AllVehicles {};
         class Static : Land {};
         class Building : Static {};
         class NonStrategic : Building {};
         class Fence : NonStrategic {};
         class WireFence: Fence {};

    10. Now to finally define our class. To keep it simple I will copy Gunslinger's streetlamp, but you could change some of the attributes if you want. Notice I have provided a final set of '};' to close off the cfgVehicles class (this will be the first and last object we are adding).

         class snYpir_streetlamp: WireFence
         {
             // public scope
             scope=public;
            
             // will appear under the support menu
             vehicleClass="Support";
            
             // it is a civilian object
             side=TCivilian;
            
             // ?
             cost=1;
            
             // small map size
             mapSize=1;
            
             // dies similar to how a tree dies
             destrType=destructtree;
            
             // display name in the editor
             displayName="snYpir's StreetLamp";
            
             // icon to use (notice the pathname, for when we create snYpir_streetlamp.pbo)
             icon=\snYpir_streetlamp\lightpole.jpg;
            
             // use the existing streetlamp model (.p3d extension is optional)
             model=\data3d\lampadrevo;
         };
    };

    11. We can now save the config.cpp file and exit. Now we are going to make a pbo file. Open up StuffPBO (that you downloaded from the editing center's downloads page). Click on 'Set Input' and navigate into the 'folder' (where the config.cpp and icon file are located). Click on 'Set OutPut', find your OFP 'addons' folder and then type 'snYpir_streetlamp' into the 'File name:' text box. Click on 'Save', and then click on 'Stuff!'.

    Finished! Now you can load up OFP, go to the mission editor, add a new civilian unit of type 'support' and you will see the new streetlamp addon. You can now distribute the tiny snYpir_streetlamp.pbo file with your mission and be confident that people will be able to play your mission with or without Gunslinger's addon.

    Making a vehicle addon

    As was earlier alluded to, the CfgVehicles class is the key to making a vehicle addon. Now this class can get very complicated. Looking at the Apache or Chinook config.cpp file is not dissimilar to receiving a kick in the balls, so I am going to keep it simple. I am firstly going to step through how to make a new type of armoured car.

    A Simple Vehicle Example - The Hummer

    The best way to learn is by example, so lets take a look at the most simple vehicle addon example I could find. Here is the CfgVehicles class specification for the hummer addon:

    class CfgVehicles
    {
         class All {};
         class AllVehicles: All {};
         class Land: AllVehicles {};
         class LandVehicle: Land {};
         class Car: LandVehicle {};
         class Jeep : Car {};
         class HMMWV: Jeep
         {
             displayName= $STR_DN_HMMV;
             model=\humr\HMMWV.p3d;
             picture=\humr\ihmmwv.paa;
             armor = 80;
             type=VArmor;
             cost=100000;
             dammageHalf[]=
             {
                 ...
             };
             dammageFull[]=
             {
                 ...
             };
             armorGlass=0.5;
             armorWheels=0.1;
             soundEngine[]={\humr\HMMWVengine,db-25,1.25};
             typicalCargo[]={Soldier, Soldier, SoldierLAW, Officer};
         };
    };

    By now this class should look very familiar. We are taking a jeep as the base class, and changing attributes such as armor, armorGlass and armorWheels to turn it into an armored jeep.

    'displayName' is being read out of the stringtable.csv file (just like for a normal mission), simply because BIS wanted to cater for a range of different languages. Everything bar 'cost' is self explanatory.

    'dammageHalf' lists the textures to be used when the vehicle is damaged by half it's total armour value. 'type' specifies the type of armour this vehicle will use (other allowed types are VSoft and VAir). This vehicle has armored glass and wheels. The sound made by the hummer is set, and finally 'typicalCargo' sets the units that will be in this vehicle should the vehicle not be set as 'Empty' in the editor (?).

    More Complicated Vehicles - The Vulcan

    So what about more complicated vehicles? The hummer above was simple, because all it does is drive. It doesn't have a radar or a turret. Lets take a look at the CfgVehicles class for the Vulcan AA system.

    class CfgVehicles
    {
         class All {};
         class AllVehicles: All {};
         class Land: AllVehicles {};
         class LandVehicle: Land {};
         class Tank: LandVehicle
         {
             class TurretBase {};
         };
         class APC: Tank {};
         class M113: APC {};

         class Vulcan: M113
         {
             displayName=$STR_DN_VULCAN;
             picture=\vulcan\ivulcan.paa;
             icon = antiAC.paa;
             armor=180;
             cost=1000000;
             model=\vulcan\m163a1vulcan;

             irScanRange = 4000; // long range radar
             irScanGround = false; // NO IR on ground targets
             gunnerCanSee = CanSeeOptics+CanSeeEar+CanSeeCompass+CanSeeRadar;

             weapons[]={VulcanCannon};
             magazines[]={VulcanCannon};

             class Turret: TurretBase
             {
                 minElev=-3;
                 maxElev=+70;
             };

             //threat[] VSoft, VArmor, VAir
             threat[]={0.5, 0.5, 1};

             gunnerOpticsModel = "optika_zsu_gunner";
             commanderOpticsModel = "optika_tanke_auxiliary";

             gunnerAction = ManActVulcanGunner;
             gunnerInAction = ManActVulcanGunner;

             // outGunnerMayFire = true;
             forceHideGunner = true;
             viewGunnerInExternal = true;
             transportSoldier = 0;
         };
    };

    Now we are seeing something different! Let's firstly examine the inheritance structure for the vulcan.

    class All {};
    class AllVehicles: All {};
    class Land: AllVehicles {};
    class LandVehicle: Land {};
    class Tank: LandVehicle
    {
         class TurretBase {};
    };
    class APC: Tank {};
    class M113: APC {};

    class Vulcan: M113
    {

    Scared yet? Ignore the turret for now, and simply observe that the Vulcan is an M113, which is an APC, which is a Tank... etc. right up to class All (the base class for all vehicles in the game).

    Now what about class TurretBase {};? Well we all know that the M113 doesn't have a turret. What this line does is make our Vulcan inherit the characteristics of a tank with a turret, as well as the characteristics of the M113. Leaving us with an M113 with a turret, which is of course exactly what we want for the Vulcan.

    Following this is the Vulcan's attributes, and i'll now point out some of the interesting ones.

    The vulcan cannon is a ground to air weapon, and so the following is used to specify scan ranges for the vehicles 'radar'. This radar is the same one that you would observe if you were the commander of the vehicle.

    irScanRange = 4000; // long range radar
    irScanGround = false; // NO IR on ground targets

    The following line specifies the sensors that the gunner of the weapon can use to detect targets (notice we are using the constants defined at the top of the file):

    gunnerCanSee = CanSeeOptics+CanSeeEar+CanSeeCompass+CanSeeRadar;

    The weapon of the Vulcan had earlier been specified (in the cfgAmmo and cfgWeapons classes) and hence we can just plug the new weapons straight onto the vehicle:

    weapons[]={VulcanCannon};
    magazines[]={VulcanCannon};

    Now we are going to specify the attributes for the turret on the vulcan. Now the turret is a class of it's own, and for this reason the syntax below is used to set the attributes of the turret attached to this vehicle. The 'class Turret: TurretBase' line simply says 'go to the turret so I can set some attributes for it'. The maximum and minimum elevation are being set for the turret at +70 and -3 respectively:

    class Turret: TurretBase
    {
         minElev=-3;
         maxElev=+70;
    };

    The next line specifies what types of vehicles are of the highest threat to the Vulcan. Ie. what type of vehicle will the Vulcan shoot first if it is controlled by AI. The threats are listed in order, VSoft (soft skinned vehicles like trucks), VArmour (tanks and such) and lastly VAir which is the highest priority target.

    //threat[] VSoft, VArmor, VAir
    threat[]={0.5, 0.5, 1};

    The optics for the gunner and commander are specified:

    gunnerOpticsModel = "optika_zsu_gunner";
    commanderOpticsModel = "optika_tanke_auxiliary";

    Some of the animations used by the gunner are specified(?):

    gunnerAction = ManActVulcanGunner;
    gunnerInAction = ManActVulcanGunner;

    And finally, some micellaneous attributes are set. 'transportSoldier = 0;' specifies that this vehicle cannot carry any troops. If this was 2, it would be able to transport two troops.

    // outGunnerMayFire = true;
    forceHideGunner = true;
    viewGunnerInExternal = true;
    transportSoldier = 0;

    And after all that the cfgVehicles class for the Vulcan AA system is complete! But, this config.cpp file is far from over. A number of class definitions remain.

    As per the weapon addon, the CfgNonAIVehicles class is used to (?).

    class CfgNonAIVehicles
    {
         class ProxyCrew {};
         class Proxygunner: ProxyCrew {};
         class Proxyvulcangunner: Proxygunner {};
    };

    And finally, the CfgVehicleActions and CfgMovesMC classes (?) NFI. Perhaps define animations?

    Creating air vehicles - The SU25

    The final vehicle addon that we will be examining in this part of the tutorial is the Su25. It provides a good example of how to firstly create a number of different types of ammunition and weapons, add these to the vehicle and then set indicators (cockpit systems). Here is the abreviated cfgVehicles class for the Su25 addon (again I have skipped the weapon and ammunition classes, see the cpp file for this addon for more information):

    class CfgVehicles
    {
         class All {};
         class AllVehicles: All {};
         class Air: AllVehicles {};
         class Plane: Air {};

         class Su25: Plane
         {
             ...
             crew = SoldierEPilot;
             ...
             weapons[]={Ch29TLauncher, Rocket57x64, MachineGun30A10};
             magazines[]={Ch29TLauncher, Rocket57x64, MachineGun30A10};
             fov=0.5;

             type=VAir;
             //threat[] VSoft, VArmor, VAir
             threat[]={0.1, 1, 0.7};

             class Reflectors
             {
                 class Reflector
                 {
                     ...
                 };
             };

             class IndicatorAltRadar
             {
                 // max for this indicator is 1000 feet (i.e. 304m)
                 // note: this is actualy Baro altitude (name is wrong)
                 selection = "alt";
                 axis = "osa_alt";
                 angle = -340;
                 min = 0;
                 max = 1000;
             };
             class IndicatorAltRadar2
             {
                 ...
             };
             class IndicatorSpeed
             {
                 ...
             };
             class IndicatorVertSpeed
             {
                 ...
             };
             class IndicatorVertSpeed2
             {
                 ...
             };
         };
    };

    Firstly, note that crew is set to 'SoldierEPilot'. This will make 'SoldierEPilot''s appear driving the aircraft as default.

    Following is a good example of how to add multiple weapons systems to a vehicle (simply seperating different class names with comments).

    As per the Vulcan, the type of this vehicle and threats are set with:

    type=VAir;
    //threat[] VSoft, VArmor, VAir
    threat[]={0.1, 1, 0.7};

    If you wanted to make an air superiority fighter, you would use:

    threat[]={0.1, 0.1, 1};

    Following the threat attributes we start to specify the attributes for various sub-classes of this vehicle (as we did for the turret of the Vulcan).

    The 'class Reflector' defines a light for the plane. You can see that color is specified (red, green, blue and alpha value), the position, the direction, the size and the brightness of the light. It is quite possible that you could use a reflector class of your own to make a streetlamp light up, for example.

    Then we set the aircraft's indicators. 'Indicators' can be thought of as cockpit systems. If this was a jeep, we would be referring to the speedometer. Because the Su25 is an aircraft, there are many different types of indicators.

    You can see altitude indicators, speed indicators and vertical speed indicators. If we wanted to turn the Su-25 into an F-111, you would firstly increase the maximum speed of the aircraft and then adjust the cockpit indicators as appropriate.

    And I will leave vehicle addons there for now. The best way to learn is to examine and modify the official vehicle addons, experimenting with the various attributes. Have fun!

    Making a face addon

    The class name for custom face addons is 'CfgFaces', and works in a similar fashion to any other custom addon. Make a config.cpp file, and copy the .jpg images (your custom faces) into the same folder as the config.cpp file.

    The only classes you need in the config.cpp file are CfgPatches and CfgFaces. For example:

    class CfgPatches
    {
         class Faces
         {
             units[] = {};
             weapons[] = {};
             requiredVersion = version of OFP required for this addon to work;
         };
    };

    class CfgFaces
    {
         class FaceClassName
         {
             name="snYpir's camo face";
             texture="\name of your addon's pbo\name of image.jpg";
             east=1;
             west=1;
         };
    };

    'east=1' and 'west=1' simply refer to the side of soldier that this face can be used for.

    Adding new groups

    'Groups' are added by clicking the 'groups' button (F2) in the editor. They are pre-configured groups of units, for example the infantry squad or tank platoon that came as standard as part of OFP. You can easily make your own groups if you want to. If you have put together a bunch of different units, that would naturally be grouped together in a mission, then you should create a group that is distributed as part of your addon.

    You can of course do this in the same config.cpp file as everything else - remember that an addon can only have one config.cpp file but many classes within that one file.

    The class to add to make a new groups is class CfgGroups {}. It's structure more or less mirrors the structure of the 'Add Group' window in the editor. You need to specify a side for the group, a type and then finally the group itself. Here is an example of part of the default structure of class CfgGroups (ie what is used as default by the editor):

    class CfgGroups
    {
        class West
        {
             class Armored
             {
                 class Unit0
                 {
                 };
                 // other group types here
             };
             class Infantry
             {
                 class BasicInfantry
                 {
                 };
                 class MechanizedInfantry
                 {
                 };
             };
        };
    };

    This should be fairly familiar, ie if you opened up the editor right now, clicked on groups you can see a side west, with armored and infantry. When you make your CfgGroups class this is the same structure that you will use. You can use existing 'sides' and 'types' with no problems. Following is an example that you can copy-paste and modify to suit your needs. The complete .cpp file can be downloaded here (it needs to be renamed to config.cpp of course), and here is an example addon pbo if you want to see the final effect.

    class CfgGroups
    {
         // This will make an M1 Section appear under West | Armored
         class West
         {
             // side - appears in top box
             name="West";
             class Armored
             {
                 // type
                 name="Armoured";
                 class M1Section
                 {
                     // name of group
                     name="M1 Section";
                     class Unit0
                     {
                         // this name does nothing
                         name="tank1";
                         side=1;
                         vehicle="M1Abrams";
                         rank="CAPTAIN";
                         position[]={0,5,0};
                     };
                     class Unit1
                     {
                         name="tank2";
                         side=1;
                         vehicle="M1Abrams";
                         rank="CAPTAIN";
                         position[]={-20,0,0};
                     };
                 };
             };
         };

         // This will make an Counter-terrorist squad appear under CT | Black Ops
         class CT
         {
             // side - appears in top box
             name="CT"
             class BlackOps
             {
                 // type
                 name="Black Ops";
                 class CTSquad
                 {
                     // name of group
                     name="CT Squad";
                     class Unit0
                     {
                         name="1";
                         side=1;
                         vehicle="SoldierWSaboteur";
                         rank="CAPTAIN";
                         position[]={0,5,0};
                     };
                     class Unit1
                     {
                         name="2";
                         side=1;
                         vehicle="SoldierWSaboteur";
                         rank="Lieutnant";
                         position[]={-20,0,0};
                     };
                     class Unit2
                     {
                         name="3";
                         side=1;
                         vehicle="SoldierWSaboteur";
                         rank="Sergeant";
                         position[]={20,0,0};
                     };
                     class Unit3
                     {
                         name="4";
                         side=1;
                         vehicle="SoldierWSniper";
                         rank="Sergeant";
                         position[]={40,0,0};
                     };
                 };
             };
         };
    };

    So the first class makes an M1 Section available under West | Armored, and the second makes a totally new side and type of group. Hopefully this is fairly self explanatory. Any questions, plz hit the forum!

    Adding new markers

    Sorry for the delay in getting this section up, I sort of forgot that I never actually wrote it (damn!). But anyways, here it is, better late than never I suppose ;)

    Markers are of course those symbols that you see on the map in OFP. You add then by hitting F6 (markers) in the editor, and they can be of various colours and sizes. To add new markers to the game you must make a marker addon. This is fairly easy, but the tricky bit is actually making the image for your new marker.

    A mate and I sat down awhile back and drew up some NATO standard icons of the map screen, to make it all a little more realistic. This is how we worked out how to add new markers to the game.

    For this part of the tutorial you need two things:

     

  • TexView - the offical paa/pac file viewer from BIS. Available from our downloads page.
  • Adobe Photoshope - Or some other image editor that saves images in the Targa TGA format that TexView can read.

     

    Step 1: Drawing your marker

    The images used for markers in OFP make use of an alpha channel in order to make the markers transparent on the map screen. An alpha channel is not as scary as it sounds. Rather than each pixel representing a colour, images that use the an alpha channel use each pixel as a representation of how see-through that pixel is. So each pixel can represent any level of transparency, from totally transparent to fully opaque.

    If you have not done so, de-pbo the Data.pbo file (residing in your /DTA folder within your OFP directory). Open up 'marker_destroy.paa' in TexView. This is the 'destroy' icon used within OFP. You can see that it simply looks white, on a grey background.

    Understand that the image you are seeing is not white at all, and the background is not grey. Think of it like this: the whiter the image the less see-through it is, and the greyer the image the more transparent. All OFP has to do is colour the texture and display it to the screen; the grey bits will not be visible and all the user will see is the icons itself. Now to make our own.

    Open photoshop, and hit File -> New -> Image and select the size of your marker. Your size should be either 32 by 32 or 64 by 64 (pixels). Make the background white (transparent).

    Now hit ? -> ? (damn must open photoshop hold on) and select 'alpha channel'. Now rather than drawing in colours, we are drawing in level of transparency. Black will be totally opaque, and white is totally transparent.

    Now to draw your marker. Just draw, for this example, an 'A'. Select the colour black in the colour selection area, grab the pen tool, and draw the 'A' freehand. Now save your image (somewhere you will remember!) as a 'TGA' format image, of either 24 or 32 bit depth.

    Now open TexView, open the image you just saved, and re-save it as a .paa file. Save it as mymarker.paa for the purpose of this tutorial. You have finished making the texture for your new marker!

    Step 2: The CfgMarkers class

    In your addons folder, make a new folder called 'mymarker' and copy the .paa file you just saved in there. Make a new text file in the folder, and then rename it to config.cpp. Open config.cpp in your favourite text editor. Now to write the class.

    No defines are needed, we will just do the CfgPatches class. Here is one that will suffice for all your marker addon needs (don't worry about changing it):

    class CfgPatches
    {
         class Markers
         {
             units[] = {};
             weapons[] = {};
             requiredVersion = 1.10;
         };
    };

    Now for the class that will actually contain the definition of your new marker. Here is an example that will work, provided you have saved your texture as 'mymarker.paa'. Copy the following into your config.cpp file:

    // class to define new icons
    class CfgMarkers
    {
         class mymarker1
         {
             // name of icon
             name="My Marker";

             // image to use for icon
             icon="\mymarker\mymarker.paa";

             // default color of icon (in this case blue)
             color[]={0.100000,0.100000,0.900000,0.800000};

             // size of icon
             size=32;
         };
    };

    The class name for the marker is not that important, as long as it is different to all your other markers then you want have a problem. The name below is what will be displayed in the editor, so make it something descriptive.

    You can see we specify the image (relative to the pbo file we will later stuff, named 'mymarker.pbo'), and the default color of the image (in this case blue, specified in red/green/blue). We also specified the size of the icon, in this case 32. 32 is a good size for markers in general.

    And that's it! Pretty simple huh? We have told OFP where to find the image for the marker, what it's default colour is, it's display name and it's size.

    Open up StuffPBO, and stuff the folder into 'mymarker.pbo' in your addons folder. Open up OFP, head for the mission editor, hit F6 and double click on the map. Then select the name of your marker from the drop down list. Hit ok and walla! You have a new marker. Pretty damn cool I reckon.

    Other marker classes

    In addition to making a single icon, you can also define what shaded areas look like. Open up '90_horizontal.paa' in TexView (out of the data.pbo file) and it should look fairly familiar. You are staring at the horizontal shaded area is used to mark large areas within the game.

    The texture format is the same as for our single marker addon above, and uses the alpha channel in the same way. However, when adding an area to be shaded you use the CfgMarkerBrushes class instead of the CfgMarkers class. Suppose you have saved a new texture as myarea.paa, and it will be in the addon pbo named myarea.pbo. Here is the CfgMarkerBrushes definition you would use:

    class CfgMarkerBrushes
    {
         class myarea1
         {
             name="My Shaded Area";
             texture="myarea.paa";
         };
    };

    And finally there is the CfgMarkerColors class, which you can use to define new colour if you wish. Here is an example to make the colour green. The colour is specified in red, green, blue and alpha value - a lower alpha value means a more transparent colour.

    class CfgMarkerColors
    {
         class mygreen
         {
             name="My pretty shade of green";
             color[]={0.000000,0.600000,0.000000,0.800000};
         };
    };

    And that just about wraps it up for markers. Hope this helps you out! I have also extracted all the default marker definitions for you. Take a look at them here.

    Installing your addon

    Addons go in the 'addons' folder in your Operation Flashpoint directory, with all the various pictures and sound files that the addon will use. The smartest way to distribute your new addon is to use 'StuffPBO' (available in the downloads section of this site) to wrap your addon and it's associated goodies up in a PBO file.

    Your addon will not work unless it is in a pbo file in the addons folder.
    Remember, if your addon defines new classes then every mission that uses your addon will require it to run!

    Hints and tips

     

  • If you have DePBO'ed data3d.pbo, and have copied a model from it across to your addon, make sure to use unpack-sqm.exe to decrypt the model before you StuffPBO it up, even if you have not edited the model at all.

  • a-lone-wolf (creater of LST 54, and the medivac choppers) always includes a config.bin file with his addons. I don't think it is neccasary, but if you want to do exactly what the official addons do then de-pbo one of a-lone-wolf's addons (grab em from the custom vehicles page) and take a look at his config.bin files in a hex editor. You can see that all it contains is a link to the addon's pbo file. So it's your call, but until definite evidence is found that you need to include a config.bin file I wouldn't worry about it.

     

    Examples

    In order to know what you have to work with in your CfgAmmo, CfgWeapons and CfgVehicles classes I have compiled a series of references that detail exactly how the standard units (ammo, weapon and vehicle) are configured (this is from the config.cpp file that is used by the game itself).

     

  • Ammunition class definitions
  • Weapon class definitions

     

    Because of the huge number of vehicles in the game I have split up the vehicle definitions:

     

  • High level class definitions for vehicles (class All and class AllVehicles)
  • Land vehicles
  • Air vehicles
  • Ship vehicles

     

    Here are the class definitions of most of the miscellaneous vehicles (buildings, fires, ammo boxes etc) used in the game:

     

  • Misc vehicles

     

    Also, you may download the following example .cpp files to experiment with (right-click and save as). Don't forget that they must be re-named 'config.cpp' and put in a pbo file to work as an addon!

    Vehicle addons:

    Apache
    Ch47
    Hummer
    Su25
    Trabant (civy car)
    Vulcan
    Cessna with an MG and 3 other civy vehicles
    (by Kegetys). This is a very good example of how to add a machine gun to a civilian vehicle.
    LST54 (by a-lone-wolf). Good example of how to load a transport unit with weapons and ammo.
    Realistic A10 (by Armourdave)
    Realistic SU-25 (by Armourdave)
    German Police Car (by OddJob). Shows how to load a model with adjusted textures, and a new sound.
    Normal soldiers with ghillie suits (by snYpir). How to do some simple skin-changes using existing models.
    Ranger units with scoped M16's (by SelectThis)
    Keg's Misc2 addon (by Kegetys). A bunch of good stuff ranging from new bombs to making an M60 sound for a Blackhawk's MG.
    Working streetlamp (by Kegetys). How the man made working streetlights!
    Glasses addons (by Kegetys). How to make new glasses using class CfgGlasses {}.

    Weapon addons:

    RPG-29 (by Armourdave)
    M16 Shotgun (by Kegetys)
    Javelin AT (by Kegetys)
    Kozlice
    Long Range Sniper Rifle and HKMP5 with scope ([SV]dr.Grbec)

    Object Addons (allow you to use extra objects in the game):

    Gunslinger's Editor Addon
    Objects1 (by Kegetys)
    Objects2 (by Kegetys)

    Big thanks to Kegetys for the first ever user addons and also his command list.

    Face Addons

    Faces1 (by Devil)

    Back to the top.