.qc scripts are simple text files, edited in Notepad, and are needed to compile a model. They tell studiomdl.exe where the mesh, textures and animations are but more importantly sets up parameters that Half-Life will need. Some of these interact with the monster's intelligence code, the animation engine, swap skins or body parts, play sound files, spawn sprite animations or beam effects, and can even trigger events in a map. Keep in mind that your model may need code written to handle these features; they can't just exist and work from the model. This describes the most common commands, and gives examples of script files that can be a basis for most others.
Studiomdl Commands
First is a list of the common commands for studiomdl, with parameters, a description, and an example:
$modelname <path>
This tells studiomdl where to put the final compiled model.
example: $modelname "C:\Half-Life\valve\models\player\Gordon"
$cd <path>
This directs studiomdl to start in this folder when looking for files. It's the same as DOS' "change directory" command.
example: $cd "C:\Half-Life\valve\models\source\Gordon"
$cdtexture <path>
This tells studiomdl where the textures are if they're in a separate folder from the mesh.
example: $cdtexture "C:\Half-Life\valve\models\source\Gordon\textures"
$externaltextures
This tells studiomdl to save skin textures as a separate *t.mdl file. The reason is skins only have to be loaded into memory when this model is in the player's view.
example: $externaltextures
$cliptotextures
This tells studiomdl to compile the skin textures in with the model. It's most commonly used with player models.
example: $cliptotextures
$scale #
This resizes the model up or down. If you want it smaller, make it less than 1; or more than 1 to make it bigger.
example: $scale 1.2
$origin <X> <Y> <Z>
This offsets the model's origin so, for example, it's feet are really on the ground. This is an easy fix if it wasn't done correctly when the model was made. It can also be put throughout the .qc file to offset a model or animations. It's mostly used for player models and weapons.
example: $origin 0 0 36
$eyeposition <X> <Y> <Z>
This is for monsters to tell the game where their eyes are in reference to their origin. The origin is usually taken from the model, or can be redefined in the .qc file.
example: $eyeposition 0 0 65
$body <smd name> [reverse]
This is the reference .smd file for the model; the basic model with a skin. It can include the reverse command, which flips all of the face's normals around. Reverse is used -only- in case problems occur exporting and normals are reversed by 3D Studio Max.
example: $body studio "monster" reverse
$bodygroup <groupname> {smd groups}
This lets your model have interchangeable parts. This example has a monster that can hold a shotgun, mp5 or neither. The same setup can be used for interchangeable heads. Don't include the .smd extension.
example:
$bodygroup weapons
{
studio "shotgun"
studio "mp5"
blank
}
$texturegroup <groupname> {bmp groups}
This lets your model have interchangeable skins. This example shows how the normal body skin and normal head skin is replaced by a pain skin for each. Be sure to include the .bmp extension.
example:
$texturegroup pain
{
{ "body_normal.bmp" "head_normal.bmp" }
{ "body_pain.bmp" "head_pain.bmp" }
}
$renamebone <old bone name> <new bone name>
Character Studio versions 2.x and higher used different names for some of the Biped's bones. If you mix models or animations from earlier versions then they need to be called the same thing. This command let's you easily rename all of them during the compile, instead of having to rename them in each .max file.
example: $renamebone "Bip01 R Clavicle" "Bip01 R Arm"
$include <.qc filename>
This tells studiomdl to include another .qc file in the compile.
example: $include "C:\Half-Life\valve\models\player\player_shared.qc"
$attachment <#> <bone> <X> <Y> <Z>
These are points referenced from bones that sprite effects are spawned from, usually muzzleflashes for weapons. See the event command for more details about sprites. The coordinates are offset from the bone, not the model's origin.
example: $attachment 0 "Bip01 R Hand" 20 2 5
$controller <#> <bone> <axis of Rotation> <limits of rotation>
This allows the game to control the rotation of bones. The most obvious example is a monster's head, in example 1. This allows the game to rotate the head from -60 degrees to +60 on the X axis. Example 2 shows how the mouth controller is set up so that this monster can talk.
example 1: $controller 0 "Bip01 Head" XR -60 60
example 2: $controller mouth "Bone03" ZR 0 45
$hbox <group #> <bone> <X> <Y> <Z> <X> <Y> <Z>
These define hitboxes, which are invisible boxes around each bone used to determine where the model is being shot at. They are divided into 8 different groups listed below. All bones belonging in each group are defined to that hitbox group. The two examples below show the leg and foot being assigned to the same group, # 7.
example: $hbox 7 "Bip01 R Leg1" 0.31 -3.97 -2.84 17.60 3.94 2.97
example: $hbox 7 "Bip01 R Foot" -0.56 -2.34 -2.19 3.81 8.00 2.66
Hitbox Groups: | | | | 0: Generic | 2: Chest | 4: Left Arm | 6: Left Leg | 1: Head | 3: Stomach | 5: Right Arm | 7: Right Leg |
The two sets of coordinates are for one corner point of the box, and the opposite corner point. An easy way to get these coordinates is to run studiomdl with the -h flag and have it output to a text file like this >hitboxes.txt. Your .qc file only needs the path and filename of your reference model.
example: studiomdl.exe -h gordon.qc >hitboxes.txt
You can see the hitboxes with the model viewers, or in Half-Life using the r_drawentities 3 command described in my list of href="http://www.thewavelength.net/content/index.php?act=ST&f=41&t=163&s=">console commands.
$sequencegroupsize <# in KB>
This separates the animations from the mesh into smaller files. The reason is that animations can be loaded into memory only when needed, instead of having to load everything in whether or not it's used. It's most useful for monsters with scripted sequences.
example: $sequencegroupsize 64
$sequence <name> "smd" [motion extraction] [fps <#>] [blend <axis> <start> <end>] [origin <X> <Y> <Z>] [scale <#>] [loop] [frame <start> <end>] [<activity> <multiplier>] {event <#> <frame> <options>}
This is just an animation file, but it's by far the most complicated command. It includes many other commands, which are detailed below. Then below those are href="#$sequence examples">examples using the $sequence command.
Here are the sub-commands for $sequence:
[motion extraction] This is to extract out motion from animations such as walking and running. The most common options for this are: X, Y, LX, and LY, which are for movement along the x and y axis. LX and LY are for linear movement. I've found that X and Y work equally as well as LX and LY. You can extract from one axis or combine them, and even from the Z axis. This motion will be used in Half-Life to move the monster.
[fps <#>] This sets the frames per second that the animation plays at, if you want to adjust it here.
example: fps 15
[blend <axis> <start> <end>] You can list two .smd animations and blend them together. This is useful for shooting because you can animate at two extreme angles and the game blends between them to aim and shoot in the right direction. This example blends from -45 to +45 degrees on the X-axis. It seems the angles are very important but the axis is almost arbitrary.
example: blend XR -45 45
[origin <X> <Y> <Z>] Same idea as $origin but only applies to this animation.
example: origin 0 0 13
[scale <#>] Same idea as $scale but only applies to this animation.
example: scale 1.3
[loop] Indicates that this animation loops.
example: loop
[frame <start> <end>] This limits the frames that are used from the smd file, to make post-editing easier.
example: frame 5 10
[<activity> <multiplier>] AI-controlled activities. The game automatically runs these animations without extra code. This example has act_range_attack2 chosen since there are 2 types of range attacks, with a multiplier of 3. This means there can be several animations using this activity, and this one will be randomly chosen 3 times more often. Valve's Modeling Tutorial has a complete listing of these actions.
example: ACT_RANGE_ATTACK2 3
{event <#> <frame> <options>} Animation events. These vary quite a bit, but are the most fun. Events can call either a sound, sprite, map trigger, or a programming code event that can do whatever you'd like.
example 1: { event 5004 1 "weapons\shoot.wav" }
Event 5004 plays this sound on frame 1. Include the path starting from your mod folder.
example 2: { event 5001 1 "20" }
Events 5001, 5011 and 5021 are for sprites, particularly muzzleflashes for weapons. This example plays the mp5 sprite, muzzleflash1.spr on frame 1. "20" indicates that sprite # 0 is scaled 2 times larger than normal. Below is a chart of muzzleflash sprites with the number that they are assigned to and what they're used for:
sprite number: name - use | | | 0: muzzleflash1.spr - mp5 | 1: muzzleflash2.spr - shotgun, pistols | 2: muzzleflash3.spr - hornetgun |
An attachment point needs to be defined for these to show up in Half-Life. Event 5001 has it's origin at $attachment 0, 5011's origin is at $attachment 1, and 5021's origin is at $attachment 2.
example 3: { event 5002 10 "5" }
Event 5002 is for sparks. Here it plays on frame 10 and is scaled up 5 times. It's origin is the lowest attachment number, zero, unless you don't define zero. Then it will be at $attachment 1.
example 4: { event 7 2 }
This simply plays event # 7 on frame 2. Event 7 can be anything. This needs to be defined in the monster's AI code.
example 5: { event 1003 20 "bigexplosion" }
Event 1003 actually triggers a sequence to happen in a map, this one called "bigexplosion", on frame 20. These are most likely going to be part of scripted sequences and only happen once.
Here are examples for $sequence:
example 1: $sequence crouch_shoot_mp5 "crouch_shoot_mp5"
This is as simple as it gets, and is the minimum needed for it to work. crouch_shoot_mp5 is the animation name, and "crouch_shoot_mp5" is the actual animation file, without the .smd extension.
example 2: $sequence crouch_shoot_mp5 "crouch_shootdown_mp5" "crouch_shootup_mp5" blend XR -30 40 fps 20 origin 0 0 18 loop ACT_RANGE_ATTACK1 2 { event 5001 0 "40" }
This is how complicated the same animation can get. crouch_shoot_mp5 is still the animation name, but "crouch_shootdown_mp5" and "crouch_shootup_mp5" smd files are being blended together to create it. Therefore the blend command is used, with the parameters of XR -30 40 to set the X-axis rotation from -30 to +40 degrees. The fps is adjusted to 20 to slow it down from the original file's setting of 30. Since this is a crouching animation, the origin is lowered to bring the model's feet to the ground. It's a looping animation so the loop flag is set, plus this is a range-attack so it's labeled as ACT_RANGE_ATTACK1. It could've also been ACT_RANGE_ATTACK2 since there are two of these attacks automatically set up in code. This activity has a multiplier of 2 so if there are others to choose from, the game will randomly choose this one 2 times more often than the others. And finally event 5001, which is a muzzleflash sprite, plays on frame 0. "40" indicates that sprite number 0, or muzzleflash1.spr, is scaled 4 times larger than normal.
example 3: $sequence shoot "shoot" { { event 5001 1 "20" } { event 5004 1 "hks1.wav" } }
This example uses events to show a muzzleflash sprite and play a sound for a weapon shooting.
That wraps up the $sequence command, and all the common commands for studiomdl. Next are example scripts.
Example Scripts
Here are some complete example scripts that can be used to get started with. My comments are in red and usually follow the line they refer to.
Player Models
//=====================================================
// Dukowski multiplayer model
//=====================================================
$modelname "C:\Half-Life\valve\models\player\Dukowski\Dukowski.mdl"
// This is where the final model is compiled to.
$cd "C:\Half-Life\valve\models\player"
// This is the root folder where models and animations should go.
$cdtexture "C:\Half-Life\valve\models\player\dmatch\Dukowski"
// This indicates that the textures are in a separate folder. They don't have to be separate though. color="#000000">
$cliptotextures
// $cliptotextures tells studiomdl to compile the textures in with the model.
$scale 1.0
// Scale is kept at 1:1 from the original model.
$origin 0 0 36
// Multiplayer models' origins need to be this so their feet are on the ground.
$bodygroup body
{
studio "..\dmatch\Dukowski\Dukowski"
// This is the reference model. A high and low res version of the model can go here.
}
// Rename Character Studio R2 bones, if there are any.
$renamebone "Bip01 L Thigh" "Bip01 L Leg"
$renamebone "Bip01 L Calf" "Bip01 L Leg1"
$renamebone "Bip01 R Thigh" "Bip01 R Leg"
$renamebone "Bip01 R Calf" "Bip01 R Leg1"
$renamebone "Bip01 L Clavicle" "Bip01 L Arm"
$renamebone "Bip01 L UpperArm" "Bip01 L Arm1"
$renamebone "Bip01 L Forearm" "Bip01 L Arm2"
$renamebone "Bip01 R Clavicle" "Bip01 R Arm"
$renamebone "Bip01 R UpperArm" "Bip01 R Arm1"
$renamebone "Bip01 R Forearm" "Bip01 R Arm2"
// make attachment points for muzzleflash effects
// These attachment coordinates have an X 1 after them. I assume they're for axis and direction, but I haven't
// found that changing these make a difference.
$attachment 0 "Bip01 R Hand" 20 2 5 X 1
$attachment 1 "Bip01 R Hand" 15 1.5 3.75 X 1
$attachment 2 "Bip01 R Hand" 30 3 7.5 X 1
// add backbone
// Multiplayer models' spine is controlled by the game to have that famous pelvis twist.
$controller 0 "Bip01 Spine" XR -30 30
$controller 1 "Bip01 Spine1" XR -30 30
$controller 2 "Bip01 Spine2" XR -30 30
$controller 3 "Bip01 Spine3" XR -30 30
// hitboxes
// For multiplayer models, hitboxes are defined in the player.mdl that is on the server, not in custom ones chosen
// by a client. Therefore unless you're making a server player model, you probably don't need these hitboxes.
$hbox 3 "Bip01 Pelvis" -4.69 -4.44 -6.75 4.00 5.56 6.75
$hbox 6 "Bip01 L Leg" 2.66 -3.69 -3.09 18.16 4.88 3.31
$hbox 6 "Bip01 L Leg1" 0.38 -3.97 -2.84 17.60 4.00 2.94
$hbox 6 "Bip01 L Foot" -0.59 -2.34 -2.63 3.79 8.00 2.19
$hbox 7 "Bip01 R Leg" 2.47 -3.69 -3.16 18.13 4.88 3.38
$hbox 7 "Bip01 R Leg1" 0.31 -3.97 -2.84 17.60 3.94 2.97
$hbox 7 "Bip01 R Foot" -0.56 -2.34 -2.19 3.81 8.00 2.66
$hbox 3 "Bip01 Spine1" -3.25 -5.50 -5.50 4.83 5.50 5.50
$hbox 2 "Bip01 Spine2" -0.06 -5.53 -7.59 8.00 7.00 7.59
$hbox 2 "Bip01 Spine3" -2.25 -6.81 -6.31 6.50 5.09 6.31
$hbox 2 "Bip01 Neck" -3.11 -1.50 -3.00 2.05 3.50 3.00
$hbox 1 "Bip01 Head" 0.09 -3.66 -3.00 8.41 5.09 3.00
$hbox 4 "Bip01 L Arm" 0.94 -2.88 -4.13 5.44 4.28 3.50
$hbox 4 "Bip01 L Arm1" -2.16 -2.34 -2.56 11.56 3.41 2.38
$hbox 4 "Bip01 L Arm2" 0.59 -1.81 -2.19 10.75 2.84 2.41
$hbox 4 "Bip01 L Hand" 0.00 -1.00 -2.00 3.00 1.50 3.50
$hbox 5 "Bip01 R Arm" 1.38 -2.84 -3.56 5.69 4.31 4.31
$hbox 5 "Bip01 R Arm1" -1.88 -2.47 -2.16 11.81 3.28 2.81
$hbox 5 "Bip01 R Arm2" 0.44 -1.97 -2.34 10.59 2.72 2.22
$hbox 5 "Bip01 R Hand" 0.00 -1.00 -2.00 3.00 1.50 3.50
// standard animations
$sequence look_idle "new_idle2" loop fps 14 ACT_IDLE 2
$sequence idle "new_idle" loop fps 14 ACT_IDLE 1
$sequence deep_idle "new_idle3" loop fps 12 ACT_IDLE 4
// Here are three idle animations, all called ACT_IDLE. The game can randomly pick one to play based
// on it's multiplier. deep_idle will be chosen 4 times more than the others.
$sequence run2 "new_run" LX loop fps 40 ACT_RUN 1
// LX is used to extract out the forward motion on the X-axis.
$sequence walk2handed "new_walk" LX loop fps 26 ACT_WALK 1
$sequence 2handshoot "shoot_2handed" fps 20 ACT_RANGE_ATTACK1 1
$sequence crawl "crouch_moveforward" LX loop fps 22 ACT_CROUCH 1 origin 0 0 18
// The origin is changed just for this animation.
$sequence crouch_idle "crouch_idle" loop fps 12 ACT_CROUCHIDLE 1 origin 0 0 18 rotate 8
// The rotate command is used rarely. It's parameters are simply: rotate <angle>. It's used to rotate your model
// on the Z-axis from here, instead of having to go back and reanimate it.
$sequence jump "player_jump" fps 30 ACT_HOP 1
$sequence long_jump "player_longjump" LX fps 24 ACT_LEAP 1
$sequence swim "player_swim" loop fps 14 ACT_SWIM 1 origin 0 0 0
$sequence treadwater "player_treadwater" loop fps 14 ACT_HOVER 1
$sequence run "ref_run" LX loop fps 31
$sequence walk "ref_walk" LX loop fps 31
$sequence aim_2 "ref_aimdown_twohanded" "ref_aimup_twohanded" loop fps 14 blend XR -45 45
// The blend command is used to combine these two animations. They are aiming down and up and the game
// can blend the two angles to come up with any angle in between.
$sequence shoot_2 "ref_shootdown_twohanded" "ref_shootup_twohanded" loop fps 14 blend XR -45 45
$sequence aim_1 "ref_aimdown_onehanded" "ref_aimup_onehanded" loop fps 14 blend XR -45 45
$sequence shoot_1 "ref_shootdown_onehanded" "ref_shootup_onehanded" loop fps 14 blend XR -45 45
//death animations
$sequence die_simple "die_simple" fps 22 ACT_DIESIMPLE 1 { event 2001 10 }
// Event 2001 is played on frame 10. This is a code event that makes the player dead.
$sequence die_backwards1 "die_backward" fps 26 ACT_DIEBACKWARD 4 { event 2001 14 }
$sequence die_backwards "player_die2" fps 30 ACT_DIEBACKWARD 1 { event 2001 15 }
$sequence die_forwards "player_die1" fps 26 ACT_DIEFORWARD 1 { event 2001 9 }
$sequence headshot "die_headshot" fps 24 ACT_DIE_HEADSHOT 4 { event 2001 23 }
$sequence die_spin "player_die3" fps 30 ACT_DIE_HEADSHOT 1 { event 2001 16 }
$sequence gutshot "die_gutshot" fps 26 ACT_DIE_GUTSHOT 1 { event 2001 23 }
// weapons animations
// crowbar, grenade
$sequence ref_aim_crowbar "ref_aimdown_crowbar" "ref_aimup_crowbar" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_crowbar "ref_swingdown_crowbar" "ref_swingup_crowbar" blend XR -45 45 fps 24
$sequence crouch_aim_crowbar "crouch_aimdown_crowbar" "crouch_aimup_crowbar" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_crowbar "crouch_swingdown_crowbar" "crouch_swingup_crowbar" blend XR -45 45 fps 24 origin 0 0 18
// tipmines, satchel
$sequence ref_aim_trip "ref_aimdown_trip" "ref_aimup_trip" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_trip "ref_placedown_trip" "ref_placeup_trip" blend XR -45 45 fps 18
$sequence crouch_aim_trip "crouch_aimdown_trip" "crouch_aimup_trip" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_trip "crouch_placedown_trip" "crouch_placeup_trip" blend XR -45 45 fps 16 origin 0 0 18
// 9mm
$sequence ref_aim_onehanded "ref_aimdown_onehanded" "ref_aimup_onehanded" blend XR -50 35 fps 12 LOOP
$sequence ref_shoot_onehanded "ref_shootdown_onehanded" "ref_shootup_onehanded" blend XR -50 35 fps 16 { event 5011 0 "21" }
$sequence crouch_aim_onehanded "crouch_aimdown_onehanded" "crouch_aimup_onehanded" blend XR -50 35 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_onehanded "crouch_shootdown_onehanded" "crouch_shootup_onehanded" blend XR -50 35 fps 16 { event 5011 0 "21" } origin 0 0 18
// Event 5011 is played on frame 0, using sprite "21". This is muzzleflash2.spr scaled up 2 times.
// 5011 is similar to 5001, but has it's origin at $attachment 1. color="#000000">
// python
$sequence ref_aim_python "ref_aimdown_onehanded" "ref_aimup_onehanded" blend XR -50 35 fps 12 LOOP
$sequence ref_shoot_python "ref_shootdown_python" "ref_shootup_python" blend XR -50 35 fps 16 { event 5011 0 "31" }
$sequence crouch_aim_python "crouch_aimdown_onehanded" "crouch_aimup_onehanded" blend XR -50 35 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_python "crouch_shootdown_python" "crouch_shootup_python" blend XR -50 35 fps 16 { event 5011 0 "31" } origin 0 0 18
// shotgun
$sequence ref_aim_shotgun "ref_aimdown_shotgun" "ref_aimup_shotgun" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_shotgun "ref_shootdown_shotgun" "ref_shootup_shotgun" blend XR -45 45 fps 15 { event 5021 0 "51" }
$sequence crouch_aim_shotgun "crouch_aimdown_shotgun" "crouch_aimup_shotgun" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_shotgun "crouch_shootdown_shotgun" "crouch_shootup_shotgun" blend XR -45 45 fps 15 { event 5021 0 "51" } origin 0 0 18
// Event 5021 is played on frame 0, using sprite "51". This is muzzleflash2.spr scaled up 5 times.
// 5021 has it's origin at $attachment 2.
// gauss
$sequence ref_aim_gauss "ref_aimdown_guass" "ref_aimup_guass" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_gauss "ref_shootdown_guass" "ref_shootup_guass" blend XR -45 45 fps 15
$sequence crouch_aim_gauss "crouch_aimdown_guass" "crouch_aimup_guass" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_gauss "crouch_shootdown_guass" "crouch_shootup_guass" blend XR -45 45 fps 15 origin 0 0 18
// mp5
$sequence ref_aim_mp5 "ref_aimdown_mp5" "ref_aimup_mp5" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_mp5 "ref_shootdown_mp5" "ref_shootup_mp5" blend XR -45 45 fps 20 LOOP { event 5001 0 "40" }
$sequence crouch_aim_mp5 "crouch_aimdown_mp5" "crouch_aimup_mp5" blend XR -30 40 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_mp5 "crouch_shootdown_mp5" "crouch_shootup_mp5" blend XR -30 40 fps 20 LOOP { event 5001 0 "40" } origin 0 0 18
// Event 5001 is played on frame 0, using sprite "40". This is muzzleflash1.spr scaled up 4 times.
// 5001 has it's origin at $attachment 0.
// rpg
$sequence ref_aim_rpg "ref_aimdown_rpg" "ref_aimup_rpg" blend XR -45 40 fps 12 LOOP
$sequence ref_shoot_rpg "ref_shootdown_rpg" "ref_shootup_rpg" blend XR -45 40 fps 18
$sequence crouch_aim_rpg "crouch_aimdown_rpg" "crouch_aimup_rpg" blend XR -45 40 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_rpg "crouch_shootdown_rpg" "crouch_shootup_rpg" blend XR -45 40 fps 18 origin 0 0 18
// egon
$sequence ref_aim_egon "ref_aimdown_egon" "ref_aimup_egon" blend XR -45 35 fps 12 LOOP
$sequence ref_shoot_egon "ref_aimdown_egon" "ref_aimup_egon" blend XR -45 35 fps 18 LOOP
$sequence crouch_aim_egon "crouch_aimdown_egon" "crouch_aimup_egon" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_egon "crouch_aimdown_egon" "crouch_aimup_egon" blend XR -45 45 fps 18 LOOP origin 0 0 18
// squeak
$sequence ref_aim_squeak "ref_aimdown_squeak" "ref_aimup_squeak" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_squeak "ref_shootdown_squeak" "ref_shootup_squeak" blend XR -45 45 fps 14
$sequence crouch_aim_squeak "crouch_aimdown_squeak" "crouch_aimup_squeak" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_squeak "crouch_shootdown_squeak" "crouch_shootup_squeak" blend XR -45 45 fps 14 origin 0 0 18
// hive
$sequence ref_aim_hive "ref_aimdown_hive" "ref_aimup_hive" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_hive "ref_shootdown_hive" "ref_shootup_hive" blend XR -45 45 fps 15
$sequence crouch_aim_hive "crouch_aimdown_hive" "crouch_aimup_hive" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_hive "crouch_shootdown_hive" "crouch_shootup_hive" blend XR -45 45 fps 15 origin 0 0 18
// crossbow
$sequence ref_aim_bow "ref_aimdown_bow" "ref_aimup_bow" blend XR -45 45 fps 12 LOOP
$sequence ref_shoot_bow "ref_aimdown_bow" "ref_aimup_bow" blend XR -45 45 fps 16
$sequence crouch_aim_bow "crouch_aimdown_bow" "crouch_aimup_bow" blend XR -45 45 fps 12 LOOP origin 0 0 18
$sequence crouch_shoot_bow "crouch_aimdown_bow" "crouch_aimup_bow" blend XR -45 45 fps 16 origin 0 0 18
// dead model poses
$origin 0 0 0
$sequence deadback "dead_pose_back" fps 10
$sequence deadsitting "dead_pose_sitting" fps 10
$sequence deadstomach "dead_pose_stomach" fps 10
$sequence deadtable "dead_pose_table" fps 10 |
Weapons
// w_9mmAR.qc
// mp5 world model - uses same reference model as p_9mmAR.mdl
$scale 1.3
// Scale is a little larger for world models.
$modelname "C:\Half-Life\valve\models\w_9mmAR.mdl"
// This is where the final model is compiled to.
$cd "C:\Half-Life\valve\models\world_mp5"
// This is the root folder where models and animations should go.
$externaltextures
// Only world models have external textures.
$body studio "world_mp5"
// This is the reference model.
$sequence idle "world_mp5" fps 10
// This is the reference model used for an idle animation, since world models don't animate. |
// p_9mmAR.qc
// mp5 player model - uses same reference model as w_9mmAR.mdl
$scale 1.0
// Scale is kept at 1:1 from the original model.
$modelname "C:\Half-Life\valve\models\p_9mmAR.mdl"
// This is where the final model is compiled to.
$cd "C:\Half-Life\valve\models\world_mp5"
// This is the root folder where models and animations should go. $cliptotextures
// $cliptotextures tells studiomdl to compile the textures in with the model.
$body studio "world_mp5"
// This is the reference model.
$sequence idle "world_mp5" fps 10
// This is the reference model used for an idle animation, since player models don't animate. |
// v_9mmAR.qc
// mp5 viewmodel
$modelname "C:\Half-Life\valve\models\v_9mmAR.mdl"
// This is where the final model is compiled to.
$cd "C:\Half-Life\valve\models\v_mp5"
// This is the root folder where models and animations should go.
$cliptotextures
// $cliptotextures tells studiomdl to compile the textures in with the model.
$scale 1.0
// Scale is kept at 1:1 from the original model.
$origin 2 10 8
// The origin is adjusted a little here.
$body studio "mp5sd"
// This is the reference model.
$attachment 0 "Bone09" -14 1 -0.5 X -1
// This attachment point is for the muzzleflash sprite.
$sequence longidle "long_idle" fps 8
$sequence idle1 "idle1" fps 35
$sequence grenade "grenadeshoot" fps 30
$sequence reload "reload" fps 30 {
{ event 5004 5 "mp5/cliprelease1.wav" }
{ event 5004 25 "mp5/clipinsert1.wav" }
}
// There are two sound files played. Event 5004 plays cliprelease1.wav on frame 5
// and clipinsert1.wav on frame 25.
$sequence deploy "deploy" frame 4 15 fps 12
// The frame command limits this original animation to only frames 4 to 15.
$sequence shoot "shoot1" fps 10 { event 5001 0 "20" }
$sequence shoot "shoot2" fps 10 { event 5001 0 "20" }
$sequence shoot "shoot3" fps 10 { event 5001 0 "20" }
// Here are the muzzleflash sprites for the shooting animations. Event 5001 is played on frame 0,
// using sprite "20". This is muzzleflash1.spr scaled up 2 times. Event 5001's origin is $attachment 0. |
Items
// flag.qc
// This is just like a CTF flag. Two different skins can be chosen.
$modelname "C:\Half-Life\valve\flag.mdl"
// This is where the final model is compiled to.
$cd "C:\Half-Life\valve\models\source\flag"
// This is the root folder where models and animations should go.
$scale 1.0
// Scale is the same as the original model. $body studio "flag"
// This is the reference model. There only needs to be one since
// we're swapping skins to get the appropriate flag. color="#000000">
// A texturegroup is defined for different colored flags. color="#000000">
$texturegroup skins
{
{ "red.bmp" }
{ "blue.bmp" }
}
$sequence idle "flagwave" fps 10 |
Monsters
$modelname "C:\Half-Life\valve\models\monster.mdl"
// This is where the final model is compiled to.
$cd "C:\Half-Life\valve\models\source\monster"
// This is the root folder where models and animations should go.
$externaltextures
// $externaltextures tells studiomdl to save skin textures as a separate *t.mdl file.
$sequencegroupsize 64
// $sequencegroupsize saves the animations into 64K files.
$scale 1.1
// Scale is a little larger than the original model.
$eyeposition 0 0 70
// $eyeposition tells the game where the eyes are in reference to the origin.
$attachment 0 "Bip01 R Hand" 15 3.5 5
$controller 0 "Bip01 Head" XR -40 40
$controller mouth "Bone03" ZR 0 45
// There is an attachment for the muzzleflash sprite, plus a controller to move the head
// and a controller to move the mouth.
$body studio "monster"
// This is the reference model.
// A bodygroup is defined so this monster can hold a pistol and also have it holstered.
$bodygroup weapon
{
studio "pistol"
blank
}
// A texturegroup is defined so this monster can have pain skins.
$texturegroup pain
{
{ "body_normal.bmp" "head_normal.bmp" }
{ "body_pain.bmp" "head_pain.bmp" }
}
// Hitboxes divide these bones into groups, and give the coordinates for each box.
$hbox 3 "Bip01 Pelvis" -4.69 -4.44 -6.75 4.00 5.56 6.75
$hbox 6 "Bip01 L Leg" 2.66 -3.69 -3.09 18.16 4.88 3.31
$hbox 6 "Bip01 L Leg1" 0.38 -3.97 -2.84 17.60 4.00 2.94
$hbox 6 "Bip01 L Foot" -0.59 -2.34 -2.63 3.79 8.00 2.19
$hbox 7 "Bip01 R Leg" 2.47 -3.69 -3.16 18.13 4.88 3.38
$hbox 7 "Bip01 R Leg1" 0.31 -3.97 -2.84 17.60 3.94 2.97
$hbox 7 "Bip01 R Foot" -0.56 -2.34 -2.19 3.81 8.00 2.66
$hbox 3 "Bip01 Spine1" -3.25 -5.50 -5.50 4.83 5.50 5.50
$hbox 2 "Bip01 Spine2" -0.06 -5.53 -7.59 8.00 7.00 7.59
$hbox 2 "Bip01 Spine3" -2.25 -6.81 -6.31 6.50 5.09 6.31
$hbox 2 "Bip01 Neck" -3.11 -1.50 -3.00 2.05 3.50 3.00
$hbox 1 "Bip01 Head" 0.09 -3.66 -3.00 8.41 5.09 3.00 color="#FF0000">// The head is always 1.
$hbox 4 "Bip01 L Arm" 0.94 -2.88 -4.13 5.44 4.28 3.50
$hbox 4 "Bip01 L Arm1" -2.16 -2.34 -2.56 11.56 3.41 2.38
$hbox 4 "Bip01 L Arm2" 0.59 -1.81 -2.19 10.75 2.84 2.41
$hbox 4 "Bip01 L Hand" 0.00 -1.00 -2.00 3.00 1.50 3.50
$hbox 5 "Bip01 R Arm" 1.38 -2.84 -3.56 5.69 4.31 4.31
$hbox 5 "Bip01 R Arm1" -1.88 -2.47 -2.16 11.81 3.28 2.81
$hbox 5 "Bip01 R Arm2" 0.44 -1.97 -2.34 10.59 2.72 2.22
$hbox 5 "Bip01 R Hand" 0.00 -1.00 -2.00 3.00 1.50 3.50
// basic animations
$sequence idle "idle" loop fps 8 ACT_IDLE 1
$sequence idle2 "idle2" loop fps 10 ACT_IDLE 3
// Here are two idle animations, both called ACT_IDLE. The game can randomly pick one to play based on
// it's multiplier. idle2 will be chosen 3 times more often than the other.
$sequence walk "walk" LX fps 10 loop ACT_WALK 1 {
{ event 1004 10 "footstep1.wav" } { event 1004 20 "footstep2.wav" }
}
$sequence run "run" LX fps 25 loop ACT_RUN 1 {
{ event 1004 10 "footstep1.wav" } { event 1004 20 "footstep2.wav" }
}
// LX is used to extract out the forward motion on the X-axis. Then event 1004 is used to play footstep sounds on frames 10 and 20. This is when the model's feet touch the ground.
$sequence turnleft "turnl" fps 15 ACT_TURN_LEFT 1
$sequence turnright "turnr" fps 15 ACT_TURN_RIGHT 1
// attacks
$sequence shoot1 "shoot1up" "shoot1down" loop fps 20 blend XR -50 50 ACT_RANGE_ATTACK1 1 {
{ event 5001 1 "21" } { event 6 1 }
}
$sequence shoot2 "shoot2up" "shoot2down" loop fps 25 blend XR -50 50 ACT_RANGE_ATTACK1 3 {
{ event 5001 1 "21" } { event 6 1 }
}
$sequence shootcrouch "shoot_crouchdown" "shoot_crouchup" loop fps 20 blend XR -50 50 ACT_RANGE_ATTACK2 1 { event 5001 1 "21" } { event 6 1 }
// These shooting animations have event 5001 show muzzleflash2.spr on frame 1 and run event # 6 also on
// frame 1. I use 5001 because it's origin is set to $attachment 0. Event 6 is defined in monster AI
// as the actual code that shoots the enemy. Plus the blend command is used to combine these two
// animations to get an accurate angle towards the enemy. color="#000000">
$sequence punch "punch_down" "punch_up" loop fps 20 blend XR -50 50 ACT_MELEE_ATTACK1 1 { event 7 5 }
// Event 7 is a code event that knocks the player around on frame 5, since this is a melee attack. color="#000000">
$sequence reload "reload" fps 15 ACT_RELOAD 1
$sequence draw "draw_weapon" fps 25 ACT_ARM 1 { event 4 10 }
// Event 4 is a code event that changes the weapon bodygroup to the pistol.
$sequence holster "holster_weapon" fps 10 ACT_DISARM 1 { event 5 15 }
// Event 5 is a code event that changes the weapon bodygroup to the blank one so the monster
// isn't holding the pistol anymore.
// pain & death
$sequence flinch_sm "flinch_sm" fps 20 ACT_SMALL_FLINCH 1
$sequence lflinch "leftarm_flinch" fps 15 ACT_FLINCH_LEFTARM 1
$sequence rflinch "rightarm_flinch" fps 15 ACT_FLINCH_RIGHTARM 1
$sequence diesimple "death" X fps 20 ACT_DIESIMPLE 1 { event 2001 10 }
$sequence dieviolent "die_violent" X fps 25 ACT_DIE_HEADSHOT 1 { event 2001 10 }
// Event 2001 tells the game that this monster is dead on frame 10.
// scripted sequences
$sequence blowupbuilding "blowupbuilding" fps 25 {
{ event 1004 28 "buttonpress.wav" }
{ event 1003 30 "bigexplosion" }
{ event 2001 50 }
}
// Here's a scripted sequence that uses event 1004 to play a sound on frame 28. The monster has hit a button to detonate explosives. Then event 1003 triggers the sequence "bigexplosion" in the map on frame 30. The monster dies so event 2001 tells the game that it's dead on frame 50. |
|