This tutorial will show you how you can use
models (.mdl) for the health/HEV chargers (
func_healthcharger
/
func_recharge
), which are normally
brush entities. You need to use ZHLT compilers (or its descendants) to properly swap the brush entities' brush models with .mdl files. See the accompanying vault item for models and a sample .rmf using the methods described in this tutorial.
This tutorial requires
no custom coding and is intended to work entirely within the confines of vanilla Half-Life's behaviour. Therefore switching skins the usual way or controller bones is out of scope of this tutorial.
The gobbledygook
You can safely skip this section. Go ahead.
We will be exploiting the overlap in the way the engine handles brush models and studio models.
- Brush models are what brush entities normally use. Every compiled bsp file contains one or more brush models, with the first one being the world itself.
- Studio models (so called because Valve used 3D Studio Max) are what point entities normally use e.g. NPCs, weapons, and ammos.
Interestingly in the engine code, the way the engine loads and handles the two have overlaps with regards to the properties. The relevant ones are listed below:
Keyvalue |
Brush model |
Studio model |
frame |
Normal or activated texture (0,1) |
Progress of current animation (0-255) |
skin |
Contents (empty, solid ,water, etc) |
Skin |
As you can see, the way the engine switches texture differs between brush and studio models. With that in mind, we need to prepare our studio model to cater to the way the engine handles brush models. As the health/HEV chargers change the frame value between 0 and 1, the studio model therefore has to be in an animation sequence where at 0/255th of the animation sequence the model shows the ON state, and at 1/255th the OFF state. This translates to using duplicate polygons for the ON/OFF states parented to different bones that moves in the sequence instead of using skin groups.
As for the brush entities, the
model
keyvalue can be set to point to a
.mdl
file, but care should be given to ensure it's precached by an earlier entity. Using ZHLT's
zhlt_usemodel
keyvalue guarantees this. Also, most (but not all!) brush entities will accept key values intended for studio models (e.g.
cycler
entity) such as
body
,
sequence
,
framerate
etc. For this tutorial we will be setting our
sequence
value this way. Most importantly,
angles
(Pitch Yaw Roll) rotates the entity for
func_healthcharger
/
func_recharge
and thus can be used to orient the models properly.
Preparing the model
In order to have the model work for brush entities, it needs to have an animation where the 0/255th of the timeline represents the ON state and 1/255th of the timeline represents the OFF state. For this we need:
- Both ON and OFF state textures (i.e.
+0
and +A
prefixed textures) as materials.
- 2 or more bones, with 1 being the root bone.
- A duplicate of the faces where the texture changes between the ON and OFF state. The original faces should have the OFF material, and vice versa.
- Faces with the OFF material is parented with the rest of the model to the root bone.
- Faces with the ON material is parented to the second bone.
- At 0/255th of the animation the second bone is positioned so that the ON material is at the front (just 0.1u in front of the rest of the model should work.)
- At 1/255th of the animation the second bone is positioned so that the ON material is at the back and thus the OFF material is visible.
To get the faces to be where it needs to be at the exact fractions of the sequence you can use 2 methods:
- 2-frame animation, where the second frame has the ON material bone position extrapolated (e.g. between 0.1 and -32.0 on the X axis, the bone will be surely be <0.0 at 1/255th of the sequence.)
- 256+ frame animation, where the second frame has the ON material bone positioned safely away from the visible part and remain there for the rest of the animation. Use more frames to be sure.
Other important properties:
- The model should face East (positive towards X axis) when placed in a map with the Yaw value 0, usually using
$origin <x> <y> <z> <r=270>
QC command.
- The origin of the model and the brush entity should agree. It should be vertically centered as that's where the health/HEV chargers would actually be. The easiest way is to have the origin at dead center, so that it aligns perfectly with the exact center of the equivalent brush version of the health/HEV chargers (by way of converting the normal brush to an ORIGIN brush.)
Optional properties (recommended for versatility, but not required for this tutorial):
- An idle animation with the ON material in front
- ON/OFF skin groups
This tutorial will not be touching on modeling or animation aspects. Please consult
The303's modeling tutorial for modeling for GoldSrc.
A model from the vault. The OFF faces are hidden behind the model
On the second frame, the faces switch place and remains there till the end.
Using the models in the map
This tutorial supposes that the models you've prepared in the previous section has the following sequences:
0
: idle (ON faces always visible.)
1
: onoff (OFF faces visible at exactly 1/255th of the sequence) – we will use this sequence.
Part A: Template entity[ies]
- Create a
monster_furniture
or cycler
entity for each model you want to use. Give it a name.
- Set the entity's model to one of the models.
- Put this entity someplace inaccessible in the map.
Part B: func_healthcharger
/ func_recharge
entities
- Place down a brush the size of the normal health/HEV charger (32w 48h 8d) where you want them to be. You can even use prefabs, provided they are of the basic single brush variety.
- Turn the brush into an ORIGIN brush: apply the ORIGIN texture to all faces of the brush.
- Tie the brush to entity (
func_healthcharger
/func_recharge
).
- Set the entity's
angles
(Pitch Yaw Roll) to face perpendicularly away from the wall.
- Turn off SmartEdit mode and add the following keyvalues:
zhlt_usemodel
= <name of template entity>
sequence
= 1
(index of the sequence as set up earlier)
Part C: Lighting and clipping
- To add clipping, place a
CLIP
brush with the size of the chargers (usually 32w 48h 8d) overlapping the ORIGIN-textured brushed placed down earlier.
- To have the model take a more fitting lighting (rather than taking the lighting off the floor, see Tutorial: models and lighting for more info), add a small brush textured with
black_HIDDEN
just below the origin brush from Part B. Tie this brush to a func_detail
entity and set "Passable" to Yes. Then add a light
entity slightly above this brush and with values 255 255 255 5
(adjust brightness to taste).
Result
No props; these are the actual, fully-functional func_healthcharger
/ func_recharge
entities.
See also the linked vault below.
References
Vault
Loading embedded content: Vault Item #6897