npc_apache help

Likely so that a level designer can fine-tune the apache’s behavior to the level at hand. AI is a finicky thing.

And yeah, documentation would be nice.

The Apache really is no worse than the Hunter-Chopper in Half-Life 2 when it comes to setup. The difficulty is really in deciphering how it’s set up, particularly since at the time of this writing, the boss battle in Surface Tension bm_c2a5c doesn’t decompile correctly.

My level, Bravado, makes heavy use of the Apache. I put my original .vmf inside the .vpk file so others can understand how it works. But here are some observations. Some of this is based on the Hunter-Chopper, others based on using developer 2 in Surface Tension (specifically the map bm_c2a5c) or looking at the decompiled .vmf in Notepad++.

  • First off, the npc_apache is missing a number of spawnflags. Among them is the ability to use it as a Template NPC, which is how it works in bm_c2a5c. In Hammer, you can turn off SmartEdit and manually enter 7424. Hammer may set that number as 0, but it’s been saved, don’t worry. 7424 will create four “???” Flags. Other than Template NPC, I couldn’t tell you what they do, but they are important.

[list][]The reason you want to set it as a Template NPC is because something about this method allows the rotor sound to work. If you use a point_template, the Apache will spawn, but under some circumstances, the rotor sound may not play (and EnableRotorSound doesn’t fix it). It seems like many Apaches in Black Mesa are already present at the start of the level.
[/
:m][]As with other Flying NPCs, the Apache follows path_tracks. So, you’ll want at least one path_track, if not a connected chain of them. Path_tracks should also have a non-zero Path Radius (allows for some wiggle room in what counts as “passing” the path_track). 64 is a good start. Orientation Type should be set to No Change. I am not certain if info_node_airs are necessary. They aren’t for a Hunter-Chopper, but I wound up using them with the Apache because they seemed to help (could be placebo effect). You’ll want to position these at each path_track and along the connections at roughly 512 units between each one.[/:m]
[*]So, on your npc_template_maker, there are a number of things you should consider doing OnSpawnNPC:

  • SetHealth. It appears that you need to manually set the amount of health on the Apache, or else it’s essentially invulnerable. Each rocket does about 100 damage to it, so in my case, I SetHealth to 550. In bm_c2a5c, it’s set as 350 and, based on reaching some path point, gets set to 200 more.
  • DisableMinigun. This is the Apache’s machine gun, its base weapon. You can send EnableMinigun when you want it to start firing.
  • DisableRockets. This prevents the Apache from doing its double-rocket attack. In bm_c2a5c, EnableRockets occurs OnDamaged, with a 2 second delay (so the player doesn’t immediately get a rocket to the face when it’s switched on!). This also causes the Apache to play a warning noise.
  • DisableRocketBarrage. This prevents the Apache from doing its crazy multi-rocket assault thing. I never enabled this in my level. In bm_c2a5c, EnableRocketBarrage occurs when it reaches some path_track (likely a distant one).
  • SetRocketTarget (parameter: !player). This should happen .1 seconds after DisableRockets, and certainly before EnableRockets. Makes the player the target of the rockets.
    [/:m][]To make the Apache move around, there are two main ways of doing this:
  • FlyToSpecificTrackViaPath (parameter: a path_track). If you want the Apache to automatically move along a chain of path_tracks, give it the name of the path_track at the end. It will trace backwards from that and follow the previous path_tracks to get here.
  • SetTrack (parameter: a path_track). This tells the Apache to move to this path_track. If there’s only one path_track, it will basically hover there. (Note: I haven’t tried the following, but I’m assuming this based on the Hunter-Chopper): If there’s more than one path_track connected to this, the Apache will move between them based on its AI, which can be influenced by the ChooseNearestPoint and ChooseFarthestPoint commands - in this way, you can make it move with the player, but along a pre-defined path.
    [/:m][]To get the Apache to focus on the player:
  • Set up an ai_relationship with the Subject as the Apache, Target as !player, Disposition as Hate, and Priority to some positive number. You can have this Start Active, or use ApplyRelationship when you want the Apache to start attacking.
  • Create an aiscripted_schedule with the Target NPC as the Apache, Set Enemy to Goal Entity as the Schedule to Run, and the Goal Entity to !player. Also set Interruptability to Death. When you want the Apache to focus on the player, send this entity a StartSchedule input. This will make the Apache focus doggedly on attacking the player. It actually does a good job of leading the player too, even when the player can’t be seen.
    [/:m][]You can trigger the Apache to do smoke effects by using ForceIncrementDamageEffectLevel (parameter: 1). I did this OnHalfHealth. This also causes the Apache to play an alarm sound, signaling that it’s near death. I think there may be two levels of effects you can do (i.e. you can do this command again to get even more effects).[/:m]
    [
    ]The Apache’s death is a tricky thing. If you’ve made it this far, you’ll probably notice that the Apache doesn’t die. It will sit there, smoking away, and keep attacking you no matter how many rockets you throw at it. There are two parts necessary for the Apache to die:
  • First, you need to use the Apache’s OnWishToDie input to send it the command SelfDestruct. This puts it into a death spiral and starts it flying toward an info_target_helicoptercrash. (This is something that diverges from how the Hunter-Chopper works. For one, the Hunter-Chopper doesn’t need a crash point, but the Apache requires it. Secondly, sending a second SelfDestruct command to the Hunter-Chopper causes it to immediately blow up. That’s a failsafe that’s missing on the Apache, unfortunately, which leads to my second point).
  • Once the Apache reaches the info_target_helicoptercrash, it will explode. You can use the OnCrashed output of the info_target_helicoptercrash to do this when this happens. You must have an info_target_helicoptercrash in a reachable location. Otherwise, the Apache won’t stop exploding (which goes back to what I said before - the Hunter-Chopper had failsafes for this kind of thing).

[list][]Okay, so “reachable location.” You can’t just put the info_target_helicoptercrash just anywhere. It has to be near some collision for the Apache to slam into (func_clip_vphysics can be used for invisible collision). Preferably, this should be on the ground. As I’ve learned, walls are problematic. The Apache’s fuselage gib is so enormous, it will likely get caught in the wall. You’ll see in my map that I did a hacky workaround for this, where I use a trigger_once around the info_target_helicoptercrash to Kill the Apache and then spawn my own gibs in a predictable manner. Why did I do this instead of putting it on the ground? Because I didn’t build the arena with this in mind, so there’s a whole lot of potential obstructions to reaching the ground.
[/
:m][/list:u][/*:m][/list:u]

Is there a good reason why npc_template_maker is preferred over point_template?

I had issues with the rotor sound not playing when I used a point_template.

For most other things, I use point_templates. I used to use npc_template_makers a lot, but point_template really streamlines things much better. My only reason to use npc_template_makers now is if if I need to replenish enemies from varied spawn locations (using the info_npc_spawn_destination feature).

Also, they come in handy when using the env_xen_portal_template, which is the Black Mesa entity which spawns enemies with all the green teleporting effects automatically!

I almost never use plain npc_makers (or, likewise, the env_xen_portal). Mostly because I like to imbue my NPCs with a little personality and scripting, and having each one be a distinct setup is helpful for that.

I’m not really a part of this conversation, but I thought all that information was very interesting – thank you Maki for taking the time to post all those technical details, and while we’re at it , let me say I really liked your Bravado map! One of the few peccadilloes I have with Black Mesa is that Apache death animation. In the original Half Life, and with the aerial enemies in Half Life 2, I think some of the most satisfying moments were watching them go down differently and randomly depending on all the variables. It gives those fights great replay value and seems a lot more realistic than the current death animation in which the Apache sort of…“belly-dances” while it makes a suicidal beeline for the rockface. Based on what you mentioned about the huge gib of the Apache “corpse” and the problems of it getting stuck or potentially obstructing the player if it goes down randomly, I’m assuming that’s why the devs had to hard code the death scenes as such, correct? You said though that the Hunter-Chopper from HL2 had a failsafe SelfDestruct which caused it to explode eliminating this problem…I wonder why that is not present in the Apache? It seems like that would be the perfect solution (then again, I know nothing of the inner workings of the game and what other technical challenges might be present). Anyway, not trying to be unduly critical. The Apache showdown in Surface Tension is still badass on the whole…and it will be even more fun to fight when that glitch of the rockets ricocheting off it is fixed :slight_smile:

The apache’s rockets still target the player, even if the SetRocketTarget command is used on a different enemy.

Yes, the Hunter-Chopper and Combine Gunships both have a failsafe for if they can’t get to the crash point. When their hitpoints are depleted, they automatically go into their death spiral and begin heading toward an info_target_helicopter_crash if one exists. Now, sometimes, they’ll explode on their own when they reach the crash point, but this isn’t a guaranteed event (it might, like the Apache, be based on hitting collision or something). So, as a failsafe, you can surround the crash point in a trigger_once for NPCs which calls SelfDestruct when triggered. As a second failsafe to that, you can also have SelfDestruct ready to go on a logic_timer or logic_relay that occurs OnShotDown, just in case you need to blow it up based on time because it got stuck on the way there.

There seem to be multiple differences with the Apache. It seems to default to either infinite or extremely high health. It will never go into the death spiral on its own. It requires a crash point. And it doesn’t obey SelfDestruct. Also, like I said, that fuselage gib is enormous. In the context of the cliffs in Surface Tension, there’s really not a problem with that, but anywhere else, that thing has a risk of blocking critical paths and generally getting in the way. And since there’s obviously no Gravity Gun, that’s kind of a problem when it happens! :slight_smile:

It also has misleading flags and outputs in the FGD which aren’t used in the boss battle at all, like Enable Boss Stage Outputs and the mBossStage stuff. Suggesting that, for whatever reason, the Apache’s been through quite a lot of programming and reprogramming.

Founded in 2004, Leakfree.org became one of the first online communities dedicated to Valve’s Source engine development. It is more famously known for the formation of Black Mesa: Source under the 'Leakfree Modification Team' handle in September 2004.