Howto:Adding Bombable to FlightGear Aircraft: Difference between revisions

no edit summary
No edit summary
(32 intermediate revisions by 3 users not shown)
Line 1: Line 1:
How to make a FlightGear aircraft work with [[Bombable]].
{{Template:Bombable_Navigation}}


To make FlightGear aircraft work with Bombable--both as the main aircraft, an AI aircraft, and via Multiplayer (MP)--you need three things:
[[File:camel-through-wing.jpg|thumb]]
[[File:spad-vs-camel.jpg|thumb]]
[[File:warthog-down-on-bay-bridge.jpg|thumb]]
How to make a [[FlightGear]] [[aircraft]] work with [[Bombable]].
 
When you follow these instructions, you will add the following properties to your aircraft:
 
* AI aircraft can fly, maneuver, dodge, and attack the main aircraft.  They can avoid the ground (aircraft) or stay on the ground (ships, vehicles) while maneuvering.
* AI and MP aircraft can be damaged by the main aircraft and will stop functioning, crash, catch fire, explode, etc., appropriately when hit by weapons or bombs.  MP aircraft will report damage back over MP to the main aircraft, making multiplayer dogfights possible.
* MP aircraft will display weapons shooting whenever the remote MP aircraft is shooting, and report damage back to the main aircraft if the remote MP aircraft shoots or damages your aircraft.
* AI and MP aircraft can have smoke, contrails, and damaged engine smoke
* AI aircraft can automatically follow the main aircraft and attack it with weapons, which will be visible.
* You can design and customize the features per aircraft--to make, for instance, a maneuverable twisty dogfighter, light and easily damaged, or a fast, heavily armored energy fighter with lower maneuverability.
 
To make FlightGear aircraft work with Bombable--as the main aircraft, an AI aircraft, and via Multiplayer (MP)--you need three things:


* Weapons submodels that report impacts properly
* Weapons submodels that report impacts properly
Line 15: Line 29:
* We will add the files/mods needed for AI aircraft to the FGDATA/aircraft/F-15E directories (rather than creating a new, separate FGDATA/AI/Aircraft version of the F-15E)
* We will add the files/mods needed for AI aircraft to the FGDATA/aircraft/F-15E directories (rather than creating a new, separate FGDATA/AI/Aircraft version of the F-15E)
* We're just going to mod the existing F-15E directories and aircraft without changing and aircraft or file names (rather than creating a separate, new, differently named F-15E-Bombable aircraft)
* We're just going to mod the existing F-15E directories and aircraft without changing and aircraft or file names (rather than creating a separate, new, differently named F-15E-Bombable aircraft)
===Helpful/Needed files===
* [http://www.flightgear.org/forums/viewtopic.php?t=5742 Bombable download]
* [http://www.fguk.eu/index.php/forum/development-hangar/3632-f-15e-project F-15E model from FGUK]
* [http://brenthugh.com/flightgear/F-15E.zip F-15E model with the mods as described in this article] (finished and working version, though still un-polished, as described below, but with several updates and fixes beyond those mentioned in the article)


==Step 1: Check the weapons models for impact reporting==
==Step 1: Check the weapons models for impact reporting==
Line 24: Line 44:


  <PropertyList>
  <PropertyList>
 
   <!-- Gauche -->
   <!-- Gauche -->
   <submodel>
   <submodel>
Line 47: Line 67:
  250 pound, 500 pound, 1000 pound, 2000 pound
  250 pound, 500 pound, 1000 pound, 2000 pound


In this case, we make the following changes to the submodel names:
The name simply needs to include the appropriate keyword in some way--so if you have another name you prefer, just include the keyword at the end, like "MKFD Special Munition (250 pound)".
 
In this case, it is a 20 mm gatling gun, so more into cannon range, with projectiles weighing in at about .25 lb.  So we simply add "cannon" to each of the submodel names:


   <submodel>
   <submodel>
     <name>left gun</name>
     <name>left cannon</name>


   <submodel>
   <submodel>
     <name>right gun</name>
     <name>right cannon</name>


===Collision and impact reporting===
===Collision and impact reporting===
Line 74: Line 96:
       sim/ai/aircraft/impact/bomb
       sim/ai/aircraft/impact/bomb


According to the FG documentation, the <collision-report> setting is no longer used, so you can safely delete or just leave it be.
According to the FG documentation, the <collision-report> setting is no longer used, so you can safely delete it (though it does no harm to leave it be).


For the F-15E, this section of each <submodel> looks fine, so we just leave it alone.
For the F-15E, this section of each <submodel> looks fine, so we just leave it alone.
We save the file with the changes to the <name> sections.


==STEP 2: Adding code needed for MultiPlayer to the -set.xml file==
==STEP 2: Adding code needed for MultiPlayer to the -set.xml file==
Line 90: Line 114:
In the case of the F-15E, we open FGDATA\Aircraft\F-15E\F-15E_StrikeEagle-set.xml and find:
In the case of the F-15E, we open FGDATA\Aircraft\F-15E\F-15E_StrikeEagle-set.xml and find:


<?xml version="1.0"?>
<?xml version="1.0"?>
  <PropertyList>
  <PropertyList>
   <sim>
   <sim>
Line 99: Line 123:
   . . .
   . . .


[Make_an_aircraft#The_-set.xml_file|Find out more about the -set.xml file here.]
[[Howto: Make_an_aircraft#The_-set.xml_file|Find out more about the -set.xml file here.]]


The <sim> section is what we are looking for.
The <sim> section is what we are looking for.
Line 138: Line 162:
       <int n="14" alias="controls/armament/trigger4" />
       <int n="14" alias="controls/armament/trigger4" />


Each alias should correspond to a different <trigger> section in the submodel.xml definitions.
Each alias should correspond to a different <trigger> property in the submodel.xml definitions.


Save the -set.xml file with the changes.
Save the -set.xml file with the changes.


==STEP 3: Add the Bombable Nasal code==
==STEP 3: Add the Bombable Nasal code to the Model XML file==


Bombable needs to have certain code run when the AI or MP aircraft initializes.  The code is in [[Nasal]], FlightGear's scripting language. The code gives Bombable needed information about the aircraft (dimensions, vulnerabilities, weapons, etc) and also the code tells Bombable which systems to initialize for this aircraft.
Bombable needs to have certain code run when the AI or MP aircraft initializes.  The code is in [[Nasal]], FlightGear's scripting language. The code gives Bombable needed information about the aircraft (dimensions, vulnerabilities, weapons, etc) and also the code tells Bombable which systems to initialize for this aircraft.
Line 151: Line 175:


* Create the -bombableinclude.xml file
* Create the -bombableinclude.xml file
* Link the -bombableinclude.xml file to the existing -set.xml file
* Link the -bombableinclude.xml file to the aircraft's existing model XML file


===Create the -bombableinclude.xml file===  
===Create the -bombableinclude.xml file===  
In the Bombable distribution, these files are named [aircraftname]-bombableinclude.xml and are generally found in FGDATA/AI/Aircraft/[aircraftname/Models.
In the Bombable distribution, the include files are named [aircraftname]-bombableinclude.xml and are generally found in FGDATA/AI/Aircraft/[aircraftname]/Models.


In this case, the most similar aircraft in the Bombable distribution is the A-10. If [[Bombable]] is installed, the needed file is in:
In this case, the most similar aircraft in the Bombable distribution is the A-10. If [[Bombable]] is installed, the needed file is in:
Line 162: Line 186:
Open the file with a text editor and save it with a new name in your F-15E directory.  The new name & directory should be something like:
Open the file with a text editor and save it with a new name in your F-15E directory.  The new name & directory should be something like:


  FGDATA\Aircraft\F-15E\F-15E_StrikeEagle-bombableinclude.xml
  FGDATA\Aircraft\F-15E\Models\F-15E_StrikeEagle-bombableinclude.xml


Now you can open and edit this file.  Most changes are quite obvious--change the name, change the dimensions, etc.
Now you can open and edit this file.  Most changes are quite obvious--change the name, change the dimensions, etc.
Line 168: Line 192:
When done, we end up with a file like this:
When done, we end up with a file like this:


<?xml version="1.0"?>
  <?xml version="1.0"?>
 
<PropertyList>
  <PropertyList>
        <!-- Nasal code -->
        <!-- Nasal code -->
<nasal>
  <nasal>
            <load>
   
            <![CDATA[
 
              print("Loading F-15E ", cmdarg().getPath());
  <load>
  <![CDATA[
      var nodeName = cmdarg().getPath();  
  print("Loading F-15E ", cmdarg().getPath());
 
      ##checks whether it has been initialized already; if so, just return
        var nodeName = cmdarg().getPath();  
      if ( bombable.check_overall_initialized (nodeName) ) return;
 
        ##checks whether it has been initialized already; if so, just return
        if ( bombable.check_overall_initialized (nodeName) ) return;
 
 
############################################
 
#A-10 INITIALIZER
 
  var object_init = func() {
  ############################################
  # Datas of this object are under: cmdarg().getPath()
  #FUNCTION object_init, INITIALIZER
  var thisNodeName = cmdarg().getPath();
  var object_init = func() {
  var thisNode = props.globals.getNode(thisNodeName);
  # Datas of this object are under: cmdarg().getPath()
    ########################################################################
  var thisNodeName = cmdarg().getPath();
    ########################################################################
  var thisNode = props.globals.getNode(thisNodeName);
        # INITIALIZE BOMBABLE
  # Add some useful nodes
        #  
 
        # Initialize constants and main routines for maintaining altitude
 
        # relative to ground-level, relocating after file/reset, and  
 
        # creating bombable/shootable objects.
          ########################################################################
        #
          ########################################################################
        # These routines are found in FG/nasal/bombable.nas
          # INITIALIZE BOMBABLE
        # 
          #  
          ########################################################################             
          # Initialize constants and main routines for maintaining altitude
        # INITIALIZE BOMBABLE Object
          # relative to ground-level, relocating after file/reset, and  
        # This object will be slurped in the object's node as a child
          # creating bombable/shootable objects.
        # node named "bombable".               
        # All distances are specified in meters.
        # All altitudes are relative to current ground level at the object's
        # location
        #
         
        thisNodeName = cmdarg().getPath();
        var bombableObject = { 
         
         
          objectNodeName : thisNodeName,
          objectNode : props.globals.getNode(thisNodeName),
          updateTime_s : 1/3, #time, in seconds, between the updates that
          #keep the object at its AGL. Tradeoff is high-speed updates look more
          #realistic but slow down the framerate/cause jerkiness.  Faster-moving
          #objects will need more frequent updates to look realistic.
          #update time faster than about 1/3 seems to have a noticeable effect
          #on frame rate                   
                       
          #########################################                             
          # ALTITUDE DEFINITIONS
          #       
          altitudes : {
            wheelsOnGroundAGL_m : 1 , #altitude correction to add to your aircraft or ship that is needed to put wheels on ground (or, for a ship, make it float in the water at the correct level).  For most objects this is 0 but some models need a small correction to place them exactly at ground level
           
            minimumAGL_m : 100, #minimum altitude above ground level this object is allowed to fly
            maximumAGL_m : 3000, #maximum altitude AGL this object is allowed to fly, ie, operational ceiling    
            crashedAGL_m : 0.6, #altitude AGL when crashed.  Ships will sink to this level, aircraft or vehicles will sink into the ground as landing gear collapses or tires deflate. Should be negative, even just -0.001.
          },
          # 
          #########################################
          # VELOCITIES DEFINITIONS
           #  
           #  
           velocities : {             
           # These routines are found in FG/nasal/bombable.nas
            maxSpeedReduce_percent : 0.5, #max % to reduce speed, per step, when damaged
            minSpeed_kt : 112, #minimum speed to reduce to when damaged.  Ground vehicles and ships might stop completely when damaged but aircraft will need a minimum speed so they keep moving until they hit the ground.
   
            damagedAltitudeChangeMaxRate_meterspersecond : 30, #max rate to sink or fly downwards when damaged, in meters/second
          },
           #   
           #   
           #########################################
           ########################################################################             
           # EVASION DEFINITIONS
          # INITIALIZE BOMBABLE Object
          # This object will be slurped in the object's node as a child
          # node named "bombable".               
          # All distances are specified in meters.
          # All altitudes are relative to current ground level at the object's
           # location
           #  
           #  
          # The evasion system makes the AI aircraft dodge when they come under
         
           # fire.  
           thisNodeName = cmdarg().getPath();
           evasions : {              
 
            dodgeDelayMax_sec : 15, #max time to delay/wait between dodges
           var bombableObject = {   
            dodgeDelayMin_sec : 5, #minimum time to delay/wait between dodges
            dodgeMax_deg : 75, #Max amount to turn when dodging
                              #90 degrees = instant turn, unrealistic
                              #up to 80 is usually OK, somewhere in 80-85 starts to be unrealistically fast
                              #>85 is usually very unrealistic. You must test this in your scenario, however.
              
              
            dodgeMin_deg : 57, #minimum amount to turn when dodging
            dodgeROverLPreference_percent : 50, # Preference for right turns vs. left when dodging.  90% means 90% right turns, 50% means 50% right turns.
            dodgeAltMin_m : -6000, #Aircraft will begin to move up or down
            dodgeAltMax_m : 6000, #Max & Min are relative to current alt
            dodgeVertSpeedClimb_mps : 500, #Max speed to climb when evading
            dodgeVertSpeedDive_mps : 1000, #Max speed to dive when evading
          },
          # 
          #########################################
          # ATTACK DEFINITIONS
          #
          # The attack system makes the AI aircraft turn and fly towards
          # other aircraft
          attacks : {             
            maxDistance_m : 14000, #max distance to turn & attack main aircraft
            minDistance_m : 500, #min distance to turn & attack main aircraft, ie, fly away this far before turning to attack again
            continueAttackAngle_deg : 40, #when within minDistance_m, the aircraft will continue to turn towards the main aircraft and attack *if* if the angle is less than this amount from dead ahead
            altitudeHigherCutoff_m : 20000, # will attack the main aircraft unless this amount higher than it or more
            altitudeLowerCutoff_m : 15000, # will attack the main aircraft unless this amount lower than it or more
            climbPower : 11000, # How powerful the aircraft is when climbing during an attack; 4000 would be typical for, say a Zero--scale accordingly for others; higher is stronger
            divePower : 15000, # How powerful the aircraft is when diving during and attack; 6000 typical of a Zero--could be much more than climbPower if the aircraft is a weak climber but a strong diver             
            rollMin_deg : 58, #when turning on attack, roll to this angle min
            rollMax_deg : 74, #when turning on attack, roll to this angle max
                              #90 degrees = instant turn, unrealistic
                              #up to 80 might be OK, depending on aircraft & speed; somewhere in 80-85 starts to be unrealistically fast
                              #>85 is usually very unrealistic.  You must test this in your scenario, however.
              
              
             attackCheckTime_sec : 10, # check for need to attack/correct course this often   
             objectNodeName : thisNodeName,
            attackCheckTimeEngaged_sec : 0.5, # once engaged with enemy, check/update course this frequently
            objectNode : props.globals.getNode(thisNodeName),
                  
            updateTime_s : 1/3, #time, in seconds, between the updates that
           },
            #keep the object at its AGL. Tradeoff is high-speed updates look more
         
            #realistic but slow down the framerate/cause jerkiness.  Faster-moving
          #   
            #objects will need more frequent updates to look realistic.
            #update time faster than about 1/3 seems to have a noticeable effect
            #on frame rate                   
 
                         
            #########################################                             
            # ALTITUDE DEFINITIONS
            #       
            altitudes : {
              wheelsOnGroundAGL_m : 1 , #altitude correction to add to your aircraft or ship that is needed to put wheels on ground (or, for a ship, make it float in the water at the correct level).  For most objects this is 0 but some models need a small correction to place them exactly at ground level
             
              minimumAGL_m : 300, #minimum altitude above ground level this object is allowed to fly
              maximumAGL_m : 50000, #maximum altitude AGL this object is allowed to fly, ie, operational ceiling    
              crashedAGL_m : 0.6, #altitude AGL when crashed.  Ships will sink to this level, aircraft or vehicles will sink into the ground as landing gear collapses or tires deflate. Should be negative, even just -0.001.
            },
            # 
            #########################################
            # VELOCITIES DEFINITIONS
            #
            velocities : {             
              maxSpeedReduce_percent : 0.5, #max % to reduce speed, per step, when damaged
              minSpeed_kt : 112, #minimum speed to reduce to when damaged.  Ground vehicles and ships might stop completely when damaged but aircraft will need a minimum speed so they keep moving until they hit the ground.
              cruiseSpeed_kt : 550, #cruising speed, typical/optimal cruising speed, V C for aircraft
             
              attackSpeed_kt : 900, #typical/optimal speed when aggressively attacking or evading, in
                                  #level flight for aircraft
             
              maxSpeed_kt : 1400 , #Maximum possible speed under dive or downhill conditions, V NE for aircraft
     
              damagedAltitudeChangeMaxRate_meterspersecond : 30, #max rate to sink or fly downwards when damaged, in meters/second
 
              #The terminal velocities are calculated by opening the 'real' AC
              #in FG, level flight, full throttle, then putting
              #the AC at different angles of attack with the autopilot,
              #and noting the terminal airspeed & vertical speed velocities.
              #For best results, do it near sea level, under 5000 feet altitude.
              #One or two each of climb & dive velocities are probably sufficient.
              #However if you do more we may be able to use the more precise
              #data in the future.
              #
              #Note that these are intended to be true airspeed whereas FG's
              #/velocities/airspeed-kt reports indicated airspeed, so some
              #conversion or reference to groundspeed-kt is needed.
              #
              #In FG /velocities/groundspeed-kt is equal (or close
              #to equal, except for wind . . .) true airspeed when pitch=0
              #but as pitch increases or decreases that will change.
              #                         
              diveTerminalVelocities: {
                  point1: { airspeed_kt : 1060, vertical_speed_fps : - 337},
                  point2: { airspeed_kt : 1230, vertical_speed_fps : - 755},
                 
              },
 
              climbTerminalVelocities: {
                point1: { airspeed_kt : 468, vertical_speed_fps : 236},
                point2: { airspeed_kt : 843, vertical_speed_fps : 251},
                #point3: { airspeed_kt : 1100, vertical_speed_fps : 161},
           
              },
             
            },
            # 
            #########################################
            # EVASION DEFINITIONS
            #
            # The evasion system makes the AI aircraft dodge when they come under
            # fire.
            evasions : {             
              dodgeDelayMax_sec : 15, #max time to delay/wait between dodges
              dodgeDelayMin_sec : 5, #minimum time to delay/wait between dodges
              dodgeMax_deg : 88, #Max amount to turn when dodging
                                #90 degrees = instant turn, unrealistic
                                #up to 80 is usually OK, somewhere in 80-85 starts to be unrealistically fast
                                #>85 is usually very unrealistic.  You must test this in your scenario, however.
             
              dodgeMin_deg : 83, #minimum amount to turn when dodging         
              rollRateMax_degpersec : 300, #you can figure this out by rolling the corresponding FG aircraft and timing a 180 or 360 deg roll           
              dodgeROverLPreference_percent : 50, # Preference for right turns vs. left when dodging.  90% means 90% right turns, 50% means 50% right turns.
              dodgeAltMin_m : -8000, #Aircraft will begin to move up or down
              dodgeAltMax_m : 8000, #Max & Min are relative to current alt
              dodgeVertSpeedClimb_mps : 1500, #Max speed to climb when evading
              dodgeVertSpeedDive_mps : 1500, #Max speed to dive when evading
            },
            # 
            #########################################
            # ATTACK DEFINITIONS
            #
            # The attack system makes the AI aircraft turn and fly towards
            # other aircraft
            attacks : {             
              maxDistance_m : 30000, #max distance to turn & attack main aircraft
              minDistance_m : 4000, #min distance to turn & attack main aircraft, ie, fly away this far before turning to attack again
              continueAttackAngle_deg : 80, #when within minDistance_m, the aircraft will continue to turn towards the main aircraft and attack *if* if the angle is less than this amount from dead ahead
              altitudeHigherCutoff_m : 30000, # will attack the main aircraft unless this amount higher than it or more
              altitudeLowerCutoff_m : 30000, # will attack the main aircraft unless this amount lower than it or more
              climbPower : 8000, # How powerful the aircraft is when climbing during an attack; 4000 would be typical for, say a Zero--scale accordingly for others; higher is stronger
              divePower : 10000, # How powerful the aircraft is when diving during and attack; 6000 typical of a Zero--could be much more than climbPower if the aircraft is a weak climber but a strong diver             
              rollMin_deg : 82, #when turning on attack, roll to this angle min
                                #for sedate, Cessna-like manuevers make rollMin low.  If you want an aggressive,
                                #attacking, aiming fighter keep it close to rollMax, or even almost equal to rollMax
              rollMax_deg : 87, #when turning on attack, roll to this angle max
                                #90 degrees = instant turn, unrealistic
                                #up to 80 might be OK, depending on aircraft & speed; somewhere in 80-85 starts to be unrealistically fast
                                #>85 is usually very unrealistic.  You must test this in your scenario, however.
              rollRateMax_degpersec : 120, #you can figure this out by rolling the corresponding FG aircraft and timing a 180 or 360 deg roll           
              attackCheckTime_sec : 10, # check for need to attack/correct course this often   
              attackCheckTimeEngaged_sec : 0.5, # once engaged with enemy, check/update course this frequently
                 
            },
           
            # 
            #########################################
            # WEAPONS DEFINITIONS
            #
            # The weapons system makes the AI aircraft fire on the main aircraft
            # You can define any number of weapons--just enclose each in curly brackets
            # and separate with commas (,).         
            weapons : {
              front_gun :  #internal name - this can be any name you want; must be a valid nasal variable name
                 {             
                  name : "Machine Gun", # name presented to users, ie in on-screen messages
                  maxDamage_percent : 5, # maximum percentage damage one hit from the aircraft's main weapon/machine guns will do to an opponent
                  maxDamageDistance_m : 2000, # maximum distance at which the aircrafts main weapon/maching guns will be able to damage an opponent
                  weaponAngle_deg  :  { heading: 0, elevation: 0 }, # direction the aircraft's main weapon is aimed. 
                                                                    # 0,0 = straight ahead, 90,0=directly right, 0,90=directly up, 0,180=directly back, etc.
                  weaponOffset_m : {x:2, y:0, z:0}, # Offset of the weapon from the main aircraft center
                  weaponSize_m : {start:.1, end:.1}, # Visual size of the weapon's projectile, in meters, at start & end of its path
 
                },   
              sidewinder_missile :  #internal name - this can be any name you want; must be a valid nasal variable name
                {             
                  name : "Sidewinder guided missile", # name presented to users, ie in on-screen messages
                  maxDamage_percent : 40, # maximum percentage damage one hit from the aircraft's main weapon/machine guns will do to an opponent
                  maxDamageDistance_m : 6000, # maximum distance at which the aircrafts main weapon/machine guns will be able to damage an opponent
                  weaponAngle_deg  :  { heading: 0, elevation: 0 }, # direction the aircraft's main weapon is aimed. 
                                                                    # 0,0 = straight ahead, 90,0=directly right, 0,90=directly up, 0,180=directly back, etc.
                  weaponOffset_m : {x:2, y:0, z:0}, # Offset of the weapon from the main aircraft center
                  weaponSize_m : {start:1, end:1}, # Visual size of the weapon's projectile, in meters, at start & end of its path
 
                },   
 
 
            }, 
           
            # 
            #########################################
            # DIMENSION DEFINITIONS
            #
            # All dimensions are in meters
            #            
            #         
            dimensions : {                 
              width_m : 17.53,  #width of your object, ie, for aircraft, wingspan
              length_m : 16.26, #length of your object, ie, for aircraft, distance nose to tail
              height_m : 4.47, #height of your object, ie, for aircraft ground to highest point when sitting on runway
             
              damageRadius_m : 8, #typically 1/2 the longest dimension of the object. Hits within this distance of the
                                  #center of object have some possibility of damage
              vitalDamageRadius_m : 2, #typically the radius of the fuselage or cockpit or other most
                                      # vital area at the center of the object.  Always smaller than damageRadius_m
                                     
              crashRadius_m : 6, #It's a crash if the main aircraft hits in this area.
                                 
            },
            #
            #########################################
            # VULNERABILITIES DEFINITIONS       
            #
            vulnerabilities : {                 
              damageVulnerability : 9, #Vulnerability to damage from armament, 1=normal M1 tank; higher to make objects easier to kill and lower to make them more difficult.  This is a multiplier, so 5 means 5X easier to kill than an M1, 1/5 means 5X harder to kill.
             
              engineDamageVulnerability_percent : 6, #Chance that a small-caliber machine-gun round will damage the engine.     
             
              fireVulnerability_percent : 5, #Vulnerability to catching on fire. 100% means even the slightest impact will set it on fire; 20% means quite difficult to set on fire; 0% means set on fire only when completely damaged; -1% means never set on fire.                         
             
              fireDamageRate_percentpersecond : .1, #Amount of damage to add, per second, when on fire.  100%=completely damaged. Warthog is relatively damage-resistant.
             
              fireExtinguishMaxTime_seconds : 80, #Once a fire starts, for this many seconds there is a chance to put out the fire; fires lasting longer than this won't be put out until the object burns out.
             
              fireExtinguishSuccess_percentage : 45, #Chance of the crew putting out the fire within the MaxTime above. Warthoge is relatively damage-resistant.
             
              explosiveMass_kg : 27772 , #mass of the object in KG, but give at least a 2-10X bonus to anything carrying flammables or high explosives.
            },
            #
            #########################################
            # LIVERY DEFINITIONS
            #
            # Path to livery files to use at different damage levels.
            # Path is relative to the AI aircraft's directory.
            # The object will start with the first livery listed and
            # change to succeeding liveries as the damage
            # level increases. The final livery should indicate full damage/
            # object destroyed.       
            #
            # If you don't want to specify any special liveries simply set
            # damageLivery : nil and the object's normal livery will be used. 
            #                                                          
            damageLiveries : {
              damageLivery : [ ]                       
            },
                             
          };
 
           #########################################
           #########################################
           # WEAPONS DEFINITIONS
           # INITIALIZE ROUTINES
           #  
           #  
           # The weapons system makes the AI aircraft fire on the main aircraft
           # OVERALL INITIALIZER: Needed to make all the others work
           # You can define any number of weapons--just enclose each in curly brackets
           bombable.initialize ( bombableObject );
          # and separate with commas (,).         
           #
           weapons : {
          # LOCATION: Relocate object to maintain its position after file/reset     
            front_gun :  #internal name - this can be any name you want; must be a valid nasal variable name
          # (best not used for airplanes)
              {             
          # bombable.location_init ( thisNodeName );
                name : "Machine Gun", # name presented to users, ie in on-screen messages
           #
                maxDamage_percent : 5, # maximum percentage damage one hit from the aircraft's main weapon/machine guns will do to an opponent
           # GROUND: Keep object at altitude relative to ground level
                maxDamageDistance_m : 400, # maximum distance at which the aircrafts main weapon/maching guns will be able to damage an opponent
           bombable.ground_init ( thisNodeName );
                weaponAngle_deg  :  { heading: 0, elevation: 0 }, # direction the aircraft's main weapon is aimed. 
                                                                  # 0,0 = straight ahead, 90,0=directly right, 0,90=directly up, 0,180=directly back, etc.
                weaponOffset_m : {x:2, y:0, z:0}, # Offset of the weapon from the main aircraft center
                weaponSize_m : {start:.1, end:.1}, # Visual size of the weapon's projectile, in meters, at start & end of its path
              },   
          }, 
         
           #
           #########################################
           # DIMENSION DEFINITIONS
           #
           #
           # All dimensions are in meters
           # ATTACK: Make the object attack the main aircraft      
          # source: http://en.wikipedia.org/wiki/Fairchild_Republic_A-10_Thunderbolt_II         
           bombable.attack_init ( thisNodeName );
          #         
          dimensions : {                 
            width_m : 17.53,  #width of your object, ie, for aircraft, wingspan
            length_m : 16.26, #length of your object, ie, for aircraft, distance nose to tail
            height_m : 4.47, #height of your object, ie, for aircraft ground to highest point when sitting on runway
           
            damageRadius_m : 8, #typically 1/2 the longest dimension of the object. Hits within this distance of the
                                #center of object have some possibility of damage
            vitalDamageRadius_m : 2, #typically the radius of the fuselage or cockpit or other most
                                    # vital area at the center of the object.  Always smaller than damageRadius_m
                                   
            crashRadius_m : 6, #It's a crash if the main aircraft hits in this area.
                               
           },
           #
           #
           #########################################
           # WEAPONS: Make the object shoot the main aircraft       
           # VULNERABILITIES DEFINITIONS       
           bombable.weapons_init ( thisNodeName );               
           #
           #
           vulnerabilities : {                 
           # BOMBABLE: Make the object bombable/damageable       
            damageVulnerability : 9, #Vulnerability to damage from armament, 1=normal M1 tank; higher to make objects easier to kill and lower to make them more difficult.  This is a multiplier, so 5 means 5X easier to kill than an M1, 1/5 means 5X harder to kill.
          bombable.bombable_init ( thisNodeName );
           
            engineDamageVulnerability_percent : 6, #Chance that a small-caliber machine-gun round will damage the engine.     
           
            fireVulnerability_percent : 5, #Vulnerability to catching on fire. 100% means even the slightest impact will set it on fire; 20% means quite difficult to set on fire; 0% means set on fire only when completely damaged; -1% means never set on fire.                         
           
            fireDamageRate_percentpersecond : .1, #Amount of damage to add, per second, when on fire.  100%=completely damaged. Warthog is relatively damage-resistant.
           
            fireExtinguishMaxTime_seconds : 80, #Once a fire starts, for this many seconds there is a chance to put out the fire; fires lasting longer than this won't be put out until the object burns out.
           
            fireExtinguishSuccess_percentage : 45, #Chance of the crew putting out the fire within the MaxTime above. Warthoge is relatively damage-resistant.
           
            explosiveMass_kg : 27772 , #mass of the object in KG, but give at least a 2-10X bonus to anything carrying flammables or high explosives.
          },
           #
           #
           #########################################
           # SMOKE/CONTRAIL: Start a flare, contrail, smoke trail, or exhaust
           # LIVERY DEFINITIONS
          # trail for the object.
          # Smoke types available: flare, jetcontrail, pistonexhaust, smoketrail,
          # damagedengine                       
          bombable.startSmoke("jetcontrail", thisNodeName );
           #F-15E already has contrails, we're leaving this out
           #
           #
           # Path to livery files to use at different damage levels.
           # END INITIALIZE BOMBABLE
          # Path is relative to the AI aircraft's directory.
          ########################################################################
          # The object will start with the first livery listed and
          ########################################################################                 
          # change to succeeding liveries as the damage
       
          # level increases. The final livery should indicate full damage/
 
          # object destroyed.       
 
          #
  }
          # If you don't want to specify any special liveries simply set
 
          # damageLivery : nil and the object's normal livery will be used. 
  object_init();
          #                                                           
  ]]>
          damageLiveries : {
  </load>
            damageLivery : [  ]                       
  <unload>
          },
  <![CDATA[
                           
  print("Unload F-15E.");
        };
        #########################################
        # INITIALIZE ROUTINES
        #
        # OVERALL INITIALIZER: Needed to make all the others work
        bombable.initialize ( bombableObject );
        #
        # LOCATION: Relocate object to maintain its position after file/reset     
        # (best not used for airplanes)
        # bombable.location_init ( thisNodeName );
        #
        # GROUND: Keep object at altitude relative to ground level
        bombable.ground_init ( thisNodeName );
        #
        # ATTACK: Make the object attack the main aircraft       
        bombable.attack_init ( thisNodeName );
        #
        # WEAPONS: Make the object shoot the main aircraft       
        bombable.weapons_init ( thisNodeName );               
        #
        # BOMBABLE: Make the object bombable/damageable       
        bombable.bombable_init ( thisNodeName );
        #
        # SMOKE/CONTRAIL: Start a flare, contrail, smoke trail, or exhaust
        # trail for the object.
        # Smoke types available: flare, jetcontrail, pistonexhaust, smoketrail,
        # damagedengine                       
        bombable.startSmoke("jetcontrail", thisNodeName );
        #
        # END INITIALIZE BOMBABLE
        ########################################################################
        ########################################################################                 
     
      }
      object_init();
      ]]>
      </load>
      <unload>
      <![CDATA[
        print("Unload F-15E.");
         var nodeName= cmdarg().getPath();   
         var nodeName= cmdarg().getPath();   
         bombable.de_overall_initialize( nodeName );
         bombable.de_overall_initialize( nodeName );
Line 421: Line 505:
         bombable.attack_del( nodeName );
         bombable.attack_del( nodeName );
         bombable.weapons_del (nodeName);       
         bombable.weapons_del (nodeName);       
   
  # </unload>
    ]]>
 
    </unload>
  ]]>
  </nasal>   
  </unload>
  </nasal>   
</PropertyList>
 
  </PropertyList>
 
Save this file with the name you have chosen ( FGDATA\Aircraft\F-15E\Models\F-15E_StrikeEagle-bombableinclude.xml).


Save this file with the name you have chosen ( FGDATA\Aircraft\F-15E\F-15E_StrikeEagle-bombableinclude.xml).
===Link the -bombableinclude.xml file to the existing F-15 model file===


===Link the -bombableinclude.xml file to the existing -set.xml file===
Now that we have created the -bombableinclude.xml file, we need to set up the aircraft to load the file on startup.
Now that we have created the -bombableinclude.xml file, we need to set up the aircraft to load the file on startup.


Load the file F-15E_StrikeEagle-set.xml again.
AI scenarios (and MP aircraft) load the aircraft's model file.  So we need to locate that file and include the new -bombableinclude.xml file in it.


At the beginning of that file you will find this:
Where is the model file?  Look in the aircraft's -set.xml file. In that file will be a section called <model>.  For the F-15E it looks like this:
 
  <model>
  <path>Aircraft/F-15E/Models/F-15E_StrikeEagle.xml</path>
  </model>
 
So Aircraft/F-15E/Models/F-15E_StrikeEagle.xml is our model file.
 
 
Load Aircraft/F-15E/Models/F-15E_StrikeEagle.xml in a text editor. At the beginning of that file you will find this:


  <?xml version="1.0"?>
  <?xml version="1.0"?>
Line 448: Line 543:


Save the file.
Save the file.
===Notes===
* The statement include="F-15E_StrikeEagle-bombableinclude.xml" indicates that F-15E_StrikeEagle-bombableinclude.xml will be in the same directory as F-15E_StrikeEagle.xml.  That directory is Aircraft/F-15E/Models -- so make sure that the -bombableinclude.xml file is indeed in that directory!
* Model files can have only ONE Nasal <load> section and one <unload> section.
If you have more than one, the second and subsequent <load>/<unload> sections are ignored.
The problem?  Your aircraft may already have a <load> or <unload> section.  When you add the Bombable code, one of the two <load> sections (the pre-existing one or Bombable's) will be ignored.
The solution is to combine the two <load> sections into one, and the same with the <unload> sections.  You'll need to know a little about [[Nasal]] programming to do anything complicated, but as a rule you can just copy/paste whatever is in the aircraft's <load> section to the start of Bombable's <load> section, and the same with <unload>.
* You'll notice the Nasal code starts with ''<![CDATA['' and ends with '']]>''.  That is needed to make Nasal code work within XML files.  [http://www.w3schools.com/xml/xml_cdata.asp CDATA usage is explained here.]


==STEP 4. Add to an AI Scenario==
==STEP 4. Add to an AI Scenario==
Now we can add the F-15E to an AI scenario.
Now we can add the F-15E to an AI scenario.


Create a file named F-15E-demo.xml and save it in your FGDATA/AI directory:
Create a file named F-15E-demo.xml and save it in your FGDATA/AI directory.
 
Most of the entries in the scenario file are self-explanatory.  For the <model> entry you'll need the path of the same model file for the F-15 that we located in Step 3--which is Aircraft/F-15E/Models/F-15E_StrikeEagle.xml.
 
Here is how the file should look when you are done:


  <?xml version="1.0"?>
  <?xml version="1.0"?>
Line 463: Line 575:
       <callsign>Jones</callsign>
       <callsign>Jones</callsign>
       <name>F15E Leader</name>
       <name>F15E Leader</name>
       <model type="string">Aircraft/F-15E/F-15E_StrikeEagle-set.xml</model>
       <model type="string">Aircraft/F-15E/Models/F-15E_StrikeEagle.xml</model>
       <latitude type="double">37.608720</latitude>
       <latitude type="double">37.608720</latitude>
       <longitude type="double">-122.3076</longitude>
       <longitude type="double">-122.3076</longitude>
       <altitude type="double">309</altitude>
       <altitude type="double">309</altitude>
       <speed>280.0</speed>
       <speed>280.0</speed>
       <heading type="double">355</heading>
       <heading type="double">192</heading>
     </entry>
     </entry>
      
      
Line 475: Line 587:
       <callsign>Cooper</callsign>
       <callsign>Cooper</callsign>
       <name>F15E Wingman</name>
       <name>F15E Wingman</name>
       <model type="string">Aircraft/F-15E/F-15E_StrikeEagle-set.xml</model>
       <model type="string">Aircraft/F-15E/Models/F-15E_StrikeEagle.xml</model>
       <latitude type="double">37.608200</latitude>
       <latitude type="double">37.608200</latitude>
       <longitude type="double">-122.2988</longitude>
       <longitude type="double">-122.2988</longitude>
       <altitude type="double">309</altitude>
       <altitude type="double">309</altitude>
       <speed>270.0</speed>
       <speed>270.0</speed>
       <heading type="double">90</heading>
       <heading type="double">192</heading>
     </entry>
     </entry>
   <scenario>
   <scenario>
   
   
  </PropertyList>
  </PropertyList>
Again, save as FGDATA/AI/F-15E-demo.xml.  When you start FGRun next time, F-15E-demo will be listed as one of the scenario file options.  (You may need to quit and re-start FGRun.)


==STEP 5. Troubleshooting==
==STEP 5. Troubleshooting==
Line 547: Line 661:
The best/easiest way to test XML files is load them in Internet Explorer.  It will parse the XML file and display any errors it finds.  (If you don't have access to IE there are other XML parsers available.)  This is far easier and faster than starting and re-starting FG repeatedly, and IE gives better, more informative error messages as well.
The best/easiest way to test XML files is load them in Internet Explorer.  It will parse the XML file and display any errors it finds.  (If you don't have access to IE there are other XML parsers available.)  This is far easier and faster than starting and re-starting FG repeatedly, and IE gives better, more informative error messages as well.


==Where your aircraft files are==
==IMPORTANT POSTSCRIPT: Where your aircraft files are==
An important detail in getting Bombable to work with aircraft over AI and MP is the directories you store the files in and the names you choose to use for them.
An important detail in getting Bombable to work with aircraft over AI and MP is the directories you store the files in and the names you choose to use for them.


Line 588: Line 702:


Bombable will work with any of those options--so it is really up to you.
Bombable will work with any of those options--so it is really up to you.
==EXTRA: Making livery change with damage==
Once you have Bombable working with your aircraft there is a bonus: bombable.nas will handle setting the livery colors and
automatically changing them as the object becomes damaged. 
For an example of how this works and looks, take a look at the Bombable scenarios involving the M1 tank and the Jeep.
For this to work your model must have different liveries available
and then animate the liveries so that the texture used is the one shown
in this path: /ai/model/model[X]/bombable/texture-corps-path.  The /ai/model/model[X]/ part is assumed for AI craft so you need to add <texture-prop>bombable/texture-corps-path</texture-prop> in the right place of your XML file.
Example from Jeep.xml in the jeep-bombable directory:
<animation>
  <type>material</type>
  <object-name>jeep-body</object-name>
  <object-name>roof1</object-name>
  <object-name>roof2</object-name>
  <object-name>softroof</object-name>
  <object-name>chassis</object-name>
  <object-name>chassis.002</object-name>
  <object-name>Plane</object-name>
  <object-name>hinge</object-name>
  <object-name>screen</object-name>
  <object-name>wiper.L</object-name>
  <object-name>wiper.R</object-name>
  <object-name>seat.L</object-name>
  <object-name>seat.R</object-name>
  <texture-prop>bombable/texture-corps-path</texture-prop>
  <transparency>
      <alpha>1.0</alpha>
  </transparency>
</animation>
 
Additionally, if you want to change your object's the livery color programmatically (for instance, if you include a menu item to select different liveries) you can use the following code in the -bombableinclude.xml file (see above) to change all liveries, including damage liveries, that the object uses:
Example:
    liveries = [
        "Models/livery_nodamage.png",
        "Models/livery_slightdamage.png",
        "Models/livery_highdamage.png");
    ];
    bombable.set_livery (cmdarg().getPath(), liveries);
You can include liveries for as many different levels of damage (ie, fine gradations of change from undamaged to completely damaged) as you like.  For instance:
Example:
    liveries = [
        "Models/livery_nodamage.png",
        "Models/livery_barelydamaged.png",
        "Models/livery_justslightlydamaged.png",
        "Models/livery_alittlemoredamage.png",
        "Models/livery_fairlydamaged.png",         
        "Models/livery_kindadamaged.png",
        "Models/livery_prettydamaged.png",
        "Models/livery_whoawereintroublenow.png",                 
        "Models/livery_finishedoff.png");
    ];
    bombable.set_livery (cmdarg().getPath(), liveries); 
==Related content==
* [[Bombable]]
* [[Howto:Nasal in scenery object XML files]]
* [[Interactive Traffic]]
* [[AI Systems#AI Models]]
* [[Howto:Add submodels]]
* [[Howto:Make an aircraft]]
[[Category:Aircraft enhancement|Bombable]]
[[Category:Bombable]]
[[Category:Nasal howto|Bombable]]