Working With Dropships

Overview

From littering a highway with rollermines, to shipping out troops or simply providing some atmosphere, the use of dropships can do a lot to add variety to a map. The intent of this article is to show you how to spawn dropships and make them interact with the world around them through a mapadd script. How exactly you use them is left to your imagination.

It can be helpful while going through this page to run SMOD in a window so you can quickly and easily switch back and forth.
You can do this by right-clicking on it in your Steam games menu, choosing Properties, choosing Set Launch Options, and adding -window.

The reader should already be familiar with mapadd syntax, grabbing coordinates, using the input/output system, and other basics.

This page makes particular use of these entities:
aiscripted_schedule
info_target
npc_apcdriver
npc_combinedropship
path_corner
path_track
prop_vehicle_apc
scripted_sequence

While reading these shouldn't be required to understand the page, it can help you along and give you other ideas.

How-To

Moving Around

To begin, you can plan where the ship is going to go. Use the console (ex. noclip and Impulse 90) to grab coordinates for the intended path, ensuring there's plenty of room for it to manuever; the ship is very large and takes wide turns.

Next, those coordinates need to be turned into something useful. Below is a snippet from the example script of a path_track, which is basically a node type used for directing or moving certain entities down a controlled path (or set of paths).

"path_track" // Track begin
        {
        "origin" "-4650 4510 2080"
        "angle" "0 -90 0"
        "keyvalues"
            {
            "targetname" "Nomad_n00" // Name of this track piece.
            "target" "Nomad_n01" // Name of the next track piece.
            //"OnPass" "Nomad,FlyToSpecificTrackViaPath,Nomad_n04,0,-1"
            "OnPass" "Nomad,FlyToPathTrack,Nomad_n01,0,-1"
            }
        }

The first two lines in keyvalues set the targetname for this node and target the next node in the track's sequence. In this example, the node sequence goes through Nomad_n00 to Nomad_n04, where the track ends.

The OnPass output fires whenever a vehicle finishes traveling to the node. Note that the first OnPass line is commented; we could normally use the dropship's FlyToSpecificTrackViaPath input at the start of the track and the dropship would follow it smoothly to its end. In this example however, there isn't a proper node graph for flying NPCs, so the ship must be walked each step of the way by using FlyToPathTrack.

Once a string of similar tracks has been placed, the script needs a ship to boss around. Below is another snippet of the dropship in this example (named here as Nomad), which will start behind a large building and eventually fly behind another.

"npc_combinedropship"
        {
        "origin" "-4650 4510 2080"
        "angle" "0 -90 0"
        "keyvalues"
            {
            "targetname" "Nomad"
            "target" "Nomad_n00"
            }
        }

Nothing special here, aside from the target value. All this does is tell the ship to immediately go to the node called Nomad_n00, where the track begins. After that, the node's OnPass output takes care of the rest. Once the dropship reaches the last track piece and is no longer needed, it should be deleted like so:

    "path_track"
        {
        "origin" "1000 -2625 1150"
        "angle" "10 0 0"        
        "keyvalues"
            {
            "targetname" "Nomad_n04"
            "OnPass"     "Nomad,Kill,,0,-1"
            }
        }

Because of the way dropship sounds work, it won't sound like it's vanished but will instead fade away little by little. Now that the ship is moving around like it ought, some more commands are probably in order.

Dropping Cargo

Armored Personnel Carriers

Moving on from the last section, we only need to add a few more things to get the dropship plopping down a big bad APC. If you want to make certain the vehicle is dropped off in the same spot every time, you'll probably want to start by making an info_target to mark your landing point. Ideally, you'll want to use impulse 90's trace coordinates when staring at the ground of a wide, flat area.

"info_target"
        {
        "origin" "-269 1713 -140"
        "angle" "0 270 0"
        "keyvalues"
            {
            "targetname" "Nomad_nLand"
            }
        }

Something simple like the above will get the job done. After that, begin with an APC in the Entities section, since making it within a label will crash the game.

    "prop_vehicle_apc"
        {
        "keyvalues"
            {
            "targetname" "Ranger"
            "model" "models/combine_apc.mdl"
            "vehiclescript" "scripts/vehicles/apc_npc.txt"
            "solid" "6"
            }
        }

The above sets the model of the APC (named here as Ranger), gives it the relevant vehicle script, and sets the model so that its bounding box will determine how it handles collisions. Note that it has no origins set since it will be attached to the dropship anyway. The APC itself can do little without a driver however, so a driver it will get:

    "npc_apcdriver"
        {
        "keyvalues"
            {
            "targetname" "Ranger_dr"
            "vehicle" "Ranger"
            "spawnflags" "256" // Long range behavior.
            }
        }

Now that we have a manned APC and a landing point set up, the APC just needs to be set for dropping off. This can be done by adding a few things to the dropship.

    "npc_combinedropship"
        {
        "origin" "-4650 4510 2080"
        "angle" "0 -90 0"
        "keyvalues"
            {
            "targetname" "Nomad"
            "target" "Nomad_n00"
            "landtarget" "Nomad_nLand"
            "cratetype" "-2"
            "APCVehicleName" "Ranger"
            "OnCrateShotDownBeforeDropoff" "Nomad,FlyToPathTrack,Nomad_n03,0,-1"
            "OnFinishedDropOff" "Nomad,FlyToPathTrack,Nomad_n03,0,-1"
            }
        }

landtarget sets the info_target set up before as the ship's landing point. cratetype tells the dropship it will be carrying an APC, while the next line specifies Ranger as the one it will carry. The two outputs are for if 1. the APC gets shot down before it's dropped off or 2. the drop happens without a hitch. In either case, the dropship will continue on its flight path.

Now, pick a point on your flight path where you want the ship to stop and drop off the APC. Comment out the normal OnPass and place another that uses the ship's LandLeaveCrate command, like so:

"path_track"
        {
        "origin" "-100 1720 580"
        "angle" "10 -15 0"        
        "keyvalues"
            {
            "targetname" "Nomad_n02"
            "target" "Nomad_n03"
            //"OnPass" "Nomad,FlyToPathTrack,Nomad_n03,0,-1"
            "OnPass" "Nomad,LandLeaveCrate,8,0,-1"
            }
        }

That's that. You should now have a dropship that flies onto the scene and leaves behind some firepower and once OnFinishedDropOff kicks in, it will leave as quickly as it came.

ad01_t.jpg ad02_t.jpg

Troops

Set-up

Deploying soldiers from a dropship is far trickier when using a mapadd script. You could normally:

  • Place a template NPC.
  • Set the dropship's cratetype to 1.
  • Set the NPC as the dropship's NPCTemplate / NPCTemplate(2-6).
  • Use the dropship's LandLeaveCrate or LandTakeCrate input to drop off between 1-6 soldiers, copies of the template NPC(s).
  • Set the dropship's Dustoff points to order the soldiers around once they've touched down.

However, because the template flag does not work in SMOD mapadds, soldiers cannot be dropped in the usual way. What one can do is to mimic the effect as much as possible. This section is intended to show how to accomplish just that.

For the sake of brevity, it's assumed you've already gone through the APC section above because much of it applies here. All in all, you'll need:

  • A working flight path.
  • A landing point, ideally in a wide and flat area.
  • A dropship set to cratetype 1 and prepared with the LandLeaveCrate command.

You'll also need coordinates for:

  • Each individual soldier's "dustoff" spot. This is where the soldiers will travel to once they've hopped out and touched down. Make sure they're spaced out a little; you don't need your troops blocking one another.
  • The spot your soldiers will be "spawning" from (within the dropship container). If your landing spot is in a flat area, this should be about -20 units downward from that point, and about 50 units toward the troop container's door. Some trial and error may still be needed, but shouldn't take that long.

Soldiers and Sequences

Once you have the above, create some soldiers that are hidden away and give them all unique targetnames and a squadname, like so:

    "npc_combine_s"
        {
        "origin" "-5000 -5000 -5000"
        "keyvalues"
            {
            "targetname" "Soldier01"
            "squadname" "sq_Nomad"
            "additionalequipment" "weapon_shotgun"
            "spawnflags" "256"
            }
        }
    "npc_combine_s"
        {
        "origin" "-5000 -5000 -5000"
        "keyvalues"
            {
            "targetname" "Soldier02"
            "squadname" "sq_Nomad"
            "additionalequipment" "weapon_smg1"
            "spawnflags" "256"
            }
        }

Next, some scripted_sequences are needed at the spot you want your troops to "spawn" from, with one sequence for each soldier. If you're unfamiliar with sequences, they force NPCs to play animations and are usually for in-game cutscenes and such. These particular sequences will teleport the soldiers to the dropship container and then play the soldiers' dropship animations, making them appear to hop out like they normally would. Below is a pair of sequences for the two soldiers:

"scripted_sequence" // First Overwatch soldier exits Nomad's troop container.
        {
        "origin" "-269 1763 -120"
        "angle" "0 270 0"
        "keyvalues"
            {
            "targetname"     "seq_Nomad_Deploy01"
            "m_iszEntity"     "Soldier01" // This is the NPC we want to manipulate with this sequence.
            "m_iszIdle"     "Idle1" // Play this anim while waiting for BeginSequence, or before using Entry/Play.
            "m_iszPlay"     "Dropship_Deploy" // Once the BeginSequence is used, play this animation.
            "m_fMoveTo"     "4" // The soldier will be teleported to this sequence once BeginSequence is used.
            "spawnflags"     "228" // AI is essentially disabled.  Won't engage enemies, etc. while grabbed by the sequence.
            "OnEndSequence" "AIS_Soldier01_Go00,StartSchedule,,0,-1" // After hopping out, move to dustoff point and make room for the next guy.
            "OnEndSequence" "seq_Nomad_Deploy02,BeginSequence,,.35,-1" // A little after touching down, Soldier #2 should begin hopping out.
            }
        }
    "scripted_sequence" // Second soldier exit's the troop container.
        {
        "origin" "-269 1763 -120"
        "angle" "0 270 0"
        "keyvalues"
            {
            "targetname"     "seq_Nomad_Deploy02"
            "m_iszEntity"     "Soldier02"
            "m_iszIdle"     "Idle1"
            "m_iszPlay"     "Dropship_Deploy"
            "m_fMoveTo"     "4"
            "spawnflags"     "228"
            "OnEndSequence" "AIS_Soldier02_Go00,StartSchedule,,0,-1"
            }
        }

If you read it thoroughly, you'll notice two of the outputs call for StartSchedule inputs, which are for aiscripted_schedules. Those will be covered later but for now, we've got what we want. Next, add an OnFinishDropoff output to the dropship that will begin the first soldier's landing sequence, like so:

    "npc_combinedropship"
        {
        "origin" "-4650 4510 2080"
        "angle" "0 -90 0"
        "keyvalues"
            {
            "targetname"         "Nomad"
            "target"             "Nomad_n00"
            "landtarget"         "Nomad_nLand"
            "cratetype"         "1"
            "OnCrateShotDownBeforeDropoff" "Nomad,FlyToPathTrack,Nomad_n03,0,-1"
            "OnFinishedDropOff" "Nomad,FlyToPathTrack,Nomad_n03,0,-1" // 
            "OnFinishedDropoff" "seq_Nomad_Deploy01,BeginSequence,,1,-1" // First soldier deploys from the container.
            }
        }

You should now have a result like that pictured below. Not done quite yet, but it's close.

td0101_t.jpg td0102_t.jpg td0103_t.jpg

Paths and Schedules

Now that the soldiers are deploying, let's set up the dustoff points they'll use once outside the container. You should already have the trace coordinates from before, so use those to create one path_corner node for each soldier. Below is the first soldier's node from the example script:

"path_corner"
        {
        "origin" "-320 1190 -82"
        "angle" "0 270 0"
        "keyvalues"
            {
            "targetname" "Soldier01_n00"
            }
        }

The guy isn't going to read your mind and go there automatically though. One way to order him to the point is through an AIscripted_schedule, like that shown below.

"aiscripted_schedule"
        {
        "keyvalues"
            {
            "targetname"    "AIS_Soldier01_Go00"
            "m_iszEntity"    "Soldier01"
            "forcestate"    "2"                 // Prep for potential contact.
            "goalent"        "Soldier01_n00"        // This is our target.
            "schedule"        "2"                    // The target is something we want to run to.
            "interruptability" "2"                 // Advance at all costs.  Order will only be interrupted by the soldier's death.
            }
        }

This schedule as well as the second soldier's are put into action by our sequences' OnEndSequence outputs, if you'll recall. So once the soldiers finish touching down, they'll move to their respective dustoff points.

That should be a wrap on how to use soldiers with dropships. The script won't be anything spectacular on its own just yet, but it will give you a good start. The rest is left to you.

td0201_t.jpg td0202_t.jpg

Rollermines


Dumping a payload of mines from a dropship is dead easy compared to the other cargo. Because the ship's DropMines command doesn't depend on templates or other entities, there isn't extra work needed for it. Mind that rollermines deployed in this way will come out one by one, not all at once. Also, ensure that you precache npc_rollermine if it's not already in the map or you're likely to get stuttering when the mines begin to drop.

Now, to set it up all you really need is a working flight path and something to trigger your ship's DropMines input. Below, a path_track that uses an output to drop 8 mines.

    "path_track"
        {
        "origin" "-400 1720 580"
        "angle" "10 -15 0"        
        "keyvalues"
            {
            "targetname" "Nomad_n02"
            "target" "Nomad_n03"
            "OnPass" "Nomad,FlyToPathTrack,Nomad_n03,0,-1"
            "OnPass" "Nomad,DropMines,8,2,-1"
            }
        }

Simple enough!

md01_t.jpg md02_t.jpg

Wrap-Up

The purpose of this page along with the other mapadd pages, is to serve as a starting point for your own script ideas. Keep in mind that just about anything's possible, it's just a matter of figuring how to get there.

The example scripts this article is based on can be downloaded below for reference. Simply rename the one you want to see in action to gm_construct.txt.

downloadac.png


Customization

Mapadd Command Reference (Non-LUA)Command Reference (LUA)Getting StartedPorts 'n' Doors
Alarm, Alarm!Color Correction in SMODDoor BreachingMobile APCsWorking With Dropships
Supply Drop (LUA)Countdown (LUA)
kh0rn3's Mapadd Generator
Scripts addcontentsoverride_classsmod_custom_explosivesmodaclistSMOD Soundscripts

npc_gib_modelnpc_replace_modelnpc_shieldsetnpc_weapon_randomizenpc_weaponweight

excludeweaponsweapon_categoryweapon_customConsole Command List
Other Crosshair CustomizationGenerating AI NodesUsing the NodemakerSubViewCam
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License