MOH Miscellneous Script Documentation


Contents:
MOH Script Syntax Summary
Moveanim Commands
Anim_attached commands
Model Surface Script Control
PlayerSpawn Stuff
Camera Tutorial
Description of the use of Huddraw set of script commands
Scripting Objectives
Mission Briefing Tutorial
Awarding Medals
Giving and Taking Stuff from the Player
Gun Turrets


MOH Script Syntax Summary

program:
--------
statement_list

statement_list:
---------------
statement statement ... statement

statement:
----------
identifier event_parameter_list :
case integer event_parameter_list :
case identifier event_parameter_list :
compound_statement
if prim_expr statement
if prim_expr statement else statement
while prim_expr statement
for ( statement ; expr ; statement_list ) statement
try compound_statement catch compound_statement
switch prim_expr compound_statement
break
continue
identifier event_parameter_list
nonident_prim_expr identifier event_parameter_list
nonident_prim_expr = expr
nonident_prim_expr += expr
nonident_prim_expr -= expr
nonident_prim_expr ++
nonident_prim_expr --
;

compound_statement:
-------------------
{ statement_list }

expr:
-----
expr && expr
expr || expr
expr & expr
expr | expr
expr ^ expr
expr == expr
expr != expr
expr < expr
expr > expr
expr <= expr
expr >= expr
expr + expr
expr - expr
expr * expr
expr / expr
expr % expr
nonident_prim_expr
func_prim_expr

func_prim_expr:
---------------
identifier event_parameter_list
nonident_prim_expr identifier event_parameter_list
- func_prim_expr
~ func_prim_expr
! func_prim_expr
identifier :: prim_expr
nonident_prim_expr :: prim_expr

event_parameter_list:
---------------------
prim_expr prim_expr ... prim_expr

prim_expr:
----------
nonident_prim_expr
identifier_prim
prim_expr :: prim_expr

nonident_prim_expr:
-------------------
$ prim_expr
nonident_prim_expr . identifier
nonident_prim_expr . size
nonident_prim_expr [ expr ]
string
integer
float
( number number number )
game
level
local
parm
self
group
( expr )
- nonident_prim_expr
~ nonident_prim_expr
! nonident_prim_expr
NULL
NIL

number:
-------
float
integer


Automatically started scripts
=============================

1) maps/mapname.scr
A level script is associated with each map, and is loaded and started at the start of that map (and not for subsequent starts from a saved game). This script is used for triggering all map related dynamic objects such as doors, elevators, AI, etc. maps/mapname.scr corresponds to maps/mapname.bsp. A level script is optional.

2) maps/mapname_precache.scr
A level precache script is associated with each map, and is loaded and started whenever the map is loaded (even from a saved game). This script is used for precaching map specific resources. maps/mapname_precache.scr corresponds to maps/mapname.bsp. A level precache script is optional.

3) Scripts in the anim directory are executed to carry out animation behavior of AI characters. Which script is executed is determined by internal AI state or scripts such as global/shoot.scr.


Threads
=======

A thread executes commands in a script one at a time in order. Multiple threads can exist. The automatically started scripts start execution with a single thread at the start of the file.

All threads belong to a group of threads, denoted "group". The current thread is denoted "local". The group of threads that a thread belongs to will be discussed in the next section.


Methods of creation of threads
------------------------------

1) Automatic
The new thread initially is the only thread in its group.

2) Command: thread label
The new thread belongs to the same group of threads as the original thread.

3) Command: thread filename::label
The new thread initially is the only thread in its group.

4) Command: object thread label
The new thread initially is the only thread in its group.

5) Command: object thread filename::label
The new thread initially is the only thread in its group.


Predefined object references
============================

1) game
Refers to the unique game object which maintains its state across levels. Only primitive values (integers/floats/strings/vectors) will persist across levels.

2) level
Refers to the unique level object which maintains its state for the duration of a level.

3) local
Refers to the thread executing the current command.

4) parm
Refers to the unique parm object which can be used to pass parameters to new threads.
Note that any use of this variable could be coded "better" by using parameters in the creation of new threads.

5) self
Refers to the object that the thread is processing for. This object is the same for all threads in a group of threads.

6) group
Refers to the object representing the group of threads the thread executing the current command belongs to.


self object
===========

The "self" object has its value set at the creation of a group of threads. The following are some such situations:

1) Automatically started scripts
self is NULL for level scripts. self is the character for animation scripts.

2) Command: thread label
Since the new thread has the same group as the original thread, self in the new thread is equal to self in the original thread.

3) Command: thread filename::label
self in the new thread is set equal to self in the original thread.

4) Command: object thread label
self in the new thread is set equal to object.

5) Command: object thread filename::label
self in the new thread is set equal to object.

6) If a thread is initiated in response to an event of an object, then self is set equal to this object.


switch (selection) statement
============================

Standard usage
--------------
switch (expr)
{
label1:
	statement
	...
	statement
	break

label2:
	statement
	...
	statement
	break

case 0:
	statement
	...
	statement
	break	

case 1:
	statement
	...
	statement
	break

default:
	statement
	...
	statement
	break
}
The expression expr is evaluated and cast to a string. Code execution tranfers to the matching label or to the optional default label if there is no match. The case prefix is required for integers, and optional for strings. The break command makes the switch statement finish.


if (conditional) statement
==========================

Standard usage
--------------
if (expr)
	statement

if (expr)
	statement
else
	statement

if (expr)
{
	statement
	...
	statement
}

if (expr)
{
	statement
	...
	statement
}
else
{
	statement
	...
	statement
}

arithmetic binary operators
===========================

precedence
----------

The operators are listed in order of later evaluation to sooner evaluation:

||
&&
|
^
&
== !=
< > <= >=
+ -
* / %


descriptions
------------

|| logical or (outputs 0 or 1)

&& logical and (outputs 0 or 1)

| bitwise or (outputs integer)

^ bitwise exclusive or (outputs integer)

& bitwise and (outputs integer)

== equality (outputs 0 or 1)

!= inequality (outputs 0 or 1)

< less than (outputs 0 or 1)

> gretaer than (outputs 0 or 1)

<= less than or equal (outputs 0 or 1)

>= greater than or equal (outputs 0 or 1)

+ plus (numeric or string types)

- minus

* multiply

/ divide

% modulus (remainder after division by integer)


while statement
===============

Standard usage
--------------
while (expr)
	statement

while (expr)
{
	statement
	...
	statement
}
At the start of a cycle of the loop the expression expr is evaluated and cast to boolean (true or false). While the expression evaluates to true the statement(s) are executed.
A continue placed inside such a loop will move the code execution point to the end of the current cycle of the loop.
A break placed inside such a loop will terminate execution of the loop (code execution will continue sfter the loop).


Example
-------
local.n = 1
while (local.n <= 10)
{
	println local.n
	local.n++
}

for statement
=============

Standard usage
--------------
for ( statement1 ; expr ; statement2 )
	statement

for ( statement1 ; expr ; statement2 )
{
	statement
	...
	statement
}
At the start of execution of this entire statement, statement1 is executed. At the start of a cycle of the loop the expression expr is evaluated and cast to boolean (true or false). While the expression evaluates to true the statement(s) are executed. At the end of each cycle of the loop, statement2 is executed.
A continue placed inside such a loop will move the code execution point to the end of the current cycle of the loop.
A break placed inside such a loop will terminate execution of the loop (code execution will continue after the loop).


Example
-------
for (local.n = 1; local.n <= 10; local.n++)
{
	println local.n
	local.n++
}
Vectors (coordinates)
=====================

Standard usage
--------------

( number number number )


Example
-------

(1.1 23.2 -15.5) is preferable to "1.1 23.2 -15.5" since the latter is a string which would be cast to a vector each time it is interpretted as a vector.


Note
----

Due to a parsing deficiency, vectors like (-1 2 3) should be written ( -1 2 3). That is, a space must be between the "(" and the "-".


Targetname operator $
=====================

The targetname operator $ converts a string to the object with targetname equal to that string.

Examples
--------

$my_targetname // object with targetname "my_targetname"

local.t = "my_targetname2"
$(local.t) // object with targetname "my_targetname2"


Variables
=========

Any object in the game can have variables in its variable list.


Examples
--------

game.a // variable a for game object

level.b // variable b for level object

local.c // variable c for local object

parm.d // variable d for parm object

self.e // variable e for self object

group.f // variable f for group object

$my_targetname.g // variable g for object with targetname "my_targetname"

self.enemy.health // for this to make sense self.enemy would be an object and self.enemy.health would be the health variable of this object


Arrays
======

Standard usage
--------------

nonident_prim_expr [ expr ]

nonident_prim_expr is a non-identify primitive expression and expr is an arbitrary expression.
nonident_prim_expr [ expr ] interprets nonident_prim_expr as an array and accesses the element at the position at which expr evaluates to.
Indexing of arrays can be by integers or strings.


Types of arrays
---------------

1) Constant array
Created by expression of the form entry_1::entry_2::entry_3:: ... :: entry_n
Constant arrays start their indexing at 1.
Once created a constant array can not be changed but it can be read for its values.

2) Hash table array
Unitialised entries evaluate to NIL. Any new entry can be set.

3) Targetname array
Created by the $ targetname operator if more than one entity exists for that targetname.
For example, $player is an array if more than one player is in the game.
Targetname arrays start their indexing at 1.

Examples
--------
println local.n[10]    // prints the element at position 10 of the local.n array

local.n[1][3] = 10     // sets the element at position (1, 3) of the local.n array equal to 10 (Hash table array)

local.n = hello::world::this::is::a::test::123    // consant array
println local.n[1]     // prints hello
println local.n[7]     // prints 123
println local.n[8]     // results in Script Error: const array index '8' out of range
println local.n[hello]     // results in Script Error: const array index '0' out of range

local.n[hello][world][5] = 23
local.a = local.n[hello]
local.b = local.a[world]
println local.b[5]     // prints 23

for (local.n = 1; local.n <= 10; local.n++)
	println game.stats[game.stats_name[local.n]]    // print out element in game.stats array at position game.stats_name[local.n]

local.a = (a::b)::c
println local.a[1][1]   // prints a
println local.a[1][2]   // prints b
println local.a[2]      // prints c
Vector Examples
---------------

Vectors are accessed like arrays in the indices 0, 1, 2.
A vector could be set like
local.my_vector = (10 -2 60.1)

Then this vector could be accessed like:
println local.n[2]
which would print 60.1 to the console.


Example
-------
$player.origin += (5 6 7) // offset the player's origin by (5 6 7).


Make Array Example
------------------
local.Path1 = makeArray
t1 300 10 200
t2 
t3
t4
t5
t6
t7 NIL 10 200
t8
t9
t10
t11
t12
t13
t14 0 10 200
endArray

println local.Path1[1][2]
println local.Path1[1][3]
println local.Path1[1][4]
println local.Path1[1][5]
println local.Path1[14][1]
println local.Path1[15][1]
end
results in:
300
10
200
NIL
t14
NIL
printed to console.


Automatic casting
=================

If a parameter in a statement is required to be of some type, then an automatic cast will be attempted.


Accessing characters of a string
================================

Characters of a string are accessed by the [] array operator. Indexing starts at 0.
For example, "abc"[2] evaluates to the string "c".
There is no character type, so characters are just strings of length 1.





Moveanim command

If you have an animated prop that you want to use in the game and it is not an actor, simply create a ScriptModel assign it a targetname and use the “moveanim” command. The command only takes one argument, the name of the animation, it can be used as follows:

	// $truck is a ScriptModel entity with a tiki that has a drive_and_crash animation
	while (1)
	{
		$truck moveanim drive_and_crash
		$truck waittill animdone
	}
This will make the truck playback his “drive_and_crash” animation and the moveanim command will cause the truck to move through the world like a normal script object.





Anim_attached command

If you want to play back an animation that has movement in it on an Actor that has been attached to another object, use the “anim_attached” command. Below is an example of a guy that has been attached to a bone and is then animated:

// Main script
$dude script actorthread
end

actorthread:
	self attach $plane "seat01" 1 ( 0 0 0 )
	self exec global/disable_ai.scr

	self anim_attached idle
	self waittill animdone

	self anim_attached standup
	self waittill animdone

	self anim_attached walk
	self waittill animdone

	end




Model Surface Script Control
To control the surfaces of a model from script you can use the surface command

$targetname surface (+/-)command

        + sets the flag, - clears the flag
        Valid surface commands are:
        skin1 - set the skin1 offset bit
        skin2 - set the skin2 offset bit
        nodraw - don't draw this surface

Asserting the nodraw flag will cause the surface not to be drawn.

By setting the “skin1” or “skin2” bits, you can offset the shader being used for that surface and change it. Multiple shaders for that surface need to be defined in the tiki file.





PlayerSpawn Stuff

To spawn something near the player, either within the player's view or behind him use the player spawn command.

playerspawn model [range] [vector_offset] [inFOV] [speed]

        model - name of model to spawn
        range - how close does this need to be to the player to actually get spawned, default 480 (30 foot radius).
        vector_offset - oriented vector offset of where to spawn the item, default (0 0 0)
        inFOV
                1 Only spawn when this position is within the FOV of the player
                -1 Only spawn when this position is outside the FOV of the player
                0 (default) don't care, always spawn
        speed - how fast the effect should travel, in other words, how long before the effect gets spawned. The delay is calculated based on the distance between object and player divided by the speed
                0 no delay
                960 (default) 60 feet per second. If the object is 60 feet from the player, the player effect will spawn one second later.





Camera Tutorial

To spawn a camera from script use the following command:

spawn Camera targetname MyCamera

To spawn a camera in your map, use a func_camera:

func_camera ORBIT START_ON AUTOMATIC NO_TRACE NO_WATCH LEVEL_EXIT

Camera used for cinematic sequences.

"target" points to the target to orbit or follow. If it points to a path, the camera will follow the path.
"speed" specifies how fast to move on the path or orbit. (default 1).
"fov" specifies fov of camera, default 90. if fov is less than 3 than an auto-fov feature is assumed. The fov will then specify the ratio to be used to keep a watched entity zoomed in and on the screen.
"follow_yaw" specifies yaw of the follow camera, default 0.
"follow_distance" the distance to follow or orbit if the target is not a path. (default 128).
"orbit_height" specifies height of camera from origin for orbiting, default 128.
"nextcamera" a link to the next camera in a chain of cameras
"thread" a thread label that will be fired when the camera is looked through
"auto_state" if specified, denotes the state the player must be in for the camera to engage any number of states can be specified and only the first few letters need be specified as well a state of 'pipe' would mean that any player state that started with 'pipe' would trigger this camera
"auto_radius" the radius, in which the camera will automatically turn on (default 512)
"auto_starttime" how long it takes for the camera to be switched to (default 0.2)
"auto_stoptime" how long it takes for the camera to switch back to the player (default 0.2)
"auto_maxfov" Sets the maximum FOV that should be used when automatically calculating FOV. (default 90)

ORBIT tells the camera to create a circular path around the object it points to. It the camera points to a path, it will loop when it gets to the end of the path.
START_ON causes the camera to be moving as soon as it is spawned.
AUTOMATIC causes the camera to be switched to automatically when the player is within a certain radius, if "thread" is specified, that thread will be triggered when the camers is activated
NO_TRACE when the camera is in automatic mode, it will try to trace to the player before switching automatically, this turns off that feature
NO_WATCH if this is an automatic camera, the camera will automatically watch the player unless this is set, camera's "score" will be affected by how close to the middle of the camera the player is.
LEVEL_EXIT if the camera is being used, the level exit state will be set

Switching between cameras is accomplished with these commands:

cuecamera cameraName [switchTime]
Switch to the specified camera. If switch time is specified and you are not already in camera view, the camera will smoothly transition from the third person camera to this camera
cueplayer [switchTime]
Switch back to third person mode. If switchtime is specified, than camera will switch over that period of time.


Other useful scripting commands for cinematics:

freezeplayer
Freezes the player wherever he is standing

releaseplayer
Release the player after he has been frozen

Script commands for the camera are as follows:
All commands must have the targetname of the camera pre-pended.

start
Start the camera moving or watching

pause
Pause the camera along its path.

continue
Resume the camera’s movement

stop
Stop the camera from moving and watching

speed newSpeed
Set the speed of the camera

fov newFov [fadeTime]
Set the fov of the camera and optionally the time over which the fov should transition, default is whatever the camera’s fadetime is set to.

follow targetEntity [targetWatchEntity]
Start following an entity, if that entity is a splinepath then the path will be followed. If targetWatchEntity is specified than that entity will be watched while following targetEntity. By default targetEntity will be watched as well.

follow_distance followDistance
Distance at which the camera should follow an entity, also used for orbit radius.

follow_yaw yawOffset
Yaw offset of the camera following an entity

follow_yaw_absolute
Make the follow yaw absolute rather than relative to the follow entity’s angles

follow_yaw_relative
Make the follow yaw relative to the follow entitiy’s angles

orbit targetEntity [targetWatchEntity]
Start orbiting an entity, if that entity is a splinepath then the path will be followed and looped. If targetWatchEntity is specified than that entity will be watched while following targetEntity. By default targetEntity will be watched as well.

orbit_height newHeight
Height offset for orbiting an entity

watch watchEntity [fadeTime]
Start watching an entity, and optionally the time over which the transition should occur. The default transition time is the camera’s fadetime.

watchpath [fadeTime]
Start looking along the direction of movement and optionally the time over which the transition should occur. The default transition time is the camera’s fadetime.

watchnode [fadeTime]
Start basing the camera’s orientation off of what is stored in the camera path nodes and optionally the time over which the transition should occur. The default transition time is the camera’s fadetime.

nowatch [fadeTime]
Stop watching an entity, looking along a path or anything else. The camera’s orientation is now static. Optionally transition overt the time specified. The default transition time is the camera’s fadetime.

lookat targetEntity
Immediately make the camera look at the given entity

turnto newAngles
Immediately turn the camera to the desired angles. NewAngles is a vector

moveto targetEntity
Immediately move the camera to the targetEntity’s origin

movetopos newPosition
Immediately move to the specified world space position

fadetime newFadetime
Specifiy a new fadetime for this camera, this fadetime will be used for any of the watch or follow commands if no explicit fadetime is specified.

cut
Switch cameras immediately, don’t transition over time

setthread threadName
Sets the thread of the camera which is accessed from a trigger_camerause


Here is an example script file using a camera that is placed at the players position and then tracks the player followed by a plane:


// move the cameras origin to the players position
local.pos = $player.origin + (0 0 64)
$watch_camera movetopos local.pos

// tell the camera to watch the player
// the '0' is to fade in no time at all
// NOTE the ""’s are necessary
$watch_camera watch "$player" 0

// cut causes the camera to transition to its new state immediately
$watch_camera cut

// NOT NEEDED FOR OTHER ENTITIES
// HACK to make the player visible
setcvar cg_3rd_person 1

// cuecamera causes us to switch to a camera
cuecamera $watch_camera

wait 6

println "switching to plane"
// watch the plane
// tell the camera to watch the plane
// the '2' is to switch to our new watch over 2 seconds
// NOTE the ""’s are necessary
$watch_camera watch "$plane" 2

// cut causes the camera to transition to its new state immediately
// we don't want that here so we aren't doing it
//$watch_camera cut

wait 8

println "switching to player"

// NOT NEEDED FOR OTHER ENTITIES
// HACK to make the player invisible again
setcvar cg_3rd_person 0
// cueplayer causes us to switch back to the player
cueplayer




Description of the use of the huddraw set of script commands
The huddraw script commands allow you to draw up to 256 different graphic icons on the player’s hud. The element to adjust with each command is specified by an index number in the range of 0 to 255. They currently broadcast to all players, but that could be changed if the need arises.

Commands Summary


huddraw_shader <index> <shader name>
This sets the shader to use for a particular huddraw element.

huddraw_align <index> <horizontal> <vertical>
This sets the alignment of the huddraw element. Valid values for horizontal alignment are “left”, “center”, and “right”.Valid values for vertical alignment are “top”, “center”, and “bottom”.

huddraw_rect <index> <X position> <Y position> <width> <height>
This sets the position and size of the huddraw element. X and Y specify the position of the upper left corner position. Higher values of X move it to the right, and highervalues of Y move it down. When you set the alignment, the XY position specified is relative to that alignment. For example, if you align it to the right edge of the hud, the X position should be less than zero so that it the upper left corner will be brought back to the left onto the screen.

huddraw_virtualsize <index> <virtual>
This let’s you set the huddraw element’s size and position according to a virtual screen resolution of 640x480. What this means is that it lets you treat the hud like it’s always at 640x480, and it will be properly resized and positioned according to the actual resolution.

huddraw_color <index> <red> <green> <blue>
This set the color of the huddraw element. Each color channel should be between 0 and 1.

huddraw_alpha <index> <alpha>
This set the alpha of the huddraw element. It should be set between 0 and 1. This is also used to turn off a huddraw element that is no longer wanted by setting the alpha to 0.

huddraw_string <index> <string>
This sets the huddraw element to display a string instead of a shader graphic. The size of the font can not be adjusted, but the color and alpha settings do affect the text. The width and height parameters of huddraw_rect are only used for alignment centering, Not for setting the size of the string.

huddraw_font <index> <fontname>
This sets the font for a string displaying huddraw element to use. The names of available font can be gotten from the game/main/fonts folder. The file names of the .ritualfont files in there are the names used for the fonts.





Scripting Objectives

This document describes how to create and manage the objective list for a level.


Objective Components.

Each objective in the objective list has four components: an index, a status attribute, a text message, and a location

The index component must be a value greater than zero and determines the order in which the objective is displayed in the objective list. Objectives with a smaller index value are displayed before (higher on the list) objectives with higher index values. Typically, the objectives in an objective list are numbered sequentially starting at 1.

The status attribute component determines how the objective is displayed in the objective list. If this attribute is 1, then the objective is not displayed in the objective list. If this attribute is 2, then the objective is displayed, unchecked (not completed), in the objective list. If this attribute is 3, then the objective is displayed, checked (completed), in the objective list.

The text message component is the string that is displayed for the objective.

The location component is optional and marks a location in the level. When the objective becomes the “current” objective (see below), the location component is used to set the objective pointer on the HUD compass


Creating An Objective List.

Objectives are added to the objective list using the following script command:

waitthread global/objectives.scr::add_objectives <idx> <attr> <text> <loc>

Where <idx>, <attr>, <text> and <loc> are, respectively, the index, status attribute, text message and location components of the objective to be added.

When an objective is initially added to the objective list, the status attribute component that is specified must be either 1 or 2. That is, you cannot initially add a completed objective to the objective list.

Remember that only those objectives whose status attribute component is 2 or 3 will be displayed in the objective list.


Setting The Current Objective.

The current objective is set using the following script command:

waitthread global/objectives.scr::current_objectives <idx>

The value specified by <idx> should correspond to the index component of an objective in the objective list.

When the current objective is displayed in the objective list, it is shown in yellow text, rather than the default white text.


Level Objective Scripting Example.

This is an example of how the objectives for a simple level might be managed. Explanations for some script commands are provided where appropriate. The script commands are part of the script file (.SCR) for the level.


//
// test.scr
//

// add the first objective
waitthread global/objectives.scr::add_objectives 1 2 "Find the first objective." $objective1trigger.origin

// add the second objective
waitthread global/objectives.scr::add_objectives 2 2 "Find the second objective." $objective2trigger.origin

// add the third objective
waitthread global/objectives.scr::add_objectives 3 2 "Find the third objective." $objective3trigger.origin

// add the final objective, though not displayed
waitthread global/objectives.scr::add_objectives 4 1 "Find the final objective." $endleveltrigger.origin

// set the current objective to index #1
waitthread global/objectives.scr::current_objectives 1

// start the thread that waits for objective 1 completion
thread objective1

end


// thread that waits for objective 1 completion
objective1:

// wait for the trigger to be encroached
$objective1trigger waittill trigger

// mark objective 1 as complete
waitthread global/objectives.scr::add_objectives 1 3

// set the current objective to index #2
waitthread global/objectives.scr::current_objectives 2

// start the thread that waits for objective 1 completion
thread objective2

end


// thread that waits for objective 2 completion
objective2:

// wait for the trigger to be encroached
$objective2trigger waittill trigger

// mark objective 2 as complete
waitthread global/objectives.scr::add_objectives 2 3

// set the current objective to index #3
waitthread global/objectives.scr::current_objectives 3

// start the thread that waits for objective 3 completion
thread objective3

end


// thread that waits for objective 3 completion
objective3:

// wait for the trigger to be encroached
$objective3trigger waittill trigger

// disable display of objectives 1,2,3 enable objective 4
waitthread global/objectives.scr::add_objectives 1 1
waitthread global/objectives.scr::add_objectives 2 1
waitthread global/objectives.scr::add_objectives 3 1
waitthread global/objectives.scr::add_objectives 4 2

// set the current objective to index #4
waitthread global/objectives.scr::current_objectives 4

// start the thread that waits for final objective completion
thread objective4

end


// thread that waits for final objective completion
objective4:

// wait for the trigger to be encroached
$endleveltrigger waittill trigger

// mark final objective as complete
waitthread global/objectives.scr::add_objectives 4 3

// transition to next level
exec global/missioncomplete.scr nextlevelmapname bsp2bsp

end




Mission Briefing Tutorial

This document describes how to create a mission briefing. The mission briefing is technically a playable level, though the script for the level disables player movement. The script is also responsible for playing the briefing, which is essentially a series of menus in displayed in slideshow fashion. In this tutorial, we will examine a typical MOHAA mission briefing level.


How The System Works.

The player begins a mission from the briefingroom menu (this is the internal name of the menu that is run after selecting “new game” or “briefing room” in the main menu). When the mission and difficulty level are selected, the menu starts the corresponding briefing level.

The briefing level is a simple, unlit room in which a sequence of menus is displayed. The level script starts threads to disable player movement and check for the fire button. The main script thread consists of instructions to (1) show slides (menus), (2) play sound effects, and (3) wait for the next slide cue. Once the slideshow is complete, the script executes the command to load the first playable map for the mission.


Dissecting briefing5.scr.

If we examine the level script file (included below for reference) for the mission 5 briefing level of MOHAA, we can begin to understand how the briefing levels work.

The first 15 lines properly configure the level into “briefing” mode. On line 4, the HUD is disabled. On line 10, the thread to poll the fire button (to prematurely end the briefing) is started. On line 13, player physics is disabled. Finally, on line 14, the thread to disable player movement is started.

The remaining code in the main thread is written specifically for the sequence of images and sounds needed for (in this case) mission 5.

The “slides” that are displayed are actually menus and are displayed as demonstrated on lines 21 and 28 (among others). Notice that whenever a new menu is displayed over another, the former menu is hidden afterwards.

Sounds are cued as demonstrated on lines 17, 19 and 23 (among others). Lines 49 and 50 show how the script can cue a sound and pause until the sound ends.

Lines 24, 30 and 36 (among others) show how to pause the script for a specific amount of time.

Finally, when the briefing is complete, the script executes another thread (see line 68) to launch the first map of the mission. In this case, the map is m5l1a (see line 74).


Reference.

For reference, a slightly modified version of briefing5.scr, the script file for the briefing level for mission 5 in MOHAA.


 1:  start:
 2:  
 3:  level waittill prespawn
 4:  drawhud 0
 5:  
 6:  level waittill spawn
 7:  exec global/briefing_save.scr
 8:  
 9:  // spawn the thread that will allow the player to skip the briefing
10:  thread briefingskip
11:  
12:  // prevent the player from trying to move around
13:  $player physics_off
14:  thread freezeplayerview
15:  
16:  //starts music track for mission briefing
17:  $player playsound mb5_music
18:  
19:  $player playsound slide_advance
20:  
21:  showmenu briefing5a 1
22:  
23:  $player playsound mb_501
24:  wait 10
25:  
26:  $player playsound slide_advance
27:  
28:  showmenu briefing5a2 1
29:  hidemenu briefing5a 1
30:  wait 8
31:  
32:  $player playsound slide_advance
33:  
34:  showmenu briefing5a3 1
35:  hidemenu briefing5a2 1
36:  wait 4
37:  
38:  $player playsound slide_advance
39:  
40:  showmenu briefing5b 1
41:  hidemenu briefing5a3 1
42:  wait 8
43:  
44:  $player playsound slide_advance
45:  
46:  showmenu briefing5c 1
47:  hidemenu briefing5b 1
48:  
49:  $player playsound mb_502 wait
50:  $player waittill sounddone
51:  
52:  $player playsound slide_advance
53:  
54:  showmenu briefing5d 1
55:  hidemenu briefing5c 1
56:  
57:  $player playsound mb_503 wait
58:  $player waittill sounddone
59:  
60:  $player playsound slide_advance
61:  
62:  showmenu briefing5e 1
63:  hidemenu briefing5d 1
64:  
65:  $player playsound mb_504 wait
66:  $player waittill sounddone
67:  
68:  goto endbriefing
69:  
70:  end
71:  
72:  endbriefing:
73:  
74:  $player stufftext "spmap m5l1a"
75:  
76:  end
77:  
78:  briefingskip:
79:  
80:      if($player.fireheld)
81:      {
82:          goto endbriefing
83:      }
84:  
85:      // check again next server frame
86:      wait 0.01
87:  
88:      goto briefingskip
89:  
90:  end
91:  
92:  freezeplayerview:
93:  
94:      $player.viewangles = (0 0 0)
95:  
96:      wait 0.01
97:      goto freezeplayerview
98:  
99:  end




Awarding Medals

There are up to six medals that can be awarded in Spearhead. Awarding medals is very easy:


if (...)
{
    setcvar g_medal0 "1"
    println "You got a medal!"
}

As per the example, simply set the cvar for the medal you are awarding to "1". That's it!

Additionally a medal can be awarded according to your skill level:


level.skill = getcvar (skill)

if (level.skill == "0")
{ 
    setcvar "g_eogmedal2" "1" //Bronze Star
}
else if (level.skill == "1")
{
    setcvar "g_eogmedal1" "1" //Silver Star 
}

else if (level.skill == "2")
{ 
    setcvar "g_eogmedal0" "1" //Distinguished Service Cross
}

end




Giving and Taking Stuff from the Player

To give an item to a player (any quantity of it) simply use the following script command:
$player item items/blaa.tik <num>
$player is a targetname that’s automatically recognized as the player. The items/blaa.tik should be replaced by the tik file for the item, relative to the models folder. For example, to give a bratwurst, you’d use items/bratwurst.tik. This command can also be used to give the player weapons, such as weapons/colt45.tik.

To give the player ammo, this script command should be used:
$player ammo type amount
Type is a small string identifier for the type of ammo to give, and amount is the amount of that ammo type to give to the player. The different ammo types are:

To take something away from the player (item, weapon, or ammo) use the following script command:
$player take name
If taking away an item or weapon, name is the tik file of the item or weapon to take. If taking away ammo, name is the string identifier of that ammo type (they’re listed above). This command takes away all of the specified thing, be it items, a weapon, or ammo.

To take away everything the player has, use the following script command:
$player takeall
This takes all items, weapons, and ammo the player has, leaving the poor wretch humiliated and destitute.





Gun Turrets
Gun turrets are fixed location guns that can be used by AI, or players, or controlled by script. In the editor’s right click menu, they are located under “turret”. Any models used for turret stands are located in “static/turret”.

Placement:
        Turrets rotate around their origin, so to properly place them, their origin should be located directly over their attachment point to whatever they’re attached to. The origin is the place where the entity’s direction arrow comes out of.

Commands: The following are the commands that can be used specifically to control a turret. Any commands used to control entities can also be used on the turrets. All of these commands can be used from both the editor (by setting it as a key value), or in a script (by issuing it as a command).