This tutorial will show you how sequence events trigger entities in maps, how to setup a map to use it, and how to add events to a sequence.
For this tutorial you'd need:
What we'll learn from this tutorial:
- How sequence events work
- How to trigger entities using sequence events
- How to add sequence events with HLAM or QC script
- How to watch out for side effects
Preface
You will be familiar with the Barney at the Sector C lobby, who swivels his chair back and forth as he alternate between reading some manual and typing into his computer.
However, when you look at the map (which comes with the Half-Life SDK by the way) there is nothing triggering his chair, a
func_door_rotating
named
introchair
. So how is the chair moving on its own?
Nothing points at the chair in the editor...
...And the entity report proves it
Actually, Barney's animation "
sit1
" used in one of the
scripted_sequence
entities is triggering the chair to swivel back and forth. How so? With sequence events.
What are sequence events? How does this work?
Sequence events are pieces of data associated with a particular frame of a sequence (aka animation). It has an event ID and a options value.
You see it in action with the footsteps fellow scientists make as they walk, a few of their dialogues, the beeps and boops of buttons pressed by Barneys, and muzzleflashes at the ends of barrels of NPCs. It's also used on attack animations to time the exact frame of the animation that the NPC deals damage. It's used for a plethora of things. A list of common and per-NPC events are available on
The303's QC reference page.
But the event we'll be focusing on in this tutorial is the event number 1003. This event takes as its options value a string that is a name of an entity in a map. At the exact frame of that event in the animation, the game triggers (more exactly toggles) entities with that name.
If we look at Barney's "
sit1
" animation in Half-Life Asset Manager, we will see that it has 2 of such events, both with the options value
introchair
. And with that, the puzzle pieces come together: A
scripted_sequence
takes
barneyatdesk
to perform the "
sit1
" animation, and within the animation event 1003s trigger the swivel chair, and that toggles the chair (actually a
func_door_rotating
) to move back and forth (or rather, open and close because it's actually a door.)
This is a powerful feature as it allows frame-perfect triggering of entities in the level synchronized to the animation, without having to mess with timings using trigger delays or
multi_managers
.
Using Event 1003s
To use the feature is pretty straightforward.
First use HLAM to open the model file associated with the target NPC. For a list of models associated with which NPC entity, take a look at
Reference: Entities and their models.
It should be noted that the expansion packs contain animations not present in Half-Life. You might want to copy over those models instead of using the ones from Half-Life to use in your mod.
Then find the sequence you want to use. Once you find them, see if it has any event with ID 1003. If it has then it's simply the case of copying the name, and pasting it to the appropriate entity you want to get triggered. In the case that there isn't, read through to the next section where we will add events to the model's sequence.
Last is to setup a
scripted_sequence
. If you're not familiar, here's
an overview. Basically you want to target an NPC whose model contains the animation with event 1003s, and put the name of that animation as either the idle or action animation, as the case may be.
Example
For an example setup, we will create a new map with a blank room in JACK and place in it the following entities:
- a
monster_barney
named ben
- a
func_door
named the_door
- a
func_button
with the following properties:
- name:
button
[Barney's animation buttonpush
targets this.]
- target:
the_door
- a
scripted_sequence
with the following properties:
- name:
plsopen
- target monster:
ben
- action animation:
buttonpush
. [This animation will target button
.]
- a
trigger_once
targeting plsopen
An overview of the setup
Notice that nothing targets
button
, but when we compile and run the map, running into the
trigger_once
makes ben play the animation
buttonpush
, and
button
gets triggered as
buttonpush
is being acted. This is event 1003 at work.
💡 Make event 1003s target a
trigger_relay
or a
multi_manager
to ensure only the selected monster can trigger things (contrast to buttons and brush triggers which can be triggered by players.)
Adding events to sequences
Using HLAM
Adding events to sequences is really easy using HLAM.
- Open the model.
- Using the Sequence widget, navigate to the desired sequence.
- Scrub through the animation timeline to find the frame where you want an event to happen. Round the value and take note of it.
- Under Events, press the green plus button.
- Enter the frame number, event ID number, and the options value. For event 1003, the options value is the name of the entity to trigger.
- Repeat for any number of events you wish to add. Save the model when you're done.
Now you can use the animation in scripted_sequences and have the animation trigger entities in your map.
Using QC script
If you already have a QC file that you compile into models, here's how to add an event to a
$sequence
.
First, rewrite the
$sequence
entry to have the following form (newlines included):
$sequence "<name of sequence>" "<name of smd file>" {
fps <value>
// events go here
// other stuff goes here
}
Then you'd want to play through the animation timeline to get the frame number where the event should occur. You can do this in your modelling software or with HLAM. Now that we have the frame number we can insert the event entry like this:
$sequence "<name of sequence>" "<name of smd file>" {
fps <value>
// events go here
// event 1003: trigger entities in map
{ event 1003 <frame> "<target in map>" } // triggers <target in map> on frame <frame>
// other stuff goes here
}
Note that the whitespaces between the curly braces and the content are significant. studiomdl will fail to parse the entry or even error out if there's no whitespace.
Repeat the above steps as required for the event IDs you wanted. Save the QC file once done.
Now compile the model and review the model in HLAM (reload if it's already open). The sequence should have the events as specified, at the specified frames.
🤔 If you're adding events to a stock sequence, consider duplicating the sequence to a name unique to the map e.g. "<mapname>_do_thing" and add events to it. That way stock animations and their events continue to work for Half-Life, and you don't accidentally use the stock animation and accidentally trigger things in your map with the event 1003s.
Caveats
- Using stock animations containing event 1003s in
scripted_sequences
may have unintended side effects, if any entity in the map matches the value of the animation event. Therefore it's always prudent to check the animation with HLAM for event 1003s, and avoid that name for any entity in the map if the animation is not intended to trigger anything.
- It's preferable to duplicate a sequence to use a unique name that's called only on a single map so that you can customize the sequence events as desired and minimizing side effects mentioned above.
References
Vault
Loading embedded content: Vault Item #6851